@proyecto-viviana/solid-stately 0.2.4 → 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 (243) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +30 -283
  3. package/dist/autocomplete/createAutocompleteState.d.ts +3 -2
  4. package/dist/autocomplete/index.d.ts +1 -1
  5. package/dist/calendar/createCalendarState.d.ts +22 -7
  6. package/dist/calendar/createDateFieldState.d.ts +30 -7
  7. package/dist/calendar/createDatePickerState.d.ts +60 -0
  8. package/dist/calendar/createRangeCalendarState.d.ts +27 -8
  9. package/dist/calendar/createTimeFieldState.d.ts +34 -7
  10. package/dist/calendar/index.d.ts +7 -6
  11. package/dist/checkbox/createCheckboxGroupState.d.ts +12 -3
  12. package/dist/checkbox/index.d.ts +1 -1
  13. package/dist/collections/ListCollection.d.ts +1 -1
  14. package/dist/collections/createListState.d.ts +8 -8
  15. package/dist/collections/createMenuState.d.ts +7 -7
  16. package/dist/collections/createSelectionState.d.ts +5 -5
  17. package/dist/collections/index.d.ts +5 -5
  18. package/dist/collections/types.d.ts +23 -12
  19. package/dist/color/Color.d.ts +1 -1
  20. package/dist/color/createColorAreaState.d.ts +4 -2
  21. package/dist/color/createColorFieldState.d.ts +38 -12
  22. package/dist/color/createColorSliderState.d.ts +9 -2
  23. package/dist/color/createColorWheelState.d.ts +13 -2
  24. package/dist/color/getColorChannels.d.ts +20 -0
  25. package/dist/color/index.d.ts +6 -6
  26. package/dist/color/types.d.ts +4 -4
  27. package/dist/combobox/createComboBoxState.d.ts +27 -13
  28. package/dist/combobox/index.d.ts +1 -1
  29. package/dist/data/createAsyncList.d.ts +111 -0
  30. package/dist/data/createListData.d.ts +65 -0
  31. package/dist/data/createTreeData.d.ts +65 -0
  32. package/dist/data/index.d.ts +3 -0
  33. package/dist/datepicker/index.d.ts +8 -0
  34. package/dist/disclosure/createDisclosureState.d.ts +2 -2
  35. package/dist/disclosure/index.d.ts +1 -1
  36. package/dist/dnd/createDragState.d.ts +2 -2
  37. package/dist/dnd/createDraggableCollectionState.d.ts +2 -2
  38. package/dist/dnd/createDropState.d.ts +2 -2
  39. package/dist/dnd/createDroppableCollectionState.d.ts +3 -3
  40. package/dist/dnd/index.d.ts +5 -5
  41. package/dist/dnd/types.d.ts +16 -16
  42. package/dist/form/createFormValidationState.d.ts +3 -3
  43. package/dist/form/index.d.ts +1 -1
  44. package/dist/grid/createGridState.d.ts +2 -2
  45. package/dist/grid/index.d.ts +2 -2
  46. package/dist/grid/types.d.ts +17 -11
  47. package/dist/index.d.ts +31 -25
  48. package/dist/index.js +7990 -6264
  49. package/dist/index.js.map +1 -7
  50. package/dist/menu/index.d.ts +8 -0
  51. package/dist/numberfield/createNumberFieldState.d.ts +2 -2
  52. package/dist/numberfield/index.d.ts +1 -1
  53. package/dist/overlays/createOverlayTriggerState.d.ts +2 -2
  54. package/dist/overlays/index.d.ts +1 -1
  55. package/dist/radio/createRadioGroupState.d.ts +13 -4
  56. package/dist/radio/index.d.ts +1 -1
  57. package/dist/searchfield/createSearchFieldState.d.ts +2 -2
  58. package/dist/searchfield/index.d.ts +2 -2
  59. package/dist/select/createSelectState.d.ts +20 -3
  60. package/dist/select/index.d.ts +1 -1
  61. package/dist/selection/index.d.ts +11 -0
  62. package/dist/slider/createSliderState.d.ts +3 -3
  63. package/dist/slider/index.d.ts +2 -2
  64. package/dist/steplist/createStepListState.d.ts +48 -0
  65. package/dist/steplist/index.d.ts +1 -0
  66. package/dist/table/TableCollection.d.ts +3 -3
  67. package/dist/table/createTableColumnResizeState.d.ts +54 -0
  68. package/dist/table/createTableState.d.ts +2 -2
  69. package/dist/table/index.d.ts +5 -3
  70. package/dist/table/types.d.ts +10 -10
  71. package/dist/tabs/createTabListState.d.ts +5 -5
  72. package/dist/tabs/index.d.ts +1 -1
  73. package/dist/textfield/createTextFieldState.d.ts +2 -2
  74. package/dist/textfield/index.d.ts +1 -1
  75. package/dist/toast/createToastState.d.ts +15 -3
  76. package/dist/toast/index.d.ts +1 -1
  77. package/dist/toggle/createToggleGroupState.d.ts +45 -0
  78. package/dist/toggle/createToggleState.d.ts +2 -2
  79. package/dist/toggle/index.d.ts +2 -1
  80. package/dist/tooltip/createTooltipTriggerState.d.ts +2 -2
  81. package/dist/tooltip/index.d.ts +1 -1
  82. package/dist/tree/TreeCollection.d.ts +5 -4
  83. package/dist/tree/createTreeState.d.ts +2 -2
  84. package/dist/tree/index.d.ts +3 -3
  85. package/dist/tree/types.d.ts +19 -13
  86. package/dist/utils/index.d.ts +1 -1
  87. package/dist/utils/reactivity.d.ts +1 -1
  88. package/package.json +30 -30
  89. package/src/autocomplete/createAutocompleteState.d.ts +19 -17
  90. package/src/autocomplete/createAutocompleteState.ts +25 -32
  91. package/src/autocomplete/index.d.ts +6 -2
  92. package/src/autocomplete/index.ts +1 -1
  93. package/src/calendar/createCalendarState.d.ts +139 -117
  94. package/src/calendar/createCalendarState.ts +221 -74
  95. package/src/calendar/createDateFieldState.d.ts +130 -95
  96. package/src/calendar/createDateFieldState.ts +286 -151
  97. package/src/calendar/createDatePickerState.ts +347 -0
  98. package/src/calendar/createRangeCalendarState.d.ts +154 -129
  99. package/src/calendar/createRangeCalendarState.ts +293 -79
  100. package/src/calendar/createTimeFieldState.d.ts +81 -79
  101. package/src/calendar/createTimeFieldState.ts +187 -108
  102. package/src/calendar/index.d.ts +80 -7
  103. package/src/calendar/index.ts +21 -12
  104. package/src/checkbox/createCheckboxGroupState.d.ts +57 -55
  105. package/src/checkbox/createCheckboxGroupState.ts +57 -30
  106. package/src/checkbox/index.d.ts +6 -2
  107. package/src/checkbox/index.ts +1 -1
  108. package/src/collections/ListCollection.d.ts +25 -22
  109. package/src/collections/ListCollection.ts +152 -146
  110. package/src/collections/createListState.d.ts +73 -58
  111. package/src/collections/createListState.ts +267 -264
  112. package/src/collections/createMenuState.d.ts +36 -31
  113. package/src/collections/createMenuState.ts +112 -106
  114. package/src/collections/createSelectionState.d.ts +78 -65
  115. package/src/collections/createSelectionState.ts +340 -336
  116. package/src/collections/index.d.ts +38 -6
  117. package/src/collections/index.ts +41 -46
  118. package/src/collections/types.d.ts +101 -101
  119. package/src/collections/types.ts +181 -169
  120. package/src/color/Color.d.ts +20 -5
  121. package/src/color/Color.ts +1054 -951
  122. package/src/color/createColorAreaState.d.ts +67 -65
  123. package/src/color/createColorAreaState.ts +301 -293
  124. package/src/color/createColorFieldState.d.ts +46 -44
  125. package/src/color/createColorFieldState.ts +428 -292
  126. package/src/color/createColorSliderState.d.ts +58 -56
  127. package/src/color/createColorSliderState.ts +272 -241
  128. package/src/color/createColorWheelState.d.ts +42 -40
  129. package/src/color/createColorWheelState.ts +248 -211
  130. package/src/color/getColorChannels.ts +36 -0
  131. package/src/color/index.d.ts +36 -7
  132. package/src/color/index.ts +44 -47
  133. package/src/color/types.d.ts +68 -63
  134. package/src/color/types.ts +119 -127
  135. package/src/combobox/createComboBoxState.d.ts +107 -105
  136. package/src/combobox/createComboBoxState.ts +790 -703
  137. package/src/combobox/index.d.ts +10 -2
  138. package/src/combobox/index.ts +13 -13
  139. package/src/data/createAsyncList.ts +403 -0
  140. package/src/data/createListData.ts +298 -0
  141. package/src/data/createTreeData.ts +646 -0
  142. package/src/data/index.ts +25 -0
  143. package/src/datepicker/index.ts +32 -0
  144. package/src/disclosure/createDisclosureState.d.ts +47 -43
  145. package/src/disclosure/createDisclosureState.ts +9 -23
  146. package/src/disclosure/index.d.ts +10 -2
  147. package/src/disclosure/index.ts +1 -1
  148. package/src/dnd/createDragState.d.ts +51 -42
  149. package/src/dnd/createDragState.ts +151 -153
  150. package/src/dnd/createDraggableCollectionState.d.ts +52 -41
  151. package/src/dnd/createDraggableCollectionState.ts +158 -165
  152. package/src/dnd/createDropState.d.ts +64 -45
  153. package/src/dnd/createDropState.ts +202 -212
  154. package/src/dnd/createDroppableCollectionState.d.ts +88 -59
  155. package/src/dnd/createDroppableCollectionState.ts +354 -357
  156. package/src/dnd/index.d.ts +54 -6
  157. package/src/dnd/index.ts +63 -76
  158. package/src/dnd/types.d.ts +167 -156
  159. package/src/dnd/types.ts +316 -317
  160. package/src/form/createFormValidationState.d.ts +47 -45
  161. package/src/form/createFormValidationState.ts +356 -389
  162. package/src/form/index.d.ts +16 -2
  163. package/src/form/index.ts +15 -15
  164. package/src/grid/createGridState.d.ts +7 -4
  165. package/src/grid/createGridState.ts +44 -51
  166. package/src/grid/index.d.ts +3 -3
  167. package/src/grid/index.ts +2 -8
  168. package/src/grid/types.d.ts +136 -129
  169. package/src/grid/types.ts +24 -17
  170. package/src/index.d.ts +310 -26
  171. package/src/index.ts +87 -79
  172. package/src/menu/index.ts +17 -0
  173. package/src/numberfield/createNumberFieldState.d.ts +56 -54
  174. package/src/numberfield/createNumberFieldState.ts +422 -383
  175. package/src/numberfield/index.d.ts +6 -2
  176. package/src/numberfield/index.ts +5 -5
  177. package/src/overlays/createOverlayTriggerState.d.ts +22 -20
  178. package/src/overlays/createOverlayTriggerState.ts +66 -67
  179. package/src/overlays/index.d.ts +6 -2
  180. package/src/overlays/index.ts +5 -5
  181. package/src/radio/createRadioGroupState.d.ts +54 -52
  182. package/src/radio/createRadioGroupState.ts +66 -30
  183. package/src/radio/index.d.ts +7 -2
  184. package/src/radio/index.ts +1 -1
  185. package/src/searchfield/createSearchFieldState.d.ts +16 -14
  186. package/src/searchfield/createSearchFieldState.ts +56 -62
  187. package/src/searchfield/index.d.ts +3 -3
  188. package/src/searchfield/index.ts +2 -5
  189. package/src/select/createSelectState.d.ts +63 -61
  190. package/src/select/createSelectState.ts +290 -181
  191. package/src/select/index.d.ts +2 -2
  192. package/src/select/index.ts +1 -5
  193. package/src/selection/index.ts +27 -0
  194. package/src/slider/createSliderState.d.ts +60 -60
  195. package/src/slider/createSliderState.ts +233 -211
  196. package/src/slider/index.d.ts +3 -3
  197. package/src/slider/index.ts +2 -6
  198. package/src/ssr/index.d.ts +1 -1
  199. package/src/ssr/index.ts +2 -2
  200. package/src/steplist/createStepListState.ts +191 -0
  201. package/src/steplist/index.ts +5 -0
  202. package/src/table/TableCollection.d.ts +42 -40
  203. package/src/table/TableCollection.ts +61 -64
  204. package/src/table/createTableColumnResizeState.ts +242 -0
  205. package/src/table/createTableState.d.ts +7 -4
  206. package/src/table/createTableState.ts +10 -7
  207. package/src/table/index.d.ts +14 -4
  208. package/src/table/index.ts +10 -3
  209. package/src/table/types.d.ts +98 -92
  210. package/src/table/types.ts +17 -13
  211. package/src/tabs/createTabListState.d.ts +59 -57
  212. package/src/tabs/createTabListState.ts +58 -39
  213. package/src/tabs/index.d.ts +8 -2
  214. package/src/tabs/index.ts +1 -1
  215. package/src/textfield/createTextFieldState.d.ts +16 -14
  216. package/src/textfield/createTextFieldState.ts +7 -18
  217. package/src/textfield/index.d.ts +6 -2
  218. package/src/textfield/index.ts +1 -1
  219. package/src/toast/createToastState.d.ts +92 -81
  220. package/src/toast/createToastState.ts +56 -44
  221. package/src/toast/index.d.ts +12 -2
  222. package/src/toast/index.ts +1 -1
  223. package/src/toggle/createToggleGroupState.ts +117 -0
  224. package/src/toggle/createToggleState.d.ts +19 -19
  225. package/src/toggle/createToggleState.ts +2 -16
  226. package/src/toggle/index.d.ts +2 -2
  227. package/src/toggle/index.ts +6 -4
  228. package/src/tooltip/createTooltipTriggerState.d.ts +17 -17
  229. package/src/tooltip/createTooltipTriggerState.ts +184 -183
  230. package/src/tooltip/index.d.ts +7 -2
  231. package/src/tooltip/index.ts +6 -6
  232. package/src/tree/TreeCollection.d.ts +26 -23
  233. package/src/tree/TreeCollection.ts +215 -175
  234. package/src/tree/createTreeState.d.ts +7 -4
  235. package/src/tree/createTreeState.ts +390 -392
  236. package/src/tree/index.d.ts +10 -4
  237. package/src/tree/index.ts +13 -13
  238. package/src/tree/types.d.ts +131 -126
  239. package/src/tree/types.ts +183 -174
  240. package/src/utils/index.d.ts +2 -2
  241. package/src/utils/index.ts +1 -1
  242. package/src/utils/reactivity.d.ts +2 -2
  243. package/src/utils/reactivity.ts +3 -3
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) Proyecto Viviana contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,113 +1,23 @@
1
1
  # @proyecto-viviana/solid-stately
2
2
 
3
- A SolidJS port of [React Stately](https://react-spectrum.adobe.com/react-stately/) - headless state management for UI components.
3
+ SolidJS port of React Stately state primitives.
4
4
 
5
- ## Installation
5
+ This package is the state layer below `solidaria` and
6
+ `solidaria-components`. It owns controlled/uncontrolled state, collection
7
+ models, selection, date/time state, validation state, and related utilities.
8
+
9
+ ## Install
6
10
 
7
11
  ```bash
8
- bun add @proyecto-viviana/solid-stately solid-js
12
+ npm install @proyecto-viviana/solid-stately solid-js
9
13
  ```
10
14
 
11
- ## Overview
12
-
13
- solid-stately provides state management hooks that handle the complex logic for UI components like toggles, selections, overlays, and collections. These hooks return reactive state and update functions that you can use with any UI.
14
-
15
- This package is the foundation layer of the Proyecto Viviana component library, providing the state logic that powers the accessibility hooks in `@proyecto-viviana/solidaria`.
16
-
17
- ## Available Hooks
18
-
19
- ### Toggle & Selection
20
-
21
- | Hook | Description |
22
- |------|-------------|
23
- | `createToggleState` | Boolean toggle state for checkboxes, switches |
24
- | `createCheckboxGroupState` | Multi-selection checkbox group |
25
- | `createRadioGroupState` | Single-selection radio group |
26
-
27
- ### Overlays
28
-
29
- | Hook | Description |
30
- |------|-------------|
31
- | `createOverlayTriggerState` | Open/close state for modals, popovers, menus |
32
-
33
- ### Collections & Lists
34
-
35
- | Hook | Description |
36
- |------|-------------|
37
- | `createListState` | List with selection and keyboard focus |
38
- | `createSingleSelectListState` | Single-selection list (e.g., for select dropdowns) |
39
- | `createSelectionState` | Low-level selection management |
40
- | `createMenuState` | Menu state with action support |
41
- | `createMenuTriggerState` | Menu trigger open/close state |
42
- | `createSelectState` | Select dropdown state |
43
- | `ListCollection` | Collection data structure for lists |
44
- | `createListCollection` | Create a list collection from items |
45
-
46
- ### Navigation
47
-
48
- | Hook | Description |
49
- |------|-------------|
50
- | `createTabListState` | Tab navigation state with keyboard support |
51
-
52
- ### Form Controls
53
-
54
- | Hook | Description |
55
- |------|-------------|
56
- | `createTextFieldState` | Text input state |
57
- | `createNumberFieldState` | Numeric input with validation |
58
- | `createSearchFieldState` | Search input with clear functionality |
59
- | `createSliderState` | Range slider state |
60
- | `createFormValidationState` | Form validation state with realtime/native modes |
61
-
62
- ### Grid & Table
63
-
64
- | Hook | Description |
65
- |------|-------------|
66
- | `createGridState` | Grid state with keyboard navigation |
67
- | `createTableState` | Table state with sorting and selection |
68
- | `TableCollection` | Collection data structure for tables |
69
-
70
- ### Tree
71
-
72
- | Hook | Description |
73
- |------|-------------|
74
- | `createTreeState` | Tree state with expand/collapse |
75
- | `TreeCollection` | Collection data structure for trees |
76
-
77
- ### Color
78
-
79
- | Hook | Description |
80
- |------|-------------|
81
- | `createColorSliderState` | Color channel slider state |
82
- | `createColorAreaState` | 2D color area picker state |
83
- | `createColorWheelState` | Circular hue wheel state |
84
- | `createColorFieldState` | Color text input state |
85
-
86
- ### Drag & Drop
87
-
88
- | Hook | Description |
89
- |------|-------------|
90
- | `createDragState` | Drag operation state |
91
- | `createDropState` | Drop target state |
92
- | `createDraggableCollectionState` | Collection-level drag state |
93
- | `createDroppableCollectionState` | Collection-level drop state |
94
-
95
- ### Utilities
96
-
97
- | Hook | Description |
98
- |------|-------------|
99
- | `createId` | Generate unique IDs (SSR-safe) |
100
- | `createIsSSR` | Detect server-side rendering |
101
- | `canUseDOM` | Check if DOM is available |
102
-
103
- ## Usage Examples
104
-
105
- ### Toggle State
15
+ ## Usage
106
16
 
107
17
  ```tsx
108
- import { createToggleState } from '@proyecto-viviana/solid-stately';
18
+ import { createToggleState } from "@proyecto-viviana/solid-stately";
109
19
 
110
- function Checkbox(props) {
20
+ export function Toggle(props) {
111
21
  const state = createToggleState({
112
22
  isSelected: props.isSelected,
113
23
  defaultSelected: props.defaultSelected,
@@ -115,198 +25,35 @@ function Checkbox(props) {
115
25
  });
116
26
 
117
27
  return (
118
- <label>
119
- <input
120
- type="checkbox"
121
- checked={state.isSelected()}
122
- onChange={() => state.toggle()}
123
- />
28
+ <button aria-pressed={state.isSelected()} onClick={() => state.toggle()}>
124
29
  {props.children}
125
- </label>
30
+ </button>
126
31
  );
127
32
  }
128
33
  ```
129
34
 
130
- ### List State with Selection
131
-
132
- ```tsx
133
- import { createListState } from '@proyecto-viviana/solid-stately';
134
-
135
- function ListBox(props) {
136
- const state = createListState({
137
- items: props.items,
138
- getKey: (item) => item.id,
139
- getTextValue: (item) => item.name,
140
- selectionMode: 'single',
141
- onSelectionChange: props.onSelectionChange,
142
- });
143
-
144
- return (
145
- <ul>
146
- <For each={props.items}>
147
- {(item) => {
148
- const key = item.id;
149
- const isSelected = () => state.selectionManager.isSelected(key);
150
-
151
- return (
152
- <li
153
- onClick={() => state.selectionManager.toggleSelection(key)}
154
- style={{ background: isSelected() ? 'blue' : 'white' }}
155
- >
156
- {item.name}
157
- </li>
158
- );
159
- }}
160
- </For>
161
- </ul>
162
- );
163
- }
164
- ```
35
+ ## Public Surface
165
36
 
166
- ### Overlay State
37
+ The source of truth is [`src/index.ts`](src/index.ts). Keep this README focused
38
+ on package purpose and verification rather than duplicating the full export
39
+ list.
167
40
 
168
- ```tsx
169
- import { createOverlayTriggerState } from '@proyecto-viviana/solid-stately';
41
+ Major areas currently covered:
170
42
 
171
- function Modal(props) {
172
- const state = createOverlayTriggerState({
173
- isOpen: props.isOpen,
174
- defaultOpen: props.defaultOpen,
175
- onOpenChange: props.onOpenChange,
176
- });
43
+ - toggles, checkbox groups, radio groups, and disclosure;
44
+ - overlays, tooltips, toasts, forms, and validation;
45
+ - collections, selection, menus, selects, combo boxes, tabs;
46
+ - grid, table, tree, list data, and async list helpers;
47
+ - date/time/calendar state and internationalized date helpers;
48
+ - number fields, search fields, sliders, and color state;
49
+ - drag-and-drop state and SSR utilities.
177
50
 
178
- return (
179
- <>
180
- <button onClick={() => state.open()}>Open Modal</button>
181
- <Show when={state.isOpen()}>
182
- <div class="modal">
183
- {props.children}
184
- <button onClick={() => state.close()}>Close</button>
185
- </div>
186
- </Show>
187
- </>
188
- );
189
- }
190
- ```
51
+ ## Verification
191
52
 
192
- ### Tab State
193
-
194
- ```tsx
195
- import { createTabListState } from '@proyecto-viviana/solid-stately';
196
-
197
- function Tabs(props) {
198
- const state = createTabListState({
199
- items: props.tabs,
200
- getKey: (tab) => tab.id,
201
- selectedKey: props.selectedKey,
202
- onSelectionChange: props.onSelectionChange,
203
- });
204
-
205
- return (
206
- <div>
207
- <div role="tablist">
208
- <For each={props.tabs}>
209
- {(tab) => (
210
- <button
211
- role="tab"
212
- aria-selected={state.selectedKey() === tab.id}
213
- onClick={() => state.setSelectedKey(tab.id)}
214
- >
215
- {tab.label}
216
- </button>
217
- )}
218
- </For>
219
- </div>
220
- <div role="tabpanel">
221
- {props.tabs.find(t => t.id === state.selectedKey())?.content}
222
- </div>
223
- </div>
224
- );
225
- }
226
- ```
227
-
228
- ### Slider State
229
-
230
- ```tsx
231
- import { createSliderState } from '@proyecto-viviana/solid-stately';
232
-
233
- function Slider(props) {
234
- const state = createSliderState({
235
- value: props.value,
236
- defaultValue: props.defaultValue ?? 50,
237
- minValue: props.minValue ?? 0,
238
- maxValue: props.maxValue ?? 100,
239
- step: props.step ?? 1,
240
- onChange: props.onChange,
241
- });
242
-
243
- const percent = () => state.getValuePercent() * 100;
244
-
245
- return (
246
- <div>
247
- <input
248
- type="range"
249
- min={state.minValue}
250
- max={state.maxValue}
251
- step={state.step}
252
- value={state.value()}
253
- onInput={(e) => state.setValue(parseFloat(e.target.value))}
254
- />
255
- <span>{state.getFormattedValue()}</span>
256
- </div>
257
- );
258
- }
259
- ```
260
-
261
- ## Key Concepts
262
-
263
- ### Controlled vs Uncontrolled
264
-
265
- All state hooks support both controlled and uncontrolled patterns:
266
-
267
- ```tsx
268
- // Uncontrolled - uses internal state
269
- const state = createToggleState({
270
- defaultSelected: false,
271
- onChange: (isSelected) => console.log('Changed:', isSelected),
272
- });
273
-
274
- // Controlled - uses external state
275
- const [isSelected, setIsSelected] = createSignal(false);
276
- const state = createToggleState({
277
- isSelected: isSelected(),
278
- onChange: setIsSelected,
279
- });
280
- ```
281
-
282
- ### MaybeAccessor Pattern
283
-
284
- Props can be passed as values or accessors for reactive updates:
285
-
286
- ```tsx
287
- // Static value
288
- createToggleState({ defaultSelected: true });
289
-
290
- // Reactive accessor
291
- createToggleState({
292
- get isDisabled() { return props.isDisabled; }
293
- });
294
- ```
295
-
296
- ## TypeScript
297
-
298
- All hooks are fully typed. Import types as needed:
299
-
300
- ```tsx
301
- import {
302
- createListState,
303
- type ListState,
304
- type ListStateProps,
305
- type Key,
306
- type Selection,
307
- } from '@proyecto-viviana/solid-stately';
53
+ ```bash
54
+ vp run --filter @proyecto-viviana/solid-stately build
55
+ vp test run packages
308
56
  ```
309
57
 
310
- ## License
311
-
312
- MIT
58
+ State changes should include tests for controlled and uncontrolled use, default
59
+ values, callbacks, validation, and disabled/read-only behavior where applicable.
@@ -3,7 +3,8 @@
3
3
  *
4
4
  * Based on @react-stately/autocomplete useAutocompleteState.
5
5
  */
6
- import { type Accessor } from 'solid-js';
6
+ import { type Accessor } from "solid-js";
7
+ import { type MaybeAccessor } from "../utils";
7
8
  export interface AutocompleteState {
8
9
  /** The current value of the autocomplete input. */
9
10
  inputValue: Accessor<string>;
@@ -42,4 +43,4 @@ export interface AutocompleteStateOptions {
42
43
  * state.setFocusedNodeId('item-1');
43
44
  * ```
44
45
  */
45
- export declare function createAutocompleteState(props?: AutocompleteStateOptions): AutocompleteState;
46
+ export declare function createAutocompleteState(props?: MaybeAccessor<AutocompleteStateOptions>): AutocompleteState;
@@ -1 +1 @@
1
- export { createAutocompleteState, type AutocompleteState, type AutocompleteStateOptions, } from './createAutocompleteState';
1
+ export { createAutocompleteState, type AutocompleteState, type AutocompleteStateOptions, } from "./createAutocompleteState";
@@ -4,17 +4,20 @@
4
4
  * Provides state management for calendar components.
5
5
  * Based on @react-stately/calendar useCalendarState
6
6
  */
7
- import { type Accessor } from 'solid-js';
8
- import { type CalendarDate, type DateValue } from '@internationalized/date';
9
- import { type MaybeAccessor } from '../utils';
10
- export type ValidationState = 'valid' | 'invalid';
7
+ import { type Accessor } from "solid-js";
8
+ import { type Calendar as InternationalizedCalendar, type CalendarDate, type CalendarIdentifier, type DateValue } from "@internationalized/date";
9
+ import { type MaybeAccessor } from "../utils";
10
+ export type ValidationState = "valid" | "invalid";
11
+ export type CalendarPageBehavior = "single" | "visible";
12
+ export type CalendarSelectionAlignment = "start" | "center" | "end";
13
+ export type CalendarDayOfWeek = "sun" | "mon" | "tue" | "wed" | "thu" | "fri" | "sat";
11
14
  export interface CalendarStateProps<T extends DateValue = DateValue> {
12
15
  /** The current value (controlled). */
13
16
  value?: MaybeAccessor<T | null>;
14
17
  /** The default value (uncontrolled). */
15
18
  defaultValue?: T | null;
16
19
  /** Handler called when the value changes. */
17
- onChange?: (value: T) => void;
20
+ onChange?: (value: T | null) => void;
18
21
  /** The minimum allowed date. */
19
22
  minValue?: MaybeAccessor<DateValue | undefined>;
20
23
  /** The maximum allowed date. */
@@ -26,17 +29,23 @@ export interface CalendarStateProps<T extends DateValue = DateValue> {
26
29
  /** Whether dates outside the visible range are automatically focused. */
27
30
  autoFocus?: boolean;
28
31
  /** The date that is focused when the calendar first mounts. */
29
- focusedValue?: MaybeAccessor<DateValue | undefined>;
32
+ focusedValue?: MaybeAccessor<DateValue | null | undefined>;
30
33
  /** The default focused date (uncontrolled). */
31
34
  defaultFocusedValue?: DateValue;
32
35
  /** Handler called when the focused date changes. */
33
36
  onFocusChange?: (date: CalendarDate) => void;
34
37
  /** The locale to use for formatting. */
35
- locale?: string;
38
+ locale?: MaybeAccessor<string | undefined>;
39
+ /** Creates a calendar object for a locale calendar identifier. */
40
+ createCalendar?: (identifier: CalendarIdentifier) => InternationalizedCalendar;
36
41
  /** Callback that is called for each date in the calendar to determine if it is unavailable. */
37
42
  isDateUnavailable?: (date: DateValue) => boolean;
38
43
  /** The number of months to display at once. */
39
44
  visibleMonths?: number;
45
+ /** Controls whether paging advances by one month or by the visible month range. */
46
+ pageBehavior?: CalendarPageBehavior;
47
+ /** Determines how the visible months align around the initial focused date. */
48
+ selectionAlignment?: CalendarSelectionAlignment;
40
49
  /** Whether to automatically focus the calendar when it is mounted. */
41
50
  autoFocusOnMount?: boolean;
42
51
  /** Controls which days are disabled. */
@@ -68,8 +77,14 @@ export interface CalendarState<T extends DateValue = DateValue> {
68
77
  }>;
69
78
  /** The timezone used for date calculations. */
70
79
  timeZone: string;
80
+ /** The locale used for formatting and locale-specific week starts. */
81
+ locale: Accessor<string>;
82
+ /** The explicitly requested first weekday, or undefined for the locale default. */
83
+ firstDayOfWeek: Accessor<CalendarDayOfWeek | undefined>;
71
84
  /** The validation state. */
72
85
  validationState: Accessor<ValidationState | undefined>;
86
+ /** Whether the current value is invalid according to validation state. */
87
+ isValueInvalid: Accessor<boolean>;
73
88
  /** Whether a date is selected. */
74
89
  isSelected: (date: DateValue) => boolean;
75
90
  /** Whether a date is focused. */
@@ -4,11 +4,12 @@
4
4
  * Provides state management for date field components with segment-based editing.
5
5
  * Based on @react-stately/datepicker useDateFieldState
6
6
  */
7
- import { type Accessor } from 'solid-js';
8
- import { type CalendarDate, type DateValue } from '@internationalized/date';
9
- import { type MaybeAccessor } from '../utils';
10
- import type { ValidationState } from './createCalendarState';
11
- export type DateSegmentType = 'year' | 'month' | 'day' | 'hour' | 'minute' | 'second' | 'dayPeriod' | 'era' | 'timeZoneName' | 'literal';
7
+ import { type Accessor } from "solid-js";
8
+ import { CalendarDate, type DateValue } from "@internationalized/date";
9
+ import { type MaybeAccessor } from "../utils";
10
+ import type { ValidationState } from "./createCalendarState";
11
+ import { type ValidationBehavior, type ValidationFunction, type ValidationResult } from "../form";
12
+ export type DateSegmentType = "year" | "month" | "day" | "hour" | "minute" | "second" | "dayPeriod" | "era" | "timeZoneName" | "literal";
12
13
  export interface DateSegment {
13
14
  /** The type of segment. */
14
15
  type: DateSegmentType;
@@ -44,18 +45,26 @@ export interface DateFieldStateProps<T extends DateValue = DateValue> {
44
45
  isReadOnly?: MaybeAccessor<boolean>;
45
46
  /** Whether the field is required. */
46
47
  isRequired?: MaybeAccessor<boolean>;
48
+ /** Whether the value is invalid (controlled). */
49
+ isInvalid?: boolean;
47
50
  /** The locale to use for formatting. */
48
51
  locale?: string;
49
52
  /** The granularity of the date/time (day, hour, minute, second). */
50
- granularity?: 'day' | 'hour' | 'minute' | 'second';
53
+ granularity?: "day" | "hour" | "minute" | "second";
51
54
  /** Whether to show the hour in 12 or 24 hour format. */
52
55
  hourCycle?: 12 | 24;
53
56
  /** Whether to hide the time zone. */
54
57
  hideTimeZone?: boolean;
55
58
  /** The placeholder date (determines segment structure). */
56
59
  placeholderValue?: DateValue;
60
+ /** Whether to force leading zeroes in month/day segments. */
61
+ shouldForceLeadingZeros?: boolean;
57
62
  /** Validation state. */
58
63
  validationState?: MaybeAccessor<ValidationState | undefined>;
64
+ /** Validation behavior mode. */
65
+ validationBehavior?: ValidationBehavior;
66
+ /** Custom validation function. */
67
+ validate?: ValidationFunction<T>;
59
68
  /** Description text. */
60
69
  description?: string;
61
70
  /** Error message. */
@@ -64,6 +73,8 @@ export interface DateFieldStateProps<T extends DateValue = DateValue> {
64
73
  allowsNonContiguousRanges?: boolean;
65
74
  /** Whether to create a date or datetime. */
66
75
  createCalendar?: (name: string) => unknown;
76
+ /** Whether a date is unavailable. */
77
+ isDateUnavailable?: (date: DateValue) => boolean;
67
78
  }
68
79
  export interface DateFieldState<T extends DateValue = DateValue> {
69
80
  /** The current value. */
@@ -95,13 +106,25 @@ export interface DateFieldState<T extends DateValue = DateValue> {
95
106
  /** The validation state. */
96
107
  validationState: Accessor<ValidationState | undefined>;
97
108
  /** The granularity. */
98
- granularity: 'day' | 'hour' | 'minute' | 'second';
109
+ granularity: "day" | "hour" | "minute" | "second";
99
110
  /** Whether the value is invalid. */
100
111
  isInvalid: Accessor<boolean>;
112
+ /** Realtime validation results, including native and custom constraints. */
113
+ realtimeValidation: Accessor<ValidationResult>;
114
+ /** Currently displayed validation results. */
115
+ displayValidation: Accessor<ValidationResult>;
116
+ /** Updates the current validation result. */
117
+ updateValidation: (result: ValidationResult) => void;
118
+ /** Resets displayed validation to valid. */
119
+ resetValidation: () => void;
120
+ /** Commits realtime validation to displayed validation. */
121
+ commitValidation: () => void;
101
122
  /** The locale. */
102
123
  locale: string;
103
124
  /** The time zone. */
104
125
  timeZone: string;
126
+ /** The default value. */
127
+ defaultValue: T | null;
105
128
  }
106
129
  /**
107
130
  * Provides state management for a date field component.
@@ -0,0 +1,60 @@
1
+ /**
2
+ * DatePickerState for Solid-Stately
3
+ *
4
+ * Provides unified state management for DatePicker components.
5
+ * Based on @react-stately/datepicker useDatePickerState
6
+ */
7
+ import { type Accessor } from "solid-js";
8
+ import { type DateValue, DateFormatter } from "@internationalized/date";
9
+ import { type MaybeAccessor } from "../utils";
10
+ import type { ValidationState } from "./createCalendarState";
11
+ import type { TimeValue } from "./createTimeFieldState";
12
+ export type Granularity = "day" | "hour" | "minute" | "second";
13
+ export type DatePickerStateProps<T extends DateValue = DateValue> = DatePickerStateOptions<T>;
14
+ export interface DatePickerStateOptions<T extends DateValue = DateValue> {
15
+ value?: MaybeAccessor<T | null>;
16
+ defaultValue?: T | null;
17
+ onChange?: (value: T | null) => void;
18
+ minValue?: MaybeAccessor<DateValue | undefined>;
19
+ maxValue?: MaybeAccessor<DateValue | undefined>;
20
+ isDisabled?: MaybeAccessor<boolean>;
21
+ isReadOnly?: MaybeAccessor<boolean>;
22
+ isRequired?: MaybeAccessor<boolean>;
23
+ granularity?: Granularity;
24
+ hourCycle?: 12 | 24;
25
+ hideTimeZone?: boolean;
26
+ placeholderValue?: DateValue;
27
+ shouldCloseOnSelect?: boolean | (() => boolean);
28
+ defaultOpen?: boolean;
29
+ isOpen?: MaybeAccessor<boolean | undefined>;
30
+ onOpenChange?: (isOpen: boolean) => void;
31
+ isDateUnavailable?: (date: DateValue) => boolean;
32
+ validationState?: MaybeAccessor<ValidationState | undefined>;
33
+ }
34
+ export interface DatePickerState<T extends DateValue = DateValue> {
35
+ value: Accessor<T | null>;
36
+ defaultValue: T | null;
37
+ setValue: (value: T | null) => void;
38
+ dateValue: Accessor<DateValue | null>;
39
+ setDateValue: (value: DateValue) => void;
40
+ timeValue: Accessor<TimeValue | null>;
41
+ setTimeValue: (value: TimeValue) => void;
42
+ granularity: Granularity;
43
+ hasTime: boolean;
44
+ isOpen: Accessor<boolean>;
45
+ open: () => void;
46
+ close: () => void;
47
+ setOpen: (isOpen: boolean) => void;
48
+ isInvalid: Accessor<boolean>;
49
+ validationState: Accessor<ValidationState | undefined>;
50
+ builtinValidation: Accessor<{
51
+ isInvalid: boolean;
52
+ }>;
53
+ showEra: Accessor<boolean>;
54
+ formatValue: (locale: string, fieldOptions?: Intl.DateTimeFormatOptions) => string;
55
+ getDateFormatter: (locale: string, formatOptions?: Intl.DateTimeFormatOptions) => DateFormatter;
56
+ }
57
+ /**
58
+ * Provides unified state management for a DatePicker component.
59
+ */
60
+ export declare function createDatePickerState<T extends DateValue = DateValue>(props?: DatePickerStateOptions<T>): DatePickerState<T>;
@@ -4,10 +4,12 @@
4
4
  * Provides state management for range calendar components.
5
5
  * Based on @react-stately/calendar useRangeCalendarState
6
6
  */
7
- import { type Accessor } from 'solid-js';
8
- import { type CalendarDate, type DateValue } from '@internationalized/date';
9
- import { type MaybeAccessor } from '../utils';
10
- import type { ValidationState } from './createCalendarState';
7
+ import { type Accessor } from "solid-js";
8
+ import { type Calendar as InternationalizedCalendar, type CalendarDate, type CalendarIdentifier, type DateValue } from "@internationalized/date";
9
+ import { type MaybeAccessor } from "../utils";
10
+ import type { CalendarDayOfWeek, ValidationState } from "./createCalendarState";
11
+ type RangeCalendarSelectionAlignment = "start" | "center" | "end";
12
+ type RangeCalendarPageBehavior = "single" | "visible";
11
13
  export interface DateRange {
12
14
  start: CalendarDate;
13
15
  end: CalendarDate;
@@ -22,7 +24,7 @@ export interface RangeCalendarStateProps<T extends DateValue = DateValue> {
22
24
  /** The default value (uncontrolled). */
23
25
  defaultValue?: RangeValue<T> | null;
24
26
  /** Handler called when the value changes. */
25
- onChange?: (value: RangeValue<T>) => void;
27
+ onChange?: (value: RangeValue<T> | null) => void;
26
28
  /** The minimum allowed date. */
27
29
  minValue?: MaybeAccessor<DateValue | undefined>;
28
30
  /** The maximum allowed date. */
@@ -32,17 +34,23 @@ export interface RangeCalendarStateProps<T extends DateValue = DateValue> {
32
34
  /** Whether the calendar is read-only. */
33
35
  isReadOnly?: MaybeAccessor<boolean>;
34
36
  /** The date that is focused when the calendar first mounts. */
35
- focusedValue?: MaybeAccessor<DateValue | undefined>;
37
+ focusedValue?: MaybeAccessor<DateValue | null | undefined>;
36
38
  /** The default focused date (uncontrolled). */
37
39
  defaultFocusedValue?: DateValue;
38
40
  /** Handler called when the focused date changes. */
39
41
  onFocusChange?: (date: CalendarDate) => void;
40
42
  /** The locale to use for formatting. */
41
- locale?: string;
43
+ locale?: MaybeAccessor<string | undefined>;
44
+ /** Creates a calendar object for a locale calendar identifier. */
45
+ createCalendar?: (identifier: CalendarIdentifier) => InternationalizedCalendar;
42
46
  /** Callback to determine if a date is unavailable. */
43
47
  isDateUnavailable?: (date: DateValue) => boolean;
44
48
  /** The number of months to display at once. */
45
- visibleMonths?: number;
49
+ visibleMonths?: MaybeAccessor<number | undefined>;
50
+ /** Controls how the initial visible months are aligned around the current value. */
51
+ selectionAlignment?: MaybeAccessor<RangeCalendarSelectionAlignment | undefined>;
52
+ /** Controls whether pagination moves by one month or the visible month count. */
53
+ pageBehavior?: MaybeAccessor<RangeCalendarPageBehavior | undefined>;
46
54
  /** Controls which days are disabled. */
47
55
  isDateDisabled?: (date: DateValue) => boolean;
48
56
  /** Validation state. */
@@ -78,8 +86,14 @@ export interface RangeCalendarState<T extends DateValue = DateValue> {
78
86
  }>;
79
87
  /** The timezone used for date calculations. */
80
88
  timeZone: string;
89
+ /** The locale used for formatting and locale-specific week starts. */
90
+ locale: Accessor<string>;
91
+ /** The explicitly requested first weekday, or undefined for the locale default. */
92
+ firstDayOfWeek: Accessor<CalendarDayOfWeek | undefined>;
81
93
  /** The validation state. */
82
94
  validationState: Accessor<ValidationState | undefined>;
95
+ /** Whether the current value is invalid according to validation state. */
96
+ isValueInvalid: Accessor<boolean>;
83
97
  /** Whether a date is within the selected range. */
84
98
  isSelected: (date: DateValue) => boolean;
85
99
  /** Whether a date is the start of the selection. */
@@ -104,6 +118,10 @@ export interface RangeCalendarState<T extends DateValue = DateValue> {
104
118
  focusPreviousSection: () => void;
105
119
  /** Moves focus to the next section (year). */
106
120
  focusNextSection: () => void;
121
+ /** Whether the previous visible range would be outside the allowed date range. */
122
+ isPreviousVisibleRangeInvalid: () => boolean;
123
+ /** Whether the next visible range would be outside the allowed date range. */
124
+ isNextVisibleRangeInvalid: () => boolean;
107
125
  /** Moves focus to the previous day. */
108
126
  focusPreviousDay: () => void;
109
127
  /** Moves focus to the next day. */
@@ -143,3 +161,4 @@ export interface RangeCalendarState<T extends DateValue = DateValue> {
143
161
  * Provides state management for a range calendar component.
144
162
  */
145
163
  export declare function createRangeCalendarState<T extends DateValue = CalendarDate>(props?: RangeCalendarStateProps<T>): RangeCalendarState<T>;
164
+ export {};