@moldable-ai/ui 0.2.26 → 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 +15 -3
- 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 -10
- 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/date-field.d.ts +1 -1
- 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/index.d.ts +1 -0
- package/dist/components/ui/index.d.ts.map +1 -1
- package/dist/components/ui/index.js +1 -0
- package/dist/components/ui/input-group.d.ts +2 -2
- 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 +49 -0
- package/dist/components/ui/toolbar-controls.d.ts.map +1 -0
- package/dist/components/ui/toolbar-controls.js +47 -0
- 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 +83 -0
- package/src/components/ui/toolbar.md +12 -6
- package/src/styles/index.css +199 -107
- 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,31 @@
|
|
|
1
|
+
# Progress
|
|
2
|
+
|
|
3
|
+
`Progress` shows determinate completion for an operation. The current visual
|
|
4
|
+
track expects `value` to be a percentage from `0` to `100`.
|
|
5
|
+
|
|
6
|
+
```tsx
|
|
7
|
+
import { Progress } from '@moldable-ai/ui'
|
|
8
|
+
|
|
9
|
+
;<div>
|
|
10
|
+
<p id="sync-progress">Syncing changes: {percent}%</p>
|
|
11
|
+
<Progress aria-labelledby="sync-progress" value={percent} />
|
|
12
|
+
</div>
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## API
|
|
16
|
+
|
|
17
|
+
- `Progress` accepts the Radix progress root props and `className`.
|
|
18
|
+
- `value` controls the indicator transform; omitted or zero values render an
|
|
19
|
+
empty track.
|
|
20
|
+
- The track and indicator use the shared primary color tokens.
|
|
21
|
+
|
|
22
|
+
## Quality and accessibility
|
|
23
|
+
|
|
24
|
+
- Clamp the supplied percentage to `0–100`.
|
|
25
|
+
- Give the progress bar an accessible name with `aria-label` or
|
|
26
|
+
`aria-labelledby`.
|
|
27
|
+
- Include the exact percentage in nearby text when users need it announced or
|
|
28
|
+
compared.
|
|
29
|
+
- Use `Spinner` when duration or completion cannot be estimated.
|
|
30
|
+
- Remove the progress bar or replace it with a clear completion state when the
|
|
31
|
+
operation finishes.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Radio Group
|
|
2
|
+
|
|
3
|
+
`RadioGroup` lets a user choose one value from a visible set of mutually
|
|
4
|
+
exclusive options.
|
|
5
|
+
|
|
6
|
+
```tsx
|
|
7
|
+
import { Label, RadioGroup, RadioGroupItem } from '@moldable-ai/ui'
|
|
8
|
+
|
|
9
|
+
;<RadioGroup defaultValue="normal" aria-label="Priority">
|
|
10
|
+
<div className="flex items-center gap-2">
|
|
11
|
+
<RadioGroupItem id="priority-normal" value="normal" />
|
|
12
|
+
<Label htmlFor="priority-normal">Normal</Label>
|
|
13
|
+
</div>
|
|
14
|
+
<div className="flex items-center gap-2">
|
|
15
|
+
<RadioGroupItem id="priority-high" value="high" />
|
|
16
|
+
<Label htmlFor="priority-high">High</Label>
|
|
17
|
+
</div>
|
|
18
|
+
</RadioGroup>
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## API
|
|
22
|
+
|
|
23
|
+
- `RadioGroup` exposes the Radix root props, including controlled `value` and
|
|
24
|
+
`onValueChange`, uncontrolled `defaultValue`, `name`, `required`, and
|
|
25
|
+
`disabled`.
|
|
26
|
+
- `RadioGroupItem` requires a unique `value` and exposes the Radix item props.
|
|
27
|
+
- The root lays options out as a grid; use `className` to change the layout.
|
|
28
|
+
|
|
29
|
+
## Quality and accessibility
|
|
30
|
+
|
|
31
|
+
- Give the group a visible label, `aria-label`, or `aria-labelledby`.
|
|
32
|
+
- Connect every item to a concise text label with matching `id` and `htmlFor`.
|
|
33
|
+
- Use a stable default only when one option is genuinely preferred.
|
|
34
|
+
- Show validation in text and apply `aria-invalid` when the choice is invalid.
|
|
35
|
+
- Use `Checkbox` for independent choices and `ToggleGroup` for compact view
|
|
36
|
+
modes rather than form options.
|
|
@@ -35,7 +35,8 @@ Use `orientation="vertical"` for editor/results splits. Each panel should establ
|
|
|
35
35
|
## API summary
|
|
36
36
|
|
|
37
37
|
- `ResizablePanelGroup`: wraps `react-resizable-panels` `Group`; `orientation` is `"horizontal"` or `"vertical"` and defaults upstream to horizontal.
|
|
38
|
-
- `ResizablePanel`: wraps `Panel` and accepts its sizing,
|
|
38
|
+
- `ResizablePanel`: wraps the upstream `Panel` and accepts its sizing,
|
|
39
|
+
collapse, callback, id, `elementRef`, and imperative `panelRef` props.
|
|
39
40
|
- `ResizablePanel` also accepts `groupResizeBehavior` for compatibility, but the current wrapper intentionally does not forward or act on it.
|
|
40
41
|
- `ResizableHandle`: wraps `Separator`; `withHandle` adds a visible grip.
|
|
41
42
|
- All parts accept `className` where supported by their underlying primitive.
|
|
@@ -32,12 +32,14 @@ configuration.
|
|
|
32
32
|
|
|
33
33
|
## API summary
|
|
34
34
|
|
|
35
|
-
- `ScrollArea`: Radix Scroll Area root with a full-size viewport
|
|
35
|
+
- `ScrollArea`: Radix Scroll Area root with a full-size viewport and the
|
|
36
|
+
scrollbar configuration selected by `scrollbars`.
|
|
36
37
|
- Accepts Radix root props, forwarded `ref`, and `className`.
|
|
37
38
|
- `scrollbars`: `vertical`, `horizontal`, `both`, or `none`.
|
|
38
39
|
- `viewportClassName`: styles the actual scrolling viewport.
|
|
39
40
|
- `safeBottom`: adds the shared chat-safe padding to the viewport exactly once.
|
|
40
41
|
- `ScrollBar`: exported scrollbar primitive with `orientation="vertical" | "horizontal"`; defaults to vertical.
|
|
42
|
+
- A corner is rendered only when both scrollbars are enabled.
|
|
41
43
|
- The root’s direct children are rendered inside the viewport.
|
|
42
44
|
- The viewport supplies focus-visible outline and ring treatment.
|
|
43
45
|
|
|
@@ -19,7 +19,12 @@ import { SearchField } from '@moldable-ai/ui'
|
|
|
19
19
|
/>
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
Use `value`/`onValueChange` for a controlled field or `defaultValue` for an
|
|
22
|
+
Use `value`/`onValueChange` for a controlled field or `defaultValue` for an
|
|
23
|
+
uncontrolled field. `variant` is `default` or `filled`; `density` is `compact`,
|
|
24
|
+
`default`, or `comfortable`. `controlSize` accepts `mini`, `small`, `medium`,
|
|
25
|
+
`large`, or `xl` and overrides the size token derived from density. `clearable`
|
|
26
|
+
defaults to true. Escape and the clear action empty a non-empty field, refocus
|
|
27
|
+
it, and call `onClear`.
|
|
23
28
|
|
|
24
29
|
## Quality bar
|
|
25
30
|
|
|
@@ -22,7 +22,12 @@ import { SegmentedControl, SegmentedControlItem } from '@moldable-ai/ui'
|
|
|
22
22
|
</SegmentedControl>
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
-
The root supports controlled `value`/`onValueChange` and uncontrolled
|
|
25
|
+
The root supports controlled `value`/`onValueChange` and uncontrolled
|
|
26
|
+
`defaultValue`. `variant` is `muted` or `outline`; `density` is `compact`,
|
|
27
|
+
`default`, or `comfortable`; and `orientation` defaults to `horizontal`.
|
|
28
|
+
`controlSize` accepts `mini`, `small`, `medium`, `large`, or `xl` and overrides
|
|
29
|
+
the size token derived from density. `fullWidth` lets each item share the
|
|
30
|
+
available width.
|
|
26
31
|
|
|
27
32
|
## Quality bar
|
|
28
33
|
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Separator
|
|
2
|
+
|
|
3
|
+
`Separator` draws a semantic-token divider between related regions. It is
|
|
4
|
+
decorative by default.
|
|
5
|
+
|
|
6
|
+
```tsx
|
|
7
|
+
import { Separator } from '@moldable-ai/ui'
|
|
8
|
+
|
|
9
|
+
;<section>
|
|
10
|
+
<h2>Workspace</h2>
|
|
11
|
+
<Separator className="my-3" />
|
|
12
|
+
<div className="flex h-8 items-center gap-3">
|
|
13
|
+
<span>Local</span>
|
|
14
|
+
<Separator orientation="vertical" />
|
|
15
|
+
<span>Synced</span>
|
|
16
|
+
</div>
|
|
17
|
+
</section>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## API
|
|
21
|
+
|
|
22
|
+
- `orientation` is `horizontal` by default and also accepts `vertical`.
|
|
23
|
+
- `decorative` defaults to `true`. Set `decorative={false}` when the divider
|
|
24
|
+
represents a meaningful structural boundary.
|
|
25
|
+
- Other Radix separator props and `className` pass through.
|
|
26
|
+
|
|
27
|
+
## Quality and accessibility
|
|
28
|
+
|
|
29
|
+
- Prefer spacing alone when a line does not clarify grouping.
|
|
30
|
+
- Keep decorative separators out of the accessibility tree with the default
|
|
31
|
+
behavior.
|
|
32
|
+
- Use a non-decorative separator sparingly; headings and landmarks usually
|
|
33
|
+
communicate structure more clearly.
|
|
34
|
+
- Give a vertical separator a parent with an explicit height because it uses
|
|
35
|
+
the full available height.
|
|
@@ -55,7 +55,9 @@ import {
|
|
|
55
55
|
</SidebarProvider>
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
-
Keep each menu item’s icon and last text span direct children of
|
|
58
|
+
Keep each menu item’s icon and last text span direct children of
|
|
59
|
+
`SidebarMenuButton`; the component uses that shape for icon sizing, active
|
|
60
|
+
icon tint, and text truncation.
|
|
59
61
|
|
|
60
62
|
## API summary
|
|
61
63
|
|
|
@@ -63,7 +65,7 @@ Keep each menu item’s icon and last text span direct children of `SidebarMenuB
|
|
|
63
65
|
|
|
64
66
|
- `SidebarProvider`: required context. Supports uncontrolled `defaultOpen`, controlled `open`/`onOpenChange`, and CSS variable overrides through `style`.
|
|
65
67
|
- `useSidebar()`: returns `state`, `open`, `setOpen`, `openMobile`, `setOpenMobile`, `isMobile`, and `toggleSidebar`.
|
|
66
|
-
- `Sidebar`: `side="left" | "right"`, `variant="sidebar" | "floating" | "inset"`, and `collapsible="offcanvas" | "icon" | "none"`.
|
|
68
|
+
- `Sidebar`: `side="left" | "right"`, `variant="sidebar" | "floating" | "inset"`, `sidebarStyle="platform" | "floating" | "edge-to-edge"`, and `collapsible="offcanvas" | "icon" | "none"`.
|
|
67
69
|
- `SidebarInset`: main content surface paired with the sidebar.
|
|
68
70
|
- `SidebarTrigger`: compact toggle button.
|
|
69
71
|
- `SidebarRail`: pointer target along the sidebar edge.
|
|
@@ -77,7 +79,7 @@ Keep each menu item’s icon and last text span direct children of `SidebarMenuB
|
|
|
77
79
|
### Menus
|
|
78
80
|
|
|
79
81
|
- `SidebarMenu` and `SidebarMenuItem` provide list structure.
|
|
80
|
-
- `SidebarMenuButton`: `isActive`, `variant="default" | "outline"`, `size="default" | "sm" | "lg"`, optional `asChild`, and `tooltip`.
|
|
82
|
+
- `SidebarMenuButton`: `isActive`, `variant="default" | "outline"`, `size="default" | "sm" | "lg"`, optional `asChild`, and `tooltip`. Active state applies the semantic selection fill and foreground to its direct icon and text.
|
|
81
83
|
- `SidebarMenuAction`: optional `asChild` and `showOnHover`.
|
|
82
84
|
- `SidebarMenuBadge`: compact trailing count.
|
|
83
85
|
- `SidebarMenuSkeleton`: optional `showIcon`.
|
|
@@ -111,3 +113,18 @@ Override the shell for the embedded full-height environment with `h-full min-h-0
|
|
|
111
113
|
The built-in Command/Ctrl+B shortcut must not conflict with editor-local bold formatting or another essential command in the same context. If it does, control sidebar state elsewhere or revisit the shortcut at the package level.
|
|
112
114
|
|
|
113
115
|
Use semantic `sidebar-*` tokens already provided by the component. In an object browser, post the active connection, collection, or selected object to desktop chat instructions and expose frequent switches through app commands.
|
|
116
|
+
|
|
117
|
+
### Sidebar style selection
|
|
118
|
+
|
|
119
|
+
Choose the visual anatomy independently from the application's base platform:
|
|
120
|
+
|
|
121
|
+
- `edge-to-edge` is the default.
|
|
122
|
+
- `floating` uses the macOS inset, material-backed shell and forces the
|
|
123
|
+
component's resolved variant to `floating`.
|
|
124
|
+
- `edge-to-edge` uses the macOS joined window/sidebar anatomy and forces the
|
|
125
|
+
resolved variant to `sidebar`.
|
|
126
|
+
It has no independent fill, blur, shadow, or internal divider and reveals
|
|
127
|
+
the app/window background beneath it.
|
|
128
|
+
- `platform` follows the selected platform pack and preserves the existing `variant` behavior.
|
|
129
|
+
|
|
130
|
+
Set `sidebarStyle` on `ThemeProvider` for the whole application, or on an individual `Sidebar` for a local override. Apps and components must use these semantic names and the stable `--m-ui-sidebar-*` roles rather than importing versioned source values.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Skeleton
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
`Skeleton` is a neutral, pulsing placeholder for content whose shape is known
|
|
6
|
+
while its data is loading. Size it to approximate the final content so the
|
|
7
|
+
layout remains stable.
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
import { Skeleton } from '@moldable-ai/ui'
|
|
13
|
+
|
|
14
|
+
;<div role="status" aria-busy="true">
|
|
15
|
+
<span className="sr-only">Loading project</span>
|
|
16
|
+
<Skeleton className="h-5 w-40" />
|
|
17
|
+
<Skeleton className="mt-3 h-20 w-full" />
|
|
18
|
+
</div>
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## API
|
|
22
|
+
|
|
23
|
+
- Accepts native `div` props and `className`.
|
|
24
|
+
- Uses the semantic accent surface, the shared control radius, and a pulse
|
|
25
|
+
animation by default.
|
|
26
|
+
- Has no size or visual variants; set dimensions and layout with `className`.
|
|
27
|
+
- Exports `Skeleton`.
|
|
28
|
+
|
|
29
|
+
## Guidance
|
|
30
|
+
|
|
31
|
+
- Match the number and approximate dimensions of the content being replaced.
|
|
32
|
+
- Put loading semantics and concise screen-reader status text on the containing
|
|
33
|
+
region.
|
|
34
|
+
- Keep skeletons non-interactive and remove them when the content resolves.
|
|
35
|
+
- Do not add a separate accessible name to every placeholder or use skeletons
|
|
36
|
+
for errors and empty states.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Slider
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
`Slider` selects one value or a bounded range along a horizontal or vertical
|
|
6
|
+
track. Use it when relative adjustment is more useful than exact text entry.
|
|
7
|
+
|
|
8
|
+
## Usage
|
|
9
|
+
|
|
10
|
+
```tsx
|
|
11
|
+
import { Slider } from '@moldable-ai/ui'
|
|
12
|
+
|
|
13
|
+
;<Slider
|
|
14
|
+
defaultValue={[50]}
|
|
15
|
+
min={0}
|
|
16
|
+
max={100}
|
|
17
|
+
step={5}
|
|
18
|
+
thumbAriaLabels={['Volume']}
|
|
19
|
+
/>
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
For a range, provide two values and a name for each thumb:
|
|
23
|
+
|
|
24
|
+
```tsx
|
|
25
|
+
<Slider
|
|
26
|
+
value={[minimum, maximum]}
|
|
27
|
+
onValueChange={([nextMinimum, nextMaximum]) => {
|
|
28
|
+
setMinimum(nextMinimum)
|
|
29
|
+
setMaximum(nextMaximum)
|
|
30
|
+
}}
|
|
31
|
+
thumbAriaLabels={['Minimum price', 'Maximum price']}
|
|
32
|
+
/>
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## API
|
|
36
|
+
|
|
37
|
+
- Accepts Radix Slider root props, including `value`, `defaultValue`,
|
|
38
|
+
`onValueChange`, `min`, `max`, `step`, `orientation`, and `disabled`.
|
|
39
|
+
- `min` defaults to `0`; `max` defaults to `100`.
|
|
40
|
+
- The number of rendered thumbs follows the length of `value` or
|
|
41
|
+
`defaultValue`. If both are omitted, the component still renders two thumb
|
|
42
|
+
elements, so pass an explicit value array.
|
|
43
|
+
- `thumbAriaLabels` assigns accessible names to thumbs in value order and is
|
|
44
|
+
required for a range.
|
|
45
|
+
- `rangeContent` renders inside the filled range; `thumbContent` renders inside
|
|
46
|
+
every thumb.
|
|
47
|
+
- Exports `Slider`.
|
|
48
|
+
|
|
49
|
+
## Guidance
|
|
50
|
+
|
|
51
|
+
- Pass an explicit one-element `value` or `defaultValue` for a single-value
|
|
52
|
+
slider and two elements for a range.
|
|
53
|
+
- Show the current numeric value nearby when precision matters; pair the slider
|
|
54
|
+
with a number field when direct entry is important.
|
|
55
|
+
- Give every thumb an accessible name, keep range labels distinct, and preserve
|
|
56
|
+
the supplied keyboard and focus behavior.
|
|
57
|
+
- Do not use a slider for a small set of named choices; use a radio or segmented
|
|
58
|
+
control instead.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Spinner
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
`Spinner` communicates indeterminate work when progress cannot be measured. It
|
|
6
|
+
renders a compact rotating loading icon with status semantics.
|
|
7
|
+
|
|
8
|
+
## Usage
|
|
9
|
+
|
|
10
|
+
```tsx
|
|
11
|
+
import { Spinner } from '@moldable-ai/ui'
|
|
12
|
+
|
|
13
|
+
;<Spinner aria-label="Loading results" />
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
When visible text already announces the state, hide the duplicate icon from
|
|
17
|
+
assistive technology:
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
<div className="flex items-center gap-2" role="status">
|
|
21
|
+
<Spinner aria-hidden="true" />
|
|
22
|
+
Loading results…
|
|
23
|
+
</div>
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## API
|
|
27
|
+
|
|
28
|
+
- Accepts native SVG props and `className`.
|
|
29
|
+
- Defaults to `role="status"` and `aria-label="Loading"`; either may be
|
|
30
|
+
overridden by passed props.
|
|
31
|
+
- Defaults to `size-4`, spins continuously, and disables the animation when the
|
|
32
|
+
user prefers reduced motion.
|
|
33
|
+
- Exports `Spinner`.
|
|
34
|
+
|
|
35
|
+
## Guidance
|
|
36
|
+
|
|
37
|
+
- Use a specific accessible label when the spinner is the only status content.
|
|
38
|
+
- Use `aria-hidden="true"` when adjacent status text already conveys the same
|
|
39
|
+
information.
|
|
40
|
+
- Keep surrounding content stable while work is in progress.
|
|
41
|
+
- Use `Progress` instead when a meaningful completion percentage is available.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# SplitView
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`SplitView` composes the resizable panel primitives with pane-oriented names.
|
|
4
4
|
|
|
5
5
|
```tsx
|
|
6
6
|
<SplitView orientation="horizontal">
|
|
@@ -10,6 +10,10 @@ Semantic naming over resizable panel primitives.
|
|
|
10
10
|
</SplitView>
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
`orientation` defaults to `horizontal`. `SplitViewPane` accepts the underlying
|
|
14
|
+
panel sizing and collapse props. `SplitViewHandle` accepts separator props and
|
|
15
|
+
adds an optional visible grip with `withHandle`.
|
|
16
|
+
|
|
17
|
+
Use it when pane resizing is part of the workflow. Provide sensible minimum
|
|
18
|
+
and default sizes, keep a handle between every adjacent pane, and preserve
|
|
19
|
+
important content. Use ordinary flex or grid for a non-resizable layout.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Switch
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
`Switch` changes a boolean setting that takes effect as soon as it is toggled.
|
|
6
|
+
Use it for preferences such as notifications, syncing, or visibility.
|
|
7
|
+
|
|
8
|
+
## Usage
|
|
9
|
+
|
|
10
|
+
```tsx
|
|
11
|
+
import { Label, Switch } from '@moldable-ai/ui'
|
|
12
|
+
|
|
13
|
+
;<div className="flex items-center justify-between gap-3">
|
|
14
|
+
<Label htmlFor="sync-changes">Sync changes</Label>
|
|
15
|
+
<Switch
|
|
16
|
+
id="sync-changes"
|
|
17
|
+
checked={syncChanges}
|
|
18
|
+
onCheckedChange={setSyncChanges}
|
|
19
|
+
/>
|
|
20
|
+
</div>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## API
|
|
24
|
+
|
|
25
|
+
- Accepts Radix Switch root props, including `checked`, `defaultChecked`,
|
|
26
|
+
`onCheckedChange`, `disabled`, `required`, `name`, and `value`.
|
|
27
|
+
- `size` is `default` or `sm` and defaults to `default`.
|
|
28
|
+
- `controlSize` accepts the shared `ControlSize` values (`mini`, `small`,
|
|
29
|
+
`medium`, `large`, or `xl`) and overrides the size-derived token setting.
|
|
30
|
+
- Without `controlSize`, `size="sm"` resolves to `small`; the default resolves
|
|
31
|
+
to `medium`.
|
|
32
|
+
- Supports checked, unchecked, active, focus-visible, and disabled states.
|
|
33
|
+
- Exports `Switch`.
|
|
34
|
+
|
|
35
|
+
## Guidance
|
|
36
|
+
|
|
37
|
+
- Pair the switch with a visible `Label` using `htmlFor` and `id`, or provide an
|
|
38
|
+
`aria-label` when no visible label is possible.
|
|
39
|
+
- Use controlled state when the value is persisted or shared with another
|
|
40
|
+
surface.
|
|
41
|
+
- Write labels for the setting itself, such as “Sync changes,” rather than
|
|
42
|
+
“Enable” or “On.”
|
|
43
|
+
- Use a checkbox for selections submitted as a group and a button for one-shot
|
|
44
|
+
actions.
|
|
@@ -28,10 +28,10 @@ Structured, comparable data with shared density and row-selection behavior.
|
|
|
28
28
|
Use `compact` for inspector-like datasets, `default` for general work, and
|
|
29
29
|
`comfortable` where scanning matters more than density.
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
a row event handler only when an app
|
|
36
|
-
For rich grid navigation, column
|
|
37
|
-
|
|
31
|
+
Pass `selected` and `onSelectionChange` together for a selectable row; either
|
|
32
|
+
prop alone marks the row as selectable. Selection is controlled by the caller
|
|
33
|
+
and toggles with pointer, Enter, or Space. Independent buttons, links, form
|
|
34
|
+
controls, and editable descendants keep their own behavior without toggling
|
|
35
|
+
the row. Call `event.preventDefault()` in a row event handler only when an app
|
|
36
|
+
needs to cancel the built-in response. For rich grid navigation, column
|
|
37
|
+
sorting, or cell editing, use a dedicated data grid.
|
|
@@ -36,7 +36,9 @@ Use the `line` variant in dense app chrome where a filled segmented control woul
|
|
|
36
36
|
|
|
37
37
|
## API summary
|
|
38
38
|
|
|
39
|
-
- `Tabs`: Radix Tabs root; supports controlled `value`/`onValueChange`,
|
|
39
|
+
- `Tabs`: Radix Tabs root; supports controlled `value`/`onValueChange`,
|
|
40
|
+
`defaultValue`, `orientation`, text direction, activation mode, and other root
|
|
41
|
+
props. Orientation defaults to `horizontal`.
|
|
40
42
|
- `TabsList`: `variant="default"` or `"line"`. Defaults to `default`.
|
|
41
43
|
- `TabsTrigger`: requires a `value` matching a content panel; supports `disabled`.
|
|
42
44
|
- `TabsContent`: requires a matching `value`.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Textarea
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
`Textarea` is a native multiline text field for notes, descriptions, comments,
|
|
6
|
+
and other freeform input.
|
|
7
|
+
|
|
8
|
+
## Usage
|
|
9
|
+
|
|
10
|
+
```tsx
|
|
11
|
+
import { Label, Textarea } from '@moldable-ai/ui'
|
|
12
|
+
|
|
13
|
+
;<div className="grid gap-2">
|
|
14
|
+
<Label htmlFor="description">Description</Label>
|
|
15
|
+
<Textarea
|
|
16
|
+
id="description"
|
|
17
|
+
name="description"
|
|
18
|
+
placeholder="Describe this project"
|
|
19
|
+
maxLength={500}
|
|
20
|
+
/>
|
|
21
|
+
</div>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## API
|
|
25
|
+
|
|
26
|
+
- Accepts native `textarea` props, event handlers, and `className`.
|
|
27
|
+
- Supports controlled `value`/`onChange` and uncontrolled `defaultValue`.
|
|
28
|
+
- Uses content-based field sizing with a minimum height of `4rem`.
|
|
29
|
+
- Includes placeholder, focus-visible, disabled, and `aria-invalid` styling.
|
|
30
|
+
- Exports `Textarea`.
|
|
31
|
+
|
|
32
|
+
## Guidance
|
|
33
|
+
|
|
34
|
+
- Always provide a visible label; use `aria-describedby` for help or validation
|
|
35
|
+
text.
|
|
36
|
+
- Set `aria-invalid="true"` only when an error is present, and associate the
|
|
37
|
+
error message with the field.
|
|
38
|
+
- Add `maxLength` and a visible character count when input length is constrained.
|
|
39
|
+
- Preserve the native keyboard, selection, form, and resize behavior.
|
|
40
|
+
- Use `Input` for a single line and a rich-text editor only when formatting is
|
|
41
|
+
genuinely required.
|
|
@@ -51,8 +51,8 @@ Multiple selection:
|
|
|
51
51
|
|
|
52
52
|
- `ToggleGroup`: Radix Toggle Group root. `type="single"` uses a string value; `type="multiple"` uses a string array.
|
|
53
53
|
- Supports controlled `value`/`onValueChange` and uncontrolled `defaultValue`.
|
|
54
|
-
- `variant`: `default` or `
|
|
55
|
-
- `size`: `
|
|
54
|
+
- `variant`: `default`, `outline`, or `filled`, shared with each item.
|
|
55
|
+
- `size`: `xs`, `sm`, `default`, or `lg`, shared with each item.
|
|
56
56
|
- `spacing`: numeric Tailwind spacing multiplier; defaults to `0`. At zero, items join into one segmented shape.
|
|
57
57
|
- `ToggleGroupItem`: requires `value`; may override `variant` or `size` when the group does not supply them.
|
|
58
58
|
- Both parts accept corresponding Radix primitive props and `className`.
|
|
@@ -9,8 +9,8 @@ Use `Button` for a one-shot command and `Switch` for a settings-style boolean th
|
|
|
9
9
|
## Usage patterns
|
|
10
10
|
|
|
11
11
|
```tsx
|
|
12
|
-
import { WrapText } from 'lucide-react'
|
|
13
|
-
import { Toggle } from '@moldable-ai/ui'
|
|
12
|
+
import { Pin, WrapText } from 'lucide-react'
|
|
13
|
+
import { Toggle, ToggleButton } from '@moldable-ai/ui'
|
|
14
14
|
|
|
15
15
|
;<Toggle
|
|
16
16
|
pressed={wrap}
|
|
@@ -24,18 +24,18 @@ import { Toggle } from '@moldable-ai/ui'
|
|
|
24
24
|
</Toggle>
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
For an icon-only toolbar control:
|
|
27
|
+
For an icon-only toolbar control, use the typed `ToggleButton` facade:
|
|
28
28
|
|
|
29
29
|
```tsx
|
|
30
|
-
<
|
|
30
|
+
<ToggleButton
|
|
31
|
+
iconOnly
|
|
31
32
|
defaultPressed
|
|
32
33
|
variant="outline"
|
|
33
34
|
size="sm"
|
|
34
|
-
className="cursor-pointer px-0"
|
|
35
35
|
aria-label="Pin inspector"
|
|
36
36
|
>
|
|
37
37
|
<Pin />
|
|
38
|
-
</
|
|
38
|
+
</ToggleButton>
|
|
39
39
|
```
|
|
40
40
|
|
|
41
41
|
Pair icon-only use with a tooltip.
|
|
@@ -45,8 +45,8 @@ Pair icon-only use with a tooltip.
|
|
|
45
45
|
- Built on Radix Toggle and accepts its root props.
|
|
46
46
|
- `pressed` and `onPressedChange`: controlled state.
|
|
47
47
|
- `defaultPressed`: uncontrolled initial state.
|
|
48
|
-
- `variant`: `default` or `
|
|
49
|
-
- `size`: `
|
|
48
|
+
- `variant`: `default`, `outline`, or `filled`.
|
|
49
|
+
- `size`: `xs`, `sm`, `default`, or `lg`.
|
|
50
50
|
- Supports native button accessibility props such as `aria-label` and `disabled`.
|
|
51
51
|
- `toggleVariants` is exported and shared by `ToggleGroup`.
|
|
52
52
|
|
|
@@ -54,7 +54,7 @@ Pair icon-only use with a tooltip.
|
|
|
54
54
|
|
|
55
55
|
- Use controlled state when the preference affects another pane or persisted setting.
|
|
56
56
|
- Make the pressed state legible through shape or icon treatment as well as color.
|
|
57
|
-
-
|
|
57
|
+
- Give icon-only toggles an accessible name and a tooltip.
|
|
58
58
|
- Keep toolbar toggles compact and aligned with adjacent controls.
|
|
59
59
|
- Use a specific icon tied to the state.
|
|
60
60
|
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Toolbar controls
|
|
2
|
+
|
|
3
|
+
Precomposed controls for native-window-aware `Toolbar` chrome. They use
|
|
4
|
+
Moldable semantic tokens, density, menus, and accessibility behavior while
|
|
5
|
+
keeping app toolbars visually consistent.
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
<Toolbar position="top">
|
|
9
|
+
<ToolbarControlGroup aria-label="Navigation">
|
|
10
|
+
<ToolbarSidebarToggle
|
|
11
|
+
expanded={sidebarOpen}
|
|
12
|
+
onExpandedChange={setSidebarOpen}
|
|
13
|
+
/>
|
|
14
|
+
<ToolbarControlSeparator />
|
|
15
|
+
<ToolbarBackButton onClick={goBack} />
|
|
16
|
+
</ToolbarControlGroup>
|
|
17
|
+
<ToolbarTitleField value={title} onChange={rename} />
|
|
18
|
+
<ToolbarActions>
|
|
19
|
+
<ToolbarControlGroup aria-label="History">
|
|
20
|
+
<ToolbarIconButton label="Undo" onClick={undo}>
|
|
21
|
+
<Undo2 />
|
|
22
|
+
</ToolbarIconButton>
|
|
23
|
+
<ToolbarControlSeparator />
|
|
24
|
+
<ToolbarIconButton label="Redo" onClick={redo}>
|
|
25
|
+
<Redo2 />
|
|
26
|
+
</ToolbarIconButton>
|
|
27
|
+
</ToolbarControlGroup>
|
|
28
|
+
<ToolbarOverflowMenu
|
|
29
|
+
items={[
|
|
30
|
+
{ id: 'history', label: 'Version history' },
|
|
31
|
+
{ id: 'export', label: 'Export' },
|
|
32
|
+
]}
|
|
33
|
+
onSelectItem={handleMoreAction}
|
|
34
|
+
/>
|
|
35
|
+
<ToolbarButton variant="prominent">Present</ToolbarButton>
|
|
36
|
+
</ToolbarActions>
|
|
37
|
+
</Toolbar>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Components
|
|
41
|
+
|
|
42
|
+
- `ToolbarButton` — text or mixed-content action. Defaults to 36px native
|
|
43
|
+
chrome; use `variant="prominent"` for the one primary action.
|
|
44
|
+
- `ToolbarIconButton` — required accessible label and optional tooltip.
|
|
45
|
+
- `ToolbarBackButton` — single chevron Back affordance for root-to-detail
|
|
46
|
+
navigation.
|
|
47
|
+
- `ToolbarSidebarToggle` — controlled sidebar visibility button with accurate
|
|
48
|
+
pressed state and dynamic label.
|
|
49
|
+
- `ToolbarOverflowMenu` — an ellipsis button backed by Moldable's declarative
|
|
50
|
+
menu API, including the native host menu when available.
|
|
51
|
+
- `ToolbarControlGroup` — a shared surface for closely related actions such as
|
|
52
|
+
Undo/Redo. It defaults to `size="xl"`, supports `size="medium"`, and makes
|
|
53
|
+
children compact quiet controls.
|
|
54
|
+
- `ToolbarControlSeparator` — divider within a related action group.
|
|
55
|
+
- `ToolbarTitleField` — an accessible, inline-editable contextual title.
|
|
56
|
+
|
|
57
|
+
`ToolbarButton` and `ToolbarIconButton` accept `appearance="quiet"` when a
|
|
58
|
+
standalone action should not have raised chrome. The default `chrome`
|
|
59
|
+
appearance uses the `toolbar` Button variant. `ToolbarControlGroup` also
|
|
60
|
+
accepts `appearance="quiet"` when related controls should not share a raised
|
|
61
|
+
surface. Raised controls use these semantic tokens:
|
|
62
|
+
|
|
63
|
+
- `--toolbar-control-background`
|
|
64
|
+
- `--toolbar-control-hover`
|
|
65
|
+
- `--toolbar-control-pressed`
|
|
66
|
+
- `--toolbar-control-border`
|
|
67
|
+
- `--toolbar-control-shadow`
|
|
68
|
+
|
|
69
|
+
The tokens adapt to light/dark appearance, increased contrast, and reduced
|
|
70
|
+
transparency.
|
|
71
|
+
|
|
72
|
+
## Composition rules
|
|
73
|
+
|
|
74
|
+
- Keep the current document or view title leading and the primary action last.
|
|
75
|
+
- Use fully rounded standalone controls and shared pill surfaces for related
|
|
76
|
+
controls. Avoid drawing a separate rounded rectangle around every icon.
|
|
77
|
+
- Prefer icon-only secondary controls and a text-only primary action.
|
|
78
|
+
- Put only genuinely related commands in `ToolbarControlGroup`.
|
|
79
|
+
- Move low-frequency commands such as history, duplicate, export, and delete
|
|
80
|
+
into `ToolbarOverflowMenu`.
|
|
81
|
+
- Keep roughly five or six visible actions. Tooltips do not replace accessible
|
|
82
|
+
labels.
|
|
83
|
+
- Use the shared Back and Sidebar controls instead of hand-building arrows.
|