@pure-ds/core 0.7.24 → 0.7.26

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 (39) hide show
  1. package/.cursorrules +12 -1
  2. package/.github/copilot-instructions.md +12 -1
  3. package/custom-elements.json +1099 -74
  4. package/dist/types/public/assets/js/pds-ask.d.ts +2 -2
  5. package/dist/types/public/assets/js/pds-ask.d.ts.map +1 -1
  6. package/dist/types/public/assets/js/pds-manager.d.ts +4 -4
  7. package/dist/types/public/assets/js/pds-manager.d.ts.map +1 -1
  8. package/dist/types/public/assets/pds/components/pds-daterange.d.ts +2 -0
  9. package/dist/types/public/assets/pds/components/pds-daterange.d.ts.map +1 -0
  10. package/dist/types/public/assets/pds/components/pds-form.d.ts.map +1 -1
  11. package/dist/types/public/assets/pds/components/pds-rating.d.ts +120 -0
  12. package/dist/types/public/assets/pds/components/pds-rating.d.ts.map +1 -0
  13. package/dist/types/public/assets/pds/components/pds-tags.d.ts +2 -0
  14. package/dist/types/public/assets/pds/components/pds-tags.d.ts.map +1 -0
  15. package/dist/types/public/assets/pds/components/pds-toaster.d.ts +3 -0
  16. package/dist/types/public/assets/pds/components/pds-toaster.d.ts.map +1 -1
  17. package/dist/types/src/js/common/ask.d.ts.map +1 -1
  18. package/dist/types/src/js/pds-core/pds-generator.d.ts.map +1 -1
  19. package/dist/types/src/js/pds-core/pds-live.d.ts.map +1 -1
  20. package/package.json +2 -2
  21. package/packages/pds-cli/bin/templates/bootstrap/pds.config.js +14 -4
  22. package/public/assets/js/app.js +1 -1
  23. package/public/assets/js/pds-ask.js +6 -6
  24. package/public/assets/js/pds-manager.js +115 -40
  25. package/public/assets/pds/components/pds-calendar.js +91 -159
  26. package/public/assets/pds/components/pds-daterange.js +683 -0
  27. package/public/assets/pds/components/pds-form.js +123 -21
  28. package/public/assets/pds/components/pds-rating.js +648 -0
  29. package/public/assets/pds/components/pds-tags.js +802 -0
  30. package/public/assets/pds/components/pds-toaster.js +35 -1
  31. package/public/assets/pds/core/pds-ask.js +6 -6
  32. package/public/assets/pds/core/pds-manager.js +115 -40
  33. package/public/assets/pds/custom-elements.json +1099 -74
  34. package/public/assets/pds/pds-css-complete.json +7 -2
  35. package/public/assets/pds/pds.css-data.json +4 -4
  36. package/public/assets/pds/vscode-custom-data.json +97 -0
  37. package/src/js/pds-core/pds-generator.js +104 -29
  38. package/src/js/pds-core/pds-live.js +5 -0
  39. package/src/js/pds-core/pds-ontology.js +2 -2
@@ -24,6 +24,9 @@ export class AppToaster extends HTMLElement {
24
24
  constructor() {
25
25
  super();
26
26
  this.toasts = [];
27
+ this.activeToastKeys = new Set();
28
+ this.activeToastIdsByKey = new Map();
29
+ this.activeToastKeysById = new Map();
27
30
  }
28
31
 
29
32
  /**
@@ -197,9 +200,16 @@ export class AppToaster extends HTMLElement {
197
200
  };
198
201
 
199
202
  const config = { ...defaults, ...options };
203
+ config.type = this.#normalizeToastType(config.type);
200
204
 
201
205
  // Calculate reading time (average 200 words per minute)
202
206
  const messageText = String(message || "");
207
+ const dedupeKey = this.#createActiveToastKey(messageText, config.type);
208
+ const activeToastId = this.activeToastIdsByKey.get(dedupeKey);
209
+ if (activeToastId) {
210
+ return activeToastId;
211
+ }
212
+
203
213
  const readingText = config.html ? messageText.replace(/<[^>]*>/g, " ") : messageText;
204
214
  const wordCount = readingText.split(/\s+/).filter(Boolean).length;
205
215
  const baseReadingTime = Math.max(2000, (wordCount / 200) * 60 * 1000); // minimum 2 seconds
@@ -208,7 +218,11 @@ export class AppToaster extends HTMLElement {
208
218
  const multiplier = config.type === "error" ? 1.5 : 1;
209
219
  const duration = config.duration || baseReadingTime * multiplier;
210
220
 
211
- return this.#showToast(messageText, config, duration);
221
+ const toastId = this.#showToast(messageText, config, duration);
222
+ this.activeToastKeys.add(dedupeKey);
223
+ this.activeToastIdsByKey.set(dedupeKey, toastId);
224
+ this.activeToastKeysById.set(toastId, dedupeKey);
225
+ return toastId;
212
226
  }
213
227
 
214
228
  /*
@@ -363,6 +377,13 @@ export class AppToaster extends HTMLElement {
363
377
  if (toastElement.parentNode === this.shadowRoot) {
364
378
  this.shadowRoot.removeChild(toastElement);
365
379
  }
380
+
381
+ const toastKey = this.activeToastKeysById.get(toastId);
382
+ if (toastKey) {
383
+ this.activeToastKeysById.delete(toastId);
384
+ this.activeToastIdsByKey.delete(toastKey);
385
+ this.activeToastKeys.delete(toastKey);
386
+ }
366
387
  }, 300);
367
388
  }
368
389
 
@@ -381,9 +402,22 @@ export class AppToaster extends HTMLElement {
381
402
  while (this.shadowRoot.firstChild) {
382
403
  this.shadowRoot.removeChild(this.shadowRoot.firstChild);
383
404
  }
405
+ this.activeToastKeys.clear();
406
+ this.activeToastIdsByKey.clear();
407
+ this.activeToastKeysById.clear();
384
408
  }, 300);
385
409
  }
386
410
 
411
+ #normalizeToastType(type) {
412
+ if (type === "info") return "information";
413
+ if (type === "danger") return "error";
414
+ return type || "information";
415
+ }
416
+
417
+ #createActiveToastKey(message, type) {
418
+ return `${String(type || "information").trim().toLowerCase()}::${String(message || "").trim()}`;
419
+ }
420
+
387
421
  /*
388
422
  * Programmatically close the toast associated with a button click.
389
423
  */
@@ -1,16 +1,16 @@
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
+ function g(o){let e=Array.isArray(o?.strings)?o.strings:[],d=Array.isArray(o?.values)?o.values:[],m=new Set,f=[],p=/(\s)(\.[\w-]+)=\s*$/;for(let t=0;t<e.length;t+=1){let s=e[t]??"",c=s.match(p);if(c&&t<d.length){let u=c[2].slice(1),y=`pds-val-${t}`;s=s.replace(p,`$1data-pds-prop="${u}:${y}"`),m.add(t)}f.push(s),t<d.length&&!m.has(t)&&f.push(`<!--pds-val-${t}-->`)}let n=document.createElement("template");n.innerHTML=f.join("");let a=(t,s)=>{let c=t.parentNode;if(!c)return;if(s==null){c.removeChild(t);return}let h=u=>{if(u!=null){if(u instanceof Node){c.insertBefore(u,t);return}if(Array.isArray(u)){u.forEach(y=>h(y));return}c.insertBefore(document.createTextNode(String(u)),t)}};h(s),c.removeChild(t)},l=document.createTreeWalker(n.content,NodeFilter.SHOW_COMMENT),r=[];for(;l.nextNode();){let t=l.currentNode;t?.nodeValue?.startsWith("pds-val-")&&r.push(t)}return r.forEach(t=>{let s=Number(t.nodeValue.replace("pds-val-",""));a(t,d[s])}),n.content.querySelectorAll("*").forEach(t=>{let s=t.getAttribute("data-pds-prop");if(!s)return;let[c,h]=s.split(":"),u=Number(String(h).replace("pds-val-",""));c&&Number.isInteger(u)&&(t[c]=d[u]),t.removeAttribute("data-pds-prop")}),n.content}function b(o,e){if(e==null)return;if(typeof e=="object"&&Array.isArray(e.strings)&&Array.isArray(e.values)){o.appendChild(g(e));return}if(e instanceof Node){o.appendChild(e);return}if(Array.isArray(e)){e.forEach(m=>b(o,m));return}let d=typeof e=="string"?e:String(e);o.appendChild(document.createTextNode(d))}function A(o){if(!o)return!0;let e=!0,d=a=>{if(!a||typeof a!="object")return"<unknown>";let l=a.tagName?String(a.tagName).toLowerCase():"node",r=a.id?`#${a.id}`:"",i=typeof a.getAttribute=="function"?a.getAttribute("name"):null,t=i?`[name="${i}"]`:"";return`${l}${r}${t}`},m=(a,l)=>{if(!a||typeof a.querySelectorAll!="function")return;let r=Array.from(a.querySelectorAll(":invalid"));if(!r.length)return;let i=r.map(t=>{let s=typeof t.validationMessage=="string"?t.validationMessage:"";return`${d(t)}${s?` \u2014 ${s}`:""}`});console.warn(`ask.validateDialogFormTree: invalid controls in ${l}:`,i)},f=(a,l)=>{try{let r=typeof a.reportValidity=="function"?a.reportValidity():a.checkValidity?.()??!0;return r||m(a,l),r}catch(r){return console.error(`ask.validateDialogFormTree: validation threw in ${l}`,r),!1}};e=f(o,"host dialog form")&&e;let p=Array.from(o.querySelectorAll("form"));for(let a of p){if(a===o)continue;e=f(a,`nested light DOM form ${d(a)}`)&&e}let n=Array.from(o.querySelectorAll("*"));for(let a of n){let l=a?.shadowRoot;if(!l)continue;let r=Array.from(l.querySelectorAll("form"));for(let i of r)e=f(i,`shadow form under ${d(a)}`)&&e}return e}function v(){let o=navigator.userAgent,e=/Safari/i.test(o),d=/(Chrome|Chromium|CriOS|FxiOS|EdgiOS|OPiOS|Opera)/i.test(o);return e&&!d}function $(o){if(window.matchMedia?.("(prefers-reduced-motion: reduce)").matches)return;let e=window.matchMedia?.("(max-width: 639px)").matches,d=o.classList.contains("dialog-no-scale-animation")?"pds-dialog-fade-enter":e?"pds-dialog-enter-mobile":"pds-dialog-enter";o.style.animation="none",o.offsetWidth,o.style.animation=`${d} var(--transition-normal) ease`,o.addEventListener("animationend",()=>{o.style.animation=""},{once:!0})}function C(o={}){return o?.liquidGlassEffects===!0}async function S(o,e={}){return e={...{title:"Confirm",type:"confirm",buttons:{ok:{name:"OK",primary:!0},cancel:{name:"Cancel",cancel:!0}}},...e},new Promise(m=>{let f=!1,p=(r,i)=>{f||(f=!0,i.close(),m(r))},n=document.createElement("dialog");v()&&n.classList.add("dialog-no-scale-animation"),C(e)&&n.classList.add("liquid-glass"),e.size&&n.classList.add(`dialog-${e.size}`),e.type&&n.classList.add(`dialog-${e.type}`),e.class&&(Array.isArray(e.class)?n.classList.add(...e.class):n.classList.add(e.class)),e.maxHeight&&n.style.setProperty("--dialog-max-height",e.maxHeight);let a=Object.entries(e.buttons).map(([r,i])=>{let t=i.primary?"btn-primary btn-sm":"btn-outline btn-sm",s=i.cancel?"button":"submit",c=i.formNoValidate?" formnovalidate":"";return`<button type="${s}" class="${t}" value="${r}"${c}>${i.name}</button>`});if(e.useForm){let r=document.createElement("div");b(r,o);let i=r.querySelector("form");if(i){n.innerHTML=`
2
2
  <header>
3
3
  <h2>${e.title}</h2>
4
4
  </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=`
5
+ `;let t=document.createElement("article");for(t.className="dialog-body";i.firstChild;)t.appendChild(i.firstChild);i.appendChild(t);let s=document.createElement("footer");s.innerHTML=a.join(""),i.appendChild(s),n.appendChild(i)}else n.innerHTML=`
6
6
  <header>
7
7
  <h2>${e.title}</h2>
8
8
  </header>
9
9
  <article id="msg-container"></article>
10
10
  <footer>
11
- ${f.join("")}
11
+ ${a.join("")}
12
12
  </footer>
13
- `,t.querySelector("#msg-container").appendChild(a)}else{t.innerHTML=`
13
+ `,n.querySelector("#msg-container").appendChild(r)}else{n.innerHTML=`
14
14
  <form method="dialog">
15
15
  <header>
16
16
  <h2>${e.title}</h2>
@@ -19,7 +19,7 @@ function g(n){let e=Array.isArray(n?.strings)?n.strings:[],c=Array.isArray(n?.va
19
19
  <article id="msg-container"></article>
20
20
 
21
21
  <footer>
22
- ${f.join("")}
22
+ ${a.join("")}
23
23
  </footer>
24
24
  </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};
25
+ `;let r=n.querySelector("#msg-container");b(r,o)}n.addEventListener("click",r=>{let i=r.target.closest('button[value="ok"]');if(i&&e.useForm){r.preventDefault();let s=n.querySelector("form");if(!s||!!!i.hasAttribute("formnovalidate")&&!A(s))return;let h=new FormData(s);p(h,n);return}r.target.closest('button[value="cancel"]')&&p(!1,n)});let l=()=>{let r=n.querySelector("form");if(r){if(r.dataset.askSubmitBound==="true")return;r.dataset.askSubmitBound="true",r.addEventListener("submit",i=>{i.preventDefault();let t=i.submitter?.value??(e.useForm?"ok":void 0),s=!!i.submitter?.hasAttribute("formnovalidate");if(e.useForm&&t==="ok"&&!s&&!A(r))return;let c;e.useForm&&t==="ok"?c=new FormData(r):c=t==="ok",p(c,n)})}else requestAnimationFrame(l)};n.addEventListener("close",()=>{setTimeout(()=>n.remove(),200)}),document.body.appendChild(n),requestAnimationFrame(l),typeof e.rendered=="function"&&e.rendered(n),n.showModal(),requestAnimationFrame(()=>$(n))})}export{S as ask};