@sableui/react 0.6.2 → 0.7.1

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 (642) hide show
  1. package/AGENTS.md +2 -2
  2. package/CHANGELOG.md +315 -0
  3. package/CONTRIBUTING.md +16 -10
  4. package/DESIGN.md +3 -3
  5. package/README.md +3 -3
  6. package/bin/sable-lint.mjs +18 -0
  7. package/bin/sable.mjs +470 -62
  8. package/dist/blocks/api-keys-block.js +44 -0
  9. package/dist/blocks/api-keys-block.meta.js +21 -0
  10. package/dist/blocks/chat-thread-block.js +17 -0
  11. package/dist/blocks/chat-thread-block.meta.js +20 -0
  12. package/dist/blocks/command-palette-block.js +24 -0
  13. package/dist/blocks/command-palette-block.meta.js +21 -0
  14. package/dist/blocks/cta-band-block.js +27 -0
  15. package/dist/blocks/cta-band-block.meta.js +20 -0
  16. package/dist/blocks/danger-zone-block.js +39 -0
  17. package/dist/blocks/danger-zone-block.meta.js +21 -0
  18. package/dist/blocks/device-comparison-block.js +69 -0
  19. package/dist/blocks/device-comparison-block.meta.js +21 -0
  20. package/dist/blocks/event-card-block.js +40 -0
  21. package/dist/blocks/event-card-block.meta.js +21 -0
  22. package/dist/blocks/faq-block.js +38 -0
  23. package/dist/blocks/faq-block.meta.js +20 -0
  24. package/dist/blocks/feature-grid-block.js +38 -0
  25. package/dist/blocks/feature-grid-block.meta.js +21 -0
  26. package/dist/blocks/feedback-form-block.js +30 -0
  27. package/dist/blocks/feedback-form-block.meta.js +21 -0
  28. package/dist/blocks/goal-progress-block.js +24 -0
  29. package/dist/blocks/goal-progress-block.meta.js +21 -0
  30. package/dist/blocks/hero-block.js +33 -0
  31. package/dist/blocks/hero-block.meta.js +21 -0
  32. package/dist/blocks/index.js +162 -1964
  33. package/dist/blocks/invite-team-block.js +36 -0
  34. package/dist/blocks/invite-team-block.meta.js +20 -0
  35. package/dist/blocks/invoice-history-block.js +41 -0
  36. package/dist/blocks/invoice-history-block.meta.js +21 -0
  37. package/dist/blocks/kpi-sparkline-block.js +29 -0
  38. package/dist/blocks/kpi-sparkline-block.meta.js +20 -0
  39. package/dist/blocks/media-player-block.js +68 -0
  40. package/dist/blocks/media-player-block.meta.js +21 -0
  41. package/dist/blocks/newsletter-block.js +35 -0
  42. package/dist/blocks/newsletter-block.meta.js +21 -0
  43. package/dist/blocks/not-found-block.js +27 -0
  44. package/dist/blocks/not-found-block.meta.js +20 -0
  45. package/dist/blocks/notification-list-block.js +32 -0
  46. package/dist/blocks/notification-list-block.meta.js +21 -0
  47. package/dist/blocks/notification-settings-block.js +25 -0
  48. package/dist/blocks/notification-settings-block.meta.js +20 -0
  49. package/dist/blocks/order-tracking-block.js +26 -0
  50. package/dist/blocks/order-tracking-block.meta.js +20 -0
  51. package/dist/blocks/pricing-card-block.js +46 -0
  52. package/dist/blocks/pricing-card-block.meta.js +21 -0
  53. package/dist/blocks/pricing-table-block.js +88 -0
  54. package/dist/blocks/pricing-table-block.meta.js +20 -0
  55. package/dist/blocks/product-card-block.js +26 -0
  56. package/dist/blocks/product-card-block.meta.js +21 -0
  57. package/dist/blocks/profile-card-block.js +58 -0
  58. package/dist/blocks/profile-card-block.meta.js +21 -0
  59. package/dist/blocks/profile-form-block.js +70 -0
  60. package/dist/blocks/profile-form-block.meta.js +21 -0
  61. package/dist/blocks/revenue-breakdown-block.js +38 -0
  62. package/dist/blocks/revenue-breakdown-block.meta.js +21 -0
  63. package/dist/blocks/sign-in-block.js +38 -0
  64. package/dist/blocks/sign-in-block.meta.js +21 -0
  65. package/dist/blocks/sign-up-block.js +48 -0
  66. package/dist/blocks/sign-up-block.meta.js +21 -0
  67. package/dist/blocks/site-footer-block.js +54 -0
  68. package/dist/blocks/site-footer-block.meta.js +20 -0
  69. package/dist/blocks/stat-row-block.js +28 -0
  70. package/dist/blocks/stat-row-block.meta.js +21 -0
  71. package/dist/blocks/steps-block.js +37 -0
  72. package/dist/blocks/steps-block.meta.js +20 -0
  73. package/dist/blocks/task-list-block.js +52 -0
  74. package/dist/blocks/task-list-block.meta.js +21 -0
  75. package/dist/blocks/team-members-block.js +49 -0
  76. package/dist/blocks/team-members-block.meta.js +21 -0
  77. package/dist/blocks/testimonial-block.js +49 -0
  78. package/dist/blocks/testimonial-block.meta.js +20 -0
  79. package/dist/blocks/traffic-sources-block.js +39 -0
  80. package/dist/blocks/traffic-sources-block.meta.js +21 -0
  81. package/dist/blocks/traffic-trend-block.js +61 -0
  82. package/dist/blocks/traffic-trend-block.meta.js +21 -0
  83. package/dist/blocks/upload-list-block.js +39 -0
  84. package/dist/blocks/upload-list-block.meta.js +21 -0
  85. package/dist/blocks/verify-code-block.js +28 -0
  86. package/dist/blocks/verify-code-block.meta.js +21 -0
  87. package/dist/blocks/wallet-block.js +48 -0
  88. package/dist/blocks/wallet-block.meta.js +21 -0
  89. package/dist/components/accordion/accordion.js +63 -0
  90. package/dist/components/accordion/accordion.meta.js +155 -0
  91. package/dist/components/accordion/index.js +15 -0
  92. package/dist/components/app-header/app-header.js +30 -0
  93. package/dist/components/app-header/app-header.meta.js +88 -0
  94. package/dist/components/app-header/index.js +7 -0
  95. package/dist/components/app-shell/app-shell-dock.js +37 -0
  96. package/dist/components/app-shell/app-shell.js +67 -0
  97. package/dist/components/app-shell/app-shell.meta.js +176 -0
  98. package/dist/components/app-shell/index.js +7 -0
  99. package/dist/components/area-chart/area-chart.js +10 -0
  100. package/dist/components/area-chart/area-chart.meta.js +218 -0
  101. package/dist/components/area-chart/index.js +7 -0
  102. package/dist/components/attachment/attachment.js +176 -0
  103. package/dist/components/attachment/attachment.meta.js +179 -0
  104. package/dist/components/attachment/attachment.variants.js +47 -0
  105. package/dist/components/attachment/index.js +7 -0
  106. package/dist/components/avatar/avatar.js +192 -0
  107. package/dist/components/avatar/avatar.meta.js +233 -0
  108. package/dist/components/avatar/avatar.variants.js +44 -0
  109. package/dist/components/avatar/index.js +22 -0
  110. package/dist/components/badge/badge.js +26 -0
  111. package/dist/components/badge/badge.meta.js +171 -0
  112. package/dist/components/badge/badge.variants.js +103 -0
  113. package/dist/components/badge/index.js +11 -0
  114. package/dist/components/banner/banner.js +76 -0
  115. package/dist/components/banner/banner.meta.js +172 -0
  116. package/dist/components/banner/banner.variants.js +44 -0
  117. package/dist/components/banner/index.js +9 -0
  118. package/dist/components/bar-chart/bar-chart.js +10 -0
  119. package/dist/components/bar-chart/bar-chart.meta.js +245 -0
  120. package/dist/components/bar-chart/index.js +7 -0
  121. package/dist/components/bottom-nav/bottom-nav.js +63 -0
  122. package/dist/components/bottom-nav/bottom-nav.meta.js +95 -0
  123. package/dist/components/bottom-nav/index.js +11 -0
  124. package/dist/components/breadcrumbs/breadcrumbs.js +90 -0
  125. package/dist/components/breadcrumbs/breadcrumbs.meta.js +111 -0
  126. package/dist/components/breadcrumbs/index.js +17 -0
  127. package/dist/components/browser/browser.js +39 -0
  128. package/dist/components/browser/browser.meta.js +80 -0
  129. package/dist/components/browser/index.js +7 -0
  130. package/dist/components/bubble/bubble.js +110 -0
  131. package/dist/components/bubble/bubble.meta.js +158 -0
  132. package/dist/components/bubble/bubble.variants.js +90 -0
  133. package/dist/components/bubble/index.js +13 -0
  134. package/dist/components/button/button.js +87 -0
  135. package/dist/components/button/button.meta.js +302 -0
  136. package/dist/components/button/button.variants.js +137 -0
  137. package/dist/components/button/index.js +9 -0
  138. package/dist/components/calendar/calendar.js +89 -0
  139. package/dist/components/calendar/calendar.meta.js +136 -0
  140. package/dist/components/calendar/index.js +7 -0
  141. package/dist/components/card/card.js +203 -0
  142. package/dist/components/card/card.meta.js +212 -0
  143. package/dist/components/card/index.js +23 -0
  144. package/dist/components/carousel/carousel.js +428 -0
  145. package/dist/components/carousel/carousel.meta.js +100 -0
  146. package/dist/components/carousel/index.js +7 -0
  147. package/dist/components/chat-composer/chat-composer.js +174 -0
  148. package/dist/components/chat-composer/chat-composer.meta.js +241 -0
  149. package/dist/components/chat-composer/chat-composer.variants.js +17 -0
  150. package/dist/components/chat-composer/index.js +7 -0
  151. package/dist/components/checkbox/checkbox-mark.js +28 -0
  152. package/dist/components/checkbox/checkbox.js +30 -0
  153. package/dist/components/checkbox/checkbox.meta.js +127 -0
  154. package/dist/components/checkbox/index.js +7 -0
  155. package/dist/components/checkbox-card/checkbox-card.js +94 -0
  156. package/dist/components/checkbox-card/checkbox-card.meta.js +154 -0
  157. package/dist/components/checkbox-card/checkbox-card.variants.js +43 -0
  158. package/dist/components/checkbox-card/index.js +11 -0
  159. package/dist/components/code/code.js +19 -0
  160. package/dist/components/code/code.meta.js +71 -0
  161. package/dist/components/code/index.js +7 -0
  162. package/dist/components/code-block/code-block.js +84 -0
  163. package/dist/components/code-block/code-block.meta.js +103 -0
  164. package/dist/components/code-block/index.js +8 -0
  165. package/dist/components/collapsible/collapsible.js +38 -0
  166. package/dist/components/collapsible/collapsible.meta.js +117 -0
  167. package/dist/components/collapsible/index.js +15 -0
  168. package/dist/components/color-field/color-field.js +293 -0
  169. package/dist/components/color-field/color-field.meta.js +142 -0
  170. package/dist/components/color-field/color.js +69 -0
  171. package/dist/components/color-field/index.js +15 -0
  172. package/dist/components/combobox/combobox.js +486 -0
  173. package/dist/components/combobox/combobox.meta.js +217 -0
  174. package/dist/components/combobox/index.js +37 -0
  175. package/dist/components/command-menu/command-menu-trigger.js +122 -0
  176. package/dist/components/command-menu/command-menu.js +433 -0
  177. package/dist/components/command-menu/command-menu.meta.js +279 -0
  178. package/dist/components/command-menu/index.js +21 -0
  179. package/dist/components/context-card/context-card.js +62 -0
  180. package/dist/components/context-card/context-card.meta.js +106 -0
  181. package/dist/components/context-card/index.js +17 -0
  182. package/dist/components/context-menu/context-menu.js +92 -0
  183. package/dist/components/context-menu/context-menu.meta.js +138 -0
  184. package/dist/components/context-menu/index.js +23 -0
  185. package/dist/components/data-table/data-table.js +142 -0
  186. package/dist/components/data-table/data-table.meta.js +146 -0
  187. package/dist/components/data-table/index.js +9 -0
  188. package/dist/components/date-picker/date-picker.js +196 -0
  189. package/dist/components/date-picker/date-picker.meta.js +164 -0
  190. package/dist/components/date-picker/index.js +7 -0
  191. package/dist/components/date-tile/date-tile.js +29 -0
  192. package/dist/components/date-tile/date-tile.meta.js +72 -0
  193. package/dist/components/date-tile/index.js +7 -0
  194. package/dist/components/destructive-action-modal/destructive-action-modal.js +130 -0
  195. package/dist/components/destructive-action-modal/destructive-action-modal.meta.js +136 -0
  196. package/dist/components/destructive-action-modal/index.js +9 -0
  197. package/dist/components/dialog/dialog.js +207 -0
  198. package/dist/components/dialog/dialog.meta.js +239 -0
  199. package/dist/components/dialog/index.js +45 -0
  200. package/dist/components/disclosure-picker/disclosure-picker.js +417 -0
  201. package/dist/components/disclosure-picker/disclosure-picker.meta.js +213 -0
  202. package/dist/components/disclosure-picker/index.js +21 -0
  203. package/dist/components/empty-state/empty-state.js +52 -0
  204. package/dist/components/empty-state/empty-state.meta.js +158 -0
  205. package/dist/components/empty-state/index.js +7 -0
  206. package/dist/components/entity/entity.js +70 -0
  207. package/dist/components/entity/entity.meta.js +108 -0
  208. package/dist/components/entity/entity.variants.js +16 -0
  209. package/dist/components/entity/index.js +7 -0
  210. package/dist/components/feedback/feedback.js +93 -0
  211. package/dist/components/feedback/feedback.meta.js +109 -0
  212. package/dist/components/feedback/index.js +7 -0
  213. package/dist/components/fieldset/fieldset.js +80 -0
  214. package/dist/components/fieldset/fieldset.meta.js +160 -0
  215. package/dist/components/fieldset/index.js +17 -0
  216. package/dist/components/file-dropzone/file-dropzone.js +193 -0
  217. package/dist/components/file-dropzone/file-dropzone.meta.js +210 -0
  218. package/dist/components/file-dropzone/file-dropzone.variants.js +26 -0
  219. package/dist/components/file-dropzone/index.js +13 -0
  220. package/dist/components/font-picker/font-picker.js +77 -0
  221. package/dist/components/font-picker/font-picker.meta.js +119 -0
  222. package/dist/components/font-picker/index.js +7 -0
  223. package/dist/components/form/form.js +145 -0
  224. package/dist/components/form/form.meta.js +142 -0
  225. package/dist/components/form/index.js +11 -0
  226. package/dist/components/gliding-highlight/gliding-highlight.js +50 -0
  227. package/dist/components/gliding-highlight/gliding-highlight.meta.js +135 -0
  228. package/dist/components/gliding-highlight/index.js +9 -0
  229. package/dist/components/gradient-art/gradient-art.js +168 -0
  230. package/dist/components/gradient-art/gradient-art.meta.js +81 -0
  231. package/dist/components/gradient-art/index.js +7 -0
  232. package/dist/components/gradient-art/renderer.js +336 -0
  233. package/dist/components/inline-status/index.js +7 -0
  234. package/dist/components/inline-status/inline-status.js +33 -0
  235. package/dist/components/inline-status/inline-status.meta.js +83 -0
  236. package/dist/components/inline-status/inline-status.variants.js +18 -0
  237. package/dist/components/input/index.js +7 -0
  238. package/dist/components/input/input.js +33 -0
  239. package/dist/components/input/input.meta.js +155 -0
  240. package/dist/components/kbd/index.js +8 -0
  241. package/dist/components/kbd/kbd.js +54 -0
  242. package/dist/components/kbd/kbd.meta.js +95 -0
  243. package/dist/components/label/index.js +7 -0
  244. package/dist/components/label/label.js +51 -0
  245. package/dist/components/label/label.meta.js +98 -0
  246. package/dist/components/line-chart/index.js +7 -0
  247. package/dist/components/line-chart/line-chart.js +10 -0
  248. package/dist/components/line-chart/line-chart.meta.js +222 -0
  249. package/dist/components/marker/index.js +7 -0
  250. package/dist/components/marker/marker.js +39 -0
  251. package/dist/components/marker/marker.meta.js +132 -0
  252. package/dist/components/marker/marker.variants.js +25 -0
  253. package/dist/components/marquee/index.js +7 -0
  254. package/dist/components/marquee/marquee.js +146 -0
  255. package/dist/components/marquee/marquee.meta.js +106 -0
  256. package/dist/components/media-image/index.js +7 -0
  257. package/dist/components/media-image/media-image.js +56 -0
  258. package/dist/components/media-image/media-image.meta.js +92 -0
  259. package/dist/components/media-tile/index.js +7 -0
  260. package/dist/components/media-tile/media-tile.js +135 -0
  261. package/dist/components/media-tile/media-tile.meta.js +133 -0
  262. package/dist/components/media-tile/media-tile.variants.js +48 -0
  263. package/dist/components/menu/index.js +33 -0
  264. package/dist/components/menu/menu.js +168 -0
  265. package/dist/components/menu/menu.meta.js +176 -0
  266. package/dist/components/message/index.js +7 -0
  267. package/dist/components/message/message.js +83 -0
  268. package/dist/components/message/message.meta.js +150 -0
  269. package/dist/components/message/message.variants.js +41 -0
  270. package/dist/components/message-scroller/index.js +9 -0
  271. package/dist/components/message-scroller/message-scroller.js +300 -0
  272. package/dist/components/message-scroller/message-scroller.meta.js +172 -0
  273. package/dist/components/meter/index.js +20 -0
  274. package/dist/components/meter/meter.js +112 -0
  275. package/dist/components/meter/meter.meta.js +227 -0
  276. package/dist/components/meter/meter.variants.js +61 -0
  277. package/dist/components/middle-truncate/index.js +7 -0
  278. package/dist/components/middle-truncate/middle-truncate.js +28 -0
  279. package/dist/components/middle-truncate/middle-truncate.meta.js +77 -0
  280. package/dist/components/note/index.js +9 -0
  281. package/dist/components/note/note.js +73 -0
  282. package/dist/components/note/note.meta.js +112 -0
  283. package/dist/components/note/note.variants.js +22 -0
  284. package/dist/components/notification-badge/index.js +15 -0
  285. package/dist/components/notification-badge/notification-badge.js +48 -0
  286. package/dist/components/notification-badge/notification-badge.meta.js +107 -0
  287. package/dist/components/notification-badge/notification-badge.variants.js +57 -0
  288. package/dist/components/number-field/index.js +7 -0
  289. package/dist/components/number-field/number-field.js +70 -0
  290. package/dist/components/number-field/number-field.meta.js +109 -0
  291. package/dist/components/otp-field/index.js +7 -0
  292. package/dist/components/otp-field/otp-field.js +70 -0
  293. package/dist/components/otp-field/otp-field.meta.js +197 -0
  294. package/dist/components/overflow-menu/index.js +7 -0
  295. package/dist/components/overflow-menu/overflow-menu.js +26 -0
  296. package/dist/components/overflow-menu/overflow-menu.meta.js +100 -0
  297. package/dist/components/page-header/index.js +7 -0
  298. package/dist/components/page-header/page-header.js +34 -0
  299. package/dist/components/page-header/page-header.meta.js +104 -0
  300. package/dist/components/page-loader/index.js +7 -0
  301. package/dist/components/page-loader/page-loader.js +37 -0
  302. package/dist/components/page-loader/page-loader.meta.js +85 -0
  303. package/dist/components/pagination/index.js +7 -0
  304. package/dist/components/pagination/pagination.js +105 -0
  305. package/dist/components/pagination/pagination.meta.js +141 -0
  306. package/dist/components/panel-group/index.js +10 -0
  307. package/dist/components/panel-group/panel-group.js +168 -0
  308. package/dist/components/panel-group/panel-group.meta.js +153 -0
  309. package/dist/components/panel-section/index.js +9 -0
  310. package/dist/components/panel-section/panel-section.js +115 -0
  311. package/dist/components/panel-section/panel-section.meta.js +156 -0
  312. package/dist/components/phone/index.js +7 -0
  313. package/dist/components/phone/phone.js +50 -0
  314. package/dist/{chunk-KFZ43RKU.js → components/phone/phone.meta.js} +3 -50
  315. package/dist/{chunk-NEQNXI2G.js → components/phone/status-icons.js} +4 -4
  316. package/dist/components/pie-chart/index.js +7 -0
  317. package/dist/components/pie-chart/pie-chart.js +191 -0
  318. package/dist/components/pie-chart/pie-chart.meta.js +210 -0
  319. package/dist/components/pill/index.js +9 -0
  320. package/dist/components/pill/pill.js +24 -0
  321. package/dist/components/pill/pill.meta.js +108 -0
  322. package/dist/components/pill/pill.variants.js +65 -0
  323. package/dist/components/popover/index.js +23 -0
  324. package/dist/components/popover/popover.js +100 -0
  325. package/dist/components/popover/popover.meta.js +136 -0
  326. package/dist/components/progress/index.js +19 -0
  327. package/dist/components/progress/progress.js +70 -0
  328. package/dist/components/progress/progress.meta.js +171 -0
  329. package/dist/components/progress/progress.variants.js +17 -0
  330. package/dist/components/radar-chart/index.js +7 -0
  331. package/dist/components/radar-chart/radar-chart.js +161 -0
  332. package/dist/components/radar-chart/radar-chart.meta.js +204 -0
  333. package/dist/components/radial-chart/index.js +7 -0
  334. package/dist/components/radial-chart/radial-chart.js +175 -0
  335. package/dist/components/radial-chart/radial-chart.meta.js +216 -0
  336. package/dist/components/radio/index.js +8 -0
  337. package/dist/components/radio/radio.js +39 -0
  338. package/dist/components/radio/radio.meta.js +104 -0
  339. package/dist/components/radio-card/index.js +7 -0
  340. package/dist/components/radio-card/radio-card.js +81 -0
  341. package/dist/components/radio-card/radio-card.meta.js +144 -0
  342. package/dist/components/radio-card/radio-card.variants.js +43 -0
  343. package/dist/components/relative-time/index.js +7 -0
  344. package/dist/components/relative-time/relative-time.js +47 -0
  345. package/dist/components/relative-time/relative-time.meta.js +77 -0
  346. package/dist/components/scroller/index.js +7 -0
  347. package/dist/components/scroller/scroller.js +111 -0
  348. package/dist/components/scroller/scroller.meta.js +118 -0
  349. package/dist/components/scrub-field/index.js +7 -0
  350. package/dist/components/scrub-field/scrub-field.js +124 -0
  351. package/dist/components/scrub-field/scrub-field.meta.js +139 -0
  352. package/dist/components/search-input/index.js +7 -0
  353. package/dist/components/search-input/search-input.js +91 -0
  354. package/dist/components/search-input/search-input.meta.js +129 -0
  355. package/dist/components/section-header/index.js +7 -0
  356. package/dist/components/section-header/section-header.js +39 -0
  357. package/dist/components/section-header/section-header.meta.js +174 -0
  358. package/dist/components/segmented-bar/index.js +14 -0
  359. package/dist/components/segmented-bar/segmented-bar.js +26 -0
  360. package/dist/components/segmented-bar/segmented-bar.meta.js +108 -0
  361. package/dist/components/segmented-bar/segmented-bar.variants.js +39 -0
  362. package/dist/components/select/index.js +25 -0
  363. package/dist/components/select/select.js +191 -0
  364. package/dist/components/select/select.meta.js +189 -0
  365. package/dist/components/separator/index.js +7 -0
  366. package/dist/components/separator/separator.js +42 -0
  367. package/dist/components/separator/separator.meta.js +84 -0
  368. package/dist/components/settings-menu/index.js +11 -0
  369. package/dist/components/settings-menu/settings-menu.js +101 -0
  370. package/dist/components/settings-menu/settings-menu.meta.js +177 -0
  371. package/dist/components/settings-menu/settings-menu.variants.js +15 -0
  372. package/dist/components/sheet/index.js +29 -0
  373. package/dist/components/sheet/sheet.js +121 -0
  374. package/dist/components/sheet/sheet.meta.js +167 -0
  375. package/dist/components/sheet/sheet.variants.js +21 -0
  376. package/dist/components/show-more/index.js +7 -0
  377. package/dist/components/show-more/show-more.js +87 -0
  378. package/dist/components/show-more/show-more.meta.js +79 -0
  379. package/dist/components/side-nav/index.js +13 -0
  380. package/dist/components/side-nav/side-nav.js +75 -0
  381. package/dist/components/side-nav/side-nav.meta.js +139 -0
  382. package/dist/components/side-nav/side-nav.variants.js +34 -0
  383. package/dist/components/sidebar/index.js +21 -0
  384. package/dist/components/sidebar/sidebar.js +196 -0
  385. package/dist/components/sidebar/sidebar.meta.js +118 -0
  386. package/dist/components/skeleton/index.js +7 -0
  387. package/dist/components/skeleton/skeleton.js +16 -0
  388. package/dist/components/skeleton/skeleton.meta.js +90 -0
  389. package/dist/components/slider/index.js +21 -0
  390. package/dist/components/slider/slider.js +115 -0
  391. package/dist/components/slider/slider.meta.js +214 -0
  392. package/dist/components/sparkline/index.js +7 -0
  393. package/dist/components/sparkline/sparkline.js +84 -0
  394. package/dist/components/sparkline/sparkline.meta.js +147 -0
  395. package/dist/components/spinner/index.js +7 -0
  396. package/dist/components/spinner/spinner.js +59 -0
  397. package/dist/components/spinner/spinner.meta.js +118 -0
  398. package/dist/components/status-bar/index.js +9 -0
  399. package/dist/components/status-bar/status-bar.js +40 -0
  400. package/dist/components/status-bar/status-bar.meta.js +117 -0
  401. package/dist/components/status-dot/index.js +9 -0
  402. package/dist/components/status-dot/status-dot.js +40 -0
  403. package/dist/components/status-dot/status-dot.meta.js +113 -0
  404. package/dist/components/status-dot/status-dot.variants.js +28 -0
  405. package/dist/components/stepper/index.js +17 -0
  406. package/dist/components/stepper/stepper.js +161 -0
  407. package/dist/components/stepper/stepper.meta.js +190 -0
  408. package/dist/components/stepper/stepper.variants.js +72 -0
  409. package/dist/components/streaming-text/index.js +7 -0
  410. package/dist/components/streaming-text/streaming-text.js +55 -0
  411. package/dist/components/streaming-text/streaming-text.meta.js +147 -0
  412. package/dist/components/switch/index.js +7 -0
  413. package/dist/components/switch/switch.js +26 -0
  414. package/dist/components/switch/switch.meta.js +133 -0
  415. package/dist/components/table/index.js +23 -0
  416. package/dist/components/table/table.js +117 -0
  417. package/dist/components/table/table.meta.js +143 -0
  418. package/dist/components/tabs/index.js +17 -0
  419. package/dist/components/tabs/tabs.js +58 -0
  420. package/dist/components/tabs/tabs.meta.js +120 -0
  421. package/dist/components/textarea/index.js +7 -0
  422. package/dist/components/textarea/textarea.js +38 -0
  423. package/dist/components/textarea/textarea.meta.js +117 -0
  424. package/dist/components/theme-selector/index.js +11 -0
  425. package/dist/components/theme-selector/theme-selector.js +145 -0
  426. package/dist/components/theme-selector/theme-selector.meta.js +181 -0
  427. package/dist/components/theme-switcher/index.js +7 -0
  428. package/dist/components/theme-switcher/theme-switcher.js +106 -0
  429. package/dist/components/theme-switcher/theme-switcher.meta.js +99 -0
  430. package/dist/components/thinking-orb/index.js +9 -0
  431. package/dist/components/thinking-orb/thinking-orb.js +126 -0
  432. package/dist/components/thinking-orb/thinking-orb.meta.js +142 -0
  433. package/dist/components/thinking-orb/thinking-orb.render.js +252 -0
  434. package/dist/components/toast/index.js +29 -0
  435. package/dist/components/toast/toast.js +254 -0
  436. package/dist/components/toast/toast.meta.js +261 -0
  437. package/dist/components/toggle/index.js +13 -0
  438. package/dist/components/toggle/toggle.js +51 -0
  439. package/dist/components/toggle/toggle.meta.js +129 -0
  440. package/dist/components/toolbar/index.js +27 -0
  441. package/dist/components/toolbar/toolbar.js +80 -0
  442. package/dist/components/toolbar/toolbar.meta.js +272 -0
  443. package/dist/components/toolbar/toolbar.variants.js +16 -0
  444. package/dist/components/tooltip/index.js +21 -0
  445. package/dist/components/tooltip/tooltip.js +74 -0
  446. package/dist/components/tooltip/tooltip.meta.js +156 -0
  447. package/dist/components/tree/index.js +12 -0
  448. package/dist/components/tree/tree.js +364 -0
  449. package/dist/components/tree/tree.meta.js +334 -0
  450. package/dist/components/video/index.js +7 -0
  451. package/dist/components/video/video.js +59 -0
  452. package/dist/components/video/video.meta.js +81 -0
  453. package/dist/components/workspace/index.js +9 -0
  454. package/dist/components/workspace/workspace.js +79 -0
  455. package/dist/components/workspace/workspace.meta.js +183 -0
  456. package/dist/foundations/accessibility.js +107 -0
  457. package/dist/foundations/index.js +25 -792
  458. package/dist/foundations/motion.js +135 -0
  459. package/dist/foundations/scrolling.js +62 -0
  460. package/dist/foundations/shape.js +113 -0
  461. package/dist/foundations/spacing.js +121 -0
  462. package/dist/foundations/surfaces.js +107 -0
  463. package/dist/foundations/types.js +0 -0
  464. package/dist/foundations/typography.js +152 -0
  465. package/dist/icon/Icon.js +30 -0
  466. package/dist/icon/IconProvider.js +27 -0
  467. package/dist/icon/compose.js +13 -0
  468. package/dist/icon/index.d.ts +13 -5
  469. package/dist/icon/index.js +13 -2
  470. package/dist/icon/registry.js +0 -0
  471. package/dist/icon-sets/brands.generated.js +123 -0
  472. package/dist/icon-sets/brands.js +10 -123
  473. package/dist/icon-sets/reicon.d.ts +3 -1
  474. package/dist/icon-sets/reicon.js +209 -1
  475. package/dist/index.d.ts +618 -34
  476. package/dist/index.js +211 -11351
  477. package/dist/ios/chrome.js +36 -0
  478. package/dist/ios/index.js +19 -315
  479. package/dist/ios/liquid-glass.js +103 -0
  480. package/dist/ios/native-app.js +46 -0
  481. package/dist/ios/navigation.js +63 -0
  482. package/dist/ios/phone-frame.js +64 -0
  483. package/dist/ios/preview-theme.js +83 -0
  484. package/dist/ios/preview.js +10 -137
  485. package/dist/ios/sheet.js +85 -0
  486. package/dist/ios/theme.js +19 -0
  487. package/dist/layout/AspectBox.js +27 -0
  488. package/dist/layout/Bleed.js +15 -0
  489. package/dist/layout/Center.js +21 -0
  490. package/dist/layout/Columns.js +70 -0
  491. package/dist/layout/Grid.js +50 -0
  492. package/dist/layout/GridOverlay.js +41 -0
  493. package/dist/layout/Page.js +11 -0
  494. package/dist/layout/Region.js +39 -0
  495. package/dist/layout/Row.js +45 -0
  496. package/dist/layout/SafeArea.js +26 -0
  497. package/dist/layout/Spacer.js +9 -0
  498. package/dist/layout/SplitPane.js +55 -0
  499. package/dist/layout/Stack.js +42 -0
  500. package/dist/layout/_responsive.js +16 -0
  501. package/dist/layout/_safeArea.js +18 -0
  502. package/dist/layout/index.d.ts +30 -8
  503. package/dist/layout/index.js +14 -2
  504. package/dist/lib/anchored-scroll.js +7 -0
  505. package/dist/lib/bleed.js +7 -0
  506. package/dist/lib/chart/cartesian.js +365 -0
  507. package/dist/lib/chart/chart-frame.js +163 -0
  508. package/dist/lib/chart/chart-legend.js +13 -0
  509. package/dist/lib/chart/chart-tooltip.js +38 -0
  510. package/dist/lib/chart/format.js +24 -0
  511. package/dist/lib/chart/geometry.js +114 -0
  512. package/dist/lib/chart/motion.js +34 -0
  513. package/dist/lib/chart/scale.js +72 -0
  514. package/dist/lib/chart/types.js +45 -0
  515. package/dist/lib/chart/use-arrival.js +41 -0
  516. package/dist/{chunk-SRQWQUTW.js → lib/cn.js} +5 -5
  517. package/dist/lib/component-guidance.js +215 -0
  518. package/dist/lib/density.js +54 -0
  519. package/dist/lib/field-shell.js +11 -0
  520. package/dist/lib/glyphs.js +9 -0
  521. package/dist/lib/heading-row.js +36 -0
  522. package/dist/lib/highlight-glide.js +84 -0
  523. package/dist/lib/hit-target.js +5 -0
  524. package/dist/lib/meta.js +0 -0
  525. package/dist/lib/portal-theme-scope.js +74 -0
  526. package/dist/{chunk-FKZXAFIY.js → lib/presentation.js} +8 -3
  527. package/dist/lib/refs.js +14 -0
  528. package/dist/lib/scrub-gesture.js +50 -0
  529. package/dist/lib/segmented.js +13 -0
  530. package/dist/lib/selection-card.js +41 -0
  531. package/dist/lib/status-tone.js +13 -0
  532. package/dist/lib/taxonomy.js +214 -0
  533. package/dist/lib/trim-label.js +20 -0
  534. package/dist/lib/use-copy.js +27 -0
  535. package/dist/lib/use-edge-fade.js +32 -0
  536. package/dist/lib/use-isomorphic-layout-effect.js +8 -0
  537. package/dist/lib/use-resize-observer.js +18 -0
  538. package/dist/lib/use-scroll-activity.js +52 -0
  539. package/dist/lib/use-wheel-to-horizontal.js +65 -0
  540. package/dist/motion/MotionProvider.js +75 -0
  541. package/dist/motion/Presence.js +112 -0
  542. package/dist/motion/Reveal.js +42 -0
  543. package/dist/motion/TextReveal.js +61 -0
  544. package/dist/motion/index.js +24 -0
  545. package/dist/motion/useInView.js +36 -0
  546. package/dist/motion/useReducedMotion.js +25 -0
  547. package/dist/motion/viewTransition.js +47 -0
  548. package/dist/patterns/auth-page.js +90 -0
  549. package/dist/patterns/auth-page.meta.js +27 -0
  550. package/dist/patterns/brand-landing-page.js +341 -0
  551. package/dist/patterns/brand-landing-page.meta.js +28 -0
  552. package/dist/patterns/chat-panel.js +185 -0
  553. package/dist/patterns/chat-panel.meta.js +31 -0
  554. package/dist/patterns/dashboard-page.js +332 -0
  555. package/dist/patterns/dashboard-page.meta.js +29 -0
  556. package/dist/patterns/feed-page.js +205 -0
  557. package/dist/patterns/feed-page.meta.js +25 -0
  558. package/dist/patterns/index.js +34 -2140
  559. package/dist/patterns/landing-page.js +356 -0
  560. package/dist/patterns/landing-page.meta.js +26 -0
  561. package/dist/patterns/list-detail-page.js +373 -0
  562. package/dist/patterns/list-detail-page.meta.js +24 -0
  563. package/dist/patterns/settings-page.js +268 -0
  564. package/dist/patterns/settings-page.meta.js +27 -0
  565. package/dist/presets/index.d.ts +7 -1
  566. package/dist/presets/index.js +53 -185
  567. package/dist/styles.css +118 -3
  568. package/dist/{theme-provider-kQszHYji.d.ts → theme-provider-S0NVJs2Y.d.ts} +6 -1
  569. package/dist/{chunk-NETUFI34.js → themes/_contract.js} +14 -2
  570. package/dist/themes/atelier/index.js +17 -1
  571. package/dist/themes/contrast.js +288 -0
  572. package/dist/themes/ember/ember.css +6 -6
  573. package/dist/themes/ember/index.js +16 -1
  574. package/dist/themes/index.d.ts +1 -1
  575. package/dist/themes/index.js +3 -8
  576. package/dist/themes/meridian/index.js +16 -1
  577. package/dist/themes/poppy/index.js +17 -1
  578. package/dist/themes/prism/index.js +17 -1
  579. package/dist/themes/prism/prism.css +2 -2
  580. package/dist/themes/registry.js +59 -0
  581. package/dist/themes/sable/index.js +16 -1
  582. package/dist/{chunk-EFLC4NA3.js → themes/theme-provider.js} +38 -54
  583. package/dist/themes/verdant/index.js +17 -1
  584. package/llms/blocks/media-player-block.md +20 -7
  585. package/llms/blocks/product-card-block.md +6 -4
  586. package/llms/blocks/task-list-block.md +1 -1
  587. package/llms/blocks/traffic-sources-block.md +1 -1
  588. package/llms/blocks/traffic-trend-block.md +5 -3
  589. package/llms/blocks/verify-code-block.md +1 -1
  590. package/llms/components/app-shell.md +5 -2
  591. package/llms/components/avatar.md +25 -3
  592. package/llms/components/button.md +20 -1
  593. package/llms/components/card.md +1 -1
  594. package/llms/components/disclosure-picker.md +168 -0
  595. package/llms/components/font-picker.md +104 -0
  596. package/llms/components/media-image.md +98 -0
  597. package/llms/components/media-tile.md +143 -0
  598. package/llms/components/page-header.md +6 -5
  599. package/llms/components/pie-chart.md +2 -2
  600. package/llms/components/radial-chart.md +1 -1
  601. package/llms/components/section-header.md +144 -0
  602. package/llms/components/sheet.md +10 -0
  603. package/llms/components/sidebar.md +4 -3
  604. package/llms/components/slider.md +14 -2
  605. package/llms/components/theme-selector.md +44 -4
  606. package/llms/components/tree.md +3 -3
  607. package/llms/layout/grid.md +24 -3
  608. package/llms/layout/region.md +16 -3
  609. package/llms/patterns/dashboard-page.md +3 -6
  610. package/llms/patterns/feed-page.md +4 -4
  611. package/llms/patterns/list-detail-page.md +1 -0
  612. package/llms/patterns/settings-page.md +2 -5
  613. package/llms/reference/utilities.md +84 -4
  614. package/llms/tasks/building-a-page.md +34 -3
  615. package/llms/tasks/converting-an-app.md +14 -4
  616. package/llms/tasks/creating-a-preset.md +4 -1
  617. package/llms/tasks/reviewing-a-design.md +19 -0
  618. package/llms/tasks/using-presets.md +19 -0
  619. package/llms-full.txt +1066 -78
  620. package/llms.txt +26 -9
  621. package/package.json +1 -1
  622. package/registry.json +2342 -164
  623. package/scripts/agent-setup.mjs +90 -0
  624. package/scripts/design-presets.mjs +59 -6
  625. package/scripts/grade.mjs +195 -29
  626. package/scripts/lint-rules.mjs +486 -10
  627. package/scripts/review-evidence.mjs +28 -1
  628. package/skills/sable/SKILL.md +67 -24
  629. package/targets/ios.json +45 -0
  630. package/dist/chunk-3IWZYBGH.js +0 -398
  631. package/dist/chunk-7MG4SHYX.js +0 -15
  632. package/dist/chunk-7QSDYBXO.js +0 -7421
  633. package/dist/chunk-ADLLDWLW.js +0 -15
  634. package/dist/chunk-C4Z3CF54.js +0 -15
  635. package/dist/chunk-EDXLM7YL.js +0 -5078
  636. package/dist/chunk-EHH4MHO6.js +0 -14
  637. package/dist/chunk-K7RUHUGC.js +0 -14
  638. package/dist/chunk-KO3NAEBF.js +0 -15
  639. package/dist/chunk-L4IEIQQA.js +0 -14
  640. package/dist/chunk-QJ6FWTUG.js +0 -40
  641. package/dist/chunk-VVW4UCDI.js +0 -4908
  642. package/dist/chunk-XAZGMY73.js +0 -187
@@ -0,0 +1,138 @@
1
+ // src/components/context-menu/context-menu.meta.ts
2
+ var contextMenuMeta = {
3
+ name: "ContextMenu",
4
+ summary: "Right-click menu over Base UI ContextMenu \u2014 opens on the native contextmenu event or long press and positions at the pointer. Shares Menu's roving focus, typeahead, ARIA menu/menuitem wiring, collision-aware positioning, and Esc/outside dismissal.",
5
+ status: "stable",
6
+ keywords: [
7
+ "context menu",
8
+ "right click",
9
+ "overflow",
10
+ "menu"
11
+ ],
12
+ usage: {
13
+ description: "Use ContextMenu for actions that are specific to the object or area the user invoked.",
14
+ bestPractices: [
15
+ {
16
+ guidance: "do",
17
+ description: "Use it for secondary object actions such as rename, duplicate, move, or delete."
18
+ },
19
+ {
20
+ guidance: "do",
21
+ description: "Group destructive or uncommon actions away from frequent safe actions."
22
+ },
23
+ {
24
+ guidance: "dont",
25
+ description: "Do not make ContextMenu the only way to access a primary or required action."
26
+ },
27
+ {
28
+ guidance: "dont",
29
+ description: "Do not rely on it for touch. There is no right-click on a touchscreen \u2014 the long-press fallback is discoverable by nobody, so anything in here needs a visible route too."
30
+ }
31
+ ],
32
+ anatomy: [
33
+ {
34
+ name: "ContextMenuTrigger",
35
+ required: true,
36
+ description: "The target area or element that opens the menu."
37
+ },
38
+ {
39
+ name: "ContextMenuContent",
40
+ required: true,
41
+ description: "The menu surface."
42
+ },
43
+ {
44
+ name: "ContextMenuItem",
45
+ required: true,
46
+ description: "One actionable command."
47
+ },
48
+ {
49
+ name: "ContextMenuSeparator",
50
+ required: false,
51
+ description: "A divider between command groups."
52
+ },
53
+ {
54
+ name: "ContextMenuGroup",
55
+ required: false,
56
+ description: "A semantic group of related commands."
57
+ },
58
+ {
59
+ name: "ContextMenuGroupLabel",
60
+ required: false,
61
+ description: "An optional label for a command group."
62
+ }
63
+ ]
64
+ },
65
+ related: {
66
+ components: [
67
+ "Menu",
68
+ "OverflowMenu"
69
+ ]
70
+ },
71
+ props: [
72
+ {
73
+ name: "ContextMenu (Root)",
74
+ type: "Base UI ContextMenu.Root props (open, defaultOpen, onOpenChange, orientation, loopFocus)",
75
+ default: "\u2014",
76
+ description: "Groups all parts and controls open state. Renders no element. Uncontrolled by default."
77
+ }
78
+ ],
79
+ subcomponents: [
80
+ {
81
+ name: "ContextMenuTrigger",
82
+ type: "Base UI ContextMenu.Trigger props + className + render",
83
+ description: "The right-clickable area that opens the menu on contextmenu (right click) or long press. Renders a <div>."
84
+ },
85
+ {
86
+ name: "ContextMenuContent",
87
+ type: "Base UI Popup props + { side, align, sideOffset, className }",
88
+ description: "Portal + Positioner + Popup. Positions at the pointer. side is which side of the anchor the popup renders against (auto-flips on collision), align its alignment along that side, sideOffset the gap in px. Defaults to side='bottom', align='start', sideOffset=6."
89
+ },
90
+ {
91
+ name: "ContextMenuItem",
92
+ type: 'Base UI ContextMenu.Item props + variant?: "default" | "destructive" + className (disabled, closeOnClick, onClick)',
93
+ description: 'An interactive row. Lays out as a flex row, so a leading Icon sits inline before the label. Highlights via data-[highlighted]; dims via data-[disabled], and disabled items are skipped by keyboard focus. variant="destructive" marks a destructive command (Delete, Remove) and keeps its destructive ink while highlighted; never fake it with a text-destructive class, which the highlight repaints.'
94
+ },
95
+ {
96
+ name: "ContextMenuSeparator",
97
+ type: "Base UI Separator props + className",
98
+ description: "Hairline rule between item runs."
99
+ },
100
+ {
101
+ name: "ContextMenuGroup",
102
+ type: "Base UI ContextMenu.Group props + className",
103
+ description: "Groups related items under an accessible label auto-associated with the group."
104
+ },
105
+ {
106
+ name: "ContextMenuGroupLabel",
107
+ type: "Base UI ContextMenu.GroupLabel props + className",
108
+ description: "The label for a ContextMenuGroup. Auto-associated with the group it sits in."
109
+ }
110
+ ],
111
+ tokensUsed: [
112
+ "popover",
113
+ "popover-foreground",
114
+ "border",
115
+ "accent",
116
+ "accent-foreground",
117
+ "muted-foreground"
118
+ ],
119
+ a11y: [
120
+ "Base UI provides role=menu/menuitem, roving tabindex, arrow-key navigation, and typeahead.",
121
+ "Opens on right click (contextmenu) or long press; Esc and outside-press dismiss and restore focus.",
122
+ "Animate open/close via data-[starting-style]/data-[ending-style] attributes.",
123
+ "ContextMenuGroupLabel is auto-associated with its ContextMenuGroup for screen readers."
124
+ ],
125
+ examples: [
126
+ {
127
+ label: "Basic",
128
+ code: '<ContextMenu><ContextMenuTrigger className="rounded-md border border-dashed border-border p-8 text-center text-body-sm text-muted-foreground">Right-click here</ContextMenuTrigger><ContextMenuContent><ContextMenuItem>Cut</ContextMenuItem><ContextMenuItem>Copy</ContextMenuItem><ContextMenuItem>Paste</ContextMenuItem><ContextMenuSeparator /><ContextMenuItem variant="destructive">Delete</ContextMenuItem></ContextMenuContent></ContextMenu>'
129
+ },
130
+ {
131
+ label: "Grouped",
132
+ code: '<ContextMenu><ContextMenuTrigger className="rounded-md border border-dashed border-border p-8">Right-click here</ContextMenuTrigger><ContextMenuContent><ContextMenuGroup><ContextMenuGroupLabel>Layout</ContextMenuGroupLabel><ContextMenuItem>Move up</ContextMenuItem><ContextMenuItem>Move down</ContextMenuItem></ContextMenuGroup><ContextMenuSeparator /><ContextMenuItem>Duplicate</ContextMenuItem></ContextMenuContent></ContextMenu>'
133
+ }
134
+ ]
135
+ };
136
+ export {
137
+ contextMenuMeta
138
+ };
@@ -0,0 +1,23 @@
1
+ // src/components/context-menu/index.ts
2
+ import {
3
+ ContextMenu,
4
+ ContextMenuPortal,
5
+ ContextMenuTrigger,
6
+ ContextMenuContent,
7
+ ContextMenuItem,
8
+ ContextMenuSeparator,
9
+ ContextMenuGroup,
10
+ ContextMenuGroupLabel
11
+ } from "./context-menu.js";
12
+ import { contextMenuMeta } from "./context-menu.meta.js";
13
+ export {
14
+ ContextMenu,
15
+ ContextMenuContent,
16
+ ContextMenuGroup,
17
+ ContextMenuGroupLabel,
18
+ ContextMenuItem,
19
+ ContextMenuPortal,
20
+ ContextMenuSeparator,
21
+ ContextMenuTrigger,
22
+ contextMenuMeta
23
+ };
@@ -0,0 +1,142 @@
1
+ "use client";
2
+
3
+ // src/components/data-table/data-table.tsx
4
+ import { useMemo, useState } from "react";
5
+ import { Icon } from "../../icon/index.js";
6
+ import { cn } from "../../lib/cn.js";
7
+ import { Button } from "../button/button.js";
8
+ import {
9
+ Table,
10
+ TableBody,
11
+ TableCaption,
12
+ TableCell,
13
+ TableHead,
14
+ TableHeader,
15
+ TableRow
16
+ } from "../table/index.js";
17
+ import { jsx, jsxs } from "react/jsx-runtime";
18
+ var ALIGN = {
19
+ start: "text-start",
20
+ center: "text-center",
21
+ // End-aligned columns are the numeric ones: tabular figures keep the
22
+ // digits on one grid down the column.
23
+ end: "text-end tabular-nums"
24
+ };
25
+ function DataTable({
26
+ columns,
27
+ data,
28
+ rowKey,
29
+ onRowClick,
30
+ isRowSelected,
31
+ defaultSort,
32
+ empty = "No results.",
33
+ caption,
34
+ className
35
+ }) {
36
+ const [sort, setSort] = useState(defaultSort ?? null);
37
+ function toggleSort(key) {
38
+ setSort((prev) => {
39
+ if (prev?.key !== key) return { key, direction: "asc" };
40
+ if (prev.direction === "asc") return { key, direction: "desc" };
41
+ return null;
42
+ });
43
+ }
44
+ const rows = useMemo(() => {
45
+ if (!sort) return data;
46
+ const col = columns.find((c) => c.key === sort.key);
47
+ if (!col) return data;
48
+ const getValue = col.sortValue ?? ((row) => row[col.key]);
49
+ return [...data].sort((a, b) => {
50
+ const va = getValue(a);
51
+ const vb = getValue(b);
52
+ let c = 0;
53
+ if (va == null && vb == null) c = 0;
54
+ else if (va == null) c = 1;
55
+ else if (vb == null) c = -1;
56
+ else if (va < vb) c = -1;
57
+ else if (va > vb) c = 1;
58
+ return sort.direction === "asc" ? c : -c;
59
+ });
60
+ }, [data, sort, columns]);
61
+ return /* @__PURE__ */ jsxs(Table, { className, children: [
62
+ caption ? /* @__PURE__ */ jsx(TableCaption, { children: caption }) : null,
63
+ /* @__PURE__ */ jsx(TableHeader, { children: /* @__PURE__ */ jsx(TableRow, { children: columns.map((col) => {
64
+ const active = sort?.key === col.key;
65
+ return /* @__PURE__ */ jsx(
66
+ TableHead,
67
+ {
68
+ "aria-sort": active ? sort.direction === "asc" ? "ascending" : "descending" : void 0,
69
+ className: cn(col.align && ALIGN[col.align], col.className),
70
+ children: col.sortable ? (
71
+ // The negative inline margin cancels Button's padding so
72
+ // the label stays on the column's text edge; the header's
73
+ // own type and ink win over Button's action tier. In an
74
+ // end-aligned column the chevron leads, so the LABEL is
75
+ // what sits on the numbers' edge.
76
+ /* @__PURE__ */ jsxs(
77
+ Button,
78
+ {
79
+ variant: "ghost",
80
+ size: "xs",
81
+ onClick: () => toggleSort(col.key),
82
+ className: cn(
83
+ "-mx-2 gap-1 text-label-md text-muted-foreground hover:text-foreground",
84
+ col.align === "end" && "flex-row-reverse"
85
+ ),
86
+ children: [
87
+ col.header,
88
+ /* @__PURE__ */ jsx(
89
+ Icon,
90
+ {
91
+ name: active && sort.direction === "desc" ? "chevron-down" : "chevron-up",
92
+ className: cn("text-xs", !active && "opacity-60")
93
+ }
94
+ )
95
+ ]
96
+ }
97
+ )
98
+ ) : col.header
99
+ },
100
+ col.key
101
+ );
102
+ }) }) }),
103
+ /* @__PURE__ */ jsx(TableBody, { children: rows.length === 0 ? /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(
104
+ TableCell,
105
+ {
106
+ colSpan: columns.length,
107
+ className: cn(
108
+ "text-center text-muted-foreground",
109
+ typeof empty === "string" && "py-8"
110
+ ),
111
+ children: empty
112
+ }
113
+ ) }) : rows.map((row, i) => /* @__PURE__ */ jsx(
114
+ TableRow,
115
+ {
116
+ "data-selected": isRowSelected?.(row) ? "" : void 0,
117
+ onClick: onRowClick ? () => onRowClick(row) : void 0,
118
+ tabIndex: onRowClick ? 0 : void 0,
119
+ onKeyDown: onRowClick ? (e) => {
120
+ if (e.target !== e.currentTarget) return;
121
+ if (e.key !== "Enter" && e.key !== " ") return;
122
+ e.preventDefault();
123
+ onRowClick(row);
124
+ } : void 0,
125
+ className: onRowClick ? "cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring" : void 0,
126
+ children: columns.map((col) => /* @__PURE__ */ jsx(
127
+ TableCell,
128
+ {
129
+ className: cn(col.align && ALIGN[col.align], col.className),
130
+ children: col.cell ? col.cell(row) : row[col.key]
131
+ },
132
+ col.key
133
+ ))
134
+ },
135
+ rowKey ? rowKey(row, i) : i
136
+ )) })
137
+ ] });
138
+ }
139
+ DataTable.displayName = "DataTable";
140
+ export {
141
+ DataTable
142
+ };
@@ -0,0 +1,146 @@
1
+ // src/components/data-table/data-table.meta.ts
2
+ var dataTableMeta = {
3
+ name: "DataTable",
4
+ summary: "A data-driven table over the Table primitives \u2014 a columns def + data array with built-in client-side sorting (click a sortable header to cycle asc \u2192 desc \u2192 none), optional row click / selection, and an empty state. For server data or paging, sort/page the data and pair with Pagination.",
5
+ keywords: [
6
+ "data table",
7
+ "table",
8
+ "sortable",
9
+ "columns",
10
+ "rows",
11
+ "empty state",
12
+ "pagination",
13
+ "list"
14
+ ],
15
+ usage: {
16
+ description: "Use DataTable when a data array and column definition should render a sortable, semantic table with optional row actions and an empty state. Use the lower-level Table parts for hand-authored markup or highly custom row layouts.",
17
+ bestPractices: [
18
+ {
19
+ guidance: "do",
20
+ description: "Put a table that fills a card in <CardContent flush>. The table runs edge to edge and its first and last columns inset to the card padding on their own; do not hand-set pl-6 / pr-6 on columns."
21
+ },
22
+ {
23
+ guidance: "do",
24
+ description: "Provide stable rowKey values for dynamic data so selection and sorting do not jump."
25
+ },
26
+ {
27
+ guidance: "do",
28
+ description: "Use sortable only on columns where ordering is obvious and useful."
29
+ },
30
+ {
31
+ guidance: "do",
32
+ description: "Pair server-side datasets with Pagination and pass already-sorted/paged rows."
33
+ },
34
+ {
35
+ guidance: "dont",
36
+ description: "Make every row clickable and also fill it with competing buttons. Choose a clear row interaction model."
37
+ },
38
+ {
39
+ guidance: "dont",
40
+ description: "Use DataTable for heterogeneous cards or timeline content. A list or card layout will scan better."
41
+ }
42
+ ],
43
+ anatomy: [
44
+ {
45
+ name: "Columns",
46
+ required: true,
47
+ description: "Definitions for headers, cell renderers, sorting, alignment, and classes."
48
+ },
49
+ {
50
+ name: "Rows",
51
+ required: true,
52
+ description: "The data array rendered through the column definitions."
53
+ },
54
+ {
55
+ name: "Empty state",
56
+ required: false,
57
+ description: "Content spanning all columns when the row array is empty."
58
+ },
59
+ {
60
+ name: "Caption",
61
+ required: false,
62
+ description: "Accessible table caption rendered by the underlying Table."
63
+ }
64
+ ]
65
+ },
66
+ related: {
67
+ components: ["Table", "Pagination", "EmptyState", "Badge"],
68
+ patterns: ["DashboardPage", "ListDetailPage"]
69
+ },
70
+ status: "stable",
71
+ props: [
72
+ {
73
+ name: "columns",
74
+ type: "DataTableColumn<Row>[]",
75
+ description: "Column defs: { key, header, cell?, sortValue?, sortable?, align?, className? }. cell defaults to row[key]; sortValue defaults to row[key]. When cell renders a formatted string (e.g. a date), pass sortValue returning the underlying value (e.g. date.getTime()) so the column sorts by the real value, not the rendered text."
76
+ },
77
+ {
78
+ name: "data",
79
+ type: "Row[]",
80
+ description: "The rows to render."
81
+ },
82
+ {
83
+ name: "rowKey",
84
+ type: "(row, index) => string | number",
85
+ default: "index",
86
+ description: "Stable React key per row."
87
+ },
88
+ {
89
+ name: "onRowClick",
90
+ type: "(row) => void",
91
+ description: "Row click handler \u2014 makes rows pointer-interactive."
92
+ },
93
+ {
94
+ name: "isRowSelected",
95
+ type: "(row) => boolean",
96
+ description: "Mark a row visually selected (data-selected). Derive it from a stable id (row.id === selectedId), not the row index, so selection survives re-sorts."
97
+ },
98
+ {
99
+ name: "defaultSort",
100
+ type: '{ key: string; direction: "asc" | "desc" }',
101
+ description: "Initial sort column + direction."
102
+ },
103
+ {
104
+ name: "empty",
105
+ type: "ReactNode",
106
+ default: '"No results."',
107
+ description: "Rendered spanning all columns when data is empty. Pass an EmptyState for the full treatment (icon, title, next step)."
108
+ },
109
+ {
110
+ name: "caption",
111
+ type: "ReactNode",
112
+ description: "Bottom table caption."
113
+ }
114
+ ],
115
+ tokensUsed: ["muted-foreground", "foreground", "ring"],
116
+ a11y: [
117
+ "Sorted columns set aria-sort=ascending/descending on the header cell.",
118
+ "Sortable headers are real <button>s with a focus-visible ring, keyboard-operable.",
119
+ "Inherits the Table's scrollable frame and semantic <table>/<th>/<td> structure."
120
+ ],
121
+ examples: [
122
+ {
123
+ label: "Sortable columns",
124
+ code: '<DataTable data={users} columns={[{ key: "name", header: "Name", sortable: true }, { key: "role", header: "Role" }, { key: "joined", header: "Joined", sortable: true, sortValue: (u) => u.joinedAt, cell: (u) => formatDate(u.joinedAt) }]} />'
125
+ },
126
+ {
127
+ label: "Clickable rows",
128
+ code: "<DataTable data={posts} columns={cols} onRowClick={(p) => navigate(`/post/${p.id}`)} rowKey={(p) => p.id} />"
129
+ },
130
+ {
131
+ label: "Rich status column",
132
+ code: '<DataTable data={deployments} rowKey={(row) => row.id} columns={[{ key: "name", header: "Name", sortable: true }, { key: "status", header: "Status", cell: (row) => <Badge appearance="plain" tone={row.status === "failed" ? "destructive" : row.status === "building" ? "warning" : "success"} dot>{row.statusLabel}</Badge> }, { key: "owner", header: "Owner", cell: (row) => <Entity className="[--entity-px:0] [--entity-py:0]" leading={<Avatar src={row.owner.avatar} alt={row.owner.name} fallback={row.owner.initials} size="sm" />} title={row.owner.name} /> }]} />'
133
+ },
134
+ {
135
+ label: "In a card, edge to edge",
136
+ code: '<Card><CardHeader><CardTitle>Deployments</CardTitle></CardHeader><CardContent flush><DataTable data={deployments} rowKey={(row) => row.id} columns={[{ key: "project", header: "Project", sortable: true }, { key: "duration", header: "Duration", align: "end" }]} /></CardContent></Card>'
137
+ },
138
+ {
139
+ label: "Empty state",
140
+ code: '<DataTable data={[]} columns={[{ key: "name", header: "Name" }, { key: "status", header: "Status" }]} empty={<EmptyState icon={<Icon name="search" />} title="No deployments" description="Try a different filter or create a deployment." action={<Button>Create deployment</Button>} />} />'
141
+ }
142
+ ]
143
+ };
144
+ export {
145
+ dataTableMeta
146
+ };
@@ -0,0 +1,9 @@
1
+ // src/components/data-table/index.ts
2
+ import {
3
+ DataTable
4
+ } from "./data-table.js";
5
+ import { dataTableMeta } from "./data-table.meta.js";
6
+ export {
7
+ DataTable,
8
+ dataTableMeta
9
+ };
@@ -0,0 +1,196 @@
1
+ "use client";
2
+
3
+ // src/components/date-picker/date-picker.tsx
4
+ import {
5
+ format,
6
+ setHours,
7
+ setMilliseconds,
8
+ setMinutes,
9
+ setSeconds
10
+ } from "date-fns";
11
+ import { useId, useState } from "react";
12
+ import { Icon } from "../../icon/index.js";
13
+ import { cn } from "../../lib/cn.js";
14
+ import { useDensity, useTypeTier } from "../../lib/density.js";
15
+ import { FIELD_INVALID, FIELD_SHELL, MOBILE_FIELD_TIER } from "../../lib/field-shell.js";
16
+ import { Calendar } from "../calendar/calendar.js";
17
+ import { Popover, PopoverContent, PopoverTrigger } from "../popover/popover.js";
18
+ import {
19
+ Select,
20
+ SelectContent,
21
+ SelectItem,
22
+ SelectTrigger
23
+ } from "../select/select.js";
24
+ import { jsx, jsxs } from "react/jsx-runtime";
25
+ function rangeMatchers(minDate, maxDate) {
26
+ const matchers = [];
27
+ if (minDate) matchers.push({ before: minDate });
28
+ if (maxDate) matchers.push({ after: maxDate });
29
+ return matchers.length ? matchers : void 0;
30
+ }
31
+ var HOURS = Array.from({ length: 24 }, (_, h) => h);
32
+ function pad(n) {
33
+ return String(n).padStart(2, "0");
34
+ }
35
+ function parseDefaultTime(time) {
36
+ const match = /^(\d{1,2}):(\d{1,2})$/.exec(time);
37
+ if (!match) return [0, 0];
38
+ return [
39
+ Math.min(23, Math.max(0, Number(match[1]))),
40
+ Math.min(59, Math.max(0, Number(match[2])))
41
+ ];
42
+ }
43
+ function atTime(date, hours, minutes) {
44
+ return setMilliseconds(setSeconds(setMinutes(setHours(date, hours), minutes), 0), 0);
45
+ }
46
+ function DatePicker(props) {
47
+ const {
48
+ value: valueProp,
49
+ defaultValue,
50
+ onValueChange,
51
+ onChange,
52
+ granularity = "day",
53
+ minuteStep = 5,
54
+ defaultTime = "00:00",
55
+ placeholder,
56
+ disabled,
57
+ minDate,
58
+ maxDate,
59
+ className,
60
+ id,
61
+ "aria-label": ariaLabel,
62
+ "aria-labelledby": ariaLabelledBy,
63
+ "aria-describedby": ariaDescribedBy,
64
+ "aria-invalid": ariaInvalid,
65
+ "aria-required": ariaRequired
66
+ } = props;
67
+ const timeLabelId = useId();
68
+ const tier = useTypeTier();
69
+ const density = useDensity();
70
+ const [open, setOpen] = useState(false);
71
+ const [uncontrolled, setUncontrolled] = useState(defaultValue);
72
+ const controlled = "value" in props;
73
+ const value = controlled ? valueProp : uncontrolled;
74
+ const withTime = granularity === "minute";
75
+ function commit(next) {
76
+ if (!controlled) setUncontrolled(next);
77
+ onValueChange?.(next);
78
+ onChange?.(next);
79
+ }
80
+ const [defaultHours, defaultMinutes] = parseDefaultTime(defaultTime);
81
+ const hours = value?.getHours() ?? defaultHours;
82
+ const minutes = value?.getMinutes() ?? defaultMinutes;
83
+ const step = Math.max(1, Math.floor(minuteStep));
84
+ const steps = Array.from({ length: Math.ceil(60 / step) }, (_, i) => i * step);
85
+ const minuteOptions = steps.includes(minutes) ? steps : [...steps, minutes].sort((a, b) => a - b);
86
+ function handleDay(next) {
87
+ if (!withTime) {
88
+ commit(next);
89
+ setOpen(false);
90
+ return;
91
+ }
92
+ commit(next ? atTime(next, hours, minutes) : void 0);
93
+ }
94
+ function timeBase() {
95
+ return atTime(value ?? /* @__PURE__ */ new Date(), hours, minutes);
96
+ }
97
+ function handleHour(next) {
98
+ if (next == null) return;
99
+ commit(setHours(timeBase(), Number(next)));
100
+ }
101
+ function handleMinute(next) {
102
+ if (next == null) return;
103
+ commit(setMinutes(timeBase(), Number(next)));
104
+ }
105
+ const label = value ? (
106
+ // 24-hour, matching the hour / minute Selects below — the trigger
107
+ // and the row that sets it must not show the same time two ways.
108
+ format(value, withTime ? "MMM d, yyyy 'at' HH:mm" : "PP")
109
+ ) : placeholder ?? (withTime ? "Pick date & time" : "Pick a date");
110
+ return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
111
+ /* @__PURE__ */ jsx(
112
+ PopoverTrigger,
113
+ {
114
+ render: (
115
+ // The field shell, not an outline Button: in a form a date sits
116
+ // beside Inputs and Selects, and has to be the same shape they
117
+ // are (soft-square field radius, input border, card surface) —
118
+ // an outline Button is a pill in most themes. CommandMenuTrigger
119
+ // is the same move: a button wearing the field.
120
+ // design-lint-disable-next-line raw-button -- a field-shaped trigger (FIELD_SHELL, like CommandMenuTrigger), not a button-shaped action
121
+ /* @__PURE__ */ jsxs(
122
+ "button",
123
+ {
124
+ type: "button",
125
+ id,
126
+ "aria-label": ariaLabel,
127
+ "aria-labelledby": ariaLabelledBy,
128
+ "aria-describedby": ariaDescribedBy,
129
+ "aria-invalid": ariaInvalid,
130
+ "aria-required": ariaRequired,
131
+ disabled,
132
+ className: cn(
133
+ "inline-flex h-(--control-md) items-center gap-2 ps-3 pe-3 text-start text-foreground",
134
+ // Select's type: the density tier, plus the 16px phone tier
135
+ // its form-row neighbours take (lib/field-shell).
136
+ tier.body,
137
+ density === "comfortable" && MOBILE_FIELD_TIER,
138
+ FIELD_SHELL,
139
+ FIELD_INVALID,
140
+ className
141
+ ),
142
+ children: [
143
+ /* @__PURE__ */ jsx(Icon, { name: "calendar", className: "shrink-0 text-sm text-muted-foreground" }),
144
+ /* @__PURE__ */ jsx("span", { className: cn("truncate", !value && "text-muted-foreground"), children: label })
145
+ ]
146
+ }
147
+ )
148
+ )
149
+ }
150
+ ),
151
+ /* @__PURE__ */ jsxs(PopoverContent, { align: "start", className: "w-auto p-3", children: [
152
+ /* @__PURE__ */ jsx(
153
+ Calendar,
154
+ {
155
+ bare: true,
156
+ mode: "single",
157
+ selected: value,
158
+ onSelect: handleDay,
159
+ disabled: rangeMatchers(minDate, maxDate),
160
+ defaultMonth: value ?? minDate,
161
+ startMonth: minDate,
162
+ endMonth: maxDate
163
+ }
164
+ ),
165
+ withTime && // One group named "Time" holding the two Selects, rather than a
166
+ // <label> — a label names one control, and this names a pair.
167
+ /* @__PURE__ */ jsxs(
168
+ "div",
169
+ {
170
+ role: "group",
171
+ "aria-labelledby": timeLabelId,
172
+ className: "mt-3 flex items-center gap-2 border-t border-border pt-3",
173
+ children: [
174
+ /* @__PURE__ */ jsx("span", { id: timeLabelId, className: "text-label-md text-muted-foreground", children: "Time" }),
175
+ /* @__PURE__ */ jsxs("div", { className: "ms-auto flex items-center gap-1", children: [
176
+ /* @__PURE__ */ jsxs(Select, { value: pad(hours), onValueChange: handleHour, children: [
177
+ /* @__PURE__ */ jsx(SelectTrigger, { "aria-label": "Hour", className: "w-18" }),
178
+ /* @__PURE__ */ jsx(SelectContent, { children: HOURS.map((h) => /* @__PURE__ */ jsx(SelectItem, { value: pad(h), children: pad(h) }, h)) })
179
+ ] }),
180
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: ":" }),
181
+ /* @__PURE__ */ jsxs(Select, { value: pad(minutes), onValueChange: handleMinute, children: [
182
+ /* @__PURE__ */ jsx(SelectTrigger, { "aria-label": "Minute", className: "w-18" }),
183
+ /* @__PURE__ */ jsx(SelectContent, { children: minuteOptions.map((m) => /* @__PURE__ */ jsx(SelectItem, { value: pad(m), children: pad(m) }, m)) })
184
+ ] })
185
+ ] })
186
+ ]
187
+ }
188
+ )
189
+ ] })
190
+ ] });
191
+ }
192
+ DatePicker.displayName = "DatePicker";
193
+ export {
194
+ DatePicker,
195
+ rangeMatchers
196
+ };