@create-ui/cli 0.6.0 → 0.6.1
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-KFQXWKJJ.js +19 -0
- package/dist/chunk-KFQXWKJJ.js.map +1 -0
- package/dist/{chunk-2ELKDGGM.js → chunk-OGAWGP7T.js} +3 -3
- package/dist/{chunk-2ELKDGGM.js.map → chunk-OGAWGP7T.js.map} +1 -1
- package/dist/chunk-OITQ46YK.js +99 -0
- package/dist/chunk-OITQ46YK.js.map +1 -0
- package/dist/index.js +16 -16
- package/dist/index.js.map +1 -1
- package/dist/mcp/index.js +1 -1
- package/dist/registry/index.d.ts +3 -1
- package/dist/registry/index.js +1 -1
- package/dist/skills/createui/SKILL.md +81 -52
- package/dist/skills/createui/cli.md +1 -1
- package/dist/skills/createui/customization.md +14 -12
- package/dist/skills/createui/evals/evals.json +77 -0
- package/dist/skills/createui/mcp.md +12 -26
- package/dist/skills/createui/rules/a11y.md +148 -0
- package/dist/skills/createui/rules/composition.md +64 -26
- package/dist/skills/createui/rules/forms.md +2 -2
- package/dist/skills/createui/rules/icons.md +1 -1
- package/dist/skills/createui/rules/styling.md +2 -2
- package/dist/utils/index.js +1 -1
- package/dist/utils/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-643QI2I2.js +0 -102
- package/dist/chunk-643QI2I2.js.map +0 -1
- package/dist/chunk-KQTXDVKV.js +0 -19
- package/dist/chunk-KQTXDVKV.js.map +0 -1
- package/dist/skills/createui/reference/accordion.md +0 -127
- package/dist/skills/createui/reference/app-store-badge.md +0 -88
- package/dist/skills/createui/reference/aspect-ratio.md +0 -52
- package/dist/skills/createui/reference/avatar.md +0 -230
- package/dist/skills/createui/reference/badge.md +0 -110
- package/dist/skills/createui/reference/breadcrumb.md +0 -153
- package/dist/skills/createui/reference/button-group.md +0 -116
- package/dist/skills/createui/reference/button.md +0 -104
- package/dist/skills/createui/reference/checkbox-group.md +0 -118
- package/dist/skills/createui/reference/checkbox.md +0 -79
- package/dist/skills/createui/reference/chip.md +0 -115
- package/dist/skills/createui/reference/close-button.md +0 -83
- package/dist/skills/createui/reference/country-flag.md +0 -109
- package/dist/skills/createui/reference/credit-card-input.md +0 -76
- package/dist/skills/createui/reference/date-input.md +0 -71
- package/dist/skills/createui/reference/dropdown-menu.md +0 -164
- package/dist/skills/createui/reference/field.md +0 -186
- package/dist/skills/createui/reference/info-tooltip.md +0 -110
- package/dist/skills/createui/reference/inline-alert.md +0 -146
- package/dist/skills/createui/reference/input-group.md +0 -171
- package/dist/skills/createui/reference/input-otp.md +0 -130
- package/dist/skills/createui/reference/input-stepper.md +0 -120
- package/dist/skills/createui/reference/input.md +0 -118
- package/dist/skills/createui/reference/label.md +0 -121
- package/dist/skills/createui/reference/pagination.md +0 -157
- package/dist/skills/createui/reference/phone-input.md +0 -77
- package/dist/skills/createui/reference/progress.md +0 -158
- package/dist/skills/createui/reference/radio-group.md +0 -133
- package/dist/skills/createui/reference/radio.md +0 -79
- package/dist/skills/createui/reference/scroll-area.md +0 -212
- package/dist/skills/createui/reference/segmented-control.md +0 -146
- package/dist/skills/createui/reference/select.md +0 -204
- package/dist/skills/createui/reference/separator.md +0 -99
- package/dist/skills/createui/reference/social-login-button.md +0 -130
- package/dist/skills/createui/reference/spinner.md +0 -68
- package/dist/skills/createui/reference/status-badge.md +0 -89
- package/dist/skills/createui/reference/switch-group.md +0 -122
- package/dist/skills/createui/reference/switch.md +0 -75
- package/dist/skills/createui/reference/tab-menu.md +0 -165
- package/dist/skills/createui/reference/text-link.md +0 -84
- package/dist/skills/createui/reference/textarea.md +0 -50
- package/dist/skills/createui/reference/toast.md +0 -162
- package/dist/skills/createui/reference/tooltip.md +0 -63
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
<!-- GENERATED FILE - do not edit. Source: registry/ui/status-badge.tsx. Regenerate with `pnpm skill:build`. Curated notes: apps/v4/scripts/skill-reference/notes/status-badge.md -->
|
|
2
|
-
|
|
3
|
-
# status-badge
|
|
4
|
-
|
|
5
|
-
Tiny presence dot only, no built-in label; 12 status colors and xs/sm/md sizes, place text beside it yourself
|
|
6
|
-
|
|
7
|
-
Install: `npx @create-ui/cli add status-badge`
|
|
8
|
-
|
|
9
|
-
## Import
|
|
10
|
-
|
|
11
|
-
```tsx
|
|
12
|
-
import { StatusBadge } from "@/components/ui/status-badge"
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
Also exported: `statusBadgeVariants`
|
|
16
|
-
|
|
17
|
-
## StatusBadge props
|
|
18
|
-
|
|
19
|
-
| Prop | Type | Default |
|
|
20
|
-
| --- | --- | --- |
|
|
21
|
-
| variant | `primary \| danger \| success \| warning \| info \| highlighted \| away \| verified \| cyan \| lime \| neutral \| white` (Error tone is \"danger\" (there is no \"error\" or \"destructive\" key); \"white\" is the only variant that drops the built-in outline ring, for use on dark surfaces) | `primary` |
|
|
22
|
-
| size | `xs \| sm \| md` (Fixed pixel diameters (xs 4px, sm 6px, md 8px); standalone, no Field/InputGroup size cascade) | `md` |
|
|
23
|
-
|
|
24
|
-
Extends `React.ComponentProps<"span">`.
|
|
25
|
-
|
|
26
|
-
## Examples
|
|
27
|
-
|
|
28
|
-
From `status-badge-demo`:
|
|
29
|
-
|
|
30
|
-
```tsx
|
|
31
|
-
import { StatusBadge } from "@/components/ui/status-badge"
|
|
32
|
-
|
|
33
|
-
export default function StatusBadgeDemo() {
|
|
34
|
-
return (
|
|
35
|
-
<div className="flex flex-wrap items-center gap-4">
|
|
36
|
-
<div className="flex items-center gap-2">
|
|
37
|
-
<StatusBadge variant="success" />
|
|
38
|
-
<span className="text-body text-sm">Online</span>
|
|
39
|
-
</div>
|
|
40
|
-
<div className="flex items-center gap-2">
|
|
41
|
-
<StatusBadge variant="away" />
|
|
42
|
-
<span className="text-body text-sm">Away</span>
|
|
43
|
-
</div>
|
|
44
|
-
<div className="flex items-center gap-2">
|
|
45
|
-
<StatusBadge variant="danger" />
|
|
46
|
-
<span className="text-body text-sm">Offline</span>
|
|
47
|
-
</div>
|
|
48
|
-
</div>
|
|
49
|
-
)
|
|
50
|
-
}
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
From `status-badge-in-avatar`:
|
|
54
|
-
|
|
55
|
-
```tsx
|
|
56
|
-
import { StatusBadge } from "@/components/ui/status-badge"
|
|
57
|
-
|
|
58
|
-
export default function StatusBadgeInAvatar() {
|
|
59
|
-
return (
|
|
60
|
-
<div className="flex flex-wrap items-center gap-6">
|
|
61
|
-
<div className="relative">
|
|
62
|
-
<div className="from-light to-weak size-10 rounded-full bg-gradient-to-br" />
|
|
63
|
-
<StatusBadge variant="success" className="absolute right-0 bottom-0" />
|
|
64
|
-
</div>
|
|
65
|
-
<div className="relative">
|
|
66
|
-
<div className="from-light to-weak size-10 rounded-full bg-gradient-to-br" />
|
|
67
|
-
<StatusBadge variant="away" className="absolute right-0 bottom-0" />
|
|
68
|
-
</div>
|
|
69
|
-
<div className="relative">
|
|
70
|
-
<div className="from-light to-weak size-10 rounded-full bg-gradient-to-br" />
|
|
71
|
-
<StatusBadge variant="neutral" className="absolute right-0 bottom-0" />
|
|
72
|
-
</div>
|
|
73
|
-
</div>
|
|
74
|
-
)
|
|
75
|
-
}
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
More: `npx @create-ui/cli view status-badge` or MCP `get_item_examples_from_registries` with "status-badge-demo" / "status-badge-example".
|
|
79
|
-
|
|
80
|
-
## When to use
|
|
81
|
-
StatusBadge is a dot-only presence/state indicator (a single `<span role="status">` circle): online dots on avatars, live markers on rows, status legends. It carries no text; a sibling label or the host element gives it meaning. If the indicator needs a label or count use Badge, for transient events use Toast, and for loading use Spinner.
|
|
82
|
-
|
|
83
|
-
## Gotchas
|
|
84
|
-
- Do not pass children; the component renders a fixed-size dot (`size-1`/`1.5`/`2`, i.e. 4-8px) and any content would overflow the box. Render the label as a sibling in a flex row: `<StatusBadge variant="success" /> <span>Online</span>`.
|
|
85
|
-
- A white outline ring (`outline-static-white outline`) is built into every variant so the dot stays legible layered over avatars; only the `white` variant removes it (`outline-0`). Do not re-add `ring-*` or borders to fake this.
|
|
86
|
-
- Avatar pinning is manual composition: wrap the avatar in `relative` and position the badge with `className="absolute right-0 bottom-0"`. There is no `position`/anchor prop.
|
|
87
|
-
- This is not shadcn's `Badge`: no text slot and no `asChild`.
|
|
88
|
-
- `role="status"` is hardcoded, but the dot has no announced content, so pair it with a visible text label or put `aria-label` on the surrounding element.
|
|
89
|
-
- No `data-variant`/`data-size` attributes are emitted; CSS targeting goes through `data-slot="status-badge"` plus classes. `shrink-0` is built in, so it will not squash in tight flex rows.
|
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
<!-- GENERATED FILE - do not edit. Source: registry/ui/switch-group.tsx. Regenerate with `pnpm skill:build`. Curated notes: apps/v4/scripts/skill-reference/notes/switch-group.md -->
|
|
2
|
-
|
|
3
|
-
# switch-group
|
|
4
|
-
|
|
5
|
-
Field wrapper that labels a Switch and cascades variant, size, shape, thumbType and ioTrigger; placement left or right
|
|
6
|
-
|
|
7
|
-
Install: `npx @create-ui/cli add switch-group`
|
|
8
|
-
|
|
9
|
-
## Import
|
|
10
|
-
|
|
11
|
-
```tsx
|
|
12
|
-
import { SwitchGroup } from "@/components/ui/switch-group"
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
Also exported: `switchGroupVariants`
|
|
16
|
-
|
|
17
|
-
## SwitchGroup props
|
|
18
|
-
|
|
19
|
-
| Prop | Type | Default |
|
|
20
|
-
| --- | --- | --- |
|
|
21
|
-
| variant | `SwitchVariant` | `primary` |
|
|
22
|
-
| size | `xs \| sm \| md` (Sets the Field label scale and the child Switch size via context; Field's own size and orientation props are stripped from the API (orientation is locked horizontal)) | `md` |
|
|
23
|
-
| shape | `SwitchShape` | `pill` |
|
|
24
|
-
| thumbType | `SwitchThumbType` | `short` |
|
|
25
|
-
| ioTrigger | `boolean` | `false` |
|
|
26
|
-
| placement | `left \| right` (right is a CSS-only flip (flex-row-reverse); keep the Switch first in the DOM either way) | `left` |
|
|
27
|
-
|
|
28
|
-
Extends `React.ComponentProps<typeof Field>`.
|
|
29
|
-
|
|
30
|
-
## Examples
|
|
31
|
-
|
|
32
|
-
From `switch-group-demo`:
|
|
33
|
-
|
|
34
|
-
```tsx
|
|
35
|
-
import { FieldContent } from "@/components/ui/field"
|
|
36
|
-
import { Label, LabelDescription, LabelMain } from "@/components/ui/label"
|
|
37
|
-
import { Switch } from "@/components/ui/switch"
|
|
38
|
-
import { SwitchGroup } from "@/components/ui/switch-group"
|
|
39
|
-
|
|
40
|
-
export default function SwitchGroupDemo() {
|
|
41
|
-
return (
|
|
42
|
-
<SwitchGroup className="w-[340px]">
|
|
43
|
-
<Switch id="sw-demo" defaultChecked />
|
|
44
|
-
<FieldContent>
|
|
45
|
-
<LabelMain>
|
|
46
|
-
<Label htmlFor="sw-demo">Push notifications</Label>
|
|
47
|
-
<LabelDescription>
|
|
48
|
-
Get alerts the moment something happens on your account.
|
|
49
|
-
</LabelDescription>
|
|
50
|
-
</LabelMain>
|
|
51
|
-
</FieldContent>
|
|
52
|
-
</SwitchGroup>
|
|
53
|
-
)
|
|
54
|
-
}
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
From `switch-group-disabled`:
|
|
58
|
-
|
|
59
|
-
```tsx
|
|
60
|
-
import { FieldContent } from "@/components/ui/field"
|
|
61
|
-
import { Label, LabelDescription, LabelMain } from "@/components/ui/label"
|
|
62
|
-
import { Switch } from "@/components/ui/switch"
|
|
63
|
-
import { SwitchGroup } from "@/components/ui/switch-group"
|
|
64
|
-
|
|
65
|
-
export default function SwitchGroupDisabled() {
|
|
66
|
-
return (
|
|
67
|
-
<div className="flex flex-col gap-6">
|
|
68
|
-
<SwitchGroup disabled className="w-[340px]">
|
|
69
|
-
<Switch id="sw-disabled-on" checked disabled />
|
|
70
|
-
<FieldContent>
|
|
71
|
-
<LabelMain>
|
|
72
|
-
<Label htmlFor="sw-disabled-on">Push notifications</Label>
|
|
73
|
-
<LabelDescription>
|
|
74
|
-
Disabled state cascades to label and description.
|
|
75
|
-
</LabelDescription>
|
|
76
|
-
</LabelMain>
|
|
77
|
-
</FieldContent>
|
|
78
|
-
</SwitchGroup>
|
|
79
|
-
|
|
80
|
-
<SwitchGroup disabled className="w-[340px]">
|
|
81
|
-
<Switch id="sw-disabled-off" checked={false} disabled />
|
|
82
|
-
<FieldContent>
|
|
83
|
-
<LabelMain>
|
|
84
|
-
<Label htmlFor="sw-disabled-off">Marketing emails</Label>
|
|
85
|
-
<LabelDescription>
|
|
86
|
-
The unchecked row reads muted too.
|
|
87
|
-
</LabelDescription>
|
|
88
|
-
</LabelMain>
|
|
89
|
-
</FieldContent>
|
|
90
|
-
</SwitchGroup>
|
|
91
|
-
</div>
|
|
92
|
-
)
|
|
93
|
-
}
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
More: `npx @create-ui/cli view switch-group` or MCP `get_item_examples_from_registries` with "switch-group-demo" / "switch-group-example".
|
|
97
|
-
|
|
98
|
-
## When to use
|
|
99
|
-
One labelled switch row for settings that apply the moment they flip: notification preferences, feature flags, privacy toggles. Stack several SwitchGroups in a column for a settings panel. Do NOT use it inside a submit-to-save form (use CheckboxGroup), for one-of-many selection (use RadioGroup), or for a bare unlabelled toggle in a toolbar or table cell (use Switch directly).
|
|
100
|
-
|
|
101
|
-
## Gotchas
|
|
102
|
-
- Despite the name, SwitchGroup is a single row, not a multi-switch container, and it renders no Switch of its own. There is no SwitchGroupItem; you compose the anatomy yourself:
|
|
103
|
-
|
|
104
|
-
```tsx
|
|
105
|
-
<SwitchGroup>
|
|
106
|
-
<Switch id="x" />
|
|
107
|
-
<FieldContent>
|
|
108
|
-
<LabelMain>
|
|
109
|
-
<Label htmlFor="x">Title</Label>
|
|
110
|
-
<LabelDescription>Optional helper.</LabelDescription>
|
|
111
|
-
</LabelMain>
|
|
112
|
-
<FieldFooter>{/* optional, e.g. TextLink */}</FieldFooter>
|
|
113
|
-
</FieldContent>
|
|
114
|
-
</SwitchGroup>
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
- The child Switch resolves each look prop as explicit prop ?? SwitchContext ?? default, so any prop set directly on the Switch silently overrides the group; configure looks on the group and keep the Switch bare except id/checked/disabled.
|
|
118
|
-
- The context the group provides carries variant, size, shape, thumbType, ioTrigger only. SwitchGroup has no thumbIcon prop and never forwards one; set thumbIcon on the Switch itself.
|
|
119
|
-
- Label association is manual: the Field root is a role="group" div, not a label, so always pair Switch id with Label htmlFor.
|
|
120
|
-
- For a disabled row, set disabled on BOTH the group (label/description fade via Field) and the child Switch (the actual control), as in switch-group-disabled.
|
|
121
|
-
- The label block must sit inside FieldContent: Field only top-aligns the switch when a direct [data-slot=field-content] child exists (has-[] selector), so loose Label siblings sit in a row and break the stacking.
|
|
122
|
-
- SwitchGroup is a Field, so its root is full-width: placed inline (e.g. the right side of a justify-between header or toolbar) it wraps onto its own full-width line unless you constrain it with an explicit width (className="w-auto", max-w-*, or a fixed width).
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
<!-- GENERATED FILE - do not edit. Source: registry/ui/switch.tsx. Regenerate with `pnpm skill:build`. Curated notes: apps/v4/scripts/skill-reference/notes/switch.md -->
|
|
2
|
-
|
|
3
|
-
# switch
|
|
4
|
-
|
|
5
|
-
Toggle switch; variant primary/info/neutral/inverse/semantic, thumbType short/long, ioTrigger and thumbIcon options
|
|
6
|
-
|
|
7
|
-
Install: `npx @create-ui/cli add switch`
|
|
8
|
-
|
|
9
|
-
## Import
|
|
10
|
-
|
|
11
|
-
```tsx
|
|
12
|
-
import { Switch } from "@/components/ui/switch"
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
Also exported: `SwitchContext`, `switchVariants`
|
|
16
|
-
|
|
17
|
-
## Switch props
|
|
18
|
-
|
|
19
|
-
| Prop | Type | Default |
|
|
20
|
-
| --- | --- | --- |
|
|
21
|
-
| variant | `primary \| info \| neutral \| inverse \| semantic` (semantic = red when off, green when on (accept/reject patterns)) | `primary` |
|
|
22
|
-
| size | `md \| sm \| xs` | `md` |
|
|
23
|
-
| shape | `pill \| rounded` | `pill` |
|
|
24
|
-
| thumbType | `short \| long` (long is a statically wider thumb and track; checked travel distance is unchanged) | `short` |
|
|
25
|
-
| ioTrigger | `boolean` (aria-hidden I/O glyphs in the track: line when on, circle when off) | `false` |
|
|
26
|
-
| thumbIcon | `boolean` (aria-hidden check/close icons inside the thumb) | `false` |
|
|
27
|
-
|
|
28
|
-
Extends `React.ComponentProps<typeof SwitchPrimitive.Root>`.
|
|
29
|
-
|
|
30
|
-
## Examples
|
|
31
|
-
|
|
32
|
-
From `switch-demo`:
|
|
33
|
-
|
|
34
|
-
```tsx
|
|
35
|
-
import { Switch } from "@/components/ui/switch"
|
|
36
|
-
|
|
37
|
-
export default function SwitchDemo() {
|
|
38
|
-
return (
|
|
39
|
-
<div className="flex items-center gap-3">
|
|
40
|
-
<Switch defaultChecked />
|
|
41
|
-
<Switch />
|
|
42
|
-
</div>
|
|
43
|
-
)
|
|
44
|
-
}
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
From `switch-thumb-icon`:
|
|
48
|
-
|
|
49
|
-
```tsx
|
|
50
|
-
import { Switch } from "@/components/ui/switch"
|
|
51
|
-
|
|
52
|
-
export default function SwitchThumbIcon() {
|
|
53
|
-
return (
|
|
54
|
-
<div className="flex items-center gap-4">
|
|
55
|
-
<Switch thumbIcon defaultChecked />
|
|
56
|
-
<Switch thumbIcon />
|
|
57
|
-
</div>
|
|
58
|
-
)
|
|
59
|
-
}
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
More: `npx @create-ui/cli view switch` or MCP `get_item_examples_from_registries` with "switch-demo" / "switch-example".
|
|
63
|
-
|
|
64
|
-
## When to use
|
|
65
|
-
|
|
66
|
-
A single standalone on/off control. A boolean that only commits on form submit is `Checkbox`. A switch with a label and description in one apply-immediately row is `SwitchGroup` (it wraps `Field orientation="horizontal"` and feeds `SwitchContext`); do not hand-roll that row from `Field` + `Switch`. Exception: inside a submit-to-save form that deliberately uses toggles, `SwitchGroup` is wrong - compose `Field size="md" orientation="horizontal"` + `FieldContent` (`FieldLabel` + `FieldDescription`) + `Switch`, as in the field-composition example.
|
|
67
|
-
|
|
68
|
-
## Gotchas
|
|
69
|
-
|
|
70
|
-
- Every visual prop resolves `prop ?? SwitchContext ?? default`. `SwitchGroup` provides context for `variant`/`size`/`shape`/`thumbType`/`ioTrigger`, so set those on the group, not the inner Switch. `thumbIcon` is NOT in the group context; set it on the Switch itself. For an ad-hoc cluster, wrap in the exported `SwitchContext.Provider`.
|
|
71
|
-
- `Field` size does NOT cascade here: Switch reads only `SwitchContext`, never Field's context. In a plain `Field` row, set `size` on the Switch itself.
|
|
72
|
-
- Do not pass children to `<Switch>`; it renders its own thumb/icon internals and silently replaces anything you pass. The label lives outside (`Label htmlFor` + `id`, or `aria-label`).
|
|
73
|
-
- Track width is a fixed pixel value per `size` x `thumbType`, and the checked `translate-x` is fixed per `size` (22/18/14px). Overriding width via `className` desyncs the thumb travel; change `size`/`thumbType` instead.
|
|
74
|
-
- The clickable area is silently enlarged by an `after:` pseudo-element (12px horizontally, 8px vertically past the track); keep other clickable controls clear of that zone.
|
|
75
|
-
- Error state comes from passing `aria-invalid` (persistent red outline), not from a variant.
|
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
<!-- GENERATED FILE - do not edit. Source: registry/ui/tab-menu.tsx. Regenerate with `pnpm skill:build`. Curated notes: apps/v4/scripts/skill-reference/notes/tab-menu.md -->
|
|
2
|
-
|
|
3
|
-
# tab-menu
|
|
4
|
-
|
|
5
|
-
Navigation tab list with no content panels; vertical/horizontal button and line variants, leadingIcon/trailingIcon items
|
|
6
|
-
|
|
7
|
-
Install: `npx @create-ui/cli add tab-menu`
|
|
8
|
-
|
|
9
|
-
## Import
|
|
10
|
-
|
|
11
|
-
```tsx
|
|
12
|
-
import { TabMenu, TabMenuItem } from "@/components/ui/tab-menu"
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
Also exported: `tabMenuVariants`, `tabMenuItemVariants`
|
|
16
|
-
|
|
17
|
-
## TabMenu props
|
|
18
|
-
|
|
19
|
-
| Prop | Type | Default |
|
|
20
|
-
| --- | --- | --- |
|
|
21
|
-
| variant | `vertical-button \| vertical-line \| horizontal-line \| horizontal-button` | `vertical-button` |
|
|
22
|
-
| size | `sm \| md \| lg` | `md` |
|
|
23
|
-
| indicator | `left \| top \| bottom` (line variants render no active line without it; designed pairings: vertical-button+left, vertical-line/horizontal-line+top|bottom; horizontal-button takes none) | - |
|
|
24
|
-
| value | `string` | - |
|
|
25
|
-
| defaultValue | `string` | - |
|
|
26
|
-
| onValueChange | `(value: string) => void` | - |
|
|
27
|
-
|
|
28
|
-
Extends `React.ComponentProps<"div">`.
|
|
29
|
-
|
|
30
|
-
## TabMenuItem props
|
|
31
|
-
|
|
32
|
-
| Prop | Type | Default |
|
|
33
|
-
| --- | --- | --- |
|
|
34
|
-
| asChild | `boolean` | `false` |
|
|
35
|
-
| value | `string` | - |
|
|
36
|
-
| selected | `boolean` (overrides value matching; use for route-driven tabs where the pathname decides) | - |
|
|
37
|
-
| leadingIcon | `ReactNode` | - |
|
|
38
|
-
| trailingIcon | `ReactNode` | - |
|
|
39
|
-
| label | `ReactNode` (the label slot; bare children are NOT the label (they render as extra content next to it, e.g. a Badge)) | - |
|
|
40
|
-
|
|
41
|
-
Extends `React.ComponentProps<"button">`.
|
|
42
|
-
|
|
43
|
-
## Icons
|
|
44
|
-
|
|
45
|
-
Icons go through icon props - never as children next to text, and never with sizing classes (the component sizes icons per `size`): `TabMenuItem` (`leadingIcon` / `trailingIcon`). Import icons from `@create-ui/assets/icons` (Remix `Ri*`).
|
|
46
|
-
|
|
47
|
-
## Examples
|
|
48
|
-
|
|
49
|
-
From `tab-menu-demo`:
|
|
50
|
-
|
|
51
|
-
```tsx
|
|
52
|
-
import {
|
|
53
|
-
RiBankCardFill,
|
|
54
|
-
RiInboxLine,
|
|
55
|
-
RiInformationFill,
|
|
56
|
-
RiSettings6Fill,
|
|
57
|
-
} from "@create-ui/assets/icons"
|
|
58
|
-
|
|
59
|
-
import { TabMenu, TabMenuItem } from "@/components/ui/tab-menu"
|
|
60
|
-
|
|
61
|
-
export default function TabMenuDemo() {
|
|
62
|
-
return (
|
|
63
|
-
<TabMenu
|
|
64
|
-
variant="horizontal-line"
|
|
65
|
-
indicator="bottom"
|
|
66
|
-
size="lg"
|
|
67
|
-
defaultValue="activity"
|
|
68
|
-
>
|
|
69
|
-
<TabMenuItem
|
|
70
|
-
value="overview"
|
|
71
|
-
leadingIcon={<RiInformationFill />}
|
|
72
|
-
label="Overview"
|
|
73
|
-
/>
|
|
74
|
-
<TabMenuItem
|
|
75
|
-
value="activity"
|
|
76
|
-
leadingIcon={<RiInboxLine />}
|
|
77
|
-
label="Activity"
|
|
78
|
-
/>
|
|
79
|
-
<TabMenuItem
|
|
80
|
-
value="billing"
|
|
81
|
-
leadingIcon={<RiBankCardFill />}
|
|
82
|
-
label="Billing"
|
|
83
|
-
/>
|
|
84
|
-
<TabMenuItem
|
|
85
|
-
value="settings"
|
|
86
|
-
leadingIcon={<RiSettings6Fill />}
|
|
87
|
-
label="Settings"
|
|
88
|
-
/>
|
|
89
|
-
</TabMenu>
|
|
90
|
-
)
|
|
91
|
-
}
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
From `tab-menu-with-badge`:
|
|
95
|
-
|
|
96
|
-
```tsx
|
|
97
|
-
import {
|
|
98
|
-
RiBankCardFill,
|
|
99
|
-
RiInboxLine,
|
|
100
|
-
RiSettings6Fill,
|
|
101
|
-
} from "@create-ui/assets/icons"
|
|
102
|
-
|
|
103
|
-
import { Badge } from "@/components/ui/badge"
|
|
104
|
-
import { StatusBadge } from "@/components/ui/status-badge"
|
|
105
|
-
import { TabMenu, TabMenuItem } from "@/components/ui/tab-menu"
|
|
106
|
-
|
|
107
|
-
export default function TabMenuWithBadge() {
|
|
108
|
-
return (
|
|
109
|
-
<TabMenu
|
|
110
|
-
className="w-[320px]"
|
|
111
|
-
variant="vertical-button"
|
|
112
|
-
size="lg"
|
|
113
|
-
defaultValue="activity"
|
|
114
|
-
>
|
|
115
|
-
<TabMenuItem
|
|
116
|
-
value="activity"
|
|
117
|
-
leadingIcon={<RiInboxLine />}
|
|
118
|
-
label="Activity"
|
|
119
|
-
>
|
|
120
|
-
<Badge variant="info" appearance="soft" size="sm">
|
|
121
|
-
12
|
|
122
|
-
</Badge>
|
|
123
|
-
</TabMenuItem>
|
|
124
|
-
<TabMenuItem
|
|
125
|
-
value="billing"
|
|
126
|
-
leadingIcon={<RiBankCardFill />}
|
|
127
|
-
label="Billing"
|
|
128
|
-
>
|
|
129
|
-
<Badge variant="success" appearance="soft" size="sm">
|
|
130
|
-
New
|
|
131
|
-
</Badge>
|
|
132
|
-
</TabMenuItem>
|
|
133
|
-
<TabMenuItem
|
|
134
|
-
value="settings"
|
|
135
|
-
leadingIcon={<RiSettings6Fill />}
|
|
136
|
-
label="Settings"
|
|
137
|
-
>
|
|
138
|
-
<StatusBadge variant="primary" size="md" />
|
|
139
|
-
</TabMenuItem>
|
|
140
|
-
</TabMenu>
|
|
141
|
-
)
|
|
142
|
-
}
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
More: `npx @create-ui/cli view tab-menu` or MCP `get_item_examples_from_registries` with "tab-menu-demo" / "tab-menu-example".
|
|
146
|
-
|
|
147
|
-
## When to use
|
|
148
|
-
|
|
149
|
-
Tab-style navigation: settings sidebars, section switchers, routed nav as links. TabMenu renders the tab list only; there are no content-panel components, so render panels yourself keyed by the active value (`{tab === "billing" && <BillingPanel />}`). For 2-5 inline mutually exclusive options without rich item content, use SegmentedControl instead.
|
|
150
|
-
|
|
151
|
-
## Gotchas
|
|
152
|
-
|
|
153
|
-
- There is no shadcn-style `Tabs` / `TabsList` / `TabsTrigger` / `TabsContent` set; do not invent one. `TabMenu` itself owns the value (`defaultValue`, or controlled `value` + `onValueChange`) and that is the whole API.
|
|
154
|
-
- Text goes in the `label` prop; bare children are NOT the label, they render as extra content beside it (the badge slot, see tab-menu-with-badge). Icons only via `leadingIcon` / `trailingIcon`, never as children.
|
|
155
|
-
- `asChild` needs exactly one non-Fragment element child or it silently falls back to a plain `<button>`. The child's own text becomes the label (`label` is only a fallback when the child has no children) and the extra-children badge slot is unavailable; icons stay as props on `TabMenuItem`:
|
|
156
|
-
|
|
157
|
-
```tsx
|
|
158
|
-
<TabMenuItem asChild value="billing" leadingIcon={<RiBankCardFill />}>
|
|
159
|
-
<Link href="/billing">Billing</Link>
|
|
160
|
-
</TabMenuItem>
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
- Line variants show no active marker beyond text color unless `indicator` is set; button variants (`vertical-button`, `horizontal-button`) get the sliding `bg-weak` pill automatically.
|
|
164
|
-
- This is not ARIA tabs: a `role="group"` of `aria-pressed` buttons where every item is its own Tab stop; there is no arrow-key roving like Radix Tabs. asChild items get no `aria-pressed`; their `disabled` maps to `aria-disabled` + `tabIndex={-1}`.
|
|
165
|
-
- An item `onClick` that calls `event.preventDefault()` blocks the value commit; `disabled` items skip both `onClick` and `onValueChange`.
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
<!-- GENERATED FILE - do not edit. Source: registry/ui/text-link.tsx. Regenerate with `pnpm skill:build`. Curated notes: apps/v4/scripts/skill-reference/notes/text-link.md -->
|
|
2
|
-
|
|
3
|
-
# text-link
|
|
4
|
-
|
|
5
|
-
Inline anchor link with six color variants; underline, visited and disabled states, leadingIcon/trailingIcon, asChild
|
|
6
|
-
|
|
7
|
-
Install: `npx @create-ui/cli add text-link`
|
|
8
|
-
|
|
9
|
-
## Import
|
|
10
|
-
|
|
11
|
-
```tsx
|
|
12
|
-
import { TextLink } from "@/components/ui/text-link"
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
Also exported: `textLinkVariants`
|
|
16
|
-
|
|
17
|
-
## TextLink props
|
|
18
|
-
|
|
19
|
-
| Prop | Type | Default |
|
|
20
|
-
| --- | --- | --- |
|
|
21
|
-
| variant | `primary \| neutral \| inverse \| danger \| success \| info` | `primary` |
|
|
22
|
-
| size | `xs \| sm \| md \| lg` | `md` |
|
|
23
|
-
| visited | `boolean` (Prop-controlled only (purple-500 text, violet underline); the component never reacts to the CSS :visited pseudo-class) | `false` |
|
|
24
|
-
| disabled | `boolean` (Sets aria-disabled, tabIndex=-1 and pointer-events-none but keeps href; remove href yourself if the target is meaningless) | `false` |
|
|
25
|
-
| asChild | `boolean` (The child's own children become the label; TextLink clones the child and re-injects the label wrapped in its content/underline/icon spans) | `false` |
|
|
26
|
-
| leadingIcon | `ReactNode` | - |
|
|
27
|
-
| trailingIcon | `ReactNode` | - |
|
|
28
|
-
| underline | `boolean` (Renders a hairline span (data-slot=text-link-underline), not text-decoration; base forces no-underline, so use this prop, never the Tailwind underline class) | `false` |
|
|
29
|
-
|
|
30
|
-
Extends `React.ComponentProps<"a">`.
|
|
31
|
-
|
|
32
|
-
## Icons
|
|
33
|
-
|
|
34
|
-
Icons go through icon props - never as children next to text, and never with sizing classes (the component sizes icons per `size`): `TextLink` (`leadingIcon` / `trailingIcon`). Import icons from `@create-ui/assets/icons` (Remix `Ri*`).
|
|
35
|
-
|
|
36
|
-
## Examples
|
|
37
|
-
|
|
38
|
-
From `text-link-demo`:
|
|
39
|
-
|
|
40
|
-
```tsx
|
|
41
|
-
import { TextLink } from "@/components/ui/text-link"
|
|
42
|
-
|
|
43
|
-
export default function TextLinkDemo() {
|
|
44
|
-
return <TextLink href="#">Read the documentation</TextLink>
|
|
45
|
-
}
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
From `text-link-in-prose`:
|
|
49
|
-
|
|
50
|
-
```tsx
|
|
51
|
-
import { TextLink } from "@/components/ui/text-link"
|
|
52
|
-
|
|
53
|
-
export default function TextLinkInProse() {
|
|
54
|
-
return (
|
|
55
|
-
<p className="text-paragraph-md text-body max-w-prose">
|
|
56
|
-
Create UI ships components as source files you copy into your project.
|
|
57
|
-
Start with the{" "}
|
|
58
|
-
<TextLink href="#" underline>
|
|
59
|
-
installation guide
|
|
60
|
-
</TextLink>{" "}
|
|
61
|
-
to scaffold a new app, then browse the{" "}
|
|
62
|
-
<TextLink href="#">component reference</TextLink> to see every primitive
|
|
63
|
-
in one place.
|
|
64
|
-
</p>
|
|
65
|
-
)
|
|
66
|
-
}
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
More: `npx @create-ui/cli view text-link` or MCP `get_item_examples_from_registries` with "text-link-demo" / "text-link-example".
|
|
70
|
-
|
|
71
|
-
## When to use
|
|
72
|
-
Inline link inside body copy, list items, table cells, and helper text, where the control must read as text in the line, not as a button. Renders a native `<a>` by default, or slots a router link (`next/link` etc.) via `asChild`. Do not use it when the control needs a filled hit area (use `Button`, optionally `asChild` over an `<a>`), for menu rows (`DropdownMenuItem`), or for breadcrumb trails (`BreadcrumbItem`).
|
|
73
|
-
|
|
74
|
-
## Gotchas
|
|
75
|
-
- There is no `as` prop: the root is always `<a>` unless `asChild` swaps in the child element. For a non-navigation click action, slot a `<button>` via `asChild`.
|
|
76
|
-
- `asChild` is smarter than a plain shadcn Slot: icons and `underline` still work because TextLink extracts the child's children as the label and clones the child with its own internal spans. The child must be a single valid element:
|
|
77
|
-
```tsx
|
|
78
|
-
<TextLink asChild underline trailingIcon={<RiArrowRightSLine />}>
|
|
79
|
-
<Link href="/docs">Continue</Link>
|
|
80
|
-
</TextLink>
|
|
81
|
-
```
|
|
82
|
-
- The label span is `whitespace-nowrap`: a multi-word link mid-sentence never wraps and can overflow narrow prose containers; keep labels short or override on `[data-slot=text-link-content]`.
|
|
83
|
-
- Focus is an `outline-*` treatment (transparent at rest, colored on focus-visible) per the system-wide outline rule; do not add `ring-*` via className.
|
|
84
|
-
- The label span carries small per-size horizontal padding (`px-0.5` to `px-1.5`), so the link text never sits perfectly flush with adjacent prose.
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
<!-- GENERATED FILE - do not edit. Source: registry/ui/textarea.tsx. Regenerate with `pnpm skill:build`. Curated notes: apps/v4/scripts/skill-reference/notes/textarea.md -->
|
|
2
|
-
|
|
3
|
-
# textarea
|
|
4
|
-
|
|
5
|
-
Multi-line text input; size and state inherit from Field, resizable x/y/both with custom grip, loading spinner overlay
|
|
6
|
-
|
|
7
|
-
Install: `npx @create-ui/cli add textarea`
|
|
8
|
-
|
|
9
|
-
## Import
|
|
10
|
-
|
|
11
|
-
```tsx
|
|
12
|
-
import { Textarea } from "@/components/ui/textarea"
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
Also exported: `textareaVariants`
|
|
16
|
-
|
|
17
|
-
## Textarea props
|
|
18
|
-
|
|
19
|
-
| Prop | Type | Default |
|
|
20
|
-
| --- | --- | --- |
|
|
21
|
-
| size | `xs \| sm \| md` | `sm` |
|
|
22
|
-
| resizable | `x \| y \| both` (Use this prop, never resize-x/resize-y classes; base is resize-none and the prop hides the webkit grip and overlays the custom corner glyph.) | - |
|
|
23
|
-
| loading | `boolean` (Makes the textarea readOnly + aria-busy with pointer-events-none, NOT disabled; it stays in the tab order and its value still submits.) | - |
|
|
24
|
-
|
|
25
|
-
Extends `React.ComponentProps<"textarea">`.
|
|
26
|
-
|
|
27
|
-
## Examples
|
|
28
|
-
|
|
29
|
-
From `textarea-demo`:
|
|
30
|
-
|
|
31
|
-
```tsx
|
|
32
|
-
import { Textarea } from "@/components/ui/textarea"
|
|
33
|
-
|
|
34
|
-
export default function TextareaDemo() {
|
|
35
|
-
return <Textarea placeholder="Write something..." />
|
|
36
|
-
}
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
More: `npx @create-ui/cli view textarea` or MCP `get_item_examples_from_registries` with "textarea-demo" / "textarea-example".
|
|
40
|
-
|
|
41
|
-
## When to use
|
|
42
|
-
Multi-line free text: bios, messages, feedback, descriptions, comments. For single-line input use `Input`. Never place a raw `Textarea` inside an `InputGroup`; use `InputGroupTextarea` there, since the group manages size and state through its own context.
|
|
43
|
-
|
|
44
|
-
## Gotchas
|
|
45
|
-
- Field cascade: `size`, `loading`, and `disabled` resolve as explicit prop ?? Field context ?? default, so explicit props win. `invalid` is OR-combined instead: `<Field invalid>` alone flips the error styling, sets `aria-invalid`, and renders the warning icon, and `aria-invalid={false}` on the textarea cannot cancel it.
|
|
46
|
-
- The DOM shape changes with state: a `data-slot="textarea-wrapper"` div only exists when `resizable` is set or a status icon (loading/invalid) is showing; otherwise the bare `<textarea>` is returned. `className` always lands on the textarea itself, but parent-selector CSS can break across states.
|
|
47
|
-
- `loading` is not `disabled`: it sets `readOnly`, `aria-busy`, and `pointer-events-none`. If you need the field skipped on submit, set `disabled` too. When `loading` and invalid are both true, the spinner wins over the warning icon.
|
|
48
|
-
- Resize must go through the `resizable` prop. Adding `resize-y` via `className` shows the native browser grip with no design-system glyph; the prop hides the webkit resizer and grid-stacks the custom corner icon.
|
|
49
|
-
- The status icon (spinner / `RiErrorWarningLine`) renders bottom-LEFT inside the textarea and is `aria-hidden`; spinner size auto-pairs with the textarea size. Communicate the actual error text via `FieldHelper`, not the icon.
|
|
50
|
-
- Base height is `min-h-[132px]`, so small `rows` values have no visible effect; override height with a `min-h-*` class.
|