Initial Commit
This commit is contained in:
@@ -0,0 +1,138 @@
|
||||
# ToggleGroup
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs --> - toggle-group.variants — `toggleGroupVariants` and `…
|
||||
- [toggle-group.variants](./toggle-group.variants.md) — `toggleGroupVariants` and `toggleGroupItemVariants` are the cva (class-variance-authority) configurations powering `<To…
|
||||
- toggle-group.variants — `toggleGroupVariants` and `…
|
||||
|
||||
- [toggle-group.variants](./toggle-group.variants.md) — `toggleGroupVariants` and `toggleGroupItemVariants` are the cva (class-variance-authority) configurations powering `<To…
|
||||
|
||||
- toggle-group.variants — `toggleGroupVariants` and `…
|
||||
|
||||
- [toggle-group.variants](./toggle-group.variants.md) — `toggleGroupVariants` and `toggleGroupItemVariants` are the cva (class-variance-authority) configurations powering `<To…
|
||||
|
||||
- toggle-group.variants — `toggleGroupVariants` and `…
|
||||
|
||||
- [toggle-group.variants](./toggle-group.variants.md) — `toggleGroupVariants` and `toggleGroupItemVariants` are the cva (class-variance-authority) configurations powering `<To…
|
||||
- [toggle-group.variants](./toggle-group.variants.md) — `toggleGroupVariants` and `toggleGroupItemVariants` are the cva (class-variance-authority) configurations powering `<To…
|
||||
|
||||
## Purpose
|
||||
|
||||
`<ToggleGroup>` and `<ToggleGroupItem>` are the chassis option-set picker built on `@radix-ui/react-toggle-group`. Radix supplies the a11y semantics (`role="group"`, roving tabindex across items, arrow-key navigation, native `Space` activation, controlled `value` propagation in both `single` and `multiple` modes); the chassis layers cva variant resolution and propagates `variant` + `size` to every `<ToggleGroupItem>` via context so consumers do not need to repeat the props on every item.
|
||||
|
||||
Per the shadcn rule, option sets of 2–7 choices use `<ToggleGroup>`; do not loop `<Button>` with manual `aria-pressed` state. The `single` mode exposes a string `value`, the `multiple` mode exposes a string array — both routes preserve the discriminated union in the type signature so consumers get autocomplete on the right shape.
|
||||
|
||||
## Features
|
||||
|
||||
- Two visual variants (`default`, `outline`) shared with `<Toggle>` for visual coherence.
|
||||
- Three sizes (`sm`, `default`, `lg`) for dense or roomy toolbars.
|
||||
- `single` and `multiple` selection modes with the discriminated `value` shape preserved.
|
||||
- Variant + size propagation from group to items via React context (per-item override wins over inherited).
|
||||
- Roving tabindex across items provided by Radix — only one item is in the tab order at any time.
|
||||
- Refs forwarded on both `<ToggleGroup>` and `<ToggleGroupItem>`.
|
||||
- `motion-reduce:transition-none` collapses transitions for `prefers-reduced-motion: reduce`.
|
||||
- Theme-driven variant overrides via `useThemedVariants("ToggleGroup" | "ToggleGroupItem")`.
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```tsx
|
||||
import { ToggleGroup, ToggleGroupItem } from "@suaveplan/react-ui";
|
||||
import { AlignLeftIcon, AlignCenterIcon, AlignRightIcon } from "lucide-react";
|
||||
|
||||
export function AlignmentPicker() {
|
||||
return (
|
||||
<ToggleGroup type="single" defaultValue="left" aria-label="Text alignment">
|
||||
<ToggleGroupItem value="left" aria-label="Left align">
|
||||
<AlignLeftIcon />
|
||||
</ToggleGroupItem>
|
||||
<ToggleGroupItem value="center" aria-label="Center align">
|
||||
<AlignCenterIcon />
|
||||
</ToggleGroupItem>
|
||||
<ToggleGroupItem value="right" aria-label="Right align">
|
||||
<AlignRightIcon />
|
||||
</ToggleGroupItem>
|
||||
</ToggleGroup>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
```tsx
|
||||
import { ToggleGroup, ToggleGroupItem, FieldSet, FieldLegend } from "@suaveplan/react-ui";
|
||||
import { useState } from "react";
|
||||
|
||||
export function FilterPicker() {
|
||||
const [filters, setFilters] = useState<string[]>([]);
|
||||
|
||||
return (
|
||||
<FieldSet>
|
||||
<FieldLegend>Filters</FieldLegend>
|
||||
<ToggleGroup
|
||||
type="multiple"
|
||||
value={filters}
|
||||
onValueChange={setFilters}
|
||||
variant="outline"
|
||||
size="sm"
|
||||
>
|
||||
<ToggleGroupItem value="open">Open</ToggleGroupItem>
|
||||
<ToggleGroupItem value="closed">Closed</ToggleGroupItem>
|
||||
<ToggleGroupItem value="merged">Merged</ToggleGroupItem>
|
||||
<ToggleGroupItem value="draft">Draft</ToggleGroupItem>
|
||||
</ToggleGroup>
|
||||
</FieldSet>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
### `<ToggleGroup>`
|
||||
|
||||
`forwardRef<ComponentRef<typeof ToggleGroupPrimitive.Root>, ToggleGroupProps>` — renders the Radix Root with the discriminated-union shape preserved.
|
||||
|
||||
#### `ToggleGroupProps`
|
||||
|
||||
Inherits the discriminated-union shape of Radix `ToggleGroupPrimitive.Root` (`{ type: "single", value?: string }` or `{ type: "multiple", value?: string[] }`) minus `asChild`. Adds:
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|---|---|---|---|
|
||||
| `variant` | `"default" \| "outline"` | `"default"` | Inherited by every item via context. |
|
||||
| `size` | `"sm" \| "default" \| "lg"` | `"default"` | Inherited by every item via context. |
|
||||
|
||||
Common Radix props consumers will use:
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|---|---|---|---|
|
||||
| `type` | `"single" \| "multiple"` | _required_ | Selection mode. |
|
||||
| `value` | `string \| string[]` | _uncontrolled_ | Selected value(s). |
|
||||
| `defaultValue` | `string \| string[]` | _none_ | Initial value(s) for uncontrolled use. |
|
||||
| `onValueChange` | `(value: string \| string[]) => void` | _none_ | Fires on value change. |
|
||||
| `disabled` | `boolean` | `false` | Disables every item. |
|
||||
|
||||
### `<ToggleGroupItem>`
|
||||
|
||||
`forwardRef<ComponentRef<typeof ToggleGroupPrimitive.Item>, ToggleGroupItemProps>` — renders a Radix Item.
|
||||
|
||||
#### `ToggleGroupItemProps`
|
||||
|
||||
Inherits every prop from Radix `ToggleGroupPrimitive.Item` except `asChild`. Adds:
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|---|---|---|---|
|
||||
| `variant` | `"default" \| "outline"` | _from group context_ | Per-item override. |
|
||||
| `size` | `"sm" \| "default" \| "lg"` | _from group context_ | Per-item override. |
|
||||
| `value` | `string` | _required_ | Unique value within the surrounding group. |
|
||||
|
||||
#### `toggleGroupVariants` / `toggleGroupItemVariants`
|
||||
|
||||
Both bare cva resolvers exported for external composition.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
- The variant + size propagation uses React context rather than React.cloneElement so deeply-nested item wrappers (`<TooltipTrigger asChild><ToggleGroupItem>...</ToggleGroupItem></TooltipTrigger>`) still receive the inherited values.
|
||||
- Per-item `variant` / `size` overrides win over the inherited context values because the cva call resolves `variant ?? ctx.variant` at render time.
|
||||
- The discriminated-union type is preserved at the public surface so consumers get autocomplete on `value: string` for `type: "single"` vs `value: string[]` for `type: "multiple"`. Internally the chassis casts to a relaxed shape because TypeScript cannot narrow the spread back to the original union after the chassis adds its own props.
|
||||
- The chassis NEVER uses `space-x-*` for the row layout — `flex gap-1` flows the same in RTL.
|
||||
- Refs target the Radix Root + Item — consumers can `.focus()` programmatically through the forwarded refs.
|
||||
Reference in New Issue
Block a user