@pure-ds/core 0.7.30 → 0.7.33

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 (86) hide show
  1. package/.github/copilot-instructions.md +20 -11
  2. package/LOCALIZATION.md +197 -0
  3. package/dist/types/pds.config.d.ts +1 -1
  4. package/dist/types/pds.config.d.ts.map +1 -1
  5. package/dist/types/pds.d.ts +150 -0
  6. package/dist/types/public/assets/pds/components/pds-form.d.ts +2 -2
  7. package/dist/types/public/assets/pds/components/pds-form.d.ts.map +1 -1
  8. package/dist/types/public/assets/pds/components/pds-omnibox.d.ts +2 -2
  9. package/dist/types/public/assets/pds/components/pds-omnibox.d.ts.map +1 -1
  10. package/dist/types/public/assets/pds/components/pds-rating.d.ts +1 -119
  11. package/dist/types/public/assets/pds/components/pds-rating.d.ts.map +1 -1
  12. package/dist/types/public/assets/pds/components/pds-treeview.d.ts.map +1 -1
  13. package/dist/types/public/assets/pds/components/pds-upload.d.ts.map +1 -1
  14. package/dist/types/src/js/common/ask.d.ts.map +1 -1
  15. package/dist/types/src/js/common/font-loader.d.ts.map +1 -1
  16. package/dist/types/src/js/common/localization-resource-provider.d.ts +49 -0
  17. package/dist/types/src/js/common/localization-resource-provider.d.ts.map +1 -0
  18. package/dist/types/src/js/common/localization.d.ts +25 -0
  19. package/dist/types/src/js/common/localization.d.ts.map +1 -0
  20. package/dist/types/src/js/common/msg.d.ts +1 -2
  21. package/dist/types/src/js/common/msg.d.ts.map +1 -1
  22. package/dist/types/src/js/common/pds-log.d.ts +3 -0
  23. package/dist/types/src/js/common/pds-log.d.ts.map +1 -0
  24. package/dist/types/src/js/lit.d.ts +0 -7
  25. package/dist/types/src/js/lit.d.ts.map +1 -1
  26. package/dist/types/src/js/pds-core/pds-config.d.ts +51 -0
  27. package/dist/types/src/js/pds-core/pds-config.d.ts.map +1 -1
  28. package/dist/types/src/js/pds-core/pds-enhancers.d.ts.map +1 -1
  29. package/dist/types/src/js/pds-core/pds-live.d.ts.map +1 -1
  30. package/dist/types/src/js/pds-core/pds-registry.d.ts.map +1 -1
  31. package/dist/types/src/js/pds-core/pds-runtime.d.ts.map +1 -1
  32. package/dist/types/src/js/pds-core/pds-start-helpers.d.ts.map +1 -1
  33. package/dist/types/src/js/pds-localization.d.ts +3 -0
  34. package/dist/types/src/js/pds-localization.d.ts.map +1 -0
  35. package/dist/types/src/js/pds-singleton.d.ts +13 -0
  36. package/dist/types/src/js/pds-singleton.d.ts.map +1 -0
  37. package/dist/types/src/js/pds.d.ts +9 -1
  38. package/dist/types/src/js/pds.d.ts.map +1 -1
  39. package/package.json +10 -4
  40. package/packages/pds-cli/README.md +2 -0
  41. package/packages/pds-cli/lib/pds-mcp-core.js +2 -2
  42. package/public/assets/js/app.js +9 -11
  43. package/public/assets/js/lit.js +3 -94
  44. package/public/assets/js/pds-ask.js +4 -4
  45. package/public/assets/js/pds-enhancers.js +1 -1
  46. package/public/assets/js/pds-localization.js +1 -0
  47. package/public/assets/js/pds-manager.js +118 -118
  48. package/public/assets/js/pds.js +2 -2
  49. package/public/assets/pds/components/pds-calendar.js +4 -4
  50. package/public/assets/pds/components/pds-daterange.js +11 -8
  51. package/public/assets/pds/components/pds-form.js +22 -22
  52. package/public/assets/pds/components/pds-live-edit.js +503 -42
  53. package/public/assets/pds/components/pds-live-importer.js +66 -66
  54. package/public/assets/pds/components/pds-live-template-canvas.js +3 -3
  55. package/public/assets/pds/components/pds-omnibox.js +4 -4
  56. package/public/assets/pds/components/pds-rating.js +5 -3
  57. package/public/assets/pds/components/pds-tags.js +5 -5
  58. package/public/assets/pds/components/pds-theme.js +4 -4
  59. package/public/assets/pds/components/pds-toaster.js +6 -6
  60. package/public/assets/pds/components/pds-treeview.js +8 -4
  61. package/public/assets/pds/components/pds-upload.js +7 -6
  62. package/public/assets/pds/core/pds-ask.js +4 -4
  63. package/public/assets/pds/core/pds-enhancers.js +1 -1
  64. package/public/assets/pds/core/pds-localization.js +1 -0
  65. package/public/assets/pds/core/pds-manager.js +118 -118
  66. package/public/assets/pds/core.js +2 -2
  67. package/public/assets/pds/external/lit.js +3 -94
  68. package/readme.md +34 -6
  69. package/src/js/common/ask.js +530 -0
  70. package/src/js/common/common.js +122 -0
  71. package/src/js/common/font-loader.js +202 -0
  72. package/src/js/common/localization-resource-provider.js +274 -0
  73. package/src/js/common/localization.js +839 -0
  74. package/src/js/common/msg.js +9 -0
  75. package/src/js/common/pds-core/pds.d.ts +128 -0
  76. package/src/js/common/pds-log.js +144 -0
  77. package/src/js/common/toast.js +122 -0
  78. package/src/js/pds-core/pds-config.js +51 -10
  79. package/src/js/pds-core/pds-enhancers.js +5 -3
  80. package/src/js/pds-core/pds-live.js +7 -5
  81. package/src/js/pds-core/pds-registry.js +6 -4
  82. package/src/js/pds-core/pds-runtime.js +12 -8
  83. package/src/js/pds-core/pds-start-helpers.js +9 -4
  84. package/src/js/pds-singleton.js +49 -0
  85. package/src/js/pds.d.ts +150 -0
  86. package/src/js/pds.js +420 -40
@@ -0,0 +1,9 @@
1
+ export {
2
+ msg,
3
+ str,
4
+ joinStringsAndValues,
5
+ configureLocalization,
6
+ loadLocale,
7
+ setLocale,
8
+ getLocalizationState,
9
+ } from "./localization.js";
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Runtime registry singleton that controls live vs static behavior.
3
+ * Consumers can call `registry.setDesigner(designer)` to enable live mode
4
+ * or `registry.setStaticMode(paths)` to point to static asset modules.
5
+ */
6
+ export interface PDSRegistry {
7
+ /** Attach a designer instance and switch the registry to live mode. */
8
+ setDesigner(designer: any, meta?: { presetName?: string }): void;
9
+ /** Switch to static mode and override static paths (keys: tokens, primitives, components, utilities, styles) */
10
+ setStaticMode(paths?: Record<string, string>): void;
11
+ /** Return a constructable stylesheet for the requested layer or null on failure. */
12
+ getStylesheet(layer: string): Promise<CSSStyleSheet | null>;
13
+ /** Return a BLOB URL (live mode only) for layer imports used in CSS */
14
+ getBlobURL(layer: string): string | null;
15
+ /** 'live' or 'static' */
16
+ readonly mode: string;
17
+ /** true when a live designer instance is registered */
18
+ readonly isLive: boolean;
19
+ /** true when a designer instance exists */
20
+ readonly hasDesigner: boolean;
21
+ }
22
+
23
+ /** A small shape describing component metadata used by the PDS ontology. */
24
+ export interface ComponentDef {
25
+ /** canonical name of the component (e.g., 'Button') */
26
+ name: string;
27
+ /** optional HTML tag name for the component ('pds-button') */
28
+ tag?: string;
29
+ /** documented props and their types/metadata */
30
+ props?: Record<string, any>;
31
+ /** human-friendly description used by the designer */
32
+ description?: string;
33
+ }
34
+
35
+ /**
36
+ * Generator - programmatic API to produce tokens, layered CSS and helper modules from a config.
37
+ * Typical usage:
38
+ * const g = new Generator({ example: true });
39
+ * // tokens may be returned synchronously or via a Promise
40
+ * const tokens = await g.generateTokens?.();
41
+ * const css = await g.generateCSS?.();
42
+ */
43
+ export class Generator {
44
+ constructor(options?: any);
45
+ /** runtime options / config passed to the generator */
46
+ options: any;
47
+ /** generated token object */
48
+ tokens: Record<string, any>;
49
+ /** concatenated CSS (layered) */
50
+ css: string;
51
+ /** Generate the token map (may be async in some implementations) */
52
+ generateTokens?(): Record<string, any> | Promise<Record<string, any>>;
53
+ /** Generate the CSS string (may be async) */
54
+ generateCSS?(): string | Promise<string>;
55
+ }
56
+
57
+ /** Public runtime surface exported as `PDS` */
58
+ export interface PDSEventMap {
59
+ 'pds:ready': CustomEvent<{ mode: 'live' | 'static'; generator?: Generator; config: any; theme: string; autoDefiner?: any }>;
60
+ 'pds:error': CustomEvent<{ error: any }>;
61
+ 'pds:theme:changed': CustomEvent<{ theme: string; requested?: string; source: 'system' | 'programmatic' }>;
62
+ 'pds:config-changed': CustomEvent<{ at: number; mode?: 'live' | 'static'; source?: string; preset?: string }>;
63
+ 'pds:design:updated': CustomEvent<{ config: any; designer?: any }>;
64
+ 'pds:design:field:changed': CustomEvent<{ field: string; config: any }>;
65
+ 'pds:inspector:mode:changed': CustomEvent<{ active: boolean }>;
66
+ 'pds:inspector:deactivate': CustomEvent<{}>;
67
+ 'pds:docs:view': CustomEvent<{ file: string }>;
68
+ }
69
+
70
+ export const PDS: {
71
+ /** Registry singleton to query/adopt styles and control live/static behavior. */
72
+ registry: PDSRegistry;
73
+ /** Live-only accessor for the Generator class. */
74
+ getGenerator?: () => Promise<typeof Generator>;
75
+ /** Presets keyed by id (lowercased). Available in live mode. */
76
+ presets?: Record<string, any>;
77
+ /** Ontology metadata about components (live mode). */
78
+ ontology?: any;
79
+ /** Apply generated styles to the document (live mode). */
80
+ applyStyles?: (generator?: Generator) => void;
81
+ /** Adopt multiple named layers into a ShadowRoot. See `LAYER-ARCHITECTURE.md` for layer ordering. */
82
+ adoptLayers: (shadowRoot: ShadowRoot, layers?: string[], additionalSheets?: CSSStyleSheet[]) => Promise<void>;
83
+ /** Convenience to adopt only primitives/styles commonly needed by components. */
84
+ adoptPrimitives: (shadowRoot: ShadowRoot, additionalSheets?: CSSStyleSheet[]) => Promise<void>;
85
+ /** Create a constructable stylesheet from a CSS string. May throw on invalid CSS in some browsers. */
86
+ createStylesheet: (css: string) => CSSStyleSheet;
87
+ /** Utility to inspect whether runtime is running in live mode. */
88
+ isLiveMode: () => boolean;
89
+ /** Find a component definition for a given DOM element, or null if not matched (live mode). */
90
+ findComponentForElement?: (el: Element) => ComponentDef | null;
91
+ /** Primary unified entry point to start PDS in live or static mode. Default mode is 'live'. */
92
+ start: (config: {
93
+ mode?: 'live' | 'static';
94
+ preset?: string;
95
+ design?: any;
96
+ autoDefine?: {
97
+ /** AutoDefiner is bundled with PDS core; external moduleURL overrides are not supported. */
98
+ baseURL?: string;
99
+ predefine?: string[];
100
+ mapper?: (tag: string) => string | undefined | null | false;
101
+ scanExisting?: boolean;
102
+ observeShadows?: boolean;
103
+ patchAttachShadow?: boolean;
104
+ debounceMs?: number;
105
+ onError?: (tag: string, err: any) => void;
106
+ };
107
+ applyGlobalStyles?: boolean;
108
+ manageTheme?: boolean;
109
+ themeStorageKey?: string;
110
+ // live-only
111
+ preloadStyles?: boolean;
112
+ criticalLayers?: string[];
113
+ // static-only
114
+ staticPaths?: Record<string, string>;
115
+ enhancers?: Array<any>;
116
+ }) => Promise<{ generator?: Generator; config: any; theme: string; autoDefiner?: any }>;
117
+ /** Preload minimal CSS to prevent flash of unstyled content. Call before DOM content renders. */
118
+ preloadCritical?: (config: any, options?: {
119
+ theme?: string;
120
+ layers?: string[];
121
+ }) => void;
122
+ /** EventTarget API (strongly typed for common PDS events). */
123
+ addEventListener: <K extends keyof PDSEventMap>(type: K, listener: (ev: PDSEventMap[K]) => any, options?: boolean | AddEventListenerOptions) => void;
124
+ removeEventListener: <K extends keyof PDSEventMap>(type: K, listener: (ev: PDSEventMap[K]) => any, options?: boolean | EventListenerOptions) => void;
125
+ dispatchEvent: (event: PDSEventMap[keyof PDSEventMap] | Event) => boolean;
126
+ };
127
+
128
+ export { PDS as default };
@@ -0,0 +1,144 @@
1
+ const __SUPPORTED_LOG_LEVELS = new Set(["log", "warn", "error", "debug", "info"]);
2
+ const __PDS_SINGLETON_KEY = "__PURE_DS_PDS_SINGLETON__";
3
+
4
+ let __logProvider = null;
5
+ let __contextProvider = null;
6
+
7
+ function __resolveGlobalPDS() {
8
+ try {
9
+ const scope = typeof globalThis !== "undefined" ? globalThis : window;
10
+ const candidate = scope?.[__PDS_SINGLETON_KEY];
11
+ if (candidate && typeof candidate === "object") {
12
+ return candidate;
13
+ }
14
+ } catch (error) {
15
+ return null;
16
+ }
17
+ return null;
18
+ }
19
+
20
+ function __normalizeContext(context) {
21
+ if (!context || typeof context !== "object") {
22
+ return null;
23
+ }
24
+ return {
25
+ mode: context.mode === "live" || context.mode === "static" ? context.mode : null,
26
+ debug: context.debug === true,
27
+ thisArg: context.thisArg,
28
+ };
29
+ }
30
+
31
+ function __normalizeLevel(level) {
32
+ if (typeof level !== "string") return "log";
33
+ const normalized = level.toLowerCase();
34
+ return __SUPPORTED_LOG_LEVELS.has(normalized) ? normalized : "log";
35
+ }
36
+
37
+ function __resolveContext() {
38
+ if (typeof __contextProvider === "function") {
39
+ try {
40
+ const configuredContext = __normalizeContext(__contextProvider());
41
+ if (configuredContext) {
42
+ return configuredContext;
43
+ }
44
+ } catch (error) {}
45
+ }
46
+
47
+ const globalPDS = __resolveGlobalPDS();
48
+ if (globalPDS) {
49
+ const mode =
50
+ globalPDS?.mode ||
51
+ globalPDS?.compiled?.mode ||
52
+ (globalPDS?.registry?.isLive ? "live" : "static");
53
+ const debug =
54
+ (globalPDS?.debug ||
55
+ globalPDS?.currentConfig?.debug ||
56
+ globalPDS?.currentConfig?.design?.debug ||
57
+ globalPDS?.compiled?.debug ||
58
+ globalPDS?.compiled?.design?.debug ||
59
+ false) === true;
60
+ return {
61
+ mode,
62
+ debug,
63
+ thisArg: globalPDS,
64
+ };
65
+ }
66
+
67
+ return { mode: null, debug: false };
68
+ }
69
+
70
+ function __resolveLogger() {
71
+ if (typeof __logProvider === "function") {
72
+ try {
73
+ const logger = __logProvider();
74
+ if (typeof logger === "function") {
75
+ return logger;
76
+ }
77
+ } catch (error) {}
78
+ }
79
+
80
+ const globalPDS = __resolveGlobalPDS();
81
+ if (typeof globalPDS?.logHandler === "function") {
82
+ return globalPDS.logHandler;
83
+ }
84
+
85
+ return null;
86
+ }
87
+
88
+ function __consoleLog(level, message, ...data) {
89
+ if (typeof console === "undefined") return;
90
+ const method =
91
+ typeof console[level] === "function"
92
+ ? console[level].bind(console)
93
+ : typeof console.log === "function"
94
+ ? console.log.bind(console)
95
+ : null;
96
+ if (!method) return;
97
+
98
+ if (data.length > 0) {
99
+ method(message, ...data);
100
+ } else {
101
+ method(message);
102
+ }
103
+ }
104
+
105
+ function __shouldUseConsoleFallback(level, context) {
106
+ const debugEnabled = context?.debug === true;
107
+ const staticMode = context?.mode === "static";
108
+
109
+ if (staticMode && !debugEnabled) {
110
+ return false;
111
+ }
112
+
113
+ if (!debugEnabled && level !== "error" && level !== "warn") {
114
+ return false;
115
+ }
116
+
117
+ return true;
118
+ }
119
+
120
+ export function configurePDSLogger({ getLogger, getContext } = {}) {
121
+ __logProvider = typeof getLogger === "function" ? getLogger : null;
122
+ __contextProvider = typeof getContext === "function" ? getContext : null;
123
+ }
124
+
125
+ export function pdsLog(level = "log", message, ...data) {
126
+ const normalizedLevel = __normalizeLevel(level);
127
+ const context = __resolveContext();
128
+ const customLogger = __resolveLogger();
129
+
130
+ if (customLogger) {
131
+ try {
132
+ customLogger.call(context?.thisArg, normalizedLevel, message, ...data);
133
+ return;
134
+ } catch (error) {
135
+ __consoleLog("error", "Custom log handler failed:", error);
136
+ }
137
+ }
138
+
139
+ if (!__shouldUseConsoleFallback(normalizedLevel, context)) {
140
+ return;
141
+ }
142
+
143
+ __consoleLog(normalizedLevel, message, ...data);
144
+ }
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Toast notification utilities for PDS
3
+ * Ensures pds-toaster component is properly initialized before use
4
+ */
5
+
6
+ /**
7
+ * Ensures pds-toaster exists in DOM and is fully loaded
8
+ * @returns {Promise<HTMLElement>} The pds-toaster element
9
+ * @private
10
+ */
11
+ async function ensureToaster() {
12
+ let toaster = document.querySelector('pds-toaster');
13
+ if (!toaster) {
14
+ toaster = document.createElement('pds-toaster');
15
+ document.body.appendChild(toaster);
16
+ await customElements.whenDefined('pds-toaster');
17
+ }
18
+ return toaster;
19
+ }
20
+
21
+ /**
22
+ * Display a toast notification
23
+ *
24
+ * This method automatically ensures the pds-toaster component exists and is loaded
25
+ * before displaying the notification. The toaster element is appended to document.body
26
+ * if not already present.
27
+ *
28
+ * @param {string} message - The message to display
29
+ * @param {Object} [options={}] - Toast configuration
30
+ * @param {"information"|"success"|"warning"|"error"} [options.type="information"] - Toast type/severity
31
+ * @param {number} [options.duration] - Duration in milliseconds (auto-calculated if not provided based on message length)
32
+ * @param {boolean} [options.closable=true] - Whether the toast can be manually closed
33
+ * @param {boolean} [options.persistent=false] - If true, toast won't auto-dismiss (requires manual close)
34
+ * @param {boolean} [options.html=false] - Render `message` as HTML (trusted content only)
35
+ * @param {{label: string, onClick?: Function, dismissOnClick?: boolean}} [options.action] - Optional action button config
36
+ * @returns {Promise<string>} Toast ID (can be used to dismiss programmatically)
37
+ *
38
+ * @example
39
+ * // Simple success toast
40
+ * await PDS.toast('Changes saved successfully!', { type: 'success' });
41
+ *
42
+ * @example
43
+ * // Error with custom duration
44
+ * await PDS.toast('Failed to save changes', {
45
+ * type: 'error',
46
+ * duration: 8000
47
+ * });
48
+ *
49
+ * @example
50
+ * // Persistent warning (must be manually closed)
51
+ * await PDS.toast('This action cannot be undone', {
52
+ * type: 'warning',
53
+ * persistent: true
54
+ * });
55
+ *
56
+ * @example
57
+ * // Get toast ID to dismiss later
58
+ * const toastId = await PDS.toast('Processing...', { persistent: true });
59
+ * // ... later
60
+ * const toaster = document.querySelector('pds-toaster');
61
+ * toaster.dismissToast(toastId);
62
+ */
63
+ export async function toast(message, options = {}) {
64
+ const toaster = await ensureToaster();
65
+ return toaster.toast(message, options);
66
+ }
67
+
68
+ /**
69
+ * Display a success toast (convenience method)
70
+ *
71
+ * @param {string} message - The success message
72
+ * @param {Object} [options={}] - Additional toast options (type is preset to 'success')
73
+ * @returns {Promise<string>} Toast ID
74
+ *
75
+ * @example
76
+ * await PDS.toast.success('Profile updated!');
77
+ */
78
+ toast.success = async function(message, options = {}) {
79
+ return toast(message, { ...options, type: 'success' });
80
+ };
81
+
82
+ /**
83
+ * Display an error toast (convenience method)
84
+ *
85
+ * @param {string} message - The error message
86
+ * @param {Object} [options={}] - Additional toast options (type is preset to 'error')
87
+ * @returns {Promise<string>} Toast ID
88
+ *
89
+ * @example
90
+ * await PDS.toast.error('Failed to connect to server');
91
+ */
92
+ toast.error = async function(message, options = {}) {
93
+ return toast(message, { ...options, type: 'error' });
94
+ };
95
+
96
+ /**
97
+ * Display a warning toast (convenience method)
98
+ *
99
+ * @param {string} message - The warning message
100
+ * @param {Object} [options={}] - Additional toast options (type is preset to 'warning')
101
+ * @returns {Promise<string>} Toast ID
102
+ *
103
+ * @example
104
+ * await PDS.toast.warning('Session will expire in 5 minutes');
105
+ */
106
+ toast.warning = async function(message, options = {}) {
107
+ return toast(message, { ...options, type: 'warning' });
108
+ };
109
+
110
+ /**
111
+ * Display an information toast (convenience method)
112
+ *
113
+ * @param {string} message - The information message
114
+ * @param {Object} [options={}] - Additional toast options (type is preset to 'information')
115
+ * @returns {Promise<string>} Toast ID
116
+ *
117
+ * @example
118
+ * await PDS.toast.info('New features available!');
119
+ */
120
+ toast.info = async function(message, options = {}) {
121
+ return toast(message, { ...options, type: 'information' });
122
+ };
@@ -247,6 +247,24 @@ import { enums } from "./pds-enums.js";
247
247
  * @property {boolean} [debug]
248
248
  */
249
249
 
250
+ /**
251
+ * @typedef {Object} PDSLocalizationProvider
252
+ * @property {(context: { key: string, values: any[], options?: Record<string, any>, locale: string, defaultLocale: string, messages: Record<string, string>, messagesByLocale?: Record<string, Record<string, string>>, template?: { strings: string[], values: any[] } | null }) => (string | undefined | null)} [translate]
253
+ * @property {(context: { locale: string, defaultLocale: string, reason?: string, loadedLocales?: string[], messages?: Record<string, string>, load?: boolean }) => (Promise<Record<string, string | { content?: string }>> | Record<string, string | { content?: string }> | void)} [loadLocale]
254
+ * @property {(context: { locale: string, defaultLocale: string, reason?: string, loadedLocales?: string[], messages?: Record<string, string>, load?: boolean }) => (Promise<Record<string, string | { content?: string }>> | Record<string, string | { content?: string }> | void)} [setLocale]
255
+ */
256
+
257
+ /**
258
+ * @typedef {Object} PDSLocalizationConfig
259
+ * @property {string} [locale]
260
+ * @property {string[]} [locales]
261
+ * @property {Record<string, string | { content?: string }>} [messages]
262
+ * @property {PDSLocalizationProvider} [provider]
263
+ * @property {PDSLocalizationProvider["translate"]} [translate]
264
+ * @property {PDSLocalizationProvider["loadLocale"]} [loadLocale]
265
+ * @property {PDSLocalizationProvider["setLocale"]} [setLocale]
266
+ */
267
+
250
268
  /**
251
269
  * @typedef {Object} PDSInitConfig
252
270
  * @property {string} [mode]
@@ -262,6 +280,7 @@ import { enums } from "./pds-enums.js";
262
280
  * @property {string} [managerURL]
263
281
  * @property {any} [manager]
264
282
  * @property {boolean} [liveEdit]
283
+ * @property {PDSLocalizationConfig} [localization]
265
284
  * @property {any} [log]
266
285
  */
267
286
 
@@ -794,6 +813,19 @@ const __INIT_CONFIG_SPEC__ = {
794
813
  managerURL: { type: "string" },
795
814
  manager: { type: __ANY_TYPE__ },
796
815
  liveEdit: { type: "boolean" },
816
+ localization: {
817
+ type: "object",
818
+ allowUnknown: false,
819
+ properties: {
820
+ locale: { type: "string" },
821
+ locales: { type: "array", items: { type: "string" } },
822
+ messages: { type: "object", allowUnknown: true },
823
+ provider: { type: __ANY_TYPE__ },
824
+ translate: { type: __ANY_TYPE__ },
825
+ loadLocale: { type: __ANY_TYPE__ },
826
+ setLocale: { type: __ANY_TYPE__ },
827
+ },
828
+ },
797
829
  log: { type: __ANY_TYPE__ },
798
830
  },
799
831
  };
@@ -2641,15 +2673,24 @@ export const PDS_DEFAULT_CONFIG_FORM_SCHEMA = buildDesignConfigFormSchema(
2641
2673
  * @param {...any} data - additional data to log
2642
2674
  */
2643
2675
  export function defaultLog(level = "log", message, ...data) {
2644
- // Access debug from 'this' context when called as method, or check for common locations
2645
- const debug = this?.debug || this?.design?.debug || false;
2646
-
2647
- if (debug || level === "error" || level === "warn") {
2648
- const method = console[level] || console.log;
2649
- if (data.length > 0) {
2650
- method(message, ...data);
2651
- } else {
2652
- method(message);
2653
- }
2676
+ const runtimeLogger = globalThis?.PDS?.log;
2677
+ if (typeof runtimeLogger === "function") {
2678
+ runtimeLogger(level, message, ...data);
2679
+ return;
2680
+ }
2681
+
2682
+ if (typeof console === "undefined") return;
2683
+ const method =
2684
+ typeof console[level] === "function"
2685
+ ? console[level].bind(console)
2686
+ : typeof console.log === "function"
2687
+ ? console.log.bind(console)
2688
+ : null;
2689
+ if (!method) return;
2690
+
2691
+ if (data.length > 0) {
2692
+ method(message, ...data);
2693
+ } else {
2694
+ method(message);
2654
2695
  }
2655
2696
  }
@@ -1,3 +1,5 @@
1
+ import { msg } from "../common/localization.js";
2
+
1
3
  /**
2
4
  * PDS Enhancers - Single Source of Truth
3
5
  *
@@ -502,7 +504,7 @@ function enhanceColorInput(elem) {
502
504
 
503
505
  if (isUnset) {
504
506
  output.value = "";
505
- output.textContent = "not set";
507
+ output.textContent = msg("not set");
506
508
  control.dataset.value = "";
507
509
  control.dataset.unset = "1";
508
510
  swatch.dataset.unset = "1";
@@ -686,7 +688,7 @@ function enhanceRequired(elem) {
686
688
  if (form && !form.querySelector(".required-legend")) {
687
689
  const legend = document.createElement("small");
688
690
  legend.classList.add("required-legend");
689
- legend.textContent = "* Required fields";
691
+ legend.textContent = msg("* Required fields");
690
692
  form.insertBefore(
691
693
  legend,
692
694
  form.querySelector(".form-actions") || form.lastElementChild,
@@ -707,7 +709,7 @@ function enhanceOpenGroup(elem) {
707
709
 
708
710
  const addInput = document.createElement("input");
709
711
  addInput.type = "text";
710
- addInput.placeholder = "Add item...";
712
+ addInput.placeholder = msg("Add item...");
711
713
  addInput.classList.add("input-text", "input-sm");
712
714
  addInput.style.width = "auto";
713
715
 
@@ -751,7 +751,7 @@ async function __attachLiveAPIs(PDS, { applyResolvedTheme, setupSystemListenerIf
751
751
  PDS.applyLivePreset = async function(presetId, options = {}) {
752
752
  if (!presetId) return false;
753
753
  if (!PDS.registry?.isLive) {
754
- console.warn("PDS.applyLivePreset is only available in live mode.");
754
+ PDS.log("warn", "PDS.applyLivePreset is only available in live mode.");
755
755
  return false;
756
756
  }
757
757
 
@@ -775,7 +775,8 @@ async function __attachLiveAPIs(PDS, { applyResolvedTheme, setupSystemListenerIf
775
775
  normalized.presetInfo?.name ||
776
776
  normalized.generatorConfig?.design?.name ||
777
777
  presetId;
778
- console.warn(
778
+ PDS.log(
779
+ "warn",
779
780
  `PDS theme "${resolvedTheme}" not supported by preset "${presetName}".`
780
781
  );
781
782
  }
@@ -886,7 +887,7 @@ async function __attachLiveAPIs(PDS, { applyResolvedTheme, setupSystemListenerIf
886
887
  document.head.insertBefore(styleEl, document.head.firstChild);
887
888
  }
888
889
  } catch (error) {
889
- console.warn("PDS preload failed:", error);
890
+ PDS.log("warn", "PDS preload failed:", error);
890
891
  }
891
892
  };
892
893
 
@@ -947,7 +948,7 @@ export async function startLive(PDS, config, { emitReady, emitConfigChanged, app
947
948
  document.adoptedStyleSheets = [foucSheet, ...document.adoptedStyleSheets];
948
949
  }
949
950
  } catch (e) {
950
- console.warn("Constructable stylesheets not supported, using <style> tag fallback:", e);
951
+ PDS.log("warn", "Constructable stylesheets not supported, using <style> tag fallback:", e);
951
952
  const existingFoucStyle = document.head.querySelector("style[data-pds-fouc]");
952
953
  if (!existingFoucStyle) {
953
954
  const foucStyle = document.createElement("style");
@@ -989,7 +990,8 @@ export async function startLive(PDS, config, { emitReady, emitConfigChanged, app
989
990
  normalized.generatorConfig?.design?.name ||
990
991
  normalized.generatorConfig?.preset ||
991
992
  "current preset";
992
- console.warn(
993
+ PDS.log(
994
+ "warn",
993
995
  `PDS theme "${resolvedTheme}" not supported by preset "${presetName}".`
994
996
  );
995
997
  }
@@ -3,6 +3,8 @@
3
3
  // PDS REGISTRY - Global mode manager for live vs static mode
4
4
  // ============================================================================
5
5
 
6
+ import { PDS } from "../pds-singleton.js";
7
+
6
8
  class PDSRegistry {
7
9
  constructor() {
8
10
  this._mode = "static"; // Default to static mode
@@ -46,10 +48,10 @@ class PDSRegistry {
46
48
  const module = await import(/* @vite-ignore */ this._staticPaths[layer]);
47
49
  return module[layer]; // Return exported stylesheet
48
50
  } catch (error) {
49
- // No access to config in static mode, fall back to console
50
- console.error(`[PDS Registry] Failed to load static ${layer}:`, error);
51
- console.error(`[PDS Registry] Looking for: ${this._staticPaths[layer]}`);
52
- console.error(`[PDS Registry] Make sure you've run 'npm run pds:build' and configured PDS.start() with the correct static.root path`);
51
+ // Route through centralized logger fallback behavior
52
+ PDS.log("error", `Registry: failed to load static ${layer}:`, error);
53
+ PDS.log("error", `Registry: looking for ${this._staticPaths[layer]}`);
54
+ PDS.log("error", "Registry: make sure you've run 'npm run pds:build' and configured PDS.start() with the correct static.root path");
53
55
  // Return empty stylesheet as fallback
54
56
  const fallback = new CSSStyleSheet();
55
57
  fallback.replaceSync("/* Failed to load " + layer + " */");
@@ -4,6 +4,7 @@
4
4
  * generator bundle lean and optional.
5
5
  */
6
6
  import { registry as pdsRegistry } from "./pds-registry.js";
7
+ import { PDS } from "../pds-singleton.js";
7
8
 
8
9
  /**
9
10
  * Install runtime styles for PDS using constructable stylesheets when
@@ -48,7 +49,7 @@ export function installRuntimeStyles(cssText) {
48
49
  // Update the stylesheet content in place
49
50
  el.textContent = cssText;
50
51
  } catch (err) {
51
- console.warn("installRuntimeStyles failed:", err);
52
+ PDS.log("warn", "installRuntimeStyles failed:", err);
52
53
  }
53
54
  }
54
55
 
@@ -60,8 +61,9 @@ export function applyStyles(generator) {
60
61
  const target = generator;
61
62
 
62
63
  if (!target || typeof target !== "object") {
63
- console.error(
64
- "[Runtime] applyStyles requires an explicit generator instance in live mode"
64
+ PDS.log(
65
+ "error",
66
+ "Runtime applyStyles requires an explicit generator instance in live mode"
65
67
  );
66
68
  return;
67
69
  }
@@ -72,7 +74,7 @@ export function applyStyles(generator) {
72
74
  if (!cssText) {
73
75
  target.options?.log?.(
74
76
  "warn",
75
- "[Runtime] No CSS available on generator to apply"
77
+ "Runtime: no CSS available on generator to apply"
76
78
  );
77
79
  return;
78
80
  }
@@ -108,8 +110,9 @@ export async function adoptPrimitives(
108
110
  shadowRoot.adoptedStyleSheets = [primitives, ...additionalSheets];
109
111
  } catch (error) {
110
112
  const componentName = shadowRoot.host?.tagName?.toLowerCase() || "unknown";
111
- console.error(
112
- `[PDS Adopter] <${componentName}> failed to adopt primitives:`,
113
+ PDS.log(
114
+ "error",
115
+ `Adopter: <${componentName}> failed to adopt primitives:`,
113
116
  error
114
117
  );
115
118
  // Continue with just additional sheets as fallback
@@ -177,8 +180,9 @@ export async function adoptLayers(
177
180
  shadowRoot.adoptedStyleSheets = [...validStylesheets, ...safeAdditionalSheets];
178
181
  } catch (error) {
179
182
  const componentName = shadowRoot.host?.tagName?.toLowerCase() || "unknown";
180
- console.error(
181
- `[PDS Adopter] <${componentName}> failed to adopt layers:`,
183
+ PDS.log(
184
+ "error",
185
+ `Adopter: <${componentName}> failed to adopt layers:`,
182
186
  error
183
187
  );
184
188
  // Continue with just additional sheets as fallback