-
Notifications
You must be signed in to change notification settings - Fork 0
Add segmented control primitive and improve dropdown menu keyboard ergonomics #8
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
Merged
Merged
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
96f59e1
feat: add segmented control and menu typeahead
Copilot ef98d71
fix: remove duplicate segmented control keydown path
Copilot f95d30b
test: fix segmented control listener assertion timing
Copilot d90a470
test: rename segmented control setup hook
Copilot dbc53ad
Potential fix for pull request finding 'Useless assignment to local v…
JosunLP f9ac91f
Potential fix for pull request finding 'Unused variable, import, func…
JosunLP 1b7f3f2
test: cover segmented control keyboard handler
Copilot 6c71faf
test: use public keyboard path in segmented control test
Copilot e4eff31
test: tighten segmented control keyboard regression
Copilot f477e1e
refactor: simplify segmented control next-button fallback
Copilot 334874f
fix: align segmented control style lookup and docs repo link
Copilot File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,133 @@ | ||
| # Segmented Control | ||
|
|
||
| The `bq-segmented-control` component provides a compact, touch-friendly single-choice control for toggling between views, density modes, filters, or app states. | ||
|
|
||
| It fills the gap between a full tab set and a radio group by keeping the interaction inline while still exposing form participation and radio-group accessibility semantics. | ||
|
|
||
| ## Import | ||
|
|
||
| ```ts | ||
| import '@bquery/ui/components/segmented-control'; | ||
| ``` | ||
|
|
||
| ## Basic Usage | ||
|
|
||
| ```html | ||
| <bq-segmented-control | ||
| label="View mode" | ||
| name="view" | ||
| value="overview" | ||
| > | ||
| <button value="overview">Overview</button> | ||
| <button value="board">Board</button> | ||
| <button value="activity">Activity</button> | ||
| </bq-segmented-control> | ||
| ``` | ||
|
|
||
| ## Sizes | ||
|
|
||
| ```html | ||
| <bq-segmented-control label="Density" size="sm" value="compact"> | ||
| <button value="compact">Compact</button> | ||
| <button value="comfortable">Comfortable</button> | ||
| </bq-segmented-control> | ||
|
|
||
| <bq-segmented-control label="Density" size="md" value="comfortable"> | ||
| <button value="compact">Compact</button> | ||
| <button value="comfortable">Comfortable</button> | ||
| </bq-segmented-control> | ||
|
|
||
| <bq-segmented-control label="Density" size="lg" value="spacious"> | ||
| <button value="comfortable">Comfortable</button> | ||
| <button value="spacious">Spacious</button> | ||
| </bq-segmented-control> | ||
| ``` | ||
|
|
||
| ## Full-Width Layout | ||
|
|
||
| Use `full-width` when each option should share the available width, which is especially useful on mobile layouts and settings screens. | ||
|
|
||
| ```html | ||
| <bq-segmented-control | ||
| label="Results layout" | ||
| full-width | ||
| value="cards" | ||
| > | ||
| <button value="cards">Cards</button> | ||
| <button value="table">Table</button> | ||
| <button value="split">Split</button> | ||
| </bq-segmented-control> | ||
| ``` | ||
|
|
||
| ## Disabled States | ||
|
|
||
| The host can disable the entire control, and individual segment buttons can also be disabled. | ||
|
|
||
| ```html | ||
| <bq-segmented-control label="Publishing state" value="draft"> | ||
| <button value="draft">Draft</button> | ||
| <button value="scheduled" disabled>Scheduled</button> | ||
| <button value="published">Published</button> | ||
| </bq-segmented-control> | ||
| ``` | ||
|
|
||
| ## Properties | ||
|
|
||
| | Property | Type | Default | Description | | ||
| | --- | --- | --- | --- | | ||
| | `label` | `string` | `''` | Visible group label. Also used to label the radiogroup. | | ||
| | `hint` | `string` | `''` | Supporting copy rendered below the control and linked with `aria-describedby`. | | ||
| | `name` | `string` | `''` | Form field name used for the hidden proxy input. | | ||
| | `value` | `string` | `''` | Selected segment value. Falls back to the first enabled segment when omitted. | | ||
| | `size` | `sm \| md \| lg` | `md` | Controls the segment button sizing. | | ||
| | `full-width` | `boolean` | `false` | Expands the control and evenly distributes each segment. | | ||
| | `disabled` | `boolean` | `false` | Disables the entire control. | | ||
| | `aria-label` | `string` | `''` | Accessible label when you do not render a visible `label`. | | ||
|
|
||
| ## Events | ||
|
|
||
| | Event | Detail | Description | | ||
| | --- | --- | --- | | ||
| | `bq-change` | `{ value: string }` | Fired when the selected segment changes. | | ||
|
|
||
| ## Slots | ||
|
|
||
| | Slot | Description | | ||
| | --- | --- | | ||
| | *(default)* | Segment buttons. Use native `<button value="...">...</button>` elements for the best accessibility and keyboard behavior. | | ||
|
|
||
| ## CSS Parts | ||
|
|
||
| | Part | Description | | ||
| | --- | --- | | ||
| | `field` | Wrapper around label, control, and hint | | ||
| | `label` | Visible group label | | ||
| | `control` | Segmented control track | | ||
| | `hint` | Supporting text | | ||
|
|
||
| ## Keyboard Interactions | ||
|
|
||
| | Key | Action | | ||
| | --- | --- | | ||
| | `ArrowRight` / `ArrowDown` | Moves to the next enabled segment and selects it | | ||
| | `ArrowLeft` / `ArrowUp` | Moves to the previous enabled segment and selects it | | ||
| | `Home` | Selects the first enabled segment | | ||
| | `End` | Selects the last enabled segment | | ||
| | `Enter` / `Space` | Selects the focused segment | | ||
|
|
||
| ## Accessibility Notes | ||
|
|
||
| - The control uses `role="radiogroup"` and each slotted button receives `role="radio"` with `aria-checked`. | ||
| - A visible `label` is preferred. If the UI should stay label-free, pass a localizable `aria-label`. | ||
| - The selected segment keeps `tabindex="0"` while inactive or disabled items move to `tabindex="-1"` to support roving focus. | ||
| - Arrow-key behavior follows the WAI-ARIA radio-group pattern and respects RTL layouts for horizontal navigation. | ||
|
|
||
| ## Localization Notes | ||
|
|
||
| - Keep the `label`, `hint`, and each button’s text content fully localizable in the host application. | ||
| - Segment `value` attributes should stay stable across locales so application state and forms do not depend on translated text. | ||
|
|
||
| ## Theming Notes | ||
|
|
||
| - The track and selected state use the shared token system (`--bq-bg-*`, `--bq-border-*`, `--bq-color-primary-*`, and focus-ring tokens). | ||
| - Use `::part(control)` for layout adjustments and host-level token overrides for bespoke themes without forking the component. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,102 @@ | ||
| # Architecture, Gap Analysis, and Roadmap | ||
|
|
||
| This page summarizes the current state of `@bquery/ui`, the research-informed gap analysis for the library’s next phase, and the first implementation batch landed in this update. | ||
|
|
||
| ## Current State Analysis | ||
|
|
||
| `@bquery/ui` already ships a strong cross-framework base: | ||
|
|
||
| - a broad core set of actions, forms, overlays, navigation, and feedback components, | ||
| - a reusable token and theme system with dark mode support, | ||
| - localized defaults through `src/i18n`, | ||
| - and focused accessibility utilities for focus management, live regions, and overlay behavior. | ||
|
|
||
| ### Current strengths | ||
|
|
||
| - **Accessible foundation**: overlays, tabs, tables, and form controls already expose meaningful keyboard and ARIA behavior. | ||
| - **Consistent design primitives**: tokens and theme helpers provide a shared visual language instead of one-off component colors. | ||
| - **Framework portability**: the custom-element architecture keeps the library usable in Angular, React, Vue, Svelte, and plain HTML. | ||
| - **Good documentation/testing baseline**: VitePress, Storybook, and Bun-based component tests are already in place. | ||
|
|
||
| ### Current constraints | ||
|
|
||
| - Components are mostly **single-file implementations**, so new patterns should stay simple and composable instead of adding deep abstraction layers prematurely. | ||
| - The library is strong in core controls but still lighter in **composite app patterns** such as segmented controls, advanced selects, command bars, and richer data views. | ||
| - The current docs explain individual APIs well, but the library benefits from more pages that explain **architecture and product direction**. | ||
|
|
||
| ## Research-Informed Gap Analysis | ||
|
|
||
| Reviewing mature systems such as Radix UI, shadcn/ui, Chakra UI, Mantine, Material UI, Ant Design, Headless UI, and React Aria highlights a few recurring expectations: | ||
|
|
||
| ### Essential next additions | ||
|
|
||
| - **Compact single-choice controls** like segmented controls and toggle groups | ||
| - **Richer menu behaviors** such as typeahead and tighter keyboard ergonomics | ||
| - **More composable app-shell and settings primitives** | ||
| - **Higher-level data controls** like richer tables, column controls, and filtering patterns | ||
|
|
||
| ### High-value improvements | ||
|
|
||
| - Better **keyboard parity** across all navigation and overlay components | ||
| - More **documentation pages for architecture, roadmap, theming, and usage patterns** | ||
| - Continued refinement of **mobile-friendly sizing, focus behavior, and RTL-aware navigation** | ||
|
|
||
| ### Advanced future opportunities | ||
|
|
||
| - Date and time primitives | ||
| - Command palette and workspace navigation patterns | ||
| - Multi-select and richer combobox behavior | ||
| - Split layouts, resizable panels, and app-shell primitives | ||
|
|
||
| ## Prioritized Roadmap | ||
|
|
||
| ### 1. Strengthen navigation and selection primitives | ||
|
|
||
| Add compact view/filter controls and improve keyboard ergonomics for menu-like components. | ||
|
|
||
| ### 2. Expand composable form building blocks | ||
|
|
||
| Prioritize segmented control, richer select patterns, and advanced field composition before heavier enterprise widgets. | ||
|
|
||
| ### 3. Grow app-scale patterns | ||
|
|
||
| Add settings-page primitives, command surfaces, responsive navigation helpers, and more structured documentation recipes. | ||
|
|
||
| ### 4. Deepen data-heavy capabilities | ||
|
|
||
| Iterate on the table with more controls and patterns instead of jumping straight to a full enterprise grid. | ||
|
|
||
| ## First High-Value Batch Implemented Here | ||
|
|
||
| This update focuses on a coherent, maintainable first batch: | ||
|
|
||
| 1. **New `bq-segmented-control` component** | ||
| - compact single-selection control, | ||
| - radio-group accessibility semantics, | ||
| - keyboard support, | ||
| - form participation, | ||
| - sizing and full-width options for mobile-friendly layouts. | ||
|
|
||
| 2. **Improved `bq-dropdown-menu` keyboard UX** | ||
| - adds **typeahead navigation** for faster action discovery in larger menus. | ||
|
|
||
| 3. **Documentation improvements** | ||
| - new segmented-control reference page, | ||
| - this architecture and roadmap guide, | ||
| - updated catalog/sidebar coverage, | ||
| - updated dropdown-menu keyboard guidance. | ||
|
|
||
| ## Why this batch matters | ||
|
|
||
| This batch improves the library in a way that mirrors mature UI ecosystems without overextending the architecture: | ||
|
|
||
| - it adds a missing **foundational choice primitive**, | ||
| - strengthens an existing **overlay/navigation component**, | ||
| - and improves documentation so the library feels more like an intentional platform than a loose collection of widgets. | ||
|
|
||
| ## Recommended Next Steps | ||
|
|
||
| - Add a composable **combobox / rich select** next. | ||
| - Expand **table recipes** and column-control patterns. | ||
| - Add more **layout and workspace primitives** for responsive app shells and settings pages. | ||
| - Continue auditing older components for shared size/variant/state consistency. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.