@pure-ds/core 0.7.1 → 0.7.3

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 (44) hide show
  1. package/.cursorrules +38 -1
  2. package/.github/copilot-instructions.md +32 -0
  3. package/custom-elements.json +77 -46
  4. package/dist/types/public/assets/js/pds-manager.d.ts +1 -1
  5. package/dist/types/public/assets/js/pds-manager.d.ts.map +1 -1
  6. package/dist/types/public/assets/js/pds.d.ts.map +1 -1
  7. package/dist/types/src/js/pds-core/pds-live.d.ts.map +1 -1
  8. package/dist/types/src/js/pds-core/pds-start-helpers.d.ts.map +1 -1
  9. package/package.json +1 -1
  10. package/packages/pds-cli/bin/pds-static.js +13 -2
  11. package/packages/pds-cli/bin/sync-assets.js +34 -0
  12. package/public/assets/js/app.js +1543 -4
  13. package/public/assets/js/app.js.map +7 -0
  14. package/public/assets/js/lit.js +1078 -3
  15. package/public/assets/js/lit.js.map +7 -0
  16. package/public/assets/js/pds-ask.js +239 -9
  17. package/public/assets/js/pds-ask.js.map +7 -0
  18. package/public/assets/js/pds-auto-definer.js +306 -1
  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 +15914 -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 +1409 -2
  28. package/public/assets/js/pds.js.map +7 -0
  29. package/public/assets/pds/components/pds-scrollrow.js +2 -4
  30. package/public/assets/pds/core/pds-ask.js +239 -9
  31. package/public/assets/pds/core/pds-auto-definer.js +306 -1
  32. package/public/assets/pds/core/pds-autocomplete.js +590 -7
  33. package/public/assets/pds/core/pds-enhancers.js +689 -1
  34. package/public/assets/pds/core/pds-manager.js +15914 -3101
  35. package/public/assets/pds/core/pds-toast.js +30 -1
  36. package/public/assets/pds/core.js +1409 -2
  37. package/public/assets/pds/custom-elements.json +77 -46
  38. package/public/assets/pds/external/lit.js +1078 -3
  39. package/public/assets/pds/pds-css-complete.json +2 -2
  40. package/public/assets/pds/pds.css-data.json +1 -1
  41. package/public/assets/pds/vscode-custom-data.json +5 -13
  42. package/src/js/pds-core/pds-live.js +0 -3
  43. package/src/js/pds-core/pds-start-helpers.js +13 -25
  44. package/src/js/pds.js +0 -4
@@ -1,25 +1,255 @@
1
- function g(n){let e=Array.isArray(n?.strings)?n.strings:[],c=Array.isArray(n?.values)?n.values:[],u=new Set,t=[],f=/(\s)(\.[\w-]+)=\s*$/;for(let r=0;r<e.length;r+=1){let s=e[r]??"",l=s.match(f);if(l&&r<c.length){let d=l[2].slice(1),y=`pds-val-${r}`;s=s.replace(f,`$1data-pds-prop="${d}:${y}"`),u.add(r)}t.push(s),r<c.length&&!u.has(r)&&t.push(`<!--pds-val-${r}-->`)}let m=document.createElement("template");m.innerHTML=t.join("");let a=(r,s)=>{let l=r.parentNode;if(!l)return;if(s==null){l.removeChild(r);return}let p=d=>{if(d!=null){if(d instanceof Node){l.insertBefore(d,r);return}if(Array.isArray(d)){d.forEach(y=>p(y));return}l.insertBefore(document.createTextNode(String(d)),r)}};p(s),l.removeChild(r)},i=document.createTreeWalker(m.content,NodeFilter.SHOW_COMMENT),o=[];for(;i.nextNode();){let r=i.currentNode;r?.nodeValue?.startsWith("pds-val-")&&o.push(r)}return o.forEach(r=>{let s=Number(r.nodeValue.replace("pds-val-",""));a(r,c[s])}),m.content.querySelectorAll("*").forEach(r=>{let s=r.getAttribute("data-pds-prop");if(!s)return;let[l,p]=s.split(":"),d=Number(String(p).replace("pds-val-",""));l&&Number.isInteger(d)&&(r[l]=c[d]),r.removeAttribute("data-pds-prop")}),m.content}function b(n,e){if(e==null)return;if(typeof e=="object"&&Array.isArray(e.strings)&&Array.isArray(e.values)){n.appendChild(g(e));return}if(e instanceof Node){n.appendChild(e);return}if(Array.isArray(e)){e.forEach(u=>b(n,u));return}let c=typeof e=="string"?e:String(e);n.appendChild(document.createTextNode(c))}function A(){let n=navigator.userAgent,e=/Safari/i.test(n),c=/(Chrome|Chromium|CriOS|FxiOS|EdgiOS|OPiOS|Opera)/i.test(n);return e&&!c}function C(n){if(window.matchMedia?.("(prefers-reduced-motion: reduce)").matches)return;let e=window.matchMedia?.("(max-width: 639px)").matches,c=n.classList.contains("dialog-no-scale-animation")?"pds-dialog-fade-enter":e?"pds-dialog-enter-mobile":"pds-dialog-enter";n.style.animation="none",n.offsetWidth,n.style.animation=`${c} var(--transition-normal) ease`,n.addEventListener("animationend",()=>{n.style.animation=""},{once:!0})}function x(n={}){return n?.liquidGlassEffects===!0}async function E(n,e={}){return e={...{title:"Confirm",type:"confirm",buttons:{ok:{name:"OK",primary:!0},cancel:{name:"Cancel",cancel:!0}}},...e},new Promise(u=>{let t=document.createElement("dialog");A()&&t.classList.add("dialog-no-scale-animation"),x(e)&&t.classList.add("liquid-glass"),e.size&&t.classList.add(`dialog-${e.size}`),e.type&&t.classList.add(`dialog-${e.type}`),e.class&&(Array.isArray(e.class)?t.classList.add(...e.class):t.classList.add(e.class)),e.maxHeight&&t.style.setProperty("--dialog-max-height",e.maxHeight);let f=Object.entries(e.buttons).map(([a,i])=>{let o=i.primary?"btn-primary btn-sm":"btn-outline btn-sm";return`<button type="${i.cancel?"button":"submit"}" class="${o}" value="${a}">${i.name}</button>`});if(e.useForm){let a=document.createElement("div");b(a,n);let i=a.querySelector("form");if(i){t.innerHTML=`
1
+ // src/js/common/common.js
2
+ function fragmentFromTemplateLike(templateLike) {
3
+ const strings = Array.isArray(templateLike?.strings) ? templateLike.strings : [];
4
+ const values = Array.isArray(templateLike?.values) ? templateLike.values : [];
5
+ const consumedValues = /* @__PURE__ */ new Set();
6
+ const htmlParts = [];
7
+ const propBindingPattern = /(\s)(\.[\w-]+)=\s*$/;
8
+ for (let i = 0; i < strings.length; i += 1) {
9
+ let chunk = strings[i] ?? "";
10
+ const match = chunk.match(propBindingPattern);
11
+ if (match && i < values.length) {
12
+ const propToken = match[2];
13
+ const propName = propToken.slice(1);
14
+ const marker = `pds-val-${i}`;
15
+ chunk = chunk.replace(
16
+ propBindingPattern,
17
+ `$1data-pds-prop="${propName}:${marker}"`
18
+ );
19
+ consumedValues.add(i);
20
+ }
21
+ htmlParts.push(chunk);
22
+ if (i < values.length && !consumedValues.has(i)) {
23
+ htmlParts.push(`<!--pds-val-${i}-->`);
24
+ }
25
+ }
26
+ const tpl = document.createElement("template");
27
+ tpl.innerHTML = htmlParts.join("");
28
+ const replaceValueAtMarker = (markerNode, value) => {
29
+ const parent = markerNode.parentNode;
30
+ if (!parent)
31
+ return;
32
+ if (value == null) {
33
+ parent.removeChild(markerNode);
34
+ return;
35
+ }
36
+ const insertValue = (val) => {
37
+ if (val == null)
38
+ return;
39
+ if (val instanceof Node) {
40
+ parent.insertBefore(val, markerNode);
41
+ return;
42
+ }
43
+ if (Array.isArray(val)) {
44
+ val.forEach((item) => insertValue(item));
45
+ return;
46
+ }
47
+ parent.insertBefore(document.createTextNode(String(val)), markerNode);
48
+ };
49
+ insertValue(value);
50
+ parent.removeChild(markerNode);
51
+ };
52
+ const walker = document.createTreeWalker(tpl.content, NodeFilter.SHOW_COMMENT);
53
+ const markers = [];
54
+ while (walker.nextNode()) {
55
+ const node = walker.currentNode;
56
+ if (node?.nodeValue?.startsWith("pds-val-")) {
57
+ markers.push(node);
58
+ }
59
+ }
60
+ markers.forEach((node) => {
61
+ const index = Number(node.nodeValue.replace("pds-val-", ""));
62
+ replaceValueAtMarker(node, values[index]);
63
+ });
64
+ const elements = tpl.content.querySelectorAll("*");
65
+ elements.forEach((el) => {
66
+ const propAttr = el.getAttribute("data-pds-prop");
67
+ if (!propAttr)
68
+ return;
69
+ const [propName, markerValue] = propAttr.split(":");
70
+ const index = Number(String(markerValue).replace("pds-val-", ""));
71
+ if (propName && Number.isInteger(index)) {
72
+ el[propName] = values[index];
73
+ }
74
+ el.removeAttribute("data-pds-prop");
75
+ });
76
+ return tpl.content;
77
+ }
78
+
79
+ // src/js/common/ask.js
80
+ function appendMessageContent(container, message) {
81
+ if (message == null)
82
+ return;
83
+ if (typeof message === "object" && Array.isArray(message.strings) && Array.isArray(message.values)) {
84
+ container.appendChild(fragmentFromTemplateLike(message));
85
+ return;
86
+ }
87
+ if (message instanceof Node) {
88
+ container.appendChild(message);
89
+ return;
90
+ }
91
+ if (Array.isArray(message)) {
92
+ message.forEach((item) => appendMessageContent(container, item));
93
+ return;
94
+ }
95
+ const text = typeof message === "string" ? message : String(message);
96
+ container.appendChild(document.createTextNode(text));
97
+ }
98
+ function isSafariBrowser() {
99
+ const userAgent = navigator.userAgent;
100
+ const isSafariEngine = /Safari/i.test(userAgent);
101
+ const isOtherBrowser = /(Chrome|Chromium|CriOS|FxiOS|EdgiOS|OPiOS|Opera)/i.test(userAgent);
102
+ return isSafariEngine && !isOtherBrowser;
103
+ }
104
+ function playDialogEnterAnimation(dialog) {
105
+ if (window.matchMedia?.("(prefers-reduced-motion: reduce)").matches) {
106
+ return;
107
+ }
108
+ const isMobile = window.matchMedia?.("(max-width: 639px)").matches;
109
+ const animationName = dialog.classList.contains("dialog-no-scale-animation") ? "pds-dialog-fade-enter" : isMobile ? "pds-dialog-enter-mobile" : "pds-dialog-enter";
110
+ dialog.style.animation = "none";
111
+ void dialog.offsetWidth;
112
+ dialog.style.animation = `${animationName} var(--transition-normal) ease`;
113
+ dialog.addEventListener("animationend", () => {
114
+ dialog.style.animation = "";
115
+ }, { once: true });
116
+ }
117
+ function shouldUseLiquidGlass(options = {}) {
118
+ return options?.liquidGlassEffects === true;
119
+ }
120
+ async function ask(message, options = {}) {
121
+ const defaults = {
122
+ title: "Confirm",
123
+ type: "confirm",
124
+ // 'alert', 'confirm', 'custom'
125
+ buttons: {
126
+ ok: { name: "OK", primary: true },
127
+ cancel: { name: "Cancel", cancel: true }
128
+ }
129
+ };
130
+ options = { ...defaults, ...options };
131
+ return new Promise((resolve) => {
132
+ const dialog = document.createElement("dialog");
133
+ if (isSafariBrowser()) {
134
+ dialog.classList.add("dialog-no-scale-animation");
135
+ }
136
+ if (shouldUseLiquidGlass(options))
137
+ dialog.classList.add("liquid-glass");
138
+ if (options.size) {
139
+ dialog.classList.add(`dialog-${options.size}`);
140
+ }
141
+ if (options.type) {
142
+ dialog.classList.add(`dialog-${options.type}`);
143
+ }
144
+ if (options.class) {
145
+ if (Array.isArray(options.class)) {
146
+ dialog.classList.add(...options.class);
147
+ } else {
148
+ dialog.classList.add(options.class);
149
+ }
150
+ }
151
+ if (options.maxHeight) {
152
+ dialog.style.setProperty("--dialog-max-height", options.maxHeight);
153
+ }
154
+ const buttons = Object.entries(options.buttons).map(([code, obj]) => {
155
+ const btnClass = obj.primary ? "btn-primary btn-sm" : "btn-outline btn-sm";
156
+ const btnType = obj.cancel ? "button" : "submit";
157
+ return `<button type="${btnType}" class="${btnClass}" value="${code}">${obj.name}</button>`;
158
+ });
159
+ if (options.useForm) {
160
+ const tempContainer = document.createElement("div");
161
+ appendMessageContent(tempContainer, message);
162
+ const form = tempContainer.querySelector("form");
163
+ if (form) {
164
+ dialog.innerHTML = /*html*/
165
+ `
2
166
  <header>
3
- <h2>${e.title}</h2>
167
+ <h2>${options.title}</h2>
4
168
  </header>
5
- `;let o=document.createElement("article");for(o.className="dialog-body";i.firstChild;)o.appendChild(i.firstChild);i.appendChild(o);let h=document.createElement("footer");h.innerHTML=f.join(""),i.appendChild(h),t.appendChild(i)}else t.innerHTML=`
169
+ `;
170
+ const article = document.createElement("article");
171
+ article.className = "dialog-body";
172
+ while (form.firstChild) {
173
+ article.appendChild(form.firstChild);
174
+ }
175
+ form.appendChild(article);
176
+ const footer = document.createElement("footer");
177
+ footer.innerHTML = buttons.join("");
178
+ form.appendChild(footer);
179
+ dialog.appendChild(form);
180
+ } else {
181
+ dialog.innerHTML = /*html*/
182
+ `
6
183
  <header>
7
- <h2>${e.title}</h2>
184
+ <h2>${options.title}</h2>
8
185
  </header>
9
186
  <article id="msg-container"></article>
10
187
  <footer>
11
- ${f.join("")}
188
+ ${buttons.join("")}
12
189
  </footer>
13
- `,t.querySelector("#msg-container").appendChild(a)}else{t.innerHTML=`
190
+ `;
191
+ const article = dialog.querySelector("#msg-container");
192
+ article.appendChild(tempContainer);
193
+ }
194
+ } else {
195
+ dialog.innerHTML = /*html*/
196
+ `
14
197
  <form method="dialog">
15
198
  <header>
16
- <h2>${e.title}</h2>
199
+ <h2>${options.title}</h2>
17
200
  </header>
18
201
 
19
202
  <article id="msg-container"></article>
20
203
 
21
204
  <footer>
22
- ${f.join("")}
205
+ ${buttons.join("")}
23
206
  </footer>
24
207
  </form>
25
- `;let a=t.querySelector("#msg-container");b(a,n)}t.addEventListener("click",a=>{a.target.closest('button[value="cancel"]')&&(t.close(),u(!1))});let m=()=>{let a=t.querySelector("form");a?a.addEventListener("submit",i=>{i.preventDefault();let o;e.useForm&&i.submitter.value==="ok"?(console.log("Found form:",a),console.log("Form elements:",a?Array.from(a.elements):"no form"),o=new FormData(a),console.log("FormData entries:",Array.from(o.entries()))):o=i.submitter.value==="ok",t.close(),u(o)}):requestAnimationFrame(m)};m(),t.addEventListener("close",()=>{setTimeout(()=>t.remove(),200)}),document.body.appendChild(t),typeof e.rendered=="function"&&e.rendered(t),t.showModal(),requestAnimationFrame(()=>C(t))})}export{E as ask};
208
+ `;
209
+ const article = dialog.querySelector("#msg-container");
210
+ appendMessageContent(article, message);
211
+ }
212
+ dialog.addEventListener("click", (e) => {
213
+ const btn = e.target.closest('button[value="cancel"]');
214
+ if (btn) {
215
+ dialog.close();
216
+ resolve(false);
217
+ }
218
+ });
219
+ const setupFormListener = () => {
220
+ const form = dialog.querySelector("form");
221
+ if (form) {
222
+ form.addEventListener("submit", (event) => {
223
+ event.preventDefault();
224
+ let result;
225
+ if (options.useForm && event.submitter.value === "ok") {
226
+ console.log("Found form:", form);
227
+ console.log("Form elements:", form ? Array.from(form.elements) : "no form");
228
+ result = new FormData(form);
229
+ console.log("FormData entries:", Array.from(result.entries()));
230
+ } else {
231
+ result = event.submitter.value === "ok";
232
+ }
233
+ dialog.close();
234
+ resolve(result);
235
+ });
236
+ } else {
237
+ requestAnimationFrame(setupFormListener);
238
+ }
239
+ };
240
+ setupFormListener();
241
+ dialog.addEventListener("close", () => {
242
+ setTimeout(() => dialog.remove(), 200);
243
+ });
244
+ document.body.appendChild(dialog);
245
+ if (typeof options.rendered === "function") {
246
+ options.rendered(dialog);
247
+ }
248
+ dialog.showModal();
249
+ requestAnimationFrame(() => playDialogEnterAnimation(dialog));
250
+ });
251
+ }
252
+ export {
253
+ ask
254
+ };
255
+ //# sourceMappingURL=pds-ask.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/js/common/common.js", "../../../src/js/common/ask.js"],
4
+ "sourcesContent": ["export function isObject(item) {\n return item && typeof item === 'object' && !Array.isArray(item);\n}\n\nexport function deepMerge(target, source) {\n const output = { ...target };\n if (isObject(target) && isObject(source)) {\n Object.keys(source).forEach(key => {\n if (isObject(source[key])) {\n if (!(key in target))\n Object.assign(output, { [key]: source[key] });\n else\n output[key] = deepMerge(target[key], source[key]);\n } else {\n Object.assign(output, { [key]: source[key] });\n }\n });\n }\n return output;\n }\n\n/**\n * Build a DocumentFragment from a template-like object (strings + values)\n * @param {{strings: string[], values: unknown[]}} templateLike\n * @returns {DocumentFragment}\n */\nexport function fragmentFromTemplateLike(templateLike) {\n const strings = Array.isArray(templateLike?.strings) ? templateLike.strings : [];\n const values = Array.isArray(templateLike?.values) ? templateLike.values : [];\n const consumedValues = new Set();\n const htmlParts = [];\n\n const propBindingPattern = /(\\s)(\\.[\\w-]+)=\\s*$/;\n\n for (let i = 0; i < strings.length; i += 1) {\n let chunk = strings[i] ?? \"\";\n const match = chunk.match(propBindingPattern);\n\n if (match && i < values.length) {\n const propToken = match[2];\n const propName = propToken.slice(1);\n const marker = `pds-val-${i}`;\n chunk = chunk.replace(\n propBindingPattern,\n `$1data-pds-prop=\"${propName}:${marker}\"`\n );\n consumedValues.add(i);\n }\n\n htmlParts.push(chunk);\n\n if (i < values.length && !consumedValues.has(i)) {\n htmlParts.push(`<!--pds-val-${i}-->`);\n }\n }\n\n const tpl = document.createElement(\"template\");\n tpl.innerHTML = htmlParts.join(\"\");\n\n const replaceValueAtMarker = (markerNode, value) => {\n const parent = markerNode.parentNode;\n if (!parent) return;\n\n if (value == null) {\n parent.removeChild(markerNode);\n return;\n }\n\n const insertValue = (val) => {\n if (val == null) return;\n if (val instanceof Node) {\n parent.insertBefore(val, markerNode);\n return;\n }\n if (Array.isArray(val)) {\n val.forEach((item) => insertValue(item));\n return;\n }\n parent.insertBefore(document.createTextNode(String(val)), markerNode);\n };\n\n insertValue(value);\n parent.removeChild(markerNode);\n };\n\n const walker = document.createTreeWalker(tpl.content, NodeFilter.SHOW_COMMENT);\n const markers = [];\n while (walker.nextNode()) {\n const node = walker.currentNode;\n if (node?.nodeValue?.startsWith(\"pds-val-\")) {\n markers.push(node);\n }\n }\n\n markers.forEach((node) => {\n const index = Number(node.nodeValue.replace(\"pds-val-\", \"\"));\n replaceValueAtMarker(node, values[index]);\n });\n\n const elements = tpl.content.querySelectorAll(\"*\");\n elements.forEach((el) => {\n const propAttr = el.getAttribute(\"data-pds-prop\");\n if (!propAttr) return;\n const [propName, markerValue] = propAttr.split(\":\");\n const index = Number(String(markerValue).replace(\"pds-val-\", \"\"));\n if (propName && Number.isInteger(index)) {\n el[propName] = values[index];\n }\n el.removeAttribute(\"data-pds-prop\");\n });\n\n return tpl.content;\n}\n\n/**\n * Parses an HTML string into a NodeList\n * @param {String} html\n * @returns {NodeListOf<ChildNode>}\n */\nexport function parseHTML(html) {\n return new DOMParser().parseFromString(html, \"text/html\").body.childNodes;\n}", "import { fragmentFromTemplateLike } from \"./common.js\";\r\n\r\n/**\r\n * Get the current page title for dialogs\r\n */\r\nfunction getPageTitle() {\r\n return document.title || \r\n document.querySelector('h1')?.textContent || \r\n 'Application';\r\n}\r\n\r\n/**\r\n * Append message content using vanilla DOM APIs\r\n * @param {HTMLElement} container\r\n * @param {unknown} message\r\n */\r\nfunction appendMessageContent(container, message) {\r\n if (message == null) return;\r\n\r\n if (\r\n typeof message === \"object\" &&\r\n Array.isArray(message.strings) &&\r\n Array.isArray(message.values)\r\n ) {\r\n container.appendChild(fragmentFromTemplateLike(message));\r\n return;\r\n }\r\n\r\n if (message instanceof Node) {\r\n container.appendChild(message);\r\n return;\r\n }\r\n\r\n if (Array.isArray(message)) {\r\n message.forEach((item) => appendMessageContent(container, item));\r\n return;\r\n }\r\n\r\n const text = typeof message === \"string\" ? message : String(message);\r\n container.appendChild(document.createTextNode(text));\r\n}\r\n\r\nfunction isSafariBrowser() {\r\n const userAgent = navigator.userAgent;\r\n const isSafariEngine = /Safari/i.test(userAgent);\r\n const isOtherBrowser = /(Chrome|Chromium|CriOS|FxiOS|EdgiOS|OPiOS|Opera)/i.test(userAgent);\r\n return isSafariEngine && !isOtherBrowser;\r\n}\r\n\r\nfunction playDialogEnterAnimation(dialog) {\r\n if (window.matchMedia?.('(prefers-reduced-motion: reduce)').matches) {\r\n return;\r\n }\r\n\r\n const isMobile = window.matchMedia?.('(max-width: 639px)').matches;\r\n const animationName = dialog.classList.contains('dialog-no-scale-animation')\r\n ? 'pds-dialog-fade-enter'\r\n : isMobile\r\n ? 'pds-dialog-enter-mobile'\r\n : 'pds-dialog-enter';\r\n\r\n dialog.style.animation = 'none';\r\n void dialog.offsetWidth;\r\n dialog.style.animation = `${animationName} var(--transition-normal) ease`;\r\n\r\n dialog.addEventListener('animationend', () => {\r\n dialog.style.animation = '';\r\n }, { once: true });\r\n}\r\n\r\nfunction shouldUseLiquidGlass(options = {}) {\r\n return options?.liquidGlassEffects === true;\r\n}\r\n\r\n/**\r\n * Create a PDS-compliant dialog with proper semantic structure\r\n * @param {string|Node|Array} message - Message content (string or DOM nodes)\r\n * @param {Object} options - Dialog options\r\n * @returns {Promise} Resolves with result when dialog closes\r\n */\r\nexport async function ask(message, options = {}) {\r\n \r\n const defaults = {\r\n title: \"Confirm\",\r\n type: \"confirm\", // 'alert', 'confirm', 'custom'\r\n buttons: {\r\n ok: { name: \"OK\", primary: true },\r\n cancel: { name: \"Cancel\", cancel: true },\r\n },\r\n };\r\n \r\n options = { ...defaults, ...options };\r\n \r\n return new Promise((resolve) => {\r\n // Create native dialog element\r\n const dialog = document.createElement(\"dialog\");\r\n\r\n if (isSafariBrowser()) {\r\n dialog.classList.add(\"dialog-no-scale-animation\");\r\n }\r\n \r\n if (shouldUseLiquidGlass(options))\r\n dialog.classList.add(\"liquid-glass\");\r\n \r\n // Add optional CSS classes\r\n if (options.size) {\r\n dialog.classList.add(`dialog-${options.size}`); // dialog-sm, dialog-lg, dialog-xl\r\n }\r\n if (options.type) {\r\n dialog.classList.add(`dialog-${options.type}`);\r\n }\r\n if (options.class) {\r\n if (Array.isArray(options.class)) {\r\n dialog.classList.add(...options.class);\r\n } else {\r\n dialog.classList.add(options.class);\r\n }\r\n }\r\n \r\n // Set maxHeight via CSS custom property (constrained to 90vh by default)\r\n if (options.maxHeight) {\r\n dialog.style.setProperty('--dialog-max-height', options.maxHeight);\r\n }\r\n\r\n // Build button elements\r\n const buttons = Object.entries(options.buttons).map(([code, obj]) => {\r\n const btnClass = obj.primary ? \"btn-primary btn-sm\" : \"btn-outline btn-sm\";\r\n const btnType = obj.cancel ? \"button\" : \"submit\";\r\n return `<button type=\"${btnType}\" class=\"${btnClass}\" value=\"${code}\">${obj.name}</button>`;\r\n });\r\n\r\n // Create PDS-compliant dialog structure\r\n // When useForm is true, don't wrap in a form - let the content provide the form\r\n if (options.useForm) {\r\n // Create a temporary container to render the message content\r\n const tempContainer = document.createElement(\"div\");\r\n appendMessageContent(tempContainer, message);\r\n \r\n // Find the form in the rendered content\r\n const form = tempContainer.querySelector(\"form\");\r\n if (form) {\r\n // Build dialog structure with form as direct child for proper flex layout\r\n dialog.innerHTML = /*html*/ `\r\n <header>\r\n <h2>${options.title}</h2>\r\n </header>\r\n `;\r\n \r\n // Create article wrapper and move form children into it (preserves DOM nodes & bindings)\r\n const article = document.createElement(\"article\");\r\n article.className = \"dialog-body\";\r\n while (form.firstChild) {\r\n article.appendChild(form.firstChild);\r\n }\r\n form.appendChild(article);\r\n \r\n // Add footer with buttons\r\n const footer = document.createElement(\"footer\");\r\n footer.innerHTML = buttons.join(\"\");\r\n form.appendChild(footer);\r\n \r\n // Append the restructured form to dialog\r\n dialog.appendChild(form);\r\n } else {\r\n // No form found, use standard article structure\r\n dialog.innerHTML = /*html*/ `\r\n <header>\r\n <h2>${options.title}</h2>\r\n </header>\r\n <article id=\"msg-container\"></article>\r\n <footer>\r\n ${buttons.join(\"\")}\r\n </footer>\r\n `;\r\n const article = dialog.querySelector(\"#msg-container\");\r\n article.appendChild(tempContainer);\r\n }\r\n } else {\r\n dialog.innerHTML = /*html*/ `\r\n <form method=\"dialog\">\r\n <header>\r\n <h2>${options.title}</h2>\r\n </header>\r\n \r\n <article id=\"msg-container\"></article>\r\n \r\n <footer>\r\n ${buttons.join(\"\")}\r\n </footer>\r\n </form>\r\n `;\r\n\r\n // Render message content\r\n const article = dialog.querySelector(\"#msg-container\");\r\n appendMessageContent(article, message);\r\n }\r\n\r\n // Handle cancel button clicks\r\n dialog.addEventListener(\"click\", (e) => {\r\n const btn = e.target.closest('button[value=\"cancel\"]');\r\n if (btn) {\r\n dialog.close();\r\n resolve(false);\r\n }\r\n });\r\n\r\n // Wait for form to exist before adding submit listener\r\n const setupFormListener = () => {\r\n const form = dialog.querySelector(\"form\");\r\n if (form) {\r\n form.addEventListener(\"submit\", (event) => {\r\n event.preventDefault();\r\n \r\n let result;\r\n if (options.useForm && event.submitter.value === \"ok\") {\r\n console.log(\"Found form:\", form);\r\n console.log(\"Form elements:\", form ? Array.from(form.elements) : \"no form\");\r\n result = new FormData(form);\r\n console.log(\"FormData entries:\", Array.from(result.entries()));\r\n } else {\r\n result = (event.submitter.value === \"ok\");\r\n }\r\n\r\n dialog.close();\r\n resolve(result);\r\n });\r\n } else {\r\n // Form doesn't exist yet, wait and try again\r\n requestAnimationFrame(setupFormListener);\r\n }\r\n };\r\n \r\n setupFormListener();\r\n\r\n // Handle dialog close event\r\n dialog.addEventListener(\"close\", () => {\r\n // Small delay to allow exit animation\r\n setTimeout(() => dialog.remove(), 200);\r\n });\r\n\r\n // Append to body and show\r\n document.body.appendChild(dialog);\r\n\r\n // Call optional rendered callback\r\n if (typeof options.rendered === \"function\") {\r\n options.rendered(dialog);\r\n }\r\n\r\n // Show the dialog as modal\r\n dialog.showModal();\r\n\r\n requestAnimationFrame(() => playDialogEnterAnimation(dialog));\r\n });\r\n}\r\n\r\n/**\r\n * Show an alert dialog\r\n * @param {string|Node|Array} message - Alert message\r\n * @param {Object} options - Optional dialog options\r\n * @returns {Promise}\r\n */\r\nexport async function alert(message, options = {}) {\r\n const defaults = {\r\n title: getPageTitle(),\r\n type: \"alert\",\r\n buttons: {\r\n ok: { name: \"OK\", primary: true },\r\n },\r\n };\r\n\r\n return ask(message, { ...defaults, ...options });\r\n}\r\n\r\n/**\r\n * Show a confirmation dialog\r\n * @param {string|Node|Array} message - Confirmation message\r\n * @param {Object} options - Optional dialog options\r\n * @returns {Promise<boolean>}\r\n */\r\nexport async function confirm(message, options = {}) {\r\n const defaults = {\r\n title: \"Confirm Action\",\r\n type: \"confirm\",\r\n buttons: {\r\n ok: { name: \"Confirm\", primary: true },\r\n cancel: { name: \"Cancel\", cancel: true },\r\n },\r\n };\r\n\r\n return ask(message, { ...defaults, ...options });\r\n}\r\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -1 +1,306 @@
1
- async function P(...h){let i={};h.length&&typeof h[h.length-1]=="object"&&(i=h.pop()||{});let m=h,{baseURL:f,mapper:w=n=>`${n}.js`,onError:E=(n,r)=>console.error(`[defineWebComponents] ${n}:`,r)}=i,d=f?new URL(f,typeof location<"u"?location.href:import.meta.url):new URL("./",import.meta.url),l=n=>n.toLowerCase().replace(/(^|-)([a-z])/g,(r,s,u)=>u.toUpperCase()),b=async n=>{try{if(customElements.get(n))return{tag:n,status:"already-defined"};let r=w(n),u=await import(r instanceof URL?r.href:new URL(r,d).href),c=u?.default??u?.[l(n)];if(!c){if(customElements.get(n))return{tag:n,status:"self-defined"};throw new Error(`No export found for ${n}. Expected default export or named export "${l(n)}".`)}return customElements.get(n)?{tag:n,status:"race-already-defined"}:(customElements.define(n,c),{tag:n,status:"defined"})}catch(r){throw E(n,r),r}};return Promise.all(m.map(b))}var M=class{constructor(i={}){let{baseURL:m,mapper:f,onError:w,predicate:E=()=>!0,attributeModule:d="data-module",root:l=document,scanExisting:b=!0,debounceMs:n=16,observeShadows:r=!0,enhancers:s=[],patchAttachShadow:u=!0}=i,c=new Set,y=new Set,$=new Set,S=new Map,U=new WeakMap,v=new WeakMap,p=0,T=!1,x=null,W=e=>{if(!e||!s.length)return;let o=v.get(e);o||(o=new Set,v.set(e,o));for(let t of s)if(!(!t.selector||!t.run)&&!o.has(t.selector))try{e.matches&&e.matches(t.selector)&&(t.run(e),o.add(t.selector))}catch(a){console.warn(`[AutoDefiner] Error applying enhancer for selector "${t.selector}":`,a)}},A=(e,o)=>{if(!T&&!(!e||!e.includes("-"))&&!customElements.get(e)&&!y.has(e)&&!$.has(e)){if(o&&o.getAttribute){let t=o.getAttribute(d);t&&!S.has(e)&&S.set(e,t)}c.add(e),O()}},O=()=>{p||(p=setTimeout(N,n))},L=e=>{if(e){if(e.nodeType===1){let o=e,t=o.tagName?.toLowerCase();t&&t.includes("-")&&!customElements.get(t)&&E(t,o)&&A(t,o),W(o),r&&o.shadowRoot&&C(o.shadowRoot)}e.querySelectorAll&&e.querySelectorAll("*").forEach(o=>{let t=o.tagName?.toLowerCase();t&&t.includes("-")&&!customElements.get(t)&&E(t,o)&&A(t,o),W(o),r&&o.shadowRoot&&C(o.shadowRoot)})}},C=e=>{if(!e||U.has(e))return;L(e);let o=new MutationObserver(t=>{for(let a of t)a.addedNodes?.forEach(R=>{L(R)}),a.type==="attributes"&&a.target&&L(a.target)});o.observe(e,{childList:!0,subtree:!0,attributes:!0,attributeFilter:[d,...s.map(t=>t.selector).filter(t=>t.startsWith("data-"))]}),U.set(e,o)};async function N(){if(clearTimeout(p),p=0,!c.size)return;let e=Array.from(c);c.clear(),e.forEach(o=>y.add(o));try{let o=t=>S.get(t)??(f?f(t):`${t}.js`);await P(...e,{baseURL:m,mapper:o,onError:(t,a)=>{$.add(t),w?.(t,a)}})}catch{}finally{e.forEach(o=>y.delete(o))}}let _=l===document?document.documentElement:l,j=new MutationObserver(e=>{for(let o of e)o.addedNodes?.forEach(t=>{L(t)}),o.type==="attributes"&&o.target&&L(o.target)});if(j.observe(_,{childList:!0,subtree:!0,attributes:!0,attributeFilter:[d,...s.map(e=>e.selector).filter(e=>e.startsWith("data-"))]}),r&&u&&Element.prototype.attachShadow){let e=Element.prototype.attachShadow;Element.prototype.attachShadow=function(t){let a=e.call(this,t);if(t&&t.mode==="open"){C(a);let R=this.tagName?.toLowerCase();R&&R.includes("-")&&!customElements.get(R)&&A(R,this)}return a},x=()=>Element.prototype.attachShadow=e}return b&&L(_),{stop(){T=!0,j.disconnect(),x&&x(),p&&(clearTimeout(p),p=0),U.forEach(e=>e.disconnect())},flush:N}}static async define(...i){let m={};i.length&&typeof i[i.length-1]=="object"&&(m=i.pop()||{});let f=i,{baseURL:w,mapper:E=r=>`${r}.js`,onError:d=(r,s)=>console.error(`[defineWebComponents] ${r}:`,s)}=m,l=w?new URL(w,typeof location<"u"?location.href:import.meta.url):new URL("./",import.meta.url),b=r=>r.toLowerCase().replace(/(^|-)([a-z])/g,(s,u,c)=>c.toUpperCase()),n=async r=>{try{if(customElements.get(r))return{tag:r,status:"already-defined"};let s=E(r),c=await import(s instanceof URL?s.href:new URL(s,l).href),y=c?.default??c?.[b(r)];if(!y){if(customElements.get(r))return{tag:r,status:"self-defined"};throw new Error(`No export found for ${r}. Expected default export or named export "${b(r)}".`)}return customElements.get(r)?{tag:r,status:"race-already-defined"}:(customElements.define(r,y),{tag:r,status:"defined"})}catch(s){throw d(r,s),s}};return Promise.all(f.map(n))}};export{M as AutoDefiner};
1
+ // node_modules/pure-web/src/js/auto-definer.js
2
+ async function defineWebComponents(...args) {
3
+ let opts = {};
4
+ if (args.length && typeof args[args.length - 1] === "object") {
5
+ opts = args.pop() || {};
6
+ }
7
+ const tags = args;
8
+ const {
9
+ baseURL,
10
+ mapper = (tag) => `${tag}.js`,
11
+ onError = (tag, err) => console.error(`[defineWebComponents] ${tag}:`, err)
12
+ } = opts;
13
+ const base = baseURL ? new URL(
14
+ baseURL,
15
+ typeof location !== "undefined" ? location.href : import.meta.url
16
+ ) : new URL("./", import.meta.url);
17
+ const toPascal = (tag) => tag.toLowerCase().replace(/(^|-)([a-z])/g, (_, __, c) => c.toUpperCase());
18
+ const loadOne = async (tag) => {
19
+ try {
20
+ if (customElements.get(tag))
21
+ return { tag, status: "already-defined" };
22
+ const spec = mapper(tag);
23
+ const href = spec instanceof URL ? spec.href : new URL(spec, base).href;
24
+ const mod = await import(href);
25
+ const Named = mod?.default ?? mod?.[toPascal(tag)];
26
+ if (!Named) {
27
+ if (customElements.get(tag))
28
+ return { tag, status: "self-defined" };
29
+ throw new Error(
30
+ `No export found for ${tag}. Expected default export or named export "${toPascal(
31
+ tag
32
+ )}".`
33
+ );
34
+ }
35
+ if (!customElements.get(tag)) {
36
+ customElements.define(tag, Named);
37
+ return { tag, status: "defined" };
38
+ }
39
+ return { tag, status: "race-already-defined" };
40
+ } catch (err) {
41
+ onError(tag, err);
42
+ throw err;
43
+ }
44
+ };
45
+ return Promise.all(tags.map(loadOne));
46
+ }
47
+ var AutoDefiner = class {
48
+ constructor(options = {}) {
49
+ const {
50
+ baseURL,
51
+ mapper,
52
+ onError,
53
+ predicate = () => true,
54
+ attributeModule = "data-module",
55
+ root = document,
56
+ scanExisting = true,
57
+ debounceMs = 16,
58
+ observeShadows = true,
59
+ enhancers = [],
60
+ // [{String selector, Function run(elem)}]
61
+ patchAttachShadow = true
62
+ } = options;
63
+ const pending = /* @__PURE__ */ new Set();
64
+ const inFlight = /* @__PURE__ */ new Set();
65
+ const knownMissing = /* @__PURE__ */ new Set();
66
+ const perTagModulePath = /* @__PURE__ */ new Map();
67
+ const shadowObservers = /* @__PURE__ */ new WeakMap();
68
+ const enhancerApplied = /* @__PURE__ */ new WeakMap();
69
+ let timer = 0;
70
+ let stopped = false;
71
+ let restoreAttachShadow = null;
72
+ const applyEnhancers = (element) => {
73
+ if (!element || !enhancers.length)
74
+ return;
75
+ let appliedEnhancers = enhancerApplied.get(element);
76
+ if (!appliedEnhancers) {
77
+ appliedEnhancers = /* @__PURE__ */ new Set();
78
+ enhancerApplied.set(element, appliedEnhancers);
79
+ }
80
+ for (const enhancer of enhancers) {
81
+ if (!enhancer.selector || !enhancer.run)
82
+ continue;
83
+ if (appliedEnhancers.has(enhancer.selector))
84
+ continue;
85
+ try {
86
+ if (element.matches && element.matches(enhancer.selector)) {
87
+ enhancer.run(element);
88
+ appliedEnhancers.add(enhancer.selector);
89
+ }
90
+ } catch (err) {
91
+ console.warn(
92
+ `[AutoDefiner] Error applying enhancer for selector "${enhancer.selector}":`,
93
+ err
94
+ );
95
+ }
96
+ }
97
+ };
98
+ const queueTag = (tag, el) => {
99
+ if (stopped)
100
+ return;
101
+ if (!tag || !tag.includes("-"))
102
+ return;
103
+ if (customElements.get(tag))
104
+ return;
105
+ if (inFlight.has(tag))
106
+ return;
107
+ if (knownMissing.has(tag))
108
+ return;
109
+ if (el && el.getAttribute) {
110
+ const override = el.getAttribute(attributeModule);
111
+ if (override && !perTagModulePath.has(tag)) {
112
+ perTagModulePath.set(tag, override);
113
+ }
114
+ }
115
+ pending.add(tag);
116
+ schedule();
117
+ };
118
+ const schedule = () => {
119
+ if (timer)
120
+ return;
121
+ timer = setTimeout(flush, debounceMs);
122
+ };
123
+ const crawlTree = (rootNode) => {
124
+ if (!rootNode)
125
+ return;
126
+ if (rootNode.nodeType === 1) {
127
+ const el = (
128
+ /** @type {Element} */
129
+ rootNode
130
+ );
131
+ const tag = el.tagName?.toLowerCase();
132
+ if (tag && tag.includes("-") && !customElements.get(tag) && predicate(tag, el)) {
133
+ queueTag(tag, el);
134
+ }
135
+ applyEnhancers(el);
136
+ if (observeShadows && el.shadowRoot) {
137
+ observeShadowRoot(el.shadowRoot);
138
+ }
139
+ }
140
+ if (rootNode.querySelectorAll) {
141
+ rootNode.querySelectorAll("*").forEach((e) => {
142
+ const t = e.tagName?.toLowerCase();
143
+ if (t && t.includes("-") && !customElements.get(t) && predicate(t, e)) {
144
+ queueTag(t, e);
145
+ }
146
+ applyEnhancers(e);
147
+ if (observeShadows && e.shadowRoot) {
148
+ observeShadowRoot(e.shadowRoot);
149
+ }
150
+ });
151
+ }
152
+ };
153
+ const observeShadowRoot = (sr) => {
154
+ if (!sr || shadowObservers.has(sr))
155
+ return;
156
+ crawlTree(sr);
157
+ const mo = new MutationObserver((mutations) => {
158
+ for (const m of mutations) {
159
+ m.addedNodes?.forEach((n) => {
160
+ crawlTree(n);
161
+ });
162
+ if (m.type === "attributes" && m.target) {
163
+ crawlTree(m.target);
164
+ }
165
+ }
166
+ });
167
+ mo.observe(sr, {
168
+ childList: true,
169
+ subtree: true,
170
+ attributes: true,
171
+ attributeFilter: [
172
+ attributeModule,
173
+ ...enhancers.map((e) => e.selector).filter((s) => s.startsWith("data-"))
174
+ ]
175
+ });
176
+ shadowObservers.set(sr, mo);
177
+ };
178
+ async function flush() {
179
+ clearTimeout(timer);
180
+ timer = 0;
181
+ if (!pending.size)
182
+ return;
183
+ const tags = Array.from(pending);
184
+ pending.clear();
185
+ tags.forEach((t) => inFlight.add(t));
186
+ try {
187
+ const effectiveMapper = (tag) => perTagModulePath.get(tag) ?? (mapper ? mapper(tag) : `${tag}.js`);
188
+ await defineWebComponents(...tags, {
189
+ baseURL,
190
+ mapper: effectiveMapper,
191
+ onError: (tag, err) => {
192
+ knownMissing.add(tag);
193
+ onError?.(tag, err);
194
+ }
195
+ });
196
+ } catch {
197
+ } finally {
198
+ tags.forEach((t) => inFlight.delete(t));
199
+ }
200
+ }
201
+ const mountNode = root === document ? document.documentElement : root;
202
+ const obs = new MutationObserver((mutations) => {
203
+ for (const m of mutations) {
204
+ m.addedNodes?.forEach((n) => {
205
+ crawlTree(n);
206
+ });
207
+ if (m.type === "attributes" && m.target) {
208
+ crawlTree(m.target);
209
+ }
210
+ }
211
+ });
212
+ obs.observe(mountNode, {
213
+ childList: true,
214
+ subtree: true,
215
+ attributes: true,
216
+ attributeFilter: [
217
+ attributeModule,
218
+ ...enhancers.map((e) => e.selector).filter((s) => s.startsWith("data-"))
219
+ ]
220
+ });
221
+ if (observeShadows && patchAttachShadow && Element.prototype.attachShadow) {
222
+ const orig = Element.prototype.attachShadow;
223
+ Element.prototype.attachShadow = function patchedAttachShadow(init) {
224
+ const sr = orig.call(this, init);
225
+ if (init && init.mode === "open") {
226
+ observeShadowRoot(sr);
227
+ const tag = this.tagName?.toLowerCase();
228
+ if (tag && tag.includes("-") && !customElements.get(tag)) {
229
+ queueTag(tag, this);
230
+ }
231
+ }
232
+ return sr;
233
+ };
234
+ restoreAttachShadow = () => Element.prototype.attachShadow = orig;
235
+ }
236
+ if (scanExisting) {
237
+ crawlTree(mountNode);
238
+ }
239
+ return {
240
+ stop() {
241
+ stopped = true;
242
+ obs.disconnect();
243
+ if (restoreAttachShadow)
244
+ restoreAttachShadow();
245
+ if (timer) {
246
+ clearTimeout(timer);
247
+ timer = 0;
248
+ }
249
+ shadowObservers.forEach((mo) => mo.disconnect());
250
+ },
251
+ flush
252
+ };
253
+ }
254
+ /**
255
+ * Dynamically load and (idempotently) define a set of web components by tag name.
256
+ */
257
+ static async define(...args) {
258
+ let opts = {};
259
+ if (args.length && typeof args[args.length - 1] === "object") {
260
+ opts = args.pop() || {};
261
+ }
262
+ const tags = args;
263
+ const {
264
+ baseURL,
265
+ mapper = (tag) => `${tag}.js`,
266
+ onError = (tag, err) => console.error(`[defineWebComponents] ${tag}:`, err)
267
+ } = opts;
268
+ const base = baseURL ? new URL(
269
+ baseURL,
270
+ typeof location !== "undefined" ? location.href : import.meta.url
271
+ ) : new URL("./", import.meta.url);
272
+ const toPascal = (tag) => tag.toLowerCase().replace(/(^|-)([a-z])/g, (_, __, c) => c.toUpperCase());
273
+ const loadOne = async (tag) => {
274
+ try {
275
+ if (customElements.get(tag))
276
+ return { tag, status: "already-defined" };
277
+ const spec = mapper(tag);
278
+ const href = spec instanceof URL ? spec.href : new URL(spec, base).href;
279
+ const mod = await import(href);
280
+ const Named = mod?.default ?? mod?.[toPascal(tag)];
281
+ if (!Named) {
282
+ if (customElements.get(tag))
283
+ return { tag, status: "self-defined" };
284
+ throw new Error(
285
+ `No export found for ${tag}. Expected default export or named export "${toPascal(
286
+ tag
287
+ )}".`
288
+ );
289
+ }
290
+ if (!customElements.get(tag)) {
291
+ customElements.define(tag, Named);
292
+ return { tag, status: "defined" };
293
+ }
294
+ return { tag, status: "race-already-defined" };
295
+ } catch (err) {
296
+ onError(tag, err);
297
+ throw err;
298
+ }
299
+ };
300
+ return Promise.all(tags.map(loadOne));
301
+ }
302
+ };
303
+ export {
304
+ AutoDefiner
305
+ };
306
+ //# sourceMappingURL=pds-auto-definer.js.map