@sableui/react 0.6.1 → 0.7.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 (633) hide show
  1. package/AGENTS.md +2 -2
  2. package/CHANGELOG.md +285 -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 +200 -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 +33 -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 +611 -33
  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 +25 -6
  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 +19 -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 +210 -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.js +43 -185
  566. package/dist/styles.css +118 -3
  567. package/dist/{theme-provider-kQszHYji.d.ts → theme-provider-S0NVJs2Y.d.ts} +6 -1
  568. package/dist/{chunk-NETUFI34.js → themes/_contract.js} +14 -2
  569. package/dist/themes/atelier/index.js +17 -1
  570. package/dist/themes/contrast.js +288 -0
  571. package/dist/themes/ember/ember.css +6 -6
  572. package/dist/themes/ember/index.js +16 -1
  573. package/dist/themes/index.d.ts +1 -1
  574. package/dist/themes/index.js +3 -8
  575. package/dist/themes/meridian/index.js +16 -1
  576. package/dist/themes/poppy/index.js +17 -1
  577. package/dist/themes/prism/index.js +17 -1
  578. package/dist/themes/prism/prism.css +2 -2
  579. package/dist/themes/registry.js +59 -0
  580. package/dist/themes/sable/index.js +16 -1
  581. package/dist/{chunk-EFLC4NA3.js → themes/theme-provider.js} +38 -54
  582. package/dist/themes/verdant/index.js +17 -1
  583. package/llms/blocks/media-player-block.md +20 -7
  584. package/llms/blocks/product-card-block.md +6 -4
  585. package/llms/blocks/task-list-block.md +1 -1
  586. package/llms/blocks/verify-code-block.md +1 -1
  587. package/llms/components/app-shell.md +5 -2
  588. package/llms/components/avatar.md +25 -3
  589. package/llms/components/button.md +20 -1
  590. package/llms/components/card.md +1 -1
  591. package/llms/components/disclosure-picker.md +168 -0
  592. package/llms/components/font-picker.md +104 -0
  593. package/llms/components/media-image.md +98 -0
  594. package/llms/components/media-tile.md +143 -0
  595. package/llms/components/page-header.md +6 -5
  596. package/llms/components/section-header.md +144 -0
  597. package/llms/components/sheet.md +10 -0
  598. package/llms/components/sidebar.md +4 -3
  599. package/llms/components/slider.md +14 -2
  600. package/llms/components/theme-selector.md +44 -4
  601. package/llms/components/tree.md +3 -3
  602. package/llms/layout/grid.md +24 -3
  603. package/llms/patterns/dashboard-page.md +3 -6
  604. package/llms/patterns/feed-page.md +4 -4
  605. package/llms/patterns/list-detail-page.md +1 -0
  606. package/llms/patterns/settings-page.md +2 -5
  607. package/llms/reference/utilities.md +84 -4
  608. package/llms/tasks/converting-an-app.md +14 -4
  609. package/llms/tasks/reviewing-a-design.md +15 -0
  610. package/llms-full.txt +981 -65
  611. package/llms.txt +27 -10
  612. package/package.json +1 -1
  613. package/registry.json +2324 -171
  614. package/scripts/agent-setup.mjs +90 -0
  615. package/scripts/design-presets.mjs +46 -4
  616. package/scripts/grade.mjs +195 -29
  617. package/scripts/lint-rules.mjs +486 -10
  618. package/scripts/review-evidence.mjs +28 -1
  619. package/skills/sable/SKILL.md +56 -22
  620. package/targets/ios.json +45 -0
  621. package/dist/chunk-3IWZYBGH.js +0 -398
  622. package/dist/chunk-7MG4SHYX.js +0 -15
  623. package/dist/chunk-7QSDYBXO.js +0 -7421
  624. package/dist/chunk-ADLLDWLW.js +0 -15
  625. package/dist/chunk-C4Z3CF54.js +0 -15
  626. package/dist/chunk-EDXLM7YL.js +0 -5078
  627. package/dist/chunk-EHH4MHO6.js +0 -14
  628. package/dist/chunk-K7RUHUGC.js +0 -14
  629. package/dist/chunk-KO3NAEBF.js +0 -15
  630. package/dist/chunk-L4IEIQQA.js +0 -14
  631. package/dist/chunk-QJ6FWTUG.js +0 -40
  632. package/dist/chunk-VVW4UCDI.js +0 -4908
  633. package/dist/chunk-XAZGMY73.js +0 -187
@@ -0,0 +1,117 @@
1
+ // src/components/collapsible/collapsible.meta.ts
2
+ var collapsibleMeta = {
3
+ name: "Collapsible",
4
+ summary: "Show/hide a panel of content over Base UI Collapsible \u2014 open/close state, ARIA expanded wiring, and the animated height transition. The minimal primitive behind Accordion: a trigger that toggles an overflow-clipped panel.",
5
+ status: "stable",
6
+ keywords: [
7
+ "collapsible",
8
+ "disclosure",
9
+ "expand",
10
+ "collapse"
11
+ ],
12
+ usage: {
13
+ description: "Use Collapsible for a single piece of optional content that can expand in place.",
14
+ bestPractices: [
15
+ {
16
+ guidance: "do",
17
+ description: "Use it for local detail, advanced settings, or secondary context."
18
+ },
19
+ {
20
+ guidance: "do",
21
+ description: "Make the trigger label describe the hidden content, not the mechanism."
22
+ },
23
+ {
24
+ guidance: "dont",
25
+ description: "Do not use Collapsible for multi-section navigation; use Accordion or Tabs instead."
26
+ },
27
+ {
28
+ guidance: "dont",
29
+ description: "Do not animate it by transitioning height from auto. Use the motion-disclosure recipe, which transitions to the measured panel height \u2014 `auto` does not animate and the panel will snap."
30
+ }
31
+ ],
32
+ anatomy: [
33
+ {
34
+ name: "CollapsibleTrigger",
35
+ required: true,
36
+ description: "The control that toggles the panel."
37
+ },
38
+ {
39
+ name: "CollapsiblePanel",
40
+ required: true,
41
+ description: "The content that expands or collapses."
42
+ },
43
+ {
44
+ name: "CollapsibleIndicator",
45
+ required: false,
46
+ description: "A visual affordance for open or closed state."
47
+ }
48
+ ]
49
+ },
50
+ related: {
51
+ components: [
52
+ "Accordion",
53
+ "ShowMore"
54
+ ]
55
+ },
56
+ props: [
57
+ {
58
+ name: "Collapsible (Root)",
59
+ type: "Base UI Collapsible.Root props (open, defaultOpen, onOpenChange, disabled)",
60
+ default: "\u2014",
61
+ description: "Groups the trigger and panel and owns open state. Uncontrolled by default; pass `open` + `onOpenChange` to control it."
62
+ },
63
+ {
64
+ name: "defaultOpen",
65
+ type: "boolean",
66
+ default: "false",
67
+ description: "Whether the panel starts open in the uncontrolled case."
68
+ },
69
+ {
70
+ name: "disabled",
71
+ type: "boolean",
72
+ default: "false",
73
+ description: "Disables the trigger and prevents toggling."
74
+ }
75
+ ],
76
+ subcomponents: [
77
+ {
78
+ name: "CollapsibleTrigger",
79
+ type: "Base UI Collapsible.Trigger props + render",
80
+ description: 'The button that toggles the panel. Compose with render={<Button variant="ghost" \u2026 />}.'
81
+ },
82
+ {
83
+ name: "CollapsiblePanel",
84
+ type: "Base UI Collapsible.Panel props + className (keepMounted, hiddenUntilFound)",
85
+ description: "The collapsible contents. Overflow-hidden; animates height via the --collapsible-panel-height var Base UI sets."
86
+ },
87
+ {
88
+ name: "CollapsibleIndicator",
89
+ type: "{ className? }",
90
+ description: "Auto-rotating disclosure chevron. Place it inside the trigger content and add the `group/collapsible` class to the trigger so it flips 180\xB0 on open."
91
+ }
92
+ ],
93
+ tokensUsed: ["foreground", "muted-foreground"],
94
+ a11y: [
95
+ "Base UI wires aria-expanded on the trigger and aria-controls/id between trigger and panel.",
96
+ "Trigger is a real <button>; toggles on click and Enter/Space.",
97
+ "Animate open/close via data-[starting-style]/data-[ending-style]; data-[panel-open] marks the open state.",
98
+ "Set hiddenUntilFound on the panel to let in-page browser search expand it."
99
+ ],
100
+ examples: [
101
+ {
102
+ label: "Basic",
103
+ code: '<Collapsible><CollapsibleTrigger render={<Button variant="ghost">Details</Button>} /><CollapsiblePanel><p className="pt-3">Hidden content revealed on toggle.</p></CollapsiblePanel></Collapsible>'
104
+ },
105
+ {
106
+ label: "Open by default",
107
+ code: '<Collapsible defaultOpen><CollapsibleTrigger render={<Button variant="ghost">Summary</Button>} /><CollapsiblePanel><p className="pt-3">Visible on first render.</p></CollapsiblePanel></Collapsible>'
108
+ },
109
+ {
110
+ label: "With rotating chevron",
111
+ code: '<Collapsible><CollapsibleTrigger className="group/collapsible" render={<Button variant="ghost">Details <CollapsibleIndicator /></Button>} /><CollapsiblePanel><p className="pt-3">Revealed on toggle.</p></CollapsiblePanel></Collapsible>'
112
+ }
113
+ ]
114
+ };
115
+ export {
116
+ collapsibleMeta
117
+ };
@@ -0,0 +1,15 @@
1
+ // src/components/collapsible/index.ts
2
+ import {
3
+ Collapsible,
4
+ CollapsibleTrigger,
5
+ CollapsibleIndicator,
6
+ CollapsiblePanel
7
+ } from "./collapsible.js";
8
+ import { collapsibleMeta } from "./collapsible.meta.js";
9
+ export {
10
+ Collapsible,
11
+ CollapsibleIndicator,
12
+ CollapsiblePanel,
13
+ CollapsibleTrigger,
14
+ collapsibleMeta
15
+ };
@@ -0,0 +1,293 @@
1
+ "use client";
2
+
3
+ // src/components/color-field/color-field.tsx
4
+ import { useCallback, useRef, useState } from "react";
5
+ import { Icon } from "../../icon/index.js";
6
+ import { cn } from "../../lib/cn.js";
7
+ import { Button } from "../button/index.js";
8
+ import { Input } from "../input/index.js";
9
+ import { Popover, PopoverContent, PopoverTrigger } from "../popover/index.js";
10
+ import { TRANSPARENT, formatHex, hsvToRgb, hueColor, isTransparent, parseHex, rgbToHsv } from "./color.js";
11
+ import { jsx, jsxs } from "react/jsx-runtime";
12
+ function useAreaDrag(onChange) {
13
+ const ref = useRef(null);
14
+ return {
15
+ ref,
16
+ onPointerDown: useCallback(
17
+ (event) => {
18
+ const el = ref.current;
19
+ if (!el || event.button !== 0) return;
20
+ event.preventDefault();
21
+ const emit = (clientX, clientY) => {
22
+ const box = el.getBoundingClientRect();
23
+ if (box.width === 0 || box.height === 0) return;
24
+ onChange(
25
+ Math.min(1, Math.max(0, (clientX - box.left) / box.width)),
26
+ Math.min(1, Math.max(0, (clientY - box.top) / box.height))
27
+ );
28
+ };
29
+ emit(event.clientX, event.clientY);
30
+ const onMove = (e) => emit(e.clientX, e.clientY);
31
+ const onUp = () => {
32
+ window.removeEventListener("pointermove", onMove);
33
+ window.removeEventListener("pointerup", onUp);
34
+ window.removeEventListener("pointercancel", onUp);
35
+ };
36
+ window.addEventListener("pointermove", onMove);
37
+ window.addEventListener("pointerup", onUp);
38
+ window.addEventListener("pointercancel", onUp);
39
+ },
40
+ [onChange]
41
+ )
42
+ };
43
+ }
44
+ function seed(value) {
45
+ const parsed = isTransparent(value) ? null : parseHex(value);
46
+ const rgb = parsed?.rgb ?? { r: 0, g: 0, b: 0 };
47
+ return { hsv: rgbToHsv(rgb), a: parsed?.a ?? 1, key: value };
48
+ }
49
+ function ColorField({
50
+ value,
51
+ onValueChange,
52
+ allowTransparent = false,
53
+ allowAlpha = false,
54
+ swatches,
55
+ label = "Colour",
56
+ className,
57
+ ...props
58
+ }) {
59
+ const [picker, setPicker] = useState(() => seed(value));
60
+ const [hexDraft, setHexDraft] = useState(null);
61
+ const transparent = isTransparent(value);
62
+ if (picker.key !== value) {
63
+ setPicker(isTransparent(value) ? { ...picker, key: value } : seed(value));
64
+ setHexDraft(null);
65
+ }
66
+ const rgb = hsvToRgb(picker.hsv);
67
+ const solid = formatHex(rgb);
68
+ const withAlpha = formatHex(rgb, allowAlpha ? picker.a : 1);
69
+ const commit = (next, emitted) => {
70
+ setPicker({ ...next, key: emitted });
71
+ setHexDraft(null);
72
+ onValueChange(emitted);
73
+ };
74
+ const setHsv = (hsv) => {
75
+ const emitted = formatHex(hsvToRgb(hsv), allowAlpha ? picker.a : 1);
76
+ commit({ ...picker, hsv }, emitted);
77
+ };
78
+ const sv = useAreaDrag((x, y) => setHsv({ ...picker.hsv, s: x, v: 1 - y }));
79
+ const hue = useAreaDrag((x) => setHsv({ ...picker.hsv, h: x * 360 }));
80
+ const alpha = useAreaDrag((x) => commit({ ...picker, a: x }, formatHex(rgb, x)));
81
+ return /* @__PURE__ */ jsxs(Popover, { children: [
82
+ /* @__PURE__ */ jsx(
83
+ PopoverTrigger,
84
+ {
85
+ render: /* @__PURE__ */ jsx(
86
+ "button",
87
+ {
88
+ type: "button",
89
+ "aria-label": `${label}: ${transparent ? "transparent" : withAlpha}`,
90
+ className: cn(
91
+ "checkerboard [--checkerboard-size:8px]",
92
+ "size-(--control-xs) shrink-0 rounded-xs ring-1 ring-hairline-strong",
93
+ "motion-interactive focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-ring",
94
+ className
95
+ ),
96
+ ...props,
97
+ children: /* @__PURE__ */ jsx(
98
+ "span",
99
+ {
100
+ "aria-hidden": true,
101
+ className: "block size-full rounded-[inherit]",
102
+ style: { backgroundColor: transparent ? "transparent" : withAlpha }
103
+ }
104
+ )
105
+ }
106
+ )
107
+ }
108
+ ),
109
+ /* @__PURE__ */ jsx(PopoverContent, { align: "start", className: "w-56 p-2", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
110
+ /* @__PURE__ */ jsxs(
111
+ "div",
112
+ {
113
+ ref: sv.ref,
114
+ onPointerDown: sv.onPointerDown,
115
+ className: "relative h-28 w-full cursor-crosshair rounded-concentric-md/2 ring-1 ring-hairline",
116
+ style: { backgroundColor: hueColor(picker.hsv.h) },
117
+ children: [
118
+ /* @__PURE__ */ jsx(
119
+ "div",
120
+ {
121
+ "aria-hidden": true,
122
+ className: "absolute inset-0 rounded-[inherit]",
123
+ style: {
124
+ backgroundImage: (
125
+ // design-lint-disable-next-line inline-color -- axes of the colour space, not theme surfaces
126
+ "linear-gradient(to right, #fff, transparent), linear-gradient(to top, #000, transparent)"
127
+ )
128
+ }
129
+ }
130
+ ),
131
+ /* @__PURE__ */ jsx(
132
+ "span",
133
+ {
134
+ "aria-hidden": true,
135
+ className: (
136
+ // design-lint-disable-next-line raw-black-white -- handle over arbitrary user colour; no token can guarantee contrast
137
+ "absolute size-3 -translate-x-1/2 -translate-y-1/2 rounded-full ring-2 ring-white ring-inset shadow-(--knob-shadow)"
138
+ ),
139
+ style: {
140
+ left: `${picker.hsv.s * 100}%`,
141
+ top: `${(1 - picker.hsv.v) * 100}%`,
142
+ backgroundColor: solid,
143
+ outline: "1px solid rgb(0 0 0 / 0.35)"
144
+ }
145
+ }
146
+ )
147
+ ]
148
+ }
149
+ ),
150
+ /* @__PURE__ */ jsx(
151
+ "div",
152
+ {
153
+ ref: hue.ref,
154
+ onPointerDown: hue.onPointerDown,
155
+ className: "relative h-3 w-full cursor-ew-resize rounded-full ring-1 ring-hairline",
156
+ style: {
157
+ backgroundImage: (
158
+ // design-lint-disable-next-line inline-color -- the hue wheel IS these six primaries
159
+ "linear-gradient(to right, #f00, #ff0, #0f0, #0ff, #00f, #f0f, #f00)"
160
+ )
161
+ },
162
+ children: /* @__PURE__ */ jsx(
163
+ "span",
164
+ {
165
+ "aria-hidden": true,
166
+ className: (
167
+ // design-lint-disable-next-line raw-black-white -- handle over arbitrary hue; see HANDLE CONTRAST above
168
+ "absolute top-1/2 size-3 -translate-x-1/2 -translate-y-1/2 rounded-full bg-white ring-1 ring-black/30"
169
+ ),
170
+ style: { left: `${picker.hsv.h / 360 * 100}%` }
171
+ }
172
+ )
173
+ }
174
+ ),
175
+ allowAlpha ? /* @__PURE__ */ jsxs(
176
+ "div",
177
+ {
178
+ ref: alpha.ref,
179
+ onPointerDown: alpha.onPointerDown,
180
+ className: "checkerboard [--checkerboard-size:8px] relative h-3 w-full cursor-ew-resize rounded-full ring-1 ring-hairline",
181
+ children: [
182
+ /* @__PURE__ */ jsx(
183
+ "div",
184
+ {
185
+ "aria-hidden": true,
186
+ className: "absolute inset-0 rounded-[inherit]",
187
+ style: {
188
+ backgroundImage: `linear-gradient(to right, ${formatHex(rgb, 0)}, ${solid})`
189
+ }
190
+ }
191
+ ),
192
+ /* @__PURE__ */ jsx(
193
+ "span",
194
+ {
195
+ "aria-hidden": true,
196
+ className: (
197
+ // design-lint-disable-next-line raw-black-white -- handle over arbitrary hue and checkerboard; see HANDLE CONTRAST above
198
+ "absolute top-1/2 size-3 -translate-x-1/2 -translate-y-1/2 rounded-full bg-white ring-1 ring-black/30"
199
+ ),
200
+ style: { left: `${picker.a * 100}%` }
201
+ }
202
+ )
203
+ ]
204
+ }
205
+ ) : null,
206
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
207
+ /* @__PURE__ */ jsx(
208
+ Input,
209
+ {
210
+ "aria-label": `${label} hex`,
211
+ value: hexDraft ?? (transparent ? "" : withAlpha),
212
+ placeholder: transparent ? TRANSPARENT : void 0,
213
+ spellCheck: false,
214
+ onChange: (event) => {
215
+ const next = event.target.value;
216
+ setHexDraft(next);
217
+ const parsed = parseHex(next);
218
+ if (!parsed) return;
219
+ const emitted = formatHex(parsed.rgb, allowAlpha ? parsed.a : 1);
220
+ setPicker({ hsv: rgbToHsv(parsed.rgb), a: parsed.a, key: emitted });
221
+ onValueChange(emitted);
222
+ },
223
+ onBlur: () => setHexDraft(null),
224
+ size: "xs",
225
+ className: "min-w-0 flex-1 text-ui-num"
226
+ }
227
+ ),
228
+ typeof window !== "undefined" && "EyeDropper" in window ? /* @__PURE__ */ jsx(
229
+ Button,
230
+ {
231
+ size: "icon-xs",
232
+ variant: "ghost",
233
+ "aria-label": "Pick colour from screen",
234
+ onClick: async () => {
235
+ try {
236
+ const result = await new window.EyeDropper().open();
237
+ const parsed = parseHex(String(result.sRGBHex));
238
+ if (!parsed) return;
239
+ const emitted = formatHex(parsed.rgb, allowAlpha ? picker.a : 1);
240
+ commit({ hsv: rgbToHsv(parsed.rgb), a: picker.a, key: emitted }, emitted);
241
+ } catch {
242
+ }
243
+ },
244
+ children: /* @__PURE__ */ jsx(Icon, { name: "eyedropper" })
245
+ }
246
+ ) : null
247
+ ] }),
248
+ swatches?.length ? /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1", children: swatches.map((swatch) => /* @__PURE__ */ jsx(
249
+ "button",
250
+ {
251
+ type: "button",
252
+ "aria-label": swatch,
253
+ onClick: () => {
254
+ const parsed = parseHex(swatch);
255
+ if (!parsed) return;
256
+ const emitted = formatHex(parsed.rgb, allowAlpha ? parsed.a : 1);
257
+ commit({ hsv: rgbToHsv(parsed.rgb), a: parsed.a, key: emitted }, emitted);
258
+ },
259
+ className: "hit-target size-5 rounded-xs ring-1 ring-hairline-strong motion-interactive hover:scale-110 [--hit-target-size:24px]",
260
+ style: { backgroundColor: swatch }
261
+ },
262
+ swatch
263
+ )) }) : null,
264
+ allowTransparent ? (
265
+ // Inside the picker, as a value — not a switch beside the field.
266
+ /* @__PURE__ */ jsxs(
267
+ Button,
268
+ {
269
+ size: "xs",
270
+ variant: transparent ? "secondary" : "ghost",
271
+ "aria-pressed": transparent,
272
+ onClick: () => transparent ? commit(picker, formatHex(rgb, allowAlpha ? picker.a : 1)) : commit(picker, TRANSPARENT),
273
+ className: "w-full justify-start gap-1.5 text-ui-md",
274
+ children: [
275
+ /* @__PURE__ */ jsx(
276
+ "span",
277
+ {
278
+ "aria-hidden": true,
279
+ className: "checkerboard [--checkerboard-size:6px] size-3 shrink-0 rounded-xs ring-1 ring-hairline-strong"
280
+ }
281
+ ),
282
+ "Transparent"
283
+ ]
284
+ }
285
+ )
286
+ ) : null
287
+ ] }) })
288
+ ] });
289
+ }
290
+ ColorField.displayName = "ColorField";
291
+ export {
292
+ ColorField
293
+ };
@@ -0,0 +1,142 @@
1
+ // src/components/color-field/color-field.meta.ts
2
+ var colorFieldMeta = {
3
+ name: "ColorField",
4
+ summary: "A colour swatch that opens a themed picker \u2014 saturation/value area, hue and alpha sliders, hex entry, presets, and transparent as a value rather than a separate toggle.",
5
+ keywords: [
6
+ "color",
7
+ "colour",
8
+ "color picker",
9
+ "swatch",
10
+ "hex",
11
+ "alpha",
12
+ "transparency",
13
+ "eyedropper",
14
+ "property",
15
+ "workspace"
16
+ ],
17
+ usage: {
18
+ description: 'Use ColorField wherever a colour is a property: a canvas background, an effect parameter, a stroke or fill. It is sized to the control ladder so it lines up inside a PropertyRow or PropertyPair. Deliberately not <input type="color">, which opens the OS dialog \u2014 that ignores the theme entirely, cannot show a transparency checkerboard, has no alpha channel, hosts no eyedropper or presets, and renders at whatever size the platform picks, so it never aligns in a property grid.',
19
+ bestPractices: [
20
+ {
21
+ guidance: "do",
22
+ description: 'Use allowTransparent when "no colour" is a real value. It appears inside the picker as a value; a transparent switch sitting beside a colour control reads as two properties when it is one.'
23
+ },
24
+ {
25
+ guidance: "do",
26
+ description: "Pass swatches when a surface has a house palette. Presets are how most colour choices actually get made, and they cost one row."
27
+ },
28
+ {
29
+ guidance: "do",
30
+ description: "Decide whether your persistence layer accepts 8-digit hex before enabling allowAlpha. The value format is the contract \u2014 see the tokens note."
31
+ },
32
+ {
33
+ guidance: "dont",
34
+ description: "Put a separate opacity slider next to a ColorField that already has allowAlpha. Two controls writing one channel is how they drift out of sync."
35
+ },
36
+ {
37
+ guidance: "dont",
38
+ description: "Re-derive hue from the committed value on every render. Grey has no hue, so dragging saturation to zero would snap the hue slider to red with no way back \u2014 ColorField keeps hue in its own state for exactly this reason."
39
+ },
40
+ {
41
+ guidance: "dont",
42
+ description: "Hand-roll a transparency checkerboard. Use the `checkerboard` utility with `--checkerboard-size` (~16px for an artboard, ~8px for a 24px swatch); two hand-rolled copies had already drifted before it existed. Its colours come from --panel / --panel-raised, so it is correct in both modes. It is deliberately not named bg-checkerboard: a custom bg-* utility lands in tailwind-merge's background group and silently evicts, or is evicted by, a real bg-* colour class."
43
+ }
44
+ ],
45
+ anatomy: [
46
+ {
47
+ name: "Trigger",
48
+ required: true,
49
+ description: "A swatch at --control-xs with a hairline ring, on a checkerboard so a translucent or transparent value reads as such."
50
+ },
51
+ {
52
+ name: "Picker",
53
+ required: true,
54
+ description: "Saturation/value area over the current hue, a hue slider, an alpha slider when allowAlpha, and a hex field."
55
+ },
56
+ {
57
+ name: "Presets",
58
+ required: false,
59
+ description: "An optional swatch row, and the Transparent entry when allowTransparent."
60
+ }
61
+ ]
62
+ },
63
+ related: {
64
+ components: ["PropertyRow", "PropertyPair", "ScrubField", "Input", "Popover"]
65
+ },
66
+ status: "stable",
67
+ props: [
68
+ {
69
+ name: "value",
70
+ type: "string",
71
+ description: 'The current value: "transparent", "#rrggbb", or "#rrggbbaa".'
72
+ },
73
+ {
74
+ name: "onValueChange",
75
+ type: "(value: string) => void",
76
+ description: "Called with the new value on every commit, including mid-drag."
77
+ },
78
+ {
79
+ name: "allowTransparent",
80
+ type: "boolean",
81
+ default: "false",
82
+ description: 'Offers "transparent" as a value inside the picker. Colour \u2192 transparent \u2192 colour restores the colour you had.'
83
+ },
84
+ {
85
+ name: "allowAlpha",
86
+ type: "boolean",
87
+ default: "false",
88
+ description: "Enables the alpha slider, and therefore 8-digit hex output. Off by default because it widens the value format."
89
+ },
90
+ { name: "swatches", type: "string[]", description: "Optional preset row." },
91
+ {
92
+ name: "label",
93
+ type: "string",
94
+ default: '"Colour"',
95
+ description: "Accessible name for the trigger; the current value is appended to it."
96
+ }
97
+ ],
98
+ a11y: [
99
+ `The trigger's accessible name includes the current value, so a screen reader announces the colour rather than just "button" \u2014 the swatch itself conveys nothing without sight.`,
100
+ "The Transparent entry is a toggle with aria-pressed, because it is a state of the value and not a navigation action.",
101
+ "The hex field is the keyboard path to any colour. The saturation/value area and the sliders are pointer-driven and are NOT keyboard operable \u2014 a known gap, and the reason the hex field is never hidden.",
102
+ "The eyedropper is only rendered where the EyeDropper API exists (Chromium), rather than shown and broken elsewhere."
103
+ ],
104
+ tokensUsed: ["panel", "panel-raised", "hairline", "hairline-strong", "ring", "popover"],
105
+ examples: [
106
+ {
107
+ label: "Canvas background",
108
+ code: `<PropertyRow label="Background">
109
+ <ColorField value={background} onValueChange={setBackground} allowTransparent />
110
+ </PropertyRow>`
111
+ },
112
+ {
113
+ label: "With alpha and a palette",
114
+ code: `<ColorField
115
+ value={tint}
116
+ onValueChange={setTint}
117
+ allowAlpha
118
+ swatches={["#f43f5e", "#facc15", "#22c55e", "#3b82f6", "#a855f7"]}
119
+ label="Tint"
120
+ />`
121
+ },
122
+ {
123
+ label: "The value format is the contract",
124
+ code: `// ColorField only ever EMITS these three shapes:
125
+ // "transparent" | "#rrggbb" | "#rrggbbaa"
126
+ // It accepts #rgb and #rgba on paste but never produces them, so a consumer's
127
+ // parser has three cases to handle rather than five.
128
+ //
129
+ // Alpha is omitted when fully opaque \u2014 "#3b82f6", never "#3b82f6ff" \u2014 so a
130
+ // parser written before alpha support keeps reading opaque colours correctly.
131
+ // Only enable allowAlpha once your parser and your persisted format accept the
132
+ // 8-digit form, or a document saved by a newer build degrades on an older one.
133
+
134
+ import { parseHex, isTransparent } from "@sableui/react"
135
+
136
+ const parsed = isTransparent(value) ? null : parseHex(value) // null = not a colour`
137
+ }
138
+ ]
139
+ };
140
+ export {
141
+ colorFieldMeta
142
+ };
@@ -0,0 +1,69 @@
1
+ // src/components/color-field/color.ts
2
+ var TRANSPARENT = "transparent";
3
+ function isTransparent(value) {
4
+ return value.trim().toLowerCase() === TRANSPARENT;
5
+ }
6
+ var clamp = (n, min, max) => Math.min(max, Math.max(min, n));
7
+ var byte = (n) => clamp(Math.round(n), 0, 255);
8
+ function parseHex(input) {
9
+ const hex = input.trim().replace(/^#/, "").toLowerCase();
10
+ if (!/^[0-9a-f]+$/.test(hex)) return null;
11
+ const expand = (c) => Number.parseInt(c + c, 16);
12
+ if (hex.length === 3 || hex.length === 4) {
13
+ return {
14
+ rgb: { r: expand(hex[0]), g: expand(hex[1]), b: expand(hex[2]) },
15
+ a: hex.length === 4 ? expand(hex[3]) / 255 : 1
16
+ };
17
+ }
18
+ if (hex.length === 6 || hex.length === 8) {
19
+ const pair = (i) => Number.parseInt(hex.slice(i, i + 2), 16);
20
+ return {
21
+ rgb: { r: pair(0), g: pair(2), b: pair(4) },
22
+ a: hex.length === 8 ? pair(6) / 255 : 1
23
+ };
24
+ }
25
+ return null;
26
+ }
27
+ function formatHex(rgb, a = 1) {
28
+ const hex = (n) => byte(n).toString(16).padStart(2, "0");
29
+ const base = `#${hex(rgb.r)}${hex(rgb.g)}${hex(rgb.b)}`;
30
+ const alpha = clamp(a, 0, 1);
31
+ return alpha >= 1 ? base : `${base}${hex(alpha * 255)}`;
32
+ }
33
+ function rgbToHsv({ r, g, b }) {
34
+ const rn = r / 255;
35
+ const gn = g / 255;
36
+ const bn = b / 255;
37
+ const max = Math.max(rn, gn, bn);
38
+ const min = Math.min(rn, gn, bn);
39
+ const d = max - min;
40
+ let h = 0;
41
+ if (d !== 0) {
42
+ if (max === rn) h = (gn - bn) / d % 6;
43
+ else if (max === gn) h = (bn - rn) / d + 2;
44
+ else h = (rn - gn) / d + 4;
45
+ h *= 60;
46
+ if (h < 0) h += 360;
47
+ }
48
+ return { h, s: max === 0 ? 0 : d / max, v: max };
49
+ }
50
+ function hsvToRgb({ h, s, v }) {
51
+ const hn = (h % 360 + 360) % 360;
52
+ const c = v * clamp(s, 0, 1);
53
+ const x = c * (1 - Math.abs(hn / 60 % 2 - 1));
54
+ const m = v - c;
55
+ const [r, g, b] = hn < 60 ? [c, x, 0] : hn < 120 ? [x, c, 0] : hn < 180 ? [0, c, x] : hn < 240 ? [0, x, c] : hn < 300 ? [x, 0, c] : [c, 0, x];
56
+ return { r: byte((r + m) * 255), g: byte((g + m) * 255), b: byte((b + m) * 255) };
57
+ }
58
+ function hueColor(h) {
59
+ return formatHex(hsvToRgb({ h, s: 1, v: 1 }));
60
+ }
61
+ export {
62
+ TRANSPARENT,
63
+ formatHex,
64
+ hsvToRgb,
65
+ hueColor,
66
+ isTransparent,
67
+ parseHex,
68
+ rgbToHsv
69
+ };
@@ -0,0 +1,15 @@
1
+ // src/components/color-field/index.ts
2
+ import { ColorField } from "./color-field.js";
3
+ import { TRANSPARENT, formatHex, hsvToRgb, hueColor, isTransparent, parseHex, rgbToHsv } from "./color.js";
4
+ import { colorFieldMeta } from "./color-field.meta.js";
5
+ export {
6
+ ColorField,
7
+ TRANSPARENT,
8
+ colorFieldMeta,
9
+ formatHex,
10
+ hsvToRgb,
11
+ hueColor,
12
+ isTransparent,
13
+ parseHex,
14
+ rgbToHsv
15
+ };