@sableui/react 0.6.2 → 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 +273 -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 +980 -64
  611. package/llms.txt +26 -9
  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,135 @@
1
+ "use client";
2
+
3
+ // src/components/media-tile/media-tile.tsx
4
+ import { useRender } from "@base-ui/react/use-render";
5
+ import { AspectBox } from "../../layout/AspectBox.js";
6
+ import { cn } from "../../lib/cn.js";
7
+ import { MediaImage } from "../media-image/index.js";
8
+ import {
9
+ mediaTileInsetVariants,
10
+ mediaTileSubtitleVariants,
11
+ mediaTileTitleVariants,
12
+ mediaTileVariants
13
+ } from "./media-tile.variants.js";
14
+ import { jsx, jsxs } from "react/jsx-runtime";
15
+ var ASPECT = { square: 1, video: 16 / 9, poster: 2 / 3 };
16
+ function TileLink({
17
+ href,
18
+ render,
19
+ className,
20
+ children
21
+ }) {
22
+ return useRender({
23
+ render: render ?? /* @__PURE__ */ jsx("a", { href }),
24
+ props: { className, children },
25
+ defaultTagName: "a"
26
+ });
27
+ }
28
+ function MediaTile({
29
+ title,
30
+ subtitle,
31
+ src,
32
+ alt,
33
+ seed,
34
+ aspect = "square",
35
+ size = "md",
36
+ href,
37
+ render,
38
+ subtitleHref,
39
+ subtitleRender,
40
+ action,
41
+ badge,
42
+ titleAs: TitleTag = "p",
43
+ loading,
44
+ className,
45
+ ...props
46
+ }) {
47
+ const linked = href != null || render != null;
48
+ const subtitleLinked = subtitleHref != null || subtitleRender != null;
49
+ const ratio = typeof aspect === "number" ? aspect : ASPECT[aspect];
50
+ const titleText = typeof title === "string" ? title : void 0;
51
+ return /* @__PURE__ */ jsxs(
52
+ "div",
53
+ {
54
+ "data-slot": "media-tile",
55
+ "data-size": size,
56
+ className: cn(
57
+ mediaTileVariants({ size }),
58
+ mediaTileInsetVariants({ size }),
59
+ "[--stretched-link-radius:var(--media-tile-radius)]",
60
+ className
61
+ ),
62
+ ...props,
63
+ children: [
64
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-col gap-0.5", children: [
65
+ /* @__PURE__ */ jsx(TitleTag, { title: titleText, className: mediaTileTitleVariants({ size }), children: linked ? /* @__PURE__ */ jsx(
66
+ TileLink,
67
+ {
68
+ href,
69
+ render,
70
+ className: "stretched-link motion-interactive",
71
+ children: title
72
+ }
73
+ ) : title }),
74
+ subtitle != null ? subtitleLinked ? /* @__PURE__ */ jsx(
75
+ TileLink,
76
+ {
77
+ href: subtitleHref,
78
+ render: subtitleRender,
79
+ className: cn(
80
+ mediaTileSubtitleVariants({ size }),
81
+ // Raised over the stretched overlay, so it is its own target.
82
+ // `self-start` keeps the hit area to the words, not the column.
83
+ "relative z-10 max-w-full self-start rounded-xs motion-interactive hover:text-foreground hover:underline focus-visible:text-foreground focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring"
84
+ ),
85
+ children: subtitle
86
+ }
87
+ ) : /* @__PURE__ */ jsx("p", { className: mediaTileSubtitleVariants({ size }), children: subtitle }) : null
88
+ ] }),
89
+ /* @__PURE__ */ jsxs(
90
+ AspectBox,
91
+ {
92
+ ratio,
93
+ "data-slot": "media-tile-cover",
94
+ className: "order-first rounded-(--media-tile-radius)",
95
+ children: [
96
+ /* @__PURE__ */ jsx(MediaImage, { src, alt, seed: seed ?? titleText, loading }),
97
+ linked || action != null ? (
98
+ // The tile answers the pointer and the keyboard alike: a light scrim
99
+ // deepens the cover so the action reads over any artwork. Hover only
100
+ // where the device can hover — on touch a tap would leave it stuck on.
101
+ /* @__PURE__ */ jsx(
102
+ "span",
103
+ {
104
+ "aria-hidden": true,
105
+ className: "pointer-events-none absolute inset-0 bg-overlay/25 opacity-0 motion-interactive group-focus-within:opacity-100 [@media(hover:hover)]:group-hover:opacity-100"
106
+ }
107
+ )
108
+ ) : null,
109
+ badge != null ? /* @__PURE__ */ jsx(
110
+ "div",
111
+ {
112
+ "data-slot": "media-tile-badge",
113
+ className: "pointer-events-none absolute start-(--media-tile-inset) top-(--media-tile-inset) z-10 flex",
114
+ children: badge
115
+ }
116
+ ) : null,
117
+ action != null ? /* @__PURE__ */ jsx(
118
+ "div",
119
+ {
120
+ "data-slot": "media-tile-action",
121
+ className: "reveal-on-hover absolute end-(--media-tile-inset) bottom-(--media-tile-inset) z-10 flex drop-shadow-md [--reveal-offset:calc(var(--spacing)*1)]",
122
+ children: action
123
+ }
124
+ ) : null
125
+ ]
126
+ }
127
+ )
128
+ ]
129
+ }
130
+ );
131
+ }
132
+ MediaTile.displayName = "MediaTile";
133
+ export {
134
+ MediaTile
135
+ };
@@ -0,0 +1,133 @@
1
+ // src/components/media-tile/media-tile.meta.ts
2
+ var mediaTileMeta = {
3
+ name: "MediaTile",
4
+ summary: "A cover-first tile \u2014 square, 16:9 or poster artwork with an optional play-style action over it, then a title and a subtitle that can each be links \u2014 that is one link as a whole without nesting its other controls inside one.",
5
+ status: "beta",
6
+ keywords: [
7
+ "album",
8
+ "album art",
9
+ "cover",
10
+ "tile",
11
+ "media card",
12
+ "video thumbnail",
13
+ "podcast",
14
+ "playlist",
15
+ "gallery",
16
+ "product tile",
17
+ "poster",
18
+ "grid item",
19
+ "play button",
20
+ "music"
21
+ ],
22
+ usage: {
23
+ description: "The item in a media grid or shelf: an album, a playlist, a video, a podcast, a film, a photo, a product. The cover leads and carries the weight; the title and subtitle sit underneath without a card around them. The whole tile follows the title's link, the subtitle can link somewhere else (the artist, the channel), and an action \u2014 usually play \u2014 floats over the cover's corner, revealed on hover and focus and always shown on touch. A missing or broken cover becomes GradientArt seeded by the title, so a grid of items without artwork still reads as distinct things.",
24
+ bestPractices: [
25
+ {
26
+ guidance: "do",
27
+ description: 'Lay tiles out with `Grid` (`<Grid minItemWidth="10rem">`) or a horizontal `Scroller` for a shelf. The tile fills its cell; the grid decides the width.'
28
+ },
29
+ {
30
+ guidance: "do",
31
+ description: 'Pass `render={<Link to="\u2026" />}` (or `href`) for where the tile goes, and `subtitleRender` / `subtitleHref` for a second destination. Each stays a separate control; never wrap the tile in your own link.'
32
+ },
33
+ {
34
+ guidance: "do",
35
+ description: 'Name the action for its item \u2014 `aria-label="Play Low tide, high noon"`, not "Play". A grid of twenty identical "Play" buttons is unusable from a screen reader\'s list of controls.'
36
+ },
37
+ {
38
+ guidance: "do",
39
+ description: 'Use `titleAs="h3"` when the tiles sit under a section heading, so screen-reader users can move tile to tile by heading.'
40
+ },
41
+ {
42
+ guidance: "dont",
43
+ description: "Do not build this from `Card render={<Link />}`. A card that is a link cannot hold a second link or a button \u2014 interactive content cannot nest \u2014 which is exactly what a media tile needs."
44
+ },
45
+ {
46
+ guidance: "dont",
47
+ description: "Do not put more than one action on the cover. A second control over the art is a toolbar on a thumbnail; move secondary actions (add to queue, share) into an OverflowMenu in the action slot or onto the item's page."
48
+ },
49
+ {
50
+ guidance: "dont",
51
+ description: "Do not use it for a framed commerce card with a price and a buy button \u2014 that is ProductCardBlock \u2014 or for a person, which is an Avatar."
52
+ }
53
+ ],
54
+ anatomy: [
55
+ { name: "Cover", required: true, description: "An AspectBox holding MediaImage: the image, or GradientArt seeded by the title. Drawn first, read last." },
56
+ { name: "Title", required: true, description: "The item's name. When the tile links, this is the link, stretched over the whole tile." },
57
+ { name: "Subtitle", required: false, description: "The second line. Optionally its own link, raised above the stretched one." },
58
+ { name: "Action", required: false, description: "One control over the cover's bottom-end corner \u2014 usually play. Revealed on hover and focus; always visible on touch." },
59
+ { name: "Badge", required: false, description: `A static label over the cover's top-start corner \u2014 a duration, "New". Click-through.` }
60
+ ]
61
+ },
62
+ related: { components: ["MediaImage", "GradientArt", "Grid", "AspectBox", "Card", "Scroller"] },
63
+ props: [
64
+ { name: "title", type: "ReactNode", description: "The item's name. Seeds the fallback art when it is a string." },
65
+ { name: "subtitle", type: "ReactNode", description: "The second line \u2014 an artist, a channel, a year." },
66
+ { name: "src", type: "string", description: "Cover image URL. Without one, or when it fails, the cover is GradientArt seeded by the item." },
67
+ { name: "alt", type: "string", default: '""', description: "Cover alt text. Empty by default: the title below already names the item." },
68
+ { name: "seed", type: "string | number", description: "Seeds the fallback art. Defaults to `title` when it is a string." },
69
+ {
70
+ name: "aspect",
71
+ type: '"square" | "video" | "poster" | number',
72
+ default: '"square"',
73
+ description: "The cover's shape: square (albums, podcasts), video (16:9), poster (2:3 \u2014 films, books), or any width / height ratio."
74
+ },
75
+ { name: "size", type: '"sm" | "md" | "lg"', default: '"md"', description: "Moves the type tier, the cover-to-text gap, the corner and the overlay inset together." },
76
+ { name: "href", type: "string", description: "Where the tile goes. The title becomes the link, stretched over the whole tile." },
77
+ { name: "render", type: "useRender.RenderProp", description: 'The title link\'s element, for a router: `render={<Link to="/albums/1" />}`. Takes precedence over `href`.' },
78
+ { name: "subtitleHref", type: "string", description: "Makes the subtitle its own link \u2014 a separate tab stop above the tile's." },
79
+ { name: "subtitleRender", type: "useRender.RenderProp", description: "The subtitle link's element, for a router." },
80
+ { name: "action", type: "ReactNode", description: "One control over the cover's bottom-end corner, usually a play Button. Hidden until hover or focus on hover-capable devices; always shown on touch." },
81
+ { name: "badge", type: "ReactNode", description: 'A static label on the cover\'s top-start corner \u2014 `<Badge appearance="overlay">`.' },
82
+ { name: "titleAs", type: '"h2" | "h3" | "h4" | "h5" | "p"', default: '"p"', description: "The title's element. A heading one level below the section's lets screen-reader users move tile to tile." },
83
+ { name: "loading", type: '"lazy" | "eager"', default: '"lazy"', description: "Native image loading. `eager` for the first row above the fold." },
84
+ { name: "...div props", type: 'Omit<ComponentPropsWithRef<"div">, "title">', description: "Spread onto the root." }
85
+ ],
86
+ variants: { size: ["sm", "md", "lg"], aspect: ["square", "video", "poster"] },
87
+ tokensUsed: ["foreground", "muted-foreground", "muted", "overlay", "ring"],
88
+ motion: [
89
+ {
90
+ slot: "arrival",
91
+ recipe: "motion-fade",
92
+ part: "Cover",
93
+ why: "The cover image fades in over a quiet surface once it decodes, so a grid loading on a slow connection settles tile by tile instead of popping."
94
+ },
95
+ {
96
+ slot: "response",
97
+ recipe: "motion-interactive",
98
+ part: "Cover",
99
+ why: "Hovering the tile deepens the cover with a light scrim and lifts the action in (`reveal-on-hover`), so it is clear the whole tile is one target and where its action is."
100
+ },
101
+ { slot: "transition", recipe: "none", part: "root", why: "A tile has no states of its own to move between; the action carries any (play / pause)." },
102
+ { slot: "activity", recipe: "none", part: "root", why: "Nothing runs inside a tile; a now-playing indicator belongs to the player, not the grid." }
103
+ ],
104
+ a11y: [
105
+ "No nested interactive content: the title is the tile's link, and its `stretched-link` overlay covers the tile, while the subtitle link and the action sit above it as separate controls.",
106
+ "Tab order is title \u2192 subtitle \u2192 action. The text comes first in the DOM and the cover is drawn above it with CSS `order`, so focus follows how a reader names the item.",
107
+ "Focusing the title link rings the whole tile, rounded like the cover, because the whole tile is what the link is; the subtitle link and the action ring themselves.",
108
+ "The action is hidden with opacity only, and only where the device can hover; it stays in the tab order and the accessibility tree, appears when anything in the tile has focus, and is always visible on touch.",
109
+ 'The cover is decorative by default (`alt=""`), since the title names the item; the fallback art is aria-hidden.',
110
+ "Truncated titles keep their full text in the link's accessible name and in a `title` tooltip."
111
+ ],
112
+ examples: [
113
+ {
114
+ label: "Album grid",
115
+ code: '<Grid minItemWidth="10rem" gap={3}>\n {albums.map((album) => (\n <MediaTile\n key={album.id}\n title={album.title}\n subtitle={album.artist}\n src={album.cover}\n render={<Link to={`/albums/${album.id}`} />}\n subtitleRender={<Link to={`/artists/${album.artistId}`} />}\n action={\n <Button size="icon" aria-label={`Play ${album.title}`} onClick={() => play(album)}>\n <Icon name="play" variant="solid" />\n </Button>\n }\n />\n ))}\n</Grid>'
116
+ },
117
+ {
118
+ label: "Video tile with a duration",
119
+ code: '<MediaTile\n aspect="video"\n title="Building a synth from scratch"\n subtitle="Undertow Sessions \xB7 2 days ago"\n src={video.thumbnail}\n href={`/watch/${video.id}`}\n badge={<Badge appearance="overlay">12:04</Badge>}\n/>'
120
+ },
121
+ {
122
+ label: "Gallery, no links",
123
+ code: '<Grid minItemWidth="8rem" gap={2}>\n {photos.map((photo) => (\n <MediaTile key={photo.id} size="sm" title={photo.caption} src={photo.url} alt={photo.description} />\n ))}\n</Grid>'
124
+ },
125
+ {
126
+ label: "Poster shelf",
127
+ code: '<MediaTile aspect="poster" size="lg" titleAs="h3" title="The Long Dark" subtitle="2026 \xB7 Drama" href="/films/the-long-dark" />'
128
+ }
129
+ ]
130
+ };
131
+ export {
132
+ mediaTileMeta
133
+ };
@@ -0,0 +1,48 @@
1
+ // src/components/media-tile/media-tile.variants.ts
2
+ import { cva } from "class-variance-authority";
3
+ var mediaTileVariants = cva("group relative isolate flex min-w-0 flex-col", {
4
+ variants: {
5
+ size: {
6
+ sm: "gap-2 [--media-tile-radius:var(--radius-sm)]",
7
+ md: "gap-3 [--media-tile-radius:var(--radius-md)]",
8
+ lg: "gap-3 [--media-tile-radius:var(--radius-lg)]"
9
+ }
10
+ },
11
+ defaultVariants: { size: "md" }
12
+ });
13
+ var mediaTileInsetVariants = cva("", {
14
+ variants: {
15
+ size: {
16
+ sm: "[--media-tile-inset:calc(var(--spacing)*1.5)]",
17
+ md: "[--media-tile-inset:calc(var(--spacing)*2)]",
18
+ lg: "[--media-tile-inset:calc(var(--spacing)*3)]"
19
+ }
20
+ },
21
+ defaultVariants: { size: "md" }
22
+ });
23
+ var mediaTileTitleVariants = cva("min-w-0 truncate text-foreground", {
24
+ variants: {
25
+ size: {
26
+ sm: "text-label-md",
27
+ md: "text-label-lg",
28
+ lg: "text-title-lg"
29
+ }
30
+ },
31
+ defaultVariants: { size: "md" }
32
+ });
33
+ var mediaTileSubtitleVariants = cva("min-w-0 truncate text-muted-foreground", {
34
+ variants: {
35
+ size: {
36
+ sm: "text-caption",
37
+ md: "text-body-sm",
38
+ lg: "text-body-md"
39
+ }
40
+ },
41
+ defaultVariants: { size: "md" }
42
+ });
43
+ export {
44
+ mediaTileInsetVariants,
45
+ mediaTileSubtitleVariants,
46
+ mediaTileTitleVariants,
47
+ mediaTileVariants
48
+ };
@@ -0,0 +1,33 @@
1
+ // src/components/menu/index.ts
2
+ import {
3
+ Menu,
4
+ MenuTrigger,
5
+ MenuPortal,
6
+ MenuContent,
7
+ MenuItem,
8
+ MenuSeparator,
9
+ MenuGroup,
10
+ MenuGroupLabel,
11
+ MenuSubmenu,
12
+ MenuSubmenuTrigger,
13
+ MenuRadioGroup,
14
+ MenuRadioItem,
15
+ MenuCheckboxItem
16
+ } from "./menu.js";
17
+ import { menuMeta } from "./menu.meta.js";
18
+ export {
19
+ Menu,
20
+ MenuCheckboxItem,
21
+ MenuContent,
22
+ MenuGroup,
23
+ MenuGroupLabel,
24
+ MenuItem,
25
+ MenuPortal,
26
+ MenuRadioGroup,
27
+ MenuRadioItem,
28
+ MenuSeparator,
29
+ MenuSubmenu,
30
+ MenuSubmenuTrigger,
31
+ MenuTrigger,
32
+ menuMeta
33
+ };
@@ -0,0 +1,168 @@
1
+ // src/components/menu/menu.tsx
2
+ import { Menu as Base } from "@base-ui/react/menu";
3
+ import { Icon } from "../../icon/index.js";
4
+ import { anchoredScroll } from "../../lib/anchored-scroll.js";
5
+ import { cn } from "../../lib/cn.js";
6
+ import { withPortalThemeScope } from "../../lib/portal-theme-scope.js";
7
+ import { useAnchoredDensity, useTypeTier } from "../../lib/density.js";
8
+ import { HighlightGlide } from "../../lib/highlight-glide.js";
9
+ import { jsx, jsxs } from "react/jsx-runtime";
10
+ var Menu = Base.Root;
11
+ var MenuTrigger = Base.Trigger;
12
+ var MenuPortal = withPortalThemeScope(Base.Portal);
13
+ function MenuContent({
14
+ className,
15
+ children,
16
+ side = "bottom",
17
+ align = "start",
18
+ sideOffset = 6,
19
+ ...props
20
+ }) {
21
+ const anchoredDensity = useAnchoredDensity();
22
+ return /* @__PURE__ */ jsx(MenuPortal, { children: /* @__PURE__ */ jsx(Base.Positioner, { side, align, sideOffset, className: "z-(--z-overlay)", children: /* @__PURE__ */ jsxs(
23
+ Base.Popup,
24
+ {
25
+ ...anchoredDensity,
26
+ className: cn(
27
+ "min-w-40 rounded-md border border-border-floating bg-popover popup-inset text-popover-foreground shadow-md outline-none",
28
+ // A menu taller than the room under its trigger scrolls inside
29
+ // itself instead of running off the screen. Rationale for the cap,
30
+ // the thin scrollbar and the overscroll containment: lib/anchored-scroll.
31
+ anchoredScroll,
32
+ "motion-pop",
33
+ className
34
+ ),
35
+ ...props,
36
+ children: [
37
+ /* @__PURE__ */ jsx(HighlightGlide, {}),
38
+ children
39
+ ]
40
+ }
41
+ ) }) });
42
+ }
43
+ var MENU_ITEM_DESTRUCTIVE = (
44
+ // The ink is pulled a quarter toward --foreground (as Badge's soft tones
45
+ // are), from --destructive-text rather than the fill: dark fills sit low
46
+ // enough for a white label, and ink mixed from them measured 3.8:1 on
47
+ // Meridian's popover. From the text token every theme clears 4.5:1 (worst
48
+ // 5.4:1, Prism dark, on the 10% red wash).
49
+ "text-[color-mix(in_oklch,var(--destructive-text)_75%,var(--foreground))] data-[highlighted]:bg-destructive/10 data-[highlighted]:text-[color-mix(in_oklch,var(--destructive-text)_75%,var(--foreground))]"
50
+ );
51
+ function MenuItem({ className, variant = "default", ...props }) {
52
+ const tier = useTypeTier();
53
+ return /* @__PURE__ */ jsx(
54
+ Base.Item,
55
+ {
56
+ className: cn(
57
+ `flex cursor-default select-none items-center gap-(--item-gap) rounded-popup-item px-(--item-px) py-1.5 ${tier.body} outline-none motion-interactive data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:shrink-0`,
58
+ variant === "destructive" && MENU_ITEM_DESTRUCTIVE,
59
+ className
60
+ ),
61
+ ...props
62
+ }
63
+ );
64
+ }
65
+ function MenuSeparator({ className, ...props }) {
66
+ return /* @__PURE__ */ jsx(
67
+ Base.Separator,
68
+ {
69
+ className: cn("popup-bleed my-1 h-px bg-border", className),
70
+ ...props
71
+ }
72
+ );
73
+ }
74
+ function MenuGroup({ className, ...props }) {
75
+ return /* @__PURE__ */ jsx(Base.Group, { className: cn(className), ...props });
76
+ }
77
+ function MenuGroupLabel({ className, ...props }) {
78
+ const tier = useTypeTier();
79
+ return /* @__PURE__ */ jsx(
80
+ Base.GroupLabel,
81
+ {
82
+ className: cn(
83
+ `select-none px-(--item-px) py-1.5 ${tier.label} text-muted-foreground`,
84
+ className
85
+ ),
86
+ ...props
87
+ }
88
+ );
89
+ }
90
+ var MenuSubmenu = Base.SubmenuRoot;
91
+ function MenuSubmenuTrigger({
92
+ className,
93
+ children,
94
+ value,
95
+ ...props
96
+ }) {
97
+ const tier = useTypeTier();
98
+ return /* @__PURE__ */ jsxs(
99
+ Base.SubmenuTrigger,
100
+ {
101
+ className: cn(
102
+ `flex cursor-default select-none items-center gap-(--item-gap) rounded-popup-item px-(--item-px) py-1.5 ${tier.body} outline-none motion-interactive data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[popup-open]:bg-accent data-[popup-open]:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:shrink-0`,
103
+ className
104
+ ),
105
+ ...props,
106
+ children: [
107
+ /* @__PURE__ */ jsx("span", { className: "flex-1 truncate text-start", children }),
108
+ value !== void 0 ? /* @__PURE__ */ jsx("span", { className: "truncate text-muted-foreground", children: value }) : null,
109
+ /* @__PURE__ */ jsx(Icon, { name: "chevron-right", className: "text-xs opacity-60" })
110
+ ]
111
+ }
112
+ );
113
+ }
114
+ var MenuRadioGroup = Base.RadioGroup;
115
+ function MenuRadioItem({ className, children, ...props }) {
116
+ const tier = useTypeTier();
117
+ return /* @__PURE__ */ jsxs(
118
+ Base.RadioItem,
119
+ {
120
+ className: cn(
121
+ `flex cursor-default select-none items-center gap-(--item-gap) rounded-popup-item px-(--item-px) py-1.5 ${tier.body} outline-none motion-interactive data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50`,
122
+ className
123
+ ),
124
+ ...props,
125
+ children: [
126
+ /* @__PURE__ */ jsx("span", { className: "flex size-4 shrink-0 items-center justify-center", children: /* @__PURE__ */ jsx(Base.RadioItemIndicator, { children: /* @__PURE__ */ jsx(Icon, { name: "check", className: "text-xs" }) }) }),
127
+ /* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children })
128
+ ]
129
+ }
130
+ );
131
+ }
132
+ function MenuCheckboxItem({
133
+ className,
134
+ children,
135
+ ...props
136
+ }) {
137
+ const tier = useTypeTier();
138
+ return /* @__PURE__ */ jsxs(
139
+ Base.CheckboxItem,
140
+ {
141
+ className: cn(
142
+ `flex cursor-default select-none items-center gap-(--item-gap) rounded-popup-item px-(--item-px) py-1.5 ${tier.body} outline-none motion-interactive data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50`,
143
+ className
144
+ ),
145
+ ...props,
146
+ children: [
147
+ /* @__PURE__ */ jsx("span", { className: "flex size-4 shrink-0 items-center justify-center", children: /* @__PURE__ */ jsx(Base.CheckboxItemIndicator, { children: /* @__PURE__ */ jsx(Icon, { name: "check", className: "text-xs" }) }) }),
148
+ /* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children })
149
+ ]
150
+ }
151
+ );
152
+ }
153
+ export {
154
+ MENU_ITEM_DESTRUCTIVE,
155
+ Menu,
156
+ MenuCheckboxItem,
157
+ MenuContent,
158
+ MenuGroup,
159
+ MenuGroupLabel,
160
+ MenuItem,
161
+ MenuPortal,
162
+ MenuRadioGroup,
163
+ MenuRadioItem,
164
+ MenuSeparator,
165
+ MenuSubmenu,
166
+ MenuSubmenuTrigger,
167
+ MenuTrigger
168
+ };