@moldable-ai/ui 0.2.29 → 0.2.31
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/catalog/component-catalog.d.ts +9 -2
- package/dist/catalog/component-catalog.d.ts.map +1 -1
- package/dist/catalog/component-catalog.js +11 -7
- package/dist/catalog/core-control-stories.d.ts.map +1 -1
- package/dist/catalog/core-control-stories.js +1 -1
- package/dist/catalog/core-foundation-stories.d.ts.map +1 -1
- package/dist/catalog/core-foundation-stories.js +5 -5
- package/dist/components/ui/app-frame.d.ts +20 -1
- package/dist/components/ui/app-frame.d.ts.map +1 -1
- package/dist/components/ui/app-frame.js +37 -7
- package/dist/components/ui/badge.d.ts +1 -1
- package/dist/components/ui/badge.js +1 -1
- package/dist/components/ui/button.d.ts +5 -3
- package/dist/components/ui/button.d.ts.map +1 -1
- package/dist/components/ui/button.js +39 -11
- package/dist/components/ui/card.d.ts +12 -2
- package/dist/components/ui/card.d.ts.map +1 -1
- package/dist/components/ui/card.js +3 -2
- package/dist/components/ui/checkbox.d.ts +4 -1
- package/dist/components/ui/checkbox.d.ts.map +1 -1
- package/dist/components/ui/checkbox.js +4 -4
- package/dist/components/ui/context-menu.js +6 -6
- package/dist/components/ui/dropdown-menu.js +6 -6
- package/dist/components/ui/icon-button.d.ts +1 -1
- package/dist/components/ui/icon-button.d.ts.map +1 -1
- package/dist/components/ui/icon-button.js +1 -0
- package/dist/components/ui/input.d.ts +6 -2
- package/dist/components/ui/input.d.ts.map +1 -1
- package/dist/components/ui/input.js +2 -2
- package/dist/components/ui/material.d.ts +8 -3
- package/dist/components/ui/material.d.ts.map +1 -1
- package/dist/components/ui/material.js +2 -2
- package/dist/components/ui/search-field.d.ts +3 -1
- package/dist/components/ui/search-field.d.ts.map +1 -1
- package/dist/components/ui/search-field.js +16 -6
- package/dist/components/ui/segmented-control.d.ts +3 -1
- package/dist/components/ui/segmented-control.d.ts.map +1 -1
- package/dist/components/ui/segmented-control.js +23 -17
- package/dist/components/ui/select.js +2 -2
- package/dist/components/ui/sidebar.d.ts +5 -3
- package/dist/components/ui/sidebar.d.ts.map +1 -1
- package/dist/components/ui/sidebar.js +53 -15
- package/dist/components/ui/status.d.ts +1 -1
- package/dist/components/ui/status.js +1 -1
- package/dist/components/ui/switch.d.ts +3 -1
- package/dist/components/ui/switch.d.ts.map +1 -1
- package/dist/components/ui/switch.js +3 -2
- package/dist/components/ui/toolbar-controls.d.ts +3 -1
- package/dist/components/ui/toolbar-controls.d.ts.map +1 -1
- package/dist/components/ui/toolbar-controls.js +14 -7
- package/dist/components/ui/toolbar.d.ts +5 -4
- package/dist/components/ui/toolbar.d.ts.map +1 -1
- package/dist/components/ui/toolbar.js +3 -3
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/lib/frame-lifecycle.d.ts +1 -0
- package/dist/lib/frame-lifecycle.d.ts.map +1 -1
- package/dist/lib/frame-lifecycle.js +7 -0
- package/dist/lib/theme.d.ts +39 -5
- package/dist/lib/theme.d.ts.map +1 -1
- package/dist/lib/theme.js +105 -17
- package/dist/tokens/contracts.d.ts +79 -0
- package/dist/tokens/contracts.d.ts.map +1 -0
- package/dist/tokens/contracts.js +57 -0
- package/dist/tokens/index.d.ts +2 -0
- package/dist/tokens/index.d.ts.map +1 -0
- package/dist/tokens/index.js +1 -0
- package/docs/README.md +2 -0
- package/docs/adaptive-materials.md +14 -9
- package/docs/design-tokens.md +10 -6
- package/docs/foundations.md +3 -3
- package/docs/macos-design-audit.md +144 -0
- package/docs/native-integration.md +4 -4
- package/docs/platform-architecture.md +189 -0
- package/docs/standalone-app-windows.md +37 -0
- package/docs/visual-regression.md +6 -8
- package/package.json +13 -1
- package/src/components/ui/accordion.md +46 -0
- package/src/components/ui/alert.md +12 -4
- package/src/components/ui/app-frame.md +8 -5
- package/src/components/ui/aspect-ratio.md +37 -0
- package/src/components/ui/avatar.md +48 -0
- package/src/components/ui/breadcrumb.md +52 -0
- package/src/components/ui/button-group.md +43 -0
- package/src/components/ui/button.md +20 -4
- package/src/components/ui/calendar.md +42 -0
- package/src/components/ui/card.md +43 -0
- package/src/components/ui/carousel.md +47 -0
- package/src/components/ui/chart.md +52 -0
- package/src/components/ui/checkbox.md +36 -0
- package/src/components/ui/collapsible.md +2 -3
- package/src/components/ui/color-well.md +14 -4
- package/src/components/ui/combobox.md +3 -3
- package/src/components/ui/confirm-dialog.md +5 -4
- package/src/components/ui/context-menu.md +3 -2
- package/src/components/ui/date-field.md +6 -1
- package/src/components/ui/date-picker.md +6 -3
- package/src/components/ui/dialog.md +14 -12
- package/src/components/ui/drawer.md +58 -0
- package/src/components/ui/error-boundary-view.md +1 -1
- package/src/components/ui/field.md +2 -1
- package/src/components/ui/form.md +71 -0
- package/src/components/ui/grid.md +4 -3
- package/src/components/ui/icon-button.md +4 -1
- package/src/components/ui/input-group.md +49 -0
- package/src/components/ui/input-otp.md +56 -0
- package/src/components/ui/input.md +40 -0
- package/src/components/ui/inspector.md +47 -7
- package/src/components/ui/item.md +5 -3
- package/src/components/ui/kbd.md +30 -0
- package/src/components/ui/label.md +29 -0
- package/src/components/ui/list.md +2 -2
- package/src/components/ui/material.md +25 -12
- package/src/components/ui/menu-items.md +60 -0
- package/src/components/ui/menubar.md +58 -0
- package/src/components/ui/message-scroller-primitive.md +70 -0
- package/src/components/ui/message-scroller.md +86 -0
- package/src/components/ui/navigation-button-group.md +4 -3
- package/src/components/ui/navigation-menu.md +52 -0
- package/src/components/ui/number-input.md +8 -0
- package/src/components/ui/pagination.md +51 -0
- package/src/components/ui/panel.md +6 -0
- package/src/components/ui/popover.md +10 -7
- package/src/components/ui/progress.md +31 -0
- package/src/components/ui/radio-group.md +36 -0
- package/src/components/ui/resizable.md +2 -1
- package/src/components/ui/scroll-area.md +3 -1
- package/src/components/ui/search-field.md +6 -1
- package/src/components/ui/segmented-control.md +6 -1
- package/src/components/ui/separator.md +35 -0
- package/src/components/ui/sidebar.md +20 -3
- package/src/components/ui/skeleton.md +36 -0
- package/src/components/ui/slider.md +58 -0
- package/src/components/ui/spinner.md +41 -0
- package/src/components/ui/split-view.md +8 -4
- package/src/components/ui/switch.md +44 -0
- package/src/components/ui/table.md +7 -7
- package/src/components/ui/tabs.md +3 -1
- package/src/components/ui/textarea.md +41 -0
- package/src/components/ui/toggle-group.md +2 -2
- package/src/components/ui/toggle.md +9 -9
- package/src/components/ui/toolbar-controls.md +17 -9
- package/src/components/ui/toolbar.md +6 -6
- package/src/styles/index.css +171 -117
- package/src/tokens/contracts.ts +131 -0
- package/src/tokens/index.css +6 -0
- package/src/tokens/index.ts +23 -0
- package/src/tokens/macos-26/README.md +37 -0
- package/src/tokens/macos-26/aliases.css +53 -0
- package/src/tokens/macos-26/compatibility.css +7 -0
- package/src/tokens/macos-26/index.css +3 -0
- package/src/tokens/macos-26/source/provenance.generated.json +28 -0
- package/src/tokens/macos-26/source/sidebar.generated.css +29 -0
- package/src/tokens/macos-26/source.css +7 -0
- package/src/tokens/macos-26/web-adaptations.json +25 -0
- package/src/tokens/macos-26/web-adaptations.md +15 -0
- package/src/tokens/macos-27/accessibility.css +11 -0
- package/src/tokens/macos-27/aliases.css +304 -0
- package/src/tokens/macos-27/compatibility.css +212 -0
- package/src/tokens/macos-27/index.css +15 -0
- package/src/tokens/macos-27/recipes.css +23 -0
- package/src/tokens/macos-27/source/chrome.generated.css +338 -0
- package/src/tokens/macos-27/source/colors.generated.css +140 -0
- package/src/tokens/macos-27/source/context.generated.css +18 -0
- package/src/tokens/macos-27/source/controls.generated.css +764 -0
- package/src/tokens/macos-27/source/effects.generated.css +68 -0
- package/src/tokens/macos-27/source/kit.generated.css +50 -0
- package/src/tokens/macos-27/source/overlays-status.generated.css +931 -0
- package/src/tokens/macos-27/source/paint-styles.generated.css +81 -0
- package/src/tokens/macos-27/source/provenance.generated.json +62 -0
- package/src/tokens/macos-27/source/sizes.generated.css +385 -0
- package/src/tokens/macos-27/source/source.generated.json +554 -0
- package/src/tokens/macos-27/source/text-styles.generated.css +116 -0
- package/src/tokens/macos-27/source.css +17 -0
- package/src/tokens/macos-27/web-adaptations.css +98 -0
- package/src/tokens/macos-27/web-adaptations.json +163 -0
- package/src/tokens/macos-27/web-adaptations.md +117 -0
- package/src/tokens/moldable/brand.css +48 -0
- package/src/tokens/moldable/index.css +1 -0
- package/src/tokens/platform-contract.test.ts +290 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Accordion
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
`Accordion` organizes related sections into independently expandable items. Use
|
|
6
|
+
it when several peer sections should share one disclosure pattern; use
|
|
7
|
+
`Collapsible` for a single disclosed region.
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
import {
|
|
13
|
+
Accordion,
|
|
14
|
+
AccordionContent,
|
|
15
|
+
AccordionItem,
|
|
16
|
+
AccordionTrigger,
|
|
17
|
+
} from '@moldable-ai/ui'
|
|
18
|
+
|
|
19
|
+
;<Accordion type="single" collapsible>
|
|
20
|
+
<AccordionItem value="storage">
|
|
21
|
+
<AccordionTrigger>Storage</AccordionTrigger>
|
|
22
|
+
<AccordionContent>
|
|
23
|
+
Files remain in the current Moldable workspace.
|
|
24
|
+
</AccordionContent>
|
|
25
|
+
</AccordionItem>
|
|
26
|
+
</Accordion>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## API
|
|
30
|
+
|
|
31
|
+
- `Accordion` exposes the Radix root props, including `type="single"` or
|
|
32
|
+
`type="multiple"`, controlled state, and orientation.
|
|
33
|
+
- `AccordionItem` requires the Radix item `value` and adds a dividing border.
|
|
34
|
+
- `AccordionTrigger` renders a full-width trigger with a state-aware chevron.
|
|
35
|
+
- `AccordionContent` provides the open and close animation. Its `className`
|
|
36
|
+
styles the inner content wrapper; remaining props apply to the Radix content
|
|
37
|
+
element.
|
|
38
|
+
- Radix manages trigger relationships, expanded state, and keyboard behavior.
|
|
39
|
+
|
|
40
|
+
## Quality bar
|
|
41
|
+
|
|
42
|
+
- Keep trigger labels short and make each section understandable when closed.
|
|
43
|
+
- Choose single or multiple expansion based on the task, not visual density.
|
|
44
|
+
- Do not put another interactive control inside a trigger.
|
|
45
|
+
- Do not hide required validation errors or the only primary action in a closed
|
|
46
|
+
item.
|
|
@@ -11,8 +11,15 @@ Use `AlertDialog` when the user must confirm an action. Use `Empty` for the norm
|
|
|
11
11
|
## Usage patterns
|
|
12
12
|
|
|
13
13
|
```tsx
|
|
14
|
-
import { CircleAlert } from 'lucide-react'
|
|
15
|
-
import {
|
|
14
|
+
import { CircleAlert, InfoIcon } from 'lucide-react'
|
|
15
|
+
import {
|
|
16
|
+
Alert,
|
|
17
|
+
AlertActions,
|
|
18
|
+
AlertDescription,
|
|
19
|
+
AlertDismiss,
|
|
20
|
+
AlertTitle,
|
|
21
|
+
Button,
|
|
22
|
+
} from '@moldable-ai/ui'
|
|
16
23
|
|
|
17
24
|
;<Alert tone="danger">
|
|
18
25
|
<CircleAlert />
|
|
@@ -40,8 +47,9 @@ owned by the caller:
|
|
|
40
47
|
|
|
41
48
|
## API summary
|
|
42
49
|
|
|
43
|
-
- `tone`: `neutral`, `info`, `success`, `warning`, or `danger
|
|
44
|
-
|
|
50
|
+
- `tone`: `neutral`, `info`, `success`, `warning`, or `danger`; defaults to
|
|
51
|
+
`neutral`.
|
|
52
|
+
- `density`: `compact` or `default`; defaults to `default`.
|
|
45
53
|
- Neutral through warning tones default to `role="status"`; danger defaults to
|
|
46
54
|
`role="alert"`. The native `role` prop can override that choice.
|
|
47
55
|
- `variant="default"` and `variant="destructive"` remain compatibility aliases.
|
|
@@ -4,7 +4,7 @@ The top-level shell for an app that can run in its own window or inside a host
|
|
|
4
4
|
surface.
|
|
5
5
|
|
|
6
6
|
```tsx
|
|
7
|
-
<AppFrame>
|
|
7
|
+
<AppFrame nativeMaterial={{ background: true, sidebar: true }}>
|
|
8
8
|
<Toolbar position="top">
|
|
9
9
|
<ToolbarTitle>Today</ToolbarTitle>
|
|
10
10
|
<ToolbarActions>{/* compact actions */}</ToolbarActions>
|
|
@@ -29,8 +29,11 @@ surface.
|
|
|
29
29
|
- `AppFrameContent` applies the shared chat-safe padding by default. The value is
|
|
30
30
|
zero in a standalone window and is updated by the embedded host lifecycle.
|
|
31
31
|
- Use `mode="embedded"` or `mode="window"` only for deterministic previews and
|
|
32
|
-
tests. Runtime apps should normally use `mode="auto"`;
|
|
33
|
-
|
|
34
|
-
app iframe.
|
|
32
|
+
tests. Runtime apps should normally use `mode="auto"`; the host may set
|
|
33
|
+
`data-moldable-display-mode` when a window still uses an app iframe.
|
|
35
34
|
- Material samples only renderer content. Native behind-window material remains
|
|
36
|
-
host-owned.
|
|
35
|
+
host-owned. `nativeMaterial={{ background: true }}` reveals the host's
|
|
36
|
+
frosted full-window material, while `nativeMaterial={{ sidebar: true }}`
|
|
37
|
+
allows a compatible sidebar to declare its region. Declare each matching
|
|
38
|
+
`window.nativeMaterial` option in `moldable.json`. Every option defaults off,
|
|
39
|
+
and portable semantic fills remain in unsupported environments.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# AspectRatio
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
`AspectRatio` reserves a stable rectangular area for media whose width and
|
|
6
|
+
height should scale together. Use it for previews, thumbnails, video, and other
|
|
7
|
+
content where layout shift would be distracting.
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
import { AspectRatio } from '@moldable-ai/ui'
|
|
13
|
+
|
|
14
|
+
;<AspectRatio ratio={16 / 9} className="rounded-control overflow-hidden">
|
|
15
|
+
<img
|
|
16
|
+
src={previewUrl}
|
|
17
|
+
alt="Workspace preview"
|
|
18
|
+
className="size-full object-cover"
|
|
19
|
+
/>
|
|
20
|
+
</AspectRatio>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## API
|
|
24
|
+
|
|
25
|
+
- Accepts the Radix aspect-ratio root props.
|
|
26
|
+
- `ratio` is the desired width divided by height, such as `16 / 9` or `1`.
|
|
27
|
+
- The component adds `data-slot="aspect-ratio"` and otherwise leaves content
|
|
28
|
+
rendering to the caller.
|
|
29
|
+
|
|
30
|
+
## Quality bar
|
|
31
|
+
|
|
32
|
+
- Set an explicit ratio that matches the expected media.
|
|
33
|
+
- Give images useful alternative text, or an empty `alt` when decorative.
|
|
34
|
+
- Choose `object-cover` or `object-contain` deliberately; the component does
|
|
35
|
+
not crop or fit its child.
|
|
36
|
+
- Do not use an aspect ratio wrapper when the content must determine its own
|
|
37
|
+
height.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Avatar
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
`Avatar` presents a person, account, or other recognizable identity in a
|
|
6
|
+
compact circular frame. It includes image, fallback, badge, and overlapping
|
|
7
|
+
group primitives.
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
import {
|
|
13
|
+
Avatar,
|
|
14
|
+
AvatarFallback,
|
|
15
|
+
AvatarGroup,
|
|
16
|
+
AvatarGroupCount,
|
|
17
|
+
AvatarImage,
|
|
18
|
+
} from '@moldable-ai/ui'
|
|
19
|
+
|
|
20
|
+
;<AvatarGroup>
|
|
21
|
+
<Avatar size="sm">
|
|
22
|
+
<AvatarImage src={owner.photoUrl} alt={owner.name} />
|
|
23
|
+
<AvatarFallback>RM</AvatarFallback>
|
|
24
|
+
</Avatar>
|
|
25
|
+
<AvatarGroupCount>+3</AvatarGroupCount>
|
|
26
|
+
</AvatarGroup>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## API
|
|
30
|
+
|
|
31
|
+
- `Avatar`: Radix root props plus `size="sm"`, `"default"`, or `"lg"`;
|
|
32
|
+
defaults to `default`.
|
|
33
|
+
- `AvatarImage`: Radix image props.
|
|
34
|
+
- `AvatarFallback`: Radix fallback props, including delayed fallback behavior.
|
|
35
|
+
- `AvatarBadge`: native `span` props for a compact corner marker.
|
|
36
|
+
- `AvatarGroup` and `AvatarGroupCount`: native `div` props for an overlapping
|
|
37
|
+
group and its remaining count.
|
|
38
|
+
|
|
39
|
+
## Quality bar
|
|
40
|
+
|
|
41
|
+
- Provide a stable fallback, usually initials or a short recognizable mark.
|
|
42
|
+
- Use meaningful image `alt` text, or empty `alt` when adjacent text already
|
|
43
|
+
names the same identity.
|
|
44
|
+
- Keep one size across an avatar group.
|
|
45
|
+
- Give a badge additional accessible context when its color or icon conveys
|
|
46
|
+
status.
|
|
47
|
+
- Do not use an avatar as an unlabeled action; wrap it in the appropriate
|
|
48
|
+
button or link when interactive.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Breadcrumb
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
`Breadcrumb` shows the current location within a hierarchy and lets users
|
|
6
|
+
return to ancestor levels. Use it for nested app content, not as a substitute
|
|
7
|
+
for browser history or primary navigation.
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
import {
|
|
13
|
+
Breadcrumb,
|
|
14
|
+
BreadcrumbItem,
|
|
15
|
+
BreadcrumbLink,
|
|
16
|
+
BreadcrumbList,
|
|
17
|
+
BreadcrumbPage,
|
|
18
|
+
BreadcrumbSeparator,
|
|
19
|
+
} from '@moldable-ai/ui'
|
|
20
|
+
|
|
21
|
+
;<Breadcrumb>
|
|
22
|
+
<BreadcrumbList>
|
|
23
|
+
<BreadcrumbItem>
|
|
24
|
+
<BreadcrumbLink href="/projects">Projects</BreadcrumbLink>
|
|
25
|
+
</BreadcrumbItem>
|
|
26
|
+
<BreadcrumbSeparator />
|
|
27
|
+
<BreadcrumbItem>
|
|
28
|
+
<BreadcrumbPage>Launch plan</BreadcrumbPage>
|
|
29
|
+
</BreadcrumbItem>
|
|
30
|
+
</BreadcrumbList>
|
|
31
|
+
</Breadcrumb>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## API
|
|
35
|
+
|
|
36
|
+
- `Breadcrumb` renders a `nav` with `aria-label="breadcrumb"`.
|
|
37
|
+
- `BreadcrumbList` and `BreadcrumbItem` render an `ol` and `li`.
|
|
38
|
+
- `BreadcrumbLink` renders an anchor; `asChild` applies its behavior to a
|
|
39
|
+
caller-provided link component.
|
|
40
|
+
- `BreadcrumbPage` marks the current page with `aria-current="page"` and
|
|
41
|
+
disabled link semantics.
|
|
42
|
+
- `BreadcrumbSeparator` is hidden from assistive technology and uses a right
|
|
43
|
+
chevron unless children are provided.
|
|
44
|
+
- `BreadcrumbEllipsis` renders a presentation-only overflow marker.
|
|
45
|
+
|
|
46
|
+
## Quality bar
|
|
47
|
+
|
|
48
|
+
- End with exactly one current page and do not make it navigable.
|
|
49
|
+
- Represent omitted middle levels with `BreadcrumbEllipsis`; keep the root and
|
|
50
|
+
current location visible.
|
|
51
|
+
- Keep labels concise and preserve their hierarchy on narrow layouts.
|
|
52
|
+
- Do not add slash characters in text; use `BreadcrumbSeparator`.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# ButtonGroup
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
`ButtonGroup` joins closely related controls into one compact visual group. Use
|
|
6
|
+
it for adjacent actions or a control assembled from buttons, inputs, and select
|
|
7
|
+
triggers.
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
import { Button, ButtonGroup, ButtonGroupSeparator } from '@moldable-ai/ui'
|
|
13
|
+
|
|
14
|
+
;<ButtonGroup aria-label="Text alignment">
|
|
15
|
+
<Button variant="outline">Left</Button>
|
|
16
|
+
<Button variant="outline">Center</Button>
|
|
17
|
+
<Button variant="outline">Right</Button>
|
|
18
|
+
<ButtonGroupSeparator />
|
|
19
|
+
<Button variant="outline">Justify</Button>
|
|
20
|
+
</ButtonGroup>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## API
|
|
24
|
+
|
|
25
|
+
- `ButtonGroup` accepts native `div` props and
|
|
26
|
+
`orientation="horizontal" | "vertical"`; visual orientation defaults to
|
|
27
|
+
`horizontal`. It renders `role="group"`.
|
|
28
|
+
- Direct children share adjoining corners and borders. Focused children rise
|
|
29
|
+
above neighboring borders.
|
|
30
|
+
- `ButtonGroupText` accepts native `div` props and `asChild`; use it for
|
|
31
|
+
non-interactive text or an icon beside the controls.
|
|
32
|
+
- `ButtonGroupSeparator` accepts `Separator` props and defaults to
|
|
33
|
+
`orientation="vertical"`. Set it to `horizontal` inside a vertical group.
|
|
34
|
+
- `buttonGroupVariants` is exported for composing the group layout.
|
|
35
|
+
|
|
36
|
+
## Quality bar
|
|
37
|
+
|
|
38
|
+
- Add an accessible label when the group’s purpose is not already named.
|
|
39
|
+
- Keep every action independently focusable and labeled.
|
|
40
|
+
- Use semantic button variants and shared controls so theme and density tokens
|
|
41
|
+
remain consistent.
|
|
42
|
+
- Do not group unrelated actions merely to save space.
|
|
43
|
+
- Do not use `ButtonGroupText` for an action.
|
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
## Purpose
|
|
4
4
|
|
|
5
|
-
`Button` starts an immediate action or, with `asChild`, gives button styling
|
|
5
|
+
`Button` starts an immediate action or, with `asChild`, gives button styling to
|
|
6
|
+
another interactive element. Use it for commands such as save, run, refresh,
|
|
7
|
+
connect, archive, and open.
|
|
6
8
|
|
|
7
9
|
Use a link for navigation. Use `Toggle` when the control represents an on/off view state, and `ToggleGroup` when the user chooses among a small set of modes.
|
|
8
10
|
|
|
@@ -31,7 +33,13 @@ import { RefreshCw } from 'lucide-react'
|
|
|
31
33
|
</Button>
|
|
32
34
|
```
|
|
33
35
|
|
|
34
|
-
Keep toolbar actions compact (`xs`, `sm`, `icon-xs`, or
|
|
36
|
+
Keep ordinary pane-toolbar actions compact (`xs`, `sm`, `icon-xs`, or
|
|
37
|
+
`icon-sm`). In an app-owned native titlebar, use the 36px controls provided by
|
|
38
|
+
`ToolbarButton` and `ToolbarIconButton`. Reserve `default` or `lg` for the
|
|
39
|
+
primary action in a form, setup state, or focused control dock. Set `loading`
|
|
40
|
+
while that button's async action is in flight. The button blocks pointer and
|
|
41
|
+
keyboard activation, exposes `aria-busy`, keeps its accessible label mounted,
|
|
42
|
+
and centers a width-stable spinner.
|
|
35
43
|
|
|
36
44
|
Use `loading` for the action that started the request. Disable the whole form only when editing during the request would be unsafe or would invalidate the submitted payload; do not disable unrelated controls merely to communicate progress.
|
|
37
45
|
|
|
@@ -45,8 +53,16 @@ For links that should look like buttons:
|
|
|
45
53
|
|
|
46
54
|
## API summary
|
|
47
55
|
|
|
48
|
-
- `variant`: `default`, `
|
|
49
|
-
|
|
56
|
+
- `variant`: `default`, `prominent`, `bordered`, `borderless`, `tinted`,
|
|
57
|
+
`toolbar`, `destructive`, `destructive-tinted`, `outline`, `secondary`,
|
|
58
|
+
`ghost`, or `link`. Defaults to `default`; `default` and `prominent` share
|
|
59
|
+
the prominent recipe. Prefer the toolbar-control wrappers instead of
|
|
60
|
+
applying `toolbar` directly.
|
|
61
|
+
- `size`: `default`, `xs`, `sm`, `lg`, `xl`, `mini`, `small`, `medium`,
|
|
62
|
+
`large`, `icon`, `icon-xs`, `icon-sm`, `icon-lg`, or `icon-xl`. Defaults to
|
|
63
|
+
`default`.
|
|
64
|
+
- `controlSize`: overrides the platform control-size token resolved from
|
|
65
|
+
`size`; accepts `mini`, `small`, `medium`, `large`, or `xl`.
|
|
50
66
|
- `asChild`: renders a Radix `Slot` so the child owns the element and semantics.
|
|
51
67
|
- `loading`: blocks activation, applies disabled behavior and `aria-busy`, and overlays the shared `Spinner` without unmounting or resizing the label. Defaults to `false`.
|
|
52
68
|
- Accepts native button props, including `type`, `disabled`, `aria-*`, and event handlers.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Calendar
|
|
2
|
+
|
|
3
|
+
An always-visible `react-day-picker` calendar for single dates, ranges,
|
|
4
|
+
multiple dates, and custom month layouts. Use `DatePicker` when the calendar
|
|
5
|
+
should open from a compact date-only field.
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { Calendar } from '@moldable-ai/ui'
|
|
9
|
+
|
|
10
|
+
;<Calendar
|
|
11
|
+
aria-label="Choose a due date"
|
|
12
|
+
mode="single"
|
|
13
|
+
selected={date}
|
|
14
|
+
onSelect={setDate}
|
|
15
|
+
disabled={{ before: new Date() }}
|
|
16
|
+
/>
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## API
|
|
20
|
+
|
|
21
|
+
- Accepts the current `DayPicker` props, including `mode`, `selected`,
|
|
22
|
+
`onSelect`, `month`, `locale`, `disabled`, and `showWeekNumber`.
|
|
23
|
+
- `showOutsideDays` defaults to `true`.
|
|
24
|
+
- `captionLayout` defaults to `label`.
|
|
25
|
+
- `buttonVariant` sets the shared `Button` variant used by previous and next
|
|
26
|
+
month controls; it defaults to `ghost`.
|
|
27
|
+
- `formatters` and `components` extend or replace the wrapper defaults. The
|
|
28
|
+
default month-dropdown formatter uses abbreviated month names.
|
|
29
|
+
- `className` styles the root. Entries in `classNames` replace the
|
|
30
|
+
corresponding wrapper class entry.
|
|
31
|
+
- `CalendarDayButton` is exported for advanced `DayPicker` composition; the
|
|
32
|
+
built-in calendar already installs it.
|
|
33
|
+
|
|
34
|
+
## Keyboard and quality
|
|
35
|
+
|
|
36
|
+
Day buttons use native button activation. Arrow keys move by day or week;
|
|
37
|
+
Shift+Left/Right moves by month, Shift+Up/Down by year, Page Up/Down by month,
|
|
38
|
+
Shift+Page Up/Down by year, and Home/End to the week boundary.
|
|
39
|
+
|
|
40
|
+
Provide a visible label or accessible name, pass the intended locale, and keep
|
|
41
|
+
disabled dates explainable outside the grid. Store a date-only selection
|
|
42
|
+
without converting it through UTC unless the domain is truly time-based.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Card
|
|
2
|
+
|
|
3
|
+
`Card` groups related content on one bounded surface. Its optional anatomy
|
|
4
|
+
keeps a title, description, trailing action, content, and footer aligned.
|
|
5
|
+
|
|
6
|
+
```tsx
|
|
7
|
+
import {
|
|
8
|
+
Card,
|
|
9
|
+
CardAction,
|
|
10
|
+
CardContent,
|
|
11
|
+
CardDescription,
|
|
12
|
+
CardHeader,
|
|
13
|
+
CardTitle,
|
|
14
|
+
} from '@moldable-ai/ui'
|
|
15
|
+
|
|
16
|
+
;<Card surface="raised">
|
|
17
|
+
<CardHeader>
|
|
18
|
+
<CardTitle>Project brief</CardTitle>
|
|
19
|
+
<CardDescription>Updated five minutes ago</CardDescription>
|
|
20
|
+
<CardAction>{/* compact action */}</CardAction>
|
|
21
|
+
</CardHeader>
|
|
22
|
+
<CardContent>{/* related content */}</CardContent>
|
|
23
|
+
</Card>
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## API
|
|
27
|
+
|
|
28
|
+
- `Card` accepts native `div` props and `surface`: `default`, `raised`,
|
|
29
|
+
`recessed`, or `plain`. The default is `default`.
|
|
30
|
+
- `default` uses the card fill, border, and shadow; `raised` uses the raised
|
|
31
|
+
surface; `recessed` uses the inset surface; `plain` provides structure
|
|
32
|
+
without chrome.
|
|
33
|
+
- `CardHeader`, `CardTitle`, `CardDescription`, `CardAction`, `CardContent`,
|
|
34
|
+
and `CardFooter` accept native `div` props.
|
|
35
|
+
- `CardProps` and `CardSurface` are exported.
|
|
36
|
+
- Adding `border-b` to the header or `border-t` to the footer also enables
|
|
37
|
+
their matching separator spacing.
|
|
38
|
+
|
|
39
|
+
Cards do not add region, heading, or button semantics. Use a real heading
|
|
40
|
+
inside `CardTitle` when the title participates in the document outline, and
|
|
41
|
+
keep actions as separate buttons or links. Do not make a whole card clickable
|
|
42
|
+
by attaching button behavior to its `div`; use an explicit interactive element
|
|
43
|
+
with a visible focus state.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Carousel
|
|
2
|
+
|
|
3
|
+
An Embla-backed sequence of peer slides with optional previous and next
|
|
4
|
+
controls.
|
|
5
|
+
|
|
6
|
+
```tsx
|
|
7
|
+
import {
|
|
8
|
+
Carousel,
|
|
9
|
+
CarouselContent,
|
|
10
|
+
CarouselItem,
|
|
11
|
+
CarouselNext,
|
|
12
|
+
CarouselPrevious,
|
|
13
|
+
} from '@moldable-ai/ui'
|
|
14
|
+
|
|
15
|
+
;<Carousel aria-label="Recent projects" className="mx-auto w-full max-w-lg">
|
|
16
|
+
<CarouselContent>
|
|
17
|
+
{projects.map((project) => (
|
|
18
|
+
<CarouselItem key={project.id}>{project.name}</CarouselItem>
|
|
19
|
+
))}
|
|
20
|
+
</CarouselContent>
|
|
21
|
+
<CarouselPrevious />
|
|
22
|
+
<CarouselNext />
|
|
23
|
+
</Carousel>
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## API
|
|
27
|
+
|
|
28
|
+
- `Carousel` accepts native `div` props plus `orientation`, `opts`, `plugins`,
|
|
29
|
+
and `setApi`. `orientation` defaults to `horizontal` and determines Embla's
|
|
30
|
+
axis, overriding `opts.axis`.
|
|
31
|
+
- `setApi` receives the initialized `CarouselApi`, which is also exported.
|
|
32
|
+
- `CarouselContent` owns the clipped viewport and flex track.
|
|
33
|
+
- `CarouselItem` is one full-basis slide by default. Override its basis through
|
|
34
|
+
`className` to show multiple slides.
|
|
35
|
+
- `CarouselPrevious` and `CarouselNext` accept shared `Button` props. They
|
|
36
|
+
default to `variant="outline"` and `size="icon"` and disable themselves at
|
|
37
|
+
their respective scroll boundary.
|
|
38
|
+
|
|
39
|
+
The root exposes carousel region semantics and each item exposes slide group
|
|
40
|
+
semantics; provide the root with `aria-label` or `aria-labelledby`. Left and
|
|
41
|
+
Right Arrow scroll from anywhere inside the root in both orientations. Up and
|
|
42
|
+
Down Arrow handling is not implemented, so prefer a horizontal carousel when
|
|
43
|
+
keyboard direction must match its visual axis.
|
|
44
|
+
|
|
45
|
+
Keep slide order stable, make important content available without hover, and
|
|
46
|
+
avoid placing text-editing controls inside the carousel because captured
|
|
47
|
+
Left/Right Arrow keys scroll the sequence.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Chart
|
|
2
|
+
|
|
3
|
+
Theme-aware wrappers for Recharts. `ChartContainer` supplies responsive sizing,
|
|
4
|
+
semantic chart styling, and config-driven labels, icons, and CSS color
|
|
5
|
+
variables.
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import {
|
|
9
|
+
ChartContainer,
|
|
10
|
+
ChartTooltip,
|
|
11
|
+
ChartTooltipContent,
|
|
12
|
+
type ChartConfig,
|
|
13
|
+
} from '@moldable-ai/ui'
|
|
14
|
+
import { Bar, BarChart, XAxis } from 'recharts'
|
|
15
|
+
|
|
16
|
+
const config = {
|
|
17
|
+
completed: { label: 'Completed', color: 'var(--chart-1)' },
|
|
18
|
+
} satisfies ChartConfig
|
|
19
|
+
|
|
20
|
+
<ChartContainer config={config} className="h-64 w-full">
|
|
21
|
+
<BarChart accessibilityLayer data={data}>
|
|
22
|
+
<XAxis dataKey="day" />
|
|
23
|
+
<ChartTooltip content={<ChartTooltipContent />} />
|
|
24
|
+
<Bar dataKey="completed" fill="var(--color-completed)" />
|
|
25
|
+
</BarChart>
|
|
26
|
+
</ChartContainer>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## API
|
|
30
|
+
|
|
31
|
+
- `ChartConfig` maps each series key to an optional `label` and `icon`, plus
|
|
32
|
+
either one `color` or both `theme.light` and `theme.dark` colors.
|
|
33
|
+
- `ChartContainer` accepts native `div` props, required `config`, one Recharts
|
|
34
|
+
chart child, and an optional chart-scoping `id`. That `id` seeds the
|
|
35
|
+
generated `data-chart` value; it is not forwarded as the element's HTML
|
|
36
|
+
`id`. The container wraps its child in `ResponsiveContainer`, so give it a
|
|
37
|
+
definite width and height.
|
|
38
|
+
- Configured colors become `--color-{series}` variables scoped to that chart.
|
|
39
|
+
- `ChartTooltip` and `ChartLegend` are the Recharts primitives.
|
|
40
|
+
- `ChartTooltipContent` supports `indicator="dot" | "line" | "dashed"`,
|
|
41
|
+
`hideLabel`, `hideIndicator`, `nameKey`, and `labelKey`. It consumes the
|
|
42
|
+
Recharts `active`, `payload`, `label`, `labelFormatter`, `formatter`, and
|
|
43
|
+
`color` inputs supplied by `ChartTooltip`.
|
|
44
|
+
- `ChartLegendContent` supports `hideIcon`, `nameKey`, `payload`, and
|
|
45
|
+
`verticalAlign`.
|
|
46
|
+
- `ChartStyle` is exported for advanced composition; `ChartContainer` already
|
|
47
|
+
renders it.
|
|
48
|
+
|
|
49
|
+
Enable Recharts' `accessibilityLayer` on the chart primitive. Use literal
|
|
50
|
+
series labels, semantic color variables, and another cue when color carries
|
|
51
|
+
meaning. For charts whose exact values matter, provide a nearby textual
|
|
52
|
+
summary or table rather than relying on a pointer tooltip.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Checkbox
|
|
2
|
+
|
|
3
|
+
A binary or mixed-state form control built on Radix Checkbox.
|
|
4
|
+
|
|
5
|
+
```tsx
|
|
6
|
+
import { Checkbox } from '@moldable-ai/ui'
|
|
7
|
+
|
|
8
|
+
;<label className="flex items-center gap-2">
|
|
9
|
+
<Checkbox
|
|
10
|
+
checked={enabled}
|
|
11
|
+
onCheckedChange={(checked) => setEnabled(checked === true)}
|
|
12
|
+
/>
|
|
13
|
+
Enable notifications
|
|
14
|
+
</label>
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## API and behavior
|
|
18
|
+
|
|
19
|
+
- Accepts Radix Checkbox root props, including controlled `checked` and
|
|
20
|
+
`onCheckedChange`, uncontrolled `defaultChecked`, `disabled`, `required`,
|
|
21
|
+
`name`, `value`, and `form`.
|
|
22
|
+
- `checked` and `defaultChecked` support `true`, `false`, or
|
|
23
|
+
`'indeterminate'`. Activating an indeterminate checkbox moves it to checked.
|
|
24
|
+
- `controlSize` is optional and accepts `mini`, `small`, `medium`, `large`, or
|
|
25
|
+
`xl`; when omitted, theme defaults determine its dimensions.
|
|
26
|
+
- The check and indeterminate dash indicators are included.
|
|
27
|
+
|
|
28
|
+
Associate every checkbox with visible label text through a wrapping `label` or
|
|
29
|
+
matching `htmlFor` and `id`. Space toggles the focused control; Enter is
|
|
30
|
+
intentionally prevented. Radix exposes the mixed value as
|
|
31
|
+
`aria-checked="mixed"` and preserves native form participation.
|
|
32
|
+
|
|
33
|
+
Use a checkbox for an independently selectable choice. Use `RadioGroup` for
|
|
34
|
+
one choice from a set and `Switch` for a settings-style state that takes effect
|
|
35
|
+
immediately. Do not rely on the checkmark or accent color as the only
|
|
36
|
+
explanation of the choice.
|
|
@@ -41,9 +41,8 @@ Radix. Space and Enter toggle it. The chevron is decorative.
|
|
|
41
41
|
|
|
42
42
|
## Motion
|
|
43
43
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
the transition.
|
|
44
|
+
The section content animates by default. Set `motion="none"` when movement
|
|
45
|
+
would distract or when a parent owns the transition.
|
|
47
46
|
|
|
48
47
|
## Don't
|
|
49
48
|
|
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
# ColorWell
|
|
2
2
|
|
|
3
|
-
Compact color selection or read-only swatch.
|
|
3
|
+
Compact native color selection or a read-only swatch.
|
|
4
4
|
|
|
5
5
|
```tsx
|
|
6
6
|
<ColorWell aria-label="Project color" value={color} onValueChange={setColor} />
|
|
7
7
|
```
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
## API
|
|
10
|
+
|
|
11
|
+
- `value` accepts a native color-input value (normally `#rrggbb`) or `null`; an
|
|
12
|
+
empty value displays a checkerboard swatch.
|
|
13
|
+
- `onValueChange` receives the native color input value.
|
|
14
|
+
- `size` is `sm`, `default`, or `lg` and defaults to `default`.
|
|
15
|
+
- `readOnly` defaults to `false`. When true, the component renders a
|
|
16
|
+
non-interactive image role instead of an input.
|
|
17
|
+
- The accessible label defaults to “Choose color”; provide a specific label in
|
|
18
|
+
app UI.
|
|
19
|
+
|
|
20
|
+
The interactive form uses the browser's native color input. Never make color
|
|
21
|
+
the only representation of a status or category.
|
|
@@ -4,9 +4,9 @@ Searchable single- or multi-value selection for longer option sets.
|
|
|
4
4
|
|
|
5
5
|
## When to use
|
|
6
6
|
|
|
7
|
-
Use `Combobox` when users need to filter
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
Use `Combobox` when users need to filter a longer option set or manage multiple
|
|
8
|
+
selections. Use `Select` for a short fixed list, `Command` for actions, and
|
|
9
|
+
`Input` for unconstrained text.
|
|
10
10
|
|
|
11
11
|
## Anatomy
|
|
12
12
|
|
|
@@ -71,10 +71,11 @@ colors or custom dialog elevation.
|
|
|
71
71
|
## Keyboard and accessibility
|
|
72
72
|
|
|
73
73
|
The component inherits alert-dialog semantics and focus containment. The
|
|
74
|
-
dialog content receives initial focus
|
|
75
|
-
action
|
|
76
|
-
|
|
77
|
-
|
|
74
|
+
dialog content receives initial focus. Command+Enter activates the confirm
|
|
75
|
+
action on macOS and iOS-family runtimes; Control+Enter does so elsewhere.
|
|
76
|
+
Plain Enter keeps the focused control's native behavior, and pending state
|
|
77
|
+
prevents dismissal. Write a specific title and describe the consequence, not
|
|
78
|
+
merely “Are you sure?”. Error copy is announced with `role="alert"`.
|
|
78
79
|
|
|
79
80
|
## Do
|
|
80
81
|
|
|
@@ -119,10 +119,11 @@ command palette as well as the context menu.
|
|
|
119
119
|
|
|
120
120
|
## Platform behavior
|
|
121
121
|
|
|
122
|
-
With `items`, a
|
|
122
|
+
With `items`, a `contextmenu` event such as a secondary click opens the
|
|
123
123
|
host-native menu when `nativeMenu` is advertised. The pointer position is its
|
|
124
124
|
anchor, `selectedId` is delivered to `onSelectItem`, and dismissal is a no-op.
|
|
125
|
-
No portable menu is rendered while that native request is open.
|
|
125
|
+
No portable menu is rendered while that native request is open. Radix's
|
|
126
|
+
touch/pen long press opens the portable menu directly.
|
|
126
127
|
|
|
127
128
|
When the service is not advertised, including web and iOS, the same items
|
|
128
129
|
automatically render through the existing Radix anatomy. If advertised
|
|
@@ -29,4 +29,9 @@ Values use the native timezone-free `YYYY-MM-DD` form. Use `value`/`onValueChang
|
|
|
29
29
|
- Use a calendar popover only for workflows that require richer range, availability, or event selection.
|
|
30
30
|
- Do not replace the native picker to imitate a desktop control.
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
`DateField` itself is renderer-owned and does not call the host. A call site
|
|
33
|
+
that deliberately prefers the host picker can use `useHostDateTimePicker()` or
|
|
34
|
+
`pickDateTimeWithHost('date', ...)`, then keep `DateField` as its portable
|
|
35
|
+
fallback. A `status: 'fallback'` result does not open renderer UI for the
|
|
36
|
+
caller. See
|
|
37
|
+
[`host-date-time-picker.md`](../../lib/host-date-time-picker.md).
|