@create-ui/cli 0.5.7 → 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.
- package/dist/{chunk-RMTTHCB3.js → chunk-2ELKDGGM.js} +3 -3
- package/dist/{chunk-RMTTHCB3.js.map → chunk-2ELKDGGM.js.map} +1 -1
- package/dist/chunk-643QI2I2.js +102 -0
- package/dist/chunk-643QI2I2.js.map +1 -0
- package/dist/{chunk-NQFMXHMH.js → chunk-KQTXDVKV.js} +3 -3
- package/dist/chunk-KQTXDVKV.js.map +1 -0
- package/dist/index.js +35 -35
- package/dist/index.js.map +1 -1
- package/dist/mcp/index.js +1 -1
- package/dist/registry/index.js +1 -1
- package/dist/skills/createui/SKILL.md +201 -177
- package/dist/skills/createui/agents/openai.yml +1 -1
- package/dist/skills/createui/cli.md +42 -42
- package/dist/skills/createui/customization.md +20 -15
- package/dist/skills/createui/evals/evals.json +68 -5
- package/dist/skills/createui/mcp.md +14 -5
- package/dist/skills/createui/reference/accordion.md +127 -0
- package/dist/skills/createui/reference/app-store-badge.md +88 -0
- package/dist/skills/createui/reference/aspect-ratio.md +52 -0
- package/dist/skills/createui/reference/avatar.md +230 -0
- package/dist/skills/createui/reference/badge.md +110 -0
- package/dist/skills/createui/reference/breadcrumb.md +153 -0
- package/dist/skills/createui/reference/button-group.md +116 -0
- package/dist/skills/createui/reference/button.md +104 -0
- package/dist/skills/createui/reference/checkbox-group.md +118 -0
- package/dist/skills/createui/reference/checkbox.md +79 -0
- package/dist/skills/createui/reference/chip.md +115 -0
- package/dist/skills/createui/reference/close-button.md +83 -0
- package/dist/skills/createui/reference/command.md +69 -0
- package/dist/skills/createui/reference/country-flag.md +109 -0
- package/dist/skills/createui/reference/credit-card-input.md +76 -0
- package/dist/skills/createui/reference/date-input.md +71 -0
- package/dist/skills/createui/reference/dropdown-menu.md +164 -0
- package/dist/skills/createui/reference/field.md +186 -0
- package/dist/skills/createui/reference/info-tooltip.md +110 -0
- package/dist/skills/createui/reference/inline-alert.md +146 -0
- package/dist/skills/createui/reference/input-group.md +171 -0
- package/dist/skills/createui/reference/input-otp.md +130 -0
- package/dist/skills/createui/reference/input-stepper.md +120 -0
- package/dist/skills/createui/reference/input.md +118 -0
- package/dist/skills/createui/reference/label.md +121 -0
- package/dist/skills/createui/reference/pagination.md +157 -0
- package/dist/skills/createui/reference/password-strength.md +70 -0
- package/dist/skills/createui/reference/phone-input.md +77 -0
- package/dist/skills/createui/reference/progress.md +158 -0
- package/dist/skills/createui/reference/radio-group.md +133 -0
- package/dist/skills/createui/reference/radio.md +79 -0
- package/dist/skills/createui/reference/scroll-area.md +212 -0
- package/dist/skills/createui/reference/segmented-control.md +146 -0
- package/dist/skills/createui/reference/select.md +204 -0
- package/dist/skills/createui/reference/separator.md +99 -0
- package/dist/skills/createui/reference/social-login-button.md +130 -0
- package/dist/skills/createui/reference/spinner.md +68 -0
- package/dist/skills/createui/reference/status-badge.md +89 -0
- package/dist/skills/createui/reference/switch-group.md +122 -0
- package/dist/skills/createui/reference/switch.md +75 -0
- package/dist/skills/createui/reference/tab-menu.md +165 -0
- package/dist/skills/createui/reference/text-link.md +84 -0
- package/dist/skills/createui/reference/textarea.md +50 -0
- package/dist/skills/createui/reference/toast.md +162 -0
- package/dist/skills/createui/reference/tooltip.md +63 -0
- package/dist/skills/createui/rules/composition.md +41 -25
- package/dist/skills/createui/rules/design.md +266 -0
- package/dist/skills/createui/rules/forms.md +44 -15
- package/dist/skills/createui/rules/icons.md +64 -18
- package/dist/skills/createui/rules/styling.md +53 -14
- package/dist/utils/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-M5DYT2NE.js +0 -64
- package/dist/chunk-M5DYT2NE.js.map +0 -1
- 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'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.
|