feat: ToggleGroup/ToggleGroupItem compound component (binary-toggle refactor)#288
Open
feat: ToggleGroup/ToggleGroupItem compound component (binary-toggle refactor)#288
Conversation
…le stack
Introduces a compound-component ToggleGroup + ToggleGroupItem following
shadcn/Radix naming and API conventions (context-based, value + onValueChange,
data-state on every item):
- New file console/src/components/ui/toggle-group.tsx exports ToggleGroup
(root, <fieldset> with implicit role=group) and ToggleGroupItem (<button
aria-pressed>) with React context wiring so size/disabled flow from root
to items without prop-drilling.
- data-state="on"/"off" on every item, mirroring Radix behaviour; CSS
selectors added in styles.css alongside the existing .active.is-on/is-off
rules to provide a data-attribute hook for future transitions.
- size prop ("sm" | "default") on ToggleGroup; .toggle-group--sm reduces
padding for dense table rows.
- SegmentedToggle and BooleanToggle are now thin wrappers that delegate to
ToggleGroup/ToggleGroupItem; BooleanToggle gains and forwards size prop.
- ToggleGroup/ToggleGroupItem re-exported from ui.tsx for a single import
path.
- Skills table toggle gains size="sm" for compact display in table rows.
- No behaviour changes; all existing CSS classes, active-state visual
styling, and aria-pressed semantics are preserved.
- Use cx() from lib/cx instead of hand-rolled class string concatenation
- Remove size from ToggleGroupContextValue: items never read it; the size
class is applied on the fieldset in ToggleGroup itself
- Wrap context value in useMemo to avoid unnecessary re-renders of all
ToggleGroupItems when the parent re-renders with unchanged props
- Consolidate export+import in ui.tsx to import + export {} (single source)
Member
Author
Code reviewNo issues found. Checked for bugs and CLAUDE.md compliance. 🤖 Generated with Claude Code - If this code review was useful, please react with 👍. Otherwise, react with 👎. |
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Summary
Replaces the hand-rolled
SegmentedToggle/BooleanToggle/BooleanFieldstack with a cleanToggleGroup+ToggleGroupItemprimitive modelled after the shadcn/Radix compound-component pattern.Old pattern
SegmentedTogglerendered a<fieldset class="binary-toggle">directly, applying active-state purely through CSS class names (active is-on/active is-off). No shared context, nodata-stateattribute, nosizevariant.New component
console/src/components/ui/toggle-group.tsx<ToggleGroup>root +<ToggleGroupItem>children (shadcn/Radix compound pattern)<fieldset>— carries implicitrole="group", biome-compliant semantic HTMLvalue/onValueChangeToggleGroupContextwiresvalue,onValueChange,disabled,sizefrom root to itemsdata-state"on"/"off"on every item, matching Radix behaviour exactlyaria-pressedsizeprop"sm"/"default"on root;.toggle-group--smreduces padding for dense table rowsactiveTone'is-on'(success green) /'is-off'(muted grey).binary-toggle/.binary-toggle-buttonclasses retained; additive[data-state="on"]selectors added alongside the existing.active.is-on/.active.is-offrulesExisting wrappers updated
SegmentedToggle→ thin wrapper aroundToggleGroup+ToggleGroupItem(options-array convenience API unchanged)BooleanToggle→ gainssizeprop, forwards toSegmentedToggle→ToggleGroupBooleanField— no change needed (always form/default size)Pages updated
BooleanField→BooleanToggle→SegmentedToggle→ToggleGroup(17 toggles, automatic)BooleanPillunchanged)BooleanPillonly — read-only display, no changesize="sm"explicitlyNo behaviour changes
All existing CSS classes, visual styling,
aria-pressedsemantics, andonChangeAPIs are preserved. The only observable difference isdata-stateon toggle items and the Skills table toggle being slightly smaller.