vanilla-jui 1.5.9 → 1.5.11
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/index.d.ts +4 -1
- package/dist/index.js +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/components/flow.ts +181 -77
- package/src/components/form.ts +103 -60
- package/src/css/form.css +33 -23
- package/src/primitives/toast.ts +3 -2
- package/src/validation/validator.ts +104 -12
package/src/components/form.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
For,
|
|
3
3
|
type ElementProps,
|
|
4
|
+
bindAttr,
|
|
4
5
|
createDeepStore,
|
|
5
6
|
createEffect,
|
|
6
7
|
createMemo,
|
|
@@ -135,6 +136,7 @@ export interface FormButton {
|
|
|
135
136
|
export interface FormValidatorConfig {
|
|
136
137
|
rules?: Record<string, Record<string, unknown>>;
|
|
137
138
|
messages?: Record<string, Record<string, string>>;
|
|
139
|
+
vanilla?: boolean;
|
|
138
140
|
onSubmit?: (() => void) | null;
|
|
139
141
|
[key: string]: unknown;
|
|
140
142
|
}
|
|
@@ -212,10 +214,10 @@ const DEFAULT_CLASS_NAMES: FormClassNames = {
|
|
|
212
214
|
horizontal: 'is-horizontal',
|
|
213
215
|
itemVertical: 'is-item-vertical',
|
|
214
216
|
itemHorizontal: 'is-item-horizontal',
|
|
215
|
-
item: 'form-
|
|
216
|
-
label: '
|
|
217
|
+
item: 'form-field',
|
|
218
|
+
label: 'field-legend',
|
|
217
219
|
required: 'is-required',
|
|
218
|
-
control: '
|
|
220
|
+
control: 'field-control',
|
|
219
221
|
helpInvalid: 'is-invalid',
|
|
220
222
|
buttons: 'form-buttons',
|
|
221
223
|
button: 'j-button',
|
|
@@ -442,6 +444,7 @@ function cloneValidator(validator: unknown): FormValidatorConfig {
|
|
|
442
444
|
) as Partial<FormValidatorConfig> & Record<string, unknown>;
|
|
443
445
|
return {
|
|
444
446
|
...source,
|
|
447
|
+
vanilla: source.vanilla === true,
|
|
445
448
|
rules: isPlainObject(source.rules)
|
|
446
449
|
? (source.rules as FormValidatorConfig['rules'])
|
|
447
450
|
: {},
|
|
@@ -510,6 +513,20 @@ function autoComplete(type: string): string {
|
|
|
510
513
|
return 'on';
|
|
511
514
|
}
|
|
512
515
|
|
|
516
|
+
function nonEmptyAttribute(value: unknown): string | null {
|
|
517
|
+
if (typeof value !== 'string') return null;
|
|
518
|
+
const attribute = value.trim();
|
|
519
|
+
return attribute.length > 0 ? attribute : null;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
function bindNonEmptyAttribute(
|
|
523
|
+
element: Element,
|
|
524
|
+
name: string,
|
|
525
|
+
value: () => unknown
|
|
526
|
+
): void {
|
|
527
|
+
bindAttr(element, name, () => nonEmptyAttribute(value()));
|
|
528
|
+
}
|
|
529
|
+
|
|
513
530
|
function isSelected(
|
|
514
531
|
value: FormField['value'] | undefined,
|
|
515
532
|
optionValue: FormOption['value']
|
|
@@ -625,7 +642,7 @@ export function createForm(input: FormProps = {}): Form {
|
|
|
625
642
|
control.classList.remove('is-valid', 'is-invalid');
|
|
626
643
|
}
|
|
627
644
|
for (const help of all<HTMLElement>(
|
|
628
|
-
'[data-
|
|
645
|
+
'[data-field-help], [data-validator-help]',
|
|
629
646
|
element
|
|
630
647
|
)) {
|
|
631
648
|
if (help.dataset.validatorHelp || help.classList.contains('is-invalid')) {
|
|
@@ -725,11 +742,9 @@ export function createForm(input: FormProps = {}): Form {
|
|
|
725
742
|
...extra,
|
|
726
743
|
name: () => fieldAccessor().name,
|
|
727
744
|
id,
|
|
728
|
-
placeholder: () => fieldAccessor().placeholder || '',
|
|
729
745
|
required: () => !!fieldAccessor().required,
|
|
730
746
|
disabled: () => state.submitting || !!fieldAccessor().disabled,
|
|
731
|
-
|
|
732
|
-
'data-form-field': () => fieldAccessor().name || id,
|
|
747
|
+
'data-field-item': () => fieldAccessor().name || id,
|
|
733
748
|
});
|
|
734
749
|
|
|
735
750
|
const choiceGroupView = (
|
|
@@ -751,7 +766,7 @@ export function createForm(input: FormProps = {}): Form {
|
|
|
751
766
|
field.size ? `is-${field.size}` : ''
|
|
752
767
|
);
|
|
753
768
|
},
|
|
754
|
-
'data-
|
|
769
|
+
'data-field-choice-group': () => fieldAccessor().name || id,
|
|
755
770
|
'data-choice-type': type,
|
|
756
771
|
'data-choice-layout': () =>
|
|
757
772
|
fieldAccessor().vertical ? 'vertical' : 'horizontal',
|
|
@@ -762,7 +777,7 @@ export function createForm(input: FormProps = {}): Form {
|
|
|
762
777
|
return jsx('label', {
|
|
763
778
|
className: () =>
|
|
764
779
|
type === 'radio' ? state.className.radioLabel : '',
|
|
765
|
-
'data-
|
|
780
|
+
'data-field-choice': () => fieldAccessor().name || id,
|
|
766
781
|
for: optionId,
|
|
767
782
|
children: [
|
|
768
783
|
jsx('input', {
|
|
@@ -793,7 +808,7 @@ export function createForm(input: FormProps = {}): Form {
|
|
|
793
808
|
jsx('span', {
|
|
794
809
|
className: () =>
|
|
795
810
|
type === 'radio' ? state.className.radioText : '',
|
|
796
|
-
'data-
|
|
811
|
+
'data-field-choice-text': '',
|
|
797
812
|
children: asRenderable(
|
|
798
813
|
item.text ?? item.label ?? stringifyFormValue(item.value)
|
|
799
814
|
),
|
|
@@ -817,7 +832,14 @@ export function createForm(input: FormProps = {}): Form {
|
|
|
817
832
|
controlProps<HTMLTextAreaElement>(fieldAccessor, id, {
|
|
818
833
|
className: () =>
|
|
819
834
|
fieldAccessor().className || state.className.textarea,
|
|
820
|
-
|
|
835
|
+
placeholder: () => fieldAccessor().placeholder || '',
|
|
836
|
+
readonly: () => !!fieldAccessor().readonly,
|
|
837
|
+
ref: (element: HTMLTextAreaElement) =>
|
|
838
|
+
bindNonEmptyAttribute(
|
|
839
|
+
element,
|
|
840
|
+
'autocomplete',
|
|
841
|
+
() => fieldAccessor().autocomplete
|
|
842
|
+
),
|
|
821
843
|
value: () => stringifyControlValue(fieldAccessor().value),
|
|
822
844
|
onInput: (event: Event) => {
|
|
823
845
|
const target = event.currentTarget;
|
|
@@ -833,7 +855,12 @@ export function createForm(input: FormProps = {}): Form {
|
|
|
833
855
|
'select',
|
|
834
856
|
controlProps<HTMLSelectElement>(fieldAccessor, id, {
|
|
835
857
|
className: () => fieldAccessor().className || state.className.select,
|
|
836
|
-
|
|
858
|
+
ref: (element: HTMLSelectElement) =>
|
|
859
|
+
bindNonEmptyAttribute(
|
|
860
|
+
element,
|
|
861
|
+
'autocomplete',
|
|
862
|
+
() => fieldAccessor().autocomplete
|
|
863
|
+
),
|
|
837
864
|
multiple: () => !!fieldAccessor().multiple,
|
|
838
865
|
value: () =>
|
|
839
866
|
fieldAccessor().multiple
|
|
@@ -875,7 +902,7 @@ export function createForm(input: FormProps = {}): Form {
|
|
|
875
902
|
field.size ? `is-${field.size}` : names.switchSizeMd
|
|
876
903
|
);
|
|
877
904
|
},
|
|
878
|
-
'data-
|
|
905
|
+
'data-field-switch': () => fieldAccessor().name || id,
|
|
879
906
|
for: id,
|
|
880
907
|
children: [
|
|
881
908
|
jsx('input', {
|
|
@@ -895,7 +922,7 @@ export function createForm(input: FormProps = {}): Form {
|
|
|
895
922
|
}),
|
|
896
923
|
jsx('span', {
|
|
897
924
|
className: () => state.className.switchSlider,
|
|
898
|
-
'data-
|
|
925
|
+
'data-field-switch-slider': '',
|
|
899
926
|
}),
|
|
900
927
|
],
|
|
901
928
|
}) as HTMLLabelElement;
|
|
@@ -916,6 +943,8 @@ export function createForm(input: FormProps = {}): Form {
|
|
|
916
943
|
...controlProps<HTMLInputElement>(fieldAccessor, id, {
|
|
917
944
|
type: inputType,
|
|
918
945
|
className: () => fieldAccessor().className || state.className.input,
|
|
946
|
+
placeholder: () => fieldAccessor().placeholder || '',
|
|
947
|
+
readonly: () => !!fieldAccessor().readonly,
|
|
919
948
|
autocomplete: () =>
|
|
920
949
|
fieldAccessor().autocomplete || autoComplete(inputType),
|
|
921
950
|
value: () => fieldAccessor().value ?? '',
|
|
@@ -939,54 +968,67 @@ export function createForm(input: FormProps = {}): Form {
|
|
|
939
968
|
): HTMLElement => {
|
|
940
969
|
const fieldAccessor = (): FormField => itemAccessor().payload;
|
|
941
970
|
const id = resolveFieldId(fieldAccessor(), indexAccessor());
|
|
942
|
-
|
|
971
|
+
const isGroupedControl = (): boolean => {
|
|
972
|
+
const type = itemAccessor().type;
|
|
973
|
+
return (
|
|
974
|
+
type === 'custom' ||
|
|
975
|
+
type === 'radio' ||
|
|
976
|
+
(type === 'checkbox' && Array.isArray(fieldAccessor().options))
|
|
977
|
+
);
|
|
978
|
+
};
|
|
979
|
+
const hasFieldLabel = (): boolean => {
|
|
980
|
+
const label = fieldAccessor().label;
|
|
981
|
+
return label !== false && label !== undefined;
|
|
982
|
+
};
|
|
983
|
+
const fieldTitle = (): HTMLElement | null => {
|
|
984
|
+
if (!hasFieldLabel()) return null;
|
|
985
|
+
const props = {
|
|
986
|
+
className: () =>
|
|
987
|
+
joinClasses(
|
|
988
|
+
state.className.label,
|
|
989
|
+
fieldIsRequired(fieldAccessor(), state.validator.rules)
|
|
990
|
+
? state.className.required
|
|
991
|
+
: ''
|
|
992
|
+
),
|
|
993
|
+
'data-field-label': () => fieldAccessor().name || id,
|
|
994
|
+
children: () => asRenderable(fieldAccessor().label),
|
|
995
|
+
};
|
|
996
|
+
if (isGroupedControl()) return jsx('legend', props) as HTMLElement;
|
|
997
|
+
return jsx('label', { ...props, for: id }) as HTMLElement;
|
|
998
|
+
};
|
|
999
|
+
const controlContainer = (): HTMLElement =>
|
|
1000
|
+
jsx('div', {
|
|
1001
|
+
className: () => state.className.control,
|
|
1002
|
+
'data-field-control': () =>
|
|
1003
|
+
fieldAccessor().name || String(indexAccessor()),
|
|
1004
|
+
children: [
|
|
1005
|
+
asRenderable(
|
|
1006
|
+
controlView(itemAccessor, fieldAccessor, id, indexAccessor)
|
|
1007
|
+
),
|
|
1008
|
+
() => {
|
|
1009
|
+
const current = fieldAccessor();
|
|
1010
|
+
return current.help
|
|
1011
|
+
? jsx('div', {
|
|
1012
|
+
className: 'help-block',
|
|
1013
|
+
'data-field-help': () =>
|
|
1014
|
+
fieldAccessor().name || String(indexAccessor()),
|
|
1015
|
+
children: () => asRenderable(fieldAccessor().help),
|
|
1016
|
+
})
|
|
1017
|
+
: null;
|
|
1018
|
+
},
|
|
1019
|
+
],
|
|
1020
|
+
}) as HTMLElement;
|
|
1021
|
+
const rootProps = {
|
|
943
1022
|
className: () => state.className.item,
|
|
944
|
-
'data-form-
|
|
1023
|
+
'data-form-field': () => fieldAccessor().name || String(indexAccessor()),
|
|
945
1024
|
style: () => ({
|
|
946
1025
|
display: itemAccessor().type === 'hidden' ? 'none' : '',
|
|
947
1026
|
}),
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
}
|
|
954
|
-
return jsx('label', {
|
|
955
|
-
className: () =>
|
|
956
|
-
joinClasses(
|
|
957
|
-
state.className.label,
|
|
958
|
-
fieldIsRequired(fieldAccessor(), state.validator.rules)
|
|
959
|
-
? state.className.required
|
|
960
|
-
: ''
|
|
961
|
-
),
|
|
962
|
-
'data-form-label': () => fieldAccessor().name || id,
|
|
963
|
-
for: id,
|
|
964
|
-
children: () => asRenderable(fieldAccessor().label),
|
|
965
|
-
});
|
|
966
|
-
},
|
|
967
|
-
jsx('div', {
|
|
968
|
-
className: () => state.className.control,
|
|
969
|
-
'data-form-control': () =>
|
|
970
|
-
fieldAccessor().name || String(indexAccessor()),
|
|
971
|
-
children: [
|
|
972
|
-
asRenderable(
|
|
973
|
-
controlView(itemAccessor, fieldAccessor, id, indexAccessor)
|
|
974
|
-
),
|
|
975
|
-
() => {
|
|
976
|
-
const current = fieldAccessor();
|
|
977
|
-
return current.help
|
|
978
|
-
? jsx('div', {
|
|
979
|
-
className: 'help-block',
|
|
980
|
-
'data-form-help': () =>
|
|
981
|
-
fieldAccessor().name || String(indexAccessor()),
|
|
982
|
-
children: () => asRenderable(fieldAccessor().help),
|
|
983
|
-
})
|
|
984
|
-
: null;
|
|
985
|
-
},
|
|
986
|
-
],
|
|
987
|
-
}),
|
|
988
|
-
],
|
|
989
|
-
}) as HTMLElement;
|
|
1027
|
+
};
|
|
1028
|
+
return jsx('fieldset', {
|
|
1029
|
+
...rootProps,
|
|
1030
|
+
children: [fieldTitle, controlContainer],
|
|
1031
|
+
}) as HTMLFieldSetElement;
|
|
990
1032
|
};
|
|
991
1033
|
|
|
992
1034
|
const itemView = (
|
|
@@ -1000,7 +1042,7 @@ export function createForm(input: FormProps = {}): Form {
|
|
|
1000
1042
|
style: {
|
|
1001
1043
|
justifyContent: buttonsJustifyContent,
|
|
1002
1044
|
},
|
|
1003
|
-
'data-
|
|
1045
|
+
'data-field-buttons': '',
|
|
1004
1046
|
hidden: () => state.buttons.length === 0,
|
|
1005
1047
|
children: For({
|
|
1006
1048
|
each: () => state.buttons,
|
|
@@ -1112,9 +1154,10 @@ export function createForm(input: FormProps = {}): Form {
|
|
|
1112
1154
|
: state.className.itemHorizontal
|
|
1113
1155
|
),
|
|
1114
1156
|
id: () => state.id,
|
|
1157
|
+
novalidate: () => state.validator.vanilla === false,
|
|
1115
1158
|
'data-form': 'root',
|
|
1116
1159
|
'data-form-layout': () => (state.vertical ? 'vertical' : 'horizontal'),
|
|
1117
|
-
'data-form-
|
|
1160
|
+
'data-form-field-layout': () =>
|
|
1118
1161
|
state.itemVertical ? 'vertical' : 'horizontal',
|
|
1119
1162
|
onSubmit: (event: Event) => void handleSubmit(event),
|
|
1120
1163
|
onReset: (event: Event) => {
|
package/src/css/form.css
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
@layer components {
|
|
2
2
|
.j-form,
|
|
3
|
-
.j-form .form-
|
|
4
|
-
.j-form .form-
|
|
3
|
+
.j-form .form-field,
|
|
4
|
+
.j-form .form-field .field-legend {
|
|
5
5
|
display: flex;
|
|
6
6
|
}
|
|
7
7
|
|
|
@@ -15,52 +15,62 @@
|
|
|
15
15
|
gap: var(--form-gap-horizontal, var(--s2));
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
.j-form .form-
|
|
18
|
+
.j-form .form-field {
|
|
19
19
|
gap: var(--form-label-gap, var(--space));
|
|
20
20
|
margin: 0;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
.j-form
|
|
23
|
+
.j-form fieldset.form-field {
|
|
24
|
+
border: 0;
|
|
25
|
+
padding: 0;
|
|
26
|
+
min-inline-size: 0;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.j-form.is-item-vertical .form-field {
|
|
24
30
|
flex-direction: column;
|
|
25
31
|
}
|
|
26
32
|
|
|
27
|
-
.j-form.is-item-horizontal .form-
|
|
33
|
+
.j-form.is-item-horizontal .form-field {
|
|
28
34
|
flex-direction: row;
|
|
29
35
|
}
|
|
30
36
|
|
|
31
|
-
.j-form .form-
|
|
37
|
+
.j-form .form-field .field-legend {
|
|
32
38
|
color: var(--form-item-label-color, var(--ui-fg-muted));
|
|
33
39
|
font-size: var(--form-item-label-size, var(--font-size-sm));
|
|
34
40
|
}
|
|
35
41
|
|
|
36
|
-
.j-form .form-
|
|
37
|
-
|
|
42
|
+
.j-form .form-field > legend.field-legend {
|
|
43
|
+
padding: 0;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.j-form .form-field .field-legend,
|
|
47
|
+
.j-form .form-field .field-control {
|
|
38
48
|
gap: var(--form-label-gap, var(--space));
|
|
39
49
|
}
|
|
40
50
|
|
|
41
|
-
.j-form.is-horizontal .form-
|
|
51
|
+
.j-form.is-horizontal .form-field .field-legend {
|
|
42
52
|
align-items: center;
|
|
43
53
|
height: var(--horizontal-form-label-height, var(--el-height-md));
|
|
44
54
|
}
|
|
45
55
|
|
|
46
|
-
|
|
56
|
+
.j-form .field-legend.is-required::after {
|
|
47
57
|
content: '*';
|
|
48
58
|
color: var(--required-color, var(--state-danger));
|
|
49
59
|
}
|
|
50
60
|
|
|
51
|
-
.j-form .form-
|
|
61
|
+
.j-form .form-field .field-control {
|
|
52
62
|
display: flex;
|
|
53
63
|
flex-direction: column;
|
|
54
64
|
margin: 0;
|
|
55
65
|
}
|
|
56
66
|
|
|
57
|
-
.j-form .form-
|
|
67
|
+
.j-form .form-field .field-control .help-block {
|
|
58
68
|
font-size: var(--form-help-block-font-size, var(--font-size-sm));
|
|
59
69
|
color: var(--form-help-block-color, var(--ui-fg-soft));
|
|
60
70
|
margin: 0;
|
|
61
71
|
}
|
|
62
72
|
|
|
63
|
-
.j-form .form-
|
|
73
|
+
.j-form .form-field .field-control .help-block.is-invalid {
|
|
64
74
|
color: var(--state-danger);
|
|
65
75
|
}
|
|
66
76
|
|
|
@@ -70,7 +80,7 @@
|
|
|
70
80
|
margin-top: 1rem;
|
|
71
81
|
}
|
|
72
82
|
|
|
73
|
-
.j-form [data-
|
|
83
|
+
.j-form [data-field-buttons] button {
|
|
74
84
|
position: relative;
|
|
75
85
|
}
|
|
76
86
|
|
|
@@ -178,31 +188,31 @@
|
|
|
178
188
|
}
|
|
179
189
|
|
|
180
190
|
/* input validate */
|
|
181
|
-
.j-input.is-valid,
|
|
182
|
-
.j-input.is-invalid,
|
|
191
|
+
/* .j-input.is-valid,
|
|
183
192
|
.j-select.is-valid,
|
|
184
|
-
.j-select.is-invalid,
|
|
185
193
|
.j-textarea.is-valid,
|
|
194
|
+
.j-input.is-invalid,
|
|
195
|
+
.j-select.is-invalid,
|
|
186
196
|
.j-textarea.is-invalid {
|
|
187
197
|
padding-right: calc(1.4285714286em + 0.875rem);
|
|
188
198
|
background-repeat: no-repeat;
|
|
189
199
|
background-position: right calc(0.3571428572em + 0.21875rem) center;
|
|
190
200
|
background-size: calc(0.7142857143em + 0.4375rem)
|
|
191
201
|
calc(0.7142857143em + 0.4375rem);
|
|
192
|
-
}
|
|
202
|
+
} */
|
|
193
203
|
|
|
194
|
-
.j-input.is-valid,
|
|
204
|
+
/* .j-input.is-valid,
|
|
195
205
|
.j-select.is-valid,
|
|
196
206
|
.j-textarea.is-valid {
|
|
197
207
|
border-color: var(--form-valid-border-color, var(--state-success));
|
|
198
208
|
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%232fb344' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='20 6 9 17 4 12'%3e%3c/polyline%3e%3c/svg%3e");
|
|
199
|
-
}
|
|
209
|
+
} */
|
|
200
210
|
|
|
201
211
|
.j-input.is-invalid,
|
|
202
212
|
.j-select.is-invalid,
|
|
203
213
|
.j-textarea.is-invalid {
|
|
204
214
|
border-color: var(--form-invalid-border-color, var(--state-danger));
|
|
205
|
-
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23d63939' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cline x1='18' y1='6' x2='6' y2='18'%3e%3c/line%3e%3cline x1='6' y1='6' x2='18' y2='18'%3e%3c/line%3e%3c/svg%3e");
|
|
215
|
+
/* background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23d63939' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cline x1='18' y1='6' x2='6' y2='18'%3e%3c/line%3e%3cline x1='6' y1='6' x2='18' y2='18'%3e%3c/line%3e%3c/svg%3e"); */
|
|
206
216
|
}
|
|
207
217
|
|
|
208
218
|
/* type color */
|
|
@@ -851,11 +861,11 @@
|
|
|
851
861
|
box-shadow: var(--input-focus-shadow, none);
|
|
852
862
|
}
|
|
853
863
|
|
|
854
|
-
.j-input.is-valid:focus-within,
|
|
864
|
+
/* .j-input.is-valid:focus-within,
|
|
855
865
|
.j-select.is-valid:focus-within {
|
|
856
866
|
border-color: transparent;
|
|
857
867
|
outline-color: var(--form-valid-border-color, var(--state-success));
|
|
858
|
-
}
|
|
868
|
+
} */
|
|
859
869
|
|
|
860
870
|
.j-input.is-invalid:focus-within,
|
|
861
871
|
.j-select.is-invalid:focus-within {
|
package/src/primitives/toast.ts
CHANGED
|
@@ -156,9 +156,10 @@ async function closeByUser(
|
|
|
156
156
|
toast: HTMLElement,
|
|
157
157
|
options: ToastOptions
|
|
158
158
|
): Promise<void> {
|
|
159
|
-
|
|
160
|
-
await options.onClose?.();
|
|
159
|
+
const shouldCancel = isToastLoading(options);
|
|
161
160
|
hide(toast);
|
|
161
|
+
if (shouldCancel) await options.onCancel?.();
|
|
162
|
+
await options.onClose?.();
|
|
162
163
|
}
|
|
163
164
|
|
|
164
165
|
function bindToastStatus(
|