@vielzeug/refine 26.10.7 → 26.10.9

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 +378 -241
  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 +13 -13
package/dist/select.cjs CHANGED
@@ -1,4 +1,4 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./inputs/shared/native-field-event.cjs"),t=require("./styles/mixins/accessibility.css.cjs"),n=require("./styles/mixins/shape.css.cjs"),r=require("./styles/mixins/theme.css.cjs"),i=require("./core/choice-field.cjs"),a=require("./core/ore.cjs"),o=require("./core/option-list.cjs"),s=require("./shared/prop-bundles.cjs"),c=require("./icon.cjs"),l=require("./chip.cjs"),u=require("./input.cjs"),d=require("./inputs/select/select.css.cjs");let f=require("@vielzeug/ripple"),p=require("@vielzeug/ore");var isIconImage=e=>e.includes(`/`)||e.startsWith(`data:`),normalizeIcons=e=>{let t=(Array.isArray(e)?e:e?.split(` `))?.map(e=>e.trim()).filter(Boolean);return t?.length?t:void 0},m=`ore-select`;(0,p.define)(m,{formAssociated:!0,props:{...s.themableBundle,...s.sizableBundle,...s.disablableBundle,...s.loadableBundle,...s.roundableBundle,error:p.prop.string(),fullwidth:p.prop.bool(!1),helper:p.prop.string(),"hide-label":p.prop.bool(!1),label:p.prop.string(),"label-placement":p.prop.oneOf([`inset`,`outside`],`inset`),multiple:p.prop.bool(!1),name:p.prop.string(),options:p.prop.json(void 0),placeholder:p.prop.string(),required:p.prop.bool(!1),success:p.prop.bool(!1),value:p.prop.string(),variant:p.prop.string()},setup(t){let n=(0,p.getHost)(),r=(0,p.useEmit)(),s=(0,p.useSlots)(),c=n.shadowRoot,l=(0,f.signal)([]),u=(0,f.computed)(()=>!!t.loading.value);function normalizeOption(e){return{disabled:!!e.disabled,disabledReason:e.disabledReason,group:e.group,icons:normalizeIcons(e.icon),label:e.label??e.value,value:e.value}}let d=(0,f.computed)(()=>{let e=t.options.value;return Array.isArray(e)?e.map(normalizeOption):l.value}),m=null,h=null,g=a.lifecycleSignal(p.onCleanup),_=i.createChoiceField({disabled:t.disabled,error:t.error,helper:t.helper,label:t.label,labelPlacement:t[`label-placement`],multiple:t.multiple,prefix:`select`,required:t.required,signal:g,value:t.value});_.attachFormField((0,p.useField)({disabled:_.disabled,onReset:_.reset,toFormValue:e=>e,validationMessage:_.validationMessage,validity:_.validity,value:_.formValue}));let v=o.createListboxDropdown({getBoundary:()=>n,getFocusedOptionElement:()=>h?.querySelector(`[data-focused]`)??null,getItems:()=>d.value,getPanel:()=>h,getReference:()=>m,getTrigger:()=>m,isDisabled:()=>_.disabled.value,isItemDisabled:e=>e.disabled,onClose:e=>{r(`open-change`,{open:!1,reason:e}),_.triggerValidation(`blur`)},onOpen:e=>r(`open-change`,{open:!0,reason:e}),signal:g}),{triggerValidation:y}=_,b=_.selectedValues,x=_.disabled;e.defineFieldValue(n,()=>_.formValue.value,e=>{_.setValues(e?e.split(`,`):[])});let{fieldId:S}=_,C=`listbox-${S}`,{focusedIndex:w,isOpen:T}=v;(0,p.bind)({attr:{"has-error":()=>t.error.value?!0:void 0,open:()=>T.value?!0:void 0,size:t.size,variant:t.variant}});function readOptions(){let e=c?.querySelector(`slot`);if(!e)return;let t=e.assignedElements({flatten:!0}),n=[];for(let e of t)if(e.tagName===`OPTION`){let t=e;n.push({disabled:t.disabled,disabledReason:t.dataset.disabledReason,icons:normalizeIcons(t.dataset.icon),label:t.text||t.value,value:t.value})}else if(e.tagName===`OPTGROUP`){let t=e,r=t.label;for(let e of Array.from(t.querySelectorAll(`option`))){let t=e;n.push({disabled:t.disabled,disabledReason:t.dataset.disabledReason,group:r,icons:normalizeIcons(t.dataset.icon),label:t.text||t.value,value:t.value})}}l.value=n}let E=(0,f.computed)(()=>{if(b.value.length===0)return``;if(t.multiple.value&&b.value.length>1)return`${b.value.length} selected`;let e=b.value[0];return d.value.find(t=>t.value===e)?.label??e}),D=(0,f.computed)(()=>{if(t.multiple.value||b.value.length===0)return;let e=b.value[0];return d.value.find(t=>t.value===e)?.icons}),O=(0,f.computed)(()=>t.multiple.value?b.value.map(e=>({label:d.value.find(t=>t.value===e)?.label??e,value:e})):[]),k=(0,f.computed)(()=>t.multiple.value&&b.value.length>0),A=(0,f.computed)(()=>E.value||t.placeholder.value||``);function buildFlatList(e){let t=[],n=new Map;for(let t of e){let e=t.group,r=n.get(e);r||(r=[],n.set(e,r)),r.push(t)}let r=0;for(let[e,i]of n){e!==void 0&&t.push({label:e,type:`group`});for(let e of i)t.push({idx:r++,opt:e,type:`option`})}return t}let j=(0,f.computed)(()=>buildFlatList(d.value));function emitChange(){e.setFieldValue(n,_.formValue.value),e.dispatchNativeFieldEvent(n,`input`),e.dispatchNativeFieldEvent(n,`change`)}function removeChip(e){e.stopPropagation();let t=e.detail?.value;t!==void 0&&(_.removeValue(t),emitChange(),y(`change`))}function openPopup(e=`programmatic`){h&&`showPopover`in h&&!h.matches(`:popover-open`)&&h.showPopover(),v.open(e),requestAnimationFrame(()=>{let e=b.value.length>0?d.value.findIndex(e=>e.value===b.value[0]):-1;if(e>=0){v.set(e);return}v.navigate(`first`)})}function selectOption(e,n){e.disabled||(t.multiple.value?_.toggleValue(e.value):(_.selectValue(e.value),v.close()),emitChange(),y(`change`))}function handleTriggerKeydown(e){if(!x.value&&!v.handleKeydown(e))switch(e.key){case` `:case`Enter`:if(e.preventDefault(),T.value){let t=w.value,n=d.value;t>=0&&t<n.length&&selectOption(n[t],e)}else openPopup(`keyboard`);break;case`Tab`:v.close()}}let inputValue=()=>A.value,hideLabel=()=>t[`hide-label`].value,inputLabel=()=>hideLabel()?``:t.label.value??``,triggerAriaLabel=()=>hideLabel()?t.label.value??``:null,inputPlaceholder=()=>t.placeholder.value??``,inputLabelPlacement=()=>t[`label-placement`].value??`inset`,inputColor=()=>t.color?.value??void 0,inputSize=()=>t.size?.value??void 0,inputVariant=()=>t.variant?.value??void 0,inputRounded=()=>t.rounded?.value??void 0,inputHelper=()=>t.helper.value??``,inputError=()=>t.error.value??``,inputDisabled=()=>x.value?!0:void 0,inputRequired=()=>t.required.value?!0:void 0,inputFullwidth=()=>t.fullwidth.value?!0:void 0,tabIndexAttr=()=>x.value?`-1`:`0`;(0,f.watch)(s.elements(),()=>readOptions(),{immediate:!0});let M=(0,f.effect)(()=>{T.value?h&&`showPopover`in h&&!h.matches(`:popover-open`)&&h.showPopover():h&&`hidePopover`in h&&h.matches(`:popover-open`)&&h.hidePopover()});return(0,p.onCleanup)(()=>M.dispose()),(0,p.onMounted)(()=>{let onTriggerClick=null,onTriggerKeydown=null;return m&&(onTriggerClick=e=>{e.stopPropagation(),!x.value&&(T.value?v.close(`trigger`):openPopup(`click`))},onTriggerKeydown=e=>{handleTriggerKeydown(e)},m.addEventListener(`click`,onTriggerClick),m.addEventListener(`keydown`,onTriggerKeydown)),()=>{m&&onTriggerClick&&m.removeEventListener(`click`,onTriggerClick),m&&onTriggerKeydown&&m.removeEventListener(`keydown`,onTriggerKeydown)}}),p.html`
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./inputs/shared/native-field-event.cjs"),t=require("./styles/mixins/accessibility.css.cjs"),n=require("./styles/mixins/shape.css.cjs"),r=require("./styles/mixins/theme.css.cjs"),i=require("./core/choice-field.cjs"),a=require("./core/ore.cjs"),o=require("./core/option-list.cjs"),s=require("./shared/types.cjs"),c=require("./shared/prop-bundles.cjs"),l=require("./icon.cjs"),u=require("./chip.cjs"),d=require("./input.cjs"),f=require("./inputs/select/select.css.cjs");let p=require("@vielzeug/ripple"),m=require("@vielzeug/ore");var isIconImage=e=>e.includes(`/`)||e.startsWith(`data:`),normalizeIcons=e=>{let t=(Array.isArray(e)?e:e?.split(` `))?.map(e=>e.trim()).filter(Boolean);return t?.length?t:void 0},h=`ore-select`;(0,m.define)(h,{formAssociated:!0,props:{...c.themableBundle,...c.sizableBundle,...c.disablableBundle,...c.loadableBundle,...c.roundableBundle,error:m.prop.string(),fullwidth:m.prop.bool(!1),helper:m.prop.string(),"hide-label":m.prop.bool(!1),label:m.prop.string(),"label-placement":m.prop.oneOf([`inset`,`outside`],`inset`),multiple:m.prop.bool(!1),name:m.prop.string(),options:m.prop.json(void 0),placeholder:m.prop.string(),required:m.prop.bool(!1),success:m.prop.bool(!1),value:m.prop.string(),variant:m.prop.oneOf(s.INPUT_VARIANTS)},setup(t){let n=(0,m.getHost)(),r=(0,m.useEmit)(),s=(0,m.useSlots)(),c=n.shadowRoot,l=(0,p.signal)([]),u=(0,p.computed)(()=>!!t.loading.value);function normalizeOption(e){return{disabled:!!e.disabled,disabledReason:e.disabledReason,group:e.group,icons:normalizeIcons(e.icon),label:e.label??e.value,value:e.value}}let d=(0,p.computed)(()=>{let e=t.options.value;return Array.isArray(e)?e.map(normalizeOption):l.value}),f=null,h=null,g=a.lifecycleSignal(m.onCleanup),_=i.createChoiceField({disabled:t.disabled,error:t.error,helper:t.helper,label:t.label,labelPlacement:t[`label-placement`],multiple:t.multiple,prefix:`select`,required:t.required,signal:g,value:t.value});_.attachFormField((0,m.useField)({disabled:_.disabled,onReset:_.reset,toFormValue:e=>e,validity:_.validity,value:_.formValue}));let v=o.createListboxDropdown({getBoundary:()=>n,getFocusedOptionElement:()=>h?.querySelector(`[data-focused]`)??null,getItems:()=>d.value,getPanel:()=>h,getReference:()=>f,getTrigger:()=>f,isDisabled:()=>_.disabled.value,isItemDisabled:e=>e.disabled,onClose:e=>{r(`open-change`,{open:!1,reason:e}),_.triggerValidation(`blur`)},onOpen:e=>r(`open-change`,{open:!0,reason:e}),signal:g}),{triggerValidation:y}=_,b=_.selectedValues,x=_.disabled;e.defineFieldValue(n,()=>_.formValue.value,e=>{_.setValues(e?e.split(`,`):[])});let{fieldId:S}=_,C=`listbox-${S}`,{focusedIndex:w,isOpen:T}=v;(0,m.bind)({attr:{"has-error":()=>t.error.value?!0:void 0,open:()=>T.value?!0:void 0,size:t.size,variant:t.variant}});function readOptions(){let e=c?.querySelector(`slot`);if(!e)return;let t=e.assignedElements({flatten:!0}),n=[];for(let e of t)if(e.tagName===`OPTION`){let t=e;n.push({disabled:t.disabled,disabledReason:t.dataset.disabledReason,icons:normalizeIcons(t.dataset.icon),label:t.text||t.value,value:t.value})}else if(e.tagName===`OPTGROUP`){let t=e,r=t.label;for(let e of Array.from(t.querySelectorAll(`option`))){let t=e;n.push({disabled:t.disabled,disabledReason:t.dataset.disabledReason,group:r,icons:normalizeIcons(t.dataset.icon),label:t.text||t.value,value:t.value})}}l.value=n}let E=(0,p.computed)(()=>{if(b.value.length===0)return``;if(t.multiple.value&&b.value.length>1)return`${b.value.length} selected`;let e=b.value[0];return d.value.find(t=>t.value===e)?.label??e}),D=(0,p.computed)(()=>{if(t.multiple.value||b.value.length===0)return;let e=b.value[0];return d.value.find(t=>t.value===e)?.icons}),O=(0,p.computed)(()=>t.multiple.value?b.value.map(e=>({label:d.value.find(t=>t.value===e)?.label??e,value:e})):[]),k=(0,p.computed)(()=>t.multiple.value&&b.value.length>0),A=(0,p.computed)(()=>E.value||t.placeholder.value||``);function buildFlatList(e){let t=[],n=new Map;for(let t of e){let e=t.group,r=n.get(e);r||(r=[],n.set(e,r)),r.push(t)}let r=0;for(let[e,i]of n){e!==void 0&&t.push({label:e,type:`group`});for(let e of i)t.push({idx:r++,opt:e,type:`option`})}return t}let j=(0,p.computed)(()=>buildFlatList(d.value));function emitChange(){e.setFieldValue(n,_.formValue.value),e.dispatchNativeFieldEvent(n,`input`),e.dispatchNativeFieldEvent(n,`change`)}function removeChip(e){e.stopPropagation();let t=e.detail?.value;t!==void 0&&(_.removeValue(t),emitChange(),y(`change`))}function openPopup(e=`programmatic`){h&&`showPopover`in h&&!h.matches(`:popover-open`)&&h.showPopover(),v.open(e),requestAnimationFrame(()=>{let e=b.value.length>0?d.value.findIndex(e=>e.value===b.value[0]):-1;if(e>=0){v.set(e);return}v.navigate(`first`)})}function selectOption(e,n){e.disabled||(t.multiple.value?_.toggleValue(e.value):(_.selectValue(e.value),v.close()),emitChange(),y(`change`))}function handleTriggerKeydown(e){if(!x.value&&!v.handleKeydown(e))switch(e.key){case` `:case`Enter`:if(e.preventDefault(),T.value){let t=w.value,n=d.value;t>=0&&t<n.length&&selectOption(n[t],e)}else openPopup(`keyboard`);break;case`Tab`:v.close()}}let inputValue=()=>A.value,hideLabel=()=>t[`hide-label`].value,inputLabel=()=>hideLabel()?``:t.label.value??``,triggerAriaLabel=()=>hideLabel()?t.label.value??``:null,inputPlaceholder=()=>t.placeholder.value??``,inputLabelPlacement=()=>t[`label-placement`].value??`inset`,inputColor=()=>t.color?.value??void 0,inputSize=()=>t.size?.value??void 0,inputVariant=()=>t.variant?.value??void 0,inputRounded=()=>t.rounded?.value??void 0,inputHelper=()=>t.helper.value??``,inputError=()=>t.error.value??``,inputDisabled=()=>x.value?!0:void 0,inputRequired=()=>t.required.value?!0:void 0,inputFullwidth=()=>t.fullwidth.value?!0:void 0,tabIndexAttr=()=>x.value?`-1`:`0`;(0,p.watch)(s.elements(),()=>readOptions(),{immediate:!0});let M=(0,p.effect)(()=>{T.value?h&&`showPopover`in h&&!h.matches(`:popover-open`)&&h.showPopover():h&&`hidePopover`in h&&h.matches(`:popover-open`)&&h.hidePopover()});return(0,m.onCleanup)(()=>M.dispose()),(0,m.onMounted)(()=>{let onTriggerClick=null,onTriggerKeydown=null;return f&&(onTriggerClick=e=>{e.stopPropagation(),!x.value&&(T.value?v.close(`trigger`):openPopup(`click`))},onTriggerKeydown=e=>{handleTriggerKeydown(e)},f.addEventListener(`click`,onTriggerClick),f.addEventListener(`keydown`,onTriggerKeydown)),()=>{f&&onTriggerClick&&f.removeEventListener(`click`,onTriggerClick),f&&onTriggerKeydown&&f.removeEventListener(`keydown`,onTriggerKeydown)}}),m.html`
2
2
  <slot style="display:none"></slot>
3
3
  <ore-input
4
4
  class="trigger"
@@ -26,12 +26,12 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=requi
26
26
  ?required="${inputRequired}"
27
27
  ?fullwidth="${inputFullwidth}"
28
28
  ?success="${()=>t.success.value}"
29
- ref="${e=>{m=e}}">
30
- ${()=>{let e=D.value;return e?.length?p.html`<span class="trigger-selected-icons" slot="prefix">
31
- ${e.map(e=>isIconImage(e)?p.html`<img alt="" aria-hidden="true" class="trigger-selected-icon--image" src="${e}" />`:p.html`<ore-icon aria-hidden="true" class="trigger-selected-icon" name="${e}" size="14"></ore-icon>`)}
32
- </span>`:p.html``}}
29
+ ref="${e=>{f=e}}">
30
+ ${()=>{let e=D.value;return e?.length?m.html`<span class="trigger-selected-icons" slot="prefix">
31
+ ${e.map(e=>isIconImage(e)?m.html`<img alt="" aria-hidden="true" class="trigger-selected-icon--image" src="${e}" />`:m.html`<ore-icon aria-hidden="true" class="trigger-selected-icon" name="${e}" size="14"></ore-icon>`)}
32
+ </span>`:m.html``}}
33
33
  <div slot="prefix" class="chips-row" ?hidden="${()=>!k.value}">
34
- ${()=>O.value.map(e=>p.html`
34
+ ${()=>O.value.map(e=>m.html`
35
35
  <ore-chip
36
36
  value="${e.value}"
37
37
  label="${e.label}"
@@ -63,9 +63,9 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=requi
63
63
  <div class="dropdown-loading" ?hidden="${()=>!u.value}">Loading…</div>
64
64
  <div class="dropdown-empty" ?hidden="${()=>u.value||d.value.length>0}">No options</div>
65
65
  <div class="options-list" ?hidden="${()=>u.value||d.value.length===0}">
66
- ${()=>j.value.map(e=>e.type===`group`?p.html`
66
+ ${()=>j.value.map(e=>e.type===`group`?m.html`
67
67
  <div class="optgroup-label" role="presentation">${e.label}</div>
68
- `:p.html`
68
+ `:m.html`
69
69
  <div
70
70
  class="option"
71
71
  role="option"
@@ -79,11 +79,11 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=requi
79
79
  ?data-disabled="${()=>e.opt.disabled}"
80
80
  @click="${t=>{t.stopPropagation(),selectOption(e.opt,t)}}"
81
81
  @pointerenter="${()=>{v.set(e.idx)}}">
82
- ${e.opt.icons?.length?p.html`<span class="option-icons" aria-hidden="true">
83
- ${e.opt.icons.map(e=>isIconImage(e)?p.html`<img alt="" class="option-icon option-icon--image" src="${e}" />`:p.html`<ore-icon class="option-icon" name="${e}" size="14"></ore-icon>`)}
84
- </span>`:p.html``}
82
+ ${e.opt.icons?.length?m.html`<span class="option-icons" aria-hidden="true">
83
+ ${e.opt.icons.map(e=>isIconImage(e)?m.html`<img alt="" class="option-icon option-icon--image" src="${e}" />`:m.html`<ore-icon class="option-icon" name="${e}" size="14"></ore-icon>`)}
84
+ </span>`:m.html``}
85
85
  <span>${e.opt.label}</span>
86
- ${e.opt.disabled&&e.opt.disabledReason?p.html`<small class="disabled-reason" title="${e.opt.disabledReason}">${e.opt.disabledReason}</small>`:p.html``}
86
+ ${e.opt.disabled&&e.opt.disabledReason?m.html`<small class="disabled-reason" title="${e.opt.disabledReason}">${e.opt.disabledReason}</small>`:m.html``}
87
87
  <span class="option-check" aria-hidden="true">
88
88
  <ore-icon name="check" size="14" stroke-width="2.5" aria-hidden="true"></ore-icon>
89
89
  </span>
@@ -91,5 +91,5 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=requi
91
91
  `)}
92
92
  </div>
93
93
  </div>
94
- `},shadow:{delegatesFocus:!0},styles:[r.colorThemeMixin,t.reducedMotionMixin,n.roundedVariantMixin,d.default]}),exports.CHIP_TAG=l.CHIP_TAG,exports.ICON_TAG=c.ICON_TAG,exports.INPUT_TAG=u.INPUT_TAG,exports.SELECT_TAG=m;
94
+ `},shadow:{delegatesFocus:!0},styles:[r.colorThemeMixin,t.reducedMotionMixin,n.roundedVariantMixin,f.default]}),exports.CHIP_TAG=u.CHIP_TAG,exports.ICON_TAG=l.ICON_TAG,exports.INPUT_TAG=d.INPUT_TAG,exports.SELECT_TAG=h;
95
95
  //# sourceMappingURL=select.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"select.cjs","names":[],"sources":["../src/inputs/select/select.ts"],"sourcesContent":["import { bind, define, getHost, html, onCleanup, onMounted, prop, useEmit, useField, useSlots } from '@vielzeug/ore';\nimport { computed, effect, signal, watch } from '@vielzeug/ripple';\n\nimport type { OverlayOpenChangeDetail, OverlayOpenReason } from '../../core';\nimport { createChoiceField, createListboxDropdown, lifecycleSignal } from '../../core';\nimport type { SelectableFieldProps } from '../../shared';\nimport { disablableBundle, loadableBundle, roundableBundle, sizableBundle, themableBundle } from '../../shared';\nimport { colorThemeMixin, reducedMotionMixin, roundedVariantMixin } from '../../styles';\nimport type { VisualVariant } from '../../types';\nimport { defineFieldValue, dispatchNativeFieldEvent, setFieldValue } from '../shared/native-field-event';\nimport componentStyles from './select.css?inline';\n\nexport { ICON_TAG } from '../../content/icon/icon';\nexport { CHIP_TAG } from '../../feedback/chip/chip';\nexport { INPUT_TAG } from '../input/input';\n\n// ── Types ─────────────────────────────────────────────────────────────\n\ntype OptionItem = {\n disabled: boolean;\n disabledReason?: string;\n group?: string;\n icons?: string[];\n label: string;\n value: string;\n};\n\nexport type OreSelectOptionInput = {\n disabled?: boolean;\n /** Explanation displayed and announced when the option is disabled. */\n disabledReason?: string;\n group?: string;\n /** Icon(s) rendered before the option label: lucide name(s) or image URL(s). */\n icon?: string | string[];\n label?: string;\n value: string;\n};\n\ntype FlatRow =\n | {\n idx: number;\n opt: OptionItem;\n type: 'option';\n }\n | {\n label: string;\n type: 'group';\n };\n\n/**\n * Icon sources containing a path separator or a `data:` scheme are treated as image URLs and\n * rendered as `<img>`; anything else is a lucide icon name rendered via `ore-icon`.\n */\nconst isIconImage = (icon: string): boolean => icon.includes('/') || icon.startsWith('data:');\n\n/** Normalizes an icon value: single name/URL, space-separated list, or array: to icon entries. */\nconst normalizeIcons = (icon: string | string[] | undefined): string[] | undefined => {\n const list = Array.isArray(icon) ? icon : icon?.split(' ');\n const icons = list?.map((entry) => entry.trim()).filter(Boolean);\n return icons?.length ? icons : undefined;\n};\n\n// ── Styles ─────────────────────────────────────────────────────────────\n\n// ── Component Props ─────────────────────────────────────────────────────────────\n\n/** Select component properties */\n\nexport type OreSelectEvents = {\n change: Event;\n input: Event;\n 'open-change': OverlayOpenChangeDetail;\n};\n\nexport type OreSelectProps = SelectableFieldProps<Exclude<VisualVariant, 'frost'>> & {\n /** Hide the visible label while preserving the accessible name via `aria-label` */\n 'hide-label'?: boolean;\n /** Show loading state in dropdown */\n loading?: boolean;\n /** Allow selecting multiple options */\n multiple?: boolean;\n /** JS options array (alternative to slotted <option> elements) */\n options?: OreSelectOptionInput[];\n /** Mark the field as required */\n required?: boolean;\n};\n\n/**\n * A fully custom form-associated select dropdown with keyboard navigation and ARIA support.\n * Reads `<option>` and `<optgroup>` children from the default slot.\n *\n * @element ore-select\n *\n * @attr {string} label - Label text\n * @attr {string} label-placement - 'inset' | 'outside'\n * @attr {boolean} hide-label - Hide the visible label; the label text is exposed as `aria-label` on the trigger instead\n * @attr {string} value - Current selected value(s) (comma-separated for multiple)\n * @attr {string} placeholder - Placeholder when no option selected\n * @attr {string} name - Form field name\n * @attr {boolean} multiple - Enable multi-select\n * @attr {boolean} disabled - Disable the select\n * @attr {boolean} required - Required field\n * @attr {string} helper - Helper text below the select\n * @attr {string} error - Error message\n * @attr {boolean} success - Show an inline success check icon (suppressed while `error` is set)\n * @attr {string} color - Theme color: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error'\n * @attr {string} variant - Visual variant: 'solid' | 'flat' | 'bordered' | 'outline' | 'ghost' | 'text'\n * @attr {string} size - Component size: 'sm' | 'md' | 'lg'\n * @attr {string} rounded - Border radius: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'\n * @attr {boolean} fullwidth - Expand to full width\n *\n * @fires input - Fired when selection changes.\n * @fires change - Fired when selection changes.\n * @fires open-change - Fired when the dropdown state changes. detail: { open, reason }\n *\n * @slot - `<option>` and `<optgroup>` elements\n *\n * @cssprop --select-bg - Background\n * @cssprop --select-border-color - Border color\n * @cssprop --select-min-width - Minimum width of the select; the trigger floors at it too, so the control never renders wider than its host\n * @cssprop --select-radius - Border radius\n * @cssprop --select-padding - Padding\n * @cssprop --select-font-size - Font size\n * @cssprop --select-placeholder-color - Placeholder text color\n *\n * @part trigger - The `ore-input` trigger element that opens the dropdown.\n * @part dropdown - The dropdown listbox panel container.\n *\n * @example\n * ```html\n * <ore-select label=\"Role\" value=\"admin\">\n * <option value=\"admin\">Administrator</option>\n * <option value=\"editor\">Editor</option>\n * <option value=\"viewer\">Viewer</option>\n * </ore-select>\n *\n * <ore-select label=\"Tags\" multiple color=\"primary\">\n * <optgroup label=\"Frontend\">\n * <option value=\"react\">React</option>\n * <option value=\"vue\">Vue</option>\n * </optgroup>\n * <optgroup label=\"Backend\">\n * <option value=\"node\">Node.js</option>\n * </optgroup>\n * </ore-select>\n * ```\n */\nexport const SELECT_TAG = 'ore-select' as const;\ndefine<OreSelectProps>(SELECT_TAG, {\n formAssociated: true,\n props: {\n ...themableBundle,\n ...sizableBundle,\n ...disablableBundle,\n ...loadableBundle,\n ...roundableBundle,\n error: prop.string(),\n fullwidth: prop.bool(false),\n helper: prop.string(),\n 'hide-label': prop.bool(false),\n label: prop.string(),\n 'label-placement': prop.oneOf(['inset', 'outside'] as const, 'inset'),\n multiple: prop.bool(false),\n name: prop.string(),\n options: prop.json(undefined as OreSelectOptionInput[] | undefined),\n placeholder: prop.string(),\n required: prop.bool(false),\n success: prop.bool(false),\n value: prop.string(),\n variant: prop.string<Exclude<VisualVariant, 'frost'>>(),\n },\n setup(props) {\n const el = getHost();\n const emit = useEmit<OreSelectEvents>();\n const slots = useSlots();\n\n const shadowRoot = el.shadowRoot;\n // ────────────────────────────────────────────────────────────────\n // State & Context\n // ────────────────────────────────────────────────────────────────\n\n const slottedOptions = signal<OptionItem[]>([]);\n const isLoading = computed(() => Boolean(props.loading.value));\n\n // Merged options: explicit prop value overrides slotted options\n function normalizeOption(option: OreSelectOptionInput): OptionItem {\n return {\n disabled: Boolean(option.disabled),\n disabledReason: option.disabledReason,\n group: option.group,\n icons: normalizeIcons(option.icon),\n label: option.label ?? option.value,\n value: option.value,\n };\n }\n\n const options = computed(() => {\n const explicitOptions = props.options.value;\n\n return Array.isArray(explicitOptions) ? explicitOptions.map(normalizeOption) : slottedOptions.value;\n });\n let triggerEl: HTMLElement | null = null;\n let dropdownEl: HTMLElement | null = null;\n\n const abortSignal = lifecycleSignal(onCleanup);\n const choice = createChoiceField({\n disabled: props.disabled,\n error: props.error,\n helper: props.helper,\n label: props.label,\n labelPlacement: props['label-placement'],\n multiple: props.multiple,\n prefix: 'select',\n required: props.required,\n signal: abortSignal,\n value: props.value,\n });\n\n choice.attachFormField(\n useField<string>({\n disabled: choice.disabled,\n onReset: choice.reset,\n toFormValue: (v) => v,\n validationMessage: choice.validationMessage,\n validity: choice.validity,\n value: choice.formValue,\n }),\n );\n\n const optionList = createListboxDropdown<OptionItem>({\n getBoundary: () => el,\n getFocusedOptionElement: () => dropdownEl?.querySelector<HTMLElement>('[data-focused]') ?? null,\n getItems: () => options.value,\n getPanel: () => dropdownEl,\n getReference: () => triggerEl,\n getTrigger: () => triggerEl,\n isDisabled: () => choice.disabled.value,\n isItemDisabled: (option) => option.disabled,\n onClose: (reason) => {\n emit('open-change', { open: false, reason });\n choice.triggerValidation('blur');\n },\n onOpen: (reason) => emit('open-change', { open: true, reason }),\n signal: abortSignal,\n });\n\n const { triggerValidation } = choice;\n const selectedValues = choice.selectedValues;\n const isDisabled = choice.disabled;\n\n defineFieldValue(\n el,\n () => choice.formValue.value,\n (value) => {\n choice.setValues(value ? value.split(',') : []);\n },\n );\n\n const { fieldId: selectId } = choice;\n const listboxId = `listbox-${selectId}`;\n const { focusedIndex, isOpen } = optionList;\n\n // Sync host attributes for CSS hooks\n bind({\n attr: {\n 'has-error': () => (props.error.value ? true : undefined),\n open: () => (isOpen.value ? true : undefined),\n size: props.size,\n variant: props.variant,\n },\n });\n\n // ────────────────────────────────────────────────────────────────\n // Option Reading from Slot\n // ────────────────────────────────────────────────────────────────\n\n function readOptions() {\n const slot = shadowRoot?.querySelector<HTMLSlotElement>('slot');\n\n if (!slot) return;\n\n const assigned = slot.assignedElements({ flatten: true });\n const items: OptionItem[] = [];\n\n for (const el of assigned) {\n if (el.tagName === 'OPTION') {\n const opt = el as HTMLOptionElement;\n\n items.push({\n disabled: opt.disabled,\n disabledReason: opt.dataset.disabledReason,\n icons: normalizeIcons(opt.dataset.icon),\n label: opt.text || opt.value,\n value: opt.value,\n });\n } else if (el.tagName === 'OPTGROUP') {\n const group = el as HTMLOptGroupElement;\n const groupLabel = group.label;\n\n for (const child of Array.from(group.querySelectorAll('option'))) {\n const opt = child as HTMLOptionElement;\n\n items.push({\n disabled: opt.disabled,\n disabledReason: opt.dataset.disabledReason,\n group: groupLabel,\n icons: normalizeIcons(opt.dataset.icon),\n label: opt.text || opt.value,\n value: opt.value,\n });\n }\n }\n }\n\n slottedOptions.value = items;\n }\n\n const displayLabel = computed(() => {\n if (selectedValues.value.length === 0) return '';\n\n if (props.multiple.value && selectedValues.value.length > 1) {\n return `${selectedValues.value.length} selected`;\n }\n\n const first = selectedValues.value[0];\n\n return options.value.find((o) => o.value === first)?.label ?? first;\n });\n const selectedIcons = computed(() => {\n if (props.multiple.value || selectedValues.value.length === 0) return undefined;\n const first = selectedValues.value[0];\n\n return options.value.find((o) => o.value === first)?.icons;\n });\n const selectedChipItems = computed(() => {\n if (!props.multiple.value) return [];\n\n return selectedValues.value.map((value) => ({\n label: options.value.find((o) => o.value === value)?.label ?? value,\n value,\n }));\n });\n const showChips = computed(() => props.multiple.value && selectedValues.value.length > 0);\n const triggerText = computed(() => displayLabel.value || props.placeholder.value || '');\n\n function buildFlatList(opts: OptionItem[]): FlatRow[] {\n const flat: FlatRow[] = [];\n const groups = new Map<string | undefined, OptionItem[]>();\n\n for (const opt of opts) {\n const key = opt.group;\n\n let group = groups.get(key);\n\n if (!group) {\n group = [];\n groups.set(key, group);\n }\n\n group.push(opt);\n }\n\n let globalIdx = 0;\n\n for (const [groupLabel, groupOpts] of groups) {\n if (groupLabel !== undefined) flat.push({ label: groupLabel, type: 'group' });\n\n for (const opt of groupOpts) flat.push({ idx: globalIdx++, opt, type: 'option' });\n }\n\n return flat;\n }\n\n const flatRows = computed(() => buildFlatList(options.value));\n\n function emitChange(): void {\n setFieldValue(el, choice.formValue.value);\n dispatchNativeFieldEvent(el, 'input');\n dispatchNativeFieldEvent(el, 'change');\n }\n\n function removeChip(event: Event): void {\n event.stopPropagation();\n\n const value = (event as CustomEvent<{ value?: string }>).detail?.value;\n\n if (value === undefined) return;\n\n choice.removeValue(value);\n emitChange();\n triggerValidation('change');\n }\n\n function openPopup(reason: OverlayOpenReason = 'programmatic') {\n // Show the popover before positioning so the positioner measures the element in the top\n // layer, not inside a possible ancestor containing block (a transformed dialog panel).\n if (dropdownEl && 'showPopover' in dropdownEl && !dropdownEl.matches(':popover-open')) dropdownEl.showPopover();\n optionList.open(reason);\n\n requestAnimationFrame(() => {\n const selectedIndex =\n selectedValues.value.length > 0\n ? options.value.findIndex((option) => option.value === selectedValues.value[0])\n : -1;\n\n if (selectedIndex >= 0) {\n optionList.set(selectedIndex);\n\n return;\n }\n\n optionList.navigate('first');\n });\n }\n\n // Selection\n\n function selectOption(opt: OptionItem, _e?: Event) {\n if (opt.disabled) return;\n\n if (props.multiple.value) {\n choice.toggleValue(opt.value);\n } else {\n choice.selectValue(opt.value);\n optionList.close();\n }\n\n emitChange();\n triggerValidation('change');\n }\n\n // Keyboard navigation\n\n function handleTriggerKeydown(e: KeyboardEvent) {\n if (isDisabled.value) return;\n\n // Let optionList handle arrow key navigation\n if (optionList.handleKeydown(e)) return;\n\n switch (e.key) {\n case ' ':\n case 'Enter':\n e.preventDefault();\n\n if (isOpen.value) {\n const idx = focusedIndex.value;\n const opts = options.value;\n\n if (idx >= 0 && idx < opts.length) selectOption(opts[idx], e);\n } else {\n openPopup('keyboard');\n }\n\n break;\n case 'Tab':\n optionList.close();\n break;\n }\n }\n\n // ore-input prop helpers\n const inputValue = () => triggerText.value;\n const hideLabel = () => props['hide-label'].value;\n // When hide-label is set, suppress the visible label passed to ore-input (no inset\n // label renders, avoiding extra trigger height) but expose the label text as\n // aria-label on the trigger so the combobox retains its accessible name.\n const inputLabel = () => (hideLabel() ? '' : (props.label.value ?? ''));\n const triggerAriaLabel = () => (hideLabel() ? (props.label.value ?? '') : null);\n const inputPlaceholder = () => props.placeholder.value ?? '';\n const inputLabelPlacement = () => props['label-placement'].value ?? 'inset';\n const inputColor = () => props.color?.value ?? undefined;\n const inputSize = () => props.size?.value ?? undefined;\n const inputVariant = () => props.variant?.value ?? undefined;\n const inputRounded = () => props.rounded?.value ?? undefined;\n const inputHelper = () => props.helper.value ?? '';\n const inputError = () => props.error.value ?? '';\n const inputDisabled = () => (isDisabled.value ? true : undefined);\n const inputRequired = () => (props.required.value ? true : undefined);\n const inputFullwidth = () => (props.fullwidth.value ? true : undefined);\n const tabIndexAttr = () => (isDisabled.value ? '-1' : '0');\n\n watch(slots.elements(), () => readOptions(), { immediate: true });\n\n const stopPopoverSync = effect(() => {\n if (isOpen.value) {\n if (dropdownEl && 'showPopover' in dropdownEl && !dropdownEl.matches(':popover-open')) dropdownEl.showPopover();\n } else {\n if (dropdownEl && 'hidePopover' in dropdownEl && dropdownEl.matches(':popover-open')) dropdownEl.hidePopover();\n }\n });\n\n onCleanup(() => stopPopoverSync.dispose());\n\n onMounted(() => {\n let onTriggerClick: ((event: MouseEvent) => void) | null = null;\n let onTriggerKeydown: ((event: KeyboardEvent) => void) | null = null;\n\n if (triggerEl) {\n onTriggerClick = (event: MouseEvent) => {\n event.stopPropagation();\n\n if (isDisabled.value) return;\n\n if (isOpen.value) optionList.close('trigger');\n else openPopup('click');\n };\n onTriggerKeydown = (event: KeyboardEvent) => {\n handleTriggerKeydown(event);\n };\n\n triggerEl.addEventListener('click', onTriggerClick);\n triggerEl.addEventListener('keydown', onTriggerKeydown);\n }\n\n return () => {\n if (triggerEl && onTriggerClick) triggerEl.removeEventListener('click', onTriggerClick);\n\n if (triggerEl && onTriggerKeydown) triggerEl.removeEventListener('keydown', onTriggerKeydown);\n };\n });\n\n return html`\n <slot style=\"display:none\"></slot>\n <ore-input\n class=\"trigger\"\n part=\"trigger\"\n readonly\n tabindex=\"${tabIndexAttr}\"\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n aria-controls=\"${listboxId}\"\n aria-label=\"${triggerAriaLabel}\"\n aria-disabled=\"${() => (isDisabled.value ? 'true' : null)}\"\n aria-expanded=\"${() => String(isOpen.value)}\"\n aria-invalid=\"${() => (props.error.value ? 'true' : null)}\"\n value=\"${inputValue}\"\n label=\"${inputLabel}\"\n placeholder=\"${inputPlaceholder}\"\n label-placement=\"${inputLabelPlacement}\"\n color=\"${inputColor}\"\n size=\"${inputSize}\"\n variant=\"${inputVariant}\"\n rounded=\"${inputRounded}\"\n helper=\"${inputHelper}\"\n error=\"${inputError}\"\n ?disabled=\"${inputDisabled}\"\n ?required=\"${inputRequired}\"\n ?fullwidth=\"${inputFullwidth}\"\n ?success=\"${() => props.success.value}\"\n ref=\"${(el: HTMLElement) => {\n triggerEl = el;\n }}\">\n ${() => {\n const icons = selectedIcons.value;\n\n if (!icons?.length) return html``;\n\n return html`<span class=\"trigger-selected-icons\" slot=\"prefix\">\n ${icons.map((icon) =>\n isIconImage(icon)\n ? html`<img alt=\"\" aria-hidden=\"true\" class=\"trigger-selected-icon--image\" src=\"${icon}\" />`\n : html`<ore-icon aria-hidden=\"true\" class=\"trigger-selected-icon\" name=\"${icon}\" size=\"14\"></ore-icon>`,\n )}\n </span>`;\n }}\n <div slot=\"prefix\" class=\"chips-row\" ?hidden=\"${() => !showChips.value}\">\n ${() =>\n selectedChipItems.value.map(\n (item) => html`\n <ore-chip\n value=\"${item.value}\"\n label=\"${item.label}\"\n mode=\"removable\"\n variant=\"flat\"\n size=\"sm\"\n color=\"${props.color}\"\n @remove=\"${removeChip}\">\n ${item.label}\n </ore-chip>\n `,\n )}\n </div>\n <span slot=\"suffix\" class=\"trigger-suffix\" aria-hidden=\"true\">\n <span class=\"loader\"></span>\n <span class=\"trigger-icon\">\n <ore-icon name=\"chevron-down\" size=\"14\" stroke-width=\"2\" aria-hidden=\"true\"></ore-icon>\n </span>\n </span>\n </ore-input>\n <div\n class=\"dropdown\"\n part=\"dropdown\"\n popover=\"manual\"\n ?data-open=\"${isOpen}\"\n role=\"listbox\"\n id=\"${listboxId}\"\n aria-label=\"Options\"\n ref=\"${(el: HTMLElement) => {\n dropdownEl = el;\n }}\">\n <div class=\"dropdown-loading\" ?hidden=\"${() => !isLoading.value}\">Loading…</div>\n <div class=\"dropdown-empty\" ?hidden=\"${() => isLoading.value || options.value.length > 0}\">No options</div>\n <div class=\"options-list\" ?hidden=\"${() => isLoading.value || options.value.length === 0}\">\n ${() =>\n flatRows.value.map((row) =>\n row.type === 'group'\n ? html`\n <div class=\"optgroup-label\" role=\"presentation\">${row.label}</div>\n `\n : html`\n <div\n class=\"option\"\n role=\"option\"\n id=\"${`${selectId}-opt-${row.idx}`}\"\n data-option-index=\"${String(row.idx)}\"\n data-option-value=\"${row.opt.value}\"\n aria-selected=\"${() => String(selectedValues.value.includes(row.opt.value))}\"\n aria-disabled=\"${() => String(row.opt.disabled)}\"\n ?data-focused=\"${() => focusedIndex.value === row.idx}\"\n ?data-selected=\"${() => selectedValues.value.includes(row.opt.value)}\"\n ?data-disabled=\"${() => row.opt.disabled}\"\n @click=\"${(e: MouseEvent) => {\n e.stopPropagation();\n selectOption(row.opt, e);\n }}\"\n @pointerenter=\"${() => {\n optionList.set(row.idx);\n }}\">\n ${\n row.opt.icons?.length\n ? html`<span class=\"option-icons\" aria-hidden=\"true\">\n ${row.opt.icons.map((icon) =>\n isIconImage(icon)\n ? html`<img alt=\"\" class=\"option-icon option-icon--image\" src=\"${icon}\" />`\n : html`<ore-icon class=\"option-icon\" name=\"${icon}\" size=\"14\"></ore-icon>`,\n )}\n </span>`\n : html``\n }\n <span>${row.opt.label}</span>\n ${\n row.opt.disabled && row.opt.disabledReason\n ? html`<small class=\"disabled-reason\" title=\"${row.opt.disabledReason}\">${row.opt.disabledReason}</small>`\n : html``\n }\n <span class=\"option-check\" aria-hidden=\"true\">\n <ore-icon name=\"check\" size=\"14\" stroke-width=\"2.5\" aria-hidden=\"true\"></ore-icon>\n </span>\n </div>\n `,\n )}\n </div>\n </div>\n `;\n },\n shadow: { delegatesFocus: true },\n styles: [colorThemeMixin, reducedMotionMixin, roundedVariantMixin, componentStyles],\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"select.cjs","names":[],"sources":["../src/inputs/select/select.ts"],"sourcesContent":["import { bind, define, getHost, html, onCleanup, onMounted, prop, useEmit, useField, useSlots } from '@vielzeug/ore';\nimport { computed, effect, signal, watch } from '@vielzeug/ripple';\n\nimport type { OverlayOpenChangeDetail, OverlayOpenReason } from '../../core';\nimport { createChoiceField, createListboxDropdown, lifecycleSignal } from '../../core';\nimport type { SelectableFieldProps } from '../../shared';\nimport { disablableBundle, loadableBundle, roundableBundle, sizableBundle, themableBundle } from '../../shared';\nimport { colorThemeMixin, reducedMotionMixin, roundedVariantMixin } from '../../styles';\nimport { INPUT_VARIANTS, type InputVariant } from '../../types';\nimport { defineFieldValue, dispatchNativeFieldEvent, setFieldValue } from '../shared/native-field-event';\nimport componentStyles from './select.css?inline';\n\nexport { ICON_TAG } from '../../content/icon/icon';\nexport { CHIP_TAG } from '../../feedback/chip/chip';\nexport { INPUT_TAG } from '../input/input';\n\n// ── Types ─────────────────────────────────────────────────────────────\n\ntype OptionItem = {\n disabled: boolean;\n disabledReason?: string;\n group?: string;\n icons?: string[];\n label: string;\n value: string;\n};\n\nexport type OreSelectOptionInput = {\n disabled?: boolean;\n /** Explanation displayed and announced when the option is disabled. */\n disabledReason?: string;\n group?: string;\n /** Icon(s) rendered before the option label: lucide name(s) or image URL(s). */\n icon?: string | string[];\n label?: string;\n value: string;\n};\n\ntype FlatRow =\n | {\n idx: number;\n opt: OptionItem;\n type: 'option';\n }\n | {\n label: string;\n type: 'group';\n };\n\n/**\n * Icon sources containing a path separator or a `data:` scheme are treated as image URLs and\n * rendered as `<img>`; anything else is a lucide icon name rendered via `ore-icon`.\n */\nconst isIconImage = (icon: string): boolean => icon.includes('/') || icon.startsWith('data:');\n\n/** Normalizes an icon value: single name/URL, space-separated list, or array: to icon entries. */\nconst normalizeIcons = (icon: string | string[] | undefined): string[] | undefined => {\n const list = Array.isArray(icon) ? icon : icon?.split(' ');\n const icons = list?.map((entry) => entry.trim()).filter(Boolean);\n return icons?.length ? icons : undefined;\n};\n\n// ── Styles ─────────────────────────────────────────────────────────────\n\n// ── Component Props ─────────────────────────────────────────────────────────────\n\n/** Select component properties */\n\nexport type OreSelectEvents = {\n change: Event;\n input: Event;\n 'open-change': OverlayOpenChangeDetail;\n};\n\nexport type OreSelectProps = SelectableFieldProps<InputVariant> & {\n /** Hide the visible label while preserving the accessible name via `aria-label` */\n 'hide-label'?: boolean;\n /** Show loading state in dropdown */\n loading?: boolean;\n /** Allow selecting multiple options */\n multiple?: boolean;\n /** JS options array (alternative to slotted <option> elements) */\n options?: OreSelectOptionInput[];\n /** Mark the field as required */\n required?: boolean;\n};\n\n/**\n * A fully custom form-associated select dropdown with keyboard navigation and ARIA support.\n * Reads `<option>` and `<optgroup>` children from the default slot.\n *\n * @element ore-select\n *\n * @attr {string} label - Label text\n * @attr {string} label-placement - 'inset' | 'outside'\n * @attr {boolean} hide-label - Hide the visible label; the label text is exposed as `aria-label` on the trigger instead\n * @attr {string} value - Current selected value(s) (comma-separated for multiple)\n * @attr {string} placeholder - Placeholder when no option selected\n * @attr {string} name - Form field name\n * @attr {boolean} multiple - Enable multi-select\n * @attr {boolean} disabled - Disable the select\n * @attr {boolean} required - Required field\n * @attr {string} helper - Helper text below the select\n * @attr {string} error - Error message\n * @attr {boolean} success - Show an inline success check icon (suppressed while `error` is set)\n * @attr {string} color - Theme color: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error'\n * @attr {string} variant - Visual variant: 'solid' | 'flat' | 'bordered' | 'outline' | 'ghost' | 'text'\n * @attr {string} size - Component size: 'sm' | 'md' | 'lg'\n * @attr {string} rounded - Border radius: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'\n * @attr {boolean} fullwidth - Expand to full width\n *\n * @fires input - Fired when selection changes.\n * @fires change - Fired when selection changes.\n * @fires open-change - Fired when the dropdown state changes. detail: { open, reason }\n *\n * @slot - `<option>` and `<optgroup>` elements\n *\n * @cssprop --select-bg - Background\n * @cssprop --select-border-color - Border color\n * @cssprop --select-min-width - Minimum width of the select; the trigger floors at it too, so the control never renders wider than its host\n * @cssprop --select-radius - Border radius\n * @cssprop --select-padding - Padding\n * @cssprop --select-font-size - Font size\n * @cssprop --select-placeholder-color - Placeholder text color\n *\n * @part trigger - The `ore-input` trigger element that opens the dropdown.\n * @part dropdown - The dropdown listbox panel container.\n *\n * @example\n * ```html\n * <ore-select label=\"Role\" value=\"admin\">\n * <option value=\"admin\">Administrator</option>\n * <option value=\"editor\">Editor</option>\n * <option value=\"viewer\">Viewer</option>\n * </ore-select>\n *\n * <ore-select label=\"Tags\" multiple color=\"primary\">\n * <optgroup label=\"Frontend\">\n * <option value=\"react\">React</option>\n * <option value=\"vue\">Vue</option>\n * </optgroup>\n * <optgroup label=\"Backend\">\n * <option value=\"node\">Node.js</option>\n * </optgroup>\n * </ore-select>\n * ```\n */\nexport const SELECT_TAG = 'ore-select' as const;\ndefine<OreSelectProps>(SELECT_TAG, {\n formAssociated: true,\n props: {\n ...themableBundle,\n ...sizableBundle,\n ...disablableBundle,\n ...loadableBundle,\n ...roundableBundle,\n error: prop.string(),\n fullwidth: prop.bool(false),\n helper: prop.string(),\n 'hide-label': prop.bool(false),\n label: prop.string(),\n 'label-placement': prop.oneOf(['inset', 'outside'] as const, 'inset'),\n multiple: prop.bool(false),\n name: prop.string(),\n options: prop.json(undefined as OreSelectOptionInput[] | undefined),\n placeholder: prop.string(),\n required: prop.bool(false),\n success: prop.bool(false),\n value: prop.string(),\n variant: prop.oneOf(INPUT_VARIANTS),\n },\n setup(props) {\n const el = getHost();\n const emit = useEmit<OreSelectEvents>();\n const slots = useSlots();\n\n const shadowRoot = el.shadowRoot;\n // ────────────────────────────────────────────────────────────────\n // State & Context\n // ────────────────────────────────────────────────────────────────\n\n const slottedOptions = signal<OptionItem[]>([]);\n const isLoading = computed(() => Boolean(props.loading.value));\n\n // Merged options: explicit prop value overrides slotted options\n function normalizeOption(option: OreSelectOptionInput): OptionItem {\n return {\n disabled: Boolean(option.disabled),\n disabledReason: option.disabledReason,\n group: option.group,\n icons: normalizeIcons(option.icon),\n label: option.label ?? option.value,\n value: option.value,\n };\n }\n\n const options = computed(() => {\n const explicitOptions = props.options.value;\n\n return Array.isArray(explicitOptions) ? explicitOptions.map(normalizeOption) : slottedOptions.value;\n });\n let triggerEl: HTMLElement | null = null;\n let dropdownEl: HTMLElement | null = null;\n\n const abortSignal = lifecycleSignal(onCleanup);\n const choice = createChoiceField({\n disabled: props.disabled,\n error: props.error,\n helper: props.helper,\n label: props.label,\n labelPlacement: props['label-placement'],\n multiple: props.multiple,\n prefix: 'select',\n required: props.required,\n signal: abortSignal,\n value: props.value,\n });\n\n choice.attachFormField(\n useField<string>({\n disabled: choice.disabled,\n onReset: choice.reset,\n toFormValue: (v) => v,\n validity: choice.validity,\n value: choice.formValue,\n }),\n );\n\n const optionList = createListboxDropdown<OptionItem>({\n getBoundary: () => el,\n getFocusedOptionElement: () => dropdownEl?.querySelector<HTMLElement>('[data-focused]') ?? null,\n getItems: () => options.value,\n getPanel: () => dropdownEl,\n getReference: () => triggerEl,\n getTrigger: () => triggerEl,\n isDisabled: () => choice.disabled.value,\n isItemDisabled: (option) => option.disabled,\n onClose: (reason) => {\n emit('open-change', { open: false, reason });\n choice.triggerValidation('blur');\n },\n onOpen: (reason) => emit('open-change', { open: true, reason }),\n signal: abortSignal,\n });\n\n const { triggerValidation } = choice;\n const selectedValues = choice.selectedValues;\n const isDisabled = choice.disabled;\n\n defineFieldValue(\n el,\n () => choice.formValue.value,\n (value) => {\n choice.setValues(value ? value.split(',') : []);\n },\n );\n\n const { fieldId: selectId } = choice;\n const listboxId = `listbox-${selectId}`;\n const { focusedIndex, isOpen } = optionList;\n\n // Sync host attributes for CSS hooks\n bind({\n attr: {\n 'has-error': () => (props.error.value ? true : undefined),\n open: () => (isOpen.value ? true : undefined),\n size: props.size,\n variant: props.variant,\n },\n });\n\n // ────────────────────────────────────────────────────────────────\n // Option Reading from Slot\n // ────────────────────────────────────────────────────────────────\n\n function readOptions() {\n const slot = shadowRoot?.querySelector<HTMLSlotElement>('slot');\n\n if (!slot) return;\n\n const assigned = slot.assignedElements({ flatten: true });\n const items: OptionItem[] = [];\n\n for (const el of assigned) {\n if (el.tagName === 'OPTION') {\n const opt = el as HTMLOptionElement;\n\n items.push({\n disabled: opt.disabled,\n disabledReason: opt.dataset.disabledReason,\n icons: normalizeIcons(opt.dataset.icon),\n label: opt.text || opt.value,\n value: opt.value,\n });\n } else if (el.tagName === 'OPTGROUP') {\n const group = el as HTMLOptGroupElement;\n const groupLabel = group.label;\n\n for (const child of Array.from(group.querySelectorAll('option'))) {\n const opt = child as HTMLOptionElement;\n\n items.push({\n disabled: opt.disabled,\n disabledReason: opt.dataset.disabledReason,\n group: groupLabel,\n icons: normalizeIcons(opt.dataset.icon),\n label: opt.text || opt.value,\n value: opt.value,\n });\n }\n }\n }\n\n slottedOptions.value = items;\n }\n\n const displayLabel = computed(() => {\n if (selectedValues.value.length === 0) return '';\n\n if (props.multiple.value && selectedValues.value.length > 1) {\n return `${selectedValues.value.length} selected`;\n }\n\n const first = selectedValues.value[0];\n\n return options.value.find((o) => o.value === first)?.label ?? first;\n });\n const selectedIcons = computed(() => {\n if (props.multiple.value || selectedValues.value.length === 0) return undefined;\n const first = selectedValues.value[0];\n\n return options.value.find((o) => o.value === first)?.icons;\n });\n const selectedChipItems = computed(() => {\n if (!props.multiple.value) return [];\n\n return selectedValues.value.map((value) => ({\n label: options.value.find((o) => o.value === value)?.label ?? value,\n value,\n }));\n });\n const showChips = computed(() => props.multiple.value && selectedValues.value.length > 0);\n const triggerText = computed(() => displayLabel.value || props.placeholder.value || '');\n\n function buildFlatList(opts: OptionItem[]): FlatRow[] {\n const flat: FlatRow[] = [];\n const groups = new Map<string | undefined, OptionItem[]>();\n\n for (const opt of opts) {\n const key = opt.group;\n\n let group = groups.get(key);\n\n if (!group) {\n group = [];\n groups.set(key, group);\n }\n\n group.push(opt);\n }\n\n let globalIdx = 0;\n\n for (const [groupLabel, groupOpts] of groups) {\n if (groupLabel !== undefined) flat.push({ label: groupLabel, type: 'group' });\n\n for (const opt of groupOpts) flat.push({ idx: globalIdx++, opt, type: 'option' });\n }\n\n return flat;\n }\n\n const flatRows = computed(() => buildFlatList(options.value));\n\n function emitChange(): void {\n setFieldValue(el, choice.formValue.value);\n dispatchNativeFieldEvent(el, 'input');\n dispatchNativeFieldEvent(el, 'change');\n }\n\n function removeChip(event: Event): void {\n event.stopPropagation();\n\n const value = (event as CustomEvent<{ value?: string }>).detail?.value;\n\n if (value === undefined) return;\n\n choice.removeValue(value);\n emitChange();\n triggerValidation('change');\n }\n\n function openPopup(reason: OverlayOpenReason = 'programmatic') {\n // Show the popover before positioning so the positioner measures the element in the top\n // layer, not inside a possible ancestor containing block (a transformed dialog panel).\n if (dropdownEl && 'showPopover' in dropdownEl && !dropdownEl.matches(':popover-open')) dropdownEl.showPopover();\n optionList.open(reason);\n\n requestAnimationFrame(() => {\n const selectedIndex =\n selectedValues.value.length > 0\n ? options.value.findIndex((option) => option.value === selectedValues.value[0])\n : -1;\n\n if (selectedIndex >= 0) {\n optionList.set(selectedIndex);\n\n return;\n }\n\n optionList.navigate('first');\n });\n }\n\n // Selection\n\n function selectOption(opt: OptionItem, _e?: Event) {\n if (opt.disabled) return;\n\n if (props.multiple.value) {\n choice.toggleValue(opt.value);\n } else {\n choice.selectValue(opt.value);\n optionList.close();\n }\n\n emitChange();\n triggerValidation('change');\n }\n\n // Keyboard navigation\n\n function handleTriggerKeydown(e: KeyboardEvent) {\n if (isDisabled.value) return;\n\n // Let optionList handle arrow key navigation\n if (optionList.handleKeydown(e)) return;\n\n switch (e.key) {\n case ' ':\n case 'Enter':\n e.preventDefault();\n\n if (isOpen.value) {\n const idx = focusedIndex.value;\n const opts = options.value;\n\n if (idx >= 0 && idx < opts.length) selectOption(opts[idx], e);\n } else {\n openPopup('keyboard');\n }\n\n break;\n case 'Tab':\n optionList.close();\n break;\n }\n }\n\n // ore-input prop helpers\n const inputValue = () => triggerText.value;\n const hideLabel = () => props['hide-label'].value;\n // When hide-label is set, suppress the visible label passed to ore-input (no inset\n // label renders, avoiding extra trigger height) but expose the label text as\n // aria-label on the trigger so the combobox retains its accessible name.\n const inputLabel = () => (hideLabel() ? '' : (props.label.value ?? ''));\n const triggerAriaLabel = () => (hideLabel() ? (props.label.value ?? '') : null);\n const inputPlaceholder = () => props.placeholder.value ?? '';\n const inputLabelPlacement = () => props['label-placement'].value ?? 'inset';\n const inputColor = () => props.color?.value ?? undefined;\n const inputSize = () => props.size?.value ?? undefined;\n const inputVariant = () => props.variant?.value ?? undefined;\n const inputRounded = () => props.rounded?.value ?? undefined;\n const inputHelper = () => props.helper.value ?? '';\n const inputError = () => props.error.value ?? '';\n const inputDisabled = () => (isDisabled.value ? true : undefined);\n const inputRequired = () => (props.required.value ? true : undefined);\n const inputFullwidth = () => (props.fullwidth.value ? true : undefined);\n const tabIndexAttr = () => (isDisabled.value ? '-1' : '0');\n\n watch(slots.elements(), () => readOptions(), { immediate: true });\n\n const stopPopoverSync = effect(() => {\n if (isOpen.value) {\n if (dropdownEl && 'showPopover' in dropdownEl && !dropdownEl.matches(':popover-open')) dropdownEl.showPopover();\n } else {\n if (dropdownEl && 'hidePopover' in dropdownEl && dropdownEl.matches(':popover-open')) dropdownEl.hidePopover();\n }\n });\n\n onCleanup(() => stopPopoverSync.dispose());\n\n onMounted(() => {\n let onTriggerClick: ((event: MouseEvent) => void) | null = null;\n let onTriggerKeydown: ((event: KeyboardEvent) => void) | null = null;\n\n if (triggerEl) {\n onTriggerClick = (event: MouseEvent) => {\n event.stopPropagation();\n\n if (isDisabled.value) return;\n\n if (isOpen.value) optionList.close('trigger');\n else openPopup('click');\n };\n onTriggerKeydown = (event: KeyboardEvent) => {\n handleTriggerKeydown(event);\n };\n\n triggerEl.addEventListener('click', onTriggerClick);\n triggerEl.addEventListener('keydown', onTriggerKeydown);\n }\n\n return () => {\n if (triggerEl && onTriggerClick) triggerEl.removeEventListener('click', onTriggerClick);\n\n if (triggerEl && onTriggerKeydown) triggerEl.removeEventListener('keydown', onTriggerKeydown);\n };\n });\n\n return html`\n <slot style=\"display:none\"></slot>\n <ore-input\n class=\"trigger\"\n part=\"trigger\"\n readonly\n tabindex=\"${tabIndexAttr}\"\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n aria-controls=\"${listboxId}\"\n aria-label=\"${triggerAriaLabel}\"\n aria-disabled=\"${() => (isDisabled.value ? 'true' : null)}\"\n aria-expanded=\"${() => String(isOpen.value)}\"\n aria-invalid=\"${() => (props.error.value ? 'true' : null)}\"\n value=\"${inputValue}\"\n label=\"${inputLabel}\"\n placeholder=\"${inputPlaceholder}\"\n label-placement=\"${inputLabelPlacement}\"\n color=\"${inputColor}\"\n size=\"${inputSize}\"\n variant=\"${inputVariant}\"\n rounded=\"${inputRounded}\"\n helper=\"${inputHelper}\"\n error=\"${inputError}\"\n ?disabled=\"${inputDisabled}\"\n ?required=\"${inputRequired}\"\n ?fullwidth=\"${inputFullwidth}\"\n ?success=\"${() => props.success.value}\"\n ref=\"${(el: HTMLElement) => {\n triggerEl = el;\n }}\">\n ${() => {\n const icons = selectedIcons.value;\n\n if (!icons?.length) return html``;\n\n return html`<span class=\"trigger-selected-icons\" slot=\"prefix\">\n ${icons.map((icon) =>\n isIconImage(icon)\n ? html`<img alt=\"\" aria-hidden=\"true\" class=\"trigger-selected-icon--image\" src=\"${icon}\" />`\n : html`<ore-icon aria-hidden=\"true\" class=\"trigger-selected-icon\" name=\"${icon}\" size=\"14\"></ore-icon>`,\n )}\n </span>`;\n }}\n <div slot=\"prefix\" class=\"chips-row\" ?hidden=\"${() => !showChips.value}\">\n ${() =>\n selectedChipItems.value.map(\n (item) => html`\n <ore-chip\n value=\"${item.value}\"\n label=\"${item.label}\"\n mode=\"removable\"\n variant=\"flat\"\n size=\"sm\"\n color=\"${props.color}\"\n @remove=\"${removeChip}\">\n ${item.label}\n </ore-chip>\n `,\n )}\n </div>\n <span slot=\"suffix\" class=\"trigger-suffix\" aria-hidden=\"true\">\n <span class=\"loader\"></span>\n <span class=\"trigger-icon\">\n <ore-icon name=\"chevron-down\" size=\"14\" stroke-width=\"2\" aria-hidden=\"true\"></ore-icon>\n </span>\n </span>\n </ore-input>\n <div\n class=\"dropdown\"\n part=\"dropdown\"\n popover=\"manual\"\n ?data-open=\"${isOpen}\"\n role=\"listbox\"\n id=\"${listboxId}\"\n aria-label=\"Options\"\n ref=\"${(el: HTMLElement) => {\n dropdownEl = el;\n }}\">\n <div class=\"dropdown-loading\" ?hidden=\"${() => !isLoading.value}\">Loading…</div>\n <div class=\"dropdown-empty\" ?hidden=\"${() => isLoading.value || options.value.length > 0}\">No options</div>\n <div class=\"options-list\" ?hidden=\"${() => isLoading.value || options.value.length === 0}\">\n ${() =>\n flatRows.value.map((row) =>\n row.type === 'group'\n ? html`\n <div class=\"optgroup-label\" role=\"presentation\">${row.label}</div>\n `\n : html`\n <div\n class=\"option\"\n role=\"option\"\n id=\"${`${selectId}-opt-${row.idx}`}\"\n data-option-index=\"${String(row.idx)}\"\n data-option-value=\"${row.opt.value}\"\n aria-selected=\"${() => String(selectedValues.value.includes(row.opt.value))}\"\n aria-disabled=\"${() => String(row.opt.disabled)}\"\n ?data-focused=\"${() => focusedIndex.value === row.idx}\"\n ?data-selected=\"${() => selectedValues.value.includes(row.opt.value)}\"\n ?data-disabled=\"${() => row.opt.disabled}\"\n @click=\"${(e: MouseEvent) => {\n e.stopPropagation();\n selectOption(row.opt, e);\n }}\"\n @pointerenter=\"${() => {\n optionList.set(row.idx);\n }}\">\n ${\n row.opt.icons?.length\n ? html`<span class=\"option-icons\" aria-hidden=\"true\">\n ${row.opt.icons.map((icon) =>\n isIconImage(icon)\n ? html`<img alt=\"\" class=\"option-icon option-icon--image\" src=\"${icon}\" />`\n : html`<ore-icon class=\"option-icon\" name=\"${icon}\" size=\"14\"></ore-icon>`,\n )}\n </span>`\n : html``\n }\n <span>${row.opt.label}</span>\n ${\n row.opt.disabled && row.opt.disabledReason\n ? html`<small class=\"disabled-reason\" title=\"${row.opt.disabledReason}\">${row.opt.disabledReason}</small>`\n : html``\n }\n <span class=\"option-check\" aria-hidden=\"true\">\n <ore-icon name=\"check\" size=\"14\" stroke-width=\"2.5\" aria-hidden=\"true\"></ore-icon>\n </span>\n </div>\n `,\n )}\n </div>\n </div>\n `;\n },\n shadow: { delegatesFocus: true },\n styles: [colorThemeMixin, reducedMotionMixin, roundedVariantMixin, componentStyles],\n});\n"],"mappings":"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"}
package/dist/select.js CHANGED
@@ -1,4 +1,4 @@
1
- import{defineFieldValue as e,dispatchNativeFieldEvent as t,setFieldValue as n}from"./inputs/shared/native-field-event.js";import{reducedMotionMixin as r}from"./styles/mixins/accessibility.css.js";import{roundedVariantMixin as i}from"./styles/mixins/shape.css.js";import{colorThemeMixin as a}from"./styles/mixins/theme.css.js";import{createChoiceField as o}from"./core/choice-field.js";import{lifecycleSignal as s}from"./core/ore.js";import{createListboxDropdown as c}from"./core/option-list.js";import{disablableBundle as l,loadableBundle as u,roundableBundle as d,sizableBundle as f,themableBundle as p}from"./shared/prop-bundles.js";import{ICON_TAG as m}from"./icon.js";import{CHIP_TAG as h}from"./chip.js";import{INPUT_TAG as g}from"./input.js";import _ from"./inputs/select/select.css.js";import{computed as v,effect as y,signal as b,watch as x}from"@vielzeug/ripple";import{bind as S,define as C,getHost as w,html as T,onCleanup as E,onMounted as D,prop as O,useEmit as k,useField as A,useSlots as j}from"@vielzeug/ore";var isIconImage=e=>e.includes(`/`)||e.startsWith(`data:`),normalizeIcons=e=>{let t=(Array.isArray(e)?e:e?.split(` `))?.map(e=>e.trim()).filter(Boolean);return t?.length?t:void 0},M=`ore-select`;C(M,{formAssociated:!0,props:{...p,...f,...l,...u,...d,error:O.string(),fullwidth:O.bool(!1),helper:O.string(),"hide-label":O.bool(!1),label:O.string(),"label-placement":O.oneOf([`inset`,`outside`],`inset`),multiple:O.bool(!1),name:O.string(),options:O.json(void 0),placeholder:O.string(),required:O.bool(!1),success:O.bool(!1),value:O.string(),variant:O.string()},setup(r){let i=w(),a=k(),l=j(),u=i.shadowRoot,d=b([]),f=v(()=>!!r.loading.value);function normalizeOption(e){return{disabled:!!e.disabled,disabledReason:e.disabledReason,group:e.group,icons:normalizeIcons(e.icon),label:e.label??e.value,value:e.value}}let p=v(()=>{let e=r.options.value;return Array.isArray(e)?e.map(normalizeOption):d.value}),m=null,h=null,g=s(E),_=o({disabled:r.disabled,error:r.error,helper:r.helper,label:r.label,labelPlacement:r[`label-placement`],multiple:r.multiple,prefix:`select`,required:r.required,signal:g,value:r.value});_.attachFormField(A({disabled:_.disabled,onReset:_.reset,toFormValue:e=>e,validationMessage:_.validationMessage,validity:_.validity,value:_.formValue}));let C=c({getBoundary:()=>i,getFocusedOptionElement:()=>h?.querySelector(`[data-focused]`)??null,getItems:()=>p.value,getPanel:()=>h,getReference:()=>m,getTrigger:()=>m,isDisabled:()=>_.disabled.value,isItemDisabled:e=>e.disabled,onClose:e=>{a(`open-change`,{open:!1,reason:e}),_.triggerValidation(`blur`)},onOpen:e=>a(`open-change`,{open:!0,reason:e}),signal:g}),{triggerValidation:O}=_,M=_.selectedValues,N=_.disabled;e(i,()=>_.formValue.value,e=>{_.setValues(e?e.split(`,`):[])});let{fieldId:P}=_,F=`listbox-${P}`,{focusedIndex:I,isOpen:L}=C;S({attr:{"has-error":()=>r.error.value?!0:void 0,open:()=>L.value?!0:void 0,size:r.size,variant:r.variant}});function readOptions(){let e=u?.querySelector(`slot`);if(!e)return;let t=e.assignedElements({flatten:!0}),n=[];for(let e of t)if(e.tagName===`OPTION`){let t=e;n.push({disabled:t.disabled,disabledReason:t.dataset.disabledReason,icons:normalizeIcons(t.dataset.icon),label:t.text||t.value,value:t.value})}else if(e.tagName===`OPTGROUP`){let t=e,r=t.label;for(let e of Array.from(t.querySelectorAll(`option`))){let t=e;n.push({disabled:t.disabled,disabledReason:t.dataset.disabledReason,group:r,icons:normalizeIcons(t.dataset.icon),label:t.text||t.value,value:t.value})}}d.value=n}let R=v(()=>{if(M.value.length===0)return``;if(r.multiple.value&&M.value.length>1)return`${M.value.length} selected`;let e=M.value[0];return p.value.find(t=>t.value===e)?.label??e}),z=v(()=>{if(r.multiple.value||M.value.length===0)return;let e=M.value[0];return p.value.find(t=>t.value===e)?.icons}),B=v(()=>r.multiple.value?M.value.map(e=>({label:p.value.find(t=>t.value===e)?.label??e,value:e})):[]),V=v(()=>r.multiple.value&&M.value.length>0),H=v(()=>R.value||r.placeholder.value||``);function buildFlatList(e){let t=[],n=new Map;for(let t of e){let e=t.group,r=n.get(e);r||(r=[],n.set(e,r)),r.push(t)}let r=0;for(let[e,i]of n){e!==void 0&&t.push({label:e,type:`group`});for(let e of i)t.push({idx:r++,opt:e,type:`option`})}return t}let U=v(()=>buildFlatList(p.value));function emitChange(){n(i,_.formValue.value),t(i,`input`),t(i,`change`)}function removeChip(e){e.stopPropagation();let t=e.detail?.value;t!==void 0&&(_.removeValue(t),emitChange(),O(`change`))}function openPopup(e=`programmatic`){h&&`showPopover`in h&&!h.matches(`:popover-open`)&&h.showPopover(),C.open(e),requestAnimationFrame(()=>{let e=M.value.length>0?p.value.findIndex(e=>e.value===M.value[0]):-1;if(e>=0){C.set(e);return}C.navigate(`first`)})}function selectOption(e,t){e.disabled||(r.multiple.value?_.toggleValue(e.value):(_.selectValue(e.value),C.close()),emitChange(),O(`change`))}function handleTriggerKeydown(e){if(!N.value&&!C.handleKeydown(e))switch(e.key){case` `:case`Enter`:if(e.preventDefault(),L.value){let t=I.value,n=p.value;t>=0&&t<n.length&&selectOption(n[t],e)}else openPopup(`keyboard`);break;case`Tab`:C.close()}}let inputValue=()=>H.value,hideLabel=()=>r[`hide-label`].value,inputLabel=()=>hideLabel()?``:r.label.value??``,triggerAriaLabel=()=>hideLabel()?r.label.value??``:null,inputPlaceholder=()=>r.placeholder.value??``,inputLabelPlacement=()=>r[`label-placement`].value??`inset`,inputColor=()=>r.color?.value??void 0,inputSize=()=>r.size?.value??void 0,inputVariant=()=>r.variant?.value??void 0,inputRounded=()=>r.rounded?.value??void 0,inputHelper=()=>r.helper.value??``,inputError=()=>r.error.value??``,inputDisabled=()=>N.value?!0:void 0,inputRequired=()=>r.required.value?!0:void 0,inputFullwidth=()=>r.fullwidth.value?!0:void 0,tabIndexAttr=()=>N.value?`-1`:`0`;x(l.elements(),()=>readOptions(),{immediate:!0});let W=y(()=>{L.value?h&&`showPopover`in h&&!h.matches(`:popover-open`)&&h.showPopover():h&&`hidePopover`in h&&h.matches(`:popover-open`)&&h.hidePopover()});return E(()=>W.dispose()),D(()=>{let onTriggerClick=null,onTriggerKeydown=null;return m&&(onTriggerClick=e=>{e.stopPropagation(),!N.value&&(L.value?C.close(`trigger`):openPopup(`click`))},onTriggerKeydown=e=>{handleTriggerKeydown(e)},m.addEventListener(`click`,onTriggerClick),m.addEventListener(`keydown`,onTriggerKeydown)),()=>{m&&onTriggerClick&&m.removeEventListener(`click`,onTriggerClick),m&&onTriggerKeydown&&m.removeEventListener(`keydown`,onTriggerKeydown)}}),T`
1
+ import{defineFieldValue as e,dispatchNativeFieldEvent as t,setFieldValue as n}from"./inputs/shared/native-field-event.js";import{reducedMotionMixin as r}from"./styles/mixins/accessibility.css.js";import{roundedVariantMixin as i}from"./styles/mixins/shape.css.js";import{colorThemeMixin as a}from"./styles/mixins/theme.css.js";import{createChoiceField as o}from"./core/choice-field.js";import{lifecycleSignal as s}from"./core/ore.js";import{createListboxDropdown as c}from"./core/option-list.js";import{INPUT_VARIANTS as l}from"./shared/types.js";import{disablableBundle as u,loadableBundle as d,roundableBundle as f,sizableBundle as p,themableBundle as m}from"./shared/prop-bundles.js";import{ICON_TAG as h}from"./icon.js";import{CHIP_TAG as g}from"./chip.js";import{INPUT_TAG as _}from"./input.js";import v from"./inputs/select/select.css.js";import{computed as y,effect as b,signal as x,watch as S}from"@vielzeug/ripple";import{bind as C,define as w,getHost as T,html as E,onCleanup as D,onMounted as O,prop as k,useEmit as A,useField as j,useSlots as M}from"@vielzeug/ore";var isIconImage=e=>e.includes(`/`)||e.startsWith(`data:`),normalizeIcons=e=>{let t=(Array.isArray(e)?e:e?.split(` `))?.map(e=>e.trim()).filter(Boolean);return t?.length?t:void 0},N=`ore-select`;w(N,{formAssociated:!0,props:{...m,...p,...u,...d,...f,error:k.string(),fullwidth:k.bool(!1),helper:k.string(),"hide-label":k.bool(!1),label:k.string(),"label-placement":k.oneOf([`inset`,`outside`],`inset`),multiple:k.bool(!1),name:k.string(),options:k.json(void 0),placeholder:k.string(),required:k.bool(!1),success:k.bool(!1),value:k.string(),variant:k.oneOf(l)},setup(r){let i=T(),a=A(),l=M(),u=i.shadowRoot,d=x([]),f=y(()=>!!r.loading.value);function normalizeOption(e){return{disabled:!!e.disabled,disabledReason:e.disabledReason,group:e.group,icons:normalizeIcons(e.icon),label:e.label??e.value,value:e.value}}let p=y(()=>{let e=r.options.value;return Array.isArray(e)?e.map(normalizeOption):d.value}),m=null,h=null,g=s(D),_=o({disabled:r.disabled,error:r.error,helper:r.helper,label:r.label,labelPlacement:r[`label-placement`],multiple:r.multiple,prefix:`select`,required:r.required,signal:g,value:r.value});_.attachFormField(j({disabled:_.disabled,onReset:_.reset,toFormValue:e=>e,validity:_.validity,value:_.formValue}));let v=c({getBoundary:()=>i,getFocusedOptionElement:()=>h?.querySelector(`[data-focused]`)??null,getItems:()=>p.value,getPanel:()=>h,getReference:()=>m,getTrigger:()=>m,isDisabled:()=>_.disabled.value,isItemDisabled:e=>e.disabled,onClose:e=>{a(`open-change`,{open:!1,reason:e}),_.triggerValidation(`blur`)},onOpen:e=>a(`open-change`,{open:!0,reason:e}),signal:g}),{triggerValidation:w}=_,k=_.selectedValues,N=_.disabled;e(i,()=>_.formValue.value,e=>{_.setValues(e?e.split(`,`):[])});let{fieldId:P}=_,F=`listbox-${P}`,{focusedIndex:I,isOpen:L}=v;C({attr:{"has-error":()=>r.error.value?!0:void 0,open:()=>L.value?!0:void 0,size:r.size,variant:r.variant}});function readOptions(){let e=u?.querySelector(`slot`);if(!e)return;let t=e.assignedElements({flatten:!0}),n=[];for(let e of t)if(e.tagName===`OPTION`){let t=e;n.push({disabled:t.disabled,disabledReason:t.dataset.disabledReason,icons:normalizeIcons(t.dataset.icon),label:t.text||t.value,value:t.value})}else if(e.tagName===`OPTGROUP`){let t=e,r=t.label;for(let e of Array.from(t.querySelectorAll(`option`))){let t=e;n.push({disabled:t.disabled,disabledReason:t.dataset.disabledReason,group:r,icons:normalizeIcons(t.dataset.icon),label:t.text||t.value,value:t.value})}}d.value=n}let R=y(()=>{if(k.value.length===0)return``;if(r.multiple.value&&k.value.length>1)return`${k.value.length} selected`;let e=k.value[0];return p.value.find(t=>t.value===e)?.label??e}),z=y(()=>{if(r.multiple.value||k.value.length===0)return;let e=k.value[0];return p.value.find(t=>t.value===e)?.icons}),B=y(()=>r.multiple.value?k.value.map(e=>({label:p.value.find(t=>t.value===e)?.label??e,value:e})):[]),V=y(()=>r.multiple.value&&k.value.length>0),H=y(()=>R.value||r.placeholder.value||``);function buildFlatList(e){let t=[],n=new Map;for(let t of e){let e=t.group,r=n.get(e);r||(r=[],n.set(e,r)),r.push(t)}let r=0;for(let[e,i]of n){e!==void 0&&t.push({label:e,type:`group`});for(let e of i)t.push({idx:r++,opt:e,type:`option`})}return t}let U=y(()=>buildFlatList(p.value));function emitChange(){n(i,_.formValue.value),t(i,`input`),t(i,`change`)}function removeChip(e){e.stopPropagation();let t=e.detail?.value;t!==void 0&&(_.removeValue(t),emitChange(),w(`change`))}function openPopup(e=`programmatic`){h&&`showPopover`in h&&!h.matches(`:popover-open`)&&h.showPopover(),v.open(e),requestAnimationFrame(()=>{let e=k.value.length>0?p.value.findIndex(e=>e.value===k.value[0]):-1;if(e>=0){v.set(e);return}v.navigate(`first`)})}function selectOption(e,t){e.disabled||(r.multiple.value?_.toggleValue(e.value):(_.selectValue(e.value),v.close()),emitChange(),w(`change`))}function handleTriggerKeydown(e){if(!N.value&&!v.handleKeydown(e))switch(e.key){case` `:case`Enter`:if(e.preventDefault(),L.value){let t=I.value,n=p.value;t>=0&&t<n.length&&selectOption(n[t],e)}else openPopup(`keyboard`);break;case`Tab`:v.close()}}let inputValue=()=>H.value,hideLabel=()=>r[`hide-label`].value,inputLabel=()=>hideLabel()?``:r.label.value??``,triggerAriaLabel=()=>hideLabel()?r.label.value??``:null,inputPlaceholder=()=>r.placeholder.value??``,inputLabelPlacement=()=>r[`label-placement`].value??`inset`,inputColor=()=>r.color?.value??void 0,inputSize=()=>r.size?.value??void 0,inputVariant=()=>r.variant?.value??void 0,inputRounded=()=>r.rounded?.value??void 0,inputHelper=()=>r.helper.value??``,inputError=()=>r.error.value??``,inputDisabled=()=>N.value?!0:void 0,inputRequired=()=>r.required.value?!0:void 0,inputFullwidth=()=>r.fullwidth.value?!0:void 0,tabIndexAttr=()=>N.value?`-1`:`0`;S(l.elements(),()=>readOptions(),{immediate:!0});let W=b(()=>{L.value?h&&`showPopover`in h&&!h.matches(`:popover-open`)&&h.showPopover():h&&`hidePopover`in h&&h.matches(`:popover-open`)&&h.hidePopover()});return D(()=>W.dispose()),O(()=>{let onTriggerClick=null,onTriggerKeydown=null;return m&&(onTriggerClick=e=>{e.stopPropagation(),!N.value&&(L.value?v.close(`trigger`):openPopup(`click`))},onTriggerKeydown=e=>{handleTriggerKeydown(e)},m.addEventListener(`click`,onTriggerClick),m.addEventListener(`keydown`,onTriggerKeydown)),()=>{m&&onTriggerClick&&m.removeEventListener(`click`,onTriggerClick),m&&onTriggerKeydown&&m.removeEventListener(`keydown`,onTriggerKeydown)}}),E`
2
2
  <slot style="display:none"></slot>
3
3
  <ore-input
4
4
  class="trigger"
@@ -27,11 +27,11 @@ import{defineFieldValue as e,dispatchNativeFieldEvent as t,setFieldValue as n}fr
27
27
  ?fullwidth="${inputFullwidth}"
28
28
  ?success="${()=>r.success.value}"
29
29
  ref="${e=>{m=e}}">
30
- ${()=>{let e=z.value;return e?.length?T`<span class="trigger-selected-icons" slot="prefix">
31
- ${e.map(e=>isIconImage(e)?T`<img alt="" aria-hidden="true" class="trigger-selected-icon--image" src="${e}" />`:T`<ore-icon aria-hidden="true" class="trigger-selected-icon" name="${e}" size="14"></ore-icon>`)}
32
- </span>`:T``}}
30
+ ${()=>{let e=z.value;return e?.length?E`<span class="trigger-selected-icons" slot="prefix">
31
+ ${e.map(e=>isIconImage(e)?E`<img alt="" aria-hidden="true" class="trigger-selected-icon--image" src="${e}" />`:E`<ore-icon aria-hidden="true" class="trigger-selected-icon" name="${e}" size="14"></ore-icon>`)}
32
+ </span>`:E``}}
33
33
  <div slot="prefix" class="chips-row" ?hidden="${()=>!V.value}">
34
- ${()=>B.value.map(e=>T`
34
+ ${()=>B.value.map(e=>E`
35
35
  <ore-chip
36
36
  value="${e.value}"
37
37
  label="${e.label}"
@@ -63,27 +63,27 @@ import{defineFieldValue as e,dispatchNativeFieldEvent as t,setFieldValue as n}fr
63
63
  <div class="dropdown-loading" ?hidden="${()=>!f.value}">Loading…</div>
64
64
  <div class="dropdown-empty" ?hidden="${()=>f.value||p.value.length>0}">No options</div>
65
65
  <div class="options-list" ?hidden="${()=>f.value||p.value.length===0}">
66
- ${()=>U.value.map(e=>e.type===`group`?T`
66
+ ${()=>U.value.map(e=>e.type===`group`?E`
67
67
  <div class="optgroup-label" role="presentation">${e.label}</div>
68
- `:T`
68
+ `:E`
69
69
  <div
70
70
  class="option"
71
71
  role="option"
72
72
  id="${`${P}-opt-${e.idx}`}"
73
73
  data-option-index="${String(e.idx)}"
74
74
  data-option-value="${e.opt.value}"
75
- aria-selected="${()=>String(M.value.includes(e.opt.value))}"
75
+ aria-selected="${()=>String(k.value.includes(e.opt.value))}"
76
76
  aria-disabled="${()=>String(e.opt.disabled)}"
77
77
  ?data-focused="${()=>I.value===e.idx}"
78
- ?data-selected="${()=>M.value.includes(e.opt.value)}"
78
+ ?data-selected="${()=>k.value.includes(e.opt.value)}"
79
79
  ?data-disabled="${()=>e.opt.disabled}"
80
80
  @click="${t=>{t.stopPropagation(),selectOption(e.opt,t)}}"
81
- @pointerenter="${()=>{C.set(e.idx)}}">
82
- ${e.opt.icons?.length?T`<span class="option-icons" aria-hidden="true">
83
- ${e.opt.icons.map(e=>isIconImage(e)?T`<img alt="" class="option-icon option-icon--image" src="${e}" />`:T`<ore-icon class="option-icon" name="${e}" size="14"></ore-icon>`)}
84
- </span>`:T``}
81
+ @pointerenter="${()=>{v.set(e.idx)}}">
82
+ ${e.opt.icons?.length?E`<span class="option-icons" aria-hidden="true">
83
+ ${e.opt.icons.map(e=>isIconImage(e)?E`<img alt="" class="option-icon option-icon--image" src="${e}" />`:E`<ore-icon class="option-icon" name="${e}" size="14"></ore-icon>`)}
84
+ </span>`:E``}
85
85
  <span>${e.opt.label}</span>
86
- ${e.opt.disabled&&e.opt.disabledReason?T`<small class="disabled-reason" title="${e.opt.disabledReason}">${e.opt.disabledReason}</small>`:T``}
86
+ ${e.opt.disabled&&e.opt.disabledReason?E`<small class="disabled-reason" title="${e.opt.disabledReason}">${e.opt.disabledReason}</small>`:E``}
87
87
  <span class="option-check" aria-hidden="true">
88
88
  <ore-icon name="check" size="14" stroke-width="2.5" aria-hidden="true"></ore-icon>
89
89
  </span>
@@ -91,5 +91,5 @@ import{defineFieldValue as e,dispatchNativeFieldEvent as t,setFieldValue as n}fr
91
91
  `)}
92
92
  </div>
93
93
  </div>
94
- `},shadow:{delegatesFocus:!0},styles:[a,r,i,_]});export{h as CHIP_TAG,m as ICON_TAG,g as INPUT_TAG,M as SELECT_TAG};
94
+ `},shadow:{delegatesFocus:!0},styles:[a,r,i,v]});export{g as CHIP_TAG,h as ICON_TAG,_ as INPUT_TAG,N as SELECT_TAG};
95
95
  //# sourceMappingURL=select.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"select.js","names":[],"sources":["../src/inputs/select/select.ts"],"sourcesContent":["import { bind, define, getHost, html, onCleanup, onMounted, prop, useEmit, useField, useSlots } from '@vielzeug/ore';\nimport { computed, effect, signal, watch } from '@vielzeug/ripple';\n\nimport type { OverlayOpenChangeDetail, OverlayOpenReason } from '../../core';\nimport { createChoiceField, createListboxDropdown, lifecycleSignal } from '../../core';\nimport type { SelectableFieldProps } from '../../shared';\nimport { disablableBundle, loadableBundle, roundableBundle, sizableBundle, themableBundle } from '../../shared';\nimport { colorThemeMixin, reducedMotionMixin, roundedVariantMixin } from '../../styles';\nimport type { VisualVariant } from '../../types';\nimport { defineFieldValue, dispatchNativeFieldEvent, setFieldValue } from '../shared/native-field-event';\nimport componentStyles from './select.css?inline';\n\nexport { ICON_TAG } from '../../content/icon/icon';\nexport { CHIP_TAG } from '../../feedback/chip/chip';\nexport { INPUT_TAG } from '../input/input';\n\n// ── Types ─────────────────────────────────────────────────────────────\n\ntype OptionItem = {\n disabled: boolean;\n disabledReason?: string;\n group?: string;\n icons?: string[];\n label: string;\n value: string;\n};\n\nexport type OreSelectOptionInput = {\n disabled?: boolean;\n /** Explanation displayed and announced when the option is disabled. */\n disabledReason?: string;\n group?: string;\n /** Icon(s) rendered before the option label: lucide name(s) or image URL(s). */\n icon?: string | string[];\n label?: string;\n value: string;\n};\n\ntype FlatRow =\n | {\n idx: number;\n opt: OptionItem;\n type: 'option';\n }\n | {\n label: string;\n type: 'group';\n };\n\n/**\n * Icon sources containing a path separator or a `data:` scheme are treated as image URLs and\n * rendered as `<img>`; anything else is a lucide icon name rendered via `ore-icon`.\n */\nconst isIconImage = (icon: string): boolean => icon.includes('/') || icon.startsWith('data:');\n\n/** Normalizes an icon value: single name/URL, space-separated list, or array: to icon entries. */\nconst normalizeIcons = (icon: string | string[] | undefined): string[] | undefined => {\n const list = Array.isArray(icon) ? icon : icon?.split(' ');\n const icons = list?.map((entry) => entry.trim()).filter(Boolean);\n return icons?.length ? icons : undefined;\n};\n\n// ── Styles ─────────────────────────────────────────────────────────────\n\n// ── Component Props ─────────────────────────────────────────────────────────────\n\n/** Select component properties */\n\nexport type OreSelectEvents = {\n change: Event;\n input: Event;\n 'open-change': OverlayOpenChangeDetail;\n};\n\nexport type OreSelectProps = SelectableFieldProps<Exclude<VisualVariant, 'frost'>> & {\n /** Hide the visible label while preserving the accessible name via `aria-label` */\n 'hide-label'?: boolean;\n /** Show loading state in dropdown */\n loading?: boolean;\n /** Allow selecting multiple options */\n multiple?: boolean;\n /** JS options array (alternative to slotted <option> elements) */\n options?: OreSelectOptionInput[];\n /** Mark the field as required */\n required?: boolean;\n};\n\n/**\n * A fully custom form-associated select dropdown with keyboard navigation and ARIA support.\n * Reads `<option>` and `<optgroup>` children from the default slot.\n *\n * @element ore-select\n *\n * @attr {string} label - Label text\n * @attr {string} label-placement - 'inset' | 'outside'\n * @attr {boolean} hide-label - Hide the visible label; the label text is exposed as `aria-label` on the trigger instead\n * @attr {string} value - Current selected value(s) (comma-separated for multiple)\n * @attr {string} placeholder - Placeholder when no option selected\n * @attr {string} name - Form field name\n * @attr {boolean} multiple - Enable multi-select\n * @attr {boolean} disabled - Disable the select\n * @attr {boolean} required - Required field\n * @attr {string} helper - Helper text below the select\n * @attr {string} error - Error message\n * @attr {boolean} success - Show an inline success check icon (suppressed while `error` is set)\n * @attr {string} color - Theme color: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error'\n * @attr {string} variant - Visual variant: 'solid' | 'flat' | 'bordered' | 'outline' | 'ghost' | 'text'\n * @attr {string} size - Component size: 'sm' | 'md' | 'lg'\n * @attr {string} rounded - Border radius: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'\n * @attr {boolean} fullwidth - Expand to full width\n *\n * @fires input - Fired when selection changes.\n * @fires change - Fired when selection changes.\n * @fires open-change - Fired when the dropdown state changes. detail: { open, reason }\n *\n * @slot - `<option>` and `<optgroup>` elements\n *\n * @cssprop --select-bg - Background\n * @cssprop --select-border-color - Border color\n * @cssprop --select-min-width - Minimum width of the select; the trigger floors at it too, so the control never renders wider than its host\n * @cssprop --select-radius - Border radius\n * @cssprop --select-padding - Padding\n * @cssprop --select-font-size - Font size\n * @cssprop --select-placeholder-color - Placeholder text color\n *\n * @part trigger - The `ore-input` trigger element that opens the dropdown.\n * @part dropdown - The dropdown listbox panel container.\n *\n * @example\n * ```html\n * <ore-select label=\"Role\" value=\"admin\">\n * <option value=\"admin\">Administrator</option>\n * <option value=\"editor\">Editor</option>\n * <option value=\"viewer\">Viewer</option>\n * </ore-select>\n *\n * <ore-select label=\"Tags\" multiple color=\"primary\">\n * <optgroup label=\"Frontend\">\n * <option value=\"react\">React</option>\n * <option value=\"vue\">Vue</option>\n * </optgroup>\n * <optgroup label=\"Backend\">\n * <option value=\"node\">Node.js</option>\n * </optgroup>\n * </ore-select>\n * ```\n */\nexport const SELECT_TAG = 'ore-select' as const;\ndefine<OreSelectProps>(SELECT_TAG, {\n formAssociated: true,\n props: {\n ...themableBundle,\n ...sizableBundle,\n ...disablableBundle,\n ...loadableBundle,\n ...roundableBundle,\n error: prop.string(),\n fullwidth: prop.bool(false),\n helper: prop.string(),\n 'hide-label': prop.bool(false),\n label: prop.string(),\n 'label-placement': prop.oneOf(['inset', 'outside'] as const, 'inset'),\n multiple: prop.bool(false),\n name: prop.string(),\n options: prop.json(undefined as OreSelectOptionInput[] | undefined),\n placeholder: prop.string(),\n required: prop.bool(false),\n success: prop.bool(false),\n value: prop.string(),\n variant: prop.string<Exclude<VisualVariant, 'frost'>>(),\n },\n setup(props) {\n const el = getHost();\n const emit = useEmit<OreSelectEvents>();\n const slots = useSlots();\n\n const shadowRoot = el.shadowRoot;\n // ────────────────────────────────────────────────────────────────\n // State & Context\n // ────────────────────────────────────────────────────────────────\n\n const slottedOptions = signal<OptionItem[]>([]);\n const isLoading = computed(() => Boolean(props.loading.value));\n\n // Merged options: explicit prop value overrides slotted options\n function normalizeOption(option: OreSelectOptionInput): OptionItem {\n return {\n disabled: Boolean(option.disabled),\n disabledReason: option.disabledReason,\n group: option.group,\n icons: normalizeIcons(option.icon),\n label: option.label ?? option.value,\n value: option.value,\n };\n }\n\n const options = computed(() => {\n const explicitOptions = props.options.value;\n\n return Array.isArray(explicitOptions) ? explicitOptions.map(normalizeOption) : slottedOptions.value;\n });\n let triggerEl: HTMLElement | null = null;\n let dropdownEl: HTMLElement | null = null;\n\n const abortSignal = lifecycleSignal(onCleanup);\n const choice = createChoiceField({\n disabled: props.disabled,\n error: props.error,\n helper: props.helper,\n label: props.label,\n labelPlacement: props['label-placement'],\n multiple: props.multiple,\n prefix: 'select',\n required: props.required,\n signal: abortSignal,\n value: props.value,\n });\n\n choice.attachFormField(\n useField<string>({\n disabled: choice.disabled,\n onReset: choice.reset,\n toFormValue: (v) => v,\n validationMessage: choice.validationMessage,\n validity: choice.validity,\n value: choice.formValue,\n }),\n );\n\n const optionList = createListboxDropdown<OptionItem>({\n getBoundary: () => el,\n getFocusedOptionElement: () => dropdownEl?.querySelector<HTMLElement>('[data-focused]') ?? null,\n getItems: () => options.value,\n getPanel: () => dropdownEl,\n getReference: () => triggerEl,\n getTrigger: () => triggerEl,\n isDisabled: () => choice.disabled.value,\n isItemDisabled: (option) => option.disabled,\n onClose: (reason) => {\n emit('open-change', { open: false, reason });\n choice.triggerValidation('blur');\n },\n onOpen: (reason) => emit('open-change', { open: true, reason }),\n signal: abortSignal,\n });\n\n const { triggerValidation } = choice;\n const selectedValues = choice.selectedValues;\n const isDisabled = choice.disabled;\n\n defineFieldValue(\n el,\n () => choice.formValue.value,\n (value) => {\n choice.setValues(value ? value.split(',') : []);\n },\n );\n\n const { fieldId: selectId } = choice;\n const listboxId = `listbox-${selectId}`;\n const { focusedIndex, isOpen } = optionList;\n\n // Sync host attributes for CSS hooks\n bind({\n attr: {\n 'has-error': () => (props.error.value ? true : undefined),\n open: () => (isOpen.value ? true : undefined),\n size: props.size,\n variant: props.variant,\n },\n });\n\n // ────────────────────────────────────────────────────────────────\n // Option Reading from Slot\n // ────────────────────────────────────────────────────────────────\n\n function readOptions() {\n const slot = shadowRoot?.querySelector<HTMLSlotElement>('slot');\n\n if (!slot) return;\n\n const assigned = slot.assignedElements({ flatten: true });\n const items: OptionItem[] = [];\n\n for (const el of assigned) {\n if (el.tagName === 'OPTION') {\n const opt = el as HTMLOptionElement;\n\n items.push({\n disabled: opt.disabled,\n disabledReason: opt.dataset.disabledReason,\n icons: normalizeIcons(opt.dataset.icon),\n label: opt.text || opt.value,\n value: opt.value,\n });\n } else if (el.tagName === 'OPTGROUP') {\n const group = el as HTMLOptGroupElement;\n const groupLabel = group.label;\n\n for (const child of Array.from(group.querySelectorAll('option'))) {\n const opt = child as HTMLOptionElement;\n\n items.push({\n disabled: opt.disabled,\n disabledReason: opt.dataset.disabledReason,\n group: groupLabel,\n icons: normalizeIcons(opt.dataset.icon),\n label: opt.text || opt.value,\n value: opt.value,\n });\n }\n }\n }\n\n slottedOptions.value = items;\n }\n\n const displayLabel = computed(() => {\n if (selectedValues.value.length === 0) return '';\n\n if (props.multiple.value && selectedValues.value.length > 1) {\n return `${selectedValues.value.length} selected`;\n }\n\n const first = selectedValues.value[0];\n\n return options.value.find((o) => o.value === first)?.label ?? first;\n });\n const selectedIcons = computed(() => {\n if (props.multiple.value || selectedValues.value.length === 0) return undefined;\n const first = selectedValues.value[0];\n\n return options.value.find((o) => o.value === first)?.icons;\n });\n const selectedChipItems = computed(() => {\n if (!props.multiple.value) return [];\n\n return selectedValues.value.map((value) => ({\n label: options.value.find((o) => o.value === value)?.label ?? value,\n value,\n }));\n });\n const showChips = computed(() => props.multiple.value && selectedValues.value.length > 0);\n const triggerText = computed(() => displayLabel.value || props.placeholder.value || '');\n\n function buildFlatList(opts: OptionItem[]): FlatRow[] {\n const flat: FlatRow[] = [];\n const groups = new Map<string | undefined, OptionItem[]>();\n\n for (const opt of opts) {\n const key = opt.group;\n\n let group = groups.get(key);\n\n if (!group) {\n group = [];\n groups.set(key, group);\n }\n\n group.push(opt);\n }\n\n let globalIdx = 0;\n\n for (const [groupLabel, groupOpts] of groups) {\n if (groupLabel !== undefined) flat.push({ label: groupLabel, type: 'group' });\n\n for (const opt of groupOpts) flat.push({ idx: globalIdx++, opt, type: 'option' });\n }\n\n return flat;\n }\n\n const flatRows = computed(() => buildFlatList(options.value));\n\n function emitChange(): void {\n setFieldValue(el, choice.formValue.value);\n dispatchNativeFieldEvent(el, 'input');\n dispatchNativeFieldEvent(el, 'change');\n }\n\n function removeChip(event: Event): void {\n event.stopPropagation();\n\n const value = (event as CustomEvent<{ value?: string }>).detail?.value;\n\n if (value === undefined) return;\n\n choice.removeValue(value);\n emitChange();\n triggerValidation('change');\n }\n\n function openPopup(reason: OverlayOpenReason = 'programmatic') {\n // Show the popover before positioning so the positioner measures the element in the top\n // layer, not inside a possible ancestor containing block (a transformed dialog panel).\n if (dropdownEl && 'showPopover' in dropdownEl && !dropdownEl.matches(':popover-open')) dropdownEl.showPopover();\n optionList.open(reason);\n\n requestAnimationFrame(() => {\n const selectedIndex =\n selectedValues.value.length > 0\n ? options.value.findIndex((option) => option.value === selectedValues.value[0])\n : -1;\n\n if (selectedIndex >= 0) {\n optionList.set(selectedIndex);\n\n return;\n }\n\n optionList.navigate('first');\n });\n }\n\n // Selection\n\n function selectOption(opt: OptionItem, _e?: Event) {\n if (opt.disabled) return;\n\n if (props.multiple.value) {\n choice.toggleValue(opt.value);\n } else {\n choice.selectValue(opt.value);\n optionList.close();\n }\n\n emitChange();\n triggerValidation('change');\n }\n\n // Keyboard navigation\n\n function handleTriggerKeydown(e: KeyboardEvent) {\n if (isDisabled.value) return;\n\n // Let optionList handle arrow key navigation\n if (optionList.handleKeydown(e)) return;\n\n switch (e.key) {\n case ' ':\n case 'Enter':\n e.preventDefault();\n\n if (isOpen.value) {\n const idx = focusedIndex.value;\n const opts = options.value;\n\n if (idx >= 0 && idx < opts.length) selectOption(opts[idx], e);\n } else {\n openPopup('keyboard');\n }\n\n break;\n case 'Tab':\n optionList.close();\n break;\n }\n }\n\n // ore-input prop helpers\n const inputValue = () => triggerText.value;\n const hideLabel = () => props['hide-label'].value;\n // When hide-label is set, suppress the visible label passed to ore-input (no inset\n // label renders, avoiding extra trigger height) but expose the label text as\n // aria-label on the trigger so the combobox retains its accessible name.\n const inputLabel = () => (hideLabel() ? '' : (props.label.value ?? ''));\n const triggerAriaLabel = () => (hideLabel() ? (props.label.value ?? '') : null);\n const inputPlaceholder = () => props.placeholder.value ?? '';\n const inputLabelPlacement = () => props['label-placement'].value ?? 'inset';\n const inputColor = () => props.color?.value ?? undefined;\n const inputSize = () => props.size?.value ?? undefined;\n const inputVariant = () => props.variant?.value ?? undefined;\n const inputRounded = () => props.rounded?.value ?? undefined;\n const inputHelper = () => props.helper.value ?? '';\n const inputError = () => props.error.value ?? '';\n const inputDisabled = () => (isDisabled.value ? true : undefined);\n const inputRequired = () => (props.required.value ? true : undefined);\n const inputFullwidth = () => (props.fullwidth.value ? true : undefined);\n const tabIndexAttr = () => (isDisabled.value ? '-1' : '0');\n\n watch(slots.elements(), () => readOptions(), { immediate: true });\n\n const stopPopoverSync = effect(() => {\n if (isOpen.value) {\n if (dropdownEl && 'showPopover' in dropdownEl && !dropdownEl.matches(':popover-open')) dropdownEl.showPopover();\n } else {\n if (dropdownEl && 'hidePopover' in dropdownEl && dropdownEl.matches(':popover-open')) dropdownEl.hidePopover();\n }\n });\n\n onCleanup(() => stopPopoverSync.dispose());\n\n onMounted(() => {\n let onTriggerClick: ((event: MouseEvent) => void) | null = null;\n let onTriggerKeydown: ((event: KeyboardEvent) => void) | null = null;\n\n if (triggerEl) {\n onTriggerClick = (event: MouseEvent) => {\n event.stopPropagation();\n\n if (isDisabled.value) return;\n\n if (isOpen.value) optionList.close('trigger');\n else openPopup('click');\n };\n onTriggerKeydown = (event: KeyboardEvent) => {\n handleTriggerKeydown(event);\n };\n\n triggerEl.addEventListener('click', onTriggerClick);\n triggerEl.addEventListener('keydown', onTriggerKeydown);\n }\n\n return () => {\n if (triggerEl && onTriggerClick) triggerEl.removeEventListener('click', onTriggerClick);\n\n if (triggerEl && onTriggerKeydown) triggerEl.removeEventListener('keydown', onTriggerKeydown);\n };\n });\n\n return html`\n <slot style=\"display:none\"></slot>\n <ore-input\n class=\"trigger\"\n part=\"trigger\"\n readonly\n tabindex=\"${tabIndexAttr}\"\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n aria-controls=\"${listboxId}\"\n aria-label=\"${triggerAriaLabel}\"\n aria-disabled=\"${() => (isDisabled.value ? 'true' : null)}\"\n aria-expanded=\"${() => String(isOpen.value)}\"\n aria-invalid=\"${() => (props.error.value ? 'true' : null)}\"\n value=\"${inputValue}\"\n label=\"${inputLabel}\"\n placeholder=\"${inputPlaceholder}\"\n label-placement=\"${inputLabelPlacement}\"\n color=\"${inputColor}\"\n size=\"${inputSize}\"\n variant=\"${inputVariant}\"\n rounded=\"${inputRounded}\"\n helper=\"${inputHelper}\"\n error=\"${inputError}\"\n ?disabled=\"${inputDisabled}\"\n ?required=\"${inputRequired}\"\n ?fullwidth=\"${inputFullwidth}\"\n ?success=\"${() => props.success.value}\"\n ref=\"${(el: HTMLElement) => {\n triggerEl = el;\n }}\">\n ${() => {\n const icons = selectedIcons.value;\n\n if (!icons?.length) return html``;\n\n return html`<span class=\"trigger-selected-icons\" slot=\"prefix\">\n ${icons.map((icon) =>\n isIconImage(icon)\n ? html`<img alt=\"\" aria-hidden=\"true\" class=\"trigger-selected-icon--image\" src=\"${icon}\" />`\n : html`<ore-icon aria-hidden=\"true\" class=\"trigger-selected-icon\" name=\"${icon}\" size=\"14\"></ore-icon>`,\n )}\n </span>`;\n }}\n <div slot=\"prefix\" class=\"chips-row\" ?hidden=\"${() => !showChips.value}\">\n ${() =>\n selectedChipItems.value.map(\n (item) => html`\n <ore-chip\n value=\"${item.value}\"\n label=\"${item.label}\"\n mode=\"removable\"\n variant=\"flat\"\n size=\"sm\"\n color=\"${props.color}\"\n @remove=\"${removeChip}\">\n ${item.label}\n </ore-chip>\n `,\n )}\n </div>\n <span slot=\"suffix\" class=\"trigger-suffix\" aria-hidden=\"true\">\n <span class=\"loader\"></span>\n <span class=\"trigger-icon\">\n <ore-icon name=\"chevron-down\" size=\"14\" stroke-width=\"2\" aria-hidden=\"true\"></ore-icon>\n </span>\n </span>\n </ore-input>\n <div\n class=\"dropdown\"\n part=\"dropdown\"\n popover=\"manual\"\n ?data-open=\"${isOpen}\"\n role=\"listbox\"\n id=\"${listboxId}\"\n aria-label=\"Options\"\n ref=\"${(el: HTMLElement) => {\n dropdownEl = el;\n }}\">\n <div class=\"dropdown-loading\" ?hidden=\"${() => !isLoading.value}\">Loading…</div>\n <div class=\"dropdown-empty\" ?hidden=\"${() => isLoading.value || options.value.length > 0}\">No options</div>\n <div class=\"options-list\" ?hidden=\"${() => isLoading.value || options.value.length === 0}\">\n ${() =>\n flatRows.value.map((row) =>\n row.type === 'group'\n ? html`\n <div class=\"optgroup-label\" role=\"presentation\">${row.label}</div>\n `\n : html`\n <div\n class=\"option\"\n role=\"option\"\n id=\"${`${selectId}-opt-${row.idx}`}\"\n data-option-index=\"${String(row.idx)}\"\n data-option-value=\"${row.opt.value}\"\n aria-selected=\"${() => String(selectedValues.value.includes(row.opt.value))}\"\n aria-disabled=\"${() => String(row.opt.disabled)}\"\n ?data-focused=\"${() => focusedIndex.value === row.idx}\"\n ?data-selected=\"${() => selectedValues.value.includes(row.opt.value)}\"\n ?data-disabled=\"${() => row.opt.disabled}\"\n @click=\"${(e: MouseEvent) => {\n e.stopPropagation();\n selectOption(row.opt, e);\n }}\"\n @pointerenter=\"${() => {\n optionList.set(row.idx);\n }}\">\n ${\n row.opt.icons?.length\n ? html`<span class=\"option-icons\" aria-hidden=\"true\">\n ${row.opt.icons.map((icon) =>\n isIconImage(icon)\n ? html`<img alt=\"\" class=\"option-icon option-icon--image\" src=\"${icon}\" />`\n : html`<ore-icon class=\"option-icon\" name=\"${icon}\" size=\"14\"></ore-icon>`,\n )}\n </span>`\n : html``\n }\n <span>${row.opt.label}</span>\n ${\n row.opt.disabled && row.opt.disabledReason\n ? html`<small class=\"disabled-reason\" title=\"${row.opt.disabledReason}\">${row.opt.disabledReason}</small>`\n : html``\n }\n <span class=\"option-check\" aria-hidden=\"true\">\n <ore-icon name=\"check\" size=\"14\" stroke-width=\"2.5\" aria-hidden=\"true\"></ore-icon>\n </span>\n </div>\n `,\n )}\n </div>\n </div>\n `;\n },\n shadow: { delegatesFocus: true },\n styles: [colorThemeMixin, reducedMotionMixin, roundedVariantMixin, componentStyles],\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"select.js","names":[],"sources":["../src/inputs/select/select.ts"],"sourcesContent":["import { bind, define, getHost, html, onCleanup, onMounted, prop, useEmit, useField, useSlots } from '@vielzeug/ore';\nimport { computed, effect, signal, watch } from '@vielzeug/ripple';\n\nimport type { OverlayOpenChangeDetail, OverlayOpenReason } from '../../core';\nimport { createChoiceField, createListboxDropdown, lifecycleSignal } from '../../core';\nimport type { SelectableFieldProps } from '../../shared';\nimport { disablableBundle, loadableBundle, roundableBundle, sizableBundle, themableBundle } from '../../shared';\nimport { colorThemeMixin, reducedMotionMixin, roundedVariantMixin } from '../../styles';\nimport { INPUT_VARIANTS, type InputVariant } from '../../types';\nimport { defineFieldValue, dispatchNativeFieldEvent, setFieldValue } from '../shared/native-field-event';\nimport componentStyles from './select.css?inline';\n\nexport { ICON_TAG } from '../../content/icon/icon';\nexport { CHIP_TAG } from '../../feedback/chip/chip';\nexport { INPUT_TAG } from '../input/input';\n\n// ── Types ─────────────────────────────────────────────────────────────\n\ntype OptionItem = {\n disabled: boolean;\n disabledReason?: string;\n group?: string;\n icons?: string[];\n label: string;\n value: string;\n};\n\nexport type OreSelectOptionInput = {\n disabled?: boolean;\n /** Explanation displayed and announced when the option is disabled. */\n disabledReason?: string;\n group?: string;\n /** Icon(s) rendered before the option label: lucide name(s) or image URL(s). */\n icon?: string | string[];\n label?: string;\n value: string;\n};\n\ntype FlatRow =\n | {\n idx: number;\n opt: OptionItem;\n type: 'option';\n }\n | {\n label: string;\n type: 'group';\n };\n\n/**\n * Icon sources containing a path separator or a `data:` scheme are treated as image URLs and\n * rendered as `<img>`; anything else is a lucide icon name rendered via `ore-icon`.\n */\nconst isIconImage = (icon: string): boolean => icon.includes('/') || icon.startsWith('data:');\n\n/** Normalizes an icon value: single name/URL, space-separated list, or array: to icon entries. */\nconst normalizeIcons = (icon: string | string[] | undefined): string[] | undefined => {\n const list = Array.isArray(icon) ? icon : icon?.split(' ');\n const icons = list?.map((entry) => entry.trim()).filter(Boolean);\n return icons?.length ? icons : undefined;\n};\n\n// ── Styles ─────────────────────────────────────────────────────────────\n\n// ── Component Props ─────────────────────────────────────────────────────────────\n\n/** Select component properties */\n\nexport type OreSelectEvents = {\n change: Event;\n input: Event;\n 'open-change': OverlayOpenChangeDetail;\n};\n\nexport type OreSelectProps = SelectableFieldProps<InputVariant> & {\n /** Hide the visible label while preserving the accessible name via `aria-label` */\n 'hide-label'?: boolean;\n /** Show loading state in dropdown */\n loading?: boolean;\n /** Allow selecting multiple options */\n multiple?: boolean;\n /** JS options array (alternative to slotted <option> elements) */\n options?: OreSelectOptionInput[];\n /** Mark the field as required */\n required?: boolean;\n};\n\n/**\n * A fully custom form-associated select dropdown with keyboard navigation and ARIA support.\n * Reads `<option>` and `<optgroup>` children from the default slot.\n *\n * @element ore-select\n *\n * @attr {string} label - Label text\n * @attr {string} label-placement - 'inset' | 'outside'\n * @attr {boolean} hide-label - Hide the visible label; the label text is exposed as `aria-label` on the trigger instead\n * @attr {string} value - Current selected value(s) (comma-separated for multiple)\n * @attr {string} placeholder - Placeholder when no option selected\n * @attr {string} name - Form field name\n * @attr {boolean} multiple - Enable multi-select\n * @attr {boolean} disabled - Disable the select\n * @attr {boolean} required - Required field\n * @attr {string} helper - Helper text below the select\n * @attr {string} error - Error message\n * @attr {boolean} success - Show an inline success check icon (suppressed while `error` is set)\n * @attr {string} color - Theme color: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error'\n * @attr {string} variant - Visual variant: 'solid' | 'flat' | 'bordered' | 'outline' | 'ghost' | 'text'\n * @attr {string} size - Component size: 'sm' | 'md' | 'lg'\n * @attr {string} rounded - Border radius: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'\n * @attr {boolean} fullwidth - Expand to full width\n *\n * @fires input - Fired when selection changes.\n * @fires change - Fired when selection changes.\n * @fires open-change - Fired when the dropdown state changes. detail: { open, reason }\n *\n * @slot - `<option>` and `<optgroup>` elements\n *\n * @cssprop --select-bg - Background\n * @cssprop --select-border-color - Border color\n * @cssprop --select-min-width - Minimum width of the select; the trigger floors at it too, so the control never renders wider than its host\n * @cssprop --select-radius - Border radius\n * @cssprop --select-padding - Padding\n * @cssprop --select-font-size - Font size\n * @cssprop --select-placeholder-color - Placeholder text color\n *\n * @part trigger - The `ore-input` trigger element that opens the dropdown.\n * @part dropdown - The dropdown listbox panel container.\n *\n * @example\n * ```html\n * <ore-select label=\"Role\" value=\"admin\">\n * <option value=\"admin\">Administrator</option>\n * <option value=\"editor\">Editor</option>\n * <option value=\"viewer\">Viewer</option>\n * </ore-select>\n *\n * <ore-select label=\"Tags\" multiple color=\"primary\">\n * <optgroup label=\"Frontend\">\n * <option value=\"react\">React</option>\n * <option value=\"vue\">Vue</option>\n * </optgroup>\n * <optgroup label=\"Backend\">\n * <option value=\"node\">Node.js</option>\n * </optgroup>\n * </ore-select>\n * ```\n */\nexport const SELECT_TAG = 'ore-select' as const;\ndefine<OreSelectProps>(SELECT_TAG, {\n formAssociated: true,\n props: {\n ...themableBundle,\n ...sizableBundle,\n ...disablableBundle,\n ...loadableBundle,\n ...roundableBundle,\n error: prop.string(),\n fullwidth: prop.bool(false),\n helper: prop.string(),\n 'hide-label': prop.bool(false),\n label: prop.string(),\n 'label-placement': prop.oneOf(['inset', 'outside'] as const, 'inset'),\n multiple: prop.bool(false),\n name: prop.string(),\n options: prop.json(undefined as OreSelectOptionInput[] | undefined),\n placeholder: prop.string(),\n required: prop.bool(false),\n success: prop.bool(false),\n value: prop.string(),\n variant: prop.oneOf(INPUT_VARIANTS),\n },\n setup(props) {\n const el = getHost();\n const emit = useEmit<OreSelectEvents>();\n const slots = useSlots();\n\n const shadowRoot = el.shadowRoot;\n // ────────────────────────────────────────────────────────────────\n // State & Context\n // ────────────────────────────────────────────────────────────────\n\n const slottedOptions = signal<OptionItem[]>([]);\n const isLoading = computed(() => Boolean(props.loading.value));\n\n // Merged options: explicit prop value overrides slotted options\n function normalizeOption(option: OreSelectOptionInput): OptionItem {\n return {\n disabled: Boolean(option.disabled),\n disabledReason: option.disabledReason,\n group: option.group,\n icons: normalizeIcons(option.icon),\n label: option.label ?? option.value,\n value: option.value,\n };\n }\n\n const options = computed(() => {\n const explicitOptions = props.options.value;\n\n return Array.isArray(explicitOptions) ? explicitOptions.map(normalizeOption) : slottedOptions.value;\n });\n let triggerEl: HTMLElement | null = null;\n let dropdownEl: HTMLElement | null = null;\n\n const abortSignal = lifecycleSignal(onCleanup);\n const choice = createChoiceField({\n disabled: props.disabled,\n error: props.error,\n helper: props.helper,\n label: props.label,\n labelPlacement: props['label-placement'],\n multiple: props.multiple,\n prefix: 'select',\n required: props.required,\n signal: abortSignal,\n value: props.value,\n });\n\n choice.attachFormField(\n useField<string>({\n disabled: choice.disabled,\n onReset: choice.reset,\n toFormValue: (v) => v,\n validity: choice.validity,\n value: choice.formValue,\n }),\n );\n\n const optionList = createListboxDropdown<OptionItem>({\n getBoundary: () => el,\n getFocusedOptionElement: () => dropdownEl?.querySelector<HTMLElement>('[data-focused]') ?? null,\n getItems: () => options.value,\n getPanel: () => dropdownEl,\n getReference: () => triggerEl,\n getTrigger: () => triggerEl,\n isDisabled: () => choice.disabled.value,\n isItemDisabled: (option) => option.disabled,\n onClose: (reason) => {\n emit('open-change', { open: false, reason });\n choice.triggerValidation('blur');\n },\n onOpen: (reason) => emit('open-change', { open: true, reason }),\n signal: abortSignal,\n });\n\n const { triggerValidation } = choice;\n const selectedValues = choice.selectedValues;\n const isDisabled = choice.disabled;\n\n defineFieldValue(\n el,\n () => choice.formValue.value,\n (value) => {\n choice.setValues(value ? value.split(',') : []);\n },\n );\n\n const { fieldId: selectId } = choice;\n const listboxId = `listbox-${selectId}`;\n const { focusedIndex, isOpen } = optionList;\n\n // Sync host attributes for CSS hooks\n bind({\n attr: {\n 'has-error': () => (props.error.value ? true : undefined),\n open: () => (isOpen.value ? true : undefined),\n size: props.size,\n variant: props.variant,\n },\n });\n\n // ────────────────────────────────────────────────────────────────\n // Option Reading from Slot\n // ────────────────────────────────────────────────────────────────\n\n function readOptions() {\n const slot = shadowRoot?.querySelector<HTMLSlotElement>('slot');\n\n if (!slot) return;\n\n const assigned = slot.assignedElements({ flatten: true });\n const items: OptionItem[] = [];\n\n for (const el of assigned) {\n if (el.tagName === 'OPTION') {\n const opt = el as HTMLOptionElement;\n\n items.push({\n disabled: opt.disabled,\n disabledReason: opt.dataset.disabledReason,\n icons: normalizeIcons(opt.dataset.icon),\n label: opt.text || opt.value,\n value: opt.value,\n });\n } else if (el.tagName === 'OPTGROUP') {\n const group = el as HTMLOptGroupElement;\n const groupLabel = group.label;\n\n for (const child of Array.from(group.querySelectorAll('option'))) {\n const opt = child as HTMLOptionElement;\n\n items.push({\n disabled: opt.disabled,\n disabledReason: opt.dataset.disabledReason,\n group: groupLabel,\n icons: normalizeIcons(opt.dataset.icon),\n label: opt.text || opt.value,\n value: opt.value,\n });\n }\n }\n }\n\n slottedOptions.value = items;\n }\n\n const displayLabel = computed(() => {\n if (selectedValues.value.length === 0) return '';\n\n if (props.multiple.value && selectedValues.value.length > 1) {\n return `${selectedValues.value.length} selected`;\n }\n\n const first = selectedValues.value[0];\n\n return options.value.find((o) => o.value === first)?.label ?? first;\n });\n const selectedIcons = computed(() => {\n if (props.multiple.value || selectedValues.value.length === 0) return undefined;\n const first = selectedValues.value[0];\n\n return options.value.find((o) => o.value === first)?.icons;\n });\n const selectedChipItems = computed(() => {\n if (!props.multiple.value) return [];\n\n return selectedValues.value.map((value) => ({\n label: options.value.find((o) => o.value === value)?.label ?? value,\n value,\n }));\n });\n const showChips = computed(() => props.multiple.value && selectedValues.value.length > 0);\n const triggerText = computed(() => displayLabel.value || props.placeholder.value || '');\n\n function buildFlatList(opts: OptionItem[]): FlatRow[] {\n const flat: FlatRow[] = [];\n const groups = new Map<string | undefined, OptionItem[]>();\n\n for (const opt of opts) {\n const key = opt.group;\n\n let group = groups.get(key);\n\n if (!group) {\n group = [];\n groups.set(key, group);\n }\n\n group.push(opt);\n }\n\n let globalIdx = 0;\n\n for (const [groupLabel, groupOpts] of groups) {\n if (groupLabel !== undefined) flat.push({ label: groupLabel, type: 'group' });\n\n for (const opt of groupOpts) flat.push({ idx: globalIdx++, opt, type: 'option' });\n }\n\n return flat;\n }\n\n const flatRows = computed(() => buildFlatList(options.value));\n\n function emitChange(): void {\n setFieldValue(el, choice.formValue.value);\n dispatchNativeFieldEvent(el, 'input');\n dispatchNativeFieldEvent(el, 'change');\n }\n\n function removeChip(event: Event): void {\n event.stopPropagation();\n\n const value = (event as CustomEvent<{ value?: string }>).detail?.value;\n\n if (value === undefined) return;\n\n choice.removeValue(value);\n emitChange();\n triggerValidation('change');\n }\n\n function openPopup(reason: OverlayOpenReason = 'programmatic') {\n // Show the popover before positioning so the positioner measures the element in the top\n // layer, not inside a possible ancestor containing block (a transformed dialog panel).\n if (dropdownEl && 'showPopover' in dropdownEl && !dropdownEl.matches(':popover-open')) dropdownEl.showPopover();\n optionList.open(reason);\n\n requestAnimationFrame(() => {\n const selectedIndex =\n selectedValues.value.length > 0\n ? options.value.findIndex((option) => option.value === selectedValues.value[0])\n : -1;\n\n if (selectedIndex >= 0) {\n optionList.set(selectedIndex);\n\n return;\n }\n\n optionList.navigate('first');\n });\n }\n\n // Selection\n\n function selectOption(opt: OptionItem, _e?: Event) {\n if (opt.disabled) return;\n\n if (props.multiple.value) {\n choice.toggleValue(opt.value);\n } else {\n choice.selectValue(opt.value);\n optionList.close();\n }\n\n emitChange();\n triggerValidation('change');\n }\n\n // Keyboard navigation\n\n function handleTriggerKeydown(e: KeyboardEvent) {\n if (isDisabled.value) return;\n\n // Let optionList handle arrow key navigation\n if (optionList.handleKeydown(e)) return;\n\n switch (e.key) {\n case ' ':\n case 'Enter':\n e.preventDefault();\n\n if (isOpen.value) {\n const idx = focusedIndex.value;\n const opts = options.value;\n\n if (idx >= 0 && idx < opts.length) selectOption(opts[idx], e);\n } else {\n openPopup('keyboard');\n }\n\n break;\n case 'Tab':\n optionList.close();\n break;\n }\n }\n\n // ore-input prop helpers\n const inputValue = () => triggerText.value;\n const hideLabel = () => props['hide-label'].value;\n // When hide-label is set, suppress the visible label passed to ore-input (no inset\n // label renders, avoiding extra trigger height) but expose the label text as\n // aria-label on the trigger so the combobox retains its accessible name.\n const inputLabel = () => (hideLabel() ? '' : (props.label.value ?? ''));\n const triggerAriaLabel = () => (hideLabel() ? (props.label.value ?? '') : null);\n const inputPlaceholder = () => props.placeholder.value ?? '';\n const inputLabelPlacement = () => props['label-placement'].value ?? 'inset';\n const inputColor = () => props.color?.value ?? undefined;\n const inputSize = () => props.size?.value ?? undefined;\n const inputVariant = () => props.variant?.value ?? undefined;\n const inputRounded = () => props.rounded?.value ?? undefined;\n const inputHelper = () => props.helper.value ?? '';\n const inputError = () => props.error.value ?? '';\n const inputDisabled = () => (isDisabled.value ? true : undefined);\n const inputRequired = () => (props.required.value ? true : undefined);\n const inputFullwidth = () => (props.fullwidth.value ? true : undefined);\n const tabIndexAttr = () => (isDisabled.value ? '-1' : '0');\n\n watch(slots.elements(), () => readOptions(), { immediate: true });\n\n const stopPopoverSync = effect(() => {\n if (isOpen.value) {\n if (dropdownEl && 'showPopover' in dropdownEl && !dropdownEl.matches(':popover-open')) dropdownEl.showPopover();\n } else {\n if (dropdownEl && 'hidePopover' in dropdownEl && dropdownEl.matches(':popover-open')) dropdownEl.hidePopover();\n }\n });\n\n onCleanup(() => stopPopoverSync.dispose());\n\n onMounted(() => {\n let onTriggerClick: ((event: MouseEvent) => void) | null = null;\n let onTriggerKeydown: ((event: KeyboardEvent) => void) | null = null;\n\n if (triggerEl) {\n onTriggerClick = (event: MouseEvent) => {\n event.stopPropagation();\n\n if (isDisabled.value) return;\n\n if (isOpen.value) optionList.close('trigger');\n else openPopup('click');\n };\n onTriggerKeydown = (event: KeyboardEvent) => {\n handleTriggerKeydown(event);\n };\n\n triggerEl.addEventListener('click', onTriggerClick);\n triggerEl.addEventListener('keydown', onTriggerKeydown);\n }\n\n return () => {\n if (triggerEl && onTriggerClick) triggerEl.removeEventListener('click', onTriggerClick);\n\n if (triggerEl && onTriggerKeydown) triggerEl.removeEventListener('keydown', onTriggerKeydown);\n };\n });\n\n return html`\n <slot style=\"display:none\"></slot>\n <ore-input\n class=\"trigger\"\n part=\"trigger\"\n readonly\n tabindex=\"${tabIndexAttr}\"\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n aria-controls=\"${listboxId}\"\n aria-label=\"${triggerAriaLabel}\"\n aria-disabled=\"${() => (isDisabled.value ? 'true' : null)}\"\n aria-expanded=\"${() => String(isOpen.value)}\"\n aria-invalid=\"${() => (props.error.value ? 'true' : null)}\"\n value=\"${inputValue}\"\n label=\"${inputLabel}\"\n placeholder=\"${inputPlaceholder}\"\n label-placement=\"${inputLabelPlacement}\"\n color=\"${inputColor}\"\n size=\"${inputSize}\"\n variant=\"${inputVariant}\"\n rounded=\"${inputRounded}\"\n helper=\"${inputHelper}\"\n error=\"${inputError}\"\n ?disabled=\"${inputDisabled}\"\n ?required=\"${inputRequired}\"\n ?fullwidth=\"${inputFullwidth}\"\n ?success=\"${() => props.success.value}\"\n ref=\"${(el: HTMLElement) => {\n triggerEl = el;\n }}\">\n ${() => {\n const icons = selectedIcons.value;\n\n if (!icons?.length) return html``;\n\n return html`<span class=\"trigger-selected-icons\" slot=\"prefix\">\n ${icons.map((icon) =>\n isIconImage(icon)\n ? html`<img alt=\"\" aria-hidden=\"true\" class=\"trigger-selected-icon--image\" src=\"${icon}\" />`\n : html`<ore-icon aria-hidden=\"true\" class=\"trigger-selected-icon\" name=\"${icon}\" size=\"14\"></ore-icon>`,\n )}\n </span>`;\n }}\n <div slot=\"prefix\" class=\"chips-row\" ?hidden=\"${() => !showChips.value}\">\n ${() =>\n selectedChipItems.value.map(\n (item) => html`\n <ore-chip\n value=\"${item.value}\"\n label=\"${item.label}\"\n mode=\"removable\"\n variant=\"flat\"\n size=\"sm\"\n color=\"${props.color}\"\n @remove=\"${removeChip}\">\n ${item.label}\n </ore-chip>\n `,\n )}\n </div>\n <span slot=\"suffix\" class=\"trigger-suffix\" aria-hidden=\"true\">\n <span class=\"loader\"></span>\n <span class=\"trigger-icon\">\n <ore-icon name=\"chevron-down\" size=\"14\" stroke-width=\"2\" aria-hidden=\"true\"></ore-icon>\n </span>\n </span>\n </ore-input>\n <div\n class=\"dropdown\"\n part=\"dropdown\"\n popover=\"manual\"\n ?data-open=\"${isOpen}\"\n role=\"listbox\"\n id=\"${listboxId}\"\n aria-label=\"Options\"\n ref=\"${(el: HTMLElement) => {\n dropdownEl = el;\n }}\">\n <div class=\"dropdown-loading\" ?hidden=\"${() => !isLoading.value}\">Loading…</div>\n <div class=\"dropdown-empty\" ?hidden=\"${() => isLoading.value || options.value.length > 0}\">No options</div>\n <div class=\"options-list\" ?hidden=\"${() => isLoading.value || options.value.length === 0}\">\n ${() =>\n flatRows.value.map((row) =>\n row.type === 'group'\n ? html`\n <div class=\"optgroup-label\" role=\"presentation\">${row.label}</div>\n `\n : html`\n <div\n class=\"option\"\n role=\"option\"\n id=\"${`${selectId}-opt-${row.idx}`}\"\n data-option-index=\"${String(row.idx)}\"\n data-option-value=\"${row.opt.value}\"\n aria-selected=\"${() => String(selectedValues.value.includes(row.opt.value))}\"\n aria-disabled=\"${() => String(row.opt.disabled)}\"\n ?data-focused=\"${() => focusedIndex.value === row.idx}\"\n ?data-selected=\"${() => selectedValues.value.includes(row.opt.value)}\"\n ?data-disabled=\"${() => row.opt.disabled}\"\n @click=\"${(e: MouseEvent) => {\n e.stopPropagation();\n selectOption(row.opt, e);\n }}\"\n @pointerenter=\"${() => {\n optionList.set(row.idx);\n }}\">\n ${\n row.opt.icons?.length\n ? html`<span class=\"option-icons\" aria-hidden=\"true\">\n ${row.opt.icons.map((icon) =>\n isIconImage(icon)\n ? html`<img alt=\"\" class=\"option-icon option-icon--image\" src=\"${icon}\" />`\n : html`<ore-icon class=\"option-icon\" name=\"${icon}\" size=\"14\"></ore-icon>`,\n )}\n </span>`\n : html``\n }\n <span>${row.opt.label}</span>\n ${\n row.opt.disabled && row.opt.disabledReason\n ? html`<small class=\"disabled-reason\" title=\"${row.opt.disabledReason}\">${row.opt.disabledReason}</small>`\n : html``\n }\n <span class=\"option-check\" aria-hidden=\"true\">\n <ore-icon name=\"check\" size=\"14\" stroke-width=\"2.5\" aria-hidden=\"true\"></ore-icon>\n </span>\n </div>\n `,\n )}\n </div>\n </div>\n `;\n },\n shadow: { delegatesFocus: true },\n styles: [colorThemeMixin, reducedMotionMixin, roundedVariantMixin, componentStyles],\n});\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./styles/mixins/theme.css.cjs"),t=require("./content/separator/separator.css.cjs");let n=require("@vielzeug/ore");var r=`ore-separator`;(0,n.define)(r,{props:{color:n.prop.string(),decorative:n.prop.bool(!0),label:n.prop.string(),orientation:n.prop.oneOf([`horizontal`,`vertical`],`horizontal`)},setup(e){let roleAttr=()=>e.decorative.value?`none`:`separator`,ariaHidden=()=>e.decorative.value?`true`:null;return n.html`
2
- ${()=>e.label.value?n.html`
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./styles/mixins/theme.css.cjs"),t=require("./shared/types.cjs"),n=require("./content/separator/separator.css.cjs");let r=require("@vielzeug/ore");var i=`ore-separator`;(0,r.define)(i,{props:{color:r.prop.oneOf(t.THEME_COLORS),decorative:r.prop.bool(!0),label:r.prop.string(),orientation:r.prop.oneOf([`horizontal`,`vertical`],`horizontal`)},setup(e){let roleAttr=()=>e.decorative.value?`none`:`separator`,ariaHidden=()=>e.decorative.value?`true`:null;return r.html`
2
+ ${()=>e.label.value?r.html`
3
3
  <div class="separator-wrapper" part="wrapper">
4
4
  <hr
5
5
  class="separator"
@@ -15,7 +15,7 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=requi
15
15
  aria-hidden="${ariaHidden}"
16
16
  aria-orientation="${()=>e.orientation.value}" />
17
17
  </div>
18
- `:n.html`
18
+ `:r.html`
19
19
  <hr
20
20
  class="separator"
21
21
  part="separator"
@@ -23,5 +23,5 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=requi
23
23
  aria-hidden="${ariaHidden}"
24
24
  aria-orientation="${()=>e.orientation.value}" />
25
25
  `}
26
- `},styles:[e.colorThemeMixin,t.default]}),exports.SEPARATOR_TAG=r;
26
+ `},styles:[e.colorThemeMixin,n.default]}),exports.SEPARATOR_TAG=i;
27
27
  //# sourceMappingURL=separator.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"separator.cjs","names":[],"sources":["../src/content/separator/separator.ts"],"sourcesContent":["import { define, html, prop } from '@vielzeug/ore';\nimport { colorThemeMixin } from '../../styles';\nimport type { ThemeColor } from '../../types';\nimport componentStyles from './separator.css?inline';\n\n/** Separator component properties */\nexport type OreSeparatorProps = {\n /** Theme color tint */\n color?: ThemeColor;\n /** Decorative only (default true): set to false for semantic separators */\n decorative?: boolean;\n /** Optional label text centered on the separator */\n label?: string;\n /** Orientation of the separator */\n orientation?: 'horizontal' | 'vertical';\n};\n\n/**\n * A simple visual divider between sections of content.\n *\n * @element ore-separator\n *\n * @attr {string} orientation - 'horizontal' (default) | 'vertical'\n * @attr {boolean} decorative - When true (default), aria-hidden is applied\n * @attr {string} label - Optional centered label text\n * @attr {string} color - Theme color: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error'\n *\n * @cssprop --separator-color - Line color\n * @cssprop --separator-size - Line thickness\n * @cssprop --separator-spacing - Vertical margin\n *\n * @part wrapper - Root wrapper container.\n * @part separator - Separator element.\n * @part label - Label element.\n * @example\n * ```html\n * <ore-separator></ore-separator>\n * <ore-separator label=\"or\"></ore-separator>\n * <ore-separator orientation=\"vertical\"></ore-separator>\n * ```\n */\nexport const SEPARATOR_TAG = 'ore-separator' as const;\ndefine<OreSeparatorProps>(SEPARATOR_TAG, {\n props: {\n color: prop.string<ThemeColor>(),\n decorative: prop.bool(true),\n label: prop.string(),\n orientation: prop.oneOf(['horizontal', 'vertical'] as const, 'horizontal'),\n },\n setup(props) {\n const roleAttr = () => (props.decorative.value ? 'none' : 'separator');\n const ariaHidden = () => (props.decorative.value ? 'true' : null);\n\n return html`\n ${() =>\n props.label.value\n ? html`\n <div class=\"separator-wrapper\" part=\"wrapper\">\n <hr\n class=\"separator\"\n part=\"separator\"\n role=\"${roleAttr}\"\n aria-hidden=\"${ariaHidden}\"\n aria-orientation=\"${() => props.orientation.value}\" />\n <span class=\"separator-label\" part=\"label\">${() => props.label.value}</span>\n <hr\n class=\"separator\"\n part=\"separator\"\n role=\"${roleAttr}\"\n aria-hidden=\"${ariaHidden}\"\n aria-orientation=\"${() => props.orientation.value}\" />\n </div>\n `\n : html`\n <hr\n class=\"separator\"\n part=\"separator\"\n role=\"${roleAttr}\"\n aria-hidden=\"${ariaHidden}\"\n aria-orientation=\"${() => props.orientation.value}\" />\n `}\n `;\n },\n styles: [colorThemeMixin, componentStyles],\n});\n"],"mappings":"sMAyCA,IAAa,EAAgB,iBAC7B,EAAA,EAAA,OAAA,CAA0B,EAAe,CACvC,MAAO,CACL,MAAO,EAAA,KAAK,OAAmB,EAC/B,WAAY,EAAA,KAAK,KAAK,EAAI,EAC1B,MAAO,EAAA,KAAK,OAAO,EACnB,YAAa,EAAA,KAAK,MAAM,CAAC,aAAc,UAAU,EAAY,YAAY,CAC3E,EACA,MAAM,EAAO,CACX,IAAM,aAAkB,EAAM,WAAW,MAAQ,OAAS,YACpD,eAAoB,EAAM,WAAW,MAAQ,OAAS,KAE5D,MAAO,GAAA,IAAI;YAEP,EAAM,MAAM,MACR,EAAA,IAAI;;;;;0BAKU,SAAS;iCACF,WAAW;0CACA,EAAM,YAAY,MAAM;iEACD,EAAM,MAAM,MAAM;;;;0BAI3D,SAAS;iCACF,WAAW;0CACA,EAAM,YAAY,MAAM;;cAGxD,EAAA,IAAI;;;;wBAIQ,SAAS;+BACF,WAAW;wCACA,EAAM,YAAY,MAAM;cACpD;KAEZ,EACA,OAAQ,CAAC,EAAA,gBAAiB,EAAA,OAAe,CAC3C,CAAC"}
1
+ {"version":3,"file":"separator.cjs","names":[],"sources":["../src/content/separator/separator.ts"],"sourcesContent":["import { define, html, prop } from '@vielzeug/ore';\nimport { colorThemeMixin } from '../../styles';\nimport { THEME_COLORS, type ThemeColor } from '../../types';\nimport componentStyles from './separator.css?inline';\n\n/** Separator component properties */\nexport type OreSeparatorProps = {\n /** Theme color tint */\n color?: ThemeColor;\n /** Decorative only (default true): set to false for semantic separators */\n decorative?: boolean;\n /** Optional label text centered on the separator */\n label?: string;\n /** Orientation of the separator */\n orientation?: 'horizontal' | 'vertical';\n};\n\n/**\n * A simple visual divider between sections of content.\n *\n * @element ore-separator\n *\n * @attr {string} orientation - 'horizontal' (default) | 'vertical'\n * @attr {boolean} decorative - When true (default), aria-hidden is applied\n * @attr {string} label - Optional centered label text\n * @attr {string} color - Theme color: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error'\n *\n * @cssprop --separator-color - Line color\n * @cssprop --separator-size - Line thickness\n * @cssprop --separator-spacing - Vertical margin\n *\n * @part wrapper - Root wrapper container.\n * @part separator - Separator element.\n * @part label - Label element.\n * @example\n * ```html\n * <ore-separator></ore-separator>\n * <ore-separator label=\"or\"></ore-separator>\n * <ore-separator orientation=\"vertical\"></ore-separator>\n * ```\n */\nexport const SEPARATOR_TAG = 'ore-separator' as const;\ndefine<OreSeparatorProps>(SEPARATOR_TAG, {\n props: {\n color: prop.oneOf(THEME_COLORS),\n decorative: prop.bool(true),\n label: prop.string(),\n orientation: prop.oneOf(['horizontal', 'vertical'] as const, 'horizontal'),\n },\n setup(props) {\n const roleAttr = () => (props.decorative.value ? 'none' : 'separator');\n const ariaHidden = () => (props.decorative.value ? 'true' : null);\n\n return html`\n ${() =>\n props.label.value\n ? html`\n <div class=\"separator-wrapper\" part=\"wrapper\">\n <hr\n class=\"separator\"\n part=\"separator\"\n role=\"${roleAttr}\"\n aria-hidden=\"${ariaHidden}\"\n aria-orientation=\"${() => props.orientation.value}\" />\n <span class=\"separator-label\" part=\"label\">${() => props.label.value}</span>\n <hr\n class=\"separator\"\n part=\"separator\"\n role=\"${roleAttr}\"\n aria-hidden=\"${ariaHidden}\"\n aria-orientation=\"${() => props.orientation.value}\" />\n </div>\n `\n : html`\n <hr\n class=\"separator\"\n part=\"separator\"\n role=\"${roleAttr}\"\n aria-hidden=\"${ariaHidden}\"\n aria-orientation=\"${() => props.orientation.value}\" />\n `}\n `;\n },\n styles: [colorThemeMixin, componentStyles],\n});\n"],"mappings":"sOAyCA,IAAa,EAAgB,iBAC7B,EAAA,EAAA,OAAA,CAA0B,EAAe,CACvC,MAAO,CACL,MAAO,EAAA,KAAK,MAAM,EAAA,YAAY,EAC9B,WAAY,EAAA,KAAK,KAAK,EAAI,EAC1B,MAAO,EAAA,KAAK,OAAO,EACnB,YAAa,EAAA,KAAK,MAAM,CAAC,aAAc,UAAU,EAAY,YAAY,CAC3E,EACA,MAAM,EAAO,CACX,IAAM,aAAkB,EAAM,WAAW,MAAQ,OAAS,YACpD,eAAoB,EAAM,WAAW,MAAQ,OAAS,KAE5D,MAAO,GAAA,IAAI;YAEP,EAAM,MAAM,MACR,EAAA,IAAI;;;;;0BAKU,SAAS;iCACF,WAAW;0CACA,EAAM,YAAY,MAAM;iEACD,EAAM,MAAM,MAAM;;;;0BAI3D,SAAS;iCACF,WAAW;0CACA,EAAM,YAAY,MAAM;;cAGxD,EAAA,IAAI;;;;wBAIQ,SAAS;+BACF,WAAW;wCACA,EAAM,YAAY,MAAM;cACpD;KAEZ,EACA,OAAQ,CAAC,EAAA,gBAAiB,EAAA,OAAe,CAC3C,CAAC"}