@data-slot/combobox 0.2.72 → 0.2.74
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
|
@@ -64,6 +64,7 @@ controller.destroy();
|
|
|
64
64
|
| `combobox` | Root container |
|
|
65
65
|
| `combobox-input` | Text input for filtering |
|
|
66
66
|
| `combobox-trigger` | Optional button that toggles the popup |
|
|
67
|
+
| `combobox-value` | Optional selected-value text target (typically inside `combobox-trigger`) |
|
|
67
68
|
| `combobox-content` | Popup container |
|
|
68
69
|
| `combobox-list` | Scrollable list wrapper |
|
|
69
70
|
| `combobox-item` | Individual selectable option |
|
|
@@ -88,6 +89,27 @@ controller.destroy();
|
|
|
88
89
|
</div>
|
|
89
90
|
```
|
|
90
91
|
|
|
92
|
+
### Popup-Input Composition (Optional)
|
|
93
|
+
|
|
94
|
+
Use this when you want a trigger with committed value text and a separate search input inside the popup.
|
|
95
|
+
|
|
96
|
+
```html
|
|
97
|
+
<div data-slot="combobox">
|
|
98
|
+
<button data-slot="combobox-trigger">
|
|
99
|
+
<span data-slot="combobox-value">Select country...</span>
|
|
100
|
+
</button>
|
|
101
|
+
<div data-slot="combobox-content" hidden>
|
|
102
|
+
<input data-slot="combobox-input" placeholder="Search countries..." />
|
|
103
|
+
<div data-slot="combobox-list">...</div>
|
|
104
|
+
</div>
|
|
105
|
+
</div>
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
In popup-input mode (`combobox-input` inside `combobox-content`):
|
|
109
|
+
- Selection text is synced to `combobox-value`.
|
|
110
|
+
- Search input is cleared each time the popup opens.
|
|
111
|
+
- Closing keeps the popup input empty.
|
|
112
|
+
|
|
91
113
|
### Native Label Support
|
|
92
114
|
|
|
93
115
|
Use a standard HTML `<label for="...">` element to label the combobox. The `for` attribute should match the `id` on the input. Clicking the label focuses the input, and `aria-labelledby` is set automatically.
|
|
@@ -118,7 +140,7 @@ Options can be passed via JavaScript or data attributes (JS takes precedence).
|
|
|
118
140
|
| `openOnFocus` | `data-open-on-focus` | `boolean` | `true` | Open popup when input is focused |
|
|
119
141
|
| `autoHighlight` | `data-auto-highlight` | `boolean` | `false` | Auto-highlight first visible item after non-whitespace query input |
|
|
120
142
|
| `filter` | - | `function` | substring | Custom filter function |
|
|
121
|
-
| `itemToStringValue` | - | `(item: HTMLElement \| null, value: string \| null) => string` | item label | Custom text resolver for selected
|
|
143
|
+
| `itemToStringValue` | - | `(item: HTMLElement \| null, value: string \| null) => string` | item label | Custom text resolver for committed selected-value text (input in inline mode, `combobox-value` in popup-input mode) |
|
|
122
144
|
| `side` | `data-side` | `"top" \| "bottom"` | `"bottom"` | Popup placement |
|
|
123
145
|
| `align` | `data-align` | `"start" \| "center" \| "end"` | `"start"` | Popup alignment |
|
|
124
146
|
| `sideOffset` | `data-side-offset` | `number` | `4` | Distance from input (px) |
|
|
@@ -29,7 +29,7 @@ interface ComboboxOptions {
|
|
|
29
29
|
autoHighlight?: boolean;
|
|
30
30
|
/** Custom filter function. Return true to show item. */
|
|
31
31
|
filter?: (inputValue: string, itemValue: string, itemLabel: string) => boolean;
|
|
32
|
-
/** Custom text resolver for
|
|
32
|
+
/** Custom text resolver for committed selected-value text (input in inline mode, combobox-value in popup-input mode) */
|
|
33
33
|
itemToStringValue?: ComboboxItemToStringValue;
|
|
34
34
|
/** @default "bottom" */
|
|
35
35
|
side?: Side;
|
|
@@ -29,7 +29,7 @@ interface ComboboxOptions {
|
|
|
29
29
|
autoHighlight?: boolean;
|
|
30
30
|
/** Custom filter function. Return true to show item. */
|
|
31
31
|
filter?: (inputValue: string, itemValue: string, itemLabel: string) => boolean;
|
|
32
|
-
/** Custom text resolver for
|
|
32
|
+
/** Custom text resolver for committed selected-value text (input in inline mode, combobox-value in popup-input mode) */
|
|
33
33
|
itemToStringValue?: ComboboxItemToStringValue;
|
|
34
34
|
/** @default "bottom" */
|
|
35
35
|
side?: Side;
|
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`),d=(0,e.getPart)(r,`combobox-positioner`),f=d&&s&&d.contains(s)?d:null,p=(0,e.getPart)(r,`combobox-portal`),ee=p&&f&&p.contains(f)?p:null;if(!o||!s)throw Error(`Combobox requires combobox-input and combobox-content slots`);let te=a.defaultValue??(0,e.getDataString)(r,`defaultValue`)??null,ne=a.defaultOpen??(0,e.getDataBool)(r,`defaultOpen`)??!1,m=a.placeholder??(0,e.getDataString)(r,`placeholder`)??``,h=a.disabled??(0,e.getDataBool)(r,`disabled`)??!1,g=a.required??(0,e.getDataBool)(r,`required`)??!1,_=a.name??(0,e.getDataString)(r,`name`)??null,re=a.openOnFocus??(0,e.getDataBool)(r,`openOnFocus`)??!0,v=a.autoHighlight??(0,e.getDataBool)(r,`autoHighlight`)??!1,y=a.filter??null,ie=a.onValueChange,ae=a.onOpenChange,oe=a.onInputValueChange,b=a.itemToStringValue??null,se=a.side??(0,e.getDataEnum)(s,`side`,t)??(0,e.getDataEnum)(r,`side`,t)??`bottom`,ce=a.align??(0,e.getDataEnum)(s,`align`,n)??(0,e.getDataEnum)(r,`align`,n)??`start`,le=a.sideOffset??(0,e.getDataNumber)(s,`sideOffset`)??(0,e.getDataNumber)(r,`sideOffset`)??4,ue=a.alignOffset??(0,e.getDataNumber)(s,`alignOffset`)??(0,e.getDataNumber)(r,`alignOffset`)??0,x=a.avoidCollisions??(0,e.getDataBool)(s,`avoidCollisions`)??(0,e.getDataBool)(r,`avoidCollisions`)??!0,de=a.collisionPadding??(0,e.getDataNumber)(s,`collisionPadding`)??(0,e.getDataNumber)(r,`collisionPadding`)??8,S=!1,C=te,w=-1,T=!1,E=[],fe=r.ownerDocument??document,D=-1/0,O=!1,k=[],A=[],j=[],M=new Map,N=null,P=(0,e.createPortalLifecycle)({content:s,root:r,wrapperSlot:f?void 0:`combobox-positioner`,container:f??void 0,mountTarget:f?ee??f:void 0}),F=!1,I=e=>e.hasAttribute(`disabled`)||e.hasAttribute(`data-disabled`)||e.getAttribute(`aria-disabled`)===`true`,L=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()??``)},R=e=>e.hasAttribute(`data-value`)?e.getAttribute(`data-value`):void 0,pe=t=>t===null?null:(0,e.getParts)(c??s,`combobox-item`).find(e=>R(e)===t)??null,z=e=>{let t=pe(e);return b?b(t,e):t?L(t):``},me=(0,e.ensureId)(o,`combobox-input`),B=c??s,he=(0,e.ensureId)(B,`combobox-list`);o.setAttribute(`role`,`combobox`),o.setAttribute(`aria-autocomplete`,`list`),o.setAttribute(`autocomplete`,`off`),o.setAttribute(`aria-controls`,he),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 V=document.querySelector(`label[for="${CSS.escape(me)}"]`);if(V){let t=(0,e.ensureId)(V,`combobox-label`),n=o.getAttribute(`aria-labelledby`);o.setAttribute(`aria-labelledby`,n?`${n} ${t}`:t),B.setAttribute(`aria-labelledby`,t)}h&&(o.setAttribute(`aria-disabled`,`true`),o.disabled=!0,l&&(l.setAttribute(`aria-disabled`,`true`),l.setAttribute(`data-disabled`,``))),g&&(o.setAttribute(`aria-required`,`true`),o.required=!0);let ge=()=>{g&&o.setCustomValidity(C===null?`Please select a value`:``)};m&&(o.placeholder=m),_&&(o.name&&o.removeAttribute(`name`),N=document.createElement(`input`),N.type=`hidden`,N.name=_,N.value=C??``,r.appendChild(N));let _e=y??((e,t,n)=>n.toLowerCase().includes(e.toLowerCase())),ve=()=>{let t=c??s;k=(0,e.getParts)(t,`combobox-item`);for(let t of k)t.setAttribute(`role`,`option`),(0,e.ensureId)(t,`combobox-item`),I(t)?t.setAttribute(`aria-disabled`,`true`):t.removeAttribute(`aria-disabled`),R(t)===C?((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=()=>{A=k.filter(e=>!e.hidden),j=A.filter(e=>!I(e)),M=new Map(j.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 k){let t=R(e)??``,n=L(e),a=r===``||_e(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=P.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:se,align:ce,sideOffset:le,alignOffset:ue,avoidCollisions:x,collisionPadding:de,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:()=>S,ancestorScroll:!1,onUpdate:G,ignoreScrollTarget:e=>e instanceof Node&&s.contains(e)}),ye=e=>c&&c.contains(e)&&c.scrollHeight>c.clientHeight?c:s,q=t=>{for(let n=0;n<j.length;n++){let r=j[n];n===t?(r.setAttribute(`data-highlighted`,``),o.setAttribute(`aria-activedescendant`,r.id),(0,e.ensureItemVisibleInContainer)(r,ye(r))):r.removeAttribute(`data-highlighted`)}w=t},J=()=>{for(let e of k)e.removeAttribute(`data-highlighted`);w=-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:()=>{F||(P.restore(),s.hidden=!0)}}),Z=(t,n=!1)=>{if(S!==t&&!(h&&t)){if(t){S=!0,(0,e.setAria)(o,`expanded`,!0),P.mount(),s.hidden=!1,Y(`open`),X.enter(),ve(),T=!1,W(o.value);let t=j.findIndex(e=>R(e)===C);t>=0?q(t):J(),K.start(),G(),K.update(),requestAnimationFrame(()=>{S&&K.update()})}else S=!1,(0,e.setAria)(o,`expanded`,!1),Y(`closed`),J(),T=!1,K.stop(),X.exit(),o.value=z(C);(0,e.emit)(r,`combobox:open-change`,{open:S}),ae?.(S)}},Q=(t,n=!1)=>{if(C===t&&!n)return;let i=C;C=t,ge(),N&&(N.value=t??``),t===null?r.removeAttribute(`data-value`):r.setAttribute(`data-value`,t);let a=c??s,l=k.length>0?k:(0,e.getParts)(a,`combobox-item`);for(let n of l)R(n)===t?((0,e.setAria)(n,`selected`,!0),n.setAttribute(`data-selected`,``)):((0,e.setAria)(n,`selected`,!1),n.removeAttribute(`data-selected`));o.value=z(t),!n&&i!==t&&((0,e.emit)(r,`combobox:change`,{value:t}),ie?.(t))},$=e=>{if(I(e))return;let t=R(e);t!==void 0&&(Q(t),Z(!1))};return(0,e.setAria)(o,`expanded`,!1),s.hidden=!0,Y(`closed`),Q(C,!0),E.push((0,e.on)(fe,`keydown`,e=>{e.key===`Tab`&&(D=Date.now())},{capture:!0}),(0,e.on)(o,`pointerdown`,()=>{O=!0}),(0,e.on)(o,`input`,()=>{let t=o.value,n=t.trim()!==``;(0,e.emit)(r,`combobox:input-change`,{inputValue:t}),oe?.(t),S?(W(t),v&&n&&j.length>0?q(0):J(),K.update()):(Z(!0),v&&n&&j.length>0?q(0):w!==-1&&J())}),(0,e.on)(o,`keydown`,e=>{if(!h)switch(e.key){case`ArrowDown`:{if(e.preventDefault(),!S){Z(!0);return}T=!0;let t=j.length;if(t===0)return;q(w===-1?0:(w+1)%t);break}case`ArrowUp`:{if(e.preventDefault(),!S){Z(!0);return}T=!0;let t=j.length;if(t===0)return;q(w===-1?t-1:(w-1+t)%t);break}case`Home`:if(!S)return;e.preventDefault(),T=!0,j.length>0&&q(0);break;case`End`:if(!S)return;e.preventDefault(),T=!0,j.length>0&&q(j.length-1);break;case`Enter`:if(!S)return;e.preventDefault(),w>=0&&w<j.length&&$(j[w]);break;case`Escape`:S?(e.preventDefault(),Z(!1)):C!==null&&(e.preventDefault(),Q(null));break;case`Tab`:S&&Z(!1,!0);break}}),(0,e.on)(o,`focus`,()=>{if(h)return;o.select();let e=O||Date.now()-D<=750;O=!1,re&&!S&&e&&Z(!0)})),l&&E.push((0,e.on)(l,`click`,()=>{h||(S?Z(!1):(Z(!0),o.focus()))})),E.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(!(T&&(T=!1,t&&M.get(t)===w)))if(t&&!I(t)&&!t.hidden){let e=M.get(t);e!==void 0&&e!==w&&q(e)}else J()}),(0,e.on)(s,`pointerleave`,()=>{T||J()}),(0,e.on)(s,`mousedown`,e=>{e.preventDefault()})),E.push((0,e.createDismissLayer)({root:r,isOpen:()=>S,onDismiss:()=>Z(!1),closeOnClickOutside:!0,closeOnEscape:!1})),E.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&&(b=t.itemToStringValue,o.value=z(C))})),ne&&Z(!0),{get value(){return C},get inputValue(){return o.value},get isOpen(){return S},select:e=>Q(e),clear:()=>Q(null),open:()=>Z(!0),close:()=>Z(!1),setItemToStringValue:e=>{b=e,o.value=z(C)},destroy:()=>{F=!0,K.stop(),X.cleanup(),P.cleanup(),E.forEach(e=>e()),E.length=0,N&&N.parentNode&&N.parentNode.removeChild(N),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)(r,`combobox-value`),d=(0,e.getPart)(c??s??r,`combobox-empty`),f=(0,e.getPart)(r,`combobox-positioner`),p=f&&s&&f.contains(s)?f:null,m=(0,e.getPart)(r,`combobox-portal`),ee=m&&p&&m.contains(p)?m:null;if(!o||!s)throw Error(`Combobox requires combobox-input and combobox-content slots`);let h=s.contains(o),g=u?.textContent?.trim()??``,te=a.defaultValue??(0,e.getDataString)(r,`defaultValue`)??null,ne=a.defaultOpen??(0,e.getDataBool)(r,`defaultOpen`)??!1,_=a.placeholder??(0,e.getDataString)(r,`placeholder`)??``,v=a.disabled??(0,e.getDataBool)(r,`disabled`)??!1,re=a.required??(0,e.getDataBool)(r,`required`)??!1,y=a.name??(0,e.getDataString)(r,`name`)??null,ie=a.openOnFocus??(0,e.getDataBool)(r,`openOnFocus`)??!0,b=a.autoHighlight??(0,e.getDataBool)(r,`autoHighlight`)??!1,ae=a.filter??null,oe=a.onValueChange,se=a.onOpenChange,ce=a.onInputValueChange,x=a.itemToStringValue??null,le=a.side??(0,e.getDataEnum)(s,`side`,t)??(0,e.getDataEnum)(r,`side`,t)??`bottom`,ue=a.align??(0,e.getDataEnum)(s,`align`,n)??(0,e.getDataEnum)(r,`align`,n)??`start`,de=a.sideOffset??(0,e.getDataNumber)(s,`sideOffset`)??(0,e.getDataNumber)(r,`sideOffset`)??4,fe=a.alignOffset??(0,e.getDataNumber)(s,`alignOffset`)??(0,e.getDataNumber)(r,`alignOffset`)??0,pe=a.avoidCollisions??(0,e.getDataBool)(s,`avoidCollisions`)??(0,e.getDataBool)(r,`avoidCollisions`)??!0,me=a.collisionPadding??(0,e.getDataNumber)(s,`collisionPadding`)??(0,e.getDataNumber)(r,`collisionPadding`)??8,S=!1,C=te,w=-1,T=!1,E=[],he=r.ownerDocument??document,D=-1/0,O=!1,k=[],A=[],j=[],M=new Map,N=null,P=(0,e.createPortalLifecycle)({content:s,root:r,wrapperSlot:p?void 0:`combobox-positioner`,container:p??void 0,mountTarget:p?ee??p:void 0}),F=!1,I=e=>e.hasAttribute(`disabled`)||e.hasAttribute(`data-disabled`)||e.getAttribute(`aria-disabled`)===`true`,L=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()??``)},R=e=>e.hasAttribute(`data-value`)?e.getAttribute(`data-value`):void 0,ge=t=>t===null?null:(0,e.getParts)(c??s,`combobox-item`).find(e=>R(e)===t)??null,z=e=>{let t=ge(e);return x?x(t,e):t?L(t):``},_e=(0,e.ensureId)(o,`combobox-input`),B=c??s,ve=(0,e.ensureId)(B,`combobox-list`);o.setAttribute(`role`,`combobox`),o.setAttribute(`aria-autocomplete`,`list`),o.setAttribute(`autocomplete`,`off`),o.setAttribute(`aria-controls`,ve),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 V=document.querySelector(`label[for="${CSS.escape(_e)}"]`);if(V){let t=(0,e.ensureId)(V,`combobox-label`),n=o.getAttribute(`aria-labelledby`);o.setAttribute(`aria-labelledby`,n?`${n} ${t}`:t),B.setAttribute(`aria-labelledby`,t)}v&&(o.setAttribute(`aria-disabled`,`true`),o.disabled=!0,l&&(l.setAttribute(`aria-disabled`,`true`),l.setAttribute(`data-disabled`,``))),re&&(o.setAttribute(`aria-required`,`true`),o.required=!0);let ye=()=>{re&&o.setCustomValidity(C===null?`Please select a value`:``)};_&&(o.placeholder=_),u&&(u.textContent=g||_,u.textContent.trim().length>0&&(u.setAttribute(`data-placeholder`,``),l?.setAttribute(`data-placeholder`,``))),y&&(o.name&&o.removeAttribute(`name`),N=document.createElement(`input`),N.type=`hidden`,N.name=y,N.value=C??``,r.appendChild(N));let be=ae??((e,t,n)=>n.toLowerCase().includes(e.toLowerCase())),xe=()=>{let t=c??s;k=(0,e.getParts)(t,`combobox-item`);for(let t of k)t.setAttribute(`role`,`option`),(0,e.ensureId)(t,`combobox-item`),I(t)?t.setAttribute(`aria-disabled`,`true`):t.removeAttribute(`aria-disabled`),R(t)===C?((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=()=>{A=k.filter(e=>!e.hidden),j=A.filter(e=>!I(e)),M=new Map(j.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 k){let t=R(e)??``,n=L(e),a=r===``||be(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`);d&&(d.hidden=i>0),i===0?s.setAttribute(`data-empty`,``):s.removeAttribute(`data-empty`),H()},G=()=>{let n=P.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:le,align:ue,sideOffset:de,alignOffset:fe,avoidCollisions:pe,collisionPadding:me,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:()=>S,ancestorScroll:!1,onUpdate:G,ignoreScrollTarget:e=>e instanceof Node&&s.contains(e)}),Se=e=>c&&c.contains(e)&&c.scrollHeight>c.clientHeight?c:s,q=t=>{for(let n=0;n<j.length;n++){let r=j[n];n===t?(r.setAttribute(`data-highlighted`,``),o.setAttribute(`aria-activedescendant`,r.id),(0,e.ensureItemVisibleInContainer)(r,Se(r))):r.removeAttribute(`data-highlighted`)}w=t},J=()=>{for(let e of k)e.removeAttribute(`data-highlighted`);w=-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:()=>{F||(P.restore(),s.hidden=!0)}}),Z=(t,n=!1)=>{if(S!==t&&!(v&&t)){if(t){S=!0,(0,e.setAria)(o,`expanded`,!0),P.mount(),s.hidden=!1,Y(`open`),X.enter(),xe(),T=!1,h&&(o.value=``),W(o.value);let t=j.findIndex(e=>R(e)===C);t>=0?q(t):J(),K.start(),G(),K.update(),requestAnimationFrame(()=>{S&&K.update()})}else S=!1,(0,e.setAria)(o,`expanded`,!1),Y(`closed`),J(),T=!1,K.stop(),X.exit(),h?o.value=``:o.value=z(C);(0,e.emit)(r,`combobox:open-change`,{open:S}),se?.(S)}},Q=(t,n=!1)=>{if(C===t&&!n)return;let i=C;C=t,ye(),N&&(N.value=t??``),t===null?r.removeAttribute(`data-value`):r.setAttribute(`data-value`,t);let a=c??s,d=k.length>0?k:(0,e.getParts)(a,`combobox-item`);for(let n of d)R(n)===t?((0,e.setAria)(n,`selected`,!0),n.setAttribute(`data-selected`,``)):((0,e.setAria)(n,`selected`,!1),n.removeAttribute(`data-selected`));let f=z(t);h||(o.value=f),u?t===null?(u.textContent=g||_,(u.textContent??``).trim().length>0?(u.setAttribute(`data-placeholder`,``),l?.setAttribute(`data-placeholder`,``)):(u.removeAttribute(`data-placeholder`),l?.removeAttribute(`data-placeholder`))):(u.textContent=f,u.removeAttribute(`data-placeholder`),l?.removeAttribute(`data-placeholder`)):l&&(t===null?l.setAttribute(`data-placeholder`,``):l.removeAttribute(`data-placeholder`)),!n&&i!==t&&((0,e.emit)(r,`combobox:change`,{value:t}),oe?.(t))},$=e=>{if(I(e))return;let t=R(e);t!==void 0&&(Q(t),Z(!1))};return(0,e.setAria)(o,`expanded`,!1),s.hidden=!0,Y(`closed`),Q(C,!0),E.push((0,e.on)(he,`keydown`,e=>{e.key===`Tab`&&(D=Date.now())},{capture:!0}),(0,e.on)(o,`pointerdown`,()=>{O=!0}),(0,e.on)(o,`input`,()=>{let t=o.value,n=t.trim()!==``;(0,e.emit)(r,`combobox:input-change`,{inputValue:t}),ce?.(t),S?(W(t),b&&n&&j.length>0?q(0):J(),K.update()):(Z(!0),b&&n&&j.length>0?q(0):w!==-1&&J())}),(0,e.on)(o,`keydown`,e=>{if(!v)switch(e.key){case`ArrowDown`:{if(e.preventDefault(),!S){Z(!0);return}T=!0;let t=j.length;if(t===0)return;q(w===-1?0:(w+1)%t);break}case`ArrowUp`:{if(e.preventDefault(),!S){Z(!0);return}T=!0;let t=j.length;if(t===0)return;q(w===-1?t-1:(w-1+t)%t);break}case`Home`:if(!S)return;e.preventDefault(),T=!0,j.length>0&&q(0);break;case`End`:if(!S)return;e.preventDefault(),T=!0,j.length>0&&q(j.length-1);break;case`Enter`:if(!S)return;e.preventDefault(),w>=0&&w<j.length&&$(j[w]);break;case`Escape`:S?(e.preventDefault(),Z(!1)):C!==null&&(e.preventDefault(),Q(null));break;case`Tab`:S&&Z(!1,!0);break}}),(0,e.on)(o,`focus`,()=>{if(v)return;o.select();let e=O||Date.now()-D<=750;O=!1,ie&&!S&&e&&Z(!0)})),l&&E.push((0,e.on)(l,`click`,()=>{v||(S?Z(!1):(Z(!0),o.focus()))})),E.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(!(T&&(T=!1,t&&M.get(t)===w)))if(t&&!I(t)&&!t.hidden){let e=M.get(t);e!==void 0&&e!==w&&q(e)}else J()}),(0,e.on)(s,`pointerleave`,()=>{T||J()}),(0,e.on)(s,`mousedown`,e=>{e.preventDefault()})),E.push((0,e.createDismissLayer)({root:r,isOpen:()=>S,onDismiss:()=>Z(!1),closeOnClickOutside:!0,closeOnEscape:!1})),E.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&&(x=t.itemToStringValue,Q(C,!0))})),ne&&Z(!0),{get value(){return C},get inputValue(){return o.value},get isOpen(){return S},select:e=>Q(e),clear:()=>Q(null),open:()=>Z(!0),close:()=>Z(!1),setItemToStringValue:e=>{x=e,Q(C,!0)},destroy:()=>{F=!0,K.stop(),X.cleanup(),P.cleanup(),E.forEach(e=>e()),E.length=0,N&&N.parentNode&&N.parentNode.removeChild(N),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`],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`),C=d(p,`combobox-positioner`),w=C&&b&&C.contains(b)?C:null,T=d(p,`combobox-portal`),re=T&&w&&T.contains(w)?T:null;if(!y||!b)throw Error(`Combobox requires combobox-input and combobox-content slots`);let ie=_.defaultValue??u(p,`defaultValue`)??null,ae=_.defaultOpen??s(p,`defaultOpen`)??!1,E=_.placeholder??u(p,`placeholder`)??``,D=_.disabled??s(p,`disabled`)??!1,O=_.required??s(p,`required`)??!1,oe=_.name??u(p,`name`)??null,se=_.openOnFocus??s(p,`openOnFocus`)??!0,ce=_.autoHighlight??s(p,`autoHighlight`)??!1,le=_.filter??null,ue=_.onValueChange,de=_.onOpenChange,fe=_.onInputValueChange,k=_.itemToStringValue??null,pe=_.side??c(b,`side`,g)??c(p,`side`,g)??`bottom`,me=_.align??c(b,`align`,te)??c(p,`align`,te)??`start`,he=_.sideOffset??l(b,`sideOffset`)??l(p,`sideOffset`)??4,ge=_.alignOffset??l(b,`alignOffset`)??l(p,`alignOffset`)??0,_e=_.avoidCollisions??s(b,`avoidCollisions`)??s(p,`avoidCollisions`)??!0,ve=_.collisionPadding??l(b,`collisionPadding`)??l(p,`collisionPadding`)??8,A=!1,j=ie,M=-1,N=!1,P=[],ye=p.ownerDocument??document,F=-1/0,I=!1,L=[],be=[],R=[],z=new Map,B=null,V=n({content:b,root:p,wrapperSlot:w?void 0:`combobox-positioner`,container:w??void 0,mountTarget:w?re??w:void 0}),xe=!1,H=e=>e.hasAttribute(`disabled`)||e.hasAttribute(`data-disabled`)||e.getAttribute(`aria-disabled`)===`true`,Se=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,Ce=e=>e===null?null:f(x??b,`combobox-item`).find(t=>U(t)===e)??null,W=e=>{let t=Ce(e);return k?k(t,e):t?Se(t):``},we=o(y,`combobox-input`),Te=x??b,Ee=o(Te,`combobox-list`);y.setAttribute(`role`,`combobox`),y.setAttribute(`aria-autocomplete`,`list`),y.setAttribute(`autocomplete`,`off`),y.setAttribute(`aria-controls`,Ee),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 De=document.querySelector(`label[for="${CSS.escape(we)}"]`);if(De){let e=o(De,`combobox-label`),t=y.getAttribute(`aria-labelledby`);y.setAttribute(`aria-labelledby`,t?`${t} ${e}`:e),Te.setAttribute(`aria-labelledby`,e)}D&&(y.setAttribute(`aria-disabled`,`true`),y.disabled=!0,S&&(S.setAttribute(`aria-disabled`,`true`),S.setAttribute(`data-disabled`,``))),O&&(y.setAttribute(`aria-required`,`true`),y.required=!0);let Oe=()=>{O&&y.setCustomValidity(j===null?`Please select a value`:``)};E&&(y.placeholder=E),oe&&(y.name&&y.removeAttribute(`name`),B=document.createElement(`input`),B.type=`hidden`,B.name=oe,B.value=j??``,p.appendChild(B));let ke=le??((e,t,n)=>n.toLowerCase().includes(e.toLowerCase())),Ae=()=>{let e=x??b;L=f(e,`combobox-item`);for(let e of L)e.setAttribute(`role`,`option`),o(e,`combobox-item`),H(e)?e.setAttribute(`aria-disabled`,`true`):e.removeAttribute(`aria-disabled`),U(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)}}je()},je=()=>{be=L.filter(e=>!e.hidden),R=be.filter(e=>!H(e)),z=new Map(R.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},Me=e=>{let t=x??b,n=e.trim(),r=0;for(let e of L){let t=U(e)??``,i=Se(e),a=n===``||ke(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`),je()},Ne=()=>{let t=V.container,n=p.ownerDocument.defaultView??window,r=p.getBoundingClientRect();b.style.minWidth=`${r.width}px`;let i=e({anchorRect:r,contentRect:b.getBoundingClientRect(),side:pe,align:me,sideOffset:he,alignOffset:ge,avoidCollisions:_e,collisionPadding:ve,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:()=>A,ancestorScroll:!1,onUpdate:Ne,ignoreScrollTarget:e=>e instanceof Node&&b.contains(e)}),Pe=e=>x&&x.contains(e)&&x.scrollHeight>x.clientHeight?x:b,q=e=>{for(let t=0;t<R.length;t++){let n=R[t];t===e?(n.setAttribute(`data-highlighted`,``),y.setAttribute(`aria-activedescendant`,n.id),ee(n,Pe(n))):n.removeAttribute(`data-highlighted`)}M=e},J=()=>{for(let e of L)e.removeAttribute(`data-highlighted`);M=-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:()=>{xe||(V.restore(),b.hidden=!0)}}),Z=(e,t=!1)=>{if(A!==e&&!(D&&e)){if(e){A=!0,h(y,`expanded`,!0),V.mount(),b.hidden=!1,Y(`open`),X.enter(),Ae(),N=!1,Me(y.value);let e=R.findIndex(e=>U(e)===j);e>=0?q(e):J(),K.start(),Ne(),K.update(),requestAnimationFrame(()=>{A&&K.update()})}else A=!1,h(y,`expanded`,!1),Y(`closed`),J(),N=!1,K.stop(),X.exit(),y.value=W(j);a(p,`combobox:open-change`,{open:A}),de?.(A)}},Q=(e,t=!1)=>{if(j===e&&!t)return;let n=j;j=e,Oe(),B&&(B.value=e??``),e===null?p.removeAttribute(`data-value`):p.setAttribute(`data-value`,e);let r=x??b,i=L.length>0?L: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}),ue?.(e))},$=e=>{if(H(e))return;let t=U(e);t!==void 0&&(Q(t),Z(!1))};return h(y,`expanded`,!1),b.hidden=!0,Y(`closed`),Q(j,!0),P.push(m(ye,`keydown`,e=>{e.key===`Tab`&&(F=Date.now())},{capture:!0}),m(y,`pointerdown`,()=>{I=!0}),m(y,`input`,()=>{let e=y.value,t=e.trim()!==``;a(p,`combobox:input-change`,{inputValue:e}),fe?.(e),A?(Me(e),ce&&t&&R.length>0?q(0):J(),K.update()):(Z(!0),ce&&t&&R.length>0?q(0):M!==-1&&J())}),m(y,`keydown`,e=>{if(!D)switch(e.key){case`ArrowDown`:{if(e.preventDefault(),!A){Z(!0);return}N=!0;let t=R.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=R.length;if(t===0)return;q(M===-1?t-1:(M-1+t)%t);break}case`Home`:if(!A)return;e.preventDefault(),N=!0,R.length>0&&q(0);break;case`End`:if(!A)return;e.preventDefault(),N=!0,R.length>0&&q(R.length-1);break;case`Enter`:if(!A)return;e.preventDefault(),M>=0&&M<R.length&&$(R[M]);break;case`Escape`:A?(e.preventDefault(),Z(!1)):j!==null&&(e.preventDefault(),Q(null));break;case`Tab`:A&&Z(!1,!0);break}}),m(y,`focus`,()=>{if(D)return;y.select();let e=I||Date.now()-F<=750;I=!1,se&&!A&&e&&Z(!0)})),S&&P.push(m(S,`click`,()=>{D||(A?Z(!1):(Z(!0),y.focus()))})),P.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(!(N&&(N=!1,t&&z.get(t)===M)))if(t&&!H(t)&&!t.hidden){let e=z.get(t);e!==void 0&&e!==M&&q(e)}else J()}),m(b,`pointerleave`,()=>{N||J()}),m(b,`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&&(y.value=t.inputValue),t?.itemToStringValue!==void 0&&(k=t.itemToStringValue,y.value=W(j))})),ae&&Z(!0),{get value(){return j},get inputValue(){return y.value},get isOpen(){return A},select:e=>Q(e),clear:()=>Q(null),open:()=>Z(!0),close:()=>Z(!1),setItemToStringValue:e=>{k=e,y.value=W(j)},destroy:()=>{xe=!0,K.stop(),X.cleanup(),V.cleanup(),P.forEach(e=>e()),P.length=0,B&&B.parentNode&&B.parentNode.removeChild(B),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};
|
|
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(p,`combobox-value`),te=d(S??x??p,`combobox-empty`),T=d(p,`combobox-positioner`),E=T&&x&&T.contains(x)?T:null,D=d(p,`combobox-portal`),ne=D&&E&&D.contains(E)?D:null;if(!b||!x)throw Error(`Combobox requires combobox-input and combobox-content slots`);let O=x.contains(b),re=w?.textContent?.trim()??``,ie=v.defaultValue??u(p,`defaultValue`)??null,ae=v.defaultOpen??s(p,`defaultOpen`)??!1,k=v.placeholder??u(p,`placeholder`)??``,A=v.disabled??s(p,`disabled`)??!1,oe=v.required??s(p,`required`)??!1,j=v.name??u(p,`name`)??null,se=v.openOnFocus??s(p,`openOnFocus`)??!0,ce=v.autoHighlight??s(p,`autoHighlight`)??!1,le=v.filter??null,ue=v.onValueChange,de=v.onOpenChange,fe=v.onInputValueChange,M=v.itemToStringValue??null,pe=v.side??c(x,`side`,g)??c(p,`side`,g)??`bottom`,me=v.align??c(x,`align`,_)??c(p,`align`,_)??`start`,he=v.sideOffset??l(x,`sideOffset`)??l(p,`sideOffset`)??4,ge=v.alignOffset??l(x,`alignOffset`)??l(p,`alignOffset`)??0,_e=v.avoidCollisions??s(x,`avoidCollisions`)??s(p,`avoidCollisions`)??!0,ve=v.collisionPadding??l(x,`collisionPadding`)??l(p,`collisionPadding`)??8,N=!1,P=ie,F=-1,I=!1,L=[],ye=p.ownerDocument??document,be=-1/0,R=!1,z=[],B=[],V=[],H=new Map,U=null,W=n({content:x,root:p,wrapperSlot:E?void 0:`combobox-positioner`,container:E??void 0,mountTarget:E?ne??E:void 0}),xe=!1,G=e=>e.hasAttribute(`disabled`)||e.hasAttribute(`data-disabled`)||e.getAttribute(`aria-disabled`)===`true`,Se=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()??``)},K=e=>e.hasAttribute(`data-value`)?e.getAttribute(`data-value`):void 0,Ce=e=>e===null?null:f(S??x,`combobox-item`).find(t=>K(t)===e)??null,we=e=>{let t=Ce(e);return M?M(t,e):t?Se(t):``},Te=o(b,`combobox-input`),Ee=S??x,De=o(Ee,`combobox-list`);b.setAttribute(`role`,`combobox`),b.setAttribute(`aria-autocomplete`,`list`),b.setAttribute(`autocomplete`,`off`),b.setAttribute(`aria-controls`,De),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 Oe=document.querySelector(`label[for="${CSS.escape(Te)}"]`);if(Oe){let e=o(Oe,`combobox-label`),t=b.getAttribute(`aria-labelledby`);b.setAttribute(`aria-labelledby`,t?`${t} ${e}`:e),Ee.setAttribute(`aria-labelledby`,e)}A&&(b.setAttribute(`aria-disabled`,`true`),b.disabled=!0,C&&(C.setAttribute(`aria-disabled`,`true`),C.setAttribute(`data-disabled`,``))),oe&&(b.setAttribute(`aria-required`,`true`),b.required=!0);let ke=()=>{oe&&b.setCustomValidity(P===null?`Please select a value`:``)};k&&(b.placeholder=k),w&&(w.textContent=re||k,w.textContent.trim().length>0&&(w.setAttribute(`data-placeholder`,``),C?.setAttribute(`data-placeholder`,``))),j&&(b.name&&b.removeAttribute(`name`),U=document.createElement(`input`),U.type=`hidden`,U.name=j,U.value=P??``,p.appendChild(U));let Ae=le??((e,t,n)=>n.toLowerCase().includes(e.toLowerCase())),je=()=>{let e=S??x;z=f(e,`combobox-item`);for(let e of z)e.setAttribute(`role`,`option`),o(e,`combobox-item`),G(e)?e.setAttribute(`aria-disabled`,`true`):e.removeAttribute(`aria-disabled`),K(e)===P?(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)}}Me()},Me=()=>{B=z.filter(e=>!e.hidden),V=B.filter(e=>!G(e)),H=new Map(V.map((e,t)=>[e,t]))},Ne=(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},Pe=e=>{let t=S??x,n=e.trim(),r=0;for(let e of z){let t=K(e)??``,i=Se(e),a=n===``||Ae(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=!Ne(e,`previous`)||!Ne(e,`next`);te&&(te.hidden=r>0),r===0?x.setAttribute(`data-empty`,``):x.removeAttribute(`data-empty`),Me()},Fe=()=>{let t=W.container,n=p.ownerDocument.defaultView??window,r=p.getBoundingClientRect();x.style.minWidth=`${r.width}px`;let i=e({anchorRect:r,contentRect:x.getBoundingClientRect(),side:pe,align:me,sideOffset:he,alignOffset:ge,avoidCollisions:_e,collisionPadding:ve,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))},q=r({observedElements:[p,x],isActive:()=>N,ancestorScroll:!1,onUpdate:Fe,ignoreScrollTarget:e=>e instanceof Node&&x.contains(e)}),Ie=e=>S&&S.contains(e)&&S.scrollHeight>S.clientHeight?S:x,J=e=>{for(let t=0;t<V.length;t++){let n=V[t];t===e?(n.setAttribute(`data-highlighted`,``),b.setAttribute(`aria-activedescendant`,n.id),ee(n,Ie(n))):n.removeAttribute(`data-highlighted`)}F=e},Y=()=>{for(let e of z)e.removeAttribute(`data-highlighted`);F=-1,b.removeAttribute(`aria-activedescendant`)},X=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`))},Z=i({element:x,onExitComplete:()=>{xe||(W.restore(),x.hidden=!0)}}),Q=(e,t=!1)=>{if(N!==e&&!(A&&e)){if(e){N=!0,h(b,`expanded`,!0),W.mount(),x.hidden=!1,X(`open`),Z.enter(),je(),I=!1,O&&(b.value=``),Pe(b.value);let e=V.findIndex(e=>K(e)===P);e>=0?J(e):Y(),q.start(),Fe(),q.update(),requestAnimationFrame(()=>{N&&q.update()})}else N=!1,h(b,`expanded`,!1),X(`closed`),Y(),I=!1,q.stop(),Z.exit(),O?b.value=``:b.value=we(P);a(p,`combobox:open-change`,{open:N}),de?.(N)}},$=(e,t=!1)=>{if(P===e&&!t)return;let n=P;P=e,ke(),U&&(U.value=e??``),e===null?p.removeAttribute(`data-value`):p.setAttribute(`data-value`,e);let r=S??x,i=z.length>0?z:f(r,`combobox-item`);for(let t of i)K(t)===e?(h(t,`selected`,!0),t.setAttribute(`data-selected`,``)):(h(t,`selected`,!1),t.removeAttribute(`data-selected`));let o=we(e);O||(b.value=o),w?e===null?(w.textContent=re||k,(w.textContent??``).trim().length>0?(w.setAttribute(`data-placeholder`,``),C?.setAttribute(`data-placeholder`,``)):(w.removeAttribute(`data-placeholder`),C?.removeAttribute(`data-placeholder`))):(w.textContent=o,w.removeAttribute(`data-placeholder`),C?.removeAttribute(`data-placeholder`)):C&&(e===null?C.setAttribute(`data-placeholder`,``):C.removeAttribute(`data-placeholder`)),!t&&n!==e&&(a(p,`combobox:change`,{value:e}),ue?.(e))},Le=e=>{if(G(e))return;let t=K(e);t!==void 0&&($(t),Q(!1))};return h(b,`expanded`,!1),x.hidden=!0,X(`closed`),$(P,!0),L.push(m(ye,`keydown`,e=>{e.key===`Tab`&&(be=Date.now())},{capture:!0}),m(b,`pointerdown`,()=>{R=!0}),m(b,`input`,()=>{let e=b.value,t=e.trim()!==``;a(p,`combobox:input-change`,{inputValue:e}),fe?.(e),N?(Pe(e),ce&&t&&V.length>0?J(0):Y(),q.update()):(Q(!0),ce&&t&&V.length>0?J(0):F!==-1&&Y())}),m(b,`keydown`,e=>{if(!A)switch(e.key){case`ArrowDown`:{if(e.preventDefault(),!N){Q(!0);return}I=!0;let t=V.length;if(t===0)return;J(F===-1?0:(F+1)%t);break}case`ArrowUp`:{if(e.preventDefault(),!N){Q(!0);return}I=!0;let t=V.length;if(t===0)return;J(F===-1?t-1:(F-1+t)%t);break}case`Home`:if(!N)return;e.preventDefault(),I=!0,V.length>0&&J(0);break;case`End`:if(!N)return;e.preventDefault(),I=!0,V.length>0&&J(V.length-1);break;case`Enter`:if(!N)return;e.preventDefault(),F>=0&&F<V.length&&Le(V[F]);break;case`Escape`:N?(e.preventDefault(),Q(!1)):P!==null&&(e.preventDefault(),$(null));break;case`Tab`:N&&Q(!1,!0);break}}),m(b,`focus`,()=>{if(A)return;b.select();let e=R||Date.now()-be<=750;R=!1,se&&!N&&e&&Q(!0)})),C&&L.push(m(C,`click`,()=>{A||(N?Q(!1):(Q(!0),b.focus()))})),L.push(m(x,`click`,e=>{let t=e.target.closest?.(`[data-slot="combobox-item"]`);t&&!t.hidden&&Le(t)}),m(x,`pointermove`,e=>{let t=e.target.closest?.(`[data-slot="combobox-item"]`);if(!(I&&(I=!1,t&&H.get(t)===F)))if(t&&!G(t)&&!t.hidden){let e=H.get(t);e!==void 0&&e!==F&&J(e)}else Y()}),m(x,`pointerleave`,()=>{I||Y()}),m(x,`mousedown`,e=>{e.preventDefault()})),L.push(t({root:p,isOpen:()=>N,onDismiss:()=>Q(!1),closeOnClickOutside:!0,closeOnEscape:!1})),L.push(m(p,`combobox:set`,e=>{let t=e.detail;t?.value!==void 0&&$(t.value),t?.open!==void 0&&Q(t.open),t?.inputValue!==void 0&&(b.value=t.inputValue),t?.itemToStringValue!==void 0&&(M=t.itemToStringValue,$(P,!0))})),ae&&Q(!0),{get value(){return P},get inputValue(){return b.value},get isOpen(){return N},select:e=>$(e),clear:()=>$(null),open:()=>Q(!0),close:()=>Q(!1),setItemToStringValue:e=>{M=e,$(P,!0)},destroy:()=>{xe=!0,q.stop(),Z.cleanup(),W.cleanup(),L.forEach(e=>e()),L.length=0,U&&U.parentNode&&U.parentNode.removeChild(U),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};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@data-slot/combobox",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.74",
|
|
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
|
+
"@data-slot/core": "0.2.74"
|
|
44
44
|
}
|
|
45
45
|
}
|