@pure-ds/core 0.7.38 → 0.7.40

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.
@@ -65,6 +65,7 @@ export class PdsOmnibox extends HTMLElement {
65
65
  #lengthProbe;
66
66
  #suggestionsUpdatedHandler;
67
67
  #suggestionsObserver;
68
+ #overlayOverflowOverrides = new Map();
68
69
 
69
70
  constructor() {
70
71
  super();
@@ -96,6 +97,7 @@ export class PdsOmnibox extends HTMLElement {
96
97
  }
97
98
  this.#teardownAutoCompleteSizing();
98
99
  this.#teardownSuggestionsObserver();
100
+ this.#setOverlayClippingOverride(false);
99
101
  const autoComplete = this.#input?._autoComplete;
100
102
  if (autoComplete) {
101
103
  autoComplete.controller?.().clear?.("disconnected");
@@ -765,6 +767,7 @@ export class PdsOmnibox extends HTMLElement {
765
767
  this.#suggestionsObserver = new MutationObserver(() => {
766
768
  if (!suggestion.classList.contains("ac-active")) {
767
769
  this.removeAttribute("data-suggestions-open");
770
+ this.#setOverlayClippingOverride(false);
768
771
  this.#clearSuggestionOverlayStyles(suggestion);
769
772
  this.#resetIconToDefault();
770
773
  }
@@ -819,7 +822,7 @@ export class PdsOmnibox extends HTMLElement {
819
822
  return null;
820
823
  }
821
824
 
822
- #hasTransformedAncestor(startNode) {
825
+ #getFixedContainingBlock(startNode) {
823
826
  let current = startNode;
824
827
  let safety = 0;
825
828
  while (current && safety < 80) {
@@ -831,19 +834,21 @@ export class PdsOmnibox extends HTMLElement {
831
834
  style.filter !== "none" ||
832
835
  style.backdropFilter !== "none"
833
836
  ) {
834
- return true;
837
+ return current;
835
838
  }
836
839
  }
837
840
  current = this.#getComposedParent(current);
838
841
  safety += 1;
839
842
  }
840
- return false;
843
+ return null;
841
844
  }
842
845
 
843
846
  #shouldUseFixedSuggestionOverlay(container) {
844
847
  if (!container) return false;
845
- if (this.closest("pds-drawer, dialog")) return false;
846
- return !this.#hasTransformedAncestor(this);
848
+
849
+ // Always prefer viewport overlay positioning so results are not clipped by
850
+ // parent overflow containers (for example dialog bodies or drawers).
851
+ return true;
847
852
  }
848
853
 
849
854
  #positionSuggestionInline({ container, suggestion, rect, direction, offset, maxHeight }) {
@@ -865,6 +870,7 @@ export class PdsOmnibox extends HTMLElement {
865
870
  container,
866
871
  suggestion,
867
872
  rect,
873
+ containingBlock,
868
874
  viewportHeight,
869
875
  viewportWidth,
870
876
  direction,
@@ -878,21 +884,28 @@ export class PdsOmnibox extends HTMLElement {
878
884
  return;
879
885
  }
880
886
 
887
+ const blockRect = containingBlock?.getBoundingClientRect?.();
888
+ const originLeft = Number.isFinite(blockRect?.left) ? blockRect.left : 0;
889
+ const originTop = Number.isFinite(blockRect?.top) ? blockRect.top : 0;
890
+ const blockBottom = Number.isFinite(blockRect?.bottom)
891
+ ? blockRect.bottom
892
+ : viewportHeight;
893
+
881
894
  const clampedLeft = Math.max(gap, Math.min(rect.left, viewportWidth - rect.width - gap));
882
895
  const clampedWidth = Math.max(0, Math.min(rect.width, viewportWidth - gap * 2));
883
896
 
884
897
  suggestion.style.position = "fixed";
885
- suggestion.style.left = `${Math.round(clampedLeft)}px`;
898
+ suggestion.style.left = `${Math.round(clampedLeft - originLeft)}px`;
886
899
  suggestion.style.width = `${Math.round(clampedWidth)}px`;
887
900
  suggestion.style.maxWidth = `${Math.round(Math.max(0, viewportWidth - gap * 2))}px`;
888
901
  suggestion.style.right = "auto";
889
902
 
890
903
  if (direction === "up") {
891
904
  suggestion.style.top = "auto";
892
- suggestion.style.bottom = `${Math.round(viewportHeight - rect.top + offset)}px`;
905
+ suggestion.style.bottom = `${Math.round(blockBottom - rect.top + offset)}px`;
893
906
  } else {
894
907
  suggestion.style.bottom = "auto";
895
- suggestion.style.top = `${Math.round(rect.bottom + offset)}px`;
908
+ suggestion.style.top = `${Math.round(rect.bottom - originTop + offset)}px`;
896
909
  }
897
910
 
898
911
  container.setAttribute("data-direction", direction);
@@ -900,6 +913,68 @@ export class PdsOmnibox extends HTMLElement {
900
913
  container.style.setProperty("--ac-max-height", `${maxHeight}px`);
901
914
  }
902
915
 
916
+ #collectClippingAncestors(startNode, stopAt) {
917
+ const targets = [];
918
+ let current = this.#getComposedParent(startNode);
919
+
920
+ while (current instanceof Element) {
921
+ const tagName = String(current.tagName || "").toUpperCase();
922
+ if (tagName === "HTML" || tagName === "BODY") {
923
+ break;
924
+ }
925
+
926
+ const style = getComputedStyle(current);
927
+ const clips = [style.overflow, style.overflowX, style.overflowY].some(
928
+ (value) => value && value !== "visible",
929
+ );
930
+
931
+ if (clips) {
932
+ targets.push(current);
933
+ }
934
+
935
+ if (stopAt && current === stopAt) {
936
+ break;
937
+ }
938
+
939
+ current = this.#getComposedParent(current);
940
+ }
941
+
942
+ return targets;
943
+ }
944
+
945
+ #setOverlayClippingOverride(enabled, stopAt) {
946
+ if (enabled) {
947
+ if (this.#overlayOverflowOverrides.size) {
948
+ return;
949
+ }
950
+
951
+ const startNode = this.#input?.parentElement || this;
952
+ const targets = this.#collectClippingAncestors(startNode, stopAt);
953
+
954
+ targets.forEach((element) => {
955
+ this.#overlayOverflowOverrides.set(element, {
956
+ overflow: element.style.overflow,
957
+ overflowX: element.style.overflowX,
958
+ overflowY: element.style.overflowY,
959
+ });
960
+
961
+ element.style.overflow = "visible";
962
+ element.style.overflowX = "visible";
963
+ element.style.overflowY = "visible";
964
+ });
965
+
966
+ return;
967
+ }
968
+
969
+ this.#overlayOverflowOverrides.forEach((previous, element) => {
970
+ element.style.overflow = previous.overflow;
971
+ element.style.overflowX = previous.overflowX;
972
+ element.style.overflowY = previous.overflowY;
973
+ });
974
+
975
+ this.#overlayOverflowOverrides.clear();
976
+ }
977
+
903
978
  #updateSuggestionMaxHeight() {
904
979
  if (!this.#input) return;
905
980
  const container = this.#input.parentElement;
@@ -908,6 +983,7 @@ export class PdsOmnibox extends HTMLElement {
908
983
  const rect = container.getBoundingClientRect();
909
984
  const viewportHeight = window.visualViewport?.height || window.innerHeight;
910
985
  const gap = this.#readSpacingToken(container, "--ac-viewport-gap") || 0;
986
+ const containingBlock = this.#getFixedContainingBlock(container);
911
987
  const root = container.shadowRoot ?? container;
912
988
  const suggestion = root?.querySelector?.(".ac-suggestion");
913
989
  const currentDirection =
@@ -948,10 +1024,13 @@ export class PdsOmnibox extends HTMLElement {
948
1024
  this.toggleAttribute("data-suggestions-open", Boolean(isSuggestionActive));
949
1025
 
950
1026
  if (!suggestion || !isSuggestionActive || suggestion.classList.contains("full-mobile")) {
1027
+ this.#setOverlayClippingOverride(false);
951
1028
  this.#clearSuggestionOverlayStyles(suggestion);
952
1029
  return;
953
1030
  }
954
1031
 
1032
+ this.#setOverlayClippingOverride(true, containingBlock);
1033
+
955
1034
  if (!this.#shouldUseFixedSuggestionOverlay(container)) {
956
1035
  this.#positionSuggestionInline({
957
1036
  container,
@@ -969,6 +1048,7 @@ export class PdsOmnibox extends HTMLElement {
969
1048
  container,
970
1049
  suggestion,
971
1050
  rect,
1051
+ containingBlock,
972
1052
  viewportHeight,
973
1053
  viewportWidth,
974
1054
  direction,
@@ -1,7 +1,7 @@
1
- function m(o){return new DOMParser().parseFromString(o,"text/html").body.childNodes}function y(o,t=100){let e;return function(...i){let r=()=>{clearTimeout(e),o(...i)};clearTimeout(e),e=setTimeout(r,t)}}function p(o){setTimeout(o,0)}function b(o){try{if(typeof o!="string"||o.indexOf(`
2
- `)!==-1||o.indexOf(" ")!==-1||o.startsWith("#/"))return!1;let t=new URL(o,window.location.origin);return t.protocol==="http:"||t.protocol==="https:"}catch{return!1}}function x(o,t,e){let s=window.screen.width/2-t/2,i=window.screen.height/2-e/2;return window.open(o,"",`toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=yes, width=${t}, height=${e}, top=${i}, left=${s}`)}var g={result:"ac-suggestion",item:"ac-itm"},f=class o 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,p(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 o(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(g.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",y(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=x("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(`.${g.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":p(this.moveResult(1));break;case"ArrowUp":p(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="${`${g.item} cat-${n.category} ${n.class??""}`.trim()}"${n.style?` style="${n.style}"`:""}>
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
4
  ${this.handleImageOrIcon(n)}
5
5
  <span class="text">${this.formatResultItem(n,e,r)}</span>
6
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(m(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=a=>(typeof a=="string"&&(a={text:a}),a),n=a=>i?a.map(h=>({text:h[i]})):a.map(h=>r(h)),u=a=>(this.settings.max&&this.settings.max>0&&(a.length=this.settings.max),a);return this.aborter=new AbortController,this.aborterSignal=this.aborter.signal,new Promise(a=>{let h=l=>{l=this.sort(l,t),this.settings.cache!==!1&&this.caches.set(t.search,l),a(l)};if(b(this.items)){if(this.settings.minlength>0&&(!t.search||t.search.length<this.settings.minlength)){h([]);return}let l=this.formatSearch(this.items,t);fetch(l).then(c=>{if(c.status===200){c.json().then(d=>{d=n(d),h(u(d.filter(w=>this.isMatch(t,w))))});return}throw Error(`HTTP error ${c.status} - ${l}`)})}else if(Array.isArray(this.items)){let l=!0;this.items=this.items.map(c=>typeof c=="string"?{text:c}:(l=!1,c)),l&&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(c=>{c=c.map(d=>r(d)),c=n(c),h(c)});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")))}}};export{f as AutoComplete};
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};
@@ -765,6 +765,16 @@
765
765
  "name": "COMPONENT_TAG",
766
766
  "description": "PdsLiveTemplateCanvas component"
767
767
  },
768
+ {
769
+ "name": "pds-locale",
770
+ "description": "Locale switcher component.\r\n\r\nThe component only persists canonical 5-letter locale tags (`xx-YY`),\r\nfor example `en-US` and `nl-NL`.",
771
+ "attributes": [
772
+ {
773
+ "name": "data-label",
774
+ "description": "Accessible label for the locale radio group."
775
+ }
776
+ ]
777
+ },
768
778
  {
769
779
  "name": "pds-omnibox",
770
780
  "description": "PdsOmnibox component",
package/src/js/pds.js CHANGED
@@ -677,7 +677,7 @@ PDS.loadAutoComplete = async () => {
677
677
  );
678
678
 
679
679
  if (!__autoCompletePromise) {
680
- __autoCompletePromise = import(autoCompleteModuleURL)
680
+ __autoCompletePromise = import(/* @vite-ignore */ autoCompleteModuleURL)
681
681
  .then((mod) => {
682
682
  const autoCompleteCtor =
683
683
  mod?.AutoComplete ||
@@ -978,7 +978,7 @@ async function start(config) {
978
978
  rest?.manager?.url ||
979
979
  new URL("core/pds-manager.js", assetRootURL).href ||
980
980
  new URL("./pds-manager.js", import.meta.url).href;
981
- const { startLive } = await import(managerUrl);
981
+ const { startLive } = await import(/* @vite-ignore */ managerUrl);
982
982
  startResult = await startLive(PDS, rest, {
983
983
  emitReady: __emitPDSReady,
984
984
  emitConfigChanged: __emitPDSConfigChanged,