@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.
Files changed (181) hide show
  1. package/dist/catalog/component-catalog.d.ts +9 -2
  2. package/dist/catalog/component-catalog.d.ts.map +1 -1
  3. package/dist/catalog/component-catalog.js +11 -7
  4. package/dist/catalog/core-control-stories.d.ts.map +1 -1
  5. package/dist/catalog/core-control-stories.js +1 -1
  6. package/dist/catalog/core-foundation-stories.d.ts.map +1 -1
  7. package/dist/catalog/core-foundation-stories.js +5 -5
  8. package/dist/components/ui/app-frame.d.ts +20 -1
  9. package/dist/components/ui/app-frame.d.ts.map +1 -1
  10. package/dist/components/ui/app-frame.js +37 -7
  11. package/dist/components/ui/badge.d.ts +1 -1
  12. package/dist/components/ui/badge.js +1 -1
  13. package/dist/components/ui/button.d.ts +5 -3
  14. package/dist/components/ui/button.d.ts.map +1 -1
  15. package/dist/components/ui/button.js +39 -11
  16. package/dist/components/ui/card.d.ts +12 -2
  17. package/dist/components/ui/card.d.ts.map +1 -1
  18. package/dist/components/ui/card.js +3 -2
  19. package/dist/components/ui/checkbox.d.ts +4 -1
  20. package/dist/components/ui/checkbox.d.ts.map +1 -1
  21. package/dist/components/ui/checkbox.js +4 -4
  22. package/dist/components/ui/context-menu.js +6 -6
  23. package/dist/components/ui/dropdown-menu.js +6 -6
  24. package/dist/components/ui/icon-button.d.ts +1 -1
  25. package/dist/components/ui/icon-button.d.ts.map +1 -1
  26. package/dist/components/ui/icon-button.js +1 -0
  27. package/dist/components/ui/input.d.ts +6 -2
  28. package/dist/components/ui/input.d.ts.map +1 -1
  29. package/dist/components/ui/input.js +2 -2
  30. package/dist/components/ui/material.d.ts +8 -3
  31. package/dist/components/ui/material.d.ts.map +1 -1
  32. package/dist/components/ui/material.js +2 -2
  33. package/dist/components/ui/search-field.d.ts +3 -1
  34. package/dist/components/ui/search-field.d.ts.map +1 -1
  35. package/dist/components/ui/search-field.js +16 -6
  36. package/dist/components/ui/segmented-control.d.ts +3 -1
  37. package/dist/components/ui/segmented-control.d.ts.map +1 -1
  38. package/dist/components/ui/segmented-control.js +23 -17
  39. package/dist/components/ui/select.js +2 -2
  40. package/dist/components/ui/sidebar.d.ts +5 -3
  41. package/dist/components/ui/sidebar.d.ts.map +1 -1
  42. package/dist/components/ui/sidebar.js +53 -15
  43. package/dist/components/ui/status.d.ts +1 -1
  44. package/dist/components/ui/status.js +1 -1
  45. package/dist/components/ui/switch.d.ts +3 -1
  46. package/dist/components/ui/switch.d.ts.map +1 -1
  47. package/dist/components/ui/switch.js +3 -2
  48. package/dist/components/ui/toolbar-controls.d.ts +3 -1
  49. package/dist/components/ui/toolbar-controls.d.ts.map +1 -1
  50. package/dist/components/ui/toolbar-controls.js +14 -7
  51. package/dist/components/ui/toolbar.d.ts +5 -4
  52. package/dist/components/ui/toolbar.d.ts.map +1 -1
  53. package/dist/components/ui/toolbar.js +3 -3
  54. package/dist/index.d.ts +2 -1
  55. package/dist/index.d.ts.map +1 -1
  56. package/dist/index.js +3 -1
  57. package/dist/lib/frame-lifecycle.d.ts +1 -0
  58. package/dist/lib/frame-lifecycle.d.ts.map +1 -1
  59. package/dist/lib/frame-lifecycle.js +7 -0
  60. package/dist/lib/theme.d.ts +39 -5
  61. package/dist/lib/theme.d.ts.map +1 -1
  62. package/dist/lib/theme.js +105 -17
  63. package/dist/tokens/contracts.d.ts +79 -0
  64. package/dist/tokens/contracts.d.ts.map +1 -0
  65. package/dist/tokens/contracts.js +57 -0
  66. package/dist/tokens/index.d.ts +2 -0
  67. package/dist/tokens/index.d.ts.map +1 -0
  68. package/dist/tokens/index.js +1 -0
  69. package/docs/README.md +2 -0
  70. package/docs/adaptive-materials.md +14 -9
  71. package/docs/design-tokens.md +10 -6
  72. package/docs/foundations.md +3 -3
  73. package/docs/macos-design-audit.md +144 -0
  74. package/docs/native-integration.md +4 -4
  75. package/docs/platform-architecture.md +189 -0
  76. package/docs/standalone-app-windows.md +37 -0
  77. package/docs/visual-regression.md +6 -8
  78. package/package.json +13 -1
  79. package/src/components/ui/accordion.md +46 -0
  80. package/src/components/ui/alert.md +12 -4
  81. package/src/components/ui/app-frame.md +8 -5
  82. package/src/components/ui/aspect-ratio.md +37 -0
  83. package/src/components/ui/avatar.md +48 -0
  84. package/src/components/ui/breadcrumb.md +52 -0
  85. package/src/components/ui/button-group.md +43 -0
  86. package/src/components/ui/button.md +20 -4
  87. package/src/components/ui/calendar.md +42 -0
  88. package/src/components/ui/card.md +43 -0
  89. package/src/components/ui/carousel.md +47 -0
  90. package/src/components/ui/chart.md +52 -0
  91. package/src/components/ui/checkbox.md +36 -0
  92. package/src/components/ui/collapsible.md +2 -3
  93. package/src/components/ui/color-well.md +14 -4
  94. package/src/components/ui/combobox.md +3 -3
  95. package/src/components/ui/confirm-dialog.md +5 -4
  96. package/src/components/ui/context-menu.md +3 -2
  97. package/src/components/ui/date-field.md +6 -1
  98. package/src/components/ui/date-picker.md +6 -3
  99. package/src/components/ui/dialog.md +14 -12
  100. package/src/components/ui/drawer.md +58 -0
  101. package/src/components/ui/error-boundary-view.md +1 -1
  102. package/src/components/ui/field.md +2 -1
  103. package/src/components/ui/form.md +71 -0
  104. package/src/components/ui/grid.md +4 -3
  105. package/src/components/ui/icon-button.md +4 -1
  106. package/src/components/ui/input-group.md +49 -0
  107. package/src/components/ui/input-otp.md +56 -0
  108. package/src/components/ui/input.md +40 -0
  109. package/src/components/ui/inspector.md +47 -7
  110. package/src/components/ui/item.md +5 -3
  111. package/src/components/ui/kbd.md +30 -0
  112. package/src/components/ui/label.md +29 -0
  113. package/src/components/ui/list.md +2 -2
  114. package/src/components/ui/material.md +25 -12
  115. package/src/components/ui/menu-items.md +60 -0
  116. package/src/components/ui/menubar.md +58 -0
  117. package/src/components/ui/message-scroller-primitive.md +70 -0
  118. package/src/components/ui/message-scroller.md +86 -0
  119. package/src/components/ui/navigation-button-group.md +4 -3
  120. package/src/components/ui/navigation-menu.md +52 -0
  121. package/src/components/ui/number-input.md +8 -0
  122. package/src/components/ui/pagination.md +51 -0
  123. package/src/components/ui/panel.md +6 -0
  124. package/src/components/ui/popover.md +10 -7
  125. package/src/components/ui/progress.md +31 -0
  126. package/src/components/ui/radio-group.md +36 -0
  127. package/src/components/ui/resizable.md +2 -1
  128. package/src/components/ui/scroll-area.md +3 -1
  129. package/src/components/ui/search-field.md +6 -1
  130. package/src/components/ui/segmented-control.md +6 -1
  131. package/src/components/ui/separator.md +35 -0
  132. package/src/components/ui/sidebar.md +20 -3
  133. package/src/components/ui/skeleton.md +36 -0
  134. package/src/components/ui/slider.md +58 -0
  135. package/src/components/ui/spinner.md +41 -0
  136. package/src/components/ui/split-view.md +8 -4
  137. package/src/components/ui/switch.md +44 -0
  138. package/src/components/ui/table.md +7 -7
  139. package/src/components/ui/tabs.md +3 -1
  140. package/src/components/ui/textarea.md +41 -0
  141. package/src/components/ui/toggle-group.md +2 -2
  142. package/src/components/ui/toggle.md +9 -9
  143. package/src/components/ui/toolbar-controls.md +17 -9
  144. package/src/components/ui/toolbar.md +6 -6
  145. package/src/styles/index.css +171 -117
  146. package/src/tokens/contracts.ts +131 -0
  147. package/src/tokens/index.css +6 -0
  148. package/src/tokens/index.ts +23 -0
  149. package/src/tokens/macos-26/README.md +37 -0
  150. package/src/tokens/macos-26/aliases.css +53 -0
  151. package/src/tokens/macos-26/compatibility.css +7 -0
  152. package/src/tokens/macos-26/index.css +3 -0
  153. package/src/tokens/macos-26/source/provenance.generated.json +28 -0
  154. package/src/tokens/macos-26/source/sidebar.generated.css +29 -0
  155. package/src/tokens/macos-26/source.css +7 -0
  156. package/src/tokens/macos-26/web-adaptations.json +25 -0
  157. package/src/tokens/macos-26/web-adaptations.md +15 -0
  158. package/src/tokens/macos-27/accessibility.css +11 -0
  159. package/src/tokens/macos-27/aliases.css +304 -0
  160. package/src/tokens/macos-27/compatibility.css +212 -0
  161. package/src/tokens/macos-27/index.css +15 -0
  162. package/src/tokens/macos-27/recipes.css +23 -0
  163. package/src/tokens/macos-27/source/chrome.generated.css +338 -0
  164. package/src/tokens/macos-27/source/colors.generated.css +140 -0
  165. package/src/tokens/macos-27/source/context.generated.css +18 -0
  166. package/src/tokens/macos-27/source/controls.generated.css +764 -0
  167. package/src/tokens/macos-27/source/effects.generated.css +68 -0
  168. package/src/tokens/macos-27/source/kit.generated.css +50 -0
  169. package/src/tokens/macos-27/source/overlays-status.generated.css +931 -0
  170. package/src/tokens/macos-27/source/paint-styles.generated.css +81 -0
  171. package/src/tokens/macos-27/source/provenance.generated.json +62 -0
  172. package/src/tokens/macos-27/source/sizes.generated.css +385 -0
  173. package/src/tokens/macos-27/source/source.generated.json +554 -0
  174. package/src/tokens/macos-27/source/text-styles.generated.css +116 -0
  175. package/src/tokens/macos-27/source.css +17 -0
  176. package/src/tokens/macos-27/web-adaptations.css +98 -0
  177. package/src/tokens/macos-27/web-adaptations.json +163 -0
  178. package/src/tokens/macos-27/web-adaptations.md +117 -0
  179. package/src/tokens/moldable/brand.css +48 -0
  180. package/src/tokens/moldable/index.css +1 -0
  181. package/src/tokens/platform-contract.test.ts +290 -0
@@ -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
- Semantic naming over resizable panel primitives.
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
- Use when pane resizing is part of the workflow. Provide sensible minimum and
14
- default sizes, preserve important content, and persist sizes only when that
15
- improves repeated work. Use `PanelGroup` for non-resizable layouts.
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
- When a row is selectable, selection is controlled by the caller and can be
32
- toggled with pointer, Enter, or Space. Independent buttons, links, form
33
- controls, and editable descendants keep their own pointer and keyboard
34
- behavior without toggling the containing row. Call `event.preventDefault()` in
35
- a row event handler only when an app needs to cancel the built-in row response.
36
- For rich grid navigation, column sorting, or cell editing, use a dedicated data
37
- grid rather than layering those interactions onto a basic table.
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`, `defaultValue`, `orientation`, activation direction, and other root props. Orientation defaults to `horizontal`.
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 `outline`, shared with each item.
55
- - `size`: `default`, `sm`, or `lg`, shared with each item.
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
- <Toggle
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
- </Toggle>
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 `outline`.
49
- - `size`: `default`, `sm`, or `lg`.
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
- - Add `cursor-pointer`, an accessible name, and a tooltip for icon-only toggles.
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
 
@@ -6,11 +6,14 @@ keeping app toolbars visually consistent.
6
6
 
7
7
  ```tsx
8
8
  <Toolbar position="top">
9
- <ToolbarSidebarToggle
10
- expanded={sidebarOpen}
11
- onExpandedChange={setSidebarOpen}
12
- />
13
- <ToolbarBackButton onClick={goBack} />
9
+ <ToolbarControlGroup aria-label="Navigation">
10
+ <ToolbarSidebarToggle
11
+ expanded={sidebarOpen}
12
+ onExpandedChange={setSidebarOpen}
13
+ />
14
+ <ToolbarControlSeparator />
15
+ <ToolbarBackButton onClick={goBack} />
16
+ </ToolbarControlGroup>
14
17
  <ToolbarTitleField value={title} onChange={rename} />
15
18
  <ToolbarActions>
16
19
  <ToolbarControlGroup aria-label="History">
@@ -29,7 +32,7 @@ keeping app toolbars visually consistent.
29
32
  ]}
30
33
  onSelectItem={handleMoreAction}
31
34
  />
32
- <ToolbarButton variant="default">Present</ToolbarButton>
35
+ <ToolbarButton variant="prominent">Present</ToolbarButton>
33
36
  </ToolbarActions>
34
37
  </Toolbar>
35
38
  ```
@@ -37,7 +40,7 @@ keeping app toolbars visually consistent.
37
40
  ## Components
38
41
 
39
42
  - `ToolbarButton` — text or mixed-content action. Defaults to 36px native
40
- chrome; use `variant="default"` for the one primary action.
43
+ chrome; use `variant="prominent"` for the one primary action.
41
44
  - `ToolbarIconButton` — required accessible label and optional tooltip.
42
45
  - `ToolbarBackButton` — single chevron Back affordance for root-to-detail
43
46
  navigation.
@@ -46,13 +49,16 @@ keeping app toolbars visually consistent.
46
49
  - `ToolbarOverflowMenu` — an ellipsis button backed by Moldable's declarative
47
50
  menu API, including the native host menu when available.
48
51
  - `ToolbarControlGroup` — a shared surface for closely related actions such as
49
- Undo/Redo. Children automatically become compact quiet controls.
52
+ Undo/Redo. It defaults to `size="xl"`, supports `size="medium"`, and makes
53
+ children compact quiet controls.
50
54
  - `ToolbarControlSeparator` — divider within a related action group.
51
55
  - `ToolbarTitleField` — an accessible, inline-editable contextual title.
52
56
 
53
57
  `ToolbarButton` and `ToolbarIconButton` accept `appearance="quiet"` when a
54
58
  standalone action should not have raised chrome. The default `chrome`
55
- appearance uses the `toolbar` Button variant and these semantic tokens:
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:
56
62
 
57
63
  - `--toolbar-control-background`
58
64
  - `--toolbar-control-hover`
@@ -66,6 +72,8 @@ transparency.
66
72
  ## Composition rules
67
73
 
68
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.
69
77
  - Prefer icon-only secondary controls and a text-only primary action.
70
78
  - Put only genuinely related commands in `ToolbarControlGroup`.
71
79
  - Move low-frequency commands such as history, duplicate, export, and delete
@@ -12,9 +12,9 @@ embedded view.
12
12
  <ToolbarDescription>Local workspace</ToolbarDescription>
13
13
  </ToolbarContent>
14
14
  <ToolbarActions>
15
- <Button size="icon-sm" aria-label="New note">
15
+ <ToolbarIconButton label="New note" tooltip>
16
16
  <Plus />
17
- </Button>
17
+ </ToolbarIconButton>
18
18
  </ToolbarActions>
19
19
  </Toolbar>
20
20
  ```
@@ -28,10 +28,10 @@ when there is no useful view context; the remaining toolbar still provides a
28
28
  drag surface and a safe home for right-aligned actions.
29
29
 
30
30
  The `inset` prop defaults to `auto`. Use `none` for a top toolbar that is not
31
- window chrome, `windowControls` to force the standard control lane, or
32
- `windowControlsAndButton` when another leading control sits beside the native
33
- traffic lights. Set `draggable={false}` only for top toolbars that are nested
34
- inside app content.
31
+ window chrome, `windowControls` to explicitly declare the standard control
32
+ lane, or `windowControlsAndButton` when another leading control sits beside
33
+ the native traffic lights. Set `draggable={false}` only for top toolbars that
34
+ are nested inside app content.
35
35
 
36
36
  The default toolbar uses `material="regular"`. The `plain` and `panel` variants
37
37
  default to `material="none"`; pass a material explicitly only when the toolbar