@vielzeug/refine 26.10.0 → 26.10.5

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 (468) hide show
  1. package/README.md +1 -1
  2. package/dist/accordion-item.cjs.map +1 -1
  3. package/dist/accordion-item.js.map +1 -1
  4. package/dist/accordion.cjs.map +1 -1
  5. package/dist/accordion.js.map +1 -1
  6. package/dist/async.cjs.map +1 -1
  7. package/dist/async.js.map +1 -1
  8. package/dist/badge.cjs.map +1 -1
  9. package/dist/badge.js.map +1 -1
  10. package/dist/box.cjs.map +1 -1
  11. package/dist/box.js.map +1 -1
  12. package/dist/button.cjs +3 -3
  13. package/dist/button.cjs.map +1 -1
  14. package/dist/button.js +3 -3
  15. package/dist/button.js.map +1 -1
  16. package/dist/calendar.cjs.map +1 -1
  17. package/dist/calendar.js.map +1 -1
  18. package/dist/carousel.cjs.map +1 -1
  19. package/dist/carousel.js.map +1 -1
  20. package/dist/chat-message.cjs.map +1 -1
  21. package/dist/chat-message.js.map +1 -1
  22. package/dist/chat-panel.cjs.map +1 -1
  23. package/dist/chat-panel.js.map +1 -1
  24. package/dist/checkbox-group.cjs.map +1 -1
  25. package/dist/checkbox-group.js.map +1 -1
  26. package/dist/chip.cjs.map +1 -1
  27. package/dist/chip.js.map +1 -1
  28. package/dist/code-window.cjs.map +1 -1
  29. package/dist/code-window.js.map +1 -1
  30. package/dist/combobox.cjs.map +1 -1
  31. package/dist/combobox.js.map +1 -1
  32. package/dist/command-palette.cjs +9 -1
  33. package/dist/command-palette.cjs.map +1 -1
  34. package/dist/command-palette.js +9 -1
  35. package/dist/command-palette.js.map +1 -1
  36. package/dist/content/card/card.css.cjs.map +1 -1
  37. package/dist/content/card/card.css.js.map +1 -1
  38. package/dist/content/carousel/carousel-slide.css.cjs.map +1 -1
  39. package/dist/content/carousel/carousel-slide.css.js.map +1 -1
  40. package/dist/content/carousel/carousel.css.cjs.map +1 -1
  41. package/dist/content/carousel/carousel.css.js.map +1 -1
  42. package/dist/content/carousel/carousel.d.ts +5 -5
  43. package/dist/content/chat-message/chat-message.css.cjs +1 -1
  44. package/dist/content/chat-message/chat-message.css.cjs.map +1 -1
  45. package/dist/content/chat-message/chat-message.css.js +1 -1
  46. package/dist/content/chat-message/chat-message.css.js.map +1 -1
  47. package/dist/content/chat-message/chat-message.d.ts +4 -4
  48. package/dist/content/chat-message/chat-message.d.ts.map +1 -1
  49. package/dist/content/chat-panel/chat-panel.d.ts +1 -1
  50. package/dist/content/code-window/code-window.css.cjs.map +1 -1
  51. package/dist/content/code-window/code-window.css.js.map +1 -1
  52. package/dist/content/code-window/code-window.d.ts +4 -4
  53. package/dist/content/index.d.ts +4 -0
  54. package/dist/content/index.d.ts.map +1 -1
  55. package/dist/content/list/_list-item-reveal.cjs.map +1 -1
  56. package/dist/content/list/_list-item-reveal.d.ts +4 -4
  57. package/dist/content/list/_list-item-reveal.d.ts.map +1 -1
  58. package/dist/content/list/_list-item-reveal.js.map +1 -1
  59. package/dist/content/list/list-item.css.cjs.map +1 -1
  60. package/dist/content/list/list-item.css.js.map +1 -1
  61. package/dist/content/list/list-item.d.ts +8 -8
  62. package/dist/content/list/list-item.d.ts.map +1 -1
  63. package/dist/content/list/list.d.ts +8 -8
  64. package/dist/content/list/list.d.ts.map +1 -1
  65. package/dist/content/qr-code/qr-code.d.ts +1 -1
  66. package/dist/content/rank-list/rank-item.css.cjs +2 -0
  67. package/dist/content/rank-list/rank-item.css.cjs.map +1 -0
  68. package/dist/content/rank-list/rank-item.css.js +2 -0
  69. package/dist/content/rank-list/rank-item.css.js.map +1 -0
  70. package/dist/content/rank-list/rank-item.d.ts +68 -0
  71. package/dist/content/rank-list/rank-item.d.ts.map +1 -0
  72. package/dist/content/rank-list/rank-list.css.cjs +2 -0
  73. package/dist/content/rank-list/rank-list.css.cjs.map +1 -0
  74. package/dist/content/rank-list/rank-list.css.js +2 -0
  75. package/dist/content/rank-list/rank-list.css.js.map +1 -0
  76. package/dist/content/rank-list/rank-list.d.ts +44 -0
  77. package/dist/content/rank-list/rank-list.d.ts.map +1 -0
  78. package/dist/content/separator/separator.d.ts +1 -1
  79. package/dist/content/separator/separator.d.ts.map +1 -1
  80. package/dist/content/speech-player/speech-player.css.cjs.map +1 -1
  81. package/dist/content/speech-player/speech-player.css.js.map +1 -1
  82. package/dist/content/speech-player/speech-player.d.ts +12 -12
  83. package/dist/content/speech-player/speech-player.d.ts.map +1 -1
  84. package/dist/content/stepper/step.css.cjs.map +1 -1
  85. package/dist/content/stepper/step.css.js.map +1 -1
  86. package/dist/content/stepper/step.d.ts +3 -3
  87. package/dist/content/stepper/step.d.ts.map +1 -1
  88. package/dist/content/stepper/stepper.css.cjs.map +1 -1
  89. package/dist/content/stepper/stepper.css.js.map +1 -1
  90. package/dist/content/stepper/stepper.d.ts +3 -3
  91. package/dist/content/stepper/stepper.d.ts.map +1 -1
  92. package/dist/content/table/table.css.cjs.map +1 -1
  93. package/dist/content/table/table.css.js.map +1 -1
  94. package/dist/content/table/table.d.ts +3 -3
  95. package/dist/content/table/table.d.ts.map +1 -1
  96. package/dist/content/text/text.css.cjs.map +1 -1
  97. package/dist/content/text/text.css.js.map +1 -1
  98. package/dist/content/text/text.d.ts +2 -2
  99. package/dist/content/text/text.d.ts.map +1 -1
  100. package/dist/cookie-banner.cjs.map +1 -1
  101. package/dist/cookie-banner.js.map +1 -1
  102. package/dist/copy-command.cjs +1 -1
  103. package/dist/copy-command.cjs.map +1 -1
  104. package/dist/copy-command.js +1 -1
  105. package/dist/copy-command.js.map +1 -1
  106. package/dist/core/announcer.cjs.map +1 -1
  107. package/dist/core/announcer.d.ts +2 -2
  108. package/dist/core/announcer.js.map +1 -1
  109. package/dist/core/aria-reflection.cjs.map +1 -1
  110. package/dist/core/aria-reflection.d.ts +3 -3
  111. package/dist/core/aria-reflection.js.map +1 -1
  112. package/dist/core/auto-resize.cjs.map +1 -1
  113. package/dist/core/auto-resize.d.ts +1 -1
  114. package/dist/core/auto-resize.js.map +1 -1
  115. package/dist/core/checkable.cjs.map +1 -1
  116. package/dist/core/checkable.d.ts +2 -2
  117. package/dist/core/checkable.d.ts.map +1 -1
  118. package/dist/core/checkable.js.map +1 -1
  119. package/dist/core/choice-field.cjs.map +1 -1
  120. package/dist/core/choice-field.d.ts +3 -3
  121. package/dist/core/choice-field.d.ts.map +1 -1
  122. package/dist/core/choice-field.js.map +1 -1
  123. package/dist/core/composer.cjs.map +1 -1
  124. package/dist/core/composer.d.ts +4 -4
  125. package/dist/core/composer.d.ts.map +1 -1
  126. package/dist/core/composer.js.map +1 -1
  127. package/dist/core/date-picker.cjs.map +1 -1
  128. package/dist/core/date-picker.d.ts +5 -5
  129. package/dist/core/date-picker.d.ts.map +1 -1
  130. package/dist/core/date-picker.js.map +1 -1
  131. package/dist/core/direction.cjs.map +1 -1
  132. package/dist/core/direction.d.ts +1 -1
  133. package/dist/core/direction.js.map +1 -1
  134. package/dist/core/field-base.cjs.map +1 -1
  135. package/dist/core/field-base.d.ts +9 -9
  136. package/dist/core/field-base.d.ts.map +1 -1
  137. package/dist/core/field-base.js.map +1 -1
  138. package/dist/core/focus.cjs.map +1 -1
  139. package/dist/core/focus.d.ts +1 -1
  140. package/dist/core/focus.js.map +1 -1
  141. package/dist/core/icon-registry.cjs.map +1 -1
  142. package/dist/core/icon-registry.d.ts +1 -1
  143. package/dist/core/icon-registry.js.map +1 -1
  144. package/dist/core/icons.cjs.map +1 -1
  145. package/dist/core/icons.js.map +1 -1
  146. package/dist/core/keyboard.cjs.map +1 -1
  147. package/dist/core/keyboard.d.ts +1 -1
  148. package/dist/core/keyboard.js.map +1 -1
  149. package/dist/core/numbers.cjs.map +1 -1
  150. package/dist/core/numbers.d.ts +1 -1
  151. package/dist/core/numbers.js.map +1 -1
  152. package/dist/core/overlay.cjs.map +1 -1
  153. package/dist/core/overlay.d.ts +6 -6
  154. package/dist/core/overlay.js.map +1 -1
  155. package/dist/core/parse.cjs.map +1 -1
  156. package/dist/core/parse.d.ts +1 -1
  157. package/dist/core/parse.js.map +1 -1
  158. package/dist/core/positioner.cjs.map +1 -1
  159. package/dist/core/positioner.d.ts +3 -3
  160. package/dist/core/positioner.js.map +1 -1
  161. package/dist/core/ref-callback.cjs.map +1 -1
  162. package/dist/core/ref-callback.d.ts +2 -2
  163. package/dist/core/ref-callback.d.ts.map +1 -1
  164. package/dist/core/ref-callback.js.map +1 -1
  165. package/dist/core/text-field.cjs.map +1 -1
  166. package/dist/core/text-field.d.ts +6 -6
  167. package/dist/core/text-field.d.ts.map +1 -1
  168. package/dist/core/text-field.js.map +1 -1
  169. package/dist/counter.cjs +1 -0
  170. package/dist/counter.cjs.map +1 -1
  171. package/dist/counter.js +1 -0
  172. package/dist/counter.js.map +1 -1
  173. package/dist/custom-elements.json +334 -87
  174. package/dist/datagrid.cjs.map +1 -1
  175. package/dist/datagrid.js.map +1 -1
  176. package/dist/date-picker.cjs +1 -1
  177. package/dist/date-picker.cjs.map +1 -1
  178. package/dist/date-picker.js +1 -1
  179. package/dist/date-picker.js.map +1 -1
  180. package/dist/dialog.cjs.map +1 -1
  181. package/dist/dialog.js.map +1 -1
  182. package/dist/disclosure/accordion-item/accordion-item.css.cjs +1 -1
  183. package/dist/disclosure/accordion-item/accordion-item.css.cjs.map +1 -1
  184. package/dist/disclosure/accordion-item/accordion-item.css.js +1 -1
  185. package/dist/disclosure/accordion-item/accordion-item.css.js.map +1 -1
  186. package/dist/disclosure/tab-item/tab-item.d.ts +1 -1
  187. package/dist/disclosure/tab-item/tab-item.d.ts.map +1 -1
  188. package/dist/drawer.cjs.map +1 -1
  189. package/dist/drawer.js.map +1 -1
  190. package/dist/feedback/alert/alert.css.cjs.map +1 -1
  191. package/dist/feedback/alert/alert.css.js.map +1 -1
  192. package/dist/feedback/badge/badge.css.cjs.map +1 -1
  193. package/dist/feedback/badge/badge.css.js.map +1 -1
  194. package/dist/feedback/badge/badge.d.ts +1 -1
  195. package/dist/feedback/badge/badge.d.ts.map +1 -1
  196. package/dist/feedback/chip/chip.css.cjs.map +1 -1
  197. package/dist/feedback/chip/chip.css.js.map +1 -1
  198. package/dist/feedback/chip/chip.d.ts +3 -3
  199. package/dist/feedback/chip/chip.d.ts.map +1 -1
  200. package/dist/feedback/cookie-banner/cookie-banner.css.cjs.map +1 -1
  201. package/dist/feedback/cookie-banner/cookie-banner.css.js.map +1 -1
  202. package/dist/feedback/cookie-banner/cookie-banner.d.ts +8 -8
  203. package/dist/feedback/cookie-banner/cookie-banner.d.ts.map +1 -1
  204. package/dist/feedback/progress/progress.css.cjs.map +1 -1
  205. package/dist/feedback/progress/progress.css.js.map +1 -1
  206. package/dist/feedback/progress/progress.d.ts +1 -1
  207. package/dist/feedback/progress/progress.d.ts.map +1 -1
  208. package/dist/feedback/skeleton/skeleton.css.cjs.map +1 -1
  209. package/dist/feedback/skeleton/skeleton.css.js.map +1 -1
  210. package/dist/feedback/skeleton/skeleton.d.ts +1 -1
  211. package/dist/feedback/skeleton/skeleton.d.ts.map +1 -1
  212. package/dist/feedback/toast/toast.css.cjs +1 -1
  213. package/dist/feedback/toast/toast.css.cjs.map +1 -1
  214. package/dist/feedback/toast/toast.css.js +1 -1
  215. package/dist/feedback/toast/toast.css.js.map +1 -1
  216. package/dist/feedback/toast/toast.d.ts +1 -1
  217. package/dist/feedback/toast/toast.d.ts.map +1 -1
  218. package/dist/feedback/typing-indicator/typing-indicator.d.ts +2 -2
  219. package/dist/file-input.cjs +1 -1
  220. package/dist/file-input.cjs.map +1 -1
  221. package/dist/file-input.js +1 -1
  222. package/dist/file-input.js.map +1 -1
  223. package/dist/frameworks/elements.d.ts +1 -1
  224. package/dist/grid-item.cjs.map +1 -1
  225. package/dist/grid-item.js.map +1 -1
  226. package/dist/grid.cjs.map +1 -1
  227. package/dist/grid.js.map +1 -1
  228. package/dist/icon.cjs.map +1 -1
  229. package/dist/icon.js.map +1 -1
  230. package/dist/input.cjs.map +1 -1
  231. package/dist/input.js.map +1 -1
  232. package/dist/inputs/button/button.css.cjs.map +1 -1
  233. package/dist/inputs/button/button.css.js.map +1 -1
  234. package/dist/inputs/button/button.d.ts +3 -3
  235. package/dist/inputs/button/button.d.ts.map +1 -1
  236. package/dist/inputs/calendar/calendar.css.cjs.map +1 -1
  237. package/dist/inputs/calendar/calendar.css.js.map +1 -1
  238. package/dist/inputs/calendar/calendar.d.ts +2 -2
  239. package/dist/inputs/checkbox-group/checkbox-group.d.ts +2 -2
  240. package/dist/inputs/checkbox-group/checkbox-group.d.ts.map +1 -1
  241. package/dist/inputs/combobox/combobox.css.cjs.map +1 -1
  242. package/dist/inputs/combobox/combobox.css.js.map +1 -1
  243. package/dist/inputs/counter/counter.css.cjs +1 -1
  244. package/dist/inputs/counter/counter.css.cjs.map +1 -1
  245. package/dist/inputs/counter/counter.css.js +1 -1
  246. package/dist/inputs/counter/counter.css.js.map +1 -1
  247. package/dist/inputs/counter/counter.d.ts +2 -1
  248. package/dist/inputs/counter/counter.d.ts.map +1 -1
  249. package/dist/inputs/datagrid/datagrid.css.cjs.map +1 -1
  250. package/dist/inputs/datagrid/datagrid.css.js.map +1 -1
  251. package/dist/inputs/datagrid/datagrid.d.ts +5 -5
  252. package/dist/inputs/date-picker/date-picker.css.cjs.map +1 -1
  253. package/dist/inputs/date-picker/date-picker.css.js.map +1 -1
  254. package/dist/inputs/date-picker/date-picker.d.ts +1 -1
  255. package/dist/inputs/file-input/file-input-upload.cjs.map +1 -1
  256. package/dist/inputs/file-input/file-input-upload.d.ts +6 -6
  257. package/dist/inputs/file-input/file-input-upload.js.map +1 -1
  258. package/dist/inputs/file-input/file-input.css.cjs.map +1 -1
  259. package/dist/inputs/file-input/file-input.css.js.map +1 -1
  260. package/dist/inputs/file-input/file-input.d.ts +6 -6
  261. package/dist/inputs/input/input.css.cjs +1 -1
  262. package/dist/inputs/input/input.css.cjs.map +1 -1
  263. package/dist/inputs/input/input.css.js +1 -1
  264. package/dist/inputs/input/input.css.js.map +1 -1
  265. package/dist/inputs/input/input.d.ts +6 -6
  266. package/dist/inputs/input/input.d.ts.map +1 -1
  267. package/dist/inputs/message-composer/message-composer.css.cjs.map +1 -1
  268. package/dist/inputs/message-composer/message-composer.css.js.map +1 -1
  269. package/dist/inputs/message-composer/message-composer.d.ts +7 -7
  270. package/dist/inputs/message-composer/message-composer.d.ts.map +1 -1
  271. package/dist/inputs/number-input/number-input.css.cjs.map +1 -1
  272. package/dist/inputs/number-input/number-input.css.js.map +1 -1
  273. package/dist/inputs/number-input/number-input.d.ts +2 -2
  274. package/dist/inputs/otp-input/otp-input.css.cjs.map +1 -1
  275. package/dist/inputs/otp-input/otp-input.css.js.map +1 -1
  276. package/dist/inputs/qr-scanner/qr-scanner.d.ts +1 -1
  277. package/dist/inputs/qr-scanner/qr-scanner.d.ts.map +1 -1
  278. package/dist/inputs/rating/rating.d.ts +1 -1
  279. package/dist/inputs/rating/rating.d.ts.map +1 -1
  280. package/dist/inputs/select/select.css.cjs +1 -1
  281. package/dist/inputs/select/select.css.cjs.map +1 -1
  282. package/dist/inputs/select/select.css.js +1 -1
  283. package/dist/inputs/select/select.css.js.map +1 -1
  284. package/dist/inputs/select/select.d.ts +1 -1
  285. package/dist/inputs/select/select.d.ts.map +1 -1
  286. package/dist/inputs/shared/field-binding.cjs.map +1 -1
  287. package/dist/inputs/shared/field-binding.d.ts +2 -2
  288. package/dist/inputs/shared/field-binding.d.ts.map +1 -1
  289. package/dist/inputs/shared/field-binding.js.map +1 -1
  290. package/dist/inputs/shared/native-field-event.cjs.map +1 -1
  291. package/dist/inputs/shared/native-field-event.d.ts +1 -1
  292. package/dist/inputs/shared/native-field-event.js.map +1 -1
  293. package/dist/inputs/shared/templates.cjs.map +1 -1
  294. package/dist/inputs/shared/templates.d.ts +3 -3
  295. package/dist/inputs/shared/templates.js.map +1 -1
  296. package/dist/inputs/slider/slider.css.cjs.map +1 -1
  297. package/dist/inputs/slider/slider.css.js.map +1 -1
  298. package/dist/inputs/slider/slider.d.ts +1 -1
  299. package/dist/inputs/slider/slider.d.ts.map +1 -1
  300. package/dist/inputs/textarea/textarea.css.cjs.map +1 -1
  301. package/dist/inputs/textarea/textarea.css.js.map +1 -1
  302. package/dist/inputs/textarea/textarea.d.ts +1 -1
  303. package/dist/inputs/time-picker/time-picker.css.cjs.map +1 -1
  304. package/dist/inputs/time-picker/time-picker.css.js.map +1 -1
  305. package/dist/inputs/time-picker/time-picker.d.ts +1 -1
  306. package/dist/layout/box/box.css.cjs.map +1 -1
  307. package/dist/layout/box/box.css.js.map +1 -1
  308. package/dist/layout/box/box.d.ts +1 -1
  309. package/dist/layout/grid/grid.d.ts +1 -1
  310. package/dist/layout/grid-item/grid-item.d.ts +3 -3
  311. package/dist/layout/grid-item/grid-item.d.ts.map +1 -1
  312. package/dist/layout/navbar/navbar.css.cjs +1 -1
  313. package/dist/layout/navbar/navbar.css.cjs.map +1 -1
  314. package/dist/layout/navbar/navbar.css.js +1 -1
  315. package/dist/layout/navbar/navbar.css.js.map +1 -1
  316. package/dist/layout/navbar/navbar.d.ts +3 -3
  317. package/dist/layout/sidebar/sidebar-item.css.cjs.map +1 -1
  318. package/dist/layout/sidebar/sidebar-item.css.js.map +1 -1
  319. package/dist/layout/sidebar/sidebar.d.ts +5 -5
  320. package/dist/layout/sidebar/sidebar.d.ts.map +1 -1
  321. package/dist/list-item.cjs.map +1 -1
  322. package/dist/list-item.js.map +1 -1
  323. package/dist/list.cjs.map +1 -1
  324. package/dist/list.js.map +1 -1
  325. package/dist/menu.cjs +6 -5
  326. package/dist/menu.cjs.map +1 -1
  327. package/dist/menu.js +6 -5
  328. package/dist/menu.js.map +1 -1
  329. package/dist/message-composer.cjs.map +1 -1
  330. package/dist/message-composer.js.map +1 -1
  331. package/dist/navbar.cjs.map +1 -1
  332. package/dist/navbar.js.map +1 -1
  333. package/dist/number-input.cjs.map +1 -1
  334. package/dist/number-input.js.map +1 -1
  335. package/dist/otp-input.cjs.map +1 -1
  336. package/dist/otp-input.js.map +1 -1
  337. package/dist/overlay/command-palette/command-palette-items.cjs.map +1 -1
  338. package/dist/overlay/command-palette/command-palette-items.d.ts +1 -1
  339. package/dist/overlay/command-palette/command-palette-items.js.map +1 -1
  340. package/dist/overlay/command-palette/command-palette.css.cjs +1 -1
  341. package/dist/overlay/command-palette/command-palette.css.cjs.map +1 -1
  342. package/dist/overlay/command-palette/command-palette.css.js +1 -1
  343. package/dist/overlay/command-palette/command-palette.css.js.map +1 -1
  344. package/dist/overlay/command-palette/command-palette.d.ts +7 -3
  345. package/dist/overlay/command-palette/command-palette.d.ts.map +1 -1
  346. package/dist/overlay/command-palette/command-palette.types.d.ts +16 -6
  347. package/dist/overlay/command-palette/command-palette.types.d.ts.map +1 -1
  348. package/dist/overlay/dialog/dialog.css.cjs +1 -1
  349. package/dist/overlay/dialog/dialog.css.cjs.map +1 -1
  350. package/dist/overlay/dialog/dialog.css.js +1 -1
  351. package/dist/overlay/dialog/dialog.css.js.map +1 -1
  352. package/dist/overlay/dialog/dialog.d.ts +2 -2
  353. package/dist/overlay/dialog/dialog.d.ts.map +1 -1
  354. package/dist/overlay/drawer/drawer.css.cjs.map +1 -1
  355. package/dist/overlay/drawer/drawer.css.js.map +1 -1
  356. package/dist/overlay/drawer/drawer.d.ts +1 -1
  357. package/dist/overlay/drawer/drawer.d.ts.map +1 -1
  358. package/dist/overlay/menu/menu-item.css.cjs.map +1 -1
  359. package/dist/overlay/menu/menu-item.css.js.map +1 -1
  360. package/dist/overlay/menu/menu.d.ts.map +1 -1
  361. package/dist/overlay/shared/use-dialog.cjs.map +1 -1
  362. package/dist/overlay/shared/use-dialog.d.ts +6 -6
  363. package/dist/overlay/shared/use-dialog.d.ts.map +1 -1
  364. package/dist/overlay/shared/use-dialog.js.map +1 -1
  365. package/dist/overlay/shared/use-floating-trigger.cjs.map +1 -1
  366. package/dist/overlay/shared/use-floating-trigger.d.ts +1 -1
  367. package/dist/overlay/shared/use-floating-trigger.d.ts.map +1 -1
  368. package/dist/overlay/shared/use-floating-trigger.js.map +1 -1
  369. package/dist/overlay/tooltip/tooltip.css.cjs.map +1 -1
  370. package/dist/overlay/tooltip/tooltip.css.js.map +1 -1
  371. package/dist/progress.cjs.map +1 -1
  372. package/dist/progress.js.map +1 -1
  373. package/dist/qr-code.cjs.map +1 -1
  374. package/dist/qr-code.js.map +1 -1
  375. package/dist/qr-scanner.cjs.map +1 -1
  376. package/dist/qr-scanner.js.map +1 -1
  377. package/dist/radio-group.cjs.map +1 -1
  378. package/dist/radio-group.js.map +1 -1
  379. package/dist/radio.cjs.map +1 -1
  380. package/dist/radio.js.map +1 -1
  381. package/dist/rank-item.cjs +21 -0
  382. package/dist/rank-item.cjs.map +1 -0
  383. package/dist/rank-item.js +21 -0
  384. package/dist/rank-item.js.map +1 -0
  385. package/dist/rank-list.cjs +4 -0
  386. package/dist/rank-list.cjs.map +1 -0
  387. package/dist/rank-list.js +4 -0
  388. package/dist/rank-list.js.map +1 -0
  389. package/dist/rating.cjs.map +1 -1
  390. package/dist/rating.js.map +1 -1
  391. package/dist/refine.cjs +111 -80
  392. package/dist/refine.cjs.map +1 -1
  393. package/dist/refine.iife.js +111 -80
  394. package/dist/refine.iife.js.map +1 -1
  395. package/dist/refine.js +112 -81
  396. package/dist/refine.js.map +1 -1
  397. package/dist/select.cjs.map +1 -1
  398. package/dist/select.js.map +1 -1
  399. package/dist/separator.cjs.map +1 -1
  400. package/dist/separator.js.map +1 -1
  401. package/dist/shared/index.d.ts +3 -3
  402. package/dist/shared/size-presets.cjs.map +1 -1
  403. package/dist/shared/size-presets.d.ts +4 -4
  404. package/dist/shared/size-presets.js.map +1 -1
  405. package/dist/shared/types.d.ts +1 -1
  406. package/dist/sidebar.cjs.map +1 -1
  407. package/dist/sidebar.js.map +1 -1
  408. package/dist/skeleton.cjs.map +1 -1
  409. package/dist/skeleton.js.map +1 -1
  410. package/dist/slider.cjs.map +1 -1
  411. package/dist/slider.js.map +1 -1
  412. package/dist/speech-player.cjs.map +1 -1
  413. package/dist/speech-player.js.map +1 -1
  414. package/dist/step.cjs.map +1 -1
  415. package/dist/step.js.map +1 -1
  416. package/dist/stepper.cjs.map +1 -1
  417. package/dist/stepper.js.map +1 -1
  418. package/dist/styles/fouc.css +2 -2
  419. package/dist/styles/mixins/accessibility.css.cjs.map +1 -1
  420. package/dist/styles/mixins/accessibility.css.d.ts +4 -4
  421. package/dist/styles/mixins/accessibility.css.js.map +1 -1
  422. package/dist/styles/mixins/animation.css.cjs +2 -2
  423. package/dist/styles/mixins/animation.css.cjs.map +1 -1
  424. package/dist/styles/mixins/animation.css.d.ts +4 -4
  425. package/dist/styles/mixins/animation.css.js +2 -2
  426. package/dist/styles/mixins/animation.css.js.map +1 -1
  427. package/dist/styles/mixins/field-variants.css.cjs +2 -2
  428. package/dist/styles/mixins/field-variants.css.cjs.map +1 -1
  429. package/dist/styles/mixins/field-variants.css.d.ts +6 -6
  430. package/dist/styles/mixins/field-variants.css.d.ts.map +1 -1
  431. package/dist/styles/mixins/field-variants.css.js +2 -2
  432. package/dist/styles/mixins/field-variants.css.js.map +1 -1
  433. package/dist/styles/mixins/shape.css.cjs.map +1 -1
  434. package/dist/styles/mixins/shape.css.d.ts +9 -9
  435. package/dist/styles/mixins/shape.css.d.ts.map +1 -1
  436. package/dist/styles/mixins/shape.css.js.map +1 -1
  437. package/dist/styles/mixins/variants.css.cjs.map +1 -1
  438. package/dist/styles/mixins/variants.css.d.ts +1 -1
  439. package/dist/styles/mixins/variants.css.js.map +1 -1
  440. package/dist/styles/theme.css +36 -28
  441. package/dist/tab-item.cjs.map +1 -1
  442. package/dist/tab-item.js.map +1 -1
  443. package/dist/tab-panel.cjs.map +1 -1
  444. package/dist/tab-panel.js.map +1 -1
  445. package/dist/table.cjs.map +1 -1
  446. package/dist/table.js.map +1 -1
  447. package/dist/text.cjs.map +1 -1
  448. package/dist/text.js.map +1 -1
  449. package/dist/textarea.cjs.map +1 -1
  450. package/dist/textarea.js.map +1 -1
  451. package/dist/theme.cjs.map +1 -1
  452. package/dist/theme.d.ts +2 -2
  453. package/dist/theme.js.map +1 -1
  454. package/dist/time-picker.cjs +1 -1
  455. package/dist/time-picker.cjs.map +1 -1
  456. package/dist/time-picker.js +1 -1
  457. package/dist/time-picker.js.map +1 -1
  458. package/dist/toast.cjs.map +1 -1
  459. package/dist/toast.js.map +1 -1
  460. package/dist/types/elements.d.ts +6 -2
  461. package/dist/typing-indicator.cjs.map +1 -1
  462. package/dist/typing-indicator.js.map +1 -1
  463. package/dist/utils/css.cjs.map +1 -1
  464. package/dist/utils/css.js.map +1 -1
  465. package/dist/utils/link.cjs.map +1 -1
  466. package/dist/utils/link.d.ts +2 -2
  467. package/dist/utils/link.js.map +1 -1
  468. package/package.json +31 -14
@@ -1 +1 @@
1
- {"version":3,"file":"step.css.js","names":[],"sources":["../../../src/content/stepper/step.css?inline"],"sourcesContent":["@layer refine.base {\n :host {\n --step-indicator-size: var(--size-8);\n --step-font-size: var(--text-sm);\n --step-gap: var(--size-2);\n display: flex;\n flex: 1 1 0%;\n min-width: 0;\n }\n\n .step {\n position: relative;\n box-sizing: border-box;\n display: flex;\n align-items: center;\n width: 100%;\n list-style: none;\n }\n\n /* Horizontal (default) layout centers the indicator above the label in each equal-width\n column (see `.control`/`.content` below) so the indicator sits at a predictable, constant\n horizontal position — the midpoint of its own step — regardless of label length. The full\n line between two indicators is drawn as *two* halves — this step's own `.connector-leading`\n (its own left edge to its own indicator) and `.connector-trailing` (its own indicator to its\n own right edge) — each confined entirely inside this step's own box. Reaching a single\n connector backward into the previous step's box (an earlier attempt) doesn't work: `ore-step`\n is its own custom element/shadow root, so a later sibling's positioned content always paints\n in front of an earlier sibling's regardless of internal stacking, and `.control`'s own hover\n background only covers its own box — so the part of the line sitting outside it looked like\n a stray line poking out next to the hover highlight instead of being part of it. */\n .connector {\n position: absolute;\n top: calc(var(--size-1) + var(--step-indicator-size) / 2);\n width: calc(50% - var(--step-indicator-size) / 2);\n height: var(--stepper-connector-size, 2px);\n background: var(--stepper-connector-color, var(--color-contrast-200));\n border-radius: var(--rounded-full);\n transform: translateY(-50%);\n transition: background var(--transition-fast);\n }\n\n .connector-leading {\n left: 0;\n }\n\n .connector-trailing {\n right: 0;\n }\n\n /* No preceding/following step to connect to. */\n :host(:first-of-type) .connector-leading {\n display: none;\n }\n\n :host(:last-of-type) .connector-trailing {\n display: none;\n }\n\n .control {\n all: unset;\n\n /* Declared after `all: unset` (which resets `position` back to `static`), not before it.\n Puts `.control` in the same paint order as `.connector` (also positioned) instead of\n `.connector` — being absolutely positioned — automatically painting above all of this\n *static*, normal-flow content regardless of DOM order. `.control` comes after\n `.connector` in the markup, so with both positioned it (and the opaque indicator inside\n it) now correctly paints over the connector line instead of the line cutting across\n every indicator. */\n position: relative;\n box-sizing: border-box;\n display: flex;\n flex: 1 1 auto;\n flex-direction: column;\n gap: var(--step-gap);\n align-items: center;\n width: 100%;\n min-width: 0;\n padding: var(--size-1);\n font-family: inherit;\n cursor: default;\n border-radius: var(--rounded-lg);\n }\n\n button.control {\n min-height: var(--_touch-target, auto);\n cursor: pointer;\n transition: background var(--transition-fast);\n }\n\n button.control:focus-visible {\n outline: var(--border-2) solid var(--_theme-base, var(--color-contrast-500));\n outline-offset: var(--border-2);\n }\n\n button.control[aria-disabled='true'] {\n cursor: not-allowed;\n opacity: 0.5;\n }\n\n .indicator {\n /* Without this, the `border` below adds on top of `width`/`height` instead of being\n included in them, rendering the indicator ~2 * border-width larger per axis than\n `--step-indicator-size` — every connector position calc using that variable to line up\n with the indicator's true center/edge (especially the vertical connector's horizontal\n `left`, which has no flexbox centering to fall back on) would then be off by that much. */\n box-sizing: border-box;\n display: flex;\n flex: 0 0 auto;\n align-items: center;\n justify-content: center;\n width: var(--step-indicator-size);\n height: var(--step-indicator-size);\n font-size: var(--step-font-size);\n font-weight: var(--font-semibold);\n color: var(--color-contrast-500);\n background: var(--color-contrast-100);\n border: var(--border-2) solid var(--color-contrast-200);\n border-radius: var(--rounded-full);\n transition:\n background var(--transition-fast),\n color var(--transition-fast),\n border-color var(--transition-fast);\n }\n\n .icon-slot[hidden] {\n display: none;\n }\n\n .number {\n line-height: 1;\n }\n\n .content {\n display: flex;\n flex: 1 1 auto;\n flex-direction: column;\n align-items: center;\n min-width: 0;\n max-width: 100%;\n text-align: center;\n }\n\n .label {\n display: flex;\n gap: var(--size-1);\n align-items: baseline;\n justify-content: center;\n min-width: 0;\n max-width: 100%;\n font-size: var(--step-font-size);\n font-weight: var(--font-medium);\n color: var(--color-contrast-700);\n }\n\n .label-text {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .optional-hint {\n flex: 0 0 auto;\n font-size: var(--text-xs);\n font-weight: var(--font-normal);\n color: var(--color-contrast-400);\n }\n\n .description {\n font-size: var(--text-xs);\n color: var(--color-contrast-500);\n }\n\n .description[hidden] {\n display: none;\n }\n\n .sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n white-space: nowrap;\n border-width: 0;\n clip-path: inset(50%);\n }\n}\n\n@layer refine.states {\n :host([current]) .indicator {\n color: var(--_theme-contrast, var(--color-canvas));\n background: var(--_theme-base, var(--color-contrast-800));\n border-color: var(--_theme-base, var(--color-contrast-800));\n }\n\n :host([current]) .label {\n font-weight: var(--font-semibold);\n color: var(--color-contrast-900);\n }\n\n :host([completed]) .indicator {\n color: var(--_theme-contrast, var(--color-canvas));\n background: var(--_theme-focus, var(--color-contrast-600));\n border-color: var(--_theme-focus, var(--color-contrast-600));\n }\n\n /* A completed step colors both the segment leading into it and the one trailing out of it\n (progress has fully passed through); the current step only colors the leading segment\n (progress has arrived, but not yet moved past it into the next step). */\n :host([completed]) .connector,\n :host([current]) .connector-leading {\n background: var(--_theme-focus, var(--color-contrast-400));\n }\n\n :host([error]) .indicator {\n color: var(--color-canvas);\n background: var(--color-error);\n border-color: var(--color-error);\n }\n\n :host([error]) .label {\n color: var(--color-error);\n }\n\n :host([disabled]) .label,\n :host([disabled]) .description {\n color: var(--color-contrast-400);\n }\n\n :host([disabled]) .indicator {\n opacity: 0.6;\n }\n}\n\n@layer refine.sizes {\n :host([size='sm']) {\n --step-indicator-size: var(--size-6);\n --step-font-size: var(--text-xs);\n --step-gap: var(--size-1-5);\n }\n\n :host(:not([size])),\n :host([size='md']) {\n --step-indicator-size: var(--size-8);\n --step-font-size: var(--text-sm);\n --step-gap: var(--size-2);\n }\n\n :host([size='lg']) {\n --step-indicator-size: var(--size-10);\n --step-font-size: var(--text-base);\n --step-gap: var(--size-2-5);\n }\n\n @media (pointer: coarse) {\n :host(:not([size])),\n :host([size='sm']),\n :host([size='md']) {\n --step-indicator-size: var(--size-9);\n --step-font-size: var(--text-sm);\n }\n }\n}\n\n@layer refine.orientation {\n /* Vertical (mobile-friendly) layout: back to the inline icon-beside-label arrangement (more\n compact for narrow/mobile widths), with `padding-block-start` reserving room for a\n top-to-bottom connector into this step's own indicator instead of the horizontal\n center-to-center line above. */\n :host([orientation='vertical']) {\n flex: 0 0 auto;\n width: 100%;\n }\n\n :host([orientation='vertical']) .step {\n align-items: flex-start;\n padding-block-start: var(--stepper-gap, var(--size-4));\n }\n\n :host([orientation='vertical']:first-of-type) .step {\n padding-block-start: 0;\n }\n\n :host([orientation='vertical']) .control {\n flex-direction: row;\n align-items: flex-start;\n }\n\n :host([orientation='vertical']) .content {\n align-items: flex-start;\n text-align: left;\n }\n\n :host([orientation='vertical']) .label {\n justify-content: flex-start;\n }\n\n /* Same two-halves idea as horizontal, rotated: `.connector-leading` runs from this step's own\n top edge down into its indicator (through the `padding-block-start` gap reserved above).\n `.connector-trailing` runs from the *bottom* of this step's indicator down to this step's\n own bottom edge — using `top`+`bottom` (no fixed `height`) so it stretches to whatever this\n step's content actually needs, instead of a fixed length that only reached as far as the\n padding gap. A step with a longer description is taller, and its trailing segment grows\n with it — the next step's leading segment then only has to bridge the fixed padding gap,\n so the two halves always meet exactly at the boundary between the two steps regardless of\n how much content either one has. */\n :host([orientation='vertical']) .connector-leading {\n top: 0;\n left: calc(var(--size-1) + var(--step-indicator-size) / 2);\n width: var(--stepper-connector-size, 2px);\n height: calc(var(--stepper-gap, var(--size-4)) + var(--size-1));\n transform: translateX(-50%);\n }\n\n :host([orientation='vertical']) .connector-trailing {\n inset: calc(var(--stepper-gap, var(--size-4)) + var(--size-1) + var(--step-indicator-size)) auto 0\n calc(var(--size-1) + var(--step-indicator-size) / 2);\n width: var(--stepper-connector-size, 2px);\n height: auto;\n transform: translateX(-50%);\n }\n\n /* The first step's `padding-block-start` is reset to 0 above (no incoming line to make room\n for) — `.connector-trailing`'s `top` has to drop the same gap term here, or it starts\n lower than the indicator's true bottom edge and its `bottom: 0` counterpart can compute a\n negative (clamped to 0) height, hiding the segment entirely. */\n :host([orientation='vertical']:first-of-type) .connector-trailing {\n top: calc(var(--size-1) + var(--step-indicator-size));\n }\n}\n\n@media (forced-colors: active) {\n .indicator {\n border: 1px solid ButtonText;\n }\n\n :host([current]) .indicator,\n :host([completed]) .indicator {\n border: 1px solid Highlight;\n }\n}\n"],"mappings":""}
1
+ {"version":3,"file":"step.css.js","names":[],"sources":["../../../src/content/stepper/step.css?inline"],"sourcesContent":["@layer refine.base {\n :host {\n --step-indicator-size: var(--size-8);\n --step-font-size: var(--text-sm);\n --step-gap: var(--size-2);\n display: flex;\n flex: 1 1 0%;\n min-width: 0;\n }\n\n .step {\n position: relative;\n box-sizing: border-box;\n display: flex;\n align-items: center;\n width: 100%;\n list-style: none;\n }\n\n /* Horizontal (default) layout centers the indicator above the label in each equal-width\n column (see `.control`/`.content` below) so the indicator sits at a predictable, constant\n horizontal position: the midpoint of its own step: regardless of label length. The full\n line between two indicators is drawn as *two* halves: this step's own `.connector-leading`\n (its own left edge to its own indicator) and `.connector-trailing` (its own indicator to its\n own right edge): each confined entirely inside this step's own box. Reaching a single\n connector backward into the previous step's box (an earlier attempt) doesn't work: `ore-step`\n is its own custom element/shadow root, so a later sibling's positioned content always paints\n in front of an earlier sibling's regardless of internal stacking, and `.control`'s own hover\n background only covers its own box, so the part of the line sitting outside it looked like\n a stray line poking out next to the hover highlight instead of being part of it. */\n .connector {\n position: absolute;\n top: calc(var(--size-1) + var(--step-indicator-size) / 2);\n width: calc(50% - var(--step-indicator-size) / 2);\n height: var(--stepper-connector-size, 2px);\n background: var(--stepper-connector-color, var(--color-contrast-200));\n border-radius: var(--rounded-full);\n transform: translateY(-50%);\n transition: background var(--transition-fast);\n }\n\n .connector-leading {\n left: 0;\n }\n\n .connector-trailing {\n right: 0;\n }\n\n /* No preceding/following step to connect to. */\n :host(:first-of-type) .connector-leading {\n display: none;\n }\n\n :host(:last-of-type) .connector-trailing {\n display: none;\n }\n\n .control {\n all: unset;\n\n /* Declared after `all: unset` (which resets `position` back to `static`), not before it.\n Puts `.control` in the same paint order as `.connector` (also positioned) instead of\n `.connector`: being absolutely positioned: automatically painting above all of this\n *static*, normal-flow content regardless of DOM order. `.control` comes after\n `.connector` in the markup, so with both positioned it (and the opaque indicator inside\n it) now correctly paints over the connector line instead of the line cutting across\n every indicator. */\n position: relative;\n box-sizing: border-box;\n display: flex;\n flex: 1 1 auto;\n flex-direction: column;\n gap: var(--step-gap);\n align-items: center;\n width: 100%;\n min-width: 0;\n padding: var(--size-1);\n font-family: inherit;\n cursor: default;\n border-radius: var(--rounded-lg);\n }\n\n button.control {\n min-height: var(--_touch-target, auto);\n cursor: pointer;\n transition: background var(--transition-fast);\n }\n\n button.control:focus-visible {\n outline: var(--border-2) solid var(--_theme-base, var(--color-contrast-500));\n outline-offset: var(--border-2);\n }\n\n button.control[aria-disabled='true'] {\n cursor: not-allowed;\n opacity: 0.5;\n }\n\n .indicator {\n /* Without this, the `border` below adds on top of `width`/`height` instead of being\n included in them, rendering the indicator ~2 * border-width larger per axis than\n `--step-indicator-size`: every connector position calc using that variable to line up\n with the indicator's true center/edge (especially the vertical connector's horizontal\n `left`, which has no flexbox centering to fall back on) would then be off by that much. */\n box-sizing: border-box;\n display: flex;\n flex: 0 0 auto;\n align-items: center;\n justify-content: center;\n width: var(--step-indicator-size);\n height: var(--step-indicator-size);\n font-size: var(--step-font-size);\n font-weight: var(--font-semibold);\n color: var(--color-contrast-500);\n background: var(--color-contrast-100);\n border: var(--border-2) solid var(--color-contrast-200);\n border-radius: var(--rounded-full);\n transition:\n background var(--transition-fast),\n color var(--transition-fast),\n border-color var(--transition-fast);\n }\n\n .icon-slot[hidden] {\n display: none;\n }\n\n .number {\n line-height: 1;\n }\n\n .content {\n display: flex;\n flex: 1 1 auto;\n flex-direction: column;\n align-items: center;\n min-width: 0;\n max-width: 100%;\n text-align: center;\n }\n\n .label {\n display: flex;\n gap: var(--size-1);\n align-items: baseline;\n justify-content: center;\n min-width: 0;\n max-width: 100%;\n font-size: var(--step-font-size);\n font-weight: var(--font-medium);\n color: var(--color-contrast-700);\n }\n\n .label-text {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .optional-hint {\n flex: 0 0 auto;\n font-size: var(--text-xs);\n font-weight: var(--font-normal);\n color: var(--color-contrast-400);\n }\n\n .description {\n font-size: var(--text-xs);\n color: var(--color-contrast-500);\n }\n\n .description[hidden] {\n display: none;\n }\n\n .sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n white-space: nowrap;\n border-width: 0;\n clip-path: inset(50%);\n }\n}\n\n@layer refine.states {\n :host([current]) .indicator {\n color: var(--_theme-contrast, var(--color-canvas));\n background: var(--_theme-base, var(--color-contrast-800));\n border-color: var(--_theme-base, var(--color-contrast-800));\n }\n\n :host([current]) .label {\n font-weight: var(--font-semibold);\n color: var(--color-contrast-900);\n }\n\n :host([completed]) .indicator {\n color: var(--_theme-contrast, var(--color-canvas));\n background: var(--_theme-focus, var(--color-contrast-600));\n border-color: var(--_theme-focus, var(--color-contrast-600));\n }\n\n /* A completed step colors both the segment leading into it and the one trailing out of it\n (progress has fully passed through); the current step only colors the leading segment\n (progress has arrived, but not yet moved past it into the next step). */\n :host([completed]) .connector,\n :host([current]) .connector-leading {\n background: var(--_theme-focus, var(--color-contrast-400));\n }\n\n :host([error]) .indicator {\n color: var(--color-canvas);\n background: var(--color-error);\n border-color: var(--color-error);\n }\n\n :host([error]) .label {\n color: var(--color-error);\n }\n\n :host([disabled]) .label,\n :host([disabled]) .description {\n color: var(--color-contrast-400);\n }\n\n :host([disabled]) .indicator {\n opacity: 0.6;\n }\n}\n\n@layer refine.sizes {\n :host([size='sm']) {\n --step-indicator-size: var(--size-6);\n --step-font-size: var(--text-xs);\n --step-gap: var(--size-1-5);\n }\n\n :host(:not([size])),\n :host([size='md']) {\n --step-indicator-size: var(--size-8);\n --step-font-size: var(--text-sm);\n --step-gap: var(--size-2);\n }\n\n :host([size='lg']) {\n --step-indicator-size: var(--size-10);\n --step-font-size: var(--text-base);\n --step-gap: var(--size-2-5);\n }\n\n @media (pointer: coarse) {\n :host(:not([size])),\n :host([size='sm']),\n :host([size='md']) {\n --step-indicator-size: var(--size-9);\n --step-font-size: var(--text-sm);\n }\n }\n}\n\n@layer refine.orientation {\n /* Vertical (mobile-friendly) layout: back to the inline icon-beside-label arrangement (more\n compact for narrow/mobile widths), with `padding-block-start` reserving room for a\n top-to-bottom connector into this step's own indicator instead of the horizontal\n center-to-center line above. */\n :host([orientation='vertical']) {\n flex: 0 0 auto;\n width: 100%;\n }\n\n :host([orientation='vertical']) .step {\n align-items: flex-start;\n padding-block-start: var(--stepper-gap, var(--size-4));\n }\n\n :host([orientation='vertical']:first-of-type) .step {\n padding-block-start: 0;\n }\n\n :host([orientation='vertical']) .control {\n flex-direction: row;\n align-items: flex-start;\n }\n\n :host([orientation='vertical']) .content {\n align-items: flex-start;\n text-align: left;\n }\n\n :host([orientation='vertical']) .label {\n justify-content: flex-start;\n }\n\n /* Same two-halves idea as horizontal, rotated: `.connector-leading` runs from this step's own\n top edge down into its indicator (through the `padding-block-start` gap reserved above).\n `.connector-trailing` runs from the *bottom* of this step's indicator down to this step's\n own bottom edge: using `top`+`bottom` (no fixed `height`) so it stretches to whatever this\n step's content actually needs, instead of a fixed length that only reached as far as the\n padding gap. A step with a longer description is taller, and its trailing segment grows\n with it: the next step's leading segment then only has to bridge the fixed padding gap,\n so the two halves always meet exactly at the boundary between the two steps regardless of\n how much content either one has. */\n :host([orientation='vertical']) .connector-leading {\n top: 0;\n left: calc(var(--size-1) + var(--step-indicator-size) / 2);\n width: var(--stepper-connector-size, 2px);\n height: calc(var(--stepper-gap, var(--size-4)) + var(--size-1));\n transform: translateX(-50%);\n }\n\n :host([orientation='vertical']) .connector-trailing {\n inset: calc(var(--stepper-gap, var(--size-4)) + var(--size-1) + var(--step-indicator-size)) auto 0\n calc(var(--size-1) + var(--step-indicator-size) / 2);\n width: var(--stepper-connector-size, 2px);\n height: auto;\n transform: translateX(-50%);\n }\n\n /* The first step's `padding-block-start` is reset to 0 above (no incoming line to make room\n for): `.connector-trailing`'s `top` has to drop the same gap term here, or it starts\n lower than the indicator's true bottom edge and its `bottom: 0` counterpart can compute a\n negative (clamped to 0) height, hiding the segment entirely. */\n :host([orientation='vertical']:first-of-type) .connector-trailing {\n top: calc(var(--size-1) + var(--step-indicator-size));\n }\n}\n\n@media (forced-colors: active) {\n .indicator {\n border: 1px solid ButtonText;\n }\n\n :host([current]) .indicator,\n :host([completed]) .indicator {\n border: 1px solid Highlight;\n }\n}\n"],"mappings":""}
@@ -6,13 +6,13 @@ export type OreStepProps = {
6
6
  * this value); only takes effect on its own when `ore-step` is rendered standalone.
7
7
  */
8
8
  color?: ThemeColor;
9
- /** Disables this step — it cannot be navigated to and is skipped by keyboard navigation. */
9
+ /** Disables this step: it cannot be navigated to and is skipped by keyboard navigation. */
10
10
  disabled?: boolean;
11
11
  /** Marks this step as failed/invalid. Overrides the completed/current indicator visuals. */
12
12
  error?: boolean;
13
13
  /**
14
14
  * Marks this step as optional. Renders a small "(optional)" hint next to the label.
15
- * Purely presentational — has no effect on navigation.
15
+ * Purely presentational: has no effect on navigation.
16
16
  */
17
17
  optional?: boolean;
18
18
  /** Orientation. Inherited from the parent `ore-stepper` when nested inside one. */
@@ -24,7 +24,7 @@ export type OreStepProps = {
24
24
  };
25
25
  /**
26
26
  * A single step trigger. Must be placed as a direct child of `ore-stepper`, which provides
27
- * this step's current/completed/navigable/index/total state via context — those are derived,
27
+ * this step's current/completed/navigable/index/total state via context: those are derived,
28
28
  * read-only attributes on this element, not settable props.
29
29
  *
30
30
  * @element ore-step
@@ -1 +1 @@
1
- {"version":3,"file":"step.d.ts","sourceRoot":"","sources":["../../../src/content/stepper/step.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAK7D,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,MAAM,MAAM,YAAY,GAAG;IACzB;;;OAGG;IACH,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,4FAA4F;IAC5F,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,4FAA4F;IAC5F,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,mFAAmF;IACnF,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC;IACxC,sFAAsF;IACtF,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,eAAO,MAAM,QAAQ,EAAG,UAAmB,CAAC"}
1
+ {"version":3,"file":"step.d.ts","sourceRoot":"","sources":["../../../src/content/stepper/step.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAK7D,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,MAAM,MAAM,YAAY,GAAG;IACzB;;;OAGG;IACH,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,2FAA2F;IAC3F,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,4FAA4F;IAC5F,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,mFAAmF;IACnF,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC;IACxC,sFAAsF;IACtF,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,eAAO,MAAM,QAAQ,EAAG,UAAmB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"stepper.css.cjs","names":[],"sources":["../../../src/content/stepper/stepper.css?inline"],"sourcesContent":["@layer refine.base {\n :host {\n display: block;\n width: 100%;\n }\n\n nav {\n display: block;\n width: 100%;\n }\n\n .steps {\n /* Spacing between steps comes from each ore-step's own `padding-inline-start` /\n `padding-block-start` (see step.css), not a flex `gap` here — that lets each step's\n connector line be drawn from its own edge to its own indicator using the exact same\n length it was given room for, with no separate gap value to keep in sync by hand. */\n display: flex;\n gap: 0;\n align-items: flex-start;\n width: 100%;\n padding: 0;\n margin: 0;\n list-style: none;\n }\n\n .stepper-message {\n display: block;\n margin-top: var(--size-3);\n }\n}\n\n@layer refine.orientation {\n :host([orientation='vertical']) .steps {\n flex-direction: column;\n align-items: stretch;\n }\n}\n"],"mappings":""}
1
+ {"version":3,"file":"stepper.css.cjs","names":[],"sources":["../../../src/content/stepper/stepper.css?inline"],"sourcesContent":["@layer refine.base {\n :host {\n display: block;\n width: 100%;\n }\n\n nav {\n display: block;\n width: 100%;\n }\n\n .steps {\n /* Spacing between steps comes from each ore-step's own `padding-inline-start` /\n `padding-block-start` (see step.css), not a flex `gap` here, that lets each step's\n connector line be drawn from its own edge to its own indicator using the exact same\n length it was given room for, with no separate gap value to keep in sync by hand. */\n display: flex;\n gap: 0;\n align-items: flex-start;\n width: 100%;\n padding: 0;\n margin: 0;\n list-style: none;\n }\n\n .stepper-message {\n display: block;\n margin-top: var(--size-3);\n }\n}\n\n@layer refine.orientation {\n :host([orientation='vertical']) .steps {\n flex-direction: column;\n align-items: stretch;\n }\n}\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"stepper.css.js","names":[],"sources":["../../../src/content/stepper/stepper.css?inline"],"sourcesContent":["@layer refine.base {\n :host {\n display: block;\n width: 100%;\n }\n\n nav {\n display: block;\n width: 100%;\n }\n\n .steps {\n /* Spacing between steps comes from each ore-step's own `padding-inline-start` /\n `padding-block-start` (see step.css), not a flex `gap` here — that lets each step's\n connector line be drawn from its own edge to its own indicator using the exact same\n length it was given room for, with no separate gap value to keep in sync by hand. */\n display: flex;\n gap: 0;\n align-items: flex-start;\n width: 100%;\n padding: 0;\n margin: 0;\n list-style: none;\n }\n\n .stepper-message {\n display: block;\n margin-top: var(--size-3);\n }\n}\n\n@layer refine.orientation {\n :host([orientation='vertical']) .steps {\n flex-direction: column;\n align-items: stretch;\n }\n}\n"],"mappings":""}
1
+ {"version":3,"file":"stepper.css.js","names":[],"sources":["../../../src/content/stepper/stepper.css?inline"],"sourcesContent":["@layer refine.base {\n :host {\n display: block;\n width: 100%;\n }\n\n nav {\n display: block;\n width: 100%;\n }\n\n .steps {\n /* Spacing between steps comes from each ore-step's own `padding-inline-start` /\n `padding-block-start` (see step.css), not a flex `gap` here, that lets each step's\n connector line be drawn from its own edge to its own indicator using the exact same\n length it was given room for, with no separate gap value to keep in sync by hand. */\n display: flex;\n gap: 0;\n align-items: flex-start;\n width: 100%;\n padding: 0;\n margin: 0;\n list-style: none;\n }\n\n .stepper-message {\n display: block;\n margin-top: var(--size-3);\n }\n}\n\n@layer refine.orientation {\n :host([orientation='vertical']) .steps {\n flex-direction: column;\n align-items: stretch;\n }\n}\n"],"mappings":""}
@@ -23,16 +23,16 @@ export type OreStepperProps = {
23
23
  clickable?: boolean;
24
24
  /** Theme color for the current/completed step indicators */
25
25
  color?: ThemeColor;
26
- /** Disables the whole stepper — no step is navigable regardless of `clickable` */
26
+ /** Disables the whole stepper: no step is navigable regardless of `clickable` */
27
27
  disabled?: boolean;
28
28
  /** Accessible label for the nav landmark */
29
29
  label?: string;
30
30
  /**
31
- * Restricts navigation to completed steps and the current step — steps ahead of the
31
+ * Restricts navigation to completed steps and the current step: steps ahead of the
32
32
  * current one cannot be clicked or focused, even when `clickable` is set.
33
33
  */
34
34
  linear?: boolean;
35
- /** Layout orientation — 'horizontal' (default, desktop) or 'vertical' (compact/mobile-friendly) */
35
+ /** Layout orientation: 'horizontal' (default, desktop) or 'vertical' (compact/mobile-friendly) */
36
36
  orientation?: 'horizontal' | 'vertical';
37
37
  /** Component size */
38
38
  size?: ComponentSize;
@@ -1 +1 @@
1
- {"version":3,"file":"stepper.d.ts","sourceRoot":"","sources":["../../../src/content/stepper/stepper.ts"],"names":[],"mappings":"AAaA,OAAO,EAAY,KAAK,QAAQ,EAAiB,MAAM,kBAAkB,CAAC;AAG1E,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAe7D,gEAAgE;AAChE,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC7B,KAAK,EAAE,QAAQ,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC;IACxC,YAAY,EAAE,QAAQ,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAC3C,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC1B,WAAW,EAAE,QAAQ,CAAC,YAAY,GAAG,UAAU,CAAC,CAAC;IACjD,IAAI,EAAE,QAAQ,CAAC,aAAa,GAAG,SAAS,CAAC,CAAC;IAC1C,0FAA0F;IAC1F,UAAU,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;CAChC,CAAC;AACF,6CAA6C;AAC7C,eAAO,MAAM,WAAW,sDAAkD,CAAC;AAE3E,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,wGAAwG;IACxG,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,4DAA4D;IAC5D,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,kFAAkF;IAClF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,mGAAmG;IACnG,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC;IACxC,qBAAqB;IACrB,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,qDAAqD;IACrD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,eAAO,MAAM,WAAW,EAAG,aAAsB,CAAC"}
1
+ {"version":3,"file":"stepper.d.ts","sourceRoot":"","sources":["../../../src/content/stepper/stepper.ts"],"names":[],"mappings":"AAaA,OAAO,EAAY,KAAK,QAAQ,EAAiB,MAAM,kBAAkB,CAAC;AAG1E,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAe7D,gEAAgE;AAChE,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC7B,KAAK,EAAE,QAAQ,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC;IACxC,YAAY,EAAE,QAAQ,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAC3C,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC1B,WAAW,EAAE,QAAQ,CAAC,YAAY,GAAG,UAAU,CAAC,CAAC;IACjD,IAAI,EAAE,QAAQ,CAAC,aAAa,GAAG,SAAS,CAAC,CAAC;IAC1C,0FAA0F;IAC1F,UAAU,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;CAChC,CAAC;AACF,6CAA6C;AAC7C,eAAO,MAAM,WAAW,sDAAkD,CAAC;AAE3E,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,wGAAwG;IACxG,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,4DAA4D;IAC5D,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,iFAAiF;IACjF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,kGAAkG;IAClG,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC;IACxC,qBAAqB;IACrB,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,qDAAqD;IACrD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,eAAO,MAAM,WAAW,EAAG,aAAsB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"table.css.cjs","names":[],"sources":["../../../src/content/table/table.css?inline"],"sourcesContent":["/* ore-table — shadow DOM (proxy/mirror).\n *\n * Shadow tree (managed by table.ts):\n * :host display:block — token host (tableBaseMixin)\n * └─ .scroll-container overflow:auto — sticky / max-height context\n * └─ table display:table — native table semantics\n * ├─ caption — optional caption bar\n * ├─ thead — rows built from ore-tr[head]\n * ├─ tbody — rows built from plain ore-tr\n * └─ tfoot — rows built from ore-tr[foot]\n * └─ tr > th / td — mirrored from ore-th / ore-td\n *\n * Light DOM (consumer):\n * <ore-tr head><ore-th>…</ore-th></ore-tr>\n * <ore-tr><ore-td>…</ore-td></ore-tr>\n * <ore-tr foot><ore-td>…</ore-td></ore-tr>\n *\n * tableBaseMixin('table') handles: :host tokens, .scroll-container,\n * table width/collapse, loading state, size variants, fullwidth, bordered,\n * and sticky scroll-container activation.\n * This file handles: caption, section backgrounds, body tr/th/td, and variants.\n * No ::slotted() needed — the shadow tree owns all rendered th/td elements.\n */\n\n@layer refine.base {\n :host {\n border: none;\n border-radius: 0;\n box-shadow: var(--table-shadow, none);\n }\n\n /* ── Caption ─────────────────────────────────────────────────────────── */\n\n caption {\n padding: var(--size-3);\n font-size: var(--text-xs);\n font-weight: var(--font-semibold);\n color: var(--color-contrast-500);\n text-align: start;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n caption-side: top;\n background: var(--_header-bg);\n }\n\n /* ── Section backgrounds ─────────────────────────────────────────────── */\n\n thead,\n tfoot {\n background: var(--_header-bg);\n }\n\n thead {\n border-block-end: var(--border) solid var(--_border-color);\n }\n\n tfoot {\n border-block-start: var(--border) solid var(--_border-color);\n }\n\n /* ── Body rows ───────────────────────────────────────────────────────── */\n\n tbody tr {\n border-block-end: var(--border) solid var(--_border-color);\n transition: background var(--transition-fast);\n }\n\n tbody tr:hover {\n background: var(--_row-hover-bg);\n }\n\n /* ── Cells ───────────────────────────────────────────────────────────── */\n\n th,\n td {\n padding: var(--_cell-padding-y) var(--_cell-padding-x);\n font-size: var(--_font-size);\n font-weight: normal;\n vertical-align: middle;\n color: var(--color-contrast-800);\n text-align: start;\n }\n\n /* ── Header cells ────────────────────────────────────────────────────── */\n\n thead th,\n thead td,\n tfoot th,\n tfoot td {\n font-size: var(--text-xs);\n font-weight: var(--font-semibold);\n color: var(--color-contrast-500);\n text-transform: uppercase;\n letter-spacing: 0.04em;\n white-space: nowrap;\n user-select: none;\n }\n}\n\n@layer refine.variants {\n /* ── Bordered: vertical cell separators ─────────────────────────────── */\n\n :host([bordered]) th,\n :host([bordered]) td {\n border-inline-end: var(--border) solid var(--_border-color);\n }\n\n :host([bordered]) th:last-child,\n :host([bordered]) td:last-child {\n border-inline-end: none;\n }\n\n /* ── Striped ─────────────────────────────────────────────────────────── */\n\n :host([striped]) tbody tr:nth-child(even) {\n background: var(--_stripe-bg);\n }\n\n /* ── Sticky header ───────────────────────────────────────────────────── */\n\n /* tableBaseMixin activates overflow-y:auto on .scroll-container when\n [sticky] is present. position:sticky on thead is relative to that context. */\n\n :host([sticky]) thead {\n position: sticky;\n top: 0;\n z-index: 2;\n background: var(--table-sticky-header-bg, color-mix(in oklch, var(--_header-bg) 94%, transparent));\n\n /* border-collapse merges the bottom border into the cell below, which\n scrolls away under the sticky header. Use box-shadow instead — it\n travels with the element regardless of border-collapse. */\n box-shadow: inset 0 calc(var(--border) * -1) 0 var(--_border-color);\n backdrop-filter: blur(var(--table-sticky-blur, var(--blur-md))) saturate(140%);\n }\n}\n"],"mappings":""}
1
+ {"version":3,"file":"table.css.cjs","names":[],"sources":["../../../src/content/table/table.css?inline"],"sourcesContent":["/* ore-table: shadow DOM (proxy/mirror).\n *\n * Shadow tree (managed by table.ts):\n * :host (display:block): token host (tableBaseMixin)\n * └─ .scroll-container (overflow:auto): sticky / max-height context\n * └─ table (display:table): native table semantics\n * ├─ caption: optional caption bar\n * ├─ thead: rows built from ore-tr[head]\n * ├─ tbody: rows built from plain ore-tr\n * └─ tfoot: rows built from ore-tr[foot]\n * └─ tr > th / td: mirrored from ore-th / ore-td\n *\n * Light DOM (consumer):\n * <ore-tr head><ore-th>…</ore-th></ore-tr>\n * <ore-tr><ore-td>…</ore-td></ore-tr>\n * <ore-tr foot><ore-td>…</ore-td></ore-tr>\n *\n * tableBaseMixin('table') handles: :host tokens, .scroll-container,\n * table width/collapse, loading state, size variants, fullwidth, bordered,\n * and sticky scroll-container activation.\n * This file handles: caption, section backgrounds, body tr/th/td, and variants.\n * No ::slotted() needed: the shadow tree owns all rendered th/td elements.\n */\n\n@layer refine.base {\n :host {\n border: none;\n border-radius: 0;\n box-shadow: var(--table-shadow, none);\n }\n\n /* ── Caption ─────────────────────────────────────────────────────────── */\n\n caption {\n padding: var(--size-3);\n font-size: var(--text-xs);\n font-weight: var(--font-semibold);\n color: var(--color-contrast-500);\n text-align: start;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n caption-side: top;\n background: var(--_header-bg);\n }\n\n /* ── Section backgrounds ─────────────────────────────────────────────── */\n\n thead,\n tfoot {\n background: var(--_header-bg);\n }\n\n thead {\n border-block-end: var(--border) solid var(--_border-color);\n }\n\n tfoot {\n border-block-start: var(--border) solid var(--_border-color);\n }\n\n /* ── Body rows ───────────────────────────────────────────────────────── */\n\n tbody tr {\n border-block-end: var(--border) solid var(--_border-color);\n transition: background var(--transition-fast);\n }\n\n tbody tr:hover {\n background: var(--_row-hover-bg);\n }\n\n /* ── Cells ───────────────────────────────────────────────────────────── */\n\n th,\n td {\n padding: var(--_cell-padding-y) var(--_cell-padding-x);\n font-size: var(--_font-size);\n font-weight: normal;\n vertical-align: middle;\n color: var(--color-contrast-800);\n text-align: start;\n }\n\n /* ── Header cells ────────────────────────────────────────────────────── */\n\n thead th,\n thead td,\n tfoot th,\n tfoot td {\n font-size: var(--text-xs);\n font-weight: var(--font-semibold);\n color: var(--color-contrast-500);\n text-transform: uppercase;\n letter-spacing: 0.04em;\n white-space: nowrap;\n user-select: none;\n }\n}\n\n@layer refine.variants {\n /* ── Bordered: vertical cell separators ─────────────────────────────── */\n\n :host([bordered]) th,\n :host([bordered]) td {\n border-inline-end: var(--border) solid var(--_border-color);\n }\n\n :host([bordered]) th:last-child,\n :host([bordered]) td:last-child {\n border-inline-end: none;\n }\n\n /* ── Striped ─────────────────────────────────────────────────────────── */\n\n :host([striped]) tbody tr:nth-child(even) {\n background: var(--_stripe-bg);\n }\n\n /* ── Sticky header ───────────────────────────────────────────────────── */\n\n /* tableBaseMixin activates overflow-y:auto on .scroll-container when\n [sticky] is present. position:sticky on thead is relative to that context. */\n\n :host([sticky]) thead {\n position: sticky;\n top: 0;\n z-index: 2;\n background: var(--table-sticky-header-bg, color-mix(in oklch, var(--_header-bg) 94%, transparent));\n\n /* border-collapse merges the bottom border into the cell below, which\n scrolls away under the sticky header. Use box-shadow instead: it\n travels with the element regardless of border-collapse. */\n box-shadow: inset 0 calc(var(--border) * -1) 0 var(--_border-color);\n backdrop-filter: blur(var(--table-sticky-blur, var(--blur-md))) saturate(140%);\n }\n}\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"table.css.js","names":[],"sources":["../../../src/content/table/table.css?inline"],"sourcesContent":["/* ore-table — shadow DOM (proxy/mirror).\n *\n * Shadow tree (managed by table.ts):\n * :host display:block — token host (tableBaseMixin)\n * └─ .scroll-container overflow:auto — sticky / max-height context\n * └─ table display:table — native table semantics\n * ├─ caption — optional caption bar\n * ├─ thead — rows built from ore-tr[head]\n * ├─ tbody — rows built from plain ore-tr\n * └─ tfoot — rows built from ore-tr[foot]\n * └─ tr > th / td — mirrored from ore-th / ore-td\n *\n * Light DOM (consumer):\n * <ore-tr head><ore-th>…</ore-th></ore-tr>\n * <ore-tr><ore-td>…</ore-td></ore-tr>\n * <ore-tr foot><ore-td>…</ore-td></ore-tr>\n *\n * tableBaseMixin('table') handles: :host tokens, .scroll-container,\n * table width/collapse, loading state, size variants, fullwidth, bordered,\n * and sticky scroll-container activation.\n * This file handles: caption, section backgrounds, body tr/th/td, and variants.\n * No ::slotted() needed — the shadow tree owns all rendered th/td elements.\n */\n\n@layer refine.base {\n :host {\n border: none;\n border-radius: 0;\n box-shadow: var(--table-shadow, none);\n }\n\n /* ── Caption ─────────────────────────────────────────────────────────── */\n\n caption {\n padding: var(--size-3);\n font-size: var(--text-xs);\n font-weight: var(--font-semibold);\n color: var(--color-contrast-500);\n text-align: start;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n caption-side: top;\n background: var(--_header-bg);\n }\n\n /* ── Section backgrounds ─────────────────────────────────────────────── */\n\n thead,\n tfoot {\n background: var(--_header-bg);\n }\n\n thead {\n border-block-end: var(--border) solid var(--_border-color);\n }\n\n tfoot {\n border-block-start: var(--border) solid var(--_border-color);\n }\n\n /* ── Body rows ───────────────────────────────────────────────────────── */\n\n tbody tr {\n border-block-end: var(--border) solid var(--_border-color);\n transition: background var(--transition-fast);\n }\n\n tbody tr:hover {\n background: var(--_row-hover-bg);\n }\n\n /* ── Cells ───────────────────────────────────────────────────────────── */\n\n th,\n td {\n padding: var(--_cell-padding-y) var(--_cell-padding-x);\n font-size: var(--_font-size);\n font-weight: normal;\n vertical-align: middle;\n color: var(--color-contrast-800);\n text-align: start;\n }\n\n /* ── Header cells ────────────────────────────────────────────────────── */\n\n thead th,\n thead td,\n tfoot th,\n tfoot td {\n font-size: var(--text-xs);\n font-weight: var(--font-semibold);\n color: var(--color-contrast-500);\n text-transform: uppercase;\n letter-spacing: 0.04em;\n white-space: nowrap;\n user-select: none;\n }\n}\n\n@layer refine.variants {\n /* ── Bordered: vertical cell separators ─────────────────────────────── */\n\n :host([bordered]) th,\n :host([bordered]) td {\n border-inline-end: var(--border) solid var(--_border-color);\n }\n\n :host([bordered]) th:last-child,\n :host([bordered]) td:last-child {\n border-inline-end: none;\n }\n\n /* ── Striped ─────────────────────────────────────────────────────────── */\n\n :host([striped]) tbody tr:nth-child(even) {\n background: var(--_stripe-bg);\n }\n\n /* ── Sticky header ───────────────────────────────────────────────────── */\n\n /* tableBaseMixin activates overflow-y:auto on .scroll-container when\n [sticky] is present. position:sticky on thead is relative to that context. */\n\n :host([sticky]) thead {\n position: sticky;\n top: 0;\n z-index: 2;\n background: var(--table-sticky-header-bg, color-mix(in oklch, var(--_header-bg) 94%, transparent));\n\n /* border-collapse merges the bottom border into the cell below, which\n scrolls away under the sticky header. Use box-shadow instead — it\n travels with the element regardless of border-collapse. */\n box-shadow: inset 0 calc(var(--border) * -1) 0 var(--_border-color);\n backdrop-filter: blur(var(--table-sticky-blur, var(--blur-md))) saturate(140%);\n }\n}\n"],"mappings":""}
1
+ {"version":3,"file":"table.css.js","names":[],"sources":["../../../src/content/table/table.css?inline"],"sourcesContent":["/* ore-table: shadow DOM (proxy/mirror).\n *\n * Shadow tree (managed by table.ts):\n * :host (display:block): token host (tableBaseMixin)\n * └─ .scroll-container (overflow:auto): sticky / max-height context\n * └─ table (display:table): native table semantics\n * ├─ caption: optional caption bar\n * ├─ thead: rows built from ore-tr[head]\n * ├─ tbody: rows built from plain ore-tr\n * └─ tfoot: rows built from ore-tr[foot]\n * └─ tr > th / td: mirrored from ore-th / ore-td\n *\n * Light DOM (consumer):\n * <ore-tr head><ore-th>…</ore-th></ore-tr>\n * <ore-tr><ore-td>…</ore-td></ore-tr>\n * <ore-tr foot><ore-td>…</ore-td></ore-tr>\n *\n * tableBaseMixin('table') handles: :host tokens, .scroll-container,\n * table width/collapse, loading state, size variants, fullwidth, bordered,\n * and sticky scroll-container activation.\n * This file handles: caption, section backgrounds, body tr/th/td, and variants.\n * No ::slotted() needed: the shadow tree owns all rendered th/td elements.\n */\n\n@layer refine.base {\n :host {\n border: none;\n border-radius: 0;\n box-shadow: var(--table-shadow, none);\n }\n\n /* ── Caption ─────────────────────────────────────────────────────────── */\n\n caption {\n padding: var(--size-3);\n font-size: var(--text-xs);\n font-weight: var(--font-semibold);\n color: var(--color-contrast-500);\n text-align: start;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n caption-side: top;\n background: var(--_header-bg);\n }\n\n /* ── Section backgrounds ─────────────────────────────────────────────── */\n\n thead,\n tfoot {\n background: var(--_header-bg);\n }\n\n thead {\n border-block-end: var(--border) solid var(--_border-color);\n }\n\n tfoot {\n border-block-start: var(--border) solid var(--_border-color);\n }\n\n /* ── Body rows ───────────────────────────────────────────────────────── */\n\n tbody tr {\n border-block-end: var(--border) solid var(--_border-color);\n transition: background var(--transition-fast);\n }\n\n tbody tr:hover {\n background: var(--_row-hover-bg);\n }\n\n /* ── Cells ───────────────────────────────────────────────────────────── */\n\n th,\n td {\n padding: var(--_cell-padding-y) var(--_cell-padding-x);\n font-size: var(--_font-size);\n font-weight: normal;\n vertical-align: middle;\n color: var(--color-contrast-800);\n text-align: start;\n }\n\n /* ── Header cells ────────────────────────────────────────────────────── */\n\n thead th,\n thead td,\n tfoot th,\n tfoot td {\n font-size: var(--text-xs);\n font-weight: var(--font-semibold);\n color: var(--color-contrast-500);\n text-transform: uppercase;\n letter-spacing: 0.04em;\n white-space: nowrap;\n user-select: none;\n }\n}\n\n@layer refine.variants {\n /* ── Bordered: vertical cell separators ─────────────────────────────── */\n\n :host([bordered]) th,\n :host([bordered]) td {\n border-inline-end: var(--border) solid var(--_border-color);\n }\n\n :host([bordered]) th:last-child,\n :host([bordered]) td:last-child {\n border-inline-end: none;\n }\n\n /* ── Striped ─────────────────────────────────────────────────────────── */\n\n :host([striped]) tbody tr:nth-child(even) {\n background: var(--_stripe-bg);\n }\n\n /* ── Sticky header ───────────────────────────────────────────────────── */\n\n /* tableBaseMixin activates overflow-y:auto on .scroll-container when\n [sticky] is present. position:sticky on thead is relative to that context. */\n\n :host([sticky]) thead {\n position: sticky;\n top: 0;\n z-index: 2;\n background: var(--table-sticky-header-bg, color-mix(in oklch, var(--_header-bg) 94%, transparent));\n\n /* border-collapse merges the bottom border into the cell below, which\n scrolls away under the sticky header. Use box-shadow instead: it\n travels with the element regardless of border-collapse. */\n box-shadow: inset 0 calc(var(--border) * -1) 0 var(--_border-color);\n backdrop-filter: blur(var(--table-sticky-blur, var(--blur-md))) saturate(140%);\n }\n}\n"],"mappings":""}
@@ -2,7 +2,7 @@
2
2
  export type OreTableProps = {
3
3
  /** Adds a thicker outer border */
4
4
  bordered?: boolean;
5
- /** Visible caption text — also used as the accessible table label via `aria-label` */
5
+ /** Visible caption text: also used as the accessible table label via `aria-label` */
6
6
  caption?: string;
7
7
  /** Cell density: `'compact'` | `'cozy'` (default) | `'comfortable'` */
8
8
  density?: 'compact' | 'cozy' | 'comfortable';
@@ -22,8 +22,8 @@ export type OreTableProps = {
22
22
  * into a fully-native shadow `<table>`. Cell attributes (`colspan`, `rowspan`,
23
23
  * `scope`, etc.) are mirrored. Changes are observed and synced incrementally.
24
24
  *
25
- * Native table features — sticky headers, colspan/rowspan, the table layout
26
- * algorithm — all work because the shadow tree contains real table elements.
25
+ * Native table features: sticky headers, colspan/rowspan, the table layout
26
+ * algorithm: all work because the shadow tree contains real table elements.
27
27
  *
28
28
  * @element ore-table
29
29
  *
@@ -1 +1 @@
1
- {"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../../src/content/table/table.ts"],"names":[],"mappings":"AAOA,iCAAiC;AACjC,MAAM,MAAM,aAAa,GAAG;IAC1B,kCAAkC;IAClC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,sFAAsF;IACtF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,OAAO,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,aAAa,CAAC;IAC7C,uDAAuD;IACvD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,yDAAyD;IACzD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,qEAAqE;IACrE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,yCAAyC;IACzC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAkKF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AACH,eAAO,MAAM,SAAS,EAAG,WAAoB,CAAC"}
1
+ {"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../../src/content/table/table.ts"],"names":[],"mappings":"AAOA,iCAAiC;AACjC,MAAM,MAAM,aAAa,GAAG;IAC1B,kCAAkC;IAClC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qFAAqF;IACrF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,OAAO,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,aAAa,CAAC;IAC7C,uDAAuD;IACvD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,yDAAyD;IACzD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,qEAAqE;IACrE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,yCAAyC;IACzC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAkKF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AACH,eAAO,MAAM,SAAS,EAAG,WAAoB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"text.css.cjs","names":[],"sources":["../../../src/content/text/text.css?inline"],"sourcesContent":["/* ========================================\n Base Styles & Defaults\n ======================================== */\n\n:host {\n /* Internal variables with CSS custom property fallbacks */\n --_size: var(--text-size, var(--text-base));\n --_weight: var(--text-weight, var(--font-normal));\n --_color: var(--text-color, var(--text-color-body));\n --_line-height: var(--text-line-height, var(--leading-normal));\n --_letter-spacing: var(--text-letter-spacing, normal);\n\n display: block;\n font-size: var(--_size);\n font-weight: var(--_weight);\n line-height: var(--_line-height);\n color: var(--_color);\n letter-spacing: var(--_letter-spacing);\n}\n\n:host([hidden]) {\n display: none;\n}\n\n/* ========================================\n Unlayered display overrides\n These must live outside any @layer so they can beat the unlayered\n display: block on :host. Same cascade rule that was fixed for [lines].\n ======================================== */\n\n/* Multi-line truncation */\n:host([lines]) {\n display: -webkit-box;\n -webkit-box-orient: vertical;\n overflow: hidden;\n -webkit-line-clamp: var(--_lines);\n}\n\n/* Inline semantic tags — but not when align/truncate force block layout */\n:host(:is([as='span'], [as='label'], [as='code']):not([align], [truncate])) {\n display: inline;\n}\n\n/* ========================================\n Variant Styles\n ======================================== */\n\n/* Body (default) — uses base defaults above */\n\n/* Heading\n Default size: --heading-md (24px)\n Letter-spacing: --tracking-header (-0.05em) per theme guidelines\n Line-height: --leading-tight (1.15) for display headings */\n:host([variant='heading']) {\n --_size: var(--text-size, var(--heading-md));\n --_weight: var(--text-weight, var(--font-semibold));\n --_color: var(--text-color, var(--text-color-heading));\n --_line-height: var(--text-line-height, var(--leading-tight));\n --_letter-spacing: var(--text-letter-spacing, var(--tracking-header));\n}\n\n/* Label — slightly tighter line-height for UI labels */\n:host([variant='label']) {\n --_size: var(--text-size, var(--text-sm));\n --_weight: var(--text-weight, var(--font-medium));\n --_color: var(--text-color, var(--text-color-heading));\n --_line-height: var(--text-line-height, var(--leading-snug));\n}\n\n/* Caption */\n:host([variant='caption']) {\n --_size: var(--text-size, var(--text-sm));\n --_color: var(--text-color, var(--text-color-secondary));\n}\n\n/* Overline */\n:host([variant='overline']) {\n --_size: var(--text-size, var(--text-xs));\n --_weight: var(--text-weight, var(--font-semibold));\n --_line-height: var(--text-line-height, var(--leading-none));\n --_letter-spacing: var(--text-letter-spacing, 0.08em);\n\n text-transform: uppercase;\n}\n\n/* Code */\n:host([variant='code']) {\n --_size: var(--text-size, var(--text-sm));\n\n font-family: var(--font-mono, monospace);\n}\n\n/* ========================================\n Size Variants — body scale (--text-*)\n Used by all variants except heading.\n ======================================== */\n\n:host([size='2xs']) {\n --_size: var(--text-size, var(--text-2xs));\n}\n\n:host([size='xs']) {\n --_size: var(--text-size, var(--text-xs));\n}\n\n:host([size='sm']) {\n --_size: var(--text-size, var(--text-sm));\n}\n\n:host([size='md']) {\n --_size: var(--text-size, var(--text-base));\n}\n\n:host([size='lg']) {\n --_size: var(--text-size, var(--text-lg));\n}\n\n:host([size='xl']) {\n --_size: var(--text-size, var(--text-xl));\n}\n\n:host([size='2xl']) {\n --_size: var(--text-size, var(--text-2xl));\n}\n\n/* ========================================\n Size Variants — heading scale (--heading-*)\n Compound selectors override the body-scale rules above when\n variant=\"heading\" and a size is also provided.\n ======================================== */\n\n:host([variant='heading'][size='xs']) {\n --_size: var(--text-size, var(--heading-xs));\n}\n\n:host([variant='heading'][size='sm']) {\n --_size: var(--text-size, var(--heading-sm));\n}\n\n:host([variant='heading'][size='md']) {\n --_size: var(--text-size, var(--heading-md));\n}\n\n:host([variant='heading'][size='lg']) {\n --_size: var(--text-size, var(--heading-lg));\n}\n\n:host([variant='heading'][size='xl']) {\n --_size: var(--text-size, var(--heading-xl));\n}\n\n:host([variant='heading'][size='2xl']) {\n --_size: var(--text-size, var(--heading-2xl));\n}\n\n/* ========================================\n Weight Variants\n ======================================== */\n\n:host([weight='normal']) {\n --_weight: var(--text-weight, var(--font-normal));\n}\n\n:host([weight='medium']) {\n --_weight: var(--text-weight, var(--font-medium));\n}\n\n:host([weight='semibold']) {\n --_weight: var(--text-weight, var(--font-semibold));\n}\n\n:host([weight='bold']) {\n --_weight: var(--text-weight, var(--font-bold));\n}\n\n/* ========================================\n Color Variants\n Semantic colors map to --text-color-* tokens.\n Theme colors map to --color-* base tokens.\n ======================================== */\n\n:host([color='primary']) {\n --_color: var(--text-color, var(--color-primary));\n}\n\n:host([color='secondary']) {\n --_color: var(--text-color, var(--color-secondary));\n}\n\n:host([color='info']) {\n --_color: var(--text-color, var(--color-info));\n}\n\n:host([color='success']) {\n --_color: var(--text-color, var(--color-success));\n}\n\n:host([color='warning']) {\n --_color: var(--text-color, var(--color-warning));\n}\n\n:host([color='error']) {\n --_color: var(--text-color, var(--color-error));\n}\n\n/* Semantic text colors */\n:host([color='heading']) {\n --_color: var(--text-color, var(--text-color-heading)); /* --color-contrast-900 */\n}\n\n:host([color='body']) {\n --_color: var(--text-color, var(--text-color-body)); /* --color-contrast-800 */\n}\n\n:host([color='muted']) {\n --_color: var(--text-color, var(--text-color-secondary)); /* --color-contrast-600 — AA compliant */\n}\n\n:host([color='tertiary']) {\n --_color: var(--text-color, var(--text-color-tertiary)); /* --color-contrast-500 — AA for large text */\n}\n\n:host([color='disabled']) {\n --_color: var(--text-color, var(--text-color-disabled)); /* --color-contrast-400 */\n}\n\n:host([color='contrast']) {\n --_color: var(--text-color, var(--text-color-contrast)); /* --color-contrast-100 */\n}\n\n@layer refine.utilities {\n /* ========================================\n Alignment\n ======================================== */\n\n :host([align]) {\n display: block;\n }\n\n :host([align='left']) {\n text-align: start;\n }\n\n :host([align='center']) {\n text-align: center;\n }\n\n :host([align='right']) {\n text-align: end;\n }\n\n :host([align='justify']) {\n text-align: justify;\n }\n\n /* ========================================\n Truncate (single-line)\n ======================================== */\n\n :host([truncate]) {\n display: block;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n /* ========================================\n Italic\n ======================================== */\n\n :host([italic]) {\n font-style: italic;\n }\n\n /* ========================================\n Block Display for Certain Tags\n ======================================== */\n\n :host([as='p']),\n :host([as='div']),\n :host(:is([as='h1'], [as='h2'], [as='h3'], [as='h4'], [as='h5'], [as='h6'])) {\n display: block;\n }\n\n /* Note: display: inline for span/label/code is handled outside this @layer\n (above) so it can override the unlayered :host { display: block }. */\n}\n"],"mappings":""}
1
+ {"version":3,"file":"text.css.cjs","names":[],"sources":["../../../src/content/text/text.css?inline"],"sourcesContent":["/* ========================================\n Base Styles & Defaults\n ======================================== */\n\n:host {\n /* Internal variables with CSS custom property fallbacks */\n --_size: var(--text-size, var(--text-base));\n --_weight: var(--text-weight, var(--font-normal));\n --_color: var(--text-color, var(--text-color-body));\n --_line-height: var(--text-line-height, var(--leading-normal));\n --_letter-spacing: var(--text-letter-spacing, normal);\n\n display: block;\n font-size: var(--_size);\n font-weight: var(--_weight);\n line-height: var(--_line-height);\n color: var(--_color);\n letter-spacing: var(--_letter-spacing);\n}\n\n:host([hidden]) {\n display: none;\n}\n\n/* ========================================\n Unlayered display overrides\n These must live outside any @layer so they can beat the unlayered\n display: block on :host. Same cascade rule that was fixed for [lines].\n ======================================== */\n\n/* Multi-line truncation */\n:host([lines]) {\n display: -webkit-box;\n -webkit-box-orient: vertical;\n overflow: hidden;\n -webkit-line-clamp: var(--_lines);\n}\n\n/* Inline semantic tags, but not when align/truncate force block layout */\n:host(:is([as='span'], [as='label'], [as='code']):not([align], [truncate])) {\n display: inline;\n}\n\n/* ========================================\n Variant Styles\n ======================================== */\n\n/* Body (default): uses base defaults above */\n\n/* Heading\n Default size: --heading-md (24px)\n Letter-spacing: --tracking-header (-0.05em) per theme guidelines\n Line-height: --leading-tight (1.15) for display headings */\n:host([variant='heading']) {\n --_size: var(--text-size, var(--heading-md));\n --_weight: var(--text-weight, var(--font-semibold));\n --_color: var(--text-color, var(--text-color-heading));\n --_line-height: var(--text-line-height, var(--leading-tight));\n --_letter-spacing: var(--text-letter-spacing, var(--tracking-header));\n}\n\n/* Label: slightly tighter line-height for UI labels */\n:host([variant='label']) {\n --_size: var(--text-size, var(--text-sm));\n --_weight: var(--text-weight, var(--font-medium));\n --_color: var(--text-color, var(--text-color-heading));\n --_line-height: var(--text-line-height, var(--leading-snug));\n}\n\n/* Caption */\n:host([variant='caption']) {\n --_size: var(--text-size, var(--text-sm));\n --_color: var(--text-color, var(--text-color-secondary));\n}\n\n/* Overline */\n:host([variant='overline']) {\n --_size: var(--text-size, var(--text-xs));\n --_weight: var(--text-weight, var(--font-semibold));\n --_line-height: var(--text-line-height, var(--leading-none));\n --_letter-spacing: var(--text-letter-spacing, 0.08em);\n\n text-transform: uppercase;\n}\n\n/* Code */\n:host([variant='code']) {\n --_size: var(--text-size, var(--text-sm));\n\n font-family: var(--font-mono, monospace);\n}\n\n/* ========================================\n Size Variants: body scale (--text-*)\n Used by all variants except heading.\n ======================================== */\n\n:host([size='2xs']) {\n --_size: var(--text-size, var(--text-2xs));\n}\n\n:host([size='xs']) {\n --_size: var(--text-size, var(--text-xs));\n}\n\n:host([size='sm']) {\n --_size: var(--text-size, var(--text-sm));\n}\n\n:host([size='md']) {\n --_size: var(--text-size, var(--text-base));\n}\n\n:host([size='lg']) {\n --_size: var(--text-size, var(--text-lg));\n}\n\n:host([size='xl']) {\n --_size: var(--text-size, var(--text-xl));\n}\n\n:host([size='2xl']) {\n --_size: var(--text-size, var(--text-2xl));\n}\n\n/* ========================================\n Size Variants: heading scale (--heading-*)\n Compound selectors override the body-scale rules above when\n variant=\"heading\" and a size is also provided.\n ======================================== */\n\n:host([variant='heading'][size='xs']) {\n --_size: var(--text-size, var(--heading-xs));\n}\n\n:host([variant='heading'][size='sm']) {\n --_size: var(--text-size, var(--heading-sm));\n}\n\n:host([variant='heading'][size='md']) {\n --_size: var(--text-size, var(--heading-md));\n}\n\n:host([variant='heading'][size='lg']) {\n --_size: var(--text-size, var(--heading-lg));\n}\n\n:host([variant='heading'][size='xl']) {\n --_size: var(--text-size, var(--heading-xl));\n}\n\n:host([variant='heading'][size='2xl']) {\n --_size: var(--text-size, var(--heading-2xl));\n}\n\n/* ========================================\n Weight Variants\n ======================================== */\n\n:host([weight='normal']) {\n --_weight: var(--text-weight, var(--font-normal));\n}\n\n:host([weight='medium']) {\n --_weight: var(--text-weight, var(--font-medium));\n}\n\n:host([weight='semibold']) {\n --_weight: var(--text-weight, var(--font-semibold));\n}\n\n:host([weight='bold']) {\n --_weight: var(--text-weight, var(--font-bold));\n}\n\n/* ========================================\n Color Variants\n Semantic colors map to --text-color-* tokens.\n Theme colors map to --color-* base tokens.\n ======================================== */\n\n:host([color='primary']) {\n --_color: var(--text-color, var(--color-primary));\n}\n\n:host([color='secondary']) {\n --_color: var(--text-color, var(--color-secondary));\n}\n\n:host([color='info']) {\n --_color: var(--text-color, var(--color-info));\n}\n\n:host([color='success']) {\n --_color: var(--text-color, var(--color-success));\n}\n\n:host([color='warning']) {\n --_color: var(--text-color, var(--color-warning));\n}\n\n:host([color='error']) {\n --_color: var(--text-color, var(--color-error));\n}\n\n/* Semantic text colors */\n:host([color='heading']) {\n --_color: var(--text-color, var(--text-color-heading)); /* --color-contrast-900 */\n}\n\n:host([color='body']) {\n --_color: var(--text-color, var(--text-color-body)); /* --color-contrast-800 */\n}\n\n:host([color='muted']) {\n --_color: var(--text-color, var(--text-color-secondary)); /* --color-contrast-600: AA compliant */\n}\n\n:host([color='tertiary']) {\n --_color: var(--text-color, var(--text-color-tertiary)); /* --color-contrast-500: AA for large text */\n}\n\n:host([color='disabled']) {\n --_color: var(--text-color, var(--text-color-disabled)); /* --color-contrast-400 */\n}\n\n:host([color='contrast']) {\n --_color: var(--text-color, var(--text-color-contrast)); /* --color-contrast-100 */\n}\n\n@layer refine.utilities {\n /* ========================================\n Alignment\n ======================================== */\n\n :host([align]) {\n display: block;\n }\n\n :host([align='left']) {\n text-align: start;\n }\n\n :host([align='center']) {\n text-align: center;\n }\n\n :host([align='right']) {\n text-align: end;\n }\n\n :host([align='justify']) {\n text-align: justify;\n }\n\n /* ========================================\n Truncate (single-line)\n ======================================== */\n\n :host([truncate]) {\n display: block;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n /* ========================================\n Italic\n ======================================== */\n\n :host([italic]) {\n font-style: italic;\n }\n\n /* ========================================\n Block Display for Certain Tags\n ======================================== */\n\n :host([as='p']),\n :host([as='div']),\n :host(:is([as='h1'], [as='h2'], [as='h3'], [as='h4'], [as='h5'], [as='h6'])) {\n display: block;\n }\n\n /* Note: display: inline for span/label/code is handled outside this @layer\n (above) so it can override the unlayered :host { display: block }. */\n}\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"text.css.js","names":[],"sources":["../../../src/content/text/text.css?inline"],"sourcesContent":["/* ========================================\n Base Styles & Defaults\n ======================================== */\n\n:host {\n /* Internal variables with CSS custom property fallbacks */\n --_size: var(--text-size, var(--text-base));\n --_weight: var(--text-weight, var(--font-normal));\n --_color: var(--text-color, var(--text-color-body));\n --_line-height: var(--text-line-height, var(--leading-normal));\n --_letter-spacing: var(--text-letter-spacing, normal);\n\n display: block;\n font-size: var(--_size);\n font-weight: var(--_weight);\n line-height: var(--_line-height);\n color: var(--_color);\n letter-spacing: var(--_letter-spacing);\n}\n\n:host([hidden]) {\n display: none;\n}\n\n/* ========================================\n Unlayered display overrides\n These must live outside any @layer so they can beat the unlayered\n display: block on :host. Same cascade rule that was fixed for [lines].\n ======================================== */\n\n/* Multi-line truncation */\n:host([lines]) {\n display: -webkit-box;\n -webkit-box-orient: vertical;\n overflow: hidden;\n -webkit-line-clamp: var(--_lines);\n}\n\n/* Inline semantic tags — but not when align/truncate force block layout */\n:host(:is([as='span'], [as='label'], [as='code']):not([align], [truncate])) {\n display: inline;\n}\n\n/* ========================================\n Variant Styles\n ======================================== */\n\n/* Body (default) — uses base defaults above */\n\n/* Heading\n Default size: --heading-md (24px)\n Letter-spacing: --tracking-header (-0.05em) per theme guidelines\n Line-height: --leading-tight (1.15) for display headings */\n:host([variant='heading']) {\n --_size: var(--text-size, var(--heading-md));\n --_weight: var(--text-weight, var(--font-semibold));\n --_color: var(--text-color, var(--text-color-heading));\n --_line-height: var(--text-line-height, var(--leading-tight));\n --_letter-spacing: var(--text-letter-spacing, var(--tracking-header));\n}\n\n/* Label — slightly tighter line-height for UI labels */\n:host([variant='label']) {\n --_size: var(--text-size, var(--text-sm));\n --_weight: var(--text-weight, var(--font-medium));\n --_color: var(--text-color, var(--text-color-heading));\n --_line-height: var(--text-line-height, var(--leading-snug));\n}\n\n/* Caption */\n:host([variant='caption']) {\n --_size: var(--text-size, var(--text-sm));\n --_color: var(--text-color, var(--text-color-secondary));\n}\n\n/* Overline */\n:host([variant='overline']) {\n --_size: var(--text-size, var(--text-xs));\n --_weight: var(--text-weight, var(--font-semibold));\n --_line-height: var(--text-line-height, var(--leading-none));\n --_letter-spacing: var(--text-letter-spacing, 0.08em);\n\n text-transform: uppercase;\n}\n\n/* Code */\n:host([variant='code']) {\n --_size: var(--text-size, var(--text-sm));\n\n font-family: var(--font-mono, monospace);\n}\n\n/* ========================================\n Size Variants — body scale (--text-*)\n Used by all variants except heading.\n ======================================== */\n\n:host([size='2xs']) {\n --_size: var(--text-size, var(--text-2xs));\n}\n\n:host([size='xs']) {\n --_size: var(--text-size, var(--text-xs));\n}\n\n:host([size='sm']) {\n --_size: var(--text-size, var(--text-sm));\n}\n\n:host([size='md']) {\n --_size: var(--text-size, var(--text-base));\n}\n\n:host([size='lg']) {\n --_size: var(--text-size, var(--text-lg));\n}\n\n:host([size='xl']) {\n --_size: var(--text-size, var(--text-xl));\n}\n\n:host([size='2xl']) {\n --_size: var(--text-size, var(--text-2xl));\n}\n\n/* ========================================\n Size Variants — heading scale (--heading-*)\n Compound selectors override the body-scale rules above when\n variant=\"heading\" and a size is also provided.\n ======================================== */\n\n:host([variant='heading'][size='xs']) {\n --_size: var(--text-size, var(--heading-xs));\n}\n\n:host([variant='heading'][size='sm']) {\n --_size: var(--text-size, var(--heading-sm));\n}\n\n:host([variant='heading'][size='md']) {\n --_size: var(--text-size, var(--heading-md));\n}\n\n:host([variant='heading'][size='lg']) {\n --_size: var(--text-size, var(--heading-lg));\n}\n\n:host([variant='heading'][size='xl']) {\n --_size: var(--text-size, var(--heading-xl));\n}\n\n:host([variant='heading'][size='2xl']) {\n --_size: var(--text-size, var(--heading-2xl));\n}\n\n/* ========================================\n Weight Variants\n ======================================== */\n\n:host([weight='normal']) {\n --_weight: var(--text-weight, var(--font-normal));\n}\n\n:host([weight='medium']) {\n --_weight: var(--text-weight, var(--font-medium));\n}\n\n:host([weight='semibold']) {\n --_weight: var(--text-weight, var(--font-semibold));\n}\n\n:host([weight='bold']) {\n --_weight: var(--text-weight, var(--font-bold));\n}\n\n/* ========================================\n Color Variants\n Semantic colors map to --text-color-* tokens.\n Theme colors map to --color-* base tokens.\n ======================================== */\n\n:host([color='primary']) {\n --_color: var(--text-color, var(--color-primary));\n}\n\n:host([color='secondary']) {\n --_color: var(--text-color, var(--color-secondary));\n}\n\n:host([color='info']) {\n --_color: var(--text-color, var(--color-info));\n}\n\n:host([color='success']) {\n --_color: var(--text-color, var(--color-success));\n}\n\n:host([color='warning']) {\n --_color: var(--text-color, var(--color-warning));\n}\n\n:host([color='error']) {\n --_color: var(--text-color, var(--color-error));\n}\n\n/* Semantic text colors */\n:host([color='heading']) {\n --_color: var(--text-color, var(--text-color-heading)); /* --color-contrast-900 */\n}\n\n:host([color='body']) {\n --_color: var(--text-color, var(--text-color-body)); /* --color-contrast-800 */\n}\n\n:host([color='muted']) {\n --_color: var(--text-color, var(--text-color-secondary)); /* --color-contrast-600 — AA compliant */\n}\n\n:host([color='tertiary']) {\n --_color: var(--text-color, var(--text-color-tertiary)); /* --color-contrast-500 — AA for large text */\n}\n\n:host([color='disabled']) {\n --_color: var(--text-color, var(--text-color-disabled)); /* --color-contrast-400 */\n}\n\n:host([color='contrast']) {\n --_color: var(--text-color, var(--text-color-contrast)); /* --color-contrast-100 */\n}\n\n@layer refine.utilities {\n /* ========================================\n Alignment\n ======================================== */\n\n :host([align]) {\n display: block;\n }\n\n :host([align='left']) {\n text-align: start;\n }\n\n :host([align='center']) {\n text-align: center;\n }\n\n :host([align='right']) {\n text-align: end;\n }\n\n :host([align='justify']) {\n text-align: justify;\n }\n\n /* ========================================\n Truncate (single-line)\n ======================================== */\n\n :host([truncate]) {\n display: block;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n /* ========================================\n Italic\n ======================================== */\n\n :host([italic]) {\n font-style: italic;\n }\n\n /* ========================================\n Block Display for Certain Tags\n ======================================== */\n\n :host([as='p']),\n :host([as='div']),\n :host(:is([as='h1'], [as='h2'], [as='h3'], [as='h4'], [as='h5'], [as='h6'])) {\n display: block;\n }\n\n /* Note: display: inline for span/label/code is handled outside this @layer\n (above) so it can override the unlayered :host { display: block }. */\n}\n"],"mappings":""}
1
+ {"version":3,"file":"text.css.js","names":[],"sources":["../../../src/content/text/text.css?inline"],"sourcesContent":["/* ========================================\n Base Styles & Defaults\n ======================================== */\n\n:host {\n /* Internal variables with CSS custom property fallbacks */\n --_size: var(--text-size, var(--text-base));\n --_weight: var(--text-weight, var(--font-normal));\n --_color: var(--text-color, var(--text-color-body));\n --_line-height: var(--text-line-height, var(--leading-normal));\n --_letter-spacing: var(--text-letter-spacing, normal);\n\n display: block;\n font-size: var(--_size);\n font-weight: var(--_weight);\n line-height: var(--_line-height);\n color: var(--_color);\n letter-spacing: var(--_letter-spacing);\n}\n\n:host([hidden]) {\n display: none;\n}\n\n/* ========================================\n Unlayered display overrides\n These must live outside any @layer so they can beat the unlayered\n display: block on :host. Same cascade rule that was fixed for [lines].\n ======================================== */\n\n/* Multi-line truncation */\n:host([lines]) {\n display: -webkit-box;\n -webkit-box-orient: vertical;\n overflow: hidden;\n -webkit-line-clamp: var(--_lines);\n}\n\n/* Inline semantic tags, but not when align/truncate force block layout */\n:host(:is([as='span'], [as='label'], [as='code']):not([align], [truncate])) {\n display: inline;\n}\n\n/* ========================================\n Variant Styles\n ======================================== */\n\n/* Body (default): uses base defaults above */\n\n/* Heading\n Default size: --heading-md (24px)\n Letter-spacing: --tracking-header (-0.05em) per theme guidelines\n Line-height: --leading-tight (1.15) for display headings */\n:host([variant='heading']) {\n --_size: var(--text-size, var(--heading-md));\n --_weight: var(--text-weight, var(--font-semibold));\n --_color: var(--text-color, var(--text-color-heading));\n --_line-height: var(--text-line-height, var(--leading-tight));\n --_letter-spacing: var(--text-letter-spacing, var(--tracking-header));\n}\n\n/* Label: slightly tighter line-height for UI labels */\n:host([variant='label']) {\n --_size: var(--text-size, var(--text-sm));\n --_weight: var(--text-weight, var(--font-medium));\n --_color: var(--text-color, var(--text-color-heading));\n --_line-height: var(--text-line-height, var(--leading-snug));\n}\n\n/* Caption */\n:host([variant='caption']) {\n --_size: var(--text-size, var(--text-sm));\n --_color: var(--text-color, var(--text-color-secondary));\n}\n\n/* Overline */\n:host([variant='overline']) {\n --_size: var(--text-size, var(--text-xs));\n --_weight: var(--text-weight, var(--font-semibold));\n --_line-height: var(--text-line-height, var(--leading-none));\n --_letter-spacing: var(--text-letter-spacing, 0.08em);\n\n text-transform: uppercase;\n}\n\n/* Code */\n:host([variant='code']) {\n --_size: var(--text-size, var(--text-sm));\n\n font-family: var(--font-mono, monospace);\n}\n\n/* ========================================\n Size Variants: body scale (--text-*)\n Used by all variants except heading.\n ======================================== */\n\n:host([size='2xs']) {\n --_size: var(--text-size, var(--text-2xs));\n}\n\n:host([size='xs']) {\n --_size: var(--text-size, var(--text-xs));\n}\n\n:host([size='sm']) {\n --_size: var(--text-size, var(--text-sm));\n}\n\n:host([size='md']) {\n --_size: var(--text-size, var(--text-base));\n}\n\n:host([size='lg']) {\n --_size: var(--text-size, var(--text-lg));\n}\n\n:host([size='xl']) {\n --_size: var(--text-size, var(--text-xl));\n}\n\n:host([size='2xl']) {\n --_size: var(--text-size, var(--text-2xl));\n}\n\n/* ========================================\n Size Variants: heading scale (--heading-*)\n Compound selectors override the body-scale rules above when\n variant=\"heading\" and a size is also provided.\n ======================================== */\n\n:host([variant='heading'][size='xs']) {\n --_size: var(--text-size, var(--heading-xs));\n}\n\n:host([variant='heading'][size='sm']) {\n --_size: var(--text-size, var(--heading-sm));\n}\n\n:host([variant='heading'][size='md']) {\n --_size: var(--text-size, var(--heading-md));\n}\n\n:host([variant='heading'][size='lg']) {\n --_size: var(--text-size, var(--heading-lg));\n}\n\n:host([variant='heading'][size='xl']) {\n --_size: var(--text-size, var(--heading-xl));\n}\n\n:host([variant='heading'][size='2xl']) {\n --_size: var(--text-size, var(--heading-2xl));\n}\n\n/* ========================================\n Weight Variants\n ======================================== */\n\n:host([weight='normal']) {\n --_weight: var(--text-weight, var(--font-normal));\n}\n\n:host([weight='medium']) {\n --_weight: var(--text-weight, var(--font-medium));\n}\n\n:host([weight='semibold']) {\n --_weight: var(--text-weight, var(--font-semibold));\n}\n\n:host([weight='bold']) {\n --_weight: var(--text-weight, var(--font-bold));\n}\n\n/* ========================================\n Color Variants\n Semantic colors map to --text-color-* tokens.\n Theme colors map to --color-* base tokens.\n ======================================== */\n\n:host([color='primary']) {\n --_color: var(--text-color, var(--color-primary));\n}\n\n:host([color='secondary']) {\n --_color: var(--text-color, var(--color-secondary));\n}\n\n:host([color='info']) {\n --_color: var(--text-color, var(--color-info));\n}\n\n:host([color='success']) {\n --_color: var(--text-color, var(--color-success));\n}\n\n:host([color='warning']) {\n --_color: var(--text-color, var(--color-warning));\n}\n\n:host([color='error']) {\n --_color: var(--text-color, var(--color-error));\n}\n\n/* Semantic text colors */\n:host([color='heading']) {\n --_color: var(--text-color, var(--text-color-heading)); /* --color-contrast-900 */\n}\n\n:host([color='body']) {\n --_color: var(--text-color, var(--text-color-body)); /* --color-contrast-800 */\n}\n\n:host([color='muted']) {\n --_color: var(--text-color, var(--text-color-secondary)); /* --color-contrast-600: AA compliant */\n}\n\n:host([color='tertiary']) {\n --_color: var(--text-color, var(--text-color-tertiary)); /* --color-contrast-500: AA for large text */\n}\n\n:host([color='disabled']) {\n --_color: var(--text-color, var(--text-color-disabled)); /* --color-contrast-400 */\n}\n\n:host([color='contrast']) {\n --_color: var(--text-color, var(--text-color-contrast)); /* --color-contrast-100 */\n}\n\n@layer refine.utilities {\n /* ========================================\n Alignment\n ======================================== */\n\n :host([align]) {\n display: block;\n }\n\n :host([align='left']) {\n text-align: start;\n }\n\n :host([align='center']) {\n text-align: center;\n }\n\n :host([align='right']) {\n text-align: end;\n }\n\n :host([align='justify']) {\n text-align: justify;\n }\n\n /* ========================================\n Truncate (single-line)\n ======================================== */\n\n :host([truncate]) {\n display: block;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n /* ========================================\n Italic\n ======================================== */\n\n :host([italic]) {\n font-style: italic;\n }\n\n /* ========================================\n Block Display for Certain Tags\n ======================================== */\n\n :host([as='p']),\n :host([as='div']),\n :host(:is([as='h1'], [as='h2'], [as='h3'], [as='h4'], [as='h5'], [as='h6'])) {\n display: block;\n }\n\n /* Note: display: inline for span/label/code is handled outside this @layer\n (above) so it can override the unlayered :host { display: block }. */\n}\n"],"mappings":""}
@@ -2,7 +2,7 @@
2
2
  export type OreTextProps = {
3
3
  /** Text alignment */
4
4
  align?: 'left' | 'center' | 'right' | 'justify';
5
- /** Semantic HTML element to render as — sets the correct ARIA role/level on the host */
5
+ /** Semantic HTML element to render as: sets the correct ARIA role/level on the host */
6
6
  as?: 'span' | 'p' | 'div' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'label' | 'code';
7
7
  /** Text color (semantic + theme colors) */
8
8
  color?: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error' | 'heading' | 'body' | 'muted' | 'tertiary' | 'disabled' | 'contrast';
@@ -10,7 +10,7 @@ export type OreTextProps = {
10
10
  italic?: boolean;
11
11
  /** Clamp text to N lines with an ellipsis (multi-line truncation) */
12
12
  lines?: number;
13
- /** Text size — maps to --text-* tokens for body variants and --heading-* tokens for the heading variant */
13
+ /** Text size: maps to --text-* tokens for body variants and --heading-* tokens for the heading variant */
14
14
  size?: '2xs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';
15
15
  /** Enable single-line text truncation with ellipsis */
16
16
  truncate?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../../src/content/text/text.ts"],"names":[],"mappings":"AAIA,gCAAgC;AAChC,MAAM,MAAM,YAAY,GAAG;IACzB,qBAAqB;IACrB,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;IAChD,wFAAwF;IACxF,EAAE,CAAC,EAAE,MAAM,GAAG,GAAG,GAAG,KAAK,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,OAAO,GAAG,MAAM,CAAC;IACvF,2CAA2C;IAC3C,KAAK,CAAC,EACF,SAAS,GACT,WAAW,GACX,MAAM,GACN,SAAS,GACT,SAAS,GACT,OAAO,GACP,SAAS,GACT,MAAM,GACN,OAAO,GACP,UAAU,GACV,UAAU,GACV,UAAU,CAAC;IACf,wBAAwB;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2GAA2G;IAC3G,IAAI,CAAC,EAAE,KAAK,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,CAAC;IACxD,uDAAuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,4BAA4B;IAC5B,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC;IACzE,kBAAkB;IAClB,MAAM,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,MAAM,CAAC;CACpD,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,eAAO,MAAM,QAAQ,EAAG,UAAmB,CAAC"}
1
+ {"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../../src/content/text/text.ts"],"names":[],"mappings":"AAIA,gCAAgC;AAChC,MAAM,MAAM,YAAY,GAAG;IACzB,qBAAqB;IACrB,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;IAChD,uFAAuF;IACvF,EAAE,CAAC,EAAE,MAAM,GAAG,GAAG,GAAG,KAAK,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,OAAO,GAAG,MAAM,CAAC;IACvF,2CAA2C;IAC3C,KAAK,CAAC,EACF,SAAS,GACT,WAAW,GACX,MAAM,GACN,SAAS,GACT,SAAS,GACT,OAAO,GACP,SAAS,GACT,MAAM,GACN,OAAO,GACP,UAAU,GACV,UAAU,GACV,UAAU,CAAC;IACf,wBAAwB;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0GAA0G;IAC1G,IAAI,CAAC,EAAE,KAAK,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,CAAC;IACxD,uDAAuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,4BAA4B;IAC5B,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC;IACzE,kBAAkB;IAClB,MAAM,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,MAAM,CAAC;CACpD,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,eAAO,MAAM,QAAQ,EAAG,UAAmB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"cookie-banner.cjs","names":[],"sources":["../src/feedback/cookie-banner/cookie-banner.ts"],"sourcesContent":["import { createId, define, each, getHost, html, prop, useEmit, when } from '@vielzeug/ore';\nimport { signal, watch } from '@vielzeug/ripple';\n\nimport { reducedMotionMixin } from '../../styles';\n\n// The child components this banner renders. The bare-import form is not enough:\n// the per-entry library build drops side-effect-only imports between entry\n// modules, so these re-export the tags as bindings — the bundler keeps the\n// module link, and importing `@vielzeug/refine/cookie-banner` registers\n// ore-button and ore-checkbox on its own.\n\nimport { eventFieldChecked } from '../../inputs/shared/native-field-event';\nimport componentStyles from './cookie-banner.css?inline';\n\nexport { BUTTON_TAG } from '../../inputs/button/button';\nexport { CHECKBOX_TAG } from '../../inputs/checkbox/checkbox';\n/** A consent category offered as an opt-in checkbox. `id` is the key the `decide` detail is built from. */\nexport type OreCookieBannerCategory = { description?: string; id: string; label: string };\n\n/** All rendered labels, each with an English default — pass translated strings for other locales. */\nexport type OreCookieBannerLabels = Partial<{\n acceptAll: string;\n essential: string;\n essentialNote: string;\n heading: string;\n reject: string;\n save: string;\n}>;\n\n/** The consent record emitted by `decide`: every category id plus `essential`, always true. */\nexport type CookieConsentRecord = Record<string, boolean>;\n\n/** Element interface exposing the imperative API for `ore-cookie-banner`. */\nexport interface CookieBannerElement extends HTMLElement, OreCookieBannerProps {\n /** Hides the banner without emitting anything — persistence stays with the consumer. */\n hide(): void;\n /** Shows the banner again, for example from a \"Cookie settings\" link after a decision. */\n show(): void;\n}\n\nexport type OreCookieBannerEvents = {\n /** A decision was made. `detail.consent` holds every category id; persist it and gate embeds on it. */\n decide: { consent: CookieConsentRecord };\n};\n\nexport type OreCookieBannerProps = {\n /** Optional categories rendered as checkboxes; \"Essential\" is always shown as always-on. */\n categories?: OreCookieBannerCategory[];\n /** Current consent record, used to seed the checkboxes when the banner is shown again. */\n consent?: CookieConsentRecord;\n /** Hides the banner automatically after `decide` fires (default true). Set false to keep it open. */\n hideOnDecide?: boolean;\n /** All rendered labels, each with an English default. */\n labels?: OreCookieBannerLabels;\n /** Viewport edge the banner docks to. */\n position?: 'bottom' | 'top';\n};\n\nconst DEFAULT_LABELS = {\n acceptAll: 'Accept all',\n essential: 'Essential',\n essentialNote: 'Required for the site to work',\n heading: 'Your privacy',\n reject: 'Reject non-essential',\n save: 'Save choices',\n} as const;\n\n/**\n * A fixed-position consent banner for cookie/tracker opt-in: a short policy text\n * (default slot, links included), optional per-category opt-in checkboxes with\n * descriptions, and accept-all / reject / save actions.\n *\n * The layout is a single column — heading, policy text, a scrollable category\n * panel, and actions — that scales linearly from one to many categories. Each\n * category renders as a checkbox row; its optional `description` passes through\n * the checkbox's `helper` mechanism, so it is both visible below the label and\n * linked to the control via `aria-describedby`. The category panel scrolls\n * internally when it exceeds `--cookie-banner-categories-max-height`, so the\n * banner itself never grows past the viewport.\n *\n * The banner owns presentation only. It never stores anything: listen for `decide`,\n * persist the emitted record yourself (localStorage, a CMP, your own backend), and\n * gate third-party embeds on it. The banner hides itself after `decide` unless\n * `hide-on-decide` is set to false. Call `show()` again to let the user revise\n * their choice.\n *\n * The banner is a non-modal `role=\"dialog\"`: screen readers announce it when it\n * appears, focus moves to the dialog card itself on `show()` — a neutral target,\n * so no action is preselected for keyboard users — and returns to the previously\n * focused element on `hide()`. A banner that is simply present at page load (never\n * shown via `show()`) does not steal focus and is not announced; consumers that\n * want a load-time announcement should call `show()` from a user gesture.\n *\n * The `decide` record contains exactly the currently configured category ids\n * (plus `essential`, always true). Replace — do not merge — the stored record\n * with it, so categories removed between sessions drop their stale keys.\n *\n * @element ore-cookie-banner\n *\n * @attr {string} position - Viewport edge: 'bottom' (default) | 'top'\n * @attr {boolean} hide-on-decide - Hides the banner after `decide` (default true)\n *\n * @fires decide - A decision was made. detail: { consent } — every category id plus `essential`, always true.\n *\n * @slot - Policy text, including links to the privacy policy and imprint\n *\n * @cssprop --cookie-banner-width - Maximum width of the banner card (default min(560px, viewport-fit))\n * @cssprop --cookie-banner-inset - Distance from the viewport edges (default --size-4)\n * @cssprop --cookie-banner-z-index - Stacking order (default --z-modal)\n * @cssprop --cookie-banner-categories-max-height - Category panel scroll threshold (default 16rem)\n *\n * @part banner - The banner card\n * @part text - The slot wrapper for the policy text\n * @part categories - The scrollable category panel\n * @part actions - The action buttons\n *\n * @example\n * ```html\n * <ore-cookie-banner>\n * We use cookies to keep you logged in and, with your consent, to embed music\n * from YouTube. <a href=\"/privacy\">Privacy policy</a>.\n * </ore-cookie-banner>\n * <script type=\"module\">\n * import '@vielzeug/refine/cookie-banner';\n *\n * const banner = document.querySelector('ore-cookie-banner');\n * banner.categories = [\n * { id: 'music', label: 'Music embeds', description: 'Embed music from YouTube' },\n * { id: 'stats', label: 'Statistics', description: 'Anonymous usage analytics' },\n * ];\n * banner.addEventListener('decide', (event) => {\n * localStorage.setItem('consent', JSON.stringify(event.detail.consent));\n * });\n * </script>\n * ```\n */\nexport const COOKIE_BANNER_TAG = 'ore-cookie-banner' as const;\ndefine<OreCookieBannerProps>(COOKIE_BANNER_TAG, {\n props: {\n categories: prop.data<OreCookieBannerCategory[]>([]),\n consent: prop.data<CookieConsentRecord>({}),\n hideOnDecide: prop.bool(true),\n labels: prop.data<Partial<OreCookieBannerLabels>>({}),\n position: prop.string<'bottom' | 'top'>(),\n },\n setup(props) {\n const host = getHost() as CookieBannerElement;\n const emit = useEmit<OreCookieBannerEvents>();\n const headingId = createId('cookie-banner-heading');\n const textId = createId('cookie-banner-text');\n\n // Working copy of the checkbox state while the banner is open; seeded from\n // `consent` whenever the banner is (re)shown.\n const draft = signal<CookieConsentRecord>({});\n\n const seedDraft = (): void => {\n const base = props.consent.value ?? {};\n draft.value = Object.fromEntries(\n (props.categories.value ?? []).map((category) => [category.id, base[category.id] === true]),\n );\n };\n watch(() => props.consent.value, seedDraft);\n watch(() => props.categories.value, seedDraft);\n seedDraft();\n\n const label = (key: keyof typeof DEFAULT_LABELS): string => props.labels.value?.[key] ?? DEFAULT_LABELS[key];\n\n // The element that had focus before the banner opened; `hide()` returns to it.\n let restoreFocusTo: HTMLElement | null = null;\n\n // Focus lands on the dialog card itself — a neutral target, so no action is\n // preselected for keyboard users. Screen readers announce the dialog's name\n // when focus enters it.\n const focusCard = (): void => {\n const card = host.shadowRoot?.querySelector<HTMLElement>('.banner');\n (card ?? host).focus();\n };\n\n const decide = (consent: CookieConsentRecord): void => {\n emit('decide', { consent: { ...consent, essential: true } });\n if (props.hideOnDecide.value !== false) host.hide();\n };\n\n const acceptAll = (): void => {\n decide(Object.fromEntries((props.categories.value ?? []).map((category) => [category.id, true])));\n };\n\n const reject = (): void => {\n decide(Object.fromEntries((props.categories.value ?? []).map((category) => [category.id, false])));\n };\n\n const save = (): void => {\n decide({ ...draft.value });\n };\n\n const setCategory = (id: string, checked: boolean): void => {\n draft.value = { ...draft.value, [id]: checked };\n };\n\n host.show = (): void => {\n if (!host.hidden) return;\n restoreFocusTo = document.activeElement instanceof HTMLElement ? document.activeElement : null;\n seedDraft();\n host.hidden = false;\n focusCard();\n };\n host.hide = (): void => {\n host.hidden = true;\n restoreFocusTo?.focus();\n restoreFocusTo = null;\n };\n\n const categories = (): OreCookieBannerCategory[] => props.categories.value ?? [];\n\n return html`\n <div\n class=\"banner\"\n part=\"banner\"\n role=\"dialog\"\n aria-modal=\"false\"\n aria-labelledby=\"${headingId}\"\n aria-describedby=\"${textId}\"\n tabindex=\"-1\">\n <h2 class=\"heading\" part=\"heading\" id=\"${headingId}\">${() => label('heading')}</h2>\n <div class=\"text\" part=\"text\" id=\"${textId}\">\n <slot></slot>\n </div>\n ${when(\n () => categories().length > 0,\n () => html`\n <div class=\"categories\" part=\"categories\">\n <div class=\"category-row\">\n <ore-checkbox checked disabled helper=\"${() => label('essentialNote')}\">\n ${() => label('essential')}\n </ore-checkbox>\n </div>\n ${each(\n categories,\n (category) => category.id,\n (category) => html`\n <div class=\"category-row\">\n <ore-checkbox\n checked=\"${() => draft.value[category.value.id] === true}\"\n helper=\"${() => category.value.description ?? ''}\"\n @change=\"${(event: Event) => setCategory(category.value.id, eventFieldChecked(event))}\">\n ${() => category.value.label}\n </ore-checkbox>\n </div>\n `,\n )}\n </div>\n `,\n )}\n <div class=\"actions\" part=\"actions\">\n <ore-button size=\"sm\" variant=\"ghost\" @click=\"${reject}\">${() => label('reject')}</ore-button>\n ${when(\n () => categories().length > 0,\n () => html`<ore-button size=\"sm\" variant=\"bordered\" @click=\"${save}\">${() => label('save')}</ore-button>`,\n )}\n <ore-button color=\"primary\" size=\"sm\" @click=\"${acceptAll}\">${() => label('acceptAll')}</ore-button>\n </div>\n </div>\n `;\n },\n styles: [reducedMotionMixin, componentStyles],\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"cookie-banner.cjs","names":[],"sources":["../src/feedback/cookie-banner/cookie-banner.ts"],"sourcesContent":["import { createId, define, each, getHost, html, prop, useEmit, when } from '@vielzeug/ore';\nimport { signal, watch } from '@vielzeug/ripple';\n\nimport { reducedMotionMixin } from '../../styles';\n\n// The child components this banner renders. The bare-import form is not enough:\n// the per-entry library build drops side-effect-only imports between entry\n// modules, so these re-export the tags as bindings: the bundler keeps the\n// module link, and importing `@vielzeug/refine/cookie-banner` registers\n// ore-button and ore-checkbox on its own.\n\nimport { eventFieldChecked } from '../../inputs/shared/native-field-event';\nimport componentStyles from './cookie-banner.css?inline';\n\nexport { BUTTON_TAG } from '../../inputs/button/button';\nexport { CHECKBOX_TAG } from '../../inputs/checkbox/checkbox';\n/** A consent category offered as an opt-in checkbox. `id` is the key the `decide` detail is built from. */\nexport type OreCookieBannerCategory = { description?: string; id: string; label: string };\n\n/** All rendered labels, each with an English default: pass translated strings for other locales. */\nexport type OreCookieBannerLabels = Partial<{\n acceptAll: string;\n essential: string;\n essentialNote: string;\n heading: string;\n reject: string;\n save: string;\n}>;\n\n/** The consent record emitted by `decide`: every category id plus `essential`, always true. */\nexport type CookieConsentRecord = Record<string, boolean>;\n\n/** Element interface exposing the imperative API for `ore-cookie-banner`. */\nexport interface CookieBannerElement extends HTMLElement, OreCookieBannerProps {\n /** Hides the banner without emitting anything: persistence stays with the consumer. */\n hide(): void;\n /** Shows the banner again, for example from a \"Cookie settings\" link after a decision. */\n show(): void;\n}\n\nexport type OreCookieBannerEvents = {\n /** A decision was made. `detail.consent` holds every category id; persist it and gate embeds on it. */\n decide: { consent: CookieConsentRecord };\n};\n\nexport type OreCookieBannerProps = {\n /** Optional categories rendered as checkboxes; \"Essential\" is always shown as always-on. */\n categories?: OreCookieBannerCategory[];\n /** Current consent record, used to seed the checkboxes when the banner is shown again. */\n consent?: CookieConsentRecord;\n /** Hides the banner automatically after `decide` fires (default true). Set false to keep it open. */\n hideOnDecide?: boolean;\n /** All rendered labels, each with an English default. */\n labels?: OreCookieBannerLabels;\n /** Viewport edge the banner docks to. */\n position?: 'bottom' | 'top';\n};\n\nconst DEFAULT_LABELS = {\n acceptAll: 'Accept all',\n essential: 'Essential',\n essentialNote: 'Required for the site to work',\n heading: 'Your privacy',\n reject: 'Reject non-essential',\n save: 'Save choices',\n} as const;\n\n/**\n * A fixed-position consent banner for cookie/tracker opt-in: a short policy text\n * (default slot, links included), optional per-category opt-in checkboxes with\n * descriptions, and accept-all / reject / save actions.\n *\n * The layout is a single column: heading, policy text, a scrollable category\n * panel, and actions, that scales linearly from one to many categories. Each\n * category renders as a checkbox row; its optional `description` passes through\n * the checkbox's `helper` mechanism, so it is both visible below the label and\n * linked to the control via `aria-describedby`. The category panel scrolls\n * internally when it exceeds `--cookie-banner-categories-max-height`, so the\n * banner itself never grows past the viewport.\n *\n * The banner owns presentation only. It never stores anything: listen for `decide`,\n * persist the emitted record yourself (localStorage, a CMP, your own backend), and\n * gate third-party embeds on it. The banner hides itself after `decide` unless\n * `hide-on-decide` is set to false. Call `show()` again to let the user revise\n * their choice.\n *\n * The banner is a non-modal `role=\"dialog\"`: screen readers announce it when it\n * appears, focus moves to the dialog card itself on `show()`: a neutral target,\n * so no action is preselected for keyboard users, and returns to the previously\n * focused element on `hide()`. A banner that is simply present at page load (never\n * shown via `show()`) does not steal focus and is not announced; consumers that\n * want a load-time announcement should call `show()` from a user gesture.\n *\n * The `decide` record contains exactly the currently configured category ids\n * (plus `essential`, always true). Replace: do not merge: the stored record\n * with it, so categories removed between sessions drop their stale keys.\n *\n * @element ore-cookie-banner\n *\n * @attr {string} position - Viewport edge: 'bottom' (default) | 'top'\n * @attr {boolean} hide-on-decide - Hides the banner after `decide` (default true)\n *\n * @fires decide - A decision was made. detail: { consent }: every category id plus `essential`, always true.\n *\n * @slot - Policy text, including links to the privacy policy and imprint\n *\n * @cssprop --cookie-banner-width - Maximum width of the banner card (default min(560px, viewport-fit))\n * @cssprop --cookie-banner-inset - Distance from the viewport edges (default --size-4)\n * @cssprop --cookie-banner-z-index - Stacking order (default --z-modal)\n * @cssprop --cookie-banner-categories-max-height - Category panel scroll threshold (default 16rem)\n *\n * @part banner - The banner card\n * @part text - The slot wrapper for the policy text\n * @part categories - The scrollable category panel\n * @part actions - The action buttons\n *\n * @example\n * ```html\n * <ore-cookie-banner>\n * We use cookies to keep you logged in and, with your consent, to embed music\n * from YouTube. <a href=\"/privacy\">Privacy policy</a>.\n * </ore-cookie-banner>\n * <script type=\"module\">\n * import '@vielzeug/refine/cookie-banner';\n *\n * const banner = document.querySelector('ore-cookie-banner');\n * banner.categories = [\n * { id: 'music', label: 'Music embeds', description: 'Embed music from YouTube' },\n * { id: 'stats', label: 'Statistics', description: 'Anonymous usage analytics' },\n * ];\n * banner.addEventListener('decide', (event) => {\n * localStorage.setItem('consent', JSON.stringify(event.detail.consent));\n * });\n * </script>\n * ```\n */\nexport const COOKIE_BANNER_TAG = 'ore-cookie-banner' as const;\ndefine<OreCookieBannerProps>(COOKIE_BANNER_TAG, {\n props: {\n categories: prop.data<OreCookieBannerCategory[]>([]),\n consent: prop.data<CookieConsentRecord>({}),\n hideOnDecide: prop.bool(true),\n labels: prop.data<Partial<OreCookieBannerLabels>>({}),\n position: prop.string<'bottom' | 'top'>(),\n },\n setup(props) {\n const host = getHost() as CookieBannerElement;\n const emit = useEmit<OreCookieBannerEvents>();\n const headingId = createId('cookie-banner-heading');\n const textId = createId('cookie-banner-text');\n\n // Working copy of the checkbox state while the banner is open; seeded from\n // `consent` whenever the banner is (re)shown.\n const draft = signal<CookieConsentRecord>({});\n\n const seedDraft = (): void => {\n const base = props.consent.value ?? {};\n draft.value = Object.fromEntries(\n (props.categories.value ?? []).map((category) => [category.id, base[category.id] === true]),\n );\n };\n watch(() => props.consent.value, seedDraft);\n watch(() => props.categories.value, seedDraft);\n seedDraft();\n\n const label = (key: keyof typeof DEFAULT_LABELS): string => props.labels.value?.[key] ?? DEFAULT_LABELS[key];\n\n // The element that had focus before the banner opened; `hide()` returns to it.\n let restoreFocusTo: HTMLElement | null = null;\n\n // Focus lands on the dialog card itself: a neutral target, so no action is\n // preselected for keyboard users. Screen readers announce the dialog's name\n // when focus enters it.\n const focusCard = (): void => {\n const card = host.shadowRoot?.querySelector<HTMLElement>('.banner');\n (card ?? host).focus();\n };\n\n const decide = (consent: CookieConsentRecord): void => {\n emit('decide', { consent: { ...consent, essential: true } });\n if (props.hideOnDecide.value !== false) host.hide();\n };\n\n const acceptAll = (): void => {\n decide(Object.fromEntries((props.categories.value ?? []).map((category) => [category.id, true])));\n };\n\n const reject = (): void => {\n decide(Object.fromEntries((props.categories.value ?? []).map((category) => [category.id, false])));\n };\n\n const save = (): void => {\n decide({ ...draft.value });\n };\n\n const setCategory = (id: string, checked: boolean): void => {\n draft.value = { ...draft.value, [id]: checked };\n };\n\n host.show = (): void => {\n if (!host.hidden) return;\n restoreFocusTo = document.activeElement instanceof HTMLElement ? document.activeElement : null;\n seedDraft();\n host.hidden = false;\n focusCard();\n };\n host.hide = (): void => {\n host.hidden = true;\n restoreFocusTo?.focus();\n restoreFocusTo = null;\n };\n\n const categories = (): OreCookieBannerCategory[] => props.categories.value ?? [];\n\n return html`\n <div\n class=\"banner\"\n part=\"banner\"\n role=\"dialog\"\n aria-modal=\"false\"\n aria-labelledby=\"${headingId}\"\n aria-describedby=\"${textId}\"\n tabindex=\"-1\">\n <h2 class=\"heading\" part=\"heading\" id=\"${headingId}\">${() => label('heading')}</h2>\n <div class=\"text\" part=\"text\" id=\"${textId}\">\n <slot></slot>\n </div>\n ${when(\n () => categories().length > 0,\n () => html`\n <div class=\"categories\" part=\"categories\">\n <div class=\"category-row\">\n <ore-checkbox checked disabled helper=\"${() => label('essentialNote')}\">\n ${() => label('essential')}\n </ore-checkbox>\n </div>\n ${each(\n categories,\n (category) => category.id,\n (category) => html`\n <div class=\"category-row\">\n <ore-checkbox\n checked=\"${() => draft.value[category.value.id] === true}\"\n helper=\"${() => category.value.description ?? ''}\"\n @change=\"${(event: Event) => setCategory(category.value.id, eventFieldChecked(event))}\">\n ${() => category.value.label}\n </ore-checkbox>\n </div>\n `,\n )}\n </div>\n `,\n )}\n <div class=\"actions\" part=\"actions\">\n <ore-button size=\"sm\" variant=\"ghost\" @click=\"${reject}\">${() => label('reject')}</ore-button>\n ${when(\n () => categories().length > 0,\n () => html`<ore-button size=\"sm\" variant=\"bordered\" @click=\"${save}\">${() => label('save')}</ore-button>`,\n )}\n <ore-button color=\"primary\" size=\"sm\" @click=\"${acceptAll}\">${() => label('acceptAll')}</ore-button>\n </div>\n </div>\n `;\n },\n styles: [reducedMotionMixin, componentStyles],\n});\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"cookie-banner.js","names":[],"sources":["../src/feedback/cookie-banner/cookie-banner.ts"],"sourcesContent":["import { createId, define, each, getHost, html, prop, useEmit, when } from '@vielzeug/ore';\nimport { signal, watch } from '@vielzeug/ripple';\n\nimport { reducedMotionMixin } from '../../styles';\n\n// The child components this banner renders. The bare-import form is not enough:\n// the per-entry library build drops side-effect-only imports between entry\n// modules, so these re-export the tags as bindings — the bundler keeps the\n// module link, and importing `@vielzeug/refine/cookie-banner` registers\n// ore-button and ore-checkbox on its own.\n\nimport { eventFieldChecked } from '../../inputs/shared/native-field-event';\nimport componentStyles from './cookie-banner.css?inline';\n\nexport { BUTTON_TAG } from '../../inputs/button/button';\nexport { CHECKBOX_TAG } from '../../inputs/checkbox/checkbox';\n/** A consent category offered as an opt-in checkbox. `id` is the key the `decide` detail is built from. */\nexport type OreCookieBannerCategory = { description?: string; id: string; label: string };\n\n/** All rendered labels, each with an English default — pass translated strings for other locales. */\nexport type OreCookieBannerLabels = Partial<{\n acceptAll: string;\n essential: string;\n essentialNote: string;\n heading: string;\n reject: string;\n save: string;\n}>;\n\n/** The consent record emitted by `decide`: every category id plus `essential`, always true. */\nexport type CookieConsentRecord = Record<string, boolean>;\n\n/** Element interface exposing the imperative API for `ore-cookie-banner`. */\nexport interface CookieBannerElement extends HTMLElement, OreCookieBannerProps {\n /** Hides the banner without emitting anything — persistence stays with the consumer. */\n hide(): void;\n /** Shows the banner again, for example from a \"Cookie settings\" link after a decision. */\n show(): void;\n}\n\nexport type OreCookieBannerEvents = {\n /** A decision was made. `detail.consent` holds every category id; persist it and gate embeds on it. */\n decide: { consent: CookieConsentRecord };\n};\n\nexport type OreCookieBannerProps = {\n /** Optional categories rendered as checkboxes; \"Essential\" is always shown as always-on. */\n categories?: OreCookieBannerCategory[];\n /** Current consent record, used to seed the checkboxes when the banner is shown again. */\n consent?: CookieConsentRecord;\n /** Hides the banner automatically after `decide` fires (default true). Set false to keep it open. */\n hideOnDecide?: boolean;\n /** All rendered labels, each with an English default. */\n labels?: OreCookieBannerLabels;\n /** Viewport edge the banner docks to. */\n position?: 'bottom' | 'top';\n};\n\nconst DEFAULT_LABELS = {\n acceptAll: 'Accept all',\n essential: 'Essential',\n essentialNote: 'Required for the site to work',\n heading: 'Your privacy',\n reject: 'Reject non-essential',\n save: 'Save choices',\n} as const;\n\n/**\n * A fixed-position consent banner for cookie/tracker opt-in: a short policy text\n * (default slot, links included), optional per-category opt-in checkboxes with\n * descriptions, and accept-all / reject / save actions.\n *\n * The layout is a single column — heading, policy text, a scrollable category\n * panel, and actions — that scales linearly from one to many categories. Each\n * category renders as a checkbox row; its optional `description` passes through\n * the checkbox's `helper` mechanism, so it is both visible below the label and\n * linked to the control via `aria-describedby`. The category panel scrolls\n * internally when it exceeds `--cookie-banner-categories-max-height`, so the\n * banner itself never grows past the viewport.\n *\n * The banner owns presentation only. It never stores anything: listen for `decide`,\n * persist the emitted record yourself (localStorage, a CMP, your own backend), and\n * gate third-party embeds on it. The banner hides itself after `decide` unless\n * `hide-on-decide` is set to false. Call `show()` again to let the user revise\n * their choice.\n *\n * The banner is a non-modal `role=\"dialog\"`: screen readers announce it when it\n * appears, focus moves to the dialog card itself on `show()` — a neutral target,\n * so no action is preselected for keyboard users — and returns to the previously\n * focused element on `hide()`. A banner that is simply present at page load (never\n * shown via `show()`) does not steal focus and is not announced; consumers that\n * want a load-time announcement should call `show()` from a user gesture.\n *\n * The `decide` record contains exactly the currently configured category ids\n * (plus `essential`, always true). Replace — do not merge — the stored record\n * with it, so categories removed between sessions drop their stale keys.\n *\n * @element ore-cookie-banner\n *\n * @attr {string} position - Viewport edge: 'bottom' (default) | 'top'\n * @attr {boolean} hide-on-decide - Hides the banner after `decide` (default true)\n *\n * @fires decide - A decision was made. detail: { consent } — every category id plus `essential`, always true.\n *\n * @slot - Policy text, including links to the privacy policy and imprint\n *\n * @cssprop --cookie-banner-width - Maximum width of the banner card (default min(560px, viewport-fit))\n * @cssprop --cookie-banner-inset - Distance from the viewport edges (default --size-4)\n * @cssprop --cookie-banner-z-index - Stacking order (default --z-modal)\n * @cssprop --cookie-banner-categories-max-height - Category panel scroll threshold (default 16rem)\n *\n * @part banner - The banner card\n * @part text - The slot wrapper for the policy text\n * @part categories - The scrollable category panel\n * @part actions - The action buttons\n *\n * @example\n * ```html\n * <ore-cookie-banner>\n * We use cookies to keep you logged in and, with your consent, to embed music\n * from YouTube. <a href=\"/privacy\">Privacy policy</a>.\n * </ore-cookie-banner>\n * <script type=\"module\">\n * import '@vielzeug/refine/cookie-banner';\n *\n * const banner = document.querySelector('ore-cookie-banner');\n * banner.categories = [\n * { id: 'music', label: 'Music embeds', description: 'Embed music from YouTube' },\n * { id: 'stats', label: 'Statistics', description: 'Anonymous usage analytics' },\n * ];\n * banner.addEventListener('decide', (event) => {\n * localStorage.setItem('consent', JSON.stringify(event.detail.consent));\n * });\n * </script>\n * ```\n */\nexport const COOKIE_BANNER_TAG = 'ore-cookie-banner' as const;\ndefine<OreCookieBannerProps>(COOKIE_BANNER_TAG, {\n props: {\n categories: prop.data<OreCookieBannerCategory[]>([]),\n consent: prop.data<CookieConsentRecord>({}),\n hideOnDecide: prop.bool(true),\n labels: prop.data<Partial<OreCookieBannerLabels>>({}),\n position: prop.string<'bottom' | 'top'>(),\n },\n setup(props) {\n const host = getHost() as CookieBannerElement;\n const emit = useEmit<OreCookieBannerEvents>();\n const headingId = createId('cookie-banner-heading');\n const textId = createId('cookie-banner-text');\n\n // Working copy of the checkbox state while the banner is open; seeded from\n // `consent` whenever the banner is (re)shown.\n const draft = signal<CookieConsentRecord>({});\n\n const seedDraft = (): void => {\n const base = props.consent.value ?? {};\n draft.value = Object.fromEntries(\n (props.categories.value ?? []).map((category) => [category.id, base[category.id] === true]),\n );\n };\n watch(() => props.consent.value, seedDraft);\n watch(() => props.categories.value, seedDraft);\n seedDraft();\n\n const label = (key: keyof typeof DEFAULT_LABELS): string => props.labels.value?.[key] ?? DEFAULT_LABELS[key];\n\n // The element that had focus before the banner opened; `hide()` returns to it.\n let restoreFocusTo: HTMLElement | null = null;\n\n // Focus lands on the dialog card itself — a neutral target, so no action is\n // preselected for keyboard users. Screen readers announce the dialog's name\n // when focus enters it.\n const focusCard = (): void => {\n const card = host.shadowRoot?.querySelector<HTMLElement>('.banner');\n (card ?? host).focus();\n };\n\n const decide = (consent: CookieConsentRecord): void => {\n emit('decide', { consent: { ...consent, essential: true } });\n if (props.hideOnDecide.value !== false) host.hide();\n };\n\n const acceptAll = (): void => {\n decide(Object.fromEntries((props.categories.value ?? []).map((category) => [category.id, true])));\n };\n\n const reject = (): void => {\n decide(Object.fromEntries((props.categories.value ?? []).map((category) => [category.id, false])));\n };\n\n const save = (): void => {\n decide({ ...draft.value });\n };\n\n const setCategory = (id: string, checked: boolean): void => {\n draft.value = { ...draft.value, [id]: checked };\n };\n\n host.show = (): void => {\n if (!host.hidden) return;\n restoreFocusTo = document.activeElement instanceof HTMLElement ? document.activeElement : null;\n seedDraft();\n host.hidden = false;\n focusCard();\n };\n host.hide = (): void => {\n host.hidden = true;\n restoreFocusTo?.focus();\n restoreFocusTo = null;\n };\n\n const categories = (): OreCookieBannerCategory[] => props.categories.value ?? [];\n\n return html`\n <div\n class=\"banner\"\n part=\"banner\"\n role=\"dialog\"\n aria-modal=\"false\"\n aria-labelledby=\"${headingId}\"\n aria-describedby=\"${textId}\"\n tabindex=\"-1\">\n <h2 class=\"heading\" part=\"heading\" id=\"${headingId}\">${() => label('heading')}</h2>\n <div class=\"text\" part=\"text\" id=\"${textId}\">\n <slot></slot>\n </div>\n ${when(\n () => categories().length > 0,\n () => html`\n <div class=\"categories\" part=\"categories\">\n <div class=\"category-row\">\n <ore-checkbox checked disabled helper=\"${() => label('essentialNote')}\">\n ${() => label('essential')}\n </ore-checkbox>\n </div>\n ${each(\n categories,\n (category) => category.id,\n (category) => html`\n <div class=\"category-row\">\n <ore-checkbox\n checked=\"${() => draft.value[category.value.id] === true}\"\n helper=\"${() => category.value.description ?? ''}\"\n @change=\"${(event: Event) => setCategory(category.value.id, eventFieldChecked(event))}\">\n ${() => category.value.label}\n </ore-checkbox>\n </div>\n `,\n )}\n </div>\n `,\n )}\n <div class=\"actions\" part=\"actions\">\n <ore-button size=\"sm\" variant=\"ghost\" @click=\"${reject}\">${() => label('reject')}</ore-button>\n ${when(\n () => categories().length > 0,\n () => html`<ore-button size=\"sm\" variant=\"bordered\" @click=\"${save}\">${() => label('save')}</ore-button>`,\n )}\n <ore-button color=\"primary\" size=\"sm\" @click=\"${acceptAll}\">${() => label('acceptAll')}</ore-button>\n </div>\n </div>\n `;\n },\n styles: [reducedMotionMixin, componentStyles],\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"cookie-banner.js","names":[],"sources":["../src/feedback/cookie-banner/cookie-banner.ts"],"sourcesContent":["import { createId, define, each, getHost, html, prop, useEmit, when } from '@vielzeug/ore';\nimport { signal, watch } from '@vielzeug/ripple';\n\nimport { reducedMotionMixin } from '../../styles';\n\n// The child components this banner renders. The bare-import form is not enough:\n// the per-entry library build drops side-effect-only imports between entry\n// modules, so these re-export the tags as bindings: the bundler keeps the\n// module link, and importing `@vielzeug/refine/cookie-banner` registers\n// ore-button and ore-checkbox on its own.\n\nimport { eventFieldChecked } from '../../inputs/shared/native-field-event';\nimport componentStyles from './cookie-banner.css?inline';\n\nexport { BUTTON_TAG } from '../../inputs/button/button';\nexport { CHECKBOX_TAG } from '../../inputs/checkbox/checkbox';\n/** A consent category offered as an opt-in checkbox. `id` is the key the `decide` detail is built from. */\nexport type OreCookieBannerCategory = { description?: string; id: string; label: string };\n\n/** All rendered labels, each with an English default: pass translated strings for other locales. */\nexport type OreCookieBannerLabels = Partial<{\n acceptAll: string;\n essential: string;\n essentialNote: string;\n heading: string;\n reject: string;\n save: string;\n}>;\n\n/** The consent record emitted by `decide`: every category id plus `essential`, always true. */\nexport type CookieConsentRecord = Record<string, boolean>;\n\n/** Element interface exposing the imperative API for `ore-cookie-banner`. */\nexport interface CookieBannerElement extends HTMLElement, OreCookieBannerProps {\n /** Hides the banner without emitting anything: persistence stays with the consumer. */\n hide(): void;\n /** Shows the banner again, for example from a \"Cookie settings\" link after a decision. */\n show(): void;\n}\n\nexport type OreCookieBannerEvents = {\n /** A decision was made. `detail.consent` holds every category id; persist it and gate embeds on it. */\n decide: { consent: CookieConsentRecord };\n};\n\nexport type OreCookieBannerProps = {\n /** Optional categories rendered as checkboxes; \"Essential\" is always shown as always-on. */\n categories?: OreCookieBannerCategory[];\n /** Current consent record, used to seed the checkboxes when the banner is shown again. */\n consent?: CookieConsentRecord;\n /** Hides the banner automatically after `decide` fires (default true). Set false to keep it open. */\n hideOnDecide?: boolean;\n /** All rendered labels, each with an English default. */\n labels?: OreCookieBannerLabels;\n /** Viewport edge the banner docks to. */\n position?: 'bottom' | 'top';\n};\n\nconst DEFAULT_LABELS = {\n acceptAll: 'Accept all',\n essential: 'Essential',\n essentialNote: 'Required for the site to work',\n heading: 'Your privacy',\n reject: 'Reject non-essential',\n save: 'Save choices',\n} as const;\n\n/**\n * A fixed-position consent banner for cookie/tracker opt-in: a short policy text\n * (default slot, links included), optional per-category opt-in checkboxes with\n * descriptions, and accept-all / reject / save actions.\n *\n * The layout is a single column: heading, policy text, a scrollable category\n * panel, and actions, that scales linearly from one to many categories. Each\n * category renders as a checkbox row; its optional `description` passes through\n * the checkbox's `helper` mechanism, so it is both visible below the label and\n * linked to the control via `aria-describedby`. The category panel scrolls\n * internally when it exceeds `--cookie-banner-categories-max-height`, so the\n * banner itself never grows past the viewport.\n *\n * The banner owns presentation only. It never stores anything: listen for `decide`,\n * persist the emitted record yourself (localStorage, a CMP, your own backend), and\n * gate third-party embeds on it. The banner hides itself after `decide` unless\n * `hide-on-decide` is set to false. Call `show()` again to let the user revise\n * their choice.\n *\n * The banner is a non-modal `role=\"dialog\"`: screen readers announce it when it\n * appears, focus moves to the dialog card itself on `show()`: a neutral target,\n * so no action is preselected for keyboard users, and returns to the previously\n * focused element on `hide()`. A banner that is simply present at page load (never\n * shown via `show()`) does not steal focus and is not announced; consumers that\n * want a load-time announcement should call `show()` from a user gesture.\n *\n * The `decide` record contains exactly the currently configured category ids\n * (plus `essential`, always true). Replace: do not merge: the stored record\n * with it, so categories removed between sessions drop their stale keys.\n *\n * @element ore-cookie-banner\n *\n * @attr {string} position - Viewport edge: 'bottom' (default) | 'top'\n * @attr {boolean} hide-on-decide - Hides the banner after `decide` (default true)\n *\n * @fires decide - A decision was made. detail: { consent }: every category id plus `essential`, always true.\n *\n * @slot - Policy text, including links to the privacy policy and imprint\n *\n * @cssprop --cookie-banner-width - Maximum width of the banner card (default min(560px, viewport-fit))\n * @cssprop --cookie-banner-inset - Distance from the viewport edges (default --size-4)\n * @cssprop --cookie-banner-z-index - Stacking order (default --z-modal)\n * @cssprop --cookie-banner-categories-max-height - Category panel scroll threshold (default 16rem)\n *\n * @part banner - The banner card\n * @part text - The slot wrapper for the policy text\n * @part categories - The scrollable category panel\n * @part actions - The action buttons\n *\n * @example\n * ```html\n * <ore-cookie-banner>\n * We use cookies to keep you logged in and, with your consent, to embed music\n * from YouTube. <a href=\"/privacy\">Privacy policy</a>.\n * </ore-cookie-banner>\n * <script type=\"module\">\n * import '@vielzeug/refine/cookie-banner';\n *\n * const banner = document.querySelector('ore-cookie-banner');\n * banner.categories = [\n * { id: 'music', label: 'Music embeds', description: 'Embed music from YouTube' },\n * { id: 'stats', label: 'Statistics', description: 'Anonymous usage analytics' },\n * ];\n * banner.addEventListener('decide', (event) => {\n * localStorage.setItem('consent', JSON.stringify(event.detail.consent));\n * });\n * </script>\n * ```\n */\nexport const COOKIE_BANNER_TAG = 'ore-cookie-banner' as const;\ndefine<OreCookieBannerProps>(COOKIE_BANNER_TAG, {\n props: {\n categories: prop.data<OreCookieBannerCategory[]>([]),\n consent: prop.data<CookieConsentRecord>({}),\n hideOnDecide: prop.bool(true),\n labels: prop.data<Partial<OreCookieBannerLabels>>({}),\n position: prop.string<'bottom' | 'top'>(),\n },\n setup(props) {\n const host = getHost() as CookieBannerElement;\n const emit = useEmit<OreCookieBannerEvents>();\n const headingId = createId('cookie-banner-heading');\n const textId = createId('cookie-banner-text');\n\n // Working copy of the checkbox state while the banner is open; seeded from\n // `consent` whenever the banner is (re)shown.\n const draft = signal<CookieConsentRecord>({});\n\n const seedDraft = (): void => {\n const base = props.consent.value ?? {};\n draft.value = Object.fromEntries(\n (props.categories.value ?? []).map((category) => [category.id, base[category.id] === true]),\n );\n };\n watch(() => props.consent.value, seedDraft);\n watch(() => props.categories.value, seedDraft);\n seedDraft();\n\n const label = (key: keyof typeof DEFAULT_LABELS): string => props.labels.value?.[key] ?? DEFAULT_LABELS[key];\n\n // The element that had focus before the banner opened; `hide()` returns to it.\n let restoreFocusTo: HTMLElement | null = null;\n\n // Focus lands on the dialog card itself: a neutral target, so no action is\n // preselected for keyboard users. Screen readers announce the dialog's name\n // when focus enters it.\n const focusCard = (): void => {\n const card = host.shadowRoot?.querySelector<HTMLElement>('.banner');\n (card ?? host).focus();\n };\n\n const decide = (consent: CookieConsentRecord): void => {\n emit('decide', { consent: { ...consent, essential: true } });\n if (props.hideOnDecide.value !== false) host.hide();\n };\n\n const acceptAll = (): void => {\n decide(Object.fromEntries((props.categories.value ?? []).map((category) => [category.id, true])));\n };\n\n const reject = (): void => {\n decide(Object.fromEntries((props.categories.value ?? []).map((category) => [category.id, false])));\n };\n\n const save = (): void => {\n decide({ ...draft.value });\n };\n\n const setCategory = (id: string, checked: boolean): void => {\n draft.value = { ...draft.value, [id]: checked };\n };\n\n host.show = (): void => {\n if (!host.hidden) return;\n restoreFocusTo = document.activeElement instanceof HTMLElement ? document.activeElement : null;\n seedDraft();\n host.hidden = false;\n focusCard();\n };\n host.hide = (): void => {\n host.hidden = true;\n restoreFocusTo?.focus();\n restoreFocusTo = null;\n };\n\n const categories = (): OreCookieBannerCategory[] => props.categories.value ?? [];\n\n return html`\n <div\n class=\"banner\"\n part=\"banner\"\n role=\"dialog\"\n aria-modal=\"false\"\n aria-labelledby=\"${headingId}\"\n aria-describedby=\"${textId}\"\n tabindex=\"-1\">\n <h2 class=\"heading\" part=\"heading\" id=\"${headingId}\">${() => label('heading')}</h2>\n <div class=\"text\" part=\"text\" id=\"${textId}\">\n <slot></slot>\n </div>\n ${when(\n () => categories().length > 0,\n () => html`\n <div class=\"categories\" part=\"categories\">\n <div class=\"category-row\">\n <ore-checkbox checked disabled helper=\"${() => label('essentialNote')}\">\n ${() => label('essential')}\n </ore-checkbox>\n </div>\n ${each(\n categories,\n (category) => category.id,\n (category) => html`\n <div class=\"category-row\">\n <ore-checkbox\n checked=\"${() => draft.value[category.value.id] === true}\"\n helper=\"${() => category.value.description ?? ''}\"\n @change=\"${(event: Event) => setCategory(category.value.id, eventFieldChecked(event))}\">\n ${() => category.value.label}\n </ore-checkbox>\n </div>\n `,\n )}\n </div>\n `,\n )}\n <div class=\"actions\" part=\"actions\">\n <ore-button size=\"sm\" variant=\"ghost\" @click=\"${reject}\">${() => label('reject')}</ore-button>\n ${when(\n () => categories().length > 0,\n () => html`<ore-button size=\"sm\" variant=\"bordered\" @click=\"${save}\">${() => label('save')}</ore-button>`,\n )}\n <ore-button color=\"primary\" size=\"sm\" @click=\"${acceptAll}\">${() => label('acceptAll')}</ore-button>\n </div>\n </div>\n `;\n },\n styles: [reducedMotionMixin, componentStyles],\n});\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./styles/mixins/accessibility.css.cjs"),t=require("./icon.cjs"),n=require("./content/copy-command/copy-command.css.cjs");let r=require("@vielzeug/ripple"),i=require("@vielzeug/ore");var a=`ore-copy-command`;(0,i.define)(a,{props:{rounded:i.prop.string(`md`),size:i.prop.string(`md`),value:i.prop.string(``),variant:i.prop.string(`flat`)},setup(e){let t=(0,i.useEmit)(),n=(0,i.useSlots)(),a=(0,r.signal)(!1),o=(0,r.signal)(!1),s=null;(0,i.onCleanup)(()=>{s!==null&&clearTimeout(s)});let handleCopy=async()=>{let n=e.value.value??``;if(n){s!==null&&clearTimeout(s);try{await navigator.clipboard.writeText(n),a.value=!0,o.value=!1,t(`copy`,{value:n})}catch{a.value=!1,o.value=!0}s=setTimeout(()=>{a.value=!1,o.value=!1,s=null},2e3)}},c=(0,r.computed)(()=>n.has(`suffix`).value),l=(0,r.computed)(()=>a.value?`Copied!`:o.value?`Copy failed — press to try again`:`Copy: ${e.value.value??``}`);return i.html`
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./styles/mixins/accessibility.css.cjs"),t=require("./icon.cjs"),n=require("./content/copy-command/copy-command.css.cjs");let r=require("@vielzeug/ripple"),i=require("@vielzeug/ore");var a=`ore-copy-command`;(0,i.define)(a,{props:{rounded:i.prop.string(`md`),size:i.prop.string(`md`),value:i.prop.string(``),variant:i.prop.string(`flat`)},setup(e){let t=(0,i.useEmit)(),n=(0,i.useSlots)(),a=(0,r.signal)(!1),o=(0,r.signal)(!1),s=null;(0,i.onCleanup)(()=>{s!==null&&clearTimeout(s)});let handleCopy=async()=>{let n=e.value.value??``;if(n){s!==null&&clearTimeout(s);try{await navigator.clipboard.writeText(n),a.value=!0,o.value=!1,t(`copy`,{value:n})}catch{a.value=!1,o.value=!0}s=setTimeout(()=>{a.value=!1,o.value=!1,s=null},2e3)}},c=(0,r.computed)(()=>n.has(`suffix`).value),l=(0,r.computed)(()=>a.value?`Copied!`:o.value?`Copy failed: press to try again`:`Copy: ${e.value.value??``}`);return i.html`
2
2
  <div class="wrapper" part="wrapper">
3
3
  <button class="command" part="command" type="button" aria-label="${l}" @click=${handleCopy}>
4
4
  <code class="command-text" part="command-text">${e.value}</code>
@@ -1 +1 @@
1
- {"version":3,"file":"copy-command.cjs","names":[],"sources":["../src/content/copy-command/copy-command.ts"],"sourcesContent":["import { define, html, onCleanup, prop, useEmit, useSlots } from '@vielzeug/ore';\nimport { computed, signal } from '@vielzeug/ripple';\nimport { srOnlyMixin } from '../../styles';\nimport type { ComponentSize, RoundedSize } from '../../types';\n\nimport componentStyles from './copy-command.css?inline';\n\nexport { ICON_TAG } from '../icon/icon';\n/** Copy command component properties */\nexport type OreCopyCommandProps = {\n /** Border radius size */\n rounded?: RoundedSize;\n /** Component size */\n size?: ComponentSize;\n /** The command string to display and copy to clipboard */\n value?: string;\n /** Visual style variant */\n variant?: 'flat' | 'bordered' | 'ghost';\n};\n\n/** Copy command component events */\nexport type OreCopyCommandEvents = {\n /** Emitted when the command is successfully copied to the clipboard */\n copy: { value: string };\n};\n\n/**\n * A styled, copy-to-clipboard command display component.\n * Shows a command string in a monospace code block with a copy button.\n * Clicking the component copies the value to the clipboard, shows a transient\n * check-mark confirmation, and emits a `copy` event.\n *\n * @element ore-copy-command\n *\n * @attr {string} value - The command string to display and copy\n * @attr {string} size - Component size: 'sm' | 'md' | 'lg'\n * @attr {string} variant - Visual style: 'flat' | 'bordered' | 'ghost'\n * @attr {string} rounded - Border radius: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'\n *\n * @fires copy - Emitted on successful clipboard write. detail: { value: string }\n *\n * @slot suffix - Optional controls appended after the copy button (e.g. a cycle button)\n *\n * @cssprop --copy-command-bg - Background color of the command block\n * @cssprop --copy-command-color - Text color of the command string\n * @cssprop --copy-command-border-color - Border color\n * @cssprop --copy-command-radius - Border radius (overrides the `rounded` attribute)\n * @cssprop --copy-command-padding - Inner padding of the command button\n * @cssprop --copy-command-font-size - Font size of the command string\n * @cssprop --copy-command-icon-color - Color of the copy/check icon\n * @cssprop --copy-command-hover-bg - Background on hover\n *\n * @part wrapper - Outer flex container\n * @part command - The copy button element\n * @part command-text - The `<code>` element displaying the command string\n * @part copy-icon - The icon wrapper span\n * @part suffix - Suffix slot container\n *\n * @example\n * ```html\n * <ore-copy-command value=\"npm install @vielzeug/ripple\"></ore-copy-command>\n *\n * <ore-copy-command value=\"npx -y @vielzeug/codex\" size=\"sm\" variant=\"bordered\"></ore-copy-command>\n *\n * <!-- With a suffix slot (e.g. a cycle button) -->\n * <ore-copy-command value=\"npm install @vielzeug/ripple\">\n * <button slot=\"suffix\" type=\"button\" aria-label=\"Next package\">›</button>\n * </ore-copy-command>\n * ```\n */\nexport const COPY_COMMAND_TAG = 'ore-copy-command' as const;\n\ndefine<OreCopyCommandProps>(COPY_COMMAND_TAG, {\n props: {\n rounded: prop.string<RoundedSize>('md'),\n size: prop.string<ComponentSize>('md'),\n value: prop.string(''),\n variant: prop.string<'flat' | 'bordered' | 'ghost'>('flat'),\n },\n\n setup(props) {\n const emit = useEmit<OreCopyCommandEvents>();\n const slots = useSlots();\n\n const copied = signal(false);\n const copyFailed = signal(false);\n let resetTimer: ReturnType<typeof setTimeout> | null = null;\n\n onCleanup(() => {\n if (resetTimer !== null) clearTimeout(resetTimer);\n });\n\n const handleCopy = async () => {\n const text = props.value.value ?? '';\n\n if (!text) return;\n\n if (resetTimer !== null) clearTimeout(resetTimer);\n\n try {\n await navigator.clipboard.writeText(text);\n copied.value = true;\n copyFailed.value = false;\n emit('copy', { value: text });\n } catch {\n // Clipboard access denied or unavailable (e.g. insecure context) — surface it instead of failing silently\n copied.value = false;\n copyFailed.value = true;\n }\n\n resetTimer = setTimeout(() => {\n copied.value = false;\n copyFailed.value = false;\n resetTimer = null;\n }, 2000);\n };\n\n const hasSuffix = computed(() => slots.has('suffix').value);\n const btnLabel = computed(() => {\n if (copied.value) return 'Copied!';\n\n if (copyFailed.value) return 'Copy failed — press to try again';\n\n return `Copy: ${props.value.value ?? ''}`;\n });\n\n return html`\n <div class=\"wrapper\" part=\"wrapper\">\n <button class=\"command\" part=\"command\" type=\"button\" aria-label=\"${btnLabel}\" @click=${handleCopy}>\n <code class=\"command-text\" part=\"command-text\">${props.value}</code>\n <span class=\"copy-icon\" part=\"copy-icon\" aria-hidden=\"true\">\n ${() => {\n if (copied.value)\n return html`\n <ore-icon name=\"check\" size=\"14\" class=\"icon-copied\" aria-hidden=\"true\"></ore-icon>\n `;\n\n if (copyFailed.value)\n return html`\n <ore-icon name=\"circle-alert\" size=\"14\" class=\"icon-failed\" aria-hidden=\"true\"></ore-icon>\n `;\n\n return html`\n <ore-icon name=\"copy\" size=\"14\" aria-hidden=\"true\"></ore-icon>\n `;\n }}\n </span>\n </button>\n <div class=\"suffix\" part=\"suffix\" ?hidden=\"${() => !hasSuffix.value}\">\n <slot name=\"suffix\"></slot>\n </div>\n </div>\n <div role=\"status\" class=\"sr-only\">\n ${() => {\n if (copied.value) return 'Copied to clipboard.';\n\n if (copyFailed.value) return 'Copy failed. Select the command text and copy it manually.';\n\n return '';\n }}\n </div>\n `;\n },\n\n styles: [srOnlyMixin, componentStyles],\n});\n"],"mappings":"0QAsEA,IAAa,EAAmB,oBAEhC,EAAA,EAAA,OAAA,CAA4B,EAAkB,CAC5C,MAAO,CACL,QAAS,EAAA,KAAK,OAAoB,IAAI,EACtC,KAAM,EAAA,KAAK,OAAsB,IAAI,EACrC,MAAO,EAAA,KAAK,OAAO,EAAE,EACrB,QAAS,EAAA,KAAK,OAAsC,MAAM,CAC5D,EAEA,MAAM,EAAO,CACX,IAAM,GAAA,EAAO,EAAA,QAAA,CAA8B,EACrC,GAAA,EAAQ,EAAA,SAAA,CAAS,EAEjB,GAAA,EAAS,EAAA,OAAA,CAAO,EAAK,EACrB,GAAA,EAAa,EAAA,OAAA,CAAO,EAAK,EAC3B,EAAmD,MAEvD,EAAA,EAAA,UAAA,KAAgB,CACV,IAAe,MAAM,aAAa,CAAU,CAClD,CAAC,EAED,IAAM,WAAa,SAAY,CAC7B,IAAM,EAAO,EAAM,MAAM,OAAS,GAE7B,KAEL,CAAI,IAAe,MAAM,aAAa,CAAU,EAEhD,GAAI,CACF,MAAM,UAAU,UAAU,UAAU,CAAI,EACxC,EAAO,MAAQ,GACf,EAAW,MAAQ,GACnB,EAAK,OAAQ,CAAE,MAAO,CAAK,CAAC,CAC9B,MAAQ,CAEN,EAAO,MAAQ,GACf,EAAW,MAAQ,EACrB,CAEA,EAAa,eAAiB,CAC5B,EAAO,MAAQ,GACf,EAAW,MAAQ,GACnB,EAAa,IACf,EAAG,GAAI,CAjByC,CAkBlD,EAEM,GAAA,EAAY,EAAA,SAAA,KAAe,EAAM,IAAI,QAAQ,CAAC,CAAC,KAAK,EACpD,GAAA,EAAW,EAAA,SAAA,KACX,EAAO,MAAc,UAErB,EAAW,MAAc,mCAEtB,SAAS,EAAM,MAAM,OAAS,IACtC,EAED,MAAO,GAAA,IAAI;;2EAE4D,EAAS,WAAW,WAAW;2DAC/C,EAAM,MAAM;;kBAGrD,EAAO,MACF,EAAA,IAAI;;kBAIT,EAAW,MACN,EAAA,IAAI;;kBAIN,EAAA,IAAI;;gBAGX;;;yDAG6C,CAAC,EAAU,MAAM;;;;;cAM9D,EAAO,MAAc,uBAErB,EAAW,MAAc,6DAEtB,GACP;;KAGR,EAEA,OAAQ,CAAC,EAAA,YAAa,EAAA,OAAe,CACvC,CAAC"}
1
+ {"version":3,"file":"copy-command.cjs","names":[],"sources":["../src/content/copy-command/copy-command.ts"],"sourcesContent":["import { define, html, onCleanup, prop, useEmit, useSlots } from '@vielzeug/ore';\nimport { computed, signal } from '@vielzeug/ripple';\nimport { srOnlyMixin } from '../../styles';\nimport type { ComponentSize, RoundedSize } from '../../types';\n\nimport componentStyles from './copy-command.css?inline';\n\nexport { ICON_TAG } from '../icon/icon';\n/** Copy command component properties */\nexport type OreCopyCommandProps = {\n /** Border radius size */\n rounded?: RoundedSize;\n /** Component size */\n size?: ComponentSize;\n /** The command string to display and copy to clipboard */\n value?: string;\n /** Visual style variant */\n variant?: 'flat' | 'bordered' | 'ghost';\n};\n\n/** Copy command component events */\nexport type OreCopyCommandEvents = {\n /** Emitted when the command is successfully copied to the clipboard */\n copy: { value: string };\n};\n\n/**\n * A styled, copy-to-clipboard command display component.\n * Shows a command string in a monospace code block with a copy button.\n * Clicking the component copies the value to the clipboard, shows a transient\n * check-mark confirmation, and emits a `copy` event.\n *\n * @element ore-copy-command\n *\n * @attr {string} value - The command string to display and copy\n * @attr {string} size - Component size: 'sm' | 'md' | 'lg'\n * @attr {string} variant - Visual style: 'flat' | 'bordered' | 'ghost'\n * @attr {string} rounded - Border radius: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'\n *\n * @fires copy - Emitted on successful clipboard write. detail: { value: string }\n *\n * @slot suffix - Optional controls appended after the copy button (e.g. a cycle button)\n *\n * @cssprop --copy-command-bg - Background color of the command block\n * @cssprop --copy-command-color - Text color of the command string\n * @cssprop --copy-command-border-color - Border color\n * @cssprop --copy-command-radius - Border radius (overrides the `rounded` attribute)\n * @cssprop --copy-command-padding - Inner padding of the command button\n * @cssprop --copy-command-font-size - Font size of the command string\n * @cssprop --copy-command-icon-color - Color of the copy/check icon\n * @cssprop --copy-command-hover-bg - Background on hover\n *\n * @part wrapper - Outer flex container\n * @part command - The copy button element\n * @part command-text - The `<code>` element displaying the command string\n * @part copy-icon - The icon wrapper span\n * @part suffix - Suffix slot container\n *\n * @example\n * ```html\n * <ore-copy-command value=\"npm install @vielzeug/ripple\"></ore-copy-command>\n *\n * <ore-copy-command value=\"npx -y @vielzeug/codex\" size=\"sm\" variant=\"bordered\"></ore-copy-command>\n *\n * <!-- With a suffix slot (e.g. a cycle button) -->\n * <ore-copy-command value=\"npm install @vielzeug/ripple\">\n * <button slot=\"suffix\" type=\"button\" aria-label=\"Next package\">›</button>\n * </ore-copy-command>\n * ```\n */\nexport const COPY_COMMAND_TAG = 'ore-copy-command' as const;\n\ndefine<OreCopyCommandProps>(COPY_COMMAND_TAG, {\n props: {\n rounded: prop.string<RoundedSize>('md'),\n size: prop.string<ComponentSize>('md'),\n value: prop.string(''),\n variant: prop.string<'flat' | 'bordered' | 'ghost'>('flat'),\n },\n\n setup(props) {\n const emit = useEmit<OreCopyCommandEvents>();\n const slots = useSlots();\n\n const copied = signal(false);\n const copyFailed = signal(false);\n let resetTimer: ReturnType<typeof setTimeout> | null = null;\n\n onCleanup(() => {\n if (resetTimer !== null) clearTimeout(resetTimer);\n });\n\n const handleCopy = async () => {\n const text = props.value.value ?? '';\n\n if (!text) return;\n\n if (resetTimer !== null) clearTimeout(resetTimer);\n\n try {\n await navigator.clipboard.writeText(text);\n copied.value = true;\n copyFailed.value = false;\n emit('copy', { value: text });\n } catch {\n // Clipboard access denied or unavailable (e.g. insecure context): surface it instead of failing silently\n copied.value = false;\n copyFailed.value = true;\n }\n\n resetTimer = setTimeout(() => {\n copied.value = false;\n copyFailed.value = false;\n resetTimer = null;\n }, 2000);\n };\n\n const hasSuffix = computed(() => slots.has('suffix').value);\n const btnLabel = computed(() => {\n if (copied.value) return 'Copied!';\n\n if (copyFailed.value) return 'Copy failed: press to try again';\n\n return `Copy: ${props.value.value ?? ''}`;\n });\n\n return html`\n <div class=\"wrapper\" part=\"wrapper\">\n <button class=\"command\" part=\"command\" type=\"button\" aria-label=\"${btnLabel}\" @click=${handleCopy}>\n <code class=\"command-text\" part=\"command-text\">${props.value}</code>\n <span class=\"copy-icon\" part=\"copy-icon\" aria-hidden=\"true\">\n ${() => {\n if (copied.value)\n return html`\n <ore-icon name=\"check\" size=\"14\" class=\"icon-copied\" aria-hidden=\"true\"></ore-icon>\n `;\n\n if (copyFailed.value)\n return html`\n <ore-icon name=\"circle-alert\" size=\"14\" class=\"icon-failed\" aria-hidden=\"true\"></ore-icon>\n `;\n\n return html`\n <ore-icon name=\"copy\" size=\"14\" aria-hidden=\"true\"></ore-icon>\n `;\n }}\n </span>\n </button>\n <div class=\"suffix\" part=\"suffix\" ?hidden=\"${() => !hasSuffix.value}\">\n <slot name=\"suffix\"></slot>\n </div>\n </div>\n <div role=\"status\" class=\"sr-only\">\n ${() => {\n if (copied.value) return 'Copied to clipboard.';\n\n if (copyFailed.value) return 'Copy failed. Select the command text and copy it manually.';\n\n return '';\n }}\n </div>\n `;\n },\n\n styles: [srOnlyMixin, componentStyles],\n});\n"],"mappings":"0QAsEA,IAAa,EAAmB,oBAEhC,EAAA,EAAA,OAAA,CAA4B,EAAkB,CAC5C,MAAO,CACL,QAAS,EAAA,KAAK,OAAoB,IAAI,EACtC,KAAM,EAAA,KAAK,OAAsB,IAAI,EACrC,MAAO,EAAA,KAAK,OAAO,EAAE,EACrB,QAAS,EAAA,KAAK,OAAsC,MAAM,CAC5D,EAEA,MAAM,EAAO,CACX,IAAM,GAAA,EAAO,EAAA,QAAA,CAA8B,EACrC,GAAA,EAAQ,EAAA,SAAA,CAAS,EAEjB,GAAA,EAAS,EAAA,OAAA,CAAO,EAAK,EACrB,GAAA,EAAa,EAAA,OAAA,CAAO,EAAK,EAC3B,EAAmD,MAEvD,EAAA,EAAA,UAAA,KAAgB,CACV,IAAe,MAAM,aAAa,CAAU,CAClD,CAAC,EAED,IAAM,WAAa,SAAY,CAC7B,IAAM,EAAO,EAAM,MAAM,OAAS,GAE7B,KAEL,CAAI,IAAe,MAAM,aAAa,CAAU,EAEhD,GAAI,CACF,MAAM,UAAU,UAAU,UAAU,CAAI,EACxC,EAAO,MAAQ,GACf,EAAW,MAAQ,GACnB,EAAK,OAAQ,CAAE,MAAO,CAAK,CAAC,CAC9B,MAAQ,CAEN,EAAO,MAAQ,GACf,EAAW,MAAQ,EACrB,CAEA,EAAa,eAAiB,CAC5B,EAAO,MAAQ,GACf,EAAW,MAAQ,GACnB,EAAa,IACf,EAAG,GAAI,CAjByC,CAkBlD,EAEM,GAAA,EAAY,EAAA,SAAA,KAAe,EAAM,IAAI,QAAQ,CAAC,CAAC,KAAK,EACpD,GAAA,EAAW,EAAA,SAAA,KACX,EAAO,MAAc,UAErB,EAAW,MAAc,kCAEtB,SAAS,EAAM,MAAM,OAAS,IACtC,EAED,MAAO,GAAA,IAAI;;2EAE4D,EAAS,WAAW,WAAW;2DAC/C,EAAM,MAAM;;kBAGrD,EAAO,MACF,EAAA,IAAI;;kBAIT,EAAW,MACN,EAAA,IAAI;;kBAIN,EAAA,IAAI;;gBAGX;;;yDAG6C,CAAC,EAAU,MAAM;;;;;cAM9D,EAAO,MAAc,uBAErB,EAAW,MAAc,6DAEtB,GACP;;KAGR,EAEA,OAAQ,CAAC,EAAA,YAAa,EAAA,OAAe,CACvC,CAAC"}
@@ -1,4 +1,4 @@
1
- import{srOnlyMixin as e}from"./styles/mixins/accessibility.css.js";import{ICON_TAG as t}from"./icon.js";import n from"./content/copy-command/copy-command.css.js";import{computed as r,signal as i}from"@vielzeug/ripple";import{define as a,html as o,onCleanup as s,prop as c,useEmit as l,useSlots as u}from"@vielzeug/ore";var d=`ore-copy-command`;a(d,{props:{rounded:c.string(`md`),size:c.string(`md`),value:c.string(``),variant:c.string(`flat`)},setup(e){let t=l(),n=u(),a=i(!1),c=i(!1),d=null;s(()=>{d!==null&&clearTimeout(d)});let handleCopy=async()=>{let n=e.value.value??``;if(n){d!==null&&clearTimeout(d);try{await navigator.clipboard.writeText(n),a.value=!0,c.value=!1,t(`copy`,{value:n})}catch{a.value=!1,c.value=!0}d=setTimeout(()=>{a.value=!1,c.value=!1,d=null},2e3)}},f=r(()=>n.has(`suffix`).value),p=r(()=>a.value?`Copied!`:c.value?`Copy failed — press to try again`:`Copy: ${e.value.value??``}`);return o`
1
+ import{srOnlyMixin as e}from"./styles/mixins/accessibility.css.js";import{ICON_TAG as t}from"./icon.js";import n from"./content/copy-command/copy-command.css.js";import{computed as r,signal as i}from"@vielzeug/ripple";import{define as a,html as o,onCleanup as s,prop as c,useEmit as l,useSlots as u}from"@vielzeug/ore";var d=`ore-copy-command`;a(d,{props:{rounded:c.string(`md`),size:c.string(`md`),value:c.string(``),variant:c.string(`flat`)},setup(e){let t=l(),n=u(),a=i(!1),c=i(!1),d=null;s(()=>{d!==null&&clearTimeout(d)});let handleCopy=async()=>{let n=e.value.value??``;if(n){d!==null&&clearTimeout(d);try{await navigator.clipboard.writeText(n),a.value=!0,c.value=!1,t(`copy`,{value:n})}catch{a.value=!1,c.value=!0}d=setTimeout(()=>{a.value=!1,c.value=!1,d=null},2e3)}},f=r(()=>n.has(`suffix`).value),p=r(()=>a.value?`Copied!`:c.value?`Copy failed: press to try again`:`Copy: ${e.value.value??``}`);return o`
2
2
  <div class="wrapper" part="wrapper">
3
3
  <button class="command" part="command" type="button" aria-label="${p}" @click=${handleCopy}>
4
4
  <code class="command-text" part="command-text">${e.value}</code>