@vielzeug/refine 2.3.0 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (193) hide show
  1. package/dist/accordion-item.cjs +1 -1
  2. package/dist/accordion-item.cjs.map +1 -1
  3. package/dist/accordion-item.js +1 -1
  4. package/dist/accordion-item.js.map +1 -1
  5. package/dist/card.cjs +1 -1
  6. package/dist/card.cjs.map +1 -1
  7. package/dist/card.js +1 -1
  8. package/dist/card.js.map +1 -1
  9. package/dist/chat-message.cjs +1 -1
  10. package/dist/chat-message.cjs.map +1 -1
  11. package/dist/chat-message.js +1 -1
  12. package/dist/chat-message.js.map +1 -1
  13. package/dist/combobox.cjs +9 -7
  14. package/dist/combobox.cjs.map +1 -1
  15. package/dist/combobox.js +55 -48
  16. package/dist/combobox.js.map +1 -1
  17. package/dist/content/index.d.ts +2 -0
  18. package/dist/content/index.d.ts.map +1 -1
  19. package/dist/content/list/list-item.css.cjs +1 -1
  20. package/dist/content/list/list-item.css.cjs.map +1 -1
  21. package/dist/content/list/list-item.css.js +1 -1
  22. package/dist/content/list/list-item.css.js.map +1 -1
  23. package/dist/content/list/list-item.d.ts +9 -0
  24. package/dist/content/list/list-item.d.ts.map +1 -1
  25. package/dist/content/stats/stats.css.cjs +2 -0
  26. package/dist/content/stats/stats.css.cjs.map +1 -0
  27. package/dist/content/stats/stats.css.js +6 -0
  28. package/dist/content/stats/stats.css.js.map +1 -0
  29. package/dist/content/stats/stats.d.ts +72 -0
  30. package/dist/content/stats/stats.d.ts.map +1 -0
  31. package/dist/core/auto-resize.cjs +1 -1
  32. package/dist/core/auto-resize.cjs.map +1 -1
  33. package/dist/core/auto-resize.js +1 -1
  34. package/dist/core/auto-resize.js.map +1 -1
  35. package/dist/custom-elements.json +5087 -4791
  36. package/dist/datagrid.cjs +199 -179
  37. package/dist/datagrid.cjs.map +1 -1
  38. package/dist/datagrid.js +435 -321
  39. package/dist/datagrid.js.map +1 -1
  40. package/dist/disclosure/tab-item/tab-item.css.cjs +1 -1
  41. package/dist/disclosure/tab-item/tab-item.css.cjs.map +1 -1
  42. package/dist/disclosure/tab-item/tab-item.css.js +1 -1
  43. package/dist/disclosure/tab-item/tab-item.css.js.map +1 -1
  44. package/dist/disclosure/tab-item/tab-item.d.ts +3 -0
  45. package/dist/disclosure/tab-item/tab-item.d.ts.map +1 -1
  46. package/dist/disclosure/tabs/tabs.css.cjs +1 -1
  47. package/dist/disclosure/tabs/tabs.css.cjs.map +1 -1
  48. package/dist/disclosure/tabs/tabs.css.js +1 -1
  49. package/dist/disclosure/tabs/tabs.css.js.map +1 -1
  50. package/dist/disclosure/tabs/tabs.d.ts +4 -0
  51. package/dist/disclosure/tabs/tabs.d.ts.map +1 -1
  52. package/dist/frameworks/elements.d.ts +2 -1
  53. package/dist/icon.cjs +1 -1
  54. package/dist/icon.cjs.map +1 -1
  55. package/dist/icon.js +1 -1
  56. package/dist/icon.js.map +1 -1
  57. package/dist/input.cjs +5 -4
  58. package/dist/input.cjs.map +1 -1
  59. package/dist/input.js +14 -8
  60. package/dist/input.js.map +1 -1
  61. package/dist/inputs/combobox/combobox-options.cjs +1 -1
  62. package/dist/inputs/combobox/combobox-options.cjs.map +1 -1
  63. package/dist/inputs/combobox/combobox-options.d.ts.map +1 -1
  64. package/dist/inputs/combobox/combobox-options.js +1 -0
  65. package/dist/inputs/combobox/combobox-options.js.map +1 -1
  66. package/dist/inputs/combobox/combobox.css.cjs +1 -1
  67. package/dist/inputs/combobox/combobox.css.cjs.map +1 -1
  68. package/dist/inputs/combobox/combobox.css.js +1 -1
  69. package/dist/inputs/combobox/combobox.css.js.map +1 -1
  70. package/dist/inputs/combobox/combobox.d.ts +1 -0
  71. package/dist/inputs/combobox/combobox.d.ts.map +1 -1
  72. package/dist/inputs/combobox/combobox.types.d.ts +7 -0
  73. package/dist/inputs/combobox/combobox.types.d.ts.map +1 -1
  74. package/dist/inputs/datagrid/datagrid-model.cjs +1 -1
  75. package/dist/inputs/datagrid/datagrid-model.cjs.map +1 -1
  76. package/dist/inputs/datagrid/datagrid-model.d.ts +17 -3
  77. package/dist/inputs/datagrid/datagrid-model.d.ts.map +1 -1
  78. package/dist/inputs/datagrid/datagrid-model.js +93 -70
  79. package/dist/inputs/datagrid/datagrid-model.js.map +1 -1
  80. package/dist/inputs/datagrid/datagrid.css.cjs +1 -1
  81. package/dist/inputs/datagrid/datagrid.css.cjs.map +1 -1
  82. package/dist/inputs/datagrid/datagrid.css.js +1 -1
  83. package/dist/inputs/datagrid/datagrid.css.js.map +1 -1
  84. package/dist/inputs/datagrid/datagrid.d.ts +54 -4
  85. package/dist/inputs/datagrid/datagrid.d.ts.map +1 -1
  86. package/dist/inputs/index.d.ts +1 -1
  87. package/dist/inputs/index.d.ts.map +1 -1
  88. package/dist/inputs/input/input.css.cjs +1 -1
  89. package/dist/inputs/input/input.css.cjs.map +1 -1
  90. package/dist/inputs/input/input.css.js +1 -1
  91. package/dist/inputs/input/input.css.js.map +1 -1
  92. package/dist/inputs/input/input.d.ts +3 -0
  93. package/dist/inputs/input/input.d.ts.map +1 -1
  94. package/dist/inputs/select/select.css.cjs +1 -1
  95. package/dist/inputs/select/select.css.cjs.map +1 -1
  96. package/dist/inputs/select/select.css.js +1 -1
  97. package/dist/inputs/select/select.css.js.map +1 -1
  98. package/dist/inputs/select/select.d.ts +5 -0
  99. package/dist/inputs/select/select.d.ts.map +1 -1
  100. package/dist/layout/navbar/navbar.d.ts +2 -0
  101. package/dist/layout/navbar/navbar.d.ts.map +1 -1
  102. package/dist/layout/sidebar/sidebar.css.cjs +1 -1
  103. package/dist/layout/sidebar/sidebar.css.cjs.map +1 -1
  104. package/dist/layout/sidebar/sidebar.css.js +1 -1
  105. package/dist/layout/sidebar/sidebar.css.js.map +1 -1
  106. package/dist/layout/sidebar/sidebar.d.ts +8 -0
  107. package/dist/layout/sidebar/sidebar.d.ts.map +1 -1
  108. package/dist/list-item.cjs +6 -5
  109. package/dist/list-item.cjs.map +1 -1
  110. package/dist/list-item.js +23 -17
  111. package/dist/list-item.js.map +1 -1
  112. package/dist/list.cjs +1 -1
  113. package/dist/list.cjs.map +1 -1
  114. package/dist/list.js +1 -1
  115. package/dist/list.js.map +1 -1
  116. package/dist/menu.cjs +1 -1
  117. package/dist/menu.cjs.map +1 -1
  118. package/dist/menu.js +1 -1
  119. package/dist/menu.js.map +1 -1
  120. package/dist/navbar.cjs +2 -2
  121. package/dist/navbar.cjs.map +1 -1
  122. package/dist/navbar.js +7 -5
  123. package/dist/navbar.js.map +1 -1
  124. package/dist/navigation-menu.cjs +1 -1
  125. package/dist/navigation-menu.cjs.map +1 -1
  126. package/dist/navigation-menu.js +1 -1
  127. package/dist/navigation-menu.js.map +1 -1
  128. package/dist/overlay/popover/popover.css.cjs +1 -1
  129. package/dist/overlay/popover/popover.css.cjs.map +1 -1
  130. package/dist/overlay/popover/popover.css.js +1 -1
  131. package/dist/overlay/popover/popover.css.js.map +1 -1
  132. package/dist/overlay/popover/popover.d.ts +1 -0
  133. package/dist/overlay/popover/popover.d.ts.map +1 -1
  134. package/dist/overlay/shared/use-dialog.cjs +1 -1
  135. package/dist/overlay/shared/use-dialog.cjs.map +1 -1
  136. package/dist/overlay/shared/use-dialog.js +1 -1
  137. package/dist/overlay/shared/use-dialog.js.map +1 -1
  138. package/dist/overlay/shared/use-floating-trigger.cjs +1 -1
  139. package/dist/overlay/shared/use-floating-trigger.cjs.map +1 -1
  140. package/dist/overlay/shared/use-floating-trigger.js +1 -1
  141. package/dist/overlay/shared/use-floating-trigger.js.map +1 -1
  142. package/dist/popover.cjs.map +1 -1
  143. package/dist/popover.js.map +1 -1
  144. package/dist/radio.cjs +1 -1
  145. package/dist/radio.cjs.map +1 -1
  146. package/dist/radio.js +10 -8
  147. package/dist/radio.js.map +1 -1
  148. package/dist/rating.cjs +1 -1
  149. package/dist/rating.cjs.map +1 -1
  150. package/dist/rating.js +1 -1
  151. package/dist/rating.js.map +1 -1
  152. package/dist/refine.cjs +372 -323
  153. package/dist/refine.cjs.map +1 -1
  154. package/dist/refine.iife.js +372 -323
  155. package/dist/refine.iife.js.map +1 -1
  156. package/dist/refine.js +402 -353
  157. package/dist/refine.js.map +1 -1
  158. package/dist/select.cjs +16 -14
  159. package/dist/select.cjs.map +1 -1
  160. package/dist/select.js +118 -112
  161. package/dist/select.js.map +1 -1
  162. package/dist/sidebar.cjs +28 -23
  163. package/dist/sidebar.cjs.map +1 -1
  164. package/dist/sidebar.js +112 -77
  165. package/dist/sidebar.js.map +1 -1
  166. package/dist/slider.cjs +1 -1
  167. package/dist/slider.cjs.map +1 -1
  168. package/dist/slider.js +1 -1
  169. package/dist/slider.js.map +1 -1
  170. package/dist/stats.cjs +18 -0
  171. package/dist/stats.cjs.map +1 -0
  172. package/dist/stats.js +88 -0
  173. package/dist/stats.js.map +1 -0
  174. package/dist/stepper.cjs +1 -1
  175. package/dist/stepper.cjs.map +1 -1
  176. package/dist/stepper.js +1 -1
  177. package/dist/stepper.js.map +1 -1
  178. package/dist/styles/mixins/animation.css.cjs +2 -0
  179. package/dist/styles/mixins/animation.css.cjs.map +1 -1
  180. package/dist/styles/mixins/animation.css.d.ts.map +1 -1
  181. package/dist/styles/mixins/animation.css.js +2 -0
  182. package/dist/styles/mixins/animation.css.js.map +1 -1
  183. package/dist/tab-item.cjs +1 -1
  184. package/dist/tab-item.cjs.map +1 -1
  185. package/dist/tab-item.js +3 -2
  186. package/dist/tab-item.js.map +1 -1
  187. package/dist/tabs.cjs +1 -1
  188. package/dist/tabs.cjs.map +1 -1
  189. package/dist/tabs.js +3 -1
  190. package/dist/tabs.js.map +1 -1
  191. package/dist/toast.cjs.map +1 -1
  192. package/dist/toast.js.map +1 -1
  193. package/package.json +64 -56
package/dist/select.cjs CHANGED
@@ -1,29 +1,30 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./styles/mixins/accessibility.css.cjs"),t=require("./styles/mixins/shape.css.cjs"),n=require("./styles/mixins/theme.css.cjs"),r=require("./core/choice-field.cjs"),i=require("./core/ore.cjs"),a=require("./core/option-list.cjs"),o=require("./shared/prop-bundles.cjs"),s=require("./inputs/shared/native-field-event.cjs"),c=require("./inputs/select/select.css.cjs");let l=require("@vielzeug/ore"),u=require("@vielzeug/ripple");var d=`ore-select`;(0,l.define)(d,{formAssociated:!0,props:{...o.themableBundle,...o.sizableBundle,...o.disablableBundle,...o.loadableBundle,...o.roundableBundle,error:l.prop.string(),fullwidth:l.prop.bool(!1),helper:l.prop.string(),label:l.prop.string(),"label-placement":l.prop.oneOf([`inset`,`outside`],`inset`),multiple:l.prop.bool(!1),name:l.prop.string(),options:l.prop.json(void 0),placeholder:l.prop.string(),required:l.prop.bool(!1),success:l.prop.bool(!1),value:l.prop.string(),variant:l.prop.string()},setup(e){let t=(0,l.getHost)(),n=(0,l.useEmit)(),o=(0,l.useSlots)(),c=t.shadowRoot,d=(0,u.signal)([]),f=(0,u.computed)(()=>!!e.loading.value);function p(e){return{disabled:!!e.disabled,group:e.group,label:e.label??e.value,value:e.value}}let m=(0,u.computed)(()=>{let t=e.options.value;return Array.isArray(t)?t.map(p):d.value}),h=null,g=null,_=i.lifecycleSignal(l.onCleanup),v=r.createChoiceField({disabled:e.disabled,error:e.error,helper:e.helper,label:e.label,labelPlacement:e[`label-placement`],multiple:e.multiple,prefix:`select`,required:e.required,signal:_,value:e.value});v.attachFormField((0,l.useField)({disabled:v.disabled,onReset:v.reset,toFormValue:e=>e,validationMessage:v.validationMessage,validity:v.validity,value:v.formValue}));let y=a.createListboxDropdown({getBoundary:()=>t,getFocusedOptionElement:()=>g?.querySelector(`[data-focused]`)??null,getItems:()=>m.value,getPanel:()=>g,getReference:()=>h,getTrigger:()=>h,isDisabled:()=>v.disabled.value,isItemDisabled:e=>e.disabled,onClose:e=>{n(`open-change`,{open:!1,reason:e}),v.triggerValidation(`blur`)},onOpen:e=>n(`open-change`,{open:!0,reason:e}),signal:_}),{triggerValidation:b}=v,x=v.selectedValues,S=v.disabled;s.defineFieldValue(t,()=>v.formValue.value,e=>{v.setValues(e?e.split(`,`):[])});let{fieldId:C}=v,w=`listbox-${C}`,{focusedIndex:T,isOpen:E}=y;(0,l.bind)({attr:{"has-error":()=>e.error.value?!0:void 0,open:()=>E.value?!0:void 0,size:e.size,variant:e.variant}});function D(){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,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,group:r,label:t.text||t.value,value:t.value})}}d.value=n}let O=(0,u.computed)(()=>{if(x.value.length===0)return``;if(e.multiple.value&&x.value.length>1)return`${x.value.length} selected`;let t=x.value[0];return m.value.find(e=>e.value===t)?.label??t}),k=(0,u.computed)(()=>e.multiple.value?x.value.map(e=>({label:m.value.find(t=>t.value===e)?.label??e,value:e})):[]),A=(0,u.computed)(()=>e.multiple.value&&x.value.length>0),j=(0,u.computed)(()=>O.value||e.placeholder.value||``);function M(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 N=(0,u.computed)(()=>M(m.value));function P(){s.setFieldValue(t,v.formValue.value),s.dispatchNativeFieldEvent(t,`input`),s.dispatchNativeFieldEvent(t,`change`)}function F(e){e.stopPropagation();let t=e.detail?.value;t!==void 0&&(v.removeValue(t),P(),b(`change`))}function I(e=`programmatic`){y.open(e),requestAnimationFrame(()=>{let e=x.value.length>0?m.value.findIndex(e=>e.value===x.value[0]):-1;if(e>=0){y.set(e);return}y.navigate(`first`)})}function L(t,n){t.disabled||(e.multiple.value?v.toggleValue(t.value):(v.selectValue(t.value),y.close()),P(),b(`change`))}function R(e){if(!S.value&&!y.handleKeydown(e))switch(e.key){case` `:case`Enter`:if(e.preventDefault(),E.value){let t=T.value,n=m.value;t>=0&&t<n.length&&L(n[t],e)}else I(`keyboard`);break;case`Tab`:y.close()}}let z=()=>j.value,B=()=>e.label.value??``,V=()=>e.placeholder.value??``,H=()=>e[`label-placement`].value??`inset`,U=()=>e.color?.value??void 0,W=()=>e.size?.value??void 0,G=()=>e.variant?.value??void 0,K=()=>e.rounded?.value??void 0,q=()=>e.helper.value??``,J=()=>e.error.value??``,Y=()=>S.value?!0:void 0,X=()=>e.required.value?!0:void 0,Z=()=>e.fullwidth.value?!0:void 0,Q=()=>S.value?`-1`:`0`;(0,u.watch)(o.elements(),()=>D(),{immediate:!0});let $=(0,u.effect)(()=>{E.value?g&&`showPopover`in g&&!g.matches(`:popover-open`)&&g.showPopover():g&&`hidePopover`in g&&g.matches(`:popover-open`)&&g.hidePopover()});return(0,l.onCleanup)(()=>$.dispose()),(0,l.onMounted)(()=>{let e=null,t=null;return h&&(e=e=>{e.stopPropagation(),!S.value&&(E.value?y.close(`trigger`):I(`click`))},t=e=>{R(e)},h.addEventListener(`click`,e),h.addEventListener(`keydown`,t)),()=>{h&&e&&h.removeEventListener(`click`,e),h&&t&&h.removeEventListener(`keydown`,t)}}),l.html`
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./styles/mixins/accessibility.css.cjs"),t=require("./styles/mixins/shape.css.cjs"),n=require("./styles/mixins/theme.css.cjs"),r=require("./core/choice-field.cjs"),i=require("./core/ore.cjs"),a=require("./core/option-list.cjs"),o=require("./shared/prop-bundles.cjs"),s=require("./inputs/shared/native-field-event.cjs"),c=require("./inputs/select/select.css.cjs");let l=require("@vielzeug/ore"),u=require("@vielzeug/ripple");var d=`ore-select`;(0,l.define)(d,{formAssociated:!0,props:{...o.themableBundle,...o.sizableBundle,...o.disablableBundle,...o.loadableBundle,...o.roundableBundle,error:l.prop.string(),fullwidth:l.prop.bool(!1),helper:l.prop.string(),"hide-label":l.prop.bool(!1),label:l.prop.string(),"label-placement":l.prop.oneOf([`inset`,`outside`],`inset`),multiple:l.prop.bool(!1),name:l.prop.string(),options:l.prop.json(void 0),placeholder:l.prop.string(),required:l.prop.bool(!1),success:l.prop.bool(!1),value:l.prop.string(),variant:l.prop.string()},setup(e){let t=(0,l.getHost)(),n=(0,l.useEmit)(),o=(0,l.useSlots)(),c=t.shadowRoot,d=(0,u.signal)([]),f=(0,u.computed)(()=>!!e.loading.value);function p(e){return{disabled:!!e.disabled,disabledReason:e.disabledReason,group:e.group,label:e.label??e.value,value:e.value}}let m=(0,u.computed)(()=>{let t=e.options.value;return Array.isArray(t)?t.map(p):d.value}),h=null,g=null,_=i.lifecycleSignal(l.onCleanup),v=r.createChoiceField({disabled:e.disabled,error:e.error,helper:e.helper,label:e.label,labelPlacement:e[`label-placement`],multiple:e.multiple,prefix:`select`,required:e.required,signal:_,value:e.value});v.attachFormField((0,l.useField)({disabled:v.disabled,onReset:v.reset,toFormValue:e=>e,validationMessage:v.validationMessage,validity:v.validity,value:v.formValue}));let y=a.createListboxDropdown({getBoundary:()=>t,getFocusedOptionElement:()=>g?.querySelector(`[data-focused]`)??null,getItems:()=>m.value,getPanel:()=>g,getReference:()=>h,getTrigger:()=>h,isDisabled:()=>v.disabled.value,isItemDisabled:e=>e.disabled,onClose:e=>{n(`open-change`,{open:!1,reason:e}),v.triggerValidation(`blur`)},onOpen:e=>n(`open-change`,{open:!0,reason:e}),signal:_}),{triggerValidation:b}=v,x=v.selectedValues,S=v.disabled;s.defineFieldValue(t,()=>v.formValue.value,e=>{v.setValues(e?e.split(`,`):[])});let{fieldId:C}=v,w=`listbox-${C}`,{focusedIndex:T,isOpen:E}=y;(0,l.bind)({attr:{"has-error":()=>e.error.value?!0:void 0,open:()=>E.value?!0:void 0,size:e.size,variant:e.variant}});function D(){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,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,label:t.text||t.value,value:t.value})}}d.value=n}let O=(0,u.computed)(()=>{if(x.value.length===0)return``;if(e.multiple.value&&x.value.length>1)return`${x.value.length} selected`;let t=x.value[0];return m.value.find(e=>e.value===t)?.label??t}),k=(0,u.computed)(()=>e.multiple.value?x.value.map(e=>({label:m.value.find(t=>t.value===e)?.label??e,value:e})):[]),A=(0,u.computed)(()=>e.multiple.value&&x.value.length>0),j=(0,u.computed)(()=>O.value||e.placeholder.value||``);function M(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 N=(0,u.computed)(()=>M(m.value));function P(){s.setFieldValue(t,v.formValue.value),s.dispatchNativeFieldEvent(t,`input`),s.dispatchNativeFieldEvent(t,`change`)}function F(e){e.stopPropagation();let t=e.detail?.value;t!==void 0&&(v.removeValue(t),P(),b(`change`))}function I(e=`programmatic`){y.open(e),requestAnimationFrame(()=>{let e=x.value.length>0?m.value.findIndex(e=>e.value===x.value[0]):-1;if(e>=0){y.set(e);return}y.navigate(`first`)})}function L(t,n){t.disabled||(e.multiple.value?v.toggleValue(t.value):(v.selectValue(t.value),y.close()),P(),b(`change`))}function R(e){if(!S.value&&!y.handleKeydown(e))switch(e.key){case` `:case`Enter`:if(e.preventDefault(),E.value){let t=T.value,n=m.value;t>=0&&t<n.length&&L(n[t],e)}else I(`keyboard`);break;case`Tab`:y.close()}}let z=()=>j.value,B=()=>e[`hide-label`].value,V=()=>B()?``:e.label.value??``,H=()=>B()?e.label.value??``:null,U=()=>e.placeholder.value??``,W=()=>e[`label-placement`].value??`inset`,G=()=>e.color?.value??void 0,K=()=>e.size?.value??void 0,q=()=>e.variant?.value??void 0,J=()=>e.rounded?.value??void 0,Y=()=>e.helper.value??``,X=()=>e.error.value??``,Z=()=>S.value?!0:void 0,Q=()=>e.required.value?!0:void 0,$=()=>e.fullwidth.value?!0:void 0,ee=()=>S.value?`-1`:`0`;(0,u.watch)(o.elements(),()=>D(),{immediate:!0});let te=(0,u.effect)(()=>{E.value?g&&`showPopover`in g&&!g.matches(`:popover-open`)&&g.showPopover():g&&`hidePopover`in g&&g.matches(`:popover-open`)&&g.hidePopover()});return(0,l.onCleanup)(()=>te.dispose()),(0,l.onMounted)(()=>{let e=null,t=null;return h&&(e=e=>{e.stopPropagation(),!S.value&&(E.value?y.close(`trigger`):I(`click`))},t=e=>{R(e)},h.addEventListener(`click`,e),h.addEventListener(`keydown`,t)),()=>{h&&e&&h.removeEventListener(`click`,e),h&&t&&h.removeEventListener(`keydown`,t)}}),l.html`
2
2
  <slot style="display:none"></slot>
3
3
  <ore-input
4
4
  class="trigger"
5
5
  part="trigger"
6
6
  readonly
7
- tabindex="${Q}"
7
+ tabindex="${ee}"
8
8
  role="combobox"
9
9
  aria-haspopup="listbox"
10
10
  aria-controls="${w}"
11
+ aria-label="${H}"
11
12
  aria-disabled="${()=>S.value?`true`:null}"
12
13
  aria-expanded="${()=>String(E.value)}"
13
14
  aria-invalid="${()=>e.error.value?`true`:null}"
14
15
  value="${z}"
15
- label="${B}"
16
- placeholder="${V}"
17
- label-placement="${H}"
18
- color="${U}"
19
- size="${W}"
20
- variant="${G}"
21
- rounded="${K}"
22
- helper="${q}"
23
- error="${J}"
24
- ?disabled="${Y}"
25
- ?required="${X}"
26
- ?fullwidth="${Z}"
16
+ label="${V}"
17
+ placeholder="${U}"
18
+ label-placement="${W}"
19
+ color="${G}"
20
+ size="${K}"
21
+ variant="${q}"
22
+ rounded="${J}"
23
+ helper="${Y}"
24
+ error="${X}"
25
+ ?disabled="${Z}"
26
+ ?required="${Q}"
27
+ ?fullwidth="${$}"
27
28
  ?success="${()=>e.success.value}"
28
29
  ref="${e=>{h=e}}">
29
30
  <div slot="prefix" class="chips-row" ?hidden="${()=>!A.value}">
@@ -76,6 +77,7 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=requi
76
77
  @click="${t=>{t.stopPropagation(),L(e.opt,t)}}"
77
78
  @pointerenter="${()=>{y.set(e.idx)}}">
78
79
  <span>${e.opt.label}</span>
80
+ ${e.opt.disabled&&e.opt.disabledReason?l.html`<small class="disabled-reason" title="${e.opt.disabledReason}">${e.opt.disabledReason}</small>`:l.html``}
79
81
  <span class="option-check" aria-hidden="true">
80
82
  <ore-icon name="check" size="14" stroke-width="2.5" aria-hidden="true"></ore-icon>
81
83
  </span>
@@ -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 type { VisualVariant } from '../../types';\nimport '../../feedback/chip/chip';\nimport '../../content/icon/icon';\nimport '../input/input';\nimport { disablableBundle, loadableBundle, roundableBundle, sizableBundle, themableBundle } from '../../shared';\nimport { colorThemeMixin, reducedMotionMixin, roundedVariantMixin } from '../../styles';\nimport { defineFieldValue, dispatchNativeFieldEvent, setFieldValue } from '../shared/native-field-event';\nimport componentStyles from './select.css?inline';\n\n// ── Types ─────────────────────────────────────────────────────────────\n\ntype OptionItem = {\n disabled: boolean;\n group?: string;\n label: string;\n value: string;\n};\n\nexport type OreSelectOptionInput = {\n disabled?: boolean;\n group?: 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// ── 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 /** 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 {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-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 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 group: option.group,\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({ disabled: opt.disabled, label: opt.text || opt.value, value: opt.value });\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({ disabled: opt.disabled, group: groupLabel, label: opt.text || opt.value, value: opt.value });\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 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 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 inputLabel = () => props.label.value ?? '';\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-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 <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 <span>${row.opt.label}</span>\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 type { VisualVariant } from '../../types';\nimport '../../feedback/chip/chip';\nimport '../../content/icon/icon';\nimport '../input/input';\nimport { disablableBundle, loadableBundle, roundableBundle, sizableBundle, themableBundle } from '../../shared';\nimport { colorThemeMixin, reducedMotionMixin, roundedVariantMixin } from '../../styles';\nimport { defineFieldValue, dispatchNativeFieldEvent, setFieldValue } from '../shared/native-field-event';\nimport componentStyles from './select.css?inline';\n\n// ── Types ─────────────────────────────────────────────────────────────\n\ntype OptionItem = {\n disabled: boolean;\n disabledReason?: string;\n group?: 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 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// ── 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-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 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 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 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 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 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 <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 <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":"2fAiIA,IAAa,EAAa,cAC1B,EAAA,EAAA,OAAA,CAAuB,EAAY,CACjC,eAAgB,GAChB,MAAO,CACL,GAAG,EAAA,eACH,GAAG,EAAA,cACH,GAAG,EAAA,iBACH,GAAG,EAAA,eACH,GAAG,EAAA,gBACH,MAAO,EAAA,KAAK,OAAO,EACnB,UAAW,EAAA,KAAK,KAAK,EAAK,EAC1B,OAAQ,EAAA,KAAK,OAAO,EACpB,aAAc,EAAA,KAAK,KAAK,EAAK,EAC7B,MAAO,EAAA,KAAK,OAAO,EACnB,kBAAmB,EAAA,KAAK,MAAM,CAAC,QAAS,SAAS,EAAY,OAAO,EACpE,SAAU,EAAA,KAAK,KAAK,EAAK,EACzB,KAAM,EAAA,KAAK,OAAO,EAClB,QAAS,EAAA,KAAK,KAAK,IAAA,EAA+C,EAClE,YAAa,EAAA,KAAK,OAAO,EACzB,SAAU,EAAA,KAAK,KAAK,EAAK,EACzB,QAAS,EAAA,KAAK,KAAK,EAAK,EACxB,MAAO,EAAA,KAAK,OAAO,EACnB,QAAS,EAAA,KAAK,OAAwC,CACxD,EACA,MAAM,EAAO,CACX,IAAM,GAAA,EAAK,EAAA,QAAA,CAAQ,EACb,GAAA,EAAO,EAAA,QAAA,CAAyB,EAChC,GAAA,EAAQ,EAAA,SAAA,CAAS,EAEjB,EAAa,EAAG,WAKhB,GAAA,EAAiB,EAAA,OAAA,CAAqB,CAAC,CAAC,EACxC,GAAA,EAAY,EAAA,SAAA,KAAe,EAAQ,EAAM,QAAQ,KAAM,EAG7D,SAAS,EAAgB,EAA0C,CACjE,MAAO,CACL,SAAU,EAAQ,EAAO,SACzB,eAAgB,EAAO,eACvB,MAAO,EAAO,MACd,MAAO,EAAO,OAAS,EAAO,MAC9B,MAAO,EAAO,KAChB,CACF,CAEA,IAAM,GAAA,EAAU,EAAA,SAAA,KAAe,CAC7B,IAAM,EAAkB,EAAM,QAAQ,MAEtC,OAAO,MAAM,QAAQ,CAAe,EAAI,EAAgB,IAAI,CAAe,EAAI,EAAe,KAChG,CAAC,EACG,EAAgC,KAChC,EAAiC,KAE/B,EAAc,EAAA,gBAAgB,EAAA,SAAS,EACvC,EAAS,EAAA,kBAAkB,CAC/B,SAAU,EAAM,SAChB,MAAO,EAAM,MACb,OAAQ,EAAM,OACd,MAAO,EAAM,MACb,eAAgB,EAAM,mBACtB,SAAU,EAAM,SAChB,OAAQ,SACR,SAAU,EAAM,SAChB,OAAQ,EACR,MAAO,EAAM,KACf,CAAC,EAED,EAAO,iBAAA,EACL,EAAA,SAAA,CAAiB,CACf,SAAU,EAAO,SACjB,QAAS,EAAO,MAChB,YAAc,GAAM,EACpB,kBAAmB,EAAO,kBAC1B,SAAU,EAAO,SACjB,MAAO,EAAO,SAChB,CAAC,CACH,EAEA,IAAM,EAAa,EAAA,sBAAkC,CACnD,gBAAmB,EACnB,4BAA+B,GAAY,cAA2B,gBAAgB,GAAK,KAC3F,aAAgB,EAAQ,MACxB,aAAgB,EAChB,iBAAoB,EACpB,eAAkB,EAClB,eAAkB,EAAO,SAAS,MAClC,eAAiB,GAAW,EAAO,SACnC,QAAU,GAAW,CACnB,EAAK,cAAe,CAAE,KAAM,GAAO,QAAO,CAAC,EAC3C,EAAO,kBAAkB,MAAM,CACjC,EACA,OAAS,GAAW,EAAK,cAAe,CAAE,KAAM,GAAM,QAAO,CAAC,EAC9D,OAAQ,CACV,CAAC,EAEK,CAAE,qBAAsB,EACxB,EAAiB,EAAO,eACxB,EAAa,EAAO,SAE1B,EAAA,iBACE,MACM,EAAO,UAAU,MACtB,GAAU,CACT,EAAO,UAAU,EAAQ,EAAM,MAAM,GAAG,EAAI,CAAC,CAAC,CAChD,CACF,EAEA,GAAM,CAAE,QAAS,GAAa,EACxB,EAAY,WAAW,IACvB,CAAE,eAAc,UAAW,GAGjC,EAAA,EAAA,KAAA,CAAK,CACH,KAAM,CACJ,gBAAoB,EAAM,MAAM,MAAQ,GAAO,IAAA,GAC/C,SAAa,EAAO,MAAQ,GAAO,IAAA,GACnC,KAAM,EAAM,KACZ,QAAS,EAAM,OACjB,CACF,CAAC,EAMD,SAAS,GAAc,CACrB,IAAM,EAAO,GAAY,cAA+B,MAAM,EAE9D,GAAI,CAAC,EAAM,OAEX,IAAM,EAAW,EAAK,iBAAiB,CAAE,QAAS,EAAK,CAAC,EAClD,EAAsB,CAAC,EAE7B,IAAK,IAAM,KAAM,EACf,GAAI,EAAG,UAAY,SAAU,CAC3B,IAAM,EAAM,EAEZ,EAAM,KAAK,CACT,SAAU,EAAI,SACd,eAAgB,EAAI,QAAQ,eAC5B,MAAO,EAAI,MAAQ,EAAI,MACvB,MAAO,EAAI,KACb,CAAC,CACH,MAAO,GAAI,EAAG,UAAY,WAAY,CACpC,IAAM,EAAQ,EACR,EAAa,EAAM,MAEzB,IAAK,IAAM,KAAS,MAAM,KAAK,EAAM,iBAAiB,QAAQ,CAAC,EAAG,CAChE,IAAM,EAAM,EAEZ,EAAM,KAAK,CACT,SAAU,EAAI,SACd,eAAgB,EAAI,QAAQ,eAC5B,MAAO,EACP,MAAO,EAAI,MAAQ,EAAI,MACvB,MAAO,EAAI,KACb,CAAC,CACH,CACF,CAGF,EAAe,MAAQ,CACzB,CAEA,IAAM,GAAA,EAAe,EAAA,SAAA,KAAe,CAClC,GAAI,EAAe,MAAM,SAAW,EAAG,MAAO,GAE9C,GAAI,EAAM,SAAS,OAAS,EAAe,MAAM,OAAS,EACxD,MAAO,GAAG,EAAe,MAAM,OAAO,WAGxC,IAAM,EAAQ,EAAe,MAAM,GAEnC,OAAO,EAAQ,MAAM,KAAM,GAAM,EAAE,QAAU,CAAK,CAAC,EAAE,OAAS,CAChE,CAAC,EACK,GAAA,EAAoB,EAAA,SAAA,KACnB,EAAM,SAAS,MAEb,EAAe,MAAM,IAAK,IAAW,CAC1C,MAAO,EAAQ,MAAM,KAAM,GAAM,EAAE,QAAU,CAAK,CAAC,EAAE,OAAS,EAC9D,OACF,EAAE,EALgC,CAAC,CAMpC,EACK,GAAA,EAAY,EAAA,SAAA,KAAe,EAAM,SAAS,OAAS,EAAe,MAAM,OAAS,CAAC,EAClF,GAAA,EAAc,EAAA,SAAA,KAAe,EAAa,OAAS,EAAM,YAAY,OAAS,EAAE,EAEtF,SAAS,EAAc,EAA+B,CACpD,IAAM,EAAkB,CAAC,EACnB,EAAS,IAAI,IAEnB,IAAK,IAAM,KAAO,EAAM,CACtB,IAAM,EAAM,EAAI,MAEZ,EAAQ,EAAO,IAAI,CAAG,EAErB,IACH,EAAQ,CAAC,EACT,EAAO,IAAI,EAAK,CAAK,GAGvB,EAAM,KAAK,CAAG,CAChB,CAEA,IAAI,EAAY,EAEhB,IAAK,GAAM,CAAC,EAAY,KAAc,EAAQ,CACxC,IAAe,IAAA,IAAW,EAAK,KAAK,CAAE,MAAO,EAAY,KAAM,OAAQ,CAAC,EAE5E,IAAK,IAAM,KAAO,EAAW,EAAK,KAAK,CAAE,IAAK,IAAa,MAAK,KAAM,QAAS,CAAC,CAClF,CAEA,OAAO,CACT,CAEA,IAAM,GAAA,EAAW,EAAA,SAAA,KAAe,EAAc,EAAQ,KAAK,CAAC,EAE5D,SAAS,GAAmB,CAC1B,EAAA,cAAc,EAAI,EAAO,UAAU,KAAK,EACxC,EAAA,yBAAyB,EAAI,OAAO,EACpC,EAAA,yBAAyB,EAAI,QAAQ,CACvC,CAEA,SAAS,EAAW,EAAoB,CACtC,EAAM,gBAAgB,EAEtB,IAAM,EAAS,EAA0C,QAAQ,MAE7D,IAAU,IAAA,KAEd,EAAO,YAAY,CAAK,EACxB,EAAW,EACX,EAAkB,QAAQ,EAC5B,CAEA,SAAS,EAAU,EAA4B,eAAgB,CAC7D,EAAW,KAAK,CAAM,EAEtB,0BAA4B,CAC1B,IAAM,EACJ,EAAe,MAAM,OAAS,EAC1B,EAAQ,MAAM,UAAW,GAAW,EAAO,QAAU,EAAe,MAAM,EAAE,EAC5E,GAEN,GAAI,GAAiB,EAAG,CACtB,EAAW,IAAI,CAAa,EAE5B,MACF,CAEA,EAAW,SAAS,OAAO,CAC7B,CAAC,CACH,CAIA,SAAS,EAAa,EAAiB,EAAY,CAC7C,EAAI,WAEJ,EAAM,SAAS,MACjB,EAAO,YAAY,EAAI,KAAK,GAE5B,EAAO,YAAY,EAAI,KAAK,EAC5B,EAAW,MAAM,GAGnB,EAAW,EACX,EAAkB,QAAQ,EAC5B,CAIA,SAAS,EAAqB,EAAkB,CAC1C,MAAW,OAGX,GAAW,cAAc,CAAC,EAE9B,OAAQ,EAAE,IAAV,CACE,IAAK,IACL,IAAK,QAGH,GAFA,EAAE,eAAe,EAEb,EAAO,MAAO,CAChB,IAAM,EAAM,EAAa,MACnB,EAAO,EAAQ,MAEjB,GAAO,GAAK,EAAM,EAAK,QAAQ,EAAa,EAAK,GAAM,CAAC,CAC9D,MACE,EAAU,UAAU,EAGtB,MACF,IAAK,MACH,EAAW,MAAM,CAErB,CACF,CAGA,IAAM,MAAmB,EAAY,MAC/B,MAAkB,EAAM,aAAa,CAAC,MAItC,MAAoB,EAAU,EAAI,GAAM,EAAM,MAAM,OAAS,GAC7D,MAA0B,EAAU,EAAK,EAAM,MAAM,OAAS,GAAM,KACpE,MAAyB,EAAM,YAAY,OAAS,GACpD,MAA4B,EAAM,kBAAkB,CAAC,OAAS,QAC9D,MAAmB,EAAM,OAAO,OAAS,IAAA,GACzC,MAAkB,EAAM,MAAM,OAAS,IAAA,GACvC,MAAqB,EAAM,SAAS,OAAS,IAAA,GAC7C,MAAqB,EAAM,SAAS,OAAS,IAAA,GAC7C,MAAoB,EAAM,OAAO,OAAS,GAC1C,MAAmB,EAAM,MAAM,OAAS,GACxC,MAAuB,EAAW,MAAQ,GAAO,IAAA,GACjD,MAAuB,EAAM,SAAS,MAAQ,GAAO,IAAA,GACrD,MAAwB,EAAM,UAAU,MAAQ,GAAO,IAAA,GACvD,OAAsB,EAAW,MAAQ,KAAO,KAEtD,EAAA,EAAA,MAAA,CAAM,EAAM,SAAS,MAAS,EAAY,EAAG,CAAE,UAAW,EAAK,CAAC,EAEhE,IAAM,IAAA,EAAkB,EAAA,OAAA,KAAa,CAC/B,EAAO,MACL,GAAc,gBAAiB,GAAc,CAAC,EAAW,QAAQ,eAAe,GAAG,EAAW,YAAY,EAE1G,GAAc,gBAAiB,GAAc,EAAW,QAAQ,eAAe,GAAG,EAAW,YAAY,CAEjH,CAAC,EAgCD,OA9BA,EAAA,EAAA,UAAA,KAAgB,GAAgB,QAAQ,CAAC,GAEzC,EAAA,EAAA,UAAA,KAAgB,CACd,IAAI,EAAuD,KACvD,EAA4D,KAmBhE,OAjBI,IACF,EAAkB,GAAsB,CACtC,EAAM,gBAAgB,EAElB,GAAW,QAEX,EAAO,MAAO,EAAW,MAAM,SAAS,EACvC,EAAU,OAAO,EACxB,EACA,EAAoB,GAAyB,CAC3C,EAAqB,CAAK,CAC5B,EAEA,EAAU,iBAAiB,QAAS,CAAc,EAClD,EAAU,iBAAiB,UAAW,CAAgB,OAG3C,CACP,GAAa,GAAgB,EAAU,oBAAoB,QAAS,CAAc,EAElF,GAAa,GAAkB,EAAU,oBAAoB,UAAW,CAAgB,CAC9F,CACF,CAAC,EAEM,EAAA,IAAI;;;;;;oBAMK,GAAa;;;yBAGR,EAAU;sBACb,EAAiB;6BACP,EAAW,MAAQ,OAAS,KAAM;6BACnC,OAAO,EAAO,KAAK,EAAE;4BACrB,EAAM,MAAM,MAAQ,OAAS,KAAM;iBACjD,EAAW;iBACX,EAAW;uBACL,EAAiB;2BACb,EAAoB;iBAC9B,EAAW;gBACZ,EAAU;mBACP,EAAa;mBACb,EAAa;kBACd,EAAY;iBACb,EAAW;qBACP,EAAc;qBACd,EAAc;sBACb,EAAe;wBACX,EAAM,QAAQ,MAAM;eAC9B,GAAoB,CAC1B,EAAY,CACd,EAAE;4DACoD,CAAC,EAAU,MAAM;gBAEnE,EAAkB,MAAM,IACrB,GAAS,EAAA,IAAI;;2BAED,EAAK,MAAM;2BACX,EAAK,MAAM;;;;2BAIX,EAAM,MAAM;6BACV,EAAW;oBACpB,EAAK,MAAM;;eAGnB,EAAE;;;;;;;;;;;;;sBAaQ,EAAO;;cAEf,EAAU;;eAER,GAAoB,CAC1B,EAAa,CACf,EAAE;qDAC6C,CAAC,EAAU,MAAM;mDACnB,EAAU,OAAS,EAAQ,MAAM,OAAS,EAAE;iDAC9C,EAAU,OAAS,EAAQ,MAAM,SAAW,EAAE;gBAErF,EAAS,MAAM,IAAK,GAClB,EAAI,OAAS,QACT,EAAA,IAAI;sEACgD,EAAI,MAAM;oBAE9D,EAAA,IAAI;;;;4BAIM,GAAG,EAAS,OAAO,EAAI,MAAM;2CACd,OAAO,EAAI,GAAG,EAAE;2CAChB,EAAI,IAAI,MAAM;2CACZ,OAAO,EAAe,MAAM,SAAS,EAAI,IAAI,KAAK,CAAC,EAAE;2CACrD,OAAO,EAAI,IAAI,QAAQ,EAAE;2CACzB,EAAa,QAAU,EAAI,IAAI;4CAC9B,EAAe,MAAM,SAAS,EAAI,IAAI,KAAK,EAAE;4CAC7C,EAAI,IAAI,SAAS;gCAC9B,GAAkB,CAC3B,EAAE,gBAAgB,EAClB,EAAa,EAAI,IAAK,CAAC,CACzB,EAAE;2CACqB,CACrB,EAAW,IAAI,EAAI,GAAG,CACxB,EAAE;8BACM,EAAI,IAAI,MAAM;wBAEpB,EAAI,IAAI,UAAY,EAAI,IAAI,eACxB,EAAA,IAAI,yCAAyC,EAAI,IAAI,eAAe,IAAI,EAAI,IAAI,eAAe,UAC/F,EAAA,IAAI,GACT;;;;;mBAMX,EAAE;;;KAIZ,EACA,OAAQ,CAAE,eAAgB,EAAK,EAC/B,OAAQ,CAAC,EAAA,gBAAiB,EAAA,mBAAoB,EAAA,oBAAqB,EAAA,OAAe,CACpF,CAAC"}
package/dist/select.js CHANGED
@@ -5,13 +5,13 @@ import { createChoiceField as r } from "./core/choice-field.js";
5
5
  import { lifecycleSignal as i } from "./core/ore.js";
6
6
  import { createListboxDropdown as a } from "./core/option-list.js";
7
7
  import { disablableBundle as o, loadableBundle as s, roundableBundle as c, sizableBundle as l, themableBundle as u } from "./shared/prop-bundles.js";
8
- import { defineFieldValue as d, dispatchNativeFieldEvent as f, setFieldValue as ee } from "./inputs/shared/native-field-event.js";
9
- import p from "./inputs/select/select.css.js";
10
- import { bind as m, define as h, getHost as g, html as _, onCleanup as v, onMounted as y, prop as b, useEmit as x, useField as S, useSlots as C } from "@vielzeug/ore";
11
- import { computed as w, effect as T, signal as E, watch as D } from "@vielzeug/ripple";
8
+ import { defineFieldValue as d, dispatchNativeFieldEvent as f, setFieldValue as p } from "./inputs/shared/native-field-event.js";
9
+ import m from "./inputs/select/select.css.js";
10
+ import { bind as h, define as g, getHost as _, html as v, onCleanup as y, onMounted as b, prop as x, useEmit as ee, useField as S, useSlots as C } from "@vielzeug/ore";
11
+ import { computed as w, effect as T, signal as E, watch as te } from "@vielzeug/ripple";
12
12
  //#region src/inputs/select/select.ts
13
- var O = "ore-select";
14
- h(O, {
13
+ var D = "ore-select";
14
+ g(D, {
15
15
  formAssociated: !0,
16
16
  props: {
17
17
  ...u,
@@ -19,34 +19,36 @@ h(O, {
19
19
  ...o,
20
20
  ...s,
21
21
  ...c,
22
- error: b.string(),
23
- fullwidth: b.bool(!1),
24
- helper: b.string(),
25
- label: b.string(),
26
- "label-placement": b.oneOf(["inset", "outside"], "inset"),
27
- multiple: b.bool(!1),
28
- name: b.string(),
29
- options: b.json(void 0),
30
- placeholder: b.string(),
31
- required: b.bool(!1),
32
- success: b.bool(!1),
33
- value: b.string(),
34
- variant: b.string()
22
+ error: x.string(),
23
+ fullwidth: x.bool(!1),
24
+ helper: x.string(),
25
+ "hide-label": x.bool(!1),
26
+ label: x.string(),
27
+ "label-placement": x.oneOf(["inset", "outside"], "inset"),
28
+ multiple: x.bool(!1),
29
+ name: x.string(),
30
+ options: x.json(void 0),
31
+ placeholder: x.string(),
32
+ required: x.bool(!1),
33
+ success: x.bool(!1),
34
+ value: x.string(),
35
+ variant: x.string()
35
36
  },
36
37
  setup(e) {
37
- let t = g(), n = x(), o = C(), s = t.shadowRoot, c = E([]), l = w(() => !!e.loading.value);
38
+ let t = _(), n = ee(), o = C(), s = t.shadowRoot, c = E([]), l = w(() => !!e.loading.value);
38
39
  function u(e) {
39
40
  return {
40
41
  disabled: !!e.disabled,
42
+ disabledReason: e.disabledReason,
41
43
  group: e.group,
42
44
  label: e.label ?? e.value,
43
45
  value: e.value
44
46
  };
45
47
  }
46
- let p = w(() => {
48
+ let m = w(() => {
47
49
  let t = e.options.value;
48
50
  return Array.isArray(t) ? t.map(u) : c.value;
49
- }), h = null, b = null, O = i(v), k = r({
51
+ }), g = null, x = null, D = i(y), O = r({
50
52
  disabled: e.disabled,
51
53
  error: e.error,
52
54
  helper: e.helper,
@@ -55,49 +57,49 @@ h(O, {
55
57
  multiple: e.multiple,
56
58
  prefix: "select",
57
59
  required: e.required,
58
- signal: O,
60
+ signal: D,
59
61
  value: e.value
60
62
  });
61
- k.attachFormField(S({
62
- disabled: k.disabled,
63
- onReset: k.reset,
63
+ O.attachFormField(S({
64
+ disabled: O.disabled,
65
+ onReset: O.reset,
64
66
  toFormValue: (e) => e,
65
- validationMessage: k.validationMessage,
66
- validity: k.validity,
67
- value: k.formValue
67
+ validationMessage: O.validationMessage,
68
+ validity: O.validity,
69
+ value: O.formValue
68
70
  }));
69
- let A = a({
71
+ let k = a({
70
72
  getBoundary: () => t,
71
- getFocusedOptionElement: () => b?.querySelector("[data-focused]") ?? null,
72
- getItems: () => p.value,
73
- getPanel: () => b,
74
- getReference: () => h,
75
- getTrigger: () => h,
76
- isDisabled: () => k.disabled.value,
73
+ getFocusedOptionElement: () => x?.querySelector("[data-focused]") ?? null,
74
+ getItems: () => m.value,
75
+ getPanel: () => x,
76
+ getReference: () => g,
77
+ getTrigger: () => g,
78
+ isDisabled: () => O.disabled.value,
77
79
  isItemDisabled: (e) => e.disabled,
78
80
  onClose: (e) => {
79
81
  n("open-change", {
80
82
  open: !1,
81
83
  reason: e
82
- }), k.triggerValidation("blur");
84
+ }), O.triggerValidation("blur");
83
85
  },
84
86
  onOpen: (e) => n("open-change", {
85
87
  open: !0,
86
88
  reason: e
87
89
  }),
88
- signal: O
89
- }), { triggerValidation: j } = k, M = k.selectedValues, N = k.disabled;
90
- d(t, () => k.formValue.value, (e) => {
91
- k.setValues(e ? e.split(",") : []);
90
+ signal: D
91
+ }), { triggerValidation: A } = O, j = O.selectedValues, M = O.disabled;
92
+ d(t, () => O.formValue.value, (e) => {
93
+ O.setValues(e ? e.split(",") : []);
92
94
  });
93
- let { fieldId: P } = k, F = `listbox-${P}`, { focusedIndex: I, isOpen: L } = A;
94
- m({ attr: {
95
+ let { fieldId: N } = O, P = `listbox-${N}`, { focusedIndex: F, isOpen: I } = k;
96
+ h({ attr: {
95
97
  "has-error": () => e.error.value ? !0 : void 0,
96
- open: () => L.value ? !0 : void 0,
98
+ open: () => I.value ? !0 : void 0,
97
99
  size: e.size,
98
100
  variant: e.variant
99
101
  } });
100
- function R() {
102
+ function L() {
101
103
  let e = s?.querySelector("slot");
102
104
  if (!e) return;
103
105
  let t = e.assignedElements({ flatten: !0 }), n = [];
@@ -105,6 +107,7 @@ h(O, {
105
107
  let t = e;
106
108
  n.push({
107
109
  disabled: t.disabled,
110
+ disabledReason: t.dataset.disabledReason,
108
111
  label: t.text || t.value,
109
112
  value: t.value
110
113
  });
@@ -114,6 +117,7 @@ h(O, {
114
117
  let t = e;
115
118
  n.push({
116
119
  disabled: t.disabled,
120
+ disabledReason: t.dataset.disabledReason,
117
121
  group: r,
118
122
  label: t.text || t.value,
119
123
  value: t.value
@@ -122,16 +126,16 @@ h(O, {
122
126
  }
123
127
  c.value = n;
124
128
  }
125
- let z = w(() => {
126
- if (M.value.length === 0) return "";
127
- if (e.multiple.value && M.value.length > 1) return `${M.value.length} selected`;
128
- let t = M.value[0];
129
- return p.value.find((e) => e.value === t)?.label ?? t;
130
- }), B = w(() => e.multiple.value ? M.value.map((e) => ({
131
- label: p.value.find((t) => t.value === e)?.label ?? e,
129
+ let R = w(() => {
130
+ if (j.value.length === 0) return "";
131
+ if (e.multiple.value && j.value.length > 1) return `${j.value.length} selected`;
132
+ let t = j.value[0];
133
+ return m.value.find((e) => e.value === t)?.label ?? t;
134
+ }), z = w(() => e.multiple.value ? j.value.map((e) => ({
135
+ label: m.value.find((t) => t.value === e)?.label ?? e,
132
136
  value: e
133
- })) : []), V = w(() => e.multiple.value && M.value.length > 0), H = w(() => z.value || e.placeholder.value || "");
134
- function U(e) {
137
+ })) : []), B = w(() => e.multiple.value && j.value.length > 0), V = w(() => R.value || e.placeholder.value || "");
138
+ function H(e) {
135
139
  let t = [], n = /* @__PURE__ */ new Map();
136
140
  for (let t of e) {
137
141
  let e = t.group, r = n.get(e);
@@ -151,86 +155,87 @@ h(O, {
151
155
  }
152
156
  return t;
153
157
  }
154
- let W = w(() => U(p.value));
155
- function G() {
156
- ee(t, k.formValue.value), f(t, "input"), f(t, "change");
158
+ let U = w(() => H(m.value));
159
+ function W() {
160
+ p(t, O.formValue.value), f(t, "input"), f(t, "change");
157
161
  }
158
- function te(e) {
162
+ function G(e) {
159
163
  e.stopPropagation();
160
164
  let t = e.detail?.value;
161
- t !== void 0 && (k.removeValue(t), G(), j("change"));
165
+ t !== void 0 && (O.removeValue(t), W(), A("change"));
162
166
  }
163
167
  function K(e = "programmatic") {
164
- A.open(e), requestAnimationFrame(() => {
165
- let e = M.value.length > 0 ? p.value.findIndex((e) => e.value === M.value[0]) : -1;
168
+ k.open(e), requestAnimationFrame(() => {
169
+ let e = j.value.length > 0 ? m.value.findIndex((e) => e.value === j.value[0]) : -1;
166
170
  if (e >= 0) {
167
- A.set(e);
171
+ k.set(e);
168
172
  return;
169
173
  }
170
- A.navigate("first");
174
+ k.navigate("first");
171
175
  });
172
176
  }
173
177
  function q(t, n) {
174
- t.disabled || (e.multiple.value ? k.toggleValue(t.value) : (k.selectValue(t.value), A.close()), G(), j("change"));
178
+ t.disabled || (e.multiple.value ? O.toggleValue(t.value) : (O.selectValue(t.value), k.close()), W(), A("change"));
175
179
  }
176
180
  function J(e) {
177
- if (!N.value && !A.handleKeydown(e)) switch (e.key) {
181
+ if (!M.value && !k.handleKeydown(e)) switch (e.key) {
178
182
  case " ":
179
183
  case "Enter":
180
- if (e.preventDefault(), L.value) {
181
- let t = I.value, n = p.value;
184
+ if (e.preventDefault(), I.value) {
185
+ let t = F.value, n = m.value;
182
186
  t >= 0 && t < n.length && q(n[t], e);
183
187
  } else K("keyboard");
184
188
  break;
185
- case "Tab": A.close();
189
+ case "Tab": k.close();
186
190
  }
187
191
  }
188
- let Y = () => H.value, X = () => e.label.value ?? "", Z = () => e.placeholder.value ?? "", Q = () => e["label-placement"].value ?? "inset", ne = () => e.color?.value ?? void 0, re = () => e.size?.value ?? void 0, ie = () => e.variant?.value ?? void 0, ae = () => e.rounded?.value ?? void 0, oe = () => e.helper.value ?? "", $ = () => e.error.value ?? "", se = () => N.value ? !0 : void 0, ce = () => e.required.value ? !0 : void 0, le = () => e.fullwidth.value ? !0 : void 0, ue = () => N.value ? "-1" : "0";
189
- D(o.elements(), () => R(), { immediate: !0 });
190
- let de = T(() => {
191
- L.value ? b && "showPopover" in b && !b.matches(":popover-open") && b.showPopover() : b && "hidePopover" in b && b.matches(":popover-open") && b.hidePopover();
192
+ let Y = () => V.value, X = () => e["hide-label"].value, Z = () => X() ? "" : e.label.value ?? "", Q = () => X() ? e.label.value ?? "" : null, ne = () => e.placeholder.value ?? "", re = () => e["label-placement"].value ?? "inset", ie = () => e.color?.value ?? void 0, ae = () => e.size?.value ?? void 0, oe = () => e.variant?.value ?? void 0, $ = () => e.rounded?.value ?? void 0, se = () => e.helper.value ?? "", ce = () => e.error.value ?? "", le = () => M.value ? !0 : void 0, ue = () => e.required.value ? !0 : void 0, de = () => e.fullwidth.value ? !0 : void 0, fe = () => M.value ? "-1" : "0";
193
+ te(o.elements(), () => L(), { immediate: !0 });
194
+ let pe = T(() => {
195
+ I.value ? x && "showPopover" in x && !x.matches(":popover-open") && x.showPopover() : x && "hidePopover" in x && x.matches(":popover-open") && x.hidePopover();
192
196
  });
193
- return v(() => de.dispose()), y(() => {
197
+ return y(() => pe.dispose()), b(() => {
194
198
  let e = null, t = null;
195
- return h && (e = (e) => {
196
- e.stopPropagation(), !N.value && (L.value ? A.close("trigger") : K("click"));
199
+ return g && (e = (e) => {
200
+ e.stopPropagation(), !M.value && (I.value ? k.close("trigger") : K("click"));
197
201
  }, t = (e) => {
198
202
  J(e);
199
- }, h.addEventListener("click", e), h.addEventListener("keydown", t)), () => {
200
- h && e && h.removeEventListener("click", e), h && t && h.removeEventListener("keydown", t);
203
+ }, g.addEventListener("click", e), g.addEventListener("keydown", t)), () => {
204
+ g && e && g.removeEventListener("click", e), g && t && g.removeEventListener("keydown", t);
201
205
  };
202
- }), _`
206
+ }), v`
203
207
  <slot style="display:none"></slot>
204
208
  <ore-input
205
209
  class="trigger"
206
210
  part="trigger"
207
211
  readonly
208
- tabindex="${ue}"
212
+ tabindex="${fe}"
209
213
  role="combobox"
210
214
  aria-haspopup="listbox"
211
- aria-controls="${F}"
212
- aria-disabled="${() => N.value ? "true" : null}"
213
- aria-expanded="${() => String(L.value)}"
215
+ aria-controls="${P}"
216
+ aria-label="${Q}"
217
+ aria-disabled="${() => M.value ? "true" : null}"
218
+ aria-expanded="${() => String(I.value)}"
214
219
  aria-invalid="${() => e.error.value ? "true" : null}"
215
220
  value="${Y}"
216
- label="${X}"
217
- placeholder="${Z}"
218
- label-placement="${Q}"
219
- color="${ne}"
220
- size="${re}"
221
- variant="${ie}"
222
- rounded="${ae}"
223
- helper="${oe}"
224
- error="${$}"
225
- ?disabled="${se}"
226
- ?required="${ce}"
227
- ?fullwidth="${le}"
221
+ label="${Z}"
222
+ placeholder="${ne}"
223
+ label-placement="${re}"
224
+ color="${ie}"
225
+ size="${ae}"
226
+ variant="${oe}"
227
+ rounded="${$}"
228
+ helper="${se}"
229
+ error="${ce}"
230
+ ?disabled="${le}"
231
+ ?required="${ue}"
232
+ ?fullwidth="${de}"
228
233
  ?success="${() => e.success.value}"
229
234
  ref="${(e) => {
230
- h = e;
235
+ g = e;
231
236
  }}">
232
- <div slot="prefix" class="chips-row" ?hidden="${() => !V.value}">
233
- ${() => B.value.map((t) => _`
237
+ <div slot="prefix" class="chips-row" ?hidden="${() => !B.value}">
238
+ ${() => z.value.map((t) => v`
234
239
  <ore-chip
235
240
  value="${t.value}"
236
241
  label="${t.label}"
@@ -238,7 +243,7 @@ h(O, {
238
243
  variant="flat"
239
244
  size="sm"
240
245
  color="${e.color}"
241
- @remove="${te}">
246
+ @remove="${G}">
242
247
  ${t.label}
243
248
  </ore-chip>
244
249
  `)}
@@ -254,37 +259,38 @@ h(O, {
254
259
  class="dropdown"
255
260
  part="dropdown"
256
261
  popover="manual"
257
- ?data-open="${L}"
262
+ ?data-open="${I}"
258
263
  role="listbox"
259
- id="${F}"
264
+ id="${P}"
260
265
  aria-label="Options"
261
266
  ref="${(e) => {
262
- b = e;
267
+ x = e;
263
268
  }}">
264
269
  <div class="dropdown-loading" ?hidden="${() => !l.value}">Loading…</div>
265
- <div class="dropdown-empty" ?hidden="${() => l.value || p.value.length > 0}">No options</div>
266
- <div class="options-list" ?hidden="${() => l.value || p.value.length === 0}">
267
- ${() => W.value.map((e) => e.type === "group" ? _`
270
+ <div class="dropdown-empty" ?hidden="${() => l.value || m.value.length > 0}">No options</div>
271
+ <div class="options-list" ?hidden="${() => l.value || m.value.length === 0}">
272
+ ${() => U.value.map((e) => e.type === "group" ? v`
268
273
  <div class="optgroup-label" role="presentation">${e.label}</div>
269
- ` : _`
274
+ ` : v`
270
275
  <div
271
276
  class="option"
272
277
  role="option"
273
- id="${`${P}-opt-${e.idx}`}"
278
+ id="${`${N}-opt-${e.idx}`}"
274
279
  data-option-index="${String(e.idx)}"
275
280
  data-option-value="${e.opt.value}"
276
- aria-selected="${() => String(M.value.includes(e.opt.value))}"
281
+ aria-selected="${() => String(j.value.includes(e.opt.value))}"
277
282
  aria-disabled="${() => String(e.opt.disabled)}"
278
- ?data-focused="${() => I.value === e.idx}"
279
- ?data-selected="${() => M.value.includes(e.opt.value)}"
283
+ ?data-focused="${() => F.value === e.idx}"
284
+ ?data-selected="${() => j.value.includes(e.opt.value)}"
280
285
  ?data-disabled="${() => e.opt.disabled}"
281
286
  @click="${(t) => {
282
287
  t.stopPropagation(), q(e.opt, t);
283
288
  }}"
284
289
  @pointerenter="${() => {
285
- A.set(e.idx);
290
+ k.set(e.idx);
286
291
  }}">
287
292
  <span>${e.opt.label}</span>
293
+ ${e.opt.disabled && e.opt.disabledReason ? v`<small class="disabled-reason" title="${e.opt.disabledReason}">${e.opt.disabledReason}</small>` : v``}
288
294
  <span class="option-check" aria-hidden="true">
289
295
  <ore-icon name="check" size="14" stroke-width="2.5" aria-hidden="true"></ore-icon>
290
296
  </span>
@@ -299,10 +305,10 @@ h(O, {
299
305
  n,
300
306
  e,
301
307
  t,
302
- p
308
+ m
303
309
  ]
304
310
  });
305
311
  //#endregion
306
- export { O as SELECT_TAG };
312
+ export { D as SELECT_TAG };
307
313
 
308
314
  //# sourceMappingURL=select.js.map