@vielzeug/refine 26.10.7 → 26.10.10

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 (326) hide show
  1. package/README.md +6 -0
  2. package/dist/accordion-item.cjs +2 -2
  3. package/dist/accordion-item.cjs.map +1 -1
  4. package/dist/accordion-item.js +6 -6
  5. package/dist/accordion-item.js.map +1 -1
  6. package/dist/accordion.cjs +2 -2
  7. package/dist/accordion.cjs.map +1 -1
  8. package/dist/accordion.js +2 -2
  9. package/dist/accordion.js.map +1 -1
  10. package/dist/alert.cjs +2 -2
  11. package/dist/alert.cjs.map +1 -1
  12. package/dist/alert.js +2 -2
  13. package/dist/alert.js.map +1 -1
  14. package/dist/avatar.cjs +3 -3
  15. package/dist/avatar.cjs.map +1 -1
  16. package/dist/avatar.js +2 -2
  17. package/dist/avatar.js.map +1 -1
  18. package/dist/badge.cjs +2 -2
  19. package/dist/badge.cjs.map +1 -1
  20. package/dist/badge.js +2 -2
  21. package/dist/badge.js.map +1 -1
  22. package/dist/box.cjs +2 -2
  23. package/dist/box.cjs.map +1 -1
  24. package/dist/box.js +2 -2
  25. package/dist/box.js.map +1 -1
  26. package/dist/button-group.cjs +2 -2
  27. package/dist/button-group.cjs.map +1 -1
  28. package/dist/button-group.js +2 -2
  29. package/dist/button-group.js.map +1 -1
  30. package/dist/button.cjs +9 -9
  31. package/dist/button.cjs.map +1 -1
  32. package/dist/button.js +8 -8
  33. package/dist/button.js.map +1 -1
  34. package/dist/card.cjs +2 -2
  35. package/dist/card.cjs.map +1 -1
  36. package/dist/card.js +2 -2
  37. package/dist/card.js.map +1 -1
  38. package/dist/carousel.cjs +6 -6
  39. package/dist/carousel.cjs.map +1 -1
  40. package/dist/carousel.js +6 -6
  41. package/dist/carousel.js.map +1 -1
  42. package/dist/chat-message.cjs +4 -4
  43. package/dist/chat-message.cjs.map +1 -1
  44. package/dist/chat-message.js +4 -4
  45. package/dist/chat-message.js.map +1 -1
  46. package/dist/checkbox-group.cjs +1 -1
  47. package/dist/checkbox-group.cjs.map +1 -1
  48. package/dist/checkbox-group.js +1 -1
  49. package/dist/checkbox-group.js.map +1 -1
  50. package/dist/checkbox.cjs +1 -1
  51. package/dist/checkbox.cjs.map +1 -1
  52. package/dist/checkbox.js +1 -1
  53. package/dist/checkbox.js.map +1 -1
  54. package/dist/chip.cjs +8 -8
  55. package/dist/chip.cjs.map +1 -1
  56. package/dist/chip.js +8 -8
  57. package/dist/chip.js.map +1 -1
  58. package/dist/combobox.cjs +8 -8
  59. package/dist/combobox.cjs.map +1 -1
  60. package/dist/combobox.js +11 -11
  61. package/dist/combobox.js.map +1 -1
  62. package/dist/content/avatar/avatar.d.ts +2 -1
  63. package/dist/content/avatar/avatar.d.ts.map +1 -1
  64. package/dist/content/card/card.d.ts +6 -3
  65. package/dist/content/card/card.d.ts.map +1 -1
  66. package/dist/content/carousel/carousel.d.ts +5 -3
  67. package/dist/content/carousel/carousel.d.ts.map +1 -1
  68. package/dist/content/chat-message/chat-message.d.ts +2 -1
  69. package/dist/content/chat-message/chat-message.d.ts.map +1 -1
  70. package/dist/content/copy-command/copy-command.d.ts +1 -1
  71. package/dist/content/copy-command/copy-command.d.ts.map +1 -1
  72. package/dist/content/keyboard-key/keyboard-key.d.ts +2 -1
  73. package/dist/content/keyboard-key/keyboard-key.d.ts.map +1 -1
  74. package/dist/content/list/list.d.ts +2 -1
  75. package/dist/content/list/list.d.ts.map +1 -1
  76. package/dist/content/marquee/marquee.d.ts +3 -2
  77. package/dist/content/marquee/marquee.d.ts.map +1 -1
  78. package/dist/content/pagination/pagination.d.ts +1 -1
  79. package/dist/content/pagination/pagination.d.ts.map +1 -1
  80. package/dist/content/qr-code/qr-code.d.ts +0 -41
  81. package/dist/content/qr-code/qr-code.d.ts.map +1 -1
  82. package/dist/content/separator/separator.d.ts +1 -1
  83. package/dist/content/separator/separator.d.ts.map +1 -1
  84. package/dist/content/stepper/step.d.ts +1 -1
  85. package/dist/content/stepper/step.d.ts.map +1 -1
  86. package/dist/content/table/table.d.ts +2 -1
  87. package/dist/content/table/table.d.ts.map +1 -1
  88. package/dist/content/text/text.d.ts +13 -6
  89. package/dist/content/text/text.d.ts.map +1 -1
  90. package/dist/cookie-banner.cjs +1 -1
  91. package/dist/cookie-banner.cjs.map +1 -1
  92. package/dist/cookie-banner.js +1 -1
  93. package/dist/cookie-banner.js.map +1 -1
  94. package/dist/copy-command.cjs +6 -6
  95. package/dist/copy-command.cjs.map +1 -1
  96. package/dist/copy-command.js +7 -7
  97. package/dist/copy-command.js.map +1 -1
  98. package/dist/core/checkable.cjs +1 -1
  99. package/dist/core/checkable.cjs.map +1 -1
  100. package/dist/core/checkable.d.ts +6 -7
  101. package/dist/core/checkable.d.ts.map +1 -1
  102. package/dist/core/checkable.js +1 -1
  103. package/dist/core/checkable.js.map +1 -1
  104. package/dist/core/choice-field.cjs +1 -1
  105. package/dist/core/choice-field.cjs.map +1 -1
  106. package/dist/core/choice-field.d.ts +6 -6
  107. package/dist/core/choice-field.d.ts.map +1 -1
  108. package/dist/core/choice-field.js +1 -1
  109. package/dist/core/choice-field.js.map +1 -1
  110. package/dist/core/text-field.cjs +1 -1
  111. package/dist/core/text-field.cjs.map +1 -1
  112. package/dist/core/text-field.d.ts +8 -8
  113. package/dist/core/text-field.d.ts.map +1 -1
  114. package/dist/core/text-field.js +1 -1
  115. package/dist/core/text-field.js.map +1 -1
  116. package/dist/counter.cjs +2 -2
  117. package/dist/counter.cjs.map +1 -1
  118. package/dist/counter.js +2 -2
  119. package/dist/counter.js.map +1 -1
  120. package/dist/custom-elements.json +886 -749
  121. package/dist/datagrid.cjs +47 -47
  122. package/dist/datagrid.cjs.map +1 -1
  123. package/dist/datagrid.js +51 -51
  124. package/dist/datagrid.js.map +1 -1
  125. package/dist/date-picker.cjs +9 -9
  126. package/dist/date-picker.cjs.map +1 -1
  127. package/dist/date-picker.js +11 -11
  128. package/dist/date-picker.js.map +1 -1
  129. package/dist/dialog.cjs +3 -3
  130. package/dist/dialog.cjs.map +1 -1
  131. package/dist/dialog.js +3 -3
  132. package/dist/dialog.js.map +1 -1
  133. package/dist/disclosure/accordion/accordion.d.ts +4 -2
  134. package/dist/disclosure/accordion/accordion.d.ts.map +1 -1
  135. package/dist/disclosure/accordion-item/accordion-item.d.ts +1 -1
  136. package/dist/disclosure/accordion-item/accordion-item.d.ts.map +1 -1
  137. package/dist/disclosure/tab-item/tab-item.d.ts +1 -1
  138. package/dist/disclosure/tab-item/tab-item.d.ts.map +1 -1
  139. package/dist/disclosure/tabs/tabs.d.ts +1 -1
  140. package/dist/disclosure/tabs/tabs.d.ts.map +1 -1
  141. package/dist/drawer.cjs +4 -4
  142. package/dist/drawer.cjs.map +1 -1
  143. package/dist/drawer.js +2 -2
  144. package/dist/drawer.js.map +1 -1
  145. package/dist/feedback/alert/alert.d.ts +2 -1
  146. package/dist/feedback/alert/alert.d.ts.map +1 -1
  147. package/dist/feedback/badge/badge.d.ts +7 -4
  148. package/dist/feedback/badge/badge.d.ts.map +1 -1
  149. package/dist/feedback/chip/chip.d.ts +7 -5
  150. package/dist/feedback/chip/chip.d.ts.map +1 -1
  151. package/dist/grid-item.cjs +2 -2
  152. package/dist/grid-item.cjs.map +1 -1
  153. package/dist/grid-item.js +2 -2
  154. package/dist/grid-item.js.map +1 -1
  155. package/dist/grid.cjs +2 -2
  156. package/dist/grid.cjs.map +1 -1
  157. package/dist/grid.js +2 -2
  158. package/dist/grid.js.map +1 -1
  159. package/dist/input.cjs +7 -7
  160. package/dist/input.cjs.map +1 -1
  161. package/dist/input.js +8 -8
  162. package/dist/input.js.map +1 -1
  163. package/dist/inputs/button/button.d.ts +3 -2
  164. package/dist/inputs/button/button.d.ts.map +1 -1
  165. package/dist/inputs/button-group/button-group.d.ts +1 -37
  166. package/dist/inputs/button-group/button-group.d.ts.map +1 -1
  167. package/dist/inputs/combobox/combobox.types.d.ts +2 -2
  168. package/dist/inputs/combobox/combobox.types.d.ts.map +1 -1
  169. package/dist/inputs/counter/counter.d.ts +3 -2
  170. package/dist/inputs/counter/counter.d.ts.map +1 -1
  171. package/dist/inputs/datagrid/datagrid-model.cjs +1 -1
  172. package/dist/inputs/datagrid/datagrid-model.cjs.map +1 -1
  173. package/dist/inputs/datagrid/datagrid-model.d.ts +2 -1
  174. package/dist/inputs/datagrid/datagrid-model.d.ts.map +1 -1
  175. package/dist/inputs/datagrid/datagrid-model.js +1 -1
  176. package/dist/inputs/datagrid/datagrid-model.js.map +1 -1
  177. package/dist/inputs/datagrid/datagrid.d.ts +4 -2
  178. package/dist/inputs/datagrid/datagrid.d.ts.map +1 -1
  179. package/dist/inputs/date-picker/date-picker.d.ts +3 -2
  180. package/dist/inputs/date-picker/date-picker.d.ts.map +1 -1
  181. package/dist/inputs/input/input.d.ts +5 -3
  182. package/dist/inputs/input/input.d.ts.map +1 -1
  183. package/dist/inputs/message-composer/message-composer.d.ts +3 -2
  184. package/dist/inputs/message-composer/message-composer.d.ts.map +1 -1
  185. package/dist/inputs/number-input/number-input.d.ts +1 -1
  186. package/dist/inputs/number-input/number-input.d.ts.map +1 -1
  187. package/dist/inputs/otp-input/otp-input.d.ts +3 -2
  188. package/dist/inputs/otp-input/otp-input.d.ts.map +1 -1
  189. package/dist/inputs/query-bar/query-bar.d.ts.map +1 -1
  190. package/dist/inputs/select/select.d.ts +2 -2
  191. package/dist/inputs/select/select.d.ts.map +1 -1
  192. package/dist/inputs/textarea/textarea.d.ts +4 -3
  193. package/dist/inputs/textarea/textarea.d.ts.map +1 -1
  194. package/dist/inputs/time-picker/time-picker.d.ts +2 -2
  195. package/dist/inputs/time-picker/time-picker.d.ts.map +1 -1
  196. package/dist/keyboard-key.cjs +3 -3
  197. package/dist/keyboard-key.cjs.map +1 -1
  198. package/dist/keyboard-key.js +3 -3
  199. package/dist/keyboard-key.js.map +1 -1
  200. package/dist/layout/box/box.d.ts +6 -3
  201. package/dist/layout/box/box.d.ts.map +1 -1
  202. package/dist/layout/grid/grid.d.ts +11 -6
  203. package/dist/layout/grid/grid.d.ts.map +1 -1
  204. package/dist/layout/grid-item/grid-item.d.ts +8 -4
  205. package/dist/layout/grid-item/grid-item.d.ts.map +1 -1
  206. package/dist/layout/navbar/navbar.d.ts +4 -2
  207. package/dist/layout/navbar/navbar.d.ts.map +1 -1
  208. package/dist/layout/sidebar/sidebar.d.ts +2 -1
  209. package/dist/layout/sidebar/sidebar.d.ts.map +1 -1
  210. package/dist/list-item.cjs +1 -1
  211. package/dist/list-item.cjs.map +1 -1
  212. package/dist/list-item.js +1 -1
  213. package/dist/list-item.js.map +1 -1
  214. package/dist/list.cjs +2 -2
  215. package/dist/list.cjs.map +1 -1
  216. package/dist/list.js +2 -2
  217. package/dist/list.js.map +1 -1
  218. package/dist/marquee.cjs +3 -3
  219. package/dist/marquee.cjs.map +1 -1
  220. package/dist/marquee.js +3 -3
  221. package/dist/marquee.js.map +1 -1
  222. package/dist/menu.cjs +3 -3
  223. package/dist/menu.cjs.map +1 -1
  224. package/dist/menu.js +3 -3
  225. package/dist/menu.js.map +1 -1
  226. package/dist/message-composer.cjs +10 -10
  227. package/dist/message-composer.cjs.map +1 -1
  228. package/dist/message-composer.js +7 -7
  229. package/dist/message-composer.js.map +1 -1
  230. package/dist/navbar.cjs +10 -10
  231. package/dist/navbar.cjs.map +1 -1
  232. package/dist/navbar.js +13 -13
  233. package/dist/navbar.js.map +1 -1
  234. package/dist/number-input.cjs +3 -3
  235. package/dist/number-input.cjs.map +1 -1
  236. package/dist/number-input.js +4 -4
  237. package/dist/number-input.js.map +1 -1
  238. package/dist/otp-input.cjs +4 -4
  239. package/dist/otp-input.cjs.map +1 -1
  240. package/dist/otp-input.js +4 -4
  241. package/dist/otp-input.js.map +1 -1
  242. package/dist/overlay/dialog/dialog.d.ts +7 -4
  243. package/dist/overlay/dialog/dialog.d.ts.map +1 -1
  244. package/dist/overlay/drawer/drawer.d.ts +4 -2
  245. package/dist/overlay/drawer/drawer.d.ts.map +1 -1
  246. package/dist/overlay/menu/menu.d.ts +2 -1
  247. package/dist/overlay/menu/menu.d.ts.map +1 -1
  248. package/dist/pagination.cjs +9 -9
  249. package/dist/pagination.cjs.map +1 -1
  250. package/dist/pagination.js +9 -9
  251. package/dist/pagination.js.map +1 -1
  252. package/dist/qr-code.cjs +2 -2
  253. package/dist/qr-code.cjs.map +1 -1
  254. package/dist/qr-code.js +2 -2
  255. package/dist/qr-code.js.map +1 -1
  256. package/dist/query-bar.cjs +7 -7
  257. package/dist/query-bar.cjs.map +1 -1
  258. package/dist/query-bar.js +8 -8
  259. package/dist/query-bar.js.map +1 -1
  260. package/dist/radio-group.cjs +1 -1
  261. package/dist/radio-group.cjs.map +1 -1
  262. package/dist/radio-group.js +1 -1
  263. package/dist/radio-group.js.map +1 -1
  264. package/dist/refine.cjs +123 -123
  265. package/dist/refine.cjs.map +1 -1
  266. package/dist/refine.iife.js +123 -123
  267. package/dist/refine.iife.js.map +1 -1
  268. package/dist/refine.js +124 -124
  269. package/dist/refine.js.map +1 -1
  270. package/dist/select.cjs +13 -13
  271. package/dist/select.cjs.map +1 -1
  272. package/dist/select.js +15 -15
  273. package/dist/select.js.map +1 -1
  274. package/dist/separator.cjs +4 -4
  275. package/dist/separator.cjs.map +1 -1
  276. package/dist/separator.js +4 -4
  277. package/dist/separator.js.map +1 -1
  278. package/dist/shared/prop-bundles.cjs +1 -1
  279. package/dist/shared/prop-bundles.cjs.map +1 -1
  280. package/dist/shared/prop-bundles.d.ts +7 -8
  281. package/dist/shared/prop-bundles.d.ts.map +1 -1
  282. package/dist/shared/prop-bundles.js +1 -1
  283. package/dist/shared/prop-bundles.js.map +1 -1
  284. package/dist/shared/types.cjs +2 -0
  285. package/dist/shared/types.cjs.map +1 -0
  286. package/dist/shared/types.d.ts +27 -9
  287. package/dist/shared/types.d.ts.map +1 -1
  288. package/dist/shared/types.js +2 -0
  289. package/dist/shared/types.js.map +1 -0
  290. package/dist/sidebar.cjs +7 -7
  291. package/dist/sidebar.cjs.map +1 -1
  292. package/dist/sidebar.js +4 -4
  293. package/dist/sidebar.js.map +1 -1
  294. package/dist/step.cjs +10 -10
  295. package/dist/step.cjs.map +1 -1
  296. package/dist/step.js +10 -10
  297. package/dist/step.js.map +1 -1
  298. package/dist/tab-item.cjs +4 -4
  299. package/dist/tab-item.cjs.map +1 -1
  300. package/dist/tab-item.js +5 -5
  301. package/dist/tab-item.js.map +1 -1
  302. package/dist/table.cjs +2 -2
  303. package/dist/table.cjs.map +1 -1
  304. package/dist/table.js +2 -2
  305. package/dist/table.js.map +1 -1
  306. package/dist/tabs.cjs +2 -2
  307. package/dist/tabs.cjs.map +1 -1
  308. package/dist/tabs.js +4 -4
  309. package/dist/tabs.js.map +1 -1
  310. package/dist/text.cjs +2 -2
  311. package/dist/text.cjs.map +1 -1
  312. package/dist/text.js +2 -2
  313. package/dist/text.js.map +1 -1
  314. package/dist/textarea.cjs +7 -7
  315. package/dist/textarea.cjs.map +1 -1
  316. package/dist/textarea.js +7 -7
  317. package/dist/textarea.js.map +1 -1
  318. package/dist/time-picker.cjs +7 -7
  319. package/dist/time-picker.cjs.map +1 -1
  320. package/dist/time-picker.js +7 -7
  321. package/dist/time-picker.js.map +1 -1
  322. package/dist/tooltip.cjs +1 -1
  323. package/dist/tooltip.cjs.map +1 -1
  324. package/dist/tooltip.js +1 -1
  325. package/dist/tooltip.js.map +1 -1
  326. package/package.json +15 -14
package/dist/avatar.js CHANGED
@@ -1,4 +1,4 @@
1
- import{roundedVariantMixin as e,sizeVariantMixin as t}from"./styles/mixins/shape.css.js";import{colorThemeMixin as n}from"./styles/mixins/theme.css.js";import{roundableBundle as r,sizableBundle as i,themableBundle as a}from"./shared/prop-bundles.js";import{ICON_TAG as o}from"./icon.js";import s from"./content/avatar/avatar.css.js";import{computed as c,signal as l,watch as u}from"@vielzeug/ripple";import{define as d,html as f,prop as p}from"@vielzeug/ore";var m={away:`Away`,busy:`Busy`,offline:`Offline`,online:`Online`},h=`ore-avatar`;d(h,{props:{...a,...i,...r,alt:p.string(),initials:p.string(),src:p.string(),status:p.string()},setup(e){let t=l(!1);u(e.src,()=>{t.value=!1});let attachImgListeners=e=>{e&&(e.addEventListener(`error`,()=>{t.value=!0}),e.addEventListener(`load`,()=>{t.value=!1}))},n=c(()=>{if(e.initials.value)return e.initials.value.slice(0,2);let t=e.alt.value;if(!t)return``;let n=t.trim().split(/\s+/);return n.length>=2?(n[0][0]+n[n.length-1][0]).toUpperCase():n[0].slice(0,2).toUpperCase()}),r=c(()=>!!e.src.value&&!t.value),i=c(()=>!r.value&&!!n.value),a=c(()=>!r.value&&!i.value),avatarLabel=()=>{let t=e.alt.value||null,n=e.status.value,r=n?m[n]:null;return!t&&!r?null:t?r?`${t}, ${r}`:t:`Status: ${r}`},avatarRole=()=>avatarLabel()?`img`:null;return f`
1
+ import{roundedVariantMixin as e,sizeVariantMixin as t}from"./styles/mixins/shape.css.js";import{colorThemeMixin as n}from"./styles/mixins/theme.css.js";import{roundableBundle as r,sizableBundle as i,themableBundle as a}from"./shared/prop-bundles.js";import{ICON_TAG as o}from"./icon.js";import s from"./content/avatar/avatar.css.js";import{computed as c,signal as l,watch as u}from"@vielzeug/ripple";import{define as d,html as f,prop as p}from"@vielzeug/ore";var m=[`online`,`offline`,`busy`,`away`],h={away:`Away`,busy:`Busy`,offline:`Offline`,online:`Online`},g=`ore-avatar`;d(g,{props:{...a,...i,...r,alt:p.string(),initials:p.string(),src:p.string(),status:p.oneOf(m)},setup(e){let t=l(!1);u(e.src,()=>{t.value=!1});let attachImgListeners=e=>{e&&(e.addEventListener(`error`,()=>{t.value=!0}),e.addEventListener(`load`,()=>{t.value=!1}))},n=c(()=>{if(e.initials.value)return e.initials.value.slice(0,2);let t=e.alt.value;if(!t)return``;let n=t.trim().split(/\s+/);return n.length>=2?(n[0][0]+n[n.length-1][0]).toUpperCase():n[0].slice(0,2).toUpperCase()}),r=c(()=>!!e.src.value&&!t.value),i=c(()=>!r.value&&!!n.value),a=c(()=>!r.value&&!i.value),avatarLabel=()=>{let t=e.alt.value||null,n=e.status.value,r=n?h[n]:null;return!t&&!r?null:t?r?`${t}, ${r}`:t:`Status: ${r}`},avatarRole=()=>avatarLabel()?`img`:null;return f`
2
2
  <span class="avatar" part="avatar" aria-label="${avatarLabel}" role="${avatarRole}">
3
3
  ${()=>e.src.value?f`
4
4
  <img
@@ -19,5 +19,5 @@ import{roundedVariantMixin as e,sizeVariantMixin as t}from"./styles/mixins/shape
19
19
  ${()=>e.status.value?f`
20
20
  <span class="status" part="status" data-status="${e.status}" aria-hidden="true"></span>
21
21
  `:``}
22
- `},styles:[n,e,t({lg:{fontSize:`var(--avatar-font-size, var(--text-base))`,size:`var(--avatar-size, var(--size-14))`},md:{fontSize:`var(--avatar-font-size, var(--text-sm))`,size:`var(--avatar-size, var(--size-10))`},sm:{fontSize:`var(--avatar-font-size, var(--text-xs))`,size:`var(--avatar-size, var(--size-7))`}}),s]});export{h as AVATAR_TAG,o as ICON_TAG};
22
+ `},styles:[n,e,t({lg:{fontSize:`var(--avatar-font-size, var(--text-base))`,size:`var(--avatar-size, var(--size-14))`},md:{fontSize:`var(--avatar-font-size, var(--text-sm))`,size:`var(--avatar-size, var(--size-10))`},sm:{fontSize:`var(--avatar-font-size, var(--text-xs))`,size:`var(--avatar-size, var(--size-7))`}}),s]});export{m as AVATAR_STATUSES,g as AVATAR_TAG,o as ICON_TAG};
23
23
  //# sourceMappingURL=avatar.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"avatar.js","names":[],"sources":["../src/content/avatar/avatar.ts"],"sourcesContent":["import { define, html, prop } from '@vielzeug/ore';\nimport { computed, signal, watch } from '@vielzeug/ripple';\nimport { roundableBundle, sizableBundle, themableBundle } from '../../shared';\nimport { colorThemeMixin, roundedVariantMixin, sizeVariantMixin } from '../../styles';\nimport type { ComponentSize, RoundedSize, ThemeColor } from '../../types';\nimport componentStyles from './avatar.css?inline';\n\nexport { ICON_TAG } from '../icon/icon';\nexport type AvatarStatus = 'online' | 'offline' | 'busy' | 'away';\n\nconst STATUS_LABELS: Record<AvatarStatus, string> = {\n away: 'Away',\n busy: 'Busy',\n offline: 'Offline',\n online: 'Online',\n};\n\n/** Avatar component properties */\nexport type OreAvatarProps = {\n /** Alt text for the image; also used to derive initials when no `initials` prop is given */\n alt?: string;\n /** Theme color (used for initials background) */\n color?: ThemeColor;\n /** Explicit initials to display when no image is available (e.g. \"JD\") */\n initials?: string;\n /** Border radius */\n rounded?: RoundedSize | '';\n /** Component size */\n size?: ComponentSize;\n /** Image source URL */\n src?: string;\n /** Online presence indicator */\n status?: AvatarStatus;\n};\n\n/**\n * Displays a user avatar: image → initials → generic fallback icon, in that priority order.\n *\n * @element ore-avatar\n *\n * @attr {string} src - Image source URL\n * @attr {string} alt - Image alt text (also used to derive initials)\n * @attr {string} initials - Explicit initials (up to 2 chars)\n * @attr {string} color - Theme color for initials background: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error'\n * @attr {string} size - 'sm' | 'md' | 'lg'\n * @attr {string} rounded - Border radius: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'\n * @attr {string} status - 'online' | 'offline' | 'busy' | 'away'\n *\n * @slot - Fallback content shown when image and initials are unavailable.\n * @cssprop --avatar-size - Diameter of the avatar\n * @cssprop --avatar-bg - Background color\n * @cssprop --avatar-color - Text/icon color\n * @cssprop --avatar-radius - Border radius\n * @cssprop --avatar-border - Border shorthand\n * @cssprop --avatar-border-color - Border color (also controls status dot border)\n *\n * @part avatar - Avatar root container.\n * @part img - Image element.\n * @part initials - Initials fallback element.\n * @part fallback - Shadow part for the `fallback` element.\n * @part status - Status indicator element.\n * @part overflow - Overflow indicator element.\n * @example\n * ```html\n * <ore-avatar src=\"/jane.jpg\" alt=\"Jane Doe\"></ore-avatar>\n * <ore-avatar initials=\"JD\" color=\"primary\"></ore-avatar>\n * <ore-avatar alt=\"John Smith\" status=\"online\"></ore-avatar>\n * ```\n */\nexport const AVATAR_TAG = 'ore-avatar' as const;\ndefine<OreAvatarProps>(AVATAR_TAG, {\n props: {\n ...themableBundle,\n ...sizableBundle,\n ...roundableBundle,\n alt: prop.string(),\n initials: prop.string(),\n src: prop.string(),\n status: prop.string<AvatarStatus>(),\n },\n setup(props) {\n const imgFailed = signal(false);\n\n // Reset stale error state whenever src changes\n watch(props.src, () => {\n imgFailed.value = false;\n });\n\n // Attach load/error listeners reactively when the img element mounts\n const attachImgListeners = (el: HTMLImageElement | null) => {\n if (!el) return;\n\n el.addEventListener('error', () => {\n imgFailed.value = true;\n });\n el.addEventListener('load', () => {\n imgFailed.value = false;\n });\n };\n const derivedInitials = computed(() => {\n if (props.initials.value) return props.initials.value.slice(0, 2);\n\n const alt = props.alt.value;\n\n if (!alt) return '';\n\n const parts = alt.trim().split(/\\s+/);\n\n if (parts.length >= 2) return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();\n\n return parts[0].slice(0, 2).toUpperCase();\n });\n const showImage = computed(() => !!props.src.value && !imgFailed.value);\n const showInitials = computed(() => !showImage.value && !!derivedInitials.value);\n const showFallback = computed(() => !showImage.value && !showInitials.value);\n const avatarLabel = () => {\n const name = (props.alt.value as string | undefined) || null;\n const statusKey = props.status.value as AvatarStatus | undefined;\n const status = statusKey ? STATUS_LABELS[statusKey] : null;\n\n if (!name && !status) return null;\n\n if (!name) return `Status: ${status}`;\n\n if (!status) return name;\n\n return `${name}, ${status}`;\n };\n const avatarRole = () => (avatarLabel() ? 'img' : null);\n\n return html`\n <span class=\"avatar\" part=\"avatar\" aria-label=\"${avatarLabel}\" role=\"${avatarRole}\">\n ${() =>\n props.src.value\n ? html`\n <img\n ref=\"${attachImgListeners}\"\n part=\"img\"\n src=\"${props.src}\"\n alt=\"${props.alt}\"\n ?hidden=\"${() => !showImage.value}\"\n aria-hidden=\"true\" />\n `\n : ''}\n ${() =>\n showInitials.value\n ? html`\n <span class=\"initials\" part=\"initials\" aria-hidden=\"true\">${derivedInitials}</span>\n `\n : ''}\n ${() =>\n showFallback.value\n ? html`\n <ore-icon class=\"icon-fallback\" part=\"fallback\" name=\"user\" size=\"50%\"></ore-icon>\n `\n : ''}\n </span>\n ${() =>\n props.status.value\n ? html`\n <span class=\"status\" part=\"status\" data-status=\"${props.status}\" aria-hidden=\"true\"></span>\n `\n : ''}\n `;\n },\n styles: [\n colorThemeMixin,\n roundedVariantMixin,\n sizeVariantMixin({\n lg: { fontSize: 'var(--avatar-font-size, var(--text-base))', size: 'var(--avatar-size, var(--size-14))' },\n md: { fontSize: 'var(--avatar-font-size, var(--text-sm))', size: 'var(--avatar-size, var(--size-10))' },\n sm: { fontSize: 'var(--avatar-font-size, var(--text-xs))', size: 'var(--avatar-size, var(--size-7))' },\n }),\n componentStyles,\n ],\n});\n"],"mappings":"2cAUA,IAAM,EAA8C,CAClD,KAAM,OACN,KAAM,OACN,QAAS,UACT,OAAQ,QACV,EAsDa,EAAa,aAC1B,EAAuB,EAAY,CACjC,MAAO,CACL,GAAG,EACH,GAAG,EACH,GAAG,EACH,IAAK,EAAK,OAAO,EACjB,SAAU,EAAK,OAAO,EACtB,IAAK,EAAK,OAAO,EACjB,OAAQ,EAAK,OAAqB,CACpC,EACA,MAAM,EAAO,CACX,IAAM,EAAY,EAAO,EAAK,EAG9B,EAAM,EAAM,QAAW,CACrB,EAAU,MAAQ,EACpB,CAAC,EAGD,IAAM,mBAAsB,GAAgC,CACrD,IAEL,EAAG,iBAAiB,YAAe,CACjC,EAAU,MAAQ,EACpB,CAAC,EACD,EAAG,iBAAiB,WAAc,CAChC,EAAU,MAAQ,EACpB,CAAC,EACH,EACM,EAAkB,MAAe,CACrC,GAAI,EAAM,SAAS,MAAO,OAAO,EAAM,SAAS,MAAM,MAAM,EAAG,CAAC,EAEhE,IAAM,EAAM,EAAM,IAAI,MAEtB,GAAI,CAAC,EAAK,MAAO,GAEjB,IAAM,EAAQ,EAAI,KAAK,CAAC,CAAC,MAAM,KAAK,EAIpC,OAFI,EAAM,QAAU,GAAW,EAAM,EAAE,CAAC,GAAK,EAAM,EAAM,OAAS,EAAE,CAAC,GAAA,CAAI,YAAY,EAE9E,EAAM,EAAE,CAAC,MAAM,EAAG,CAAC,CAAC,CAAC,YAAY,CAC1C,CAAC,EACK,EAAY,MAAe,CAAC,CAAC,EAAM,IAAI,OAAS,CAAC,EAAU,KAAK,EAChE,EAAe,MAAe,CAAC,EAAU,OAAS,CAAC,CAAC,EAAgB,KAAK,EACzE,EAAe,MAAe,CAAC,EAAU,OAAS,CAAC,EAAa,KAAK,EACrE,gBAAoB,CACxB,IAAM,EAAQ,EAAM,IAAI,OAAgC,KAClD,EAAY,EAAM,OAAO,MACzB,EAAS,EAAY,EAAc,GAAa,KAQtD,MANI,CAAC,GAAQ,CAAC,EAAe,KAExB,EAEA,EAEE,GAAG,EAAK,IAAI,IAFC,EAFF,WAAW,GAK/B,EACM,eAAoB,YAAY,EAAI,MAAQ,KAElD,MAAO,EAAI;uDACwC,YAAY,UAAU,WAAW;cAE9E,EAAM,IAAI,MACN,CAAI;;yBAEO,mBAAmB;;yBAEnB,EAAM,IAAI;yBACV,EAAM,IAAI;iCACA,CAAC,EAAU,MAAM;;gBAGtC,GAAG;cAEP,EAAa,MACT,CAAI;4EAC0D,EAAgB;gBAE9E,GAAG;cAEP,EAAa,MACT,CAAI;;gBAGJ,GAAG;;YAGT,EAAM,OAAO,MACT,CAAI;gEACgD,EAAM,OAAO;cAEjE,GAAG;KAEb,EACA,OAAQ,CACN,EACA,EACA,EAAiB,CACf,GAAI,CAAE,SAAU,4CAA6C,KAAM,oCAAqC,EACxG,GAAI,CAAE,SAAU,0CAA2C,KAAM,oCAAqC,EACtG,GAAI,CAAE,SAAU,0CAA2C,KAAM,mCAAoC,CACvG,CAAC,EACD,CACF,CACF,CAAC"}
1
+ {"version":3,"file":"avatar.js","names":[],"sources":["../src/content/avatar/avatar.ts"],"sourcesContent":["import { define, html, prop } from '@vielzeug/ore';\nimport { computed, signal, watch } from '@vielzeug/ripple';\nimport { roundableBundle, sizableBundle, themableBundle } from '../../shared';\nimport { colorThemeMixin, roundedVariantMixin, sizeVariantMixin } from '../../styles';\nimport type { ComponentSize, RoundedSize, ThemeColor } from '../../types';\nimport componentStyles from './avatar.css?inline';\n\nexport { ICON_TAG } from '../icon/icon';\nexport const AVATAR_STATUSES = ['online', 'offline', 'busy', 'away'] as const;\nexport type AvatarStatus = (typeof AVATAR_STATUSES)[number];\n\nconst STATUS_LABELS: Record<AvatarStatus, string> = {\n away: 'Away',\n busy: 'Busy',\n offline: 'Offline',\n online: 'Online',\n};\n\n/** Avatar component properties */\nexport type OreAvatarProps = {\n /** Alt text for the image; also used to derive initials when no `initials` prop is given */\n alt?: string;\n /** Theme color (used for initials background) */\n color?: ThemeColor;\n /** Explicit initials to display when no image is available (e.g. \"JD\") */\n initials?: string;\n /** Border radius */\n rounded?: RoundedSize | '';\n /** Component size */\n size?: ComponentSize;\n /** Image source URL */\n src?: string;\n /** Online presence indicator */\n status?: AvatarStatus;\n};\n\n/**\n * Displays a user avatar: image → initials → generic fallback icon, in that priority order.\n *\n * @element ore-avatar\n *\n * @attr {string} src - Image source URL\n * @attr {string} alt - Image alt text (also used to derive initials)\n * @attr {string} initials - Explicit initials (up to 2 chars)\n * @attr {string} color - Theme color for initials background: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error'\n * @attr {string} size - 'sm' | 'md' | 'lg'\n * @attr {string} rounded - Border radius: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'\n * @attr {string} status - 'online' | 'offline' | 'busy' | 'away'\n *\n * @slot - Fallback content shown when image and initials are unavailable.\n * @cssprop --avatar-size - Diameter of the avatar\n * @cssprop --avatar-bg - Background color\n * @cssprop --avatar-color - Text/icon color\n * @cssprop --avatar-radius - Border radius\n * @cssprop --avatar-border - Border shorthand\n * @cssprop --avatar-border-color - Border color (also controls status dot border)\n *\n * @part avatar - Avatar root container.\n * @part img - Image element.\n * @part initials - Initials fallback element.\n * @part fallback - Shadow part for the `fallback` element.\n * @part status - Status indicator element.\n * @part overflow - Overflow indicator element.\n * @example\n * ```html\n * <ore-avatar src=\"/jane.jpg\" alt=\"Jane Doe\"></ore-avatar>\n * <ore-avatar initials=\"JD\" color=\"primary\"></ore-avatar>\n * <ore-avatar alt=\"John Smith\" status=\"online\"></ore-avatar>\n * ```\n */\nexport const AVATAR_TAG = 'ore-avatar' as const;\ndefine<OreAvatarProps>(AVATAR_TAG, {\n props: {\n ...themableBundle,\n ...sizableBundle,\n ...roundableBundle,\n alt: prop.string(),\n initials: prop.string(),\n src: prop.string(),\n status: prop.oneOf(AVATAR_STATUSES),\n },\n setup(props) {\n const imgFailed = signal(false);\n\n // Reset stale error state whenever src changes\n watch(props.src, () => {\n imgFailed.value = false;\n });\n\n // Attach load/error listeners reactively when the img element mounts\n const attachImgListeners = (el: HTMLImageElement | null) => {\n if (!el) return;\n\n el.addEventListener('error', () => {\n imgFailed.value = true;\n });\n el.addEventListener('load', () => {\n imgFailed.value = false;\n });\n };\n const derivedInitials = computed(() => {\n if (props.initials.value) return props.initials.value.slice(0, 2);\n\n const alt = props.alt.value;\n\n if (!alt) return '';\n\n const parts = alt.trim().split(/\\s+/);\n\n if (parts.length >= 2) return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();\n\n return parts[0].slice(0, 2).toUpperCase();\n });\n const showImage = computed(() => !!props.src.value && !imgFailed.value);\n const showInitials = computed(() => !showImage.value && !!derivedInitials.value);\n const showFallback = computed(() => !showImage.value && !showInitials.value);\n const avatarLabel = () => {\n const name = (props.alt.value as string | undefined) || null;\n const statusKey = props.status.value as AvatarStatus | undefined;\n const status = statusKey ? STATUS_LABELS[statusKey] : null;\n\n if (!name && !status) return null;\n\n if (!name) return `Status: ${status}`;\n\n if (!status) return name;\n\n return `${name}, ${status}`;\n };\n const avatarRole = () => (avatarLabel() ? 'img' : null);\n\n return html`\n <span class=\"avatar\" part=\"avatar\" aria-label=\"${avatarLabel}\" role=\"${avatarRole}\">\n ${() =>\n props.src.value\n ? html`\n <img\n ref=\"${attachImgListeners}\"\n part=\"img\"\n src=\"${props.src}\"\n alt=\"${props.alt}\"\n ?hidden=\"${() => !showImage.value}\"\n aria-hidden=\"true\" />\n `\n : ''}\n ${() =>\n showInitials.value\n ? html`\n <span class=\"initials\" part=\"initials\" aria-hidden=\"true\">${derivedInitials}</span>\n `\n : ''}\n ${() =>\n showFallback.value\n ? html`\n <ore-icon class=\"icon-fallback\" part=\"fallback\" name=\"user\" size=\"50%\"></ore-icon>\n `\n : ''}\n </span>\n ${() =>\n props.status.value\n ? html`\n <span class=\"status\" part=\"status\" data-status=\"${props.status}\" aria-hidden=\"true\"></span>\n `\n : ''}\n `;\n },\n styles: [\n colorThemeMixin,\n roundedVariantMixin,\n sizeVariantMixin({\n lg: { fontSize: 'var(--avatar-font-size, var(--text-base))', size: 'var(--avatar-size, var(--size-14))' },\n md: { fontSize: 'var(--avatar-font-size, var(--text-sm))', size: 'var(--avatar-size, var(--size-10))' },\n sm: { fontSize: 'var(--avatar-font-size, var(--text-xs))', size: 'var(--avatar-size, var(--size-7))' },\n }),\n componentStyles,\n ],\n});\n"],"mappings":"2cAQA,IAAa,EAAkB,CAAC,SAAU,UAAW,OAAQ,MAAM,EAG7D,EAA8C,CAClD,KAAM,OACN,KAAM,OACN,QAAS,UACT,OAAQ,QACV,EAsDa,EAAa,aAC1B,EAAuB,EAAY,CACjC,MAAO,CACL,GAAG,EACH,GAAG,EACH,GAAG,EACH,IAAK,EAAK,OAAO,EACjB,SAAU,EAAK,OAAO,EACtB,IAAK,EAAK,OAAO,EACjB,OAAQ,EAAK,MAAM,CAAe,CACpC,EACA,MAAM,EAAO,CACX,IAAM,EAAY,EAAO,EAAK,EAG9B,EAAM,EAAM,QAAW,CACrB,EAAU,MAAQ,EACpB,CAAC,EAGD,IAAM,mBAAsB,GAAgC,CACrD,IAEL,EAAG,iBAAiB,YAAe,CACjC,EAAU,MAAQ,EACpB,CAAC,EACD,EAAG,iBAAiB,WAAc,CAChC,EAAU,MAAQ,EACpB,CAAC,EACH,EACM,EAAkB,MAAe,CACrC,GAAI,EAAM,SAAS,MAAO,OAAO,EAAM,SAAS,MAAM,MAAM,EAAG,CAAC,EAEhE,IAAM,EAAM,EAAM,IAAI,MAEtB,GAAI,CAAC,EAAK,MAAO,GAEjB,IAAM,EAAQ,EAAI,KAAK,CAAC,CAAC,MAAM,KAAK,EAIpC,OAFI,EAAM,QAAU,GAAW,EAAM,EAAE,CAAC,GAAK,EAAM,EAAM,OAAS,EAAE,CAAC,GAAA,CAAI,YAAY,EAE9E,EAAM,EAAE,CAAC,MAAM,EAAG,CAAC,CAAC,CAAC,YAAY,CAC1C,CAAC,EACK,EAAY,MAAe,CAAC,CAAC,EAAM,IAAI,OAAS,CAAC,EAAU,KAAK,EAChE,EAAe,MAAe,CAAC,EAAU,OAAS,CAAC,CAAC,EAAgB,KAAK,EACzE,EAAe,MAAe,CAAC,EAAU,OAAS,CAAC,EAAa,KAAK,EACrE,gBAAoB,CACxB,IAAM,EAAQ,EAAM,IAAI,OAAgC,KAClD,EAAY,EAAM,OAAO,MACzB,EAAS,EAAY,EAAc,GAAa,KAQtD,MANI,CAAC,GAAQ,CAAC,EAAe,KAExB,EAEA,EAEE,GAAG,EAAK,IAAI,IAFC,EAFF,WAAW,GAK/B,EACM,eAAoB,YAAY,EAAI,MAAQ,KAElD,MAAO,EAAI;uDACwC,YAAY,UAAU,WAAW;cAE9E,EAAM,IAAI,MACN,CAAI;;yBAEO,mBAAmB;;yBAEnB,EAAM,IAAI;yBACV,EAAM,IAAI;iCACA,CAAC,EAAU,MAAM;;gBAGtC,GAAG;cAEP,EAAa,MACT,CAAI;4EAC0D,EAAgB;gBAE9E,GAAG;cAEP,EAAa,MACT,CAAI;;gBAGJ,GAAG;;YAGT,EAAM,OAAO,MACT,CAAI;gEACgD,EAAM,OAAO;cAEjE,GAAG;KAEb,EACA,OAAQ,CACN,EACA,EACA,EAAiB,CACf,GAAI,CAAE,SAAU,4CAA6C,KAAM,oCAAqC,EACxG,GAAI,CAAE,SAAU,0CAA2C,KAAM,oCAAqC,EACtG,GAAI,CAAE,SAAU,0CAA2C,KAAM,mCAAoC,CACvG,CAAC,EACD,CACF,CACF,CAAC"}
package/dist/badge.cjs CHANGED
@@ -1,4 +1,4 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./styles/mixins/shape.css.cjs"),t=require("./styles/mixins/theme.css.cjs"),n=require("./styles/mixins/variants.css.cjs"),r=require("./shared/prop-bundles.cjs"),i=require("./feedback/badge/badge.css.cjs");let a=require("@vielzeug/ripple"),o=require("@vielzeug/ore");var s=`ore-badge`;(0,o.define)(s,{props:{...r.themableBundle,size:o.prop.string(),...r.roundableBundle,anchor:o.prop.string(),count:o.prop.number(),dot:o.prop.bool(!1),label:o.prop.string(),max:o.prop.number(),variant:o.prop.string()},setup(e){let t=(0,a.computed)(()=>{let t=e.count.value==null?void 0:Number(e.count.value),n=e.max.value==null?void 0:Number(e.max.value);if(!(t===void 0||Number.isNaN(t)))return n!==void 0&&!Number.isNaN(n)&&t>n?`${n}+`:String(t)}),n=(0,a.computed)(()=>{if(e.label.value)return e.label.value;if(!e.dot.value&&t.value!=null)return`${t.value} notifications`}),r=(0,a.signal)(!1);return o.html`
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./styles/mixins/shape.css.cjs"),t=require("./styles/mixins/theme.css.cjs"),n=require("./styles/mixins/variants.css.cjs"),r=require("./shared/prop-bundles.cjs"),i=require("./feedback/badge/badge.css.cjs");let a=require("@vielzeug/ripple"),o=require("@vielzeug/ore");var s=[`top-end`,`top-start`,`bottom-end`,`bottom-start`],c=[`xs`,`sm`,`md`,`lg`],l=[`solid`,`flat`,`bordered`,`outline`,`frost`],u=`ore-badge`;(0,o.define)(u,{props:{...r.themableBundle,size:o.prop.oneOf(c),...r.roundableBundle,anchor:o.prop.oneOf(s),count:o.prop.number(),dot:o.prop.bool(!1),label:o.prop.string(),max:o.prop.number(),variant:o.prop.oneOf(l)},setup(e){let t=(0,a.computed)(()=>{let t=e.count.value==null?void 0:Number(e.count.value),n=e.max.value==null?void 0:Number(e.max.value);if(!(t===void 0||Number.isNaN(t)))return n!==void 0&&!Number.isNaN(n)&&t>n?`${n}+`:String(t)}),n=(0,a.computed)(()=>{if(e.label.value)return e.label.value;if(!e.dot.value&&t.value!=null)return`${t.value} notifications`}),r=(0,a.signal)(!1);return o.html`
2
2
  <span class="badge" part="badge" aria-label="${n}">
3
3
  <slot name="icon"></slot>
4
4
  <span ?hidden="${()=>t.value==null}">${t}</span>
@@ -9,5 +9,5 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=requi
9
9
  ></span>
10
10
  </span>
11
11
  <slot name="target"></slot>
12
- `},styles:[t.colorThemeMixin,t.forcedColorsMixin,e.roundedVariantMixin,n.frostVariantMixin(`.badge`),e.sizeVariantMixin({lg:{"--_padding-x":`var(--size-2-5)`,"--_padding-y":`var(--size-1)`,fontSize:`var(--text-sm)`},md:{"--_padding-x":`var(--size-2)`,"--_padding-y":`var(--size-0-5)`,fontSize:`var(--text-xs)`},sm:{"--_padding-x":`var(--size-1-5)`,"--_padding-y":`var(--size-px)`,fontSize:`var(--text-xs)`}}),i.default]}),exports.BADGE_TAG=s;
12
+ `},styles:[t.colorThemeMixin,t.forcedColorsMixin,e.roundedVariantMixin,n.frostVariantMixin(`.badge`),e.sizeVariantMixin({lg:{"--_padding-x":`var(--size-2-5)`,"--_padding-y":`var(--size-1)`,fontSize:`var(--text-sm)`},md:{"--_padding-x":`var(--size-2)`,"--_padding-y":`var(--size-0-5)`,fontSize:`var(--text-xs)`},sm:{"--_padding-x":`var(--size-1-5)`,"--_padding-y":`var(--size-px)`,fontSize:`var(--text-xs)`}}),i.default]}),exports.BADGE_TAG=u;
13
13
  //# sourceMappingURL=badge.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"badge.cjs","names":[],"sources":["../src/feedback/badge/badge.ts"],"sourcesContent":["import { define, html, prop } from '@vielzeug/ore';\nimport { computed, signal } from '@vielzeug/ripple';\nimport { roundableBundle, themableBundle } from '../../shared';\nimport {\n colorThemeMixin,\n forcedColorsMixin,\n frostVariantMixin,\n roundedVariantMixin,\n sizeVariantMixin,\n} from '../../styles';\nimport type { RoundedSize, ThemeColor, VisualVariant } from '../../types';\nimport componentStyles from './badge.css?inline';\n\ntype BadgeVariant = Extract<VisualVariant, 'solid' | 'flat' | 'bordered' | 'outline' | 'frost'>;\ntype BadgeSize = 'xs' | 'sm' | 'md' | 'lg';\n\n/** Badge component properties */\nexport type OreBadgeProps = {\n /**\n * When set, switches to overlay mode: the host becomes `position:relative`\n * and the badge pins to a corner over the slotted content.\n * Value controls which corner: 'top-end' (default) | 'top-start' | 'bottom-end' | 'bottom-start'\n */\n anchor?: 'top-end' | 'top-start' | 'bottom-end' | 'bottom-start';\n /** Theme color */\n color?: ThemeColor;\n /** Numeric count to display */\n count?: number;\n /** Render as a small dot with no label */\n dot?: boolean;\n /** Accessible label for assistive technology. Recommended for count-only and dot mode. */\n label?: string;\n /** Max count: displays \"<max>+\" when count exceeds this value */\n max?: number;\n /** Border radius override */\n rounded?: RoundedSize;\n /** Badge size */\n size?: BadgeSize;\n /** Visual style variant */\n variant?: BadgeVariant;\n};\n\n/**\n * A compact badge/chip for counts, statuses, and labels.\n * Supports numeric counts with overflow, dot mode, and icon slots.\n *\n * @element ore-badge\n *\n * @attr {string} color - Theme color: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error'\n * @attr {string} variant - Visual variant: 'solid' | 'flat' | 'bordered' | 'outline' | 'frost'\n * @attr {string} size - Component size: 'xs' | 'sm' | 'md' | 'lg'\n * @attr {number} count - Numeric count to display\n * @attr {number} max - Max count before showing \"<max>+\"\n * @attr {boolean} dot - Render as a dot indicator (no text)\n * @attr {string} rounded - Border radius: 'none' | 'sm' | 'md' | 'lg' | 'full' etc.\n *\n * @slot - Badge label text\n * @slot icon - Icon displayed before the label\n * @slot target - Element the badge is anchored to (used with the anchor attribute)\n *\n * @cssprop --badge-bg - Badge background color\n * @cssprop --badge-color - Badge text color\n * @cssprop --badge-border-color - Badge border color\n * @cssprop --badge-radius - Border radius\n * @cssprop --badge-font-size - Font size\n * @cssprop --badge-font-weight - Font weight\n * @cssprop --badge-padding-x - Horizontal padding\n * @cssprop --badge-padding-y - Vertical padding\n * @cssprop --badge-gap - Gap between icon and label\n *\n * @part badge - Shadow part for the `badge` element.\n * @example\n * ```html\n * <ore-badge color=\"primary\">New</ore-badge>\n * <ore-badge color=\"error\" count=\"5\"></ore-badge>\n * <ore-badge color=\"error\" count=\"120\" max=\"99\"></ore-badge>\n * <ore-badge color=\"success\" dot></ore-badge>\n * <ore-badge color=\"warning\" variant=\"flat\">Beta</ore-badge>\n * ```\n */\nexport const BADGE_TAG = 'ore-badge' as const;\ndefine<OreBadgeProps>(BADGE_TAG, {\n props: {\n ...themableBundle,\n size: prop.string<BadgeSize>(),\n ...roundableBundle,\n anchor: prop.string<'top-end' | 'top-start' | 'bottom-end' | 'bottom-start'>(),\n count: prop.number(),\n dot: prop.bool(false),\n label: prop.string(),\n max: prop.number(),\n variant: prop.string<BadgeVariant>(),\n },\n setup(props) {\n const label = computed(() => {\n const count = props.count.value != null ? Number(props.count.value) : undefined;\n const max = props.max.value != null ? Number(props.max.value) : undefined;\n\n if (count === undefined || Number.isNaN(count)) return undefined;\n\n if (max !== undefined && !Number.isNaN(max) && count > max) return `${max}+`;\n\n return String(count);\n });\n\n const ariaLabel = computed(() => {\n if (props.label.value) return props.label.value;\n\n if (props.dot.value) return undefined;\n\n if (label.value != null) return `${label.value} notifications`;\n\n return undefined;\n });\n\n /** True once the default slot carries content: an icon-only badge folds its label region\n * away rather than leaving an empty flex child (and its gap) trailing the glyph. */\n const hasSlottedLabel = signal(false);\n\n return html`\n <span class=\"badge\" part=\"badge\" aria-label=\"${ariaLabel}\">\n <slot name=\"icon\"></slot>\n <span ?hidden=\"${() => label.value == null}\">${label}</span>\n <span class=\"badge-label\" ?hidden=\"${() => label.value != null || !hasSlottedLabel.value}\"\n ><slot\n @slotchange=${(e: Event) => {\n hasSlottedLabel.value = (e.target as HTMLSlotElement).assignedNodes().length > 0;\n }}\n ></slot\n ></span>\n </span>\n <slot name=\"target\"></slot>\n `;\n },\n styles: [\n colorThemeMixin,\n forcedColorsMixin,\n roundedVariantMixin,\n frostVariantMixin('.badge'),\n sizeVariantMixin({\n lg: { '--_padding-x': 'var(--size-2-5)', '--_padding-y': 'var(--size-1)', fontSize: 'var(--text-sm)' },\n md: { '--_padding-x': 'var(--size-2)', '--_padding-y': 'var(--size-0-5)', fontSize: 'var(--text-xs)' },\n sm: { '--_padding-x': 'var(--size-1-5)', '--_padding-y': 'var(--size-px)', fontSize: 'var(--text-xs)' },\n }),\n componentStyles,\n ],\n});\n"],"mappings":"6VAgFA,IAAa,EAAY,aACzB,EAAA,EAAA,OAAA,CAAsB,EAAW,CAC/B,MAAO,CACL,GAAG,EAAA,eACH,KAAM,EAAA,KAAK,OAAkB,EAC7B,GAAG,EAAA,gBACH,OAAQ,EAAA,KAAK,OAAgE,EAC7E,MAAO,EAAA,KAAK,OAAO,EACnB,IAAK,EAAA,KAAK,KAAK,EAAK,EACpB,MAAO,EAAA,KAAK,OAAO,EACnB,IAAK,EAAA,KAAK,OAAO,EACjB,QAAS,EAAA,KAAK,OAAqB,CACrC,EACA,MAAM,EAAO,CACX,IAAM,GAAA,EAAQ,EAAA,SAAA,KAAe,CAC3B,IAAM,EAAQ,EAAM,MAAM,OAAS,KAAmC,IAAA,GAA5B,OAAO,EAAM,MAAM,KAAK,EAC5D,EAAM,EAAM,IAAI,OAAS,KAAiC,IAAA,GAA1B,OAAO,EAAM,IAAI,KAAK,EAExD,SAAU,IAAA,IAAa,OAAO,MAAM,CAAK,GAI7C,OAFI,IAAQ,IAAA,IAAa,CAAC,OAAO,MAAM,CAAG,GAAK,EAAQ,EAAY,GAAG,EAAI,GAEnE,OAAO,CAAK,CACrB,CAAC,EAEK,GAAA,EAAY,EAAA,SAAA,KAAe,CAC/B,GAAI,EAAM,MAAM,MAAO,OAAO,EAAM,MAAM,MAEtC,MAAM,IAAI,OAEV,EAAM,OAAS,KAAM,MAAO,GAAG,EAAM,MAAM,eAGjD,CAAC,EAIK,GAAA,EAAkB,EAAA,OAAA,CAAO,EAAK,EAEpC,MAAO,GAAA,IAAI;qDACsC,EAAU;;6BAEhC,EAAM,OAAS,KAAK,IAAI,EAAM;iDACV,EAAM,OAAS,MAAQ,CAAC,EAAgB,MAAM;;0BAEtE,GAAa,CAC1B,EAAgB,MAAS,EAAE,OAA2B,cAAc,CAAC,CAAC,OAAS,CACjF,EAAE;;;;;KAMZ,EACA,OAAQ,CACN,EAAA,gBACA,EAAA,kBACA,EAAA,oBACA,EAAA,kBAAkB,QAAQ,EAC1B,EAAA,iBAAiB,CACf,GAAI,CAAE,eAAgB,kBAAmB,eAAgB,gBAAiB,SAAU,gBAAiB,EACrG,GAAI,CAAE,eAAgB,gBAAiB,eAAgB,kBAAmB,SAAU,gBAAiB,EACrG,GAAI,CAAE,eAAgB,kBAAmB,eAAgB,iBAAkB,SAAU,gBAAiB,CACxG,CAAC,EACD,EAAA,OACF,CACF,CAAC"}
1
+ {"version":3,"file":"badge.cjs","names":[],"sources":["../src/feedback/badge/badge.ts"],"sourcesContent":["import { define, html, prop } from '@vielzeug/ore';\nimport { computed, signal } from '@vielzeug/ripple';\nimport { roundableBundle, themableBundle } from '../../shared';\nimport {\n colorThemeMixin,\n forcedColorsMixin,\n frostVariantMixin,\n roundedVariantMixin,\n sizeVariantMixin,\n} from '../../styles';\nimport type { RoundedSize, ThemeColor } from '../../types';\nimport componentStyles from './badge.css?inline';\n\nconst BADGE_ANCHORS = ['top-end', 'top-start', 'bottom-end', 'bottom-start'] as const;\nconst BADGE_SIZES = ['xs', 'sm', 'md', 'lg'] as const;\nconst BADGE_VARIANTS = ['solid', 'flat', 'bordered', 'outline', 'frost'] as const;\n\ntype BadgeVariant = (typeof BADGE_VARIANTS)[number];\ntype BadgeSize = (typeof BADGE_SIZES)[number];\n\n/** Badge component properties */\nexport type OreBadgeProps = {\n /**\n * When set, switches to overlay mode: the host becomes `position:relative`\n * and the badge pins to a corner over the slotted content.\n * Value controls which corner: 'top-end' (default) | 'top-start' | 'bottom-end' | 'bottom-start'\n */\n anchor?: (typeof BADGE_ANCHORS)[number];\n /** Theme color */\n color?: ThemeColor;\n /** Numeric count to display */\n count?: number;\n /** Render as a small dot with no label */\n dot?: boolean;\n /** Accessible label for assistive technology. Recommended for count-only and dot mode. */\n label?: string;\n /** Max count: displays \"<max>+\" when count exceeds this value */\n max?: number;\n /** Border radius override */\n rounded?: RoundedSize;\n /** Badge size */\n size?: BadgeSize;\n /** Visual style variant */\n variant?: BadgeVariant;\n};\n\n/**\n * A compact badge/chip for counts, statuses, and labels.\n * Supports numeric counts with overflow, dot mode, and icon slots.\n *\n * @element ore-badge\n *\n * @attr {string} color - Theme color: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error'\n * @attr {string} variant - Visual variant: 'solid' | 'flat' | 'bordered' | 'outline' | 'frost'\n * @attr {string} size - Component size: 'xs' | 'sm' | 'md' | 'lg'\n * @attr {number} count - Numeric count to display\n * @attr {number} max - Max count before showing \"<max>+\"\n * @attr {boolean} dot - Render as a dot indicator (no text)\n * @attr {string} rounded - Border radius: 'none' | 'sm' | 'md' | 'lg' | 'full' etc.\n *\n * @slot - Badge label text\n * @slot icon - Icon displayed before the label\n * @slot target - Element the badge is anchored to (used with the anchor attribute)\n *\n * @cssprop --badge-bg - Badge background color\n * @cssprop --badge-color - Badge text color\n * @cssprop --badge-border-color - Badge border color\n * @cssprop --badge-radius - Border radius\n * @cssprop --badge-font-size - Font size\n * @cssprop --badge-font-weight - Font weight\n * @cssprop --badge-padding-x - Horizontal padding\n * @cssprop --badge-padding-y - Vertical padding\n * @cssprop --badge-gap - Gap between icon and label\n *\n * @part badge - Shadow part for the `badge` element.\n * @example\n * ```html\n * <ore-badge color=\"primary\">New</ore-badge>\n * <ore-badge color=\"error\" count=\"5\"></ore-badge>\n * <ore-badge color=\"error\" count=\"120\" max=\"99\"></ore-badge>\n * <ore-badge color=\"success\" dot></ore-badge>\n * <ore-badge color=\"warning\" variant=\"flat\">Beta</ore-badge>\n * ```\n */\nexport const BADGE_TAG = 'ore-badge' as const;\ndefine<OreBadgeProps>(BADGE_TAG, {\n props: {\n ...themableBundle,\n size: prop.oneOf(BADGE_SIZES),\n ...roundableBundle,\n anchor: prop.oneOf(BADGE_ANCHORS),\n count: prop.number(),\n dot: prop.bool(false),\n label: prop.string(),\n max: prop.number(),\n variant: prop.oneOf(BADGE_VARIANTS),\n },\n setup(props) {\n const label = computed(() => {\n const count = props.count.value != null ? Number(props.count.value) : undefined;\n const max = props.max.value != null ? Number(props.max.value) : undefined;\n\n if (count === undefined || Number.isNaN(count)) return undefined;\n\n if (max !== undefined && !Number.isNaN(max) && count > max) return `${max}+`;\n\n return String(count);\n });\n\n const ariaLabel = computed(() => {\n if (props.label.value) return props.label.value;\n\n if (props.dot.value) return undefined;\n\n if (label.value != null) return `${label.value} notifications`;\n\n return undefined;\n });\n\n /** True once the default slot carries content: an icon-only badge folds its label region\n * away rather than leaving an empty flex child (and its gap) trailing the glyph. */\n const hasSlottedLabel = signal(false);\n\n return html`\n <span class=\"badge\" part=\"badge\" aria-label=\"${ariaLabel}\">\n <slot name=\"icon\"></slot>\n <span ?hidden=\"${() => label.value == null}\">${label}</span>\n <span class=\"badge-label\" ?hidden=\"${() => label.value != null || !hasSlottedLabel.value}\"\n ><slot\n @slotchange=${(e: Event) => {\n hasSlottedLabel.value = (e.target as HTMLSlotElement).assignedNodes().length > 0;\n }}\n ></slot\n ></span>\n </span>\n <slot name=\"target\"></slot>\n `;\n },\n styles: [\n colorThemeMixin,\n forcedColorsMixin,\n roundedVariantMixin,\n frostVariantMixin('.badge'),\n sizeVariantMixin({\n lg: { '--_padding-x': 'var(--size-2-5)', '--_padding-y': 'var(--size-1)', fontSize: 'var(--text-sm)' },\n md: { '--_padding-x': 'var(--size-2)', '--_padding-y': 'var(--size-0-5)', fontSize: 'var(--text-xs)' },\n sm: { '--_padding-x': 'var(--size-1-5)', '--_padding-y': 'var(--size-px)', fontSize: 'var(--text-xs)' },\n }),\n componentStyles,\n ],\n});\n"],"mappings":"6VAaA,IAAM,EAAgB,CAAC,UAAW,YAAa,aAAc,cAAc,EACrE,EAAc,CAAC,KAAM,KAAM,KAAM,IAAI,EACrC,EAAiB,CAAC,QAAS,OAAQ,WAAY,UAAW,OAAO,EAqE1D,EAAY,aACzB,EAAA,EAAA,OAAA,CAAsB,EAAW,CAC/B,MAAO,CACL,GAAG,EAAA,eACH,KAAM,EAAA,KAAK,MAAM,CAAW,EAC5B,GAAG,EAAA,gBACH,OAAQ,EAAA,KAAK,MAAM,CAAa,EAChC,MAAO,EAAA,KAAK,OAAO,EACnB,IAAK,EAAA,KAAK,KAAK,EAAK,EACpB,MAAO,EAAA,KAAK,OAAO,EACnB,IAAK,EAAA,KAAK,OAAO,EACjB,QAAS,EAAA,KAAK,MAAM,CAAc,CACpC,EACA,MAAM,EAAO,CACX,IAAM,GAAA,EAAQ,EAAA,SAAA,KAAe,CAC3B,IAAM,EAAQ,EAAM,MAAM,OAAS,KAAmC,IAAA,GAA5B,OAAO,EAAM,MAAM,KAAK,EAC5D,EAAM,EAAM,IAAI,OAAS,KAAiC,IAAA,GAA1B,OAAO,EAAM,IAAI,KAAK,EAExD,SAAU,IAAA,IAAa,OAAO,MAAM,CAAK,GAI7C,OAFI,IAAQ,IAAA,IAAa,CAAC,OAAO,MAAM,CAAG,GAAK,EAAQ,EAAY,GAAG,EAAI,GAEnE,OAAO,CAAK,CACrB,CAAC,EAEK,GAAA,EAAY,EAAA,SAAA,KAAe,CAC/B,GAAI,EAAM,MAAM,MAAO,OAAO,EAAM,MAAM,MAEtC,MAAM,IAAI,OAEV,EAAM,OAAS,KAAM,MAAO,GAAG,EAAM,MAAM,eAGjD,CAAC,EAIK,GAAA,EAAkB,EAAA,OAAA,CAAO,EAAK,EAEpC,MAAO,GAAA,IAAI;qDACsC,EAAU;;6BAEhC,EAAM,OAAS,KAAK,IAAI,EAAM;iDACV,EAAM,OAAS,MAAQ,CAAC,EAAgB,MAAM;;0BAEtE,GAAa,CAC1B,EAAgB,MAAS,EAAE,OAA2B,cAAc,CAAC,CAAC,OAAS,CACjF,EAAE;;;;;KAMZ,EACA,OAAQ,CACN,EAAA,gBACA,EAAA,kBACA,EAAA,oBACA,EAAA,kBAAkB,QAAQ,EAC1B,EAAA,iBAAiB,CACf,GAAI,CAAE,eAAgB,kBAAmB,eAAgB,gBAAiB,SAAU,gBAAiB,EACrG,GAAI,CAAE,eAAgB,gBAAiB,eAAgB,kBAAmB,SAAU,gBAAiB,EACrG,GAAI,CAAE,eAAgB,kBAAmB,eAAgB,iBAAkB,SAAU,gBAAiB,CACxG,CAAC,EACD,EAAA,OACF,CACF,CAAC"}
package/dist/badge.js CHANGED
@@ -1,4 +1,4 @@
1
- import{roundedVariantMixin as e,sizeVariantMixin as t}from"./styles/mixins/shape.css.js";import{colorThemeMixin as n,forcedColorsMixin as r}from"./styles/mixins/theme.css.js";import{frostVariantMixin as i}from"./styles/mixins/variants.css.js";import{roundableBundle as a,themableBundle as o}from"./shared/prop-bundles.js";import s from"./feedback/badge/badge.css.js";import{computed as c,signal as l}from"@vielzeug/ripple";import{define as u,html as d,prop as f}from"@vielzeug/ore";var p=`ore-badge`;u(p,{props:{...o,size:f.string(),...a,anchor:f.string(),count:f.number(),dot:f.bool(!1),label:f.string(),max:f.number(),variant:f.string()},setup(e){let t=c(()=>{let t=e.count.value==null?void 0:Number(e.count.value),n=e.max.value==null?void 0:Number(e.max.value);if(!(t===void 0||Number.isNaN(t)))return n!==void 0&&!Number.isNaN(n)&&t>n?`${n}+`:String(t)}),n=c(()=>{if(e.label.value)return e.label.value;if(!e.dot.value&&t.value!=null)return`${t.value} notifications`}),r=l(!1);return d`
1
+ import{roundedVariantMixin as e,sizeVariantMixin as t}from"./styles/mixins/shape.css.js";import{colorThemeMixin as n,forcedColorsMixin as r}from"./styles/mixins/theme.css.js";import{frostVariantMixin as i}from"./styles/mixins/variants.css.js";import{roundableBundle as a,themableBundle as o}from"./shared/prop-bundles.js";import s from"./feedback/badge/badge.css.js";import{computed as c,signal as l}from"@vielzeug/ripple";import{define as u,html as d,prop as f}from"@vielzeug/ore";var p=[`top-end`,`top-start`,`bottom-end`,`bottom-start`],m=[`xs`,`sm`,`md`,`lg`],h=[`solid`,`flat`,`bordered`,`outline`,`frost`],g=`ore-badge`;u(g,{props:{...o,size:f.oneOf(m),...a,anchor:f.oneOf(p),count:f.number(),dot:f.bool(!1),label:f.string(),max:f.number(),variant:f.oneOf(h)},setup(e){let t=c(()=>{let t=e.count.value==null?void 0:Number(e.count.value),n=e.max.value==null?void 0:Number(e.max.value);if(!(t===void 0||Number.isNaN(t)))return n!==void 0&&!Number.isNaN(n)&&t>n?`${n}+`:String(t)}),n=c(()=>{if(e.label.value)return e.label.value;if(!e.dot.value&&t.value!=null)return`${t.value} notifications`}),r=l(!1);return d`
2
2
  <span class="badge" part="badge" aria-label="${n}">
3
3
  <slot name="icon"></slot>
4
4
  <span ?hidden="${()=>t.value==null}">${t}</span>
@@ -9,5 +9,5 @@ import{roundedVariantMixin as e,sizeVariantMixin as t}from"./styles/mixins/shape
9
9
  ></span>
10
10
  </span>
11
11
  <slot name="target"></slot>
12
- `},styles:[n,r,e,i(`.badge`),t({lg:{"--_padding-x":`var(--size-2-5)`,"--_padding-y":`var(--size-1)`,fontSize:`var(--text-sm)`},md:{"--_padding-x":`var(--size-2)`,"--_padding-y":`var(--size-0-5)`,fontSize:`var(--text-xs)`},sm:{"--_padding-x":`var(--size-1-5)`,"--_padding-y":`var(--size-px)`,fontSize:`var(--text-xs)`}}),s]});export{p as BADGE_TAG};
12
+ `},styles:[n,r,e,i(`.badge`),t({lg:{"--_padding-x":`var(--size-2-5)`,"--_padding-y":`var(--size-1)`,fontSize:`var(--text-sm)`},md:{"--_padding-x":`var(--size-2)`,"--_padding-y":`var(--size-0-5)`,fontSize:`var(--text-xs)`},sm:{"--_padding-x":`var(--size-1-5)`,"--_padding-y":`var(--size-px)`,fontSize:`var(--text-xs)`}}),s]});export{g as BADGE_TAG};
13
13
  //# sourceMappingURL=badge.js.map
package/dist/badge.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"badge.js","names":[],"sources":["../src/feedback/badge/badge.ts"],"sourcesContent":["import { define, html, prop } from '@vielzeug/ore';\nimport { computed, signal } from '@vielzeug/ripple';\nimport { roundableBundle, themableBundle } from '../../shared';\nimport {\n colorThemeMixin,\n forcedColorsMixin,\n frostVariantMixin,\n roundedVariantMixin,\n sizeVariantMixin,\n} from '../../styles';\nimport type { RoundedSize, ThemeColor, VisualVariant } from '../../types';\nimport componentStyles from './badge.css?inline';\n\ntype BadgeVariant = Extract<VisualVariant, 'solid' | 'flat' | 'bordered' | 'outline' | 'frost'>;\ntype BadgeSize = 'xs' | 'sm' | 'md' | 'lg';\n\n/** Badge component properties */\nexport type OreBadgeProps = {\n /**\n * When set, switches to overlay mode: the host becomes `position:relative`\n * and the badge pins to a corner over the slotted content.\n * Value controls which corner: 'top-end' (default) | 'top-start' | 'bottom-end' | 'bottom-start'\n */\n anchor?: 'top-end' | 'top-start' | 'bottom-end' | 'bottom-start';\n /** Theme color */\n color?: ThemeColor;\n /** Numeric count to display */\n count?: number;\n /** Render as a small dot with no label */\n dot?: boolean;\n /** Accessible label for assistive technology. Recommended for count-only and dot mode. */\n label?: string;\n /** Max count: displays \"<max>+\" when count exceeds this value */\n max?: number;\n /** Border radius override */\n rounded?: RoundedSize;\n /** Badge size */\n size?: BadgeSize;\n /** Visual style variant */\n variant?: BadgeVariant;\n};\n\n/**\n * A compact badge/chip for counts, statuses, and labels.\n * Supports numeric counts with overflow, dot mode, and icon slots.\n *\n * @element ore-badge\n *\n * @attr {string} color - Theme color: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error'\n * @attr {string} variant - Visual variant: 'solid' | 'flat' | 'bordered' | 'outline' | 'frost'\n * @attr {string} size - Component size: 'xs' | 'sm' | 'md' | 'lg'\n * @attr {number} count - Numeric count to display\n * @attr {number} max - Max count before showing \"<max>+\"\n * @attr {boolean} dot - Render as a dot indicator (no text)\n * @attr {string} rounded - Border radius: 'none' | 'sm' | 'md' | 'lg' | 'full' etc.\n *\n * @slot - Badge label text\n * @slot icon - Icon displayed before the label\n * @slot target - Element the badge is anchored to (used with the anchor attribute)\n *\n * @cssprop --badge-bg - Badge background color\n * @cssprop --badge-color - Badge text color\n * @cssprop --badge-border-color - Badge border color\n * @cssprop --badge-radius - Border radius\n * @cssprop --badge-font-size - Font size\n * @cssprop --badge-font-weight - Font weight\n * @cssprop --badge-padding-x - Horizontal padding\n * @cssprop --badge-padding-y - Vertical padding\n * @cssprop --badge-gap - Gap between icon and label\n *\n * @part badge - Shadow part for the `badge` element.\n * @example\n * ```html\n * <ore-badge color=\"primary\">New</ore-badge>\n * <ore-badge color=\"error\" count=\"5\"></ore-badge>\n * <ore-badge color=\"error\" count=\"120\" max=\"99\"></ore-badge>\n * <ore-badge color=\"success\" dot></ore-badge>\n * <ore-badge color=\"warning\" variant=\"flat\">Beta</ore-badge>\n * ```\n */\nexport const BADGE_TAG = 'ore-badge' as const;\ndefine<OreBadgeProps>(BADGE_TAG, {\n props: {\n ...themableBundle,\n size: prop.string<BadgeSize>(),\n ...roundableBundle,\n anchor: prop.string<'top-end' | 'top-start' | 'bottom-end' | 'bottom-start'>(),\n count: prop.number(),\n dot: prop.bool(false),\n label: prop.string(),\n max: prop.number(),\n variant: prop.string<BadgeVariant>(),\n },\n setup(props) {\n const label = computed(() => {\n const count = props.count.value != null ? Number(props.count.value) : undefined;\n const max = props.max.value != null ? Number(props.max.value) : undefined;\n\n if (count === undefined || Number.isNaN(count)) return undefined;\n\n if (max !== undefined && !Number.isNaN(max) && count > max) return `${max}+`;\n\n return String(count);\n });\n\n const ariaLabel = computed(() => {\n if (props.label.value) return props.label.value;\n\n if (props.dot.value) return undefined;\n\n if (label.value != null) return `${label.value} notifications`;\n\n return undefined;\n });\n\n /** True once the default slot carries content: an icon-only badge folds its label region\n * away rather than leaving an empty flex child (and its gap) trailing the glyph. */\n const hasSlottedLabel = signal(false);\n\n return html`\n <span class=\"badge\" part=\"badge\" aria-label=\"${ariaLabel}\">\n <slot name=\"icon\"></slot>\n <span ?hidden=\"${() => label.value == null}\">${label}</span>\n <span class=\"badge-label\" ?hidden=\"${() => label.value != null || !hasSlottedLabel.value}\"\n ><slot\n @slotchange=${(e: Event) => {\n hasSlottedLabel.value = (e.target as HTMLSlotElement).assignedNodes().length > 0;\n }}\n ></slot\n ></span>\n </span>\n <slot name=\"target\"></slot>\n `;\n },\n styles: [\n colorThemeMixin,\n forcedColorsMixin,\n roundedVariantMixin,\n frostVariantMixin('.badge'),\n sizeVariantMixin({\n lg: { '--_padding-x': 'var(--size-2-5)', '--_padding-y': 'var(--size-1)', fontSize: 'var(--text-sm)' },\n md: { '--_padding-x': 'var(--size-2)', '--_padding-y': 'var(--size-0-5)', fontSize: 'var(--text-xs)' },\n sm: { '--_padding-x': 'var(--size-1-5)', '--_padding-y': 'var(--size-px)', fontSize: 'var(--text-xs)' },\n }),\n componentStyles,\n ],\n});\n"],"mappings":"keAgFA,IAAa,EAAY,YACzB,EAAsB,EAAW,CAC/B,MAAO,CACL,GAAG,EACH,KAAM,EAAK,OAAkB,EAC7B,GAAG,EACH,OAAQ,EAAK,OAAgE,EAC7E,MAAO,EAAK,OAAO,EACnB,IAAK,EAAK,KAAK,EAAK,EACpB,MAAO,EAAK,OAAO,EACnB,IAAK,EAAK,OAAO,EACjB,QAAS,EAAK,OAAqB,CACrC,EACA,MAAM,EAAO,CACX,IAAM,EAAQ,MAAe,CAC3B,IAAM,EAAQ,EAAM,MAAM,OAAS,KAAmC,IAAA,GAA5B,OAAO,EAAM,MAAM,KAAK,EAC5D,EAAM,EAAM,IAAI,OAAS,KAAiC,IAAA,GAA1B,OAAO,EAAM,IAAI,KAAK,EAExD,SAAU,IAAA,IAAa,OAAO,MAAM,CAAK,GAI7C,OAFI,IAAQ,IAAA,IAAa,CAAC,OAAO,MAAM,CAAG,GAAK,EAAQ,EAAY,GAAG,EAAI,GAEnE,OAAO,CAAK,CACrB,CAAC,EAEK,EAAY,MAAe,CAC/B,GAAI,EAAM,MAAM,MAAO,OAAO,EAAM,MAAM,MAEtC,MAAM,IAAI,OAEV,EAAM,OAAS,KAAM,MAAO,GAAG,EAAM,MAAM,eAGjD,CAAC,EAIK,EAAkB,EAAO,EAAK,EAEpC,MAAO,EAAI;qDACsC,EAAU;;6BAEhC,EAAM,OAAS,KAAK,IAAI,EAAM;iDACV,EAAM,OAAS,MAAQ,CAAC,EAAgB,MAAM;;0BAEtE,GAAa,CAC1B,EAAgB,MAAS,EAAE,OAA2B,cAAc,CAAC,CAAC,OAAS,CACjF,EAAE;;;;;KAMZ,EACA,OAAQ,CACN,EACA,EACA,EACA,EAAkB,QAAQ,EAC1B,EAAiB,CACf,GAAI,CAAE,eAAgB,kBAAmB,eAAgB,gBAAiB,SAAU,gBAAiB,EACrG,GAAI,CAAE,eAAgB,gBAAiB,eAAgB,kBAAmB,SAAU,gBAAiB,EACrG,GAAI,CAAE,eAAgB,kBAAmB,eAAgB,iBAAkB,SAAU,gBAAiB,CACxG,CAAC,EACD,CACF,CACF,CAAC"}
1
+ {"version":3,"file":"badge.js","names":[],"sources":["../src/feedback/badge/badge.ts"],"sourcesContent":["import { define, html, prop } from '@vielzeug/ore';\nimport { computed, signal } from '@vielzeug/ripple';\nimport { roundableBundle, themableBundle } from '../../shared';\nimport {\n colorThemeMixin,\n forcedColorsMixin,\n frostVariantMixin,\n roundedVariantMixin,\n sizeVariantMixin,\n} from '../../styles';\nimport type { RoundedSize, ThemeColor } from '../../types';\nimport componentStyles from './badge.css?inline';\n\nconst BADGE_ANCHORS = ['top-end', 'top-start', 'bottom-end', 'bottom-start'] as const;\nconst BADGE_SIZES = ['xs', 'sm', 'md', 'lg'] as const;\nconst BADGE_VARIANTS = ['solid', 'flat', 'bordered', 'outline', 'frost'] as const;\n\ntype BadgeVariant = (typeof BADGE_VARIANTS)[number];\ntype BadgeSize = (typeof BADGE_SIZES)[number];\n\n/** Badge component properties */\nexport type OreBadgeProps = {\n /**\n * When set, switches to overlay mode: the host becomes `position:relative`\n * and the badge pins to a corner over the slotted content.\n * Value controls which corner: 'top-end' (default) | 'top-start' | 'bottom-end' | 'bottom-start'\n */\n anchor?: (typeof BADGE_ANCHORS)[number];\n /** Theme color */\n color?: ThemeColor;\n /** Numeric count to display */\n count?: number;\n /** Render as a small dot with no label */\n dot?: boolean;\n /** Accessible label for assistive technology. Recommended for count-only and dot mode. */\n label?: string;\n /** Max count: displays \"<max>+\" when count exceeds this value */\n max?: number;\n /** Border radius override */\n rounded?: RoundedSize;\n /** Badge size */\n size?: BadgeSize;\n /** Visual style variant */\n variant?: BadgeVariant;\n};\n\n/**\n * A compact badge/chip for counts, statuses, and labels.\n * Supports numeric counts with overflow, dot mode, and icon slots.\n *\n * @element ore-badge\n *\n * @attr {string} color - Theme color: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error'\n * @attr {string} variant - Visual variant: 'solid' | 'flat' | 'bordered' | 'outline' | 'frost'\n * @attr {string} size - Component size: 'xs' | 'sm' | 'md' | 'lg'\n * @attr {number} count - Numeric count to display\n * @attr {number} max - Max count before showing \"<max>+\"\n * @attr {boolean} dot - Render as a dot indicator (no text)\n * @attr {string} rounded - Border radius: 'none' | 'sm' | 'md' | 'lg' | 'full' etc.\n *\n * @slot - Badge label text\n * @slot icon - Icon displayed before the label\n * @slot target - Element the badge is anchored to (used with the anchor attribute)\n *\n * @cssprop --badge-bg - Badge background color\n * @cssprop --badge-color - Badge text color\n * @cssprop --badge-border-color - Badge border color\n * @cssprop --badge-radius - Border radius\n * @cssprop --badge-font-size - Font size\n * @cssprop --badge-font-weight - Font weight\n * @cssprop --badge-padding-x - Horizontal padding\n * @cssprop --badge-padding-y - Vertical padding\n * @cssprop --badge-gap - Gap between icon and label\n *\n * @part badge - Shadow part for the `badge` element.\n * @example\n * ```html\n * <ore-badge color=\"primary\">New</ore-badge>\n * <ore-badge color=\"error\" count=\"5\"></ore-badge>\n * <ore-badge color=\"error\" count=\"120\" max=\"99\"></ore-badge>\n * <ore-badge color=\"success\" dot></ore-badge>\n * <ore-badge color=\"warning\" variant=\"flat\">Beta</ore-badge>\n * ```\n */\nexport const BADGE_TAG = 'ore-badge' as const;\ndefine<OreBadgeProps>(BADGE_TAG, {\n props: {\n ...themableBundle,\n size: prop.oneOf(BADGE_SIZES),\n ...roundableBundle,\n anchor: prop.oneOf(BADGE_ANCHORS),\n count: prop.number(),\n dot: prop.bool(false),\n label: prop.string(),\n max: prop.number(),\n variant: prop.oneOf(BADGE_VARIANTS),\n },\n setup(props) {\n const label = computed(() => {\n const count = props.count.value != null ? Number(props.count.value) : undefined;\n const max = props.max.value != null ? Number(props.max.value) : undefined;\n\n if (count === undefined || Number.isNaN(count)) return undefined;\n\n if (max !== undefined && !Number.isNaN(max) && count > max) return `${max}+`;\n\n return String(count);\n });\n\n const ariaLabel = computed(() => {\n if (props.label.value) return props.label.value;\n\n if (props.dot.value) return undefined;\n\n if (label.value != null) return `${label.value} notifications`;\n\n return undefined;\n });\n\n /** True once the default slot carries content: an icon-only badge folds its label region\n * away rather than leaving an empty flex child (and its gap) trailing the glyph. */\n const hasSlottedLabel = signal(false);\n\n return html`\n <span class=\"badge\" part=\"badge\" aria-label=\"${ariaLabel}\">\n <slot name=\"icon\"></slot>\n <span ?hidden=\"${() => label.value == null}\">${label}</span>\n <span class=\"badge-label\" ?hidden=\"${() => label.value != null || !hasSlottedLabel.value}\"\n ><slot\n @slotchange=${(e: Event) => {\n hasSlottedLabel.value = (e.target as HTMLSlotElement).assignedNodes().length > 0;\n }}\n ></slot\n ></span>\n </span>\n <slot name=\"target\"></slot>\n `;\n },\n styles: [\n colorThemeMixin,\n forcedColorsMixin,\n roundedVariantMixin,\n frostVariantMixin('.badge'),\n sizeVariantMixin({\n lg: { '--_padding-x': 'var(--size-2-5)', '--_padding-y': 'var(--size-1)', fontSize: 'var(--text-sm)' },\n md: { '--_padding-x': 'var(--size-2)', '--_padding-y': 'var(--size-0-5)', fontSize: 'var(--text-xs)' },\n sm: { '--_padding-x': 'var(--size-1-5)', '--_padding-y': 'var(--size-px)', fontSize: 'var(--text-xs)' },\n }),\n componentStyles,\n ],\n});\n"],"mappings":"keAaA,IAAM,EAAgB,CAAC,UAAW,YAAa,aAAc,cAAc,EACrE,EAAc,CAAC,KAAM,KAAM,KAAM,IAAI,EACrC,EAAiB,CAAC,QAAS,OAAQ,WAAY,UAAW,OAAO,EAqE1D,EAAY,YACzB,EAAsB,EAAW,CAC/B,MAAO,CACL,GAAG,EACH,KAAM,EAAK,MAAM,CAAW,EAC5B,GAAG,EACH,OAAQ,EAAK,MAAM,CAAa,EAChC,MAAO,EAAK,OAAO,EACnB,IAAK,EAAK,KAAK,EAAK,EACpB,MAAO,EAAK,OAAO,EACnB,IAAK,EAAK,OAAO,EACjB,QAAS,EAAK,MAAM,CAAc,CACpC,EACA,MAAM,EAAO,CACX,IAAM,EAAQ,MAAe,CAC3B,IAAM,EAAQ,EAAM,MAAM,OAAS,KAAmC,IAAA,GAA5B,OAAO,EAAM,MAAM,KAAK,EAC5D,EAAM,EAAM,IAAI,OAAS,KAAiC,IAAA,GAA1B,OAAO,EAAM,IAAI,KAAK,EAExD,SAAU,IAAA,IAAa,OAAO,MAAM,CAAK,GAI7C,OAFI,IAAQ,IAAA,IAAa,CAAC,OAAO,MAAM,CAAG,GAAK,EAAQ,EAAY,GAAG,EAAI,GAEnE,OAAO,CAAK,CACrB,CAAC,EAEK,EAAY,MAAe,CAC/B,GAAI,EAAM,MAAM,MAAO,OAAO,EAAM,MAAM,MAEtC,MAAM,IAAI,OAEV,EAAM,OAAS,KAAM,MAAO,GAAG,EAAM,MAAM,eAGjD,CAAC,EAIK,EAAkB,EAAO,EAAK,EAEpC,MAAO,EAAI;qDACsC,EAAU;;6BAEhC,EAAM,OAAS,KAAK,IAAI,EAAM;iDACV,EAAM,OAAS,MAAQ,CAAC,EAAgB,MAAM;;0BAEtE,GAAa,CAC1B,EAAgB,MAAS,EAAE,OAA2B,cAAc,CAAC,CAAC,OAAS,CACjF,EAAE;;;;;KAMZ,EACA,OAAQ,CACN,EACA,EACA,EACA,EAAkB,QAAQ,EAC1B,EAAiB,CACf,GAAI,CAAE,eAAgB,kBAAmB,eAAgB,gBAAiB,SAAU,gBAAiB,EACrG,GAAI,CAAE,eAAgB,gBAAiB,eAAgB,kBAAmB,SAAU,gBAAiB,EACrG,GAAI,CAAE,eAAgB,kBAAmB,eAAgB,iBAAkB,SAAU,gBAAiB,CACxG,CAAC,EACD,CACF,CACF,CAAC"}
package/dist/box.cjs CHANGED
@@ -1,4 +1,4 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./styles/mixins/animation.css.cjs"),t=require("./styles/mixins/shape.css.cjs"),n=require("./styles/mixins/theme.css.cjs"),r=require("./styles/mixins/variants.css.cjs"),i=require("./layout/box/box.css.cjs");let a=require("@vielzeug/ore");var o=`ore-box`;(0,a.define)(o,{props:{color:a.prop.string(),effect:a.prop.string(),elevation:a.prop.number(),fullwidth:a.prop.bool(),padding:a.prop.string(),rounded:a.prop.string(),variant:a.prop.string()},setup(){return a.html`
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./styles/mixins/animation.css.cjs"),t=require("./styles/mixins/shape.css.cjs"),n=require("./styles/mixins/theme.css.cjs"),r=require("./styles/mixins/variants.css.cjs"),i=require("./shared/types.cjs"),a=require("./layout/box/box.css.cjs");let o=require("@vielzeug/ore");var s=[`rainbow`],c=[`flat`,`solid`,`frost`],l=`ore-box`;(0,o.define)(l,{props:{color:o.prop.oneOf(i.THEME_COLORS),effect:o.prop.oneOf(s),elevation:o.prop.oneOf(i.ELEVATION_LEVELS),fullwidth:o.prop.bool(),padding:o.prop.oneOf(i.PADDING_SIZES),rounded:o.prop.oneOf(i.ROUNDED_SIZES),variant:o.prop.oneOf(c)},setup(){return o.html`
2
2
  <div class="box" part="box"><slot></slot></div>
3
- `},styles:[n.colorThemeMixin,n.elevationMixin,t.paddingMixin,t.roundedVariantMixin,r.frostVariantMixin(`.box`),e.rainbowEffectMixin(`.box`),i.default]}),exports.BOX_TAG=o;
3
+ `},styles:[n.colorThemeMixin,n.elevationMixin,t.paddingMixin,t.roundedVariantMixin,r.frostVariantMixin(`.box`),e.rainbowEffectMixin(`.box`),a.default]}),exports.BOX_TAG=l;
4
4
  //# sourceMappingURL=box.cjs.map
package/dist/box.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"box.cjs","names":[],"sources":["../src/layout/box/box.ts"],"sourcesContent":["import { define, html, prop } from '@vielzeug/ore';\nimport {\n colorThemeMixin,\n elevationMixin,\n frostVariantMixin,\n paddingMixin,\n rainbowEffectMixin,\n roundedVariantMixin,\n} from '../../styles';\nimport type { ElevationLevel, PaddingSize, RoundedSize, ThemeColor } from '../../types';\nimport componentStyles from './box.css?inline';\n\n/** Box component properties */\nexport type OreBoxProps = {\n /** Theme color */\n color?: ThemeColor;\n /** Animated border effect */\n effect?: 'rainbow';\n /** Shadow elevation level (0–5) */\n elevation?: ElevationLevel;\n /** Full width mode (100% of container) */\n fullwidth?: boolean;\n /** Internal padding size */\n padding?: PaddingSize;\n /** Border radius size */\n rounded?: RoundedSize;\n /** Visual style variant */\n variant?: 'solid' | 'flat' | 'frost';\n};\n\n/**\n * ore-box: A foundational layout primitive with theming support.\n *\n * @element ore-box\n *\n * @attr {string} variant - Style variant: 'solid' | 'flat' | 'frost'\n * @attr {string} color - Color theme: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error'\n * @attr {string} padding - Padding size: 'none' | 'sm' | 'md' | 'lg' | 'xl'\n * @attr {string} elevation - Shadow elevation: '0' | '1' | '2' | '3' | '4' | '5'\n * @attr {string} rounded - Border radius: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'\n * @attr {string} effect - Animated border effect: 'rainbow'\n * @attr {boolean} fullwidth - Expand to full width\n *\n * @slot - Default slot for content\n *\n * @part box - The inner box element\n *\n * @cssprop --box-bg - Background color\n * @cssprop --box-color - Text color\n * @cssprop --box-border - Border width\n * @cssprop --box-border-color - Border color\n * @cssprop --box-radius - Border radius\n * @cssprop --box-padding - Inner padding\n * @cssprop --box-shadow - Box shadow\n *\n * @example\n * ```html\n * <ore-box padding=\"lg\" elevation=\"2\">Simple content</ore-box>\n * <ore-box variant=\"solid\" color=\"primary\">Solid color</ore-box>\n * <ore-box variant=\"frost\" effect=\"rainbow\">Frosted glass</ore-box>\n * ```\n */\nexport const BOX_TAG = 'ore-box' as const;\ndefine<OreBoxProps>(BOX_TAG, {\n props: {\n color: prop.string<ThemeColor>(),\n effect: prop.string<'rainbow'>(),\n elevation: prop.number<ElevationLevel>(),\n fullwidth: prop.bool(),\n padding: prop.string<PaddingSize>(),\n rounded: prop.string<RoundedSize>(),\n variant: prop.string<'flat' | 'solid' | 'frost'>(),\n },\n setup() {\n return html`\n <div class=\"box\" part=\"box\"><slot></slot></div>\n `;\n },\n\n styles: [\n colorThemeMixin,\n elevationMixin,\n paddingMixin,\n roundedVariantMixin,\n frostVariantMixin('.box'),\n rainbowEffectMixin('.box'),\n componentStyles,\n ],\n});\n"],"mappings":"iUA8DA,IAAa,EAAU,WACvB,EAAA,EAAA,OAAA,CAAoB,EAAS,CAC3B,MAAO,CACL,MAAO,EAAA,KAAK,OAAmB,EAC/B,OAAQ,EAAA,KAAK,OAAkB,EAC/B,UAAW,EAAA,KAAK,OAAuB,EACvC,UAAW,EAAA,KAAK,KAAK,EACrB,QAAS,EAAA,KAAK,OAAoB,EAClC,QAAS,EAAA,KAAK,OAAoB,EAClC,QAAS,EAAA,KAAK,OAAmC,CACnD,EACA,OAAQ,CACN,MAAO,GAAA,IAAI;;KAGb,EAEA,OAAQ,CACN,EAAA,gBACA,EAAA,eACA,EAAA,aACA,EAAA,oBACA,EAAA,kBAAkB,MAAM,EACxB,EAAA,mBAAmB,MAAM,EACzB,EAAA,OACF,CACF,CAAC"}
1
+ {"version":3,"file":"box.cjs","names":[],"sources":["../src/layout/box/box.ts"],"sourcesContent":["import { define, html, prop } from '@vielzeug/ore';\nimport {\n colorThemeMixin,\n elevationMixin,\n frostVariantMixin,\n paddingMixin,\n rainbowEffectMixin,\n roundedVariantMixin,\n} from '../../styles';\nimport {\n ELEVATION_LEVELS,\n type ElevationLevel,\n PADDING_SIZES,\n type PaddingSize,\n ROUNDED_SIZES,\n type RoundedSize,\n THEME_COLORS,\n type ThemeColor,\n} from '../../types';\nimport componentStyles from './box.css?inline';\n\nconst BOX_EFFECTS = ['rainbow'] as const;\nconst BOX_VARIANTS = ['flat', 'solid', 'frost'] as const;\n\n/** Box component properties */\nexport type OreBoxProps = {\n /** Theme color */\n color?: ThemeColor;\n /** Animated border effect */\n effect?: (typeof BOX_EFFECTS)[number];\n /** Shadow elevation level (0–5) */\n elevation?: ElevationLevel;\n /** Full width mode (100% of container) */\n fullwidth?: boolean;\n /** Internal padding size */\n padding?: PaddingSize;\n /** Border radius size */\n rounded?: RoundedSize;\n /** Visual style variant */\n variant?: (typeof BOX_VARIANTS)[number];\n};\n\n/**\n * ore-box: A foundational layout primitive with theming support.\n *\n * @element ore-box\n *\n * @attr {string} variant - Style variant: 'solid' | 'flat' | 'frost'\n * @attr {string} color - Color theme: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error'\n * @attr {string} padding - Padding size: 'none' | 'sm' | 'md' | 'lg' | 'xl'\n * @attr {string} elevation - Shadow elevation: '0' | '1' | '2' | '3' | '4' | '5'\n * @attr {string} rounded - Border radius: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'\n * @attr {string} effect - Animated border effect: 'rainbow'\n * @attr {boolean} fullwidth - Expand to full width\n *\n * @slot - Default slot for content\n *\n * @part box - The inner box element\n *\n * @cssprop --box-bg - Background color\n * @cssprop --box-color - Text color\n * @cssprop --box-border - Border width\n * @cssprop --box-border-color - Border color\n * @cssprop --box-radius - Border radius\n * @cssprop --box-padding - Inner padding\n * @cssprop --box-shadow - Box shadow\n *\n * @example\n * ```html\n * <ore-box padding=\"lg\" elevation=\"2\">Simple content</ore-box>\n * <ore-box variant=\"solid\" color=\"primary\">Solid color</ore-box>\n * <ore-box variant=\"frost\" effect=\"rainbow\">Frosted glass</ore-box>\n * ```\n */\nexport const BOX_TAG = 'ore-box' as const;\ndefine<OreBoxProps>(BOX_TAG, {\n props: {\n color: prop.oneOf(THEME_COLORS),\n effect: prop.oneOf(BOX_EFFECTS),\n elevation: prop.oneOf(ELEVATION_LEVELS),\n fullwidth: prop.bool(),\n padding: prop.oneOf(PADDING_SIZES),\n rounded: prop.oneOf(ROUNDED_SIZES),\n variant: prop.oneOf(BOX_VARIANTS),\n },\n setup() {\n return html`\n <div class=\"box\" part=\"box\"><slot></slot></div>\n `;\n },\n\n styles: [\n colorThemeMixin,\n elevationMixin,\n paddingMixin,\n roundedVariantMixin,\n frostVariantMixin('.box'),\n rainbowEffectMixin('.box'),\n componentStyles,\n ],\n});\n"],"mappings":"iWAqBA,IAAM,EAAc,CAAC,SAAS,EACxB,EAAe,CAAC,OAAQ,QAAS,OAAO,EAoDjC,EAAU,WACvB,EAAA,EAAA,OAAA,CAAoB,EAAS,CAC3B,MAAO,CACL,MAAO,EAAA,KAAK,MAAM,EAAA,YAAY,EAC9B,OAAQ,EAAA,KAAK,MAAM,CAAW,EAC9B,UAAW,EAAA,KAAK,MAAM,EAAA,gBAAgB,EACtC,UAAW,EAAA,KAAK,KAAK,EACrB,QAAS,EAAA,KAAK,MAAM,EAAA,aAAa,EACjC,QAAS,EAAA,KAAK,MAAM,EAAA,aAAa,EACjC,QAAS,EAAA,KAAK,MAAM,CAAY,CAClC,EACA,OAAQ,CACN,MAAO,GAAA,IAAI;;KAGb,EAEA,OAAQ,CACN,EAAA,gBACA,EAAA,eACA,EAAA,aACA,EAAA,oBACA,EAAA,kBAAkB,MAAM,EACxB,EAAA,mBAAmB,MAAM,EACzB,EAAA,OACF,CACF,CAAC"}
package/dist/box.js CHANGED
@@ -1,4 +1,4 @@
1
- import{rainbowEffectMixin as e}from"./styles/mixins/animation.css.js";import{paddingMixin as t,roundedVariantMixin as n}from"./styles/mixins/shape.css.js";import{colorThemeMixin as r,elevationMixin as i}from"./styles/mixins/theme.css.js";import{frostVariantMixin as a}from"./styles/mixins/variants.css.js";import o from"./layout/box/box.css.js";import{define as s,html as c,prop as l}from"@vielzeug/ore";var u=`ore-box`;s(u,{props:{color:l.string(),effect:l.string(),elevation:l.number(),fullwidth:l.bool(),padding:l.string(),rounded:l.string(),variant:l.string()},setup(){return c`
1
+ import{rainbowEffectMixin as e}from"./styles/mixins/animation.css.js";import{paddingMixin as t,roundedVariantMixin as n}from"./styles/mixins/shape.css.js";import{colorThemeMixin as r,elevationMixin as i}from"./styles/mixins/theme.css.js";import{frostVariantMixin as a}from"./styles/mixins/variants.css.js";import{ELEVATION_LEVELS as o,PADDING_SIZES as s,ROUNDED_SIZES as c,THEME_COLORS as l}from"./shared/types.js";import u from"./layout/box/box.css.js";import{define as d,html as f,prop as p}from"@vielzeug/ore";var m=[`rainbow`],h=[`flat`,`solid`,`frost`],g=`ore-box`;d(g,{props:{color:p.oneOf(l),effect:p.oneOf(m),elevation:p.oneOf(o),fullwidth:p.bool(),padding:p.oneOf(s),rounded:p.oneOf(c),variant:p.oneOf(h)},setup(){return f`
2
2
  <div class="box" part="box"><slot></slot></div>
3
- `},styles:[r,i,t,n,a(`.box`),e(`.box`),o]});export{u as BOX_TAG};
3
+ `},styles:[r,i,t,n,a(`.box`),e(`.box`),u]});export{g as BOX_TAG};
4
4
  //# sourceMappingURL=box.js.map
package/dist/box.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"box.js","names":[],"sources":["../src/layout/box/box.ts"],"sourcesContent":["import { define, html, prop } from '@vielzeug/ore';\nimport {\n colorThemeMixin,\n elevationMixin,\n frostVariantMixin,\n paddingMixin,\n rainbowEffectMixin,\n roundedVariantMixin,\n} from '../../styles';\nimport type { ElevationLevel, PaddingSize, RoundedSize, ThemeColor } from '../../types';\nimport componentStyles from './box.css?inline';\n\n/** Box component properties */\nexport type OreBoxProps = {\n /** Theme color */\n color?: ThemeColor;\n /** Animated border effect */\n effect?: 'rainbow';\n /** Shadow elevation level (0–5) */\n elevation?: ElevationLevel;\n /** Full width mode (100% of container) */\n fullwidth?: boolean;\n /** Internal padding size */\n padding?: PaddingSize;\n /** Border radius size */\n rounded?: RoundedSize;\n /** Visual style variant */\n variant?: 'solid' | 'flat' | 'frost';\n};\n\n/**\n * ore-box: A foundational layout primitive with theming support.\n *\n * @element ore-box\n *\n * @attr {string} variant - Style variant: 'solid' | 'flat' | 'frost'\n * @attr {string} color - Color theme: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error'\n * @attr {string} padding - Padding size: 'none' | 'sm' | 'md' | 'lg' | 'xl'\n * @attr {string} elevation - Shadow elevation: '0' | '1' | '2' | '3' | '4' | '5'\n * @attr {string} rounded - Border radius: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'\n * @attr {string} effect - Animated border effect: 'rainbow'\n * @attr {boolean} fullwidth - Expand to full width\n *\n * @slot - Default slot for content\n *\n * @part box - The inner box element\n *\n * @cssprop --box-bg - Background color\n * @cssprop --box-color - Text color\n * @cssprop --box-border - Border width\n * @cssprop --box-border-color - Border color\n * @cssprop --box-radius - Border radius\n * @cssprop --box-padding - Inner padding\n * @cssprop --box-shadow - Box shadow\n *\n * @example\n * ```html\n * <ore-box padding=\"lg\" elevation=\"2\">Simple content</ore-box>\n * <ore-box variant=\"solid\" color=\"primary\">Solid color</ore-box>\n * <ore-box variant=\"frost\" effect=\"rainbow\">Frosted glass</ore-box>\n * ```\n */\nexport const BOX_TAG = 'ore-box' as const;\ndefine<OreBoxProps>(BOX_TAG, {\n props: {\n color: prop.string<ThemeColor>(),\n effect: prop.string<'rainbow'>(),\n elevation: prop.number<ElevationLevel>(),\n fullwidth: prop.bool(),\n padding: prop.string<PaddingSize>(),\n rounded: prop.string<RoundedSize>(),\n variant: prop.string<'flat' | 'solid' | 'frost'>(),\n },\n setup() {\n return html`\n <div class=\"box\" part=\"box\"><slot></slot></div>\n `;\n },\n\n styles: [\n colorThemeMixin,\n elevationMixin,\n paddingMixin,\n roundedVariantMixin,\n frostVariantMixin('.box'),\n rainbowEffectMixin('.box'),\n componentStyles,\n ],\n});\n"],"mappings":"oZA8DA,IAAa,EAAU,UACvB,EAAoB,EAAS,CAC3B,MAAO,CACL,MAAO,EAAK,OAAmB,EAC/B,OAAQ,EAAK,OAAkB,EAC/B,UAAW,EAAK,OAAuB,EACvC,UAAW,EAAK,KAAK,EACrB,QAAS,EAAK,OAAoB,EAClC,QAAS,EAAK,OAAoB,EAClC,QAAS,EAAK,OAAmC,CACnD,EACA,OAAQ,CACN,MAAO,EAAI;;KAGb,EAEA,OAAQ,CACN,EACA,EACA,EACA,EACA,EAAkB,MAAM,EACxB,EAAmB,MAAM,EACzB,CACF,CACF,CAAC"}
1
+ {"version":3,"file":"box.js","names":[],"sources":["../src/layout/box/box.ts"],"sourcesContent":["import { define, html, prop } from '@vielzeug/ore';\nimport {\n colorThemeMixin,\n elevationMixin,\n frostVariantMixin,\n paddingMixin,\n rainbowEffectMixin,\n roundedVariantMixin,\n} from '../../styles';\nimport {\n ELEVATION_LEVELS,\n type ElevationLevel,\n PADDING_SIZES,\n type PaddingSize,\n ROUNDED_SIZES,\n type RoundedSize,\n THEME_COLORS,\n type ThemeColor,\n} from '../../types';\nimport componentStyles from './box.css?inline';\n\nconst BOX_EFFECTS = ['rainbow'] as const;\nconst BOX_VARIANTS = ['flat', 'solid', 'frost'] as const;\n\n/** Box component properties */\nexport type OreBoxProps = {\n /** Theme color */\n color?: ThemeColor;\n /** Animated border effect */\n effect?: (typeof BOX_EFFECTS)[number];\n /** Shadow elevation level (0–5) */\n elevation?: ElevationLevel;\n /** Full width mode (100% of container) */\n fullwidth?: boolean;\n /** Internal padding size */\n padding?: PaddingSize;\n /** Border radius size */\n rounded?: RoundedSize;\n /** Visual style variant */\n variant?: (typeof BOX_VARIANTS)[number];\n};\n\n/**\n * ore-box: A foundational layout primitive with theming support.\n *\n * @element ore-box\n *\n * @attr {string} variant - Style variant: 'solid' | 'flat' | 'frost'\n * @attr {string} color - Color theme: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error'\n * @attr {string} padding - Padding size: 'none' | 'sm' | 'md' | 'lg' | 'xl'\n * @attr {string} elevation - Shadow elevation: '0' | '1' | '2' | '3' | '4' | '5'\n * @attr {string} rounded - Border radius: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'\n * @attr {string} effect - Animated border effect: 'rainbow'\n * @attr {boolean} fullwidth - Expand to full width\n *\n * @slot - Default slot for content\n *\n * @part box - The inner box element\n *\n * @cssprop --box-bg - Background color\n * @cssprop --box-color - Text color\n * @cssprop --box-border - Border width\n * @cssprop --box-border-color - Border color\n * @cssprop --box-radius - Border radius\n * @cssprop --box-padding - Inner padding\n * @cssprop --box-shadow - Box shadow\n *\n * @example\n * ```html\n * <ore-box padding=\"lg\" elevation=\"2\">Simple content</ore-box>\n * <ore-box variant=\"solid\" color=\"primary\">Solid color</ore-box>\n * <ore-box variant=\"frost\" effect=\"rainbow\">Frosted glass</ore-box>\n * ```\n */\nexport const BOX_TAG = 'ore-box' as const;\ndefine<OreBoxProps>(BOX_TAG, {\n props: {\n color: prop.oneOf(THEME_COLORS),\n effect: prop.oneOf(BOX_EFFECTS),\n elevation: prop.oneOf(ELEVATION_LEVELS),\n fullwidth: prop.bool(),\n padding: prop.oneOf(PADDING_SIZES),\n rounded: prop.oneOf(ROUNDED_SIZES),\n variant: prop.oneOf(BOX_VARIANTS),\n },\n setup() {\n return html`\n <div class=\"box\" part=\"box\"><slot></slot></div>\n `;\n },\n\n styles: [\n colorThemeMixin,\n elevationMixin,\n paddingMixin,\n roundedVariantMixin,\n frostVariantMixin('.box'),\n rainbowEffectMixin('.box'),\n componentStyles,\n ],\n});\n"],"mappings":"igBAqBA,IAAM,EAAc,CAAC,SAAS,EACxB,EAAe,CAAC,OAAQ,QAAS,OAAO,EAoDjC,EAAU,UACvB,EAAoB,EAAS,CAC3B,MAAO,CACL,MAAO,EAAK,MAAM,CAAY,EAC9B,OAAQ,EAAK,MAAM,CAAW,EAC9B,UAAW,EAAK,MAAM,CAAgB,EACtC,UAAW,EAAK,KAAK,EACrB,QAAS,EAAK,MAAM,CAAa,EACjC,QAAS,EAAK,MAAM,CAAa,EACjC,QAAS,EAAK,MAAM,CAAY,CAClC,EACA,OAAQ,CACN,MAAO,EAAI;;KAGb,EAEA,OAAQ,CACN,EACA,EACA,EACA,EACA,EAAkB,MAAM,EACxB,EAAmB,MAAM,EACzB,CACF,CACF,CAAC"}
@@ -1,6 +1,6 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./styles/mixins/shape.css.cjs"),t=require("./shared/prop-bundles.cjs"),n=require("./inputs/button-group/button-group.css.cjs");let r=require("@vielzeug/ore");var i=(0,r.createContext)(`OreButtonGroup`),a=`ore-button-group`;(0,r.define)(a,{props:{...t.themableBundle,...t.sizableBundle,...t.roundableBundle,attached:r.prop.bool(!1),fullwidth:r.prop.bool(!1),label:r.prop.string(),orientation:r.prop.string(),variant:r.prop.string()},setup(e){return(0,r.provide)(i,{color:e.color,size:e.size,variant:e.variant}),r.html`
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./styles/mixins/shape.css.cjs"),t=require("./shared/types.cjs"),n=require("./shared/prop-bundles.cjs"),r=require("./inputs/button-group/button-group.css.cjs");let i=require("@vielzeug/ore");var a=(0,i.createContext)(`OreButtonGroup`),o=[`horizontal`,`vertical`],s=`ore-button-group`;(0,i.define)(s,{props:{...n.themableBundle,...n.sizableBundle,...n.roundableBundle,attached:i.prop.bool(!1),fullwidth:i.prop.bool(!1),label:i.prop.string(),orientation:i.prop.oneOf(o),variant:i.prop.oneOf(t.VISUAL_VARIANTS)},setup(e){return(0,i.provide)(a,{color:e.color,size:e.size,variant:e.variant}),i.html`
2
2
  <div class="button-group" part="group" role="group" aria-label="${e.label}">
3
3
  <slot></slot>
4
4
  </div>
5
- `},styles:[e.roundedVariantMixin,n.default]}),exports.BUTTON_GROUP_CTX=i,exports.BUTTON_GROUP_TAG=a;
5
+ `},styles:[e.roundedVariantMixin,r.default]}),exports.BUTTON_GROUP_CTX=a,exports.BUTTON_GROUP_TAG=s;
6
6
  //# sourceMappingURL=button-group.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"button-group.cjs","names":[],"sources":["../src/inputs/button-group/button-group.ts"],"sourcesContent":["import { createContext, define, html, prop, provide } from '@vielzeug/ore';\nimport type { Readable } from '@vielzeug/ripple';\n\nimport type { ComponentSize, RoundedSize, ThemeColor } from '../../shared';\nimport { roundableBundle, sizableBundle, themableBundle } from '../../shared';\nimport { roundedVariantMixin } from '../../styles';\nimport type { ButtonVariant } from '../button/button';\nimport componentStyles from './button-group.css?inline';\n\n/** Button group properties */\nexport type OreButtonGroupProps = {\n /** Join buttons together into a single unit */\n attached?: boolean;\n /** Theme color tint for all child buttons */\n color?: ThemeColor;\n /** Group children span full width */\n fullwidth?: boolean;\n /** Label for screen readers */\n label?: string;\n /** Layout direction */\n orientation?: 'horizontal' | 'vertical';\n /** Corner radius of the group container (and its attached-mode end buttons) */\n rounded?: RoundedSize | '';\n /** Shared size for all child buttons */\n size?: ComponentSize;\n /** Shared visual variant for all child buttons */\n variant?: ButtonVariant;\n};\n\n/** Shared context propagated from ore-button-group to child ore-button elements */\nexport type ButtonGroupContext = {\n color: Readable<ThemeColor | undefined>;\n size: Readable<ComponentSize | undefined>;\n variant: Readable<ButtonVariant | undefined>;\n};\n\nexport const BUTTON_GROUP_CTX = createContext<ButtonGroupContext | undefined>('OreButtonGroup');\n\n/**\n * A container for grouping related buttons.\n * Child `ore-button` components automatically inherit the group's color, size, and variant.\n *\n * @element ore-button-group\n *\n * @attr {boolean} attached - Join buttons together into a unit\n * @attr {string} color - Shared color tint: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error'\n * @attr {boolean} fullwidth - Group spans full width\n * @attr {string} label - Accessible label\n * @attr {string} orientation - 'horizontal' | 'vertical'\n * @attr {string} rounded - Corner radius: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full' (bare attribute defaults to 'full')\n * @attr {string} size - Shared size: 'sm' | 'md' | 'lg'\n * @attr {string} variant - Shared visual variant: 'solid' | 'flat' | 'bordered' | 'outline' | 'ghost' | 'frost'\n *\n * @slot - Place ore-button elements here\n *\n * @cssprop --group-gap - Gap between buttons (non-attached mode)\n * @cssprop --group-radius - Border radius of the group container, defaults to the `rounded` attribute's token\n * @cssprop --button-radius - Passed through to child buttons to control corner radius\n * @cssprop --button-border-start - Passed through to suppress start borders in attached mode\n * @cssprop --button-border-top - Passed through to suppress top borders in vertical attached mode\n * @part group - Group container.\n * @example\n * ```html\n * <ore-button-group attached rounded=\"full\">\n * <ore-button variant=\"solid\" color=\"primary\">Save</ore-button>\n * <ore-button variant=\"solid\" color=\"primary\">Save &amp; Continue</ore-button>\n * </ore-button-group>\n * <ore-button-group orientation=\"vertical\" size=\"sm\">\n * <ore-button>Top</ore-button>\n * <ore-button>Middle</ore-button>\n * <ore-button>Bottom</ore-button>\n * </ore-button-group>\n * ```\n */\nexport const BUTTON_GROUP_TAG = 'ore-button-group' as const;\ndefine<OreButtonGroupProps>(BUTTON_GROUP_TAG, {\n props: {\n ...themableBundle,\n ...sizableBundle,\n ...roundableBundle,\n attached: prop.bool(false),\n fullwidth: prop.bool(false),\n label: prop.string(),\n orientation: prop.string<'horizontal' | 'vertical'>(),\n variant: prop.string(),\n },\n setup(props) {\n provide(BUTTON_GROUP_CTX, {\n color: props.color!,\n size: props.size!,\n variant: props.variant!,\n });\n\n return html`\n <div class=\"button-group\" part=\"group\" role=\"group\" aria-label=\"${props.label}\">\n <slot></slot>\n </div>\n `;\n },\n styles: [roundedVariantMixin, componentStyles],\n});\n"],"mappings":"kPAoCA,IAAa,GAAA,EAAmB,EAAA,cAAA,CAA8C,gBAAgB,EAsCjF,EAAmB,oBAChC,EAAA,EAAA,OAAA,CAA4B,EAAkB,CAC5C,MAAO,CACL,GAAG,EAAA,eACH,GAAG,EAAA,cACH,GAAG,EAAA,gBACH,SAAU,EAAA,KAAK,KAAK,EAAK,EACzB,UAAW,EAAA,KAAK,KAAK,EAAK,EAC1B,MAAO,EAAA,KAAK,OAAO,EACnB,YAAa,EAAA,KAAK,OAAkC,EACpD,QAAS,EAAA,KAAK,OAAO,CACvB,EACA,MAAM,EAAO,CAOX,OANA,EAAA,EAAA,QAAA,CAAQ,EAAkB,CACxB,MAAO,EAAM,MACb,KAAM,EAAM,KACZ,QAAS,EAAM,OACjB,CAAC,EAEM,EAAA,IAAI;wEACyD,EAAM,MAAM;;;KAIlF,EACA,OAAQ,CAAC,EAAA,oBAAqB,EAAA,OAAe,CAC/C,CAAC"}
1
+ {"version":3,"file":"button-group.cjs","names":[],"sources":["../src/inputs/button-group/button-group.ts"],"sourcesContent":["import { createContext, define, html, prop, provide } from '@vielzeug/ore';\nimport type { Readable } from '@vielzeug/ripple';\nimport {\n type ComponentSize,\n type RoundedSize,\n roundableBundle,\n sizableBundle,\n type ThemeColor,\n themableBundle,\n VISUAL_VARIANTS,\n} from '../../shared';\nimport { roundedVariantMixin } from '../../styles';\nimport type { ButtonVariant } from '../button/button';\nimport componentStyles from './button-group.css?inline';\n\n/** Button group properties */\nexport type OreButtonGroupProps = {\n /** Join buttons together into a single unit */\n attached?: boolean;\n /** Theme color tint for all child buttons */\n color?: ThemeColor;\n /** Group children span full width */\n fullwidth?: boolean;\n /** Label for screen readers */\n label?: string;\n /** Layout direction */\n orientation?: 'horizontal' | 'vertical';\n /** Corner radius of the group container (and its attached-mode end buttons) */\n rounded?: RoundedSize | '';\n /** Shared size for all child buttons */\n size?: ComponentSize;\n /** Shared visual variant for all child buttons */\n variant?: ButtonVariant;\n};\n\n/** Shared context propagated from ore-button-group to child ore-button elements */\nexport type ButtonGroupContext = {\n color: Readable<ThemeColor | undefined>;\n size: Readable<ComponentSize | undefined>;\n variant: Readable<ButtonVariant | undefined>;\n};\n\nexport const BUTTON_GROUP_CTX = createContext<ButtonGroupContext | undefined>('OreButtonGroup');\n\n/**\n * A container for grouping related buttons.\n * Child `ore-button` components automatically inherit the group's color, size, and variant.\n *\n * @element ore-button-group\n *\n * @attr {boolean} attached - Join buttons together into a unit\n * @attr {string} color - Shared color tint: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error'\n * @attr {boolean} fullwidth - Group spans full width\n * @attr {string} label - Accessible label\n * @attr {string} orientation - 'horizontal' | 'vertical'\n * @attr {string} rounded - Corner radius: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full' (bare attribute defaults to 'full')\n * @attr {string} size - Shared size: 'sm' | 'md' | 'lg'\n * @attr {string} variant - Shared visual variant: 'solid' | 'flat' | 'bordered' | 'outline' | 'ghost' | 'frost'\n *\n * @slot - Place ore-button elements here\n *\n * @cssprop --group-gap - Gap between buttons (non-attached mode)\n * @cssprop --group-radius - Border radius of the group container, defaults to the `rounded` attribute's token\n * @cssprop --button-radius - Passed through to child buttons to control corner radius\n * @cssprop --button-border-start - Passed through to suppress start borders in attached mode\n * @cssprop --button-border-top - Passed through to suppress top borders in vertical attached mode\n * @part group - Group container.\n * @example\n * ```html\n * <ore-button-group attached rounded=\"full\">\n * <ore-button variant=\"solid\" color=\"primary\">Save</ore-button>\n * <ore-button variant=\"solid\" color=\"primary\">Save &amp; Continue</ore-button>\n * </ore-button-group>\n * <ore-button-group orientation=\"vertical\" size=\"sm\">\n * <ore-button>Top</ore-button>\n * <ore-button>Middle</ore-button>\n * <ore-button>Bottom</ore-button>\n * </ore-button-group>\n * ```\n */\nconst BUTTON_GROUP_ORIENTATIONS = ['horizontal', 'vertical'] as const;\n\nexport const BUTTON_GROUP_TAG = 'ore-button-group' as const;\ndefine<OreButtonGroupProps>(BUTTON_GROUP_TAG, {\n props: {\n ...themableBundle,\n ...sizableBundle,\n ...roundableBundle,\n attached: prop.bool(false),\n fullwidth: prop.bool(false),\n label: prop.string(),\n orientation: prop.oneOf(BUTTON_GROUP_ORIENTATIONS),\n variant: prop.oneOf(VISUAL_VARIANTS),\n },\n setup(props) {\n provide(BUTTON_GROUP_CTX, {\n color: props.color!,\n size: props.size!,\n variant: props.variant!,\n });\n\n return html`\n <div class=\"button-group\" part=\"group\" role=\"group\" aria-label=\"${props.label}\">\n <slot></slot>\n </div>\n `;\n },\n styles: [roundedVariantMixin, componentStyles],\n});\n"],"mappings":"kRA0CA,IAAa,GAAA,EAAmB,EAAA,cAAA,CAA8C,gBAAgB,EAsCxF,EAA4B,CAAC,aAAc,UAAU,EAE9C,EAAmB,oBAChC,EAAA,EAAA,OAAA,CAA4B,EAAkB,CAC5C,MAAO,CACL,GAAG,EAAA,eACH,GAAG,EAAA,cACH,GAAG,EAAA,gBACH,SAAU,EAAA,KAAK,KAAK,EAAK,EACzB,UAAW,EAAA,KAAK,KAAK,EAAK,EAC1B,MAAO,EAAA,KAAK,OAAO,EACnB,YAAa,EAAA,KAAK,MAAM,CAAyB,EACjD,QAAS,EAAA,KAAK,MAAM,EAAA,eAAe,CACrC,EACA,MAAM,EAAO,CAOX,OANA,EAAA,EAAA,QAAA,CAAQ,EAAkB,CACxB,MAAO,EAAM,MACb,KAAM,EAAM,KACZ,QAAS,EAAM,OACjB,CAAC,EAEM,EAAA,IAAI;wEACyD,EAAM,MAAM;;;KAIlF,EACA,OAAQ,CAAC,EAAA,oBAAqB,EAAA,OAAe,CAC/C,CAAC"}
@@ -1,6 +1,6 @@
1
- import{roundedVariantMixin as e}from"./styles/mixins/shape.css.js";import{roundableBundle as t,sizableBundle as n,themableBundle as r}from"./shared/prop-bundles.js";import i from"./inputs/button-group/button-group.css.js";import{createContext as a,define as o,html as s,prop as c,provide as l}from"@vielzeug/ore";var u=a(`OreButtonGroup`),d=`ore-button-group`;o(d,{props:{...r,...n,...t,attached:c.bool(!1),fullwidth:c.bool(!1),label:c.string(),orientation:c.string(),variant:c.string()},setup(e){return l(u,{color:e.color,size:e.size,variant:e.variant}),s`
1
+ import{roundedVariantMixin as e}from"./styles/mixins/shape.css.js";import{VISUAL_VARIANTS as t}from"./shared/types.js";import{roundableBundle as n,sizableBundle as r,themableBundle as i}from"./shared/prop-bundles.js";import a from"./inputs/button-group/button-group.css.js";import{createContext as o,define as s,html as c,prop as l,provide as u}from"@vielzeug/ore";var d=o(`OreButtonGroup`),f=[`horizontal`,`vertical`],p=`ore-button-group`;s(p,{props:{...i,...r,...n,attached:l.bool(!1),fullwidth:l.bool(!1),label:l.string(),orientation:l.oneOf(f),variant:l.oneOf(t)},setup(e){return u(d,{color:e.color,size:e.size,variant:e.variant}),c`
2
2
  <div class="button-group" part="group" role="group" aria-label="${e.label}">
3
3
  <slot></slot>
4
4
  </div>
5
- `},styles:[e,i]});export{u as BUTTON_GROUP_CTX,d as BUTTON_GROUP_TAG};
5
+ `},styles:[e,a]});export{d as BUTTON_GROUP_CTX,p as BUTTON_GROUP_TAG};
6
6
  //# sourceMappingURL=button-group.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"button-group.js","names":[],"sources":["../src/inputs/button-group/button-group.ts"],"sourcesContent":["import { createContext, define, html, prop, provide } from '@vielzeug/ore';\nimport type { Readable } from '@vielzeug/ripple';\n\nimport type { ComponentSize, RoundedSize, ThemeColor } from '../../shared';\nimport { roundableBundle, sizableBundle, themableBundle } from '../../shared';\nimport { roundedVariantMixin } from '../../styles';\nimport type { ButtonVariant } from '../button/button';\nimport componentStyles from './button-group.css?inline';\n\n/** Button group properties */\nexport type OreButtonGroupProps = {\n /** Join buttons together into a single unit */\n attached?: boolean;\n /** Theme color tint for all child buttons */\n color?: ThemeColor;\n /** Group children span full width */\n fullwidth?: boolean;\n /** Label for screen readers */\n label?: string;\n /** Layout direction */\n orientation?: 'horizontal' | 'vertical';\n /** Corner radius of the group container (and its attached-mode end buttons) */\n rounded?: RoundedSize | '';\n /** Shared size for all child buttons */\n size?: ComponentSize;\n /** Shared visual variant for all child buttons */\n variant?: ButtonVariant;\n};\n\n/** Shared context propagated from ore-button-group to child ore-button elements */\nexport type ButtonGroupContext = {\n color: Readable<ThemeColor | undefined>;\n size: Readable<ComponentSize | undefined>;\n variant: Readable<ButtonVariant | undefined>;\n};\n\nexport const BUTTON_GROUP_CTX = createContext<ButtonGroupContext | undefined>('OreButtonGroup');\n\n/**\n * A container for grouping related buttons.\n * Child `ore-button` components automatically inherit the group's color, size, and variant.\n *\n * @element ore-button-group\n *\n * @attr {boolean} attached - Join buttons together into a unit\n * @attr {string} color - Shared color tint: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error'\n * @attr {boolean} fullwidth - Group spans full width\n * @attr {string} label - Accessible label\n * @attr {string} orientation - 'horizontal' | 'vertical'\n * @attr {string} rounded - Corner radius: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full' (bare attribute defaults to 'full')\n * @attr {string} size - Shared size: 'sm' | 'md' | 'lg'\n * @attr {string} variant - Shared visual variant: 'solid' | 'flat' | 'bordered' | 'outline' | 'ghost' | 'frost'\n *\n * @slot - Place ore-button elements here\n *\n * @cssprop --group-gap - Gap between buttons (non-attached mode)\n * @cssprop --group-radius - Border radius of the group container, defaults to the `rounded` attribute's token\n * @cssprop --button-radius - Passed through to child buttons to control corner radius\n * @cssprop --button-border-start - Passed through to suppress start borders in attached mode\n * @cssprop --button-border-top - Passed through to suppress top borders in vertical attached mode\n * @part group - Group container.\n * @example\n * ```html\n * <ore-button-group attached rounded=\"full\">\n * <ore-button variant=\"solid\" color=\"primary\">Save</ore-button>\n * <ore-button variant=\"solid\" color=\"primary\">Save &amp; Continue</ore-button>\n * </ore-button-group>\n * <ore-button-group orientation=\"vertical\" size=\"sm\">\n * <ore-button>Top</ore-button>\n * <ore-button>Middle</ore-button>\n * <ore-button>Bottom</ore-button>\n * </ore-button-group>\n * ```\n */\nexport const BUTTON_GROUP_TAG = 'ore-button-group' as const;\ndefine<OreButtonGroupProps>(BUTTON_GROUP_TAG, {\n props: {\n ...themableBundle,\n ...sizableBundle,\n ...roundableBundle,\n attached: prop.bool(false),\n fullwidth: prop.bool(false),\n label: prop.string(),\n orientation: prop.string<'horizontal' | 'vertical'>(),\n variant: prop.string(),\n },\n setup(props) {\n provide(BUTTON_GROUP_CTX, {\n color: props.color!,\n size: props.size!,\n variant: props.variant!,\n });\n\n return html`\n <div class=\"button-group\" part=\"group\" role=\"group\" aria-label=\"${props.label}\">\n <slot></slot>\n </div>\n `;\n },\n styles: [roundedVariantMixin, componentStyles],\n});\n"],"mappings":"yTAoCA,IAAa,EAAmB,EAA8C,gBAAgB,EAsCjF,EAAmB,mBAChC,EAA4B,EAAkB,CAC5C,MAAO,CACL,GAAG,EACH,GAAG,EACH,GAAG,EACH,SAAU,EAAK,KAAK,EAAK,EACzB,UAAW,EAAK,KAAK,EAAK,EAC1B,MAAO,EAAK,OAAO,EACnB,YAAa,EAAK,OAAkC,EACpD,QAAS,EAAK,OAAO,CACvB,EACA,MAAM,EAAO,CAOX,OANA,EAAQ,EAAkB,CACxB,MAAO,EAAM,MACb,KAAM,EAAM,KACZ,QAAS,EAAM,OACjB,CAAC,EAEM,CAAI;wEACyD,EAAM,MAAM;;;KAIlF,EACA,OAAQ,CAAC,EAAqB,CAAe,CAC/C,CAAC"}
1
+ {"version":3,"file":"button-group.js","names":[],"sources":["../src/inputs/button-group/button-group.ts"],"sourcesContent":["import { createContext, define, html, prop, provide } from '@vielzeug/ore';\nimport type { Readable } from '@vielzeug/ripple';\nimport {\n type ComponentSize,\n type RoundedSize,\n roundableBundle,\n sizableBundle,\n type ThemeColor,\n themableBundle,\n VISUAL_VARIANTS,\n} from '../../shared';\nimport { roundedVariantMixin } from '../../styles';\nimport type { ButtonVariant } from '../button/button';\nimport componentStyles from './button-group.css?inline';\n\n/** Button group properties */\nexport type OreButtonGroupProps = {\n /** Join buttons together into a single unit */\n attached?: boolean;\n /** Theme color tint for all child buttons */\n color?: ThemeColor;\n /** Group children span full width */\n fullwidth?: boolean;\n /** Label for screen readers */\n label?: string;\n /** Layout direction */\n orientation?: 'horizontal' | 'vertical';\n /** Corner radius of the group container (and its attached-mode end buttons) */\n rounded?: RoundedSize | '';\n /** Shared size for all child buttons */\n size?: ComponentSize;\n /** Shared visual variant for all child buttons */\n variant?: ButtonVariant;\n};\n\n/** Shared context propagated from ore-button-group to child ore-button elements */\nexport type ButtonGroupContext = {\n color: Readable<ThemeColor | undefined>;\n size: Readable<ComponentSize | undefined>;\n variant: Readable<ButtonVariant | undefined>;\n};\n\nexport const BUTTON_GROUP_CTX = createContext<ButtonGroupContext | undefined>('OreButtonGroup');\n\n/**\n * A container for grouping related buttons.\n * Child `ore-button` components automatically inherit the group's color, size, and variant.\n *\n * @element ore-button-group\n *\n * @attr {boolean} attached - Join buttons together into a unit\n * @attr {string} color - Shared color tint: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error'\n * @attr {boolean} fullwidth - Group spans full width\n * @attr {string} label - Accessible label\n * @attr {string} orientation - 'horizontal' | 'vertical'\n * @attr {string} rounded - Corner radius: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full' (bare attribute defaults to 'full')\n * @attr {string} size - Shared size: 'sm' | 'md' | 'lg'\n * @attr {string} variant - Shared visual variant: 'solid' | 'flat' | 'bordered' | 'outline' | 'ghost' | 'frost'\n *\n * @slot - Place ore-button elements here\n *\n * @cssprop --group-gap - Gap between buttons (non-attached mode)\n * @cssprop --group-radius - Border radius of the group container, defaults to the `rounded` attribute's token\n * @cssprop --button-radius - Passed through to child buttons to control corner radius\n * @cssprop --button-border-start - Passed through to suppress start borders in attached mode\n * @cssprop --button-border-top - Passed through to suppress top borders in vertical attached mode\n * @part group - Group container.\n * @example\n * ```html\n * <ore-button-group attached rounded=\"full\">\n * <ore-button variant=\"solid\" color=\"primary\">Save</ore-button>\n * <ore-button variant=\"solid\" color=\"primary\">Save &amp; Continue</ore-button>\n * </ore-button-group>\n * <ore-button-group orientation=\"vertical\" size=\"sm\">\n * <ore-button>Top</ore-button>\n * <ore-button>Middle</ore-button>\n * <ore-button>Bottom</ore-button>\n * </ore-button-group>\n * ```\n */\nconst BUTTON_GROUP_ORIENTATIONS = ['horizontal', 'vertical'] as const;\n\nexport const BUTTON_GROUP_TAG = 'ore-button-group' as const;\ndefine<OreButtonGroupProps>(BUTTON_GROUP_TAG, {\n props: {\n ...themableBundle,\n ...sizableBundle,\n ...roundableBundle,\n attached: prop.bool(false),\n fullwidth: prop.bool(false),\n label: prop.string(),\n orientation: prop.oneOf(BUTTON_GROUP_ORIENTATIONS),\n variant: prop.oneOf(VISUAL_VARIANTS),\n },\n setup(props) {\n provide(BUTTON_GROUP_CTX, {\n color: props.color!,\n size: props.size!,\n variant: props.variant!,\n });\n\n return html`\n <div class=\"button-group\" part=\"group\" role=\"group\" aria-label=\"${props.label}\">\n <slot></slot>\n </div>\n `;\n },\n styles: [roundedVariantMixin, componentStyles],\n});\n"],"mappings":"6WA0CA,IAAa,EAAmB,EAA8C,gBAAgB,EAsCxF,EAA4B,CAAC,aAAc,UAAU,EAE9C,EAAmB,mBAChC,EAA4B,EAAkB,CAC5C,MAAO,CACL,GAAG,EACH,GAAG,EACH,GAAG,EACH,SAAU,EAAK,KAAK,EAAK,EACzB,UAAW,EAAK,KAAK,EAAK,EAC1B,MAAO,EAAK,OAAO,EACnB,YAAa,EAAK,MAAM,CAAyB,EACjD,QAAS,EAAK,MAAM,CAAe,CACrC,EACA,MAAM,EAAO,CAOX,OANA,EAAQ,EAAkB,CACxB,MAAO,EAAM,MACb,KAAM,EAAM,KACZ,QAAS,EAAM,OACjB,CAAC,EAEM,CAAI;wEACyD,EAAM,MAAM;;;KAIlF,EACA,OAAQ,CAAC,EAAqB,CAAe,CAC/C,CAAC"}
package/dist/button.cjs CHANGED
@@ -1,24 +1,24 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./styles/mixins/accessibility.css.cjs"),t=require("./styles/mixins/animation.css.cjs"),n=require("./styles/mixins/shape.css.cjs"),r=require("./styles/mixins/states.css.cjs"),i=require("./styles/mixins/theme.css.cjs"),a=require("./styles/mixins/variants.css.cjs"),o=require("./shared/prop-bundles.cjs"),s=require("./utils/link.cjs"),c=require("./button-group.cjs"),l=require("./inputs/shared/use-form-action.cjs"),u=require("./inputs/button/button.css.cjs");let d=require("@vielzeug/ripple"),f=require("@vielzeug/ore");var p=[`solid`,`flat`,`bordered`,`outline`,`ghost`,`text`,`frost`],m=`ore-button`;(0,f.define)(m,{formAssociated:!0,props:{...o.commonProps,effect:f.prop.string(),fullheight:f.prop.bool(!1),fullwidth:f.prop.bool(!1),href:f.prop.string(),iconOnly:f.prop.bool(!1),label:f.prop.string(),rel:f.prop.string(),target:f.prop.string(),type:f.prop.oneOf([`button`,`submit`,`reset`],`button`),variant:f.prop.oneOf(p,`solid`)},setup(e){let t=(0,f.getHost)(),n=(0,f.inject)(c.BUTTON_GROUP_CTX),r=(0,d.computed)(()=>n?.color.value??e.color.value),i=(0,d.computed)(()=>n?.size.value??e.size.value),a=(0,d.computed)(()=>n?.variant.value??e.variant.value),o=(0,d.computed)(()=>!!(e.disabled.value||e.loading.value)),{effectiveRel:u,isLink:p}=s.useLinkProps(e.href,e.rel,e.target),m=(0,f.useField)({disabled:o,toFormValue:()=>null,value:(0,d.computed)(()=>``)}),handleClick=n=>{if(o.value){n.preventDefault();return}l.useFormAction(()=>p.value?null:m.internals.form,e.type,o,t)(n)},handleKeydown=e=>{p.value||(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),(t.shadowRoot?.querySelector(`[part="button"]`))?.click())};(0,f.bind)({attr:{"aria-busy":(0,d.computed)(()=>p.value?null:e.loading.value),"aria-disabled":(0,d.computed)(()=>p.value?null:o.value),"aria-label":(0,d.computed)(()=>p.value?null:e.label.value),color:r,effect:e.effect,role:(0,d.computed)(()=>p.value?null:t.getAttribute(`role`)??`button`),size:i,tabindex:(0,d.computed)(()=>p.value?null:o.value?`-1`:`0`),variant:a},on:{keydown:handleKeydown}});let buttonContent=()=>f.html`
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./styles/mixins/accessibility.css.cjs"),t=require("./styles/mixins/animation.css.cjs"),n=require("./styles/mixins/shape.css.cjs"),r=require("./styles/mixins/states.css.cjs"),i=require("./styles/mixins/theme.css.cjs"),a=require("./styles/mixins/variants.css.cjs"),o=require("./shared/types.cjs"),s=require("./shared/prop-bundles.cjs"),c=require("./utils/link.cjs"),l=require("./button-group.cjs"),u=require("./inputs/shared/use-form-action.cjs"),d=require("./inputs/button/button.css.cjs");let f=require("@vielzeug/ripple"),p=require("@vielzeug/ore");var m=[`solid`,`flat`,`bordered`,`outline`,`ghost`,`text`,`frost`],h=[`shine`,`rainbow`],g=`ore-button`;(0,p.define)(g,{formAssociated:!0,props:{...s.commonProps,effect:p.prop.oneOf(h),fullheight:p.prop.bool(!1),fullwidth:p.prop.bool(!1),href:p.prop.string(),iconOnly:p.prop.bool(!1),label:p.prop.string(),rel:p.prop.string(),target:p.prop.oneOf(o.LINK_TARGETS),type:p.prop.oneOf([`button`,`submit`,`reset`],`button`),variant:p.prop.oneOf(m,`solid`)},setup(e){let t=(0,p.getHost)(),n=(0,p.inject)(l.BUTTON_GROUP_CTX),r=(0,f.computed)(()=>n?.color.value??e.color.value),i=(0,f.computed)(()=>n?.size.value??e.size.value),a=(0,f.computed)(()=>n?.variant.value??e.variant.value),o=(0,f.computed)(()=>!!(e.disabled.value||e.loading.value)),{effectiveRel:s,isLink:d}=c.useLinkProps(e.href,e.rel,e.target),m=(0,p.useField)({disabled:o,toFormValue:()=>null,value:(0,f.computed)(()=>``)}),handleClick=n=>{if(o.value){n.preventDefault();return}u.useFormAction(()=>d.value?null:m.internals.form,e.type,o,t)(n)},handleKeydown=e=>{d.value||(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),(t.shadowRoot?.querySelector(`[part="button"]`))?.click())};(0,p.bind)({attr:{"aria-busy":(0,f.computed)(()=>d.value?null:e.loading.value),"aria-disabled":(0,f.computed)(()=>d.value?null:o.value),"aria-label":(0,f.computed)(()=>d.value?null:e.label.value),color:r,effect:e.effect,role:(0,f.computed)(()=>d.value?null:t.getAttribute(`role`)??`button`),size:i,tabindex:(0,f.computed)(()=>d.value?null:o.value?`-1`:`0`),variant:a},on:{keydown:handleKeydown}});let buttonContent=()=>p.html`
2
2
  <span class="loader" part="loader" aria-label="Loading" ?hidden=${()=>!e.loading.value}></span>
3
3
  <slot name="prefix"></slot>
4
4
  <span class="content" part="content"><slot></slot></span>
5
5
  <slot name="suffix"></slot>
6
- `;return f.html`
7
- ${()=>p.value?f.html`
6
+ `;return p.html`
7
+ ${()=>d.value?p.html`
8
8
  <a
9
9
  part="button"
10
10
  aria-busy="${e.loading}"
11
11
  aria-disabled="${o}"
12
- aria-label="${(0,d.computed)(()=>e.label.value||t.textContent?.trim()||null)}"
13
- tabindex="${(0,d.computed)(()=>o.value?`-1`:null)}"
14
- href="${(0,d.computed)(()=>o.value?null:e.href.value)}"
15
- rel="${u}"
12
+ aria-label="${(0,f.computed)(()=>e.label.value||t.textContent?.trim()||null)}"
13
+ tabindex="${(0,f.computed)(()=>o.value?`-1`:null)}"
14
+ href="${(0,f.computed)(()=>o.value?null:e.href.value)}"
15
+ rel="${s}"
16
16
  target="${e.target}"
17
17
  @click="${handleClick}">
18
18
  ${buttonContent()}
19
19
  </a>
20
- `:f.html`
20
+ `:p.html`
21
21
  <span part="button" role="presentation" @click="${handleClick}">${buttonContent()}</span>
22
22
  `}
23
- `},shadow:{delegatesFocus:!1},styles:[i.colorThemeMixin,e.coarsePointerMixin,e.reducedMotionMixin,n.roundedVariantMixin,i.forcedColorsMixin,n.sizeVariantMixin({lg:{fontSize:`var(--text-base)`,gap:`var(--size-2-5)`,height:`var(--size-12)`,iconSize:`var(--size-6)`,lineHeight:`var(--leading-relaxed)`,padding:`var(--size-2-5) var(--size-5)`},sm:{fontSize:`var(--text-sm)`,gap:`var(--size-1-5)`,height:`var(--size-8)`,iconSize:`var(--size-4)`,lineHeight:`var(--leading-tight)`,padding:`var(--size-1-5) var(--size-3)`}}),a.frostVariantMixin(`[part="button"]`),t.rainbowEffectMixin(`[part="button"]`),t.shineEffectMixin(`[part="button"]`),r.disabledLoadingMixin,u.default]}),exports.BUTTON_TAG=m,exports.BUTTON_VARIANTS=p;
23
+ `},shadow:{delegatesFocus:!1},styles:[i.colorThemeMixin,e.coarsePointerMixin,e.reducedMotionMixin,n.roundedVariantMixin,i.forcedColorsMixin,n.sizeVariantMixin({lg:{fontSize:`var(--text-base)`,gap:`var(--size-2-5)`,height:`var(--size-12)`,iconSize:`var(--size-6)`,lineHeight:`var(--leading-relaxed)`,padding:`var(--size-2-5) var(--size-5)`},sm:{fontSize:`var(--text-sm)`,gap:`var(--size-1-5)`,height:`var(--size-8)`,iconSize:`var(--size-4)`,lineHeight:`var(--leading-tight)`,padding:`var(--size-1-5) var(--size-3)`}}),a.frostVariantMixin(`[part="button"]`),t.rainbowEffectMixin(`[part="button"]`),t.shineEffectMixin(`[part="button"]`),r.disabledLoadingMixin,d.default]}),exports.BUTTON_EFFECTS=h,exports.BUTTON_TAG=g,exports.BUTTON_VARIANTS=m;
24
24
  //# sourceMappingURL=button.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"button.cjs","names":[],"sources":["../src/inputs/button/button.ts"],"sourcesContent":["import { bind, define, getHost, html, inject, prop, useField } from '@vielzeug/ore';\nimport { computed } from '@vielzeug/ripple';\nimport { commonProps } from '../../shared';\nimport {\n coarsePointerMixin,\n colorThemeMixin,\n disabledLoadingMixin,\n forcedColorsMixin,\n frostVariantMixin,\n rainbowEffectMixin,\n reducedMotionMixin,\n roundedVariantMixin,\n shineEffectMixin,\n sizeVariantMixin,\n} from '../../styles';\nimport type { ButtonType, ComponentSize, LinkTarget, RoundedSize, ThemeColor } from '../../types';\nimport { useLinkProps } from '../../utils';\nimport { BUTTON_GROUP_CTX } from '../button-group/button-group';\nimport { useFormAction } from '../shared';\nimport componentStyles from './button.css?inline';\n\nexport const BUTTON_VARIANTS = ['solid', 'flat', 'bordered', 'outline', 'ghost', 'text', 'frost'] as const;\n\n/** Visual variant for ore-button: derived from BUTTON_VARIANTS for a single source of truth. */\nexport type ButtonVariant = (typeof BUTTON_VARIANTS)[number];\n\n/** Animated border effect for ore-button. */\nexport type ButtonEffect = 'shine' | 'rainbow';\n\n/** Button component properties */\nexport type OreButtonProps = {\n /** Theme color */\n color?: ThemeColor;\n /** Disable interaction */\n disabled?: boolean;\n /** Animated border effect: 'shine' (color-aware neon sweep) or 'rainbow' */\n effect?: ButtonEffect;\n /**\n * Full height button (100% of container): the inner `[part=\"button\"]` fills its host's\n * height instead of the size preset's fixed height. Useful when the button itself is the\n * whole tappable surface of a container it doesn't otherwise control the size of (e.g. a\n * swipe-revealed row action in `ore-list-item`'s `actions-left`/`actions-right` slots).\n */\n fullheight?: boolean;\n /** Full width button (100% of container) */\n fullwidth?: boolean;\n /** When set, renders an `<a>` instead of `<button>` */\n href?: string;\n /** Icon-only mode (square aspect ratio, no padding) */\n iconOnly?: boolean;\n /** Accessible label for the inner button: required for icon-only buttons */\n label?: string;\n /** Show loading state with spinner */\n loading?: boolean;\n /** Link rel attribute (requires href) */\n rel?: string;\n /** Border radius size */\n rounded?: RoundedSize;\n /** Component size */\n size?: ComponentSize;\n /** Link target (requires href) */\n target?: LinkTarget;\n /** HTML button type attribute */\n type?: ButtonType;\n /** Visual style variant */\n variant?: ButtonVariant;\n};\n\n/**\n * A customizable button component with multiple variants, sizes, and states.\n * Supports icons, loading states, and animated border effects.\n *\n * @element ore-button\n *\n * @attr {string} type - HTML button type: 'button' | 'submit' | 'reset'\n * @attr {boolean} disabled - Disable button interaction\n * @attr {boolean} loading - Show loading state with spinner\n * @attr {string} color - Theme color: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error'\n * @attr {string} variant - Visual variant: 'solid' | 'flat' | 'bordered' | 'outline' | 'ghost' | 'text' | 'frost'\n * @attr {string} size - Button size: 'sm' | 'md' | 'lg'\n * @attr {string} rounded - Border radius: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'\n * @attr {string} effect - Animated border effect: 'shine' | 'rainbow'\n * @attr {boolean} icon-only - Icon-only mode (square aspect ratio, no padding)\n * @attr {boolean} fullwidth - Full width button (100% of container)\n * @attr {boolean} fullheight - Full height button (100% of container)\n *\n * @fires click - Emitted when button is clicked (unless disabled/loading)\n *\n * @slot - Button content (text, icons, etc.)\n * @slot prefix - Content before the button text (e.g., icons)\n * @slot suffix - Content after the button text (e.g., icons, badges)\n *\n * @part button - The inner button or anchor element\n * @part loader - The loading spinner element\n * @part content - The button content wrapper\n *\n * @cssprop --button-bg - Background color override\n * @cssprop --button-color - Text color override\n * @cssprop --button-border - Border width override\n * @cssprop --button-border-color - Border color override\n * @cssprop --button-radius - Border radius override\n * @cssprop --button-padding - Inner padding override\n * @cssprop --button-gap - Gap between icon and text override\n * @cssprop --button-font-size - Font size override\n * @cssprop --button-frost-active-bg - Background when pressed (frost variant)\n * @cssprop --button-frost-active-border-color - Border color when pressed (frost variant)\n *\n * @example\n * ```html\n * <ore-button variant=\"solid\" color=\"primary\">Click me</ore-button>\n * <ore-button loading color=\"success\">Processing...</ore-button>\n * <ore-button effect=\"shine\" color=\"primary\">Shine</ore-button>\n * <ore-button effect=\"rainbow\" variant=\"frost\">Rainbow</ore-button>\n * ```\n */\nexport const BUTTON_TAG = 'ore-button' as const;\ndefine<OreButtonProps>(BUTTON_TAG, {\n formAssociated: true,\n props: {\n ...commonProps,\n effect: prop.string<ButtonEffect>(),\n fullheight: prop.bool(false),\n fullwidth: prop.bool(false),\n href: prop.string(),\n iconOnly: prop.bool(false),\n label: prop.string(),\n rel: prop.string(),\n target: prop.string<LinkTarget>(),\n type: prop.oneOf(['button', 'submit', 'reset'] as const, 'button'),\n variant: prop.oneOf(BUTTON_VARIANTS, 'solid'),\n },\n setup(props) {\n const el = getHost();\n\n // Prefer group context over own props for color/size/variant.\n const groupCtx = inject(BUTTON_GROUP_CTX);\n const effectiveColor = computed(() => groupCtx?.color.value ?? props.color.value);\n const effectiveSize = computed(() => groupCtx?.size.value ?? props.size.value);\n const effectiveVariant = computed(() => groupCtx?.variant.value ?? props.variant.value);\n\n const isDisabled = computed(() => !!(props.disabled.value || props.loading.value));\n\n // isLink and effectiveRel are computed from signals: correct even if href changes at runtime.\n const { effectiveRel, isLink } = useLinkProps(props.href, props.rel, props.target);\n\n // Form association: relay submit/reset clicks to the associated form.\n // The inner <button> always has type=\"button\" so shadow DOM never drives native form actions.\n // getForm() returns null for link mode at runtime, so no form actions fire.\n const formField = useField({\n disabled: isDisabled,\n toFormValue: () => null,\n value: computed(() => ''),\n });\n\n const handleClick = (e: MouseEvent) => {\n if (isDisabled.value) {\n e.preventDefault();\n\n return;\n }\n\n // Link mode renders a real <a href> below: the browser handles left/middle/ctrl-click\n // navigation, target, and rel natively. No manual window.open/location.href needed.\n useFormAction(() => (isLink.value ? null : formField.internals.form), props.type, isDisabled, el)(e);\n };\n\n const handleKeydown = (e: KeyboardEvent) => {\n if (isLink.value) return;\n\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n (el.shadowRoot?.querySelector('[part=\"button\"]') as HTMLElement)?.click();\n }\n };\n\n // ARIA attributes live on the host.\n bind({\n attr: {\n 'aria-busy': computed(() => (isLink.value ? null : props.loading.value)),\n 'aria-disabled': computed(() => (isLink.value ? null : isDisabled.value)),\n 'aria-label': computed(() => (isLink.value ? null : props.label.value)),\n color: effectiveColor,\n effect: props.effect,\n role: computed(() => (isLink.value ? null : (el.getAttribute('role') ?? 'button'))),\n size: effectiveSize,\n tabindex: computed(() => (isLink.value ? null : isDisabled.value ? '-1' : '0')),\n variant: effectiveVariant,\n },\n on: {\n keydown: handleKeydown,\n },\n });\n\n // A factory, not a shared result: ore's static embed moves a result's\n // fragment children into place, consuming it. The link/button switch below\n // re-renders whenever `href` arrives or is removed at runtime (ore\n // templates set interpolated attributes after upgrade, so the first render\n // is usually the span branch), and a shared instance would render empty on\n // every switch after the first.\n const buttonContent = () => html`\n <span class=\"loader\" part=\"loader\" aria-label=\"Loading\" ?hidden=${() => !props.loading.value}></span>\n <slot name=\"prefix\"></slot>\n <span class=\"content\" part=\"content\"><slot></slot></span>\n <slot name=\"suffix\"></slot>\n `;\n\n // Link mode delegates semantics and focus to the native anchor. Button mode keeps them on\n // the form-associated host because its visual part is intentionally a non-semantic span.\n return html`\n ${() =>\n isLink.value\n ? html`\n <a\n part=\"button\"\n aria-busy=\"${props.loading}\"\n aria-disabled=\"${isDisabled}\"\n aria-label=\"${computed(() => props.label.value || el.textContent?.trim() || null)}\"\n tabindex=\"${computed(() => (isDisabled.value ? '-1' : null))}\"\n href=\"${computed(() => (isDisabled.value ? null : props.href.value))}\"\n rel=\"${effectiveRel}\"\n target=\"${props.target}\"\n @click=\"${handleClick}\">\n ${buttonContent()}\n </a>\n `\n : html`\n <span part=\"button\" role=\"presentation\" @click=\"${handleClick}\">${buttonContent()}</span>\n `}\n `;\n },\n shadow: { delegatesFocus: false },\n styles: [\n colorThemeMixin,\n coarsePointerMixin,\n reducedMotionMixin,\n roundedVariantMixin,\n forcedColorsMixin,\n sizeVariantMixin({\n lg: {\n fontSize: 'var(--text-base)',\n gap: 'var(--size-2-5)',\n height: 'var(--size-12)',\n iconSize: 'var(--size-6)',\n lineHeight: 'var(--leading-relaxed)',\n padding: 'var(--size-2-5) var(--size-5)',\n },\n sm: {\n fontSize: 'var(--text-sm)',\n gap: 'var(--size-1-5)',\n height: 'var(--size-8)',\n iconSize: 'var(--size-4)',\n lineHeight: 'var(--leading-tight)',\n padding: 'var(--size-1-5) var(--size-3)',\n },\n }),\n frostVariantMixin('[part=\"button\"]'),\n rainbowEffectMixin('[part=\"button\"]'),\n shineEffectMixin('[part=\"button\"]'),\n disabledLoadingMixin,\n componentStyles,\n ],\n});\n"],"mappings":"0lBAqBA,IAAa,EAAkB,CAAC,QAAS,OAAQ,WAAY,UAAW,QAAS,OAAQ,OAAO,EA8FnF,EAAa,cAC1B,EAAA,EAAA,OAAA,CAAuB,EAAY,CACjC,eAAgB,GAChB,MAAO,CACL,GAAG,EAAA,YACH,OAAQ,EAAA,KAAK,OAAqB,EAClC,WAAY,EAAA,KAAK,KAAK,EAAK,EAC3B,UAAW,EAAA,KAAK,KAAK,EAAK,EAC1B,KAAM,EAAA,KAAK,OAAO,EAClB,SAAU,EAAA,KAAK,KAAK,EAAK,EACzB,MAAO,EAAA,KAAK,OAAO,EACnB,IAAK,EAAA,KAAK,OAAO,EACjB,OAAQ,EAAA,KAAK,OAAmB,EAChC,KAAM,EAAA,KAAK,MAAM,CAAC,SAAU,SAAU,OAAO,EAAY,QAAQ,EACjE,QAAS,EAAA,KAAK,MAAM,EAAiB,OAAO,CAC9C,EACA,MAAM,EAAO,CACX,IAAM,GAAA,EAAK,EAAA,QAAA,CAAQ,EAGb,GAAA,EAAW,EAAA,OAAA,CAAO,EAAA,gBAAgB,EAClC,GAAA,EAAiB,EAAA,SAAA,KAAe,GAAU,MAAM,OAAS,EAAM,MAAM,KAAK,EAC1E,GAAA,EAAgB,EAAA,SAAA,KAAe,GAAU,KAAK,OAAS,EAAM,KAAK,KAAK,EACvE,GAAA,EAAmB,EAAA,SAAA,KAAe,GAAU,QAAQ,OAAS,EAAM,QAAQ,KAAK,EAEhF,GAAA,EAAa,EAAA,SAAA,KAAe,CAAC,EAAE,EAAM,SAAS,OAAS,EAAM,QAAQ,MAAM,EAG3E,CAAE,eAAc,UAAW,EAAA,aAAa,EAAM,KAAM,EAAM,IAAK,EAAM,MAAM,EAK3E,GAAA,EAAY,EAAA,SAAA,CAAS,CACzB,SAAU,EACV,gBAAmB,KACnB,OAAA,EAAO,EAAA,SAAA,KAAe,EAAE,CAC1B,CAAC,EAEK,YAAe,GAAkB,CACrC,GAAI,EAAW,MAAO,CACpB,EAAE,eAAe,EAEjB,MACF,CAIA,EAAA,kBAAqB,EAAO,MAAQ,KAAO,EAAU,UAAU,KAAO,EAAM,KAAM,EAAY,CAAE,CAAC,CAAC,CAAC,CACrG,EAEM,cAAiB,GAAqB,CACtC,EAAO,QAEP,EAAE,MAAQ,SAAW,EAAE,MAAQ,OACjC,EAAE,eAAe,GAChB,EAAG,YAAY,cAAc,iBAAiB,EAAA,EAAmB,MAAM,EAE5E,GAGA,EAAA,EAAA,KAAA,CAAK,CACH,KAAM,CACJ,aAAA,EAAa,EAAA,SAAA,KAAgB,EAAO,MAAQ,KAAO,EAAM,QAAQ,KAAM,EACvE,iBAAA,EAAiB,EAAA,SAAA,KAAgB,EAAO,MAAQ,KAAO,EAAW,KAAM,EACxE,cAAA,EAAc,EAAA,SAAA,KAAgB,EAAO,MAAQ,KAAO,EAAM,MAAM,KAAM,EACtE,MAAO,EACP,OAAQ,EAAM,OACd,MAAA,EAAM,EAAA,SAAA,KAAgB,EAAO,MAAQ,KAAQ,EAAG,aAAa,MAAM,GAAK,QAAU,EAClF,KAAM,EACN,UAAA,EAAU,EAAA,SAAA,KAAgB,EAAO,MAAQ,KAAO,EAAW,MAAQ,KAAO,GAAI,EAC9E,QAAS,CACX,EACA,GAAI,CACF,QAAS,aACX,CACF,CAAC,EAQD,IAAM,kBAAsB,EAAA,IAAI;4EAC0C,CAAC,EAAM,QAAQ,MAAM;;;;MAQ/F,MAAO,GAAA,IAAI;YAEP,EAAO,MACH,EAAA,IAAI;;;6BAGa,EAAM,QAAQ;iCACV,EAAW;+BACd,EAAA,EAAA,SAAA,KAAe,EAAM,MAAM,OAAS,EAAG,aAAa,KAAK,GAAK,IAAI,EAAE;6BACtE,EAAA,EAAA,SAAA,KAAgB,EAAW,MAAQ,KAAO,IAAK,EAAE;yBACrD,EAAA,EAAA,SAAA,KAAgB,EAAW,MAAQ,KAAO,EAAM,KAAK,KAAM,EAAE;uBAC9D,EAAa;0BACV,EAAM,OAAO;0BACb,YAAY;kBACpB,cAAc,EAAE;;cAGtB,EAAA,IAAI;gEACgD,YAAY,IAAI,cAAc,EAAE;cAClF;KAEZ,EACA,OAAQ,CAAE,eAAgB,EAAM,EAChC,OAAQ,CACN,EAAA,gBACA,EAAA,mBACA,EAAA,mBACA,EAAA,oBACA,EAAA,kBACA,EAAA,iBAAiB,CACf,GAAI,CACF,SAAU,mBACV,IAAK,kBACL,OAAQ,iBACR,SAAU,gBACV,WAAY,yBACZ,QAAS,+BACX,EACA,GAAI,CACF,SAAU,iBACV,IAAK,kBACL,OAAQ,gBACR,SAAU,gBACV,WAAY,uBACZ,QAAS,+BACX,CACF,CAAC,EACD,EAAA,kBAAkB,iBAAiB,EACnC,EAAA,mBAAmB,iBAAiB,EACpC,EAAA,iBAAiB,iBAAiB,EAClC,EAAA,qBACA,EAAA,OACF,CACF,CAAC"}
1
+ {"version":3,"file":"button.cjs","names":[],"sources":["../src/inputs/button/button.ts"],"sourcesContent":["import { bind, define, getHost, html, inject, prop, useField } from '@vielzeug/ore';\nimport { computed } from '@vielzeug/ripple';\nimport { commonProps } from '../../shared';\nimport {\n coarsePointerMixin,\n colorThemeMixin,\n disabledLoadingMixin,\n forcedColorsMixin,\n frostVariantMixin,\n rainbowEffectMixin,\n reducedMotionMixin,\n roundedVariantMixin,\n shineEffectMixin,\n sizeVariantMixin,\n} from '../../styles';\nimport {\n type ButtonType,\n type ComponentSize,\n LINK_TARGETS,\n type LinkTarget,\n type RoundedSize,\n type ThemeColor,\n} from '../../types';\nimport { useLinkProps } from '../../utils';\nimport { BUTTON_GROUP_CTX } from '../button-group/button-group';\nimport { useFormAction } from '../shared';\nimport componentStyles from './button.css?inline';\n\nexport const BUTTON_VARIANTS = ['solid', 'flat', 'bordered', 'outline', 'ghost', 'text', 'frost'] as const;\n\n/** Visual variant for ore-button: derived from BUTTON_VARIANTS for a single source of truth. */\nexport type ButtonVariant = (typeof BUTTON_VARIANTS)[number];\n\n/** Animated border effect for ore-button. */\nexport const BUTTON_EFFECTS = ['shine', 'rainbow'] as const;\nexport type ButtonEffect = (typeof BUTTON_EFFECTS)[number];\n\n/** Button component properties */\nexport type OreButtonProps = {\n /** Theme color */\n color?: ThemeColor;\n /** Disable interaction */\n disabled?: boolean;\n /** Animated border effect: 'shine' (color-aware neon sweep) or 'rainbow' */\n effect?: ButtonEffect;\n /**\n * Full height button (100% of container): the inner `[part=\"button\"]` fills its host's\n * height instead of the size preset's fixed height. Useful when the button itself is the\n * whole tappable surface of a container it doesn't otherwise control the size of (e.g. a\n * swipe-revealed row action in `ore-list-item`'s `actions-left`/`actions-right` slots).\n */\n fullheight?: boolean;\n /** Full width button (100% of container) */\n fullwidth?: boolean;\n /** When set, renders an `<a>` instead of `<button>` */\n href?: string;\n /** Icon-only mode (square aspect ratio, no padding) */\n iconOnly?: boolean;\n /** Accessible label for the inner button: required for icon-only buttons */\n label?: string;\n /** Show loading state with spinner */\n loading?: boolean;\n /** Link rel attribute (requires href) */\n rel?: string;\n /** Border radius size */\n rounded?: RoundedSize;\n /** Component size */\n size?: ComponentSize;\n /** Link target (requires href) */\n target?: LinkTarget;\n /** HTML button type attribute */\n type?: ButtonType;\n /** Visual style variant */\n variant?: ButtonVariant;\n};\n\n/**\n * A customizable button component with multiple variants, sizes, and states.\n * Supports icons, loading states, and animated border effects.\n *\n * @element ore-button\n *\n * @attr {string} type - HTML button type: 'button' | 'submit' | 'reset'\n * @attr {boolean} disabled - Disable button interaction\n * @attr {boolean} loading - Show loading state with spinner\n * @attr {string} color - Theme color: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error'\n * @attr {string} variant - Visual variant: 'solid' | 'flat' | 'bordered' | 'outline' | 'ghost' | 'text' | 'frost'\n * @attr {string} size - Button size: 'sm' | 'md' | 'lg'\n * @attr {string} rounded - Border radius: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'\n * @attr {string} effect - Animated border effect: 'shine' | 'rainbow'\n * @attr {boolean} icon-only - Icon-only mode (square aspect ratio, no padding)\n * @attr {boolean} fullwidth - Full width button (100% of container)\n * @attr {boolean} fullheight - Full height button (100% of container)\n *\n * @fires click - Emitted when button is clicked (unless disabled/loading)\n *\n * @slot - Button content (text, icons, etc.)\n * @slot prefix - Content before the button text (e.g., icons)\n * @slot suffix - Content after the button text (e.g., icons, badges)\n *\n * @part button - The inner button or anchor element\n * @part loader - The loading spinner element\n * @part content - The button content wrapper\n *\n * @cssprop --button-bg - Background color override\n * @cssprop --button-color - Text color override\n * @cssprop --button-border - Border width override\n * @cssprop --button-border-color - Border color override\n * @cssprop --button-radius - Border radius override\n * @cssprop --button-padding - Inner padding override\n * @cssprop --button-gap - Gap between icon and text override\n * @cssprop --button-font-size - Font size override\n * @cssprop --button-frost-active-bg - Background when pressed (frost variant)\n * @cssprop --button-frost-active-border-color - Border color when pressed (frost variant)\n *\n * @example\n * ```html\n * <ore-button variant=\"solid\" color=\"primary\">Click me</ore-button>\n * <ore-button loading color=\"success\">Processing...</ore-button>\n * <ore-button effect=\"shine\" color=\"primary\">Shine</ore-button>\n * <ore-button effect=\"rainbow\" variant=\"frost\">Rainbow</ore-button>\n * ```\n */\nexport const BUTTON_TAG = 'ore-button' as const;\ndefine<OreButtonProps>(BUTTON_TAG, {\n formAssociated: true,\n props: {\n ...commonProps,\n effect: prop.oneOf(BUTTON_EFFECTS),\n fullheight: prop.bool(false),\n fullwidth: prop.bool(false),\n href: prop.string(),\n iconOnly: prop.bool(false),\n label: prop.string(),\n rel: prop.string(),\n target: prop.oneOf(LINK_TARGETS),\n type: prop.oneOf(['button', 'submit', 'reset'] as const, 'button'),\n variant: prop.oneOf(BUTTON_VARIANTS, 'solid'),\n },\n setup(props) {\n const el = getHost();\n\n // Prefer group context over own props for color/size/variant.\n const groupCtx = inject(BUTTON_GROUP_CTX);\n const effectiveColor = computed(() => groupCtx?.color.value ?? props.color.value);\n const effectiveSize = computed(() => groupCtx?.size.value ?? props.size.value);\n const effectiveVariant = computed(() => groupCtx?.variant.value ?? props.variant.value);\n\n const isDisabled = computed(() => !!(props.disabled.value || props.loading.value));\n\n // isLink and effectiveRel are computed from signals: correct even if href changes at runtime.\n const { effectiveRel, isLink } = useLinkProps(props.href, props.rel, props.target);\n\n // Form association: relay submit/reset clicks to the associated form.\n // The inner <button> always has type=\"button\" so shadow DOM never drives native form actions.\n // getForm() returns null for link mode at runtime, so no form actions fire.\n const formField = useField({\n disabled: isDisabled,\n toFormValue: () => null,\n value: computed(() => ''),\n });\n\n const handleClick = (e: MouseEvent) => {\n if (isDisabled.value) {\n e.preventDefault();\n\n return;\n }\n\n // Link mode renders a real <a href> below: the browser handles left/middle/ctrl-click\n // navigation, target, and rel natively. No manual window.open/location.href needed.\n useFormAction(() => (isLink.value ? null : formField.internals.form), props.type, isDisabled, el)(e);\n };\n\n const handleKeydown = (e: KeyboardEvent) => {\n if (isLink.value) return;\n\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n (el.shadowRoot?.querySelector('[part=\"button\"]') as HTMLElement)?.click();\n }\n };\n\n // ARIA attributes live on the host.\n bind({\n attr: {\n 'aria-busy': computed(() => (isLink.value ? null : props.loading.value)),\n 'aria-disabled': computed(() => (isLink.value ? null : isDisabled.value)),\n 'aria-label': computed(() => (isLink.value ? null : props.label.value)),\n color: effectiveColor,\n effect: props.effect,\n role: computed(() => (isLink.value ? null : (el.getAttribute('role') ?? 'button'))),\n size: effectiveSize,\n tabindex: computed(() => (isLink.value ? null : isDisabled.value ? '-1' : '0')),\n variant: effectiveVariant,\n },\n on: {\n keydown: handleKeydown,\n },\n });\n\n // A factory, not a shared result: ore's static embed moves a result's\n // fragment children into place, consuming it. The link/button switch below\n // re-renders whenever `href` arrives or is removed at runtime (ore\n // templates set interpolated attributes after upgrade, so the first render\n // is usually the span branch), and a shared instance would render empty on\n // every switch after the first.\n const buttonContent = () => html`\n <span class=\"loader\" part=\"loader\" aria-label=\"Loading\" ?hidden=${() => !props.loading.value}></span>\n <slot name=\"prefix\"></slot>\n <span class=\"content\" part=\"content\"><slot></slot></span>\n <slot name=\"suffix\"></slot>\n `;\n\n // Link mode delegates semantics and focus to the native anchor. Button mode keeps them on\n // the form-associated host because its visual part is intentionally a non-semantic span.\n return html`\n ${() =>\n isLink.value\n ? html`\n <a\n part=\"button\"\n aria-busy=\"${props.loading}\"\n aria-disabled=\"${isDisabled}\"\n aria-label=\"${computed(() => props.label.value || el.textContent?.trim() || null)}\"\n tabindex=\"${computed(() => (isDisabled.value ? '-1' : null))}\"\n href=\"${computed(() => (isDisabled.value ? null : props.href.value))}\"\n rel=\"${effectiveRel}\"\n target=\"${props.target}\"\n @click=\"${handleClick}\">\n ${buttonContent()}\n </a>\n `\n : html`\n <span part=\"button\" role=\"presentation\" @click=\"${handleClick}\">${buttonContent()}</span>\n `}\n `;\n },\n shadow: { delegatesFocus: false },\n styles: [\n colorThemeMixin,\n coarsePointerMixin,\n reducedMotionMixin,\n roundedVariantMixin,\n forcedColorsMixin,\n sizeVariantMixin({\n lg: {\n fontSize: 'var(--text-base)',\n gap: 'var(--size-2-5)',\n height: 'var(--size-12)',\n iconSize: 'var(--size-6)',\n lineHeight: 'var(--leading-relaxed)',\n padding: 'var(--size-2-5) var(--size-5)',\n },\n sm: {\n fontSize: 'var(--text-sm)',\n gap: 'var(--size-1-5)',\n height: 'var(--size-8)',\n iconSize: 'var(--size-4)',\n lineHeight: 'var(--leading-tight)',\n padding: 'var(--size-1-5) var(--size-3)',\n },\n }),\n frostVariantMixin('[part=\"button\"]'),\n rainbowEffectMixin('[part=\"button\"]'),\n shineEffectMixin('[part=\"button\"]'),\n disabledLoadingMixin,\n componentStyles,\n ],\n});\n"],"mappings":"0nBA4BA,IAAa,EAAkB,CAAC,QAAS,OAAQ,WAAY,UAAW,QAAS,OAAQ,OAAO,EAMnF,EAAiB,CAAC,QAAS,SAAS,EAyFpC,EAAa,cAC1B,EAAA,EAAA,OAAA,CAAuB,EAAY,CACjC,eAAgB,GAChB,MAAO,CACL,GAAG,EAAA,YACH,OAAQ,EAAA,KAAK,MAAM,CAAc,EACjC,WAAY,EAAA,KAAK,KAAK,EAAK,EAC3B,UAAW,EAAA,KAAK,KAAK,EAAK,EAC1B,KAAM,EAAA,KAAK,OAAO,EAClB,SAAU,EAAA,KAAK,KAAK,EAAK,EACzB,MAAO,EAAA,KAAK,OAAO,EACnB,IAAK,EAAA,KAAK,OAAO,EACjB,OAAQ,EAAA,KAAK,MAAM,EAAA,YAAY,EAC/B,KAAM,EAAA,KAAK,MAAM,CAAC,SAAU,SAAU,OAAO,EAAY,QAAQ,EACjE,QAAS,EAAA,KAAK,MAAM,EAAiB,OAAO,CAC9C,EACA,MAAM,EAAO,CACX,IAAM,GAAA,EAAK,EAAA,QAAA,CAAQ,EAGb,GAAA,EAAW,EAAA,OAAA,CAAO,EAAA,gBAAgB,EAClC,GAAA,EAAiB,EAAA,SAAA,KAAe,GAAU,MAAM,OAAS,EAAM,MAAM,KAAK,EAC1E,GAAA,EAAgB,EAAA,SAAA,KAAe,GAAU,KAAK,OAAS,EAAM,KAAK,KAAK,EACvE,GAAA,EAAmB,EAAA,SAAA,KAAe,GAAU,QAAQ,OAAS,EAAM,QAAQ,KAAK,EAEhF,GAAA,EAAa,EAAA,SAAA,KAAe,CAAC,EAAE,EAAM,SAAS,OAAS,EAAM,QAAQ,MAAM,EAG3E,CAAE,eAAc,UAAW,EAAA,aAAa,EAAM,KAAM,EAAM,IAAK,EAAM,MAAM,EAK3E,GAAA,EAAY,EAAA,SAAA,CAAS,CACzB,SAAU,EACV,gBAAmB,KACnB,OAAA,EAAO,EAAA,SAAA,KAAe,EAAE,CAC1B,CAAC,EAEK,YAAe,GAAkB,CACrC,GAAI,EAAW,MAAO,CACpB,EAAE,eAAe,EAEjB,MACF,CAIA,EAAA,kBAAqB,EAAO,MAAQ,KAAO,EAAU,UAAU,KAAO,EAAM,KAAM,EAAY,CAAE,CAAC,CAAC,CAAC,CACrG,EAEM,cAAiB,GAAqB,CACtC,EAAO,QAEP,EAAE,MAAQ,SAAW,EAAE,MAAQ,OACjC,EAAE,eAAe,GAChB,EAAG,YAAY,cAAc,iBAAiB,EAAA,EAAmB,MAAM,EAE5E,GAGA,EAAA,EAAA,KAAA,CAAK,CACH,KAAM,CACJ,aAAA,EAAa,EAAA,SAAA,KAAgB,EAAO,MAAQ,KAAO,EAAM,QAAQ,KAAM,EACvE,iBAAA,EAAiB,EAAA,SAAA,KAAgB,EAAO,MAAQ,KAAO,EAAW,KAAM,EACxE,cAAA,EAAc,EAAA,SAAA,KAAgB,EAAO,MAAQ,KAAO,EAAM,MAAM,KAAM,EACtE,MAAO,EACP,OAAQ,EAAM,OACd,MAAA,EAAM,EAAA,SAAA,KAAgB,EAAO,MAAQ,KAAQ,EAAG,aAAa,MAAM,GAAK,QAAU,EAClF,KAAM,EACN,UAAA,EAAU,EAAA,SAAA,KAAgB,EAAO,MAAQ,KAAO,EAAW,MAAQ,KAAO,GAAI,EAC9E,QAAS,CACX,EACA,GAAI,CACF,QAAS,aACX,CACF,CAAC,EAQD,IAAM,kBAAsB,EAAA,IAAI;4EAC0C,CAAC,EAAM,QAAQ,MAAM;;;;MAQ/F,MAAO,GAAA,IAAI;YAEP,EAAO,MACH,EAAA,IAAI;;;6BAGa,EAAM,QAAQ;iCACV,EAAW;+BACd,EAAA,EAAA,SAAA,KAAe,EAAM,MAAM,OAAS,EAAG,aAAa,KAAK,GAAK,IAAI,EAAE;6BACtE,EAAA,EAAA,SAAA,KAAgB,EAAW,MAAQ,KAAO,IAAK,EAAE;yBACrD,EAAA,EAAA,SAAA,KAAgB,EAAW,MAAQ,KAAO,EAAM,KAAK,KAAM,EAAE;uBAC9D,EAAa;0BACV,EAAM,OAAO;0BACb,YAAY;kBACpB,cAAc,EAAE;;cAGtB,EAAA,IAAI;gEACgD,YAAY,IAAI,cAAc,EAAE;cAClF;KAEZ,EACA,OAAQ,CAAE,eAAgB,EAAM,EAChC,OAAQ,CACN,EAAA,gBACA,EAAA,mBACA,EAAA,mBACA,EAAA,oBACA,EAAA,kBACA,EAAA,iBAAiB,CACf,GAAI,CACF,SAAU,mBACV,IAAK,kBACL,OAAQ,iBACR,SAAU,gBACV,WAAY,yBACZ,QAAS,+BACX,EACA,GAAI,CACF,SAAU,iBACV,IAAK,kBACL,OAAQ,gBACR,SAAU,gBACV,WAAY,uBACZ,QAAS,+BACX,CACF,CAAC,EACD,EAAA,kBAAkB,iBAAiB,EACnC,EAAA,mBAAmB,iBAAiB,EACpC,EAAA,iBAAiB,iBAAiB,EAClC,EAAA,qBACA,EAAA,OACF,CACF,CAAC"}
package/dist/button.js CHANGED
@@ -1,24 +1,24 @@
1
- import{coarsePointerMixin as e,reducedMotionMixin as t}from"./styles/mixins/accessibility.css.js";import{rainbowEffectMixin as n,shineEffectMixin as r}from"./styles/mixins/animation.css.js";import{roundedVariantMixin as i,sizeVariantMixin as a}from"./styles/mixins/shape.css.js";import{disabledLoadingMixin as o}from"./styles/mixins/states.css.js";import{colorThemeMixin as s,forcedColorsMixin as c}from"./styles/mixins/theme.css.js";import{frostVariantMixin as l}from"./styles/mixins/variants.css.js";import{commonProps as u}from"./shared/prop-bundles.js";import{useLinkProps as d}from"./utils/link.js";import{BUTTON_GROUP_CTX as f}from"./button-group.js";import{useFormAction as p}from"./inputs/shared/use-form-action.js";import m from"./inputs/button/button.css.js";import{computed as h}from"@vielzeug/ripple";import{bind as g,define as _,getHost as v,html as y,inject as b,prop as x,useField as S}from"@vielzeug/ore";var C=[`solid`,`flat`,`bordered`,`outline`,`ghost`,`text`,`frost`],w=`ore-button`;_(w,{formAssociated:!0,props:{...u,effect:x.string(),fullheight:x.bool(!1),fullwidth:x.bool(!1),href:x.string(),iconOnly:x.bool(!1),label:x.string(),rel:x.string(),target:x.string(),type:x.oneOf([`button`,`submit`,`reset`],`button`),variant:x.oneOf(C,`solid`)},setup(e){let t=v(),n=b(f),r=h(()=>n?.color.value??e.color.value),i=h(()=>n?.size.value??e.size.value),a=h(()=>n?.variant.value??e.variant.value),o=h(()=>!!(e.disabled.value||e.loading.value)),{effectiveRel:s,isLink:c}=d(e.href,e.rel,e.target),l=S({disabled:o,toFormValue:()=>null,value:h(()=>``)}),handleClick=n=>{if(o.value){n.preventDefault();return}p(()=>c.value?null:l.internals.form,e.type,o,t)(n)},handleKeydown=e=>{c.value||(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),(t.shadowRoot?.querySelector(`[part="button"]`))?.click())};g({attr:{"aria-busy":h(()=>c.value?null:e.loading.value),"aria-disabled":h(()=>c.value?null:o.value),"aria-label":h(()=>c.value?null:e.label.value),color:r,effect:e.effect,role:h(()=>c.value?null:t.getAttribute(`role`)??`button`),size:i,tabindex:h(()=>c.value?null:o.value?`-1`:`0`),variant:a},on:{keydown:handleKeydown}});let buttonContent=()=>y`
1
+ import{coarsePointerMixin as e,reducedMotionMixin as t}from"./styles/mixins/accessibility.css.js";import{rainbowEffectMixin as n,shineEffectMixin as r}from"./styles/mixins/animation.css.js";import{roundedVariantMixin as i,sizeVariantMixin as a}from"./styles/mixins/shape.css.js";import{disabledLoadingMixin as o}from"./styles/mixins/states.css.js";import{colorThemeMixin as s,forcedColorsMixin as c}from"./styles/mixins/theme.css.js";import{frostVariantMixin as l}from"./styles/mixins/variants.css.js";import{LINK_TARGETS as u}from"./shared/types.js";import{commonProps as d}from"./shared/prop-bundles.js";import{useLinkProps as f}from"./utils/link.js";import{BUTTON_GROUP_CTX as p}from"./button-group.js";import{useFormAction as m}from"./inputs/shared/use-form-action.js";import h from"./inputs/button/button.css.js";import{computed as g}from"@vielzeug/ripple";import{bind as _,define as v,getHost as y,html as b,inject as x,prop as S,useField as C}from"@vielzeug/ore";var w=[`solid`,`flat`,`bordered`,`outline`,`ghost`,`text`,`frost`],T=[`shine`,`rainbow`],E=`ore-button`;v(E,{formAssociated:!0,props:{...d,effect:S.oneOf(T),fullheight:S.bool(!1),fullwidth:S.bool(!1),href:S.string(),iconOnly:S.bool(!1),label:S.string(),rel:S.string(),target:S.oneOf(u),type:S.oneOf([`button`,`submit`,`reset`],`button`),variant:S.oneOf(w,`solid`)},setup(e){let t=y(),n=x(p),r=g(()=>n?.color.value??e.color.value),i=g(()=>n?.size.value??e.size.value),a=g(()=>n?.variant.value??e.variant.value),o=g(()=>!!(e.disabled.value||e.loading.value)),{effectiveRel:s,isLink:c}=f(e.href,e.rel,e.target),l=C({disabled:o,toFormValue:()=>null,value:g(()=>``)}),handleClick=n=>{if(o.value){n.preventDefault();return}m(()=>c.value?null:l.internals.form,e.type,o,t)(n)},handleKeydown=e=>{c.value||(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),(t.shadowRoot?.querySelector(`[part="button"]`))?.click())};_({attr:{"aria-busy":g(()=>c.value?null:e.loading.value),"aria-disabled":g(()=>c.value?null:o.value),"aria-label":g(()=>c.value?null:e.label.value),color:r,effect:e.effect,role:g(()=>c.value?null:t.getAttribute(`role`)??`button`),size:i,tabindex:g(()=>c.value?null:o.value?`-1`:`0`),variant:a},on:{keydown:handleKeydown}});let buttonContent=()=>b`
2
2
  <span class="loader" part="loader" aria-label="Loading" ?hidden=${()=>!e.loading.value}></span>
3
3
  <slot name="prefix"></slot>
4
4
  <span class="content" part="content"><slot></slot></span>
5
5
  <slot name="suffix"></slot>
6
- `;return y`
7
- ${()=>c.value?y`
6
+ `;return b`
7
+ ${()=>c.value?b`
8
8
  <a
9
9
  part="button"
10
10
  aria-busy="${e.loading}"
11
11
  aria-disabled="${o}"
12
- aria-label="${h(()=>e.label.value||t.textContent?.trim()||null)}"
13
- tabindex="${h(()=>o.value?`-1`:null)}"
14
- href="${h(()=>o.value?null:e.href.value)}"
12
+ aria-label="${g(()=>e.label.value||t.textContent?.trim()||null)}"
13
+ tabindex="${g(()=>o.value?`-1`:null)}"
14
+ href="${g(()=>o.value?null:e.href.value)}"
15
15
  rel="${s}"
16
16
  target="${e.target}"
17
17
  @click="${handleClick}">
18
18
  ${buttonContent()}
19
19
  </a>
20
- `:y`
20
+ `:b`
21
21
  <span part="button" role="presentation" @click="${handleClick}">${buttonContent()}</span>
22
22
  `}
23
- `},shadow:{delegatesFocus:!1},styles:[s,e,t,i,c,a({lg:{fontSize:`var(--text-base)`,gap:`var(--size-2-5)`,height:`var(--size-12)`,iconSize:`var(--size-6)`,lineHeight:`var(--leading-relaxed)`,padding:`var(--size-2-5) var(--size-5)`},sm:{fontSize:`var(--text-sm)`,gap:`var(--size-1-5)`,height:`var(--size-8)`,iconSize:`var(--size-4)`,lineHeight:`var(--leading-tight)`,padding:`var(--size-1-5) var(--size-3)`}}),l(`[part="button"]`),n(`[part="button"]`),r(`[part="button"]`),o,m]});export{w as BUTTON_TAG,C as BUTTON_VARIANTS};
23
+ `},shadow:{delegatesFocus:!1},styles:[s,e,t,i,c,a({lg:{fontSize:`var(--text-base)`,gap:`var(--size-2-5)`,height:`var(--size-12)`,iconSize:`var(--size-6)`,lineHeight:`var(--leading-relaxed)`,padding:`var(--size-2-5) var(--size-5)`},sm:{fontSize:`var(--text-sm)`,gap:`var(--size-1-5)`,height:`var(--size-8)`,iconSize:`var(--size-4)`,lineHeight:`var(--leading-tight)`,padding:`var(--size-1-5) var(--size-3)`}}),l(`[part="button"]`),n(`[part="button"]`),r(`[part="button"]`),o,h]});export{T as BUTTON_EFFECTS,E as BUTTON_TAG,w as BUTTON_VARIANTS};
24
24
  //# sourceMappingURL=button.js.map