@pure-ds/core 0.7.48 → 0.7.50

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/types/pds.d.ts +7 -5
  2. package/dist/types/public/assets/pds/components/pds-toaster.d.ts +4 -1
  3. package/dist/types/public/assets/pds/components/pds-toaster.d.ts.map +1 -1
  4. package/dist/types/src/js/common/toast.d.ts +9 -0
  5. package/dist/types/src/js/common/toast.d.ts.map +1 -1
  6. package/package.json +1 -1
  7. package/public/assets/js/app.js +2131 -5
  8. package/public/assets/js/app.js.map +7 -0
  9. package/public/assets/js/lit.js +1031 -3
  10. package/public/assets/js/lit.js.map +7 -0
  11. package/public/assets/js/pds-ask.js +464 -9
  12. package/public/assets/js/pds-ask.js.map +7 -0
  13. package/public/assets/js/pds-autocomplete.js +639 -7
  14. package/public/assets/js/pds-autocomplete.js.map +7 -0
  15. package/public/assets/js/pds-enhancers.js +1471 -1
  16. package/public/assets/js/pds-enhancers.js.map +7 -0
  17. package/public/assets/js/pds-manager.js +17568 -3384
  18. package/public/assets/js/pds-manager.js.map +7 -0
  19. package/public/assets/js/pds-toast.js +30 -1
  20. package/public/assets/js/pds-toast.js.map +7 -0
  21. package/public/assets/js/pds.js +1969 -2
  22. package/public/assets/js/pds.js.map +7 -0
  23. package/public/assets/pds/components/pds-toaster.js +25 -7
  24. package/public/assets/pds/core/pds-ask.js +464 -9
  25. package/public/assets/pds/core/pds-autocomplete.js +639 -7
  26. package/public/assets/pds/core/pds-enhancers.js +1471 -1
  27. package/public/assets/pds/core/pds-manager.js +17568 -3384
  28. package/public/assets/pds/core/pds-toast.js +30 -1
  29. package/public/assets/pds/core.js +1969 -2
  30. package/public/assets/pds/external/lit.js +1031 -3
  31. package/src/js/common/toast.js +8 -0
  32. package/src/js/pds-core/pds-generator.js +1 -1
  33. package/src/js/pds.d.ts +7 -5
@@ -1,7 +1,639 @@
1
- function w(c){return new DOMParser().parseFromString(c,"text/html").body.childNodes}function v(c,t=100){let e;return function(...i){let r=()=>{clearTimeout(e),c(...i)};clearTimeout(e),e=setTimeout(r,t)}}function m(c){setTimeout(c,0)}function I(c){try{if(typeof c!="string"||c.indexOf(`
2
- `)!==-1||c.indexOf(" ")!==-1||c.startsWith("#/"))return!1;let t=new URL(c,window.location.origin);return t.protocol==="http:"||t.protocol==="https:"}catch{return!1}}function A(c,t,e){let s=window.screen.width/2-t/2,i=window.screen.height/2-e/2;return window.open(c,"",`toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=yes, width=${t}, height=${e}, top=${i}, left=${s}`)}var y={result:"ac-suggestion",item:"ac-itm"},p=class c extends EventTarget{constructor(t,e,s){super(),this.settings={emptyResultsText:"",...s},this.container=t,this.input=e,this.input.setAttribute("autocomplete","off"),this.categories=s.categories||{},this.caches=new Map,m(this.attach.bind(this))}static connect(t,e){let s=t.target;if(!s._autoComplete){if(!e?.categories)throw Error("Missing autocomplete settings");s._autoComplete=new c(s.parentNode,s,e),t.type==="focus"&&setTimeout(()=>{s._autoComplete.focusHandler(t)},100)}return s._autoComplete}on(t,e){return this.input.addEventListener(t,e),this}attach(){this.resultsDiv=document.createElement("div"),this.resultsDiv.title="",this.resultsDiv.classList.add(y.result),this.container.offsetWidth>100&&(this.resultsDiv.style.width=this.container.offsetWidth),this.resultsDiv.addEventListener("mousedown",this.resultClick.bind(this)),this.container.classList.add("ac-container"),this.input.classList.add("ac-input");let t=getComputedStyle(this.input);this.container.style.setProperty("--ac-bg-default",t.backgroundColor),this.container.style.setProperty("--ac-color-default",t.color);let e=getComputedStyle(this.input).accentColor;e!=="auto"&&this.container.style.setProperty("--ac-accent-color",e),(this.container?.shadowRoot??this.container).appendChild(this.resultsDiv),this.controller().clear("attach"),this.on("input",v(this.inputHandler.bind(this),this.settings.throttleInputMs??300)).on("focus",this.focusHandler.bind(this)).on("focusout",this.blurHandler.bind(this)).on("keyup",this.keyUpHandler.bind(this)).on("keydown",this.keyDownHandler.bind(this))}controller(){let t=this.internalController();return typeof this.settings.controller=="function"&&(t=this.settings.controller(this)??t),t}internalController(){return{show:this.show.bind(this),hide:this.hide.bind(this),clear:this.clear.bind(this),empty:()=>{}}}moveResult(t){this.controller().show();let e=this.acItems.length;this.rowIndex=this.rowIndex+t,this.rowIndex<=0?this.rowIndex=0:this.rowIndex>e-1&&(this.rowIndex=0);for(let i of this.acItems)i.classList.remove("selected");let s=this.getSelectedDiv();s?(s.classList.add("selected"),s.scrollIntoView({behavior:"smooth",block:"end",inline:"nearest"})):this.focusHandler({target:this.input})}getSelectedDiv(){return this.resultsDiv.querySelector(`div:nth-child(${this.rowIndex+1})`)}selectResult(t){if(t=t||this.getSelectedDiv(),t){let e=parseInt(t.getAttribute("data-index"));this.resultClicked=!0;let s=this.results[e],i=this.categories[s.category]??{};i.action=i.action??this.setText.bind(this),i.newTab&&(this.tabWindow=A("about:blank"));let r={...s,search:this.input.value};t.classList.add("ac-active"),setTimeout(()=>{this.controller().hide("result-selected"),r.action?r.action(r):(i.action(r),i.newTab&&(r.url?this.tabWindow.location.href=r.url:this.tabWindow.close()));var n=new Event("change",{bubbles:!0});this.input.dispatchEvent(n),this.controller().clear("result-selected");let u=new Event("result-selected");u.detail=r,this.input.dispatchEvent(u)},0)}}setText(t){let e=!1;this.input?(this.input.value=t.text,e=!0):this.container?.autoCompleteInput?(this.container.autoCompleteInput.value=t.text,e=!0):"value"in this.container&&(this.container.value=t.text,e=!0),e&&this.input&&this.input.dispatchEvent(new Event("input",{bubbles:!0})),this.controller().hide("settext")}resultClick(t){this.selectResult(t.target.closest(`.${y.item}`))}blurHandler(){setTimeout(()=>{this.resultClicked||this.controller().clear("blurred"),this.resultClicked=!1},100)}clear(){this.settings.debug||this.resultsDiv&&(this.resultsDiv.innerHTML="",this.controller().hide("clear"),this.cacheTmr&&clearTimeout(this.cacheTmr),this.cacheTmr=setTimeout(()=>{this.caches.clear()},60*1e3*5))}show(){if(!this.resultsDiv.classList.contains("ac-active")){let t=this.getViewBounds();this.resultsDiv.style.position="absolute",t.rect.width>100&&(this.resultsDiv.style.width=`${t.rect.width}px`),this.settings.direction=this.settings.direction??t.suggestedDirection,this.resultsDiv.setAttribute("data-direction",this.settings.direction),this.settings.direction==="up"?(this.resultsDiv.style.top="unset",this.resultsDiv.style.bottom=`${t.rect.height+20}px`,this.rowIndex=this.acItems.length):(this.resultsDiv.style.bottom="unset",this.resultsDiv.style.top=`${t.rect.height}px`,this.rowIndex=-1),this.resultsDiv.style.maxWidth="unset",this.resultsDiv.classList.toggle("ac-active",!0)}}getViewBounds(){let t=this.input.getBoundingClientRect();return{rect:t,suggestedDirection:t.top+t.height+500>window.innerHeight?"up":"down"}}hide(){this.resultsDiv.classList.toggle("ac-active",!1)}empty(){this.resultsDiv.innerHTML=`<div class="ac-empty">${this.settings.emptyResultsText}</div>`,this.controller().show()}inputHandler(t){this.cacheTmr&&clearTimeout(this.cacheTmr);let e={search:t.target.value,categories:this.categories};this.container.classList.add("search-running"),this.getItems(e,t).then(s=>{this.controller().clear("new-results"),this.resultsHandler(s,e),this.container.classList.remove("search-running")})}keyDownHandler(t){switch(t.key){case"Enter":t.stopPropagation(),t.preventDefault();break;case"ArrowDown":m(this.moveResult(1));break;case"ArrowUp":m(this.moveResult(-1));break}}keyUpHandler(t){switch(t.key){case"Escape":this.controller().hide("escape");break;case"Enter":this.getSelectedDiv()&&(this.container.preventEnter=!0,t.stopPropagation(),t.preventDefault(),this.selectResult(),setTimeout(()=>{this.container.preventEnter=!1},10));break;default:break}}focusHandler(t){this.controller().clear("focus");let e=t.target.value;this.suggest(e,t)}suggest(t,e){this.input.focus();let s={suggest:!0,search:t||"",categories:this.categories};this.getItems(s,e).then(i=>{this.input.dispatchEvent(new CustomEvent("show-results",{detail:{results:i}})),this.resultsHandler(i,s)})}sort(t,e){return t.sort((s,i)=>{let r=e.categories[s.category],n=e.categories[i.category],u=typeof r.sortIndex=="function"?r.sortIndex(e):r.sortIndex??0;return(typeof n.sortIndex=="function"?n.sortIndex(e):n.sortIndex??0)>u?1:-1})}resultsHandler(t,e){this.results=t,this.rowIndex=-1;let s=0,i=(r,n)=>`
3
- <div title="${n.tooltip||""}" data-index="${s}" class="${`${y.item} cat-${n.category} ${n.class??""}`.trim()}"${n.style?` style="${n.style}"`:""}>
4
- ${this.handleImageOrIcon(n)}
5
- <span class="text">${this.formatResultItem(n,e,r)}</span>
6
- ${this.settings.hideCategory?"":`<span class="category">${n.category||""}</span>`}
7
- </div>`;t.forEach(r=>{let n=e.categories[r.category]||{};r.element?this.resultsDiv.appendChild(r.element):(r=typeof r=="string"?{text:r}:r,this.resultsDiv.appendChild(w(i(n,r))[0])),s++}),t.length?(this.acItems=this.resultsDiv.querySelectorAll(".ac-itm"),this.controller().show()):e.search.length&&this.controller().empty()}handleImageOrIcon(t){return t.image?`<img src="${t.image}"/>`:typeof this.settings.iconHandler=="function"?this.settings.iconHandler(t):`<svg-icon icon="${t.icon}"></svg-icon>`}formatResultItem(t,e,s){let i=typeof t=="string"?{text:t}:t,r=i.text;return e.search&&(r=r.replace("%search%",e.search),i.description=i.description?.replace("%search%",e.search)),r=this.highlight(r,e.search),i.description&&(r=`<div>${r}</div><small>${i.description}</small>`),s.format&&(r=s.format({item:i,result:r,options:e})),r}highlight(t,e){var s=new RegExp("("+e+")","gi");return t.replace(s,'<span class="txt-hl">$1</span>')}async getItems(t,e){this.aborter&&this.aborter.abort();let s=this.caches.get(t.search);if(s)return s;let i=this.settings.map,r=l=>(typeof l=="string"&&(l={text:l}),l),n=l=>i?l.map(h=>({text:h[i]})):l.map(h=>r(h)),u=l=>(this.settings.max&&this.settings.max>0&&(l.length=this.settings.max),l);return this.aborter=new AbortController,this.aborterSignal=this.aborter.signal,new Promise(l=>{let h=o=>{o=this.sort(o,t),this.settings.cache!==!1&&this.caches.set(t.search,o),l(o)};if(I(this.items)){if(this.settings.minlength>0&&(!t.search||t.search.length<this.settings.minlength)){h([]);return}let o=this.formatSearch(this.items,t);fetch(o).then(a=>{if(a.status===200){a.json().then(d=>{d=n(d),h(u(d.filter(g=>this.isMatch(t,g))))});return}throw Error(`HTTP error ${a.status} - ${o}`)})}else if(Array.isArray(this.items)){let o=!0;this.items=this.items.map(a=>typeof a=="string"?{text:a}:(o=!1,a)),o&&this.container.classList.add("simple"),h(u(n(this.items)))}else if(typeof this.items=="function")t.control=this.container,Promise.resolve(this.items(t,e)).then(a=>{a=a.map(d=>r(d)),a=n(a),h(a)});else return h(Promise.resolve(this.items.apply(this,t)))})}async items(t){let e=[];t.results=[],t.signal=this.aborterSignal;for(var s in t.categories){let i=t.categories[s];if(i.trigger=i.trigger??(()=>!0),t.results=e,i.trigger(t)){let r=[];try{r=await i.getItems(t)}catch(n){console.warn(`Error loading items for omniBox category '${s}'.`,n)}e=e.concat(r.map(n=>(n.category=s,n)))}}return e}formatSearch(t,e){return t.indexOf("%search%")?t.replace("%search%",e.search||""):t+"?"+this.createQueryParam(e)}createQueryParam(t){let e=t.suggest?"&suggest=true":"";return`q=${t.text}${e}`}isMatch(t,e){return e.text?.indexOf("%search%")>=0?!0:t.search?e.text?.toLowerCase().indexOf(t.search.toLowerCase())>=0:t.suggest}static textFilter(t,e){return function(s){if(!t.search)return!0;if(s.hidden)return!1;let r=(e?s[e]:s).match(new RegExp(t.search,"gi"));if(r)return r;if(s.config?.tags)return s.config.tags.some(n=>n.match(new RegExp(t.search,"gi")))}}};var b=p?.prototype?.selectResult;typeof b=="function"&&p?.prototype?.__pdsSelectedItemPatched!==!0&&(p.prototype.selectResult=function(t){let e=t||this.getSelectedDiv?.();if(!e)return b.call(this,t);let s=e.getAttribute?.("data-index")??"",i=Number.parseInt(s,10),r=Number.isInteger(i)?this.results?.[i]:null,n=r&&this.categories?this.categories[r.category]:null,u=[],l=(o,a)=>{if(!o||typeof o[a]!="function")return;let d=o[a],g=!1,x=()=>{g||(o[a]=d,g=!0)};o[a]=function(f={},...C){try{return f&&typeof f=="object"&&!("selectedItem"in f)&&(f.selectedItem=e),d.call(this,f,...C)}finally{x()}},u.push(x)};l(r,"action"),l(n,"action");let h=b.call(this,e);return setTimeout(()=>{for(let o of u)o()},1e3),h},p.prototype.__pdsSelectedItemPatched=!0);export{p as AutoComplete};
1
+ // node_modules/pure-web/src/js/common.js
2
+ function parseHTML(html) {
3
+ return new DOMParser().parseFromString(html, "text/html").body.childNodes;
4
+ }
5
+ function throttle(fn, timeoutMs = 100) {
6
+ let handle;
7
+ return function executedFunction(...args) {
8
+ const fire = () => {
9
+ clearTimeout(handle);
10
+ fn(...args);
11
+ };
12
+ clearTimeout(handle);
13
+ handle = setTimeout(fire, timeoutMs);
14
+ };
15
+ }
16
+ function enQueue(fn) {
17
+ setTimeout(fn, 0);
18
+ }
19
+ function isUrl(str) {
20
+ try {
21
+ if (typeof str !== "string")
22
+ return false;
23
+ if (str.indexOf("\n") !== -1 || str.indexOf(" ") !== -1)
24
+ return false;
25
+ if (str.startsWith("#/"))
26
+ return false;
27
+ const newUrl = new URL(str, window.location.origin);
28
+ return newUrl.protocol === "http:" || newUrl.protocol === "https:";
29
+ } catch {
30
+ return false;
31
+ }
32
+ }
33
+ function openCenteredWindow(url, width, height) {
34
+ const left = window.screen.width / 2 - width / 2;
35
+ const top = window.screen.height / 2 - height / 2;
36
+ return window.open(
37
+ url,
38
+ "",
39
+ `toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=yes, width=${width}, height=${height}, top=${top}, left=${left}`
40
+ );
41
+ }
42
+
43
+ // node_modules/pure-web/src/js/autocomplete.js
44
+ var cssClasses = {
45
+ result: "ac-suggestion",
46
+ item: "ac-itm"
47
+ };
48
+ var AutoComplete = class _AutoComplete extends EventTarget {
49
+ constructor(parent, textInput, settings) {
50
+ super();
51
+ this.settings = {
52
+ emptyResultsText: "",
53
+ ...settings
54
+ };
55
+ this.container = parent;
56
+ this.input = textInput;
57
+ this.input.setAttribute("autocomplete", "off");
58
+ this.categories = settings.categories || {};
59
+ this.caches = /* @__PURE__ */ new Map();
60
+ enQueue(this.attach.bind(this));
61
+ }
62
+ /**
63
+ * Connector logic to call on @focus events.
64
+ * Lit example:
65
+ * <input type="search" @focus=${(e) => {AutoComplete.connect(e, this.autoComplete); }} />
66
+ *
67
+ * @param {*} event focus event
68
+ * @param {*} options AutoComplete options
69
+ */
70
+ static connect(event, options) {
71
+ const input = event.target;
72
+ if (!input._autoComplete) {
73
+ if (!options?.categories)
74
+ throw Error("Missing autocomplete settings");
75
+ input._autoComplete = new _AutoComplete(input.parentNode, input, options);
76
+ if (event.type === "focus") {
77
+ setTimeout(() => {
78
+ input._autoComplete.focusHandler(event);
79
+ }, 100);
80
+ }
81
+ }
82
+ return input._autoComplete;
83
+ }
84
+ on(a, b) {
85
+ this.input.addEventListener(a, b);
86
+ return this;
87
+ }
88
+ attach() {
89
+ this.resultsDiv = document.createElement("div");
90
+ this.resultsDiv.title = "";
91
+ this.resultsDiv.classList.add(cssClasses.result);
92
+ if (this.container.offsetWidth > 100)
93
+ this.resultsDiv.style.width = this.container.offsetWidth;
94
+ this.resultsDiv.addEventListener("mousedown", this.resultClick.bind(this));
95
+ this.container.classList.add("ac-container");
96
+ this.input.classList.add("ac-input");
97
+ const inputStyle = getComputedStyle(this.input);
98
+ this.container.style.setProperty(
99
+ "--ac-bg-default",
100
+ inputStyle.backgroundColor
101
+ );
102
+ this.container.style.setProperty("--ac-color-default", inputStyle.color);
103
+ const acc = getComputedStyle(this.input).accentColor;
104
+ if (acc !== "auto")
105
+ this.container.style.setProperty("--ac-accent-color", acc);
106
+ (this.container?.shadowRoot ?? this.container).appendChild(this.resultsDiv);
107
+ this.controller().clear("attach");
108
+ this.on(
109
+ "input",
110
+ throttle(
111
+ this.inputHandler.bind(this),
112
+ this.settings.throttleInputMs ?? 300
113
+ )
114
+ ).on("focus", this.focusHandler.bind(this)).on("focusout", this.blurHandler.bind(this)).on("keyup", this.keyUpHandler.bind(this)).on("keydown", this.keyDownHandler.bind(this));
115
+ }
116
+ controller() {
117
+ let c = this.internalController();
118
+ if (typeof this.settings.controller === "function")
119
+ c = this.settings.controller(this) ?? c;
120
+ return c;
121
+ }
122
+ internalController() {
123
+ return {
124
+ show: this.show.bind(this),
125
+ hide: this.hide.bind(this),
126
+ clear: this.clear.bind(this),
127
+ empty: () => {
128
+ }
129
+ };
130
+ }
131
+ moveResult(add) {
132
+ this.controller().show();
133
+ let length = this.acItems.length;
134
+ this.rowIndex = this.rowIndex + add;
135
+ if (this.rowIndex <= 0) {
136
+ this.rowIndex = 0;
137
+ } else if (this.rowIndex > length - 1) {
138
+ this.rowIndex = 0;
139
+ }
140
+ for (const r of this.acItems) {
141
+ r.classList.remove("selected");
142
+ }
143
+ let div = this.getSelectedDiv();
144
+ if (div) {
145
+ div.classList.add("selected");
146
+ div.scrollIntoView({
147
+ behavior: "smooth",
148
+ block: "end",
149
+ inline: "nearest"
150
+ });
151
+ } else {
152
+ this.focusHandler({
153
+ target: this.input
154
+ });
155
+ }
156
+ }
157
+ getSelectedDiv() {
158
+ return this.resultsDiv.querySelector(`div:nth-child(${this.rowIndex + 1})`);
159
+ }
160
+ // execute action
161
+ selectResult(div) {
162
+ div = div || this.getSelectedDiv();
163
+ if (div) {
164
+ let index = parseInt(div.getAttribute("data-index"));
165
+ this.resultClicked = true;
166
+ let result = this.results[index];
167
+ let handlingCategory = this.categories[result.category] ?? {};
168
+ handlingCategory.action = handlingCategory.action ?? this.setText.bind(this);
169
+ if (handlingCategory.newTab) {
170
+ this.tabWindow = openCenteredWindow("about:blank");
171
+ }
172
+ let options = {
173
+ ...result,
174
+ search: this.input.value
175
+ };
176
+ div.classList.add("ac-active");
177
+ setTimeout(() => {
178
+ this.controller().hide("result-selected");
179
+ if (options.action) {
180
+ options.action(options);
181
+ } else {
182
+ handlingCategory.action(options);
183
+ if (handlingCategory.newTab) {
184
+ if (options.url) {
185
+ this.tabWindow.location.href = options.url;
186
+ } else {
187
+ this.tabWindow.close();
188
+ }
189
+ }
190
+ }
191
+ var event = new Event("change", { bubbles: true });
192
+ this.input.dispatchEvent(event);
193
+ this.controller().clear("result-selected");
194
+ const ev = new Event("result-selected");
195
+ ev.detail = options;
196
+ this.input.dispatchEvent(ev);
197
+ }, 0);
198
+ }
199
+ }
200
+ setText(options) {
201
+ let valueSet = false;
202
+ if (this.input) {
203
+ this.input.value = options.text;
204
+ valueSet = true;
205
+ } else if (this.container?.autoCompleteInput) {
206
+ this.container.autoCompleteInput.value = options.text;
207
+ valueSet = true;
208
+ } else if ("value" in this.container) {
209
+ this.container.value = options.text;
210
+ valueSet = true;
211
+ }
212
+ if (valueSet && this.input) {
213
+ this.input.dispatchEvent(new Event("input", { bubbles: true }));
214
+ }
215
+ this.controller().hide("settext");
216
+ }
217
+ resultClick(event) {
218
+ this.selectResult(event.target.closest(`.${cssClasses.item}`));
219
+ }
220
+ blurHandler() {
221
+ setTimeout(() => {
222
+ if (!this.resultClicked)
223
+ this.controller().clear("blurred");
224
+ this.resultClicked = false;
225
+ }, 100);
226
+ }
227
+ clear() {
228
+ if (this.settings.debug)
229
+ return;
230
+ if (!this.resultsDiv)
231
+ return;
232
+ this.resultsDiv.innerHTML = "";
233
+ this.controller().hide("clear");
234
+ if (this.cacheTmr)
235
+ clearTimeout(this.cacheTmr);
236
+ this.cacheTmr = setTimeout(() => {
237
+ this.caches.clear();
238
+ }, 60 * 1e3 * 5);
239
+ }
240
+ show() {
241
+ if (!this.resultsDiv.classList.contains("ac-active")) {
242
+ const viewBounds = this.getViewBounds();
243
+ this.resultsDiv.style.position = "absolute";
244
+ if (viewBounds.rect.width > 100)
245
+ this.resultsDiv.style.width = `${viewBounds.rect.width}px`;
246
+ this.settings.direction = this.settings.direction ?? viewBounds.suggestedDirection;
247
+ this.resultsDiv.setAttribute("data-direction", this.settings.direction);
248
+ if (this.settings.direction === "up") {
249
+ this.resultsDiv.style.top = "unset";
250
+ this.resultsDiv.style.bottom = `${viewBounds.rect.height + 20}px`;
251
+ this.rowIndex = this.acItems.length;
252
+ } else {
253
+ this.resultsDiv.style.bottom = "unset";
254
+ this.resultsDiv.style.top = `${viewBounds.rect.height}px`;
255
+ this.rowIndex = -1;
256
+ }
257
+ this.resultsDiv.style.maxWidth = "unset";
258
+ this.resultsDiv.classList.toggle("ac-active", true);
259
+ }
260
+ }
261
+ getViewBounds() {
262
+ const rect = this.input.getBoundingClientRect();
263
+ return {
264
+ rect,
265
+ suggestedDirection: rect.top + rect.height + 500 > window.innerHeight ? "up" : "down"
266
+ };
267
+ }
268
+ hide() {
269
+ this.resultsDiv.classList.toggle("ac-active", false);
270
+ }
271
+ empty() {
272
+ this.resultsDiv.innerHTML = `<div class="ac-empty">${this.settings.emptyResultsText}</div>`;
273
+ this.controller().show();
274
+ }
275
+ inputHandler(e) {
276
+ if (this.cacheTmr)
277
+ clearTimeout(this.cacheTmr);
278
+ let options = {
279
+ search: e.target.value,
280
+ categories: this.categories
281
+ };
282
+ this.container.classList.add("search-running");
283
+ this.getItems(options, e).then((r) => {
284
+ this.controller().clear("new-results");
285
+ this.resultsHandler(r, options);
286
+ this.container.classList.remove("search-running");
287
+ });
288
+ }
289
+ keyDownHandler(e) {
290
+ switch (e.key) {
291
+ case "Enter":
292
+ e.stopPropagation();
293
+ e.preventDefault();
294
+ break;
295
+ case "ArrowDown":
296
+ enQueue(this.moveResult(1));
297
+ break;
298
+ case "ArrowUp":
299
+ enQueue(this.moveResult(-1));
300
+ break;
301
+ }
302
+ }
303
+ keyUpHandler(e) {
304
+ switch (e.key) {
305
+ case "Escape":
306
+ this.controller().hide("escape");
307
+ break;
308
+ case "Enter":
309
+ if (this.getSelectedDiv()) {
310
+ this.container.preventEnter = true;
311
+ e.stopPropagation();
312
+ e.preventDefault();
313
+ this.selectResult();
314
+ setTimeout(() => {
315
+ this.container.preventEnter = false;
316
+ }, 10);
317
+ }
318
+ break;
319
+ default:
320
+ break;
321
+ }
322
+ }
323
+ focusHandler(e) {
324
+ this.controller().clear("focus");
325
+ let value = e.target.value;
326
+ this.suggest(value, e);
327
+ }
328
+ /**
329
+ * Shows suggestion box
330
+ * @param {string} value - String to suggest results for
331
+ */
332
+ suggest(value, e) {
333
+ this.input.focus();
334
+ const options = {
335
+ suggest: true,
336
+ search: value || "",
337
+ categories: this.categories
338
+ };
339
+ this.getItems(options, e).then((r) => {
340
+ this.input.dispatchEvent(
341
+ new CustomEvent("show-results", {
342
+ detail: {
343
+ results: r
344
+ }
345
+ })
346
+ );
347
+ this.resultsHandler(r, options);
348
+ });
349
+ }
350
+ // Sort results based on static (integer) or dynamic (function) sortIndex in category.
351
+ sort(r, options) {
352
+ return r.sort((a, b) => {
353
+ const aCat = options.categories[a.category];
354
+ const bCat = options.categories[b.category];
355
+ const aIndex = typeof aCat.sortIndex === "function" ? aCat.sortIndex(options) : aCat.sortIndex ?? 0;
356
+ const bIndex = typeof bCat.sortIndex === "function" ? bCat.sortIndex(options) : bCat.sortIndex ?? 0;
357
+ return bIndex > aIndex ? 1 : -1;
358
+ });
359
+ }
360
+ resultsHandler(r, options) {
361
+ this.results = r;
362
+ this.rowIndex = -1;
363
+ let index = 0;
364
+ const singleItemTemplate = (catHandler, i) => {
365
+ return (
366
+ /*html*/
367
+ `
368
+ <div title="${i.tooltip || ""}" data-index="${index}" class="${`${cssClasses.item} cat-${i.category} ${i.class ?? ""}`.trim()}"${i.style ? ` style="${i.style}"` : ""}>
369
+ ${this.handleImageOrIcon(i)}
370
+ <span class="text">${this.formatResultItem(
371
+ i,
372
+ options,
373
+ catHandler
374
+ )}</span>
375
+ ${!this.settings.hideCategory ? `<span class="category">${i.category || ""}</span>` : ""}
376
+ </div>`
377
+ );
378
+ };
379
+ r.forEach((i) => {
380
+ let catHandler = options.categories[i.category] || {};
381
+ if (i.element) {
382
+ this.resultsDiv.appendChild(i.element);
383
+ } else {
384
+ i = typeof i === "string" ? { text: i } : i;
385
+ this.resultsDiv.appendChild(
386
+ parseHTML(singleItemTemplate(catHandler, i))[0]
387
+ );
388
+ }
389
+ index++;
390
+ });
391
+ if (r.length) {
392
+ this.acItems = this.resultsDiv.querySelectorAll(".ac-itm");
393
+ this.controller().show();
394
+ } else if (options.search.length)
395
+ this.controller().empty();
396
+ }
397
+ handleImageOrIcon(i) {
398
+ if (i.image) {
399
+ return (
400
+ /*html*/
401
+ `<img src="${i.image}"/>`
402
+ );
403
+ }
404
+ if (typeof this.settings.iconHandler === "function")
405
+ return this.settings.iconHandler(i);
406
+ return (
407
+ /*html*/
408
+ `<svg-icon icon="${i.icon}"></svg-icon>`
409
+ );
410
+ }
411
+ formatResultItem(item, options, catHandler) {
412
+ const i = typeof item === "string" ? { text: item } : item;
413
+ let result = i.text;
414
+ if (options.search) {
415
+ result = result.replace("%search%", options.search);
416
+ i.description = i.description?.replace("%search%", options.search);
417
+ }
418
+ result = this.highlight(result, options.search);
419
+ if (i.description) {
420
+ result = `<div>${result}</div><small>${i.description}</small>`;
421
+ }
422
+ if (catHandler.format) {
423
+ result = catHandler.format({
424
+ item: i,
425
+ result,
426
+ options
427
+ });
428
+ }
429
+ return result;
430
+ }
431
+ highlight(str, find) {
432
+ var reg = new RegExp("(" + find + ")", "gi");
433
+ return str.replace(reg, '<span class="txt-hl">$1</span>');
434
+ }
435
+ async getItems(options, e) {
436
+ if (this.aborter) {
437
+ this.aborter.abort();
438
+ }
439
+ let cache = this.caches.get(options.search);
440
+ if (cache)
441
+ return cache;
442
+ const prop = this.settings.map;
443
+ const normalizeItem = (i) => {
444
+ if (typeof i === "string")
445
+ i = { text: i };
446
+ return i;
447
+ };
448
+ const map = (list) => {
449
+ if (!prop) {
450
+ return list.map((i) => {
451
+ return normalizeItem(i);
452
+ });
453
+ }
454
+ return list.map((i) => {
455
+ return { text: i[prop] };
456
+ });
457
+ };
458
+ const max = (list) => {
459
+ if (this.settings.max && this.settings.max > 0) {
460
+ list.length = this.settings.max;
461
+ }
462
+ return list;
463
+ };
464
+ this.aborter = new AbortController();
465
+ this.aborterSignal = this.aborter.signal;
466
+ return new Promise((resolve) => {
467
+ const internalResolve = (data) => {
468
+ data = this.sort(data, options);
469
+ if (this.settings.cache !== false)
470
+ this.caches.set(options.search, data);
471
+ resolve(data);
472
+ };
473
+ if (isUrl(this.items)) {
474
+ if (this.settings.minlength > 0) {
475
+ if (!options.search || options.search.length < this.settings.minlength) {
476
+ internalResolve([]);
477
+ return;
478
+ }
479
+ }
480
+ let url = this.formatSearch(this.items, options);
481
+ fetch(url).then((x) => {
482
+ if (x.status === 200) {
483
+ x.json().then((items) => {
484
+ items = map(items);
485
+ internalResolve(
486
+ max(
487
+ items.filter((i) => {
488
+ return this.isMatch(options, i);
489
+ })
490
+ )
491
+ );
492
+ });
493
+ return;
494
+ }
495
+ throw Error(`HTTP error ${x.status} - ${url}`);
496
+ });
497
+ } else if (Array.isArray(this.items)) {
498
+ let simple = true;
499
+ this.items = this.items.map((i) => {
500
+ if (typeof i === "string") {
501
+ return { text: i };
502
+ }
503
+ simple = false;
504
+ return i;
505
+ });
506
+ if (simple) {
507
+ this.container.classList.add("simple");
508
+ }
509
+ internalResolve(max(map(this.items)));
510
+ } else if (typeof this.items === "function") {
511
+ options.control = this.container;
512
+ let ar = Promise.resolve(this.items(options, e));
513
+ ar.then((ar2) => {
514
+ ar2 = ar2.map((i) => {
515
+ return normalizeItem(i);
516
+ });
517
+ ar2 = map(ar2);
518
+ internalResolve(ar2);
519
+ });
520
+ } else {
521
+ return internalResolve(
522
+ Promise.resolve(this.items.apply(this, options))
523
+ );
524
+ }
525
+ });
526
+ }
527
+ async items(options) {
528
+ let arr = [];
529
+ options.results = [];
530
+ options.signal = this.aborterSignal;
531
+ for (var c in options.categories) {
532
+ let catHandler = options.categories[c];
533
+ catHandler.trigger = catHandler.trigger ?? (() => {
534
+ return true;
535
+ });
536
+ options.results = arr;
537
+ if (catHandler.trigger(options)) {
538
+ let catResults = [];
539
+ try {
540
+ catResults = await catHandler.getItems(options);
541
+ } catch (ex) {
542
+ console.warn(`Error loading items for omniBox category '${c}'.`, ex);
543
+ }
544
+ arr = arr.concat(
545
+ catResults.map((i) => {
546
+ i.category = c;
547
+ return i;
548
+ })
549
+ );
550
+ }
551
+ }
552
+ return arr;
553
+ }
554
+ formatSearch(url, options) {
555
+ if (url.indexOf("%search%")) {
556
+ return url.replace("%search%", options.search || "");
557
+ }
558
+ return url + "?" + this.createQueryParam(options);
559
+ }
560
+ createQueryParam(options) {
561
+ let suggest = options.suggest ? "&suggest=true" : "";
562
+ return `q=${options.text}${suggest}`;
563
+ }
564
+ isMatch(options, i) {
565
+ if (i.text?.indexOf("%search%") >= 0)
566
+ return true;
567
+ return options.search ? i.text?.toLowerCase().indexOf(options.search.toLowerCase()) >= 0 : options.suggest;
568
+ }
569
+ static textFilter(options, propertyName) {
570
+ return function(i) {
571
+ if (!options.search)
572
+ return true;
573
+ if (i.hidden)
574
+ return false;
575
+ const prop = propertyName ? i[propertyName] : i;
576
+ const isMatch = prop.match(new RegExp(options.search, "gi"));
577
+ if (isMatch)
578
+ return isMatch;
579
+ if (i.config?.tags) {
580
+ return i.config.tags.some((tag) => {
581
+ return tag.match(new RegExp(options.search, "gi"));
582
+ });
583
+ }
584
+ };
585
+ }
586
+ };
587
+
588
+ // src/js/pds-autocomplete.js
589
+ var originalSelectResult = AutoComplete?.prototype?.selectResult;
590
+ if (typeof originalSelectResult === "function" && AutoComplete?.prototype?.__pdsSelectedItemPatched !== true) {
591
+ AutoComplete.prototype.selectResult = function patchedSelectResult(div) {
592
+ const selectedItem = div || this.getSelectedDiv?.();
593
+ if (!selectedItem) {
594
+ return originalSelectResult.call(this, div);
595
+ }
596
+ const indexRaw = selectedItem.getAttribute?.("data-index") ?? "";
597
+ const index = Number.parseInt(indexRaw, 10);
598
+ const result = Number.isInteger(index) ? this.results?.[index] : null;
599
+ const categoryConfig = result && this.categories ? this.categories[result.category] : null;
600
+ const restores = [];
601
+ const wrapAction = (target, key) => {
602
+ if (!target || typeof target[key] !== "function")
603
+ return;
604
+ const originalAction = target[key];
605
+ let restored = false;
606
+ const restore = () => {
607
+ if (restored)
608
+ return;
609
+ target[key] = originalAction;
610
+ restored = true;
611
+ };
612
+ target[key] = function wrappedAction(options = {}, ...rest) {
613
+ try {
614
+ if (options && typeof options === "object" && !("selectedItem" in options)) {
615
+ options.selectedItem = selectedItem;
616
+ }
617
+ return originalAction.call(this, options, ...rest);
618
+ } finally {
619
+ restore();
620
+ }
621
+ };
622
+ restores.push(restore);
623
+ };
624
+ wrapAction(result, "action");
625
+ wrapAction(categoryConfig, "action");
626
+ const output = originalSelectResult.call(this, selectedItem);
627
+ setTimeout(() => {
628
+ for (const restore of restores) {
629
+ restore();
630
+ }
631
+ }, 1e3);
632
+ return output;
633
+ };
634
+ AutoComplete.prototype.__pdsSelectedItemPatched = true;
635
+ }
636
+ export {
637
+ AutoComplete
638
+ };
639
+ //# sourceMappingURL=pds-autocomplete.js.map