@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.
Files changed (242) hide show
  1. package/README.md +30 -283
  2. package/dist/autocomplete/createAutocompleteState.d.ts +2 -2
  3. package/dist/autocomplete/index.d.ts +1 -1
  4. package/dist/calendar/createCalendarState.d.ts +22 -7
  5. package/dist/calendar/createDateFieldState.d.ts +30 -7
  6. package/dist/calendar/createDatePickerState.d.ts +60 -0
  7. package/dist/calendar/createRangeCalendarState.d.ts +27 -8
  8. package/dist/calendar/createTimeFieldState.d.ts +34 -7
  9. package/dist/calendar/index.d.ts +7 -6
  10. package/dist/checkbox/createCheckboxGroupState.d.ts +6 -6
  11. package/dist/checkbox/index.d.ts +1 -1
  12. package/dist/collections/ListCollection.d.ts +1 -1
  13. package/dist/collections/createListState.d.ts +8 -8
  14. package/dist/collections/createMenuState.d.ts +7 -7
  15. package/dist/collections/createSelectionState.d.ts +5 -5
  16. package/dist/collections/index.d.ts +5 -5
  17. package/dist/collections/types.d.ts +12 -12
  18. package/dist/color/Color.d.ts +1 -1
  19. package/dist/color/createColorAreaState.d.ts +4 -2
  20. package/dist/color/createColorFieldState.d.ts +38 -12
  21. package/dist/color/createColorSliderState.d.ts +9 -2
  22. package/dist/color/createColorWheelState.d.ts +13 -2
  23. package/dist/color/getColorChannels.d.ts +1 -1
  24. package/dist/color/index.d.ts +6 -6
  25. package/dist/color/types.d.ts +4 -4
  26. package/dist/combobox/createComboBoxState.d.ts +27 -13
  27. package/dist/combobox/index.d.ts +1 -1
  28. package/dist/data/createAsyncList.d.ts +4 -4
  29. package/dist/data/createListData.d.ts +2 -2
  30. package/dist/data/createTreeData.d.ts +6 -2
  31. package/dist/data/index.d.ts +3 -3
  32. package/dist/datepicker/index.d.ts +2 -4
  33. package/dist/disclosure/createDisclosureState.d.ts +2 -2
  34. package/dist/disclosure/index.d.ts +1 -1
  35. package/dist/dnd/createDragState.d.ts +2 -2
  36. package/dist/dnd/createDraggableCollectionState.d.ts +2 -2
  37. package/dist/dnd/createDropState.d.ts +2 -2
  38. package/dist/dnd/createDroppableCollectionState.d.ts +3 -3
  39. package/dist/dnd/index.d.ts +5 -5
  40. package/dist/dnd/types.d.ts +16 -16
  41. package/dist/form/createFormValidationState.d.ts +3 -3
  42. package/dist/form/index.d.ts +1 -1
  43. package/dist/grid/createGridState.d.ts +2 -2
  44. package/dist/grid/index.d.ts +2 -2
  45. package/dist/grid/types.d.ts +13 -11
  46. package/dist/index.d.ts +31 -30
  47. package/dist/index.js +7924 -7238
  48. package/dist/index.js.map +1 -1
  49. package/dist/menu/index.d.ts +2 -2
  50. package/dist/numberfield/createNumberFieldState.d.ts +2 -2
  51. package/dist/numberfield/index.d.ts +1 -1
  52. package/dist/overlays/createOverlayTriggerState.d.ts +2 -2
  53. package/dist/overlays/index.d.ts +1 -1
  54. package/dist/radio/createRadioGroupState.d.ts +7 -7
  55. package/dist/radio/index.d.ts +1 -1
  56. package/dist/searchfield/createSearchFieldState.d.ts +2 -2
  57. package/dist/searchfield/index.d.ts +2 -2
  58. package/dist/select/createSelectState.d.ts +8 -8
  59. package/dist/select/index.d.ts +1 -1
  60. package/dist/selection/index.d.ts +5 -5
  61. package/dist/slider/createSliderState.d.ts +3 -3
  62. package/dist/slider/index.d.ts +2 -2
  63. package/dist/steplist/createStepListState.d.ts +48 -0
  64. package/dist/steplist/index.d.ts +1 -0
  65. package/dist/table/TableCollection.d.ts +3 -3
  66. package/dist/table/createTableColumnResizeState.d.ts +54 -0
  67. package/dist/table/createTableState.d.ts +2 -2
  68. package/dist/table/index.d.ts +5 -3
  69. package/dist/table/types.d.ts +10 -10
  70. package/dist/tabs/createTabListState.d.ts +5 -5
  71. package/dist/tabs/index.d.ts +1 -1
  72. package/dist/textfield/createTextFieldState.d.ts +2 -2
  73. package/dist/textfield/index.d.ts +1 -1
  74. package/dist/toast/createToastState.d.ts +8 -2
  75. package/dist/toast/index.d.ts +1 -1
  76. package/dist/toggle/createToggleGroupState.d.ts +4 -4
  77. package/dist/toggle/createToggleState.d.ts +2 -2
  78. package/dist/toggle/index.d.ts +2 -2
  79. package/dist/tooltip/createTooltipTriggerState.d.ts +2 -2
  80. package/dist/tooltip/index.d.ts +1 -1
  81. package/dist/tree/TreeCollection.d.ts +2 -2
  82. package/dist/tree/createTreeState.d.ts +2 -2
  83. package/dist/tree/index.d.ts +3 -3
  84. package/dist/tree/types.d.ts +19 -13
  85. package/dist/utils/index.d.ts +1 -1
  86. package/dist/utils/reactivity.d.ts +1 -1
  87. package/package.json +29 -30
  88. package/src/autocomplete/createAutocompleteState.d.ts +19 -17
  89. package/src/autocomplete/createAutocompleteState.ts +24 -30
  90. package/src/autocomplete/index.d.ts +6 -2
  91. package/src/autocomplete/index.ts +1 -1
  92. package/src/calendar/createCalendarState.d.ts +139 -117
  93. package/src/calendar/createCalendarState.ts +221 -74
  94. package/src/calendar/createDateFieldState.d.ts +130 -95
  95. package/src/calendar/createDateFieldState.ts +263 -151
  96. package/src/calendar/createDatePickerState.ts +347 -0
  97. package/src/calendar/createRangeCalendarState.d.ts +154 -129
  98. package/src/calendar/createRangeCalendarState.ts +293 -79
  99. package/src/calendar/createTimeFieldState.d.ts +81 -79
  100. package/src/calendar/createTimeFieldState.ts +187 -108
  101. package/src/calendar/index.d.ts +80 -7
  102. package/src/calendar/index.ts +21 -12
  103. package/src/checkbox/createCheckboxGroupState.d.ts +57 -55
  104. package/src/checkbox/createCheckboxGroupState.ts +20 -29
  105. package/src/checkbox/index.d.ts +6 -2
  106. package/src/checkbox/index.ts +1 -1
  107. package/src/collections/ListCollection.d.ts +25 -22
  108. package/src/collections/ListCollection.ts +6 -6
  109. package/src/collections/createListState.d.ts +73 -58
  110. package/src/collections/createListState.ts +19 -18
  111. package/src/collections/createMenuState.d.ts +36 -31
  112. package/src/collections/createMenuState.ts +18 -12
  113. package/src/collections/createSelectionState.d.ts +78 -65
  114. package/src/collections/createSelectionState.ts +36 -32
  115. package/src/collections/index.d.ts +38 -6
  116. package/src/collections/index.ts +5 -10
  117. package/src/collections/types.d.ts +101 -101
  118. package/src/collections/types.ts +12 -12
  119. package/src/color/Color.d.ts +20 -5
  120. package/src/color/Color.ts +357 -254
  121. package/src/color/createColorAreaState.d.ts +67 -65
  122. package/src/color/createColorAreaState.ts +21 -13
  123. package/src/color/createColorFieldState.d.ts +46 -44
  124. package/src/color/createColorFieldState.ts +285 -149
  125. package/src/color/createColorSliderState.d.ts +58 -56
  126. package/src/color/createColorSliderState.ts +45 -14
  127. package/src/color/createColorWheelState.d.ts +42 -40
  128. package/src/color/createColorWheelState.ts +101 -64
  129. package/src/color/getColorChannels.ts +7 -5
  130. package/src/color/index.d.ts +36 -7
  131. package/src/color/index.ts +6 -9
  132. package/src/color/types.d.ts +68 -63
  133. package/src/color/types.ts +11 -19
  134. package/src/combobox/createComboBoxState.d.ts +107 -105
  135. package/src/combobox/createComboBoxState.ts +176 -89
  136. package/src/combobox/index.d.ts +10 -2
  137. package/src/combobox/index.ts +1 -1
  138. package/src/data/createAsyncList.ts +89 -63
  139. package/src/data/createListData.ts +67 -67
  140. package/src/data/createTreeData.ts +304 -91
  141. package/src/data/index.ts +3 -3
  142. package/src/datepicker/index.ts +6 -10
  143. package/src/disclosure/createDisclosureState.d.ts +47 -43
  144. package/src/disclosure/createDisclosureState.ts +7 -21
  145. package/src/disclosure/index.d.ts +10 -2
  146. package/src/disclosure/index.ts +1 -1
  147. package/src/dnd/createDragState.d.ts +51 -42
  148. package/src/dnd/createDragState.ts +12 -14
  149. package/src/dnd/createDraggableCollectionState.d.ts +52 -41
  150. package/src/dnd/createDraggableCollectionState.ts +14 -21
  151. package/src/dnd/createDropState.d.ts +64 -45
  152. package/src/dnd/createDropState.ts +22 -32
  153. package/src/dnd/createDroppableCollectionState.d.ts +88 -59
  154. package/src/dnd/createDroppableCollectionState.ts +40 -43
  155. package/src/dnd/index.d.ts +54 -6
  156. package/src/dnd/index.ts +5 -18
  157. package/src/dnd/types.d.ts +167 -156
  158. package/src/dnd/types.ts +20 -21
  159. package/src/form/createFormValidationState.d.ts +47 -45
  160. package/src/form/createFormValidationState.ts +30 -63
  161. package/src/form/index.d.ts +16 -2
  162. package/src/form/index.ts +1 -1
  163. package/src/grid/createGridState.d.ts +7 -4
  164. package/src/grid/createGridState.ts +44 -51
  165. package/src/grid/index.d.ts +3 -3
  166. package/src/grid/index.ts +2 -8
  167. package/src/grid/types.d.ts +136 -129
  168. package/src/grid/types.ts +20 -18
  169. package/src/index.d.ts +310 -26
  170. package/src/index.ts +48 -89
  171. package/src/menu/index.ts +2 -4
  172. package/src/numberfield/createNumberFieldState.d.ts +56 -54
  173. package/src/numberfield/createNumberFieldState.ts +26 -31
  174. package/src/numberfield/index.d.ts +6 -2
  175. package/src/numberfield/index.ts +1 -1
  176. package/src/overlays/createOverlayTriggerState.d.ts +22 -20
  177. package/src/overlays/createOverlayTriggerState.ts +3 -4
  178. package/src/overlays/index.d.ts +6 -2
  179. package/src/overlays/index.ts +1 -1
  180. package/src/radio/createRadioGroupState.d.ts +54 -52
  181. package/src/radio/createRadioGroupState.ts +27 -29
  182. package/src/radio/index.d.ts +7 -2
  183. package/src/radio/index.ts +1 -1
  184. package/src/searchfield/createSearchFieldState.d.ts +16 -14
  185. package/src/searchfield/createSearchFieldState.ts +5 -11
  186. package/src/searchfield/index.d.ts +3 -3
  187. package/src/searchfield/index.ts +2 -5
  188. package/src/select/createSelectState.d.ts +63 -61
  189. package/src/select/createSelectState.ts +27 -27
  190. package/src/select/index.d.ts +2 -2
  191. package/src/select/index.ts +1 -5
  192. package/src/selection/index.ts +6 -7
  193. package/src/slider/createSliderState.d.ts +60 -60
  194. package/src/slider/createSliderState.ts +55 -33
  195. package/src/slider/index.d.ts +3 -3
  196. package/src/slider/index.ts +2 -6
  197. package/src/ssr/index.d.ts +1 -1
  198. package/src/ssr/index.ts +2 -2
  199. package/src/steplist/createStepListState.ts +191 -0
  200. package/src/steplist/index.ts +5 -0
  201. package/src/table/TableCollection.d.ts +42 -40
  202. package/src/table/TableCollection.ts +61 -64
  203. package/src/table/createTableColumnResizeState.ts +242 -0
  204. package/src/table/createTableState.d.ts +7 -4
  205. package/src/table/createTableState.ts +10 -7
  206. package/src/table/index.d.ts +14 -4
  207. package/src/table/index.ts +10 -3
  208. package/src/table/types.d.ts +98 -92
  209. package/src/table/types.ts +17 -13
  210. package/src/tabs/createTabListState.d.ts +59 -57
  211. package/src/tabs/createTabListState.ts +24 -31
  212. package/src/tabs/index.d.ts +8 -2
  213. package/src/tabs/index.ts +1 -1
  214. package/src/textfield/createTextFieldState.d.ts +16 -14
  215. package/src/textfield/createTextFieldState.ts +7 -18
  216. package/src/textfield/index.d.ts +6 -2
  217. package/src/textfield/index.ts +1 -1
  218. package/src/toast/createToastState.d.ts +92 -86
  219. package/src/toast/createToastState.ts +48 -43
  220. package/src/toast/index.d.ts +12 -2
  221. package/src/toast/index.ts +1 -1
  222. package/src/toggle/createToggleGroupState.ts +11 -21
  223. package/src/toggle/createToggleState.d.ts +19 -19
  224. package/src/toggle/createToggleState.ts +2 -16
  225. package/src/toggle/index.d.ts +2 -2
  226. package/src/toggle/index.ts +2 -6
  227. package/src/tooltip/createTooltipTriggerState.d.ts +17 -17
  228. package/src/tooltip/createTooltipTriggerState.ts +12 -11
  229. package/src/tooltip/index.d.ts +7 -2
  230. package/src/tooltip/index.ts +1 -1
  231. package/src/tree/TreeCollection.d.ts +26 -23
  232. package/src/tree/TreeCollection.ts +29 -22
  233. package/src/tree/createTreeState.d.ts +7 -4
  234. package/src/tree/createTreeState.ts +39 -41
  235. package/src/tree/index.d.ts +10 -4
  236. package/src/tree/index.ts +3 -3
  237. package/src/tree/types.d.ts +131 -126
  238. package/src/tree/types.ts +22 -13
  239. package/src/utils/index.d.ts +2 -2
  240. package/src/utils/index.ts +1 -1
  241. package/src/utils/reactivity.d.ts +2 -2
  242. 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 'solid-js';
9
+ import { type Accessor } from "solid-js";
10
10
  /** Standard HTML ValidityState interface. */
11
11
  export interface ValidityState {
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;
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
- /** 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[];
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 = 'aria' | 'native';
38
+ export type ValidationBehavior = "aria" | "native";
39
39
  export interface FormValidationProps<T> {
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;
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
- /** 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;
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>(props: FormValidationProps<T>): FormValidationState;
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 'solid-js';
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 = 'aria' | 'native';
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?: 'valid' | 'invalid';
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 = '__formValidationState' + Date.now();
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 === 'function') {
126
+ if (typeof validate === "function") {
143
127
  const e = validate(value);
144
- if (e && typeof e !== 'boolean') {
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: FormValidationProps<T>
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 === 'invalid' ? true : undefined)
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 === 'native') {
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 === 'native') {
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 === 'native') {
353
- setCommitQueued(true);
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 };
@@ -1,2 +1,16 @@
1
- export { createFormValidationState, mergeValidation, FormValidationContext, privateValidationStateProp, VALID_VALIDITY_STATE, DEFAULT_VALIDATION_RESULT, type FormValidationState, type FormValidationProps, type ValidationResult, type ValidationErrors, type ValidationFunction, type ValidationBehavior, type ValidityState, } from './createFormValidationState';
2
- //# sourceMappingURL=index.d.ts.map
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
@@ -12,4 +12,4 @@ export {
12
12
  type ValidationFunction,
13
13
  type ValidationBehavior,
14
14
  type ValidityState,
15
- } from './createFormValidationState';
15
+ } from "./createFormValidationState";
@@ -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 'solid-js';
6
- import type { GridState, GridStateOptions, GridCollection } from './types';
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<T extends object, C extends GridCollection<T> = GridCollection<T>>(options: Accessor<GridStateOptions<T, C>>): GridState<T, C>;
12
- //# sourceMappingURL=createGridState.d.ts.map
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 'solid-js';
7
- import type {
8
- GridState,
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
- // Selection state
37
- const [internalSelectedKeys, setInternalSelectedKeys] = createSignal<'all' | Set<Key>>(
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 ?? 'none');
52
- const selectionBehavior = createMemo(() => getOptions().selectionBehavior ?? 'toggle');
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
- // Focus mode handling
56
- const focusMode = createMemo(() => getOptions().focusMode ?? 'row');
46
+ const focusMode = createMemo(() => getOptions().focusMode ?? "row");
57
47
 
58
- // Set focused key with focus mode awareness
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() === 'cell' && key != null) {
53
+ if (focusMode() === "cell" && key != null) {
65
54
  const item = collection.getItem(key);
66
- if (item?.type === 'item') {
55
+ if (item?.type === "item") {
67
56
  const children = [...collection.getChildren(key)];
68
- if (strategy === 'last') {
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 (currentFocusedKey != null && cachedCollection && !collection.getItem(currentFocusedKey)) {
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 === 'cell' || node.type === 'rowheader' || node.type === 'column')
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 !== 'headerrow') {
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 === 'all') return true;
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: 'all' | Set<Key>) => {
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 === 'all' ||
176
- newSelection === 'all' ||
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() === 'none') return;
178
+ if (selectionMode() === "none") return;
189
179
 
190
180
  const current = selectedKeys();
191
181
 
192
- if (selectionMode() === 'single') {
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 === 'all') {
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() === 'none') return;
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() !== 'multiple') {
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 === 'item');
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() !== 'multiple') return;
261
- updateSelection('all');
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() !== 'multiple') return;
260
+ if (selectionMode() !== "multiple") return;
271
261
 
272
- if (selectedKeys() === 'all') {
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?: 'all' | Iterable<Key>): 'all' | Set<Key> {
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: 'all' | Iterable<Key>): 'all' | Set<Key> {
325
- if (keys === 'all') return 'all';
317
+ function normalizeSelection(keys: "all" | Iterable<Key>): "all" | Set<Key> {
318
+ if (keys === "all") return "all";
326
319
  return new Set(keys);
327
320
  }