@nocoo/basalt 2.2.0 → 3.1.0

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 (320) hide show
  1. package/README.md +2 -0
  2. package/ai/COMPATIBILITY.md +11 -1
  3. package/ai/DESIGN.md +398 -0
  4. package/ai/INTEGRATION.md +255 -129
  5. package/ai/RECIPES.md +51 -26
  6. package/ai/USAGE.md +4 -4
  7. package/ai/registry.json +3018 -271
  8. package/dist/charts/config.d.ts +11 -11
  9. package/dist/charts/config.js +4 -4
  10. package/dist/charts/config.js.map +1 -1
  11. package/dist/charts/date-navigation.js +10 -10
  12. package/dist/charts/date-navigation.js.map +1 -1
  13. package/dist/charts/donut.js +1 -1
  14. package/dist/charts/donut.js.map +1 -1
  15. package/dist/charts/frame.d.ts +1 -1
  16. package/dist/charts/frame.js +4 -4
  17. package/dist/charts/frame.js.map +1 -1
  18. package/dist/charts/gauge.js +5 -5
  19. package/dist/charts/gauge.js.map +1 -1
  20. package/dist/charts/heatmap-calendar.js +11 -11
  21. package/dist/charts/heatmap-calendar.js.map +1 -1
  22. package/dist/charts/heatmap-matrix.js +8 -8
  23. package/dist/charts/heatmap-matrix.js.map +1 -1
  24. package/dist/charts/item-list.js +1 -1
  25. package/dist/charts/item-list.js.map +1 -1
  26. package/dist/charts/legend.js +19 -19
  27. package/dist/charts/legend.js.map +1 -1
  28. package/dist/charts/palette.js +2 -2
  29. package/dist/charts/palette.js.map +1 -1
  30. package/dist/charts/slot-bar.js +2 -2
  31. package/dist/charts/slot-bar.js.map +1 -1
  32. package/dist/charts/sparkline.js +38 -23
  33. package/dist/charts/sparkline.js.map +1 -1
  34. package/dist/charts/stat-card.d.ts +2 -2
  35. package/dist/charts/stat-card.js +61 -58
  36. package/dist/charts/stat-card.js.map +1 -1
  37. package/dist/charts/timeline.js +18 -9
  38. package/dist/charts/timeline.js.map +1 -1
  39. package/dist/charts/tooltip.js +16 -16
  40. package/dist/charts/tooltip.js.map +1 -1
  41. package/dist/components/accordion.js +1 -1
  42. package/dist/components/accordion.js.map +1 -1
  43. package/dist/components/alert-dialog.js +4 -4
  44. package/dist/components/alert-dialog.js.map +1 -1
  45. package/dist/components/app-header.js +8 -8
  46. package/dist/components/app-header.js.map +1 -1
  47. package/dist/components/app-shell.js +1 -1
  48. package/dist/components/app-shell.js.map +1 -1
  49. package/dist/components/approval-card.d.ts +13 -0
  50. package/dist/components/approval-card.js +161 -0
  51. package/dist/components/approval-card.js.map +1 -0
  52. package/dist/components/avatar.d.ts +12 -0
  53. package/dist/components/avatar.js +39 -18
  54. package/dist/components/avatar.js.map +1 -1
  55. package/dist/components/badge.js +8 -8
  56. package/dist/components/badge.js.map +1 -1
  57. package/dist/components/banner.d.ts +2 -2
  58. package/dist/components/banner.js +9 -8
  59. package/dist/components/banner.js.map +1 -1
  60. package/dist/components/basalt-mark.js +1 -1
  61. package/dist/components/basalt-mark.js.map +1 -1
  62. package/dist/components/battery-meter.js +5 -5
  63. package/dist/components/battery-meter.js.map +1 -1
  64. package/dist/components/breadcrumbs.js +6 -6
  65. package/dist/components/breadcrumbs.js.map +1 -1
  66. package/dist/components/button.js +10 -10
  67. package/dist/components/button.js.map +1 -1
  68. package/dist/components/chat-bubble.js +4 -3
  69. package/dist/components/chat-bubble.js.map +1 -1
  70. package/dist/components/chat-composer.d.ts +21 -3
  71. package/dist/components/chat-composer.js +126 -60
  72. package/dist/components/chat-composer.js.map +1 -1
  73. package/dist/components/chat-header.js +6 -6
  74. package/dist/components/chat-header.js.map +1 -1
  75. package/dist/components/chat-inbox.js +34 -30
  76. package/dist/components/chat-inbox.js.map +1 -1
  77. package/dist/components/chat-markdown.d.ts +8 -0
  78. package/dist/components/chat-markdown.js +122 -0
  79. package/dist/components/chat-markdown.js.map +1 -0
  80. package/dist/components/chat-message.d.ts +26 -0
  81. package/dist/components/chat-message.js +145 -0
  82. package/dist/components/chat-message.js.map +1 -0
  83. package/dist/components/checkbox.js +11 -11
  84. package/dist/components/checkbox.js.map +1 -1
  85. package/dist/components/clipboard-text.js +3 -3
  86. package/dist/components/clipboard-text.js.map +1 -1
  87. package/dist/components/code.d.ts +22 -20
  88. package/dist/components/code.js +94 -32
  89. package/dist/components/code.js.map +1 -1
  90. package/dist/components/collapsible.js +8 -4
  91. package/dist/components/collapsible.js.map +1 -1
  92. package/dist/components/command-palette.js +73 -47
  93. package/dist/components/command-palette.js.map +1 -1
  94. package/dist/components/context-cards.d.ts +15 -0
  95. package/dist/components/context-cards.js +148 -0
  96. package/dist/components/context-cards.js.map +1 -0
  97. package/dist/components/context-menu.d.ts +1 -1
  98. package/dist/components/context-menu.js +18 -14
  99. package/dist/components/context-menu.js.map +1 -1
  100. package/dist/components/data-table.d.ts +14 -2
  101. package/dist/components/data-table.js +185 -135
  102. package/dist/components/data-table.js.map +1 -1
  103. package/dist/components/date-picker.js +13 -13
  104. package/dist/components/date-picker.js.map +1 -1
  105. package/dist/components/delete-resource.js +1 -1
  106. package/dist/components/delete-resource.js.map +1 -1
  107. package/dist/components/description-list.js +3 -3
  108. package/dist/components/description-list.js.map +1 -1
  109. package/dist/components/dialog.d.ts +2 -2
  110. package/dist/components/dialog.js +8 -8
  111. package/dist/components/dialog.js.map +1 -1
  112. package/dist/components/diff-table.d.ts +15 -0
  113. package/dist/components/diff-table.js +151 -0
  114. package/dist/components/diff-table.js.map +1 -0
  115. package/dist/components/dock.js +2 -2
  116. package/dist/components/dock.js.map +1 -1
  117. package/dist/components/dropdown-menu.js +23 -18
  118. package/dist/components/dropdown-menu.js.map +1 -1
  119. package/dist/components/editable-nav-item.js +63 -58
  120. package/dist/components/editable-nav-item.js.map +1 -1
  121. package/dist/components/empty.js +6 -6
  122. package/dist/components/empty.js.map +1 -1
  123. package/dist/components/fab.js +1 -1
  124. package/dist/components/fab.js.map +1 -1
  125. package/dist/components/field.js +3 -3
  126. package/dist/components/field.js.map +1 -1
  127. package/dist/components/file-dropzone.js +7 -7
  128. package/dist/components/file-dropzone.js.map +1 -1
  129. package/dist/components/filter-bar.js +6 -6
  130. package/dist/components/filter-bar.js.map +1 -1
  131. package/dist/components/flow.js +4 -3
  132. package/dist/components/flow.js.map +1 -1
  133. package/dist/components/grid.d.ts +3 -1
  134. package/dist/components/grid.js +15 -8
  135. package/dist/components/grid.js.map +1 -1
  136. package/dist/components/hover-card.js +1 -1
  137. package/dist/components/hover-card.js.map +1 -1
  138. package/dist/components/icon-picker.d.ts +8 -2
  139. package/dist/components/icon-picker.js +75 -47
  140. package/dist/components/icon-picker.js.map +1 -1
  141. package/dist/components/inline-editable.js +6 -6
  142. package/dist/components/inline-editable.js.map +1 -1
  143. package/dist/components/input-area.js +3 -3
  144. package/dist/components/input-area.js.map +1 -1
  145. package/dist/components/input-group.js +5 -5
  146. package/dist/components/input-group.js.map +1 -1
  147. package/dist/components/input.js +4 -4
  148. package/dist/components/input.js.map +1 -1
  149. package/dist/components/label.js +3 -3
  150. package/dist/components/label.js.map +1 -1
  151. package/dist/components/layer-card.d.ts +9 -4
  152. package/dist/components/layer-card.js +72 -67
  153. package/dist/components/layer-card.js.map +1 -1
  154. package/dist/components/loader.d.ts +16 -10
  155. package/dist/components/loader.js +46 -53
  156. package/dist/components/loader.js.map +1 -1
  157. package/dist/components/loading-screen.js +3 -3
  158. package/dist/components/loading-screen.js.map +1 -1
  159. package/dist/components/menu-bar.js +32 -27
  160. package/dist/components/menu-bar.js.map +1 -1
  161. package/dist/components/meter.d.ts +5 -5
  162. package/dist/components/meter.js +25 -12
  163. package/dist/components/meter.js.map +1 -1
  164. package/dist/components/multi-select.js +66 -62
  165. package/dist/components/multi-select.js.map +1 -1
  166. package/dist/components/navigation-menu.d.ts +2 -2
  167. package/dist/components/navigation-menu.js +22 -8
  168. package/dist/components/navigation-menu.js.map +1 -1
  169. package/dist/components/overlay.js +2 -2
  170. package/dist/components/overlay.js.map +1 -1
  171. package/dist/components/page-header.d.ts +3 -1
  172. package/dist/components/page-header.js +12 -12
  173. package/dist/components/page-header.js.map +1 -1
  174. package/dist/components/pagination.js +3 -3
  175. package/dist/components/pagination.js.map +1 -1
  176. package/dist/components/popover.js +18 -23
  177. package/dist/components/popover.js.map +1 -1
  178. package/dist/components/prompt-bar.d.ts +16 -0
  179. package/dist/components/prompt-bar.js +49 -0
  180. package/dist/components/prompt-bar.js.map +1 -0
  181. package/dist/components/radio.js +9 -9
  182. package/dist/components/radio.js.map +1 -1
  183. package/dist/components/recommendation-card.d.ts +13 -0
  184. package/dist/components/recommendation-card.js +123 -0
  185. package/dist/components/recommendation-card.js.map +1 -0
  186. package/dist/components/resource-list.js +1 -1
  187. package/dist/components/resource-list.js.map +1 -1
  188. package/dist/components/responsive-master-detail.js +4 -4
  189. package/dist/components/responsive-master-detail.js.map +1 -1
  190. package/dist/components/scroll-area.js +3 -3
  191. package/dist/components/scroll-area.js.map +1 -1
  192. package/dist/components/section-rule.d.ts +5 -3
  193. package/dist/components/section-rule.js +12 -12
  194. package/dist/components/section-rule.js.map +1 -1
  195. package/dist/components/segment-control.js +3 -3
  196. package/dist/components/segment-control.js.map +1 -1
  197. package/dist/components/select.js +47 -32
  198. package/dist/components/select.js.map +1 -1
  199. package/dist/components/sensitive-input.js +17 -19
  200. package/dist/components/sensitive-input.js.map +1 -1
  201. package/dist/components/sheet.d.ts +4 -4
  202. package/dist/components/sheet.js +11 -10
  203. package/dist/components/sheet.js.map +1 -1
  204. package/dist/components/sidebar.js +149 -137
  205. package/dist/components/sidebar.js.map +1 -1
  206. package/dist/components/skeleton-line.d.ts +1 -1
  207. package/dist/components/skeleton-line.js +2 -2
  208. package/dist/components/skeleton-line.js.map +1 -1
  209. package/dist/components/slider.js +2 -2
  210. package/dist/components/slider.js.map +1 -1
  211. package/dist/components/stat-strip.js +5 -4
  212. package/dist/components/stat-strip.js.map +1 -1
  213. package/dist/components/switch.js +6 -6
  214. package/dist/components/switch.js.map +1 -1
  215. package/dist/components/table-of-contents.js +5 -5
  216. package/dist/components/table-of-contents.js.map +1 -1
  217. package/dist/components/table-pager.js +2 -2
  218. package/dist/components/table-pager.js.map +1 -1
  219. package/dist/components/table.d.ts +39 -2
  220. package/dist/components/table.js +48 -17
  221. package/dist/components/table.js.map +1 -1
  222. package/dist/components/tabs.js +7 -6
  223. package/dist/components/tabs.js.map +1 -1
  224. package/dist/components/tag-badge.d.ts +10 -10
  225. package/dist/components/tag-badge.js +11 -11
  226. package/dist/components/tag-badge.js.map +1 -1
  227. package/dist/components/tag-color-picker.d.ts +8 -1
  228. package/dist/components/tag-color-picker.js +33 -25
  229. package/dist/components/tag-color-picker.js.map +1 -1
  230. package/dist/components/text.js +5 -5
  231. package/dist/components/text.js.map +1 -1
  232. package/dist/components/theme-toggle.js +1 -1
  233. package/dist/components/theme-toggle.js.map +1 -1
  234. package/dist/components/thinking.d.ts +16 -0
  235. package/dist/components/thinking.js +85 -0
  236. package/dist/components/thinking.js.map +1 -0
  237. package/dist/components/toast.js +25 -20
  238. package/dist/components/toast.js.map +1 -1
  239. package/dist/components/toggle-group.js +6 -5
  240. package/dist/components/toggle-group.js.map +1 -1
  241. package/dist/components/toggle.js +6 -6
  242. package/dist/components/toggle.js.map +1 -1
  243. package/dist/components/tool-chips.d.ts +12 -0
  244. package/dist/components/tool-chips.js +138 -0
  245. package/dist/components/tool-chips.js.map +1 -0
  246. package/dist/components/toolbar.js +3 -3
  247. package/dist/components/toolbar.js.map +1 -1
  248. package/dist/components/tooltip.js +1 -1
  249. package/dist/components/tooltip.js.map +1 -1
  250. package/dist/components/typeahead-field.js +59 -56
  251. package/dist/components/typeahead-field.js.map +1 -1
  252. package/dist/components/upload-queue.js +15 -14
  253. package/dist/components/upload-queue.js.map +1 -1
  254. package/dist/models/agent-feedback.d.ts +44 -0
  255. package/dist/models/agent-feedback.js +28 -0
  256. package/dist/models/agent-feedback.js.map +1 -0
  257. package/dist/models/avatar.d.ts +2 -0
  258. package/dist/models/avatar.js +15 -0
  259. package/dist/models/avatar.js.map +1 -0
  260. package/dist/models/code.d.ts +6 -0
  261. package/dist/models/code.js +24 -0
  262. package/dist/models/code.js.map +1 -0
  263. package/dist/models/context-cards.d.ts +13 -0
  264. package/dist/models/context-cards.js +17 -0
  265. package/dist/models/context-cards.js.map +1 -0
  266. package/dist/models/diff-table.d.ts +12 -0
  267. package/dist/models/diff-table.js +9 -0
  268. package/dist/models/diff-table.js.map +1 -0
  269. package/dist/models/recommendation.d.ts +26 -0
  270. package/dist/models/recommendation.js +23 -0
  271. package/dist/models/recommendation.js.map +1 -0
  272. package/dist/styles/base.css +14 -2
  273. package/dist/styles/standalone.css +1901 -943
  274. package/dist/styles/tailwind.css +180 -13
  275. package/dist/styles/tokens.css +681 -20
  276. package/dist/utils/cn.js +25 -4
  277. package/dist/utils/cn.js.map +1 -1
  278. package/dist/utils/control-surface.d.ts +1 -1
  279. package/dist/utils/control-surface.js +1 -1
  280. package/dist/utils/control-surface.js.map +1 -1
  281. package/dist/utils/navigation.d.ts +3 -0
  282. package/dist/utils/navigation.js +8 -0
  283. package/dist/utils/navigation.js.map +1 -0
  284. package/dist/utils/selection-indicator.d.ts +1 -1
  285. package/dist/utils/selection-indicator.js +49 -72
  286. package/dist/utils/selection-indicator.js.map +1 -1
  287. package/dist/utils/use-hover-highlight.d.ts +4 -0
  288. package/dist/utils/use-hover-highlight.js +82 -0
  289. package/dist/utils/use-hover-highlight.js.map +1 -0
  290. package/dist/viewmodels/use-approval-card.d.ts +20 -0
  291. package/dist/viewmodels/use-approval-card.js +83 -0
  292. package/dist/viewmodels/use-approval-card.js.map +1 -0
  293. package/dist/viewmodels/use-chat-composer.d.ts +16 -0
  294. package/dist/viewmodels/use-chat-composer.js +34 -0
  295. package/dist/viewmodels/use-chat-composer.js.map +1 -0
  296. package/dist/viewmodels/use-chat-message.d.ts +16 -0
  297. package/dist/viewmodels/use-chat-message.js +26 -0
  298. package/dist/viewmodels/use-chat-message.js.map +1 -0
  299. package/dist/viewmodels/use-code-block.d.ts +8 -0
  300. package/dist/viewmodels/use-code-block.js +38 -0
  301. package/dist/viewmodels/use-code-block.js.map +1 -0
  302. package/dist/viewmodels/use-context-cards.d.ts +17 -0
  303. package/dist/viewmodels/use-context-cards.js +18 -0
  304. package/dist/viewmodels/use-context-cards.js.map +1 -0
  305. package/dist/viewmodels/use-diff-table.d.ts +16 -0
  306. package/dist/viewmodels/use-diff-table.js +42 -0
  307. package/dist/viewmodels/use-diff-table.js.map +1 -0
  308. package/dist/viewmodels/use-loader.d.ts +4 -0
  309. package/dist/viewmodels/use-loader.js +22 -0
  310. package/dist/viewmodels/use-loader.js.map +1 -0
  311. package/dist/viewmodels/use-recommendation-card.d.ts +17 -0
  312. package/dist/viewmodels/use-recommendation-card.js +41 -0
  313. package/dist/viewmodels/use-recommendation-card.js.map +1 -0
  314. package/dist/viewmodels/use-thinking.d.ts +13 -0
  315. package/dist/viewmodels/use-thinking.js +18 -0
  316. package/dist/viewmodels/use-thinking.js.map +1 -0
  317. package/dist/viewmodels/use-tool-chips.d.ts +10 -0
  318. package/dist/viewmodels/use-tool-chips.js +20 -0
  319. package/dist/viewmodels/use-tool-chips.js.map +1 -0
  320. package/package.json +28 -26
@@ -1 +1 @@
1
- {"version":3,"file":"sidebar.js","names":["DialogPrimitive","SidebarContext","createContext","useSidebar","context","useContext","SidebarProvider","uncontrolled","setUncontrolled","useState","defaultCollapsed","peeking","setPeeking","width","setWidthState","clampSidebarWidth","defaultWidth","setWidth","useCallback","next","lastFocusRef","useRef","prevCollapsed","collapsed","prevOverlay","overlay","resolved","setCollapsed","onCollapsedChange","SidebarResize","cn","side","event","startX","startWidth","target","onMove","delta","move","onUp","dir","Sidebar","collapsedProp","props","body","SkeletonLine","children","resize","frameClass","BASALT_UI_CLASS","OVERLAY_MOTION","className","Dialog","open","DialogPortal","DialogOverlay","node","from","OVERLAY_LAYER","style","onMouseEnter","onMouseLeave","SidebarHeader","SidebarSearch","Search","shortcut","SidebarNav","SidebarPartition","SidebarItem","active","SidebarIconItem","SidebarGroup","setOpen","defaultOpen","Collapsible","CollapsibleTrigger","label","ChevronUp","CollapsibleContent","SidebarFooter","SidebarUser","avatar","name","email","action","ContentIsland","mobileSurface"],"sources":["../../src/components/sidebar.tsx"],"sourcesContent":["import * as DialogPrimitive from \"@radix-ui/react-dialog\";\nimport { ChevronUp, Search } from \"lucide-react\";\nimport {\n\ttype ButtonHTMLAttributes,\n\tcreateContext,\n\ttype HTMLAttributes,\n\ttype ReactNode,\n\ttype PointerEvent as ReactPointerEvent,\n\ttype RefObject,\n\tuseCallback,\n\tuseContext,\n\tuseLayoutEffect,\n\tuseRef,\n\tuseState,\n} from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { Collapsible, CollapsibleContent, CollapsibleTrigger } from \"./collapsible\";\nimport { Dialog, DialogOverlay, DialogPortal } from \"./dialog\";\nimport { OVERLAY_LAYER, OVERLAY_MOTION } from \"./overlay\";\nimport { SkeletonLine } from \"./skeleton-line\";\n\nexport type SidebarSide = \"left\" | \"right\";\n\nexport interface SidebarContextValue {\n\t/**\n\t * Whether the sidebar is currently collapsed.\n\t */\n\tcollapsed: boolean;\n\t/**\n\t * Callback to update the collapsed state.\n\t */\n\tsetCollapsed: (next: boolean) => void;\n\t/**\n\t * Which edge the sidebar occupies.\n\t */\n\tside: SidebarSide;\n\t/**\n\t * Whether the sidebar is currently displaying a loading skeleton.\n\t */\n\tloading: boolean;\n\t/**\n\t * Whether the sidebar rail expands on pointer hover.\n\t */\n\tpeek: boolean;\n\t/**\n\t * Whether the sidebar is actively hovering in peek preview mode.\n\t */\n\tpeeking: boolean;\n\t/**\n\t * Callback to update the peek preview state.\n\t */\n\tsetPeeking: (next: boolean) => void;\n\t/**\n\t * Whether the sidebar is rendering as a modal overlay drawer instead of in-flow layout chrome.\n\t */\n\toverlay: boolean;\n\t/**\n\t * Current expanded width in pixels, clamped between 180 and 400.\n\t */\n\twidth: number;\n\t/**\n\t * Callback to update the sidebar width. Value is clamped between 180 and 400 pixels.\n\t */\n\tsetWidth: (next: number) => void;\n\t/**\n\t * Reference to the last active element that held focus before opening the sidebar drawer.\n\t */\n\tlastFocusRef: RefObject<HTMLElement | null>;\n}\n\nconst SidebarContext = createContext<SidebarContextValue | null>(null);\n\n/**\n * Accesses the sidebar context value. Must be used within a `SidebarProvider`; throws an error if called outside.\n * Returns the active sidebar state and control callbacks.\n */\nexport function useSidebar(): SidebarContextValue {\n\tconst context = useContext(SidebarContext);\n\tif (!context) {\n\t\tthrow new Error(\"useSidebar must be used within SidebarProvider\");\n\t}\n\treturn context;\n}\n\nexport type SidebarProviderProps = {\n\t/**\n\t * The controlled collapsed state.\n\t */\n\tcollapsed?: boolean;\n\t/**\n\t * The uncontrolled initial collapsed state.\n\t * @default false\n\t */\n\tdefaultCollapsed?: boolean;\n\t/**\n\t * Called when the collapsed state changes.\n\t */\n\tonCollapsedChange?: (collapsed: boolean) => void;\n\t/**\n\t * Which edge the sidebar occupies.\n\t * @default left\n\t */\n\tside?: SidebarSide;\n\t/**\n\t * Replace the nav with a loading skeleton.\n\t * @default false\n\t */\n\tloading?: boolean;\n\t/**\n\t * Expand the collapsed rail on hover.\n\t * @default false\n\t */\n\tpeek?: boolean;\n\t/**\n\t * Render as an overlay instead of in-flow chrome.\n\t * @default false\n\t */\n\toverlay?: boolean;\n\t/**\n\t * Initial expanded width in pixels, clamped between 180 and 400.\n\t * @default 260\n\t */\n\tdefaultWidth?: number;\n\t/**\n\t * Sidebar chrome and page content.\n\t */\n\tchildren: ReactNode;\n};\n\nexport function SidebarProvider({\n\tcollapsed,\n\tdefaultCollapsed = false,\n\tonCollapsedChange,\n\tside = \"left\",\n\tloading = false,\n\tpeek = false,\n\toverlay = false,\n\tdefaultWidth = 260,\n\tchildren,\n}: SidebarProviderProps) {\n\tconst [uncontrolled, setUncontrolled] = useState(defaultCollapsed);\n\tconst [peeking, setPeeking] = useState(false);\n\tconst [width, setWidthState] = useState(() => clampSidebarWidth(defaultWidth));\n\tconst setWidth = useCallback((next: number) => {\n\t\tsetWidthState(clampSidebarWidth(next));\n\t}, []);\n\tconst lastFocusRef = useRef<HTMLElement | null>(null);\n\tconst prevCollapsed = useRef(collapsed ?? defaultCollapsed);\n\tconst prevOverlay = useRef(overlay);\n\tconst resolved = collapsed ?? uncontrolled;\n\tuseLayoutEffect(() => {\n\t\tif (\n\t\t\toverlay &&\n\t\t\t!resolved &&\n\t\t\t(prevCollapsed.current || !prevOverlay.current) &&\n\t\t\tdocument.activeElement instanceof HTMLElement\n\t\t) {\n\t\t\tlastFocusRef.current = document.activeElement;\n\t\t}\n\t\tprevCollapsed.current = resolved;\n\t\tprevOverlay.current = overlay;\n\t});\n\tconst setCollapsed = useCallback(\n\t\t(next: boolean) => {\n\t\t\tif (!next && document.activeElement instanceof HTMLElement) {\n\t\t\t\tlastFocusRef.current = document.activeElement;\n\t\t\t}\n\t\t\tif (collapsed === undefined) {\n\t\t\t\tsetUncontrolled(next);\n\t\t\t}\n\t\t\tonCollapsedChange?.(next);\n\t\t},\n\t\t[collapsed, onCollapsedChange],\n\t);\n\treturn (\n\t\t<SidebarContext.Provider\n\t\t\tvalue={{\n\t\t\t\tcollapsed: resolved,\n\t\t\t\tsetCollapsed,\n\t\t\t\tside,\n\t\t\t\tloading,\n\t\t\t\tpeek,\n\t\t\t\tpeeking,\n\t\t\t\tsetPeeking,\n\t\t\t\toverlay,\n\t\t\t\twidth,\n\t\t\t\tsetWidth,\n\t\t\t\tlastFocusRef,\n\t\t\t}}\n\t\t>\n\t\t\t{children}\n\t\t</SidebarContext.Provider>\n\t);\n}\n\nexport type SidebarProps = HTMLAttributes<HTMLElement> & {\n\t/**\n\t * Collapse the rail when no provider is present.\n\t * @default false\n\t */\n\tcollapsed?: boolean;\n};\n\nfunction clampSidebarWidth(next: number) {\n\treturn Math.min(400, Math.max(180, next));\n}\n\nfunction SidebarResize({\n\tside,\n\twidth,\n\tonWidth,\n}: {\n\tside: SidebarSide;\n\twidth: number;\n\tonWidth: (next: number) => void;\n}) {\n\tconst onPointerDown = (event: ReactPointerEvent<HTMLDivElement>) => {\n\t\tevent.preventDefault();\n\t\tevent.currentTarget.setPointerCapture(event.pointerId);\n\t\tconst startX = event.clientX;\n\t\tconst startWidth = width;\n\t\tconst target = event.currentTarget;\n\t\tconst onMove = (move: PointerEvent) => {\n\t\t\tconst delta = side === \"right\" ? startX - move.clientX : move.clientX - startX;\n\t\t\tonWidth(clampSidebarWidth(startWidth + delta));\n\t\t};\n\t\tconst onUp = () => {\n\t\t\ttarget.removeEventListener(\"pointermove\", onMove);\n\t\t\ttarget.removeEventListener(\"pointerup\", onUp);\n\t\t\ttarget.removeEventListener(\"pointercancel\", onUp);\n\t\t};\n\t\ttarget.addEventListener(\"pointermove\", onMove);\n\t\ttarget.addEventListener(\"pointerup\", onUp);\n\t\ttarget.addEventListener(\"pointercancel\", onUp);\n\t};\n\treturn (\n\t\t<div\n\t\t\trole=\"separator\"\n\t\t\taria-orientation=\"vertical\"\n\t\t\taria-valuenow={width}\n\t\t\taria-valuemin={180}\n\t\t\taria-valuemax={400}\n\t\t\taria-label=\"Resize sidebar\"\n\t\t\ttabIndex={0}\n\t\t\tclassName={cn(\n\t\t\t\t\"absolute top-0 h-full w-1 cursor-col-resize bg-transparent\",\n\t\t\t\tside === \"right\" ? \"left-0\" : \"right-0\",\n\t\t\t)}\n\t\t\tonPointerDown={onPointerDown}\n\t\t\tonKeyDown={(event) => {\n\t\t\t\tif (event.key !== \"ArrowLeft\" && event.key !== \"ArrowRight\") {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tevent.preventDefault();\n\t\t\t\tconst dir = event.key === \"ArrowRight\" ? 1 : -1;\n\t\t\t\tconst delta = side === \"right\" ? -dir * 8 : dir * 8;\n\t\t\t\tonWidth(clampSidebarWidth(width + delta));\n\t\t\t}}\n\t\t/>\n\t);\n}\n\nexport function Sidebar({\n\tcollapsed: collapsedProp,\n\tclassName,\n\tchildren,\n\tonMouseEnter,\n\tonMouseLeave,\n\tstyle,\n\t...props\n}: SidebarProps) {\n\tconst context = useContext(SidebarContext);\n\tconst collapsed = context\n\t\t? context.collapsed && !(context.peek && context.peeking)\n\t\t: (collapsedProp ?? false);\n\tconst side = context?.side ?? \"left\";\n\tconst overlay = context?.overlay ?? false;\n\tconst width = context?.width ?? 260;\n\tconst body = context?.loading ? (\n\t\t<div className=\"flex flex-col gap-2 p-3\" role=\"status\" aria-live=\"polite\">\n\t\t\t<SkeletonLine />\n\t\t\t<SkeletonLine />\n\t\t\t<SkeletonLine />\n\t\t</div>\n\t) : (\n\t\tchildren\n\t);\n\tconst resize =\n\t\tcontext && !collapsed ? (\n\t\t\t<SidebarResize side={side} width={context.width} onWidth={context.setWidth} />\n\t\t) : null;\n\tconst frameClass = cn(\n\t\tBASALT_UI_CLASS,\n\t\t\"relative flex shrink-0 flex-col bg-basalt-background text-sm text-basalt-foreground\",\n\t\tOVERLAY_MOTION,\n\t\tclassName,\n\t);\n\tif (overlay && context) {\n\t\treturn (\n\t\t\t<Dialog open={!context.collapsed} onOpenChange={(open) => context.setCollapsed(!open)}>\n\t\t\t\t<DialogPortal>\n\t\t\t\t\t<DialogOverlay />\n\t\t\t\t\t<DialogPrimitive.Content\n\t\t\t\t\t\tdata-basalt-sidebar=\"\"\n\t\t\t\t\t\taria-label=\"Sidebar\"\n\t\t\t\t\t\tdata-overlay=\"\"\n\t\t\t\t\t\tdata-side={side}\n\t\t\t\t\t\taria-busy={context.loading || undefined}\n\t\t\t\t\t\tonMouseEnter={onMouseEnter}\n\t\t\t\t\t\tonMouseLeave={onMouseLeave}\n\t\t\t\t\t\tref={(node) => {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tnode &&\n\t\t\t\t\t\t\t\tdocument.activeElement instanceof HTMLElement &&\n\t\t\t\t\t\t\t\t!node.contains(document.activeElement)\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tcontext.lastFocusRef.current = document.activeElement;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tonOpenAutoFocus={(event) => {\n\t\t\t\t\t\t\tconst from = \"relatedTarget\" in event ? event.relatedTarget : null;\n\t\t\t\t\t\t\tif (from instanceof HTMLElement) {\n\t\t\t\t\t\t\t\tcontext.lastFocusRef.current = from;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tonCloseAutoFocus={(event) => {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tcontext.lastFocusRef.current?.focus();\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\tframeClass,\n\t\t\t\t\t\t\tOVERLAY_LAYER,\n\t\t\t\t\t\t\t\"fixed inset-y-0 overflow-hidden shadow-md\",\n\t\t\t\t\t\t\tside === \"right\" ? \"right-0\" : \"left-0\",\n\t\t\t\t\t\t)}\n\t\t\t\t\t\tstyle={{ width, ...style }}\n\t\t\t\t\t\t{...props}\n\t\t\t\t\t>\n\t\t\t\t\t\t{body}\n\t\t\t\t\t\t{resize}\n\t\t\t\t\t</DialogPrimitive.Content>\n\t\t\t\t</DialogPortal>\n\t\t\t</Dialog>\n\t\t);\n\t}\n\treturn (\n\t\t<aside\n\t\t\tdata-basalt-sidebar=\"\"\n\t\t\tdata-collapsed={collapsed ? \"\" : undefined}\n\t\t\tdata-side={side}\n\t\t\taria-busy={context?.loading || undefined}\n\t\t\tonMouseEnter={(event) => {\n\t\t\t\tif (context?.peek && context.collapsed) {\n\t\t\t\t\tcontext.setPeeking(true);\n\t\t\t\t}\n\t\t\t\tonMouseEnter?.(event);\n\t\t\t}}\n\t\t\tonMouseLeave={(event) => {\n\t\t\t\tif (context?.peek) {\n\t\t\t\t\tcontext.setPeeking(false);\n\t\t\t\t}\n\t\t\t\tonMouseLeave?.(event);\n\t\t\t}}\n\t\t\tclassName={cn(\n\t\t\t\tframeClass,\n\t\t\t\t\"sticky transition-all duration-300 ease-in-out\",\n\t\t\t\tside === \"right\" ? \"order-last\" : undefined,\n\t\t\t\tcollapsed ? \"w-[68px] overflow-y-hidden\" : \"overflow-hidden\",\n\t\t\t)}\n\t\t\tstyle={!collapsed ? { width, ...style } : style}\n\t\t\t{...props}\n\t\t>\n\t\t\t{body}\n\t\t\t{resize}\n\t\t</aside>\n\t);\n}\n\nexport interface SidebarHeaderProps extends HTMLAttributes<HTMLDivElement> {}\n\nexport function SidebarHeader({ className, ...props }: SidebarHeaderProps) {\n\treturn <div className={cn(\"flex h-14 shrink-0 items-center px-3\", className)} {...props} />;\n}\n\n/**\n * Props for `SidebarSearch`. Renders a native `<button>` element and accepts all standard button HTML attributes and click handlers.\n */\nexport interface SidebarSearchProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n\t/**\n\t * Shortcut key display label rendered inside the trailing kbd tag. Note: this is a visual label only and does not register a global keyboard shortcut.\n\t * @default \"⌘K\"\n\t */\n\tshortcut?: string;\n}\n\nexport function SidebarSearch({\n\tshortcut = \"⌘K\",\n\tclassName,\n\tchildren,\n\t...props\n}: SidebarSearchProps) {\n\treturn (\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclassName={cn(\n\t\t\t\tBASALT_UI_CLASS,\n\t\t\t\t\"flex w-full cursor-pointer items-center gap-3 rounded-lg bg-basalt-secondary px-3 py-1.5 transition-colors hover:bg-basalt-accent\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<Search className=\"h-4 w-4 text-basalt-muted-foreground\" strokeWidth={1.5} />\n\t\t\t<span className=\"flex-1 text-left text-sm text-basalt-muted-foreground\">{children}</span>\n\t\t\t<kbd className=\"pointer-events-none hidden rounded-sm border border-basalt-border bg-basalt-card px-1.5 py-0.5 text-[10px] font-medium text-basalt-muted-foreground sm:inline-block\">\n\t\t\t\t{shortcut}\n\t\t\t</kbd>\n\t\t</button>\n\t);\n}\n\nexport interface SidebarNavProps extends HTMLAttributes<HTMLElement> {}\n\nexport function SidebarNav({ className, ...props }: SidebarNavProps) {\n\treturn (\n\t\t<nav\n\t\t\tclassName={cn(\"flex min-h-0 flex-1 flex-col overflow-y-auto overscroll-y-contain\", className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nexport interface SidebarPartitionProps extends HTMLAttributes<HTMLParagraphElement> {}\n\nexport function SidebarPartition({ className, ...props }: SidebarPartitionProps) {\n\treturn (\n\t\t<p\n\t\t\tclassName={cn(\n\t\t\t\t\"px-6 pt-3 pb-1 text-[11px] font-medium tracking-[0.14em] text-basalt-muted-foreground uppercase\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nexport type SidebarItemProps = ButtonHTMLAttributes<HTMLButtonElement> & {\n\t/**\n\t * Mark the item as the current page.\n\t * @default false\n\t */\n\tactive?: boolean;\n};\n\nexport function SidebarItem({ active = false, className, ...props }: SidebarItemProps) {\n\treturn (\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\taria-current={active ? \"page\" : undefined}\n\t\t\tclassName={cn(\n\t\t\t\t\"flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-sm font-normal transition-colors\",\n\t\t\t\tactive\n\t\t\t\t\t? \"bg-basalt-accent text-basalt-foreground\"\n\t\t\t\t\t: \"text-basalt-muted-foreground hover:bg-basalt-accent hover:text-basalt-foreground\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\n/**\n * Props for `SidebarIconItem`. Accepts standard button HTML attributes. The caller is responsible for providing accessible labeling via `aria-label` or `aria-labelledby` as icon buttons do not automatically generate accessible names.\n */\nexport interface SidebarIconItemProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n\t/**\n\t * Mark the icon button as active page item.\n\t * @default false\n\t */\n\tactive?: boolean;\n}\n\nexport function SidebarIconItem({ active = false, className, ...props }: SidebarIconItemProps) {\n\treturn (\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\taria-current={active ? \"page\" : undefined}\n\t\t\tclassName={cn(\n\t\t\t\t\"relative flex h-10 w-10 items-center justify-center rounded-lg transition-colors\",\n\t\t\t\tactive\n\t\t\t\t\t? \"bg-basalt-accent text-basalt-foreground\"\n\t\t\t\t\t: \"text-basalt-muted-foreground hover:bg-basalt-accent hover:text-basalt-foreground\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\n/**\n * Props for `SidebarGroup`. Uncontrolled collapsible section that accepts only the documented properties. It does not accept controlled open props or arbitrary DOM attributes.\n */\nexport interface SidebarGroupProps {\n\t/**\n\t * Section label displayed on the group trigger.\n\t */\n\tlabel: ReactNode;\n\t/**\n\t * Uncontrolled initial open state for the collapsible group.\n\t * @default true\n\t */\n\tdefaultOpen?: boolean;\n\t/**\n\t * Navigation items rendered inside the group.\n\t */\n\tchildren: ReactNode;\n}\n\nexport function SidebarGroup({ label, defaultOpen = true, children }: SidebarGroupProps) {\n\tconst [open, setOpen] = useState(defaultOpen);\n\treturn (\n\t\t<Collapsible open={open} onOpenChange={setOpen}>\n\t\t\t<div className=\"mt-2 px-3\">\n\t\t\t\t<CollapsibleTrigger asChild>\n\t\t\t\t\t<button type=\"button\" className=\"flex w-full items-center justify-between px-3 py-2.5\">\n\t\t\t\t\t\t<span className=\"text-sm font-normal text-basalt-muted-foreground\">{label}</span>\n\t\t\t\t\t\t<span className=\"flex h-7 w-7 shrink-0 items-center justify-center\">\n\t\t\t\t\t\t\t<ChevronUp\n\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\"h-4 w-4 text-basalt-muted-foreground transition-transform duration-200\",\n\t\t\t\t\t\t\t\t\tOVERLAY_MOTION,\n\t\t\t\t\t\t\t\t\t!open && \"rotate-180\",\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\tstrokeWidth={1.5}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</button>\n\t\t\t\t</CollapsibleTrigger>\n\t\t\t</div>\n\t\t\t<CollapsibleContent unstyled>\n\t\t\t\t<div className=\"flex flex-col gap-0.5 px-3\">{children}</div>\n\t\t\t</CollapsibleContent>\n\t\t</Collapsible>\n\t);\n}\n\nexport interface SidebarFooterProps extends HTMLAttributes<HTMLDivElement> {}\n\nexport function SidebarFooter({ className, ...props }: SidebarFooterProps) {\n\treturn <div className={cn(\"shrink-0 px-4 py-3\", className)} {...props} />;\n}\n\nexport interface SidebarUserProps {\n\t/**\n\t * User display name.\n\t */\n\tname: ReactNode;\n\t/**\n\t * Optional user email or secondary text.\n\t */\n\temail?: ReactNode;\n\t/**\n\t * Avatar element slot.\n\t */\n\tavatar?: ReactNode;\n\t/**\n\t * Trailing action slot (e.g. settings or logout button).\n\t */\n\taction?: ReactNode;\n\t/**\n\t * Additional CSS class name.\n\t */\n\tclassName?: string;\n}\n\nexport function SidebarUser({ name, email, avatar, action, className }: SidebarUserProps) {\n\treturn (\n\t\t<div className={cn(\"flex items-center gap-3\", className)}>\n\t\t\t{avatar}\n\t\t\t<div className=\"min-w-0 flex-1\">\n\t\t\t\t<p className=\"truncate text-sm font-medium text-basalt-foreground\">{name}</p>\n\t\t\t\t{email ? <p className=\"truncate text-xs text-basalt-muted-foreground\">{email}</p> : null}\n\t\t\t</div>\n\t\t\t{action}\n\t\t</div>\n\t);\n}\n\nexport interface ContentIslandProps extends HTMLAttributes<HTMLDivElement> {\n\t/** Mobile surface treatment; desktop remains an inset L1 island. @default \"inset\" */\n\tmobileSurface?: \"inset\" | \"edge-to-edge\";\n}\n\nexport function ContentIsland({\n\tmobileSurface = \"inset\",\n\tclassName,\n\t...props\n}: ContentIslandProps) {\n\treturn (\n\t\t<div\n\t\t\tdata-basalt-surface-root=\"\"\n\t\t\tdata-basalt-island={mobileSurface}\n\t\t\tclassName={cn(\n\t\t\t\t\"min-h-0 min-w-0 flex-1 bg-basalt-card text-basalt-card-foreground md:rounded-basalt-island md:p-5\",\n\t\t\t\tmobileSurface === \"inset\"\n\t\t\t\t\t? \"rounded-[16px] p-3 shadow-sm ring-1 ring-basalt-border/40\"\n\t\t\t\t\t: \"md:shadow-sm md:ring-1 md:ring-basalt-border/40\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"sidebar.js","names":["DialogPrimitive","SidebarContext","createContext","useSidebar","context","useContext","SidebarProvider","uncontrolled","setUncontrolled","useState","defaultCollapsed","peeking","setPeeking","width","setWidthState","clampSidebarWidth","defaultWidth","setWidth","useCallback","next","lastFocusRef","useRef","prevCollapsed","collapsed","prevOverlay","overlay","resolved","setCollapsed","onCollapsedChange","SidebarResize","cn","side","event","startX","startWidth","target","onMove","delta","move","onUp","dir","Sidebar","collapsedProp","props","body","SkeletonLine","children","resize","frameClass","BASALT_UI_CLASS","OVERLAY_MOTION","className","Dialog","open","DialogPortal","DialogOverlay","node","from","OVERLAY_LAYER","style","onMouseEnter","onMouseLeave","SIDEBAR_ROW_CLASS","SidebarHeader","SidebarSearch","NAV_ROW_CLASS","Search","shortcut","SidebarNav","highlightRef","useHoverHighlight","NAV_LIST_CLASS","SidebarPartition","SidebarItem","active","NAV_ITEM_CLASS","SidebarIconItem","SidebarGroup","setOpen","defaultOpen","Collapsible","CollapsibleTrigger","FOCUS_INSET","label","ChevronUp","CollapsibleContent","SidebarFooter","SidebarUser","avatar","name","email","action","ContentIsland","mobileSurface"],"sources":["../../src/components/sidebar.tsx"],"sourcesContent":["import * as DialogPrimitive from \"@radix-ui/react-dialog\";\nimport { ChevronUp, Search } from \"lucide-react\";\nimport {\n\ttype ButtonHTMLAttributes,\n\tcreateContext,\n\ttype HTMLAttributes,\n\ttype ReactNode,\n\ttype PointerEvent as ReactPointerEvent,\n\ttype RefObject,\n\tuseCallback,\n\tuseContext,\n\tuseLayoutEffect,\n\tuseRef,\n\tuseState,\n} from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { NAV_ITEM_CLASS, NAV_LIST_CLASS, NAV_ROW_CLASS } from \"../utils/navigation\";\nimport { useHoverHighlight } from \"../utils/use-hover-highlight\";\nimport { Collapsible, CollapsibleContent, CollapsibleTrigger } from \"./collapsible\";\nimport { Dialog, DialogOverlay, DialogPortal } from \"./dialog\";\nimport { FOCUS_INSET, OVERLAY_LAYER, OVERLAY_MOTION } from \"./overlay\";\nimport { SkeletonLine } from \"./skeleton-line\";\n\nexport type SidebarSide = \"left\" | \"right\";\n\nexport interface SidebarContextValue {\n\t/**\n\t * Whether the sidebar is currently collapsed.\n\t */\n\tcollapsed: boolean;\n\t/**\n\t * Callback to update the collapsed state.\n\t */\n\tsetCollapsed: (next: boolean) => void;\n\t/**\n\t * Which edge the sidebar occupies.\n\t */\n\tside: SidebarSide;\n\t/**\n\t * Whether the sidebar is currently displaying a loading skeleton.\n\t */\n\tloading: boolean;\n\t/**\n\t * Whether the sidebar rail expands on pointer hover.\n\t */\n\tpeek: boolean;\n\t/**\n\t * Whether the sidebar is actively hovering in peek preview mode.\n\t */\n\tpeeking: boolean;\n\t/**\n\t * Callback to update the peek preview state.\n\t */\n\tsetPeeking: (next: boolean) => void;\n\t/**\n\t * Whether the sidebar is rendering as a modal overlay drawer instead of in-flow layout chrome.\n\t */\n\toverlay: boolean;\n\t/**\n\t * Current expanded width in pixels, clamped between 180 and 400.\n\t */\n\twidth: number;\n\t/**\n\t * Callback to update the sidebar width. Value is clamped between 180 and 400 pixels.\n\t */\n\tsetWidth: (next: number) => void;\n\t/**\n\t * Reference to the last active element that held focus before opening the sidebar drawer.\n\t */\n\tlastFocusRef: RefObject<HTMLElement | null>;\n}\n\nconst SidebarContext = createContext<SidebarContextValue | null>(null);\n\n/**\n * Accesses the sidebar context value. Must be used within a `SidebarProvider`; throws an error if called outside.\n * Returns the active sidebar state and control callbacks.\n */\nexport function useSidebar(): SidebarContextValue {\n\tconst context = useContext(SidebarContext);\n\tif (!context) {\n\t\tthrow new Error(\"useSidebar must be used within SidebarProvider\");\n\t}\n\treturn context;\n}\n\nexport type SidebarProviderProps = {\n\t/**\n\t * The controlled collapsed state.\n\t */\n\tcollapsed?: boolean;\n\t/**\n\t * The uncontrolled initial collapsed state.\n\t * @default false\n\t */\n\tdefaultCollapsed?: boolean;\n\t/**\n\t * Called when the collapsed state changes.\n\t */\n\tonCollapsedChange?: (collapsed: boolean) => void;\n\t/**\n\t * Which edge the sidebar occupies.\n\t * @default left\n\t */\n\tside?: SidebarSide;\n\t/**\n\t * Replace the nav with a loading skeleton.\n\t * @default false\n\t */\n\tloading?: boolean;\n\t/**\n\t * Expand the collapsed rail on hover.\n\t * @default false\n\t */\n\tpeek?: boolean;\n\t/**\n\t * Render as an overlay instead of in-flow chrome.\n\t * @default false\n\t */\n\toverlay?: boolean;\n\t/**\n\t * Initial expanded width in pixels, clamped between 180 and 400.\n\t * @default 260\n\t */\n\tdefaultWidth?: number;\n\t/**\n\t * Sidebar chrome and page content.\n\t */\n\tchildren: ReactNode;\n};\n\nexport function SidebarProvider({\n\tcollapsed,\n\tdefaultCollapsed = false,\n\tonCollapsedChange,\n\tside = \"left\",\n\tloading = false,\n\tpeek = false,\n\toverlay = false,\n\tdefaultWidth = 260,\n\tchildren,\n}: SidebarProviderProps) {\n\tconst [uncontrolled, setUncontrolled] = useState(defaultCollapsed);\n\tconst [peeking, setPeeking] = useState(false);\n\tconst [width, setWidthState] = useState(() => clampSidebarWidth(defaultWidth));\n\tconst setWidth = useCallback((next: number) => {\n\t\tsetWidthState(clampSidebarWidth(next));\n\t}, []);\n\tconst lastFocusRef = useRef<HTMLElement | null>(null);\n\tconst prevCollapsed = useRef(collapsed ?? defaultCollapsed);\n\tconst prevOverlay = useRef(overlay);\n\tconst resolved = collapsed ?? uncontrolled;\n\tuseLayoutEffect(() => {\n\t\tif (\n\t\t\toverlay &&\n\t\t\t!resolved &&\n\t\t\t(prevCollapsed.current || !prevOverlay.current) &&\n\t\t\tdocument.activeElement instanceof HTMLElement\n\t\t) {\n\t\t\tlastFocusRef.current = document.activeElement;\n\t\t}\n\t\tprevCollapsed.current = resolved;\n\t\tprevOverlay.current = overlay;\n\t});\n\tconst setCollapsed = useCallback(\n\t\t(next: boolean) => {\n\t\t\tif (!next && document.activeElement instanceof HTMLElement) {\n\t\t\t\tlastFocusRef.current = document.activeElement;\n\t\t\t}\n\t\t\tif (collapsed === undefined) {\n\t\t\t\tsetUncontrolled(next);\n\t\t\t}\n\t\t\tonCollapsedChange?.(next);\n\t\t},\n\t\t[collapsed, onCollapsedChange],\n\t);\n\treturn (\n\t\t<SidebarContext.Provider\n\t\t\tvalue={{\n\t\t\t\tcollapsed: resolved,\n\t\t\t\tsetCollapsed,\n\t\t\t\tside,\n\t\t\t\tloading,\n\t\t\t\tpeek,\n\t\t\t\tpeeking,\n\t\t\t\tsetPeeking,\n\t\t\t\toverlay,\n\t\t\t\twidth,\n\t\t\t\tsetWidth,\n\t\t\t\tlastFocusRef,\n\t\t\t}}\n\t\t>\n\t\t\t{children}\n\t\t</SidebarContext.Provider>\n\t);\n}\n\nexport type SidebarProps = HTMLAttributes<HTMLElement> & {\n\t/**\n\t * Collapse the rail when no provider is present.\n\t * @default false\n\t */\n\tcollapsed?: boolean;\n};\n\nfunction clampSidebarWidth(next: number) {\n\treturn Math.min(400, Math.max(180, next));\n}\n\nfunction SidebarResize({\n\tside,\n\twidth,\n\tonWidth,\n}: {\n\tside: SidebarSide;\n\twidth: number;\n\tonWidth: (next: number) => void;\n}) {\n\tconst onPointerDown = (event: ReactPointerEvent<HTMLDivElement>) => {\n\t\tevent.preventDefault();\n\t\tevent.currentTarget.setPointerCapture(event.pointerId);\n\t\tconst startX = event.clientX;\n\t\tconst startWidth = width;\n\t\tconst target = event.currentTarget;\n\t\tconst onMove = (move: PointerEvent) => {\n\t\t\tconst delta = side === \"right\" ? startX - move.clientX : move.clientX - startX;\n\t\t\tonWidth(clampSidebarWidth(startWidth + delta));\n\t\t};\n\t\tconst onUp = () => {\n\t\t\ttarget.removeEventListener(\"pointermove\", onMove);\n\t\t\ttarget.removeEventListener(\"pointerup\", onUp);\n\t\t\ttarget.removeEventListener(\"pointercancel\", onUp);\n\t\t};\n\t\ttarget.addEventListener(\"pointermove\", onMove);\n\t\ttarget.addEventListener(\"pointerup\", onUp);\n\t\ttarget.addEventListener(\"pointercancel\", onUp);\n\t};\n\treturn (\n\t\t<div\n\t\t\trole=\"separator\"\n\t\t\taria-orientation=\"vertical\"\n\t\t\taria-valuenow={width}\n\t\t\taria-valuemin={180}\n\t\t\taria-valuemax={400}\n\t\t\taria-label=\"Resize sidebar\"\n\t\t\ttabIndex={0}\n\t\t\tclassName={cn(\n\t\t\t\t\"absolute top-0 h-full w-basalt-1 cursor-col-resize bg-transparent\",\n\t\t\t\tside === \"right\" ? \"left-0\" : \"right-0\",\n\t\t\t)}\n\t\t\tonPointerDown={onPointerDown}\n\t\t\tonKeyDown={(event) => {\n\t\t\t\tif (event.key !== \"ArrowLeft\" && event.key !== \"ArrowRight\") {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tevent.preventDefault();\n\t\t\t\tconst dir = event.key === \"ArrowRight\" ? 1 : -1;\n\t\t\t\tconst delta = side === \"right\" ? -dir * 8 : dir * 8;\n\t\t\t\tonWidth(clampSidebarWidth(width + delta));\n\t\t\t}}\n\t\t/>\n\t);\n}\n\nexport function Sidebar({\n\tcollapsed: collapsedProp,\n\tclassName,\n\tchildren,\n\tonMouseEnter,\n\tonMouseLeave,\n\tstyle,\n\t...props\n}: SidebarProps) {\n\tconst context = useContext(SidebarContext);\n\tconst collapsed = context\n\t\t? context.collapsed && !(context.peek && context.peeking)\n\t\t: (collapsedProp ?? false);\n\tconst side = context?.side ?? \"left\";\n\tconst overlay = context?.overlay ?? false;\n\tconst width = context?.width ?? 260;\n\tconst body = context?.loading ? (\n\t\t<div\n\t\t\tclassName=\"flex flex-col gap-basalt-space-lg p-basalt-space-lg\"\n\t\t\trole=\"status\"\n\t\t\taria-live=\"polite\"\n\t\t>\n\t\t\t<SkeletonLine />\n\t\t\t<SkeletonLine />\n\t\t\t<SkeletonLine />\n\t\t</div>\n\t) : (\n\t\tchildren\n\t);\n\tconst resize =\n\t\tcontext && !collapsed ? (\n\t\t\t<SidebarResize side={side} width={context.width} onWidth={context.setWidth} />\n\t\t) : null;\n\tconst frameClass = cn(\n\t\tBASALT_UI_CLASS,\n\t\t\"relative flex shrink-0 flex-col bg-basalt-background text-basalt-base text-basalt-foreground\",\n\t\tOVERLAY_MOTION,\n\t\tclassName,\n\t);\n\tif (overlay && context) {\n\t\treturn (\n\t\t\t<Dialog open={!context.collapsed} onOpenChange={(open) => context.setCollapsed(!open)}>\n\t\t\t\t<DialogPortal>\n\t\t\t\t\t<DialogOverlay />\n\t\t\t\t\t<DialogPrimitive.Content\n\t\t\t\t\t\tdata-basalt-sidebar=\"\"\n\t\t\t\t\t\taria-label=\"Sidebar\"\n\t\t\t\t\t\tdata-overlay=\"\"\n\t\t\t\t\t\tdata-side={side}\n\t\t\t\t\t\taria-busy={context.loading || undefined}\n\t\t\t\t\t\tonMouseEnter={onMouseEnter}\n\t\t\t\t\t\tonMouseLeave={onMouseLeave}\n\t\t\t\t\t\tref={(node) => {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tnode &&\n\t\t\t\t\t\t\t\tdocument.activeElement instanceof HTMLElement &&\n\t\t\t\t\t\t\t\t!node.contains(document.activeElement)\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tcontext.lastFocusRef.current = document.activeElement;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tonOpenAutoFocus={(event) => {\n\t\t\t\t\t\t\tconst from = \"relatedTarget\" in event ? event.relatedTarget : null;\n\t\t\t\t\t\t\tif (from instanceof HTMLElement) {\n\t\t\t\t\t\t\t\tcontext.lastFocusRef.current = from;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tonCloseAutoFocus={(event) => {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tcontext.lastFocusRef.current?.focus();\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\tframeClass,\n\t\t\t\t\t\t\tOVERLAY_LAYER,\n\t\t\t\t\t\t\t\"fixed inset-y-0 overflow-hidden shadow-md\",\n\t\t\t\t\t\t\tside === \"right\" ? \"right-0\" : \"left-0\",\n\t\t\t\t\t\t)}\n\t\t\t\t\t\tstyle={{ width, ...style }}\n\t\t\t\t\t\t{...props}\n\t\t\t\t\t>\n\t\t\t\t\t\t{body}\n\t\t\t\t\t\t{resize}\n\t\t\t\t\t</DialogPrimitive.Content>\n\t\t\t\t</DialogPortal>\n\t\t\t</Dialog>\n\t\t);\n\t}\n\treturn (\n\t\t<aside\n\t\t\tdata-basalt-sidebar=\"\"\n\t\t\tdata-collapsed={collapsed ? \"\" : undefined}\n\t\t\tdata-side={side}\n\t\t\taria-busy={context?.loading || undefined}\n\t\t\tonMouseEnter={(event) => {\n\t\t\t\tif (context?.peek && context.collapsed) {\n\t\t\t\t\tcontext.setPeeking(true);\n\t\t\t\t}\n\t\t\t\tonMouseEnter?.(event);\n\t\t\t}}\n\t\t\tonMouseLeave={(event) => {\n\t\t\t\tif (context?.peek) {\n\t\t\t\t\tcontext.setPeeking(false);\n\t\t\t\t}\n\t\t\t\tonMouseLeave?.(event);\n\t\t\t}}\n\t\t\tclassName={cn(\n\t\t\t\tframeClass,\n\t\t\t\t\"sticky overflow-hidden transition-[width] basalt-motion duration-basalt-normal ease-basalt\",\n\t\t\t\tside === \"right\" ? \"order-last\" : undefined,\n\t\t\t\tcollapsed && \"w-basalt-rail\",\n\t\t\t)}\n\t\t\tstyle={!collapsed ? { width, ...style } : style}\n\t\t\t{...props}\n\t\t>\n\t\t\t{body}\n\t\t\t{resize}\n\t\t</aside>\n\t);\n}\n\nconst SIDEBAR_ROW_CLASS =\n\t\"min-h-[calc(var(--basalt-line-row)+2*var(--basalt-space-lg))] py-basalt-space-lg\";\n\nexport interface SidebarHeaderProps extends HTMLAttributes<HTMLDivElement> {}\n\nexport function SidebarHeader({ className, ...props }: SidebarHeaderProps) {\n\treturn (\n\t\t<div\n\t\t\tdata-slot=\"sidebar-header\"\n\t\t\tclassName={cn(\n\t\t\t\t\"flex h-basalt-14 shrink-0 items-center gap-basalt-row-gap px-basalt-nav-inset\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\n/**\n * Props for `SidebarSearch`. Renders a native `<button>` element and accepts all standard button HTML attributes and click handlers.\n */\nexport interface SidebarSearchProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n\t/**\n\t * Shortcut key display label rendered inside the trailing kbd tag. Note: this is a visual label only and does not register a global keyboard shortcut.\n\t * @default \"⌘K\"\n\t */\n\tshortcut?: string;\n}\n\nexport function SidebarSearch({\n\tshortcut = \"⌘K\",\n\tclassName,\n\tchildren,\n\t...props\n}: SidebarSearchProps) {\n\treturn (\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclassName={cn(\n\t\t\t\tBASALT_UI_CLASS,\n\t\t\t\tNAV_ROW_CLASS,\n\t\t\t\tSIDEBAR_ROW_CLASS,\n\t\t\t\t\"w-full cursor-pointer bg-basalt-secondary transition-colors basalt-motion hover:bg-basalt-hover\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<Search className=\"h-basalt-4 w-basalt-4 text-basalt-muted-foreground\" strokeWidth={1.5} />\n\t\t\t<span className=\"flex-1 text-left text-basalt-base text-basalt-muted-foreground\">\n\t\t\t\t{children}\n\t\t\t</span>\n\t\t\t<kbd className=\"pointer-events-none hidden rounded-basalt-sm border border-basalt-border bg-basalt-card px-basalt-space-md py-basalt-space-xs text-basalt-xs font-medium text-basalt-muted-foreground sm:inline-block\">\n\t\t\t\t{shortcut}\n\t\t\t</kbd>\n\t\t</button>\n\t);\n}\n\nexport interface SidebarNavProps extends HTMLAttributes<HTMLElement> {}\n\nexport function SidebarNav({ className, ...props }: SidebarNavProps) {\n\tconst highlightRef = useHoverHighlight(undefined, { restoreOnPointerLeave: false });\n\treturn (\n\t\t<nav\n\t\t\tref={highlightRef}\n\t\t\tdata-slot=\"sidebar-nav\"\n\t\t\tclassName={cn(\n\t\t\t\tNAV_LIST_CLASS,\n\t\t\t\t\"min-h-0 flex-1 flex-col overflow-y-auto overscroll-y-contain\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nexport interface SidebarPartitionProps extends HTMLAttributes<HTMLParagraphElement> {}\n\nexport function SidebarPartition({ className, ...props }: SidebarPartitionProps) {\n\treturn (\n\t\t<p\n\t\t\tdata-slot=\"sidebar-partition\"\n\t\t\tclassName={cn(\n\t\t\t\t\"shrink-0 px-basalt-row-x pt-basalt-layout pb-basalt-space-lg text-basalt-sm font-semibold tracking-wide text-basalt-foreground uppercase\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nexport type SidebarItemProps = ButtonHTMLAttributes<HTMLButtonElement> & {\n\t/**\n\t * Mark the item as the current page.\n\t * @default false\n\t */\n\tactive?: boolean;\n};\n\nexport function SidebarItem({ active = false, className, ...props }: SidebarItemProps) {\n\treturn (\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\taria-current={active ? \"page\" : undefined}\n\t\t\tdata-basalt-hover-item=\"\"\n\t\t\tdata-sidebar-row=\"\"\n\t\t\tdata-hover-selected={active}\n\t\t\tclassName={cn(NAV_ITEM_CLASS, SIDEBAR_ROW_CLASS, \"w-full\", className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\n/**\n * Props for `SidebarIconItem`. Accepts standard button HTML attributes. The caller is responsible for providing accessible labeling via `aria-label` or `aria-labelledby` as icon buttons do not automatically generate accessible names.\n */\nexport interface SidebarIconItemProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n\t/**\n\t * Mark the icon button as active page item.\n\t * @default false\n\t */\n\tactive?: boolean;\n}\n\nexport function SidebarIconItem({ active = false, className, ...props }: SidebarIconItemProps) {\n\treturn (\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\taria-current={active ? \"page\" : undefined}\n\t\t\tdata-basalt-hover-item=\"\"\n\t\t\tdata-sidebar-row=\"\"\n\t\t\tdata-hover-selected={active}\n\t\t\tclassName={cn(\n\t\t\t\tNAV_ITEM_CLASS,\n\t\t\t\tSIDEBAR_ROW_CLASS,\n\t\t\t\t\"relative w-basalt-control justify-center\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\n/**\n * Props for `SidebarGroup`. Uncontrolled collapsible section that accepts only the documented properties. It does not accept controlled open props or arbitrary DOM attributes.\n */\nexport interface SidebarGroupProps {\n\t/**\n\t * Section label displayed on the group trigger.\n\t */\n\tlabel: ReactNode;\n\t/**\n\t * Uncontrolled initial open state for the collapsible group.\n\t * @default true\n\t */\n\tdefaultOpen?: boolean;\n\t/**\n\t * Navigation items rendered inside the group.\n\t */\n\tchildren: ReactNode;\n}\n\nexport function SidebarGroup({ label, defaultOpen = true, children }: SidebarGroupProps) {\n\tconst [open, setOpen] = useState(defaultOpen);\n\treturn (\n\t\t<Collapsible\n\t\t\topen={open}\n\t\t\tonOpenChange={setOpen}\n\t\t\tdata-slot=\"sidebar-group\"\n\t\t\tclassName=\"shrink-0 pt-basalt-layout-sm\"\n\t\t>\n\t\t\t<CollapsibleTrigger asChild>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tdata-slot=\"sidebar-group-label\"\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\"flex w-full cursor-pointer items-center justify-between gap-basalt-row-gap rounded-basalt-md px-basalt-row-x py-basalt-space-lg text-left text-basalt-xs font-semibold leading-basalt-row tracking-wide text-basalt-muted-foreground uppercase transition-colors basalt-motion hover:text-basalt-foreground\",\n\t\t\t\t\t\tFOCUS_INSET,\n\t\t\t\t\t)}\n\t\t\t\t>\n\t\t\t\t\t<span className=\"min-w-0 truncate\">{label}</span>\n\t\t\t\t\t<ChevronUp\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\"h-basalt-4 w-basalt-4 text-basalt-muted-foreground transition-transform basalt-motion duration-basalt-normal\",\n\t\t\t\t\t\t\tOVERLAY_MOTION,\n\t\t\t\t\t\t\t!open && \"rotate-180\",\n\t\t\t\t\t\t)}\n\t\t\t\t\t\tstrokeWidth={1.5}\n\t\t\t\t\t/>\n\t\t\t\t</button>\n\t\t\t</CollapsibleTrigger>\n\t\t\t<CollapsibleContent unstyled>\n\t\t\t\t<div className=\"flex flex-col gap-basalt-nav-gap pt-basalt-nav-gap\">{children}</div>\n\t\t\t</CollapsibleContent>\n\t\t</Collapsible>\n\t);\n}\n\nexport interface SidebarFooterProps extends HTMLAttributes<HTMLDivElement> {}\n\nexport function SidebarFooter({ className, ...props }: SidebarFooterProps) {\n\treturn (\n\t\t<div\n\t\t\tdata-slot=\"sidebar-footer\"\n\t\t\tclassName={cn(\n\t\t\t\t\"flex shrink-0 flex-col gap-basalt-content-gap px-basalt-nav-inset py-basalt-nav-inset\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nexport interface SidebarUserProps {\n\t/**\n\t * User display name.\n\t */\n\tname: ReactNode;\n\t/**\n\t * Optional user email or secondary text.\n\t */\n\temail?: ReactNode;\n\t/**\n\t * Avatar element slot.\n\t */\n\tavatar?: ReactNode;\n\t/**\n\t * Trailing action slot (e.g. settings or logout button).\n\t */\n\taction?: ReactNode;\n\t/**\n\t * Additional CSS class name.\n\t */\n\tclassName?: string;\n}\n\nexport function SidebarUser({ name, email, avatar, action, className }: SidebarUserProps) {\n\treturn (\n\t\t<div className={cn(\"flex items-center gap-basalt-space-lg\", className)}>\n\t\t\t{avatar}\n\t\t\t<div className=\"min-w-0 flex-1\">\n\t\t\t\t<p className=\"truncate text-basalt-base font-medium text-basalt-foreground\">{name}</p>\n\t\t\t\t{email ? (\n\t\t\t\t\t<p className=\"truncate text-basalt-sm text-basalt-muted-foreground\">{email}</p>\n\t\t\t\t) : null}\n\t\t\t</div>\n\t\t\t{action}\n\t\t</div>\n\t);\n}\n\nexport interface ContentIslandProps extends HTMLAttributes<HTMLDivElement> {\n\t/** Mobile surface treatment; desktop remains an inset L1 island. @default \"inset\" */\n\tmobileSurface?: \"inset\" | \"edge-to-edge\";\n}\n\nexport function ContentIsland({\n\tmobileSurface = \"inset\",\n\tclassName,\n\t...props\n}: ContentIslandProps) {\n\treturn (\n\t\t<div\n\t\t\tdata-basalt-surface-root=\"\"\n\t\t\tdata-basalt-island={mobileSurface}\n\t\t\tclassName={cn(\n\t\t\t\t\"min-h-0 min-w-0 flex-1 bg-basalt-card text-basalt-card-foreground md:rounded-basalt-island md:p-basalt-layout-lg lg:px-basalt-layout-xl\",\n\t\t\t\tmobileSurface === \"inset\"\n\t\t\t\t\t? \"rounded-basalt-lg p-basalt-layout shadow-sm ring-1 ring-basalt-border/40\"\n\t\t\t\t\t: \"md:shadow-sm md:ring-1 md:ring-basalt-border/40\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n"],"mappings":"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"}
@@ -19,7 +19,7 @@ export interface SkeletonLineProps extends HTMLAttributes<HTMLDivElement> {
19
19
  /**
20
20
  * Explicit height of the skeleton line in pixels.
21
21
  *
22
- * Note: When omitted, default height is governed by CSS class tokens (h-2).
22
+ * Note: When omitted, default height is governed by CSS class tokens (h-basalt-2).
23
23
  */
24
24
  height?: number;
25
25
  }
@@ -9,11 +9,11 @@ function n({ className: n, minWidth: r = 30, maxWidth: i = 100, height: a, style
9
9
  ...o
10
10
  };
11
11
  return /* @__PURE__ */ t("div", {
12
- className: e("relative h-2 overflow-hidden rounded-sm bg-basalt-muted", n),
12
+ className: e("relative h-basalt-2 overflow-hidden rounded-basalt-sm bg-basalt-muted", n),
13
13
  style: c,
14
14
  "aria-hidden": "true",
15
15
  ...s,
16
- children: /* @__PURE__ */ t("span", { className: "pointer-events-none absolute inset-0 animate-basalt-shimmer bg-gradient-to-r from-transparent via-black/10 to-transparent motion-reduce:animate-none" })
16
+ children: /* @__PURE__ */ t("span", { className: "pointer-events-none absolute inset-0 animate-basalt-shimmer bg-gradient-to-r from-transparent via-basalt-backdrop/10 to-transparent motion-reduce:animate-none" })
17
17
  });
18
18
  }
19
19
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"skeleton-line.js","names":["SkeletonLine","props","lineStyle","minWidth","maxWidth","height","style","cn","className"],"sources":["../../src/components/skeleton-line.tsx"],"sourcesContent":["import type { CSSProperties, HTMLAttributes } from \"react\";\nimport { cn } from \"../utils/cn\";\n\nexport interface SkeletonLineProps extends HTMLAttributes<HTMLDivElement> {\n\t/**\n\t * Minimum width percentage used for deterministic width computation.\n\t *\n\t * Note: Averaged with maxWidth to compute the midpoint width percentage.\n\t *\n\t * @default 30\n\t */\n\tminWidth?: number;\n\n\t/**\n\t * Maximum width percentage used for deterministic width computation.\n\t *\n\t * Note: Averaged with minWidth to compute the midpoint width percentage.\n\t *\n\t * @default 100\n\t */\n\tmaxWidth?: number;\n\n\t/**\n\t * Explicit height of the skeleton line in pixels.\n\t *\n\t * Note: When omitted, default height is governed by CSS class tokens (h-2).\n\t */\n\theight?: number;\n}\n\nexport function SkeletonLine({\n\tclassName,\n\tminWidth = 30,\n\tmaxWidth = 100,\n\theight,\n\tstyle,\n\t...props\n}: SkeletonLineProps) {\n\tconst width = (minWidth + maxWidth) / 2;\n\tconst lineStyle: CSSProperties = {\n\t\twidth: `${width}%`,\n\t\t...(height !== undefined ? { height } : {}),\n\t\t...style,\n\t};\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\"relative h-2 overflow-hidden rounded-sm bg-basalt-muted\", className)}\n\t\t\tstyle={lineStyle}\n\t\t\taria-hidden=\"true\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<span className=\"pointer-events-none absolute inset-0 animate-basalt-shimmer bg-gradient-to-r from-transparent via-black/10 to-transparent motion-reduce:animate-none\" />\n\t\t</div>\n\t);\n}\n"],"mappings":";;;;AA8BA,SAAgBA,EAAa,EAC5B,cACA,cAAW,IACX,cAAW,KACX,WACA,UACA,GAAGC,KACkB;CAErB,IAAMC,IAA2B;EAChC,OAAO,IAFOC,IAAWC,KAAY,EAErB;EAChB,GAAIC,MAAW,KAAA,IAAyB,CAAC,IAAd,EAAE,UAAO;EACpC,GAAGC;CACJ;CACA,OACC,kBAAC,OAAD;EACC,WAAWC,EAAG,2DAA2DC,CAAS;EAClF,OAAON;EACP,eAAY;EACZ,GAAID;EAEJ,UAAA,kBAAC,QAAD,EAAM,WAAU,uJAAwJ,CAAA;CACpK,CAAA;AAEP"}
1
+ {"version":3,"file":"skeleton-line.js","names":["SkeletonLine","props","lineStyle","minWidth","maxWidth","height","style","cn","className"],"sources":["../../src/components/skeleton-line.tsx"],"sourcesContent":["import type { CSSProperties, HTMLAttributes } from \"react\";\nimport { cn } from \"../utils/cn\";\n\nexport interface SkeletonLineProps extends HTMLAttributes<HTMLDivElement> {\n\t/**\n\t * Minimum width percentage used for deterministic width computation.\n\t *\n\t * Note: Averaged with maxWidth to compute the midpoint width percentage.\n\t *\n\t * @default 30\n\t */\n\tminWidth?: number;\n\n\t/**\n\t * Maximum width percentage used for deterministic width computation.\n\t *\n\t * Note: Averaged with minWidth to compute the midpoint width percentage.\n\t *\n\t * @default 100\n\t */\n\tmaxWidth?: number;\n\n\t/**\n\t * Explicit height of the skeleton line in pixels.\n\t *\n\t * Note: When omitted, default height is governed by CSS class tokens (h-basalt-2).\n\t */\n\theight?: number;\n}\n\nexport function SkeletonLine({\n\tclassName,\n\tminWidth = 30,\n\tmaxWidth = 100,\n\theight,\n\tstyle,\n\t...props\n}: SkeletonLineProps) {\n\tconst width = (minWidth + maxWidth) / 2;\n\tconst lineStyle: CSSProperties = {\n\t\twidth: `${width}%`,\n\t\t...(height !== undefined ? { height } : {}),\n\t\t...style,\n\t};\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\t\"relative h-basalt-2 overflow-hidden rounded-basalt-sm bg-basalt-muted\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\tstyle={lineStyle}\n\t\t\taria-hidden=\"true\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<span className=\"pointer-events-none absolute inset-0 animate-basalt-shimmer bg-gradient-to-r from-transparent via-basalt-backdrop/10 to-transparent motion-reduce:animate-none\" />\n\t\t</div>\n\t);\n}\n"],"mappings":";;;;AA8BA,SAAgBA,EAAa,EAC5B,cACA,cAAW,IACX,cAAW,KACX,WACA,UACA,GAAGC,KACkB;CAErB,IAAMC,IAA2B;EAChC,OAAO,IAFOC,IAAWC,KAAY,EAErB;EAChB,GAAIC,MAAW,KAAA,IAAyB,CAAC,IAAd,EAAE,UAAO;EACpC,GAAGC;CACJ;CACA,OACC,kBAAC,OAAD;EACC,WAAWC,EACV,yEACAC,CACD;EACA,OAAON;EACP,eAAY;EACZ,GAAID;EAEJ,UAAA,kBAAC,QAAD,EAAM,WAAU,iKAAkK,CAAA;CAC9K,CAAA;AAEP"}
@@ -20,12 +20,12 @@ var s = r.forwardRef(({ className: s, value: c, defaultValue: l, min: u = 0, max
20
20
  className: e(t, "relative flex touch-none select-none items-center", v ? "h-full w-auto flex-col justify-center" : "h-auto w-full", s),
21
21
  ...g,
22
22
  children: [/* @__PURE__ */ i(o.Track, {
23
- className: e("relative grow overflow-hidden rounded-full bg-basalt-muted", v ? "h-full w-2" : "h-2 w-full"),
23
+ className: e("relative grow overflow-hidden rounded-basalt-full bg-basalt-muted", v ? "h-full w-basalt-2" : "h-basalt-2 w-full"),
24
24
  children: /* @__PURE__ */ i(o.Range, { className: e("absolute bg-basalt-primary", v ? "w-full" : "h-full") })
25
25
  }), Array.from({ length: x }, (t, r) => {
26
26
  let a, s;
27
27
  x === 1 ? (a = p?.[0] ?? m, s = h) : p?.[r] === void 0 ? m && (a = x === 2 ? `${m} ${r === 0 ? "minimum" : "maximum"}` : `${m} thumb ${r + 1} of ${x}`) : a = p[r];
28
- let c = { className: e("block h-4 w-4 rounded-full border border-basalt-primary bg-basalt-background shadow", n) };
28
+ let c = { className: e("block h-basalt-4 w-basalt-4 rounded-basalt-full border border-basalt-primary bg-basalt-background shadow", n) };
29
29
  return a !== void 0 && (c["aria-label"] = a), s !== void 0 && (c["aria-labelledby"] = s), /* @__PURE__ */ i(o.Thumb, { ...c }, r);
30
30
  })]
31
31
  });
@@ -1 +1 @@
1
- {"version":3,"file":"slider.js","names":["React","SliderPrimitive","Slider","ariaLabel","ariaLabelledBy","props","isVertical","orientation","isControlled","value","initialUncontrolledCountRef","defaultValue","thumbCount","cn","BASALT_UI_CLASS","className","thumbLabel","thumbLabelledBy","labels","index","thumbProps","FOCUS_RING"],"sources":["../../src/components/slider.tsx"],"sourcesContent":["import * as SliderPrimitive from \"@radix-ui/react-slider\";\nimport * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { FOCUS_RING } from \"./overlay\";\n\ntype RadixSliderRootProps = React.ComponentPropsWithoutRef<typeof SliderPrimitive.Root>;\n\nexport interface SliderProps\n\textends Omit<\n\t\tRadixSliderRootProps,\n\t\t| \"value\"\n\t\t| \"defaultValue\"\n\t\t| \"onValueChange\"\n\t\t| \"onValueCommit\"\n\t\t| \"disabled\"\n\t\t| \"name\"\n\t\t| \"min\"\n\t\t| \"max\"\n\t\t| \"step\"\n\t\t| \"orientation\"\n\t> {\n\t/**\n\t * Controlled value array for the slider. Forwards ref to root span element.\n\t * When multiple values are provided, renders a thumb for each value.\n\t */\n\tvalue?: RadixSliderRootProps[\"value\"];\n\t/**\n\t * Uncontrolled default value array for the slider.\n\t * When multiple values are provided, renders a thumb for each value.\n\t * @default [min ?? 0]\n\t */\n\tdefaultValue?: RadixSliderRootProps[\"defaultValue\"];\n\t/**\n\t * Callback invoked when slider value changes during interaction.\n\t */\n\tonValueChange?: RadixSliderRootProps[\"onValueChange\"];\n\t/**\n\t * Callback invoked when slider interaction finishes and value is committed.\n\t */\n\tonValueCommit?: RadixSliderRootProps[\"onValueCommit\"];\n\t/**\n\t * Whether the slider is disabled from user interaction.\n\t * @default false\n\t */\n\tdisabled?: RadixSliderRootProps[\"disabled\"];\n\t/**\n\t * Form field name submitted with the slider values.\n\t */\n\tname?: RadixSliderRootProps[\"name\"];\n\t/**\n\t * Minimum allowable value.\n\t * @default 0\n\t */\n\tmin?: RadixSliderRootProps[\"min\"];\n\t/**\n\t * Maximum allowable value.\n\t * @default 100\n\t */\n\tmax?: RadixSliderRootProps[\"max\"];\n\t/**\n\t * Step interval between selectable values.\n\t * @default 1\n\t */\n\tstep?: RadixSliderRootProps[\"step\"];\n\t/**\n\t * Layout orientation of the slider track.\n\t * When set to `\"vertical\"`, the slider track and range align vertically. A container with an explicit height is required.\n\t * @default \"horizontal\"\n\t */\n\torientation?: RadixSliderRootProps[\"orientation\"];\n\t/**\n\t * Accessible labels for thumbs when rendering single or multiple values.\n\t * When provided, thumb at index `i` receives `labels[i]`. For a single thumb, `labels[0]` takes precedence over `aria-label`.\n\t * When omitted on a multi-value slider, the root `aria-label` provides a contextual fallback (e.g. `ariaLabel + \" minimum\"`),\n\t * or falls back to Radix default names (`\"Minimum\"`, `\"Maximum\"`, or `\"Value N of Total\"`).\n\t */\n\tlabels?: string[];\n}\n\nexport const Slider = React.forwardRef<React.ElementRef<typeof SliderPrimitive.Root>, SliderProps>(\n\t(\n\t\t{\n\t\t\tclassName,\n\t\t\tvalue,\n\t\t\tdefaultValue,\n\t\t\tmin = 0,\n\t\t\tmax = 100,\n\t\t\torientation = \"horizontal\",\n\t\t\tlabels,\n\t\t\t\"aria-label\": ariaLabel,\n\t\t\t\"aria-labelledby\": ariaLabelledBy,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst isVertical = orientation === \"vertical\";\n\t\tconst isControlled = value !== undefined;\n\n\t\tconst initialUncontrolledCountRef = React.useRef(defaultValue?.length ?? 1);\n\t\tconst thumbCount = isControlled ? (value?.length ?? 0) : initialUncontrolledCountRef.current;\n\n\t\treturn (\n\t\t\t<SliderPrimitive.Root\n\t\t\t\tref={ref}\n\t\t\t\tmin={min}\n\t\t\t\tmax={max}\n\t\t\t\torientation={orientation}\n\t\t\t\tvalue={value}\n\t\t\t\tdefaultValue={defaultValue}\n\t\t\t\taria-label={ariaLabel}\n\t\t\t\taria-labelledby={ariaLabelledBy}\n\t\t\t\tclassName={cn(\n\t\t\t\t\tBASALT_UI_CLASS,\n\t\t\t\t\t\"relative flex touch-none select-none items-center\",\n\t\t\t\t\tisVertical ? \"h-full w-auto flex-col justify-center\" : \"h-auto w-full\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t<SliderPrimitive.Track\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\"relative grow overflow-hidden rounded-full bg-basalt-muted\",\n\t\t\t\t\t\tisVertical ? \"h-full w-2\" : \"h-2 w-full\",\n\t\t\t\t\t)}\n\t\t\t\t>\n\t\t\t\t\t<SliderPrimitive.Range\n\t\t\t\t\t\tclassName={cn(\"absolute bg-basalt-primary\", isVertical ? \"w-full\" : \"h-full\")}\n\t\t\t\t\t/>\n\t\t\t\t</SliderPrimitive.Track>\n\t\t\t\t{Array.from({ length: thumbCount }, (_, index) => {\n\t\t\t\t\tlet thumbLabel: string | undefined;\n\t\t\t\t\tlet thumbLabelledBy: string | undefined;\n\n\t\t\t\t\tif (thumbCount === 1) {\n\t\t\t\t\t\tthumbLabel = labels?.[0] ?? ariaLabel;\n\t\t\t\t\t\tthumbLabelledBy = ariaLabelledBy;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (labels?.[index] !== undefined) {\n\t\t\t\t\t\t\tthumbLabel = labels[index];\n\t\t\t\t\t\t} else if (ariaLabel) {\n\t\t\t\t\t\t\tif (thumbCount === 2) {\n\t\t\t\t\t\t\t\tconst suffix = index === 0 ? \"minimum\" : \"maximum\";\n\t\t\t\t\t\t\t\tthumbLabel = `${ariaLabel} ${suffix}`;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthumbLabel = `${ariaLabel} thumb ${index + 1} of ${thumbCount}`;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst thumbProps: React.ComponentPropsWithoutRef<typeof SliderPrimitive.Thumb> = {\n\t\t\t\t\t\tclassName: cn(\n\t\t\t\t\t\t\t\"block h-4 w-4 rounded-full border border-basalt-primary bg-basalt-background shadow\",\n\t\t\t\t\t\t\tFOCUS_RING,\n\t\t\t\t\t\t),\n\t\t\t\t\t};\n\t\t\t\t\tif (thumbLabel !== undefined) {\n\t\t\t\t\t\tthumbProps[\"aria-label\"] = thumbLabel;\n\t\t\t\t\t}\n\t\t\t\t\tif (thumbLabelledBy !== undefined) {\n\t\t\t\t\t\tthumbProps[\"aria-labelledby\"] = thumbLabelledBy;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn <SliderPrimitive.Thumb key={index} {...thumbProps} />;\n\t\t\t\t})}\n\t\t\t</SliderPrimitive.Root>\n\t\t);\n\t},\n);\nSlider.displayName = SliderPrimitive.Root.displayName;\n"],"mappings":";;;;;;;;AAgFA,IAAaE,IAASF,EAAM,YAE1B,EACC,cACA,UACA,iBACA,SAAM,GACN,SAAM,KACN,iBAAc,cACd,WACA,cAAcG,GACd,mBAAmBC,GACnB,GAAGC,KAEJ,MACI;CACJ,IAAMC,IAAaC,MAAgB,YAC7BC,IAAeC,MAAU,KAAA,GAEzBC,IAA8BV,EAAM,OAAOW,GAAc,UAAU,CAAC,GACpEC,IAAaJ,IAAgBC,GAAO,UAAU,IAAKC,EAA4B;CAErF,OACC,kBAACT,EAAgB,MAAjB;EACM;EACA;EACA;EACQ;EACN;EACO;EACd,cAAYE;EACZ,mBAAiBC;EACjB,WAAWS,EACVC,GACA,qDACAR,IAAa,0CAA0C,iBACvDS,CACD;EACA,GAAIV;EAfL,UAAA,CAiBC,kBAACJ,EAAgB,OAAjB;GACC,WAAWY,EACV,8DACAP,IAAa,eAAe,YAC7B;GAEA,UAAA,kBAACL,EAAgB,OAAjB,EACC,WAAWY,EAAG,8BAA8BP,IAAa,WAAW,QAAQ,EAC5E,CAAA;EACqB,CAAA,GACtB,MAAM,KAAK,EAAE,QAAQM,EAAW,IAAI,GAAG,MAAU;GACjD,IAAII,GACAC;GAEJ,AAAIL,MAAe,KAClB,IAAaM,IAAS,MAAMf,GAC5B,IAAkBC,KAEdc,IAASC,OAAW,KAAA,IAEbhB,MACV,AAICa,IAJGJ,MAAe,IAEL,GAAGT,EAAU,GADXgB,MAAU,IAAI,YAAY,cAG5B,GAAGhB,EAAU,SAASgB,IAAQ,EAAE,MAAMP,OANpD,IAAaM,EAAOC;GAWtB,IAAMC,IAA2E,EAChF,WAAWP,EACV,uFACAQ,CACD,EACD;GAQA,OAPIL,MAAe,KAAA,MAClB,EAAW,gBAAgBA,IAExBC,MAAoB,KAAA,MACvB,EAAW,qBAAqBA,IAG1B,kBAAChB,EAAgB,OAAjB,EAAmC,GAAImB,EAAa,GAAxBD,CAAwB;EAC5D,CAAC,CACoB;;AAExB,CACD;AACA,EAAO,cAAclB,EAAgB,KAAK"}
1
+ {"version":3,"file":"slider.js","names":["React","SliderPrimitive","Slider","ariaLabel","ariaLabelledBy","props","isVertical","orientation","isControlled","value","initialUncontrolledCountRef","defaultValue","thumbCount","cn","BASALT_UI_CLASS","className","thumbLabel","thumbLabelledBy","labels","index","thumbProps","FOCUS_RING"],"sources":["../../src/components/slider.tsx"],"sourcesContent":["import * as SliderPrimitive from \"@radix-ui/react-slider\";\nimport * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { FOCUS_RING } from \"./overlay\";\n\ntype RadixSliderRootProps = React.ComponentPropsWithoutRef<typeof SliderPrimitive.Root>;\n\nexport interface SliderProps\n\textends Omit<\n\t\tRadixSliderRootProps,\n\t\t| \"value\"\n\t\t| \"defaultValue\"\n\t\t| \"onValueChange\"\n\t\t| \"onValueCommit\"\n\t\t| \"disabled\"\n\t\t| \"name\"\n\t\t| \"min\"\n\t\t| \"max\"\n\t\t| \"step\"\n\t\t| \"orientation\"\n\t> {\n\t/**\n\t * Controlled value array for the slider. Forwards ref to root span element.\n\t * When multiple values are provided, renders a thumb for each value.\n\t */\n\tvalue?: RadixSliderRootProps[\"value\"];\n\t/**\n\t * Uncontrolled default value array for the slider.\n\t * When multiple values are provided, renders a thumb for each value.\n\t * @default [min ?? 0]\n\t */\n\tdefaultValue?: RadixSliderRootProps[\"defaultValue\"];\n\t/**\n\t * Callback invoked when slider value changes during interaction.\n\t */\n\tonValueChange?: RadixSliderRootProps[\"onValueChange\"];\n\t/**\n\t * Callback invoked when slider interaction finishes and value is committed.\n\t */\n\tonValueCommit?: RadixSliderRootProps[\"onValueCommit\"];\n\t/**\n\t * Whether the slider is disabled from user interaction.\n\t * @default false\n\t */\n\tdisabled?: RadixSliderRootProps[\"disabled\"];\n\t/**\n\t * Form field name submitted with the slider values.\n\t */\n\tname?: RadixSliderRootProps[\"name\"];\n\t/**\n\t * Minimum allowable value.\n\t * @default 0\n\t */\n\tmin?: RadixSliderRootProps[\"min\"];\n\t/**\n\t * Maximum allowable value.\n\t * @default 100\n\t */\n\tmax?: RadixSliderRootProps[\"max\"];\n\t/**\n\t * Step interval between selectable values.\n\t * @default 1\n\t */\n\tstep?: RadixSliderRootProps[\"step\"];\n\t/**\n\t * Layout orientation of the slider track.\n\t * When set to `\"vertical\"`, the slider track and range align vertically. A container with an explicit height is required.\n\t * @default \"horizontal\"\n\t */\n\torientation?: RadixSliderRootProps[\"orientation\"];\n\t/**\n\t * Accessible labels for thumbs when rendering single or multiple values.\n\t * When provided, thumb at index `i` receives `labels[i]`. For a single thumb, `labels[0]` takes precedence over `aria-label`.\n\t * When omitted on a multi-value slider, the root `aria-label` provides a contextual fallback (e.g. `ariaLabel + \" minimum\"`),\n\t * or falls back to Radix default names (`\"Minimum\"`, `\"Maximum\"`, or `\"Value N of Total\"`).\n\t */\n\tlabels?: string[];\n}\n\nexport const Slider = React.forwardRef<React.ElementRef<typeof SliderPrimitive.Root>, SliderProps>(\n\t(\n\t\t{\n\t\t\tclassName,\n\t\t\tvalue,\n\t\t\tdefaultValue,\n\t\t\tmin = 0,\n\t\t\tmax = 100,\n\t\t\torientation = \"horizontal\",\n\t\t\tlabels,\n\t\t\t\"aria-label\": ariaLabel,\n\t\t\t\"aria-labelledby\": ariaLabelledBy,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst isVertical = orientation === \"vertical\";\n\t\tconst isControlled = value !== undefined;\n\n\t\tconst initialUncontrolledCountRef = React.useRef(defaultValue?.length ?? 1);\n\t\tconst thumbCount = isControlled ? (value?.length ?? 0) : initialUncontrolledCountRef.current;\n\n\t\treturn (\n\t\t\t<SliderPrimitive.Root\n\t\t\t\tref={ref}\n\t\t\t\tmin={min}\n\t\t\t\tmax={max}\n\t\t\t\torientation={orientation}\n\t\t\t\tvalue={value}\n\t\t\t\tdefaultValue={defaultValue}\n\t\t\t\taria-label={ariaLabel}\n\t\t\t\taria-labelledby={ariaLabelledBy}\n\t\t\t\tclassName={cn(\n\t\t\t\t\tBASALT_UI_CLASS,\n\t\t\t\t\t\"relative flex touch-none select-none items-center\",\n\t\t\t\t\tisVertical ? \"h-full w-auto flex-col justify-center\" : \"h-auto w-full\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t<SliderPrimitive.Track\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\"relative grow overflow-hidden rounded-basalt-full bg-basalt-muted\",\n\t\t\t\t\t\tisVertical ? \"h-full w-basalt-2\" : \"h-basalt-2 w-full\",\n\t\t\t\t\t)}\n\t\t\t\t>\n\t\t\t\t\t<SliderPrimitive.Range\n\t\t\t\t\t\tclassName={cn(\"absolute bg-basalt-primary\", isVertical ? \"w-full\" : \"h-full\")}\n\t\t\t\t\t/>\n\t\t\t\t</SliderPrimitive.Track>\n\t\t\t\t{Array.from({ length: thumbCount }, (_, index) => {\n\t\t\t\t\tlet thumbLabel: string | undefined;\n\t\t\t\t\tlet thumbLabelledBy: string | undefined;\n\n\t\t\t\t\tif (thumbCount === 1) {\n\t\t\t\t\t\tthumbLabel = labels?.[0] ?? ariaLabel;\n\t\t\t\t\t\tthumbLabelledBy = ariaLabelledBy;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (labels?.[index] !== undefined) {\n\t\t\t\t\t\t\tthumbLabel = labels[index];\n\t\t\t\t\t\t} else if (ariaLabel) {\n\t\t\t\t\t\t\tif (thumbCount === 2) {\n\t\t\t\t\t\t\t\tconst suffix = index === 0 ? \"minimum\" : \"maximum\";\n\t\t\t\t\t\t\t\tthumbLabel = `${ariaLabel} ${suffix}`;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthumbLabel = `${ariaLabel} thumb ${index + 1} of ${thumbCount}`;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst thumbProps: React.ComponentPropsWithoutRef<typeof SliderPrimitive.Thumb> = {\n\t\t\t\t\t\tclassName: cn(\n\t\t\t\t\t\t\t\"block h-basalt-4 w-basalt-4 rounded-basalt-full border border-basalt-primary bg-basalt-background shadow\",\n\t\t\t\t\t\t\tFOCUS_RING,\n\t\t\t\t\t\t),\n\t\t\t\t\t};\n\t\t\t\t\tif (thumbLabel !== undefined) {\n\t\t\t\t\t\tthumbProps[\"aria-label\"] = thumbLabel;\n\t\t\t\t\t}\n\t\t\t\t\tif (thumbLabelledBy !== undefined) {\n\t\t\t\t\t\tthumbProps[\"aria-labelledby\"] = thumbLabelledBy;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn <SliderPrimitive.Thumb key={index} {...thumbProps} />;\n\t\t\t\t})}\n\t\t\t</SliderPrimitive.Root>\n\t\t);\n\t},\n);\nSlider.displayName = SliderPrimitive.Root.displayName;\n"],"mappings":";;;;;;;;AAgFA,IAAaE,IAASF,EAAM,YAE1B,EACC,cACA,UACA,iBACA,SAAM,GACN,SAAM,KACN,iBAAc,cACd,WACA,cAAcG,GACd,mBAAmBC,GACnB,GAAGC,KAEJ,MACI;CACJ,IAAMC,IAAaC,MAAgB,YAC7BC,IAAeC,MAAU,KAAA,GAEzBC,IAA8BV,EAAM,OAAOW,GAAc,UAAU,CAAC,GACpEC,IAAaJ,IAAgBC,GAAO,UAAU,IAAKC,EAA4B;CAErF,OACC,kBAACT,EAAgB,MAAjB;EACM;EACA;EACA;EACQ;EACN;EACO;EACd,cAAYE;EACZ,mBAAiBC;EACjB,WAAWS,EACVC,GACA,qDACAR,IAAa,0CAA0C,iBACvDS,CACD;EACA,GAAIV;EAfL,UAAA,CAiBC,kBAACJ,EAAgB,OAAjB;GACC,WAAWY,EACV,qEACAP,IAAa,sBAAsB,mBACpC;GAEA,UAAA,kBAACL,EAAgB,OAAjB,EACC,WAAWY,EAAG,8BAA8BP,IAAa,WAAW,QAAQ,EAC5E,CAAA;EACqB,CAAA,GACtB,MAAM,KAAK,EAAE,QAAQM,EAAW,IAAI,GAAG,MAAU;GACjD,IAAII,GACAC;GAEJ,AAAIL,MAAe,KAClB,IAAaM,IAAS,MAAMf,GAC5B,IAAkBC,KAEdc,IAASC,OAAW,KAAA,IAEbhB,MACV,AAICa,IAJGJ,MAAe,IAEL,GAAGT,EAAU,GADXgB,MAAU,IAAI,YAAY,cAG5B,GAAGhB,EAAU,SAASgB,IAAQ,EAAE,MAAMP,OANpD,IAAaM,EAAOC;GAWtB,IAAMC,IAA2E,EAChF,WAAWP,EACV,4GACAQ,CACD,EACD;GAQA,OAPIL,MAAe,KAAA,MAClB,EAAW,gBAAgBA,IAExBC,MAAoB,KAAA,MACvB,EAAW,qBAAqBA,IAG1B,kBAAChB,EAAgB,OAAjB,EAAmC,GAAImB,EAAa,GAAxBD,CAAwB;EAC5D,CAAC,CACoB;;AAExB,CACD;AACA,EAAO,cAAclB,EAAgB,KAAK"}
@@ -7,16 +7,17 @@ import { jsx as i, jsxs as a } from "react/jsx-runtime";
7
7
  //#region src/components/stat-strip.tsx
8
8
  var o = r.forwardRef(({ "aria-busy": r, className: o, items: s, loading: c = !1, ...l }, u) => /* @__PURE__ */ i("dl", {
9
9
  ref: u,
10
- className: e(t, "grid grid-cols-2 gap-3 md:grid-cols-4", o),
10
+ className: e(t, "grid grid-cols-2 gap-basalt-layout md:grid-cols-4", o),
11
11
  ...l,
12
12
  "aria-busy": c ? !0 : r,
13
13
  children: s.map((e, t) => /* @__PURE__ */ a("div", {
14
- className: "rounded-basalt-lg bg-basalt-muted p-4 ring-1 ring-basalt-border",
14
+ "data-basalt-surface": "",
15
+ className: "rounded-basalt-lg p-basalt-card",
15
16
  children: [/* @__PURE__ */ i("dt", {
16
- className: "text-sm font-medium text-basalt-muted-foreground",
17
+ className: "text-basalt-base font-medium text-basalt-muted-foreground",
17
18
  children: e.label
18
19
  }), /* @__PURE__ */ i("dd", {
19
- className: "mt-1 text-lg font-medium tabular-nums text-basalt-foreground",
20
+ className: "mt-basalt-space-sm text-basalt-xl font-medium tabular-nums text-basalt-foreground",
20
21
  children: c ? /* @__PURE__ */ i(n, {}) : e.value
21
22
  })]
22
23
  }, t))
@@ -1 +1 @@
1
- {"version":3,"file":"stat-strip.js","names":["React","StatStrip","ariaBusy","props","cn","BASALT_UI_CLASS","className","loading","items","item","SkeletonLine","index"],"sources":["../../src/components/stat-strip.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { SkeletonLine } from \"./skeleton-line\";\n\nexport interface StatStripItem {\n\t/** The visible label for this statistic. */\n\tlabel: React.ReactNode;\n\t/** The visible value for this statistic. */\n\tvalue: React.ReactNode;\n}\n\nexport interface StatStripProps\n\textends Omit<React.HTMLAttributes<HTMLDListElement>, \"children\" | \"className\"> {\n\t/** Additional classes for the definition list. */\n\tclassName?: string;\n\t/** The labelled values shown in the strip. */\n\titems: readonly StatStripItem[];\n\t/**\n\t * Replace each value with a skeleton while keeping labels visible.\n\t * @default false\n\t */\n\tloading?: boolean;\n}\n\nexport const StatStrip = React.forwardRef<HTMLDListElement, StatStripProps>(\n\t({ \"aria-busy\": ariaBusy, className, items, loading = false, ...props }, ref) => {\n\t\treturn (\n\t\t\t<dl\n\t\t\t\tref={ref}\n\t\t\t\tclassName={cn(BASALT_UI_CLASS, \"grid grid-cols-2 gap-3 md:grid-cols-4\", className)}\n\t\t\t\t{...props}\n\t\t\t\taria-busy={loading ? true : ariaBusy}\n\t\t\t>\n\t\t\t\t{items.map((item, index) => (\n\t\t\t\t\t<div\n\t\t\t\t\t\tkey={index}\n\t\t\t\t\t\tclassName=\"rounded-basalt-lg bg-basalt-muted p-4 ring-1 ring-basalt-border\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<dt className=\"text-sm font-medium text-basalt-muted-foreground\">{item.label}</dt>\n\t\t\t\t\t\t<dd className=\"mt-1 text-lg font-medium tabular-nums text-basalt-foreground\">\n\t\t\t\t\t\t\t{loading ? <SkeletonLine /> : item.value}\n\t\t\t\t\t\t</dd>\n\t\t\t\t\t</div>\n\t\t\t\t))}\n\t\t\t</dl>\n\t\t);\n\t},\n);\nStatStrip.displayName = \"StatStrip\";\n"],"mappings":";;;;;;;AAyBA,IAAaC,IAAYD,EAAM,YAC7B,EAAE,aAAaE,GAAU,cAAW,UAAO,aAAU,IAAO,GAAGC,KAAS,MAEvE,kBAAC,MAAD;CACM;CACL,WAAWC,EAAGC,GAAiB,yCAAyCC,CAAS;CACjF,GAAIH;CACJ,aAAWI,IAAU,KAAOL;CAE3B,UAAAM,EAAM,KAAK,GAAM,MACjB,kBAAC,OAAD;EAEC,WAAU;EAFX,UAAA,CAIC,kBAAC,MAAD;GAAI,WAAU;GAAoD,UAAAC,EAAK;EAAU,CAAA,GACjF,kBAAC,MAAD;GAAI,WAAU;GACZ,UAAAF,IAAU,kBAACG,GAAD,CAAe,CAAA,IAAID,EAAK;EAChC,CAAA,CACA;CAPC,GAAAE,CAOD,CACL;AACE,CAAA,CAGP;AACA,EAAU,cAAc"}
1
+ {"version":3,"file":"stat-strip.js","names":["React","StatStrip","ariaBusy","props","cn","BASALT_UI_CLASS","className","loading","items","item","SkeletonLine","index"],"sources":["../../src/components/stat-strip.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { SkeletonLine } from \"./skeleton-line\";\n\nexport interface StatStripItem {\n\t/** The visible label for this statistic. */\n\tlabel: React.ReactNode;\n\t/** The visible value for this statistic. */\n\tvalue: React.ReactNode;\n}\n\nexport interface StatStripProps\n\textends Omit<React.HTMLAttributes<HTMLDListElement>, \"children\" | \"className\"> {\n\t/** Additional classes for the definition list. */\n\tclassName?: string;\n\t/** The labelled values shown in the strip. */\n\titems: readonly StatStripItem[];\n\t/**\n\t * Replace each value with a skeleton while keeping labels visible.\n\t * @default false\n\t */\n\tloading?: boolean;\n}\n\nexport const StatStrip = React.forwardRef<HTMLDListElement, StatStripProps>(\n\t({ \"aria-busy\": ariaBusy, className, items, loading = false, ...props }, ref) => {\n\t\treturn (\n\t\t\t<dl\n\t\t\t\tref={ref}\n\t\t\t\tclassName={cn(\n\t\t\t\t\tBASALT_UI_CLASS,\n\t\t\t\t\t\"grid grid-cols-2 gap-basalt-layout md:grid-cols-4\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t\taria-busy={loading ? true : ariaBusy}\n\t\t\t>\n\t\t\t\t{items.map((item, index) => (\n\t\t\t\t\t<div key={index} data-basalt-surface=\"\" className=\"rounded-basalt-lg p-basalt-card\">\n\t\t\t\t\t\t<dt className=\"text-basalt-base font-medium text-basalt-muted-foreground\">\n\t\t\t\t\t\t\t{item.label}\n\t\t\t\t\t\t</dt>\n\t\t\t\t\t\t<dd className=\"mt-basalt-space-sm text-basalt-xl font-medium tabular-nums text-basalt-foreground\">\n\t\t\t\t\t\t\t{loading ? <SkeletonLine /> : item.value}\n\t\t\t\t\t\t</dd>\n\t\t\t\t\t</div>\n\t\t\t\t))}\n\t\t\t</dl>\n\t\t);\n\t},\n);\nStatStrip.displayName = \"StatStrip\";\n"],"mappings":";;;;;;;AAyBA,IAAaC,IAAYD,EAAM,YAC7B,EAAE,aAAaE,GAAU,cAAW,UAAO,aAAU,IAAO,GAAGC,KAAS,MAEvE,kBAAC,MAAD;CACM;CACL,WAAWC,EACVC,GACA,qDACAC,CACD;CACA,GAAIH;CACJ,aAAWI,IAAU,KAAOL;CAE3B,UAAAM,EAAM,KAAK,GAAM,MACjB,kBAAC,OAAD;EAAiB,uBAAoB;EAAG,WAAU;EAAlD,UAAA,CACC,kBAAC,MAAD;GAAI,WAAU;GACZ,UAAAC,EAAK;EACH,CAAA,GACJ,kBAAC,MAAD;GAAI,WAAU;GACZ,UAAAF,IAAU,kBAACG,GAAD,CAAe,CAAA,IAAID,EAAK;EAChC,CAAA,CACA;CAPK,GAAAE,CAOL,CACL;AACE,CAAA,CAGP;AACA,EAAU,cAAc"}
@@ -12,10 +12,10 @@ function l(e, t, n) {
12
12
  return n ? e.includes(t) ? e : [...e, t] : e.filter((e) => e !== t);
13
13
  }
14
14
  var u = i.forwardRef(({ className: r, size: i = "default", ...o }, c) => /* @__PURE__ */ a(s.Root, {
15
- className: e(t, "peer inline-flex shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors data-[state=checked]:bg-basalt-primary data-[state=unchecked]:bg-basalt-input disabled:cursor-not-allowed disabled:opacity-50", n, i === "sm" ? "h-4 w-7" : "h-6 w-11", r),
15
+ className: e(t, "peer inline-flex shrink-0 cursor-pointer items-center rounded-basalt-full border-2 border-transparent transition-colors basalt-motion data-[state=checked]:bg-basalt-primary data-[state=unchecked]:bg-basalt-input disabled:cursor-not-allowed disabled:opacity-50", n, i === "sm" ? "h-basalt-4 w-basalt-7" : "h-basalt-6 w-basalt-11", r),
16
16
  ...o,
17
17
  ref: c,
18
- children: /* @__PURE__ */ a(s.Thumb, { className: e("pointer-events-none block rounded-full bg-white shadow-lg ring-0 transition-transform data-[state=unchecked]:translate-x-0", i === "sm" ? "h-3 w-3 data-[state=checked]:translate-x-3" : "h-5 w-5 data-[state=checked]:translate-x-5") })
18
+ children: /* @__PURE__ */ a(s.Thumb, { className: e("pointer-events-none block rounded-basalt-full bg-basalt-on-solid shadow-lg ring-0 transition-transform basalt-motion data-[state=unchecked]:translate-x-0", i === "sm" ? "h-basalt-3 w-basalt-3 data-[state=checked]:translate-x-basalt-3" : "h-basalt-5 w-basalt-5 data-[state=checked]:translate-x-basalt-5") })
19
19
  }));
20
20
  u.displayName = s.Root.displayName;
21
21
  var d = i.forwardRef(({ className: t, value: n, defaultValue: i, onValueChange: s, error: l, disabled: u = !1, children: d, "aria-describedby": f, "aria-invalid": p, ...m }, h) => {
@@ -42,10 +42,10 @@ var d = i.forwardRef(({ className: t, value: n, defaultValue: i, onValueChange:
42
42
  disabled: u,
43
43
  "aria-invalid": g.ariaInvalid,
44
44
  "aria-describedby": g.mergedDescribedBy,
45
- className: e("flex flex-col gap-2", t),
45
+ className: e("basalt-ui flex flex-col gap-basalt-field-gap", t),
46
46
  children: [d, g.invalid ? /* @__PURE__ */ a("p", {
47
47
  id: g.errorId,
48
- className: "text-xs text-basalt-destructive",
48
+ className: "text-basalt-sm text-basalt-destructive",
49
49
  role: "alert",
50
50
  children: l
51
51
  }) : null]
@@ -55,7 +55,7 @@ var d = i.forwardRef(({ className: t, value: n, defaultValue: i, onValueChange:
55
55
  d.displayName = "Switch.Group";
56
56
  var f = i.forwardRef(({ className: t, ...n }, r) => /* @__PURE__ */ a("legend", {
57
57
  ref: r,
58
- className: e("text-sm font-medium text-basalt-foreground", t),
58
+ className: e("mb-basalt-field-gap text-basalt-base font-medium leading-[var(--basalt-line-body)] text-basalt-foreground", t),
59
59
  ...n
60
60
  }));
61
61
  f.displayName = "Switch.Legend";
@@ -77,7 +77,7 @@ var p = i.forwardRef(({ className: e, value: t, children: n, disabled: r, size:
77
77
  });
78
78
  return n == null ? y : /* @__PURE__ */ o("label", {
79
79
  htmlFor: _,
80
- className: "flex items-center gap-2 text-sm text-basalt-foreground",
80
+ className: "flex items-center gap-basalt-space-lg text-basalt-base text-basalt-foreground",
81
81
  children: [y, n]
82
82
  });
83
83
  });
@@ -1 +1 @@
1
- {"version":3,"file":"switch.js","names":["React","SwitchPrimitives","SwitchGroupContext","nextSwitchGroupValue","checked","current","itemValue","entry","SwitchRoot","props","cn","BASALT_UI_CLASS","FOCUS_RING","size","className","SwitchGroup","describedBy","ariaInvalid","group","useCheckableGroup","children","error","SwitchLegend","SwitchItem","grouped","generatedId","controlId","id","isChecked","value","box","disabled","next","Switch"],"sources":["../../src/components/switch.tsx"],"sourcesContent":["import * as SwitchPrimitives from \"@radix-ui/react-switch\";\nimport * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { useCheckableGroup } from \"../utils/use-checkable-group\";\nimport { FOCUS_RING } from \"./overlay\";\n\ntype SwitchGroupContextValue = {\n\tvalue: string[];\n\tsetValue: (next: string[]) => void;\n\tdisabled: boolean;\n\tinvalid: boolean;\n};\n\nconst SwitchGroupContext = React.createContext<SwitchGroupContextValue | null>(null);\n\nfunction nextSwitchGroupValue(current: string[], itemValue: string, checked: boolean): string[] {\n\tif (checked) {\n\t\treturn current.includes(itemValue) ? current : [...current, itemValue];\n\t}\n\treturn current.filter((entry) => entry !== itemValue);\n}\n\nexport type SwitchProps = Omit<\n\tReact.ComponentPropsWithoutRef<typeof SwitchPrimitives.Root>,\n\t\"checked\"\n> & {\n\t/**\n\t * The controlled checked state of the switch.\n\t */\n\tchecked?: boolean;\n\t/**\n\t * The visual size of the switch.\n\t * @default default\n\t */\n\tsize?: \"default\" | \"sm\";\n};\n\nexport type SwitchGroupProps = Omit<\n\tReact.ComponentPropsWithoutRef<\"fieldset\">,\n\t\"onChange\" | \"defaultValue\" | \"disabled\"\n> & {\n\t/**\n\t * The controlled selected values.\n\t */\n\tvalue?: string[];\n\t/**\n\t * The initially selected values.\n\t */\n\tdefaultValue?: string[];\n\t/**\n\t * Called when the selected values change.\n\t */\n\tonValueChange?: (value: string[]) => void;\n\t/**\n\t * Marks the group invalid and shows alert copy.\n\t */\n\terror?: React.ReactNode;\n\t/**\n\t * Disable every item in the group.\n\t * @default false\n\t */\n\tdisabled?: boolean;\n};\n\nexport type SwitchLegendProps = React.ComponentPropsWithoutRef<\"legend\">;\n\nexport type SwitchItemProps = Omit<\n\tSwitchProps,\n\t\"checked\" | \"defaultChecked\" | \"onCheckedChange\" | \"value\"\n> & {\n\t/**\n\t * The value stored in the group when this item is on.\n\t */\n\tvalue: string;\n};\n\nconst SwitchRoot = React.forwardRef<React.ElementRef<typeof SwitchPrimitives.Root>, SwitchProps>(\n\t({ className, size = \"default\", ...props }, ref) => (\n\t\t<SwitchPrimitives.Root\n\t\t\tclassName={cn(\n\t\t\t\tBASALT_UI_CLASS,\n\t\t\t\t\"peer inline-flex shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors data-[state=checked]:bg-basalt-primary data-[state=unchecked]:bg-basalt-input disabled:cursor-not-allowed disabled:opacity-50\",\n\t\t\t\tFOCUS_RING,\n\t\t\t\tsize === \"sm\" ? \"h-4 w-7\" : \"h-6 w-11\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t\tref={ref}\n\t\t>\n\t\t\t<SwitchPrimitives.Thumb\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"pointer-events-none block rounded-full bg-white shadow-lg ring-0 transition-transform data-[state=unchecked]:translate-x-0\",\n\t\t\t\t\tsize === \"sm\"\n\t\t\t\t\t\t? \"h-3 w-3 data-[state=checked]:translate-x-3\"\n\t\t\t\t\t\t: \"h-5 w-5 data-[state=checked]:translate-x-5\",\n\t\t\t\t)}\n\t\t\t/>\n\t\t</SwitchPrimitives.Root>\n\t),\n);\nSwitchRoot.displayName = SwitchPrimitives.Root.displayName;\n\nconst SwitchGroup = React.forwardRef<HTMLFieldSetElement, SwitchGroupProps>(\n\t(\n\t\t{\n\t\t\tclassName,\n\t\t\tvalue,\n\t\t\tdefaultValue,\n\t\t\tonValueChange,\n\t\t\terror,\n\t\t\tdisabled = false,\n\t\t\tchildren,\n\t\t\t\"aria-describedby\": describedBy,\n\t\t\t\"aria-invalid\": ariaInvalid,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst group = useCheckableGroup({\n\t\t\tvalue,\n\t\t\tdefaultValue,\n\t\t\tonValueChange,\n\t\t\terror,\n\t\t\tdescribedBy,\n\t\t\tariaInvalid,\n\t\t\tform: props.form,\n\t\t\tref,\n\t\t});\n\t\treturn (\n\t\t\t<SwitchGroupContext.Provider\n\t\t\t\tvalue={{ value: group.current, setValue: group.setValue, disabled, invalid: group.invalid }}\n\t\t\t>\n\t\t\t\t<fieldset\n\t\t\t\t\tref={group.setRefs}\n\t\t\t\t\t{...props}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\taria-invalid={group.ariaInvalid}\n\t\t\t\t\taria-describedby={group.mergedDescribedBy}\n\t\t\t\t\tclassName={cn(\"flex flex-col gap-2\", className)}\n\t\t\t\t>\n\t\t\t\t\t{children}\n\t\t\t\t\t{group.invalid ? (\n\t\t\t\t\t\t<p id={group.errorId} className=\"text-xs text-basalt-destructive\" role=\"alert\">\n\t\t\t\t\t\t\t{error}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t) : null}\n\t\t\t\t</fieldset>\n\t\t\t</SwitchGroupContext.Provider>\n\t\t);\n\t},\n);\nSwitchGroup.displayName = \"Switch.Group\";\n\nconst SwitchLegend = React.forwardRef<HTMLLegendElement, SwitchLegendProps>(\n\t({ className, ...props }, ref) => (\n\t\t<legend\n\t\t\tref={ref}\n\t\t\tclassName={cn(\"text-sm font-medium text-basalt-foreground\", className)}\n\t\t\t{...props}\n\t\t/>\n\t),\n);\nSwitchLegend.displayName = \"Switch.Legend\";\n\nconst SwitchItem = React.forwardRef<\n\tReact.ElementRef<typeof SwitchPrimitives.Root>,\n\tSwitchItemProps\n>(({ className, value, children, disabled, size, id, ...props }, ref) => {\n\tconst group = React.useContext(SwitchGroupContext);\n\tconst grouped = group != null;\n\tconst generatedId = React.useId();\n\tconst controlId = id ?? generatedId;\n\tconst isChecked = grouped ? group.value.includes(value) : undefined;\n\tconst box = (\n\t\t<SwitchRoot\n\t\t\tref={ref}\n\t\t\t{...props}\n\t\t\tid={controlId}\n\t\t\tvalue={value}\n\t\t\tsize={size}\n\t\t\tchecked={isChecked}\n\t\t\tdefaultChecked={grouped ? isChecked : undefined}\n\t\t\tdisabled={disabled || group?.disabled}\n\t\t\taria-invalid={group?.invalid || undefined}\n\t\t\tclassName={className}\n\t\t\tonCheckedChange={(next) => {\n\t\t\t\tif (grouped) {\n\t\t\t\t\tgroup.setValue(nextSwitchGroupValue(group.value, value, next));\n\t\t\t\t}\n\t\t\t}}\n\t\t/>\n\t);\n\tif (children == null) {\n\t\treturn box;\n\t}\n\treturn (\n\t\t<label htmlFor={controlId} className=\"flex items-center gap-2 text-sm text-basalt-foreground\">\n\t\t\t{box}\n\t\t\t{children}\n\t\t</label>\n\t);\n});\nSwitchItem.displayName = \"Switch.Item\";\n\nexport const Switch = Object.assign(SwitchRoot, {\n\tGroup: SwitchGroup,\n\tLegend: SwitchLegend,\n\tItem: SwitchItem,\n});\n"],"mappings":";;;;;;;;;AAcA,IAAME,IAAqBF,EAAM,cAA8C,IAAI;AAEnF,SAASG,EAAqB,GAAmB,GAAmB,GAA4B;CAI/F,OAHIC,IACIC,EAAQ,SAASC,CAAS,IAAID,IAAU,CAAC,GAAGA,GAASC,CAAS,IAE/DD,EAAQ,QAAQ,MAAUE,MAAUD,CAAS;AACrD;AAwDA,IAAME,IAAaR,EAAM,YACvB,EAAE,cAAW,UAAO,WAAW,GAAGS,KAAS,MAC3C,kBAACR,EAAiB,MAAlB;CACC,WAAWS,EACVC,GACA,kPACAC,GACAC,MAAS,OAAO,YAAY,YAC5BC,CACD;CACA,GAAIL;CACC;CAEL,UAAA,kBAACR,EAAiB,OAAlB,EACC,WAAWS,EACV,8HACAG,MAAS,OACN,+CACA,4CACJ,EACA,CAAA;AACqB,CAAA,CAEzB;AACA,EAAW,cAAcZ,EAAiB,KAAK;AAE/C,IAAMc,IAAcf,EAAM,YAExB,EACC,cACA,UACA,iBACA,kBACA,UACA,cAAW,IACX,aACA,oBAAoBgB,GACpB,gBAAgBC,GAChB,GAAGR,KAEJ,MACI;CACJ,IAAMS,IAAQC,EAAkB;EAC/B;EACA;EACA;EACA;EACA;EACA;EACA,MAAMV,EAAM;EACZ;CACD,CAAC;CACD,OACC,kBAACP,EAAmB,UAApB;EACC,OAAO;GAAE,OAAOgB,EAAM;GAAS,UAAUA,EAAM;GAAU;GAAU,SAASA,EAAM;EAAQ;EAE1F,UAAA,kBAAC,YAAD;GACC,KAAKA,EAAM;GACX,GAAIT;GACM;GACV,gBAAcS,EAAM;GACpB,oBAAkBA,EAAM;GACxB,WAAWR,EAAG,uBAAuBI,CAAS;GAN/C,UAAA,CAQEM,GACAF,EAAM,UACN,kBAAC,KAAD;IAAG,IAAIA,EAAM;IAAS,WAAU;IAAkC,MAAK;IACrE,UAAAG;GACC,CAAA,IACA,IACK;;CACkB,CAAA;AAE/B,CACD;AACA,EAAY,cAAc;AAE1B,IAAMC,IAAetB,EAAM,YACzB,EAAE,cAAW,GAAGS,KAAS,MACzB,kBAAC,UAAD;CACM;CACL,WAAWC,EAAG,8CAA8CI,CAAS;CACrE,GAAIL;AACJ,CAAA,CAEH;AACA,EAAa,cAAc;AAE3B,IAAMc,IAAavB,EAAM,YAGtB,EAAE,cAAW,UAAO,aAAU,aAAU,SAAM,OAAI,GAAGS,KAAS,MAAQ;CACxE,IAAMS,IAAQlB,EAAM,WAAWE,CAAkB,GAC3CsB,IAAUN,KAAS,MACnBO,IAAczB,EAAM,MAAM,GAC1B0B,IAAYC,KAAMF,GAClBG,IAAYJ,IAAUN,EAAM,MAAM,SAASW,CAAK,IAAI,KAAA,GACpDC,IACL,kBAACtB,GAAD;EACM;EACL,GAAIC;EACJ,IAAIiB;EACG;EACD;EACN,SAASE;EACT,gBAAgBJ,IAAUI,IAAY,KAAA;EACtC,UAAUG,KAAYb,GAAO;EAC7B,gBAAcA,GAAO,WAAW,KAAA;EACrB;EACX,kBAAkB,MAAS;GAC1B,AAAIM,KACHN,EAAM,SAASf,EAAqBe,EAAM,OAAOW,GAAOG,CAAI,CAAC;EAE/D;CACA,CAAA;CAKF,OAHIZ,KAAY,OACRU,IAGP,kBAAC,SAAD;EAAO,SAASJ;EAAW,WAAU;EAArC,UAAA,CACEI,GACAV,CACK;;AAET,CAAC;AACD,EAAW,cAAc;AAEzB,IAAaa,IAAS,OAAO,OAAOzB,GAAY;CAC/C,OAAOO;CACP,QAAQO;CACR,MAAMC;AACP,CAAC"}
1
+ {"version":3,"file":"switch.js","names":["React","SwitchPrimitives","SwitchGroupContext","nextSwitchGroupValue","checked","current","itemValue","entry","SwitchRoot","props","cn","BASALT_UI_CLASS","FOCUS_RING","size","className","SwitchGroup","describedBy","ariaInvalid","group","useCheckableGroup","children","error","SwitchLegend","SwitchItem","grouped","generatedId","controlId","id","isChecked","value","box","disabled","next","Switch"],"sources":["../../src/components/switch.tsx"],"sourcesContent":["import * as SwitchPrimitives from \"@radix-ui/react-switch\";\nimport * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { useCheckableGroup } from \"../utils/use-checkable-group\";\nimport { FOCUS_RING } from \"./overlay\";\n\ntype SwitchGroupContextValue = {\n\tvalue: string[];\n\tsetValue: (next: string[]) => void;\n\tdisabled: boolean;\n\tinvalid: boolean;\n};\n\nconst SwitchGroupContext = React.createContext<SwitchGroupContextValue | null>(null);\n\nfunction nextSwitchGroupValue(current: string[], itemValue: string, checked: boolean): string[] {\n\tif (checked) {\n\t\treturn current.includes(itemValue) ? current : [...current, itemValue];\n\t}\n\treturn current.filter((entry) => entry !== itemValue);\n}\n\nexport type SwitchProps = Omit<\n\tReact.ComponentPropsWithoutRef<typeof SwitchPrimitives.Root>,\n\t\"checked\"\n> & {\n\t/**\n\t * The controlled checked state of the switch.\n\t */\n\tchecked?: boolean;\n\t/**\n\t * The visual size of the switch.\n\t * @default default\n\t */\n\tsize?: \"default\" | \"sm\";\n};\n\nexport type SwitchGroupProps = Omit<\n\tReact.ComponentPropsWithoutRef<\"fieldset\">,\n\t\"onChange\" | \"defaultValue\" | \"disabled\"\n> & {\n\t/**\n\t * The controlled selected values.\n\t */\n\tvalue?: string[];\n\t/**\n\t * The initially selected values.\n\t */\n\tdefaultValue?: string[];\n\t/**\n\t * Called when the selected values change.\n\t */\n\tonValueChange?: (value: string[]) => void;\n\t/**\n\t * Marks the group invalid and shows alert copy.\n\t */\n\terror?: React.ReactNode;\n\t/**\n\t * Disable every item in the group.\n\t * @default false\n\t */\n\tdisabled?: boolean;\n};\n\nexport type SwitchLegendProps = React.ComponentPropsWithoutRef<\"legend\">;\n\nexport type SwitchItemProps = Omit<\n\tSwitchProps,\n\t\"checked\" | \"defaultChecked\" | \"onCheckedChange\" | \"value\"\n> & {\n\t/**\n\t * The value stored in the group when this item is on.\n\t */\n\tvalue: string;\n};\n\nconst SwitchRoot = React.forwardRef<React.ElementRef<typeof SwitchPrimitives.Root>, SwitchProps>(\n\t({ className, size = \"default\", ...props }, ref) => (\n\t\t<SwitchPrimitives.Root\n\t\t\tclassName={cn(\n\t\t\t\tBASALT_UI_CLASS,\n\t\t\t\t\"peer inline-flex shrink-0 cursor-pointer items-center rounded-basalt-full border-2 border-transparent transition-colors basalt-motion data-[state=checked]:bg-basalt-primary data-[state=unchecked]:bg-basalt-input disabled:cursor-not-allowed disabled:opacity-50\",\n\t\t\t\tFOCUS_RING,\n\t\t\t\tsize === \"sm\" ? \"h-basalt-4 w-basalt-7\" : \"h-basalt-6 w-basalt-11\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t\tref={ref}\n\t\t>\n\t\t\t<SwitchPrimitives.Thumb\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"pointer-events-none block rounded-basalt-full bg-basalt-on-solid shadow-lg ring-0 transition-transform basalt-motion data-[state=unchecked]:translate-x-0\",\n\t\t\t\t\tsize === \"sm\"\n\t\t\t\t\t\t? \"h-basalt-3 w-basalt-3 data-[state=checked]:translate-x-basalt-3\"\n\t\t\t\t\t\t: \"h-basalt-5 w-basalt-5 data-[state=checked]:translate-x-basalt-5\",\n\t\t\t\t)}\n\t\t\t/>\n\t\t</SwitchPrimitives.Root>\n\t),\n);\nSwitchRoot.displayName = SwitchPrimitives.Root.displayName;\n\nconst SwitchGroup = React.forwardRef<HTMLFieldSetElement, SwitchGroupProps>(\n\t(\n\t\t{\n\t\t\tclassName,\n\t\t\tvalue,\n\t\t\tdefaultValue,\n\t\t\tonValueChange,\n\t\t\terror,\n\t\t\tdisabled = false,\n\t\t\tchildren,\n\t\t\t\"aria-describedby\": describedBy,\n\t\t\t\"aria-invalid\": ariaInvalid,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst group = useCheckableGroup({\n\t\t\tvalue,\n\t\t\tdefaultValue,\n\t\t\tonValueChange,\n\t\t\terror,\n\t\t\tdescribedBy,\n\t\t\tariaInvalid,\n\t\t\tform: props.form,\n\t\t\tref,\n\t\t});\n\t\treturn (\n\t\t\t<SwitchGroupContext.Provider\n\t\t\t\tvalue={{ value: group.current, setValue: group.setValue, disabled, invalid: group.invalid }}\n\t\t\t>\n\t\t\t\t<fieldset\n\t\t\t\t\tref={group.setRefs}\n\t\t\t\t\t{...props}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\taria-invalid={group.ariaInvalid}\n\t\t\t\t\taria-describedby={group.mergedDescribedBy}\n\t\t\t\t\tclassName={cn(\"basalt-ui flex flex-col gap-basalt-field-gap\", className)}\n\t\t\t\t>\n\t\t\t\t\t{children}\n\t\t\t\t\t{group.invalid ? (\n\t\t\t\t\t\t<p id={group.errorId} className=\"text-basalt-sm text-basalt-destructive\" role=\"alert\">\n\t\t\t\t\t\t\t{error}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t) : null}\n\t\t\t\t</fieldset>\n\t\t\t</SwitchGroupContext.Provider>\n\t\t);\n\t},\n);\nSwitchGroup.displayName = \"Switch.Group\";\n\nconst SwitchLegend = React.forwardRef<HTMLLegendElement, SwitchLegendProps>(\n\t({ className, ...props }, ref) => (\n\t\t<legend\n\t\t\tref={ref}\n\t\t\tclassName={cn(\n\t\t\t\t\"mb-basalt-field-gap text-basalt-base font-medium leading-[var(--basalt-line-body)] text-basalt-foreground\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t),\n);\nSwitchLegend.displayName = \"Switch.Legend\";\n\nconst SwitchItem = React.forwardRef<\n\tReact.ElementRef<typeof SwitchPrimitives.Root>,\n\tSwitchItemProps\n>(({ className, value, children, disabled, size, id, ...props }, ref) => {\n\tconst group = React.useContext(SwitchGroupContext);\n\tconst grouped = group != null;\n\tconst generatedId = React.useId();\n\tconst controlId = id ?? generatedId;\n\tconst isChecked = grouped ? group.value.includes(value) : undefined;\n\tconst box = (\n\t\t<SwitchRoot\n\t\t\tref={ref}\n\t\t\t{...props}\n\t\t\tid={controlId}\n\t\t\tvalue={value}\n\t\t\tsize={size}\n\t\t\tchecked={isChecked}\n\t\t\tdefaultChecked={grouped ? isChecked : undefined}\n\t\t\tdisabled={disabled || group?.disabled}\n\t\t\taria-invalid={group?.invalid || undefined}\n\t\t\tclassName={className}\n\t\t\tonCheckedChange={(next) => {\n\t\t\t\tif (grouped) {\n\t\t\t\t\tgroup.setValue(nextSwitchGroupValue(group.value, value, next));\n\t\t\t\t}\n\t\t\t}}\n\t\t/>\n\t);\n\tif (children == null) {\n\t\treturn box;\n\t}\n\treturn (\n\t\t<label\n\t\t\thtmlFor={controlId}\n\t\t\tclassName=\"flex items-center gap-basalt-space-lg text-basalt-base text-basalt-foreground\"\n\t\t>\n\t\t\t{box}\n\t\t\t{children}\n\t\t</label>\n\t);\n});\nSwitchItem.displayName = \"Switch.Item\";\n\nexport const Switch = Object.assign(SwitchRoot, {\n\tGroup: SwitchGroup,\n\tLegend: SwitchLegend,\n\tItem: SwitchItem,\n});\n"],"mappings":";;;;;;;;;AAcA,IAAME,IAAqBF,EAAM,cAA8C,IAAI;AAEnF,SAASG,EAAqB,GAAmB,GAAmB,GAA4B;CAI/F,OAHIC,IACIC,EAAQ,SAASC,CAAS,IAAID,IAAU,CAAC,GAAGA,GAASC,CAAS,IAE/DD,EAAQ,QAAQ,MAAUE,MAAUD,CAAS;AACrD;AAwDA,IAAME,IAAaR,EAAM,YACvB,EAAE,cAAW,UAAO,WAAW,GAAGS,KAAS,MAC3C,kBAACR,EAAiB,MAAlB;CACC,WAAWS,EACVC,GACA,uQACAC,GACAC,MAAS,OAAO,0BAA0B,0BAC1CC,CACD;CACA,GAAIL;CACC;CAEL,UAAA,kBAACR,EAAiB,OAAlB,EACC,WAAWS,EACV,6JACAG,MAAS,OACN,oEACA,iEACJ,EACA,CAAA;AACqB,CAAA,CAEzB;AACA,EAAW,cAAcZ,EAAiB,KAAK;AAE/C,IAAMc,IAAcf,EAAM,YAExB,EACC,cACA,UACA,iBACA,kBACA,UACA,cAAW,IACX,aACA,oBAAoBgB,GACpB,gBAAgBC,GAChB,GAAGR,KAEJ,MACI;CACJ,IAAMS,IAAQC,EAAkB;EAC/B;EACA;EACA;EACA;EACA;EACA;EACA,MAAMV,EAAM;EACZ;CACD,CAAC;CACD,OACC,kBAACP,EAAmB,UAApB;EACC,OAAO;GAAE,OAAOgB,EAAM;GAAS,UAAUA,EAAM;GAAU;GAAU,SAASA,EAAM;EAAQ;EAE1F,UAAA,kBAAC,YAAD;GACC,KAAKA,EAAM;GACX,GAAIT;GACM;GACV,gBAAcS,EAAM;GACpB,oBAAkBA,EAAM;GACxB,WAAWR,EAAG,gDAAgDI,CAAS;GANxE,UAAA,CAQEM,GACAF,EAAM,UACN,kBAAC,KAAD;IAAG,IAAIA,EAAM;IAAS,WAAU;IAAyC,MAAK;IAC5E,UAAAG;GACC,CAAA,IACA,IACK;;CACkB,CAAA;AAE/B,CACD;AACA,EAAY,cAAc;AAE1B,IAAMC,IAAetB,EAAM,YACzB,EAAE,cAAW,GAAGS,KAAS,MACzB,kBAAC,UAAD;CACM;CACL,WAAWC,EACV,6GACAI,CACD;CACA,GAAIL;AACJ,CAAA,CAEH;AACA,EAAa,cAAc;AAE3B,IAAMc,IAAavB,EAAM,YAGtB,EAAE,cAAW,UAAO,aAAU,aAAU,SAAM,OAAI,GAAGS,KAAS,MAAQ;CACxE,IAAMS,IAAQlB,EAAM,WAAWE,CAAkB,GAC3CsB,IAAUN,KAAS,MACnBO,IAAczB,EAAM,MAAM,GAC1B0B,IAAYC,KAAMF,GAClBG,IAAYJ,IAAUN,EAAM,MAAM,SAASW,CAAK,IAAI,KAAA,GACpDC,IACL,kBAACtB,GAAD;EACM;EACL,GAAIC;EACJ,IAAIiB;EACG;EACD;EACN,SAASE;EACT,gBAAgBJ,IAAUI,IAAY,KAAA;EACtC,UAAUG,KAAYb,GAAO;EAC7B,gBAAcA,GAAO,WAAW,KAAA;EACrB;EACX,kBAAkB,MAAS;GAC1B,AAAIM,KACHN,EAAM,SAASf,EAAqBe,EAAM,OAAOW,GAAOG,CAAI,CAAC;EAE/D;CACA,CAAA;CAKF,OAHIZ,KAAY,OACRU,IAGP,kBAAC,SAAD;EACC,SAASJ;EACT,WAAU;EAFX,UAAA,CAIEI,GACAV,CACK;;AAET,CAAC;AACD,EAAW,cAAc;AAEzB,IAAaa,IAAS,OAAO,OAAOzB,GAAY;CAC/C,OAAOO;CACP,QAAQO;CACR,MAAMC;AACP,CAAC"}
@@ -6,20 +6,20 @@ import { jsx as n, jsxs as r } from "react/jsx-runtime";
6
6
  function i({ title: i = "On this page", children: a, className: o }) {
7
7
  return /* @__PURE__ */ r("nav", {
8
8
  "aria-label": i || "On this page",
9
- className: e(t, "text-sm", o),
9
+ className: e(t, "text-basalt-base", o),
10
10
  children: [i ? /* @__PURE__ */ n("p", {
11
- className: "mb-3 text-xs font-semibold tracking-wide text-basalt-muted-foreground uppercase",
11
+ className: "mb-basalt-space-lg text-basalt-sm font-semibold tracking-wide text-basalt-muted-foreground uppercase",
12
12
  children: i
13
13
  }) : null, /* @__PURE__ */ n("ul", {
14
- className: "flex flex-col gap-2 border-l-2 border-basalt-border",
14
+ className: "flex flex-col gap-basalt-space-lg border-l-2 border-basalt-border",
15
15
  children: a
16
16
  })]
17
17
  });
18
18
  }
19
19
  function a({ active: t, href: r, children: i }) {
20
- let a = e("block border-l-2 py-0.5 pl-4", t ? "border-basalt-primary font-medium text-basalt-foreground" : "border-transparent text-basalt-muted-foreground");
20
+ let a = e("block border-l-2 py-basalt-space-xs pl-basalt-space-lg", t ? "border-basalt-primary font-medium text-basalt-foreground" : "border-transparent text-basalt-muted-foreground");
21
21
  return /* @__PURE__ */ n("li", {
22
- className: "-ml-0.5",
22
+ className: "-ml-basalt-space-xs",
23
23
  children: r ? /* @__PURE__ */ n("a", {
24
24
  href: r,
25
25
  "aria-current": t ? "location" : void 0,
@@ -1 +1 @@
1
- {"version":3,"file":"table-of-contents.js","names":["TableOfContents","title","cn","BASALT_UI_CLASS","className","TableOfContentsItem","active","href"],"sources":["../../src/components/table-of-contents.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\n\nexport type TableOfContentsProps = {\n\t/**\n\t * Accessible name and heading. Pass an empty string to hide the heading.\n\t * @default \"On this page\"\n\t */\n\ttitle?: string;\n\t/**\n\t * Section items.\n\t */\n\tchildren: ReactNode;\n\t/**\n\t * Additional classes for the nav.\n\t */\n\tclassName?: string;\n};\n\nexport function TableOfContents({\n\ttitle = \"On this page\",\n\tchildren,\n\tclassName,\n}: TableOfContentsProps) {\n\treturn (\n\t\t<nav aria-label={title || \"On this page\"} className={cn(BASALT_UI_CLASS, \"text-sm\", className)}>\n\t\t\t{title ? (\n\t\t\t\t<p className=\"mb-3 text-xs font-semibold tracking-wide text-basalt-muted-foreground uppercase\">\n\t\t\t\t\t{title}\n\t\t\t\t</p>\n\t\t\t) : null}\n\t\t\t<ul className=\"flex flex-col gap-2 border-l-2 border-basalt-border\">{children}</ul>\n\t\t</nav>\n\t);\n}\n\nexport type TableOfContentsItemProps = {\n\t/**\n\t * Mark the current section.\n\t * @default false\n\t */\n\tactive?: boolean;\n\t/**\n\t * Optional in-page href. Renders a link when set.\n\t */\n\thref?: string;\n\t/**\n\t * Section label.\n\t */\n\tchildren: ReactNode;\n};\n\nexport function TableOfContentsItem({ active, href, children }: TableOfContentsItemProps) {\n\tconst className = cn(\n\t\t\"block border-l-2 py-0.5 pl-4\",\n\t\tactive\n\t\t\t? \"border-basalt-primary font-medium text-basalt-foreground\"\n\t\t\t: \"border-transparent text-basalt-muted-foreground\",\n\t);\n\treturn (\n\t\t<li className=\"-ml-0.5\">\n\t\t\t{href ? (\n\t\t\t\t<a href={href} aria-current={active ? \"location\" : undefined} className={className}>\n\t\t\t\t\t{children}\n\t\t\t\t</a>\n\t\t\t) : (\n\t\t\t\t<span aria-current={active ? \"location\" : undefined} className={className}>\n\t\t\t\t\t{children}\n\t\t\t\t</span>\n\t\t\t)}\n\t\t</li>\n\t);\n}\n"],"mappings":";;;;;AAoBA,SAAgBA,EAAgB,EAC/B,WAAQ,gBACR,aACA,gBACwB;CACxB,OACC,kBAAC,OAAD;EAAK,cAAYC,KAAS;EAAgB,WAAWC,EAAGC,GAAiB,WAAWC,CAAS;EAA7F,UAAA,CACEH,IACA,kBAAC,KAAD;GAAG,WAAU;GACX,UAAAA;EACC,CAAA,IACA,MACJ,kBAAC,MAAD;GAAI,WAAU;GAAuD;EAAa,CAAA,CAC9E;;AAEP;AAkBA,SAAgBI,EAAoB,EAAE,WAAQ,SAAM,eAAsC;CACzF,IAAMD,IAAYF,EACjB,gCACAI,IACG,6DACA,iDACJ;CACA,OACC,kBAAC,MAAD;EAAI,WAAU;EACZ,UAAAC,IACA,kBAAC,KAAD;GAAS;GAAM,gBAAcD,IAAS,aAAa,KAAA;GAAsB;GACvE;EACC,CAAA,IAEH,kBAAC,QAAD;GAAM,gBAAcA,IAAS,aAAa,KAAA;GAAsB;GAC9D;EACI,CAAA;CAEJ,CAAA;AAEN"}
1
+ {"version":3,"file":"table-of-contents.js","names":["TableOfContents","title","cn","BASALT_UI_CLASS","className","TableOfContentsItem","active","href"],"sources":["../../src/components/table-of-contents.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\n\nexport type TableOfContentsProps = {\n\t/**\n\t * Accessible name and heading. Pass an empty string to hide the heading.\n\t * @default \"On this page\"\n\t */\n\ttitle?: string;\n\t/**\n\t * Section items.\n\t */\n\tchildren: ReactNode;\n\t/**\n\t * Additional classes for the nav.\n\t */\n\tclassName?: string;\n};\n\nexport function TableOfContents({\n\ttitle = \"On this page\",\n\tchildren,\n\tclassName,\n}: TableOfContentsProps) {\n\treturn (\n\t\t<nav\n\t\t\taria-label={title || \"On this page\"}\n\t\t\tclassName={cn(BASALT_UI_CLASS, \"text-basalt-base\", className)}\n\t\t>\n\t\t\t{title ? (\n\t\t\t\t<p className=\"mb-basalt-space-lg text-basalt-sm font-semibold tracking-wide text-basalt-muted-foreground uppercase\">\n\t\t\t\t\t{title}\n\t\t\t\t</p>\n\t\t\t) : null}\n\t\t\t<ul className=\"flex flex-col gap-basalt-space-lg border-l-2 border-basalt-border\">\n\t\t\t\t{children}\n\t\t\t</ul>\n\t\t</nav>\n\t);\n}\n\nexport type TableOfContentsItemProps = {\n\t/**\n\t * Mark the current section.\n\t * @default false\n\t */\n\tactive?: boolean;\n\t/**\n\t * Optional in-page href. Renders a link when set.\n\t */\n\thref?: string;\n\t/**\n\t * Section label.\n\t */\n\tchildren: ReactNode;\n};\n\nexport function TableOfContentsItem({ active, href, children }: TableOfContentsItemProps) {\n\tconst className = cn(\n\t\t\"block border-l-2 py-basalt-space-xs pl-basalt-space-lg\",\n\t\tactive\n\t\t\t? \"border-basalt-primary font-medium text-basalt-foreground\"\n\t\t\t: \"border-transparent text-basalt-muted-foreground\",\n\t);\n\treturn (\n\t\t<li className=\"-ml-basalt-space-xs\">\n\t\t\t{href ? (\n\t\t\t\t<a href={href} aria-current={active ? \"location\" : undefined} className={className}>\n\t\t\t\t\t{children}\n\t\t\t\t</a>\n\t\t\t) : (\n\t\t\t\t<span aria-current={active ? \"location\" : undefined} className={className}>\n\t\t\t\t\t{children}\n\t\t\t\t</span>\n\t\t\t)}\n\t\t</li>\n\t);\n}\n"],"mappings":";;;;;AAoBA,SAAgBA,EAAgB,EAC/B,WAAQ,gBACR,aACA,gBACwB;CACxB,OACC,kBAAC,OAAD;EACC,cAAYC,KAAS;EACrB,WAAWC,EAAGC,GAAiB,oBAAoBC,CAAS;EAF7D,UAAA,CAIEH,IACA,kBAAC,KAAD;GAAG,WAAU;GACX,UAAAA;EACC,CAAA,IACA,MACJ,kBAAC,MAAD;GAAI,WAAU;GACZ;EACE,CAAA,CACA;;AAEP;AAkBA,SAAgBI,EAAoB,EAAE,WAAQ,SAAM,eAAsC;CACzF,IAAMD,IAAYF,EACjB,0DACAI,IACG,6DACA,iDACJ;CACA,OACC,kBAAC,MAAD;EAAI,WAAU;EACZ,UAAAC,IACA,kBAAC,KAAD;GAAS;GAAM,gBAAcD,IAAS,aAAa,KAAA;GAAsB;GACvE;EACC,CAAA,IAEH,kBAAC,QAAD;GAAM,gBAAcA,IAAS,aAAa,KAAA;GAAsB;GAC9D;EACI,CAAA;CAEJ,CAAA;AAEN"}
@@ -18,9 +18,9 @@ function o({ className: o, disabled: s = !1, formatRange: c, onPageChange: l, pa
18
18
  totalCount: f
19
19
  };
20
20
  return /* @__PURE__ */ i("div", {
21
- className: e(t, "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", o),
21
+ className: e(t, "flex flex-col gap-basalt-space-lg md:flex-row md:items-center md:justify-between", o),
22
22
  children: [/* @__PURE__ */ r("p", {
23
- className: "text-sm text-basalt-muted-foreground",
23
+ className: "text-basalt-base text-basalt-muted-foreground",
24
24
  children: c ? c(h) : a(h)
25
25
  }), /* @__PURE__ */ r(n, {
26
26
  page: u,
@@ -1 +1 @@
1
- {"version":3,"file":"table-pager.js","names":["defaultRangeText","totalCount","start","end","TablePager","pageCount","pageSize","current","page","range","cn","BASALT_UI_CLASS","className","formatRange","Pagination"],"sources":["../../src/components/table-pager.tsx"],"sourcesContent":["import type * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { Pagination } from \"./pagination\";\n\nexport interface TablePagerRange {\n\tstart: number;\n\tend: number;\n\ttotalCount: number;\n}\n\nexport interface TablePagerProps {\n\t/** 1-based current page. */\n\tpage: number;\n\t/** Number of rows on each page. */\n\tpageSize: number;\n\t/** Total number of rows. */\n\ttotalCount: number;\n\t/** Called with the next 1-based page. */\n\tonPageChange: (page: number) => void;\n\t/**\n\t * Disable every pagination control while keeping the range visible.\n\t * @default false\n\t */\n\tdisabled?: boolean;\n\t/** Replace the default range copy with a custom node. */\n\tformatRange?: (range: TablePagerRange) => React.ReactNode;\n\t/** Additional classes for the pager bar. */\n\tclassName?: string;\n}\n\nfunction defaultRangeText({ start, end, totalCount }: TablePagerRange) {\n\tif (totalCount === 0) {\n\t\treturn \"No results\";\n\t}\n\treturn `Showing ${start}–${end} of ${totalCount}`;\n}\n\nexport function TablePager({\n\tclassName,\n\tdisabled = false,\n\tformatRange,\n\tonPageChange,\n\tpage,\n\tpageSize,\n\ttotalCount,\n}: TablePagerProps) {\n\tconst pageCount = Math.max(1, Math.ceil(totalCount / pageSize));\n\tconst current = Math.min(pageCount, Math.max(1, page));\n\tconst range: TablePagerRange =\n\t\ttotalCount === 0\n\t\t\t? { start: 0, end: 0, totalCount }\n\t\t\t: {\n\t\t\t\t\tstart: (current - 1) * pageSize + 1,\n\t\t\t\t\tend: Math.min(current * pageSize, totalCount),\n\t\t\t\t\ttotalCount,\n\t\t\t\t};\n\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\tBASALT_UI_CLASS,\n\t\t\t\t\"flex flex-col gap-3 md:flex-row md:items-center md:justify-between\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t>\n\t\t\t<p className=\"text-sm text-basalt-muted-foreground\">\n\t\t\t\t{formatRange ? formatRange(range) : defaultRangeText(range)}\n\t\t\t</p>\n\t\t\t<Pagination\n\t\t\t\tpage={page}\n\t\t\t\tpageCount={pageCount}\n\t\t\t\tdisabled={disabled}\n\t\t\t\tonPageChange={onPageChange}\n\t\t\t/>\n\t\t</div>\n\t);\n}\n"],"mappings":";;;;;;AA+BA,SAASA,EAAiB,EAAE,UAAO,QAAK,iBAA+B;CAItE,OAHIC,MAAe,IACX,eAED,WAAWC,EAAM,GAAGC,EAAI,MAAMF;AACtC;AAEA,SAAgBG,EAAW,EAC1B,cACA,cAAW,IACX,gBACA,iBACA,SACA,aACA,iBACmB;CACnB,IAAMC,IAAY,KAAK,IAAI,GAAG,KAAK,KAAKJ,IAAaK,CAAQ,CAAC,GACxDC,IAAU,KAAK,IAAIF,GAAW,KAAK,IAAI,GAAGG,CAAI,CAAC,GAC/CC,IACLR,MAAe,IACZ;EAAE,OAAO;EAAG,KAAK;EAAG;CAAW,IAC/B;EACA,QAAQM,IAAU,KAAKD,IAAW;EAClC,KAAK,KAAK,IAAIC,IAAUD,GAAUL,CAAU;EAC5C;CACD;CAEH,OACC,kBAAC,OAAD;EACC,WAAWS,EACVC,GACA,sEACAC,CACD;EALD,UAAA,CAOC,kBAAC,KAAD;GAAG,WAAU;GACX,UAAAC,IAAcA,EAAYJ,CAAK,IAAIT,EAAiBS,CAAK;EACxD,CAAA,GACH,kBAACK,GAAD;GACO;GACK;GACD;GACI;EACd,CAAA,CACG;;AAEP"}
1
+ {"version":3,"file":"table-pager.js","names":["defaultRangeText","totalCount","start","end","TablePager","pageCount","pageSize","current","page","range","cn","BASALT_UI_CLASS","className","formatRange","Pagination"],"sources":["../../src/components/table-pager.tsx"],"sourcesContent":["import type * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { Pagination } from \"./pagination\";\n\nexport interface TablePagerRange {\n\tstart: number;\n\tend: number;\n\ttotalCount: number;\n}\n\nexport interface TablePagerProps {\n\t/** 1-based current page. */\n\tpage: number;\n\t/** Number of rows on each page. */\n\tpageSize: number;\n\t/** Total number of rows. */\n\ttotalCount: number;\n\t/** Called with the next 1-based page. */\n\tonPageChange: (page: number) => void;\n\t/**\n\t * Disable every pagination control while keeping the range visible.\n\t * @default false\n\t */\n\tdisabled?: boolean;\n\t/** Replace the default range copy with a custom node. */\n\tformatRange?: (range: TablePagerRange) => React.ReactNode;\n\t/** Additional classes for the pager bar. */\n\tclassName?: string;\n}\n\nfunction defaultRangeText({ start, end, totalCount }: TablePagerRange) {\n\tif (totalCount === 0) {\n\t\treturn \"No results\";\n\t}\n\treturn `Showing ${start}–${end} of ${totalCount}`;\n}\n\nexport function TablePager({\n\tclassName,\n\tdisabled = false,\n\tformatRange,\n\tonPageChange,\n\tpage,\n\tpageSize,\n\ttotalCount,\n}: TablePagerProps) {\n\tconst pageCount = Math.max(1, Math.ceil(totalCount / pageSize));\n\tconst current = Math.min(pageCount, Math.max(1, page));\n\tconst range: TablePagerRange =\n\t\ttotalCount === 0\n\t\t\t? { start: 0, end: 0, totalCount }\n\t\t\t: {\n\t\t\t\t\tstart: (current - 1) * pageSize + 1,\n\t\t\t\t\tend: Math.min(current * pageSize, totalCount),\n\t\t\t\t\ttotalCount,\n\t\t\t\t};\n\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\tBASALT_UI_CLASS,\n\t\t\t\t\"flex flex-col gap-basalt-space-lg md:flex-row md:items-center md:justify-between\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t>\n\t\t\t<p className=\"text-basalt-base text-basalt-muted-foreground\">\n\t\t\t\t{formatRange ? formatRange(range) : defaultRangeText(range)}\n\t\t\t</p>\n\t\t\t<Pagination\n\t\t\t\tpage={page}\n\t\t\t\tpageCount={pageCount}\n\t\t\t\tdisabled={disabled}\n\t\t\t\tonPageChange={onPageChange}\n\t\t\t/>\n\t\t</div>\n\t);\n}\n"],"mappings":";;;;;;AA+BA,SAASA,EAAiB,EAAE,UAAO,QAAK,iBAA+B;CAItE,OAHIC,MAAe,IACX,eAED,WAAWC,EAAM,GAAGC,EAAI,MAAMF;AACtC;AAEA,SAAgBG,EAAW,EAC1B,cACA,cAAW,IACX,gBACA,iBACA,SACA,aACA,iBACmB;CACnB,IAAMC,IAAY,KAAK,IAAI,GAAG,KAAK,KAAKJ,IAAaK,CAAQ,CAAC,GACxDC,IAAU,KAAK,IAAIF,GAAW,KAAK,IAAI,GAAGG,CAAI,CAAC,GAC/CC,IACLR,MAAe,IACZ;EAAE,OAAO;EAAG,KAAK;EAAG;CAAW,IAC/B;EACA,QAAQM,IAAU,KAAKD,IAAW;EAClC,KAAK,KAAK,IAAIC,IAAUD,GAAUL,CAAU;EAC5C;CACD;CAEH,OACC,kBAAC,OAAD;EACC,WAAWS,EACVC,GACA,oFACAC,CACD;EALD,UAAA,CAOC,kBAAC,KAAD;GAAG,WAAU;GACX,UAAAC,IAAcA,EAAYJ,CAAK,IAAIT,EAAiBS,CAAK;EACxD,CAAA,GACH,kBAACK,GAAD;GACO;GACK;GACD;GACI;EACd,CAAA,CACG;;AAEP"}
@@ -1,4 +1,7 @@
1
1
  import * as React from "react";
2
+ /** Logical inline alignment. Maps to CSS `text-align: start | end`. */
3
+ export type TableTextAlign = "start" | "end";
4
+ export type TableSortDirection = "asc" | "desc";
2
5
  export type TableProps = {
3
6
  /**
4
7
  * Additional classes for the table.
@@ -33,15 +36,23 @@ export type TableHeadProps = {
33
36
  * Additional classes for the header cell.
34
37
  */
35
38
  className?: string;
39
+ /**
40
+ * Logical inline alignment. Omitted headers keep `text-start` unless native `align` is set.
41
+ */
42
+ textAlign?: TableTextAlign;
36
43
  };
37
- export declare const TableHead: ({ className, ...props }: TableHeadProps & React.ThHTMLAttributes<HTMLTableCellElement>) => React.JSX.Element;
44
+ export declare const TableHead: ({ className, textAlign, align, ...props }: TableHeadProps & React.ThHTMLAttributes<HTMLTableCellElement>) => React.JSX.Element;
38
45
  export type TableCellProps = {
39
46
  /**
40
47
  * Additional classes for the cell.
41
48
  */
42
49
  className?: string;
50
+ /**
51
+ * Logical inline alignment. Omitted cells inherit from the table or row. Native HTML `align` is unchanged.
52
+ */
53
+ textAlign?: TableTextAlign;
43
54
  };
44
- export declare const TableCell: ({ className, ...props }: TableCellProps & React.TdHTMLAttributes<HTMLTableCellElement>) => React.JSX.Element;
55
+ export declare const TableCell: ({ className, textAlign, ...props }: TableCellProps & React.TdHTMLAttributes<HTMLTableCellElement>) => React.JSX.Element;
45
56
  export type TableCaptionProps = {
46
57
  /**
47
58
  * Additional classes for the caption.
@@ -49,3 +60,29 @@ export type TableCaptionProps = {
49
60
  className?: string;
50
61
  };
51
62
  export declare function TableCaption({ className, ...props }: TableCaptionProps & React.HTMLAttributes<HTMLTableCaptionElement>): React.JSX.Element;
63
+ export type TableSortableHeaderProps = {
64
+ children: React.ReactNode;
65
+ /**
66
+ * Logical control layout. `end` places the sort icon inward of the label.
67
+ * @default "start"
68
+ */
69
+ textAlign?: TableTextAlign;
70
+ /**
71
+ * Current sort direction when this column is sorted.
72
+ */
73
+ sorted?: TableSortDirection;
74
+ className?: string;
75
+ } & Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "type" | "children" | "className">;
76
+ export declare const TableSortableHeader: React.ForwardRefExoticComponent<{
77
+ children: React.ReactNode;
78
+ /**
79
+ * Logical control layout. `end` places the sort icon inward of the label.
80
+ * @default "start"
81
+ */
82
+ textAlign?: TableTextAlign;
83
+ /**
84
+ * Current sort direction when this column is sorted.
85
+ */
86
+ sorted?: TableSortDirection;
87
+ className?: string;
88
+ } & Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "children" | "className" | "type"> & React.RefAttributes<HTMLButtonElement>>;
@@ -2,33 +2,64 @@
2
2
  import { cn as e } from "../utils/cn.js";
3
3
  import { BASALT_UI_CLASS as t } from "../utils/control-surface.js";
4
4
  import * as n from "react";
5
- import { jsx as r } from "react/jsx-runtime";
5
+ import { ArrowDown as r, ArrowUp as i, ArrowUpDown as a } from "lucide-react";
6
+ import { Fragment as o, jsx as s, jsxs as c } from "react/jsx-runtime";
6
7
  //#region src/components/table.tsx
7
- var i = n.forwardRef(({ className: n, ...i }, a) => /* @__PURE__ */ r("table", {
8
- ref: a,
8
+ var l = n.forwardRef(({ className: n, ...r }, i) => /* @__PURE__ */ s("table", {
9
+ ref: i,
9
10
  "data-basalt-table": "",
10
- className: e(t, "w-full border-separate border-spacing-0 caption-bottom text-left text-sm text-basalt-foreground", n),
11
- ...i
11
+ className: e(t, "w-full border-separate border-spacing-0 caption-bottom text-start text-basalt-code leading-[var(--basalt-line-body)] text-basalt-foreground", n),
12
+ ...r
12
13
  }));
13
- i.displayName = "Table";
14
- var a = (e) => /* @__PURE__ */ r("thead", { ...e }), o = (e) => /* @__PURE__ */ r("tbody", { ...e }), s = (e) => /* @__PURE__ */ r("tfoot", { ...e }), c = ({ className: e, variant: t = "default", ...n }) => /* @__PURE__ */ r("tr", {
14
+ l.displayName = "Table";
15
+ var u = (e) => /* @__PURE__ */ s("thead", { ...e }), d = (e) => /* @__PURE__ */ s("tbody", { ...e }), f = (e) => /* @__PURE__ */ s("tfoot", { ...e }), p = ({ className: e, variant: t = "default", ...n }) => /* @__PURE__ */ s("tr", {
15
16
  ...n,
16
17
  "aria-selected": t === "selected" || n["aria-selected"],
17
18
  className: e
18
- }), l = ({ className: t, ...n }) => /* @__PURE__ */ r("th", {
19
- className: e("border-b border-basalt-border p-3 text-left text-xs font-medium text-basalt-muted-foreground", t),
20
- ...n
21
- }), u = ({ className: t, ...n }) => /* @__PURE__ */ r("td", {
22
- className: e("p-3", t),
23
- ...n
24
19
  });
25
- function d({ className: t, ...n }) {
26
- return /* @__PURE__ */ r("caption", {
27
- className: e("mt-2 text-sm text-basalt-muted-foreground", t),
20
+ function m(e) {
21
+ if (e === "end") return "text-end tabular-nums";
22
+ if (e === "start") return "text-start";
23
+ }
24
+ var h = ({ className: t, textAlign: n, align: r, ...i }) => /* @__PURE__ */ s("th", {
25
+ className: e("relative h-basalt-table-row whitespace-nowrap border-b border-basalt-border ps-basalt-table-x pe-basalt-table-x py-basalt-table-y align-middle text-basalt-sm font-medium text-basalt-muted-foreground", m(n) ?? (r == null ? "text-start" : void 0), t),
26
+ align: r,
27
+ ...i
28
+ }), g = ({ className: t, textAlign: n, ...r }) => /* @__PURE__ */ s("td", {
29
+ className: e("relative h-basalt-table-row ps-basalt-table-x pe-basalt-table-x py-basalt-table-y align-middle", m(n), t),
30
+ ...r
31
+ });
32
+ function _({ className: t, ...n }) {
33
+ return /* @__PURE__ */ s("caption", {
34
+ className: e("px-basalt-panel-x py-basalt-panel-y text-basalt-base text-basalt-muted-foreground", t),
28
35
  ...n
29
36
  });
30
37
  }
38
+ function v({ sorted: t, trailing: n }) {
39
+ return /* @__PURE__ */ s(t === "asc" ? i : t === "desc" ? r : a, {
40
+ "aria-hidden": "true",
41
+ className: e("size-basalt-icon-sm shrink-0", n && "ms-auto", !t && "opacity-0 transition-opacity basalt-motion group-hover:opacity-60 group-focus-visible:opacity-60 motion-reduce:transition-none"),
42
+ strokeWidth: 1.5
43
+ });
44
+ }
45
+ var y = n.forwardRef(({ children: t, textAlign: n = "start", sorted: r, className: i, ...a }, l) => {
46
+ let u = /* @__PURE__ */ s("span", {
47
+ className: "flex min-w-0 items-center gap-basalt-control-gap truncate",
48
+ children: t
49
+ }), d = /* @__PURE__ */ s(v, {
50
+ sorted: r,
51
+ trailing: n !== "end"
52
+ });
53
+ return /* @__PURE__ */ s("button", {
54
+ type: "button",
55
+ ref: l,
56
+ className: e("group flex w-full cursor-pointer items-center gap-basalt-control-gap rounded-basalt-sm border-0 bg-transparent p-0 font-inherit text-inherit font-medium focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-basalt-primary", n === "end" ? "justify-end text-end" : "text-start", i),
57
+ ...a,
58
+ children: n === "end" ? /* @__PURE__ */ c(o, { children: [d, u] }) : /* @__PURE__ */ c(o, { children: [u, d] })
59
+ });
60
+ });
61
+ y.displayName = "TableSortableHeader";
31
62
  //#endregion
32
- export { i as Table, o as TableBody, d as TableCaption, u as TableCell, s as TableFooter, l as TableHead, a as TableHeader, c as TableRow };
63
+ export { l as Table, d as TableBody, _ as TableCaption, g as TableCell, f as TableFooter, h as TableHead, u as TableHeader, p as TableRow, y as TableSortableHeader };
33
64
 
34
65
  //# sourceMappingURL=table.js.map