@proyecto-viviana/solid-stately 0.2.7 → 0.3.0
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/README.md +30 -283
- package/dist/autocomplete/createAutocompleteState.d.ts +2 -2
- package/dist/autocomplete/index.d.ts +1 -1
- package/dist/calendar/createCalendarState.d.ts +22 -7
- package/dist/calendar/createDateFieldState.d.ts +30 -7
- package/dist/calendar/createDatePickerState.d.ts +60 -0
- package/dist/calendar/createRangeCalendarState.d.ts +27 -8
- package/dist/calendar/createTimeFieldState.d.ts +34 -7
- package/dist/calendar/index.d.ts +7 -6
- package/dist/checkbox/createCheckboxGroupState.d.ts +6 -6
- package/dist/checkbox/index.d.ts +1 -1
- package/dist/collections/ListCollection.d.ts +1 -1
- package/dist/collections/createListState.d.ts +8 -8
- package/dist/collections/createMenuState.d.ts +7 -7
- package/dist/collections/createSelectionState.d.ts +5 -5
- package/dist/collections/index.d.ts +5 -5
- package/dist/collections/types.d.ts +12 -12
- package/dist/color/Color.d.ts +1 -1
- package/dist/color/createColorAreaState.d.ts +4 -2
- package/dist/color/createColorFieldState.d.ts +38 -12
- package/dist/color/createColorSliderState.d.ts +9 -2
- package/dist/color/createColorWheelState.d.ts +13 -2
- package/dist/color/getColorChannels.d.ts +1 -1
- package/dist/color/index.d.ts +6 -6
- package/dist/color/types.d.ts +4 -4
- package/dist/combobox/createComboBoxState.d.ts +27 -13
- package/dist/combobox/index.d.ts +1 -1
- package/dist/data/createAsyncList.d.ts +4 -4
- package/dist/data/createListData.d.ts +2 -2
- package/dist/data/createTreeData.d.ts +6 -2
- package/dist/data/index.d.ts +3 -3
- package/dist/datepicker/index.d.ts +2 -4
- package/dist/disclosure/createDisclosureState.d.ts +2 -2
- package/dist/disclosure/index.d.ts +1 -1
- package/dist/dnd/createDragState.d.ts +2 -2
- package/dist/dnd/createDraggableCollectionState.d.ts +2 -2
- package/dist/dnd/createDropState.d.ts +2 -2
- package/dist/dnd/createDroppableCollectionState.d.ts +3 -3
- package/dist/dnd/index.d.ts +5 -5
- package/dist/dnd/types.d.ts +16 -16
- package/dist/form/createFormValidationState.d.ts +3 -3
- package/dist/form/index.d.ts +1 -1
- package/dist/grid/createGridState.d.ts +2 -2
- package/dist/grid/index.d.ts +2 -2
- package/dist/grid/types.d.ts +13 -11
- package/dist/index.d.ts +31 -30
- package/dist/index.js +7924 -7238
- package/dist/index.js.map +1 -1
- package/dist/menu/index.d.ts +2 -2
- package/dist/numberfield/createNumberFieldState.d.ts +2 -2
- package/dist/numberfield/index.d.ts +1 -1
- package/dist/overlays/createOverlayTriggerState.d.ts +2 -2
- package/dist/overlays/index.d.ts +1 -1
- package/dist/radio/createRadioGroupState.d.ts +7 -7
- package/dist/radio/index.d.ts +1 -1
- package/dist/searchfield/createSearchFieldState.d.ts +2 -2
- package/dist/searchfield/index.d.ts +2 -2
- package/dist/select/createSelectState.d.ts +8 -8
- package/dist/select/index.d.ts +1 -1
- package/dist/selection/index.d.ts +5 -5
- package/dist/slider/createSliderState.d.ts +3 -3
- package/dist/slider/index.d.ts +2 -2
- package/dist/steplist/createStepListState.d.ts +48 -0
- package/dist/steplist/index.d.ts +1 -0
- package/dist/table/TableCollection.d.ts +3 -3
- package/dist/table/createTableColumnResizeState.d.ts +54 -0
- package/dist/table/createTableState.d.ts +2 -2
- package/dist/table/index.d.ts +5 -3
- package/dist/table/types.d.ts +10 -10
- package/dist/tabs/createTabListState.d.ts +5 -5
- package/dist/tabs/index.d.ts +1 -1
- package/dist/textfield/createTextFieldState.d.ts +2 -2
- package/dist/textfield/index.d.ts +1 -1
- package/dist/toast/createToastState.d.ts +8 -2
- package/dist/toast/index.d.ts +1 -1
- package/dist/toggle/createToggleGroupState.d.ts +4 -4
- package/dist/toggle/createToggleState.d.ts +2 -2
- package/dist/toggle/index.d.ts +2 -2
- package/dist/tooltip/createTooltipTriggerState.d.ts +2 -2
- package/dist/tooltip/index.d.ts +1 -1
- package/dist/tree/TreeCollection.d.ts +2 -2
- package/dist/tree/createTreeState.d.ts +2 -2
- package/dist/tree/index.d.ts +3 -3
- package/dist/tree/types.d.ts +19 -13
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/reactivity.d.ts +1 -1
- package/package.json +29 -30
- package/src/autocomplete/createAutocompleteState.d.ts +19 -17
- package/src/autocomplete/createAutocompleteState.ts +24 -30
- package/src/autocomplete/index.d.ts +6 -2
- package/src/autocomplete/index.ts +1 -1
- package/src/calendar/createCalendarState.d.ts +139 -117
- package/src/calendar/createCalendarState.ts +221 -74
- package/src/calendar/createDateFieldState.d.ts +130 -95
- package/src/calendar/createDateFieldState.ts +263 -151
- package/src/calendar/createDatePickerState.ts +347 -0
- package/src/calendar/createRangeCalendarState.d.ts +154 -129
- package/src/calendar/createRangeCalendarState.ts +293 -79
- package/src/calendar/createTimeFieldState.d.ts +81 -79
- package/src/calendar/createTimeFieldState.ts +187 -108
- package/src/calendar/index.d.ts +80 -7
- package/src/calendar/index.ts +21 -12
- package/src/checkbox/createCheckboxGroupState.d.ts +57 -55
- package/src/checkbox/createCheckboxGroupState.ts +20 -29
- package/src/checkbox/index.d.ts +6 -2
- package/src/checkbox/index.ts +1 -1
- package/src/collections/ListCollection.d.ts +25 -22
- package/src/collections/ListCollection.ts +6 -6
- package/src/collections/createListState.d.ts +73 -58
- package/src/collections/createListState.ts +19 -18
- package/src/collections/createMenuState.d.ts +36 -31
- package/src/collections/createMenuState.ts +18 -12
- package/src/collections/createSelectionState.d.ts +78 -65
- package/src/collections/createSelectionState.ts +36 -32
- package/src/collections/index.d.ts +38 -6
- package/src/collections/index.ts +5 -10
- package/src/collections/types.d.ts +101 -101
- package/src/collections/types.ts +12 -12
- package/src/color/Color.d.ts +20 -5
- package/src/color/Color.ts +357 -254
- package/src/color/createColorAreaState.d.ts +67 -65
- package/src/color/createColorAreaState.ts +21 -13
- package/src/color/createColorFieldState.d.ts +46 -44
- package/src/color/createColorFieldState.ts +285 -149
- package/src/color/createColorSliderState.d.ts +58 -56
- package/src/color/createColorSliderState.ts +45 -14
- package/src/color/createColorWheelState.d.ts +42 -40
- package/src/color/createColorWheelState.ts +101 -64
- package/src/color/getColorChannels.ts +7 -5
- package/src/color/index.d.ts +36 -7
- package/src/color/index.ts +6 -9
- package/src/color/types.d.ts +68 -63
- package/src/color/types.ts +11 -19
- package/src/combobox/createComboBoxState.d.ts +107 -105
- package/src/combobox/createComboBoxState.ts +176 -89
- package/src/combobox/index.d.ts +10 -2
- package/src/combobox/index.ts +1 -1
- package/src/data/createAsyncList.ts +89 -63
- package/src/data/createListData.ts +67 -67
- package/src/data/createTreeData.ts +304 -91
- package/src/data/index.ts +3 -3
- package/src/datepicker/index.ts +6 -10
- package/src/disclosure/createDisclosureState.d.ts +47 -43
- package/src/disclosure/createDisclosureState.ts +7 -21
- package/src/disclosure/index.d.ts +10 -2
- package/src/disclosure/index.ts +1 -1
- package/src/dnd/createDragState.d.ts +51 -42
- package/src/dnd/createDragState.ts +12 -14
- package/src/dnd/createDraggableCollectionState.d.ts +52 -41
- package/src/dnd/createDraggableCollectionState.ts +14 -21
- package/src/dnd/createDropState.d.ts +64 -45
- package/src/dnd/createDropState.ts +22 -32
- package/src/dnd/createDroppableCollectionState.d.ts +88 -59
- package/src/dnd/createDroppableCollectionState.ts +40 -43
- package/src/dnd/index.d.ts +54 -6
- package/src/dnd/index.ts +5 -18
- package/src/dnd/types.d.ts +167 -156
- package/src/dnd/types.ts +20 -21
- package/src/form/createFormValidationState.d.ts +47 -45
- package/src/form/createFormValidationState.ts +30 -63
- package/src/form/index.d.ts +16 -2
- package/src/form/index.ts +1 -1
- package/src/grid/createGridState.d.ts +7 -4
- package/src/grid/createGridState.ts +44 -51
- package/src/grid/index.d.ts +3 -3
- package/src/grid/index.ts +2 -8
- package/src/grid/types.d.ts +136 -129
- package/src/grid/types.ts +20 -18
- package/src/index.d.ts +310 -26
- package/src/index.ts +48 -89
- package/src/menu/index.ts +2 -4
- package/src/numberfield/createNumberFieldState.d.ts +56 -54
- package/src/numberfield/createNumberFieldState.ts +26 -31
- package/src/numberfield/index.d.ts +6 -2
- package/src/numberfield/index.ts +1 -1
- package/src/overlays/createOverlayTriggerState.d.ts +22 -20
- package/src/overlays/createOverlayTriggerState.ts +3 -4
- package/src/overlays/index.d.ts +6 -2
- package/src/overlays/index.ts +1 -1
- package/src/radio/createRadioGroupState.d.ts +54 -52
- package/src/radio/createRadioGroupState.ts +27 -29
- package/src/radio/index.d.ts +7 -2
- package/src/radio/index.ts +1 -1
- package/src/searchfield/createSearchFieldState.d.ts +16 -14
- package/src/searchfield/createSearchFieldState.ts +5 -11
- package/src/searchfield/index.d.ts +3 -3
- package/src/searchfield/index.ts +2 -5
- package/src/select/createSelectState.d.ts +63 -61
- package/src/select/createSelectState.ts +27 -27
- package/src/select/index.d.ts +2 -2
- package/src/select/index.ts +1 -5
- package/src/selection/index.ts +6 -7
- package/src/slider/createSliderState.d.ts +60 -60
- package/src/slider/createSliderState.ts +55 -33
- package/src/slider/index.d.ts +3 -3
- package/src/slider/index.ts +2 -6
- package/src/ssr/index.d.ts +1 -1
- package/src/ssr/index.ts +2 -2
- package/src/steplist/createStepListState.ts +191 -0
- package/src/steplist/index.ts +5 -0
- package/src/table/TableCollection.d.ts +42 -40
- package/src/table/TableCollection.ts +61 -64
- package/src/table/createTableColumnResizeState.ts +242 -0
- package/src/table/createTableState.d.ts +7 -4
- package/src/table/createTableState.ts +10 -7
- package/src/table/index.d.ts +14 -4
- package/src/table/index.ts +10 -3
- package/src/table/types.d.ts +98 -92
- package/src/table/types.ts +17 -13
- package/src/tabs/createTabListState.d.ts +59 -57
- package/src/tabs/createTabListState.ts +24 -31
- package/src/tabs/index.d.ts +8 -2
- package/src/tabs/index.ts +1 -1
- package/src/textfield/createTextFieldState.d.ts +16 -14
- package/src/textfield/createTextFieldState.ts +7 -18
- package/src/textfield/index.d.ts +6 -2
- package/src/textfield/index.ts +1 -1
- package/src/toast/createToastState.d.ts +92 -86
- package/src/toast/createToastState.ts +48 -43
- package/src/toast/index.d.ts +12 -2
- package/src/toast/index.ts +1 -1
- package/src/toggle/createToggleGroupState.ts +11 -21
- package/src/toggle/createToggleState.d.ts +19 -19
- package/src/toggle/createToggleState.ts +2 -16
- package/src/toggle/index.d.ts +2 -2
- package/src/toggle/index.ts +2 -6
- package/src/tooltip/createTooltipTriggerState.d.ts +17 -17
- package/src/tooltip/createTooltipTriggerState.ts +12 -11
- package/src/tooltip/index.d.ts +7 -2
- package/src/tooltip/index.ts +1 -1
- package/src/tree/TreeCollection.d.ts +26 -23
- package/src/tree/TreeCollection.ts +29 -22
- package/src/tree/createTreeState.d.ts +7 -4
- package/src/tree/createTreeState.ts +39 -41
- package/src/tree/index.d.ts +10 -4
- package/src/tree/index.ts +3 -3
- package/src/tree/types.d.ts +131 -126
- package/src/tree/types.ts +22 -13
- package/src/utils/index.d.ts +2 -2
- package/src/utils/index.ts +1 -1
- package/src/utils/reactivity.d.ts +2 -2
- package/src/utils/reactivity.ts +3 -3
|
@@ -6,63 +6,63 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Port of react-stately's useFormValidationState.
|
|
8
8
|
*/
|
|
9
|
-
import { type Accessor } from
|
|
9
|
+
import { type Accessor } from "solid-js";
|
|
10
10
|
/** Standard HTML ValidityState interface. */
|
|
11
11
|
export interface ValidityState {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
12
|
+
badInput: boolean;
|
|
13
|
+
customError: boolean;
|
|
14
|
+
patternMismatch: boolean;
|
|
15
|
+
rangeOverflow: boolean;
|
|
16
|
+
rangeUnderflow: boolean;
|
|
17
|
+
stepMismatch: boolean;
|
|
18
|
+
tooLong: boolean;
|
|
19
|
+
tooShort: boolean;
|
|
20
|
+
typeMismatch: boolean;
|
|
21
|
+
valueMissing: boolean;
|
|
22
|
+
valid: boolean;
|
|
23
23
|
}
|
|
24
24
|
/** Result of validation. */
|
|
25
25
|
export interface ValidationResult {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
26
|
+
/** Whether the value is invalid. */
|
|
27
|
+
isInvalid: boolean;
|
|
28
|
+
/** Details about which validation constraints failed. */
|
|
29
|
+
validationDetails: ValidityState;
|
|
30
|
+
/** Error messages to display. */
|
|
31
|
+
validationErrors: string[];
|
|
32
32
|
}
|
|
33
33
|
/** Map of field names to their validation errors. */
|
|
34
34
|
export type ValidationErrors = Record<string, string | string[]>;
|
|
35
35
|
/** Validation function that returns error messages or true/false. */
|
|
36
36
|
export type ValidationFunction<T> = (value: T) => boolean | string | string[] | null | undefined;
|
|
37
37
|
/** Validation behavior mode. */
|
|
38
|
-
export type ValidationBehavior =
|
|
38
|
+
export type ValidationBehavior = "aria" | "native";
|
|
39
39
|
export interface FormValidationProps<T> {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
40
|
+
/** Whether the value is invalid (controlled). */
|
|
41
|
+
isInvalid?: boolean;
|
|
42
|
+
/** @deprecated Use isInvalid instead. */
|
|
43
|
+
validationState?: "valid" | "invalid";
|
|
44
|
+
/** Custom validation function. */
|
|
45
|
+
validate?: ValidationFunction<T>;
|
|
46
|
+
/** Validation behavior: 'aria' for realtime, 'native' for on submit. */
|
|
47
|
+
validationBehavior?: ValidationBehavior;
|
|
48
|
+
/** Built-in validation result from native input. */
|
|
49
|
+
builtinValidation?: ValidationResult;
|
|
50
|
+
/** Field name(s) for server error lookup. */
|
|
51
|
+
name?: string | string[];
|
|
52
|
+
/** Current field value. */
|
|
53
|
+
value: T | null;
|
|
54
54
|
}
|
|
55
55
|
export interface FormValidationState {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
56
|
+
/** Realtime validation results, updated as the user edits the value. */
|
|
57
|
+
realtimeValidation: Accessor<ValidationResult>;
|
|
58
|
+
/** Currently displayed validation results, updated when the user commits their changes. */
|
|
59
|
+
displayValidation: Accessor<ValidationResult>;
|
|
60
|
+
/** Updates the current validation result. Not displayed to the user until `commitValidation` is called. */
|
|
61
|
+
updateValidation(result: ValidationResult): void;
|
|
62
|
+
/** Resets the displayed validation state to valid when the user resets the form. */
|
|
63
|
+
resetValidation(): void;
|
|
64
|
+
/** Commits the realtime validation so it is displayed to the user. */
|
|
65
|
+
commitValidation(): void;
|
|
66
66
|
}
|
|
67
67
|
/** A valid validity state. */
|
|
68
68
|
export declare const VALID_VALIDITY_STATE: ValidityState;
|
|
@@ -92,9 +92,11 @@ export declare const privateValidationStateProp: string;
|
|
|
92
92
|
* const errors = () => validationState.displayValidation().validationErrors;
|
|
93
93
|
* ```
|
|
94
94
|
*/
|
|
95
|
-
export declare function createFormValidationState<T>(
|
|
95
|
+
export declare function createFormValidationState<T>(
|
|
96
|
+
props: FormValidationProps<T>,
|
|
97
|
+
): FormValidationState;
|
|
96
98
|
/**
|
|
97
99
|
* Merges multiple validation results into one.
|
|
98
100
|
*/
|
|
99
101
|
export declare function mergeValidation(...results: ValidationResult[]): ValidationResult;
|
|
100
|
-
//# sourceMappingURL=createFormValidationState.d.ts.map
|
|
102
|
+
//# sourceMappingURL=createFormValidationState.d.ts.map
|
|
@@ -14,11 +14,7 @@ import {
|
|
|
14
14
|
createMemo,
|
|
15
15
|
createSignal,
|
|
16
16
|
useContext,
|
|
17
|
-
} from
|
|
18
|
-
|
|
19
|
-
// ============================================
|
|
20
|
-
// TYPES
|
|
21
|
-
// ============================================
|
|
17
|
+
} from "solid-js";
|
|
22
18
|
|
|
23
19
|
/** Standard HTML ValidityState interface. */
|
|
24
20
|
export interface ValidityState {
|
|
@@ -52,13 +48,13 @@ export type ValidationErrors = Record<string, string | string[]>;
|
|
|
52
48
|
export type ValidationFunction<T> = (value: T) => boolean | string | string[] | null | undefined;
|
|
53
49
|
|
|
54
50
|
/** Validation behavior mode. */
|
|
55
|
-
export type ValidationBehavior =
|
|
51
|
+
export type ValidationBehavior = "aria" | "native";
|
|
56
52
|
|
|
57
53
|
export interface FormValidationProps<T> {
|
|
58
54
|
/** Whether the value is invalid (controlled). */
|
|
59
55
|
isInvalid?: boolean;
|
|
60
56
|
/** @deprecated Use isInvalid instead. */
|
|
61
|
-
validationState?:
|
|
57
|
+
validationState?: "valid" | "invalid";
|
|
62
58
|
/** Custom validation function. */
|
|
63
59
|
validate?: ValidationFunction<T>;
|
|
64
60
|
/** Validation behavior: 'aria' for realtime, 'native' for on submit. */
|
|
@@ -84,10 +80,6 @@ export interface FormValidationState {
|
|
|
84
80
|
commitValidation(): void;
|
|
85
81
|
}
|
|
86
82
|
|
|
87
|
-
// ============================================
|
|
88
|
-
// CONSTANTS
|
|
89
|
-
// ============================================
|
|
90
|
-
|
|
91
83
|
/** A valid validity state. */
|
|
92
84
|
export const VALID_VALIDITY_STATE: ValidityState = {
|
|
93
85
|
badInput: false,
|
|
@@ -117,19 +109,11 @@ export const DEFAULT_VALIDATION_RESULT: ValidationResult = {
|
|
|
117
109
|
validationErrors: [],
|
|
118
110
|
};
|
|
119
111
|
|
|
120
|
-
// ============================================
|
|
121
|
-
// CONTEXT
|
|
122
|
-
// ============================================
|
|
123
|
-
|
|
124
112
|
/** Context for server-side validation errors. */
|
|
125
113
|
export const FormValidationContext = createContext<ValidationErrors>({});
|
|
126
114
|
|
|
127
115
|
/** Private prop key for passing validation state to children. */
|
|
128
|
-
export const privateValidationStateProp =
|
|
129
|
-
|
|
130
|
-
// ============================================
|
|
131
|
-
// HELPERS
|
|
132
|
-
// ============================================
|
|
116
|
+
export const privateValidationStateProp = "__formValidationState" + Date.now();
|
|
133
117
|
|
|
134
118
|
function asArray<T>(v: T | T[] | undefined): T[] {
|
|
135
119
|
if (!v) {
|
|
@@ -139,9 +123,9 @@ function asArray<T>(v: T | T[] | undefined): T[] {
|
|
|
139
123
|
}
|
|
140
124
|
|
|
141
125
|
function runValidate<T>(validate: ValidationFunction<T>, value: T): string[] {
|
|
142
|
-
if (typeof validate ===
|
|
126
|
+
if (typeof validate === "function") {
|
|
143
127
|
const e = validate(value);
|
|
144
|
-
if (e && typeof e !==
|
|
128
|
+
if (e && typeof e !== "boolean") {
|
|
145
129
|
return asArray(e);
|
|
146
130
|
}
|
|
147
131
|
}
|
|
@@ -158,10 +142,7 @@ function getValidationResult(errors: string[]): ValidationResult | null {
|
|
|
158
142
|
: null;
|
|
159
143
|
}
|
|
160
144
|
|
|
161
|
-
function isEqualValidation(
|
|
162
|
-
a: ValidationResult | null,
|
|
163
|
-
b: ValidationResult | null
|
|
164
|
-
): boolean {
|
|
145
|
+
function isEqualValidation(a: ValidationResult | null, b: ValidationResult | null): boolean {
|
|
165
146
|
if (a === b) {
|
|
166
147
|
return true;
|
|
167
148
|
}
|
|
@@ -172,15 +153,11 @@ function isEqualValidation(
|
|
|
172
153
|
a.validationErrors.length === b.validationErrors.length &&
|
|
173
154
|
a.validationErrors.every((ae, i) => ae === b.validationErrors[i]) &&
|
|
174
155
|
Object.entries(a.validationDetails).every(
|
|
175
|
-
([k, v]) => b.validationDetails[k as keyof ValidityState] === v
|
|
156
|
+
([k, v]) => b.validationDetails[k as keyof ValidityState] === v,
|
|
176
157
|
)
|
|
177
158
|
);
|
|
178
159
|
}
|
|
179
160
|
|
|
180
|
-
// ============================================
|
|
181
|
-
// HOOK
|
|
182
|
-
// ============================================
|
|
183
|
-
|
|
184
161
|
/**
|
|
185
162
|
* Creates form validation state for a field.
|
|
186
163
|
*
|
|
@@ -201,21 +178,12 @@ function isEqualValidation(
|
|
|
201
178
|
* const errors = () => validationState.displayValidation().validationErrors;
|
|
202
179
|
* ```
|
|
203
180
|
*/
|
|
204
|
-
export function createFormValidationState<T>(
|
|
205
|
-
props
|
|
206
|
-
): FormValidationState {
|
|
207
|
-
const {
|
|
208
|
-
isInvalid,
|
|
209
|
-
validationState,
|
|
210
|
-
name,
|
|
211
|
-
builtinValidation: builtinValidationProp,
|
|
212
|
-
validate,
|
|
213
|
-
validationBehavior = 'aria',
|
|
214
|
-
} = props;
|
|
181
|
+
export function createFormValidationState<T>(props: FormValidationProps<T>): FormValidationState {
|
|
182
|
+
const validationBehavior = () => props.validationBehavior ?? "aria";
|
|
215
183
|
|
|
216
184
|
// Backward compatibility
|
|
217
185
|
const isInvalidProp = createMemo(
|
|
218
|
-
() => isInvalid ?? (validationState ===
|
|
186
|
+
() => props.isInvalid ?? (props.validationState === "invalid" ? true : undefined),
|
|
219
187
|
);
|
|
220
188
|
|
|
221
189
|
// Controlled error from isInvalid prop
|
|
@@ -226,11 +194,12 @@ export function createFormValidationState<T>(
|
|
|
226
194
|
validationErrors: [],
|
|
227
195
|
validationDetails: CUSTOM_VALIDITY_STATE,
|
|
228
196
|
}
|
|
229
|
-
: null
|
|
197
|
+
: null,
|
|
230
198
|
);
|
|
231
199
|
|
|
232
200
|
// Client-side validation
|
|
233
201
|
const clientError = createMemo<ValidationResult | null>(() => {
|
|
202
|
+
const validate = props.validate;
|
|
234
203
|
if (!validate || props.value == null) {
|
|
235
204
|
return null;
|
|
236
205
|
}
|
|
@@ -240,6 +209,7 @@ export function createFormValidationState<T>(
|
|
|
240
209
|
|
|
241
210
|
// Built-in validation (skip if valid)
|
|
242
211
|
const builtinValidation = createMemo<ValidationResult | undefined>(() => {
|
|
212
|
+
const builtinValidationProp = props.builtinValidation;
|
|
243
213
|
if (builtinValidationProp?.validationDetails.valid) {
|
|
244
214
|
return undefined;
|
|
245
215
|
}
|
|
@@ -249,6 +219,7 @@ export function createFormValidationState<T>(
|
|
|
249
219
|
// Server errors from context
|
|
250
220
|
const serverErrors = useContext(FormValidationContext);
|
|
251
221
|
const serverErrorMessages = createMemo(() => {
|
|
222
|
+
const name = props.name;
|
|
252
223
|
if (name) {
|
|
253
224
|
return Array.isArray(name)
|
|
254
225
|
? name.flatMap((n) => asArray(serverErrors[n]))
|
|
@@ -269,13 +240,11 @@ export function createFormValidationState<T>(
|
|
|
269
240
|
});
|
|
270
241
|
|
|
271
242
|
const serverError = createMemo<ValidationResult | null>(() =>
|
|
272
|
-
getValidationResult(isServerErrorCleared() ? [] : serverErrorMessages())
|
|
243
|
+
getValidationResult(isServerErrorCleared() ? [] : serverErrorMessages()),
|
|
273
244
|
);
|
|
274
245
|
|
|
275
246
|
// Track validation state
|
|
276
|
-
const [currentValidity, setCurrentValidity] = createSignal(
|
|
277
|
-
DEFAULT_VALIDATION_RESULT
|
|
278
|
-
);
|
|
247
|
+
const [currentValidity, setCurrentValidity] = createSignal(DEFAULT_VALIDATION_RESULT);
|
|
279
248
|
const [commitQueued, setCommitQueued] = createSignal(false);
|
|
280
249
|
|
|
281
250
|
let nextValidation = DEFAULT_VALIDATION_RESULT;
|
|
@@ -301,15 +270,13 @@ export function createFormValidationState<T>(
|
|
|
301
270
|
serverError() ||
|
|
302
271
|
clientError() ||
|
|
303
272
|
builtinValidation() ||
|
|
304
|
-
DEFAULT_VALIDATION_RESULT
|
|
273
|
+
DEFAULT_VALIDATION_RESULT,
|
|
305
274
|
);
|
|
306
275
|
|
|
307
276
|
// Display validation (what the user sees)
|
|
308
277
|
const displayValidation = createMemo<ValidationResult>(() => {
|
|
309
|
-
if (validationBehavior ===
|
|
310
|
-
return (
|
|
311
|
-
controlledError() || serverError() || currentValidity()
|
|
312
|
-
);
|
|
278
|
+
if (validationBehavior() === "native") {
|
|
279
|
+
return controlledError() || serverError() || currentValidity();
|
|
313
280
|
}
|
|
314
281
|
return (
|
|
315
282
|
controlledError() ||
|
|
@@ -325,10 +292,7 @@ export function createFormValidationState<T>(
|
|
|
325
292
|
displayValidation,
|
|
326
293
|
updateValidation(value: ValidationResult) {
|
|
327
294
|
// If validationBehavior is 'aria', update in realtime. Otherwise, store until commit.
|
|
328
|
-
if (
|
|
329
|
-
validationBehavior === 'aria' &&
|
|
330
|
-
!isEqualValidation(currentValidity(), value)
|
|
331
|
-
) {
|
|
295
|
+
if (validationBehavior() === "aria" && !isEqualValidation(currentValidity(), value)) {
|
|
332
296
|
setCurrentValidity(value);
|
|
333
297
|
} else {
|
|
334
298
|
nextValidation = value;
|
|
@@ -342,15 +306,20 @@ export function createFormValidationState<T>(
|
|
|
342
306
|
setCurrentValidity(error);
|
|
343
307
|
}
|
|
344
308
|
// Do not commit validation after the next render for native behavior.
|
|
345
|
-
if (validationBehavior ===
|
|
309
|
+
if (validationBehavior() === "native") {
|
|
346
310
|
setCommitQueued(false);
|
|
347
311
|
}
|
|
348
312
|
setServerErrorCleared(true);
|
|
349
313
|
},
|
|
350
314
|
commitValidation() {
|
|
351
315
|
// Commit validation state so the user sees it on blur/change/submit.
|
|
352
|
-
if (validationBehavior ===
|
|
353
|
-
|
|
316
|
+
if (validationBehavior() === "native") {
|
|
317
|
+
const error = clientError() || builtinValidation() || nextValidation;
|
|
318
|
+
if (!isEqualValidation(error, lastError)) {
|
|
319
|
+
lastError = error;
|
|
320
|
+
setCurrentValidity(error);
|
|
321
|
+
}
|
|
322
|
+
setCommitQueued(false);
|
|
354
323
|
}
|
|
355
324
|
setServerErrorCleared(true);
|
|
356
325
|
},
|
|
@@ -360,9 +329,7 @@ export function createFormValidationState<T>(
|
|
|
360
329
|
/**
|
|
361
330
|
* Merges multiple validation results into one.
|
|
362
331
|
*/
|
|
363
|
-
export function mergeValidation(
|
|
364
|
-
...results: ValidationResult[]
|
|
365
|
-
): ValidationResult {
|
|
332
|
+
export function mergeValidation(...results: ValidationResult[]): ValidationResult {
|
|
366
333
|
const errors = new Set<string>();
|
|
367
334
|
let isInvalid = false;
|
|
368
335
|
const validationDetails: ValidityState = { ...VALID_VALIDITY_STATE };
|
package/src/form/index.d.ts
CHANGED
|
@@ -1,2 +1,16 @@
|
|
|
1
|
-
export {
|
|
2
|
-
|
|
1
|
+
export {
|
|
2
|
+
createFormValidationState,
|
|
3
|
+
mergeValidation,
|
|
4
|
+
FormValidationContext,
|
|
5
|
+
privateValidationStateProp,
|
|
6
|
+
VALID_VALIDITY_STATE,
|
|
7
|
+
DEFAULT_VALIDATION_RESULT,
|
|
8
|
+
type FormValidationState,
|
|
9
|
+
type FormValidationProps,
|
|
10
|
+
type ValidationResult,
|
|
11
|
+
type ValidationErrors,
|
|
12
|
+
type ValidationFunction,
|
|
13
|
+
type ValidationBehavior,
|
|
14
|
+
type ValidityState,
|
|
15
|
+
} from "./createFormValidationState";
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
package/src/form/index.ts
CHANGED
|
@@ -2,11 +2,14 @@
|
|
|
2
2
|
* Grid state management for Table and GridList components.
|
|
3
3
|
* Based on @react-stately/grid/useGridState.
|
|
4
4
|
*/
|
|
5
|
-
import { type Accessor } from
|
|
6
|
-
import type { GridState, GridStateOptions, GridCollection } from
|
|
5
|
+
import { type Accessor } from "solid-js";
|
|
6
|
+
import type { GridState, GridStateOptions, GridCollection } from "./types";
|
|
7
7
|
/**
|
|
8
8
|
* Creates state management for a grid component.
|
|
9
9
|
* Handles row selection, focus management, and keyboard navigation state.
|
|
10
10
|
*/
|
|
11
|
-
export declare function createGridState<
|
|
12
|
-
|
|
11
|
+
export declare function createGridState<
|
|
12
|
+
T extends object,
|
|
13
|
+
C extends GridCollection<T> = GridCollection<T>,
|
|
14
|
+
>(options: Accessor<GridStateOptions<T, C>>): GridState<T, C>;
|
|
15
|
+
//# sourceMappingURL=createGridState.d.ts.map
|
|
@@ -3,43 +3,34 @@
|
|
|
3
3
|
* Based on @react-stately/grid/useGridState.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { createSignal, createEffect, createMemo, on, type Accessor } from
|
|
7
|
-
import type {
|
|
8
|
-
|
|
9
|
-
GridStateOptions,
|
|
10
|
-
GridCollection,
|
|
11
|
-
GridNode,
|
|
12
|
-
} from './types';
|
|
13
|
-
import type { Key, FocusStrategy } from '../collections/types';
|
|
6
|
+
import { createSignal, createEffect, createMemo, on, type Accessor } from "solid-js";
|
|
7
|
+
import type { GridState, GridStateOptions, GridCollection, GridNode } from "./types";
|
|
8
|
+
import type { Key, FocusStrategy } from "../collections/types";
|
|
14
9
|
|
|
15
10
|
/**
|
|
16
11
|
* Creates state management for a grid component.
|
|
17
12
|
* Handles row selection, focus management, and keyboard navigation state.
|
|
18
13
|
*/
|
|
19
14
|
export function createGridState<T extends object, C extends GridCollection<T> = GridCollection<T>>(
|
|
20
|
-
options: Accessor<GridStateOptions<T, C
|
|
15
|
+
options: Accessor<GridStateOptions<T, C>>,
|
|
21
16
|
): GridState<T, C> {
|
|
22
17
|
const getOptions = () => options();
|
|
23
18
|
|
|
24
|
-
// Disabled keys as a Set
|
|
25
19
|
const disabledKeys = createMemo(() => {
|
|
26
20
|
const keys = getOptions().disabledKeys;
|
|
27
21
|
return keys ? new Set(keys) : new Set<Key>();
|
|
28
22
|
});
|
|
29
23
|
|
|
30
|
-
// Focus state
|
|
31
24
|
const [isFocused, setIsFocused] = createSignal(false);
|
|
32
25
|
const [focusedKey, setFocusedKeyInternal] = createSignal<Key | null>(null);
|
|
33
26
|
const [childFocusStrategy, setChildFocusStrategy] = createSignal<FocusStrategy | null>(null);
|
|
34
27
|
const [isKeyboardNavigationDisabled, setKeyboardNavigationDisabled] = createSignal(false);
|
|
35
28
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
getInitialSelection(getOptions().defaultSelectedKeys)
|
|
29
|
+
const [internalSelectedKeys, setInternalSelectedKeys] = createSignal<"all" | Set<Key>>(
|
|
30
|
+
getInitialSelection(getOptions().defaultSelectedKeys),
|
|
39
31
|
);
|
|
40
32
|
const [anchorKey, setAnchorKey] = createSignal<Key | null>(null);
|
|
41
33
|
|
|
42
|
-
// Computed selection
|
|
43
34
|
const selectedKeys = createMemo(() => {
|
|
44
35
|
const opts = getOptions();
|
|
45
36
|
if (opts.selectedKeys !== undefined) {
|
|
@@ -48,24 +39,22 @@ export function createGridState<T extends object, C extends GridCollection<T> =
|
|
|
48
39
|
return internalSelectedKeys();
|
|
49
40
|
});
|
|
50
41
|
|
|
51
|
-
const selectionMode = createMemo(() => getOptions().selectionMode ??
|
|
52
|
-
const selectionBehavior = createMemo(() => getOptions().selectionBehavior ??
|
|
42
|
+
const selectionMode = createMemo(() => getOptions().selectionMode ?? "none");
|
|
43
|
+
const selectionBehavior = createMemo(() => getOptions().selectionBehavior ?? "toggle");
|
|
53
44
|
const disallowEmptySelection = createMemo(() => getOptions().disallowEmptySelection ?? false);
|
|
54
45
|
|
|
55
|
-
|
|
56
|
-
const focusMode = createMemo(() => getOptions().focusMode ?? 'row');
|
|
46
|
+
const focusMode = createMemo(() => getOptions().focusMode ?? "row");
|
|
57
47
|
|
|
58
|
-
|
|
59
|
-
const setFocusedKey = (key: Key | null, strategy: FocusStrategy = 'first') => {
|
|
48
|
+
const setFocusedKey = (key: Key | null, strategy: FocusStrategy = "first") => {
|
|
60
49
|
const opts = getOptions();
|
|
61
50
|
const collection = opts.collection;
|
|
62
51
|
|
|
63
52
|
// If focusMode is cell and an item is focused, focus a child cell instead
|
|
64
|
-
if (focusMode() ===
|
|
53
|
+
if (focusMode() === "cell" && key != null) {
|
|
65
54
|
const item = collection.getItem(key);
|
|
66
|
-
if (item?.type ===
|
|
55
|
+
if (item?.type === "item") {
|
|
67
56
|
const children = [...collection.getChildren(key)];
|
|
68
|
-
if (strategy ===
|
|
57
|
+
if (strategy === "last") {
|
|
69
58
|
key = children[children.length - 1]?.key ?? key;
|
|
70
59
|
} else {
|
|
71
60
|
key = children[0]?.key ?? key;
|
|
@@ -86,12 +75,16 @@ export function createGridState<T extends object, C extends GridCollection<T> =
|
|
|
86
75
|
(collection) => {
|
|
87
76
|
const currentFocusedKey = focusedKey();
|
|
88
77
|
|
|
89
|
-
if (
|
|
78
|
+
if (
|
|
79
|
+
currentFocusedKey != null &&
|
|
80
|
+
cachedCollection &&
|
|
81
|
+
!collection.getItem(currentFocusedKey)
|
|
82
|
+
) {
|
|
90
83
|
// The focused item was deleted, find a new one to focus
|
|
91
84
|
const node = cachedCollection.getItem(currentFocusedKey);
|
|
92
85
|
const parentNode =
|
|
93
86
|
node?.parentKey != null &&
|
|
94
|
-
(node.type ===
|
|
87
|
+
(node.type === "cell" || node.type === "rowheader" || node.type === "column")
|
|
95
88
|
? cachedCollection.getItem(node.parentKey)
|
|
96
89
|
: node;
|
|
97
90
|
|
|
@@ -107,13 +100,13 @@ export function createGridState<T extends object, C extends GridCollection<T> =
|
|
|
107
100
|
|
|
108
101
|
let index = Math.min(
|
|
109
102
|
diff > 1 ? Math.max(parentNode.index - diff + 1, 0) : parentNode.index,
|
|
110
|
-
rows.length - 1
|
|
103
|
+
rows.length - 1,
|
|
111
104
|
);
|
|
112
105
|
|
|
113
106
|
let newRow: GridNode<T> | null = null;
|
|
114
107
|
while (index >= 0) {
|
|
115
108
|
const row = rows[index];
|
|
116
|
-
if (!disabledKeys().has(row.key) && row.type !==
|
|
109
|
+
if (!disabledKeys().has(row.key) && row.type !== "headerrow") {
|
|
117
110
|
newRow = row;
|
|
118
111
|
break;
|
|
119
112
|
}
|
|
@@ -132,10 +125,7 @@ export function createGridState<T extends object, C extends GridCollection<T> =
|
|
|
132
125
|
if (newRow) {
|
|
133
126
|
const childNodes = newRow.hasChildNodes ? [...collection.getChildren(newRow.key)] : [];
|
|
134
127
|
const keyToFocus =
|
|
135
|
-
newRow.hasChildNodes &&
|
|
136
|
-
parentNode !== node &&
|
|
137
|
-
node &&
|
|
138
|
-
node.index < childNodes.length
|
|
128
|
+
newRow.hasChildNodes && parentNode !== node && node && node.index < childNodes.length
|
|
139
129
|
? childNodes[node.index].key
|
|
140
130
|
: newRow.key;
|
|
141
131
|
setFocusedKeyInternal(keyToFocus);
|
|
@@ -145,14 +135,14 @@ export function createGridState<T extends object, C extends GridCollection<T> =
|
|
|
145
135
|
}
|
|
146
136
|
|
|
147
137
|
cachedCollection = collection;
|
|
148
|
-
}
|
|
149
|
-
)
|
|
138
|
+
},
|
|
139
|
+
),
|
|
150
140
|
);
|
|
151
141
|
|
|
152
142
|
// Selection methods
|
|
153
143
|
const isSelected = (key: Key): boolean => {
|
|
154
144
|
const keys = selectedKeys();
|
|
155
|
-
if (keys ===
|
|
145
|
+
if (keys === "all") return true;
|
|
156
146
|
return keys.has(key);
|
|
157
147
|
};
|
|
158
148
|
|
|
@@ -160,7 +150,7 @@ export function createGridState<T extends object, C extends GridCollection<T> =
|
|
|
160
150
|
return disabledKeys().has(key);
|
|
161
151
|
};
|
|
162
152
|
|
|
163
|
-
const updateSelection = (newSelection:
|
|
153
|
+
const updateSelection = (newSelection: "all" | Set<Key>) => {
|
|
164
154
|
const opts = getOptions();
|
|
165
155
|
|
|
166
156
|
// Controlled mode
|
|
@@ -172,8 +162,8 @@ export function createGridState<T extends object, C extends GridCollection<T> =
|
|
|
172
162
|
// Uncontrolled mode
|
|
173
163
|
const current = internalSelectedKeys();
|
|
174
164
|
const isDifferent =
|
|
175
|
-
current ===
|
|
176
|
-
newSelection ===
|
|
165
|
+
current === "all" ||
|
|
166
|
+
newSelection === "all" ||
|
|
177
167
|
current.size !== (newSelection as Set<Key>).size ||
|
|
178
168
|
![...current].every((k) => (newSelection as Set<Key>).has(k));
|
|
179
169
|
|
|
@@ -185,11 +175,11 @@ export function createGridState<T extends object, C extends GridCollection<T> =
|
|
|
185
175
|
|
|
186
176
|
const toggleSelection = (key: Key) => {
|
|
187
177
|
if (isDisabled(key)) return;
|
|
188
|
-
if (selectionMode() ===
|
|
178
|
+
if (selectionMode() === "none") return;
|
|
189
179
|
|
|
190
180
|
const current = selectedKeys();
|
|
191
181
|
|
|
192
|
-
if (selectionMode() ===
|
|
182
|
+
if (selectionMode() === "single") {
|
|
193
183
|
if (isSelected(key) && !disallowEmptySelection()) {
|
|
194
184
|
updateSelection(new Set());
|
|
195
185
|
} else {
|
|
@@ -199,7 +189,7 @@ export function createGridState<T extends object, C extends GridCollection<T> =
|
|
|
199
189
|
}
|
|
200
190
|
|
|
201
191
|
// Multiple selection
|
|
202
|
-
if (current ===
|
|
192
|
+
if (current === "all") {
|
|
203
193
|
// Can't toggle when all selected without knowing all keys
|
|
204
194
|
return;
|
|
205
195
|
}
|
|
@@ -219,7 +209,7 @@ export function createGridState<T extends object, C extends GridCollection<T> =
|
|
|
219
209
|
|
|
220
210
|
const replaceSelection = (key: Key) => {
|
|
221
211
|
if (isDisabled(key)) return;
|
|
222
|
-
if (selectionMode() ===
|
|
212
|
+
if (selectionMode() === "none") return;
|
|
223
213
|
|
|
224
214
|
updateSelection(new Set([key]));
|
|
225
215
|
setAnchorKey(key);
|
|
@@ -227,7 +217,7 @@ export function createGridState<T extends object, C extends GridCollection<T> =
|
|
|
227
217
|
|
|
228
218
|
const extendSelection = (toKey: Key) => {
|
|
229
219
|
if (isDisabled(toKey)) return;
|
|
230
|
-
if (selectionMode() !==
|
|
220
|
+
if (selectionMode() !== "multiple") {
|
|
231
221
|
replaceSelection(toKey);
|
|
232
222
|
return;
|
|
233
223
|
}
|
|
@@ -239,7 +229,7 @@ export function createGridState<T extends object, C extends GridCollection<T> =
|
|
|
239
229
|
}
|
|
240
230
|
|
|
241
231
|
const collection = getOptions().collection;
|
|
242
|
-
const rows = collection.rows.filter((r) => r.type ===
|
|
232
|
+
const rows = collection.rows.filter((r) => r.type === "item");
|
|
243
233
|
const keys = rows.map((r) => r.key);
|
|
244
234
|
const anchorIndex = keys.indexOf(anchor);
|
|
245
235
|
const toIndex = keys.indexOf(toKey);
|
|
@@ -257,8 +247,8 @@ export function createGridState<T extends object, C extends GridCollection<T> =
|
|
|
257
247
|
};
|
|
258
248
|
|
|
259
249
|
const selectAll = () => {
|
|
260
|
-
if (selectionMode() !==
|
|
261
|
-
updateSelection(
|
|
250
|
+
if (selectionMode() !== "multiple") return;
|
|
251
|
+
updateSelection("all");
|
|
262
252
|
};
|
|
263
253
|
|
|
264
254
|
const clearSelection = () => {
|
|
@@ -267,9 +257,9 @@ export function createGridState<T extends object, C extends GridCollection<T> =
|
|
|
267
257
|
};
|
|
268
258
|
|
|
269
259
|
const toggleSelectAll = () => {
|
|
270
|
-
if (selectionMode() !==
|
|
260
|
+
if (selectionMode() !== "multiple") return;
|
|
271
261
|
|
|
272
|
-
if (selectedKeys() ===
|
|
262
|
+
if (selectedKeys() === "all") {
|
|
273
263
|
clearSelection();
|
|
274
264
|
} else {
|
|
275
265
|
selectAll();
|
|
@@ -298,6 +288,9 @@ export function createGridState<T extends object, C extends GridCollection<T> =
|
|
|
298
288
|
get selectionMode() {
|
|
299
289
|
return selectionMode();
|
|
300
290
|
},
|
|
291
|
+
get selectionBehavior() {
|
|
292
|
+
return selectionBehavior();
|
|
293
|
+
},
|
|
301
294
|
get selectedKeys() {
|
|
302
295
|
return selectedKeys();
|
|
303
296
|
},
|
|
@@ -316,12 +309,12 @@ export function createGridState<T extends object, C extends GridCollection<T> =
|
|
|
316
309
|
}
|
|
317
310
|
|
|
318
311
|
// Helper functions
|
|
319
|
-
function getInitialSelection(defaultKeys?:
|
|
312
|
+
function getInitialSelection(defaultKeys?: "all" | Iterable<Key>): "all" | Set<Key> {
|
|
320
313
|
if (defaultKeys === undefined) return new Set();
|
|
321
314
|
return normalizeSelection(defaultKeys);
|
|
322
315
|
}
|
|
323
316
|
|
|
324
|
-
function normalizeSelection(keys:
|
|
325
|
-
if (keys ===
|
|
317
|
+
function normalizeSelection(keys: "all" | Iterable<Key>): "all" | Set<Key> {
|
|
318
|
+
if (keys === "all") return "all";
|
|
326
319
|
return new Set(keys);
|
|
327
320
|
}
|