@nocoo/basalt 3.2.1 → 3.2.4

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 (192) hide show
  1. package/README.md +25 -19
  2. package/ai/COMPATIBILITY.md +41 -36
  3. package/ai/DESIGN.md +53 -47
  4. package/ai/INTEGRATION.md +814 -820
  5. package/ai/RECIPES.md +334 -135
  6. package/ai/USAGE.md +2 -2
  7. package/ai/registry.json +384 -27
  8. package/ai/sources.json +2 -2
  9. package/dist/assets/brand-mark.js +1 -2
  10. package/dist/charts/area.js +1 -2
  11. package/dist/charts/bar.js +1 -2
  12. package/dist/charts/bullet.js +1 -2
  13. package/dist/charts/chart-colors.js +1 -2
  14. package/dist/charts/charts.js +1 -2
  15. package/dist/charts/config.js +1 -2
  16. package/dist/charts/custom-chart.js +1 -2
  17. package/dist/charts/date-navigation.js +1 -2
  18. package/dist/charts/donut.js +1 -2
  19. package/dist/charts/frame.js +1 -2
  20. package/dist/charts/frame.js.map +1 -1
  21. package/dist/charts/funnel.js +1 -2
  22. package/dist/charts/gauge.js +1 -2
  23. package/dist/charts/grouped-bar.js +1 -2
  24. package/dist/charts/heatmap-calendar.js +3 -7
  25. package/dist/charts/heatmap-calendar.js.map +1 -1
  26. package/dist/charts/heatmap-matrix.js +1 -2
  27. package/dist/charts/item-list.js +1 -2
  28. package/dist/charts/legend.js +1 -2
  29. package/dist/charts/line.js +1 -2
  30. package/dist/charts/palette.js +1 -2
  31. package/dist/charts/radar.js +1 -2
  32. package/dist/charts/sample.js +1 -2
  33. package/dist/charts/sankey.js +1 -2
  34. package/dist/charts/series.js +1 -2
  35. package/dist/charts/slot-bar.js +1 -2
  36. package/dist/charts/sparkline.js +1 -2
  37. package/dist/charts/stacked-bar.js +1 -2
  38. package/dist/charts/stat-card.js +1 -2
  39. package/dist/charts/timeline.js +1 -2
  40. package/dist/charts/timeseries.js +1 -2
  41. package/dist/charts/tooltip.js +31 -27
  42. package/dist/charts/tooltip.js.map +1 -1
  43. package/dist/components/accordion.js +1 -2
  44. package/dist/components/alert-dialog.js +1 -2
  45. package/dist/components/app-header.js +1 -2
  46. package/dist/components/app-shell.js +1 -2
  47. package/dist/components/approval-card.js +1 -2
  48. package/dist/components/autocomplete.js +1 -2
  49. package/dist/components/avatar.js +1 -2
  50. package/dist/components/badge.js +1 -2
  51. package/dist/components/banner.js +1 -2
  52. package/dist/components/basalt-mark.js +1 -2
  53. package/dist/components/battery-meter.js +1 -2
  54. package/dist/components/breadcrumbs.js +1 -2
  55. package/dist/components/button.d.ts +1 -1
  56. package/dist/components/button.js +3 -3
  57. package/dist/components/button.js.map +1 -1
  58. package/dist/components/chat-bubble.js +1 -2
  59. package/dist/components/chat-composer.js +1 -2
  60. package/dist/components/chat-header.js +1 -2
  61. package/dist/components/chat-inbox.js +1 -2
  62. package/dist/components/chat-markdown.js +1 -2
  63. package/dist/components/chat-message.js +1 -2
  64. package/dist/components/checkbox.js +1 -2
  65. package/dist/components/clipboard-text.js +1 -2
  66. package/dist/components/code.js +1 -2
  67. package/dist/components/collapsible.js +1 -2
  68. package/dist/components/collapsible.js.map +1 -1
  69. package/dist/components/combobox.js +1 -2
  70. package/dist/components/command-palette.js +1 -2
  71. package/dist/components/confirm-dialog.js +3 -12
  72. package/dist/components/confirm-dialog.js.map +1 -1
  73. package/dist/components/context-cards.js +1 -2
  74. package/dist/components/context-menu.js +1 -2
  75. package/dist/components/data-table.js +2 -7
  76. package/dist/components/data-table.js.map +1 -1
  77. package/dist/components/date-picker.js +7 -18
  78. package/dist/components/date-picker.js.map +1 -1
  79. package/dist/components/delete-resource.js +1 -2
  80. package/dist/components/description-list.js +1 -2
  81. package/dist/components/dialog.js +1 -2
  82. package/dist/components/diff-table.js +1 -2
  83. package/dist/components/dock.js +1 -2
  84. package/dist/components/dock.js.map +1 -1
  85. package/dist/components/dropdown-menu.js +1 -2
  86. package/dist/components/editable-nav-item.js +1 -2
  87. package/dist/components/empty.js +1 -2
  88. package/dist/components/fab.js +1 -2
  89. package/dist/components/field.js +1 -2
  90. package/dist/components/file-dropzone.js +1 -2
  91. package/dist/components/filter-bar.js +1 -2
  92. package/dist/components/flow.js +1 -2
  93. package/dist/components/grid.js +1 -2
  94. package/dist/components/hover-card.js +1 -2
  95. package/dist/components/icon-picker.js +1 -2
  96. package/dist/components/inline-editable.js +1 -2
  97. package/dist/components/input-area.js +1 -2
  98. package/dist/components/input-group.js +2 -3
  99. package/dist/components/input-group.js.map +1 -1
  100. package/dist/components/input.js +1 -2
  101. package/dist/components/label.js +1 -2
  102. package/dist/components/layer-card.js +1 -2
  103. package/dist/components/link.js +1 -2
  104. package/dist/components/loader.js +1 -2
  105. package/dist/components/loading-screen.js +1 -2
  106. package/dist/components/menu-bar.js +1 -2
  107. package/dist/components/meter.js +1 -2
  108. package/dist/components/multi-select.js +1 -2
  109. package/dist/components/navigation-menu.js +1 -2
  110. package/dist/components/overlay.js +1 -2
  111. package/dist/components/page-header.js +1 -2
  112. package/dist/components/pagination.js +1 -2
  113. package/dist/components/popover.js +1 -2
  114. package/dist/components/prompt-bar.js +1 -2
  115. package/dist/components/radio.js +2 -7
  116. package/dist/components/radio.js.map +1 -1
  117. package/dist/components/recommendation-card.js +1 -2
  118. package/dist/components/resource-list.js +1 -2
  119. package/dist/components/responsive-master-detail.js +1 -2
  120. package/dist/components/scroll-area.js +1 -2
  121. package/dist/components/section-rule.js +1 -2
  122. package/dist/components/segment-control.js +1 -2
  123. package/dist/components/select.js +1 -2
  124. package/dist/components/sensitive-input.js +1 -2
  125. package/dist/components/separator.js +1 -2
  126. package/dist/components/sheet.js +1 -2
  127. package/dist/components/sidebar.d.ts +53 -19
  128. package/dist/components/sidebar.js +201 -100
  129. package/dist/components/sidebar.js.map +1 -1
  130. package/dist/components/skeleton-line.js +1 -2
  131. package/dist/components/slider.js +1 -2
  132. package/dist/components/stat-strip.js +1 -2
  133. package/dist/components/switch.js +1 -2
  134. package/dist/components/table-of-contents.js +1 -2
  135. package/dist/components/table-pager.js +1 -2
  136. package/dist/components/table.js +1 -2
  137. package/dist/components/tabs.js +1 -2
  138. package/dist/components/tag-badge.js +1 -2
  139. package/dist/components/tag-color-picker.js +1 -2
  140. package/dist/components/text.js +1 -2
  141. package/dist/components/theme-toggle.js +1 -2
  142. package/dist/components/thinking.js +1 -2
  143. package/dist/components/toast.js +1 -2
  144. package/dist/components/toggle-group.js +1 -2
  145. package/dist/components/toggle.js +1 -2
  146. package/dist/components/tool-chips.js +1 -2
  147. package/dist/components/toolbar.js +1 -2
  148. package/dist/components/tooltip.js +1 -2
  149. package/dist/components/typeahead-field.js +6 -21
  150. package/dist/components/typeahead-field.js.map +1 -1
  151. package/dist/components/upload-queue.js +1 -2
  152. package/dist/index.d.ts +1 -1
  153. package/dist/index.js +11 -11
  154. package/dist/models/agent-feedback.js +1 -2
  155. package/dist/models/avatar.js +1 -2
  156. package/dist/models/code.js +1 -2
  157. package/dist/models/context-cards.js +1 -2
  158. package/dist/models/diff-table.js +1 -2
  159. package/dist/models/recommendation.js +1 -2
  160. package/dist/providers/accent.js +2 -7
  161. package/dist/providers/accent.js.map +1 -1
  162. package/dist/providers/link.js +1 -2
  163. package/dist/providers/theme.js +2 -7
  164. package/dist/providers/theme.js.map +1 -1
  165. package/dist/styles/standalone.css +55 -11
  166. package/dist/styles/tailwind.css +2 -0
  167. package/dist/styles/tokens.css +51 -6
  168. package/dist/utils/cn.js +1 -2
  169. package/dist/utils/control-surface.js +1 -2
  170. package/dist/utils/navigation.d.ts +1 -1
  171. package/dist/utils/navigation.js +2 -3
  172. package/dist/utils/navigation.js.map +1 -1
  173. package/dist/utils/preference-store.js +1 -2
  174. package/dist/utils/selection-indicator.js +1 -2
  175. package/dist/utils/use-checkable-group.js +1 -2
  176. package/dist/utils/use-hover-highlight.js +2 -3
  177. package/dist/utils/use-hover-highlight.js.map +1 -1
  178. package/dist/viewmodels/use-approval-card.js +11 -13
  179. package/dist/viewmodels/use-approval-card.js.map +1 -1
  180. package/dist/viewmodels/use-chat-composer.js +1 -2
  181. package/dist/viewmodels/use-chat-message.js +1 -2
  182. package/dist/viewmodels/use-code-block.js +1 -2
  183. package/dist/viewmodels/use-code-block.js.map +1 -1
  184. package/dist/viewmodels/use-context-cards.js +1 -2
  185. package/dist/viewmodels/use-diff-table.js +1 -2
  186. package/dist/viewmodels/use-diff-table.js.map +1 -1
  187. package/dist/viewmodels/use-loader.js +1 -2
  188. package/dist/viewmodels/use-recommendation-card.js +1 -2
  189. package/dist/viewmodels/use-recommendation-card.js.map +1 -1
  190. package/dist/viewmodels/use-thinking.js +1 -2
  191. package/dist/viewmodels/use-tool-chips.js +1 -2
  192. package/package.json +1 -1
package/README.md CHANGED
@@ -52,12 +52,14 @@ Import order is strict. Register Basalt tokens before the Tailwind framework imp
52
52
  @import "tailwindcss";
53
53
 
54
54
  @layer base {
55
- html, body, #root {
56
- height: 100%;
57
- }
58
- body {
59
- @apply bg-basalt-background text-basalt-foreground antialiased;
60
- }
55
+ html,
56
+ body,
57
+ #root {
58
+ height: 100%;
59
+ }
60
+ body {
61
+ @apply bg-basalt-background text-basalt-foreground antialiased;
62
+ }
61
63
  }
62
64
  ```
63
65
 
@@ -79,21 +81,23 @@ Standalone CSS contains compiled design tokens, scoped control classes, keyframe
79
81
  ## Import Architecture
80
82
 
81
83
  ### 1. Root Barrel (`@nocoo/basalt`)
84
+
82
85
  Contains lightweight base components, inputs, layout surfaces, and providers:
83
86
  ```tsx compile:pkg-readme-root-import
84
87
  import {
85
- Button,
86
- Input,
87
- LayerCard,
88
- ThemeProvider,
89
- ThemeToggle,
90
- Tooltip,
91
- Toast,
92
- Sidebar
88
+ Button,
89
+ Input,
90
+ LayerCard,
91
+ ThemeProvider,
92
+ ThemeToggle,
93
+ Tooltip,
94
+ Toast,
95
+ Sidebar,
93
96
  } from "@nocoo/basalt";
94
97
  ```
95
98
 
96
99
  ### 2. Granular Subpaths (`@nocoo/basalt/components/*`, `@nocoo/basalt/charts/*`, `@nocoo/basalt/providers/*`)
100
+
97
101
  Keeps initial bundle size small by isolating complex or specialized dependencies:
98
102
  ```tsx compile:pkg-readme-granular-import
99
103
  import { DatePicker } from "@nocoo/basalt/components/date-picker";
@@ -107,6 +111,7 @@ import { useTheme } from "@nocoo/basalt/providers/theme";
107
111
  ## Framework Integration Highlights
108
112
 
109
113
  ### React 19 & Next.js Client Boundaries
114
+
110
115
  Basalt controls require browser event listeners and React context. When using Next.js App Router, render Basalt components within a client module:
111
116
 
112
117
  ```tsx compile:pkg-readme-client-app
@@ -116,15 +121,16 @@ Basalt controls require browser event listeners and React context. When using Ne
116
121
  import { Button, ThemeProvider } from "@nocoo/basalt";
117
122
 
118
123
  export function BasaltApp() {
119
- return (
120
- <ThemeProvider>
121
- <Button variant="default">Client Control</Button>
122
- </ThemeProvider>
123
- );
124
+ return (
125
+ <ThemeProvider>
126
+ <Button variant="default">Client Control</Button>
127
+ </ThemeProvider>
128
+ );
124
129
  }
125
130
  ```
126
131
 
127
132
  ### Server-Side Theme Pre-Hydration
133
+
128
134
  To eliminate theme flashing (FOUC), inject the theme class before React renders:
129
135
 
130
136
  ```html
@@ -30,6 +30,7 @@ The initial public baseline is locked to version **`2.0.3`** (commit `e61efc1`).
30
30
  - `@nocoo/basalt/styles/standalone` (Zero-dependency compiled tokens and utility CSS)
31
31
 
32
32
  ### Machine Verification
33
+
33
34
  All 110 entrypoints, their export targets, 3 CSS paths, and all 572 exported symbols (with value/type fidelity) are cataloged in `packages/basalt/public-api-baseline.json` and verified via `packages/basalt/scripts/verify-public-api.ts`. No entrypoint or public symbol present in this baseline may be removed or have its value/type identity degraded without a major version bump.
34
35
 
35
36
  ---
@@ -37,8 +38,9 @@ All 110 entrypoints, their export targets, 3 CSS paths, and all 572 exported sym
37
38
  ## 2. Export Architecture & Root vs. Granular Principles
38
39
 
39
40
  ### Root Barrel (`@nocoo/basalt`)
41
+
40
42
  The root barrel is reserved for lightweight, frequently-used leaves, standard inputs, core surfaces, and global providers.
41
- - **Included on root:** `Button`, `Input`, `Checkbox`, `Switch`, `Badge`, `Text`, `Label`, `Separator`, `LayerCard`, `DescriptionList`, `Sidebar`, `Dialog`, `Sheet`, `Popover`, `Tooltip`, `Toast`, `ThemeProvider`, `ThemeToggle`, `LinkProvider`.
43
+ - **Included on root:** `Button`, `Input`, `Checkbox`, `Switch`, `Badge`, `Text`, `Label`, `Separator`, `LayerCard`, `DescriptionList`, `Sidebar`, `SidebarBrand`, `SidebarToggle`, `Dialog`, `Sheet`, `Popover`, `Tooltip`, `Toast`, `ThemeProvider`, `ThemeToggle`, `LinkProvider`.
42
44
  - **Excluded from root:**
43
45
  - Radio inputs (`@nocoo/basalt/components/radio`)
44
46
  - Heavy visualization libraries (`@nocoo/basalt/charts/*`)
@@ -47,6 +49,7 @@ The root barrel is reserved for lightweight, frequently-used leaves, standard in
47
49
  - Application frame layout chrome (`@nocoo/basalt/components/app-shell`, `app-header`, `page-header`, `section-rule`)
48
50
 
49
51
  ### Wildcard Subpaths & Legacy Internal Helpers
52
+
50
53
  <a id="wildcard-subpaths"></a>
51
54
  In `v2.0.3`, wildcard exports (`./components/*`, `./charts/*`, `./providers/*`) exposed all non-test modules in the package, including internal building blocks:
52
55
  - **`@nocoo/basalt/components/typeahead-field`**: Internal composite input controller for autocomplete and combobox (`TypeaheadField`, `TypeaheadItem`). Provides popup list and keyboard navigation wiring.
@@ -64,13 +67,14 @@ In `v2.0.3`, wildcard exports (`./components/*`, `./charts/*`, `./providers/*`)
64
67
 
65
68
  Basalt strictly follows [SemVer 2.0.0](https://semver.org/):
66
69
 
67
- | Change Level | Permitted Changes | Examples |
68
- |---|---|---|
69
- | **PATCH** (`2.0.x`) | Backward-compatible bug fixes, internal optimizations, visual refinements that do not alter layout bounding boxes or break existing snapshots. | Fixing event propagation in `Button`, correcting border contrast ratio, fixing broken types. |
70
- | **MINOR** (`2.x.0`) | Additive, backward-compatible features; new components, new optional props, new granular export paths. | Adding a new `FilterBar` component, introducing an optional `variant` prop to `Badge`. |
71
- | **MAJOR** (`3.0.0`) | Breaking changes to existing public component signatures, DOM/ARIA structures, or removal of deprecated export paths. | Renaming required props, removing legacy wildcard subpaths, updating peer dependency minimums to React 20. |
70
+ | Change Level | Permitted Changes | Examples |
71
+ | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
72
+ | **PATCH** (`2.0.x`) | Backward-compatible bug fixes, internal optimizations, visual refinements that do not alter layout bounding boxes or break existing snapshots. | Fixing event propagation in `Button`, correcting border contrast ratio, fixing broken types. |
73
+ | **MINOR** (`2.x.0`) | Additive, backward-compatible features; new components, new optional props, new granular export paths. | Adding a new `FilterBar` component, introducing an optional `variant` prop to `Badge`. |
74
+ | **MAJOR** (`3.0.0`) | Breaking changes to existing public component signatures, DOM/ARIA structures, or removal of deprecated export paths. | Renaming required props, removing legacy wildcard subpaths, updating peer dependency minimums to React 20. |
72
75
 
73
76
  ### Layout & Default Geometry Policy
77
+
74
78
  Changes to default geometry (such as outer padding, default margins, or intrinsic dimensions) alter the visual balance of consuming applications.
75
79
  - **Bug Fixes vs Breaking Changes:** Correcting an unintended layout collapse or overflow bug (e.g., popup clipping in cards or chart height collapsing to 0px) is considered a patch/minor fix. Altering default container padding (e.g. changing `LayerCard` padding from `none` to `md`) affects caller assumptions.
76
80
  - If default geometry must evolve, before/after migration notes must be published in `CHANGELOG.md`, and backward-compatible props or opt-ins must be offered.
@@ -93,6 +97,7 @@ Basalt chart components build upon modular configuration tokens and series utili
93
97
 
94
98
  <a id="chart-config"></a>
95
99
  ### Chart Configuration (`@nocoo/basalt/charts/config`)
100
+
96
101
  Defines shared tokens, styles, and props for cartesian charts:
97
102
  - **Constants**:
98
103
  - `CHART_TYPE`: Font sizes (`axisFontSize: 11`, `legendFontSize: 12`, `tooltipTitleSize: 12`, `tooltipBodySize: 12`), `tooltipDot: 8`, stroke width (`strokeWidth: 2`), `gridDash: "3 3"`, `gridOpacity: 0.15`, and `areaFillAlpha: 0.2`.
@@ -117,6 +122,7 @@ Defines shared tokens, styles, and props for cartesian charts:
117
122
 
118
123
  <a id="chart-series"></a>
119
124
  ### Chart Series Utilities (`@nocoo/basalt/charts/series`)
125
+
120
126
  Manages series descriptor shapes, point definitions, and data key fallbacks:
121
127
  - **Types**:
122
128
  - `ChartSeriesDescriptor`: `{ key: string, label?: string, color?: string }`.
@@ -133,7 +139,6 @@ Manages series descriptor shapes, point definitions, and data key fallbacks:
133
139
  - `applyLeadColor(items: ChartSeriesDescriptor[], color?: string): ChartSeriesDescriptor[]`: If `color` is provided and the first item does not specify a `color` (`item.color ?? color`), sets the first item's color. Preserves an explicit first-item color.
134
140
  - `xyFallbackKeys(data: Array<{ y2?: number; y3?: number }>): string[]`: Scans data array and dynamically includes `"y2"` and `"y3"` if present, returning `["y", ...]` keys. Compatible with legacy XY series fallback.
135
141
 
136
-
137
142
  ---
138
143
 
139
144
  <a id="6-unreleased-migration-notes-p1p10"></a>
@@ -143,14 +148,14 @@ These notes cover the components, documentation, examples and palette changes in
143
148
 
144
149
  ### Palettes and production URL
145
150
 
146
- | Before | Current behavior | Consumer action |
147
- |---|---|---|
148
- | 24 control accents sharing chart tokens | 12 iMac / iPhone 5C-inspired accents on `--basalt-accent-1…12` | Build pickers from `useAccent().swatches`; do not assume the former count, order, labels, or token values. |
149
- | 24 distinct `CHART_COLORS` entries | Fixed five-color Blue / Pink / Green / Yellow / Gray cycle; the first four match classic control swatches exactly | Replace direct indexing beyond 4 with `getChartColor(index)` or `index % CHART_COLORS.length`. This is an intentional visual and runtime-value change, not a claim that all prior palette behavior is unchanged. |
150
- | Numbered chart tokens and 24 `chart` keys | Existing names retained as aliases of five chart colors | Keep imports; expect repeated colors. Use explicit per-series colors and descriptive legends where five categories are insufficient. |
151
- | Presets only | Optional `AccentProvider.paletteOverrides` with light/dark HSL pairs | Application owns validation and persistence. Overrides affect control swatches and semantic primary, never chart tokens. |
152
- | Ring remainder tied to a series color | Theme-aware neutral `chartMuted` track | No prop migration. Gauge is static under reduced motion and displays 0, partial, and full values without a black remainder. |
153
- | `https://basalt.hexly.ai` | `https://basaltui.com` | Update bookmarks and production links. Browser storage is origin-scoped, so old-domain theme/palette preferences cannot transfer automatically. Local `basalt.dev.hexly.ai` is unchanged. |
151
+ | Before | Current behavior | Consumer action |
152
+ | ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
153
+ | 24 control accents sharing chart tokens | 12 iMac / iPhone 5C-inspired accents on `--basalt-accent-1…12` | Build pickers from `useAccent().swatches`; do not assume the former count, order, labels, or token values. |
154
+ | 24 distinct `CHART_COLORS` entries | Fixed five-color Blue / Pink / Green / Yellow / Gray cycle; the first four match classic control swatches exactly | Replace direct indexing beyond 4 with `getChartColor(index)` or `index % CHART_COLORS.length`. This is an intentional visual and runtime-value change, not a claim that all prior palette behavior is unchanged. |
155
+ | Numbered chart tokens and 24 `chart` keys | Existing names retained as aliases of five chart colors | Keep imports; expect repeated colors. Use explicit per-series colors and descriptive legends where five categories are insufficient. |
156
+ | Presets only | Optional `AccentProvider.paletteOverrides` with light/dark HSL pairs | Application owns validation and persistence. Overrides affect control swatches and semantic primary, never chart tokens. |
157
+ | Ring remainder tied to a series color | Theme-aware neutral `chartMuted` track | No prop migration. Gauge is static under reduced motion and displays 0, partial, and full values without a black remainder. |
158
+ | `https://basalt.hexly.ai` | `https://basaltui.com` | Update bookmarks and production links. Browser storage is origin-scoped, so old-domain theme/palette preferences cannot transfer automatically. Local `basalt.dev.hexly.ai` is unchanged. |
154
159
 
155
160
  Chart gray retains its prior light/dark values. Marks use solid candy colors without contrasting outlines or shadows; their fills are not darkened. Raw candy fills can fall below 3:1 on light surfaces; use descriptive labels and `summary` / `dataAlternative` alongside them. Custom control palettes remain independent.
156
161
 
@@ -160,31 +165,31 @@ v2.1.0 includes the palette count and value changes above as an explicit excepti
160
165
 
161
166
  Persisted accent IDs are normalized on reads and selections:
162
167
 
163
- | Old ID | Retained ID |
164
- |---|---|
165
- | `jade`, `seafoam` | `teal` |
166
- | `vermilion`, `crimson` | `red` |
167
- | `magenta` | `rose` |
168
- | `orchid` | `purple` |
169
- | `cobalt` | `indigo` |
170
- | `steel` | `primary` |
171
- | `cadet` | `sky` |
172
- | `olive` | `lime` |
173
- | `gold` | `amber` |
174
- | `tangerine` | `orange` |
168
+ | Old ID | Retained ID |
169
+ | ---------------------- | ----------- |
170
+ | `jade`, `seafoam` | `teal` |
171
+ | `vermilion`, `crimson` | `red` |
172
+ | `magenta` | `rose` |
173
+ | `orchid` | `purple` |
174
+ | `cobalt` | `indigo` |
175
+ | `steel` | `primary` |
176
+ | `cadet` | `sky` |
177
+ | `olive` | `lime` |
178
+ | `gold` | `amber` |
179
+ | `tangerine` | `orange` |
175
180
 
176
181
  Other retained IDs keep their identity with the new palette values. Unknown IDs fall back to `primary`. Use IDs rather than array positions for saved selections.
177
182
 
178
183
  ### Components and application recipes
179
184
 
180
- | Area | Additions and compatibility | Application responsibility |
181
- |---|---|---|
182
- | Resource screens | Additive DataTable sorting, manual processing/pagination, header and retry options; ResourceList state/toolbar/bulk/footer slots; granular BatteryMeter | Queries, authorization, selection policy, total counts and backend requests |
183
- | Filtering | MultiSelect, FilterBar and FilterChip, including controlled search and native form/reset support | Search results and business filter state |
184
- | Uploads | FileDropzone plus UploadQueue/UploadItem, validation, progress and action callbacks | Transport, retry/cancel, object URL lifetime and server validation |
185
- | Editing and navigation | InlineEditable, EditableNavItem/FolderNavItem, IconPicker, TagBadge/TagColorPicker, ResponsiveMasterDetail | Persistence, routing, allowed icons, stable item IDs and tree policy |
186
- | App templates | Complete AppFrame, Login and Resources modules in `ai/RECIPES.md`, compiled from the installed package | Router adapters, authentication, permissions, API calls and real data |
187
- | Chart details | Values heatmap and Timeline rails use fixed chart tokens; optional `TimelineEvent.textColor` pairs custom event backgrounds with readable titles and subtitles | Choose text color for custom backgrounds; omitted `textColor` keeps the legacy white treatment for explicit event colors |
188
- | Documentation | Generated props retain generics, callback/constructor union precedence, readonly arrays and tuples | Use the declared type parameters; generated text no longer substitutes `unknown` for caller data types |
185
+ | Area | Additions and compatibility | Application responsibility |
186
+ | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
187
+ | Resource screens | Additive DataTable sorting, manual processing/pagination, header and retry options; ResourceList state/toolbar/bulk/footer slots; granular BatteryMeter | Queries, authorization, selection policy, total counts and backend requests |
188
+ | Filtering | MultiSelect, FilterBar and FilterChip, including controlled search and native form/reset support | Search results and business filter state |
189
+ | Uploads | FileDropzone plus UploadQueue/UploadItem, validation, progress and action callbacks | Transport, retry/cancel, object URL lifetime and server validation |
190
+ | Editing and navigation | InlineEditable, EditableNavItem/FolderNavItem, IconPicker, TagBadge/TagColorPicker, ResponsiveMasterDetail | Persistence, routing, allowed icons, stable item IDs and tree policy |
191
+ | App templates | Complete AppFrame, Login and Resources modules in `ai/RECIPES.md`, compiled from the installed package | Router adapters, authentication, permissions, API calls and real data |
192
+ | Chart details | Values heatmap and Timeline rails use fixed chart tokens; optional `TimelineEvent.textColor` pairs custom event backgrounds with readable titles and subtitles | Choose text color for custom backgrounds; omitted `textColor` keeps the legacy white treatment for explicit event colors |
193
+ | Documentation | Generated props retain generics, callback/constructor union precedence, readonly arrays and tuples | Use the declared type parameters; generated text no longer substitutes `unknown` for caller data types |
189
194
 
190
195
  New workflow modules stay on granular subpaths. Existing string table headers, legacy chart `y`/`y2`/`y3` inputs, required ResourceList data, and explicit series colors remain supported. No automatic downstream migration is performed. A full tree adapter, draggable SplitPane, and maps remain outside this release scope.
package/ai/DESIGN.md CHANGED
@@ -28,23 +28,23 @@ different density; opening the page layout must not enlarge compact controls.
28
28
 
29
29
  ## Spacing
30
30
 
31
- | Step | Token | Value | Reference |
32
- | --- | --- | --- | --- |
33
- | Extra small | `--basalt-space-xs` | `.125rem` | 2px |
34
- | Small | `--basalt-space-sm` | `.25rem` | 4px |
35
- | Medium | `--basalt-space-md` | `.375rem` | 6px |
36
- | Large / default | `--basalt-space-lg`, `--basalt-space-default` | `.5rem` | 8px |
31
+ | Step | Token | Value | Reference |
32
+ | --------------- | --------------------------------------------- | --------- | --------- |
33
+ | Extra small | `--basalt-space-xs` | `.125rem` | 2px |
34
+ | Small | `--basalt-space-sm` | `.25rem` | 4px |
35
+ | Medium | `--basalt-space-md` | `.375rem` | 6px |
36
+ | Large / default | `--basalt-space-lg`, `--basalt-space-default` | `.5rem` | 8px |
37
37
 
38
38
  These four steps belong to control content: labels, icons, fields, actions,
39
39
  selectable rows, menus and banner content. They are not the maximum spacing for a page
40
40
  or content surface. Card and layout boundaries use their own four-step roles:
41
41
 
42
- | Step | Card token | Layout token | Value | Reference |
43
- | --- | --- | --- | --- | --- |
44
- | Small | `--basalt-space-card-sm` | `--basalt-space-layout-sm` | `.75rem` | 12px |
45
- | Medium | `--basalt-space-card` | `--basalt-space-layout` | `1rem` | 16px |
46
- | Large | `--basalt-space-card-lg` | `--basalt-space-layout-lg` | `1.5rem` | 24px |
47
- | Extra large | `--basalt-space-card-xl` | `--basalt-space-layout-xl` | `2rem` | 32px |
42
+ | Step | Card token | Layout token | Value | Reference |
43
+ | ----------- | ------------------------ | -------------------------- | -------- | --------- |
44
+ | Small | `--basalt-space-card-sm` | `--basalt-space-layout-sm` | `.75rem` | 12px |
45
+ | Medium | `--basalt-space-card` | `--basalt-space-layout` | `1rem` | 16px |
46
+ | Large | `--basalt-space-card-lg` | `--basalt-space-layout-lg` | `1.5rem` | 24px |
47
+ | Extra large | `--basalt-space-card-xl` | `--basalt-space-layout-xl` | `2rem` | 32px |
48
48
 
49
49
  Card padding defaults to medium. LayerCard headers flow into Body by default:
50
50
  16px horizontal/top insets, no bottom inset and an 8px internal gap, without a divider.
@@ -120,15 +120,15 @@ media and shell widths. They are not an alternative margin/padding scale.
120
120
  Choose a category before implementing a component. A composite's root and its
121
121
  children can have different categories. Root module inventory:
122
122
 
123
- | Category | Reference | Component modules |
124
- | --- | --- | --- |
125
- | Inline | 22px single line | `badge`, `tag-badge` |
126
- | Action | 34px default | `button`, `input`, `select`, `toggle`, `toggle-group`, `segment-control`, `autocomplete`, `combobox`, `typeahead-field`, `sensitive-input`, `input-group`, `input-area`, `clipboard-text`, `inline-editable`, `multi-select`, `date-picker`, `icon-picker`, `tag-color-picker`, `theme-toggle`, `pagination`, `table-pager` |
127
- | Banner | 38px single line | `banner`, `toast` |
128
- | Card / content surface | Natural | `layer-card`, `approval-card`, `context-cards`, `recommendation-card`, `chat-bubble`, `code`, `empty`, `file-dropzone`, `resource-list`, `upload-queue` |
129
- | Layout / composite | Natural | `accordion`, `collapsible`, `app-header`, `app-shell`, `sidebar`, `navigation-menu`, `editable-nav-item`, `breadcrumbs`, `page-header`, `section-rule`, `filter-bar`, `toolbar`, `grid`, `flow`, `field`, `description-list`, `table`, `data-table`, `diff-table`, `tabs`, `table-of-contents`, `responsive-master-detail`, `scroll-area`, `separator`, `stat-strip`, `chat-header`, `chat-inbox`, `chat-message`, `chat-markdown`, `chat-composer`, `prompt-bar`, `thinking`, `tool-chips`, `loading-screen` |
130
- | Overlay composite | Natural; triggers/actions follow Action | `dialog`, `alert-dialog`, `confirm-dialog`, `delete-resource`, `sheet`, `dock`, `popover`, `hover-card`, `tooltip`, `dropdown-menu`, `context-menu`, `menu-bar`, `command-palette` |
131
- | Graphic / text primitive | Content-specific | `avatar`, `basalt-mark`, `battery-meter`, `meter`, `loader`, `skeleton-line`, `text`, `label`, `link`, `checkbox`, `radio`, `switch`, `slider`, `fab` |
123
+ | Category | Reference | Component modules |
124
+ | ------------------------ | --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
125
+ | Inline | 22px single line | `badge`, `tag-badge` |
126
+ | Action | 34px default | `button`, `input`, `select`, `toggle`, `toggle-group`, `segment-control`, `autocomplete`, `combobox`, `typeahead-field`, `sensitive-input`, `input-group`, `input-area`, `clipboard-text`, `inline-editable`, `multi-select`, `date-picker`, `icon-picker`, `tag-color-picker`, `theme-toggle`, `pagination`, `table-pager` |
127
+ | Banner | 38px single line | `banner`, `toast` |
128
+ | Card / content surface | Natural | `layer-card`, `approval-card`, `context-cards`, `recommendation-card`, `chat-bubble`, `code`, `empty`, `file-dropzone`, `resource-list`, `upload-queue` |
129
+ | Layout / composite | Natural | `accordion`, `collapsible`, `app-header`, `app-shell`, `sidebar`, `navigation-menu`, `editable-nav-item`, `breadcrumbs`, `page-header`, `section-rule`, `filter-bar`, `toolbar`, `grid`, `flow`, `field`, `description-list`, `table`, `data-table`, `diff-table`, `tabs`, `table-of-contents`, `responsive-master-detail`, `scroll-area`, `separator`, `stat-strip`, `chat-header`, `chat-inbox`, `chat-message`, `chat-markdown`, `chat-composer`, `prompt-bar`, `thinking`, `tool-chips`, `loading-screen` |
130
+ | Overlay composite | Natural; triggers/actions follow Action | `dialog`, `alert-dialog`, `confirm-dialog`, `delete-resource`, `sheet`, `dock`, `popover`, `hover-card`, `tooltip`, `dropdown-menu`, `context-menu`, `menu-bar`, `command-palette` |
131
+ | Graphic / text primitive | Content-specific | `avatar`, `basalt-mark`, `battery-meter`, `meter`, `loader`, `skeleton-line`, `text`, `label`, `link`, `checkbox`, `radio`, `switch`, `slider`, `fab` |
132
132
 
133
133
  Graphic primitives preserve their intrinsic shape: a checkbox mark is not a
134
134
  34px square and an avatar is not a text input. Their containing action rows use
@@ -153,7 +153,8 @@ The shared classes calculate natural size as follows:
153
153
  - `basalt-action`: 14px font, 24px line box + 4px vertical padding each side +
154
154
  1px border each side = 34px. Explicit `sm` (28px) and `lg` (40px) are shared
155
155
  size variants, not ad-hoc height utilities. Icon-only actions use a minimum
156
- derived from `1lh`, not a fixed height; icons are normally 14px.
156
+ derived from `1lh`; `icon-sm` is an actual 28px by 28px control, while `icon`
157
+ retains the default 34px contract. Icons are normally 14px.
157
158
  - `basalt-banner`: 14px font, 22px line box + 12px vertical padding = 46px.
158
159
  The outer boundary uses 16px horizontal / 12px vertical panel insets; internal
159
160
  icons and actions retain compact control spacing.
@@ -191,12 +192,12 @@ interaction contracts; do not change their containment as a global workaround.
191
192
  tokens below, with `--basalt-leading-*` for line boxes. Do not shrink text to
192
193
  fit a fixed box or introduce responsive intermediate sizes.
193
194
 
194
- | Tier | Reference | Token / utility | Roles |
195
- | --- | --- | --- | --- |
196
- | Auxiliary | 12px / `.75rem` | `--basalt-text-sm` / `text-basalt-sm` | Badges, table column headers, field hints/errors, sidebar uppercase group/partition labels, secondary metadata, chart axes/legends/tooltips, inline code and code block source (`font-mono`) |
197
- | Body | 14px / `.875rem` | `--basalt-text-base` / `text-basalt-base` | Body prose, all interactive controls and option rows (including ApprovalCard, RecommendationCard, Table cells and ContextCards), card/panel titles (LayerCard.Header, CodeBlock title, ContextCards header, StatCard title, Popover title and Empty title), PageHeader descriptions and modal/sheet descriptions (DialogDescription, AlertDialogDescription and SheetDescription) |
198
- | Section | 18px / `1.125rem` | `--basalt-text-xl` / `text-basalt-xl` | Section/category h2/h3 headings, SectionRule variant="heading" h2, modal/drawer titles (DialogTitle, AlertDialogTitle and SheetTitle) |
199
- | Page / metric | 24px / `1.5rem` | `--basalt-text-3xl` / `text-basalt-3xl` | Page main title (PageHeader h1) and primary KPI numerals (StatCard value, StatStrip value and dashboard metrics) |
195
+ | Tier | Reference | Token / utility | Roles |
196
+ | ------------- | ----------------- | ----------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
197
+ | Auxiliary | 12px / `.75rem` | `--basalt-text-sm` / `text-basalt-sm` | Badges, table column headers, field hints/errors, sidebar uppercase group/partition labels, secondary metadata, chart axes/legends/tooltips, inline code and code block source (`font-mono`) |
198
+ | Body | 14px / `.875rem` | `--basalt-text-base` / `text-basalt-base` | Body prose, all interactive controls and option rows (including ApprovalCard, RecommendationCard, Table cells and ContextCards), card/panel titles (LayerCard.Header, CodeBlock title, ContextCards header, StatCard title, Popover title and Empty title), PageHeader descriptions and modal/sheet descriptions (DialogDescription, AlertDialogDescription and SheetDescription) |
199
+ | Section | 18px / `1.125rem` | `--basalt-text-xl` / `text-basalt-xl` | Section/category h2/h3 headings, SectionRule variant="heading" h2, modal/drawer titles (DialogTitle, AlertDialogTitle and SheetTitle) |
200
+ | Page / metric | 24px / `1.5rem` | `--basalt-text-3xl` / `text-basalt-3xl` | Page main title (PageHeader h1) and primary KPI numerals (StatCard value, StatStrip value and dashboard metrics) |
200
201
 
201
202
  The only independent display-scale exemptions are LandingPage
202
203
  (`src/styles/landing.css`), LoginPage (`src/pages/LoginPage.tsx`) and the 404
@@ -254,10 +255,15 @@ interaction contracts; do not change their containment as a global workaround.
254
255
  uppercase, 16px top spacing). SidebarGroup is a compact disclosure label
255
256
  (12px / `text-basalt-sm`, semibold, uppercase, 22px line box, 8px inset, 12px
256
257
  group separation), not a destination or hover-highlight target. Ordinary sidebar
257
- destinations use 14px (`text-basalt-base`) text and 8px row insets. Groups preserve
258
- keyboard expansion and chevron motion; collapsed rails omit labels. Icons stay centered on the 68px collapsed rail, and the brand
259
- mark keeps the same center when expanded. Do not trade that axis for a global
260
- left-edge alignment.
258
+ destinations use 14px (`text-basalt-base`) text and 8px row insets. Sidebar owns
259
+ a private 24px content column: its 16px region inset composes with the row's
260
+ 8px inset, without changing the shared 8px navigation inset used by other
261
+ components. Header, footer, search, group and destination content align to that
262
+ column. `SidebarBrand` reserves a fixed 20px logo slot at 24px, keeping the logo
263
+ center on the 68px rail axis during the width transition. Its action remains
264
+ reachable below the header when collapsed. Groups preserve keyboard expansion
265
+ and chevron motion; collapsed rails omit labels. Icons stay centered on the 68px
266
+ collapsed rail. Do not trade the rail axis for a global left-edge alignment.
261
267
  - Content wells use the actual surface hierarchy, not selected tokens or muted
262
268
  fills. Skeletons, progress tracks and decorative code marks may remain subdued.
263
269
  Skeleton shimmer uses foreground at 10% opacity so it remains visible in both themes.
@@ -365,12 +371,12 @@ islands rather than wrapping the whole page in another card.
365
371
  Alignment is local to a meaningful scope, not a requirement that every text node
366
372
  start at the page edge. Establish the outer rail before composing the inner one:
367
373
 
368
- | Scope | Alignment rule |
369
- | --- | --- |
370
- | Page | PageHeader and region edges share the ContentIsland rail |
371
- | Surface | Header, body and footer share their panel inset |
372
- | Field or column | Labels, controls and values follow that group's start or end rail |
373
- | Semantic slot | Checkboxes, row numbers and status glyphs reserve their own consistent space |
374
+ | Scope | Alignment rule |
375
+ | --------------- | ---------------------------------------------------------------------------- |
376
+ | Page | PageHeader and region edges share the ContentIsland rail |
377
+ | Surface | Header, body and footer share their panel inset |
378
+ | Field or column | Labels, controls and values follow that group's start or end rail |
379
+ | Semantic slot | Checkboxes, row numbers and status glyphs reserve their own consistent space |
374
380
 
375
381
  Related text keeps its rail across sorting, selection and missing optional icons.
376
382
  Numeric headings and values share the end rail; a sort glyph sits inward of that
@@ -406,15 +412,15 @@ content width, not uniformly loose controls or one global density multiplier.
406
412
  Choose the boundary before choosing a spacing token. A valid token on the wrong
407
413
  owner is still a design error:
408
414
 
409
- | Boundary | Owner | Composition |
410
- | --- | --- | --- |
411
- | Page/region separation | `ShowcasePage` / `SectionRule` | Layout gaps, no second page inset |
412
- | Painted content or navigation panel | `LayerCard` | Header and Body slots, never an unpadded painted div |
413
- | Full-width disclosure heading | `LayerCard.Header asChild` | Slot onto `CollapsibleTrigger`; one hit target, 16/12px insets |
414
- | Expanded prose or fields | `LayerCard.Body` | Inside `CollapsibleContent unstyled`; one 16px inset |
415
- | Attached code | `CodeBlock attached` / `CodeHighlighted attached` | Direct child of unstyled disclosure; code owns its 16/12px insets |
416
- | Edge-to-edge table/list | Its row/cell components | Direct card child; panel inset on edge cells, no Body with `p-0` or compensating margins |
417
- | Compact status/action strip | `Banner` | Control spacing, not a hand-drawn card |
415
+ | Boundary | Owner | Composition |
416
+ | ----------------------------------- | ------------------------------------------------- | ---------------------------------------------------------------------------------------- |
417
+ | Page/region separation | `ShowcasePage` / `SectionRule` | Layout gaps, no second page inset |
418
+ | Painted content or navigation panel | `LayerCard` | Header and Body slots, never an unpadded painted div |
419
+ | Full-width disclosure heading | `LayerCard.Header asChild` | Slot onto `CollapsibleTrigger`; one hit target, 16/12px insets |
420
+ | Expanded prose or fields | `LayerCard.Body` | Inside `CollapsibleContent unstyled`; one 16px inset |
421
+ | Attached code | `CodeBlock attached` / `CodeHighlighted attached` | Direct child of unstyled disclosure; code owns its 16/12px insets |
422
+ | Edge-to-edge table/list | Its row/cell components | Direct card child; panel inset on edge cells, no Body with `p-0` or compensating margins |
423
+ | Compact status/action strip | `Banner` | Control spacing, not a hand-drawn card |
418
424
 
419
425
  Collapsible owns visibility, focus semantics and motion; it does not add another
420
426
  surface. Its default inset is for plain standalone text. Use `unstyled` when a