forge-select 0.5.0 → 0.6.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.
- package/dist/index.cjs +119 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.global.js +1 -1
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +119 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -221,8 +221,13 @@ declare class ForgeSelect {
|
|
|
221
221
|
private rows;
|
|
222
222
|
private navItems;
|
|
223
223
|
private highlightedIndex;
|
|
224
|
+
private typeaheadBuffer;
|
|
225
|
+
private typeaheadTimer;
|
|
224
226
|
private rowContentCache;
|
|
225
227
|
private rowHeightCache;
|
|
228
|
+
private rowOffsetsCache;
|
|
229
|
+
private scrollRafId;
|
|
230
|
+
private ancestorScrollRafId;
|
|
226
231
|
private searchIndex;
|
|
227
232
|
private expandedValues;
|
|
228
233
|
private loading;
|
|
@@ -308,6 +313,12 @@ declare class ForgeSelect {
|
|
|
308
313
|
private bindEvents;
|
|
309
314
|
private applySearchQuery;
|
|
310
315
|
private handleKeydown;
|
|
316
|
+
/**
|
|
317
|
+
* Jumps the highlight to the next nav item (wrapping) whose label starts
|
|
318
|
+
* with the accumulated buffer, matching native <select> typeahead: rapid
|
|
319
|
+
* distinct keystrokes narrow the prefix, a pause resets it.
|
|
320
|
+
*/
|
|
321
|
+
private handleTypeahead;
|
|
311
322
|
private canSelectOption;
|
|
312
323
|
private hasReachedMaximum;
|
|
313
324
|
private announceMaximum;
|
package/dist/index.d.ts
CHANGED
|
@@ -221,8 +221,13 @@ declare class ForgeSelect {
|
|
|
221
221
|
private rows;
|
|
222
222
|
private navItems;
|
|
223
223
|
private highlightedIndex;
|
|
224
|
+
private typeaheadBuffer;
|
|
225
|
+
private typeaheadTimer;
|
|
224
226
|
private rowContentCache;
|
|
225
227
|
private rowHeightCache;
|
|
228
|
+
private rowOffsetsCache;
|
|
229
|
+
private scrollRafId;
|
|
230
|
+
private ancestorScrollRafId;
|
|
226
231
|
private searchIndex;
|
|
227
232
|
private expandedValues;
|
|
228
233
|
private loading;
|
|
@@ -308,6 +313,12 @@ declare class ForgeSelect {
|
|
|
308
313
|
private bindEvents;
|
|
309
314
|
private applySearchQuery;
|
|
310
315
|
private handleKeydown;
|
|
316
|
+
/**
|
|
317
|
+
* Jumps the highlight to the next nav item (wrapping) whose label starts
|
|
318
|
+
* with the accumulated buffer, matching native <select> typeahead: rapid
|
|
319
|
+
* distinct keystrokes narrow the prefix, a pause resets it.
|
|
320
|
+
*/
|
|
321
|
+
private handleTypeahead;
|
|
311
322
|
private canSelectOption;
|
|
312
323
|
private hasReachedMaximum;
|
|
313
324
|
private announceMaximum;
|
package/dist/index.global.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var ForgeSelectBundle=(()=>{var L=Object.defineProperty;var B=Object.getOwnPropertyDescriptor;var z=Object.getOwnPropertyNames;var K=Object.prototype.hasOwnProperty;var U=(a,e)=>{for(var t in e)L(a,t,{get:e[t],enumerable:!0})},Q=(a,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of z(e))!K.call(a,s)&&s!==t&&L(a,s,{get:()=>e[s],enumerable:!(i=B(e,s))||i.enumerable});return a};var G=a=>Q(L({},"__esModule",{value:!0}),a);var ee={};U(ee,{ForgeSelect:()=>v,default:()=>v});var x=class{constructor(){this.handlers=new Map}on(e,t){let i=this.handlers.get(e);i||(i=new Set,this.handlers.set(e,i)),i.add(t)}off(e,t){this.handlers.get(e)?.delete(t)}emit(e,...t){let i=this.handlers.get(e);if(i)for(let s of[...i])s(...t)}clear(){this.handlers.clear()}};function N(a,e,t,i=4){let s=t-a.bottom,n=a.top,r=e>s&&n>s;return{dropUp:r,top:r?a.top-e-i:a.bottom+i}}var C={en:{noResults:"No results found",loading:"Loading\u2026",loadingMore:"Loading more\u2026",errorLoading:"Could not load options",createOption:'Create "{query}"',clearSelection:"Clear selection",removeItem:"Remove {label}",search:"Search",reorderHint:"{label}. Press Alt+Left or Alt+Right to reorder.",minSearchLength:"Type {count} or more characters to search",maximumSelected:"Maximum of {count} selections reached"},vi:{noResults:"Kh\xF4ng t\xECm th\u1EA5y k\u1EBFt qu\u1EA3",loading:"\u0110ang t\u1EA3i\u2026",loadingMore:"\u0110ang t\u1EA3i th\xEAm\u2026",errorLoading:"Kh\xF4ng th\u1EC3 t\u1EA3i t\xF9y ch\u1ECDn",createOption:'T\u1EA1o "{query}"',clearSelection:"X\xF3a l\u1EF1a ch\u1ECDn",removeItem:"X\xF3a {label}",search:"T\xECm ki\u1EBFm",reorderHint:"{label}. Nh\u1EA5n Alt+Tr\xE1i ho\u1EB7c Alt+Ph\u1EA3i \u0111\u1EC3 s\u1EAFp x\u1EBFp l\u1EA1i.",minSearchLength:"Nh\u1EADp th\xEAm {count} k\xFD t\u1EF1 \u0111\u1EC3 t\xECm ki\u1EBFm",maximumSelected:"\u0110\xE3 \u0111\u1EA1t t\u1ED1i \u0111a {count} l\u1EF1a ch\u1ECDn"}};function A(a){return typeof a=="string"?C[a]??C.en:{...C.en,...a}}function p(a,e){return a.replace(/\{(\w+)\}/g,(t,i)=>e[i]??t)}function V(a){let e=[];for(let t of Array.from(a.children))t instanceof HTMLOptGroupElement?e.push({label:t.label,options:Array.from(t.querySelectorAll("option")).map(F)}):t instanceof HTMLOptionElement&&e.push(F(t));return e}function F(a){let e=a.parentElement instanceof HTMLOptGroupElement&&a.parentElement.disabled;return{value:a.value,label:a.textContent?.trim()??a.value,disabled:a.disabled||e||void 0}}function b(a,e,t,i="row"){if(t){let s=t(e);typeof s=="string"?a.innerHTML=s:a.append(s);return}if(!e.avatar&&!e.description){a.textContent=e.label;return}if(e.avatar){let s=document.createElement("img");s.className=i==="row"?"forge-select__option-avatar":"forge-select__inline-avatar",s.src=e.avatar,s.alt="",s.setAttribute("loading","lazy"),s.setAttribute("decoding","async"),a.append(s)}if(i==="row"&&e.description){let s=document.createElement("span");s.className="forge-select__option-body";let n=document.createElement("span");n.className="forge-select__option-label",n.textContent=e.label;let r=document.createElement("span");r.className="forge-select__option-desc",r.textContent=e.description,s.append(n,r),a.append(s)}else{let s=document.createElement("span");s.className="forge-select__option-label",s.textContent=e.label,a.append(s)}}function j(a,e,t){if(!a.url)throw new Error("ForgeSelect: ajax requires either url or request.");if(typeof a.url=="function")return a.url(e,t);if(!a.params)return a.url;let i=new URLSearchParams;for(let[n,r]of Object.entries(a.params(e,t)))i.set(n,String(r));let s=a.url.includes("?")?"&":"?";return`${a.url}${s}${i.toString()}`}function T(a,e){let t=a.transform?a.transform(e):e;if(Array.isArray(t))return{options:t,hasMore:!1};if(!t||!Array.isArray(t.options))throw new Error("ForgeSelect: ajax.transform must return an array of options, or an object shaped like { options: Option[], hasMore?: boolean }.");return{options:t.options,hasMore:a.pagination?!!t.hasMore:!1}}var y=class{constructor(){this.entries=new Map}get(e,t=Date.now()){let i=this.entries.get(e);if(i){if(i.expiresAt<=t){this.entries.delete(e);return}return i.value}}set(e,t,i,s=Date.now()){i>0&&this.entries.set(e,{value:t,expiresAt:s+i})}clear(){this.entries.clear()}};function g(a,e=!0){let t=a.toLocaleLowerCase();return e?t.normalize("NFD").replace(/[\u0300-\u036f]/g,"").replace(/đ/g,"d"):t}function W(a,e){if(e==="label")return a.label;if(e==="description")return a.description??"";let t=e.slice(5).split("."),i=a.meta;for(let s of t){if(!i||typeof i!="object")return"";i=i[s]}return i==null?"":String(i)}var w=class{constructor(){this.cache=new WeakMap}clear(){this.cache=new WeakMap}score(e,t,i){let s=g(t.trim(),i.accentInsensitive);if(!s)return 1;if(i.scorer)return i.scorer(e,t.trim(),s);let n=`${i.accentInsensitive?"1":"0"}:${i.fields.join("\0")}`,r=this.cache.get(e);r||(r=new Map,this.cache.set(e,r));let o=r.get(n);if(o||(o=i.fields.map(c=>g(W(e,c),i.accentInsensitive)),r.set(n,o)),!(i.tokenSearch?s.split(/\s+/).filter(Boolean):[s]).every(c=>o.some(u=>u.includes(c))))return 0;let h=o[i.fields.indexOf("label")];return h===s?4:h?.startsWith(s)?3:h?.includes(s)?2:1}};function q(a,e,t=!0){let i=g(e.trim(),t).split(/\s+/).filter(Boolean);if(!i.length)return[];let s=g(a,t),n=[];for(let r of i){let o=s.indexOf(r);o>=0&&n.push([o,o+r.length])}return n.sort((r,o)=>r[0]-o[0])}function m(a){return a.options!==void 0}var H=a=>!!a.disabled;function S(a,e=H){if(!a.children)return[];let t=[];for(let i of a.children)e(i)||t.push(i.value),t.push(...S(i,e));return t}function O(a,e,t=H){if(!a.children?.length)return e.includes(a.value)?"all":"none";let i=a.children.filter(s=>!t(s)).map(s=>O(s,e,t));return i.length===0?"none":i.every(s=>s==="all")?"all":i.every(s=>s==="none")?"none":"some"}function P(a,e){let t=i=>{for(let s of i){if(s.value===e)return s;let n=s.children?t(s.children):void 0;if(n)return n}};for(let i of a){let s=t(m(i)?i.options:[i]);if(s)return s}}function M(a,e,t=H){let i=s=>{if(!s.children?.length)return;for(let o of s.children)i(o);let n=O(s,e,t),r=e.indexOf(s.value);n==="all"&&r===-1?e.push(s.value):n!=="all"&&r!==-1&&e.splice(r,1)};for(let s of a)(m(s)?s.options:[s]).forEach(i)}function D(a){let e=new Set,t=i=>{e.add(i.value),i.children?.forEach(t)};for(let i of a)(m(i)?i.options:[i]).forEach(t);return e}function $(a,e){return a.length===e.length&&a.every((t,i)=>t===e[i])}var X=36,E=5,J=100,Y=2e3,Z=0,v=class{constructor(e,t={}){this.selected=[];this.selectedOptions=new Map;this.suppressNextTagClick=!1;this.emitter=new x;this.uid=`forge-select-${++Z}`;this.searchInput=null;this.portalHost=null;this.isOpen=!1;this.isDisabled=!1;this.destroyed=!1;this.query="";this.rows=[];this.navItems=[];this.highlightedIndex=-1;this.rowContentCache=new Map;this.rowHeightCache=new Map;this.searchIndex=new w;this.expandedValues=new Set;this.loading=!1;this.loadingMore=!1;this.page=0;this.hasMore=!0;this.ajaxTimer=null;this.ajaxRequestId=0;this.ajaxController=null;this.remoteLoaded=!1;this.remoteCache=new y;this.loadError=null;this.originalDisplay="";this.originalDisabled=!1;this.nativeSelect=null;this.nativeForm=null;this.syncingNative=!1;this.isOptionDisabled=e=>e.disabled===!0||(this.opts.isOptionDisabled?.(e)??!1);this.pointerDownOnControl=!1;this.onDocumentMouseDown=e=>{let t=e.target;!this.root.contains(t)&&!this.portalHost?.contains(t)&&this.close()};this.onWindowResize=()=>{this.positionDropdown()};this.onAncestorScroll=()=>{this.portalHost&&this.positionDropdown()};this.onNativeInvalid=e=>{e.preventDefault(),this.control.classList.add("forge-select__control--invalid"),this.control.setAttribute("aria-invalid","true"),this.isOpen||this.open(),this.control.focus(),this.emitter.emit("invalid",this.nativeSelect?.validationMessage??"")};this.onNativeChange=()=>{if(!this.nativeSelect||this.destroyed||this.syncingNative)return;let e=Array.from(this.nativeSelect.selectedOptions,t=>t.value);this.applyNativeValues(e)};this.onFormReset=()=>{if(!this.nativeSelect||this.destroyed)return;let e=Array.from(this.nativeSelect.options).filter(t=>t.defaultSelected).map(t=>t.value);this.applyNativeValues(e)};let i=typeof e=="string"?document.querySelector(e):e;if(!i)throw new Error(`ForgeSelect: target element not found: ${String(e)}`);this.el=i;let s=i instanceof HTMLSelectElement?i:null;if(this.nativeSelect=s,this.nativeForm=s?.form??null,this.originalDisplay=i.style.display,this.originalDisabled=s?.disabled??!1,this.opts={placeholder:t.placeholder??"",searchable:t.searchable??!0,multiple:t.multiple??s?.multiple??!1,clearable:t.clearable??!1,allowCreate:t.allowCreate??!1,sortable:t.sortable??!1,closeOnSelect:t.closeOnSelect??!1,maxSelections:t.maxSelections==null||!Number.isFinite(t.maxSelections)?void 0:Math.max(0,Math.floor(t.maxSelections)),theme:t.theme??"default",disabled:t.disabled??s?.disabled??!1,required:t.required??s?.required??!1,data:t.data,ajax:t.ajax,templateResult:t.templateResult,templateSelection:t.templateSelection,filterOption:t.filterOption,searchFields:t.searchFields??["label","description"],tokenSearch:t.tokenSearch??!0,accentInsensitive:t.accentInsensitive??!0,searchScorer:t.searchScorer,highlightSearch:t.highlightSearch??!1,minSearchLength:Math.max(0,Math.floor(t.minSearchLength??0)),minResultsForSearch:Math.max(0,Math.floor(t.minResultsForSearch??0)),isOptionDisabled:t.isOptionDisabled,virtualScroll:t.virtualScroll,itemHeight:typeof t.itemHeight=="number"?Math.max(1,t.itemHeight):X,variableItemHeight:t.itemHeight==="auto",language:t.language??"en",plugins:t.plugins??[],openOnFocus:t.openOnFocus??!1,dropdownParent:t.dropdownParent},this.strings=A(this.opts.language),this.plugins=this.opts.plugins,s&&(s.required=this.opts.required),this.data=this.opts.data??(s?V(s):[]),s&&!this.opts.data){let n=Array.from(s.options),r=s.multiple||s.selectedIndex>0||n.some(o=>o.defaultSelected);for(let o of n)r&&o.selected&&this.selectValue(o.value,!1)}this.buildDom(),this.renderValue(),this.opts.disabled&&this.disable(),s?.addEventListener("change",this.onNativeChange),s?.addEventListener("invalid",this.onNativeInvalid),this.nativeForm?.addEventListener("reset",this.onFormReset);for(let n of this.plugins)n.onInit?.(this);for(let n of this.opts.ajax?.prefetch??[])this.prefetchRemote(n)}applyNativeValues(e){this.selected=[];for(let t of this.opts.multiple?e:e.slice(0,1))this.selectValue(t,!1);this.renderValue(),this.isOpen&&this.renderList(),this.emitter.emit("change",this.getValue())}open(){if(!(this.isOpen||this.isDisabled||this.destroyed)){this.isOpen=!0,this.dropdown.hidden=!1,this.root.classList.add("forge-select--open"),this.control.setAttribute("aria-expanded","true"),document.addEventListener("mousedown",this.onDocumentMouseDown),this.opts.ajax&&(this.opts.ajax.loadOnOpen??!0)&&!this.remoteLoaded&&this.scheduleRemoteLoad(this.query,0),this.renderList(),this.positionDropdown(),window.addEventListener("resize",this.onWindowResize),document.addEventListener("scroll",this.onAncestorScroll,!0),this.searchInput&&!this.searchInput.hidden&&this.searchInput.focus(),this.emitter.emit("open");for(let e of this.plugins)e.onOpen?.(this)}}close(){if(this.isOpen){this.isOpen=!1,this.dropdown.hidden=!0,this.root.classList.remove("forge-select--open"),this.root.classList.remove("forge-select--drop-up"),this.control.setAttribute("aria-expanded","false"),document.removeEventListener("mousedown",this.onDocumentMouseDown),window.removeEventListener("resize",this.onWindowResize),document.removeEventListener("scroll",this.onAncestorScroll,!0),this.highlightedIndex=-1,this.searchInput&&(this.searchInput.value="",this.query=""),this.emitter.emit("close");for(let e of this.plugins)e.onClose?.(this)}}positionDropdown(){let e=this.control.getBoundingClientRect(),t=N(e,this.dropdown.offsetHeight,window.innerHeight);this.root.classList.toggle("forge-select--drop-up",t.dropUp),this.portalHost&&(this.portalHost.style.top=`${t.top}px`,this.portalHost.style.left=`${e.left}px`,this.portalHost.style.width=`${e.width}px`)}destroy(){if(!this.destroyed){this.close();for(let e of this.plugins)e.onDestroy?.(this);this.destroyed=!0,this.ajaxTimer&&clearTimeout(this.ajaxTimer),this.ajaxController?.abort(),this.nativeSelect?.removeEventListener("change",this.onNativeChange),this.nativeSelect?.removeEventListener("invalid",this.onNativeInvalid),this.nativeForm?.removeEventListener("reset",this.onFormReset),this.rowContentCache.clear(),this.rowHeightCache.clear(),this.searchIndex.clear(),this.portalHost?.remove(),this.root.remove(),this.el.style.display=this.originalDisplay,this.nativeSelect&&(this.nativeSelect.disabled=this.originalDisabled),this.emitter.clear()}}getValue(){return this.opts.multiple?[...this.selected]:this.selected[0]??null}getSearchQuery(){return this.query}setSearchQuery(e,t={}){this.applySearchQuery(e,t.emitSearch??!0)}isDropdownOpen(){return this.isOpen}updateOptions(e){e.data&&this.setData(e.data),"ajax"in e&&e.ajax!==this.opts.ajax&&(this.opts.ajax=e.ajax,this.remoteLoaded=!1,this.clearRemoteCache()),e.placeholder!==void 0&&(this.opts.placeholder=e.placeholder),e.clearable!==void 0&&(this.opts.clearable=e.clearable),e.allowCreate!==void 0&&(this.opts.allowCreate=e.allowCreate),e.sortable!==void 0&&(this.opts.sortable=e.sortable),e.closeOnSelect!==void 0&&(this.opts.closeOnSelect=e.closeOnSelect),"maxSelections"in e&&(this.opts.maxSelections=e.maxSelections==null||!Number.isFinite(e.maxSelections)?void 0:Math.max(0,Math.floor(e.maxSelections))),e.theme!==void 0&&(this.opts.theme=e.theme,this.root.dataset.theme=e.theme,this.portalHost&&(this.portalHost.dataset.theme=e.theme)),e.required!==void 0&&(this.opts.required=e.required,e.required?this.control.setAttribute("aria-required","true"):this.control.removeAttribute("aria-required"),this.nativeSelect&&(this.nativeSelect.required=e.required)),e.templateResult!==void 0&&(this.opts.templateResult=e.templateResult),e.templateSelection!==void 0&&(this.opts.templateSelection=e.templateSelection),e.filterOption!==void 0&&(this.opts.filterOption=e.filterOption),e.searchFields!==void 0&&(this.opts.searchFields=e.searchFields),e.tokenSearch!==void 0&&(this.opts.tokenSearch=e.tokenSearch),e.accentInsensitive!==void 0&&(this.opts.accentInsensitive=e.accentInsensitive),e.searchScorer!==void 0&&(this.opts.searchScorer=e.searchScorer),e.highlightSearch!==void 0&&(this.opts.highlightSearch=e.highlightSearch),e.minSearchLength!==void 0&&(this.opts.minSearchLength=Math.max(0,Math.floor(e.minSearchLength))),e.minResultsForSearch!==void 0&&(this.opts.minResultsForSearch=Math.max(0,Math.floor(e.minResultsForSearch))),e.isOptionDisabled!==void 0&&(this.opts.isOptionDisabled=e.isOptionDisabled),e.virtualScroll!==void 0&&(this.opts.virtualScroll=e.virtualScroll),e.itemHeight!==void 0&&(this.opts.variableItemHeight=e.itemHeight==="auto",typeof e.itemHeight=="number"&&(this.opts.itemHeight=Math.max(1,e.itemHeight)),this.root.style.setProperty("--fs-item-height",`${this.opts.itemHeight}px`),this.portalHost?.style.setProperty("--fs-item-height",`${this.opts.itemHeight}px`)),e.language!==void 0&&(this.opts.language=e.language,this.strings=A(e.language),this.clearBtn.setAttribute("aria-label",this.strings.clearSelection),this.searchInput?.setAttribute("aria-label",this.strings.search)),e.openOnFocus!==void 0&&(this.opts.openOnFocus=e.openOnFocus),e.disabled!==void 0&&(e.disabled?this.disable():this.enable()),this.root.classList.toggle("forge-select--sortable",this.opts.sortable&&this.opts.multiple),this.updateSearchVisibility(),this.rowContentCache.clear(),this.searchIndex.clear(),this.renderValue(),this.isOpen&&this.renderList()}validate(){let e=(!this.opts.required||this.selected.length>0)&&(this.control.dataset.validationMessage??"")==="";return this.control.classList.toggle("forge-select__control--invalid",!e),this.control.setAttribute("aria-invalid",String(!e)),e}setCustomValidity(e){this.nativeSelect?.setCustomValidity(e),this.control.dataset.validationMessage=e}reportValidity(){let e=this.validate()&&(this.nativeSelect?.checkValidity()??!0);if(!e){let t=this.nativeSelect?.validationMessage??this.control.dataset.validationMessage??"";if(this.nativeSelect)return this.nativeSelect.reportValidity();this.emitter.emit("invalid",t)}return e}reload(){this.opts.ajax&&(this.clearRemoteCache(),this.remoteLoaded=!1,this.scheduleRemoteLoad(this.query,0))}clearRemoteCache(){this.remoteCache.clear()}setValue(e,t={}){let i=e==null?[]:Array.isArray(e)?e:[e],s=this.opts.multiple?i:i.slice(0,1);if(!$(s,this.selected)){this.selected=[];for(let n of s)this.selectValue(n,!1);this.afterSelectionChange(t.emitChange??!0)}}setData(e){this.ajaxTimer&&(clearTimeout(this.ajaxTimer),this.ajaxTimer=null),this.ajaxController?.abort(),this.ajaxController=null,this.ajaxRequestId+=1,this.setLoading(!1),this.loadingMore=!1,this.loadError=null,this.remoteLoaded=!0,this.page=0,this.hasMore=!1,this.data=e,this.opts.data=e,this.updateSearchVisibility(),this.rowContentCache.clear(),this.searchIndex.clear(),this.highlightedIndex=-1,this.isOpen&&this.renderList()}selectAll(){if(this.opts.multiple){this.selected=[];for(let e of this.allSelectableValues()){let t=this.findOption(e);t&&this.canSelectOption(t)&&this.selectValue(e,!1)}this.afterSelectionChange()}}clearAll(){this.clearSelection()}enable(){this.isDisabled=!1,this.root.classList.remove("forge-select--disabled"),this.control.tabIndex=0,this.control.setAttribute("aria-disabled","false"),this.nativeSelect&&(this.nativeSelect.disabled=!1)}disable(){this.close(),this.isDisabled=!0,this.root.classList.add("forge-select--disabled"),this.control.tabIndex=-1,this.control.setAttribute("aria-disabled","true"),this.nativeSelect&&(this.nativeSelect.disabled=!0)}on(e,t){this.emitter.on(e,t)}off(e,t){this.emitter.off(e,t)}applyAccessibleName(){let e=this.el.getAttribute("aria-labelledby"),t=this.el.getAttribute("aria-label");if(e)this.control.setAttribute("aria-labelledby",e);else if(t)this.control.setAttribute("aria-label",t);else if(this.el.id){let i=Array.from(document.getElementsByTagName("label")).find(s=>s.htmlFor===this.el.id);i&&(i.id||(i.id=`${this.uid}-label`),this.control.setAttribute("aria-labelledby",i.id))}}shouldShowSearch(){return this.opts.searchable&&(this.opts.ajax!=null||D(this.data).size>=this.opts.minResultsForSearch)}updateSearchVisibility(){this.searchInput&&(this.searchInput.hidden=!this.shouldShowSearch(),this.searchInput.hidden&&(this.searchInput.value="",this.query=""))}buildDom(){let e=typeof this.opts.dropdownParent=="string"?document.querySelector(this.opts.dropdownParent):this.opts.dropdownParent;if(this.opts.dropdownParent&&!e)throw new Error(`ForgeSelect: dropdown parent not found: ${String(this.opts.dropdownParent)}`);this.root=document.createElement("div"),this.root.className="forge-select",this.root.dataset.theme=this.opts.theme,this.root.style.setProperty("--fs-item-height",`${this.opts.itemHeight}px`),this.opts.sortable&&this.opts.multiple&&this.root.classList.add("forge-select--sortable"),this.control=document.createElement("div"),this.control.className="forge-select__control",this.control.setAttribute("role","combobox"),this.control.setAttribute("aria-haspopup","listbox"),this.control.setAttribute("aria-expanded","false"),this.control.setAttribute("aria-controls",`${this.uid}-list`),this.opts.required&&this.control.setAttribute("aria-required","true"),this.control.tabIndex=0,this.applyAccessibleName(),this.valueEl=document.createElement("div"),this.valueEl.className="forge-select__value",this.clearBtn=document.createElement("button"),this.clearBtn.type="button",this.clearBtn.className="forge-select__clear",this.clearBtn.setAttribute("aria-label",this.strings.clearSelection),this.clearBtn.textContent="\xD7",this.clearBtn.hidden=!0;let t=document.createElement("span");t.className="forge-select__arrow",t.setAttribute("aria-hidden","true"),this.control.append(this.valueEl,this.clearBtn,t),this.dropdown=document.createElement("div"),this.dropdown.className="forge-select__dropdown",this.dropdown.hidden=!0,this.opts.searchable&&(this.searchInput=document.createElement("input"),this.searchInput.type="search",this.searchInput.className="forge-select__search",this.searchInput.setAttribute("aria-label",this.strings.search),this.searchInput.setAttribute("aria-autocomplete","list"),this.searchInput.setAttribute("aria-controls",`${this.uid}-list`),this.searchInput.hidden=!this.shouldShowSearch(),this.dropdown.append(this.searchInput)),this.list=document.createElement("ul"),this.list.className="forge-select__list",this.list.id=`${this.uid}-list`,this.list.setAttribute("role","listbox"),this.opts.multiple&&this.list.setAttribute("aria-multiselectable","true"),this.dropdown.append(this.list),this.liveRegion=document.createElement("div"),this.liveRegion.className="forge-select__sr-only",this.liveRegion.setAttribute("role","status"),this.liveRegion.setAttribute("aria-live","polite"),this.root.append(this.control,this.liveRegion),e||this.root.append(this.dropdown),this.el.style.display="none",this.el.insertAdjacentElement("afterend",this.root),e&&(this.portalHost=document.createElement("div"),this.portalHost.className="forge-select forge-select--portal-host",this.portalHost.dataset.theme=this.opts.theme,this.portalHost.style.setProperty("--fs-item-height",`${this.opts.itemHeight}px`),this.portalHost.append(this.dropdown),e.append(this.portalHost)),this.bindEvents()}bindEvents(){this.control.addEventListener("click",e=>{if(e.target!==this.clearBtn){if(this.suppressNextTagClick){this.suppressNextTagClick=!1;return}this.isDisabled||(this.isOpen?this.close():this.open())}}),this.control.addEventListener("keydown",e=>this.handleKeydown(e)),this.control.addEventListener("mousedown",()=>{this.pointerDownOnControl=!0}),this.control.addEventListener("focus",()=>{this.opts.openOnFocus&&!this.pointerDownOnControl&&!this.isOpen&&!this.isDisabled&&this.open(),this.pointerDownOnControl=!1}),this.clearBtn.addEventListener("click",e=>{e.stopPropagation(),this.clearSelection()}),this.searchInput&&(this.searchInput.addEventListener("input",()=>{this.applySearchQuery(this.searchInput.value,!0)}),this.searchInput.addEventListener("keydown",e=>this.handleKeydown(e)),this.searchInput.addEventListener("paste",e=>{if(!this.opts.multiple||!this.opts.allowCreate)return;let i=(e.clipboardData?.getData("text")??"").split(/[,\n]+/).map(n=>n.trim()).filter(Boolean);if(i.length<2)return;e.preventDefault();let s=[];for(let n of i){let r=this.createTag(n);r&&s.push(r)}if(s.length!==0){this.searchInput.value="",this.query="",this.afterSelectionChange();for(let n of s)n.created&&this.emitter.emit("create",n.option),this.emitter.emit("select",n.option);this.opts.closeOnSelect?this.close():this.renderList()}})),this.list.addEventListener("click",e=>{let t=e.target,i=t.closest("[data-twisty]");if(i){let r=i.dataset.twisty;this.expandedValues.has(r)?this.expandedValues.delete(r):this.expandedValues.add(r),this.renderList();return}let s=t.closest("li[data-nav-index]");if(!s){let r=t.closest("li[data-option-value]"),o=r?this.findOption(r.dataset.optionValue):void 0;o&&this.hasReachedMaximum()&&!this.selected.includes(o.value)&&this.announceMaximum(o);return}let n=Number(s.dataset.navIndex);this.activateNavItem(n)}),this.list.addEventListener("scroll",()=>{this.usesVirtualScroll()&&this.renderRows(),this.maybeLoadNextPage()})}applySearchQuery(e,t){this.query=e,this.searchInput&&this.searchInput.value!==e&&(this.searchInput.value=e),this.highlightedIndex=-1,this.list.scrollTop=0,this.rowContentCache.clear(),t&&this.emitter.emit("search",e);let i=e.trim(),s=i!==""&&i.length<this.opts.minSearchLength;if(this.opts.ajax&&!s){this.scheduleRemoteLoad(e,this.opts.ajax.debounce??250);return}s&&(this.ajaxTimer&&(clearTimeout(this.ajaxTimer),this.ajaxTimer=null),this.ajaxController?.abort(),this.setLoading(!1)),this.renderList()}handleKeydown(e){if(!this.isDisabled)switch(e.key){case"Enter":e.preventDefault(),this.isOpen?this.highlightedIndex>=0&&this.activateNavItem(this.highlightedIndex):this.open();break;case" ":e.target===this.control&&(e.preventDefault(),this.isOpen||this.open());break;case"ArrowDown":e.preventDefault(),this.isOpen?this.moveHighlight(1):this.open();break;case"ArrowUp":e.preventDefault(),this.isOpen&&this.moveHighlight(-1);break;case"Escape":this.isOpen&&(e.preventDefault(),this.close(),this.control.focus());break;case"ArrowRight":this.isOpen&&this.navigateTree("right")&&e.preventDefault();break;case"ArrowLeft":this.isOpen&&this.navigateTree("left")&&e.preventDefault();break;case"Tab":this.close();break}}canSelectOption(e){if(this.opts.maxSelections==null)return!0;let t=[...this.selected];t.includes(e.value)||t.push(e.value);for(let i of S(e,this.isOptionDisabled))t.includes(i)||t.push(i);return M(this.data,t,this.isOptionDisabled),t.length<=this.opts.maxSelections}hasReachedMaximum(){return this.opts.maxSelections!=null&&this.selected.length>=this.opts.maxSelections}announceMaximum(e){let t=this.opts.maxSelections;t!=null&&(this.liveRegion.textContent=p(this.strings.maximumSelected,{count:String(t)}),this.emitter.emit("maximum",{limit:t,option:e}))}selectValue(e,t){if(this.selected.includes(e))return;let i=this.findOption(e)??this.selectedOptions.get(e)??{value:e,label:e};if(this.selectedOptions.set(e,i),this.opts.multiple){this.selected.push(e);for(let s of S(i,this.isOptionDisabled))this.selected.includes(s)||this.selected.push(s);this.syncTreeAncestors()}else this.selected=[e];t&&(this.afterSelectionChange(),this.emitter.emit("select",i))}deselectValue(e,t){let i=this.selected.indexOf(e);if(i===-1)return;let s=this.findOption(e)??this.selectedOptions.get(e);if(this.selected.splice(i,1),this.opts.multiple){if(s)for(let n of S(s,this.isOptionDisabled)){let r=this.selected.indexOf(n);r!==-1&&this.selected.splice(r,1)}this.syncTreeAncestors()}t&&(this.afterSelectionChange(),this.emitter.emit("unselect",s??{value:e,label:e}))}syncTreeAncestors(){M(this.data,this.selected,this.isOptionDisabled)}clearSelection(){this.selected.length!==0&&(this.selected=[],this.emitter.emit("clear"),this.afterSelectionChange())}allSelectableValues(){let e=[],t=i=>{this.isOptionDisabled(i)||e.push(i.value),i.children?.forEach(t)};for(let i of this.data)(m(i)?i.options:[i]).forEach(t);return e}afterSelectionChange(e=!0){this.renderValue(),this.syncNativeSelect(e),(!this.opts.required||this.selected.length>0)&&(this.control.classList.remove("forge-select__control--invalid"),this.control.removeAttribute("aria-invalid")),this.isOpen&&this.renderList(),e&&this.emitter.emit("change",this.getValue())}syncNativeSelect(e=!0){if(!(this.el instanceof HTMLSelectElement))return;let t=new Set;for(let i of Array.from(this.el.options))t.add(i.value),i.selected=this.selected.includes(i.value);for(let i of this.selected){if(t.has(i))continue;let s=document.createElement("option");s.value=i,s.textContent=this.selectedOptions.get(i)?.label??i,s.selected=!0,this.el.append(s)}if(this.opts.sortable&&this.opts.multiple)for(let i of this.selected){let s=Array.from(this.el.options).find(n=>n.value===i);s&&this.el.append(s)}if(e){this.syncingNative=!0;try{this.el.dispatchEvent(new Event("change",{bubbles:!0}))}finally{this.syncingNative=!1}}}findOption(e){return P(this.data,e)}findOptionByLabel(e){let t=e.toLowerCase(),i=s=>{for(let n of s){if(n.label.toLowerCase()===t)return n;let r=n.children?i(n.children):void 0;if(r)return r}};for(let s of this.data){let n=i(m(s)?s.options:[s]);if(n)return n}}createTag(e){let t=e.trim();if(!t)return;let i=this.findOptionByLabel(t);if(i){if(this.selected.includes(i.value))return;if(this.opts.multiple&&!this.canSelectOption(i)){this.announceMaximum(i);return}return this.selectValue(i.value,!1),{option:i,created:!1}}let s={value:t,label:t};if(this.opts.multiple&&!this.canSelectOption(s)){this.announceMaximum(s);return}return this.data.push(s),this.selectValue(s.value,!1),{option:s,created:!0}}createFromQuery(){let e=this.query.trim();if(!e)return;let t=this.createTag(e);t&&(this.searchInput&&(this.searchInput.value="",this.query=""),this.afterSelectionChange(),t.created&&this.emitter.emit("create",t.option),this.emitter.emit("select",t.option),(!this.opts.multiple||this.opts.closeOnSelect)&&this.close())}activateNavItem(e){let t=this.navItems[e];if(!t)return;if(t.kind==="create"){this.createFromQuery();return}let{value:i}=t.option;if(this.opts.multiple){let s=!1;this.selected.includes(i)?(this.deselectValue(i,!0),s=!0):this.canSelectOption(t.option)?(this.selectValue(i,!0),s=!0):this.announceMaximum(t.option),s&&this.opts.closeOnSelect&&this.close()}else this.selectValue(i,!0),this.close(),this.control.focus()}renderValue(){this.valueEl.textContent="";let e=this.selected.length>0;if(this.clearBtn.hidden=!(this.opts.clearable&&e),!e){let t=document.createElement("span");t.className="forge-select__placeholder",t.textContent=this.opts.placeholder,this.valueEl.append(t);return}if(this.opts.multiple)for(let t of this.selected){let i=this.selectedOptions.get(t)??{value:t,label:t},s=document.createElement("span");s.className="forge-select__tag";let n=document.createElement("span");n.className="forge-select__tag-label",b(n,i,this.opts.templateSelection,"inline");let r=document.createElement("button");r.type="button",r.className="forge-select__tag-remove",r.setAttribute("aria-label",p(this.strings.removeItem,{label:i.label})),r.textContent="\xD7",r.addEventListener("click",o=>{o.stopPropagation(),this.isDisabled||this.deselectValue(t,!0)}),s.append(n,r),this.opts.sortable&&(s.dataset.value=t,s.tabIndex=0,s.setAttribute("aria-roledescription","draggable item"),s.setAttribute("aria-label",p(this.strings.reorderHint,{label:i.label})),s.addEventListener("keydown",o=>this.handleTagKeydown(o,t)),this.bindTagDrag(s,t)),this.valueEl.append(s)}else{let t=this.selectedOptions.get(this.selected[0])??{value:this.selected[0],label:this.selected[0]},i=document.createElement("span");i.className="forge-select__single-value",b(i,t,this.opts.templateSelection,"inline"),this.valueEl.append(i)}}bindTagDrag(e,t){let s=0,n=!1,r=[],o=h=>{if(!n){if(Math.abs(h.clientX-s)<4)return;n=!0,r=[...this.selected],typeof this.valueEl.setPointerCapture=="function"&&this.valueEl.setPointerCapture(h.pointerId),e.classList.add("forge-select__tag--dragging")}h.preventDefault();let c=r.indexOf(t),u=Array.from(this.valueEl.querySelectorAll(".forge-select__tag"));for(let d of u){if(d===e)continue;let f=d.dataset.value;if(!f)continue;let I=r.indexOf(f);if(I===-1)continue;let R=d.getBoundingClientRect(),k=R.left+R.width/2,_=c<I;if(_?h.clientX>k:h.clientX<k){r.splice(c,1),r.splice(I,0,t),_?this.valueEl.insertBefore(e,d.nextSibling):this.valueEl.insertBefore(e,d);break}}},l=h=>{this.valueEl.removeEventListener("pointermove",o),this.valueEl.removeEventListener("pointerup",l),this.valueEl.removeEventListener("pointercancel",l),n&&(typeof this.valueEl.releasePointerCapture=="function"&&this.valueEl.releasePointerCapture(h.pointerId),e.classList.remove("forge-select__tag--dragging"),this.selected=r,this.suppressNextTagClick=!0,this.afterSelectionChange(),this.emitter.emit("reorder",[...this.selected]))};e.addEventListener("pointerdown",h=>{this.isDisabled||h.button!==0||h.target.closest(".forge-select__tag-remove")||(s=h.clientX,n=!1,this.valueEl.addEventListener("pointermove",o),this.valueEl.addEventListener("pointerup",l),this.valueEl.addEventListener("pointercancel",l))})}handleTagKeydown(e,t){if(!e.altKey||e.key!=="ArrowLeft"&&e.key!=="ArrowRight")return;let i=this.selected.indexOf(t),s=e.key==="ArrowLeft"?i-1:i+1;if(i===-1||s<0||s>=this.selected.length)return;e.preventDefault(),e.stopPropagation();let n=[...this.selected];[n[i],n[s]]=[n[s],n[i]],this.selected=n,this.afterSelectionChange(),this.emitter.emit("reorder",[...this.selected]),this.focusTagByValue(t)}focusTagByValue(e){for(let t of Array.from(this.valueEl.querySelectorAll(".forge-select__tag")))if(t.dataset.value===e){t.focus();return}}buildRows(){this.rows=[],this.navItems=[];let e=this.query.trim(),t=g(e,this.opts.accentInsensitive),i=r=>t===""||(this.opts.filterOption?this.opts.filterOption(r,e):this.searchIndex.score(r,e,{fields:this.opts.searchFields,tokenSearch:this.opts.tokenSearch,accentInsensitive:this.opts.accentInsensitive,scorer:this.opts.searchScorer})>0),s=r=>t===""||i(r)||(r.children??[]).some(s),n=(r,o,l)=>{let h=-1;this.isOptionDisabled(r)||this.hasReachedMaximum()&&!this.selected.includes(r.value)||(h=this.navItems.length,this.navItems.push({kind:"option",option:r,parentValue:l}));let u=!!r.children&&r.children.length>0;if(this.rows.push({kind:"option",option:r,navIndex:h,depth:o,hasChildren:u}),u&&(t!==""||this.expandedValues.has(r.value)))for(let f of r.children)s(f)&&n(f,o+1,r.value)};if(e!==""&&e.length<this.opts.minSearchLength){this.rows.push({kind:"min-length"});return}if(this.loading){this.rows.push({kind:"loading"});return}if(this.loadError){this.rows.push({kind:"error"});return}for(let r of this.data)if(m(r)){let o=r.options.filter(s);if(o.length===0)continue;this.rows.push({kind:"group",label:r.label}),o.forEach(l=>n(l,0))}else s(r)&&n(r,0);if(this.opts.allowCreate&&t!==""&&!this.hasExactMatch(t)){let r=this.navItems.length;this.navItems.push({kind:"create"}),this.rows.push({kind:"create",navIndex:r})}this.rows.length===0?this.rows.push({kind:"empty"}):this.loadingMore&&this.rows.push({kind:"loading-more"})}hasExactMatch(e){return!!this.findOptionByLabel(e)}usesVirtualScroll(){return this.opts.virtualScroll!==!1&&this.rows.length>J}rowKey(e,t){return e.kind==="option"?`option:${e.option.value}`:e.kind==="group"?`group:${e.label}:${t}`:`${e.kind}:${t}`}measuredRowHeight(e){return this.opts.variableItemHeight?this.rowHeightCache.get(this.rowKey(this.rows[e],e))??this.opts.itemHeight:this.opts.itemHeight}rowOffset(e){if(!this.opts.variableItemHeight)return e*this.opts.itemHeight;let t=0;for(let i=0;i<e;i+=1)t+=this.measuredRowHeight(i);return t}rowOffsets(){let e=[0];for(let t=0;t<this.rows.length;t+=1)e.push(e[t]+this.measuredRowHeight(t));return e}renderList(){this.buildRows(),this.renderRows(),this.announceStatus()}announceStatus(){let e=this.rows[0],t=this.hasReachedMaximum()?p(this.strings.maximumSelected,{count:String(this.opts.maxSelections)}):e?.kind==="loading"?this.strings.loading:e?.kind==="error"?this.strings.errorLoading:e?.kind==="empty"?this.strings.noResults:e?.kind==="min-length"?p(this.strings.minSearchLength,{count:String(this.opts.minSearchLength)}):"";this.liveRegion.textContent!==t&&(this.liveRegion.textContent=t)}renderRows(){let e=this.list.scrollTop,t=this.list.clientHeight,i=this.usesVirtualScroll();this.list.textContent="";let s=this.opts.itemHeight,n=this.opts.variableItemHeight?this.rowOffsets():null,r=0,o=this.rows.length;if(i){let l=t||s*8;if(this.opts.variableItemHeight){for(;r<this.rows.length&&n[r+1]<e;)r+=1;r=Math.max(0,r-E),o=r;let c=e+l+E*s;for(;o<this.rows.length&&n[o]<c;)o+=1}else r=Math.max(0,Math.floor(e/s)-E),o=Math.min(this.rows.length,r+Math.ceil(l/s)+E*2);let h=document.createElement("li");h.className="forge-select__spacer",h.setAttribute("aria-hidden","true"),h.style.height=`${n?.[r]??this.rowOffset(r)}px`,this.list.append(h)}for(let l=r;l<o;l++){let h=this.renderRow(this.rows[l]);if(this.list.append(h),this.opts.variableItemHeight){let c=h.getBoundingClientRect().height||h.offsetHeight;c>0&&this.rowHeightCache.set(this.rowKey(this.rows[l],l),c)}}if(i){let l=document.createElement("li");l.className="forge-select__spacer",l.setAttribute("aria-hidden","true"),l.style.height=`${n?n[this.rows.length]-n[o]:this.rowOffset(this.rows.length)-this.rowOffset(o)}px`,this.list.append(l),this.list.scrollTop!==e&&(this.list.scrollTop=e)}this.updateActiveDescendant()}renderRow(e){let t=document.createElement("li");switch(e.kind){case"group":t.className="forge-select__group-label",t.setAttribute("role","presentation"),t.textContent=e.label;break;case"empty":t.className="forge-select__empty",t.setAttribute("role","option"),t.setAttribute("aria-disabled","true"),t.setAttribute("aria-selected","false"),t.textContent=this.strings.noResults;break;case"min-length":t.className="forge-select__min-length",t.setAttribute("role","option"),t.setAttribute("aria-disabled","true"),t.setAttribute("aria-selected","false"),t.textContent=p(this.strings.minSearchLength,{count:String(this.opts.minSearchLength)});break;case"error":t.className="forge-select__error",t.setAttribute("role","option"),t.setAttribute("aria-disabled","true"),t.setAttribute("aria-selected","false"),t.textContent=this.strings.errorLoading;break;case"loading":t.className="forge-select__loading",t.setAttribute("role","option"),t.setAttribute("aria-disabled","true"),t.setAttribute("aria-selected","false"),t.textContent=this.strings.loading;break;case"loading-more":t.className="forge-select__loading-more",t.setAttribute("aria-hidden","true"),t.textContent=this.strings.loadingMore;break;case"create":t.className="forge-select__option forge-select__option--create",t.setAttribute("role","option"),t.id=`${this.uid}-nav-${e.navIndex}`,t.dataset.navIndex=String(e.navIndex),t.textContent=p(this.strings.createOption,{query:this.query.trim()}),e.navIndex===this.highlightedIndex&&t.classList.add("forge-select__option--highlighted");break;case"option":{t.className="forge-select__option",t.dataset.optionValue=e.option.value,e.option.className&&t.classList.add(...e.option.className.trim().split(/\s+/).filter(Boolean)),t.setAttribute("role","option");let i=this.selected.includes(e.option.value);if(t.setAttribute("aria-selected",String(i)),i&&t.classList.add("forge-select__option--selected"),this.opts.multiple&&e.hasChildren&&O(e.option,this.selected,this.isOptionDisabled)==="some"&&(t.classList.add("forge-select__option--indeterminate"),t.dataset.selectionState="mixed"),e.depth>0&&(t.style.paddingLeft=`calc(12px + ${e.depth} * var(--fs-tree-indent, 18px))`),this.isOptionDisabled(e.option)||this.hasReachedMaximum()&&!this.selected.includes(e.option.value)?(t.classList.add("forge-select__option--disabled"),t.setAttribute("aria-disabled","true")):(t.id=`${this.uid}-nav-${e.navIndex}`,t.dataset.navIndex=String(e.navIndex),e.navIndex===this.highlightedIndex&&t.classList.add("forge-select__option--highlighted")),e.hasChildren){let s=this.query!==""||this.expandedValues.has(e.option.value);t.setAttribute("aria-expanded",String(s));let n=document.createElement("span");n.className="forge-select__twisty",n.dataset.twisty=e.option.value,n.setAttribute("aria-hidden","true"),n.textContent=s?"\u25BC":"\u25B6",t.append(n)}t.append(this.optionContent(e.option));break}}return t}optionContent(e){if(this.opts.highlightSearch&&this.query.trim()&&!this.opts.templateResult){let i=document.createElement("span");i.className="forge-select__option-content",b(i,e,void 0);let s=i.querySelector(".forge-select__option-label")??i,n=q(e.label,this.query,this.opts.accentInsensitive);if(n.length){s.textContent="";let r=0;for(let[o,l]of n){if(o<r)continue;s.append(document.createTextNode(e.label.slice(r,o)));let h=document.createElement("mark");h.className="forge-select__match",h.textContent=e.label.slice(o,l),s.append(h),r=l}s.append(document.createTextNode(e.label.slice(r)))}return i}let t=this.rowContentCache.get(e.value);if(!t){let i=document.createElement("span");if(i.className="forge-select__option-content",b(i,e,this.opts.templateResult),this.rowContentCache.size>=Y){let s=this.rowContentCache.keys().next().value;this.rowContentCache.delete(s)}this.rowContentCache.set(e.value,i),t=i}return t.cloneNode(!0)}moveHighlight(e){if(this.navItems.length===0)return;let t=this.highlightedIndex===-1?e>0?0:this.navItems.length-1:(this.highlightedIndex+e+this.navItems.length)%this.navItems.length;this.focusNavIndex(t)}focusNavIndex(e){if(this.highlightedIndex=e,this.usesVirtualScroll()){let t=this.rows.findIndex(i=>(i.kind==="option"||i.kind==="create")&&i.navIndex===e);if(t>=0){let i=this.measuredRowHeight(t),s=this.rowOffset(t),n=this.list.clientHeight||i*8,r=this.list.scrollTop;s<r?r=s:s+i>r+n&&(r=s+i-n),r!==this.list.scrollTop&&(this.list.scrollTop=r)}this.renderRows()}else this.renderRows(),this.list.querySelector(".forge-select__option--highlighted")?.scrollIntoView?.({block:"nearest"})}navigateTree(e){let t=this.navItems[this.highlightedIndex];if(!t||t.kind!=="option")return!1;let{option:i,parentValue:s}=t,n=!!i.children?.length,r=this.query!==""||this.expandedValues.has(i.value);if(e==="right"){if(n&&!r)return this.expandedValues.add(i.value),this.renderList(),!0;if(n){let o=this.navItems.findIndex(l=>l.kind==="option"&&l.parentValue===i.value);if(o>=0)return this.focusNavIndex(o),!0}return!1}if(n&&r&&this.query==="")return this.expandedValues.delete(i.value),this.renderList(),!0;if(s){let o=this.navItems.findIndex(l=>l.kind==="option"&&l.option.value===s);if(o>=0)return this.focusNavIndex(o),!0}return!1}updateActiveDescendant(){let e=this.searchInput??this.control;this.highlightedIndex>=0?e.setAttribute("aria-activedescendant",`${this.uid}-nav-${this.highlightedIndex}`):e.removeAttribute("aria-activedescendant")}scheduleRemoteLoad(e,t){this.ajaxTimer&&clearTimeout(this.ajaxTimer);let i=++this.ajaxRequestId;this.ajaxController?.abort(),this.ajaxController=null,this.page=0,this.hasMore=!0,this.setLoading(!0),this.loadingMore=!1,this.loadError=null,this.renderList(),this.ajaxTimer=setTimeout(()=>{this.ajaxTimer=null,this.loadRemote(e,{requestId:i})},t)}setLoading(e){this.loading!==e&&(this.loading=e,this.emitter.emit("loading",e))}remoteCacheKey(e,t){return`${e}\0${t}`}async requestRemote(e,t,i){let s=this.opts.ajax,n=Math.max(0,Math.floor(s.retry??0))+1,r;for(let o=0;o<n;o+=1)try{if(s.request)return await s.request(e,t,i);let l=await fetch(j(s,e,t),{signal:i});if(l.ok===!1)throw new Error(`ForgeSelect: remote request failed with HTTP ${l.status}`);return await l.json()}catch(l){if(r=l,i.aborted||o===n-1)throw l;let h=Math.max(0,s.retryDelay??250)*2**o;await new Promise((c,u)=>{let d=setTimeout(c,h);i.addEventListener("abort",()=>{clearTimeout(d),u(new DOMException("Aborted","AbortError"))},{once:!0})})}throw r}async prefetchRemote(e){let t=this.opts.ajax;if(!t||(t.cacheTtl??3e4)<=0)return;let i=this.remoteCacheKey(e,0);if(this.remoteCache.get(i))return;let s=new AbortController;try{let n=await this.requestRemote(e,0,s.signal);this.remoteCache.set(i,T(t,n),t.cacheTtl??3e4)}catch{}}maybeLoadNextPage(){if(!this.opts.ajax?.pagination||!this.hasMore||this.loading||this.loadingMore)return;let{scrollHeight:t,scrollTop:i,clientHeight:s}=this.list,n=this.opts.itemHeight*2;t-i-s>=n||(this.loadingMore=!0,this.renderList(),this.loadRemote(this.query,{append:!0}))}async loadRemote(e,{append:t=!1,requestId:i}={}){let s=this.opts.ajax,n=i??++this.ajaxRequestId;if(n!==this.ajaxRequestId)return;this.ajaxController?.abort();let r=new AbortController;this.ajaxController=r;let o=t?this.page+1:0;try{let l=this.remoteCacheKey(e,o),h=this.remoteCache.get(l);if(!h){let d=await this.requestRemote(e,o,r.signal);h=T(s,d),this.remoteCache.set(l,h,s.cacheTtl??3e4)}if(n!==this.ajaxRequestId||this.destroyed)return;let{options:c,hasMore:u}=h;if(t){let d=D(this.data);this.data=[...this.data,...c.filter(f=>!d.has(f.value))]}else this.data=c,this.rowContentCache.clear();this.page=o,this.hasMore=u,this.remoteLoaded=!0,this.loadError=null}catch(l){if(n!==this.ajaxRequestId||this.destroyed||r.signal.aborted)return;let h=l instanceof Error?l:new Error(String(l));t||(this.data=[],this.rowContentCache.clear()),this.hasMore=!1,this.loadError=h,this.emitter.emit("error",h)}finally{n===this.ajaxRequestId&&!this.destroyed&&(this.ajaxController=null,this.setLoading(!1),this.loadingMore=!1,this.isOpen&&this.renderList())}}};return G(ee);})();
|
|
1
|
+
"use strict";var ForgeSelectBundle=(()=>{var L=Object.defineProperty;var z=Object.getOwnPropertyDescriptor;var K=Object.getOwnPropertyNames;var U=Object.prototype.hasOwnProperty;var Q=(a,e)=>{for(var t in e)L(a,t,{get:e[t],enumerable:!0})},G=(a,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of K(e))!U.call(a,s)&&s!==t&&L(a,s,{get:()=>e[s],enumerable:!(i=z(e,s))||i.enumerable});return a};var W=a=>G(L({},"__esModule",{value:!0}),a);var ie={};Q(ie,{ForgeSelect:()=>v,default:()=>v});var S=class{constructor(){this.handlers=new Map}on(e,t){let i=this.handlers.get(e);i||(i=new Set,this.handlers.set(e,i)),i.add(t)}off(e,t){this.handlers.get(e)?.delete(t)}emit(e,...t){let i=this.handlers.get(e);if(i)for(let s of[...i])s(...t)}clear(){this.handlers.clear()}};function N(a,e,t,i=4){let s=t-a.bottom,n=a.top,r=e>s&&n>s;return{dropUp:r,top:r?a.top-e-i:a.bottom+i}}var C={en:{noResults:"No results found",loading:"Loading\u2026",loadingMore:"Loading more\u2026",errorLoading:"Could not load options",createOption:'Create "{query}"',clearSelection:"Clear selection",removeItem:"Remove {label}",search:"Search",reorderHint:"{label}. Press Alt+Left or Alt+Right to reorder.",minSearchLength:"Type {count} or more characters to search",maximumSelected:"Maximum of {count} selections reached"},vi:{noResults:"Kh\xF4ng t\xECm th\u1EA5y k\u1EBFt qu\u1EA3",loading:"\u0110ang t\u1EA3i\u2026",loadingMore:"\u0110ang t\u1EA3i th\xEAm\u2026",errorLoading:"Kh\xF4ng th\u1EC3 t\u1EA3i t\xF9y ch\u1ECDn",createOption:'T\u1EA1o "{query}"',clearSelection:"X\xF3a l\u1EF1a ch\u1ECDn",removeItem:"X\xF3a {label}",search:"T\xECm ki\u1EBFm",reorderHint:"{label}. Nh\u1EA5n Alt+Tr\xE1i ho\u1EB7c Alt+Ph\u1EA3i \u0111\u1EC3 s\u1EAFp x\u1EBFp l\u1EA1i.",minSearchLength:"Nh\u1EADp th\xEAm {count} k\xFD t\u1EF1 \u0111\u1EC3 t\xECm ki\u1EBFm",maximumSelected:"\u0110\xE3 \u0111\u1EA1t t\u1ED1i \u0111a {count} l\u1EF1a ch\u1ECDn"}};function T(a){return typeof a=="string"?C[a]??C.en:{...C.en,...a}}function p(a,e){return a.replace(/\{(\w+)\}/g,(t,i)=>e[i]??t)}function V(a){let e=[];for(let t of Array.from(a.children))t instanceof HTMLOptGroupElement?e.push({label:t.label,options:Array.from(t.querySelectorAll("option")).map(F)}):t instanceof HTMLOptionElement&&e.push(F(t));return e}function F(a){let e=a.parentElement instanceof HTMLOptGroupElement&&a.parentElement.disabled;return{value:a.value,label:a.textContent?.trim()??a.value,disabled:a.disabled||e||void 0}}function b(a,e,t,i="row"){if(t){let s=t(e);typeof s=="string"?a.innerHTML=s:a.append(s);return}if(!e.avatar&&!e.description){a.textContent=e.label;return}if(e.avatar){let s=document.createElement("img");s.className=i==="row"?"forge-select__option-avatar":"forge-select__inline-avatar",s.src=e.avatar,s.alt="",s.setAttribute("loading","lazy"),s.setAttribute("decoding","async"),a.append(s)}if(i==="row"&&e.description){let s=document.createElement("span");s.className="forge-select__option-body";let n=document.createElement("span");n.className="forge-select__option-label",n.textContent=e.label;let r=document.createElement("span");r.className="forge-select__option-desc",r.textContent=e.description,s.append(n,r),a.append(s)}else{let s=document.createElement("span");s.className="forge-select__option-label",s.textContent=e.label,a.append(s)}}function j(a,e,t){if(!a.url)throw new Error("ForgeSelect: ajax requires either url or request.");if(typeof a.url=="function")return a.url(e,t);if(!a.params)return a.url;let i=new URLSearchParams;for(let[n,r]of Object.entries(a.params(e,t)))i.set(n,String(r));let s=a.url.includes("?")?"&":"?";return`${a.url}${s}${i.toString()}`}function A(a,e){let t=a.transform?a.transform(e):e;if(Array.isArray(t))return{options:t,hasMore:!1};if(!t||!Array.isArray(t.options))throw new Error("ForgeSelect: ajax.transform must return an array of options, or an object shaped like { options: Option[], hasMore?: boolean }.");return{options:t.options,hasMore:a.pagination?!!t.hasMore:!1}}var y=class{constructor(){this.entries=new Map}get(e,t=Date.now()){let i=this.entries.get(e);if(i){if(i.expiresAt<=t){this.entries.delete(e);return}return i.value}}set(e,t,i,s=Date.now()){if(!(i<=0)){if(this.entries.size>=50&&!this.entries.has(e)){let n=this.entries.keys().next().value;this.entries.delete(n)}this.entries.set(e,{value:t,expiresAt:s+i})}}clear(){this.entries.clear()}};function f(a,e=!0){let t=a.toLocaleLowerCase();return e?t.normalize("NFD").replace(/[\u0300-\u036f]/g,"").replace(/đ/g,"d"):t}function X(a,e){if(e==="label")return a.label;if(e==="description")return a.description??"";let t=e.slice(5).split("."),i=a.meta;for(let s of t){if(!i||typeof i!="object")return"";i=i[s]}return i==null?"":String(i)}var I=class{constructor(){this.cache=new WeakMap}clear(){this.cache=new WeakMap}score(e,t,i){let s=f(t.trim(),i.accentInsensitive);if(!s)return 1;if(i.scorer)return i.scorer(e,t.trim(),s);let n=`${i.accentInsensitive?"1":"0"}:${i.fields.join("\0")}`,r=this.cache.get(e);r||(r=new Map,this.cache.set(e,r));let o=r.get(n);if(o||(o=i.fields.map(c=>f(X(e,c),i.accentInsensitive)),r.set(n,o)),!(i.tokenSearch?s.split(/\s+/).filter(Boolean):[s]).every(c=>o.some(d=>d.includes(c))))return 0;let l=o[i.fields.indexOf("label")];return l===s?4:l?.startsWith(s)?3:l?.includes(s)?2:1}};function q(a,e,t=!0){let i=f(e.trim(),t).split(/\s+/).filter(Boolean);if(!i.length)return[];let s=f(a,t),n=[];for(let r of i){let o=s.indexOf(r);o>=0&&n.push([o,o+r.length])}return n.sort((r,o)=>r[0]-o[0])}function g(a){return a.options!==void 0}var R=a=>!!a.disabled;function x(a,e=R){if(!a.children)return[];let t=[];for(let i of a.children)e(i)||t.push(i.value),t.push(...x(i,e));return t}function w(a,e,t=R){if(!a.children?.length)return e.includes(a.value)?"all":"none";let i=a.children.filter(s=>!t(s)).map(s=>w(s,e,t));return i.length===0?"none":i.every(s=>s==="all")?"all":i.every(s=>s==="none")?"none":"some"}function P(a,e){let t=i=>{for(let s of i){if(s.value===e)return s;let n=s.children?t(s.children):void 0;if(n)return n}};for(let i of a){let s=t(g(i)?i.options:[i]);if(s)return s}}function H(a,e,t=R){let i=s=>{if(!s.children?.length)return;for(let o of s.children)i(o);let n=w(s,e,t),r=e.indexOf(s.value);n==="all"&&r===-1?e.push(s.value):n!=="all"&&r!==-1&&e.splice(r,1)};for(let s of a)(g(s)?s.options:[s]).forEach(i)}function M(a){let e=new Set,t=i=>{e.add(i.value),i.children?.forEach(t)};for(let i of a)(g(i)?i.options:[i]).forEach(t);return e}function B(a,e){return a.length===e.length&&a.every((t,i)=>t===e[i])}var Y=36,O=5,Z=100,J=2e3,$=10,ee=500,te=0,v=class{constructor(e,t={}){this.selected=[];this.selectedOptions=new Map;this.suppressNextTagClick=!1;this.emitter=new S;this.uid=`forge-select-${++te}`;this.searchInput=null;this.portalHost=null;this.isOpen=!1;this.isDisabled=!1;this.destroyed=!1;this.query="";this.rows=[];this.navItems=[];this.highlightedIndex=-1;this.typeaheadBuffer="";this.typeaheadTimer=null;this.rowContentCache=new Map;this.rowHeightCache=new Map;this.rowOffsetsCache=null;this.scrollRafId=null;this.ancestorScrollRafId=null;this.searchIndex=new I;this.expandedValues=new Set;this.loading=!1;this.loadingMore=!1;this.page=0;this.hasMore=!0;this.ajaxTimer=null;this.ajaxRequestId=0;this.ajaxController=null;this.remoteLoaded=!1;this.remoteCache=new y;this.loadError=null;this.originalDisplay="";this.originalDisabled=!1;this.nativeSelect=null;this.nativeForm=null;this.syncingNative=!1;this.isOptionDisabled=e=>e.disabled===!0||(this.opts.isOptionDisabled?.(e)??!1);this.pointerDownOnControl=!1;this.onDocumentMouseDown=e=>{let t=e.target;!this.root.contains(t)&&!this.portalHost?.contains(t)&&this.close()};this.onWindowResize=()=>{this.positionDropdown()};this.onAncestorScroll=()=>{this.portalHost&&this.ancestorScrollRafId==null&&(this.ancestorScrollRafId=requestAnimationFrame(()=>{this.ancestorScrollRafId=null,this.positionDropdown()}))};this.onNativeInvalid=e=>{e.preventDefault(),this.control.classList.add("forge-select__control--invalid"),this.control.setAttribute("aria-invalid","true"),this.isOpen||this.open(),this.control.focus(),this.emitter.emit("invalid",this.nativeSelect?.validationMessage??"")};this.onNativeChange=()=>{if(!this.nativeSelect||this.destroyed||this.syncingNative)return;let e=Array.from(this.nativeSelect.selectedOptions,t=>t.value);this.applyNativeValues(e)};this.onFormReset=()=>{if(!this.nativeSelect||this.destroyed)return;let e=Array.from(this.nativeSelect.options).filter(t=>t.defaultSelected).map(t=>t.value);this.applyNativeValues(e)};let i=typeof e=="string"?document.querySelector(e):e;if(!i)throw new Error(`ForgeSelect: target element not found: ${String(e)}`);this.el=i;let s=i instanceof HTMLSelectElement?i:null;if(this.nativeSelect=s,this.nativeForm=s?.form??null,this.originalDisplay=i.style.display,this.originalDisabled=s?.disabled??!1,this.opts={placeholder:t.placeholder??"",searchable:t.searchable??!0,multiple:t.multiple??s?.multiple??!1,clearable:t.clearable??!1,allowCreate:t.allowCreate??!1,sortable:t.sortable??!1,closeOnSelect:t.closeOnSelect??!1,maxSelections:t.maxSelections==null||!Number.isFinite(t.maxSelections)?void 0:Math.max(0,Math.floor(t.maxSelections)),theme:t.theme??"default",disabled:t.disabled??s?.disabled??!1,required:t.required??s?.required??!1,data:t.data,ajax:t.ajax,templateResult:t.templateResult,templateSelection:t.templateSelection,filterOption:t.filterOption,searchFields:t.searchFields??["label","description"],tokenSearch:t.tokenSearch??!0,accentInsensitive:t.accentInsensitive??!0,searchScorer:t.searchScorer,highlightSearch:t.highlightSearch??!1,minSearchLength:Math.max(0,Math.floor(t.minSearchLength??0)),minResultsForSearch:Math.max(0,Math.floor(t.minResultsForSearch??0)),isOptionDisabled:t.isOptionDisabled,virtualScroll:t.virtualScroll,itemHeight:typeof t.itemHeight=="number"?Math.max(1,t.itemHeight):Y,variableItemHeight:t.itemHeight==="auto",language:t.language??"en",plugins:t.plugins??[],openOnFocus:t.openOnFocus??!1,dropdownParent:t.dropdownParent},this.strings=T(this.opts.language),this.plugins=this.opts.plugins,s&&(s.required=this.opts.required),this.data=this.opts.data??(s?V(s):[]),s&&!this.opts.data){let n=Array.from(s.options),r=s.multiple||s.selectedIndex>0||n.some(o=>o.defaultSelected);for(let o of n)r&&o.selected&&this.selectValue(o.value,!1)}this.buildDom(),this.renderValue(),this.opts.disabled&&this.disable(),s?.addEventListener("change",this.onNativeChange),s?.addEventListener("invalid",this.onNativeInvalid),this.nativeForm?.addEventListener("reset",this.onFormReset);for(let n of this.plugins)n.onInit?.(this);for(let n of this.opts.ajax?.prefetch??[])this.prefetchRemote(n)}applyNativeValues(e){this.selected=[];for(let t of this.opts.multiple?e:e.slice(0,1))this.selectValue(t,!1);this.renderValue(),this.isOpen&&this.renderList(),this.emitter.emit("change",this.getValue())}open(){if(!(this.isOpen||this.isDisabled||this.destroyed)){this.isOpen=!0,this.dropdown.hidden=!1,this.root.classList.add("forge-select--open"),this.control.setAttribute("aria-expanded","true"),document.addEventListener("mousedown",this.onDocumentMouseDown),this.opts.ajax&&(this.opts.ajax.loadOnOpen??!0)&&!this.remoteLoaded&&this.scheduleRemoteLoad(this.query,0),this.renderList(),this.positionDropdown(),window.addEventListener("resize",this.onWindowResize),document.addEventListener("scroll",this.onAncestorScroll,!0),this.searchInput&&!this.searchInput.hidden&&this.searchInput.focus(),this.emitter.emit("open");for(let e of this.plugins)e.onOpen?.(this)}}close(){if(this.isOpen){this.isOpen=!1,this.dropdown.hidden=!0,this.root.classList.remove("forge-select--open"),this.root.classList.remove("forge-select--drop-up"),this.control.setAttribute("aria-expanded","false"),document.removeEventListener("mousedown",this.onDocumentMouseDown),window.removeEventListener("resize",this.onWindowResize),document.removeEventListener("scroll",this.onAncestorScroll,!0),this.ancestorScrollRafId!=null&&(cancelAnimationFrame(this.ancestorScrollRafId),this.ancestorScrollRafId=null),this.scrollRafId!=null&&(cancelAnimationFrame(this.scrollRafId),this.scrollRafId=null),this.typeaheadTimer&&(clearTimeout(this.typeaheadTimer),this.typeaheadTimer=null),this.typeaheadBuffer="",this.highlightedIndex=-1,this.searchInput&&(this.searchInput.value="",this.query=""),this.emitter.emit("close");for(let e of this.plugins)e.onClose?.(this)}}positionDropdown(){let e=this.control.getBoundingClientRect(),t=N(e,this.dropdown.offsetHeight,window.innerHeight);this.root.classList.toggle("forge-select--drop-up",t.dropUp),this.portalHost&&(this.portalHost.style.top=`${t.top}px`,this.portalHost.style.left=`${e.left}px`,this.portalHost.style.width=`${e.width}px`)}destroy(){if(!this.destroyed){this.close();for(let e of this.plugins)e.onDestroy?.(this);this.destroyed=!0,this.ajaxTimer&&clearTimeout(this.ajaxTimer),this.ajaxController?.abort(),this.scrollRafId!=null&&cancelAnimationFrame(this.scrollRafId),this.typeaheadTimer&&clearTimeout(this.typeaheadTimer),this.nativeSelect?.removeEventListener("change",this.onNativeChange),this.nativeSelect?.removeEventListener("invalid",this.onNativeInvalid),this.nativeForm?.removeEventListener("reset",this.onFormReset),this.rowContentCache.clear(),this.rowHeightCache.clear(),this.searchIndex.clear(),this.portalHost?.remove(),this.root.remove(),this.el.style.display=this.originalDisplay,this.nativeSelect&&(this.nativeSelect.disabled=this.originalDisabled),this.emitter.clear()}}getValue(){return this.opts.multiple?[...this.selected]:this.selected[0]??null}getSearchQuery(){return this.query}setSearchQuery(e,t={}){this.applySearchQuery(e,t.emitSearch??!0)}isDropdownOpen(){return this.isOpen}updateOptions(e){e.data&&this.setData(e.data),"ajax"in e&&e.ajax!==this.opts.ajax&&(this.opts.ajax=e.ajax,this.remoteLoaded=!1,this.clearRemoteCache()),e.placeholder!==void 0&&(this.opts.placeholder=e.placeholder),e.clearable!==void 0&&(this.opts.clearable=e.clearable),e.allowCreate!==void 0&&(this.opts.allowCreate=e.allowCreate),e.sortable!==void 0&&(this.opts.sortable=e.sortable),e.closeOnSelect!==void 0&&(this.opts.closeOnSelect=e.closeOnSelect),"maxSelections"in e&&(this.opts.maxSelections=e.maxSelections==null||!Number.isFinite(e.maxSelections)?void 0:Math.max(0,Math.floor(e.maxSelections))),e.theme!==void 0&&(this.opts.theme=e.theme,this.root.dataset.theme=e.theme,this.portalHost&&(this.portalHost.dataset.theme=e.theme)),e.required!==void 0&&(this.opts.required=e.required,e.required?this.control.setAttribute("aria-required","true"):this.control.removeAttribute("aria-required"),this.nativeSelect&&(this.nativeSelect.required=e.required)),e.templateResult!==void 0&&(this.opts.templateResult=e.templateResult),e.templateSelection!==void 0&&(this.opts.templateSelection=e.templateSelection),e.filterOption!==void 0&&(this.opts.filterOption=e.filterOption),e.searchFields!==void 0&&(this.opts.searchFields=e.searchFields),e.tokenSearch!==void 0&&(this.opts.tokenSearch=e.tokenSearch),e.accentInsensitive!==void 0&&(this.opts.accentInsensitive=e.accentInsensitive),e.searchScorer!==void 0&&(this.opts.searchScorer=e.searchScorer),e.highlightSearch!==void 0&&(this.opts.highlightSearch=e.highlightSearch),e.minSearchLength!==void 0&&(this.opts.minSearchLength=Math.max(0,Math.floor(e.minSearchLength))),e.minResultsForSearch!==void 0&&(this.opts.minResultsForSearch=Math.max(0,Math.floor(e.minResultsForSearch))),e.isOptionDisabled!==void 0&&(this.opts.isOptionDisabled=e.isOptionDisabled),e.virtualScroll!==void 0&&(this.opts.virtualScroll=e.virtualScroll),e.itemHeight!==void 0&&(this.opts.variableItemHeight=e.itemHeight==="auto",typeof e.itemHeight=="number"&&(this.opts.itemHeight=Math.max(1,e.itemHeight)),this.root.style.setProperty("--fs-item-height",`${this.opts.itemHeight}px`),this.portalHost?.style.setProperty("--fs-item-height",`${this.opts.itemHeight}px`)),e.language!==void 0&&(this.opts.language=e.language,this.strings=T(e.language),this.clearBtn.setAttribute("aria-label",this.strings.clearSelection),this.searchInput?.setAttribute("aria-label",this.strings.search)),e.openOnFocus!==void 0&&(this.opts.openOnFocus=e.openOnFocus),e.disabled!==void 0&&(e.disabled?this.disable():this.enable()),this.root.classList.toggle("forge-select--sortable",this.opts.sortable&&this.opts.multiple),this.updateSearchVisibility(),this.rowContentCache.clear(),this.rowHeightCache.clear(),this.searchIndex.clear(),this.renderValue(),this.isOpen&&this.renderList()}validate(){let e=(!this.opts.required||this.selected.length>0)&&(this.control.dataset.validationMessage??"")==="";return this.control.classList.toggle("forge-select__control--invalid",!e),this.control.setAttribute("aria-invalid",String(!e)),e}setCustomValidity(e){this.nativeSelect?.setCustomValidity(e),this.control.dataset.validationMessage=e}reportValidity(){let e=this.validate()&&(this.nativeSelect?.checkValidity()??!0);if(!e){let t=this.nativeSelect?.validationMessage??this.control.dataset.validationMessage??"";if(this.nativeSelect)return this.nativeSelect.reportValidity();this.emitter.emit("invalid",t)}return e}reload(){this.opts.ajax&&(this.clearRemoteCache(),this.remoteLoaded=!1,this.scheduleRemoteLoad(this.query,0))}clearRemoteCache(){this.remoteCache.clear()}setValue(e,t={}){let i=e==null?[]:Array.isArray(e)?e:[e],s=this.opts.multiple?i:i.slice(0,1);if(!B(s,this.selected)){this.selected=[];for(let n of s)this.selectValue(n,!1);this.afterSelectionChange(t.emitChange??!0)}}setData(e){this.ajaxTimer&&(clearTimeout(this.ajaxTimer),this.ajaxTimer=null),this.ajaxController?.abort(),this.ajaxController=null,this.ajaxRequestId+=1,this.setLoading(!1),this.loadingMore=!1,this.loadError=null,this.remoteLoaded=!0,this.page=0,this.hasMore=!1,this.data=e,this.opts.data=e,this.updateSearchVisibility(),this.rowContentCache.clear(),this.rowHeightCache.clear(),this.searchIndex.clear(),this.highlightedIndex=-1,this.isOpen&&this.renderList()}selectAll(){if(this.opts.multiple){this.selected=[];for(let e of this.allSelectableValues()){let t=this.findOption(e);t&&this.canSelectOption(t)&&this.selectValue(e,!1)}this.afterSelectionChange()}}clearAll(){this.clearSelection()}enable(){this.isDisabled=!1,this.root.classList.remove("forge-select--disabled"),this.control.tabIndex=0,this.control.setAttribute("aria-disabled","false"),this.nativeSelect&&(this.nativeSelect.disabled=!1)}disable(){this.close(),this.isDisabled=!0,this.root.classList.add("forge-select--disabled"),this.control.tabIndex=-1,this.control.setAttribute("aria-disabled","true"),this.nativeSelect&&(this.nativeSelect.disabled=!0)}on(e,t){this.emitter.on(e,t)}off(e,t){this.emitter.off(e,t)}applyAccessibleName(){let e=this.el.getAttribute("aria-labelledby"),t=this.el.getAttribute("aria-label");if(e)this.control.setAttribute("aria-labelledby",e);else if(t)this.control.setAttribute("aria-label",t);else if(this.el.id){let i=Array.from(document.getElementsByTagName("label")).find(s=>s.htmlFor===this.el.id);i&&(i.id||(i.id=`${this.uid}-label`),this.control.setAttribute("aria-labelledby",i.id))}}shouldShowSearch(){return this.opts.searchable&&(this.opts.ajax!=null||M(this.data).size>=this.opts.minResultsForSearch)}updateSearchVisibility(){this.searchInput&&(this.searchInput.hidden=!this.shouldShowSearch(),this.searchInput.hidden&&(this.searchInput.value="",this.query=""))}buildDom(){let e=typeof this.opts.dropdownParent=="string"?document.querySelector(this.opts.dropdownParent):this.opts.dropdownParent;if(this.opts.dropdownParent&&!e)throw new Error(`ForgeSelect: dropdown parent not found: ${String(this.opts.dropdownParent)}`);this.root=document.createElement("div"),this.root.className="forge-select",this.root.dataset.theme=this.opts.theme,this.root.style.setProperty("--fs-item-height",`${this.opts.itemHeight}px`),this.opts.sortable&&this.opts.multiple&&this.root.classList.add("forge-select--sortable"),this.control=document.createElement("div"),this.control.className="forge-select__control",this.control.setAttribute("role","combobox"),this.control.setAttribute("aria-haspopup","listbox"),this.control.setAttribute("aria-expanded","false"),this.control.setAttribute("aria-controls",`${this.uid}-list`),this.opts.required&&this.control.setAttribute("aria-required","true"),this.control.tabIndex=0,this.applyAccessibleName(),this.valueEl=document.createElement("div"),this.valueEl.className="forge-select__value",this.clearBtn=document.createElement("button"),this.clearBtn.type="button",this.clearBtn.className="forge-select__clear",this.clearBtn.setAttribute("aria-label",this.strings.clearSelection),this.clearBtn.textContent="\xD7",this.clearBtn.hidden=!0;let t=document.createElement("span");t.className="forge-select__arrow",t.setAttribute("aria-hidden","true"),this.control.append(this.valueEl,this.clearBtn,t),this.dropdown=document.createElement("div"),this.dropdown.className="forge-select__dropdown",this.dropdown.hidden=!0,this.opts.searchable&&(this.searchInput=document.createElement("input"),this.searchInput.type="search",this.searchInput.className="forge-select__search",this.searchInput.setAttribute("aria-label",this.strings.search),this.searchInput.setAttribute("aria-autocomplete","list"),this.searchInput.setAttribute("aria-controls",`${this.uid}-list`),this.searchInput.hidden=!this.shouldShowSearch(),this.dropdown.append(this.searchInput)),this.list=document.createElement("ul"),this.list.className="forge-select__list",this.list.id=`${this.uid}-list`,this.list.setAttribute("role","listbox"),this.opts.multiple&&this.list.setAttribute("aria-multiselectable","true"),this.dropdown.append(this.list),this.liveRegion=document.createElement("div"),this.liveRegion.className="forge-select__sr-only",this.liveRegion.setAttribute("role","status"),this.liveRegion.setAttribute("aria-live","polite"),this.root.append(this.control,this.liveRegion),e||this.root.append(this.dropdown),this.el.style.display="none",this.el.insertAdjacentElement("afterend",this.root),e&&(this.portalHost=document.createElement("div"),this.portalHost.className="forge-select forge-select--portal-host",this.portalHost.dataset.theme=this.opts.theme,this.portalHost.style.setProperty("--fs-item-height",`${this.opts.itemHeight}px`),this.portalHost.append(this.dropdown),e.append(this.portalHost)),this.bindEvents()}bindEvents(){this.control.addEventListener("click",e=>{if(e.target!==this.clearBtn){if(this.suppressNextTagClick){this.suppressNextTagClick=!1;return}this.isDisabled||(this.isOpen?this.close():this.open())}}),this.control.addEventListener("keydown",e=>this.handleKeydown(e)),this.control.addEventListener("mousedown",()=>{this.pointerDownOnControl=!0}),this.control.addEventListener("focus",()=>{this.opts.openOnFocus&&!this.pointerDownOnControl&&!this.isOpen&&!this.isDisabled&&this.open(),this.pointerDownOnControl=!1}),this.clearBtn.addEventListener("click",e=>{e.stopPropagation(),this.clearSelection()}),this.searchInput&&(this.searchInput.addEventListener("input",()=>{this.applySearchQuery(this.searchInput.value,!0)}),this.searchInput.addEventListener("keydown",e=>this.handleKeydown(e)),this.searchInput.addEventListener("paste",e=>{if(!this.opts.multiple||!this.opts.allowCreate)return;let i=(e.clipboardData?.getData("text")??"").split(/[,\n]+/).map(n=>n.trim()).filter(Boolean);if(i.length<2)return;e.preventDefault();let s=[];for(let n of i){let r=this.createTag(n);r&&s.push(r)}if(s.length!==0){this.searchInput.value="",this.query="",this.afterSelectionChange();for(let n of s)n.created&&this.emitter.emit("create",n.option),this.emitter.emit("select",n.option);this.opts.closeOnSelect?this.close():this.renderList()}})),this.list.addEventListener("click",e=>{let t=e.target,i=t.closest("[data-twisty]");if(i){let r=i.dataset.twisty;this.expandedValues.has(r)?this.expandedValues.delete(r):this.expandedValues.add(r),this.renderList();return}let s=t.closest("li[data-nav-index]");if(!s){let r=t.closest("li[data-option-value]"),o=r?this.findOption(r.dataset.optionValue):void 0;o&&this.hasReachedMaximum()&&!this.selected.includes(o.value)&&this.announceMaximum(o);return}let n=Number(s.dataset.navIndex);this.activateNavItem(n)}),this.list.addEventListener("scroll",()=>{this.scrollRafId==null&&(this.scrollRafId=requestAnimationFrame(()=>{this.scrollRafId=null,this.usesVirtualScroll()&&this.renderRows(),this.maybeLoadNextPage()}))})}applySearchQuery(e,t){this.query=e,this.searchInput&&this.searchInput.value!==e&&(this.searchInput.value=e),this.highlightedIndex=-1,this.list.scrollTop=0,t&&this.emitter.emit("search",e);let i=e.trim(),s=i!==""&&i.length<this.opts.minSearchLength;if(this.opts.ajax&&!s){this.scheduleRemoteLoad(e,this.opts.ajax.debounce??250);return}s&&(this.ajaxTimer&&(clearTimeout(this.ajaxTimer),this.ajaxTimer=null),this.ajaxController?.abort(),this.setLoading(!1)),this.renderList()}handleKeydown(e){if(!this.isDisabled)switch(e.key){case"Enter":e.preventDefault(),this.isOpen?this.highlightedIndex>=0&&this.activateNavItem(this.highlightedIndex):this.open();break;case" ":e.target===this.control&&(e.preventDefault(),this.isOpen||this.open());break;case"ArrowDown":e.preventDefault(),this.isOpen?this.moveHighlight(1):this.open();break;case"ArrowUp":e.preventDefault(),this.isOpen&&this.moveHighlight(-1);break;case"Escape":this.isOpen&&(e.preventDefault(),this.close(),this.control.focus());break;case"ArrowRight":this.isOpen&&this.navigateTree("right")&&e.preventDefault();break;case"ArrowLeft":this.isOpen&&this.navigateTree("left")&&e.preventDefault();break;case"Home":this.isOpen&&(e.preventDefault(),this.focusNavIndex(0));break;case"End":this.isOpen&&(e.preventDefault(),this.focusNavIndex(this.navItems.length-1));break;case"PageDown":this.isOpen&&(e.preventDefault(),this.focusNavIndex(Math.min(this.navItems.length-1,(this.highlightedIndex===-1?0:this.highlightedIndex)+$)));break;case"PageUp":this.isOpen&&(e.preventDefault(),this.focusNavIndex(Math.max(0,(this.highlightedIndex===-1?0:this.highlightedIndex)-$)));break;case"Tab":this.close();break;default:this.isOpen&&e.target===this.control&&e.key.length===1&&!e.ctrlKey&&!e.metaKey&&!e.altKey&&this.handleTypeahead(e.key);break}}handleTypeahead(e){this.typeaheadTimer&&clearTimeout(this.typeaheadTimer),this.typeaheadBuffer+=f(e,this.opts.accentInsensitive),this.typeaheadTimer=setTimeout(()=>{this.typeaheadBuffer="",this.typeaheadTimer=null},ee);let t=[...this.typeaheadBuffer].every(s=>s===this.typeaheadBuffer[0])?this.typeaheadBuffer[0]:this.typeaheadBuffer,i=this.navItems.length;for(let s=1;s<=i;s+=1){let n=(this.highlightedIndex+s+i)%i,r=this.navItems[n];if(r.kind==="option"&&f(r.option.label,this.opts.accentInsensitive).startsWith(t)){this.focusNavIndex(n);return}}}canSelectOption(e){if(this.opts.maxSelections==null)return!0;let t=[...this.selected];t.includes(e.value)||t.push(e.value);for(let i of x(e,this.isOptionDisabled))t.includes(i)||t.push(i);return H(this.data,t,this.isOptionDisabled),t.length<=this.opts.maxSelections}hasReachedMaximum(){return this.opts.maxSelections!=null&&this.selected.length>=this.opts.maxSelections}announceMaximum(e){let t=this.opts.maxSelections;t!=null&&(this.liveRegion.textContent=p(this.strings.maximumSelected,{count:String(t)}),this.emitter.emit("maximum",{limit:t,option:e}))}selectValue(e,t){if(this.selected.includes(e))return;let i=this.findOption(e)??this.selectedOptions.get(e)??{value:e,label:e};if(this.selectedOptions.set(e,i),this.opts.multiple){this.selected.push(e);for(let s of x(i,this.isOptionDisabled))this.selected.includes(s)||this.selected.push(s);this.syncTreeAncestors()}else this.selected=[e];t&&(this.afterSelectionChange(),this.emitter.emit("select",i))}deselectValue(e,t){let i=this.selected.indexOf(e);if(i===-1)return;let s=this.findOption(e)??this.selectedOptions.get(e);if(this.selected.splice(i,1),this.opts.multiple){if(s)for(let n of x(s,this.isOptionDisabled)){let r=this.selected.indexOf(n);r!==-1&&this.selected.splice(r,1)}this.syncTreeAncestors()}t&&(this.afterSelectionChange(),this.emitter.emit("unselect",s??{value:e,label:e}))}syncTreeAncestors(){H(this.data,this.selected,this.isOptionDisabled)}clearSelection(){this.selected.length!==0&&(this.selected=[],this.emitter.emit("clear"),this.afterSelectionChange())}allSelectableValues(){let e=[],t=i=>{this.isOptionDisabled(i)||e.push(i.value),i.children?.forEach(t)};for(let i of this.data)(g(i)?i.options:[i]).forEach(t);return e}afterSelectionChange(e=!0){this.renderValue(),this.syncNativeSelect(e),(!this.opts.required||this.selected.length>0)&&(this.control.classList.remove("forge-select__control--invalid"),this.control.removeAttribute("aria-invalid")),this.isOpen&&(this.opts.maxSelections!=null?this.renderList():this.renderRows()),e&&this.emitter.emit("change",this.getValue())}syncNativeSelect(e=!0){if(!(this.el instanceof HTMLSelectElement))return;let t=new Set;for(let i of Array.from(this.el.options))t.add(i.value),i.selected=this.selected.includes(i.value);for(let i of this.selected){if(t.has(i))continue;let s=document.createElement("option");s.value=i,s.textContent=this.selectedOptions.get(i)?.label??i,s.selected=!0,this.el.append(s)}if(this.opts.sortable&&this.opts.multiple)for(let i of this.selected){let s=Array.from(this.el.options).find(n=>n.value===i);s&&this.el.append(s)}if(e){this.syncingNative=!0;try{this.el.dispatchEvent(new Event("change",{bubbles:!0}))}finally{this.syncingNative=!1}}}findOption(e){return P(this.data,e)}findOptionByLabel(e){let t=e.toLowerCase(),i=s=>{for(let n of s){if(n.label.toLowerCase()===t)return n;let r=n.children?i(n.children):void 0;if(r)return r}};for(let s of this.data){let n=i(g(s)?s.options:[s]);if(n)return n}}createTag(e){let t=e.trim();if(!t)return;let i=this.findOptionByLabel(t);if(i){if(this.selected.includes(i.value))return;if(this.opts.multiple&&!this.canSelectOption(i)){this.announceMaximum(i);return}return this.selectValue(i.value,!1),{option:i,created:!1}}let s={value:t,label:t};if(this.opts.multiple&&!this.canSelectOption(s)){this.announceMaximum(s);return}return this.data.push(s),this.selectValue(s.value,!1),{option:s,created:!0}}createFromQuery(){let e=this.query.trim();if(!e)return;let t=this.createTag(e);t&&(this.searchInput&&(this.searchInput.value="",this.query=""),this.afterSelectionChange(),t.created&&this.emitter.emit("create",t.option),this.emitter.emit("select",t.option),!this.opts.multiple||this.opts.closeOnSelect?this.close():this.isOpen&&this.renderList())}activateNavItem(e){let t=this.navItems[e];if(!t)return;if(t.kind==="create"){this.createFromQuery();return}let{value:i}=t.option;if(this.opts.multiple){let s=!1;this.selected.includes(i)?(this.deselectValue(i,!0),s=!0):this.canSelectOption(t.option)?(this.selectValue(i,!0),s=!0):this.announceMaximum(t.option),s&&this.opts.closeOnSelect&&this.close()}else this.selectValue(i,!0),this.close(),this.control.focus()}renderValue(){this.valueEl.textContent="";let e=this.selected.length>0;if(this.clearBtn.hidden=!(this.opts.clearable&&e),!e){let t=document.createElement("span");t.className="forge-select__placeholder",t.textContent=this.opts.placeholder,this.valueEl.append(t);return}if(this.opts.multiple)for(let t of this.selected){let i=this.selectedOptions.get(t)??{value:t,label:t},s=document.createElement("span");s.className="forge-select__tag";let n=document.createElement("span");n.className="forge-select__tag-label",b(n,i,this.opts.templateSelection,"inline");let r=document.createElement("button");r.type="button",r.className="forge-select__tag-remove",r.setAttribute("aria-label",p(this.strings.removeItem,{label:i.label})),r.textContent="\xD7",r.addEventListener("click",o=>{o.stopPropagation(),this.isDisabled||this.deselectValue(t,!0)}),s.append(n,r),this.opts.sortable&&(s.dataset.value=t,s.tabIndex=0,s.setAttribute("aria-roledescription","draggable item"),s.setAttribute("aria-label",p(this.strings.reorderHint,{label:i.label})),s.addEventListener("keydown",o=>this.handleTagKeydown(o,t)),this.bindTagDrag(s,t)),this.valueEl.append(s)}else{let t=this.selectedOptions.get(this.selected[0])??{value:this.selected[0],label:this.selected[0]},i=document.createElement("span");i.className="forge-select__single-value",b(i,t,this.opts.templateSelection,"inline"),this.valueEl.append(i)}}bindTagDrag(e,t){let s=0,n=!1,r=[],o=l=>{if(!n){if(Math.abs(l.clientX-s)<4)return;n=!0,r=[...this.selected],typeof this.valueEl.setPointerCapture=="function"&&this.valueEl.setPointerCapture(l.pointerId),e.classList.add("forge-select__tag--dragging")}l.preventDefault();let c=r.indexOf(t),d=Array.from(this.valueEl.querySelectorAll(".forge-select__tag"));for(let u of d){if(u===e)continue;let m=u.dataset.value;if(!m)continue;let E=r.indexOf(m);if(E===-1)continue;let D=u.getBoundingClientRect(),k=D.left+D.width/2,_=c<E;if(_?l.clientX>k:l.clientX<k){r.splice(c,1),r.splice(E,0,t),_?this.valueEl.insertBefore(e,u.nextSibling):this.valueEl.insertBefore(e,u);break}}},h=l=>{this.valueEl.removeEventListener("pointermove",o),this.valueEl.removeEventListener("pointerup",h),this.valueEl.removeEventListener("pointercancel",h),n&&(typeof this.valueEl.releasePointerCapture=="function"&&this.valueEl.releasePointerCapture(l.pointerId),e.classList.remove("forge-select__tag--dragging"),this.selected=r,this.suppressNextTagClick=!0,this.afterSelectionChange(),this.emitter.emit("reorder",[...this.selected]))};e.addEventListener("pointerdown",l=>{this.isDisabled||l.button!==0||l.target.closest(".forge-select__tag-remove")||(s=l.clientX,n=!1,this.valueEl.addEventListener("pointermove",o),this.valueEl.addEventListener("pointerup",h),this.valueEl.addEventListener("pointercancel",h))})}handleTagKeydown(e,t){if(!e.altKey||e.key!=="ArrowLeft"&&e.key!=="ArrowRight")return;let i=this.selected.indexOf(t),s=e.key==="ArrowLeft"?i-1:i+1;if(i===-1||s<0||s>=this.selected.length)return;e.preventDefault(),e.stopPropagation();let n=[...this.selected];[n[i],n[s]]=[n[s],n[i]],this.selected=n,this.afterSelectionChange(),this.emitter.emit("reorder",[...this.selected]),this.focusTagByValue(t)}focusTagByValue(e){for(let t of Array.from(this.valueEl.querySelectorAll(".forge-select__tag")))if(t.dataset.value===e){t.focus();return}}buildRows(){this.rows=[],this.navItems=[],this.rowOffsetsCache=null;let e=this.query.trim(),t=f(e,this.opts.accentInsensitive),i=r=>t===""||(this.opts.filterOption?this.opts.filterOption(r,e):this.searchIndex.score(r,e,{fields:this.opts.searchFields,tokenSearch:this.opts.tokenSearch,accentInsensitive:this.opts.accentInsensitive,scorer:this.opts.searchScorer})>0),s=r=>t===""||i(r)||(r.children??[]).some(s),n=(r,o,h)=>{let l=-1;this.isOptionDisabled(r)||this.hasReachedMaximum()&&!this.selected.includes(r.value)||(l=this.navItems.length,this.navItems.push({kind:"option",option:r,parentValue:h}));let d=!!r.children&&r.children.length>0;if(this.rows.push({kind:"option",option:r,navIndex:l,depth:o,hasChildren:d}),d&&(t!==""||this.expandedValues.has(r.value)))for(let m of r.children)s(m)&&n(m,o+1,r.value)};if(e!==""&&e.length<this.opts.minSearchLength){this.rows.push({kind:"min-length"});return}if(this.loading){this.rows.push({kind:"loading"});return}if(this.loadError){this.rows.push({kind:"error"});return}for(let r of this.data)if(g(r)){let o=r.options.filter(s);if(o.length===0)continue;this.rows.push({kind:"group",label:r.label}),o.forEach(h=>n(h,0))}else s(r)&&n(r,0);if(this.opts.allowCreate&&t!==""&&!this.hasExactMatch(t)){let r=this.navItems.length;this.navItems.push({kind:"create"}),this.rows.push({kind:"create",navIndex:r})}this.rows.length===0?this.rows.push({kind:"empty"}):this.loadingMore&&this.rows.push({kind:"loading-more"})}hasExactMatch(e){return!!this.findOptionByLabel(e)}usesVirtualScroll(){return this.opts.virtualScroll!==!1&&this.rows.length>Z}rowKey(e,t){return e.kind==="option"?`option:${e.option.value}`:e.kind==="group"?`group:${e.label}:${t}`:`${e.kind}:${t}`}measuredRowHeight(e){return this.opts.variableItemHeight?this.rowHeightCache.get(this.rowKey(this.rows[e],e))??this.opts.itemHeight:this.opts.itemHeight}rowOffset(e){if(!this.opts.variableItemHeight)return e*this.opts.itemHeight;let t=0;for(let i=0;i<e;i+=1)t+=this.measuredRowHeight(i);return t}rowOffsets(){if(this.rowOffsetsCache)return this.rowOffsetsCache;let e=[0];for(let t=0;t<this.rows.length;t+=1)e.push(e[t]+this.measuredRowHeight(t));return this.rowOffsetsCache=e,e}renderList(){this.buildRows(),this.renderRows(),this.announceStatus()}announceStatus(){let e=this.rows[0],t=this.hasReachedMaximum()?p(this.strings.maximumSelected,{count:String(this.opts.maxSelections)}):e?.kind==="loading"?this.strings.loading:e?.kind==="error"?this.strings.errorLoading:e?.kind==="empty"?this.strings.noResults:e?.kind==="min-length"?p(this.strings.minSearchLength,{count:String(this.opts.minSearchLength)}):"";this.liveRegion.textContent!==t&&(this.liveRegion.textContent=t)}renderRows(){let e=this.list.scrollTop,t=this.list.clientHeight,i=this.usesVirtualScroll();this.list.textContent="";let s=this.opts.itemHeight,n=this.opts.variableItemHeight?this.rowOffsets():null,r=0,o=this.rows.length;if(i){let l=t||s*8;if(this.opts.variableItemHeight){for(;r<this.rows.length&&n[r+1]<e;)r+=1;r=Math.max(0,r-O),o=r;let d=e+l+O*s;for(;o<this.rows.length&&n[o]<d;)o+=1}else r=Math.max(0,Math.floor(e/s)-O),o=Math.min(this.rows.length,r+Math.ceil(l/s)+O*2);let c=document.createElement("li");c.className="forge-select__spacer",c.setAttribute("aria-hidden","true"),c.style.height=`${n?.[r]??this.rowOffset(r)}px`,this.list.append(c)}let h=[];for(let l=r;l<o;l++){let c=this.renderRow(this.rows[l]);this.list.append(c),h.push(c)}if(this.opts.variableItemHeight)for(let l=r;l<o;l++){let c=h[l-r],d=c.getBoundingClientRect().height||c.offsetHeight;if(d>0){let u=this.rowKey(this.rows[l],l);this.rowHeightCache.get(u)!==d&&(this.rowOffsetsCache=null),this.rowHeightCache.set(u,d)}}if(i){let l=document.createElement("li");l.className="forge-select__spacer",l.setAttribute("aria-hidden","true"),l.style.height=`${n?n[this.rows.length]-n[o]:this.rowOffset(this.rows.length)-this.rowOffset(o)}px`,this.list.append(l),this.list.scrollTop!==e&&(this.list.scrollTop=e)}this.updateActiveDescendant()}renderRow(e){let t=document.createElement("li");switch(e.kind){case"group":t.className="forge-select__group-label",t.setAttribute("role","presentation"),t.textContent=e.label;break;case"empty":t.className="forge-select__empty",t.setAttribute("role","option"),t.setAttribute("aria-disabled","true"),t.setAttribute("aria-selected","false"),t.textContent=this.strings.noResults;break;case"min-length":t.className="forge-select__min-length",t.setAttribute("role","option"),t.setAttribute("aria-disabled","true"),t.setAttribute("aria-selected","false"),t.textContent=p(this.strings.minSearchLength,{count:String(this.opts.minSearchLength)});break;case"error":t.className="forge-select__error",t.setAttribute("role","option"),t.setAttribute("aria-disabled","true"),t.setAttribute("aria-selected","false"),t.textContent=this.strings.errorLoading;break;case"loading":t.className="forge-select__loading",t.setAttribute("role","option"),t.setAttribute("aria-disabled","true"),t.setAttribute("aria-selected","false"),t.textContent=this.strings.loading;break;case"loading-more":t.className="forge-select__loading-more",t.setAttribute("aria-hidden","true"),t.textContent=this.strings.loadingMore;break;case"create":t.className="forge-select__option forge-select__option--create",t.setAttribute("role","option"),t.id=`${this.uid}-nav-${e.navIndex}`,t.dataset.navIndex=String(e.navIndex),t.textContent=p(this.strings.createOption,{query:this.query.trim()}),e.navIndex===this.highlightedIndex&&t.classList.add("forge-select__option--highlighted");break;case"option":{t.className="forge-select__option",t.dataset.optionValue=e.option.value,e.option.className&&t.classList.add(...e.option.className.trim().split(/\s+/).filter(Boolean)),t.setAttribute("role","option");let i=this.selected.includes(e.option.value);if(t.setAttribute("aria-selected",String(i)),i&&t.classList.add("forge-select__option--selected"),this.opts.multiple&&e.hasChildren&&w(e.option,this.selected,this.isOptionDisabled)==="some"&&(t.classList.add("forge-select__option--indeterminate"),t.dataset.selectionState="mixed"),e.depth>0&&(t.style.paddingLeft=`calc(12px + ${e.depth} * var(--fs-tree-indent, 18px))`),this.isOptionDisabled(e.option)||this.hasReachedMaximum()&&!this.selected.includes(e.option.value)?(t.classList.add("forge-select__option--disabled"),t.setAttribute("aria-disabled","true")):(t.id=`${this.uid}-nav-${e.navIndex}`,t.dataset.navIndex=String(e.navIndex),e.navIndex===this.highlightedIndex&&t.classList.add("forge-select__option--highlighted")),e.hasChildren){let s=this.query!==""||this.expandedValues.has(e.option.value);t.setAttribute("aria-expanded",String(s));let n=document.createElement("span");n.className="forge-select__twisty",n.dataset.twisty=e.option.value,n.setAttribute("aria-hidden","true"),n.textContent=s?"\u25BC":"\u25B6",t.append(n)}t.append(this.optionContent(e.option));break}}return t}optionContent(e){if(this.opts.highlightSearch&&this.query.trim()&&!this.opts.templateResult){let i=document.createElement("span");i.className="forge-select__option-content",b(i,e,void 0);let s=i.querySelector(".forge-select__option-label")??i,n=q(e.label,this.query,this.opts.accentInsensitive);if(n.length){s.textContent="";let r=0;for(let[o,h]of n){if(o<r)continue;s.append(document.createTextNode(e.label.slice(r,o)));let l=document.createElement("mark");l.className="forge-select__match",l.textContent=e.label.slice(o,h),s.append(l),r=h}s.append(document.createTextNode(e.label.slice(r)))}return i}let t=this.rowContentCache.get(e.value);if(!t){let i=document.createElement("span");if(i.className="forge-select__option-content",b(i,e,this.opts.templateResult),this.rowContentCache.size>=J){let s=this.rowContentCache.keys().next().value;this.rowContentCache.delete(s)}this.rowContentCache.set(e.value,i),t=i}return t.cloneNode(!0)}moveHighlight(e){if(this.navItems.length===0)return;let t=this.highlightedIndex===-1?e>0?0:this.navItems.length-1:(this.highlightedIndex+e+this.navItems.length)%this.navItems.length;this.focusNavIndex(t)}focusNavIndex(e){if(this.navItems.length!==0)if(this.highlightedIndex=e,this.usesVirtualScroll()){let t=this.rows.findIndex(i=>(i.kind==="option"||i.kind==="create")&&i.navIndex===e);if(t>=0){let i=this.measuredRowHeight(t),s=this.rowOffset(t),n=this.list.clientHeight||i*8,r=this.list.scrollTop;s<r?r=s:s+i>r+n&&(r=s+i-n),r!==this.list.scrollTop&&(this.list.scrollTop=r)}this.renderRows()}else this.renderRows(),this.list.querySelector(".forge-select__option--highlighted")?.scrollIntoView?.({block:"nearest"})}navigateTree(e){let t=this.navItems[this.highlightedIndex];if(!t||t.kind!=="option")return!1;let{option:i,parentValue:s}=t,n=!!i.children?.length,r=this.query!==""||this.expandedValues.has(i.value);if(e==="right"){if(n&&!r)return this.expandedValues.add(i.value),this.renderList(),!0;if(n){let o=this.navItems.findIndex(h=>h.kind==="option"&&h.parentValue===i.value);if(o>=0)return this.focusNavIndex(o),!0}return!1}if(n&&r&&this.query==="")return this.expandedValues.delete(i.value),this.renderList(),!0;if(s){let o=this.navItems.findIndex(h=>h.kind==="option"&&h.option.value===s);if(o>=0)return this.focusNavIndex(o),!0}return!1}updateActiveDescendant(){let e=this.searchInput??this.control;this.highlightedIndex>=0?e.setAttribute("aria-activedescendant",`${this.uid}-nav-${this.highlightedIndex}`):e.removeAttribute("aria-activedescendant")}scheduleRemoteLoad(e,t){this.ajaxTimer&&clearTimeout(this.ajaxTimer);let i=++this.ajaxRequestId;this.ajaxController?.abort(),this.ajaxController=null,this.page=0,this.hasMore=!0,this.setLoading(!0),this.loadingMore=!1,this.loadError=null,this.renderList(),this.ajaxTimer=setTimeout(()=>{this.ajaxTimer=null,this.loadRemote(e,{requestId:i})},t)}setLoading(e){this.loading!==e&&(this.loading=e,this.emitter.emit("loading",e))}remoteCacheKey(e,t){return`${e}\0${t}`}async requestRemote(e,t,i){let s=this.opts.ajax,n=Math.max(0,Math.floor(s.retry??0))+1,r;for(let o=0;o<n;o+=1)try{if(s.request)return await s.request(e,t,i);let h=await fetch(j(s,e,t),{signal:i});if(h.ok===!1)throw new Error(`ForgeSelect: remote request failed with HTTP ${h.status}`);return await h.json()}catch(h){if(r=h,i.aborted||o===n-1)throw h;let l=Math.max(0,s.retryDelay??250)*2**o;await new Promise((c,d)=>{let u=setTimeout(c,l);i.addEventListener("abort",()=>{clearTimeout(u),d(new DOMException("Aborted","AbortError"))},{once:!0})})}throw r}async prefetchRemote(e){let t=this.opts.ajax;if(!t||(t.cacheTtl??3e4)<=0)return;let i=this.remoteCacheKey(e,0);if(this.remoteCache.get(i))return;let s=new AbortController;try{let n=await this.requestRemote(e,0,s.signal);this.remoteCache.set(i,A(t,n),t.cacheTtl??3e4)}catch{}}maybeLoadNextPage(){if(!this.opts.ajax?.pagination||!this.hasMore||this.loading||this.loadingMore)return;let{scrollHeight:t,scrollTop:i,clientHeight:s}=this.list,n=this.opts.itemHeight*2;t-i-s>=n||(this.loadingMore=!0,this.renderList(),this.loadRemote(this.query,{append:!0}))}async loadRemote(e,{append:t=!1,requestId:i}={}){let s=this.opts.ajax,n=i??++this.ajaxRequestId;if(n!==this.ajaxRequestId)return;this.ajaxController?.abort();let r=new AbortController;this.ajaxController=r;let o=t?this.page+1:0;try{let h=this.remoteCacheKey(e,o),l=this.remoteCache.get(h);if(!l){let u=await this.requestRemote(e,o,r.signal);l=A(s,u),this.remoteCache.set(h,l,s.cacheTtl??3e4)}if(n!==this.ajaxRequestId||this.destroyed)return;let{options:c,hasMore:d}=l;if(t){let u=M(this.data);this.data=[...this.data,...c.filter(m=>!u.has(m.value))]}else this.data=c,this.rowContentCache.clear(),this.rowHeightCache.clear();this.page=o,this.hasMore=d,this.remoteLoaded=!0,this.loadError=null}catch(h){if(n!==this.ajaxRequestId||this.destroyed||r.signal.aborted)return;let l=h instanceof Error?h:new Error(String(h));t||(this.data=[],this.rowContentCache.clear(),this.rowHeightCache.clear()),this.hasMore=!1,this.loadError=l,this.emitter.emit("error",l)}finally{n===this.ajaxRequestId&&!this.destroyed&&(this.ajaxController=null,this.setLoading(!1),this.loadingMore=!1,this.isOpen&&this.renderList())}}};return W(ie);})();
|
|
2
2
|
//# sourceMappingURL=index.global.js.map
|