@pure-ds/storybook 0.4.19 → 0.4.21
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/.storybook/addons/html-preview/preview.js +82 -5
- package/dist/pds-reference.json +1 -1
- package/package.json +2 -2
- package/public/assets/js/app.js +20 -7
- package/public/assets/js/pds.js +20 -7
- package/public/assets/pds/components/pds-form.js +30 -8
- package/src/js/pds-core/pds-generator.js +20 -7
- package/stories/components/PdsForm.stories.js +454 -134
|
@@ -146,6 +146,57 @@ function serializeForDisplay(value) {
|
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
+
/**
|
|
150
|
+
* Generate realistic source code for pds-form elements
|
|
151
|
+
*/
|
|
152
|
+
function generatePdsFormMarkup(formElement) {
|
|
153
|
+
const attrs = [];
|
|
154
|
+
|
|
155
|
+
// Check for properties
|
|
156
|
+
if (formElement.jsonSchema) {
|
|
157
|
+
attrs.push('.jsonSchema=${schema}');
|
|
158
|
+
}
|
|
159
|
+
if (formElement.uiSchema) {
|
|
160
|
+
attrs.push('.uiSchema=${uiSchema}');
|
|
161
|
+
}
|
|
162
|
+
if (formElement.values) {
|
|
163
|
+
attrs.push('.values=${values}');
|
|
164
|
+
}
|
|
165
|
+
if (formElement.options && Object.keys(formElement.options).length > 0) {
|
|
166
|
+
attrs.push('.options=${options}');
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Check for common event listeners by looking at the element's event listeners
|
|
170
|
+
// Since we can't easily detect event listeners, we'll check common patterns
|
|
171
|
+
const hasSubmitHandler = formElement.getAttribute('data-has-submit') !== null || true; // Assume submit handler
|
|
172
|
+
if (hasSubmitHandler) {
|
|
173
|
+
attrs.push('@pw:submit=${(e) => handleSubmit(e.detail)}');
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Check for boolean attributes
|
|
177
|
+
if (formElement.hasAttribute('data-required')) {
|
|
178
|
+
attrs.push('data-required');
|
|
179
|
+
}
|
|
180
|
+
if (formElement.hasAttribute('hide-actions')) {
|
|
181
|
+
attrs.push('hide-actions');
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const formattedAttrs = attrs.length > 0
|
|
185
|
+
? '\n ' + attrs.join('\n ') + '\n'
|
|
186
|
+
: '';
|
|
187
|
+
|
|
188
|
+
// Check for slotted content
|
|
189
|
+
const slots = formElement.querySelectorAll('[slot]');
|
|
190
|
+
let slotContent = '';
|
|
191
|
+
if (slots.length > 0) {
|
|
192
|
+
slotContent = '\n ' + Array.from(slots).map(slot => {
|
|
193
|
+
return `<div slot="${slot.getAttribute('slot')}">\n <!-- slotted content -->\n </div>`;
|
|
194
|
+
}).join('\n ') + '\n';
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
return `<pds-form${formattedAttrs}>${slotContent}</pds-form>`;
|
|
198
|
+
}
|
|
199
|
+
|
|
149
200
|
/**
|
|
150
201
|
* Global decorator that extracts and sends HTML to the panel
|
|
151
202
|
*/
|
|
@@ -160,18 +211,44 @@ export const withHTMLExtractor = (storyFn, context) => {
|
|
|
160
211
|
// Try to get HTML from the story container
|
|
161
212
|
const container = document.querySelector('#storybook-root');
|
|
162
213
|
if (container) {
|
|
163
|
-
if
|
|
164
|
-
|
|
214
|
+
// Check if this story has pds-form elements
|
|
215
|
+
const pdsFormElements = Array.from(container.querySelectorAll('pds-form'));
|
|
216
|
+
|
|
217
|
+
if (pdsFormElements.length > 0) {
|
|
218
|
+
// Generate realistic markup for pds-form stories
|
|
219
|
+
const alerts = Array.from(container.querySelectorAll('.alert'));
|
|
220
|
+
let markup = '';
|
|
221
|
+
|
|
222
|
+
// Include any alert/info boxes before the form
|
|
223
|
+
if (alerts.length > 0) {
|
|
224
|
+
alerts.forEach(alert => {
|
|
225
|
+
markup += `<div class="alert ${alert.className.split(' ').filter(c => c !== 'alert').join(' ')}">\n`;
|
|
226
|
+
markup += ` ${alert.innerHTML.replace(/\n\s+/g, '\n ')}\n`;
|
|
227
|
+
markup += `</div>\n\n`;
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// Add pds-form markup
|
|
232
|
+
pdsFormElements.forEach(form => {
|
|
233
|
+
markup += generatePdsFormMarkup(form);
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
html = markup;
|
|
165
237
|
} else {
|
|
166
|
-
|
|
238
|
+
// No pds-form elements, use standard extraction
|
|
239
|
+
if (story && story._$litType$) {
|
|
240
|
+
html = await litToHTML(story);
|
|
241
|
+
} else {
|
|
242
|
+
html = formatHTML(extractHTML(container));
|
|
243
|
+
}
|
|
167
244
|
}
|
|
168
245
|
|
|
169
|
-
const forms =
|
|
246
|
+
const forms = pdsFormElements
|
|
170
247
|
.map((form, index) => {
|
|
171
248
|
const label =
|
|
172
249
|
form.getAttribute?.('id') ||
|
|
173
250
|
form.getAttribute?.('name') ||
|
|
174
|
-
(
|
|
251
|
+
(pdsFormElements.length > 1 ? `Form ${index + 1}` : 'Form');
|
|
175
252
|
|
|
176
253
|
const jsonSchema = serializeForDisplay(form.jsonSchema);
|
|
177
254
|
const uiSchema = serializeForDisplay(form.uiSchema);
|
package/dist/pds-reference.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pure-ds/storybook",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.21",
|
|
4
4
|
"description": "Storybook showcase for Pure Design System with live configuration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"private": false,
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"pds:build-icons": "pds-build-icons"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
|
-
"@pure-ds/core": "^0.4.
|
|
40
|
+
"@pure-ds/core": "^0.4.21"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"@custom-elements-manifest/analyzer": "^0.11.0",
|
package/public/assets/js/app.js
CHANGED
|
@@ -645,6 +645,10 @@ fieldset {
|
|
|
645
645
|
color: var(--color-primary-700);
|
|
646
646
|
}
|
|
647
647
|
}
|
|
648
|
+
|
|
649
|
+
input[type="checkbox"]{
|
|
650
|
+
border-radius: var(--radius-xs);
|
|
651
|
+
}
|
|
648
652
|
|
|
649
653
|
input[type="radio"],
|
|
650
654
|
input[type="checkbox"] {
|
|
@@ -653,18 +657,27 @@ fieldset {
|
|
|
653
657
|
width: var(--spacing-5);
|
|
654
658
|
height: var(--spacing-5);
|
|
655
659
|
min-height: var(--spacing-5);
|
|
660
|
+
padding: var(--spacing-2);
|
|
656
661
|
margin: 0;
|
|
657
662
|
cursor: pointer;
|
|
658
663
|
flex-shrink: 0;
|
|
659
664
|
accent-color: var(--color-primary-600);
|
|
660
|
-
|
|
661
|
-
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
665
|
+
|
|
666
|
+
&:focus-visible {
|
|
667
|
+
outline: none;
|
|
668
|
+
|
|
669
|
+
box-shadow:
|
|
670
|
+
0 0 0 2px var(--color-primary-500),
|
|
671
|
+
0 0 0 4px color-mix(in srgb,
|
|
672
|
+
var(--color-primary-500) 40%,
|
|
673
|
+
transparent
|
|
674
|
+
);
|
|
667
675
|
}
|
|
676
|
+
|
|
677
|
+
&:checked {
|
|
678
|
+
background-color: var(--color-primary-600);
|
|
679
|
+
}
|
|
680
|
+
|
|
668
681
|
}
|
|
669
682
|
}
|
|
670
683
|
|
package/public/assets/js/pds.js
CHANGED
|
@@ -643,6 +643,10 @@ fieldset {
|
|
|
643
643
|
color: var(--color-primary-700);
|
|
644
644
|
}
|
|
645
645
|
}
|
|
646
|
+
|
|
647
|
+
input[type="checkbox"]{
|
|
648
|
+
border-radius: var(--radius-xs);
|
|
649
|
+
}
|
|
646
650
|
|
|
647
651
|
input[type="radio"],
|
|
648
652
|
input[type="checkbox"] {
|
|
@@ -651,18 +655,27 @@ fieldset {
|
|
|
651
655
|
width: var(--spacing-5);
|
|
652
656
|
height: var(--spacing-5);
|
|
653
657
|
min-height: var(--spacing-5);
|
|
658
|
+
padding: var(--spacing-2);
|
|
654
659
|
margin: 0;
|
|
655
660
|
cursor: pointer;
|
|
656
661
|
flex-shrink: 0;
|
|
657
662
|
accent-color: var(--color-primary-600);
|
|
658
|
-
|
|
659
|
-
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
663
|
+
|
|
664
|
+
&:focus-visible {
|
|
665
|
+
outline: none;
|
|
666
|
+
|
|
667
|
+
box-shadow:
|
|
668
|
+
0 0 0 2px var(--color-primary-500),
|
|
669
|
+
0 0 0 4px color-mix(in srgb,
|
|
670
|
+
var(--color-primary-500) 40%,
|
|
671
|
+
transparent
|
|
672
|
+
);
|
|
665
673
|
}
|
|
674
|
+
|
|
675
|
+
&:checked {
|
|
676
|
+
background-color: var(--color-primary-600);
|
|
677
|
+
}
|
|
678
|
+
|
|
666
679
|
}
|
|
667
680
|
}
|
|
668
681
|
|
|
@@ -1116,6 +1116,7 @@ export class SchemaForm extends LitElement {
|
|
|
1116
1116
|
this.#deleteByPathPrefix(this.#data, path + "/");
|
|
1117
1117
|
this.requestUpdate();
|
|
1118
1118
|
this.#emit("pw:value-change", {
|
|
1119
|
+
path,
|
|
1119
1120
|
name: path,
|
|
1120
1121
|
value: i,
|
|
1121
1122
|
validity: { valid: true },
|
|
@@ -1865,7 +1866,6 @@ export class SchemaForm extends LitElement {
|
|
|
1865
1866
|
<select
|
|
1866
1867
|
id=${id}
|
|
1867
1868
|
name=${path}
|
|
1868
|
-
.value=${value ?? ""}
|
|
1869
1869
|
?disabled=${!!attrs.disabled}
|
|
1870
1870
|
?required=${!!attrs.required}
|
|
1871
1871
|
?data-dropdown=${useDropdown}
|
|
@@ -1874,7 +1874,7 @@ export class SchemaForm extends LitElement {
|
|
|
1874
1874
|
<option value="" ?selected=${value == null}>—</option>
|
|
1875
1875
|
${enumValues.map(
|
|
1876
1876
|
(v, i) =>
|
|
1877
|
-
html`<option value=${String(v)}>
|
|
1877
|
+
html`<option value=${String(v)} ?selected=${String(value) === String(v)}>
|
|
1878
1878
|
${String(enumLabels[i])}
|
|
1879
1879
|
</option>`
|
|
1880
1880
|
)}
|
|
@@ -2092,17 +2092,28 @@ export class SchemaForm extends LitElement {
|
|
|
2092
2092
|
const withoutSlash = path.startsWith("/") ? path.substring(1) : path;
|
|
2093
2093
|
if (this.uiSchema[withoutSlash]) return this.uiSchema[withoutSlash];
|
|
2094
2094
|
|
|
2095
|
-
// Try nested navigation (e.g.,
|
|
2095
|
+
// Try nested navigation (e.g., /accountType/companyName)
|
|
2096
2096
|
// Skip array indices (numeric parts and wildcard *) when navigating UI schema
|
|
2097
2097
|
const parts = path.replace(/^\//, "").split("/");
|
|
2098
2098
|
let current = this.uiSchema;
|
|
2099
|
-
for (
|
|
2099
|
+
for (let i = 0; i < parts.length; i++) {
|
|
2100
|
+
const part = parts[i];
|
|
2100
2101
|
// Skip numeric array indices and wildcard in UI schema navigation
|
|
2101
2102
|
if (/^\d+$/.test(part) || part === "*") continue;
|
|
2102
2103
|
|
|
2104
|
+
// Try both with and without leading slash for each segment
|
|
2103
2105
|
if (current && typeof current === "object" && part in current) {
|
|
2104
2106
|
current = current[part];
|
|
2107
|
+
} else if (current && typeof current === "object" && ("/" + part) in current) {
|
|
2108
|
+
current = current["/" + part];
|
|
2105
2109
|
} else {
|
|
2110
|
+
// If this is the first segment, try looking up the full path from root
|
|
2111
|
+
if (i === 0) {
|
|
2112
|
+
const fullPath = "/" + parts.join("/");
|
|
2113
|
+
if (this.uiSchema[fullPath]) {
|
|
2114
|
+
return this.uiSchema[fullPath];
|
|
2115
|
+
}
|
|
2116
|
+
}
|
|
2106
2117
|
return undefined;
|
|
2107
2118
|
}
|
|
2108
2119
|
}
|
|
@@ -2227,17 +2238,23 @@ export class SchemaForm extends LitElement {
|
|
|
2227
2238
|
this.#setByPath(this.#data, path, val);
|
|
2228
2239
|
|
|
2229
2240
|
// Apply calculated values for any dependent fields
|
|
2230
|
-
|
|
2241
|
+
// This will call requestUpdate() if there are dependents
|
|
2242
|
+
const hadDependents = this.#applyCalculatedValues(path);
|
|
2243
|
+
|
|
2244
|
+
// Only request update here if there were no dependents
|
|
2245
|
+
// (to avoid double render)
|
|
2246
|
+
if (!hadDependents) {
|
|
2247
|
+
this.requestUpdate();
|
|
2248
|
+
}
|
|
2231
2249
|
|
|
2232
|
-
this.requestUpdate();
|
|
2233
2250
|
const validity = { valid: true };
|
|
2234
|
-
this.#emit("pw:value-change", { name: path, value: val, validity });
|
|
2251
|
+
this.#emit("pw:value-change", { path, name: path, value: val, validity });
|
|
2235
2252
|
}
|
|
2236
2253
|
|
|
2237
2254
|
#applyCalculatedValues(changedPath) {
|
|
2238
2255
|
// Find fields that depend on the changed path
|
|
2239
2256
|
const dependents = this.#dependencies.get(changedPath);
|
|
2240
|
-
if (!dependents) return;
|
|
2257
|
+
if (!dependents || dependents.size === 0) return false;
|
|
2241
2258
|
|
|
2242
2259
|
for (const targetPath of dependents) {
|
|
2243
2260
|
const ui = this.#uiFor(targetPath);
|
|
@@ -2255,6 +2272,11 @@ export class SchemaForm extends LitElement {
|
|
|
2255
2272
|
}
|
|
2256
2273
|
}
|
|
2257
2274
|
}
|
|
2275
|
+
|
|
2276
|
+
// Force re-render since there were dependents
|
|
2277
|
+
// This ensures ui:visibleWhen, ui:requiredWhen, ui:disabledWhen get re-evaluated
|
|
2278
|
+
this.requestUpdate();
|
|
2279
|
+
return true; // Indicate that we triggered a re-render
|
|
2258
2280
|
}
|
|
2259
2281
|
|
|
2260
2282
|
#getByPath(obj, path) {
|
|
@@ -1838,6 +1838,10 @@ fieldset {
|
|
|
1838
1838
|
color: var(--color-primary-700);
|
|
1839
1839
|
}
|
|
1840
1840
|
}
|
|
1841
|
+
|
|
1842
|
+
input[type="checkbox"]{
|
|
1843
|
+
border-radius: var(--radius-xs);
|
|
1844
|
+
}
|
|
1841
1845
|
|
|
1842
1846
|
input[type="radio"],
|
|
1843
1847
|
input[type="checkbox"] {
|
|
@@ -1846,18 +1850,27 @@ fieldset {
|
|
|
1846
1850
|
width: var(--spacing-5);
|
|
1847
1851
|
height: var(--spacing-5);
|
|
1848
1852
|
min-height: var(--spacing-5);
|
|
1853
|
+
padding: var(--spacing-2);
|
|
1849
1854
|
margin: 0;
|
|
1850
1855
|
cursor: pointer;
|
|
1851
1856
|
flex-shrink: 0;
|
|
1852
1857
|
accent-color: var(--color-primary-600);
|
|
1853
|
-
|
|
1854
|
-
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1858
|
+
|
|
1859
|
+
&:focus-visible {
|
|
1860
|
+
outline: none;
|
|
1861
|
+
|
|
1862
|
+
box-shadow:
|
|
1863
|
+
0 0 0 2px var(--color-primary-500),
|
|
1864
|
+
0 0 0 4px color-mix(in srgb,
|
|
1865
|
+
var(--color-primary-500) 40%,
|
|
1866
|
+
transparent
|
|
1867
|
+
);
|
|
1860
1868
|
}
|
|
1869
|
+
|
|
1870
|
+
&:checked {
|
|
1871
|
+
background-color: var(--color-primary-600);
|
|
1872
|
+
}
|
|
1873
|
+
|
|
1861
1874
|
}
|
|
1862
1875
|
}
|
|
1863
1876
|
|
|
@@ -1020,6 +1020,151 @@ export const WithGridLayout = {
|
|
|
1020
1020
|
},
|
|
1021
1021
|
};
|
|
1022
1022
|
|
|
1023
|
+
export const WithGridLayoutAuto = {
|
|
1024
|
+
name: "Grid Layout - Auto",
|
|
1025
|
+
parameters: {
|
|
1026
|
+
docs: {
|
|
1027
|
+
description: {
|
|
1028
|
+
story: `Auto-fit grid layout that automatically adjusts the number of columns based on available space and minimum column width.
|
|
1029
|
+
|
|
1030
|
+
This is the **PDS way** to create responsive grids without media queries. Use \`columns: "auto"\` with \`autoSize\` to specify the minimum column width.
|
|
1031
|
+
|
|
1032
|
+
### Usage Example
|
|
1033
|
+
|
|
1034
|
+
\`\`\`html
|
|
1035
|
+
<pds-form
|
|
1036
|
+
.jsonSchema=\${schema}
|
|
1037
|
+
.uiSchema=\${uiSchema}
|
|
1038
|
+
.options=\${options}
|
|
1039
|
+
@pw:submit=\${(e) => toastFormData(e.detail)}
|
|
1040
|
+
></pds-form>
|
|
1041
|
+
|
|
1042
|
+
<script type="module">
|
|
1043
|
+
import { html } from 'lit';
|
|
1044
|
+
|
|
1045
|
+
const schema = {
|
|
1046
|
+
type: "object",
|
|
1047
|
+
properties: {
|
|
1048
|
+
productInfo: {
|
|
1049
|
+
type: "object",
|
|
1050
|
+
title: "Product Information",
|
|
1051
|
+
properties: {
|
|
1052
|
+
name: { type: "string", title: "Product Name" },
|
|
1053
|
+
sku: { type: "string", title: "SKU" },
|
|
1054
|
+
price: { type: "number", title: "Price" },
|
|
1055
|
+
// ... more fields
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
};
|
|
1060
|
+
|
|
1061
|
+
const uiSchema = {
|
|
1062
|
+
productInfo: {
|
|
1063
|
+
"ui:layout": "grid",
|
|
1064
|
+
"ui:layoutOptions": {
|
|
1065
|
+
columns: "auto", // Auto-fit columns
|
|
1066
|
+
autoSize: "md", // Min width ~200px (grid-auto-md)
|
|
1067
|
+
gap: "md"
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
};
|
|
1071
|
+
|
|
1072
|
+
const options = {
|
|
1073
|
+
widgets: { booleans: "toggle" }
|
|
1074
|
+
};
|
|
1075
|
+
</script>
|
|
1076
|
+
\`\`\`
|
|
1077
|
+
|
|
1078
|
+
### Available sizes:
|
|
1079
|
+
- \`"sm"\` → ~150px minimum width
|
|
1080
|
+
- \`"md"\` → ~200px minimum width
|
|
1081
|
+
- \`"lg"\` → ~250px minimum width
|
|
1082
|
+
- \`"xl"\` → ~300px minimum width
|
|
1083
|
+
|
|
1084
|
+
The grid automatically creates as many columns as will fit, wrapping to new rows when needed. **No JavaScript required!**`,
|
|
1085
|
+
},
|
|
1086
|
+
},
|
|
1087
|
+
},
|
|
1088
|
+
render: () => {
|
|
1089
|
+
const schema = {
|
|
1090
|
+
type: "object",
|
|
1091
|
+
properties: {
|
|
1092
|
+
productInfo: {
|
|
1093
|
+
type: "object",
|
|
1094
|
+
title: "Product Information",
|
|
1095
|
+
properties: {
|
|
1096
|
+
name: {
|
|
1097
|
+
type: "string",
|
|
1098
|
+
title: "Product Name",
|
|
1099
|
+
examples: ["Wireless Headphones"],
|
|
1100
|
+
},
|
|
1101
|
+
sku: { type: "string", title: "SKU", examples: ["WH-1000XM4"] },
|
|
1102
|
+
price: { type: "number", title: "Price", examples: [299.99] },
|
|
1103
|
+
quantity: { type: "integer", title: "Quantity", examples: [50] },
|
|
1104
|
+
category: {
|
|
1105
|
+
type: "string",
|
|
1106
|
+
title: "Category",
|
|
1107
|
+
enum: [
|
|
1108
|
+
"Electronics",
|
|
1109
|
+
"Clothing",
|
|
1110
|
+
"Books",
|
|
1111
|
+
"Home",
|
|
1112
|
+
"Sports",
|
|
1113
|
+
"Garden",
|
|
1114
|
+
],
|
|
1115
|
+
},
|
|
1116
|
+
brand: { type: "string", title: "Brand", examples: ["Sony"] },
|
|
1117
|
+
weight: { type: "number", title: "Weight (kg)", examples: [0.25] },
|
|
1118
|
+
dimensions: {
|
|
1119
|
+
type: "string",
|
|
1120
|
+
title: "Dimensions",
|
|
1121
|
+
examples: ["20 x 18 x 8 cm"],
|
|
1122
|
+
},
|
|
1123
|
+
inStock: {
|
|
1124
|
+
type: "boolean",
|
|
1125
|
+
title: "In Stock",
|
|
1126
|
+
default: true,
|
|
1127
|
+
},
|
|
1128
|
+
featured: {
|
|
1129
|
+
type: "boolean",
|
|
1130
|
+
title: "Featured Product",
|
|
1131
|
+
default: false,
|
|
1132
|
+
},
|
|
1133
|
+
},
|
|
1134
|
+
},
|
|
1135
|
+
},
|
|
1136
|
+
};
|
|
1137
|
+
|
|
1138
|
+
const uiSchema = {
|
|
1139
|
+
productInfo: {
|
|
1140
|
+
"ui:layout": "grid",
|
|
1141
|
+
"ui:layoutOptions": {
|
|
1142
|
+
columns: "auto", // Auto-fit columns
|
|
1143
|
+
autoSize: "md", // Min column width (grid-auto-md)
|
|
1144
|
+
gap: "md"
|
|
1145
|
+
},
|
|
1146
|
+
},
|
|
1147
|
+
};
|
|
1148
|
+
|
|
1149
|
+
const options = {
|
|
1150
|
+
widgets: { booleans: "toggle" },
|
|
1151
|
+
};
|
|
1152
|
+
|
|
1153
|
+
return html`
|
|
1154
|
+
<div class="alert alert-info">
|
|
1155
|
+
<p><strong>💡 Try resizing your browser window!</strong></p>
|
|
1156
|
+
<p>The grid automatically adjusts the number of columns based on available space. Fields maintain a minimum width of ~200px and wrap to new rows as needed.</p>
|
|
1157
|
+
</div>
|
|
1158
|
+
<pds-form
|
|
1159
|
+
.jsonSchema=${schema}
|
|
1160
|
+
.uiSchema=${uiSchema}
|
|
1161
|
+
.options=${options}
|
|
1162
|
+
@pw:submit=${(e) => toastFormData(e.detail)}
|
|
1163
|
+
></pds-form>
|
|
1164
|
+
`;
|
|
1165
|
+
},
|
|
1166
|
+
};
|
|
1167
|
+
|
|
1023
1168
|
export const WithAccordionLayout = {
|
|
1024
1169
|
name: "Accordion Layout",
|
|
1025
1170
|
render: () => {
|
|
@@ -2698,6 +2843,136 @@ const uiSchema = {
|
|
|
2698
2843
|
},
|
|
2699
2844
|
};
|
|
2700
2845
|
|
|
2846
|
+
export const OneOfWithPresetValues = {
|
|
2847
|
+
parameters: {
|
|
2848
|
+
docs: {
|
|
2849
|
+
description: {
|
|
2850
|
+
story: `Demonstrates that \`oneOf\` and \`anyOf\` select fields correctly display preset values.
|
|
2851
|
+
|
|
2852
|
+
This story showcases the fix for a bug where select dropdowns wouldn't show the selected value when using \`.values\` to preset form data.
|
|
2853
|
+
|
|
2854
|
+
### Example Schema:
|
|
2855
|
+
\`\`\`javascript
|
|
2856
|
+
{
|
|
2857
|
+
organizationType: {
|
|
2858
|
+
oneOf: [
|
|
2859
|
+
{ const: "ngo", title: "Non-Governmental Organization" },
|
|
2860
|
+
{ const: "charity", title: "Charitable Organization" },
|
|
2861
|
+
{ const: "company", title: "Commercial Company" }
|
|
2862
|
+
]
|
|
2863
|
+
}
|
|
2864
|
+
}
|
|
2865
|
+
\`\`\`
|
|
2866
|
+
|
|
2867
|
+
### Preset Values:
|
|
2868
|
+
\`\`\`javascript
|
|
2869
|
+
<pds-form
|
|
2870
|
+
.values=$\{{ organizationType: "charity", category: "health" }}
|
|
2871
|
+
...
|
|
2872
|
+
>
|
|
2873
|
+
\`\`\`
|
|
2874
|
+
|
|
2875
|
+
The dropdowns should correctly show "Charitable Organization" and "Health & Medical" as selected.`,
|
|
2876
|
+
},
|
|
2877
|
+
source: {
|
|
2878
|
+
code: `<pds-form
|
|
2879
|
+
data-required
|
|
2880
|
+
.jsonSchema=\${schema}
|
|
2881
|
+
.uiSchema=\${uiSchema}
|
|
2882
|
+
.values=\${initialValues}
|
|
2883
|
+
@pw:submit=\${(e) => toastFormData(e.detail)}
|
|
2884
|
+
></pds-form>`,
|
|
2885
|
+
},
|
|
2886
|
+
},
|
|
2887
|
+
},
|
|
2888
|
+
render: () => {
|
|
2889
|
+
const schema = {
|
|
2890
|
+
type: "object",
|
|
2891
|
+
title: "Organization Registration",
|
|
2892
|
+
properties: {
|
|
2893
|
+
organizationName: {
|
|
2894
|
+
type: "string",
|
|
2895
|
+
title: "Organization Name",
|
|
2896
|
+
examples: ["Red Cross International"],
|
|
2897
|
+
},
|
|
2898
|
+
organizationType: {
|
|
2899
|
+
type: "string",
|
|
2900
|
+
title: "Organization Type",
|
|
2901
|
+
oneOf: [
|
|
2902
|
+
{ const: "ngo", title: "Non-Governmental Organization" },
|
|
2903
|
+
{ const: "charity", title: "Charitable Organization" },
|
|
2904
|
+
{ const: "company", title: "Commercial Company" },
|
|
2905
|
+
{ const: "government", title: "Government Agency" },
|
|
2906
|
+
{ const: "educational", title: "Educational Institution" },
|
|
2907
|
+
],
|
|
2908
|
+
},
|
|
2909
|
+
category: {
|
|
2910
|
+
type: "string",
|
|
2911
|
+
title: "Primary Category",
|
|
2912
|
+
anyOf: [
|
|
2913
|
+
{ const: "health", title: "Health & Medical" },
|
|
2914
|
+
{ const: "education", title: "Education & Research" },
|
|
2915
|
+
{ const: "environment", title: "Environment & Conservation" },
|
|
2916
|
+
{ const: "social", title: "Social Services" },
|
|
2917
|
+
{ const: "arts", title: "Arts & Culture" },
|
|
2918
|
+
{ const: "technology", title: "Technology & Innovation" },
|
|
2919
|
+
],
|
|
2920
|
+
},
|
|
2921
|
+
registrationNumber: {
|
|
2922
|
+
type: "string",
|
|
2923
|
+
title: "Registration Number",
|
|
2924
|
+
examples: ["123-456-789"],
|
|
2925
|
+
},
|
|
2926
|
+
country: {
|
|
2927
|
+
type: "string",
|
|
2928
|
+
title: "Country",
|
|
2929
|
+
enum: ["NL", "BE", "DE", "FR", "GB"],
|
|
2930
|
+
},
|
|
2931
|
+
},
|
|
2932
|
+
required: ["organizationName", "organizationType", "category"],
|
|
2933
|
+
};
|
|
2934
|
+
|
|
2935
|
+
const uiSchema = {
|
|
2936
|
+
"ui:layout": "grid",
|
|
2937
|
+
"ui:layoutOptions": {
|
|
2938
|
+
columns: "auto", // Auto-fit columns
|
|
2939
|
+
autoSize: "md", // Min column width (grid-auto-md)
|
|
2940
|
+
gap: "md"
|
|
2941
|
+
}
|
|
2942
|
+
};
|
|
2943
|
+
|
|
2944
|
+
// Preset values that should be correctly selected in the dropdowns
|
|
2945
|
+
const initialValues = {
|
|
2946
|
+
organizationName: "Global Health Foundation",
|
|
2947
|
+
organizationType: "charity",
|
|
2948
|
+
category: "health",
|
|
2949
|
+
registrationNumber: "974983702",
|
|
2950
|
+
country: "NL",
|
|
2951
|
+
};
|
|
2952
|
+
|
|
2953
|
+
return html`
|
|
2954
|
+
<div class="alert alert-info">
|
|
2955
|
+
<p>
|
|
2956
|
+
<strong>✓ This form has preset values:</strong> The dropdowns should
|
|
2957
|
+
correctly show "Charitable Organization", "Health & Medical", and
|
|
2958
|
+
"NL" as selected.
|
|
2959
|
+
</p>
|
|
2960
|
+
<p>
|
|
2961
|
+
Try changing the values and submitting to see how oneOf/anyOf/enum
|
|
2962
|
+
work together.
|
|
2963
|
+
</p>
|
|
2964
|
+
</div>
|
|
2965
|
+
<pds-form
|
|
2966
|
+
data-required
|
|
2967
|
+
.jsonSchema=${schema}
|
|
2968
|
+
.uiSchema=${uiSchema}
|
|
2969
|
+
.values=${initialValues}
|
|
2970
|
+
@pw:submit=${(e) => toastFormData(e.detail)}
|
|
2971
|
+
></pds-form>
|
|
2972
|
+
`;
|
|
2973
|
+
},
|
|
2974
|
+
};
|
|
2975
|
+
|
|
2701
2976
|
export const ConditionalRequired = {
|
|
2702
2977
|
parameters: {
|
|
2703
2978
|
docs: {
|
|
@@ -2770,13 +3045,16 @@ export const ConditionalComplex = {
|
|
|
2770
3045
|
parameters: {
|
|
2771
3046
|
docs: {
|
|
2772
3047
|
description: {
|
|
2773
|
-
story: `A comprehensive example combining multiple conditional features
|
|
3048
|
+
story: `A comprehensive example combining multiple conditional features with accordion layout to reduce visual complexity.
|
|
2774
3049
|
|
|
2775
3050
|
### Features demonstrated:
|
|
2776
|
-
- **
|
|
3051
|
+
- **Accordion Sections**: Related fields grouped into collapsible sections
|
|
3052
|
+
- **Show/Hide**: Business account section appears only for business accounts; shipping address hidden for pickup
|
|
2777
3053
|
- **Conditional Required**: Company name required for business; phone required when preferred
|
|
2778
3054
|
- **Disable**: Email disabled when phone is preferred
|
|
2779
|
-
- **Calculations**: Full name, subtotal, shipping cost, and total are all computed automatically
|
|
3055
|
+
- **Calculations**: Full name, subtotal, shipping cost, and total are all computed automatically
|
|
3056
|
+
|
|
3057
|
+
The accordion layout prevents awkward field jumping between columns and makes the form easier to navigate.`,
|
|
2780
3058
|
},
|
|
2781
3059
|
},
|
|
2782
3060
|
},
|
|
@@ -2786,143 +3064,191 @@ export const ConditionalComplex = {
|
|
|
2786
3064
|
title: "Order Form",
|
|
2787
3065
|
properties: {
|
|
2788
3066
|
accountType: {
|
|
2789
|
-
type: "
|
|
3067
|
+
type: "object",
|
|
2790
3068
|
title: "Account Type",
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
email: {
|
|
2808
|
-
type: "string",
|
|
2809
|
-
format: "email",
|
|
2810
|
-
title: "Email",
|
|
2811
|
-
examples: ["you@example.com"],
|
|
2812
|
-
},
|
|
2813
|
-
phone: {
|
|
2814
|
-
type: "string",
|
|
2815
|
-
title: "Phone",
|
|
2816
|
-
examples: ["555-123-4567"],
|
|
2817
|
-
},
|
|
2818
|
-
firstName: {
|
|
2819
|
-
type: "string",
|
|
2820
|
-
title: "First Name",
|
|
2821
|
-
examples: ["John"],
|
|
2822
|
-
},
|
|
2823
|
-
lastName: {
|
|
2824
|
-
type: "string",
|
|
2825
|
-
title: "Last Name",
|
|
2826
|
-
examples: ["Doe"],
|
|
2827
|
-
},
|
|
2828
|
-
fullName: {
|
|
2829
|
-
type: "string",
|
|
2830
|
-
title: "Full Name (calculated)",
|
|
2831
|
-
},
|
|
2832
|
-
deliveryType: {
|
|
2833
|
-
type: "string",
|
|
2834
|
-
title: "Delivery Type",
|
|
2835
|
-
oneOf: [
|
|
2836
|
-
{ const: "standard", title: "Standard (5-7 days)" },
|
|
2837
|
-
{ const: "express", title: "Express (1-2 days)" },
|
|
2838
|
-
{ const: "pickup", title: "Pickup" },
|
|
2839
|
-
],
|
|
2840
|
-
default: "standard",
|
|
2841
|
-
},
|
|
2842
|
-
quantity: {
|
|
2843
|
-
type: "integer",
|
|
2844
|
-
title: "Quantity",
|
|
2845
|
-
minimum: 1,
|
|
2846
|
-
default: 1,
|
|
2847
|
-
},
|
|
2848
|
-
unitPrice: {
|
|
2849
|
-
type: "number",
|
|
2850
|
-
title: "Unit Price",
|
|
2851
|
-
default: 29.99,
|
|
2852
|
-
},
|
|
2853
|
-
subtotal: {
|
|
2854
|
-
type: "number",
|
|
2855
|
-
title: "Subtotal",
|
|
3069
|
+
properties: {
|
|
3070
|
+
type: {
|
|
3071
|
+
type: "string",
|
|
3072
|
+
title: "Select Account Type",
|
|
3073
|
+
oneOf: [
|
|
3074
|
+
{ const: "personal", title: "Personal" },
|
|
3075
|
+
{ const: "business", title: "Business" },
|
|
3076
|
+
],
|
|
3077
|
+
default: "personal",
|
|
3078
|
+
},
|
|
3079
|
+
companyName: {
|
|
3080
|
+
type: "string",
|
|
3081
|
+
title: "Company Name",
|
|
3082
|
+
examples: ["Acme Inc."],
|
|
3083
|
+
},
|
|
3084
|
+
},
|
|
2856
3085
|
},
|
|
2857
|
-
|
|
2858
|
-
type: "
|
|
2859
|
-
title: "
|
|
3086
|
+
contactPreferences: {
|
|
3087
|
+
type: "object",
|
|
3088
|
+
title: "Contact Information",
|
|
3089
|
+
properties: {
|
|
3090
|
+
preferPhone: {
|
|
3091
|
+
type: "boolean",
|
|
3092
|
+
title: "I prefer to be contacted by phone",
|
|
3093
|
+
default: false,
|
|
3094
|
+
},
|
|
3095
|
+
email: {
|
|
3096
|
+
type: "string",
|
|
3097
|
+
format: "email",
|
|
3098
|
+
title: "Email",
|
|
3099
|
+
examples: ["you@example.com"],
|
|
3100
|
+
},
|
|
3101
|
+
phone: {
|
|
3102
|
+
type: "string",
|
|
3103
|
+
title: "Phone",
|
|
3104
|
+
examples: ["555-123-4567"],
|
|
3105
|
+
},
|
|
3106
|
+
},
|
|
2860
3107
|
},
|
|
2861
|
-
|
|
2862
|
-
type: "
|
|
2863
|
-
title: "
|
|
3108
|
+
customerDetails: {
|
|
3109
|
+
type: "object",
|
|
3110
|
+
title: "Customer Details",
|
|
3111
|
+
properties: {
|
|
3112
|
+
firstName: {
|
|
3113
|
+
type: "string",
|
|
3114
|
+
title: "First Name",
|
|
3115
|
+
examples: ["John"],
|
|
3116
|
+
},
|
|
3117
|
+
lastName: {
|
|
3118
|
+
type: "string",
|
|
3119
|
+
title: "Last Name",
|
|
3120
|
+
examples: ["Doe"],
|
|
3121
|
+
},
|
|
3122
|
+
fullName: {
|
|
3123
|
+
type: "string",
|
|
3124
|
+
title: "Full Name (calculated)",
|
|
3125
|
+
},
|
|
3126
|
+
},
|
|
2864
3127
|
},
|
|
2865
|
-
|
|
3128
|
+
deliveryOptions: {
|
|
2866
3129
|
type: "object",
|
|
2867
|
-
title: "Shipping
|
|
3130
|
+
title: "Delivery & Shipping",
|
|
2868
3131
|
properties: {
|
|
2869
|
-
|
|
3132
|
+
deliveryType: {
|
|
2870
3133
|
type: "string",
|
|
2871
|
-
title: "
|
|
2872
|
-
|
|
3134
|
+
title: "Delivery Type",
|
|
3135
|
+
oneOf: [
|
|
3136
|
+
{ const: "standard", title: "Standard (5-7 days)" },
|
|
3137
|
+
{ const: "express", title: "Express (1-2 days)" },
|
|
3138
|
+
{ const: "pickup", title: "Pickup" },
|
|
3139
|
+
],
|
|
3140
|
+
default: "standard",
|
|
3141
|
+
},
|
|
3142
|
+
shippingAddress: {
|
|
3143
|
+
type: "object",
|
|
3144
|
+
title: "Shipping Address",
|
|
3145
|
+
properties: {
|
|
3146
|
+
street: {
|
|
3147
|
+
type: "string",
|
|
3148
|
+
title: "Street",
|
|
3149
|
+
examples: ["123 Main St"],
|
|
3150
|
+
},
|
|
3151
|
+
city: { type: "string", title: "City", examples: ["New York"] },
|
|
3152
|
+
zip: { type: "string", title: "ZIP Code", examples: ["10001"] },
|
|
3153
|
+
},
|
|
3154
|
+
},
|
|
3155
|
+
},
|
|
3156
|
+
},
|
|
3157
|
+
orderCalculations: {
|
|
3158
|
+
type: "object",
|
|
3159
|
+
title: "Order Summary",
|
|
3160
|
+
properties: {
|
|
3161
|
+
quantity: {
|
|
3162
|
+
type: "integer",
|
|
3163
|
+
title: "Quantity",
|
|
3164
|
+
minimum: 1,
|
|
3165
|
+
default: 1,
|
|
3166
|
+
},
|
|
3167
|
+
unitPrice: {
|
|
3168
|
+
type: "number",
|
|
3169
|
+
title: "Unit Price",
|
|
3170
|
+
default: 29.99,
|
|
3171
|
+
},
|
|
3172
|
+
subtotal: {
|
|
3173
|
+
type: "number",
|
|
3174
|
+
title: "Subtotal",
|
|
3175
|
+
},
|
|
3176
|
+
shippingCost: {
|
|
3177
|
+
type: "number",
|
|
3178
|
+
title: "Shipping Cost",
|
|
3179
|
+
},
|
|
3180
|
+
total: {
|
|
3181
|
+
type: "number",
|
|
3182
|
+
title: "Total",
|
|
2873
3183
|
},
|
|
2874
|
-
city: { type: "string", title: "City", examples: ["New York"] },
|
|
2875
|
-
zip: { type: "string", title: "ZIP Code", examples: ["10001"] },
|
|
2876
3184
|
},
|
|
2877
3185
|
},
|
|
2878
3186
|
},
|
|
2879
|
-
required: ["
|
|
3187
|
+
required: ["contactPreferences", "customerDetails", "deliveryOptions"],
|
|
2880
3188
|
};
|
|
2881
3189
|
|
|
2882
3190
|
const uiSchema = {
|
|
2883
|
-
"ui:layout": "
|
|
2884
|
-
"ui:layoutOptions": {
|
|
3191
|
+
"ui:layout": "accordion",
|
|
3192
|
+
"ui:layoutOptions": { openFirst: true },
|
|
2885
3193
|
|
|
2886
|
-
"/
|
|
2887
|
-
"ui:
|
|
2888
|
-
"
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
"ui:icon": "envelope",
|
|
2893
|
-
},
|
|
2894
|
-
"/phone": {
|
|
2895
|
-
"ui:requiredWhen": { "/preferPhone": true },
|
|
2896
|
-
"ui:icon": "phone",
|
|
2897
|
-
},
|
|
2898
|
-
"/fullName": {
|
|
2899
|
-
"ui:calculate": { $concat: ["/firstName", " ", "/lastName"] },
|
|
3194
|
+
"/accountType": {
|
|
3195
|
+
"ui:layout": "stack",
|
|
3196
|
+
"companyName": {
|
|
3197
|
+
"ui:visibleWhen": { "/accountType/type": "business" },
|
|
3198
|
+
"ui:requiredWhen": { "/accountType/type": "business" },
|
|
3199
|
+
},
|
|
2900
3200
|
},
|
|
2901
|
-
"/
|
|
2902
|
-
"ui:
|
|
3201
|
+
"/contactPreferences": {
|
|
3202
|
+
"ui:layout": "stack",
|
|
3203
|
+
"email": {
|
|
3204
|
+
"ui:disabledWhen": { "/contactPreferences/preferPhone": true },
|
|
3205
|
+
"ui:icon": "envelope",
|
|
3206
|
+
},
|
|
3207
|
+
"phone": {
|
|
3208
|
+
"ui:requiredWhen": { "/contactPreferences/preferPhone": true },
|
|
3209
|
+
"ui:icon": "phone",
|
|
3210
|
+
},
|
|
2903
3211
|
},
|
|
2904
|
-
"/
|
|
2905
|
-
"ui:
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
3212
|
+
"/customerDetails": {
|
|
3213
|
+
"ui:layout": "flex",
|
|
3214
|
+
"ui:layoutOptions": { gap: "md", wrap: true },
|
|
3215
|
+
"firstName": {},
|
|
3216
|
+
"lastName": {},
|
|
3217
|
+
"fullName": {
|
|
3218
|
+
"ui:calculate": { $concat: ["/customerDetails/firstName", " ", "/customerDetails/lastName"] },
|
|
3219
|
+
},
|
|
3220
|
+
},
|
|
3221
|
+
"/deliveryOptions": {
|
|
3222
|
+
"ui:layout": "stack",
|
|
3223
|
+
"shippingAddress": {
|
|
3224
|
+
"ui:visibleWhen": { "/deliveryOptions/deliveryType": { $ne: "pickup" } },
|
|
3225
|
+
"ui:layout": "flex",
|
|
3226
|
+
"ui:layoutOptions": { gap: "sm", wrap: true },
|
|
3227
|
+
},
|
|
3228
|
+
},
|
|
3229
|
+
"/orderCalculations": {
|
|
3230
|
+
"ui:layout": "stack",
|
|
3231
|
+
"subtotal": {
|
|
3232
|
+
"ui:calculate": { $multiply: ["/orderCalculations/quantity", "/orderCalculations/unitPrice"] },
|
|
3233
|
+
},
|
|
3234
|
+
"shippingCost": {
|
|
3235
|
+
"ui:calculate": {
|
|
3236
|
+
$if: {
|
|
3237
|
+
cond: { "/deliveryOptions/deliveryType": "express" },
|
|
3238
|
+
then: 25,
|
|
3239
|
+
else: {
|
|
3240
|
+
$if: {
|
|
3241
|
+
cond: { "/deliveryOptions/deliveryType": "pickup" },
|
|
3242
|
+
then: 0,
|
|
3243
|
+
else: 10,
|
|
3244
|
+
},
|
|
2914
3245
|
},
|
|
2915
3246
|
},
|
|
2916
3247
|
},
|
|
2917
3248
|
},
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
},
|
|
2922
|
-
"/shippingAddress": {
|
|
2923
|
-
"ui:visibleWhen": { "/deliveryType": { $ne: "pickup" } },
|
|
2924
|
-
"ui:layout": "flex",
|
|
2925
|
-
"ui:layoutOptions": { gap: "sm", wrap: true },
|
|
3249
|
+
"total": {
|
|
3250
|
+
"ui:calculate": { $sum: ["/orderCalculations/subtotal", "/orderCalculations/shippingCost"] },
|
|
3251
|
+
},
|
|
2926
3252
|
},
|
|
2927
3253
|
};
|
|
2928
3254
|
|
|
@@ -2931,28 +3257,19 @@ export const ConditionalComplex = {
|
|
|
2931
3257
|
<p><strong>Try these interactions:</strong></p>
|
|
2932
3258
|
<ul>
|
|
2933
3259
|
<li>
|
|
2934
|
-
|
|
2935
|
-
field appears and becomes required
|
|
2936
|
-
</li>
|
|
2937
|
-
<li>
|
|
2938
|
-
Toggle <strong>"Prefer phone contact"</strong> → Email is disabled,
|
|
2939
|
-
Phone becomes required
|
|
3260
|
+
Open <strong>Account Type</strong>, change to "Business" → Company Name field appears and becomes required
|
|
2940
3261
|
</li>
|
|
2941
3262
|
<li>
|
|
2942
|
-
|
|
2943
|
-
automatically
|
|
3263
|
+
Open <strong>Contact Information</strong>, toggle <strong>"Prefer phone contact"</strong> → Email is disabled, Phone becomes required
|
|
2944
3264
|
</li>
|
|
2945
3265
|
<li>
|
|
2946
|
-
|
|
2947
|
-
Subtotal and Total update
|
|
3266
|
+
Open <strong>Customer Details</strong>, type in <strong>First/Last Name</strong> → Full Name is calculated automatically
|
|
2948
3267
|
</li>
|
|
2949
3268
|
<li>
|
|
2950
|
-
|
|
2951
|
-
(Express: $25, Standard: $10, Pickup: $0)
|
|
3269
|
+
Open <strong>Delivery & Shipping</strong>, select <strong>"Pickup"</strong> → Shipping Address section is hidden
|
|
2952
3270
|
</li>
|
|
2953
3271
|
<li>
|
|
2954
|
-
|
|
2955
|
-
hidden
|
|
3272
|
+
Open <strong>Order Summary</strong>, change <strong>Quantity</strong> or <strong>Delivery Type</strong> → Costs update automatically
|
|
2956
3273
|
</li>
|
|
2957
3274
|
</ul>
|
|
2958
3275
|
</div>
|
|
@@ -2960,7 +3277,10 @@ export const ConditionalComplex = {
|
|
|
2960
3277
|
data-required
|
|
2961
3278
|
.jsonSchema=${schema}
|
|
2962
3279
|
.uiSchema=${uiSchema}
|
|
2963
|
-
@pw:submit=${(e) =>
|
|
3280
|
+
@pw:submit=${(e) => {
|
|
3281
|
+
console.log('✅ Form Data Structure:', e.detail);
|
|
3282
|
+
toastFormData(e.detail);
|
|
3283
|
+
}}
|
|
2964
3284
|
></pds-form>
|
|
2965
3285
|
`;
|
|
2966
3286
|
},
|