Skip to content

Refactor SelectPanel behind a feature flag with mode-specific next architecture#7732

Draft
hectahertz wants to merge 4 commits intomainfrom
hectahertz/selectpanel-next
Draft

Refactor SelectPanel behind a feature flag with mode-specific next architecture#7732
hectahertz wants to merge 4 commits intomainfrom
hectahertz/selectpanel-next

Conversation

@hectahertz
Copy link
Copy Markdown
Contributor

@hectahertz hectahertz commented Apr 7, 2026

Closes #

Changelog

New

  • Added a gated next-generation SelectPanel path behind primer_react_select_panel_next (default false).
  • Added a stable wrapper architecture:
    • SelectPanel (public entry)
    • SelectPanelLegacy (fallback path)
    • SelectPanelNext (flagged path)
  • Added shared contract/types module for SelectPanel public surface and helpers.
  • Added next-only internal modules to separate concerns:
    • state/reducer
    • side-effect hooks
    • shared frame renderer
    • mode-specific controllers (single and multi)
    • mode-specific and shared utility modules
  • Added focused next-path test suite plus direct controller-level tests.
  • Added feature story coverage for the flagged path.

Changed

  • Preserved existing public API while changing internal composition.
  • Next-path mode is explicit internally (single vs multi) and derived once in the wrapper.
  • Wrapper mode handoff now uses typed narrowing (no cast-based boundary).
  • Selection behavior is split by mode instead of interleaved branching.
  • Mode-specific actions (onSave, onSelectAllChange) are now centralized in a single mode model in SelectPanelNext orchestration.
  • Footer/layout decisioning is centralized in dedicated helpers/components.
  • Loading/empty-state handling was fixed to satisfy contract behavior for controlled, initial-empty scenarios.
  • Main SelectPanel contract tests run under both feature-flag states.

Removed

  • Removed mixed-mode branching from shared next internals where not needed.
  • Removed shared reducer ownership of single-only staged selection state.
  • Removed duplicate mode metadata from controller configs where frame already owns rendering source of truth.

Why this change

The previous implementation mixed multiple responsibilities in one large component (overlay shell, mode routing, state transitions, selection semantics, and footer behavior). That made regressions more likely and mode-specific behavior harder to reason about.

This refactor keeps rollout risk low (feature-flagged, legacy fallback intact) while making the next path easier to test, evolve, and eventually promote.

What is better now

Before
------
SelectPanel
  -> one large implementation with cross-cutting mode branches

After
-----
SelectPanel (public API unchanged)
  -> Legacy (fallback)
  -> Next (flagged)
       -> Frame (shared UI shell)
       -> Single controller (mode-specific behavior)
       -> Multi controller (mode-specific behavior)
       -> Shared + mode-specific state/hooks/utils
Mode handling
-------------
Before: infer mode repeatedly from `selected` shape in many places
After : derive once in wrapper -> pass explicit mode -> route behavior cleanly

Key practical improvements:

  • Clear ownership boundaries for rendering vs behavior vs effects.
  • Stronger boundary typing in wrapper-to-next handoff.
  • Better unit test targeting for reducer/helpers/mode behavior.
  • Contract parity maintained across legacy and next paths, including fixed initial-empty empty-state behavior.

Rollout strategy

  • Patch release
  • Minor release
  • Major release; if selected, include a written rollout or migration plan
  • None; if selected, include a brief description as to why

Rationale: Public SelectPanel API remains compatible. Internal architecture is refactored behind a default-off feature flag, with behavior parity coverage and legacy fallback preserved.

Testing & Reviewing

Validated locally:

  • runTests on:
    • packages/react/src/SelectPanel/SelectPanel.test.tsx
    • packages/react/src/SelectPanel/SelectPanelNext.test.tsx
    • Result: 231 passed, 0 failed
  • npm run type-check at repository root: passed.
  • Touched files were formatted and lint-fixed.

Suggested review path:

  1. Wrapper/flag gating and API preservation.
  2. Next architecture split (frame + mode controllers + split internals).
  3. Mode model orchestration cleanup in SelectPanelNext.
  4. Contract parity tests (both flag states) plus focused next/controller tests.

Merge checklist

  • Added/updated tests
  • Added/updated documentation
  • Added/updated previews (Storybook)
  • Changes are SSR compatible
  • Tested in Chrome
  • Tested in Firefox
  • Tested in Safari
  • Tested in Edge
  • (GitHub staff only) Integration tests pass at github/github-ui (Learn more about how to run integration tests)

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Apr 7, 2026

🦋 Changeset detected

Latest commit: 6070498

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@primer/react Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions github-actions bot added the integration-tests: recommended This change needs to be tested for breaking changes. See https://arc.net/l/quote/tdmpakpm label Apr 7, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

⚠️ Action required

👋 Hi, this pull request contains changes to the source code that github/github-ui depends on. If you are GitHub staff, test these changes with github/github-ui using the integration workflow. Check the integration testing docs for step-by-step instructions. Or, apply the integration-tests: skipped manually label to skip these checks.

To publish a canary release for integration testing, apply the Canary Release label to this PR.

@primer
Copy link
Copy Markdown
Contributor

primer bot commented Apr 7, 2026

🤖 Lint issues have been automatically fixed and committed to this PR.

@github-actions github-actions bot requested a deployment to storybook-preview-7732 April 7, 2026 15:14 Abandoned
@hectahertz hectahertz force-pushed the hectahertz/selectpanel-next branch from 4f686bc to b2587a3 Compare April 7, 2026 15:45
@hectahertz hectahertz changed the title Refactor SelectPanel behind feature flag Refactor SelectPanel behind a feature flag with mode-specific next architecture Apr 7, 2026
@primer
Copy link
Copy Markdown
Contributor

primer bot commented Apr 7, 2026

🤖 Lint issues have been automatically fixed and committed to this PR.

@github-actions github-actions bot requested a deployment to storybook-preview-7732 April 7, 2026 15:52 Abandoned
@hectahertz hectahertz force-pushed the hectahertz/selectpanel-next branch from b2587a3 to bc49f6e Compare April 7, 2026 15:57
@hectahertz hectahertz changed the base branch from hectahertz/data-action-list to main April 7, 2026 15:58
@primer
Copy link
Copy Markdown
Contributor

primer bot commented Apr 7, 2026

🤖 Lint issues have been automatically fixed and committed to this PR.

@github-actions github-actions bot requested a deployment to storybook-preview-7732 April 7, 2026 16:04 Abandoned
@primer
Copy link
Copy Markdown
Contributor

primer bot commented Apr 7, 2026

🤖 Lint issues have been automatically fixed and committed to this PR.

@github-actions github-actions bot requested a deployment to storybook-preview-7732 April 7, 2026 16:15 Abandoned
@primer
Copy link
Copy Markdown
Contributor

primer bot commented Apr 7, 2026

🤖 Lint issues have been automatically fixed and committed to this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

integration-tests: recommended This change needs to be tested for breaking changes. See https://arc.net/l/quote/tdmpakpm

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant