@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,58 @@
|
|
|
1
|
+
# Menubar
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
`Menubar` presents a persistent row of related command menus, such as File,
|
|
6
|
+
Edit, and View. Use it for command families that benefit from repeated
|
|
7
|
+
keyboard access; use `DropdownMenu` for a single contextual action menu.
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
import {
|
|
13
|
+
Menubar,
|
|
14
|
+
MenubarContent,
|
|
15
|
+
MenubarItem,
|
|
16
|
+
MenubarMenu,
|
|
17
|
+
MenubarShortcut,
|
|
18
|
+
MenubarTrigger,
|
|
19
|
+
} from '@moldable-ai/ui'
|
|
20
|
+
|
|
21
|
+
;<Menubar>
|
|
22
|
+
<MenubarMenu>
|
|
23
|
+
<MenubarTrigger className="cursor-pointer">File</MenubarTrigger>
|
|
24
|
+
<MenubarContent>
|
|
25
|
+
<MenubarItem onSelect={createDocument}>
|
|
26
|
+
New document
|
|
27
|
+
<MenubarShortcut>⌘N</MenubarShortcut>
|
|
28
|
+
</MenubarItem>
|
|
29
|
+
</MenubarContent>
|
|
30
|
+
</MenubarMenu>
|
|
31
|
+
</Menubar>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## API summary
|
|
35
|
+
|
|
36
|
+
- `Menubar`, `MenubarMenu`, and `MenubarTrigger` form the required shell.
|
|
37
|
+
- `MenubarContent` is portalled and defaults to `align="start"`,
|
|
38
|
+
`alignOffset={-4}`, and `sideOffset={8}`.
|
|
39
|
+
- `MenubarItem` supports `inset` and
|
|
40
|
+
`variant="default" | "destructive"`.
|
|
41
|
+
- Checkbox items, radio groups/items, groups, labels, separators, shortcuts,
|
|
42
|
+
and submenus are exported for structured command sets.
|
|
43
|
+
- `MenubarLabel` and `MenubarSubTrigger` support `inset`.
|
|
44
|
+
- Components otherwise accept the corresponding Radix menubar props.
|
|
45
|
+
|
|
46
|
+
## Guidance
|
|
47
|
+
|
|
48
|
+
- Keep top-level trigger labels short and conventional.
|
|
49
|
+
- Use checkbox and radio items for menu-owned state, and `onSelect` for
|
|
50
|
+
commands.
|
|
51
|
+
- Put destructive commands last or in a separated group; do not rely on color
|
|
52
|
+
alone to communicate risk.
|
|
53
|
+
- `MenubarShortcut` is display text only and does not register a handler.
|
|
54
|
+
- Radix supplies menu roles, focus movement, typeahead, Escape dismissal, and
|
|
55
|
+
submenu navigation. Preserve those semantics and give icon-only content an
|
|
56
|
+
accessible name.
|
|
57
|
+
- Keep submenus shallow and use `Popover` or `Dialog` for arbitrary form
|
|
58
|
+
controls.
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Message Scroller Primitive
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
`message-scroller-primitive.tsx` is the unstyled React wiring for the
|
|
6
|
+
in-repository transcript controller and scroll-ownership policy. The public
|
|
7
|
+
`MessageScroller*` components wrap this module with layout, button, and
|
|
8
|
+
animation styles; app code should use those wrappers.
|
|
9
|
+
|
|
10
|
+
## Anatomy
|
|
11
|
+
|
|
12
|
+
```tsx
|
|
13
|
+
<MessageScroller.Provider autoScroll>
|
|
14
|
+
<MessageScroller.Root>
|
|
15
|
+
<MessageScroller.Viewport>
|
|
16
|
+
<MessageScroller.Content>
|
|
17
|
+
<MessageScroller.Item messageId="turn-1" scrollAnchor>
|
|
18
|
+
{/* message */}
|
|
19
|
+
</MessageScroller.Item>
|
|
20
|
+
</MessageScroller.Content>
|
|
21
|
+
</MessageScroller.Viewport>
|
|
22
|
+
<MessageScroller.Button direction="end" />
|
|
23
|
+
</MessageScroller.Root>
|
|
24
|
+
</MessageScroller.Provider>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
This local-only example uses the `MessageScroller` object exported by the
|
|
28
|
+
primitive module. `Provider` must wrap every root, item, button, and hook.
|
|
29
|
+
|
|
30
|
+
## Primitive contract
|
|
31
|
+
|
|
32
|
+
- Provider defaults: `autoScroll={false}`, `defaultScrollPosition="end"`,
|
|
33
|
+
`scrollEdgeThreshold={8}`, `scrollPreviousItemPeek={64}`, and
|
|
34
|
+
`scrollMargin={0}`. Changing `defaultScrollPosition` resets the one-time
|
|
35
|
+
initial-position decision for the next content mutation.
|
|
36
|
+
- `Viewport` forwards scroll, wheel, touch, and scroll-key events after
|
|
37
|
+
notifying the controller. It defaults to a focusable messages region and
|
|
38
|
+
observes viewport size changes.
|
|
39
|
+
- `Content` defaults to an additions-only live log, observes direct child
|
|
40
|
+
mutations and size changes, and appends a hidden internal spacer.
|
|
41
|
+
- `Item` registers `messageId` elements and writes anchor data used for
|
|
42
|
+
initial placement, new-turn anchoring, targeted scrolling, and visibility.
|
|
43
|
+
- `Button` supports `direction="start" | "end"`, `behavior`, and a `render`
|
|
44
|
+
element or render function. Defaults are end, smooth, and `type="button"`.
|
|
45
|
+
Inactive buttons are inert with `tabIndex={-1}`; preventing the click event's
|
|
46
|
+
default also prevents the scroll command.
|
|
47
|
+
|
|
48
|
+
## Controller and policy behavior
|
|
49
|
+
|
|
50
|
+
The controller is the sole owner of programmatic transcript movement. The
|
|
51
|
+
policy distinguishes following the end, free reading, an anchored turn, and a
|
|
52
|
+
settling commanded jump. Wheel, touch, scroll-key, scrollbar, or other motion
|
|
53
|
+
away from a declared target gives control to the reader immediately.
|
|
54
|
+
|
|
55
|
+
It also:
|
|
56
|
+
|
|
57
|
+
- keeps a followed end pinned during growth;
|
|
58
|
+
- reanchors a streaming turn after resize;
|
|
59
|
+
- preserves the first visible row when older items are prepended;
|
|
60
|
+
- restores a stable visible leaf when content above collapses;
|
|
61
|
+
- grows the internal spacer so late items can reach the requested alignment;
|
|
62
|
+
- exposes edge state as `data-scrollable` and active programmatic movement as
|
|
63
|
+
`data-autoscrolling` on root and viewport;
|
|
64
|
+
- observes visibility only while `useMessageScrollerVisibility` has
|
|
65
|
+
subscribers.
|
|
66
|
+
|
|
67
|
+
For finer reading-position stability inside a complex item, mark stable
|
|
68
|
+
descendants with `data-message-scroll-anchor`. Do not manipulate the
|
|
69
|
+
controller, spacer, data attributes, or scroll position from a competing
|
|
70
|
+
effect; extend the wrapper API when new behavior is required.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Message Scroller
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
`MessageScroller` is the styled, public transcript scroller. It keeps streamed
|
|
6
|
+
content stable, preserves the reader's position when history is prepended or
|
|
7
|
+
content above changes size, supports turn anchors, and exposes jump and
|
|
8
|
+
visibility state.
|
|
9
|
+
|
|
10
|
+
## Usage
|
|
11
|
+
|
|
12
|
+
```tsx
|
|
13
|
+
import {
|
|
14
|
+
MessageScroller,
|
|
15
|
+
MessageScrollerButton,
|
|
16
|
+
MessageScrollerContent,
|
|
17
|
+
MessageScrollerItem,
|
|
18
|
+
MessageScrollerProvider,
|
|
19
|
+
MessageScrollerViewport,
|
|
20
|
+
} from '@moldable-ai/ui'
|
|
21
|
+
|
|
22
|
+
;<MessageScrollerProvider autoScroll defaultScrollPosition="end">
|
|
23
|
+
<MessageScroller>
|
|
24
|
+
<MessageScrollerViewport>
|
|
25
|
+
<MessageScrollerContent className="gap-3 p-3">
|
|
26
|
+
{messages.map((message) => (
|
|
27
|
+
<MessageScrollerItem
|
|
28
|
+
key={message.id}
|
|
29
|
+
messageId={message.id}
|
|
30
|
+
scrollAnchor={message.role === 'user'}
|
|
31
|
+
>
|
|
32
|
+
{renderMessage(message)}
|
|
33
|
+
</MessageScrollerItem>
|
|
34
|
+
))}
|
|
35
|
+
</MessageScrollerContent>
|
|
36
|
+
</MessageScrollerViewport>
|
|
37
|
+
<MessageScrollerButton />
|
|
38
|
+
</MessageScroller>
|
|
39
|
+
</MessageScrollerProvider>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## API summary
|
|
43
|
+
|
|
44
|
+
- `MessageScrollerProvider` is required. Defaults are `autoScroll={false}`,
|
|
45
|
+
`defaultScrollPosition="end"`, `scrollEdgeThreshold={8}`,
|
|
46
|
+
`scrollPreviousItemPeek={64}`, and `scrollMargin={0}`.
|
|
47
|
+
- Initial position can be `start`, `end`, or `last-anchor`. The last option
|
|
48
|
+
anchors the newest marked turn only when enough transcript follows it;
|
|
49
|
+
otherwise it lands at the end.
|
|
50
|
+
- `MessageScrollerViewport` is a focusable `role="region"` labelled
|
|
51
|
+
“Messages” by default. `preserveScrollOnPrepend` defaults to true.
|
|
52
|
+
- `MessageScrollerContent` defaults to `role="log"` and
|
|
53
|
+
`aria-relevant="additions"`. It accepts `spacerClassName` for the internal
|
|
54
|
+
positioning spacer.
|
|
55
|
+
- `MessageScrollerItem` accepts `messageId` and `scrollAnchor` (false by
|
|
56
|
+
default). IDs enable targeted scrolling and visibility reporting; mark the
|
|
57
|
+
start of each new turn as an anchor.
|
|
58
|
+
- `MessageScrollerButton` defaults to an end jump with smooth behavior,
|
|
59
|
+
`variant="secondary"`, and `size="icon-sm"`. It becomes inert and leaves
|
|
60
|
+
the tab order when that edge is not scrollable. `direction="start"` creates
|
|
61
|
+
the corresponding top jump.
|
|
62
|
+
|
|
63
|
+
## Hooks and behavior
|
|
64
|
+
|
|
65
|
+
- `useMessageScroller()` returns `scrollToStart`, `scrollToEnd`, and
|
|
66
|
+
`scrollToMessage`. Targeted scrolls accept `align`, `behavior`, and
|
|
67
|
+
`scrollMargin`; alignment defaults to `start` and behavior to `auto`.
|
|
68
|
+
- `useMessageScrollerScrollable()` returns `{ start, end }`.
|
|
69
|
+
- `useMessageScrollerVisibility()` returns `currentAnchorId` and ordered
|
|
70
|
+
`visibleMessageIds`.
|
|
71
|
+
- Hooks must be descendants of the provider.
|
|
72
|
+
- Reader input takes ownership immediately. With `autoScroll`, content follows
|
|
73
|
+
the end only while follow mode is active; a newly appended turn anchor is
|
|
74
|
+
held near the top with the configured previous-item peek.
|
|
75
|
+
|
|
76
|
+
## Guidance
|
|
77
|
+
|
|
78
|
+
- Give every navigable item a stable `messageId`; do not use an array index.
|
|
79
|
+
- Mark only meaningful turn starts as `scrollAnchor`.
|
|
80
|
+
- Keep one viewport as the owning vertical scroll region and give its flex
|
|
81
|
+
ancestors `min-h-0`.
|
|
82
|
+
- Preserve the default region label or supply a more specific `aria-label`.
|
|
83
|
+
- Keep the content's log semantics and busy state accurate while streaming or
|
|
84
|
+
loading history.
|
|
85
|
+
- Do not add a second effect that writes `scrollTop`; all movement must go
|
|
86
|
+
through the scroller API so it cannot fight the reader.
|
|
@@ -17,9 +17,10 @@ consistent compact treatment.
|
|
|
17
17
|
- `canGoBack` and `canGoForward` disable unavailable directions.
|
|
18
18
|
- `onBack` and `onForward` perform caller-owned navigation.
|
|
19
19
|
- `backLabel` and `forwardLabel` customize accessible names.
|
|
20
|
-
- `size` accepts the `IconButton` size scale
|
|
21
|
-
- `variant` is `ghost` or `outline`.
|
|
22
|
-
-
|
|
20
|
+
- `size` accepts the `IconButton` size scale and defaults to `sm`.
|
|
21
|
+
- `variant` is `ghost` or `outline` and defaults to `ghost`.
|
|
22
|
+
- Remaining `ButtonGroup` props apply to the root except `children` and
|
|
23
|
+
`orientation`; the component owns two buttons in a horizontal group.
|
|
23
24
|
|
|
24
25
|
## Keyboard and accessibility
|
|
25
26
|
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Navigation Menu
|
|
2
|
+
|
|
3
|
+
`NavigationMenu` presents a compact row of destinations, with optional
|
|
4
|
+
disclosure panels for grouped links. Use it for navigation, not for commands
|
|
5
|
+
or form actions.
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import {
|
|
9
|
+
NavigationMenu,
|
|
10
|
+
NavigationMenuContent,
|
|
11
|
+
NavigationMenuItem,
|
|
12
|
+
NavigationMenuLink,
|
|
13
|
+
NavigationMenuList,
|
|
14
|
+
NavigationMenuTrigger,
|
|
15
|
+
} from '@moldable-ai/ui'
|
|
16
|
+
|
|
17
|
+
;<NavigationMenu viewport={false}>
|
|
18
|
+
<NavigationMenuList>
|
|
19
|
+
<NavigationMenuItem>
|
|
20
|
+
<NavigationMenuTrigger>Projects</NavigationMenuTrigger>
|
|
21
|
+
<NavigationMenuContent>
|
|
22
|
+
<NavigationMenuLink href="/projects/recent" active>
|
|
23
|
+
Recent
|
|
24
|
+
</NavigationMenuLink>
|
|
25
|
+
<NavigationMenuLink href="/projects/shared">Shared</NavigationMenuLink>
|
|
26
|
+
</NavigationMenuContent>
|
|
27
|
+
</NavigationMenuItem>
|
|
28
|
+
</NavigationMenuList>
|
|
29
|
+
</NavigationMenu>
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## API
|
|
33
|
+
|
|
34
|
+
- `NavigationMenu` exposes the Radix root props plus `viewport`. The shared
|
|
35
|
+
viewport is rendered by default; set `viewport={false}` for a panel attached
|
|
36
|
+
to each item.
|
|
37
|
+
- `NavigationMenuList`, `NavigationMenuItem`, `NavigationMenuTrigger`,
|
|
38
|
+
`NavigationMenuContent`, `NavigationMenuLink`, and
|
|
39
|
+
`NavigationMenuIndicator` expose their corresponding Radix props.
|
|
40
|
+
- `NavigationMenuLink` accepts `active` for the current destination.
|
|
41
|
+
- `NavigationMenuViewport` and `navigationMenuTriggerStyle` are exported for
|
|
42
|
+
custom composition.
|
|
43
|
+
|
|
44
|
+
## Quality and accessibility
|
|
45
|
+
|
|
46
|
+
- Use real destinations and preserve link semantics with `href`.
|
|
47
|
+
- Give every trigger and icon-only link an accessible name.
|
|
48
|
+
- Mark only the current destination active.
|
|
49
|
+
- Keep labels short and disclosure panels easy to scan.
|
|
50
|
+
- Preserve the keyboard and focus behavior supplied by Radix; do not make
|
|
51
|
+
essential destinations available only on pointer hover.
|
|
52
|
+
- Use `Menubar`, `DropdownMenu`, or ordinary buttons for actions.
|
|
@@ -17,3 +17,11 @@ Use in inspectors and settings where the numeric value matters. Use `Slider`
|
|
|
17
17
|
when relative adjustment matters more than exact entry. Always supply a visible
|
|
18
18
|
label or `aria-label`. Treat `null` as empty input and validate domain-specific
|
|
19
19
|
constraints outside the component.
|
|
20
|
+
|
|
21
|
+
`value`/`onValueChange` provide controlled state; `defaultValue` provides
|
|
22
|
+
uncontrolled initial state. `variant` is `default` or `filled`, and `size` is
|
|
23
|
+
`sm`, `default`, or `lg`. Both default to `default`. Steppers are shown by
|
|
24
|
+
default; set `steppers={false}` to hide them. They use a finite numeric `step`
|
|
25
|
+
(falling back to `1`), start an empty value from zero, and clamp their result
|
|
26
|
+
to finite `min`/`max` values. Typed input still relies on native numeric
|
|
27
|
+
validity and caller validation.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Pagination
|
|
2
|
+
|
|
3
|
+
`Pagination` links between pages in a bounded result set.
|
|
4
|
+
|
|
5
|
+
```tsx
|
|
6
|
+
import {
|
|
7
|
+
Pagination,
|
|
8
|
+
PaginationContent,
|
|
9
|
+
PaginationItem,
|
|
10
|
+
PaginationLink,
|
|
11
|
+
PaginationNext,
|
|
12
|
+
PaginationPrevious,
|
|
13
|
+
} from '@moldable-ai/ui'
|
|
14
|
+
|
|
15
|
+
;<Pagination>
|
|
16
|
+
<PaginationContent>
|
|
17
|
+
<PaginationItem>
|
|
18
|
+
<PaginationPrevious href="?page=1" />
|
|
19
|
+
</PaginationItem>
|
|
20
|
+
<PaginationItem>
|
|
21
|
+
<PaginationLink href="?page=2" isActive>
|
|
22
|
+
2
|
|
23
|
+
</PaginationLink>
|
|
24
|
+
</PaginationItem>
|
|
25
|
+
<PaginationItem>
|
|
26
|
+
<PaginationNext href="?page=3" />
|
|
27
|
+
</PaginationItem>
|
|
28
|
+
</PaginationContent>
|
|
29
|
+
</Pagination>
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## API
|
|
33
|
+
|
|
34
|
+
- `Pagination` renders a centered `nav` named “pagination”.
|
|
35
|
+
- `PaginationContent` and `PaginationItem` render the list structure.
|
|
36
|
+
- `PaginationLink` renders an anchor. `isActive` applies the outlined state
|
|
37
|
+
and `aria-current="page"`; `size` uses the shared button size scale.
|
|
38
|
+
- `PaginationPrevious` and `PaginationNext` provide responsive text and
|
|
39
|
+
accessible labels.
|
|
40
|
+
- `PaginationEllipsis` is a decorative gap marker, not a link.
|
|
41
|
+
|
|
42
|
+
## Quality and accessibility
|
|
43
|
+
|
|
44
|
+
- Supply a real `href` for every available page and keep the current location
|
|
45
|
+
marked with `isActive`.
|
|
46
|
+
- Keep page order stable and show enough neighboring pages to retain context.
|
|
47
|
+
- At a range boundary, omit the unavailable link or implement
|
|
48
|
+
`aria-disabled`, remove it from Tab order, and prevent navigation; anchors
|
|
49
|
+
do not support the native `disabled` attribute.
|
|
50
|
+
- Do not use pagination for infinite loading or a small list that fits in one
|
|
51
|
+
view.
|
|
@@ -9,3 +9,9 @@ bounded content groups inside a pane.
|
|
|
9
9
|
|
|
10
10
|
The group and its containing shell need a definite height. Long content belongs
|
|
11
11
|
in `PanelContent`, and chat-safe padding belongs on that scrolling region.
|
|
12
|
+
|
|
13
|
+
`PanelGroup` defaults to horizontal and accepts `orientation="vertical"`.
|
|
14
|
+
`Panel` supports `surface="default" | "muted" | "sidebar" | "transparent"`
|
|
15
|
+
and `border="none" | "all" | "inline" | "block"`. Surface defaults to
|
|
16
|
+
`default`; border defaults to `none`. The structural components otherwise
|
|
17
|
+
accept native props for their rendered `section`, `header`, `div`, or `footer`.
|
|
@@ -21,11 +21,14 @@ Use `Popover` for a small, interactive surface anchored to a control. Use
|
|
|
21
21
|
|
|
22
22
|
Sizes are `content`, `sm`, `default`, and `lg`. Content is capped to the
|
|
23
23
|
collision-aware available width and height and scrolls when necessary.
|
|
24
|
-
`
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
Content defaults to `size="default"`, `align="center"`, `sideOffset={4}`, and
|
|
25
|
+
`material="regular"`. The `material` prop accepts every `MaterialVariant`:
|
|
26
|
+
the five named thicknesses plus the `regular` and `clear` compatibility
|
|
27
|
+
aliases. Use a thin surface only where the content behind it keeps text and
|
|
28
|
+
controls legible.
|
|
27
29
|
|
|
28
|
-
`
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
`PopoverContent` is already portalled. `PopoverAnchor`, `PopoverClose`, and
|
|
31
|
+
`PopoverArrow` are available when the composition needs them;
|
|
32
|
+
`PopoverPortal` is exported for custom primitive composition. Provide an
|
|
33
|
+
accessible name on an icon-only trigger or close action. Keep required
|
|
34
|
+
instructions and critical actions discoverable without hover.
|
|
@@ -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.
|