@pure-ds/core 0.7.4 → 0.7.5

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 (37) hide show
  1. package/.cursorrules +21 -0
  2. package/.github/copilot-instructions.md +21 -0
  3. package/dist/types/src/js/pds-core/pds-start-helpers.d.ts.map +1 -1
  4. package/package.json +8 -2
  5. package/packages/pds-cli/bin/pds-bootstrap.js +1 -1
  6. package/packages/pds-cli/bin/pds-import.js +1 -1
  7. package/packages/pds-cli/bin/pds-mcp-eval.js +79 -0
  8. package/packages/pds-cli/bin/pds-mcp-health.js +128 -0
  9. package/packages/pds-cli/bin/pds-mcp-server.js +140 -0
  10. package/packages/pds-cli/bin/pds-setup-mcp.js +72 -0
  11. package/packages/pds-cli/lib/pds-mcp-core.js +497 -0
  12. package/packages/pds-cli/lib/pds-mcp-eval-cases.json +72 -0
  13. package/public/assets/js/app.js +1582 -4
  14. package/public/assets/js/app.js.map +7 -0
  15. package/public/assets/js/lit.js +1078 -3
  16. package/public/assets/js/lit.js.map +7 -0
  17. package/public/assets/js/pds-ask.js +239 -9
  18. package/public/assets/js/pds-ask.js.map +7 -0
  19. package/public/assets/js/pds-autocomplete.js +590 -7
  20. package/public/assets/js/pds-autocomplete.js.map +7 -0
  21. package/public/assets/js/pds-enhancers.js +689 -1
  22. package/public/assets/js/pds-enhancers.js.map +7 -0
  23. package/public/assets/js/pds-manager.js +15947 -3101
  24. package/public/assets/js/pds-manager.js.map +7 -0
  25. package/public/assets/js/pds-toast.js +30 -1
  26. package/public/assets/js/pds-toast.js.map +7 -0
  27. package/public/assets/js/pds.js +1442 -2
  28. package/public/assets/js/pds.js.map +7 -0
  29. package/public/assets/pds/core/pds-ask.js +239 -9
  30. package/public/assets/pds/core/pds-autocomplete.js +590 -7
  31. package/public/assets/pds/core/pds-enhancers.js +689 -1
  32. package/public/assets/pds/core/pds-manager.js +15947 -3101
  33. package/public/assets/pds/core/pds-toast.js +30 -1
  34. package/public/assets/pds/core.js +1442 -2
  35. package/public/assets/pds/external/lit.js +1078 -3
  36. package/readme.md +44 -2
  37. package/src/js/pds-core/pds-start-helpers.js +0 -20
@@ -1 +1,689 @@
1
- var F=[{selector:".accordion"},{selector:"nav[data-dropdown]"},{selector:"label[data-toggle]"},{selector:"label[data-color]"},{selector:'input[type="range"]'},{selector:"form[data-required]"},{selector:"fieldset[role=group][data-open]"},{selector:"[data-clip]"},{selector:"button, a[class*='btn-']"}];function W(t){t.dataset.enhancedAccordion||(t.dataset.enhancedAccordion="true",t.addEventListener("toggle",e=>{e.target.open&&e.target.parentElement===t&&t.querySelectorAll(":scope > details[open]").forEach(n=>{n!==e.target&&(n.open=!1)})},!0))}function H(t){if(t.dataset.enhancedDropdown)return;t.dataset.enhancedDropdown="true";let e=t.lastElementChild;if(!e)return;let n=t.querySelector("[data-dropdown-toggle]")||t.querySelector("button");n&&!n.hasAttribute("type")&&n.setAttribute("type","button"),e.id||(e.id=`dropdown-${Math.random().toString(36).slice(2,9)}`);let o=e.tagName?.toLowerCase()==="menu",a=8;o&&!e.hasAttribute("role")&&e.setAttribute("role","menu"),e.hasAttribute("aria-hidden")||e.setAttribute("aria-hidden","true"),n&&(n.setAttribute("aria-haspopup","true"),n.setAttribute("aria-controls",e.id),n.setAttribute("aria-expanded","false"));let c=()=>{let s=e.getAttribute("style");e.style.visibility="hidden",e.style.display="inline-block",e.style.pointerEvents="none";let h=e.getBoundingClientRect(),f=Math.max(e.offsetWidth||0,e.scrollWidth||0,h.width||0,1),d=Math.max(e.offsetHeight||0,e.scrollHeight||0,h.height||0,1);return s===null?e.removeAttribute("style"):e.setAttribute("style",s),{width:f,height:d}},i=()=>{let s=(t.getAttribute("data-direction")||t.getAttribute("data-dropdown-direction")||t.getAttribute("data-mode")||"auto").toLowerCase();if(s==="up"||s==="down")return s;let h=(n||t).getBoundingClientRect(),{height:f}=c(),d=Math.max(0,window.innerHeight-h.bottom),b=Math.max(0,h.top),v=d>=f,y=b>=f;return v&&!y?"down":y&&!v?"up":v&&y?"down":b>d?"up":"down"},r=()=>{let s=(t.getAttribute("data-align")||t.getAttribute("data-dropdown-align")||"auto").toLowerCase();if(s==="left"||s==="right"||s==="start"||s==="end")return s==="start"?"left":s==="end"?"right":s;let h=(n||t).getBoundingClientRect(),{width:f}=c(),d=Math.max(0,window.innerWidth-h.left),b=Math.max(0,h.right),v=d>=f,y=b>=f;return v&&!y?"left":y&&!v?"right":v&&y?"left":b>d?"right":"left"},p=(s,h=8)=>{let f=getComputedStyle(t).getPropertyValue(s).trim();if(!f)return h;let d=document.createElement("span");d.style.position="fixed",d.style.visibility="hidden",d.style.pointerEvents="none",d.style.height=f,document.body.appendChild(d);let b=Number.parseFloat(getComputedStyle(d).height);return d.remove(),Number.isFinite(b)?b:h},u=()=>{e.style.removeProperty("position"),e.style.removeProperty("left"),e.style.removeProperty("top"),e.style.removeProperty("right"),e.style.removeProperty("bottom"),e.style.removeProperty("margin-top"),e.style.removeProperty("margin-bottom"),e.style.removeProperty("max-width"),e.style.removeProperty("max-inline-size"),e.style.removeProperty("max-height"),e.style.removeProperty("overflow")},l=()=>{e.getAttribute("aria-hidden")==="false"&&(u(),requestAnimationFrame(()=>{requestAnimationFrame(()=>{w()})}))},w=()=>{if(e.getAttribute("aria-hidden")!=="false")return;let s=(n||t).getBoundingClientRect(),h=window.visualViewport,f=h?.width||document.documentElement?.clientWidth||window.innerWidth,d=h?.height||document.documentElement?.clientHeight||window.innerHeight,b=h?.offsetLeft||0,v=h?.offsetTop||0,y=Math.max(1,f-a*2),T=Math.max(1,d-a*2);e.style.maxWidth=`${Math.round(y)}px`,e.style.maxInlineSize=`${Math.round(y)}px`,e.style.maxHeight=`${Math.round(T)}px`,e.style.overflow="auto";let{width:k,height:M}=c(),q=p("--spacing-2",8),P=i(),R=r();t.dataset.dropdownDirection=P,t.dataset.dropdownAlign=R;let C=R==="right"?s.right-k:s.left;k>=y-1?C=b+a:C=Math.max(b+a,Math.min(C,b+f-k-a));let S=P==="up"?s.top-q-M:s.bottom+q;S=Math.max(v+a,Math.min(S,v+d-M-a)),e.style.position="fixed",e.style.left=`${Math.round(C)}px`,e.style.top=`${Math.round(S)}px`,e.style.right="auto",e.style.bottom="auto",e.style.marginTop="0",e.style.marginBottom="0"},g=null,E=()=>{g||(g=()=>w(),window.addEventListener("resize",g),window.addEventListener("scroll",g,!0))},L=()=>{g&&(window.removeEventListener("resize",g),window.removeEventListener("scroll",g,!0),g=null)},m=null,O=()=>{m||typeof document>"u"||(m=()=>{e.getAttribute("aria-hidden")==="false"&&(t.dataset.dropdownDirection=i(),t.dataset.dropdownAlign=r(),l(),setTimeout(()=>{e.getAttribute("aria-hidden")==="false"&&l()},50),setTimeout(()=>{e.getAttribute("aria-hidden")==="false"&&l()},150))},document.addEventListener("pds:config-changed",m))},D=()=>{!m||typeof document>"u"||(document.removeEventListener("pds:config-changed",m),m=null)},A=null,I=()=>{t.dataset.dropdownDirection=i(),t.dataset.dropdownAlign=r(),e.setAttribute("aria-hidden","false"),n?.setAttribute("aria-expanded","true"),E(),O(),l(),A||(A=s=>{(s.composedPath?s.composedPath():[s.target]).some(d=>d===t)||x()},setTimeout(()=>{document.addEventListener("click",A)},0))},x=()=>{e.setAttribute("aria-hidden","true"),n?.setAttribute("aria-expanded","false"),L(),D(),u(),A&&(document.removeEventListener("click",A),A=null)},B=()=>{e.getAttribute("aria-hidden")==="false"?x():I()};n?.addEventListener("click",s=>{s.preventDefault(),s.stopPropagation(),B()}),t.addEventListener("keydown",s=>{s.key==="Escape"&&(x(),n?.focus())}),t.addEventListener("focusout",s=>{s.relatedTarget&&((s.composedPath?s.composedPath():[s.relatedTarget]).some(d=>d===t)||x())})}function N(t){if(t.dataset.enhancedToggle)return;t.dataset.enhancedToggle="true";let e=t.querySelector('input[type="checkbox"]');if(!e)return;t.hasAttribute("tabindex")||t.setAttribute("tabindex","0"),t.setAttribute("role","switch"),t.setAttribute("aria-checked",e.checked?"true":"false");let n=document.createElement("span");n.className="toggle-switch",n.setAttribute("role","presentation"),n.setAttribute("aria-hidden","true");let o=document.createElement("span");o.className="toggle-knob",n.appendChild(o),t.insertBefore(n,e.nextSibling);let a=()=>{t.setAttribute("aria-checked",e.checked?"true":"false")},c=()=>{e.disabled||(e.checked=!e.checked,a(),e.dispatchEvent(new Event("change",{bubbles:!0})))};t.addEventListener("click",i=>{i.preventDefault(),c()}),t.addEventListener("keydown",i=>{(i.key===" "||i.key==="Enter")&&(i.preventDefault(),c())}),e.addEventListener("change",a)}function $(t){if(t.dataset.enhancedColorInput)return;let e=t.querySelector('input[type="color"]');if(!e)return;t.dataset.enhancedColorInput="true";let n=t.querySelector(":scope > .color-control"),o=t.querySelector(":scope > .color-control > .color-swatch"),a=t.querySelector(":scope > .color-control > output");n||(n=document.createElement("span"),n.className="color-control",e.before(n)),o||(o=document.createElement("span"),o.className="color-swatch",n.appendChild(o)),e.parentElement!==o&&o.appendChild(e),a||(a=document.createElement("output"),n.appendChild(a));let c=()=>{if(e.dataset.colorUnset==="1"){a.value="",a.textContent="not set",n.dataset.value="",n.dataset.unset="1",o.dataset.unset="1";return}a.value=e.value,a.textContent=e.value,n.dataset.value=e.value,delete n.dataset.unset,delete o.dataset.unset};c();let i=()=>{e.dataset.colorUnset==="1"&&(e.dataset.colorUnset="0"),c()};e.addEventListener("input",i,{passive:!0}),e.addEventListener("change",i,{passive:!0})}function U(t){if(t.dataset.enhancedRange)return;let e=i=>{if(t.dataset.enhancedRangeProgrammatic)return;t.dataset.enhancedRangeProgrammatic="1";let r=Object.getOwnPropertyDescriptor(Object.getPrototypeOf(t),"value")||Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,"value");r?.get&&r?.set&&Object.defineProperty(t,"value",{configurable:!0,enumerable:r.enumerable,get(){return r.get.call(this)},set(u){r.set.call(this,u),i()}}),new MutationObserver(u=>{u.some(w=>{let g=w.attributeName;return g==="value"||g==="min"||g==="max"})&&i()}).observe(t,{attributes:!0,attributeFilter:["value","min","max"]})},n=t.closest("label"),o=n?.classList.contains("range-output"),a=t.id||`range-${Math.random().toString(36).substring(2,11)}`,c=`${a}-output`;if(t.id=a,o){let i=n.querySelector("span");if(i&&!i.classList.contains("range-output-wrapper")){let r=document.createElement("span");r.className="range-output-wrapper",r.style.display="flex",r.style.justifyContent="space-between",r.style.alignItems="center";let p=document.createElement("span");p.textContent=i.textContent,r.appendChild(p);let u=document.createElement("output");u.id=c,u.setAttribute("for",a),u.style.color="var(--surface-text-secondary, var(--color-text-secondary))",u.style.fontSize="0.875rem",u.textContent=t.value,r.appendChild(u),i.textContent="",i.appendChild(r);let l=()=>{u.textContent=t.value};t.addEventListener("input",l),t.addEventListener("change",l),e(l),l()}}else{let i=t.closest(".range-container");i||(i=document.createElement("div"),i.className="range-container",t.parentNode?.insertBefore(i,t),i.appendChild(t)),i.style.position="relative";let r=document.createElement("output");r.id=c,r.setAttribute("for",a),r.className="range-bubble",r.setAttribute("aria-live","polite"),i.appendChild(r);let p=()=>{let w=parseFloat(t.min)||0,g=parseFloat(t.max)||100,E=parseFloat(t.value),L=(E-w)/(g-w);r.style.left=`calc(${L*100}% )`,r.textContent=String(E)},u=()=>r.classList.add("visible"),l=()=>r.classList.remove("visible");t.addEventListener("input",p),t.addEventListener("pointerdown",u),t.addEventListener("pointerup",l),t.addEventListener("pointerleave",l),t.addEventListener("focus",u),t.addEventListener("blur",l),t.addEventListener("change",p),e(p),p()}t.dataset.enhancedRange="1"}function z(t){if(t.dataset.enhancedRequired)return;t.dataset.enhancedRequired="true";let e=n=>{let o;if(n.closest("[role$=group]")?o=n.closest("[role$=group]").querySelector("legend"):o=n.closest("label"),!o||o.querySelector(".required-asterisk"))return;let a=document.createElement("span");a.classList.add("required-asterisk"),a.textContent="*",a.style.marginLeft="4px";let c=o.querySelector("span, [data-label]");if(c)c.appendChild(a);else{let r=o.querySelector("input, select, textarea");r?o.insertBefore(a,r):o.appendChild(a)}let i=n.closest("form");if(i&&!i.querySelector(".required-legend")){let r=document.createElement("small");r.classList.add("required-legend"),r.textContent="* Required fields",i.insertBefore(r,i.querySelector(".form-actions")||i.lastElementChild)}};t.querySelectorAll("[required]").forEach(n=>{e(n)})}function j(t){if(t.dataset.enhancedOpenGroup)return;t.dataset.enhancedOpenGroup="true",t.classList.add("flex","flex-wrap","buttons");let e=document.createElement("input");e.type="text",e.placeholder="Add item...",e.classList.add("input-text","input-sm"),e.style.width="auto";let n=()=>t.querySelector('input[type="radio"], input[type="checkbox"]');t.appendChild(e),e.addEventListener("keydown",o=>{if(o.key==="Enter"||o.key==="Tab"){let a=e.value.trim();if(a){o.preventDefault();let c=n(),i=c?.type==="radio"?"radio":"checkbox",r=`open-group-${Math.random().toString(36).substring(2,11)}`,p=document.createElement("label"),u=document.createElement("span");u.setAttribute("data-label",""),u.textContent=a;let l=document.createElement("input");l.type=i,l.name=c?.name||t.getAttribute("data-name")||"open-group",l.value=a,l.id=r,p.appendChild(u),p.appendChild(l),t.insertBefore(p,e),e.value=""}}else if(o.key==="Backspace"&&e.value===""){o.preventDefault();let a=t.querySelectorAll("label");a.length>0&&a[a.length-1].remove()}})}function V(t){if(t.dataset.enhancedClip)return;t.dataset.enhancedClip="true",t.hasAttribute("tabindex")||t.setAttribute("tabindex","0"),t.hasAttribute("role")||t.setAttribute("role","button");let e=()=>{let o=t.getAttribute("data-clip-open")==="true";t.setAttribute("aria-expanded",o?"true":"false")},n=()=>{let o=t.getAttribute("data-clip-open")==="true";t.setAttribute("data-clip-open",o?"false":"true"),e()};t.addEventListener("click",o=>{o.defaultPrevented||n()}),t.addEventListener("keydown",o=>{(o.key===" "||o.key==="Enter")&&(o.preventDefault(),n())}),e()}function G(t){if(t.dataset.enhancedBtnWorking)return;t.dataset.enhancedBtnWorking="true";let e=null,n=!1;new MutationObserver(a=>{a.forEach(c=>{if(c.attributeName==="class"){let i=t.classList.contains("btn-working"),r=t.querySelector("pds-icon");if(i)if(r)e||(e=r.getAttribute("icon")),r.setAttribute("icon","circle-notch");else{let p=document.createElement("pds-icon");p.setAttribute("icon","circle-notch"),p.setAttribute("size","sm"),t.insertBefore(p,t.firstChild),n=!0}else c.oldValue?.includes("btn-working")&&r&&(n?(r.remove(),n=!1):e&&(r.setAttribute("icon",e),e=null))}})}).observe(t,{attributes:!0,attributeFilter:["class"],attributeOldValue:!0})}var _=new Map([[".accordion",W],["nav[data-dropdown]",H],["label[data-toggle]",N],["label[data-color]",$],['input[type="range"]',U],["form[data-required]",z],["fieldset[role=group][data-open]",j],["[data-clip]",V],["button, a[class*='btn-']",G]]),J=F.map(t=>({...t,run:_.get(t.selector)||(()=>{})}));export{J as defaultPDSEnhancers};
1
+ // src/js/pds-core/pds-enhancers.js
2
+ var enhancerDefinitions = [
3
+ { selector: ".accordion" },
4
+ { selector: "nav[data-dropdown]" },
5
+ { selector: "label[data-toggle]" },
6
+ { selector: "label[data-color]" },
7
+ { selector: 'input[type="range"]' },
8
+ { selector: "form[data-required]" },
9
+ { selector: "fieldset[role=group][data-open]" },
10
+ { selector: "[data-clip]" },
11
+ { selector: "button, a[class*='btn-']" }
12
+ ];
13
+ function enhanceAccordion(elem) {
14
+ if (elem.dataset.enhancedAccordion)
15
+ return;
16
+ elem.dataset.enhancedAccordion = "true";
17
+ elem.addEventListener(
18
+ "toggle",
19
+ (event) => {
20
+ if (event.target.open && event.target.parentElement === elem) {
21
+ elem.querySelectorAll(":scope > details[open]").forEach((details) => {
22
+ if (details !== event.target) {
23
+ details.open = false;
24
+ }
25
+ });
26
+ }
27
+ },
28
+ true
29
+ );
30
+ }
31
+ function enhanceDropdown(elem) {
32
+ if (elem.dataset.enhancedDropdown)
33
+ return;
34
+ elem.dataset.enhancedDropdown = "true";
35
+ const menu = elem.lastElementChild;
36
+ if (!menu)
37
+ return;
38
+ const trigger = elem.querySelector("[data-dropdown-toggle]") || elem.querySelector("button");
39
+ if (trigger && !trigger.hasAttribute("type")) {
40
+ trigger.setAttribute("type", "button");
41
+ }
42
+ if (!menu.id) {
43
+ menu.id = `dropdown-${Math.random().toString(36).slice(2, 9)}`;
44
+ }
45
+ const isMenu = menu.tagName?.toLowerCase() === "menu";
46
+ const VIEWPORT_PADDING = 8;
47
+ if (isMenu && !menu.hasAttribute("role")) {
48
+ menu.setAttribute("role", "menu");
49
+ }
50
+ if (!menu.hasAttribute("aria-hidden")) {
51
+ menu.setAttribute("aria-hidden", "true");
52
+ }
53
+ if (trigger) {
54
+ trigger.setAttribute("aria-haspopup", "true");
55
+ trigger.setAttribute("aria-controls", menu.id);
56
+ trigger.setAttribute("aria-expanded", "false");
57
+ }
58
+ const measureMenuSize = () => {
59
+ const previousStyle = menu.getAttribute("style");
60
+ menu.style.visibility = "hidden";
61
+ menu.style.display = "inline-block";
62
+ menu.style.pointerEvents = "none";
63
+ const rect = menu.getBoundingClientRect();
64
+ const width = Math.max(menu.offsetWidth || 0, menu.scrollWidth || 0, rect.width || 0, 1);
65
+ const height = Math.max(
66
+ menu.offsetHeight || 0,
67
+ menu.scrollHeight || 0,
68
+ rect.height || 0,
69
+ 1
70
+ );
71
+ if (previousStyle === null) {
72
+ menu.removeAttribute("style");
73
+ } else {
74
+ menu.setAttribute("style", previousStyle);
75
+ }
76
+ return { width, height };
77
+ };
78
+ const resolveDirection = () => {
79
+ const mode = (elem.getAttribute("data-direction") || elem.getAttribute("data-dropdown-direction") || elem.getAttribute("data-mode") || "auto").toLowerCase();
80
+ if (mode === "up" || mode === "down")
81
+ return mode;
82
+ const anchorRect = (trigger || elem).getBoundingClientRect();
83
+ const { height: menuHeight } = measureMenuSize();
84
+ const spaceBelow = Math.max(0, window.innerHeight - anchorRect.bottom);
85
+ const spaceAbove = Math.max(0, anchorRect.top);
86
+ const fitsDown = spaceBelow >= menuHeight;
87
+ const fitsUp = spaceAbove >= menuHeight;
88
+ if (fitsDown && !fitsUp)
89
+ return "down";
90
+ if (fitsUp && !fitsDown)
91
+ return "up";
92
+ if (fitsDown && fitsUp)
93
+ return "down";
94
+ return spaceAbove > spaceBelow ? "up" : "down";
95
+ };
96
+ const resolveAlign = () => {
97
+ const align = (elem.getAttribute("data-align") || elem.getAttribute("data-dropdown-align") || "auto").toLowerCase();
98
+ if (align === "left" || align === "right" || align === "start" || align === "end") {
99
+ return align === "start" ? "left" : align === "end" ? "right" : align;
100
+ }
101
+ const anchorRect = (trigger || elem).getBoundingClientRect();
102
+ const { width: menuWidth } = measureMenuSize();
103
+ const spaceForLeftAligned = Math.max(0, window.innerWidth - anchorRect.left);
104
+ const spaceForRightAligned = Math.max(0, anchorRect.right);
105
+ const fitsLeft = spaceForLeftAligned >= menuWidth;
106
+ const fitsRight = spaceForRightAligned >= menuWidth;
107
+ if (fitsLeft && !fitsRight)
108
+ return "left";
109
+ if (fitsRight && !fitsLeft)
110
+ return "right";
111
+ if (fitsLeft && fitsRight)
112
+ return "left";
113
+ return spaceForRightAligned > spaceForLeftAligned ? "right" : "left";
114
+ };
115
+ const readLengthToken = (tokenName, fallback = 8) => {
116
+ const raw = getComputedStyle(elem).getPropertyValue(tokenName).trim();
117
+ if (!raw)
118
+ return fallback;
119
+ const probe = document.createElement("span");
120
+ probe.style.position = "fixed";
121
+ probe.style.visibility = "hidden";
122
+ probe.style.pointerEvents = "none";
123
+ probe.style.height = raw;
124
+ document.body.appendChild(probe);
125
+ const parsed = Number.parseFloat(getComputedStyle(probe).height);
126
+ probe.remove();
127
+ return Number.isFinite(parsed) ? parsed : fallback;
128
+ };
129
+ const clearFloatingMenuPosition = () => {
130
+ menu.style.removeProperty("position");
131
+ menu.style.removeProperty("left");
132
+ menu.style.removeProperty("top");
133
+ menu.style.removeProperty("right");
134
+ menu.style.removeProperty("bottom");
135
+ menu.style.removeProperty("margin-top");
136
+ menu.style.removeProperty("margin-bottom");
137
+ menu.style.removeProperty("max-width");
138
+ menu.style.removeProperty("max-inline-size");
139
+ menu.style.removeProperty("max-height");
140
+ menu.style.removeProperty("overflow");
141
+ };
142
+ const reattachFloatingMenu = () => {
143
+ if (menu.getAttribute("aria-hidden") !== "false")
144
+ return;
145
+ clearFloatingMenuPosition();
146
+ requestAnimationFrame(() => {
147
+ requestAnimationFrame(() => {
148
+ positionFloatingMenu();
149
+ });
150
+ });
151
+ };
152
+ const positionFloatingMenu = () => {
153
+ if (menu.getAttribute("aria-hidden") !== "false")
154
+ return;
155
+ const anchorRect = (trigger || elem).getBoundingClientRect();
156
+ const viewport = window.visualViewport;
157
+ const viewportWidth = viewport?.width || document.documentElement?.clientWidth || window.innerWidth;
158
+ const viewportHeight = viewport?.height || document.documentElement?.clientHeight || window.innerHeight;
159
+ const viewportOffsetLeft = viewport?.offsetLeft || 0;
160
+ const viewportOffsetTop = viewport?.offsetTop || 0;
161
+ const maxMenuWidth = Math.max(1, viewportWidth - VIEWPORT_PADDING * 2);
162
+ const maxMenuHeight = Math.max(1, viewportHeight - VIEWPORT_PADDING * 2);
163
+ menu.style.maxWidth = `${Math.round(maxMenuWidth)}px`;
164
+ menu.style.maxInlineSize = `${Math.round(maxMenuWidth)}px`;
165
+ menu.style.maxHeight = `${Math.round(maxMenuHeight)}px`;
166
+ menu.style.overflow = "auto";
167
+ const { width: menuWidth, height: menuHeight } = measureMenuSize();
168
+ const spacing = readLengthToken("--spacing-2", 8);
169
+ const direction = resolveDirection();
170
+ const align = resolveAlign();
171
+ elem.dataset.dropdownDirection = direction;
172
+ elem.dataset.dropdownAlign = align;
173
+ let left = align === "right" ? anchorRect.right - menuWidth : anchorRect.left;
174
+ if (menuWidth >= maxMenuWidth - 1) {
175
+ left = viewportOffsetLeft + VIEWPORT_PADDING;
176
+ } else {
177
+ left = Math.max(
178
+ viewportOffsetLeft + VIEWPORT_PADDING,
179
+ Math.min(
180
+ left,
181
+ viewportOffsetLeft + viewportWidth - menuWidth - VIEWPORT_PADDING
182
+ )
183
+ );
184
+ }
185
+ let top = direction === "up" ? anchorRect.top - spacing - menuHeight : anchorRect.bottom + spacing;
186
+ top = Math.max(
187
+ viewportOffsetTop + VIEWPORT_PADDING,
188
+ Math.min(
189
+ top,
190
+ viewportOffsetTop + viewportHeight - menuHeight - VIEWPORT_PADDING
191
+ )
192
+ );
193
+ menu.style.position = "fixed";
194
+ menu.style.left = `${Math.round(left)}px`;
195
+ menu.style.top = `${Math.round(top)}px`;
196
+ menu.style.right = "auto";
197
+ menu.style.bottom = "auto";
198
+ menu.style.marginTop = "0";
199
+ menu.style.marginBottom = "0";
200
+ };
201
+ let repositionHandler = null;
202
+ const bindReposition = () => {
203
+ if (repositionHandler)
204
+ return;
205
+ repositionHandler = () => positionFloatingMenu();
206
+ window.addEventListener("resize", repositionHandler);
207
+ window.addEventListener("scroll", repositionHandler, true);
208
+ };
209
+ const unbindReposition = () => {
210
+ if (!repositionHandler)
211
+ return;
212
+ window.removeEventListener("resize", repositionHandler);
213
+ window.removeEventListener("scroll", repositionHandler, true);
214
+ repositionHandler = null;
215
+ };
216
+ let configChangedHandler = null;
217
+ const bindConfigChanged = () => {
218
+ if (configChangedHandler || typeof document === "undefined")
219
+ return;
220
+ configChangedHandler = () => {
221
+ if (menu.getAttribute("aria-hidden") !== "false")
222
+ return;
223
+ elem.dataset.dropdownDirection = resolveDirection();
224
+ elem.dataset.dropdownAlign = resolveAlign();
225
+ reattachFloatingMenu();
226
+ setTimeout(() => {
227
+ if (menu.getAttribute("aria-hidden") !== "false")
228
+ return;
229
+ reattachFloatingMenu();
230
+ }, 50);
231
+ setTimeout(() => {
232
+ if (menu.getAttribute("aria-hidden") !== "false")
233
+ return;
234
+ reattachFloatingMenu();
235
+ }, 150);
236
+ };
237
+ document.addEventListener("pds:config-changed", configChangedHandler);
238
+ };
239
+ const unbindConfigChanged = () => {
240
+ if (!configChangedHandler || typeof document === "undefined")
241
+ return;
242
+ document.removeEventListener("pds:config-changed", configChangedHandler);
243
+ configChangedHandler = null;
244
+ };
245
+ let clickHandler = null;
246
+ const openMenu = () => {
247
+ elem.dataset.dropdownDirection = resolveDirection();
248
+ elem.dataset.dropdownAlign = resolveAlign();
249
+ menu.setAttribute("aria-hidden", "false");
250
+ trigger?.setAttribute("aria-expanded", "true");
251
+ bindReposition();
252
+ bindConfigChanged();
253
+ reattachFloatingMenu();
254
+ if (!clickHandler) {
255
+ clickHandler = (event) => {
256
+ const path = event.composedPath ? event.composedPath() : [event.target];
257
+ const clickedInside = path.some((node) => node === elem);
258
+ if (!clickedInside) {
259
+ closeMenu();
260
+ }
261
+ };
262
+ setTimeout(() => {
263
+ document.addEventListener("click", clickHandler);
264
+ }, 0);
265
+ }
266
+ };
267
+ const closeMenu = () => {
268
+ menu.setAttribute("aria-hidden", "true");
269
+ trigger?.setAttribute("aria-expanded", "false");
270
+ unbindReposition();
271
+ unbindConfigChanged();
272
+ clearFloatingMenuPosition();
273
+ if (clickHandler) {
274
+ document.removeEventListener("click", clickHandler);
275
+ clickHandler = null;
276
+ }
277
+ };
278
+ const toggleMenu = () => {
279
+ if (menu.getAttribute("aria-hidden") === "false") {
280
+ closeMenu();
281
+ } else {
282
+ openMenu();
283
+ }
284
+ };
285
+ trigger?.addEventListener("click", (event) => {
286
+ event.preventDefault();
287
+ event.stopPropagation();
288
+ toggleMenu();
289
+ });
290
+ elem.addEventListener("keydown", (event) => {
291
+ if (event.key === "Escape") {
292
+ closeMenu();
293
+ trigger?.focus();
294
+ }
295
+ });
296
+ elem.addEventListener("focusout", (event) => {
297
+ if (event.relatedTarget) {
298
+ const path = event.composedPath ? event.composedPath() : [event.relatedTarget];
299
+ const focusedInside = path.some((node) => node === elem);
300
+ if (!focusedInside) {
301
+ closeMenu();
302
+ }
303
+ }
304
+ });
305
+ }
306
+ function enhanceToggle(elem) {
307
+ if (elem.dataset.enhancedToggle)
308
+ return;
309
+ elem.dataset.enhancedToggle = "true";
310
+ const checkbox = elem.querySelector('input[type="checkbox"]');
311
+ if (!checkbox)
312
+ return;
313
+ if (!elem.hasAttribute("tabindex")) {
314
+ elem.setAttribute("tabindex", "0");
315
+ }
316
+ elem.setAttribute("role", "switch");
317
+ elem.setAttribute("aria-checked", checkbox.checked ? "true" : "false");
318
+ const toggleSwitch = document.createElement("span");
319
+ toggleSwitch.className = "toggle-switch";
320
+ toggleSwitch.setAttribute("role", "presentation");
321
+ toggleSwitch.setAttribute("aria-hidden", "true");
322
+ const knob = document.createElement("span");
323
+ knob.className = "toggle-knob";
324
+ toggleSwitch.appendChild(knob);
325
+ elem.insertBefore(toggleSwitch, checkbox.nextSibling);
326
+ const updateAria = () => {
327
+ elem.setAttribute("aria-checked", checkbox.checked ? "true" : "false");
328
+ };
329
+ const toggle = () => {
330
+ if (checkbox.disabled)
331
+ return;
332
+ checkbox.checked = !checkbox.checked;
333
+ updateAria();
334
+ checkbox.dispatchEvent(new Event("change", { bubbles: true }));
335
+ };
336
+ elem.addEventListener("click", (event) => {
337
+ event.preventDefault();
338
+ toggle();
339
+ });
340
+ elem.addEventListener("keydown", (event) => {
341
+ if (event.key === " " || event.key === "Enter") {
342
+ event.preventDefault();
343
+ toggle();
344
+ }
345
+ });
346
+ checkbox.addEventListener("change", updateAria);
347
+ }
348
+ function enhanceColorInput(elem) {
349
+ if (elem.dataset.enhancedColorInput)
350
+ return;
351
+ const input = elem.querySelector('input[type="color"]');
352
+ if (!input)
353
+ return;
354
+ elem.dataset.enhancedColorInput = "true";
355
+ let control = elem.querySelector(":scope > .color-control");
356
+ let swatch = elem.querySelector(":scope > .color-control > .color-swatch");
357
+ let output = elem.querySelector(":scope > .color-control > output");
358
+ if (!control) {
359
+ control = document.createElement("span");
360
+ control.className = "color-control";
361
+ input.before(control);
362
+ }
363
+ if (!swatch) {
364
+ swatch = document.createElement("span");
365
+ swatch.className = "color-swatch";
366
+ control.appendChild(swatch);
367
+ }
368
+ if (input.parentElement !== swatch) {
369
+ swatch.appendChild(input);
370
+ }
371
+ if (!output) {
372
+ output = document.createElement("output");
373
+ control.appendChild(output);
374
+ }
375
+ const sync = () => {
376
+ const isUnset = input.dataset.colorUnset === "1";
377
+ if (isUnset) {
378
+ output.value = "";
379
+ output.textContent = "not set";
380
+ control.dataset.value = "";
381
+ control.dataset.unset = "1";
382
+ swatch.dataset.unset = "1";
383
+ return;
384
+ }
385
+ output.value = input.value;
386
+ output.textContent = input.value;
387
+ control.dataset.value = input.value;
388
+ delete control.dataset.unset;
389
+ delete swatch.dataset.unset;
390
+ };
391
+ sync();
392
+ const setResolved = () => {
393
+ if (input.dataset.colorUnset === "1") {
394
+ input.dataset.colorUnset = "0";
395
+ }
396
+ sync();
397
+ };
398
+ input.addEventListener("input", setResolved, { passive: true });
399
+ input.addEventListener("change", setResolved, { passive: true });
400
+ }
401
+ function enhanceRange(elem) {
402
+ if (elem.dataset.enhancedRange)
403
+ return;
404
+ const wireProgrammaticUpdates = (updateFn) => {
405
+ if (elem.dataset.enhancedRangeProgrammatic)
406
+ return;
407
+ elem.dataset.enhancedRangeProgrammatic = "1";
408
+ const descriptor = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(elem), "value") || Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value");
409
+ if (descriptor?.get && descriptor?.set) {
410
+ Object.defineProperty(elem, "value", {
411
+ configurable: true,
412
+ enumerable: descriptor.enumerable,
413
+ get() {
414
+ return descriptor.get.call(this);
415
+ },
416
+ set(nextValue) {
417
+ descriptor.set.call(this, nextValue);
418
+ updateFn();
419
+ }
420
+ });
421
+ }
422
+ const attrObserver = new MutationObserver((mutations) => {
423
+ const shouldUpdate = mutations.some((mutation) => {
424
+ const attr = mutation.attributeName;
425
+ return attr === "value" || attr === "min" || attr === "max";
426
+ });
427
+ if (shouldUpdate)
428
+ updateFn();
429
+ });
430
+ attrObserver.observe(elem, {
431
+ attributes: true,
432
+ attributeFilter: ["value", "min", "max"]
433
+ });
434
+ };
435
+ const label = elem.closest("label");
436
+ const hasRangeOutputClass = label?.classList.contains("range-output");
437
+ const inputId = elem.id || `range-${Math.random().toString(36).substring(2, 11)}`;
438
+ const outputId = `${inputId}-output`;
439
+ elem.id = inputId;
440
+ if (hasRangeOutputClass) {
441
+ const labelSpan = label.querySelector("span");
442
+ if (labelSpan && !labelSpan.classList.contains("range-output-wrapper")) {
443
+ const wrapper = document.createElement("span");
444
+ wrapper.className = "range-output-wrapper";
445
+ wrapper.style.display = "flex";
446
+ wrapper.style.justifyContent = "space-between";
447
+ wrapper.style.alignItems = "center";
448
+ const textSpan = document.createElement("span");
449
+ textSpan.textContent = labelSpan.textContent;
450
+ wrapper.appendChild(textSpan);
451
+ const output = document.createElement("output");
452
+ output.id = outputId;
453
+ output.setAttribute("for", inputId);
454
+ output.style.color = "var(--surface-text-secondary, var(--color-text-secondary))";
455
+ output.style.fontSize = "0.875rem";
456
+ output.textContent = elem.value;
457
+ wrapper.appendChild(output);
458
+ labelSpan.textContent = "";
459
+ labelSpan.appendChild(wrapper);
460
+ const updateOutput = () => {
461
+ output.textContent = elem.value;
462
+ };
463
+ elem.addEventListener("input", updateOutput);
464
+ elem.addEventListener("change", updateOutput);
465
+ wireProgrammaticUpdates(updateOutput);
466
+ updateOutput();
467
+ }
468
+ } else {
469
+ let container = elem.closest(".range-container");
470
+ if (!container) {
471
+ container = document.createElement("div");
472
+ container.className = "range-container";
473
+ elem.parentNode?.insertBefore(container, elem);
474
+ container.appendChild(elem);
475
+ }
476
+ container.style.position = "relative";
477
+ const bubble = document.createElement("output");
478
+ bubble.id = outputId;
479
+ bubble.setAttribute("for", inputId);
480
+ bubble.className = "range-bubble";
481
+ bubble.setAttribute("aria-live", "polite");
482
+ container.appendChild(bubble);
483
+ const updateBubble = () => {
484
+ const min = parseFloat(elem.min) || 0;
485
+ const max = parseFloat(elem.max) || 100;
486
+ const value = parseFloat(elem.value);
487
+ const pct = (value - min) / (max - min);
488
+ bubble.style.left = `calc(${pct * 100}% )`;
489
+ bubble.textContent = String(value);
490
+ };
491
+ const show = () => bubble.classList.add("visible");
492
+ const hide = () => bubble.classList.remove("visible");
493
+ elem.addEventListener("input", updateBubble);
494
+ elem.addEventListener("pointerdown", show);
495
+ elem.addEventListener("pointerup", hide);
496
+ elem.addEventListener("pointerleave", hide);
497
+ elem.addEventListener("focus", show);
498
+ elem.addEventListener("blur", hide);
499
+ elem.addEventListener("change", updateBubble);
500
+ wireProgrammaticUpdates(updateBubble);
501
+ updateBubble();
502
+ }
503
+ elem.dataset.enhancedRange = "1";
504
+ }
505
+ function enhanceRequired(elem) {
506
+ if (elem.dataset.enhancedRequired)
507
+ return;
508
+ elem.dataset.enhancedRequired = "true";
509
+ const enhanceRequiredField = (input) => {
510
+ let label;
511
+ if (input.closest("[role$=group]")) {
512
+ label = input.closest("[role$=group]").querySelector("legend");
513
+ } else {
514
+ label = input.closest("label");
515
+ }
516
+ if (!label)
517
+ return;
518
+ if (label.querySelector(".required-asterisk"))
519
+ return;
520
+ const asterisk = document.createElement("span");
521
+ asterisk.classList.add("required-asterisk");
522
+ asterisk.textContent = "*";
523
+ asterisk.style.marginLeft = "4px";
524
+ const labelText = label.querySelector("span, [data-label]");
525
+ if (labelText) {
526
+ labelText.appendChild(asterisk);
527
+ } else {
528
+ const field = label.querySelector("input, select, textarea");
529
+ if (field) {
530
+ label.insertBefore(asterisk, field);
531
+ } else {
532
+ label.appendChild(asterisk);
533
+ }
534
+ }
535
+ const form = input.closest("form");
536
+ if (form && !form.querySelector(".required-legend")) {
537
+ const legend = document.createElement("small");
538
+ legend.classList.add("required-legend");
539
+ legend.textContent = "* Required fields";
540
+ form.insertBefore(
541
+ legend,
542
+ form.querySelector(".form-actions") || form.lastElementChild
543
+ );
544
+ }
545
+ };
546
+ elem.querySelectorAll("[required]").forEach((input) => {
547
+ enhanceRequiredField(input);
548
+ });
549
+ }
550
+ function enhanceOpenGroup(elem) {
551
+ if (elem.dataset.enhancedOpenGroup)
552
+ return;
553
+ elem.dataset.enhancedOpenGroup = "true";
554
+ elem.classList.add("flex", "flex-wrap", "buttons");
555
+ const addInput = document.createElement("input");
556
+ addInput.type = "text";
557
+ addInput.placeholder = "Add item...";
558
+ addInput.classList.add("input-text", "input-sm");
559
+ addInput.style.width = "auto";
560
+ const getFirstInput = () => elem.querySelector('input[type="radio"], input[type="checkbox"]');
561
+ elem.appendChild(addInput);
562
+ addInput.addEventListener("keydown", (event) => {
563
+ if (event.key === "Enter" || event.key === "Tab") {
564
+ const value = addInput.value.trim();
565
+ if (value) {
566
+ event.preventDefault();
567
+ const firstInput = getFirstInput();
568
+ const type = firstInput?.type === "radio" ? "radio" : "checkbox";
569
+ const id = `open-group-${Math.random().toString(36).substring(2, 11)}`;
570
+ const label = document.createElement("label");
571
+ const span = document.createElement("span");
572
+ span.setAttribute("data-label", "");
573
+ span.textContent = value;
574
+ const input = document.createElement("input");
575
+ input.type = type;
576
+ input.name = firstInput?.name || elem.getAttribute("data-name") || "open-group";
577
+ input.value = value;
578
+ input.id = id;
579
+ label.appendChild(span);
580
+ label.appendChild(input);
581
+ elem.insertBefore(label, addInput);
582
+ addInput.value = "";
583
+ }
584
+ } else if (event.key === "Backspace" && addInput.value === "") {
585
+ event.preventDefault();
586
+ const labels = elem.querySelectorAll("label");
587
+ if (labels.length > 0) {
588
+ const lastLabel = labels[labels.length - 1];
589
+ lastLabel.remove();
590
+ }
591
+ }
592
+ });
593
+ }
594
+ function enhanceClip(elem) {
595
+ if (elem.dataset.enhancedClip)
596
+ return;
597
+ elem.dataset.enhancedClip = "true";
598
+ if (!elem.hasAttribute("tabindex")) {
599
+ elem.setAttribute("tabindex", "0");
600
+ }
601
+ if (!elem.hasAttribute("role")) {
602
+ elem.setAttribute("role", "button");
603
+ }
604
+ const syncAria = () => {
605
+ const isOpen = elem.getAttribute("data-clip-open") === "true";
606
+ elem.setAttribute("aria-expanded", isOpen ? "true" : "false");
607
+ };
608
+ const toggleOpen = () => {
609
+ const isOpen = elem.getAttribute("data-clip-open") === "true";
610
+ elem.setAttribute("data-clip-open", isOpen ? "false" : "true");
611
+ syncAria();
612
+ };
613
+ elem.addEventListener("click", (event) => {
614
+ if (event.defaultPrevented)
615
+ return;
616
+ toggleOpen();
617
+ });
618
+ elem.addEventListener("keydown", (event) => {
619
+ if (event.key === " " || event.key === "Enter") {
620
+ event.preventDefault();
621
+ toggleOpen();
622
+ }
623
+ });
624
+ syncAria();
625
+ }
626
+ function enhanceButtonWorking(elem) {
627
+ if (elem.dataset.enhancedBtnWorking)
628
+ return;
629
+ elem.dataset.enhancedBtnWorking = "true";
630
+ let originalIcon = null;
631
+ let addedIcon = false;
632
+ const observer = new MutationObserver((mutations) => {
633
+ mutations.forEach((mutation) => {
634
+ if (mutation.attributeName === "class") {
635
+ const hasWorking = elem.classList.contains("btn-working");
636
+ const icon = elem.querySelector("pds-icon");
637
+ if (hasWorking) {
638
+ if (icon) {
639
+ if (!originalIcon) {
640
+ originalIcon = icon.getAttribute("icon");
641
+ }
642
+ icon.setAttribute("icon", "circle-notch");
643
+ } else {
644
+ const newIcon = document.createElement("pds-icon");
645
+ newIcon.setAttribute("icon", "circle-notch");
646
+ newIcon.setAttribute("size", "sm");
647
+ elem.insertBefore(newIcon, elem.firstChild);
648
+ addedIcon = true;
649
+ }
650
+ } else if (mutation.oldValue?.includes("btn-working")) {
651
+ if (icon) {
652
+ if (addedIcon) {
653
+ icon.remove();
654
+ addedIcon = false;
655
+ } else if (originalIcon) {
656
+ icon.setAttribute("icon", originalIcon);
657
+ originalIcon = null;
658
+ }
659
+ }
660
+ }
661
+ }
662
+ });
663
+ });
664
+ observer.observe(elem, {
665
+ attributes: true,
666
+ attributeFilter: ["class"],
667
+ attributeOldValue: true
668
+ });
669
+ }
670
+ var enhancerRunners = /* @__PURE__ */ new Map([
671
+ [".accordion", enhanceAccordion],
672
+ ["nav[data-dropdown]", enhanceDropdown],
673
+ ["label[data-toggle]", enhanceToggle],
674
+ ["label[data-color]", enhanceColorInput],
675
+ ['input[type="range"]', enhanceRange],
676
+ ["form[data-required]", enhanceRequired],
677
+ ["fieldset[role=group][data-open]", enhanceOpenGroup],
678
+ ["[data-clip]", enhanceClip],
679
+ ["button, a[class*='btn-']", enhanceButtonWorking]
680
+ ]);
681
+ var defaultPDSEnhancers = enhancerDefinitions.map((meta) => ({
682
+ ...meta,
683
+ run: enhancerRunners.get(meta.selector) || (() => {
684
+ })
685
+ }));
686
+ export {
687
+ defaultPDSEnhancers
688
+ };
689
+ //# sourceMappingURL=pds-enhancers.js.map