@keyfunc/keybricks-ds 1.0.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 (418) hide show
  1. package/DEPLOY.md +204 -0
  2. package/DESIGN.md +269 -0
  3. package/INTEGRATION.md +417 -0
  4. package/SKILL.md +32 -0
  5. package/_adherence.oxlintrc.json +1469 -0
  6. package/_scripts/build-index.mjs +80 -0
  7. package/_scripts/build-tokens.mjs +135 -0
  8. package/assets/icons/icon-index.js +1 -0
  9. package/assets/icons/icon-index.json +1 -0
  10. package/assets/icons/unicons-index.js +1 -0
  11. package/assets/icons/unicons-index.json +1 -0
  12. package/assets/keybricks-logo.png +0 -0
  13. package/components/_cards/accordion.card.html +32 -0
  14. package/components/_cards/action-chip.card.html +22 -0
  15. package/components/_cards/activity.card.html +34 -0
  16. package/components/_cards/alert.card.html +32 -0
  17. package/components/_cards/app-chrome.card.html +36 -0
  18. package/components/_cards/banner.card.html +21 -0
  19. package/components/_cards/brand-visual.card.html +43 -0
  20. package/components/_cards/breadcrumb.card.html +23 -0
  21. package/components/_cards/button-1-base.card.html +39 -0
  22. package/components/_cards/button-2-states.card.html +56 -0
  23. package/components/_cards/button-3-sizes-icons.card.html +32 -0
  24. package/components/_cards/button-4-group.card.html +47 -0
  25. package/components/_cards/canvas-zoom-controls.card.html +19 -0
  26. package/components/_cards/cards-indicators.card.html +59 -0
  27. package/components/_cards/charts-1-sparkline.card.html +55 -0
  28. package/components/_cards/charts-10-gauge.card.html +31 -0
  29. package/components/_cards/charts-11-funnel.card.html +28 -0
  30. package/components/_cards/charts-12-treemap.card.html +23 -0
  31. package/components/_cards/charts-14-radar.card.html +31 -0
  32. package/components/_cards/charts-15-distribution.card.html +32 -0
  33. package/components/_cards/charts-16-pareto.card.html +25 -0
  34. package/components/_cards/charts-17-candlestick.card.html +34 -0
  35. package/components/_cards/charts-18-sankey.card.html +29 -0
  36. package/components/_cards/charts-19-chord.card.html +31 -0
  37. package/components/_cards/charts-2-line.card.html +46 -0
  38. package/components/_cards/charts-20-sunburst.card.html +38 -0
  39. package/components/_cards/charts-21-worldmap.card.html +33 -0
  40. package/components/_cards/charts-22-gantt.card.html +37 -0
  41. package/components/_cards/charts-23-bar3d.card.html +26 -0
  42. package/components/_cards/charts-24-pie3d.card.html +32 -0
  43. package/components/_cards/charts-25-surface3d.card.html +24 -0
  44. package/components/_cards/charts-26-scatter3d.card.html +24 -0
  45. package/components/_cards/charts-27-ribbon3d.card.html +23 -0
  46. package/components/_cards/charts-3-bar.card.html +71 -0
  47. package/components/_cards/charts-4-barlist.card.html +30 -0
  48. package/components/_cards/charts-5-donut.card.html +35 -0
  49. package/components/_cards/charts-6-scatter.card.html +26 -0
  50. package/components/_cards/charts-7-heatmap.card.html +28 -0
  51. package/components/_cards/charts-8-waterfall.card.html +25 -0
  52. package/components/_cards/charts-9-bullet.card.html +31 -0
  53. package/components/_cards/charts-99-fullpage.card.html +194 -0
  54. package/components/_cards/checkbox.card.html +34 -0
  55. package/components/_cards/codeblock.card.html +19 -0
  56. package/components/_cards/combobox.card.html +25 -0
  57. package/components/_cards/context-menu.card.html +21 -0
  58. package/components/_cards/datatable.card.html +48 -0
  59. package/components/_cards/date-picker.card.html +31 -0
  60. package/components/_cards/diffvalue.card.html +21 -0
  61. package/components/_cards/divider.card.html +24 -0
  62. package/components/_cards/drawer.card.html +30 -0
  63. package/components/_cards/dropdown-menu.card.html +38 -0
  64. package/components/_cards/dropzone.card.html +22 -0
  65. package/components/_cards/empty-state.card.html +29 -0
  66. package/components/_cards/filter-bar.card.html +34 -0
  67. package/components/_cards/icon-button.card.html +27 -0
  68. package/components/_cards/icons-1-core.card.html +49 -0
  69. package/components/_cards/icons-2-feather.card.html +39 -0
  70. package/components/_cards/icons-3-unicons.card.html +44 -0
  71. package/components/_cards/input.card.html +25 -0
  72. package/components/_cards/kbd.card.html +20 -0
  73. package/components/_cards/keyvalue.card.html +23 -0
  74. package/components/_cards/listrow.card.html +30 -0
  75. package/components/_cards/loading.card.html +33 -0
  76. package/components/_cards/log-viewer.card.html +23 -0
  77. package/components/_cards/modal.card.html +35 -0
  78. package/components/_cards/multi-select.card.html +26 -0
  79. package/components/_cards/number-stepper.card.html +24 -0
  80. package/components/_cards/pagination.card.html +25 -0
  81. package/components/_cards/people.card.html +46 -0
  82. package/components/_cards/pipeline-node.card.html +76 -0
  83. package/components/_cards/pipeline-palette.card.html +54 -0
  84. package/components/_cards/search.card.html +23 -0
  85. package/components/_cards/select.card.html +23 -0
  86. package/components/_cards/slider.card.html +25 -0
  87. package/components/_cards/smart-table.card.html +37 -0
  88. package/components/_cards/spreadsheet.card.html +31 -0
  89. package/components/_cards/stepper.card.html +25 -0
  90. package/components/_cards/tabs.card.html +25 -0
  91. package/components/_cards/tag.card.html +26 -0
  92. package/components/_cards/textarea.card.html +27 -0
  93. package/components/_cards/timeline.card.html +32 -0
  94. package/components/_cards/toast.card.html +33 -0
  95. package/components/_cards/toggles.card.html +68 -0
  96. package/components/_cards/tooltip.card.html +22 -0
  97. package/components/_cards/tree.card.html +150 -0
  98. package/components/_shared/frame-theme.js +16 -0
  99. package/components/_shared/src-brand.js +1 -0
  100. package/components/_shared/src-buttons.js +1 -0
  101. package/components/_shared/src-charts.js +1 -0
  102. package/components/_shared/src-data.js +1 -0
  103. package/components/_shared/src-display.js +1 -0
  104. package/components/_shared/src-feedback.js +1 -0
  105. package/components/_shared/src-forms.js +1 -0
  106. package/components/_shared/src-icons.js +1 -0
  107. package/components/_shared/src-navigation.js +1 -0
  108. package/components/_shared/src-pipeline.js +1 -0
  109. package/components/_shared/src-tabs.js +1 -0
  110. package/components/_shared/svg-download.js +19 -0
  111. package/components/_shared/view-source.js +185 -0
  112. package/components/_vue/index.mjs +114 -0
  113. package/components/brand/BrandVisual.d.ts +17 -0
  114. package/components/brand/BrandVisual.jsx +29 -0
  115. package/components/brand/BrandVisual.vue +34 -0
  116. package/components/brand/_dir.card.html +13 -0
  117. package/components/brand/brandMotifs.js +210 -0
  118. package/components/buttons/ActionChip.d.ts +10 -0
  119. package/components/buttons/ActionChip.jsx +20 -0
  120. package/components/buttons/ActionChip.vue +18 -0
  121. package/components/buttons/Button.d.ts +40 -0
  122. package/components/buttons/Button.jsx +101 -0
  123. package/components/buttons/Button.vue +87 -0
  124. package/components/buttons/IconButton.d.ts +26 -0
  125. package/components/buttons/IconButton.jsx +28 -0
  126. package/components/buttons/IconButton.vue +21 -0
  127. package/components/buttons/_dir.card.html +13 -0
  128. package/components/buttons/buttons.prompt.md +19 -0
  129. package/components/charts/Bar3D.d.ts +15 -0
  130. package/components/charts/Bar3D.jsx +93 -0
  131. package/components/charts/Bar3D.vue +79 -0
  132. package/components/charts/BarChart.d.ts +23 -0
  133. package/components/charts/BarChart.jsx +135 -0
  134. package/components/charts/BarChart.vue +139 -0
  135. package/components/charts/BarList.d.ts +13 -0
  136. package/components/charts/BarList.jsx +31 -0
  137. package/components/charts/BarList.vue +25 -0
  138. package/components/charts/BoxPlot.d.ts +18 -0
  139. package/components/charts/BoxPlot.jsx +62 -0
  140. package/components/charts/BoxPlot.vue +58 -0
  141. package/components/charts/BulletChart.d.ts +12 -0
  142. package/components/charts/BulletChart.jsx +41 -0
  143. package/components/charts/BulletChart.vue +33 -0
  144. package/components/charts/CandlestickChart.d.ts +15 -0
  145. package/components/charts/CandlestickChart.jsx +63 -0
  146. package/components/charts/CandlestickChart.vue +62 -0
  147. package/components/charts/ChartKit.d.ts +8 -0
  148. package/components/charts/ChartKit.jsx +76 -0
  149. package/components/charts/ChartKit.vue +47 -0
  150. package/components/charts/ChordChart.d.ts +13 -0
  151. package/components/charts/ChordChart.jsx +55 -0
  152. package/components/charts/ChordChart.vue +54 -0
  153. package/components/charts/DonutChart.d.ts +15 -0
  154. package/components/charts/DonutChart.jsx +73 -0
  155. package/components/charts/DonutChart.vue +61 -0
  156. package/components/charts/FunnelChart.d.ts +11 -0
  157. package/components/charts/FunnelChart.jsx +37 -0
  158. package/components/charts/FunnelChart.vue +29 -0
  159. package/components/charts/GanttChart.d.ts +20 -0
  160. package/components/charts/GanttChart.jsx +80 -0
  161. package/components/charts/GanttChart.vue +60 -0
  162. package/components/charts/GaugeChart.d.ts +13 -0
  163. package/components/charts/GaugeChart.jsx +33 -0
  164. package/components/charts/GaugeChart.vue +29 -0
  165. package/components/charts/HeatmapChart.d.ts +13 -0
  166. package/components/charts/HeatmapChart.jsx +62 -0
  167. package/components/charts/HeatmapChart.vue +38 -0
  168. package/components/charts/Histogram.d.ts +16 -0
  169. package/components/charts/Histogram.jsx +56 -0
  170. package/components/charts/Histogram.vue +53 -0
  171. package/components/charts/LineChart.d.ts +17 -0
  172. package/components/charts/LineChart.jsx +84 -0
  173. package/components/charts/LineChart.vue +86 -0
  174. package/components/charts/ParetoChart.d.ts +13 -0
  175. package/components/charts/ParetoChart.jsx +54 -0
  176. package/components/charts/ParetoChart.vue +55 -0
  177. package/components/charts/Pie3D.d.ts +17 -0
  178. package/components/charts/Pie3D.jsx +145 -0
  179. package/components/charts/Pie3D.vue +115 -0
  180. package/components/charts/RadarChart.d.ts +14 -0
  181. package/components/charts/RadarChart.jsx +79 -0
  182. package/components/charts/RadarChart.vue +73 -0
  183. package/components/charts/Ribbon3D.d.ts +13 -0
  184. package/components/charts/Ribbon3D.jsx +89 -0
  185. package/components/charts/Ribbon3D.vue +79 -0
  186. package/components/charts/SankeyChart.d.ts +15 -0
  187. package/components/charts/SankeyChart.jsx +59 -0
  188. package/components/charts/SankeyChart.vue +53 -0
  189. package/components/charts/Scatter3D.d.ts +12 -0
  190. package/components/charts/Scatter3D.jsx +69 -0
  191. package/components/charts/Scatter3D.vue +59 -0
  192. package/components/charts/ScatterChart.d.ts +12 -0
  193. package/components/charts/ScatterChart.jsx +53 -0
  194. package/components/charts/ScatterChart.vue +57 -0
  195. package/components/charts/Sparkline.d.ts +19 -0
  196. package/components/charts/Sparkline.jsx +63 -0
  197. package/components/charts/Sparkline.vue +54 -0
  198. package/components/charts/SunburstChart.d.ts +12 -0
  199. package/components/charts/SunburstChart.jsx +61 -0
  200. package/components/charts/SunburstChart.vue +60 -0
  201. package/components/charts/Surface3D.d.ts +13 -0
  202. package/components/charts/Surface3D.jsx +70 -0
  203. package/components/charts/Surface3D.vue +63 -0
  204. package/components/charts/TreemapChart.d.ts +11 -0
  205. package/components/charts/TreemapChart.jsx +35 -0
  206. package/components/charts/TreemapChart.vue +27 -0
  207. package/components/charts/WaterfallChart.d.ts +11 -0
  208. package/components/charts/WaterfallChart.jsx +59 -0
  209. package/components/charts/WaterfallChart.vue +46 -0
  210. package/components/charts/WorldMap.d.ts +21 -0
  211. package/components/charts/WorldMap.jsx +107 -0
  212. package/components/charts/WorldMap.vue +73 -0
  213. package/components/charts/_dir.card.html +7 -0
  214. package/components/charts/chart-3d.js +84 -0
  215. package/components/charts/chart-geometry.js +223 -0
  216. package/components/charts/charts.prompt.md +24 -0
  217. package/components/data/CodeBlock.d.ts +9 -0
  218. package/components/data/CodeBlock.jsx +19 -0
  219. package/components/data/CodeBlock.vue +22 -0
  220. package/components/data/DataTable.d.ts +28 -0
  221. package/components/data/DataTable.jsx +32 -0
  222. package/components/data/DataTable.vue +25 -0
  223. package/components/data/DiffValue.d.ts +11 -0
  224. package/components/data/DiffValue.jsx +15 -0
  225. package/components/data/DiffValue.vue +13 -0
  226. package/components/data/FilterBar.d.ts +16 -0
  227. package/components/data/FilterBar.jsx +22 -0
  228. package/components/data/FilterBar.vue +23 -0
  229. package/components/data/KeyValue.d.ts +16 -0
  230. package/components/data/KeyValue.jsx +25 -0
  231. package/components/data/KeyValue.vue +26 -0
  232. package/components/data/ListRow.d.ts +14 -0
  233. package/components/data/ListRow.jsx +25 -0
  234. package/components/data/ListRow.vue +25 -0
  235. package/components/data/Pagination.d.ts +12 -0
  236. package/components/data/Pagination.jsx +27 -0
  237. package/components/data/Pagination.vue +24 -0
  238. package/components/data/SmartTable.d.ts +30 -0
  239. package/components/data/SmartTable.jsx +73 -0
  240. package/components/data/SmartTable.vue +74 -0
  241. package/components/data/Spreadsheet.d.ts +33 -0
  242. package/components/data/Spreadsheet.jsx +110 -0
  243. package/components/data/Spreadsheet.vue +95 -0
  244. package/components/data/_dir.card.html +13 -0
  245. package/components/data/data.prompt.md +33 -0
  246. package/components/display/Avatar.d.ts +21 -0
  247. package/components/display/Avatar.jsx +31 -0
  248. package/components/display/Avatar.vue +34 -0
  249. package/components/display/Badge.d.ts +27 -0
  250. package/components/display/Badge.jsx +40 -0
  251. package/components/display/Badge.vue +47 -0
  252. package/components/display/Card.d.ts +27 -0
  253. package/components/display/Card.jsx +27 -0
  254. package/components/display/Card.vue +28 -0
  255. package/components/display/Divider.d.ts +8 -0
  256. package/components/display/Divider.jsx +14 -0
  257. package/components/display/Divider.vue +13 -0
  258. package/components/display/Kbd.d.ts +7 -0
  259. package/components/display/Kbd.jsx +12 -0
  260. package/components/display/Kbd.vue +9 -0
  261. package/components/display/ProgressBar.d.ts +42 -0
  262. package/components/display/ProgressBar.jsx +70 -0
  263. package/components/display/ProgressBar.vue +69 -0
  264. package/components/display/Tag.d.ts +9 -0
  265. package/components/display/Tag.jsx +15 -0
  266. package/components/display/Tag.vue +15 -0
  267. package/components/display/_dir.card.html +13 -0
  268. package/components/display/display.prompt.md +30 -0
  269. package/components/feedback/Accordion.d.ts +13 -0
  270. package/components/feedback/Accordion.jsx +21 -0
  271. package/components/feedback/Accordion.vue +22 -0
  272. package/components/feedback/ActivityItem.d.ts +25 -0
  273. package/components/feedback/ActivityItem.jsx +39 -0
  274. package/components/feedback/ActivityItem.vue +46 -0
  275. package/components/feedback/Alert.d.ts +36 -0
  276. package/components/feedback/Alert.jsx +48 -0
  277. package/components/feedback/Alert.vue +59 -0
  278. package/components/feedback/Banner.d.ts +15 -0
  279. package/components/feedback/Banner.jsx +25 -0
  280. package/components/feedback/Banner.vue +25 -0
  281. package/components/feedback/ContextMenu.d.ts +8 -0
  282. package/components/feedback/ContextMenu.jsx +18 -0
  283. package/components/feedback/ContextMenu.vue +19 -0
  284. package/components/feedback/Drawer.d.ts +18 -0
  285. package/components/feedback/Drawer.jsx +26 -0
  286. package/components/feedback/Drawer.vue +24 -0
  287. package/components/feedback/Menu.d.ts +10 -0
  288. package/components/feedback/Menu.jsx +24 -0
  289. package/components/feedback/Menu.vue +21 -0
  290. package/components/feedback/Modal.d.ts +38 -0
  291. package/components/feedback/Modal.jsx +69 -0
  292. package/components/feedback/Modal.vue +65 -0
  293. package/components/feedback/Stepper.d.ts +9 -0
  294. package/components/feedback/Stepper.jsx +24 -0
  295. package/components/feedback/Stepper.vue +18 -0
  296. package/components/feedback/Timeline.d.ts +15 -0
  297. package/components/feedback/Timeline.jsx +27 -0
  298. package/components/feedback/Timeline.vue +21 -0
  299. package/components/feedback/_dir.card.html +13 -0
  300. package/components/feedback/feedback.prompt.md +35 -0
  301. package/components/forms/Checkbox.d.ts +13 -0
  302. package/components/forms/Checkbox.jsx +17 -0
  303. package/components/forms/Checkbox.vue +18 -0
  304. package/components/forms/Combobox.d.ts +13 -0
  305. package/components/forms/Combobox.jsx +34 -0
  306. package/components/forms/Combobox.vue +35 -0
  307. package/components/forms/DatePicker.d.ts +12 -0
  308. package/components/forms/DatePicker.jsx +48 -0
  309. package/components/forms/DatePicker.vue +46 -0
  310. package/components/forms/Dropzone.d.ts +20 -0
  311. package/components/forms/Dropzone.jsx +36 -0
  312. package/components/forms/Dropzone.vue +28 -0
  313. package/components/forms/Field.d.ts +13 -0
  314. package/components/forms/Field.jsx +13 -0
  315. package/components/forms/Field.vue +12 -0
  316. package/components/forms/Input.d.ts +18 -0
  317. package/components/forms/Input.jsx +35 -0
  318. package/components/forms/Input.vue +38 -0
  319. package/components/forms/MultiSelect.d.ts +14 -0
  320. package/components/forms/MultiSelect.jsx +33 -0
  321. package/components/forms/MultiSelect.vue +36 -0
  322. package/components/forms/NumberStepper.d.ts +13 -0
  323. package/components/forms/NumberStepper.jsx +15 -0
  324. package/components/forms/NumberStepper.vue +17 -0
  325. package/components/forms/Radio.vue +16 -0
  326. package/components/forms/RadioGroup.vue +11 -0
  327. package/components/forms/SearchInput.d.ts +12 -0
  328. package/components/forms/SearchInput.jsx +17 -0
  329. package/components/forms/SearchInput.vue +14 -0
  330. package/components/forms/Select.d.ts +14 -0
  331. package/components/forms/Select.jsx +17 -0
  332. package/components/forms/Select.vue +16 -0
  333. package/components/forms/Slider.d.ts +15 -0
  334. package/components/forms/Slider.jsx +21 -0
  335. package/components/forms/Slider.vue +23 -0
  336. package/components/forms/Switch.d.ts +31 -0
  337. package/components/forms/Switch.jsx +40 -0
  338. package/components/forms/Switch.vue +16 -0
  339. package/components/forms/_dir.card.html +13 -0
  340. package/components/forms/forms.prompt.md +23 -0
  341. package/components/icons/Icon.d.ts +19 -0
  342. package/components/icons/Icon.jsx +93 -0
  343. package/components/icons/Icon.prompt.md +8 -0
  344. package/components/icons/Icon.vue +12 -0
  345. package/components/icons/Unicon.d.ts +12 -0
  346. package/components/icons/Unicon.jsx +16 -0
  347. package/components/icons/Unicon.vue +15 -0
  348. package/components/icons/_dir.card.html +13 -0
  349. package/components/icons/feather-paths.js +2 -0
  350. package/components/icons/icon-paths.js +73 -0
  351. package/components/index.d.ts +87 -0
  352. package/components/index.js +110 -0
  353. package/components/navigation/Breadcrumb.d.ts +24 -0
  354. package/components/navigation/Breadcrumb.jsx +120 -0
  355. package/components/navigation/Breadcrumb.vue +94 -0
  356. package/components/navigation/DocTree.d.ts +18 -0
  357. package/components/navigation/DocTree.jsx +37 -0
  358. package/components/navigation/DocTree.vue +25 -0
  359. package/components/navigation/Sidebar.d.ts +29 -0
  360. package/components/navigation/Sidebar.jsx +75 -0
  361. package/components/navigation/Sidebar.vue +54 -0
  362. package/components/navigation/TopBar.d.ts +27 -0
  363. package/components/navigation/TopBar.jsx +44 -0
  364. package/components/navigation/TopBar.vue +51 -0
  365. package/components/navigation/Tree.d.ts +83 -0
  366. package/components/navigation/Tree.jsx +347 -0
  367. package/components/navigation/Tree.vue +258 -0
  368. package/components/navigation/_dir.card.html +13 -0
  369. package/components/navigation/navigation.prompt.md +22 -0
  370. package/components/pipeline/ConfigPanel.d.ts +18 -0
  371. package/components/pipeline/ConfigPanel.jsx +30 -0
  372. package/components/pipeline/ConfigPanel.vue +32 -0
  373. package/components/pipeline/DataPreview.d.ts +14 -0
  374. package/components/pipeline/DataPreview.jsx +24 -0
  375. package/components/pipeline/DataPreview.vue +21 -0
  376. package/components/pipeline/NodeCard.d.ts +47 -0
  377. package/components/pipeline/NodeCard.jsx +97 -0
  378. package/components/pipeline/NodeCard.vue +75 -0
  379. package/components/pipeline/PaletteItem.vue +15 -0
  380. package/components/pipeline/PaletteListItem.vue +15 -0
  381. package/components/pipeline/PalettePanel.d.ts +20 -0
  382. package/components/pipeline/PalettePanel.jsx +74 -0
  383. package/components/pipeline/PalettePanel.vue +45 -0
  384. package/components/pipeline/PipelineCanvas.d.ts +25 -0
  385. package/components/pipeline/PipelineCanvas.jsx +94 -0
  386. package/components/pipeline/PipelineCanvas.vue +73 -0
  387. package/components/pipeline/ZoomControls.d.ts +9 -0
  388. package/components/pipeline/ZoomControls.jsx +15 -0
  389. package/components/pipeline/ZoomControls.vue +15 -0
  390. package/components/pipeline/_dir.card.html +13 -0
  391. package/components/pipeline/pipeline.prompt.md +22 -0
  392. package/components/tabs/SegmentedControl.d.ts +11 -0
  393. package/components/tabs/SegmentedControl.jsx +21 -0
  394. package/components/tabs/SegmentedControl.vue +15 -0
  395. package/components/tabs/Tabs.d.ts +13 -0
  396. package/components/tabs/Tabs.jsx +52 -0
  397. package/components/tabs/Tabs.vue +39 -0
  398. package/components/tabs/ViewToggle.d.ts +8 -0
  399. package/components/tabs/ViewToggle.jsx +12 -0
  400. package/components/tabs/ViewToggle.vue +12 -0
  401. package/components/tabs/_dir.card.html +13 -0
  402. package/components/tabs/tabs.prompt.md +14 -0
  403. package/package.json +76 -0
  404. package/readme.md +150 -0
  405. package/styles.css +10 -0
  406. package/tokens/alpha.css +27 -0
  407. package/tokens/charts.css +55 -0
  408. package/tokens/colors-extended.css +40 -0
  409. package/tokens/colors.css +39 -0
  410. package/tokens/dark.css +96 -0
  411. package/tokens/fonts.css +4 -0
  412. package/tokens/interaction.css +48 -0
  413. package/tokens/layout.css +30 -0
  414. package/tokens/motion.css +22 -0
  415. package/tokens/tokens.d.ts +680 -0
  416. package/tokens/tokens.js +1018 -0
  417. package/tokens/tokens.json +2928 -0
  418. package/tokens/typography.css +22 -0
@@ -0,0 +1,210 @@
1
+ /* Keybricks brand motifs — generative geometry for BrandVisual.
2
+ Every motif is authored against one canvas (1200×400) and expressed in fractions of W/H,
3
+ so a single component renders at any size. Deterministic: seeded PRNG per motif. */
4
+
5
+ const seeded = (s) => { let a = s >>> 0; return () => { a = (a * 1664525 + 1013904223) >>> 0; return a / 4294967296; }; };
6
+ const lerp = (a, b, t) => a + (b - a) * t;
7
+ const clamp = (v, a, b) => Math.min(b, Math.max(a, v));
8
+ const n = (v) => Math.round(v * 10) / 10;
9
+
10
+ export const motifList = ["orbit", "entropy", "focal", "manifold", "tesseract", "meridian", "ledger"];
11
+ export const motifLabels = {
12
+ orbit: "Orbit — concentric arcs",
13
+ entropy: "Entropy — crystal and dust",
14
+ focal: "Focal — depth-of-field lattice",
15
+ manifold: "Manifold — parametric surface",
16
+ tesseract: "Tesseract — nested cubes",
17
+ meridian: "Meridian — bent meridians",
18
+ ledger: "Ledger — scale and cursor",
19
+ };
20
+
21
+ const LINE = "#51a2ff", BRIGHT = "#93c5fd", HI = "#dbeafe";
22
+
23
+ /** Returns { viewBox, els } — els are plain SVG element descriptors: { t, ...attrs }. */
24
+ export function buildMotif(motif = "orbit", W = 1200, H = 400) {
25
+ const rnd = seeded(motif.length * 7919 + 104729);
26
+ const els = [];
27
+ const push = (t, a) => els.push({ t, ...a });
28
+ const line = (d, o, w = 1, stroke = LINE, filter) => push("path", { d, fill: "none", stroke, "stroke-opacity": o, "stroke-width": w, ...(filter ? { filter } : null) });
29
+ const dot = (x, y, r, fill, o) => push("circle", { cx: n(x), cy: n(y), r: n(r), fill, "fill-opacity": o });
30
+ const ring = (x, y, r, o, w = 1.5, stroke = HI) => push("circle", { cx: n(x), cy: n(y), r: n(r), fill: "none", stroke, "stroke-opacity": o, "stroke-width": w });
31
+ const marker = (x, y, s = 1) => { dot(x, y, 4.5 * s, HI, 1); ring(x, y, 12 * s, 0.55); ring(x, y, 25 * s, 0.22, 1.2, BRIGHT); };
32
+ const grid = (cols, rows, o = 0.14) => {
33
+ for (let i = 1; i < rows; i++) line(`M 0 ${n(H * i / rows)} L ${W} ${n(H * i / rows)}`, o, 1, BRIGHT);
34
+ for (let i = 1; i < cols; i++) line(`M ${n(W * i / cols)} 0 L ${n(W * i / cols)} ${H}`, o, 1, BRIGHT);
35
+ };
36
+
37
+ if (motif === "orbit") {
38
+ push("rect", { width: W, height: H, fill: "url(#kbv-bg)" });
39
+ push("ellipse", { cx: n(W * 0.72), cy: n(H * 0.2), rx: n(W * 0.36), ry: n(H * 0.78), fill: "url(#kbv-core)" });
40
+ push("ellipse", { cx: n(W * 0.12), cy: n(H * 0.92), rx: n(W * 0.28), ry: n(H * 0.5), fill: "url(#kbv-glow)", opacity: 0.55 });
41
+ grid(4, 3);
42
+ const cx = W * 0.84, cy = H * 1.06;
43
+ const arc = (r, a1, a2) => {
44
+ const p = (a) => [cx + r * Math.cos(a * Math.PI / 180), cy + r * Math.sin(a * Math.PI / 180)];
45
+ const [x1, y1] = p(a1), [x2, y2] = p(a2);
46
+ return `M ${n(x1)} ${n(y1)} A ${n(r)} ${n(r)} 0 0 1 ${n(x2)} ${n(y2)}`;
47
+ };
48
+ const wedge = (r, a1, a2) => `M ${n(cx)} ${n(cy)} L ${arc(r, a1, a2).slice(2)} Z`;
49
+ push("path", { d: wedge(H * 1.24, 194, 248), fill: LINE, opacity: 0.2 });
50
+ push("path", { d: wedge(H * 1.24, 248, 262), fill: BRIGHT, opacity: 0.16 });
51
+ push("path", { d: wedge(H * 0.86, 206, 252), fill: "#155dfc", opacity: 0.42 });
52
+ [[1.62, 0.2], [1.28, 0.34], [0.98, 0.5], [0.7, 0.66], [0.44, 0.4]].forEach(([k, o], i) =>
53
+ line(arc(H * k, 178, 272), o, i === 2 ? 1.5 : 1, i > 1 ? BRIGHT : LINE));
54
+ marker(W * 0.34, H * 0.78);
55
+ dot(W * 0.25, H * 0.28, 3, HI, 0.9);
56
+ dot(W * 0.11, H * 0.6, 2.5, BRIGHT, 0.7);
57
+ dot(W * 0.75, H * 0.28, 2.5, HI, 0.6);
58
+ }
59
+
60
+ if (motif === "entropy") {
61
+ push("rect", { width: W, height: H, fill: "url(#kbv-bg-d)" });
62
+ push("ellipse", { cx: n(W * 0.74), cy: n(H * 0.35), rx: n(W * 0.4), ry: n(H * 0.82), fill: "url(#kbv-core)" });
63
+ push("ellipse", { cx: n(W * 0.18), cy: n(H * 0.95), rx: n(W * 0.3), ry: n(H * 0.5), fill: "url(#kbv-glow)", opacity: 0.45 });
64
+ const NX = 11, NY = 6, NZ = 3, nuc = [8.2, 1.1, 2.05];
65
+ const sx = W * 0.042, sy = H * 0.072, sz = H * 0.132, nx = W * 0.745, ny = H * 0.335;
66
+ const iso = (x, y, z) => [nx + ((x - nuc[0]) - (y - nuc[1])) * sx, ny + ((x - nuc[0]) + (y - nuc[1])) * sy - (z - nuc[2]) * sz];
67
+ const nodes = new Map();
68
+ for (let x = 0; x < NX; x++) for (let y = 0; y < NY; y++) for (let z = 0; z < NZ; z++) {
69
+ const dn = Math.hypot((x - nuc[0]) * 0.92, (y - nuc[1]) * 0.72, (z - nuc[2]) * 1.15);
70
+ const order = clamp(1 - (dn - 1.5) / 5.4 + (rnd() - 0.5) * 0.24, 0, 1);
71
+ if (order < 0.1 && rnd() < 0.66) continue;
72
+ const c = iso(x, y, z), chaos = Math.pow(1 - order, 1.75);
73
+ nodes.set(`${x},${y},${z}`, { px: c[0] + (rnd() - 0.5) * W * 0.17 * chaos, py: c[1] + (rnd() - 0.5) * H * 0.52 * chaos, order, depth: x + y - z * 1.2 });
74
+ }
75
+ for (const [k, p] of nodes) {
76
+ const [x, y, z] = k.split(",").map(Number);
77
+ [[x + 1, y, z], [x, y + 1, z], [x, y, z + 1]].forEach((q) => {
78
+ const b = nodes.get(q.join(","));
79
+ if (!b) return;
80
+ const o = Math.min(p.order, b.order);
81
+ if (o < 0.28 && rnd() < 0.62) return;
82
+ const near = clamp(1 - (p.depth + 5) / 16, 0, 1);
83
+ const d = `M ${n(p.px)} ${n(p.py)} L ${n(b.px)} ${n(b.py)}`;
84
+ if (o > 0.82) line(d, 0.34, 3.4, BRIGHT, "url(#kbv-b2)");
85
+ line(d, lerp(0.05, 0.62, Math.pow(o, 1.2)) * lerp(0.55, 1.15, near), lerp(1, 1.5, o), o > 0.7 ? BRIGHT : LINE);
86
+ });
87
+ }
88
+ for (const [, p] of nodes) {
89
+ const near = clamp(1 - (p.depth + 5) / 16, 0, 1);
90
+ dot(p.px, p.py, lerp(1.1, 3.2, near) * lerp(0.65, 1, p.order), p.order > 0.72 ? HI : BRIGHT, lerp(0.2, 0.95, p.order * 0.65 + near * 0.35));
91
+ }
92
+ for (let i = 0; i < 34; i++) {
93
+ const x = rnd() * W * 0.42, y = rnd() * H, L = lerp(W * 0.004, W * 0.022, rnd());
94
+ const a = Math.atan2(ny - y, nx - x) + (rnd() - 0.5) * 0.7;
95
+ line(`M ${n(x)} ${n(y)} L ${n(x + Math.cos(a) * L)} ${n(y + Math.sin(a) * L)}`, lerp(0.07, 0.3, rnd()), 1, BRIGHT, rnd() < 0.45 ? "url(#kbv-b1)" : undefined);
96
+ }
97
+ for (let i = 0; i < 18; i++) dot(rnd() * W * 0.46, rnd() * H, lerp(0.6, 1.7, rnd()), BRIGHT, lerp(0.12, 0.42, rnd()));
98
+ push("circle", { cx: n(nx), cy: n(ny), r: n(H * 0.06), fill: LINE, "fill-opacity": 0.3, filter: "url(#kbv-b3)" });
99
+ marker(nx, ny);
100
+ }
101
+
102
+ if (motif === "focal") {
103
+ push("rect", { width: W, height: H, fill: "url(#kbv-bg-v)" });
104
+ push("ellipse", { cx: n(W * 0.5), cy: n(H * 0.3), rx: n(W * 0.42), ry: n(H * 0.5), fill: "url(#kbv-glow)" });
105
+ const R = 11, C = 15, pts = [];
106
+ for (let i = 0; i <= R; i++) {
107
+ const t = i / R, y = lerp(H * 0.26, H * 1.02, Math.pow(t, 1.4)), half = lerp(W * 0.17, W * 0.6, Math.pow(t, 1.08));
108
+ const row = [];
109
+ for (let j = 0; j <= C; j++) row.push([W * 0.48 + lerp(-half, half, j / C) - W * 0.04 * (1 - t), y - H * 0.03 * Math.sin(j / C * Math.PI * 1.6)]);
110
+ pts.push({ row, t });
111
+ }
112
+ pts.forEach(({ row, t }) => {
113
+ line(row.map(([x, y], j) => `${j ? "L" : "M"} ${n(x)} ${n(y)}`).join(" "), lerp(0.08, 0.42, t), 1, t > 0.6 ? BRIGHT : LINE);
114
+ });
115
+ for (let j = 0; j <= C; j += 1) {
116
+ line(pts.map(({ row }, i) => `${i ? "L" : "M"} ${n(row[j][0])} ${n(row[j][1])}`).join(" "), j % 3 === 0 ? 0.2 : 0.09, 1, LINE);
117
+ }
118
+ pts.forEach(({ row, t }) => row.forEach(([x, y]) => dot(x, y, lerp(1, 3, t), t > 0.55 ? HI : BRIGHT, lerp(0.22, 0.9, t))));
119
+ marker(W * 0.82, H * 0.34, 0.9);
120
+ }
121
+
122
+ if (motif === "manifold") {
123
+ push("rect", { width: W, height: H, fill: "url(#kbv-bg-v)" });
124
+ push("ellipse", { cx: n(W * 0.5), cy: n(H * 0.32), rx: n(W * 0.42), ry: n(H * 0.46), fill: "url(#kbv-glow)" });
125
+ const V = 9, U = 16, span = W * 0.46;
126
+ const f = (u, v) => {
127
+ const t = v / V, x = lerp(W * 0.5 - span * (0.35 + 0.65 * t), W * 0.5 + span * (0.35 + 0.65 * t), u / U);
128
+ const y = lerp(H * 0.27, H * 1.03, Math.pow(t, 1.5));
129
+ const z = Math.sin(u / U * Math.PI * 2.2 + t * 3) * Math.cos(t * 2.4) * H * 0.077 * (0.4 + t);
130
+ return [x, y - z, z];
131
+ };
132
+ for (let v = 0; v <= V; v++) {
133
+ let d = "", peak = null, pz = -1e9;
134
+ for (let u = 0; u <= U; u++) { const [x, y, z] = f(u, v); d += `${u ? " L " : "M "}${n(x)} ${n(y)}`; if (z > pz) { pz = z; peak = [x, y]; } }
135
+ const t = v / V;
136
+ line(d, lerp(0.15, 0.55, t), 1.2, t > 0.7 ? BRIGHT : LINE);
137
+ if (v === 6) marker(peak[0], peak[1], 0.9);
138
+ }
139
+ for (let u = 0; u <= U; u += 2) {
140
+ let d = "";
141
+ for (let v = 0; v <= V; v++) { const [x, y] = f(u, v); d += `${v ? " L " : "M "}${n(x)} ${n(y)}`; }
142
+ line(d, 0.14, 1.2);
143
+ }
144
+ }
145
+
146
+ if (motif === "tesseract") {
147
+ push("rect", { width: W, height: H, fill: "url(#kbv-bg)" });
148
+ push("ellipse", { cx: n(W * 0.5), cy: n(H * 0.46), rx: n(W * 0.4), ry: n(H * 0.56), fill: "url(#kbv-core)" });
149
+ const cx = W * 0.5, cy = H * 0.5;
150
+ const cube = (r, rt, o, c, w) => {
151
+ const p = [];
152
+ for (let i = 0; i < 4; i++) { const a = rt + i * Math.PI / 2; p.push([cx + r * Math.cos(a), cy + r * Math.sin(a) * 0.82]); }
153
+ const up = p.map(([x, y]) => [x, y - r * 0.62]);
154
+ for (let i = 0; i < 4; i++) {
155
+ const j = (i + 1) % 4;
156
+ line(`M ${n(p[i][0])} ${n(p[i][1])} L ${n(p[j][0])} ${n(p[j][1])}`, o, w, c);
157
+ line(`M ${n(up[i][0])} ${n(up[i][1])} L ${n(up[j][0])} ${n(up[j][1])}`, o, w, c);
158
+ line(`M ${n(p[i][0])} ${n(p[i][1])} L ${n(up[i][0])} ${n(up[i][1])}`, o * 0.8, w, c);
159
+ }
160
+ return { p, up };
161
+ };
162
+ const A = cube(H * 0.44, Math.PI / 4 + 0.2, 0.32, LINE, 1.2);
163
+ const B = cube(H * 0.218, Math.PI / 4 + 0.55, 0.75, BRIGHT, 1.4);
164
+ for (let i = 0; i < 4; i++) {
165
+ line(`M ${n(A.p[i][0])} ${n(A.p[i][1])} L ${n(B.p[i][0])} ${n(B.p[i][1])}`, 0.22, 1.2);
166
+ line(`M ${n(A.up[i][0])} ${n(A.up[i][1])} L ${n(B.up[i][0])} ${n(B.up[i][1])}`, 0.22, 1.2);
167
+ }
168
+ marker(B.up[1][0], B.up[1][1], 0.85);
169
+ dot(W * 0.14, H * 0.79, 2.5, HI, 0.65);
170
+ dot(W * 0.87, H * 0.2, 2.5, HI, 0.65);
171
+ }
172
+
173
+ if (motif === "meridian") {
174
+ push("rect", { width: W, height: H, fill: "url(#kbv-bg-v)" });
175
+ push("ellipse", { cx: n(W * 0.5), cy: n(H * 0.5), rx: n(W * 0.34), ry: n(H * 0.62), fill: "url(#kbv-core)" });
176
+ const cx = W * 0.5, cy = H * 0.5;
177
+ for (let j = 0; j <= 12; j++) {
178
+ const x0 = lerp(W * 0.06, W * 0.94, j / 12), k = (x0 - cx) / (W * 0.5);
179
+ let d = "";
180
+ for (let i = 0; i <= 24; i++) {
181
+ const y = lerp(-H * 0.04, H * 1.04, i / 24);
182
+ const bend = k * W * 0.055 * Math.exp(-Math.pow((y - cy) / (H * 0.42), 2));
183
+ d += `${i ? " L " : "M "}${n(x0 + bend)} ${n(y)}`;
184
+ }
185
+ line(d, lerp(0.42, 0.16, Math.abs(k)), Math.abs(k) < 0.2 ? 1.4 : 1, Math.abs(k) < 0.35 ? BRIGHT : LINE);
186
+ }
187
+ line(`M 0 ${n(cy)} L ${W} ${n(cy)}`, 0.14, 1, BRIGHT);
188
+ marker(cx, cy);
189
+ dot(W * 0.2, H * 0.22, 2.5, BRIGHT, 0.6);
190
+ dot(W * 0.84, H * 0.78, 2, BRIGHT, 0.5);
191
+ }
192
+
193
+ if (motif === "ledger") {
194
+ push("rect", { width: W, height: H, fill: "url(#kbv-bg-d)" });
195
+ push("ellipse", { cx: n(W * 0.5), cy: n(H * 1.04), rx: n(W * 0.46), ry: n(H * 0.66), fill: "url(#kbv-glow)" });
196
+ grid(8, 4, 0.12);
197
+ for (let i = 1; i < 40; i++) {
198
+ const x = W * i / 40, major = i % 5 === 0;
199
+ line(`M ${n(x)} ${n(H * 0.68)} L ${n(x)} ${n(H * 0.68 + (major ? H * 0.09 : H * 0.045))}`, major ? 0.5 : 0.24, 1, major ? BRIGHT : LINE);
200
+ }
201
+ const cur = W * 0.48;
202
+ line(`M ${n(cur)} 0 L ${n(cur)} ${H}`, 0.6, 1.4, HI);
203
+ line(`M ${n(cur)} 0 L ${n(cur)} ${H}`, 0.22, 4, BRIGHT, "url(#kbv-b2)");
204
+ marker(cur, H * 0.42, 0.9);
205
+ dot(W * 0.18, H * 0.22, 2.5, BRIGHT, 0.55);
206
+ dot(W * 0.72, H * 0.72, 2, BRIGHT, 0.45);
207
+ }
208
+
209
+ return { viewBox: `0 0 ${W} ${H}`, els };
210
+ }
@@ -0,0 +1,10 @@
1
+ import * as React from "react";
2
+ /** Tinted bulk-action chip (comparison-table actions). 30px, r8, 12px/500. */
3
+ export interface ActionChipProps {
4
+ /** success #ecfdf5/#007a55 · warning #fff7ed/#ca3500 · neutral #f5f5f5/#525252 · info · danger */
5
+ tone?: "success" | "warning" | "neutral" | "info" | "danger";
6
+ onClick?: () => void;
7
+ children?: React.ReactNode;
8
+ style?: React.CSSProperties;
9
+ }
10
+ export declare function ActionChip(props: ActionChipProps): JSX.Element;
@@ -0,0 +1,20 @@
1
+ import React from "react";
2
+
3
+ const chipTones = {
4
+ success: { background: "var(--success-bg)", color: "var(--success-text)" },
5
+ warning: { background: "var(--warning-bg)", color: "var(--warning-text)" },
6
+ neutral: { background: "var(--bg-hover)", color: "var(--text-body)" },
7
+ info: { background: "var(--info-bg)", color: "var(--action-primary)" },
8
+ danger: { background: "var(--danger-bg)", color: "var(--danger-text)" },
9
+ };
10
+
11
+ /** Tinted bulk-action chip ("Mark as New", "Mark as Overwrite", "Skip Selected"). */
12
+ export function ActionChip({ tone = "neutral", children, onClick, style }) {
13
+ const [hover, setHover] = React.useState(false);
14
+ return (
15
+ <button type="button" onClick={onClick} onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)}
16
+ style={{ height: 30, padding: "0 12px", borderRadius: "var(--radius-md)", border: "none", cursor: "pointer", fontFamily: "var(--font-sans)", fontWeight: "var(--weight-medium)", fontSize: "var(--text-sm)", lineHeight: "var(--leading-sm)", display: "inline-flex", alignItems: "center", filter: hover ? "brightness(1.06) saturate(1.05)" : "none", transition: "var(--t-hover),filter var(--dur-fast) var(--ease-out)", ...chipTones[tone], ...style }}>
17
+ {children}
18
+ </button>
19
+ );
20
+ }
@@ -0,0 +1,18 @@
1
+ <script setup>
2
+ import { ref, computed } from 'vue'
3
+ const chipTones = {
4
+ success: { background: 'var(--success-bg)', color: 'var(--success-text)' },
5
+ warning: { background: 'var(--warning-bg)', color: 'var(--warning-text)' },
6
+ neutral: { background: 'var(--bg-hover)', color: 'var(--text-body)' },
7
+ info: { background: 'var(--info-bg)', color: 'var(--action-primary)' },
8
+ danger: { background: 'var(--danger-bg)', color: 'var(--danger-text)' },
9
+ }
10
+ // Tinted bulk-action chip ("Mark as New", "Mark as Overwrite", "Skip Selected").
11
+ const props = defineProps({ tone: { type: String, default: 'neutral' }, style: Object })
12
+ defineEmits(['click'])
13
+ const hover = ref(false)
14
+ const s = computed(() => ({ height: 30, padding: '0 12px', borderRadius: 'var(--radius-md)', border: 'none', cursor: 'pointer', fontFamily: 'var(--font-sans)', fontWeight: 'var(--weight-medium)', fontSize: 'var(--text-sm)', lineHeight: 'var(--leading-sm)', display: 'inline-flex', alignItems: 'center', filter: hover.value ? 'brightness(1.06) saturate(1.05)' : 'none', transition: 'var(--t-hover),filter var(--dur-fast) var(--ease-out)', ...chipTones[props.tone], ...props.style }))
15
+ </script>
16
+ <template>
17
+ <button type="button" @click="$emit('click')" @mouseenter="hover = true" @mouseleave="hover = false" :style="s"><slot /></button>
18
+ </template>
@@ -0,0 +1,40 @@
1
+ import * as React from "react";
2
+ /**
3
+ * Keybricks button — flat, hairline, 13px default.
4
+ */
5
+ export interface ButtonProps {
6
+ /** primary (blue #155dfc) | dark (#171717, e.g. "AI Assistant") | outline | ghost | primary-soft (blue tint toggle, e.g. "Data Preview") | danger (solid red, destructive) | danger-soft (red tint, e.g. "Remove") | text (no background/border ever — underlines on hover, e.g. "View all", "Cancel") */
7
+ variant?: "primary" | "dark" | "outline" | "ghost" | "primary-soft" | "danger" | "danger-soft" | "text";
8
+ /** sm 30px/12px text (panel actions) | md 32px/13px (default) | lg 35.5px r10 medium (wizard footers) */
9
+ size?: "sm" | "md" | "lg";
10
+ /** Icon glyph name */
11
+ icon?: string;
12
+ iconSize?: number;
13
+ /** Where `icon` renders relative to the label (default "left") */
14
+ iconPosition?: "left" | "right";
15
+ /** Force 500 weight (nav/footer emphasis) */
16
+ medium?: boolean;
17
+ disabled?: boolean;
18
+ /** Shows a spinner in place of the icon and disables interaction, keeping width stable */
19
+ loading?: boolean;
20
+ /** Stretches to fill its container */
21
+ fullWidth?: boolean;
22
+ /** Square, icon-only mode — hides children, requires `label` for accessibility */
23
+ iconOnly?: boolean;
24
+ /** aria-label, required when iconOnly */
25
+ label?: string;
26
+ /** Force the press (mouse-down) styling — for specimens and controlled toggles */
27
+ pressed?: boolean;
28
+ /** Force the keyboard-focus ring — for specimens */
29
+ focused?: boolean;
30
+ onClick?: () => void;
31
+ children?: React.ReactNode;
32
+ style?: React.CSSProperties;
33
+ }
34
+ export declare function Button(props: ButtonProps): JSX.Element;
35
+ /** Attached row of Buttons sharing one outline (e.g. a segmented "Day / Week / Month" action group). */
36
+ export interface ButtonGroupProps {
37
+ children?: React.ReactNode;
38
+ style?: React.CSSProperties;
39
+ }
40
+ export declare function ButtonGroup(props: ButtonGroupProps): JSX.Element;
@@ -0,0 +1,101 @@
1
+ import React from "react";
2
+ import { Icon } from "../icons/Icon.jsx";
3
+
4
+ const btnBase = { display: "inline-flex", alignItems: "center", justifyContent: "center", gap: 6, fontFamily: "var(--font-sans)", fontWeight: "var(--weight-regular)", fontSize: "var(--text-base)", lineHeight: "var(--leading-base)", letterSpacing: "var(--tracking-base)", border: "1px solid transparent", cursor: "pointer", whiteSpace: "nowrap", boxSizing: "border-box", background: "transparent", transition: "var(--t-hover)" };
5
+
6
+ const variants = {
7
+ primary: { background: "var(--action-primary)", color: "var(--on-accent)" },
8
+ dark: { background: "var(--action-dark)", color: "var(--action-dark-fg)" },
9
+ outline: { background: "var(--bg-surface)", color: "var(--text-body)", borderColor: "var(--border-control)" },
10
+ ghost: { color: "var(--text-body)" },
11
+ "primary-soft": { background: "var(--soft-bg)", color: "var(--action-primary)", borderColor: "var(--soft-border)" },
12
+ danger: { background: "var(--danger)", color: "var(--on-accent)" },
13
+ "danger-soft": { background: "var(--danger-bg)", color: "var(--danger-text)" },
14
+ text: { color: "var(--text-secondary)", padding: "0", height: "auto" },
15
+ };
16
+ const hovers = {
17
+ primary: "var(--action-primary-hover)", dark: "var(--action-dark-hover)",
18
+ outline: "var(--bg-hover)", ghost: "var(--bg-hover)", "primary-soft": "var(--soft-hover)",
19
+ danger: "var(--danger-text)", "danger-soft": "var(--danger-bg)",
20
+ };
21
+ /** Press (mouse-down) fills — one step past hover. */
22
+ const presses = {
23
+ primary: "var(--action-primary-active)", dark: "var(--action-dark-active)",
24
+ outline: "var(--bg-press)", ghost: "var(--bg-press)", "primary-soft": "var(--soft-active)",
25
+ danger: "var(--danger-active)", "danger-soft": "var(--danger-soft-active)",
26
+ };
27
+ /** Variants that change text color (+ underline) on hover instead of a background wash. */
28
+ const colorHoverVariants = { text: "var(--text-heading)" };
29
+ const sizes = {
30
+ sm: { height: 30, padding: "6px 12px", fontSize: "var(--text-sm)", lineHeight: "var(--leading-sm)", letterSpacing: 0, borderRadius: "var(--radius-md)" },
31
+ md: { height: 32, padding: "6px 12px", borderRadius: "var(--radius-md)" },
32
+ lg: { height: 35.5, padding: "8px 16px", fontWeight: "var(--weight-medium)", borderRadius: "var(--radius-lg)" },
33
+ };
34
+ const iconOnlyPad = { sm: 0, md: 0, lg: 0 };
35
+ const iconOnlyBox = { sm: 30, md: 32, lg: 36 };
36
+
37
+ function Spinner({ size, color }) {
38
+ return <span style={{ display: "inline-block", width: size, height: size, borderRadius: "var(--radius-full)", border: "2px solid currentColor", borderTopColor: "transparent", opacity: .9, color, animation: "kb-spin .7s linear infinite", flexShrink: 0 }} />;
39
+ }
40
+
41
+ /** Keybricks button. variant: primary | dark | outline | ghost | primary-soft | danger | danger-soft | text; size: sm | md | lg. Interaction states: hover (one step darker) · press (two steps, set via mouse-down) · keyboard focus ring · loading · disabled. */
42
+ export function Button({ variant = "primary", size = "md", icon, iconSize, iconPosition = "left", medium, disabled, loading, fullWidth, iconOnly, label, pressed, focused, children, style, onClick, ...rest }) {
43
+ const [hover, setHover] = React.useState(false);
44
+ const [press, setPress] = React.useState(false);
45
+ const [focus, setFocus] = React.useState(false);
46
+ const busy = disabled || loading;
47
+ const isPressed = press || pressed;
48
+ const isFocused = focus || focused;
49
+ const s = {
50
+ ...btnBase, ...sizes[size], ...variants[variant],
51
+ ...(medium ? { fontWeight: "var(--weight-medium)" } : null),
52
+ ...(fullWidth ? { width: "100%" } : null),
53
+ ...(iconOnly ? { width: iconOnlyBox[size], padding: iconOnlyPad[size], gap: 0 } : null),
54
+ ...(busy ? { opacity: .55, cursor: "default" } : null),
55
+ ...style,
56
+ };
57
+ if (!busy) {
58
+ if (colorHoverVariants[variant]) {
59
+ if (hover || isPressed) { s.color = colorHoverVariants[variant]; s.textDecoration = "underline"; }
60
+ if (isPressed) s.opacity = .7;
61
+ } else if (isPressed) {
62
+ s.background = presses[variant];
63
+ } else if (hover) {
64
+ s.background = hovers[variant];
65
+ }
66
+ if (isFocused) s.boxShadow = "var(--ring-focus)";
67
+ }
68
+ const iSize = iconSize || (size === "sm" ? 12 : 14);
69
+ const leading = loading ? <Spinner size={iSize} color={s.color} /> : (icon && iconPosition === "left" ? <Icon name={icon} size={iSize} /> : null);
70
+ const trailing = !loading && icon && iconPosition === "right" ? <Icon name={icon} size={iSize} /> : null;
71
+ return (
72
+ <button type="button" data-press="own" style={s} disabled={busy} aria-label={iconOnly ? label : undefined} onClick={onClick}
73
+ onMouseEnter={() => setHover(true)} onMouseLeave={() => { setHover(false); setPress(false); }}
74
+ onMouseDown={() => setPress(true)} onMouseUp={() => setPress(false)}
75
+ onKeyDown={(e) => { if (e.key === " " || e.key === "Enter") setPress(true); }} onKeyUp={() => setPress(false)}
76
+ onFocus={(e) => { try { setFocus(e.target.matches(":focus-visible")); } catch (err) { setFocus(true); } }} onBlur={() => setFocus(false)} {...rest}>
77
+ {leading}
78
+ {iconOnly ? null : children}
79
+ {trailing}
80
+ </button>
81
+ );
82
+ }
83
+
84
+ /** Attached row of Buttons sharing one outline (segmented action group). Children should be <Button variant="outline"> or similar. */
85
+ export function ButtonGroup({ children, style }) {
86
+ const items = React.Children.toArray(children);
87
+ return (
88
+ <div style={{ display: "inline-flex", ...style }}>
89
+ {items.map((child, i) => React.cloneElement(child, {
90
+ key: i,
91
+ style: {
92
+ ...(child.props.style || {}),
93
+ borderRadius: 0,
94
+ ...(i === 0 ? { borderTopLeftRadius: "var(--radius-md)", borderBottomLeftRadius: "var(--radius-md)" } : null),
95
+ ...(i === items.length - 1 ? { borderTopRightRadius: "var(--radius-md)", borderBottomRightRadius: "var(--radius-md)" } : null),
96
+ marginLeft: i === 0 ? 0 : -1,
97
+ },
98
+ }))}
99
+ </div>
100
+ );
101
+ }
@@ -0,0 +1,87 @@
1
+ <script setup>
2
+ import { computed, ref } from 'vue'
3
+ import Icon from '../icons/Icon.vue'
4
+
5
+ const btnBase = { display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 6, fontFamily: 'var(--font-sans)', fontWeight: 'var(--weight-regular)', fontSize: 'var(--text-base)', lineHeight: 'var(--leading-base)', letterSpacing: 'var(--tracking-base)', border: '1px solid transparent', cursor: 'pointer', whiteSpace: 'nowrap', boxSizing: 'border-box', background: 'transparent', transition: 'var(--t-hover)' }
6
+ const variants = {
7
+ primary: { background: 'var(--action-primary)', color: 'var(--on-accent)' },
8
+ dark: { background: 'var(--action-dark)', color: 'var(--action-dark-fg)' },
9
+ outline: { background: 'var(--bg-surface)', color: 'var(--text-body)', borderColor: 'var(--border-control)' },
10
+ ghost: { color: 'var(--text-body)' },
11
+ 'primary-soft': { background: 'var(--soft-bg)', color: 'var(--action-primary)', borderColor: 'var(--soft-border)' },
12
+ danger: { background: 'var(--danger)', color: 'var(--on-accent)' },
13
+ 'danger-soft': { background: 'var(--danger-bg)', color: 'var(--danger-text)' },
14
+ text: { color: 'var(--text-secondary)', padding: '0', height: 'auto' },
15
+ }
16
+ const hovers = { primary: 'var(--action-primary-hover)', dark: 'var(--action-dark-hover)', outline: 'var(--bg-hover)', ghost: 'var(--bg-hover)', 'primary-soft': 'var(--soft-hover)', danger: 'var(--danger-text)', 'danger-soft': 'var(--danger-bg)' }
17
+ const presses = { primary: 'var(--action-primary-active)', dark: 'var(--action-dark-active)', outline: 'var(--bg-press)', ghost: 'var(--bg-press)', 'primary-soft': 'var(--soft-active)', danger: 'var(--danger-active)', 'danger-soft': 'var(--danger-soft-active)' }
18
+ const colorHoverVariants = { text: 'var(--text-heading)' }
19
+ const sizes = {
20
+ sm: { height: 30, padding: '6px 12px', fontSize: 'var(--text-sm)', lineHeight: 'var(--leading-sm)', letterSpacing: 0, borderRadius: 'var(--radius-md)' },
21
+ md: { height: 32, padding: '6px 12px', borderRadius: 'var(--radius-md)' },
22
+ lg: { height: 35.5, padding: '8px 16px', fontWeight: 'var(--weight-medium)', borderRadius: 'var(--radius-lg)' },
23
+ }
24
+ const iconOnlyPad = { sm: 0, md: 0, lg: 0 }
25
+ const iconOnlyBox = { sm: 30, md: 32, lg: 36 }
26
+
27
+ // Button — variant: primary | dark | outline | ghost | primary-soft | danger | danger-soft | text; size: sm | md | lg.
28
+ const props = defineProps({
29
+ variant: { type: String, default: 'primary' }, size: { type: String, default: 'md' },
30
+ icon: String, iconSize: Number, iconPosition: { type: String, default: 'left' },
31
+ medium: Boolean, disabled: Boolean, loading: Boolean, fullWidth: Boolean, iconOnly: Boolean,
32
+ label: String, pressed: Boolean, focused: Boolean, style: Object,
33
+ })
34
+ defineEmits(['click'])
35
+ const hover = ref(false), press = ref(false), focus = ref(false)
36
+ const busy = computed(() => props.disabled || props.loading)
37
+ const isPressed = computed(() => press.value || props.pressed)
38
+ const isFocused = computed(() => focus.value || props.focused)
39
+ const s = computed(() => {
40
+ const base = { ...btnBase, ...sizes[props.size], ...variants[props.variant],
41
+ ...(props.medium ? { fontWeight: 'var(--weight-medium)' } : null),
42
+ ...(props.fullWidth ? { width: '100%' } : null),
43
+ ...(props.iconOnly ? { width: iconOnlyBox[props.size], padding: iconOnlyPad[props.size], gap: 0 } : null),
44
+ ...(busy.value ? { opacity: .55, cursor: 'default' } : null), ...props.style }
45
+ if (!busy.value) {
46
+ if (colorHoverVariants[props.variant]) {
47
+ if (hover.value || isPressed.value) { base.color = colorHoverVariants[props.variant]; base.textDecoration = 'underline' }
48
+ if (isPressed.value) base.opacity = .7
49
+ } else if (isPressed.value) base.background = presses[props.variant]
50
+ else if (hover.value) base.background = hovers[props.variant]
51
+ if (isFocused.value) base.boxShadow = 'var(--ring-focus)'
52
+ }
53
+ return base
54
+ })
55
+ const iSize = computed(() => props.iconSize || (props.size === 'sm' ? 12 : 14))
56
+ </script>
57
+ <template>
58
+ <button type="button" data-press="own" :style="s" :disabled="busy" :aria-label="iconOnly ? label : undefined"
59
+ @click="$emit('click')" @mouseenter="hover = true" @mouseleave="hover = false; press = false"
60
+ @mousedown="press = true" @mouseup="press = false" @keydown.enter="press = true" @keydown.space="press = true" @keyup="press = false"
61
+ @focus="focus = $event.target.matches(':focus-visible')" @blur="focus = false">
62
+ <span v-if="loading" :style="{ display: 'inline-block', width: iSize, height: iSize, borderRadius: 'var(--radius-full)', border: '2px solid currentColor', borderTopColor: 'transparent', opacity: .9, animation: 'kb-spin .7s linear infinite', flexShrink: 0 }" />
63
+ <Icon v-else-if="icon && iconPosition === 'left'" :name="icon" :size="iSize" />
64
+ <slot v-if="!iconOnly" />
65
+ <Icon v-if="!loading && icon && iconPosition === 'right'" :name="icon" :size="iSize" />
66
+ </button>
67
+ </template>
68
+
69
+ <!-- ButtonGroup — attached row of Buttons sharing one outline (segmented action group). -->
70
+ <!--
71
+ <script setup name="ButtonGroup">
72
+ import { useSlots, computed } from 'vue'
73
+ const props = defineProps({ style: Object })
74
+ const slots = useSlots()
75
+ const items = computed(() => slots.default ? slots.default() : [])
76
+ </script>
77
+ <template>
78
+ <div :style="{ display: 'inline-flex', ...style }">
79
+ <template v-for="(child, i) in items" :key="i">
80
+ <component :is="child" :style="{ borderRadius: 0,
81
+ ...(i === 0 ? { borderTopLeftRadius: 'var(--radius-md)', borderBottomLeftRadius: 'var(--radius-md)' } : null),
82
+ ...(i === items.length - 1 ? { borderTopRightRadius: 'var(--radius-md)', borderBottomRightRadius: 'var(--radius-md)' } : null),
83
+ marginLeft: i === 0 ? 0 : -1 }" />
84
+ </template>
85
+ </div>
86
+ </template>
87
+ -->
@@ -0,0 +1,26 @@
1
+ import * as React from "react";
2
+ /** Square ghost icon button used in toolbars, headers, and panel chrome. */
3
+ export interface IconButtonProps {
4
+ /** Icon glyph name */
5
+ icon: string;
6
+ /** xs 22/r8 · sm 26/r4 (view toggle) · md 28/r8 (toolbar) · lg 34/r8 (top bar) */
7
+ size?: "xs" | "sm" | "md" | "lg";
8
+ /** Pressed/selected state (#f5f5f5 wash) */
9
+ active?: boolean;
10
+ /** Muted #a1a1a1 glyph */
11
+ muted?: boolean;
12
+ /** Red glyph + red-tint hover, for destructive icon actions */
13
+ danger?: boolean;
14
+ disabled?: boolean;
15
+ /** Shows a spinner in place of the icon and disables interaction */
16
+ loading?: boolean;
17
+ /** aria-label */
18
+ label?: string;
19
+ /** Force the press (mouse-down) styling — for specimens */
20
+ pressed?: boolean;
21
+ /** Force the keyboard-focus ring — for specimens */
22
+ focused?: boolean;
23
+ onClick?: () => void;
24
+ style?: React.CSSProperties;
25
+ }
26
+ export declare function IconButton(props: IconButtonProps): JSX.Element;
@@ -0,0 +1,28 @@
1
+ import React from "react";
2
+ import { Icon } from "../icons/Icon.jsx";
3
+
4
+ const ibSizes = { xs: { box: 22, icon: 14, radius: "var(--radius-md)" }, sm: { box: 26, icon: 14, radius: "var(--radius-sm)" }, md: { box: 28, icon: 16, radius: "var(--radius-md)" }, lg: { box: 34, icon: 18, radius: "var(--radius-md)" } };
5
+
6
+ /** Square ghost icon button (toolbar/back/bell/view toggles). size: xs 22 | sm 26 | md 28 | lg 34. danger tints red; loading shows a spinner and disables interaction. States: hover · press · keyboard focus ring · active (persistent toggle-on) · disabled. */
7
+ export function IconButton({ icon, size = "md", active, muted, danger, disabled, loading, label, pressed, focused, style, onClick, ...rest }) {
8
+ const [hover, setHover] = React.useState(false);
9
+ const [press, setPress] = React.useState(false);
10
+ const [focus, setFocus] = React.useState(false);
11
+ const t = ibSizes[size];
12
+ const busy = disabled || loading;
13
+ const isPressed = (press || pressed) && !busy;
14
+ const color = danger ? "var(--danger)" : muted ? "var(--text-muted)" : "var(--text-body)";
15
+ const bg = isPressed ? (danger ? "var(--danger-soft-active)" : "var(--bg-press)")
16
+ : active ? "var(--bg-active)"
17
+ : hover && !busy ? (danger ? "var(--danger-bg)" : "var(--bg-hover)") : "transparent";
18
+ return (
19
+ <button type="button" data-press="own" aria-label={label} disabled={busy} onClick={onClick}
20
+ onMouseEnter={() => setHover(true)} onMouseLeave={() => { setHover(false); setPress(false); }}
21
+ onMouseDown={() => setPress(true)} onMouseUp={() => setPress(false)}
22
+ onKeyDown={(e) => { if (e.key === " " || e.key === "Enter") setPress(true); }} onKeyUp={() => setPress(false)}
23
+ onFocus={(e) => { try { setFocus(e.target.matches(":focus-visible")); } catch (err) { setFocus(true); } }} onBlur={() => setFocus(false)}
24
+ style={{ width: t.box, height: t.box, borderRadius: t.radius, border: "none", cursor: busy ? "default" : "pointer", display: "inline-flex", alignItems: "center", justifyContent: "center", background: bg, color, opacity: busy ? .5 : 1, boxShadow: (focus || focused) && !busy ? "var(--ring-focus)" : "none", transition: "var(--t-hover)", padding: 0, flexShrink: 0, ...style }} {...rest}>
25
+ {loading ? <span style={{ display: "inline-block", width: t.icon, height: t.icon, borderRadius: "var(--radius-full)", border: "2px solid currentColor", borderTopColor: "transparent", animation: "kb-spin .7s linear infinite" }} /> : <Icon name={icon} size={t.icon} />}
26
+ </button>
27
+ );
28
+ }
@@ -0,0 +1,21 @@
1
+ <script setup>
2
+ import { ref, computed } from 'vue'
3
+ import Icon from '../icons/Icon.vue'
4
+ const ibSizes = { xs: { box: 22, icon: 14, radius: 'var(--radius-md)' }, sm: { box: 26, icon: 14, radius: 'var(--radius-sm)' }, md: { box: 28, icon: 16, radius: 'var(--radius-md)' }, lg: { box: 34, icon: 18, radius: 'var(--radius-md)' } }
5
+ // Square ghost icon button (toolbar/back/bell/view toggles). size: xs 22 | sm 26 | md 28 | lg 34.
6
+ const props = defineProps({ icon: String, size: { type: String, default: 'md' }, active: Boolean, muted: Boolean, danger: Boolean, disabled: Boolean, loading: Boolean, label: String, pressed: Boolean, focused: Boolean, style: Object })
7
+ defineEmits(['click'])
8
+ const hover = ref(false), press = ref(false), focus = ref(false)
9
+ const t = computed(() => ibSizes[props.size])
10
+ const busy = computed(() => props.disabled || props.loading)
11
+ const isPressed = computed(() => (press.value || props.pressed) && !busy.value)
12
+ const color = computed(() => props.danger ? 'var(--danger)' : props.muted ? 'var(--text-muted)' : 'var(--text-body)')
13
+ const bg = computed(() => isPressed.value ? (props.danger ? 'var(--danger-soft-active)' : 'var(--bg-press)') : props.active ? 'var(--bg-active)' : (hover.value && !busy.value ? (props.danger ? 'var(--danger-bg)' : 'var(--bg-hover)') : 'transparent'))
14
+ const s = computed(() => ({ width: t.value.box, height: t.value.box, borderRadius: t.value.radius, border: 'none', cursor: busy.value ? 'default' : 'pointer', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', background: bg.value, color: color.value, opacity: busy.value ? .5 : 1, boxShadow: (focus.value || props.focused) && !busy.value ? 'var(--ring-focus)' : 'none', transition: 'var(--t-hover)', padding: 0, flexShrink: 0, ...props.style }))
15
+ </script>
16
+ <template>
17
+ <button type="button" data-press="own" :aria-label="label" :disabled="busy" @click="$emit('click')" @mouseenter="hover = true" @mouseleave="hover = false; press = false" @mousedown="press = true" @mouseup="press = false" @keydown.enter="press = true" @keydown.space="press = true" @keyup="press = false" @focus="focus = $event.target.matches(':focus-visible')" @blur="focus = false" :style="s">
18
+ <span v-if="loading" :style="{ display: 'inline-block', width: t.icon, height: t.icon, borderRadius: 'var(--radius-full)', border: '2px solid currentColor', borderTopColor: 'transparent', animation: 'kb-spin .7s linear infinite' }" />
19
+ <Icon v-else :name="icon" :size="t.icon" />
20
+ </button>
21
+ </template>
@@ -0,0 +1,13 @@
1
+ <!-- @dsCard group="Directory Index" viewport="700x70" name="Buttons dir" subtitle="Full card: Components → Button" -->
2
+ <!DOCTYPE html>
3
+ <html><head><meta charset="utf-8"><link rel="stylesheet" href="../../styles.css">
4
+ <script src="https://unpkg.com/react@18.3.1/umd/react.development.js" integrity="sha384-hD6/rw4ppMLGNu3tX5cjIb+uRZ7UkRJ6BPkLpg4hAu/6onKUg4lLsHAs9EBPT82L" crossorigin="anonymous"></script>
5
+ <script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.development.js" integrity="sha384-u6aeetuaXnQ38mYT8rp6sbXaQe3NL9t+IBXmnYxwkUI2Hw4bsp2Wvmx4yRQF1uAm" crossorigin="anonymous"></script>
6
+ <script src="https://unpkg.com/@babel/standalone@7.29.0/babel.min.js" integrity="sha384-m08KidiNqLdpJqLq95G/LEi8Qvjl/xUYll3QILypMoQ65QorJ9Lvtp2RXYGBFj1y" crossorigin="anonymous"></script>
7
+ <script src="../../_ds_bundle.js"></script>
8
+ <style>body{margin:0;background:var(--bg-surface);padding:16px;font-family:var(--font-sans)}</style></head>
9
+ <body><div id="root"></div>
10
+ <script type="text/babel">
11
+ const { Button } = window.KeybricksDesignSystem_71231a;
12
+ ReactDOM.createRoot(document.getElementById("root")).render(<Button icon="send">Submit</Button>);
13
+ </script></body></html>
@@ -0,0 +1,19 @@
1
+ Buttons: `Button` (primary/dark/outline/ghost/primary-soft; sm/md/lg), `IconButton` (square ghost), `ActionChip` (tinted bulk actions).
2
+
3
+ ```jsx
4
+ <Button icon="send">Submit</Button>
5
+ <Button variant="dark" icon="sparkles">AI Assistant</Button>
6
+ <Button variant="ghost" icon="play">Run Test</Button>
7
+ <Button variant="text">Cancel</Button>
8
+ <Button variant="primary-soft" icon="eye" size="sm">Data Preview</Button>
9
+ <Button variant="danger" icon="trash-2">Delete Node</Button>
10
+ <Button loading>Submit</Button>
11
+ <Button icon="bell" iconOnly label="Notifications" variant="outline"/>
12
+ <Button fullWidth icon="upload">Upload Configuration File</Button>
13
+ <ButtonGroup><Button variant="outline" size="sm">Day</Button><Button variant="outline" size="sm">Week</Button></ButtonGroup>
14
+ <IconButton icon="bell" size="lg"/>
15
+ <IconButton icon="trash-2" danger label="Delete"/>
16
+ <ActionChip tone="success">Mark as New</ActionChip>
17
+ ```
18
+
19
+ Primary = the single blue CTA per view. Dark = brand-level actions (AI Assistant, Show). Ghost text buttons sit beside the CTA ("Back", "Run Test"). `text` = no background/border ever, underlines on hover — for tertiary actions like "Cancel"/"View all", never a page's main action. Danger/danger-soft = destructive actions. lg (r10, 500 weight) only in wizard footers. `loading` swaps the icon for a spinner and disables the button without changing its size; `iconOnly` needs a `label` for accessibility; `ButtonGroup` fuses adjacent buttons into one segmented control or a split button (main action + attached icon-only).
@@ -0,0 +1,15 @@
1
+ import * as React from "react";
2
+ export interface Bar3DSeries { name: string; values: number[]; color?: string; }
3
+ /** 3D cuboid bars — categories on x, series as depth rows or stacked; drag to orbit. */
4
+ export interface Bar3DProps {
5
+ series?: Bar3DSeries[];
6
+ categories?: string[];
7
+ mode?: "grouped" | "stacked";
8
+ width?: number; height?: number;
9
+ yaw?: number; pitch?: number;
10
+ /** Fraction of each cell left empty, 0–1 */ gap?: number;
11
+ interactive?: boolean;
12
+ valueFormat?: (v: number) => string;
13
+ style?: React.CSSProperties;
14
+ }
15
+ export declare function Bar3D(props: Bar3DProps): JSX.Element;