@moldable-ai/ui 0.2.20 → 0.2.21

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 (159) hide show
  1. package/dist/catalog/catalog-coverage.d.ts +15 -0
  2. package/dist/catalog/catalog-coverage.d.ts.map +1 -0
  3. package/dist/catalog/catalog-coverage.js +44 -0
  4. package/dist/catalog/catalog-manifest.d.ts.map +1 -1
  5. package/dist/catalog/catalog-manifest.js +35 -23
  6. package/dist/catalog/catalog-types.d.ts +10 -0
  7. package/dist/catalog/catalog-types.d.ts.map +1 -1
  8. package/dist/catalog/catalog-types.js +6 -0
  9. package/dist/catalog/component-catalog.d.ts.map +1 -1
  10. package/dist/catalog/component-catalog.js +16 -6
  11. package/dist/catalog/core-catalog-exclusions.d.ts +8 -0
  12. package/dist/catalog/core-catalog-exclusions.d.ts.map +1 -0
  13. package/dist/catalog/core-catalog-exclusions.js +151 -0
  14. package/dist/catalog/core-catalog.d.ts +0 -4
  15. package/dist/catalog/core-catalog.d.ts.map +1 -1
  16. package/dist/catalog/core-catalog.js +12 -98
  17. package/dist/catalog/core-collection-stories.d.ts +3 -0
  18. package/dist/catalog/core-collection-stories.d.ts.map +1 -0
  19. package/dist/catalog/core-collection-stories.js +42 -0
  20. package/dist/catalog/core-control-stories.d.ts +3 -0
  21. package/dist/catalog/core-control-stories.d.ts.map +1 -0
  22. package/dist/catalog/core-control-stories.js +94 -0
  23. package/dist/catalog/core-feedback-stories.d.ts +3 -0
  24. package/dist/catalog/core-feedback-stories.d.ts.map +1 -0
  25. package/dist/catalog/core-feedback-stories.js +50 -0
  26. package/dist/catalog/core-foundation-stories.d.ts +3 -0
  27. package/dist/catalog/core-foundation-stories.d.ts.map +1 -0
  28. package/dist/catalog/core-foundation-stories.js +53 -0
  29. package/dist/catalog/core-navigation-stories.d.ts +3 -0
  30. package/dist/catalog/core-navigation-stories.d.ts.map +1 -0
  31. package/dist/catalog/core-navigation-stories.js +25 -0
  32. package/dist/catalog/core-overlay-stories.d.ts +3 -0
  33. package/dist/catalog/core-overlay-stories.d.ts.map +1 -0
  34. package/dist/catalog/core-overlay-stories.js +20 -0
  35. package/dist/catalog/index.d.ts +3 -1
  36. package/dist/catalog/index.d.ts.map +1 -1
  37. package/dist/catalog/index.js +3 -1
  38. package/dist/components/chat/chat-panel.d.ts +0 -1
  39. package/dist/components/chat/chat-panel.d.ts.map +1 -1
  40. package/dist/components/chat/chat-panel.js +7 -11
  41. package/dist/components/ui/alert-dialog.d.ts +7 -3
  42. package/dist/components/ui/alert-dialog.d.ts.map +1 -1
  43. package/dist/components/ui/alert-dialog.js +9 -5
  44. package/dist/components/ui/alert.d.ts +19 -3
  45. package/dist/components/ui/alert.d.ts.map +1 -1
  46. package/dist/components/ui/alert.js +25 -8
  47. package/dist/components/ui/app-frame.d.ts +9 -3
  48. package/dist/components/ui/app-frame.d.ts.map +1 -1
  49. package/dist/components/ui/app-frame.js +45 -6
  50. package/dist/components/ui/collapsible.d.ts +9 -1
  51. package/dist/components/ui/collapsible.d.ts.map +1 -1
  52. package/dist/components/ui/collapsible.js +13 -2
  53. package/dist/components/ui/collection-navigation.d.ts +8 -0
  54. package/dist/components/ui/collection-navigation.d.ts.map +1 -0
  55. package/dist/components/ui/collection-navigation.js +19 -0
  56. package/dist/components/ui/command.d.ts +5 -1
  57. package/dist/components/ui/command.d.ts.map +1 -1
  58. package/dist/components/ui/command.js +13 -1
  59. package/dist/components/ui/confirm-dialog.d.ts +19 -0
  60. package/dist/components/ui/confirm-dialog.d.ts.map +1 -0
  61. package/dist/components/ui/confirm-dialog.js +45 -0
  62. package/dist/components/ui/date-picker.d.ts +24 -0
  63. package/dist/components/ui/date-picker.d.ts.map +1 -0
  64. package/dist/components/ui/date-picker.js +92 -0
  65. package/dist/components/ui/dialog.d.ts +4 -2
  66. package/dist/components/ui/dialog.d.ts.map +1 -1
  67. package/dist/components/ui/dialog.js +8 -5
  68. package/dist/components/ui/empty.d.ts +7 -2
  69. package/dist/components/ui/empty.d.ts.map +1 -1
  70. package/dist/components/ui/empty.js +20 -7
  71. package/dist/components/ui/grid.d.ts.map +1 -1
  72. package/dist/components/ui/grid.js +70 -46
  73. package/dist/components/ui/index.d.ts +4 -0
  74. package/dist/components/ui/index.d.ts.map +1 -1
  75. package/dist/components/ui/index.js +4 -0
  76. package/dist/components/ui/list.d.ts +5 -1
  77. package/dist/components/ui/list.d.ts.map +1 -1
  78. package/dist/components/ui/list.js +27 -16
  79. package/dist/components/ui/material.d.ts +34 -0
  80. package/dist/components/ui/material.d.ts.map +1 -0
  81. package/dist/components/ui/material.js +34 -0
  82. package/dist/components/ui/message-scroller-controller.d.ts +162 -0
  83. package/dist/components/ui/message-scroller-controller.d.ts.map +1 -0
  84. package/dist/components/ui/message-scroller-controller.js +888 -0
  85. package/dist/components/ui/message-scroller-policy.d.ts +74 -0
  86. package/dist/components/ui/message-scroller-policy.d.ts.map +1 -0
  87. package/dist/components/ui/message-scroller-policy.js +129 -0
  88. package/dist/components/ui/message-scroller-primitive.d.ts +55 -0
  89. package/dist/components/ui/message-scroller-primitive.d.ts.map +1 -0
  90. package/dist/components/ui/message-scroller-primitive.js +226 -0
  91. package/dist/components/ui/message-scroller.d.ts +2 -2
  92. package/dist/components/ui/message-scroller.d.ts.map +1 -1
  93. package/dist/components/ui/message-scroller.js +3 -15
  94. package/dist/components/ui/navigation-button-group.d.ts +16 -0
  95. package/dist/components/ui/navigation-button-group.d.ts.map +1 -0
  96. package/dist/components/ui/navigation-button-group.js +9 -0
  97. package/dist/components/ui/popover.d.ts +9 -2
  98. package/dist/components/ui/popover.d.ts.map +1 -1
  99. package/dist/components/ui/popover.js +13 -3
  100. package/dist/components/ui/scroll-area.d.ts +8 -2
  101. package/dist/components/ui/scroll-area.d.ts.map +1 -1
  102. package/dist/components/ui/scroll-area.js +6 -3
  103. package/dist/components/ui/search-field.d.ts.map +1 -1
  104. package/dist/components/ui/segmented-control.d.ts.map +1 -1
  105. package/dist/components/ui/segmented-control.js +6 -5
  106. package/dist/components/ui/sheet.d.ts +4 -2
  107. package/dist/components/ui/sheet.d.ts.map +1 -1
  108. package/dist/components/ui/sheet.js +12 -9
  109. package/dist/components/ui/sonner.d.ts +1 -1
  110. package/dist/components/ui/sonner.d.ts.map +1 -1
  111. package/dist/components/ui/table.d.ts.map +1 -1
  112. package/dist/components/ui/table.js +7 -2
  113. package/dist/components/ui/toggle.d.ts +12 -4
  114. package/dist/components/ui/toggle.d.ts.map +1 -1
  115. package/dist/components/ui/toggle.js +13 -2
  116. package/dist/components/ui/toolbar.d.ts +9 -2
  117. package/dist/components/ui/toolbar.d.ts.map +1 -1
  118. package/dist/components/ui/toolbar.js +23 -4
  119. package/dist/components/ui/tooltip.d.ts +8 -3
  120. package/dist/components/ui/tooltip.d.ts.map +1 -1
  121. package/dist/components/ui/tooltip.js +11 -6
  122. package/dist/lib/frame-lifecycle.d.ts +1 -0
  123. package/dist/lib/frame-lifecycle.d.ts.map +1 -1
  124. package/dist/lib/frame-lifecycle.js +3 -2
  125. package/dist/lib/theme.d.ts.map +1 -1
  126. package/dist/lib/theme.js +2 -1
  127. package/docs/README.md +3 -1
  128. package/docs/adaptive-materials.md +79 -0
  129. package/docs/app-anatomy.md +3 -1
  130. package/docs/component-catalog.md +26 -3
  131. package/docs/design-tokens.md +17 -4
  132. package/docs/foundations.md +5 -3
  133. package/docs/standalone-app-windows.md +8 -0
  134. package/package.json +1 -2
  135. package/src/components/ui/alert-dialog.md +31 -0
  136. package/src/components/ui/alert.md +28 -6
  137. package/src/components/ui/app-frame.md +5 -0
  138. package/src/components/ui/collapsible.md +52 -0
  139. package/src/components/ui/combobox.md +0 -1
  140. package/src/components/ui/command.md +54 -0
  141. package/src/components/ui/date-field.md +1 -1
  142. package/src/components/ui/date-picker.md +55 -0
  143. package/src/components/ui/dialog.md +40 -0
  144. package/src/components/ui/empty.md +8 -3
  145. package/src/components/ui/grid.md +8 -4
  146. package/src/components/ui/icon-button.md +2 -2
  147. package/src/components/ui/list.md +35 -2
  148. package/src/components/ui/material.md +51 -0
  149. package/src/components/ui/navigation-button-group.md +46 -0
  150. package/src/components/ui/popover.md +31 -0
  151. package/src/components/ui/scroll-area.md +11 -7
  152. package/src/components/ui/search-field.md +1 -1
  153. package/src/components/ui/segmented-control.md +2 -5
  154. package/src/components/ui/sheet.md +30 -0
  155. package/src/components/ui/table.md +4 -2
  156. package/src/components/ui/toggle-button.md +48 -0
  157. package/src/components/ui/toolbar.md +5 -0
  158. package/src/components/ui/tooltip.md +31 -0
  159. package/src/styles/index.css +213 -0
@@ -17,7 +17,7 @@ import {
17
17
  ListItemTitle,
18
18
  } from '@moldable-ai/ui'
19
19
 
20
- <List
20
+ ;<List
21
21
  aria-label="Documents"
22
22
  selectionMode="single"
23
23
  defaultSelectedValues={['brief']}
@@ -38,6 +38,28 @@ import {
38
38
  </List>
39
39
  ```
40
40
 
41
+ ## Sections
42
+
43
+ Group related options with `ListSection` and give every section an accessible
44
+ name. `ListSectionHeader` automatically labels its containing section:
45
+
46
+ ```tsx
47
+ <List aria-label="Documents" selectionMode="single">
48
+ <ListSection>
49
+ <ListSectionHeader>Recent</ListSectionHeader>
50
+ <ListItem value="brief">Project brief</ListItem>
51
+ <ListItem value="notes">Research notes</ListItem>
52
+ </ListSection>
53
+ <ListSection aria-label="Archived documents">
54
+ <ListItem value="archive">Archive</ListItem>
55
+ </ListSection>
56
+ </List>
57
+ ```
58
+
59
+ Use either `ListSectionHeader`, `aria-label`, or an explicit
60
+ `aria-labelledby` value for each section. Keyboard movement follows the
61
+ rendered DOM order across section boundaries.
62
+
41
63
  For controlled selection, pass an iterable to `selectedValues` and replace it when `onSelectionChange` fires:
42
64
 
43
65
  ```tsx
@@ -63,8 +85,9 @@ const [selected, setSelected] = useState<ReadonlySet<string>>(
63
85
  - Enter changes selection and invokes `onAction`.
64
86
  - A single pointer click changes selection. A double click invokes `onAction`.
65
87
  - Disabled items are skipped during keyboard navigation and cannot be selected or activated.
66
- - Interactive descendants such as buttons and links keep their own click behavior. They do not select or activate the containing item.
88
+ - Interactive descendants such as buttons and links keep their own pointer behavior. They do not select or activate the containing item.
67
89
  - Focus uses a roving `tabIndex`, so the collection contributes one stop to the tab order.
90
+ - When the list first mounts, the first selected, enabled item receives the roving tab stop. If nothing is selected, the first enabled item receives it.
68
91
 
69
92
  ## API summary
70
93
 
@@ -86,9 +109,16 @@ const [selected, setSelected] = useState<ReadonlySet<string>>(
86
109
 
87
110
  `ListItemContent`, `ListItemTitle`, `ListItemDescription`, and `ListItemActions` provide compact row layout without changing semantics.
88
111
 
112
+ ### `ListSection`
113
+
114
+ - Groups related items with `role="group"`.
115
+ - Use `ListSectionHeader` for an automatically connected visible label.
116
+ - Alternatively, provide `aria-label` or `aria-labelledby`.
117
+
89
118
  ## Do
90
119
 
91
120
  - Give every collection a visible label or `aria-label`.
121
+ - Give every section an accessible label.
92
122
  - Keep values stable when filtering or reordering.
93
123
  - Put the primary row identity in `ListItemTitle` and secondary metadata in `ListItemDescription`.
94
124
  - Use selection to represent durable collection state and action to open or execute.
@@ -98,6 +128,9 @@ const [selected, setSelected] = useState<ReadonlySet<string>>(
98
128
 
99
129
  - Do not put a `List` inside another list item.
100
130
  - Do not use array indexes as values when rows can reorder.
131
+ - Do not put buttons, links, or other interactive controls inside selectable
132
+ listbox items. Put independent actions outside the listbox or use a pattern
133
+ whose child-interaction model supports them.
101
134
  - Do not rely on double click as the only way to perform an important action.
102
135
  - Do not add a second manual arrow-key handler to the same collection.
103
136
  - Do not visually mark focus and selection as if they were the same state.
@@ -0,0 +1,51 @@
1
+ # Material
2
+
3
+ Adaptive material for navigation and control chrome.
4
+
5
+ ```tsx
6
+ <Material asChild variant="regular" elevation="none">
7
+ <Toolbar>{/* context and actions */}</Toolbar>
8
+ </Material>
9
+
10
+ <MaterialGroup variant="regular" shape="capsule" spacing="compact">
11
+ <IconButton label="Previous" variant="ghost">
12
+ <ChevronLeft />
13
+ </IconButton>
14
+ <IconButton label="Next" variant="ghost">
15
+ <ChevronRight />
16
+ </IconButton>
17
+ </MaterialGroup>
18
+ ```
19
+
20
+ ## Variants
21
+
22
+ - `regular` provides a frosted, legible control or navigation layer.
23
+ - `clear` is less frosted and is only for compact controls floating over
24
+ photos, maps, video, or another richly colored canvas.
25
+
26
+ Both variants start with an opaque fallback. Backdrop sampling is enabled only
27
+ when the renderer supports it. Reduced transparency and forced colors keep the
28
+ fallback opaque.
29
+
30
+ ## Grouping
31
+
32
+ `MaterialGroup` creates one sampled layer for a related cluster. Put ordinary
33
+ ghost or transparent controls inside it. Do not wrap each child in another
34
+ `Material`; nested sampling creates muddy, inconsistent results.
35
+
36
+ Use separate `Material` instances only when controls are spatially detached and
37
+ do not read as one group.
38
+
39
+ ## Rules
40
+
41
+ - Use material for toolbars, compact floating controls, menus, and other
42
+ temporary control layers.
43
+ - Keep documents, calendars, tables, forms, cards, sheets, and primary content
44
+ canvases opaque.
45
+ - Prefer `regular`. A `clear` surface needs stable contrast across every part
46
+ of the media behind it.
47
+ - Use `interactive` only when the material surface itself is the control.
48
+ - Do not animate blur or saturation. Shared motion tokens provide restrained
49
+ press feedback and remove it when reduced motion is requested.
50
+ - CSS material samples content inside the renderer. Native behind-window
51
+ material remains owned by the host.
@@ -0,0 +1,46 @@
1
+ # NavigationButtonGroup
2
+
3
+ `NavigationButtonGroup` presents paired back and forward actions with one
4
+ consistent compact treatment.
5
+
6
+ ```tsx
7
+ <NavigationButtonGroup
8
+ canGoBack={historyIndex > 0}
9
+ canGoForward={historyIndex < history.length - 1}
10
+ onBack={goBack}
11
+ onForward={goForward}
12
+ />
13
+ ```
14
+
15
+ ## API
16
+
17
+ - `canGoBack` and `canGoForward` disable unavailable directions.
18
+ - `onBack` and `onForward` perform caller-owned navigation.
19
+ - `backLabel` and `forwardLabel` customize accessible names.
20
+ - `size` accepts the `IconButton` size scale.
21
+ - `variant` is `ghost` or `outline`.
22
+ - Native `ButtonGroup` props apply to the group.
23
+
24
+ ## Keyboard and accessibility
25
+
26
+ The root has `role="group"` and the default accessible name “Navigation”.
27
+ Each icon button has a stable accessible name and participates in normal Tab
28
+ order. The component does not install global keyboard shortcuts.
29
+
30
+ ## Platform behavior
31
+
32
+ This component is portable. It does not own browser history, Moldable
33
+ navigation state, or native window history. Connect it to the navigation owner
34
+ for the current surface.
35
+
36
+ ## Do
37
+
38
+ - Put it in a leading toolbar group.
39
+ - Disable unavailable directions.
40
+ - Keep back and forward behavior scoped to the visible pane or app.
41
+
42
+ ## Don't
43
+
44
+ - Do not render a fake forward action when no forward history exists.
45
+ - Do not use it for undo and redo.
46
+ - Do not add a second tooltip around its buttons.
@@ -0,0 +1,31 @@
1
+ # Popover
2
+
3
+ Use `Popover` for a small, interactive surface anchored to a control. Use
4
+ `Tooltip` for terse non-interactive help, `HoverCard` for a preview, and
5
+ `Dialog` for a blocking task.
6
+
7
+ ```tsx
8
+ <Popover>
9
+ <PopoverTrigger asChild>
10
+ <Button variant="outline">View options</Button>
11
+ </PopoverTrigger>
12
+ <PopoverContent size="sm" material="regular">
13
+ <PopoverHeader>
14
+ <PopoverTitle>View options</PopoverTitle>
15
+ <PopoverDescription>Choose what appears in the list.</PopoverDescription>
16
+ </PopoverHeader>
17
+ {/* interactive controls */}
18
+ </PopoverContent>
19
+ </Popover>
20
+ ```
21
+
22
+ Sizes are `content`, `sm`, `default`, and `lg`. Content is capped to the
23
+ collision-aware available width and height and scrolls when necessary.
24
+ `material="regular"` is the standard temporary overlay. Use `clear` only above
25
+ media or a richly colored canvas where the stronger sampled effect has a clear
26
+ layering purpose.
27
+
28
+ `PopoverClose`, `PopoverPortal`, and `PopoverArrow` are available when the
29
+ composition needs them. Provide an accessible name on an icon-only close
30
+ action. Keep required instructions and critical actions discoverable without
31
+ hover.
@@ -11,10 +11,8 @@ For simple content, a native `overflow-y-auto` region is often sufficient. The i
11
11
  ```tsx
12
12
  import { ScrollArea } from '@moldable-ai/ui'
13
13
 
14
- ;<ScrollArea className="h-full min-h-0">
15
- <div className="px-3 pb-[calc(var(--chat-safe-padding,0px)+1rem)] pt-3">
16
- {/* Long list */}
17
- </div>
14
+ ;<ScrollArea className="h-full min-h-0" safeBottom>
15
+ <div className="px-3 pt-3">{/* Long list */}</div>
18
16
  </ScrollArea>
19
17
  ```
20
18
 
@@ -28,12 +26,17 @@ For a grouped list:
28
26
  </ScrollArea>
29
27
  ```
30
28
 
31
- The current `ScrollArea` composition installs a vertical scrollbar automatically.
29
+ The current `ScrollArea` composition installs a vertical scrollbar by default.
30
+ Set `scrollbars` to `horizontal`, `both`, or `none` for another explicit
31
+ configuration.
32
32
 
33
33
  ## API summary
34
34
 
35
35
  - `ScrollArea`: Radix Scroll Area root with a full-size viewport, vertical `ScrollBar`, and corner.
36
36
  - Accepts Radix root props, forwarded `ref`, and `className`.
37
+ - `scrollbars`: `vertical`, `horizontal`, `both`, or `none`.
38
+ - `viewportClassName`: styles the actual scrolling viewport.
39
+ - `safeBottom`: adds the shared chat-safe padding to the viewport exactly once.
37
40
  - `ScrollBar`: exported scrollbar primitive with `orientation="vertical" | "horizontal"`; defaults to vertical.
38
41
  - The root’s direct children are rendered inside the viewport.
39
42
  - The viewport supplies focus-visible outline and ring treatment.
@@ -43,7 +46,7 @@ The current `ScrollArea` composition installs a vertical scrollbar automatically
43
46
  - Give the scroll area a definite height through its own class and full-height ancestors.
44
47
  - Put padding on an inner content wrapper when it should scroll with the content.
45
48
  - Add `min-h-0` to flex or grid ancestors.
46
- - Add bottom chat-safe padding inside every scroll region that reaches the webview bottom.
49
+ - Enable `safeBottom` on every owning scroll region that reaches the webview bottom.
47
50
  - Keep sticky headers inside the same scrolling context as their content.
48
51
  - Test keyboard, wheel, trackpad, and scrollbar-thumb interaction.
49
52
 
@@ -54,7 +57,8 @@ The current `ScrollArea` composition installs a vertical scrollbar automatically
54
57
  - Do not put fixed controls inside the moving content when they must remain reachable.
55
58
  - Do not hide focus outlines.
56
59
  - Do not assume padding on a sibling pane protects this viewport from desktop chat.
57
- - Do not assume adding `ScrollBar` as a child of `ScrollArea` creates a second root scrollbar; children belong to the viewport in the current composition.
60
+ - Do not add `ScrollBar` as a child of `ScrollArea`; children belong to its
61
+ viewport. Use the `scrollbars` prop.
58
62
 
59
63
  ## Moldable considerations
60
64
 
@@ -9,7 +9,7 @@
9
9
  ```tsx
10
10
  import { SearchField } from '@moldable-ai/ui'
11
11
 
12
- <SearchField
12
+ ;<SearchField
13
13
  aria-label="Search projects"
14
14
  value={query}
15
15
  onValueChange={setQuery}
@@ -9,12 +9,9 @@ Use it for choices such as list/grid, week/month, or preview/edit. Use `Tabs` wh
9
9
  ## Usage
10
10
 
11
11
  ```tsx
12
- import {
13
- SegmentedControl,
14
- SegmentedControlItem,
15
- } from '@moldable-ai/ui'
12
+ import { SegmentedControl, SegmentedControlItem } from '@moldable-ai/ui'
16
13
 
17
- <SegmentedControl
14
+ ;<SegmentedControl
18
15
  aria-label="Calendar view"
19
16
  value={view}
20
17
  onValueChange={setView}
@@ -0,0 +1,30 @@
1
+ # Sheet
2
+
3
+ `Sheet` presents a secondary region from an edge while preserving the current
4
+ workspace. It is appropriate for narrow-window navigation, filters, or an
5
+ inspector that cannot remain beside the canvas.
6
+
7
+ ```tsx
8
+ <Sheet>
9
+ <SheetTrigger asChild>
10
+ <Button variant="outline">Filters</Button>
11
+ </SheetTrigger>
12
+ <SheetContent side="right" size="default">
13
+ <SheetHeader>
14
+ <SheetTitle>Filters</SheetTitle>
15
+ <SheetDescription>Limit the visible results.</SheetDescription>
16
+ </SheetHeader>
17
+ <SheetBody>{/* scrolling controls */}</SheetBody>
18
+ <SheetFooter>{/* persistent actions */}</SheetFooter>
19
+ </SheetContent>
20
+ </Sheet>
21
+ ```
22
+
23
+ Side sheets support `sm`, `default`, and `lg`. All sides respect host window
24
+ insets; their bottom edge also clears the embedded chat safe area. `SheetBody`
25
+ is the only flexing scroll owner, leaving its header, close action, and footer
26
+ reachable.
27
+
28
+ Use `Dialog` when the task is centered and blocking, `Drawer` for touch-first
29
+ presentation, and `Inspector` when contextual properties should remain visible
30
+ beside the canvas. Do not use a sheet as permanent desktop navigation.
@@ -29,7 +29,9 @@ Use `compact` for inspector-like datasets, `default` for general work, and
29
29
  `comfortable` where scanning matters more than density.
30
30
 
31
31
  When a row is selectable, selection is controlled by the caller and can be
32
- toggled with pointer, Enter, or Space. Put independent actions inside buttons
33
- and call `event.stopPropagation()` if activating them must not select the row.
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.
34
36
  For rich grid navigation, column sorting, or cell editing, use a dedicated data
35
37
  grid rather than layering those interactions onto a basic table.
@@ -0,0 +1,48 @@
1
+ # ToggleButton
2
+
3
+ `ToggleButton` is a single pressed/unpressed action. It is a semantic facade
4
+ over `Toggle`, so both share one Radix interaction model and one style source.
5
+
6
+ ```tsx
7
+ <ToggleButton pressed={showGrid} onPressedChange={setShowGrid}>
8
+ Show grid
9
+ </ToggleButton>
10
+ ```
11
+
12
+ For an icon-only toggle, opt in explicitly and provide its accessible name:
13
+
14
+ ```tsx
15
+ <ToggleButton
16
+ iconOnly
17
+ aria-label="Pin inspector"
18
+ pressed={pinned}
19
+ onPressedChange={setPinned}
20
+ >
21
+ <PinIcon />
22
+ </ToggleButton>
23
+ ```
24
+
25
+ ## Variants and sizes
26
+
27
+ - `variant`: `default`, `outline`, or `filled`.
28
+ - `size`: `xs`, `sm`, `default`, or `lg`.
29
+ - `iconOnly` makes the control square and requires `aria-label`.
30
+
31
+ ## Choosing the right control
32
+
33
+ - Use `Button` for a momentary action.
34
+ - Use `ToggleButton` for one independent visible mode or tool.
35
+ - Use `SegmentedControl` for exactly one choice from a small set.
36
+ - Use `Switch` for a persistent setting that takes effect immediately.
37
+
38
+ ## Keyboard and accessibility
39
+
40
+ Radix supplies button and `aria-pressed` semantics. Space and Enter toggle the
41
+ state. A visible text label or `aria-label` must identify the action; state
42
+ must not be communicated through color alone.
43
+
44
+ ## Don't
45
+
46
+ - Do not use a toggle for a one-time command.
47
+ - Do not group unrelated toggles into a segmented control.
48
+ - Do not put a checkbox inside a toggle button.
@@ -19,3 +19,8 @@ Compact pane chrome for context and actions.
19
19
  Use one toolbar per pane. Put the current context before actions and keep one
20
20
  clear primary action. Toolbars are not marketing headers. Icon-only actions
21
21
  need labels and tooltips.
22
+
23
+ The default toolbar uses `material="regular"`. The `plain` and `panel` variants
24
+ default to `material="none"`; pass a material explicitly only when the toolbar
25
+ actually floats over content. Reserve `material="clear"` for compact controls
26
+ over media or a richly colored canvas.
@@ -0,0 +1,31 @@
1
+ # Tooltip
2
+
3
+ Tooltips provide short, non-interactive clarification for an already named
4
+ control. They are not a replacement for an accessible name or visible
5
+ instructions.
6
+
7
+ `ThemeProvider` installs one shared `TooltipProvider`, giving neighboring
8
+ tooltips a consistent delay and grace period:
9
+
10
+ ```tsx
11
+ <Tooltip>
12
+ <TooltipTrigger asChild>
13
+ <IconButton label="Search" variant="ghost">
14
+ <Search />
15
+ </IconButton>
16
+ </TooltipTrigger>
17
+ <TooltipContent>
18
+ Search
19
+ <TooltipShortcut>⌘F</TooltipShortcut>
20
+ </TooltipContent>
21
+ </Tooltip>
22
+ ```
23
+
24
+ Use a local `TooltipProvider` only when a bounded region needs a deliberate
25
+ delay override. Do not put links, buttons, forms, or paragraphs of help inside
26
+ a tooltip; use `Popover` instead.
27
+
28
+ A disabled button does not emit pointer events. When it needs an explanation,
29
+ wrap it in a focusable neutral element and use that wrapper as the trigger.
30
+ Give the wrapper an accessible description without making the tooltip its only
31
+ name.