-
Notifications
You must be signed in to change notification settings - Fork 203
[GOOSE-180][BpkSegmentedControl] : Convert to Tab Interaction Pattern #4079
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[GOOSE-180][BpkSegmentedControl] : Convert to Tab Interaction Pattern #4079
Conversation
|
Visit https://backpack.github.io/storybook-prs/4079 to see this build running in a browser. |
|
Visit https://backpack.github.io/storybook-prs/4079 to see this build running in a browser. |
…ility and RTL support
|
Visit https://backpack.github.io/storybook-prs/4079 to see this build running in a browser. |
…for better integration with useSegmentedControlPanels
|
Visit https://backpack.github.io/storybook-prs/4079 to see this build running in a browser. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This pull request converts the BpkSegmentedControl component to implement the ARIA tabs interaction pattern, enhancing accessibility and usability. The changes introduce keyboard navigation, support for tab panels with proper ARIA relationships, and a new hook for simplified implementation.
Key Changes:
- Implemented full ARIA tabs pattern with keyboard navigation (arrow keys, Home/End) and RTL support
- Added
useSegmentedControlPanelshook for automatic ID generation and ARIA relationship management - Introduced activation modes (automatic/manual) to control tab selection behavior
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
packages/bpk-component-segmented-control/src/BpkSegmentedControl.tsx |
Core component changes: added keyboard navigation, tab roles, ARIA attributes, and useSegmentedControlPanels hook |
packages/bpk-component-segmented-control/index.ts |
Exported new useSegmentedControlPanels hook and TabPanelProps type |
packages/bpk-component-segmented-control/src/accessibility-test.tsx |
Added accessibility tests for both tab-only and tab-with-panel usage scenarios |
packages/bpk-component-segmented-control/src/BpkSegmentedControl-test.tsx |
Comprehensive test coverage for keyboard navigation, RTL support, and activation modes |
packages/bpk-component-segmented-control/README.md |
Updated documentation with usage examples, accessibility guidelines, and keyboard navigation details |
examples/bpk-component-segmented-control/examples.tsx |
Added example implementations demonstrating hook-based and conditional rendering patterns |
examples/bpk-component-segmented-control/stories.tsx |
Added Storybook stories for new example components |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // TODO: Consider removing internal state - component is controlled via selectedIndex prop. | ||
| // Internal state may cause sync issues if selectedIndex changes externally. | ||
| const [selectedButton, setSelectedButton] = useState(selectedIndex); |
Copilot
AI
Dec 11, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The component maintains internal state that duplicates the selectedIndex prop, which can lead to synchronization issues. The component should either be fully controlled (no internal state) or the internal state should sync with prop changes via useEffect. Consider using the prop value directly or adding a useEffect to sync state when selectedIndex changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is up for discussion for backpack owners.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi, good point — duplicated state can cause sync issues. Switching to a fully controlled API would be a breaking change, so we can’t do that immediately. As a pragmatic step, we’ll create a ticket to discuss deprecating internal state
packages/bpk-component-segmented-control/src/BpkSegmentedControl.tsx
Outdated
Show resolved
Hide resolved
|
Visit https://backpack.github.io/storybook-prs/4079 to see this build running in a browser. |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
|
Visit https://backpack.github.io/storybook-prs/4079 to see this build running in a browser. |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
|
Visit https://backpack.github.io/storybook-prs/4079 to see this build running in a browser. |
|
Visit https://backpack.github.io/storybook-prs/4079 to see this build running in a browser. |
IrinaWei
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Gert-Jan Vercauteren (gert-janvercauteren)
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi Noel Rajan (@FireRedNinja)!
Thanks for contributing, really appreciated.
Considering all our consumers, we might want to consider to support both tab/non-tab behaviours for this component, is there a way to keep the original segmented control interaction pattern without forcing our consumers to implement tab panel?
(In the case of flight results, this component is used as a radio button to apply filters)
Changes
This pull request introduces significant improvements to the
BpkSegmentedControlcomponent, focusing on accessibility, API, and documentation. The most notable changes are the addition of a newuseSegmentedControlPanelshook for managing tab panels with proper ARIA relationships, enhancements to keyboard navigation and activation modes, and updates to documentation and examples to reflect these improvements.Accessibility and API Improvements
useSegmentedControlPanelshook and supporting types: Provides an easy-to-use API for managing tab panels, automatically generating IDs and ARIA relationships for accessibility. Also exports new types such asTabPanelPropsfor better type safety. (packages/bpk-component-segmented-control/src/BpkSegmentedControl.tsx[1] [2];packages/bpk-component-segmented-control/index.ts[3]packages/bpk-component-segmented-control/src/BpkSegmentedControl.tsx[1] [2]packages/bpk-component-segmented-control/src/accessibility-test.tsxpackages/bpk-component-segmented-control/src/accessibility-test.tsxL22-R73)Documentation and Examples
packages/bpk-component-segmented-control/README.mdpackages/bpk-component-segmented-control/README.mdL1-R93)examples/bpk-component-segmented-control/examples.tsx[1] [2] [3];examples/bpk-component-segmented-control/stories.tsx[4] [5]Remember to include the following changes:
[Clover-123][BpkButton] Updating the colourREADME.md(If you have created a new component)README.md