@pure-ds/storybook 0.4.23 → 0.4.25
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.
- package/dist/pds-reference.json +3 -3
- package/package.json +4 -4
- package/public/assets/js/app.js +13 -8
- package/public/assets/js/pds.js +14 -9
- package/public/assets/pds/components/pds-form.js +29 -8
- package/src/js/common/toast.js +120 -0
- package/src/js/pds-configurator/pds-config-form.js +12 -26
- package/src/js/pds-configurator/pds-demo.js +17 -22
- package/src/js/pds-core/pds-config.js +1 -2
- package/src/js/pds.d.ts +62 -0
- package/src/js/pds.js +23 -4
- package/stories/GettingStarted.md +27 -3
- package/stories/components/PdsForm.stories.js +4902 -4676
- package/stories/components/PdsFormUiSchema.md +1 -1
- package/stories/utils/toast-utils.js +2 -11
|
@@ -11,7 +11,7 @@ function getStep(value) {
|
|
|
11
11
|
// Default options for pds-form
|
|
12
12
|
const DEFAULT_OPTIONS = {
|
|
13
13
|
widgets: {
|
|
14
|
-
booleans: "toggle", // 'toggle' | 'checkbox'
|
|
14
|
+
booleans: "toggle", // 'toggle' | 'toggle-with-icons' | 'checkbox'
|
|
15
15
|
numbers: "input", // 'input' | 'range'
|
|
16
16
|
selects: "standard", // 'standard' | 'dropdown'
|
|
17
17
|
},
|
|
@@ -669,10 +669,9 @@ export class SchemaForm extends LitElement {
|
|
|
669
669
|
return useRange ? "input-range" : "input-number";
|
|
670
670
|
}
|
|
671
671
|
if (schema.type === "boolean") {
|
|
672
|
-
//
|
|
673
|
-
const
|
|
674
|
-
|
|
675
|
-
return useToggle ? "toggle" : "checkbox";
|
|
672
|
+
// Return the actual boolean widget type
|
|
673
|
+
const booleanWidget = this.#getOption("widgets.booleans", "toggle");
|
|
674
|
+
return booleanWidget === "checkbox" ? "checkbox" : booleanWidget;
|
|
676
675
|
}
|
|
677
676
|
return "input-text";
|
|
678
677
|
}
|
|
@@ -1489,14 +1488,20 @@ export class SchemaForm extends LitElement {
|
|
|
1489
1488
|
this.#emit("pw:after-render-field", { path, schema: node.schema })
|
|
1490
1489
|
);
|
|
1491
1490
|
|
|
1492
|
-
// Add data-toggle for toggle switches
|
|
1493
|
-
const isToggle = node.widgetKey === "toggle";
|
|
1491
|
+
// Add data-toggle for toggle switches (both toggle and toggle-with-icons)
|
|
1492
|
+
const isToggle = node.widgetKey === "toggle" || node.widgetKey === "toggle-with-icons";
|
|
1493
|
+
const useIconToggle = node.widgetKey === "toggle-with-icons";
|
|
1494
1494
|
|
|
1495
1495
|
// Add range-output class for range inputs if enabled
|
|
1496
1496
|
const isRange = node.widgetKey === "input-range";
|
|
1497
1497
|
const useRangeOutput =
|
|
1498
1498
|
isRange && this.#getOption("enhancements.rangeOutput", true);
|
|
1499
|
-
|
|
1499
|
+
|
|
1500
|
+
// Build class list for label
|
|
1501
|
+
const labelClasses = [];
|
|
1502
|
+
if (useRangeOutput) labelClasses.push("range-output");
|
|
1503
|
+
if (useIconToggle) labelClasses.push("with-icons");
|
|
1504
|
+
const labelClass = labelClasses.length > 0 ? labelClasses.join(" ") : undefined;
|
|
1500
1505
|
|
|
1501
1506
|
const renderControlAndLabel = (isToggle) => {
|
|
1502
1507
|
if (isToggle) return html`${controlTpl} <span data-label>${label}</span>`;
|
|
@@ -1855,6 +1860,22 @@ export class SchemaForm extends LitElement {
|
|
|
1855
1860
|
`
|
|
1856
1861
|
);
|
|
1857
1862
|
|
|
1863
|
+
// Toggle switch with icons (same as toggle, styling comes from .with-icons class on label)
|
|
1864
|
+
this.defineRenderer(
|
|
1865
|
+
"toggle-with-icons",
|
|
1866
|
+
({ id, path, value, attrs, set }) => html`
|
|
1867
|
+
<input
|
|
1868
|
+
id=${id}
|
|
1869
|
+
name=${path}
|
|
1870
|
+
type="checkbox"
|
|
1871
|
+
.checked=${!!value}
|
|
1872
|
+
?disabled=${!!attrs.disabled}
|
|
1873
|
+
?required=${!!attrs.required}
|
|
1874
|
+
@change=${(e) => set(!!e.target.checked)}
|
|
1875
|
+
/>
|
|
1876
|
+
`
|
|
1877
|
+
);
|
|
1878
|
+
|
|
1858
1879
|
this.defineRenderer(
|
|
1859
1880
|
"select",
|
|
1860
1881
|
({ id, path, value, attrs, set, schema, ui, host }) => {
|
|
@@ -0,0 +1,120 @@
|
|
|
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
|
+
* @returns {Promise<string>} Toast ID (can be used to dismiss programmatically)
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* // Simple success toast
|
|
38
|
+
* await PDS.toast('Changes saved successfully!', { type: 'success' });
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* // Error with custom duration
|
|
42
|
+
* await PDS.toast('Failed to save changes', {
|
|
43
|
+
* type: 'error',
|
|
44
|
+
* duration: 8000
|
|
45
|
+
* });
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* // Persistent warning (must be manually closed)
|
|
49
|
+
* await PDS.toast('This action cannot be undone', {
|
|
50
|
+
* type: 'warning',
|
|
51
|
+
* persistent: true
|
|
52
|
+
* });
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* // Get toast ID to dismiss later
|
|
56
|
+
* const toastId = await PDS.toast('Processing...', { persistent: true });
|
|
57
|
+
* // ... later
|
|
58
|
+
* const toaster = document.querySelector('pds-toaster');
|
|
59
|
+
* toaster.dismissToast(toastId);
|
|
60
|
+
*/
|
|
61
|
+
export async function toast(message, options = {}) {
|
|
62
|
+
const toaster = await ensureToaster();
|
|
63
|
+
return toaster.toast(message, options);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Display a success toast (convenience method)
|
|
68
|
+
*
|
|
69
|
+
* @param {string} message - The success message
|
|
70
|
+
* @param {Object} [options={}] - Additional toast options (type is preset to 'success')
|
|
71
|
+
* @returns {Promise<string>} Toast ID
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* await PDS.toast.success('Profile updated!');
|
|
75
|
+
*/
|
|
76
|
+
toast.success = async function(message, options = {}) {
|
|
77
|
+
return toast(message, { ...options, type: 'success' });
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Display an error toast (convenience method)
|
|
82
|
+
*
|
|
83
|
+
* @param {string} message - The error message
|
|
84
|
+
* @param {Object} [options={}] - Additional toast options (type is preset to 'error')
|
|
85
|
+
* @returns {Promise<string>} Toast ID
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* await PDS.toast.error('Failed to connect to server');
|
|
89
|
+
*/
|
|
90
|
+
toast.error = async function(message, options = {}) {
|
|
91
|
+
return toast(message, { ...options, type: 'error' });
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Display a warning toast (convenience method)
|
|
96
|
+
*
|
|
97
|
+
* @param {string} message - The warning message
|
|
98
|
+
* @param {Object} [options={}] - Additional toast options (type is preset to 'warning')
|
|
99
|
+
* @returns {Promise<string>} Toast ID
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* await PDS.toast.warning('Session will expire in 5 minutes');
|
|
103
|
+
*/
|
|
104
|
+
toast.warning = async function(message, options = {}) {
|
|
105
|
+
return toast(message, { ...options, type: 'warning' });
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Display an information toast (convenience method)
|
|
110
|
+
*
|
|
111
|
+
* @param {string} message - The information message
|
|
112
|
+
* @param {Object} [options={}] - Additional toast options (type is preset to 'information')
|
|
113
|
+
* @returns {Promise<string>} Toast ID
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* await PDS.toast.info('New features available!');
|
|
117
|
+
*/
|
|
118
|
+
toast.info = async function(message, options = {}) {
|
|
119
|
+
return toast(message, { ...options, type: 'information' });
|
|
120
|
+
};
|
|
@@ -9,20 +9,6 @@ import { AutoComplete } from "pure-web/ac";
|
|
|
9
9
|
import { figmafyTokens } from "./figma-export.js";
|
|
10
10
|
const STORAGE_KEY = "pure-ds-config";
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
async function toast(message, options = {}) {
|
|
15
|
-
let toaster = document.querySelector("#global-toaster");
|
|
16
|
-
if (!toaster) {
|
|
17
|
-
toaster = document.createElement("pds-toaster");
|
|
18
|
-
toaster.id = "global-toaster";
|
|
19
|
-
document.body.appendChild(toaster);
|
|
20
|
-
await customElements.whenDefined("pds-toaster");
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
return toaster.toast(message, options);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
12
|
customElements.define(
|
|
27
13
|
"pds-config-form",
|
|
28
14
|
class extends LitElement {
|
|
@@ -325,7 +311,7 @@ customElements.define(
|
|
|
325
311
|
.slice(0, 3)
|
|
326
312
|
.map((i) => `• ${i.message}`)
|
|
327
313
|
.join("\n");
|
|
328
|
-
this._validationToastId = toast(
|
|
314
|
+
this._validationToastId = await PDS.toast(
|
|
329
315
|
`Design has accessibility issues. Fix before applying.\n${summary}`,
|
|
330
316
|
{ type: "error", persistent: true }
|
|
331
317
|
);
|
|
@@ -408,11 +394,11 @@ customElements.define(
|
|
|
408
394
|
}
|
|
409
395
|
}
|
|
410
396
|
|
|
411
|
-
toggleInspectorMode() {
|
|
397
|
+
async toggleInspectorMode() {
|
|
412
398
|
this.inspectorMode = !this.inspectorMode;
|
|
413
399
|
this.dispatchInspectorModeChange();
|
|
414
400
|
|
|
415
|
-
toast(
|
|
401
|
+
await PDS.toast(
|
|
416
402
|
this.inspectorMode
|
|
417
403
|
? "Code Inspector active - click any element in the showcase to view its code"
|
|
418
404
|
: "Code Inspector deactivated",
|
|
@@ -485,7 +471,7 @@ customElements.define(
|
|
|
485
471
|
return filtered;
|
|
486
472
|
}
|
|
487
473
|
|
|
488
|
-
handleFormChange = (event) => {
|
|
474
|
+
handleFormChange = async (event) => {
|
|
489
475
|
// Get values from the pds-form's serialize method or from event detail
|
|
490
476
|
let values;
|
|
491
477
|
let changedField = null;
|
|
@@ -564,7 +550,7 @@ customElements.define(
|
|
|
564
550
|
.slice(0, 3)
|
|
565
551
|
.map((i) => `• ${i.message}`)
|
|
566
552
|
.join("\n");
|
|
567
|
-
this._validationToastId = toast(
|
|
553
|
+
this._validationToastId = await PDS.toast(
|
|
568
554
|
`Design has accessibility issues. Fix before saving.\n${summary}`,
|
|
569
555
|
{ type: "error" }
|
|
570
556
|
);
|
|
@@ -635,7 +621,7 @@ customElements.define(
|
|
|
635
621
|
this.saveConfig();
|
|
636
622
|
this.applyStyles(true);
|
|
637
623
|
|
|
638
|
-
toast("Configuration reset to defaults", {
|
|
624
|
+
await PDS.toast("Configuration reset to defaults", {
|
|
639
625
|
type: "info",
|
|
640
626
|
duration: 2000,
|
|
641
627
|
});
|
|
@@ -658,7 +644,7 @@ customElements.define(
|
|
|
658
644
|
.slice(0, 3)
|
|
659
645
|
.map((i) => `• ${i.message}`)
|
|
660
646
|
.join("\n");
|
|
661
|
-
this._validationToastId = toast(
|
|
647
|
+
this._validationToastId = await PDS.toast(
|
|
662
648
|
`Preset "${preset.name}" has accessibility issues — not applied.\n${summary}`,
|
|
663
649
|
{ type: "error", persistent: true }
|
|
664
650
|
);
|
|
@@ -685,14 +671,14 @@ customElements.define(
|
|
|
685
671
|
this.saveConfig();
|
|
686
672
|
this.applyStyles(true);
|
|
687
673
|
|
|
688
|
-
toast(`"${preset.name}" preset loaded successfully!`, {
|
|
674
|
+
await PDS.toast(`"${preset.name}" preset loaded successfully!`, {
|
|
689
675
|
type: "success",
|
|
690
676
|
duration: 3000,
|
|
691
677
|
});
|
|
692
678
|
}
|
|
693
679
|
};
|
|
694
680
|
|
|
695
|
-
handleThemeChange(e) {
|
|
681
|
+
async handleThemeChange(e) {
|
|
696
682
|
try {
|
|
697
683
|
const value = e.target.value;
|
|
698
684
|
// Update centralized theme via PDS (this persists + applies + sets up listeners)
|
|
@@ -701,7 +687,7 @@ customElements.define(
|
|
|
701
687
|
// Apply immediately and emit styles using the user config (keep config separate)
|
|
702
688
|
this.applyStyles(true);
|
|
703
689
|
|
|
704
|
-
toast(`Theme set to ${value}`, { type: "info", duration: 1200 });
|
|
690
|
+
await PDS.toast(`Theme set to ${value}`, { type: "info", duration: 1200 });
|
|
705
691
|
} catch (ex) {
|
|
706
692
|
console.warn("Failed to change theme:", ex);
|
|
707
693
|
}
|
|
@@ -750,9 +736,9 @@ export const pdsConfig = ${JSON.stringify(this.config, null, 2)};
|
|
|
750
736
|
if (!this.schema) {
|
|
751
737
|
if (!this._loadingToastShown) {
|
|
752
738
|
this._loadingToastShown = true;
|
|
753
|
-
setTimeout(() => {
|
|
739
|
+
setTimeout(async () => {
|
|
754
740
|
try {
|
|
755
|
-
toast("Loading schema...", { duration: 1000 });
|
|
741
|
+
await PDS.toast("Loading schema...", { duration: 1000 });
|
|
756
742
|
} catch {}
|
|
757
743
|
}, 250);
|
|
758
744
|
}
|
|
@@ -3,11 +3,6 @@ import { PDS } from "../../../src/js/pds.js";
|
|
|
3
3
|
|
|
4
4
|
import { AutoComplete } from "pure-web/ac";
|
|
5
5
|
|
|
6
|
-
const toast = (message, options) => {
|
|
7
|
-
const toaster = document.getElementById("global-toaster");
|
|
8
|
-
toaster.toast(message, options);
|
|
9
|
-
};
|
|
10
|
-
|
|
11
6
|
customElements.define(
|
|
12
7
|
"pds-demo",
|
|
13
8
|
class extends LitElement {
|
|
@@ -3414,12 +3409,12 @@ customElements.define(
|
|
|
3414
3409
|
} catch (err) {
|
|
3415
3410
|
console.error("Error fetching README:", err);
|
|
3416
3411
|
const toaster = document.getElementById("global-toaster");
|
|
3417
|
-
|
|
3412
|
+
await PDS.toast("Error loading docs. See console.", { type: "error" });
|
|
3418
3413
|
}
|
|
3419
3414
|
}
|
|
3420
3415
|
|
|
3421
3416
|
handleTabChange(event) {
|
|
3422
|
-
toast(`Switched to tab: ${event.detail.newTab}`, { type: "info" });
|
|
3417
|
+
await PDS.toast(`Switched to tab: ${event.detail.newTab}`, { type: "info" });
|
|
3423
3418
|
}
|
|
3424
3419
|
|
|
3425
3420
|
openDrawer() {
|
|
@@ -3502,42 +3497,42 @@ customElements.define(
|
|
|
3502
3497
|
}
|
|
3503
3498
|
|
|
3504
3499
|
// Toast handler methods
|
|
3505
|
-
showSuccessToast() {
|
|
3506
|
-
toast("Your changes have been saved successfully!", {
|
|
3500
|
+
async showSuccessToast() {
|
|
3501
|
+
await PDS.toast("Your changes have been saved successfully!", {
|
|
3507
3502
|
type: "success",
|
|
3508
3503
|
});
|
|
3509
3504
|
}
|
|
3510
3505
|
|
|
3511
|
-
showInfoToast() {
|
|
3512
|
-
toast("This is an informational message with helpful context.", {
|
|
3513
|
-
type: "
|
|
3506
|
+
async showInfoToast() {
|
|
3507
|
+
await PDS.toast("This is an informational message with helpful context.", {
|
|
3508
|
+
type: "information",
|
|
3514
3509
|
});
|
|
3515
3510
|
}
|
|
3516
3511
|
|
|
3517
|
-
showWarningToast() {
|
|
3518
|
-
toast("Warning: This action cannot be undone!", {
|
|
3512
|
+
async showWarningToast() {
|
|
3513
|
+
await PDS.toast("Warning: This action cannot be undone!", {
|
|
3519
3514
|
type: "warning",
|
|
3520
3515
|
});
|
|
3521
3516
|
}
|
|
3522
3517
|
|
|
3523
|
-
showErrorToast() {
|
|
3524
|
-
toast("Error: Something went wrong. Please try again.", {
|
|
3518
|
+
async showErrorToast() {
|
|
3519
|
+
await PDS.toast("Error: Something went wrong. Please try again.", {
|
|
3525
3520
|
type: "error",
|
|
3526
3521
|
});
|
|
3527
3522
|
}
|
|
3528
3523
|
|
|
3529
|
-
showLongToast() {
|
|
3530
|
-
toast(
|
|
3524
|
+
async showLongToast() {
|
|
3525
|
+
await PDS.toast(
|
|
3531
3526
|
"This is a longer toast notification message that demonstrates how the duration is automatically calculated based on the message length. The toast will stay visible longer to give you enough time to read the entire message.",
|
|
3532
|
-
{ type: "
|
|
3527
|
+
{ type: "information" }
|
|
3533
3528
|
);
|
|
3534
3529
|
}
|
|
3535
3530
|
|
|
3536
|
-
showPersistentToast() {
|
|
3537
|
-
toast(
|
|
3531
|
+
async showPersistentToast() {
|
|
3532
|
+
await PDS.toast(
|
|
3538
3533
|
"This is a persistent toast that won't auto-dismiss. Click the × to close it.",
|
|
3539
3534
|
{
|
|
3540
|
-
type: "
|
|
3535
|
+
type: "information",
|
|
3541
3536
|
persistent: true,
|
|
3542
3537
|
}
|
|
3543
3538
|
);
|
|
@@ -737,7 +737,6 @@ export const presets = {
|
|
|
737
737
|
"Data-dense business intelligence app interface with organized hierarchy and professional polish",
|
|
738
738
|
options: {
|
|
739
739
|
liquidGlassEffects: false,
|
|
740
|
-
backgroundMesh: 2,
|
|
741
740
|
},
|
|
742
741
|
colors: {
|
|
743
742
|
primary: "#0066cc", // corporate blue for primary actions
|
|
@@ -815,7 +814,7 @@ presets.default = {
|
|
|
815
814
|
form: {
|
|
816
815
|
options: {
|
|
817
816
|
widgets: {
|
|
818
|
-
booleans: "toggle", // 'toggle' | 'checkbox'
|
|
817
|
+
booleans: "toggle", // 'toggle' | 'toggle-with-icons' | 'checkbox'
|
|
819
818
|
numbers: "input", // 'input' | 'range'
|
|
820
819
|
selects: "standard", // 'standard' | 'dropdown'
|
|
821
820
|
},
|
package/src/js/pds.d.ts
CHANGED
|
@@ -154,6 +154,68 @@ export class PDS extends EventTarget {
|
|
|
154
154
|
static validateDesign: (designConfig: any, options?: { minContrast?: number }) => { ok: boolean; issues: Array<{ path: string; message: string; ratio: number; min: number; context?: string }> };
|
|
155
155
|
static validateDesigns: (designs: Array<any> | Record<string, any>, options?: { minContrast?: number }) => { ok: boolean; results: Array<{ name?: string; ok: boolean; issues: Array<{ path: string; message: string; ratio: number; min: number; context?: string }> }> };
|
|
156
156
|
|
|
157
|
+
/**
|
|
158
|
+
* Display a toast notification.
|
|
159
|
+
*
|
|
160
|
+
* Automatically ensures the pds-toaster component exists and is loaded before displaying.
|
|
161
|
+
*
|
|
162
|
+
* @param message - The message to display
|
|
163
|
+
* @param options - Toast configuration
|
|
164
|
+
* @param options.type - Toast type/severity ("information" | "success" | "warning" | "error")
|
|
165
|
+
* @param options.duration - Duration in milliseconds (auto-calculated if not provided)
|
|
166
|
+
* @param options.closable - Whether toast can be manually closed (default: true)
|
|
167
|
+
* @param options.persistent - If true, toast won't auto-dismiss (default: false)
|
|
168
|
+
* @returns Toast ID (can be used to dismiss programmatically)
|
|
169
|
+
*
|
|
170
|
+
* @example
|
|
171
|
+
* await PDS.toast('Changes saved!', { type: 'success' });
|
|
172
|
+
*
|
|
173
|
+
* @example
|
|
174
|
+
* await PDS.toast('Error occurred', { type: 'error', persistent: true });
|
|
175
|
+
*/
|
|
176
|
+
static toast(
|
|
177
|
+
message: string,
|
|
178
|
+
options?: {
|
|
179
|
+
type?: 'information' | 'success' | 'warning' | 'error';
|
|
180
|
+
duration?: number;
|
|
181
|
+
closable?: boolean;
|
|
182
|
+
persistent?: boolean;
|
|
183
|
+
}
|
|
184
|
+
): Promise<string>;
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Display a success toast (convenience method).
|
|
188
|
+
*
|
|
189
|
+
* @param message - The success message
|
|
190
|
+
* @param options - Additional toast options (type is preset to 'success')
|
|
191
|
+
* @returns Toast ID
|
|
192
|
+
*
|
|
193
|
+
* @example
|
|
194
|
+
* await PDS.toast.success('Profile updated!');
|
|
195
|
+
*/
|
|
196
|
+
static toast: {
|
|
197
|
+
(message: string, options?: { type?: 'information' | 'success' | 'warning' | 'error'; duration?: number; closable?: boolean; persistent?: boolean }): Promise<string>;
|
|
198
|
+
success(message: string, options?: { duration?: number; closable?: boolean; persistent?: boolean }): Promise<string>;
|
|
199
|
+
error(message: string, options?: { duration?: number; closable?: boolean; persistent?: boolean }): Promise<string>;
|
|
200
|
+
warning(message: string, options?: { duration?: number; closable?: boolean; persistent?: boolean }): Promise<string>;
|
|
201
|
+
info(message: string, options?: { duration?: number; closable?: boolean; persistent?: boolean }): Promise<string>;
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Display a modal dialog for user input or confirmation.
|
|
206
|
+
*
|
|
207
|
+
* @param message - The message or prompt to display
|
|
208
|
+
* @param options - Dialog configuration
|
|
209
|
+
* @returns User's response (string for prompt, boolean for confirm, true for alert)
|
|
210
|
+
*
|
|
211
|
+
* @example
|
|
212
|
+
* const confirmed = await PDS.ask('Delete this item?', { type: 'confirm' });
|
|
213
|
+
*
|
|
214
|
+
* @example
|
|
215
|
+
* const name = await PDS.ask('Enter your name:', { type: 'prompt' });
|
|
216
|
+
*/
|
|
217
|
+
static ask(message: string, options?: any): Promise<any>;
|
|
218
|
+
|
|
157
219
|
/**
|
|
158
220
|
* Current configuration after PDS.start() completes - read-only, frozen after initialization.
|
|
159
221
|
* Contains the complete configuration used to initialize PDS, including mode, design, preset, and theme.
|
package/src/js/pds.js
CHANGED
|
@@ -56,6 +56,7 @@ import { findComponentForElement } from "./pds-core/pds-ontology.js";
|
|
|
56
56
|
import { presets, defaultLog } from "./pds-core/pds-config.js";
|
|
57
57
|
import { enums } from "./pds-core/pds-enums.js";
|
|
58
58
|
import { ask } from "./common/ask.js";
|
|
59
|
+
import { toast } from "./common/toast.js";
|
|
59
60
|
import { PDSQuery } from "./pds-core/pds-query.js";
|
|
60
61
|
import * as common from "./common/common.js";
|
|
61
62
|
import { defaultPDSEnhancers } from "./pds-core/pds-enhancers.js";
|
|
@@ -87,6 +88,7 @@ PDS.isLiveMode = () => registry.isLive;
|
|
|
87
88
|
PDS.enums = enums;
|
|
88
89
|
|
|
89
90
|
PDS.ask = ask;
|
|
91
|
+
PDS.toast = toast;
|
|
90
92
|
|
|
91
93
|
// Expose common utilities (deepMerge, isObject, etc.)
|
|
92
94
|
PDS.common = common;
|
|
@@ -961,10 +963,27 @@ async function __setupAutoDefinerAndEnhancers(options) {
|
|
|
961
963
|
enhancers: mergedEnhancers,
|
|
962
964
|
onError: (tag, err) => {
|
|
963
965
|
if (typeof tag === "string" && tag.startsWith("pds-")) {
|
|
964
|
-
//
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
)
|
|
966
|
+
// Check if this is a Lit-dependent component with missing #pds/lit import map
|
|
967
|
+
const litDependentComponents = ['pds-form', 'pds-drawer'];
|
|
968
|
+
const isLitComponent = litDependentComponents.includes(tag);
|
|
969
|
+
const isMissingLitError = err?.message?.includes('#pds/lit') ||
|
|
970
|
+
err?.message?.includes('Failed to resolve module specifier');
|
|
971
|
+
|
|
972
|
+
if (isLitComponent && isMissingLitError) {
|
|
973
|
+
console.error(
|
|
974
|
+
`❌ PDS component <${tag}> requires Lit but #pds/lit is not in import map.\n` +
|
|
975
|
+
`Add this to your HTML <head>:\n` +
|
|
976
|
+
`<script type="importmap">\n` +
|
|
977
|
+
` { "imports": { "#pds/lit": "./path/to/lit.js" } }\n` +
|
|
978
|
+
`</script>\n` +
|
|
979
|
+
`See: https://github.com/pure-ds/core#lit-components`
|
|
980
|
+
);
|
|
981
|
+
} else {
|
|
982
|
+
// Generic component not found warning
|
|
983
|
+
console.warn(
|
|
984
|
+
`⚠️ PDS component <${tag}> not found. Assets may not be installed.`
|
|
985
|
+
);
|
|
986
|
+
}
|
|
968
987
|
} else {
|
|
969
988
|
console.error(`❌ Auto-define error for <${tag}>:`, err);
|
|
970
989
|
}
|
|
@@ -10,12 +10,26 @@ From zero to hero with PDS.
|
|
|
10
10
|
npm install @pure-ds/core
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
**What happens during install:**
|
|
14
|
+
|
|
15
|
+
PDS automatically sets up your project:
|
|
16
|
+
- ✅ Creates `pds.config.js` with commented examples (if it doesn't exist)
|
|
17
|
+
- ✅ Exports static assets to your web root (components, icons, styles)
|
|
18
|
+
- ✅ Copies AI/Copilot instructions to `.github/copilot-instructions.md`
|
|
19
|
+
- ✅ Adds helper scripts to your `package.json` (`pds:export`, `pds:build-icons`)
|
|
20
|
+
|
|
21
|
+
The generated `pds.config.js` includes:
|
|
14
22
|
|
|
15
23
|
```javascript
|
|
24
|
+
// pds.config.js (auto-generated)
|
|
16
25
|
export const config = {
|
|
17
26
|
mode: "live",
|
|
18
|
-
preset: "default"
|
|
27
|
+
preset: "default",
|
|
28
|
+
|
|
29
|
+
// Uncomment and customize as needed:
|
|
30
|
+
// design: { colors: { primary: '#007acc' } },
|
|
31
|
+
// enhancers: [ /* custom enhancements */ ],
|
|
32
|
+
// autoDefine: { predefine: ['pds-icon'] }
|
|
19
33
|
}
|
|
20
34
|
```
|
|
21
35
|
|
|
@@ -23,11 +37,21 @@ Then initialize in your app:
|
|
|
23
37
|
|
|
24
38
|
```javascript
|
|
25
39
|
import { PDS } from '@pure-ds/core';
|
|
26
|
-
import { config } from "
|
|
40
|
+
import { config } from "./pds.config.js"; // project root
|
|
27
41
|
|
|
28
42
|
await PDS.start(config); // That's it! Start writing semantic HTML.
|
|
29
43
|
```
|
|
30
44
|
|
|
45
|
+
**Manual config generation:**
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
# Create or regenerate config with examples
|
|
49
|
+
npx pds-init-config
|
|
50
|
+
|
|
51
|
+
# Force overwrite existing config
|
|
52
|
+
npx pds-init-config --force
|
|
53
|
+
```
|
|
54
|
+
|
|
31
55
|
### Option B: CDN (Zero Install)
|
|
32
56
|
|
|
33
57
|
Perfect for quick prototypes and learning:
|