@pure-ds/core 0.5.60 → 0.6.1

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 (43) hide show
  1. package/dist/types/packages/pds-configurator/src/pds-home-content.d.ts +375 -0
  2. package/dist/types/packages/pds-configurator/src/pds-home-content.d.ts.map +1 -0
  3. package/dist/types/packages/pds-configurator/src/pds-home.d.ts +2 -0
  4. package/dist/types/packages/pds-configurator/src/pds-home.d.ts.map +1 -0
  5. package/dist/types/pds.config.d.ts +4 -8
  6. package/dist/types/pds.config.d.ts.map +1 -1
  7. package/dist/types/pds.d.ts +3 -1
  8. package/dist/types/public/assets/js/pds-manager.d.ts.map +1 -1
  9. package/dist/types/public/assets/js/pds.d.ts.map +1 -1
  10. package/dist/types/public/assets/pds/components/pds-live-edit.d.ts +150 -0
  11. package/dist/types/public/assets/pds/components/pds-live-edit.d.ts.map +1 -0
  12. package/dist/types/public/assets/pds/components/pds-omnibox.d.ts +2 -0
  13. package/dist/types/public/assets/pds/components/pds-omnibox.d.ts.map +1 -1
  14. package/dist/types/public/assets/pds/components/pds-richtext.d.ts.map +1 -1
  15. package/dist/types/public/assets/pds/components/pds-theme.d.ts +5 -0
  16. package/dist/types/public/assets/pds/components/pds-theme.d.ts.map +1 -1
  17. package/dist/types/src/js/pds-core/pds-config.d.ts +457 -0
  18. package/dist/types/src/js/pds-core/pds-config.d.ts.map +1 -1
  19. package/dist/types/src/js/pds-core/pds-enhancers.d.ts.map +1 -1
  20. package/dist/types/src/js/pds-core/pds-live.d.ts.map +1 -1
  21. package/dist/types/src/js/pds-core/pds-ontology.d.ts.map +1 -1
  22. package/dist/types/src/js/pds-core/pds-start-helpers.d.ts.map +1 -1
  23. package/dist/types/src/js/pds-core/pds-theme-utils.d.ts +6 -0
  24. package/dist/types/src/js/pds-core/pds-theme-utils.d.ts.map +1 -0
  25. package/dist/types/src/js/pds.d.ts.map +1 -1
  26. package/package.json +1 -4
  27. package/packages/pds-cli/bin/templates/bootstrap/pds.config.js +9 -2
  28. package/public/assets/js/app.js +106 -5636
  29. package/public/assets/js/pds-manager.js +156 -156
  30. package/public/assets/js/pds.js +7 -7
  31. package/public/assets/pds/components/pds-live-edit.js +1555 -0
  32. package/public/assets/pds/components/pds-omnibox.js +558 -369
  33. package/public/assets/pds/components/pds-richtext.js +57 -7
  34. package/public/assets/pds/components/pds-theme.js +58 -0
  35. package/readme.md +2 -2
  36. package/src/js/pds-core/pds-config.js +705 -1
  37. package/src/js/pds-core/pds-enhancers.js +61 -4
  38. package/src/js/pds-core/pds-live.js +545 -437
  39. package/src/js/pds-core/pds-ontology.js +8 -0
  40. package/src/js/pds-core/pds-start-helpers.js +15 -0
  41. package/src/js/pds-core/pds-theme-utils.js +33 -0
  42. package/src/js/pds.d.ts +3 -1
  43. package/src/js/pds.js +22 -0
@@ -341,7 +341,13 @@ export class RichText extends HTMLElement {
341
341
  async #adoptStyles() {
342
342
  // Component stylesheet (tokens + semantic vars)
343
343
  const componentStyles = PDS.createStylesheet(/*css*/ `@layer richtext {
344
- :host { display:block; color: var(--rt-fg, var(--color-text-primary)); font: var(--font-body-sm, 14px/1.35 system-ui,-apple-system,Segoe UI,Roboto,sans-serif); }
344
+ :host {
345
+ display: block;
346
+ color: var(--rt-fg, var(--color-text-primary));
347
+ font-family: var(--rt-font-family, var(--font-family-body));
348
+ font-size: var(--rt-font-size, var(--font-size-base));
349
+ line-height: var(--rt-line-height, var(--font-line-height-normal));
350
+ }
345
351
  :host([disabled]) { opacity: .6; pointer-events: none; }
346
352
  .box { border: 1px solid var(--rt-border, var(--color-border, currentColor)); border-radius: var(--radius-md,8px); background: var(--rt-bg, var(--color-input-bg)); }
347
353
  .box:focus-within {
@@ -353,11 +359,15 @@ export class RichText extends HTMLElement {
353
359
  }
354
360
  }
355
361
 
356
- .toolbar {background-color: var(--surface-subtle-bg); display:flex; gap: var(--spacing-2,10px); align-items:center; border-bottom: 1px solid var(--rt-border, var(--color-border-muted)); border-radius: var(--radius-md,8px) var(--radius-md,8px) 0 0; }
357
- .tbtn { transition: none; display:inline-flex; align-items:center; justify-content:center; width:22px; height:22px; border-radius: var(--radius-sm,6px); cursor:pointer; user-select:none; color: inherit; background: transparent; border:none; }
362
+ .toolbar { background-color: var(--surface-subtle-bg); display: flex; gap: var(--spacing-0, 2px); align-items: center; padding: var(--spacing-0, 2px); border-bottom: 1px solid var(--rt-border, var(--color-border-muted)); border-radius: var(--radius-md,8px) var(--radius-md,8px) 0 0; width: 100%; max-width: 100%; flex-wrap: nowrap; box-sizing: border-box; overflow: hidden; }
363
+ .tbtn { transition: none; display:inline-flex; align-items:center; justify-content:center; width:22px; height:22px; border-radius: var(--radius-sm,6px); cursor:pointer; user-select:none; color: inherit; background: transparent; border:none;
364
+
365
+ padding: var(--spacing-0) var(--spacing-6, 8px);
366
+
367
+ }
358
368
  .tbtn:hover { background: var(--color-surface-hover, color-mix(in oklab, CanvasText 12%, transparent)); }
359
369
  .edwrap { position:relative; }
360
- .ed { display: block; min-height:90px; max-height: 400px; overflow:auto; padding: var(--spacing-1, 0) var(--spacing-2, 0); outline:none; word-break:break-word; border-radius: 0 0 var(--radius-md,8px) var(--radius-md,8px); background: var(--rt-editor-bg, var(--color-input-bg)); }
370
+ .ed { display: block; font-weight: normal; min-height:90px; max-height: 400px; overflow:auto; padding: var(--spacing-1, 0) var(--spacing-2, 0); outline:none; word-break:break-word; border-radius: 0 0 var(--radius-md,8px) var(--radius-md,8px); background: var(--rt-editor-bg, var(--color-input-bg)); }
361
371
  .ed[contenteditable="true"]:empty::before { content: attr(data-ph); color: var(--rt-muted, var(--color-text-muted)); pointer-events:none; }
362
372
  .send { margin-left:auto; display:inline-flex; gap: var(--spacing-2,8px); align-items:center; }
363
373
  button.icon { background:transparent; border:0; color:inherit; cursor:pointer; padding:6px; border-radius: var(--radius-sm,6px); }
@@ -589,9 +599,28 @@ export class RichText extends HTMLElement {
589
599
 
590
600
  #toggleCode() {
591
601
  // Wrap selection with <code> or unwrap if already in code
592
- const sel = window.getSelection();
602
+ const root = this.shadowRoot;
603
+ const getSel = () =>
604
+ root && typeof root.getSelection === "function"
605
+ ? root.getSelection()
606
+ : window.getSelection();
607
+ let sel = getSel();
593
608
  if (!sel || sel.rangeCount === 0) return;
594
- const range = sel.getRangeAt(0);
609
+ let range = sel.getRangeAt(0);
610
+ const inEditor = (r) => {
611
+ const node =
612
+ r.commonAncestorContainer.nodeType === 1
613
+ ? r.commonAncestorContainer
614
+ : r.commonAncestorContainer.parentNode;
615
+ return !!(node && this.#editorDiv && this.#editorDiv.contains(node));
616
+ };
617
+ if (!inEditor(range)) {
618
+ this.#focus();
619
+ sel = getSel();
620
+ if (!sel || sel.rangeCount === 0) return;
621
+ range = sel.getRangeAt(0);
622
+ if (!inEditor(range)) return;
623
+ }
595
624
  // Simple toggle: if ancestor <code>, unwrap; else wrap
596
625
  const codeAncestor = this.#closestAncestor(
597
626
  range.commonAncestorContainer,
@@ -604,7 +633,28 @@ export class RichText extends HTMLElement {
604
633
  parent.removeChild(codeAncestor);
605
634
  } else {
606
635
  const wrapper = document.createElement("code");
607
- range.surroundContents(wrapper);
636
+ if (range.collapsed) {
637
+ const caret = document.createTextNode("\u200B");
638
+ wrapper.appendChild(caret);
639
+ range.insertNode(wrapper);
640
+ const next = document.createRange();
641
+ next.setStart(caret, 1);
642
+ next.collapse(true);
643
+ sel.removeAllRanges();
644
+ sel.addRange(next);
645
+ } else {
646
+ try {
647
+ range.surroundContents(wrapper);
648
+ } catch {
649
+ const contents = range.extractContents();
650
+ wrapper.appendChild(contents);
651
+ range.insertNode(wrapper);
652
+ }
653
+ const next = document.createRange();
654
+ next.selectNodeContents(wrapper);
655
+ sel.removeAllRanges();
656
+ sel.addRange(next);
657
+ }
608
658
  }
609
659
  }
610
660
 
@@ -13,6 +13,39 @@ const THEME_OPTIONS = [
13
13
 
14
14
  const DEFAULT_LABEL = "Theme";
15
15
  const LAYERS = ["tokens", "primitives", "components", "utilities"];
16
+ const DEFAULT_THEMES = ["light", "dark"];
17
+ const VALID_THEMES = new Set(DEFAULT_THEMES);
18
+
19
+ const normalizePresetThemes = (preset) => {
20
+ const themes = Array.isArray(preset?.themes)
21
+ ? preset.themes.map((theme) => String(theme).toLowerCase())
22
+ : DEFAULT_THEMES;
23
+ const normalized = themes.filter((theme) => VALID_THEMES.has(theme));
24
+ return normalized.length ? normalized : DEFAULT_THEMES;
25
+ };
26
+
27
+ const resolveThemePreference = (preference) => {
28
+ const normalized = String(preference || "").toLowerCase();
29
+ if (VALID_THEMES.has(normalized)) return normalized;
30
+
31
+ if (typeof document !== "undefined") {
32
+ const applied = document.documentElement?.getAttribute("data-theme");
33
+ if (VALID_THEMES.has(applied)) return applied;
34
+ }
35
+
36
+ if (typeof window !== "undefined" && window.matchMedia) {
37
+ const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
38
+ return prefersDark ? "dark" : "light";
39
+ }
40
+
41
+ return "light";
42
+ };
43
+
44
+ const isPresetThemeCompatible = (preset, themePreference) => {
45
+ const resolvedTheme = resolveThemePreference(themePreference);
46
+ const themes = normalizePresetThemes(preset);
47
+ return themes.includes(resolvedTheme);
48
+ };
16
49
 
17
50
  class PdsTheme extends HTMLElement {
18
51
  static get observedAttributes() {
@@ -123,6 +156,21 @@ class PdsTheme extends HTMLElement {
123
156
  return;
124
157
  }
125
158
 
159
+ const currentPreset = PDS.currentConfig?.design || null;
160
+ if (currentPreset && !isPresetThemeCompatible(currentPreset, value)) {
161
+ const resolvedTheme = resolveThemePreference(value);
162
+ const presetName =
163
+ currentPreset?.name ||
164
+ PDS.currentPreset?.name ||
165
+ PDS.currentConfig?.preset ||
166
+ "current preset";
167
+ console.warn(
168
+ `PDS theme "${resolvedTheme}" not supported by preset "${presetName}".`
169
+ );
170
+ this.#syncCheckedState();
171
+ return;
172
+ }
173
+
126
174
  if (PDS.theme !== value) {
127
175
  PDS.theme = value;
128
176
  }
@@ -157,10 +205,20 @@ class PdsTheme extends HTMLElement {
157
205
 
158
206
  #syncCheckedState() {
159
207
  const currentTheme = PDS.theme || "system";
208
+ const currentPreset = PDS.currentConfig?.design || null;
209
+ const supportedThemes = normalizePresetThemes(currentPreset);
160
210
  this.shadowRoot
161
211
  .querySelectorAll('input[type="radio"]')
162
212
  .forEach((radio) => {
163
213
  radio.checked = radio.value === currentTheme;
214
+ if (radio.value === "system") {
215
+ radio.disabled = false;
216
+ } else if (currentPreset) {
217
+ const resolved = resolveThemePreference(radio.value);
218
+ radio.disabled = !supportedThemes.includes(resolved);
219
+ } else {
220
+ radio.disabled = false;
221
+ }
164
222
  });
165
223
  }
166
224
  }
package/readme.md CHANGED
@@ -6,7 +6,7 @@
6
6
  [![License: ISC](https://img.shields.io/badge/License-ISC-blue.svg)](#license)
7
7
  [![npm version](https://img.shields.io/npm/v/@pure-ds/core.svg)](https://www.npmjs.com/package/@pure-ds/core)
8
8
 
9
- ![Pure Design System logo](public/assets/img/logo.png)
9
+ ![Pure Design System logo](public/assets/img/pds-logo.svg)
10
10
 
11
11
  ## With Great Standards Comes Great Power
12
12
 
@@ -571,7 +571,7 @@ PDS.dispatchEvent(new CustomEvent('pds:toast', {
571
571
  <script type="importmap">
572
572
  {
573
573
  "imports": {
574
- "#showdown": "https://cdn.jsdelivr.net/npm/showdown@2.1.0/dist/showdown.mjs"
574
+ "#showdown": "https://cdn.jsdelivr.net/npm/showdown@2.1.0/+esm"
575
575
  }
576
576
  }
577
577
  </script>