@create-ui/cli 0.5.8 → 0.5.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/dist/{chunk-RMTTHCB3.js → chunk-2ELKDGGM.js} +3 -3
  2. package/dist/{chunk-RMTTHCB3.js.map → chunk-2ELKDGGM.js.map} +1 -1
  3. package/dist/chunk-643QI2I2.js +102 -0
  4. package/dist/chunk-643QI2I2.js.map +1 -0
  5. package/dist/{chunk-NQFMXHMH.js → chunk-KQTXDVKV.js} +3 -3
  6. package/dist/chunk-KQTXDVKV.js.map +1 -0
  7. package/dist/index.d.ts +360 -360
  8. package/dist/index.js +2 -2
  9. package/dist/index.js.map +1 -1
  10. package/dist/mcp/index.js +1 -1
  11. package/dist/registry/index.d.ts +2 -2
  12. package/dist/registry/index.js +1 -1
  13. package/dist/schema/index.d.ts +715 -715
  14. package/dist/skills/createui/SKILL.md +201 -177
  15. package/dist/skills/createui/agents/openai.yml +1 -1
  16. package/dist/skills/createui/cli.md +42 -42
  17. package/dist/skills/createui/customization.md +20 -15
  18. package/dist/skills/createui/evals/evals.json +68 -5
  19. package/dist/skills/createui/mcp.md +14 -5
  20. package/dist/skills/createui/reference/accordion.md +127 -0
  21. package/dist/skills/createui/reference/app-store-badge.md +88 -0
  22. package/dist/skills/createui/reference/aspect-ratio.md +52 -0
  23. package/dist/skills/createui/reference/avatar.md +230 -0
  24. package/dist/skills/createui/reference/badge.md +110 -0
  25. package/dist/skills/createui/reference/breadcrumb.md +153 -0
  26. package/dist/skills/createui/reference/button-group.md +116 -0
  27. package/dist/skills/createui/reference/button.md +104 -0
  28. package/dist/skills/createui/reference/checkbox-group.md +118 -0
  29. package/dist/skills/createui/reference/checkbox.md +79 -0
  30. package/dist/skills/createui/reference/chip.md +115 -0
  31. package/dist/skills/createui/reference/close-button.md +83 -0
  32. package/dist/skills/createui/reference/command.md +69 -0
  33. package/dist/skills/createui/reference/country-flag.md +109 -0
  34. package/dist/skills/createui/reference/credit-card-input.md +76 -0
  35. package/dist/skills/createui/reference/date-input.md +71 -0
  36. package/dist/skills/createui/reference/dropdown-menu.md +164 -0
  37. package/dist/skills/createui/reference/field.md +186 -0
  38. package/dist/skills/createui/reference/info-tooltip.md +110 -0
  39. package/dist/skills/createui/reference/inline-alert.md +146 -0
  40. package/dist/skills/createui/reference/input-group.md +171 -0
  41. package/dist/skills/createui/reference/input-otp.md +130 -0
  42. package/dist/skills/createui/reference/input-stepper.md +120 -0
  43. package/dist/skills/createui/reference/input.md +118 -0
  44. package/dist/skills/createui/reference/label.md +121 -0
  45. package/dist/skills/createui/reference/pagination.md +157 -0
  46. package/dist/skills/createui/reference/password-strength.md +70 -0
  47. package/dist/skills/createui/reference/phone-input.md +77 -0
  48. package/dist/skills/createui/reference/progress.md +158 -0
  49. package/dist/skills/createui/reference/radio-group.md +133 -0
  50. package/dist/skills/createui/reference/radio.md +79 -0
  51. package/dist/skills/createui/reference/scroll-area.md +212 -0
  52. package/dist/skills/createui/reference/segmented-control.md +146 -0
  53. package/dist/skills/createui/reference/select.md +204 -0
  54. package/dist/skills/createui/reference/separator.md +99 -0
  55. package/dist/skills/createui/reference/social-login-button.md +130 -0
  56. package/dist/skills/createui/reference/spinner.md +68 -0
  57. package/dist/skills/createui/reference/status-badge.md +89 -0
  58. package/dist/skills/createui/reference/switch-group.md +122 -0
  59. package/dist/skills/createui/reference/switch.md +75 -0
  60. package/dist/skills/createui/reference/tab-menu.md +165 -0
  61. package/dist/skills/createui/reference/text-link.md +84 -0
  62. package/dist/skills/createui/reference/textarea.md +50 -0
  63. package/dist/skills/createui/reference/toast.md +162 -0
  64. package/dist/skills/createui/reference/tooltip.md +63 -0
  65. package/dist/skills/createui/rules/composition.md +41 -25
  66. package/dist/skills/createui/rules/design.md +266 -0
  67. package/dist/skills/createui/rules/forms.md +44 -15
  68. package/dist/skills/createui/rules/icons.md +64 -18
  69. package/dist/skills/createui/rules/styling.md +53 -14
  70. package/dist/utils/index.js +1 -1
  71. package/package.json +1 -1
  72. package/dist/chunk-M5DYT2NE.js +0 -64
  73. package/dist/chunk-M5DYT2NE.js.map +0 -1
  74. package/dist/chunk-NQFMXHMH.js.map +0 -1
@@ -0,0 +1,153 @@
1
+ <!-- GENERATED FILE - do not edit. Source: registry/ui/breadcrumb.tsx. Regenerate with `pnpm skill:build`. Curated notes: apps/v4/scripts/skill-reference/notes/breadcrumb.md -->
2
+
3
+ # breadcrumb
4
+
5
+ Path navigation with BreadcrumbItem, BreadcrumbSeparator (chevron, slash or dot) and BreadcrumbEllipsis for collapsing
6
+
7
+ Install: `npx @create-ui/cli add breadcrumb`
8
+
9
+ ## Import
10
+
11
+ ```tsx
12
+ import { Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbSeparator } from "@/components/ui/breadcrumb"
13
+ ```
14
+
15
+ Also exported: `breadcrumbEllipsisVariants`, `breadcrumbItemVariants`, `breadcrumbSeparatorVariants`, `useBreadcrumbContext`
16
+
17
+ ## Breadcrumb props
18
+
19
+ | Prop | Type | Default |
20
+ | --- | --- | --- |
21
+ | variant | `primary \| neutral` | - |
22
+ | appearance | `solid \| outline \| ghost` | - |
23
+ | size | `xs \| sm \| md` | - |
24
+ | shape | `rounded \| pill` | - |
25
+ | separator | `chevron \| slash \| dot` (Root-level prop; sets the glyph for every child BreadcrumbSeparator via context. On BreadcrumbSeparator itself the same axis is named variant.) | - |
26
+
27
+ Extends `React.ComponentProps<"nav">`.
28
+
29
+ ## BreadcrumbEllipsis props
30
+
31
+ | Prop | Type | Default |
32
+ | --- | --- | --- |
33
+ | variant | `primary \| neutral` | `primary` |
34
+ | appearance | `solid \| outline \| ghost` | `ghost` |
35
+ | size | `xs \| sm \| md` | `md` |
36
+ | shape | `rounded \| pill` | `rounded` |
37
+ | disabled | `boolean` | - |
38
+ | current | `boolean` (Sets aria-current to page, strongest text color, and pointer-events-none; the item stops behaving like a link. Replaces shadcn's BreadcrumbPage.) | - |
39
+
40
+ Extends `React.ComponentProps<"span">`.
41
+
42
+ ## BreadcrumbItem props
43
+
44
+ | Prop | Type | Default |
45
+ | --- | --- | --- |
46
+ | variant | `primary \| neutral` | `primary` |
47
+ | appearance | `solid \| outline \| ghost` | `ghost` |
48
+ | size | `xs \| sm \| md` | `md` |
49
+ | shape | `rounded \| pill` | `rounded` |
50
+ | asChild | `boolean` (Renders children raw through Slot: leadingIcon/trailingIcon and the icon/content/caret slot wrappers are skipped, so icons inside the child lose the automatic per-size svg sizing.) | `false` |
51
+ | leadingIcon | `ReactNode` | - |
52
+ | trailingIcon | `ReactNode` | - |
53
+ | disabled | `boolean` | - |
54
+ | current | `boolean` (Sets aria-current to page, strongest text color, and pointer-events-none; the item stops behaving like a link. Replaces shadcn's BreadcrumbPage.) | - |
55
+
56
+ Extends `React.ComponentProps<"a">`.
57
+
58
+ ## BreadcrumbSeparator props
59
+
60
+ | Prop | Type | Default |
61
+ | --- | --- | --- |
62
+ | variant | `chevron \| slash \| dot` | `chevron` |
63
+ | size | `xs \| sm \| md` | `md` |
64
+
65
+ Extends `React.ComponentProps<"span">`.
66
+
67
+ ## Icons
68
+
69
+ Icons go through icon props - never as children next to text, and never with sizing classes (the component sizes icons per `size`): `BreadcrumbItem` (`leadingIcon` / `trailingIcon`). Import icons from `@create-ui/assets/icons` (Remix `Ri*`).
70
+
71
+ ## Examples
72
+
73
+ From `breadcrumb-demo`:
74
+
75
+ ```tsx
76
+ import {
77
+ Breadcrumb,
78
+ BreadcrumbItem,
79
+ BreadcrumbSeparator,
80
+ } from "@/components/ui/breadcrumb"
81
+
82
+ export default function BreadcrumbDemo() {
83
+ return (
84
+ <Breadcrumb>
85
+ <BreadcrumbItem variant="neutral" href="#">
86
+ Workspace
87
+ </BreadcrumbItem>
88
+ <BreadcrumbSeparator />
89
+ <BreadcrumbItem variant="neutral" href="#">
90
+ Settings
91
+ </BreadcrumbItem>
92
+ <BreadcrumbSeparator />
93
+ <BreadcrumbItem variant="neutral" href="#">
94
+ Team
95
+ </BreadcrumbItem>
96
+ <BreadcrumbSeparator />
97
+ <BreadcrumbItem variant="neutral" href="#" current>
98
+ Members
99
+ </BreadcrumbItem>
100
+ </Breadcrumb>
101
+ )
102
+ }
103
+ ```
104
+
105
+ From `breadcrumb-overflow`:
106
+
107
+ ```tsx
108
+ import {
109
+ Breadcrumb,
110
+ BreadcrumbEllipsis,
111
+ BreadcrumbItem,
112
+ BreadcrumbSeparator,
113
+ } from "@/components/ui/breadcrumb"
114
+
115
+ export default function BreadcrumbOverflow() {
116
+ return (
117
+ <Breadcrumb>
118
+ <BreadcrumbItem href="#">Workspace</BreadcrumbItem>
119
+ <BreadcrumbSeparator />
120
+ <BreadcrumbEllipsis />
121
+ <BreadcrumbSeparator />
122
+ <BreadcrumbItem href="#">Team</BreadcrumbItem>
123
+ <BreadcrumbSeparator />
124
+ <BreadcrumbItem href="#" current>
125
+ Members
126
+ </BreadcrumbItem>
127
+ </Breadcrumb>
128
+ )
129
+ }
130
+ ```
131
+
132
+ More: `npx @create-ui/cli view breadcrumb` or MCP `get_item_examples_from_registries` with "breadcrumb-demo" / "breadcrumb-example".
133
+
134
+ ## When to use
135
+ Hierarchical "where am I" trail for screens several levels deep (workspace > project > page), with one-click navigation back up the tree. Do NOT use it for paging through a list (use Pagination) or for switching between sibling views (use TabMenu). For a single back-to-parent affordance, a Button with a leading chevron is lighter.
136
+
137
+ ## Gotchas
138
+ - No BreadcrumbList / BreadcrumbLink / BreadcrumbPage (shadcn parts do not exist). Items and separators are direct children of Breadcrumb (a flat nav, no ol/li). The link IS BreadcrumbItem (renders an anchor by default), and the current page is BreadcrumbItem current, not a separate component.
139
+ - Separators are never auto-injected; interleave BreadcrumbSeparator between items yourself. Set the glyph once via separator on the root; BreadcrumbSeparator reads glyph and size from context.
140
+ - Root Breadcrumb props cascade via context: items and ellipsis inherit variant/appearance/size/shape, separators inherit only size and the separator glyph. Per-child props override (explicit ?? ctx ?? default), so set axes once on the root.
141
+ - BreadcrumbEllipsis is a static span containing "...": no asChild, not a button or link. It carries item hover/cursor styling so it looks clickable, but opening a menu of collapsed items requires your own interactive wrapper.
142
+ - The root nav is flex-nowrap with overflow-x-auto and a hidden scrollbar: long trails scroll horizontally instead of wrapping.
143
+ - Items accept arbitrary children (Avatar, Badge) next to the label, but you must size-pair them manually (e.g. Avatar size="xs" inside an md item); nothing cascades into non-breadcrumb children.
144
+
145
+ ```tsx
146
+ <Breadcrumb variant="neutral" size="sm" separator="slash">
147
+ <BreadcrumbItem asChild>
148
+ <Link href="/">Home</Link>
149
+ </BreadcrumbItem>
150
+ <BreadcrumbSeparator />
151
+ <BreadcrumbItem href="/settings" current>Settings</BreadcrumbItem>
152
+ </Breadcrumb>
153
+ ```
@@ -0,0 +1,116 @@
1
+ <!-- GENERATED FILE - do not edit. Source: registry/ui/button-group.tsx. Regenerate with `pnpm skill:build`. Curated notes: apps/v4/scripts/skill-reference/notes/button-group.md -->
2
+
3
+ # button-group
4
+
5
+ Row of attached ButtonGroupItem buttons sharing borders; per-item active, loading and iconOnly, ideal for toolbars
6
+
7
+ Install: `npx @create-ui/cli add button-group`
8
+
9
+ ## Import
10
+
11
+ ```tsx
12
+ import { ButtonGroup, ButtonGroupItem } from "@/components/ui/button-group"
13
+ ```
14
+
15
+ Also exported: `buttonGroupVariants`, `buttonGroupItemVariants`
16
+
17
+ ## ButtonGroup props
18
+
19
+ | Prop | Type | Default |
20
+ | --- | --- | --- |
21
+ | variant | `primary \| neutral \| soft` | `primary` |
22
+ | shape | `rounded \| pill \| square` | `rounded` |
23
+ | size | `xs \| sm \| md \| lg \| xl` | `md` |
24
+
25
+ Extends `React.ComponentProps<"div">`.
26
+
27
+ ## ButtonGroupItem props
28
+
29
+ | Prop | Type | Default |
30
+ | --- | --- | --- |
31
+ | variant | `primary \| neutral \| soft` | `primary` |
32
+ | size | `xs \| sm \| md \| lg \| xl` | `md` |
33
+ | iconOnly | `boolean` (renders children as a single centered icon (like Button); leadingIcon/trailingIcon are ignored; add aria-label) | `false` |
34
+ | asChild | `boolean` | `false` |
35
+ | loading | `boolean` (Also blocks interaction (native disabled, or aria-disabled + tabIndex -1 under asChild); the spinner replaces trailingIcon, or the icon child when iconOnly) | `false` |
36
+ | active | `boolean` (Styling via data-active plus aria-pressed (aria-pressed is skipped under asChild); the group has no value/onValueChange - selection state is the caller's job) | `false` |
37
+ | leadingIcon | `ReactNode` | - |
38
+ | trailingIcon | `ReactNode` | - |
39
+
40
+ Extends `React.ComponentProps<"button">`.
41
+
42
+ ## Icons
43
+
44
+ Icons go through icon props - never as children next to text, and never with sizing classes (the component sizes icons per `size`): `ButtonGroupItem` (`leadingIcon` / `trailingIcon`). Import icons from `@create-ui/assets/icons` (Remix `Ri*`).
45
+
46
+ ## Examples
47
+
48
+ From `button-group-demo`:
49
+
50
+ ```tsx
51
+ import { ButtonGroup, ButtonGroupItem } from "@/components/ui/button-group"
52
+
53
+ export default function ButtonGroupDemo() {
54
+ return (
55
+ <ButtonGroup>
56
+ <ButtonGroupItem>List</ButtonGroupItem>
57
+ <ButtonGroupItem active>Grid</ButtonGroupItem>
58
+ <ButtonGroupItem>Gallery</ButtonGroupItem>
59
+ </ButtonGroup>
60
+ )
61
+ }
62
+ ```
63
+
64
+ From `button-group-composition`:
65
+
66
+ ```tsx
67
+ "use client"
68
+
69
+ import { RiExternalLinkLine } from "@create-ui/assets/icons"
70
+
71
+ import { Badge } from "@/components/ui/badge"
72
+ import { ButtonGroup, ButtonGroupItem } from "@/components/ui/button-group"
73
+
74
+ export default function ButtonGroupComposition() {
75
+ return (
76
+ <ButtonGroup>
77
+ <ButtonGroupItem>
78
+ Inbox
79
+ <Badge variant="neutral" appearance="soft" size="xs" numberOnly>
80
+ 7
81
+ </Badge>
82
+ </ButtonGroupItem>
83
+ <ButtonGroupItem active>
84
+ Drafts
85
+ <Badge variant="primary" appearance="soft" size="xs" numberOnly>
86
+ 2
87
+ </Badge>
88
+ </ButtonGroupItem>
89
+ <ButtonGroupItem asChild trailingIcon={<RiExternalLinkLine />}>
90
+ <a href="#archive">Archive</a>
91
+ </ButtonGroupItem>
92
+ </ButtonGroup>
93
+ )
94
+ }
95
+ ```
96
+
97
+ More: `npx @create-ui/cli view button-group` or MCP `get_item_examples_from_registries` with "button-group-demo" / "button-group-example".
98
+
99
+ ## When to use
100
+ A joined row of sibling actions on one bordered surface: view switchers (list/grid), inline action clusters, formatting toolbars. The root broadcasts `variant` and `size` to every item via context, so set them once on `ButtonGroup`. Not for a single standalone action (use `Button`), not for exclusive selection with managed state (use `SegmentedControl`, which has `value`/`onValueChange`), not for page navigation (use `Pagination`), not for overflow actions (use `DropdownMenu`).
101
+
102
+ ## Gotchas
103
+ - Items must be DIRECT children of `ButtonGroup`: the joined border, outer radius, and dividers come from `[&>*:first-child]` / `[&>*:last-child]` selectors on the root, so any wrapper element between group and item breaks the surface.
104
+ - Never place `<Button>` inside `ButtonGroup` (shadcn habit); `ButtonGroupItem` is the only component that reads the group context. There is also no `orientation` prop, no `ButtonGroupSeparator`, no `ButtonGroupText`.
105
+ - Item `variant`/`size` resolve as explicit prop ?? group context ?? default, so per-item overrides are possible but rarely wanted.
106
+ - With `asChild`, the child element's own children become the label and the component clones the child to re-render icons + label inside it. Icons go on `ButtonGroupItem` props, never inside the anchor:
107
+
108
+ ```tsx
109
+ <ButtonGroupItem asChild leadingIcon={<RiSettings6Fill />}>
110
+ <a href="#settings">Settings</a>
111
+ </ButtonGroupItem>
112
+ ```
113
+
114
+ - `asChild` with bare-text children (no element) silently falls back to rendering a plain `<button>`.
115
+ - `iconOnly` renders `children` as a single centered icon, exactly like `Button` - put the icon in `children`, not `leadingIcon` (which is ignored in this mode); the text label is gone, so add `aria-label`. With `loading`, the spinner replaces the icon child. For `asChild` + `iconOnly`, the icon goes inside the wrapped element.
116
+ - `iconOnly` items are a FIXED square (`size-N`). A full-width action bar (`ButtonGroup className="w-full"` with `flex-1` items, dropping to `xl:flex-none` for square on desktop) is the deliberate, correct use of `flex-1` here. But adding `flex-1` / `w-full` to an iconOnly item in a COMPACT group stretches the square into a wide rectangle - leave the width class off unless you actually want full-width equal segments.
@@ -0,0 +1,104 @@
1
+ <!-- GENERATED FILE - do not edit. Source: registry/ui/button.tsx. Regenerate with `pnpm skill:build`. Curated notes: apps/v4/scripts/skill-reference/notes/button.md -->
2
+
3
+ # button
4
+
5
+ Action button with variant, appearance, size and shape axes; leadingIcon, trailingIcon and loading props
6
+
7
+ Install: `npx @create-ui/cli add button`
8
+
9
+ ## Import
10
+
11
+ ```tsx
12
+ import { Button } from "@/components/ui/button"
13
+ ```
14
+
15
+ Also exported: `buttonVariants`
16
+
17
+ ## Button props
18
+
19
+ | Prop | Type | Default |
20
+ | --- | --- | --- |
21
+ | variant | `primary \| neutral-solid \| neutral-light \| danger \| success \| inverse-solid \| inverse-light` (color intent; combine with appearance for the visual weight) | `primary` |
22
+ | appearance | `solid \| outline \| ghost \| soft` | `solid` |
23
+ | size | `xs \| sm \| md \| lg \| xl` | `lg` |
24
+ | shape | `rounded \| pill \| square` | `rounded` |
25
+ | iconOnly | `boolean` (icon goes as children; leadingIcon/trailingIcon are silently ignored in this mode) | `false` |
26
+ | asChild | `boolean` | `false` |
27
+ | loading | `boolean` (built-in spinner + disabled state; never compose your own) | `false` |
28
+ | leadingIcon | `ReactNode` | - |
29
+ | trailingIcon | `ReactNode` | - |
30
+
31
+ Extends `React.ComponentProps<"button">`.
32
+
33
+ ## Icons
34
+
35
+ Icons go through icon props - never as children next to text, and never with sizing classes (the component sizes icons per `size`): `Button` (`leadingIcon` / `trailingIcon`). Import icons from `@create-ui/assets/icons` (Remix `Ri*`).
36
+
37
+ ## Examples
38
+
39
+ From `button-demo`:
40
+
41
+ ```tsx
42
+ import { RiArrowRightLine, RiSparklingFill } from "@create-ui/assets/icons"
43
+
44
+ import { Button } from "@/components/ui/button"
45
+
46
+ export default function ButtonDemo() {
47
+ return (
48
+ <div className="flex flex-wrap items-center gap-2">
49
+ <Button>Save changes</Button>
50
+ <Button variant="neutral-light" appearance="soft">
51
+ Cancel
52
+ </Button>
53
+ <Button
54
+ variant="primary"
55
+ appearance="outline"
56
+ trailingIcon={<RiArrowRightLine />}
57
+ >
58
+ Continue
59
+ </Button>
60
+ <Button variant="primary" iconOnly aria-label="Sparkle">
61
+ <RiSparklingFill />
62
+ </Button>
63
+ </div>
64
+ )
65
+ }
66
+ ```
67
+
68
+ From `button-with-icon`:
69
+
70
+ ```tsx
71
+ import { RiAddCircleFill, RiArrowRightLine } from "@create-ui/assets/icons"
72
+
73
+ import { Button } from "@/components/ui/button"
74
+
75
+ export default function ButtonWithIcon() {
76
+ return (
77
+ <div className="flex flex-wrap items-center gap-2">
78
+ <Button leadingIcon={<RiAddCircleFill />}>Leading</Button>
79
+ <Button trailingIcon={<RiArrowRightLine />}>Trailing</Button>
80
+ <Button
81
+ leadingIcon={<RiAddCircleFill />}
82
+ trailingIcon={<RiArrowRightLine />}
83
+ >
84
+ Both
85
+ </Button>
86
+ </div>
87
+ )
88
+ }
89
+ ```
90
+
91
+ More: `npx @create-ui/cli view button` or MCP `get_item_examples_from_registries` with "button-demo" / "button-example".
92
+
93
+ ## When to use
94
+
95
+ Any action: form submits, dialog triggers, async operations. Button-styled links use `asChild` with your router's Link. NOT for links inside prose (use `TextLink`), clustered action rows (use `ButtonGroup`), a dedicated dismiss control (use `CloseButton`), or non-interactive status labels (use `Badge`).
96
+
97
+ ## Gotchas
98
+
99
+ - There is NO `variant="outline"` / `"secondary"` / `"destructive"`: outline is `appearance="outline"`, destructive is `variant="danger"`, secondary is usually `variant="neutral-light"` or `appearance="soft"` / `"ghost"`.
100
+ - Icons go through `leadingIcon` / `trailingIcon`, never as children next to text, and never with sizing classes; the component sizes them per `size` via `[&_svg]:size-*`.
101
+ - `iconOnly` renders `children` as the icon and silently ignores `leadingIcon` / `trailingIcon`; the component adds no accessible text itself, so pass `aria-label`. With `loading` it swaps the icon for the spinner plus an sr-only "Loading".
102
+ - `loading` blocks interaction: native `disabled` (or `aria-disabled` + `tabIndex={-1}` under `asChild`) plus `aria-busy`. In text buttons the spinner replaces the leadingIcon slot while the label stays visible; spinner variant and size are auto-matched to the active variant/appearance/size.
103
+ - `asChild` clones the child and re-injects Button's own label/icon spans, so `leadingIcon` / `trailingIcon` / `loading` all still work on an `<a>`; the child's children become the label.
104
+ - The root is `inline-flex`: intrinsic-width in normal flow, but as a flex/grid child under the default `align-items: stretch` (e.g. inside a `flex flex-col` card) it fills the container and looks full-width. Add `w-fit` or `self-start` to keep it intrinsic - this is required on `DropdownMenu`/`Popover` triggers placed in a stacked layout - or `w-full` for an intentionally full-width button.
@@ -0,0 +1,118 @@
1
+ <!-- GENERATED FILE - do not edit. Source: registry/ui/checkbox-group.tsx. Regenerate with `pnpm skill:build`. Curated notes: apps/v4/scripts/skill-reference/notes/checkbox-group.md -->
2
+
3
+ # checkbox-group
4
+
5
+ Field wrapper that labels a Checkbox and cascades variant, size and shape via context; placement left or right
6
+
7
+ Install: `npx @create-ui/cli add checkbox-group`
8
+
9
+ ## Import
10
+
11
+ ```tsx
12
+ import { CheckboxGroup } from "@/components/ui/checkbox-group"
13
+ ```
14
+
15
+ Also exported: `checkboxGroupVariants`
16
+
17
+ ## CheckboxGroup props
18
+
19
+ | Prop | Type | Default |
20
+ | --- | --- | --- |
21
+ | variant | `primary \| danger` (danger only recolors FieldFooter text and cascades a danger checkbox; it does not set invalid) | `primary` |
22
+ | size | `xs \| sm \| md` (cascades to the child Checkbox via context (a bare Checkbox defaults to sm) and is forwarded to Field, so label and description scale with it) | `md` |
23
+ | shape | `CheckboxShape` | `rounded` |
24
+ | placement | `left \| right` (right is flex-row-reverse: visual flip only; keep the Checkbox first in the DOM) | `left` |
25
+
26
+ Extends `React.ComponentProps<typeof Field>`.
27
+
28
+ ## Examples
29
+
30
+ From `checkbox-group-demo`:
31
+
32
+ ```tsx
33
+ import { Checkbox } from "@/components/ui/checkbox"
34
+ import { CheckboxGroup } from "@/components/ui/checkbox-group"
35
+ import { FieldContent } from "@/components/ui/field"
36
+ import { Label, LabelDescription, LabelMain } from "@/components/ui/label"
37
+
38
+ export default function CheckboxGroupDemo() {
39
+ return (
40
+ <CheckboxGroup className="w-[340px]">
41
+ <Checkbox id="cb-demo" defaultChecked />
42
+ <FieldContent>
43
+ <LabelMain>
44
+ <Label htmlFor="cb-demo">Email notifications</Label>
45
+ <LabelDescription>
46
+ Get a digest of product updates once a week.
47
+ </LabelDescription>
48
+ </LabelMain>
49
+ </FieldContent>
50
+ </CheckboxGroup>
51
+ )
52
+ }
53
+ ```
54
+
55
+ From `checkbox-group-variants`:
56
+
57
+ ```tsx
58
+ import { Checkbox } from "@/components/ui/checkbox"
59
+ import { CheckboxGroup } from "@/components/ui/checkbox-group"
60
+ import { FieldContent, FieldFooter } from "@/components/ui/field"
61
+ import { Label, LabelDescription, LabelMain } from "@/components/ui/label"
62
+
63
+ export default function CheckboxGroupVariants() {
64
+ return (
65
+ <div className="flex flex-col gap-6">
66
+ <CheckboxGroup variant="primary" className="w-[340px]">
67
+ <Checkbox id="cb-variant-primary" defaultChecked />
68
+ <FieldContent>
69
+ <LabelMain>
70
+ <Label htmlFor="cb-variant-primary">Marketing emails</Label>
71
+ <LabelDescription>
72
+ We&apos;ll only send the things you ask for.
73
+ </LabelDescription>
74
+ </LabelMain>
75
+ </FieldContent>
76
+ </CheckboxGroup>
77
+
78
+ <CheckboxGroup variant="danger" invalid className="w-[340px]">
79
+ <Checkbox id="cb-variant-error" />
80
+ <FieldContent>
81
+ <LabelMain>
82
+ <Label htmlFor="cb-variant-error">Accept the terms</Label>
83
+ <LabelDescription>
84
+ You must agree to the terms before continuing.
85
+ </LabelDescription>
86
+ </LabelMain>
87
+ <FieldFooter>Required field.</FieldFooter>
88
+ </FieldContent>
89
+ </CheckboxGroup>
90
+ </div>
91
+ )
92
+ }
93
+ ```
94
+
95
+ More: `npx @create-ui/cli view checkbox-group` or MCP `get_item_examples_from_registries` with "checkbox-group-demo" / "checkbox-group-example".
96
+
97
+ ## When to use
98
+ A single labelled boolean row: one Checkbox plus label, description, and optional footer, composed as a Field locked to horizontal orientation. Use it for settings rows, consent lines, and opt-ins; for a multi-select list, stack several CheckboxGroup rows inside a FieldSet. It is NOT a one-of-many control (use RadioGroup) and not for bare unlabelled checks in dense table rows or toolbars (use Checkbox directly).
99
+ ## Gotchas
100
+ - Despite the name, it manages ONE checkbox, not a set. The group has no value/onValueChange; checked state lives entirely on the child Checkbox you render. A shadcn-style "stateful group container" assumption is wrong here.
101
+ - It renders no Checkbox itself; you compose the anatomy and wire id/htmlFor manually (the group does not auto-link them):
102
+
103
+ ```tsx
104
+ <CheckboxGroup>
105
+ <Checkbox id="x" />
106
+ <FieldContent>
107
+ <LabelMain>
108
+ <Label htmlFor="x">Title</Label>
109
+ <LabelDescription>Help text</LabelDescription>
110
+ </LabelMain>
111
+ </FieldContent>
112
+ </CheckboxGroup>
113
+ ```
114
+
115
+ - variant, size, and shape reach the child Checkbox through CheckboxContext (resolution: explicit prop ?? context ?? default). Never repeat them on the Checkbox; an explicit child prop wins and breaks the single point of configuration.
116
+ - variant="danger" is visual only: it paints [data-slot=field-footer] text error-base and cascades a danger checkbox. It does not flip the Field invalid flag; pass invalid (inherited Field prop) yourself when you need the data-invalid cascade on label and description.
117
+ - disabled on the group only fades label/description through Field's data-disabled; CheckboxContext carries no disabled, so the input stays focusable and toggleable. Set disabled on the child Checkbox too (the shipped disabled examples set both).
118
+ - Field's orientation and size props are stripped from the type: orientation is hardcoded to horizontal, and the group's own size is forwarded to Field, so text spacing scales without extra wiring.
@@ -0,0 +1,79 @@
1
+ <!-- GENERATED FILE - do not edit. Source: registry/ui/checkbox.tsx. Regenerate with `pnpm skill:build`. Curated notes: apps/v4/scripts/skill-reference/notes/checkbox.md -->
2
+
3
+ # checkbox
4
+
5
+ Binary check control with indeterminate state; six variants, xs/sm/md sizes and rounded/pill/square shapes
6
+
7
+ Install: `npx @create-ui/cli add checkbox`
8
+
9
+ ## Import
10
+
11
+ ```tsx
12
+ import { Checkbox } from "@/components/ui/checkbox"
13
+ ```
14
+
15
+ Also exported: `CheckboxContext`, `checkboxVariants`
16
+
17
+ ## Checkbox props
18
+
19
+ | Prop | Type | Default |
20
+ | --- | --- | --- |
21
+ | variant | `primary \| neutral \| inverse \| danger \| success \| info` (inverse is built for dark surfaces: its focus and disabled backgrounds are static black. It is not a generic outlined style.) | `primary` |
22
+ | size | `xs \| sm \| md` | `sm` |
23
+ | shape | `rounded \| pill \| square` | `rounded` |
24
+
25
+ Extends `React.ComponentProps<typeof CheckboxPrimitive.Root>`.
26
+
27
+ ## Examples
28
+
29
+ From `checkbox-demo`:
30
+
31
+ ```tsx
32
+ import { Checkbox } from "@/components/ui/checkbox"
33
+
34
+ export default function CheckboxDemo() {
35
+ return <Checkbox defaultChecked aria-label="Accept terms" />
36
+ }
37
+ ```
38
+
39
+ From `checkbox-controlled`:
40
+
41
+ ```tsx
42
+ "use client"
43
+
44
+ import * as React from "react"
45
+
46
+ import { Checkbox } from "@/components/ui/checkbox"
47
+
48
+ type CheckedState = boolean | "indeterminate"
49
+
50
+ export default function CheckboxControlled() {
51
+ const [checked, setChecked] = React.useState<CheckedState>("indeterminate")
52
+
53
+ return (
54
+ <div className="flex w-40 items-center gap-3">
55
+ <Checkbox
56
+ checked={checked}
57
+ onCheckedChange={setChecked}
58
+ aria-label="Controlled checkbox"
59
+ />
60
+ <p className="text-placeholder text-ui-control-sm">
61
+ State: <span className="text-body font-medium">{String(checked)}</span>
62
+ </p>
63
+ </div>
64
+ )
65
+ }
66
+ ```
67
+
68
+ More: `npx @create-ui/cli view checkbox` or MCP `get_item_examples_from_registries` with "checkbox-demo" / "checkbox-example".
69
+
70
+ ## When to use
71
+ Checkbox is one independent boolean (accept terms, include a row in a bulk action); `checked="indeterminate"` is for a parent summarizing partially selected children. For a labelled row with label, description, or footer, compose it inside CheckboxGroup (with FieldContent + Label) instead. Do not use it for settings that apply immediately (Switch) or single-select choices (RadioGroup).
72
+
73
+ ## Gotchas
74
+ - The check and indeterminate icons are built in (RiCheckLine / RiSubtractFill, swapped via `data-state`). Do not port shadcn's pattern of passing an icon child or a `CheckboxIndicator`; there is no indicator export, and any children you pass are overridden by the internal indicator.
75
+ - variant/size/shape resolve as explicit prop ?? CheckboxContext ?? default. CheckboxGroup provides that context (and defaults to size md, unlike a bare Checkbox), so set size/shape once on the group and leave the inner Checkbox bare. The group's own variant only covers primary/danger; other variants go on the Checkbox itself. Field does not cascade into Checkbox.
76
+ - It renders only the box, no label slot. Pair it with `<label htmlFor>` or `aria-label`. Field's invalid/disabled state does not restyle the box; mirror `aria-invalid` / `disabled` on the Checkbox itself.
77
+ - `aria-invalid` adds the red error outline on any variant. `variant="danger"` only recolors the checked fill and focus outline; the unchecked resting border stays neutral, so it is not the validation state.
78
+ - Focus styling is outline-based (`outline-2` on the root). className overrides must use `outline-*` utilities, never `ring-*`.
79
+ - The root carries the `peer` class, so a sibling label can style against state (e.g. `peer-data-[state=checked]:line-through`) with no extra wiring.