@pure-ds/storybook 0.7.26 → 0.7.29
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/Panel.jsx +128 -7
- package/.storybook/addons/html-preview/preview.js +112 -2
- package/dist/pds-reference.json +204 -3
- package/package.json +2 -2
- package/public/assets/js/app.js +1 -1
- package/public/assets/js/pds-ask.js +6 -6
- package/public/assets/js/pds-manager.js +110 -56
- package/public/assets/pds/components/pds-omnibox.js +70 -3
- package/public/assets/pds/components/pds-tags.js +160 -122
- package/public/assets/pds/core/pds-ask.js +6 -6
- package/public/assets/pds/core/pds-manager.js +110 -56
- package/public/assets/pds/custom-elements.json +175 -1
- package/public/assets/pds/pds-css-complete.json +1 -1
- package/public/assets/pds/pds-runtime-config.json +1 -1
- package/public/assets/pds/styles/pds-styles.css +56 -16
- package/public/assets/pds/styles/pds-styles.css.js +112 -32
- package/public/assets/pds/styles/pds-utilities.css +56 -16
- package/public/assets/pds/styles/pds-utilities.css.js +112 -32
- package/public/assets/pds/vscode-custom-data.json +32 -0
- package/src/js/common/ask.js +165 -37
- package/src/js/pds-core/pds-generator.js +98 -26
- package/src/js/pds.d.ts +55 -1
- package/stories/components/PdsTags.stories.js +283 -19
- package/stories/primitives/Buttons.stories.js +24 -5
- package/stories/utils/PdsAsk.stories.js +201 -9
- package/stories/utils/PdsToast.stories.js +43 -3
|
@@ -42,37 +42,77 @@ pds-icon {
|
|
|
42
42
|
.icon-text-end { flex-direction: row-reverse; }
|
|
43
43
|
|
|
44
44
|
/* Button icon utilities */
|
|
45
|
-
button,
|
|
46
|
-
|
|
45
|
+
button,
|
|
46
|
+
a.btn,
|
|
47
|
+
a.btn-primary,
|
|
48
|
+
a.btn-secondary,
|
|
49
|
+
a.btn-outline,
|
|
50
|
+
a.btn-danger,
|
|
51
|
+
a.icon-only {
|
|
52
|
+
pds-icon,
|
|
53
|
+
pds-icon[size] {
|
|
47
54
|
flex-shrink: 0;
|
|
55
|
+
width: 1em;
|
|
56
|
+
height: 1em;
|
|
48
57
|
}
|
|
49
58
|
|
|
50
59
|
&.icon-only {
|
|
51
|
-
padding: var(--spacing-2);
|
|
52
|
-
min-width: 30px;
|
|
53
|
-
|
|
54
|
-
|
|
60
|
+
padding: calc(max(calc(var(--spacing-1) * 1), var(--spacing-2)) * 0.72);
|
|
61
|
+
min-width: max(30px, calc(var(--font-size-base) + (max(calc(var(--spacing-1) * 1), var(--spacing-2)) * 2) + (var(--border-width-medium) * 2)));
|
|
62
|
+
min-height: max(30px, calc(var(--font-size-base) + (max(calc(var(--spacing-1) * 1), var(--spacing-2)) * 2) + (var(--border-width-medium) * 2)));
|
|
63
|
+
width: max(30px, calc(var(--font-size-base) + (max(calc(var(--spacing-1) * 1), var(--spacing-2)) * 2) + (var(--border-width-medium) * 2)));
|
|
64
|
+
height: max(30px, calc(var(--font-size-base) + (max(calc(var(--spacing-1) * 1), var(--spacing-2)) * 2) + (var(--border-width-medium) * 2)));
|
|
55
65
|
display: inline-flex;
|
|
56
66
|
align-items: center;
|
|
57
67
|
justify-content: center;
|
|
68
|
+
|
|
69
|
+
pds-icon,
|
|
70
|
+
pds-icon[size] {
|
|
71
|
+
width: 1.2em;
|
|
72
|
+
height: 1.2em;
|
|
73
|
+
}
|
|
58
74
|
}
|
|
59
75
|
|
|
60
76
|
&.btn-sm.icon-only {
|
|
61
|
-
|
|
62
|
-
width: calc(30px * 0.
|
|
63
|
-
height: calc(30px * 0.
|
|
77
|
+
padding: calc(calc(max(calc(var(--spacing-1) * 1), var(--spacing-2)) * 0.85) * 0.72);
|
|
78
|
+
min-width: max(calc(30px * 0.85), calc(var(--font-size-sm) + (calc(max(calc(var(--spacing-1) * 1), var(--spacing-2)) * 0.85) * 2) + (var(--border-width-medium) * 2)));
|
|
79
|
+
min-height: max(calc(30px * 0.85), calc(var(--font-size-sm) + (calc(max(calc(var(--spacing-1) * 1), var(--spacing-2)) * 0.85) * 2) + (var(--border-width-medium) * 2)));
|
|
80
|
+
width: max(calc(30px * 0.85), calc(var(--font-size-sm) + (calc(max(calc(var(--spacing-1) * 1), var(--spacing-2)) * 0.85) * 2) + (var(--border-width-medium) * 2)));
|
|
81
|
+
height: max(calc(30px * 0.85), calc(var(--font-size-sm) + (calc(max(calc(var(--spacing-1) * 1), var(--spacing-2)) * 0.85) * 2) + (var(--border-width-medium) * 2)));
|
|
82
|
+
|
|
83
|
+
pds-icon,
|
|
84
|
+
pds-icon[size] {
|
|
85
|
+
width: 1.15em;
|
|
86
|
+
height: 1.15em;
|
|
87
|
+
}
|
|
64
88
|
}
|
|
65
89
|
|
|
66
90
|
&.btn-xs.icon-only {
|
|
67
|
-
|
|
68
|
-
width: calc(30px * 0.
|
|
69
|
-
height: calc(30px * 0.
|
|
91
|
+
padding: calc(calc(max(calc(var(--spacing-1) * 1), var(--spacing-2)) * 0.7) * 0.72);
|
|
92
|
+
min-width: max(calc(30px * 0.7), calc(var(--font-size-xs) + (calc(max(calc(var(--spacing-1) * 1), var(--spacing-2)) * 0.7) * 2) + (var(--border-width-medium) * 2)));
|
|
93
|
+
min-height: max(calc(30px * 0.7), calc(var(--font-size-xs) + (calc(max(calc(var(--spacing-1) * 1), var(--spacing-2)) * 0.7) * 2) + (var(--border-width-medium) * 2)));
|
|
94
|
+
width: max(calc(30px * 0.7), calc(var(--font-size-xs) + (calc(max(calc(var(--spacing-1) * 1), var(--spacing-2)) * 0.7) * 2) + (var(--border-width-medium) * 2)));
|
|
95
|
+
height: max(calc(30px * 0.7), calc(var(--font-size-xs) + (calc(max(calc(var(--spacing-1) * 1), var(--spacing-2)) * 0.7) * 2) + (var(--border-width-medium) * 2)));
|
|
96
|
+
|
|
97
|
+
pds-icon,
|
|
98
|
+
pds-icon[size] {
|
|
99
|
+
width: 1.1em;
|
|
100
|
+
height: 1.1em;
|
|
101
|
+
}
|
|
70
102
|
}
|
|
71
103
|
|
|
72
104
|
&.btn-lg.icon-only {
|
|
73
|
-
|
|
74
|
-
width: calc(30px * 1.2);
|
|
75
|
-
height: calc(30px * 1.2);
|
|
105
|
+
padding: calc(calc(max(calc(var(--spacing-1) * 1), var(--spacing-2)) * 1.15) * 0.72);
|
|
106
|
+
min-width: max(calc(30px * 1.15), calc(var(--font-size-lg) + (calc(max(calc(var(--spacing-1) * 1), var(--spacing-2)) * 1.15) * 2) + (var(--border-width-medium) * 2)));
|
|
107
|
+
min-height: max(calc(30px * 1.15), calc(var(--font-size-lg) + (calc(max(calc(var(--spacing-1) * 1), var(--spacing-2)) * 1.15) * 2) + (var(--border-width-medium) * 2)));
|
|
108
|
+
width: max(calc(30px * 1.15), calc(var(--font-size-lg) + (calc(max(calc(var(--spacing-1) * 1), var(--spacing-2)) * 1.15) * 2) + (var(--border-width-medium) * 2)));
|
|
109
|
+
height: max(calc(30px * 1.15), calc(var(--font-size-lg) + (calc(max(calc(var(--spacing-1) * 1), var(--spacing-2)) * 1.15) * 2) + (var(--border-width-medium) * 2)));
|
|
110
|
+
|
|
111
|
+
pds-icon,
|
|
112
|
+
pds-icon[size] {
|
|
113
|
+
width: 1.25em;
|
|
114
|
+
height: 1.25em;
|
|
115
|
+
}
|
|
76
116
|
}
|
|
77
117
|
}
|
|
78
118
|
|
|
@@ -591,7 +631,7 @@ html[data-theme="dark"] .surface-inverse {
|
|
|
591
631
|
/* Touch device optimizations */
|
|
592
632
|
@media (hover: none) and (pointer: coarse) {
|
|
593
633
|
/* Touch devices - larger touch targets for interactive elements */
|
|
594
|
-
button
|
|
634
|
+
button, a, select, textarea,
|
|
595
635
|
input:not([type="radio"]):not([type="checkbox"]) {
|
|
596
636
|
min-height: 44px;
|
|
597
637
|
min-width: 44px;
|
|
@@ -720,37 +760,77 @@ pds-icon {
|
|
|
720
760
|
.icon-text-end { flex-direction: row-reverse; }
|
|
721
761
|
|
|
722
762
|
/* Button icon utilities */
|
|
723
|
-
button,
|
|
724
|
-
|
|
763
|
+
button,
|
|
764
|
+
a.btn,
|
|
765
|
+
a.btn-primary,
|
|
766
|
+
a.btn-secondary,
|
|
767
|
+
a.btn-outline,
|
|
768
|
+
a.btn-danger,
|
|
769
|
+
a.icon-only {
|
|
770
|
+
pds-icon,
|
|
771
|
+
pds-icon[size] {
|
|
725
772
|
flex-shrink: 0;
|
|
773
|
+
width: 1em;
|
|
774
|
+
height: 1em;
|
|
726
775
|
}
|
|
727
776
|
|
|
728
777
|
&.icon-only {
|
|
729
|
-
padding: var(--spacing-2);
|
|
730
|
-
min-width: 30px;
|
|
731
|
-
|
|
732
|
-
|
|
778
|
+
padding: calc(max(calc(var(--spacing-1) * 1), var(--spacing-2)) * 0.72);
|
|
779
|
+
min-width: max(30px, calc(var(--font-size-base) + (max(calc(var(--spacing-1) * 1), var(--spacing-2)) * 2) + (var(--border-width-medium) * 2)));
|
|
780
|
+
min-height: max(30px, calc(var(--font-size-base) + (max(calc(var(--spacing-1) * 1), var(--spacing-2)) * 2) + (var(--border-width-medium) * 2)));
|
|
781
|
+
width: max(30px, calc(var(--font-size-base) + (max(calc(var(--spacing-1) * 1), var(--spacing-2)) * 2) + (var(--border-width-medium) * 2)));
|
|
782
|
+
height: max(30px, calc(var(--font-size-base) + (max(calc(var(--spacing-1) * 1), var(--spacing-2)) * 2) + (var(--border-width-medium) * 2)));
|
|
733
783
|
display: inline-flex;
|
|
734
784
|
align-items: center;
|
|
735
785
|
justify-content: center;
|
|
786
|
+
|
|
787
|
+
pds-icon,
|
|
788
|
+
pds-icon[size] {
|
|
789
|
+
width: 1.2em;
|
|
790
|
+
height: 1.2em;
|
|
791
|
+
}
|
|
736
792
|
}
|
|
737
793
|
|
|
738
794
|
&.btn-sm.icon-only {
|
|
739
|
-
|
|
740
|
-
width: calc(30px * 0.
|
|
741
|
-
height: calc(30px * 0.
|
|
795
|
+
padding: calc(calc(max(calc(var(--spacing-1) * 1), var(--spacing-2)) * 0.85) * 0.72);
|
|
796
|
+
min-width: max(calc(30px * 0.85), calc(var(--font-size-sm) + (calc(max(calc(var(--spacing-1) * 1), var(--spacing-2)) * 0.85) * 2) + (var(--border-width-medium) * 2)));
|
|
797
|
+
min-height: max(calc(30px * 0.85), calc(var(--font-size-sm) + (calc(max(calc(var(--spacing-1) * 1), var(--spacing-2)) * 0.85) * 2) + (var(--border-width-medium) * 2)));
|
|
798
|
+
width: max(calc(30px * 0.85), calc(var(--font-size-sm) + (calc(max(calc(var(--spacing-1) * 1), var(--spacing-2)) * 0.85) * 2) + (var(--border-width-medium) * 2)));
|
|
799
|
+
height: max(calc(30px * 0.85), calc(var(--font-size-sm) + (calc(max(calc(var(--spacing-1) * 1), var(--spacing-2)) * 0.85) * 2) + (var(--border-width-medium) * 2)));
|
|
800
|
+
|
|
801
|
+
pds-icon,
|
|
802
|
+
pds-icon[size] {
|
|
803
|
+
width: 1.15em;
|
|
804
|
+
height: 1.15em;
|
|
805
|
+
}
|
|
742
806
|
}
|
|
743
807
|
|
|
744
808
|
&.btn-xs.icon-only {
|
|
745
|
-
|
|
746
|
-
width: calc(30px * 0.
|
|
747
|
-
height: calc(30px * 0.
|
|
809
|
+
padding: calc(calc(max(calc(var(--spacing-1) * 1), var(--spacing-2)) * 0.7) * 0.72);
|
|
810
|
+
min-width: max(calc(30px * 0.7), calc(var(--font-size-xs) + (calc(max(calc(var(--spacing-1) * 1), var(--spacing-2)) * 0.7) * 2) + (var(--border-width-medium) * 2)));
|
|
811
|
+
min-height: max(calc(30px * 0.7), calc(var(--font-size-xs) + (calc(max(calc(var(--spacing-1) * 1), var(--spacing-2)) * 0.7) * 2) + (var(--border-width-medium) * 2)));
|
|
812
|
+
width: max(calc(30px * 0.7), calc(var(--font-size-xs) + (calc(max(calc(var(--spacing-1) * 1), var(--spacing-2)) * 0.7) * 2) + (var(--border-width-medium) * 2)));
|
|
813
|
+
height: max(calc(30px * 0.7), calc(var(--font-size-xs) + (calc(max(calc(var(--spacing-1) * 1), var(--spacing-2)) * 0.7) * 2) + (var(--border-width-medium) * 2)));
|
|
814
|
+
|
|
815
|
+
pds-icon,
|
|
816
|
+
pds-icon[size] {
|
|
817
|
+
width: 1.1em;
|
|
818
|
+
height: 1.1em;
|
|
819
|
+
}
|
|
748
820
|
}
|
|
749
821
|
|
|
750
822
|
&.btn-lg.icon-only {
|
|
751
|
-
|
|
752
|
-
width: calc(30px * 1.2);
|
|
753
|
-
height: calc(30px * 1.2);
|
|
823
|
+
padding: calc(calc(max(calc(var(--spacing-1) * 1), var(--spacing-2)) * 1.15) * 0.72);
|
|
824
|
+
min-width: max(calc(30px * 1.15), calc(var(--font-size-lg) + (calc(max(calc(var(--spacing-1) * 1), var(--spacing-2)) * 1.15) * 2) + (var(--border-width-medium) * 2)));
|
|
825
|
+
min-height: max(calc(30px * 1.15), calc(var(--font-size-lg) + (calc(max(calc(var(--spacing-1) * 1), var(--spacing-2)) * 1.15) * 2) + (var(--border-width-medium) * 2)));
|
|
826
|
+
width: max(calc(30px * 1.15), calc(var(--font-size-lg) + (calc(max(calc(var(--spacing-1) * 1), var(--spacing-2)) * 1.15) * 2) + (var(--border-width-medium) * 2)));
|
|
827
|
+
height: max(calc(30px * 1.15), calc(var(--font-size-lg) + (calc(max(calc(var(--spacing-1) * 1), var(--spacing-2)) * 1.15) * 2) + (var(--border-width-medium) * 2)));
|
|
828
|
+
|
|
829
|
+
pds-icon,
|
|
830
|
+
pds-icon[size] {
|
|
831
|
+
width: 1.25em;
|
|
832
|
+
height: 1.25em;
|
|
833
|
+
}
|
|
754
834
|
}
|
|
755
835
|
}
|
|
756
836
|
|
|
@@ -1269,7 +1349,7 @@ html[data-theme="dark"] .surface-inverse {
|
|
|
1269
1349
|
/* Touch device optimizations */
|
|
1270
1350
|
@media (hover: none) and (pointer: coarse) {
|
|
1271
1351
|
/* Touch devices - larger touch targets for interactive elements */
|
|
1272
|
-
button
|
|
1352
|
+
button, a, select, textarea,
|
|
1273
1353
|
input:not([type="radio"]):not([type="checkbox"]) {
|
|
1274
1354
|
min-height: 44px;
|
|
1275
1355
|
min-width: 44px;
|
|
@@ -950,6 +950,38 @@
|
|
|
950
950
|
}
|
|
951
951
|
]
|
|
952
952
|
},
|
|
953
|
+
{
|
|
954
|
+
"name": "pds-tags",
|
|
955
|
+
"description": "Form-associated multi-select tags control built on top of `pds-omnibox`.\r\n\r\nUsers select suggestions from the omnibox and each selection is rendered as a removable\r\nchip. The component keeps selection state synchronized across:\r\n- the `value` attribute (comma-separated ids)\r\n- the `value` property (`string[]`)\r\n- form value via ElementInternals\r\n\r\nThe `options` object uses the same structure as `pds-omnibox.settings`.\r\nSee `pds-omnibox` JSDoc for the full options schema.\r\nBefore applying it, the component deep-merges internal defaults:\r\n- `hideCategory: true`\r\n- `itemGrid: \"0 1fr 0\"`\r\n- `iconHandler: () => \"\"`\r\n\r\nWhen `required` is set, at least one selected value is required for validity.",
|
|
956
|
+
"attributes": [
|
|
957
|
+
{
|
|
958
|
+
"name": "name",
|
|
959
|
+
"description": "Form field name; selected values are submitted under this name"
|
|
960
|
+
},
|
|
961
|
+
{
|
|
962
|
+
"name": "placeholder",
|
|
963
|
+
"description": "Placeholder shown in omnibox input (default: \"Search tags...\")"
|
|
964
|
+
},
|
|
965
|
+
{
|
|
966
|
+
"name": "value",
|
|
967
|
+
"description": "Comma-separated selected item ids"
|
|
968
|
+
},
|
|
969
|
+
{
|
|
970
|
+
"name": "options",
|
|
971
|
+
"description": "JSON object with the same shape as `pds-omnibox.settings`"
|
|
972
|
+
},
|
|
973
|
+
{
|
|
974
|
+
"name": "disabled",
|
|
975
|
+
"description": "Disables omnibox interaction and chip remove actions",
|
|
976
|
+
"valueSet": "v"
|
|
977
|
+
},
|
|
978
|
+
{
|
|
979
|
+
"name": "required",
|
|
980
|
+
"description": "Requires at least one selected value for validity",
|
|
981
|
+
"valueSet": "v"
|
|
982
|
+
}
|
|
983
|
+
]
|
|
984
|
+
},
|
|
953
985
|
{
|
|
954
986
|
"name": "pds-theme",
|
|
955
987
|
"description": "PdsTheme component"
|
package/src/js/common/ask.js
CHANGED
|
@@ -162,14 +162,150 @@ export async function ask(message, options = {}) {
|
|
|
162
162
|
};
|
|
163
163
|
|
|
164
164
|
options = { ...defaults, ...options };
|
|
165
|
+
|
|
166
|
+
const buttonConfigs = options.buttons && typeof options.buttons === "object"
|
|
167
|
+
? options.buttons
|
|
168
|
+
: defaults.buttons;
|
|
169
|
+
|
|
170
|
+
const resolveActionMeta = (actionCode) => {
|
|
171
|
+
if (actionCode == null) {
|
|
172
|
+
return {
|
|
173
|
+
actionCode: "dismiss",
|
|
174
|
+
actionKind: "dismiss",
|
|
175
|
+
button: null,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const button = buttonConfigs?.[actionCode] ?? null;
|
|
180
|
+
const actionKind = actionCode === "ok"
|
|
181
|
+
? "ok"
|
|
182
|
+
: actionCode === "dismiss"
|
|
183
|
+
? "dismiss"
|
|
184
|
+
: (button?.cancel || actionCode === "cancel")
|
|
185
|
+
? "cancel"
|
|
186
|
+
: "custom";
|
|
187
|
+
|
|
188
|
+
return {
|
|
189
|
+
actionCode,
|
|
190
|
+
actionKind,
|
|
191
|
+
button,
|
|
192
|
+
};
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
const normalizeBeforeCloseResult = (result) => {
|
|
196
|
+
if (typeof result === "undefined" || result === null || result === true) {
|
|
197
|
+
return { allow: true };
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (result === false) {
|
|
201
|
+
return { allow: false };
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
if (typeof result === "object") {
|
|
205
|
+
const hasResult = Object.prototype.hasOwnProperty.call(result, "result")
|
|
206
|
+
|| Object.prototype.hasOwnProperty.call(result, "value");
|
|
207
|
+
|
|
208
|
+
return {
|
|
209
|
+
allow: result.allow !== false,
|
|
210
|
+
hasResult,
|
|
211
|
+
result: Object.prototype.hasOwnProperty.call(result, "result")
|
|
212
|
+
? result.result
|
|
213
|
+
: result.value,
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
return { allow: Boolean(result) };
|
|
218
|
+
};
|
|
165
219
|
|
|
166
220
|
return new Promise((resolve) => {
|
|
167
221
|
let settled = false;
|
|
168
|
-
const settle = (value, dialog) => {
|
|
222
|
+
const settle = (value, dialog, { shouldClose = true } = {}) => {
|
|
169
223
|
if (settled) return;
|
|
170
224
|
settled = true;
|
|
171
|
-
dialog.close();
|
|
172
225
|
resolve(value);
|
|
226
|
+
|
|
227
|
+
if (!shouldClose || !dialog?.open) {
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
try {
|
|
232
|
+
dialog.close();
|
|
233
|
+
} catch (error) {
|
|
234
|
+
console.warn("ask: dialog.close() failed", error);
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
const runBeforeClose = async (context) => {
|
|
239
|
+
if (context.actionKind !== "ok" || typeof options.beforeClose !== "function") {
|
|
240
|
+
return { allow: true };
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
try {
|
|
244
|
+
const beforeCloseResult = await options.beforeClose(context);
|
|
245
|
+
return normalizeBeforeCloseResult(beforeCloseResult);
|
|
246
|
+
} catch (error) {
|
|
247
|
+
console.error("ask.beforeClose: validation failed", error);
|
|
248
|
+
return { allow: false };
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
const resolveDefaultResult = ({ actionKind, form }) => {
|
|
253
|
+
if (actionKind === "ok") {
|
|
254
|
+
if (options.useForm && form) {
|
|
255
|
+
return new FormData(form);
|
|
256
|
+
}
|
|
257
|
+
return true;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
return false;
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
const attemptResolve = async ({
|
|
264
|
+
actionCode,
|
|
265
|
+
form,
|
|
266
|
+
submitter,
|
|
267
|
+
originalEvent,
|
|
268
|
+
bypassValidation = false,
|
|
269
|
+
shouldClose = true,
|
|
270
|
+
}) => {
|
|
271
|
+
if (settled) return;
|
|
272
|
+
|
|
273
|
+
const { actionKind, button } = resolveActionMeta(actionCode);
|
|
274
|
+
const activeForm = form || dialog.querySelector("form") || null;
|
|
275
|
+
|
|
276
|
+
if (options.useForm && actionKind === "ok" && activeForm && !bypassValidation) {
|
|
277
|
+
const valid = validateDialogFormTree(activeForm);
|
|
278
|
+
if (!valid) {
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
const defaultResult = resolveDefaultResult({
|
|
284
|
+
actionKind,
|
|
285
|
+
form: activeForm,
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
const guard = await runBeforeClose({
|
|
289
|
+
actionCode,
|
|
290
|
+
actionKind,
|
|
291
|
+
dialog,
|
|
292
|
+
form: activeForm,
|
|
293
|
+
formData: options.useForm && actionKind === "ok" && activeForm
|
|
294
|
+
? defaultResult
|
|
295
|
+
: null,
|
|
296
|
+
submitter,
|
|
297
|
+
originalEvent,
|
|
298
|
+
options,
|
|
299
|
+
button,
|
|
300
|
+
defaultResult,
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
if (!guard.allow) {
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
const result = guard.hasResult ? guard.result : defaultResult;
|
|
308
|
+
settle(result, dialog, { shouldClose });
|
|
173
309
|
};
|
|
174
310
|
|
|
175
311
|
// Create native dialog element
|
|
@@ -203,7 +339,7 @@ export async function ask(message, options = {}) {
|
|
|
203
339
|
}
|
|
204
340
|
|
|
205
341
|
// Build button elements
|
|
206
|
-
const buttons = Object.entries(
|
|
342
|
+
const buttons = Object.entries(buttonConfigs).map(([code, obj]) => {
|
|
207
343
|
const btnClass = obj.primary ? "btn-primary btn-sm" : "btn-outline btn-sm";
|
|
208
344
|
const btnType = obj.cancel ? "button" : "submit";
|
|
209
345
|
const formNoValidate = obj.formNoValidate ? " formnovalidate" : "";
|
|
@@ -278,26 +414,14 @@ export async function ask(message, options = {}) {
|
|
|
278
414
|
|
|
279
415
|
// Handle cancel button clicks
|
|
280
416
|
dialog.addEventListener("click", (e) => {
|
|
281
|
-
const okBtn = e.target.closest('button[value="ok"]');
|
|
282
|
-
if (okBtn && options.useForm) {
|
|
283
|
-
e.preventDefault();
|
|
284
|
-
const form = dialog.querySelector("form");
|
|
285
|
-
if (!form) return;
|
|
286
|
-
|
|
287
|
-
const bypassValidation = Boolean(okBtn.hasAttribute("formnovalidate"));
|
|
288
|
-
if (!bypassValidation) {
|
|
289
|
-
const valid = validateDialogFormTree(form);
|
|
290
|
-
if (!valid) return;
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
const result = new FormData(form);
|
|
294
|
-
settle(result, dialog);
|
|
295
|
-
return;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
417
|
const btn = e.target.closest('button[value="cancel"]');
|
|
299
418
|
if (btn) {
|
|
300
|
-
|
|
419
|
+
attemptResolve({
|
|
420
|
+
actionCode: "cancel",
|
|
421
|
+
form: dialog.querySelector("form"),
|
|
422
|
+
submitter: btn,
|
|
423
|
+
originalEvent: e,
|
|
424
|
+
});
|
|
301
425
|
}
|
|
302
426
|
});
|
|
303
427
|
|
|
@@ -316,22 +440,13 @@ export async function ask(message, options = {}) {
|
|
|
316
440
|
const submitValue = event.submitter?.value ?? (options.useForm ? "ok" : undefined);
|
|
317
441
|
const bypassValidation = Boolean(event.submitter?.hasAttribute("formnovalidate"));
|
|
318
442
|
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
let result;
|
|
328
|
-
if (options.useForm && submitValue === "ok") {
|
|
329
|
-
result = new FormData(form);
|
|
330
|
-
} else {
|
|
331
|
-
result = (submitValue === "ok");
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
settle(result, dialog);
|
|
443
|
+
attemptResolve({
|
|
444
|
+
actionCode: submitValue,
|
|
445
|
+
form,
|
|
446
|
+
submitter: event.submitter,
|
|
447
|
+
originalEvent: event,
|
|
448
|
+
bypassValidation,
|
|
449
|
+
});
|
|
335
450
|
});
|
|
336
451
|
} else {
|
|
337
452
|
// Form doesn't exist yet, wait and try again
|
|
@@ -339,8 +454,21 @@ export async function ask(message, options = {}) {
|
|
|
339
454
|
}
|
|
340
455
|
};
|
|
341
456
|
|
|
457
|
+
dialog.addEventListener("cancel", (event) => {
|
|
458
|
+
event.preventDefault();
|
|
459
|
+
attemptResolve({
|
|
460
|
+
actionCode: "dismiss",
|
|
461
|
+
form: dialog.querySelector("form"),
|
|
462
|
+
originalEvent: event,
|
|
463
|
+
});
|
|
464
|
+
});
|
|
465
|
+
|
|
342
466
|
// Handle dialog close event
|
|
343
467
|
dialog.addEventListener("close", () => {
|
|
468
|
+
if (!settled) {
|
|
469
|
+
settle(false, dialog, { shouldClose: false });
|
|
470
|
+
}
|
|
471
|
+
|
|
344
472
|
// Small delay to allow exit animation
|
|
345
473
|
setTimeout(() => dialog.remove(), 200);
|
|
346
474
|
});
|
|
@@ -2731,18 +2731,23 @@ select {
|
|
|
2731
2731
|
|
|
2732
2732
|
/* Button styling */
|
|
2733
2733
|
button, .btn, input[type="submit"], input[type="button"], input[type="reset"] {
|
|
2734
|
+
--btn-pad-y: max(calc(var(--spacing-1) * ${buttonPaddingValue}), var(--spacing-2));
|
|
2735
|
+
--btn-target-h: max(${minButtonHeight}px, calc(var(--font-size-base) + (var(--btn-pad-y) * 2) + (var(--border-width-medium) * 2)));
|
|
2734
2736
|
display: inline-flex;
|
|
2735
2737
|
gap: var(--spacing-1);
|
|
2736
2738
|
align-items: center;
|
|
2737
2739
|
justify-content: center;
|
|
2738
|
-
min-height:
|
|
2739
|
-
|
|
2740
|
+
min-height: var(--btn-target-h);
|
|
2741
|
+
height: var(--btn-target-h);
|
|
2742
|
+
padding: var(--btn-pad-y) var(--spacing-6);
|
|
2740
2743
|
border: var(--border-width-medium) solid transparent;
|
|
2741
2744
|
border-radius: var(--radius-md);
|
|
2745
|
+
box-sizing: border-box;
|
|
2742
2746
|
font-family: var(--font-family-body);
|
|
2743
2747
|
font-size: var(--font-size-base);
|
|
2744
2748
|
font-weight: var(--font-weight-medium);
|
|
2745
2749
|
line-height: 1;
|
|
2750
|
+
white-space: nowrap;
|
|
2746
2751
|
cursor: pointer;
|
|
2747
2752
|
transition: all var(--transition-fast);
|
|
2748
2753
|
text-decoration: none;
|
|
@@ -2896,22 +2901,31 @@ button, .btn, input[type="submit"], input[type="button"], input[type="reset"] {
|
|
|
2896
2901
|
}
|
|
2897
2902
|
|
|
2898
2903
|
.btn-sm {
|
|
2899
|
-
|
|
2904
|
+
--btn-pad-y: calc(max(calc(var(--spacing-1) * ${buttonPaddingValue}), var(--spacing-2)) * 0.85);
|
|
2905
|
+
--btn-target-h: max(calc(${minButtonHeight}px * 0.85), calc(var(--font-size-sm) + (var(--btn-pad-y) * 2) + (var(--border-width-medium) * 2)));
|
|
2906
|
+
padding: var(--btn-pad-y) calc(var(--spacing-6) * 0.8);
|
|
2900
2907
|
font-size: var(--font-size-sm);
|
|
2901
|
-
min-height:
|
|
2908
|
+
min-height: var(--btn-target-h);
|
|
2909
|
+
height: var(--btn-target-h);
|
|
2902
2910
|
}
|
|
2903
2911
|
|
|
2904
2912
|
.btn-xs {
|
|
2905
|
-
|
|
2913
|
+
--btn-pad-y: calc(max(calc(var(--spacing-1) * ${buttonPaddingValue}), var(--spacing-2)) * 0.7);
|
|
2914
|
+
--btn-target-h: max(calc(${minButtonHeight}px * 0.7), calc(var(--font-size-xs) + (var(--btn-pad-y) * 2) + (var(--border-width-medium) * 2)));
|
|
2915
|
+
padding: var(--btn-pad-y) calc(var(--spacing-6) * 0.65);
|
|
2906
2916
|
font-size: var(--font-size-xs);
|
|
2907
|
-
min-height:
|
|
2917
|
+
min-height: var(--btn-target-h);
|
|
2918
|
+
height: var(--btn-target-h);
|
|
2908
2919
|
}
|
|
2909
2920
|
|
|
2910
2921
|
|
|
2911
2922
|
.btn-lg {
|
|
2912
|
-
|
|
2923
|
+
--btn-pad-y: calc(max(calc(var(--spacing-1) * ${buttonPaddingValue}), var(--spacing-2)) * 1.15);
|
|
2924
|
+
--btn-target-h: max(calc(${minButtonHeight}px * 1.15), calc(var(--font-size-lg) + (var(--btn-pad-y) * 2) + (var(--border-width-medium) * 2)));
|
|
2925
|
+
padding: var(--btn-pad-y) calc(var(--spacing-6) * 1.35);
|
|
2913
2926
|
font-size: var(--font-size-lg);
|
|
2914
|
-
min-height:
|
|
2927
|
+
min-height: var(--btn-target-h);
|
|
2928
|
+
height: var(--btn-target-h);
|
|
2915
2929
|
}
|
|
2916
2930
|
|
|
2917
2931
|
/* Working/loading state for buttons */
|
|
@@ -3887,7 +3901,25 @@ pds-tabstrip {
|
|
|
3887
3901
|
|
|
3888
3902
|
#generateIconStyles() {
|
|
3889
3903
|
const { layout = {} } = this.options.design;
|
|
3890
|
-
const
|
|
3904
|
+
const minButtonHeight = layout.buttonMinHeight || 30;
|
|
3905
|
+
const buttonPaddingValue = layout.buttonPadding || 1.0;
|
|
3906
|
+
const buttonPaddingDefault = `max(calc(var(--spacing-1) * ${buttonPaddingValue}), var(--spacing-2))`;
|
|
3907
|
+
const buttonPaddingSm = `calc(max(calc(var(--spacing-1) * ${buttonPaddingValue}), var(--spacing-2)) * 0.85)`;
|
|
3908
|
+
const buttonPaddingXs = `calc(max(calc(var(--spacing-1) * ${buttonPaddingValue}), var(--spacing-2)) * 0.7)`;
|
|
3909
|
+
const buttonPaddingLg = `calc(max(calc(var(--spacing-1) * ${buttonPaddingValue}), var(--spacing-2)) * 1.15)`;
|
|
3910
|
+
const iconOnlyPaddingScale = 0.72;
|
|
3911
|
+
const iconOnlyPaddingDefault = `calc(${buttonPaddingDefault} * ${iconOnlyPaddingScale})`;
|
|
3912
|
+
const iconOnlyPaddingSm = `calc(${buttonPaddingSm} * ${iconOnlyPaddingScale})`;
|
|
3913
|
+
const iconOnlyPaddingXs = `calc(${buttonPaddingXs} * ${iconOnlyPaddingScale})`;
|
|
3914
|
+
const iconOnlyPaddingLg = `calc(${buttonPaddingLg} * ${iconOnlyPaddingScale})`;
|
|
3915
|
+
const iconOnlyMinDefault = `${minButtonHeight}px`;
|
|
3916
|
+
const iconOnlyMinSm = `calc(${minButtonHeight}px * 0.85)`;
|
|
3917
|
+
const iconOnlyMinXs = `calc(${minButtonHeight}px * 0.7)`;
|
|
3918
|
+
const iconOnlyMinLg = `calc(${minButtonHeight}px * 1.15)`;
|
|
3919
|
+
const iconOnlySizeDefault = `max(${iconOnlyMinDefault}, calc(var(--font-size-base) + (${buttonPaddingDefault} * 2) + (var(--border-width-medium) * 2)))`;
|
|
3920
|
+
const iconOnlySizeSm = `max(${iconOnlyMinSm}, calc(var(--font-size-sm) + (${buttonPaddingSm} * 2) + (var(--border-width-medium) * 2)))`;
|
|
3921
|
+
const iconOnlySizeXs = `max(${iconOnlyMinXs}, calc(var(--font-size-xs) + (${buttonPaddingXs} * 2) + (var(--border-width-medium) * 2)))`;
|
|
3922
|
+
const iconOnlySizeLg = `max(${iconOnlyMinLg}, calc(var(--font-size-lg) + (${buttonPaddingLg} * 2) + (var(--border-width-medium) * 2)))`;
|
|
3891
3923
|
|
|
3892
3924
|
return /*css*/ `/* Icon System */
|
|
3893
3925
|
|
|
@@ -3927,37 +3959,77 @@ pds-icon {
|
|
|
3927
3959
|
.icon-text-end { flex-direction: row-reverse; }
|
|
3928
3960
|
|
|
3929
3961
|
/* Button icon utilities */
|
|
3930
|
-
button,
|
|
3931
|
-
|
|
3962
|
+
button,
|
|
3963
|
+
a.btn,
|
|
3964
|
+
a.btn-primary,
|
|
3965
|
+
a.btn-secondary,
|
|
3966
|
+
a.btn-outline,
|
|
3967
|
+
a.btn-danger,
|
|
3968
|
+
a.icon-only {
|
|
3969
|
+
pds-icon,
|
|
3970
|
+
pds-icon[size] {
|
|
3932
3971
|
flex-shrink: 0;
|
|
3972
|
+
width: 1em;
|
|
3973
|
+
height: 1em;
|
|
3933
3974
|
}
|
|
3934
3975
|
|
|
3935
3976
|
&.icon-only {
|
|
3936
|
-
padding:
|
|
3937
|
-
min-width: ${
|
|
3938
|
-
|
|
3939
|
-
|
|
3977
|
+
padding: ${iconOnlyPaddingDefault};
|
|
3978
|
+
min-width: ${iconOnlySizeDefault};
|
|
3979
|
+
min-height: ${iconOnlySizeDefault};
|
|
3980
|
+
width: ${iconOnlySizeDefault};
|
|
3981
|
+
height: ${iconOnlySizeDefault};
|
|
3940
3982
|
display: inline-flex;
|
|
3941
3983
|
align-items: center;
|
|
3942
3984
|
justify-content: center;
|
|
3985
|
+
|
|
3986
|
+
pds-icon,
|
|
3987
|
+
pds-icon[size] {
|
|
3988
|
+
width: 1.2em;
|
|
3989
|
+
height: 1.2em;
|
|
3990
|
+
}
|
|
3943
3991
|
}
|
|
3944
3992
|
|
|
3945
3993
|
&.btn-sm.icon-only {
|
|
3946
|
-
|
|
3947
|
-
width:
|
|
3948
|
-
height:
|
|
3994
|
+
padding: ${iconOnlyPaddingSm};
|
|
3995
|
+
min-width: ${iconOnlySizeSm};
|
|
3996
|
+
min-height: ${iconOnlySizeSm};
|
|
3997
|
+
width: ${iconOnlySizeSm};
|
|
3998
|
+
height: ${iconOnlySizeSm};
|
|
3999
|
+
|
|
4000
|
+
pds-icon,
|
|
4001
|
+
pds-icon[size] {
|
|
4002
|
+
width: 1.15em;
|
|
4003
|
+
height: 1.15em;
|
|
4004
|
+
}
|
|
3949
4005
|
}
|
|
3950
4006
|
|
|
3951
4007
|
&.btn-xs.icon-only {
|
|
3952
|
-
|
|
3953
|
-
width:
|
|
3954
|
-
height:
|
|
4008
|
+
padding: ${iconOnlyPaddingXs};
|
|
4009
|
+
min-width: ${iconOnlySizeXs};
|
|
4010
|
+
min-height: ${iconOnlySizeXs};
|
|
4011
|
+
width: ${iconOnlySizeXs};
|
|
4012
|
+
height: ${iconOnlySizeXs};
|
|
4013
|
+
|
|
4014
|
+
pds-icon,
|
|
4015
|
+
pds-icon[size] {
|
|
4016
|
+
width: 1.1em;
|
|
4017
|
+
height: 1.1em;
|
|
4018
|
+
}
|
|
3955
4019
|
}
|
|
3956
4020
|
|
|
3957
4021
|
&.btn-lg.icon-only {
|
|
3958
|
-
|
|
3959
|
-
width:
|
|
3960
|
-
height:
|
|
4022
|
+
padding: ${iconOnlyPaddingLg};
|
|
4023
|
+
min-width: ${iconOnlySizeLg};
|
|
4024
|
+
min-height: ${iconOnlySizeLg};
|
|
4025
|
+
width: ${iconOnlySizeLg};
|
|
4026
|
+
height: ${iconOnlySizeLg};
|
|
4027
|
+
|
|
4028
|
+
pds-icon,
|
|
4029
|
+
pds-icon[size] {
|
|
4030
|
+
width: 1.25em;
|
|
4031
|
+
height: 1.25em;
|
|
4032
|
+
}
|
|
3961
4033
|
}
|
|
3962
4034
|
}
|
|
3963
4035
|
|
|
@@ -4354,9 +4426,9 @@ nav[data-dropdown] {
|
|
|
4354
4426
|
}
|
|
4355
4427
|
|
|
4356
4428
|
/* Touch device optimizations */
|
|
4357
|
-
@media (
|
|
4429
|
+
@media (pointer: coarse) {
|
|
4358
4430
|
/* Touch devices - larger touch targets for interactive elements */
|
|
4359
|
-
|
|
4431
|
+
select, textarea,
|
|
4360
4432
|
input:not([type="radio"]):not([type="checkbox"]) {
|
|
4361
4433
|
min-height: ${minTouchTarget}px;
|
|
4362
4434
|
min-width: ${minTouchTarget}px;
|