@data-slot/combobox 0.2.43 → 0.2.45

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.
package/README.md CHANGED
@@ -102,6 +102,7 @@ Options can be passed via JavaScript or data attributes (JS takes precedence).
102
102
  | `openOnFocus` | `data-open-on-focus` | `boolean` | `true` | Open popup when input is focused |
103
103
  | `autoHighlight` | `data-auto-highlight` | `boolean` | `true` | Auto-highlight first visible item when filtering |
104
104
  | `filter` | - | `function` | substring | Custom filter function |
105
+ | `itemToStringValue` | - | `(item: HTMLElement \| null, value: string \| null) => string` | item label | Custom text resolver for selected value shown in input |
105
106
  | `side` | `data-side` | `"top" \| "bottom"` | `"bottom"` | Popup placement |
106
107
  | `align` | `data-align` | `"start" \| "center" \| "end"` | `"start"` | Popup alignment |
107
108
  | `sideOffset` | `data-side-offset` | `number` | `4` | Distance from input (px) |
@@ -128,6 +129,7 @@ interface ComboboxController {
128
129
  clear(): void; // Clear selection
129
130
  open(): void; // Open the popup
130
131
  close(): void; // Close the popup
132
+ setItemToStringValue(itemToStringValue: ((item: HTMLElement | null, value: string | null) => string) | null): void;
131
133
  destroy(): void; // Cleanup
132
134
  }
133
135
  ```
@@ -162,6 +164,11 @@ root.dispatchEvent(new CustomEvent('combobox:set', {
162
164
  root.dispatchEvent(new CustomEvent('combobox:set', {
163
165
  detail: { open: true }
164
166
  }));
167
+
168
+ // Set runtime selected-value text formatter
169
+ root.dispatchEvent(new CustomEvent('combobox:set', {
170
+ detail: { itemToStringValue: (item, value) => value ? value.toUpperCase() : '' }
171
+ }));
165
172
  ```
166
173
 
167
174
  ## Keyboard Navigation
@@ -3,6 +3,7 @@
3
3
  type Side = "top" | "bottom";
4
4
  /** Alignment of the content relative to the input */
5
5
  type Align = "start" | "center" | "end";
6
+ type ComboboxItemToStringValue = (item: HTMLElement | null, value: string | null) => string;
6
7
  interface ComboboxOptions {
7
8
  /** Initial selected value */
8
9
  defaultValue?: string;
@@ -28,6 +29,8 @@ interface ComboboxOptions {
28
29
  autoHighlight?: boolean;
29
30
  /** Custom filter function. Return true to show item. */
30
31
  filter?: (inputValue: string, itemValue: string, itemLabel: string) => boolean;
32
+ /** Custom text resolver for the selected value shown in the input */
33
+ itemToStringValue?: ComboboxItemToStringValue;
31
34
  /** @default "bottom" */
32
35
  side?: Side;
33
36
  /** @default "start" */
@@ -56,6 +59,8 @@ interface ComboboxController {
56
59
  open(): void;
57
60
  /** Close the popup */
58
61
  close(): void;
62
+ /** Set or clear runtime selected-value text resolver */
63
+ setItemToStringValue(itemToStringValue: ComboboxItemToStringValue | null): void;
59
64
  /** Cleanup all event listeners */
60
65
  destroy(): void;
61
66
  }
@@ -70,7 +75,7 @@ interface ComboboxController {
70
75
  * - **Outbound** `combobox:input-change` (on root): Fires when user types.
71
76
  * `event.detail: { inputValue: string }`
72
77
  * - **Inbound** `combobox:set` (on root): Set value, open state, or input value.
73
- * `event.detail: { value?: string | null, open?: boolean, inputValue?: string }`
78
+ * `event.detail: { value?: string | null, open?: boolean, inputValue?: string, itemToStringValue?: ComboboxItemToStringValue | null }`
74
79
  */
75
80
  declare function createCombobox(root: Element, options?: ComboboxOptions): ComboboxController;
76
81
  /**
@@ -79,4 +84,4 @@ declare function createCombobox(root: Element, options?: ComboboxOptions): Combo
79
84
  */
80
85
  declare function create(scope?: ParentNode): ComboboxController[];
81
86
  //#endregion
82
- export { Align, ComboboxController, ComboboxOptions, Side, create, createCombobox };
87
+ export { Align, ComboboxController, ComboboxItemToStringValue, ComboboxOptions, Side, create, createCombobox };
@@ -3,6 +3,7 @@
3
3
  type Side = "top" | "bottom";
4
4
  /** Alignment of the content relative to the input */
5
5
  type Align = "start" | "center" | "end";
6
+ type ComboboxItemToStringValue = (item: HTMLElement | null, value: string | null) => string;
6
7
  interface ComboboxOptions {
7
8
  /** Initial selected value */
8
9
  defaultValue?: string;
@@ -28,6 +29,8 @@ interface ComboboxOptions {
28
29
  autoHighlight?: boolean;
29
30
  /** Custom filter function. Return true to show item. */
30
31
  filter?: (inputValue: string, itemValue: string, itemLabel: string) => boolean;
32
+ /** Custom text resolver for the selected value shown in the input */
33
+ itemToStringValue?: ComboboxItemToStringValue;
31
34
  /** @default "bottom" */
32
35
  side?: Side;
33
36
  /** @default "start" */
@@ -56,6 +59,8 @@ interface ComboboxController {
56
59
  open(): void;
57
60
  /** Close the popup */
58
61
  close(): void;
62
+ /** Set or clear runtime selected-value text resolver */
63
+ setItemToStringValue(itemToStringValue: ComboboxItemToStringValue | null): void;
59
64
  /** Cleanup all event listeners */
60
65
  destroy(): void;
61
66
  }
@@ -70,7 +75,7 @@ interface ComboboxController {
70
75
  * - **Outbound** `combobox:input-change` (on root): Fires when user types.
71
76
  * `event.detail: { inputValue: string }`
72
77
  * - **Inbound** `combobox:set` (on root): Set value, open state, or input value.
73
- * `event.detail: { value?: string | null, open?: boolean, inputValue?: string }`
78
+ * `event.detail: { value?: string | null, open?: boolean, inputValue?: string, itemToStringValue?: ComboboxItemToStringValue | null }`
74
79
  */
75
80
  declare function createCombobox(root: Element, options?: ComboboxOptions): ComboboxController;
76
81
  /**
@@ -79,4 +84,4 @@ declare function createCombobox(root: Element, options?: ComboboxOptions): Combo
79
84
  */
80
85
  declare function create(scope?: ParentNode): ComboboxController[];
81
86
  //#endregion
82
- export { Align, ComboboxController, ComboboxOptions, Side, create, createCombobox };
87
+ export { Align, ComboboxController, ComboboxItemToStringValue, ComboboxOptions, Side, create, createCombobox };
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require(`@data-slot/core`);const t=[`top`,`bottom`],n=[`start`,`center`,`end`];function r(r,a={}){let o=(0,e.getPart)(r,`combobox-input`),s=(0,e.getPart)(r,`combobox-content`),c=(0,e.getPart)(r,`combobox-list`)??(0,e.getPart)(s??r,`combobox-list`),l=(0,e.getPart)(r,`combobox-trigger`),u=(0,e.getPart)(c??s??r,`combobox-empty`);if(!o||!s)throw Error(`Combobox requires combobox-input and combobox-content slots`);let ee=a.defaultValue??(0,e.getDataString)(r,`defaultValue`)??null,d=a.defaultOpen??(0,e.getDataBool)(r,`defaultOpen`)??!1,f=a.placeholder??(0,e.getDataString)(r,`placeholder`)??``,p=a.disabled??(0,e.getDataBool)(r,`disabled`)??!1,m=a.required??(0,e.getDataBool)(r,`required`)??!1,h=a.name??(0,e.getDataString)(r,`name`)??null,te=a.openOnFocus??(0,e.getDataBool)(r,`openOnFocus`)??!0,g=a.autoHighlight??(0,e.getDataBool)(r,`autoHighlight`)??!0,_=a.filter??null,ne=a.onValueChange,re=a.onOpenChange,ie=a.onInputValueChange,v=a.side??(0,e.getDataEnum)(s,`side`,t)??(0,e.getDataEnum)(r,`side`,t)??`bottom`,y=a.align??(0,e.getDataEnum)(s,`align`,n)??(0,e.getDataEnum)(r,`align`,n)??`start`,ae=a.sideOffset??(0,e.getDataNumber)(s,`sideOffset`)??(0,e.getDataNumber)(r,`sideOffset`)??4,oe=a.alignOffset??(0,e.getDataNumber)(s,`alignOffset`)??(0,e.getDataNumber)(r,`alignOffset`)??0,se=a.avoidCollisions??(0,e.getDataBool)(s,`avoidCollisions`)??(0,e.getDataBool)(r,`avoidCollisions`)??!0,ce=a.collisionPadding??(0,e.getDataNumber)(s,`collisionPadding`)??(0,e.getDataNumber)(r,`collisionPadding`)??8,b=!1,x=ee,S=-1,C=!1,w=[],T=[],E=[],D=[],O=new Map,k=null,A=(0,e.createPortalLifecycle)({content:s,root:r,wrapperSlot:`combobox-positioner`}),j=!1,M=e=>e.hasAttribute(`disabled`)||e.hasAttribute(`data-disabled`)||e.getAttribute(`aria-disabled`)===`true`,N=e=>{if(e.dataset.label)return e.dataset.label;let t=``;for(let n of e.childNodes)n.nodeType===Node.TEXT_NODE&&(t+=n.textContent);return t.trim()||(e.textContent?.trim()??``)},P=e=>e.hasAttribute(`data-value`)?e.getAttribute(`data-value`):void 0,F=t=>{if(t===null)return``;let n=(0,e.getParts)(c??s,`combobox-item`).find(e=>P(e)===t);return n?N(n):``},le=(0,e.ensureId)(o,`combobox-input`),I=c??s,L=(0,e.ensureId)(I,`combobox-list`);o.setAttribute(`role`,`combobox`),o.setAttribute(`aria-autocomplete`,`list`),o.setAttribute(`autocomplete`,`off`),o.setAttribute(`aria-controls`,L),c?c.setAttribute(`role`,`listbox`):s.setAttribute(`role`,`listbox`),l&&(l.hasAttribute(`type`)||l.setAttribute(`type`,`button`),l.tabIndex=-1,l.setAttribute(`aria-label`,`Toggle`));let R=document.querySelector(`label[for="${CSS.escape(le)}"]`);if(R){let t=(0,e.ensureId)(R,`combobox-label`),n=o.getAttribute(`aria-labelledby`);o.setAttribute(`aria-labelledby`,n?`${n} ${t}`:t),I.setAttribute(`aria-labelledby`,t)}p&&(o.setAttribute(`aria-disabled`,`true`),o.disabled=!0,l&&(l.setAttribute(`aria-disabled`,`true`),l.setAttribute(`data-disabled`,``))),m&&(o.setAttribute(`aria-required`,`true`),o.required=!0);let z=()=>{m&&o.setCustomValidity(x===null?`Please select a value`:``)};f&&(o.placeholder=f),h&&(o.name&&o.removeAttribute(`name`),k=document.createElement(`input`),k.type=`hidden`,k.name=h,k.value=x??``,r.appendChild(k));let B=_??((e,t,n)=>n.toLowerCase().includes(e.toLowerCase())),V=()=>{let t=c??s;T=(0,e.getParts)(t,`combobox-item`);for(let t of T)t.setAttribute(`role`,`option`),(0,e.ensureId)(t,`combobox-item`),M(t)?t.setAttribute(`aria-disabled`,`true`):t.removeAttribute(`aria-disabled`),P(t)===x?((0,e.setAria)(t,`selected`,!0),t.setAttribute(`data-selected`,``)):((0,e.setAria)(t,`selected`,!1),t.removeAttribute(`data-selected`));let n=(0,e.getParts)(t,`combobox-group`);for(let t of n){t.setAttribute(`role`,`group`);let n=(0,e.getPart)(t,`combobox-label`);if(n){let r=(0,e.ensureId)(n,`combobox-label`);t.setAttribute(`aria-labelledby`,r)}}H()},H=()=>{E=T.filter(e=>!e.hidden),D=E.filter(e=>!M(e)),O=new Map(D.map((e,t)=>[e,t]))},U=(e,t)=>{let n=t===`previous`?e.previousElementSibling:e.nextElementSibling;for(;n;){if(n instanceof HTMLElement&&!n.hidden&&n.dataset.slot!==`combobox-separator`)return!0;n=t===`previous`?n.previousElementSibling:n.nextElementSibling}return!1},W=t=>{let n=c??s,r=t.trim(),i=0;for(let e of T){let t=P(e)??``,n=N(e),a=r===``||B(r,t,n);e.hidden=!a,a&&i++}let a=(0,e.getParts)(n,`combobox-group`);for(let t of a)t.hidden=!(0,e.getParts)(t,`combobox-item`).some(e=>!e.hidden);let o=(0,e.getParts)(n,`combobox-separator`);for(let e of o)e.hidden=!U(e,`previous`)||!U(e,`next`);u&&(u.hidden=i>0),i===0?s.setAttribute(`data-empty`,``):s.removeAttribute(`data-empty`),H()},G=()=>{let n=A.container,i=r.ownerDocument.defaultView??window,a=r.getBoundingClientRect();s.style.minWidth=`${a.width}px`;let o=(0,e.computeFloatingPosition)({anchorRect:a,contentRect:s.getBoundingClientRect(),side:v,align:y,sideOffset:ae,alignOffset:oe,avoidCollisions:se,collisionPadding:ce,allowedSides:t});n.style.position=`absolute`,n.style.top=`0px`,n.style.left=`0px`,n.style.transform=`translate3d(${o.x+i.scrollX}px, ${o.y+i.scrollY}px, 0)`,n.style.willChange=`transform`,n.style.margin=`0`,s.setAttribute(`data-side`,o.side),s.setAttribute(`data-align`,o.align),n!==s&&(n.setAttribute(`data-side`,o.side),n.setAttribute(`data-align`,o.align))},K=(0,e.createPositionSync)({observedElements:[r,s],isActive:()=>b,ancestorScroll:!1,onUpdate:G,ignoreScrollTarget:e=>e instanceof Node&&s.contains(e)}),ue=e=>c&&c.contains(e)&&c.scrollHeight>c.clientHeight?c:s,q=t=>{for(let n=0;n<D.length;n++){let r=D[n];n===t?(r.setAttribute(`data-highlighted`,``),o.setAttribute(`aria-activedescendant`,r.id),(0,e.ensureItemVisibleInContainer)(r,ue(r))):r.removeAttribute(`data-highlighted`)}S=t},J=()=>{for(let e of T)e.removeAttribute(`data-highlighted`);S=-1,o.removeAttribute(`aria-activedescendant`)},Y=e=>{r.setAttribute(`data-state`,e),s.setAttribute(`data-state`,e),l&&l.setAttribute(`data-state`,e),e===`open`?(r.setAttribute(`data-open`,``),s.setAttribute(`data-open`,``),l&&l.setAttribute(`data-open`,``),r.removeAttribute(`data-closed`),s.removeAttribute(`data-closed`),l&&l.removeAttribute(`data-closed`)):(r.setAttribute(`data-closed`,``),s.setAttribute(`data-closed`,``),l&&l.setAttribute(`data-closed`,``),r.removeAttribute(`data-open`),s.removeAttribute(`data-open`),l&&l.removeAttribute(`data-open`))},X=(0,e.createPresenceLifecycle)({element:s,onExitComplete:()=>{j||(A.restore(),s.hidden=!0)}}),Z=(t,n=!1)=>{if(b!==t&&!(p&&t)){if(t){b=!0,(0,e.setAria)(o,`expanded`,!0),A.mount(),s.hidden=!1,Y(`open`),X.enter(),V(),C=!1,W(o.value);let t=D.findIndex(e=>P(e)===x);t>=0?q(t):g&&D.length>0?q(0):J(),K.start(),G(),K.update(),requestAnimationFrame(()=>{b&&K.update()})}else b=!1,(0,e.setAria)(o,`expanded`,!1),Y(`closed`),J(),C=!1,K.stop(),X.exit(),o.value=F(x);(0,e.emit)(r,`combobox:open-change`,{open:b}),re?.(b)}},Q=(t,n=!1)=>{if(x===t&&!n)return;let i=x;x=t,z(),k&&(k.value=t??``),t===null?r.removeAttribute(`data-value`):r.setAttribute(`data-value`,t);let a=c??s,l=T.length>0?T:(0,e.getParts)(a,`combobox-item`);for(let n of l)P(n)===t?((0,e.setAria)(n,`selected`,!0),n.setAttribute(`data-selected`,``)):((0,e.setAria)(n,`selected`,!1),n.removeAttribute(`data-selected`));o.value=F(t),!n&&i!==t&&((0,e.emit)(r,`combobox:change`,{value:t}),ne?.(t))},$=e=>{if(M(e))return;let t=P(e);t!==void 0&&(Q(t),Z(!1))};return(0,e.setAria)(o,`expanded`,!1),s.hidden=!0,Y(`closed`),Q(x,!0),w.push((0,e.on)(o,`input`,()=>{let t=o.value;(0,e.emit)(r,`combobox:input-change`,{inputValue:t}),ie?.(t),b?(W(t),g&&D.length>0?q(0):J(),K.update()):Z(!0)}),(0,e.on)(o,`keydown`,e=>{if(!p)switch(e.key){case`ArrowDown`:{if(e.preventDefault(),!b){Z(!0);return}C=!0;let t=D.length;if(t===0)return;q(S===-1?0:(S+1)%t);break}case`ArrowUp`:{if(e.preventDefault(),!b){Z(!0);return}C=!0;let t=D.length;if(t===0)return;q(S===-1?t-1:(S-1+t)%t);break}case`Home`:if(!b)return;e.preventDefault(),C=!0,D.length>0&&q(0);break;case`End`:if(!b)return;e.preventDefault(),C=!0,D.length>0&&q(D.length-1);break;case`Enter`:if(!b)return;e.preventDefault(),S>=0&&S<D.length&&$(D[S]);break;case`Escape`:b?(e.preventDefault(),Z(!1)):x!==null&&(e.preventDefault(),Q(null));break;case`Tab`:b&&Z(!1,!0);break}}),(0,e.on)(o,`focus`,()=>{p||(o.select(),te&&!b&&Z(!0))})),l&&w.push((0,e.on)(l,`click`,()=>{p||(b?Z(!1):(Z(!0),o.focus()))})),w.push((0,e.on)(s,`click`,e=>{let t=e.target.closest?.(`[data-slot="combobox-item"]`);t&&!t.hidden&&$(t)}),(0,e.on)(s,`pointermove`,e=>{let t=e.target.closest?.(`[data-slot="combobox-item"]`);if(!(C&&(C=!1,t&&O.get(t)===S)))if(t&&!M(t)&&!t.hidden){let e=O.get(t);e!==void 0&&e!==S&&q(e)}else J()}),(0,e.on)(s,`pointerleave`,()=>{C||J()}),(0,e.on)(s,`mousedown`,e=>{e.preventDefault()})),w.push((0,e.createDismissLayer)({root:r,isOpen:()=>b,onDismiss:()=>Z(!1),closeOnClickOutside:!0,closeOnEscape:!1})),w.push((0,e.on)(r,`combobox:set`,e=>{let t=e.detail;t?.value!==void 0&&Q(t.value),t?.open!==void 0&&Z(t.open),t?.inputValue!==void 0&&(o.value=t.inputValue)})),d&&Z(!0),{get value(){return x},get inputValue(){return o.value},get isOpen(){return b},select:e=>Q(e),clear:()=>Q(null),open:()=>Z(!0),close:()=>Z(!1),destroy:()=>{j=!0,K.stop(),X.cleanup(),A.cleanup(),w.forEach(e=>e()),w.length=0,k&&k.parentNode&&k.parentNode.removeChild(k),i.delete(r)}}}const i=new WeakSet;function a(t=document){let n=[];for(let a of(0,e.getRoots)(t,`combobox`))i.has(a)||(i.add(a),n.push(r(a)));return n}exports.create=a,exports.createCombobox=r;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require(`@data-slot/core`);const t=[`top`,`bottom`],n=[`start`,`center`,`end`];function r(r,a={}){let o=(0,e.getPart)(r,`combobox-input`),s=(0,e.getPart)(r,`combobox-content`),c=(0,e.getPart)(r,`combobox-list`)??(0,e.getPart)(s??r,`combobox-list`),l=(0,e.getPart)(r,`combobox-trigger`),u=(0,e.getPart)(c??s??r,`combobox-empty`);if(!o||!s)throw Error(`Combobox requires combobox-input and combobox-content slots`);let ee=a.defaultValue??(0,e.getDataString)(r,`defaultValue`)??null,d=a.defaultOpen??(0,e.getDataBool)(r,`defaultOpen`)??!1,f=a.placeholder??(0,e.getDataString)(r,`placeholder`)??``,p=a.disabled??(0,e.getDataBool)(r,`disabled`)??!1,m=a.required??(0,e.getDataBool)(r,`required`)??!1,h=a.name??(0,e.getDataString)(r,`name`)??null,te=a.openOnFocus??(0,e.getDataBool)(r,`openOnFocus`)??!0,g=a.autoHighlight??(0,e.getDataBool)(r,`autoHighlight`)??!0,ne=a.filter??null,re=a.onValueChange,_=a.onOpenChange,ie=a.onInputValueChange,v=a.itemToStringValue??null,ae=a.side??(0,e.getDataEnum)(s,`side`,t)??(0,e.getDataEnum)(r,`side`,t)??`bottom`,oe=a.align??(0,e.getDataEnum)(s,`align`,n)??(0,e.getDataEnum)(r,`align`,n)??`start`,se=a.sideOffset??(0,e.getDataNumber)(s,`sideOffset`)??(0,e.getDataNumber)(r,`sideOffset`)??4,y=a.alignOffset??(0,e.getDataNumber)(s,`alignOffset`)??(0,e.getDataNumber)(r,`alignOffset`)??0,ce=a.avoidCollisions??(0,e.getDataBool)(s,`avoidCollisions`)??(0,e.getDataBool)(r,`avoidCollisions`)??!0,le=a.collisionPadding??(0,e.getDataNumber)(s,`collisionPadding`)??(0,e.getDataNumber)(r,`collisionPadding`)??8,b=!1,x=ee,S=-1,C=!1,w=[],T=[],E=[],D=[],O=new Map,k=null,A=(0,e.createPortalLifecycle)({content:s,root:r,wrapperSlot:`combobox-positioner`}),j=!1,M=e=>e.hasAttribute(`disabled`)||e.hasAttribute(`data-disabled`)||e.getAttribute(`aria-disabled`)===`true`,N=e=>{if(e.dataset.label)return e.dataset.label;let t=``;for(let n of e.childNodes)n.nodeType===Node.TEXT_NODE&&(t+=n.textContent);return t.trim()||(e.textContent?.trim()??``)},P=e=>e.hasAttribute(`data-value`)?e.getAttribute(`data-value`):void 0,ue=t=>t===null?null:(0,e.getParts)(c??s,`combobox-item`).find(e=>P(e)===t)??null,F=e=>{let t=ue(e);return v?v(t,e):t?N(t):``},de=(0,e.ensureId)(o,`combobox-input`),I=c??s,L=(0,e.ensureId)(I,`combobox-list`);o.setAttribute(`role`,`combobox`),o.setAttribute(`aria-autocomplete`,`list`),o.setAttribute(`autocomplete`,`off`),o.setAttribute(`aria-controls`,L),c?c.setAttribute(`role`,`listbox`):s.setAttribute(`role`,`listbox`),l&&(l.hasAttribute(`type`)||l.setAttribute(`type`,`button`),l.tabIndex=-1,l.setAttribute(`aria-label`,`Toggle`));let R=document.querySelector(`label[for="${CSS.escape(de)}"]`);if(R){let t=(0,e.ensureId)(R,`combobox-label`),n=o.getAttribute(`aria-labelledby`);o.setAttribute(`aria-labelledby`,n?`${n} ${t}`:t),I.setAttribute(`aria-labelledby`,t)}p&&(o.setAttribute(`aria-disabled`,`true`),o.disabled=!0,l&&(l.setAttribute(`aria-disabled`,`true`),l.setAttribute(`data-disabled`,``))),m&&(o.setAttribute(`aria-required`,`true`),o.required=!0);let z=()=>{m&&o.setCustomValidity(x===null?`Please select a value`:``)};f&&(o.placeholder=f),h&&(o.name&&o.removeAttribute(`name`),k=document.createElement(`input`),k.type=`hidden`,k.name=h,k.value=x??``,r.appendChild(k));let B=ne??((e,t,n)=>n.toLowerCase().includes(e.toLowerCase())),V=()=>{let t=c??s;T=(0,e.getParts)(t,`combobox-item`);for(let t of T)t.setAttribute(`role`,`option`),(0,e.ensureId)(t,`combobox-item`),M(t)?t.setAttribute(`aria-disabled`,`true`):t.removeAttribute(`aria-disabled`),P(t)===x?((0,e.setAria)(t,`selected`,!0),t.setAttribute(`data-selected`,``)):((0,e.setAria)(t,`selected`,!1),t.removeAttribute(`data-selected`));let n=(0,e.getParts)(t,`combobox-group`);for(let t of n){t.setAttribute(`role`,`group`);let n=(0,e.getPart)(t,`combobox-label`);if(n){let r=(0,e.ensureId)(n,`combobox-label`);t.setAttribute(`aria-labelledby`,r)}}H()},H=()=>{E=T.filter(e=>!e.hidden),D=E.filter(e=>!M(e)),O=new Map(D.map((e,t)=>[e,t]))},U=(e,t)=>{let n=t===`previous`?e.previousElementSibling:e.nextElementSibling;for(;n;){if(n instanceof HTMLElement&&!n.hidden&&n.dataset.slot!==`combobox-separator`)return!0;n=t===`previous`?n.previousElementSibling:n.nextElementSibling}return!1},W=t=>{let n=c??s,r=t.trim(),i=0;for(let e of T){let t=P(e)??``,n=N(e),a=r===``||B(r,t,n);e.hidden=!a,a&&i++}let a=(0,e.getParts)(n,`combobox-group`);for(let t of a)t.hidden=!(0,e.getParts)(t,`combobox-item`).some(e=>!e.hidden);let o=(0,e.getParts)(n,`combobox-separator`);for(let e of o)e.hidden=!U(e,`previous`)||!U(e,`next`);u&&(u.hidden=i>0),i===0?s.setAttribute(`data-empty`,``):s.removeAttribute(`data-empty`),H()},G=()=>{let n=A.container,i=r.ownerDocument.defaultView??window,a=r.getBoundingClientRect();s.style.minWidth=`${a.width}px`;let o=(0,e.computeFloatingPosition)({anchorRect:a,contentRect:s.getBoundingClientRect(),side:ae,align:oe,sideOffset:se,alignOffset:y,avoidCollisions:ce,collisionPadding:le,allowedSides:t});n.style.position=`absolute`,n.style.top=`0px`,n.style.left=`0px`,n.style.transform=`translate3d(${o.x+i.scrollX}px, ${o.y+i.scrollY}px, 0)`,n.style.willChange=`transform`,n.style.margin=`0`,s.setAttribute(`data-side`,o.side),s.setAttribute(`data-align`,o.align),n!==s&&(n.setAttribute(`data-side`,o.side),n.setAttribute(`data-align`,o.align))},K=(0,e.createPositionSync)({observedElements:[r,s],isActive:()=>b,ancestorScroll:!1,onUpdate:G,ignoreScrollTarget:e=>e instanceof Node&&s.contains(e)}),fe=e=>c&&c.contains(e)&&c.scrollHeight>c.clientHeight?c:s,q=t=>{for(let n=0;n<D.length;n++){let r=D[n];n===t?(r.setAttribute(`data-highlighted`,``),o.setAttribute(`aria-activedescendant`,r.id),(0,e.ensureItemVisibleInContainer)(r,fe(r))):r.removeAttribute(`data-highlighted`)}S=t},J=()=>{for(let e of T)e.removeAttribute(`data-highlighted`);S=-1,o.removeAttribute(`aria-activedescendant`)},Y=e=>{r.setAttribute(`data-state`,e),s.setAttribute(`data-state`,e),l&&l.setAttribute(`data-state`,e),e===`open`?(r.setAttribute(`data-open`,``),s.setAttribute(`data-open`,``),l&&l.setAttribute(`data-open`,``),r.removeAttribute(`data-closed`),s.removeAttribute(`data-closed`),l&&l.removeAttribute(`data-closed`)):(r.setAttribute(`data-closed`,``),s.setAttribute(`data-closed`,``),l&&l.setAttribute(`data-closed`,``),r.removeAttribute(`data-open`),s.removeAttribute(`data-open`),l&&l.removeAttribute(`data-open`))},X=(0,e.createPresenceLifecycle)({element:s,onExitComplete:()=>{j||(A.restore(),s.hidden=!0)}}),Z=(t,n=!1)=>{if(b!==t&&!(p&&t)){if(t){b=!0,(0,e.setAria)(o,`expanded`,!0),A.mount(),s.hidden=!1,Y(`open`),X.enter(),V(),C=!1,W(o.value);let t=D.findIndex(e=>P(e)===x);t>=0?q(t):g&&D.length>0?q(0):J(),K.start(),G(),K.update(),requestAnimationFrame(()=>{b&&K.update()})}else b=!1,(0,e.setAria)(o,`expanded`,!1),Y(`closed`),J(),C=!1,K.stop(),X.exit(),o.value=F(x);(0,e.emit)(r,`combobox:open-change`,{open:b}),_?.(b)}},Q=(t,n=!1)=>{if(x===t&&!n)return;let i=x;x=t,z(),k&&(k.value=t??``),t===null?r.removeAttribute(`data-value`):r.setAttribute(`data-value`,t);let a=c??s,l=T.length>0?T:(0,e.getParts)(a,`combobox-item`);for(let n of l)P(n)===t?((0,e.setAria)(n,`selected`,!0),n.setAttribute(`data-selected`,``)):((0,e.setAria)(n,`selected`,!1),n.removeAttribute(`data-selected`));o.value=F(t),!n&&i!==t&&((0,e.emit)(r,`combobox:change`,{value:t}),re?.(t))},$=e=>{if(M(e))return;let t=P(e);t!==void 0&&(Q(t),Z(!1))};return(0,e.setAria)(o,`expanded`,!1),s.hidden=!0,Y(`closed`),Q(x,!0),w.push((0,e.on)(o,`input`,()=>{let t=o.value;(0,e.emit)(r,`combobox:input-change`,{inputValue:t}),ie?.(t),b?(W(t),g&&D.length>0?q(0):J(),K.update()):Z(!0)}),(0,e.on)(o,`keydown`,e=>{if(!p)switch(e.key){case`ArrowDown`:{if(e.preventDefault(),!b){Z(!0);return}C=!0;let t=D.length;if(t===0)return;q(S===-1?0:(S+1)%t);break}case`ArrowUp`:{if(e.preventDefault(),!b){Z(!0);return}C=!0;let t=D.length;if(t===0)return;q(S===-1?t-1:(S-1+t)%t);break}case`Home`:if(!b)return;e.preventDefault(),C=!0,D.length>0&&q(0);break;case`End`:if(!b)return;e.preventDefault(),C=!0,D.length>0&&q(D.length-1);break;case`Enter`:if(!b)return;e.preventDefault(),S>=0&&S<D.length&&$(D[S]);break;case`Escape`:b?(e.preventDefault(),Z(!1)):x!==null&&(e.preventDefault(),Q(null));break;case`Tab`:b&&Z(!1,!0);break}}),(0,e.on)(o,`focus`,()=>{p||(o.select(),te&&!b&&Z(!0))})),l&&w.push((0,e.on)(l,`click`,()=>{p||(b?Z(!1):(Z(!0),o.focus()))})),w.push((0,e.on)(s,`click`,e=>{let t=e.target.closest?.(`[data-slot="combobox-item"]`);t&&!t.hidden&&$(t)}),(0,e.on)(s,`pointermove`,e=>{let t=e.target.closest?.(`[data-slot="combobox-item"]`);if(!(C&&(C=!1,t&&O.get(t)===S)))if(t&&!M(t)&&!t.hidden){let e=O.get(t);e!==void 0&&e!==S&&q(e)}else J()}),(0,e.on)(s,`pointerleave`,()=>{C||J()}),(0,e.on)(s,`mousedown`,e=>{e.preventDefault()})),w.push((0,e.createDismissLayer)({root:r,isOpen:()=>b,onDismiss:()=>Z(!1),closeOnClickOutside:!0,closeOnEscape:!1})),w.push((0,e.on)(r,`combobox:set`,e=>{let t=e.detail;t?.value!==void 0&&Q(t.value),t?.open!==void 0&&Z(t.open),t?.inputValue!==void 0&&(o.value=t.inputValue),t?.itemToStringValue!==void 0&&(v=t.itemToStringValue,o.value=F(x))})),d&&Z(!0),{get value(){return x},get inputValue(){return o.value},get isOpen(){return b},select:e=>Q(e),clear:()=>Q(null),open:()=>Z(!0),close:()=>Z(!1),setItemToStringValue:e=>{v=e,o.value=F(x)},destroy:()=>{j=!0,K.stop(),X.cleanup(),A.cleanup(),w.forEach(e=>e()),w.length=0,k&&k.parentNode&&k.parentNode.removeChild(k),i.delete(r)}}}const i=new WeakSet;function a(t=document){let n=[];for(let a of(0,e.getRoots)(t,`combobox`))i.has(a)||(i.add(a),n.push(r(a)));return n}exports.create=a,exports.createCombobox=r;
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{computeFloatingPosition as e,createDismissLayer as t,createPortalLifecycle as n,createPositionSync as r,createPresenceLifecycle as i,emit as a,ensureId as o,ensureItemVisibleInContainer as ee,getDataBool as s,getDataEnum as c,getDataNumber as l,getDataString as u,getPart as d,getParts as f,getRoots as p,on as m,setAria as h}from"@data-slot/core";const g=[`top`,`bottom`],_=[`start`,`center`,`end`];function v(p,v={}){let b=d(p,`combobox-input`),x=d(p,`combobox-content`),S=d(p,`combobox-list`)??d(x??p,`combobox-list`),C=d(p,`combobox-trigger`),w=d(S??x??p,`combobox-empty`);if(!b||!x)throw Error(`Combobox requires combobox-input and combobox-content slots`);let te=v.defaultValue??u(p,`defaultValue`)??null,ne=v.defaultOpen??s(p,`defaultOpen`)??!1,T=v.placeholder??u(p,`placeholder`)??``,E=v.disabled??s(p,`disabled`)??!1,D=v.required??s(p,`required`)??!1,O=v.name??u(p,`name`)??null,re=v.openOnFocus??s(p,`openOnFocus`)??!0,k=v.autoHighlight??s(p,`autoHighlight`)??!0,ie=v.filter??null,ae=v.onValueChange,oe=v.onOpenChange,se=v.onInputValueChange,ce=v.side??c(x,`side`,g)??c(p,`side`,g)??`bottom`,le=v.align??c(x,`align`,_)??c(p,`align`,_)??`start`,ue=v.sideOffset??l(x,`sideOffset`)??l(p,`sideOffset`)??4,de=v.alignOffset??l(x,`alignOffset`)??l(p,`alignOffset`)??0,fe=v.avoidCollisions??s(x,`avoidCollisions`)??s(p,`avoidCollisions`)??!0,pe=v.collisionPadding??l(x,`collisionPadding`)??l(p,`collisionPadding`)??8,A=!1,j=te,M=-1,N=!1,P=[],F=[],I=[],L=[],R=new Map,z=null,B=n({content:x,root:p,wrapperSlot:`combobox-positioner`}),V=!1,H=e=>e.hasAttribute(`disabled`)||e.hasAttribute(`data-disabled`)||e.getAttribute(`aria-disabled`)===`true`,U=e=>{if(e.dataset.label)return e.dataset.label;let t=``;for(let n of e.childNodes)n.nodeType===Node.TEXT_NODE&&(t+=n.textContent);return t.trim()||(e.textContent?.trim()??``)},W=e=>e.hasAttribute(`data-value`)?e.getAttribute(`data-value`):void 0,G=e=>{if(e===null)return``;let t=f(S??x,`combobox-item`).find(t=>W(t)===e);return t?U(t):``},me=o(b,`combobox-input`),he=S??x,ge=o(he,`combobox-list`);b.setAttribute(`role`,`combobox`),b.setAttribute(`aria-autocomplete`,`list`),b.setAttribute(`autocomplete`,`off`),b.setAttribute(`aria-controls`,ge),S?S.setAttribute(`role`,`listbox`):x.setAttribute(`role`,`listbox`),C&&(C.hasAttribute(`type`)||C.setAttribute(`type`,`button`),C.tabIndex=-1,C.setAttribute(`aria-label`,`Toggle`));let _e=document.querySelector(`label[for="${CSS.escape(me)}"]`);if(_e){let e=o(_e,`combobox-label`),t=b.getAttribute(`aria-labelledby`);b.setAttribute(`aria-labelledby`,t?`${t} ${e}`:e),he.setAttribute(`aria-labelledby`,e)}E&&(b.setAttribute(`aria-disabled`,`true`),b.disabled=!0,C&&(C.setAttribute(`aria-disabled`,`true`),C.setAttribute(`data-disabled`,``))),D&&(b.setAttribute(`aria-required`,`true`),b.required=!0);let ve=()=>{D&&b.setCustomValidity(j===null?`Please select a value`:``)};T&&(b.placeholder=T),O&&(b.name&&b.removeAttribute(`name`),z=document.createElement(`input`),z.type=`hidden`,z.name=O,z.value=j??``,p.appendChild(z));let ye=ie??((e,t,n)=>n.toLowerCase().includes(e.toLowerCase())),be=()=>{let e=S??x;F=f(e,`combobox-item`);for(let e of F)e.setAttribute(`role`,`option`),o(e,`combobox-item`),H(e)?e.setAttribute(`aria-disabled`,`true`):e.removeAttribute(`aria-disabled`),W(e)===j?(h(e,`selected`,!0),e.setAttribute(`data-selected`,``)):(h(e,`selected`,!1),e.removeAttribute(`data-selected`));let t=f(e,`combobox-group`);for(let e of t){e.setAttribute(`role`,`group`);let t=d(e,`combobox-label`);if(t){let n=o(t,`combobox-label`);e.setAttribute(`aria-labelledby`,n)}}xe()},xe=()=>{I=F.filter(e=>!e.hidden),L=I.filter(e=>!H(e)),R=new Map(L.map((e,t)=>[e,t]))},Se=(e,t)=>{let n=t===`previous`?e.previousElementSibling:e.nextElementSibling;for(;n;){if(n instanceof HTMLElement&&!n.hidden&&n.dataset.slot!==`combobox-separator`)return!0;n=t===`previous`?n.previousElementSibling:n.nextElementSibling}return!1},Ce=e=>{let t=S??x,n=e.trim(),r=0;for(let e of F){let t=W(e)??``,i=U(e),a=n===``||ye(n,t,i);e.hidden=!a,a&&r++}let i=f(t,`combobox-group`);for(let e of i)e.hidden=!f(e,`combobox-item`).some(e=>!e.hidden);let a=f(t,`combobox-separator`);for(let e of a)e.hidden=!Se(e,`previous`)||!Se(e,`next`);w&&(w.hidden=r>0),r===0?x.setAttribute(`data-empty`,``):x.removeAttribute(`data-empty`),xe()},we=()=>{let t=B.container,n=p.ownerDocument.defaultView??window,r=p.getBoundingClientRect();x.style.minWidth=`${r.width}px`;let i=e({anchorRect:r,contentRect:x.getBoundingClientRect(),side:ce,align:le,sideOffset:ue,alignOffset:de,avoidCollisions:fe,collisionPadding:pe,allowedSides:g});t.style.position=`absolute`,t.style.top=`0px`,t.style.left=`0px`,t.style.transform=`translate3d(${i.x+n.scrollX}px, ${i.y+n.scrollY}px, 0)`,t.style.willChange=`transform`,t.style.margin=`0`,x.setAttribute(`data-side`,i.side),x.setAttribute(`data-align`,i.align),t!==x&&(t.setAttribute(`data-side`,i.side),t.setAttribute(`data-align`,i.align))},K=r({observedElements:[p,x],isActive:()=>A,ancestorScroll:!1,onUpdate:we,ignoreScrollTarget:e=>e instanceof Node&&x.contains(e)}),Te=e=>S&&S.contains(e)&&S.scrollHeight>S.clientHeight?S:x,q=e=>{for(let t=0;t<L.length;t++){let n=L[t];t===e?(n.setAttribute(`data-highlighted`,``),b.setAttribute(`aria-activedescendant`,n.id),ee(n,Te(n))):n.removeAttribute(`data-highlighted`)}M=e},J=()=>{for(let e of F)e.removeAttribute(`data-highlighted`);M=-1,b.removeAttribute(`aria-activedescendant`)},Y=e=>{p.setAttribute(`data-state`,e),x.setAttribute(`data-state`,e),C&&C.setAttribute(`data-state`,e),e===`open`?(p.setAttribute(`data-open`,``),x.setAttribute(`data-open`,``),C&&C.setAttribute(`data-open`,``),p.removeAttribute(`data-closed`),x.removeAttribute(`data-closed`),C&&C.removeAttribute(`data-closed`)):(p.setAttribute(`data-closed`,``),x.setAttribute(`data-closed`,``),C&&C.setAttribute(`data-closed`,``),p.removeAttribute(`data-open`),x.removeAttribute(`data-open`),C&&C.removeAttribute(`data-open`))},X=i({element:x,onExitComplete:()=>{V||(B.restore(),x.hidden=!0)}}),Z=(e,t=!1)=>{if(A!==e&&!(E&&e)){if(e){A=!0,h(b,`expanded`,!0),B.mount(),x.hidden=!1,Y(`open`),X.enter(),be(),N=!1,Ce(b.value);let e=L.findIndex(e=>W(e)===j);e>=0?q(e):k&&L.length>0?q(0):J(),K.start(),we(),K.update(),requestAnimationFrame(()=>{A&&K.update()})}else A=!1,h(b,`expanded`,!1),Y(`closed`),J(),N=!1,K.stop(),X.exit(),b.value=G(j);a(p,`combobox:open-change`,{open:A}),oe?.(A)}},Q=(e,t=!1)=>{if(j===e&&!t)return;let n=j;j=e,ve(),z&&(z.value=e??``),e===null?p.removeAttribute(`data-value`):p.setAttribute(`data-value`,e);let r=S??x,i=F.length>0?F:f(r,`combobox-item`);for(let t of i)W(t)===e?(h(t,`selected`,!0),t.setAttribute(`data-selected`,``)):(h(t,`selected`,!1),t.removeAttribute(`data-selected`));b.value=G(e),!t&&n!==e&&(a(p,`combobox:change`,{value:e}),ae?.(e))},$=e=>{if(H(e))return;let t=W(e);t!==void 0&&(Q(t),Z(!1))};return h(b,`expanded`,!1),x.hidden=!0,Y(`closed`),Q(j,!0),P.push(m(b,`input`,()=>{let e=b.value;a(p,`combobox:input-change`,{inputValue:e}),se?.(e),A?(Ce(e),k&&L.length>0?q(0):J(),K.update()):Z(!0)}),m(b,`keydown`,e=>{if(!E)switch(e.key){case`ArrowDown`:{if(e.preventDefault(),!A){Z(!0);return}N=!0;let t=L.length;if(t===0)return;q(M===-1?0:(M+1)%t);break}case`ArrowUp`:{if(e.preventDefault(),!A){Z(!0);return}N=!0;let t=L.length;if(t===0)return;q(M===-1?t-1:(M-1+t)%t);break}case`Home`:if(!A)return;e.preventDefault(),N=!0,L.length>0&&q(0);break;case`End`:if(!A)return;e.preventDefault(),N=!0,L.length>0&&q(L.length-1);break;case`Enter`:if(!A)return;e.preventDefault(),M>=0&&M<L.length&&$(L[M]);break;case`Escape`:A?(e.preventDefault(),Z(!1)):j!==null&&(e.preventDefault(),Q(null));break;case`Tab`:A&&Z(!1,!0);break}}),m(b,`focus`,()=>{E||(b.select(),re&&!A&&Z(!0))})),C&&P.push(m(C,`click`,()=>{E||(A?Z(!1):(Z(!0),b.focus()))})),P.push(m(x,`click`,e=>{let t=e.target.closest?.(`[data-slot="combobox-item"]`);t&&!t.hidden&&$(t)}),m(x,`pointermove`,e=>{let t=e.target.closest?.(`[data-slot="combobox-item"]`);if(!(N&&(N=!1,t&&R.get(t)===M)))if(t&&!H(t)&&!t.hidden){let e=R.get(t);e!==void 0&&e!==M&&q(e)}else J()}),m(x,`pointerleave`,()=>{N||J()}),m(x,`mousedown`,e=>{e.preventDefault()})),P.push(t({root:p,isOpen:()=>A,onDismiss:()=>Z(!1),closeOnClickOutside:!0,closeOnEscape:!1})),P.push(m(p,`combobox:set`,e=>{let t=e.detail;t?.value!==void 0&&Q(t.value),t?.open!==void 0&&Z(t.open),t?.inputValue!==void 0&&(b.value=t.inputValue)})),ne&&Z(!0),{get value(){return j},get inputValue(){return b.value},get isOpen(){return A},select:e=>Q(e),clear:()=>Q(null),open:()=>Z(!0),close:()=>Z(!1),destroy:()=>{V=!0,K.stop(),X.cleanup(),B.cleanup(),P.forEach(e=>e()),P.length=0,z&&z.parentNode&&z.parentNode.removeChild(z),y.delete(p)}}}const y=new WeakSet;function b(e=document){let t=[];for(let n of p(e,`combobox`))y.has(n)||(y.add(n),t.push(v(n)));return t}export{b as create,v as createCombobox};
1
+ import{computeFloatingPosition as e,createDismissLayer as t,createPortalLifecycle as n,createPositionSync as r,createPresenceLifecycle as i,emit as a,ensureId as o,ensureItemVisibleInContainer as ee,getDataBool as s,getDataEnum as c,getDataNumber as l,getDataString as u,getPart as d,getParts as f,getRoots as p,on as m,setAria as h}from"@data-slot/core";const g=[`top`,`bottom`],te=[`start`,`center`,`end`];function _(p,_={}){let y=d(p,`combobox-input`),b=d(p,`combobox-content`),x=d(p,`combobox-list`)??d(b??p,`combobox-list`),S=d(p,`combobox-trigger`),ne=d(x??b??p,`combobox-empty`);if(!y||!b)throw Error(`Combobox requires combobox-input and combobox-content slots`);let re=_.defaultValue??u(p,`defaultValue`)??null,ie=_.defaultOpen??s(p,`defaultOpen`)??!1,C=_.placeholder??u(p,`placeholder`)??``,w=_.disabled??s(p,`disabled`)??!1,T=_.required??s(p,`required`)??!1,E=_.name??u(p,`name`)??null,ae=_.openOnFocus??s(p,`openOnFocus`)??!0,D=_.autoHighlight??s(p,`autoHighlight`)??!0,oe=_.filter??null,se=_.onValueChange,ce=_.onOpenChange,le=_.onInputValueChange,O=_.itemToStringValue??null,ue=_.side??c(b,`side`,g)??c(p,`side`,g)??`bottom`,de=_.align??c(b,`align`,te)??c(p,`align`,te)??`start`,fe=_.sideOffset??l(b,`sideOffset`)??l(p,`sideOffset`)??4,pe=_.alignOffset??l(b,`alignOffset`)??l(p,`alignOffset`)??0,me=_.avoidCollisions??s(b,`avoidCollisions`)??s(p,`avoidCollisions`)??!0,he=_.collisionPadding??l(b,`collisionPadding`)??l(p,`collisionPadding`)??8,k=!1,A=re,j=-1,M=!1,N=[],P=[],F=[],I=[],L=new Map,R=null,z=n({content:b,root:p,wrapperSlot:`combobox-positioner`}),B=!1,V=e=>e.hasAttribute(`disabled`)||e.hasAttribute(`data-disabled`)||e.getAttribute(`aria-disabled`)===`true`,H=e=>{if(e.dataset.label)return e.dataset.label;let t=``;for(let n of e.childNodes)n.nodeType===Node.TEXT_NODE&&(t+=n.textContent);return t.trim()||(e.textContent?.trim()??``)},U=e=>e.hasAttribute(`data-value`)?e.getAttribute(`data-value`):void 0,ge=e=>e===null?null:f(x??b,`combobox-item`).find(t=>U(t)===e)??null,W=e=>{let t=ge(e);return O?O(t,e):t?H(t):``},_e=o(y,`combobox-input`),ve=x??b,ye=o(ve,`combobox-list`);y.setAttribute(`role`,`combobox`),y.setAttribute(`aria-autocomplete`,`list`),y.setAttribute(`autocomplete`,`off`),y.setAttribute(`aria-controls`,ye),x?x.setAttribute(`role`,`listbox`):b.setAttribute(`role`,`listbox`),S&&(S.hasAttribute(`type`)||S.setAttribute(`type`,`button`),S.tabIndex=-1,S.setAttribute(`aria-label`,`Toggle`));let be=document.querySelector(`label[for="${CSS.escape(_e)}"]`);if(be){let e=o(be,`combobox-label`),t=y.getAttribute(`aria-labelledby`);y.setAttribute(`aria-labelledby`,t?`${t} ${e}`:e),ve.setAttribute(`aria-labelledby`,e)}w&&(y.setAttribute(`aria-disabled`,`true`),y.disabled=!0,S&&(S.setAttribute(`aria-disabled`,`true`),S.setAttribute(`data-disabled`,``))),T&&(y.setAttribute(`aria-required`,`true`),y.required=!0);let xe=()=>{T&&y.setCustomValidity(A===null?`Please select a value`:``)};C&&(y.placeholder=C),E&&(y.name&&y.removeAttribute(`name`),R=document.createElement(`input`),R.type=`hidden`,R.name=E,R.value=A??``,p.appendChild(R));let Se=oe??((e,t,n)=>n.toLowerCase().includes(e.toLowerCase())),Ce=()=>{let e=x??b;P=f(e,`combobox-item`);for(let e of P)e.setAttribute(`role`,`option`),o(e,`combobox-item`),V(e)?e.setAttribute(`aria-disabled`,`true`):e.removeAttribute(`aria-disabled`),U(e)===A?(h(e,`selected`,!0),e.setAttribute(`data-selected`,``)):(h(e,`selected`,!1),e.removeAttribute(`data-selected`));let t=f(e,`combobox-group`);for(let e of t){e.setAttribute(`role`,`group`);let t=d(e,`combobox-label`);if(t){let n=o(t,`combobox-label`);e.setAttribute(`aria-labelledby`,n)}}we()},we=()=>{F=P.filter(e=>!e.hidden),I=F.filter(e=>!V(e)),L=new Map(I.map((e,t)=>[e,t]))},G=(e,t)=>{let n=t===`previous`?e.previousElementSibling:e.nextElementSibling;for(;n;){if(n instanceof HTMLElement&&!n.hidden&&n.dataset.slot!==`combobox-separator`)return!0;n=t===`previous`?n.previousElementSibling:n.nextElementSibling}return!1},Te=e=>{let t=x??b,n=e.trim(),r=0;for(let e of P){let t=U(e)??``,i=H(e),a=n===``||Se(n,t,i);e.hidden=!a,a&&r++}let i=f(t,`combobox-group`);for(let e of i)e.hidden=!f(e,`combobox-item`).some(e=>!e.hidden);let a=f(t,`combobox-separator`);for(let e of a)e.hidden=!G(e,`previous`)||!G(e,`next`);ne&&(ne.hidden=r>0),r===0?b.setAttribute(`data-empty`,``):b.removeAttribute(`data-empty`),we()},Ee=()=>{let t=z.container,n=p.ownerDocument.defaultView??window,r=p.getBoundingClientRect();b.style.minWidth=`${r.width}px`;let i=e({anchorRect:r,contentRect:b.getBoundingClientRect(),side:ue,align:de,sideOffset:fe,alignOffset:pe,avoidCollisions:me,collisionPadding:he,allowedSides:g});t.style.position=`absolute`,t.style.top=`0px`,t.style.left=`0px`,t.style.transform=`translate3d(${i.x+n.scrollX}px, ${i.y+n.scrollY}px, 0)`,t.style.willChange=`transform`,t.style.margin=`0`,b.setAttribute(`data-side`,i.side),b.setAttribute(`data-align`,i.align),t!==b&&(t.setAttribute(`data-side`,i.side),t.setAttribute(`data-align`,i.align))},K=r({observedElements:[p,b],isActive:()=>k,ancestorScroll:!1,onUpdate:Ee,ignoreScrollTarget:e=>e instanceof Node&&b.contains(e)}),De=e=>x&&x.contains(e)&&x.scrollHeight>x.clientHeight?x:b,q=e=>{for(let t=0;t<I.length;t++){let n=I[t];t===e?(n.setAttribute(`data-highlighted`,``),y.setAttribute(`aria-activedescendant`,n.id),ee(n,De(n))):n.removeAttribute(`data-highlighted`)}j=e},J=()=>{for(let e of P)e.removeAttribute(`data-highlighted`);j=-1,y.removeAttribute(`aria-activedescendant`)},Y=e=>{p.setAttribute(`data-state`,e),b.setAttribute(`data-state`,e),S&&S.setAttribute(`data-state`,e),e===`open`?(p.setAttribute(`data-open`,``),b.setAttribute(`data-open`,``),S&&S.setAttribute(`data-open`,``),p.removeAttribute(`data-closed`),b.removeAttribute(`data-closed`),S&&S.removeAttribute(`data-closed`)):(p.setAttribute(`data-closed`,``),b.setAttribute(`data-closed`,``),S&&S.setAttribute(`data-closed`,``),p.removeAttribute(`data-open`),b.removeAttribute(`data-open`),S&&S.removeAttribute(`data-open`))},X=i({element:b,onExitComplete:()=>{B||(z.restore(),b.hidden=!0)}}),Z=(e,t=!1)=>{if(k!==e&&!(w&&e)){if(e){k=!0,h(y,`expanded`,!0),z.mount(),b.hidden=!1,Y(`open`),X.enter(),Ce(),M=!1,Te(y.value);let e=I.findIndex(e=>U(e)===A);e>=0?q(e):D&&I.length>0?q(0):J(),K.start(),Ee(),K.update(),requestAnimationFrame(()=>{k&&K.update()})}else k=!1,h(y,`expanded`,!1),Y(`closed`),J(),M=!1,K.stop(),X.exit(),y.value=W(A);a(p,`combobox:open-change`,{open:k}),ce?.(k)}},Q=(e,t=!1)=>{if(A===e&&!t)return;let n=A;A=e,xe(),R&&(R.value=e??``),e===null?p.removeAttribute(`data-value`):p.setAttribute(`data-value`,e);let r=x??b,i=P.length>0?P:f(r,`combobox-item`);for(let t of i)U(t)===e?(h(t,`selected`,!0),t.setAttribute(`data-selected`,``)):(h(t,`selected`,!1),t.removeAttribute(`data-selected`));y.value=W(e),!t&&n!==e&&(a(p,`combobox:change`,{value:e}),se?.(e))},$=e=>{if(V(e))return;let t=U(e);t!==void 0&&(Q(t),Z(!1))};return h(y,`expanded`,!1),b.hidden=!0,Y(`closed`),Q(A,!0),N.push(m(y,`input`,()=>{let e=y.value;a(p,`combobox:input-change`,{inputValue:e}),le?.(e),k?(Te(e),D&&I.length>0?q(0):J(),K.update()):Z(!0)}),m(y,`keydown`,e=>{if(!w)switch(e.key){case`ArrowDown`:{if(e.preventDefault(),!k){Z(!0);return}M=!0;let t=I.length;if(t===0)return;q(j===-1?0:(j+1)%t);break}case`ArrowUp`:{if(e.preventDefault(),!k){Z(!0);return}M=!0;let t=I.length;if(t===0)return;q(j===-1?t-1:(j-1+t)%t);break}case`Home`:if(!k)return;e.preventDefault(),M=!0,I.length>0&&q(0);break;case`End`:if(!k)return;e.preventDefault(),M=!0,I.length>0&&q(I.length-1);break;case`Enter`:if(!k)return;e.preventDefault(),j>=0&&j<I.length&&$(I[j]);break;case`Escape`:k?(e.preventDefault(),Z(!1)):A!==null&&(e.preventDefault(),Q(null));break;case`Tab`:k&&Z(!1,!0);break}}),m(y,`focus`,()=>{w||(y.select(),ae&&!k&&Z(!0))})),S&&N.push(m(S,`click`,()=>{w||(k?Z(!1):(Z(!0),y.focus()))})),N.push(m(b,`click`,e=>{let t=e.target.closest?.(`[data-slot="combobox-item"]`);t&&!t.hidden&&$(t)}),m(b,`pointermove`,e=>{let t=e.target.closest?.(`[data-slot="combobox-item"]`);if(!(M&&(M=!1,t&&L.get(t)===j)))if(t&&!V(t)&&!t.hidden){let e=L.get(t);e!==void 0&&e!==j&&q(e)}else J()}),m(b,`pointerleave`,()=>{M||J()}),m(b,`mousedown`,e=>{e.preventDefault()})),N.push(t({root:p,isOpen:()=>k,onDismiss:()=>Z(!1),closeOnClickOutside:!0,closeOnEscape:!1})),N.push(m(p,`combobox:set`,e=>{let t=e.detail;t?.value!==void 0&&Q(t.value),t?.open!==void 0&&Z(t.open),t?.inputValue!==void 0&&(y.value=t.inputValue),t?.itemToStringValue!==void 0&&(O=t.itemToStringValue,y.value=W(A))})),ie&&Z(!0),{get value(){return A},get inputValue(){return y.value},get isOpen(){return k},select:e=>Q(e),clear:()=>Q(null),open:()=>Z(!0),close:()=>Z(!1),setItemToStringValue:e=>{O=e,y.value=W(A)},destroy:()=>{B=!0,K.stop(),X.cleanup(),z.cleanup(),N.forEach(e=>e()),N.length=0,R&&R.parentNode&&R.parentNode.removeChild(R),v.delete(p)}}}const v=new WeakSet;function y(e=document){let t=[];for(let n of p(e,`combobox`))v.has(n)||(v.add(n),t.push(_(n)));return t}export{y as create,_ as createCombobox};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@data-slot/combobox",
3
- "version": "0.2.43",
3
+ "version": "0.2.45",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "main": "./dist/index.cjs",
@@ -40,6 +40,6 @@
40
40
  ],
41
41
  "license": "MIT",
42
42
  "dependencies": {
43
- "@data-slot/core": "0.2.43"
43
+ "@data-slot/core": "0.2.45"
44
44
  }
45
45
  }