@proyecto-viviana/solid-stately 0.2.7 → 0.4.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/IncompleteDate.d.ts +61 -0
- package/dist/calendar/createCalendarState.d.ts +41 -16
- package/dist/calendar/createDateFieldState.d.ts +39 -9
- package/dist/calendar/createDatePickerState.d.ts +60 -0
- package/dist/calendar/createRangeCalendarState.d.ts +37 -10
- 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 +11 -8
- package/dist/collections/createMenuState.d.ts +7 -7
- package/dist/collections/createSelectionState.d.ts +22 -10
- package/dist/collections/getChildNodes.d.ts +11 -0
- package/dist/collections/index.d.ts +6 -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 +34 -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 +19 -17
- 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 +27 -11
- package/dist/index.d.ts +31 -30
- package/dist/index.js +9077 -7246
- 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 +14 -8
- package/dist/select/index.d.ts +1 -1
- package/dist/selection/Selection.d.ts +16 -0
- package/dist/selection/SelectionManager.d.ts +110 -0
- package/dist/selection/createMultipleSelectionState.d.ts +59 -0
- package/dist/selection/index.d.ts +6 -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 +33 -3
- package/dist/table/createTableColumnResizeState.d.ts +54 -0
- package/dist/table/createTableState.d.ts +2 -2
- package/dist/table/createTreeGridState.d.ts +15 -0
- package/dist/table/index.d.ts +6 -3
- package/dist/table/types.d.ts +68 -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 +24 -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 +27 -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/IncompleteDate.ts +430 -0
- package/src/calendar/createCalendarState.d.ts +139 -117
- package/src/calendar/createCalendarState.ts +308 -94
- package/src/calendar/createDateFieldState.d.ts +130 -95
- package/src/calendar/createDateFieldState.ts +447 -334
- package/src/calendar/createDatePickerState.ts +347 -0
- package/src/calendar/createRangeCalendarState.d.ts +154 -129
- package/src/calendar/createRangeCalendarState.ts +411 -85
- 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 +23 -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 +67 -35
- package/src/collections/createMenuState.d.ts +36 -31
- package/src/collections/createMenuState.ts +21 -12
- package/src/collections/createSelectionState.d.ts +78 -65
- package/src/collections/createSelectionState.ts +66 -52
- package/src/collections/getChildNodes.ts +98 -0
- package/src/collections/index.d.ts +38 -6
- package/src/collections/index.ts +14 -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 +184 -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 +55 -6
- package/src/dnd/index.ts +6 -18
- package/src/dnd/types.d.ts +170 -157
- package/src/dnd/types.ts +24 -22
- 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 +78 -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 +34 -18
- package/src/index.d.ts +311 -26
- package/src/index.ts +59 -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 +42 -29
- package/src/select/index.d.ts +2 -2
- package/src/select/index.ts +1 -5
- package/src/selection/Selection.ts +28 -0
- package/src/selection/SelectionManager.ts +526 -0
- package/src/selection/createMultipleSelectionState.ts +247 -0
- package/src/selection/index.ts +12 -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 +266 -99
- package/src/table/createTableColumnResizeState.ts +242 -0
- package/src/table/createTableState.d.ts +7 -4
- package/src/table/createTableState.ts +30 -7
- package/src/table/createTreeGridState.ts +146 -0
- package/src/table/index.d.ts +14 -4
- package/src/table/index.ts +13 -3
- package/src/table/types.d.ts +98 -92
- package/src/table/types.ts +83 -13
- package/src/tabs/createTabListState.d.ts +59 -57
- package/src/tabs/createTabListState.ts +34 -39
- 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 +90 -52
- package/src/toast/index.d.ts +12 -2
- package/src/toast/index.ts +2 -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 +70 -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 +30 -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
package/README.md
CHANGED
|
@@ -1,113 +1,23 @@
|
|
|
1
1
|
# @proyecto-viviana/solid-stately
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
SolidJS port of React Stately state primitives.
|
|
4
4
|
|
|
5
|
-
|
|
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
|
-
|
|
12
|
+
npm install @proyecto-viviana/solid-stately solid-js
|
|
9
13
|
```
|
|
10
14
|
|
|
11
|
-
##
|
|
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
|
|
18
|
+
import { createToggleState } from "@proyecto-viviana/solid-stately";
|
|
109
19
|
|
|
110
|
-
function
|
|
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
|
-
<
|
|
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
|
-
</
|
|
30
|
+
</button>
|
|
126
31
|
);
|
|
127
32
|
}
|
|
128
33
|
```
|
|
129
34
|
|
|
130
|
-
|
|
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
|
-
|
|
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
|
-
|
|
169
|
-
import { createOverlayTriggerState } from '@proyecto-viviana/solid-stately';
|
|
41
|
+
Major areas currently covered:
|
|
170
42
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
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
|
-
|
|
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
|
-
|
|
193
|
-
|
|
194
|
-
|
|
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
|
-
|
|
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,8 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Based on @react-stately/autocomplete useAutocompleteState.
|
|
5
5
|
*/
|
|
6
|
-
import { type Accessor } from
|
|
7
|
-
import { type MaybeAccessor } from
|
|
6
|
+
import { type Accessor } from "solid-js";
|
|
7
|
+
import { type MaybeAccessor } from "../utils";
|
|
8
8
|
export interface AutocompleteState {
|
|
9
9
|
/** The current value of the autocomplete input. */
|
|
10
10
|
inputValue: Accessor<string>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { createAutocompleteState, type AutocompleteState, type AutocompleteStateOptions, } from
|
|
1
|
+
export { createAutocompleteState, type AutocompleteState, type AutocompleteStateOptions, } from "./createAutocompleteState";
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IncompleteDate for Solid-Stately
|
|
3
|
+
*
|
|
4
|
+
* Represents a date that is incomplete or otherwise invalid as a result of user
|
|
5
|
+
* editing (for example February 31st, if the day is edited before the month).
|
|
6
|
+
* This lets a date field hold an invalid intermediate value while typing and
|
|
7
|
+
* only constrain it on blur, matching upstream behavior.
|
|
8
|
+
*
|
|
9
|
+
* Based on @react-stately/datepicker IncompleteDate
|
|
10
|
+
*/
|
|
11
|
+
import { type AnyDateTime, type Calendar, type DateValue } from "@internationalized/date";
|
|
12
|
+
import type { DateSegmentType } from "./createDateFieldState";
|
|
13
|
+
type HourCycle = "h12" | "h11" | "h23" | "h24";
|
|
14
|
+
/**
|
|
15
|
+
* This class represents a date that is incomplete or otherwise invalid as a result of user editing.
|
|
16
|
+
* For example, it can represent temporary dates such as February 31st if the user edits the day
|
|
17
|
+
* before the month. Times are represented according to an hour cycle rather than always in 24 hour
|
|
18
|
+
* time. This enables the user to adjust the day period (e.g. am/pm) independently from the hour.
|
|
19
|
+
*/
|
|
20
|
+
export declare class IncompleteDate {
|
|
21
|
+
calendar: Calendar;
|
|
22
|
+
era: string | null;
|
|
23
|
+
year: number | null;
|
|
24
|
+
month: number | null;
|
|
25
|
+
day: number | null;
|
|
26
|
+
hour: number | null;
|
|
27
|
+
hourCycle: HourCycle;
|
|
28
|
+
dayPeriod: number | null;
|
|
29
|
+
minute: number | null;
|
|
30
|
+
second: number | null;
|
|
31
|
+
millisecond: number | null;
|
|
32
|
+
offset: number | null;
|
|
33
|
+
constructor(calendar: Calendar, hourCycle: HourCycle, dateValue?: Partial<Omit<AnyDateTime, "copy">> | null);
|
|
34
|
+
copy(): IncompleteDate;
|
|
35
|
+
/** Checks whether all the specified segments have a value. */
|
|
36
|
+
isComplete(segments: DateSegmentType[]): boolean;
|
|
37
|
+
/** Checks whether the given date value matches this value for the specified segments. */
|
|
38
|
+
validate(dt: DateValue, segments: DateSegmentType[]): boolean;
|
|
39
|
+
/** Checks if the date is empty (i.e. all specified segments are null). */
|
|
40
|
+
isCleared(segments: DateSegmentType[]): boolean;
|
|
41
|
+
/** Sets the given field. */
|
|
42
|
+
set(field: DateSegmentType, value: number | string, placeholder: DateValue): IncompleteDate;
|
|
43
|
+
/** Sets the given field to null. */
|
|
44
|
+
clear(field: DateSegmentType): IncompleteDate;
|
|
45
|
+
/**
|
|
46
|
+
* Increments or decrements the given field. If it is null, then it is set to the placeholder
|
|
47
|
+
* value.
|
|
48
|
+
*/
|
|
49
|
+
cycle(field: DateSegmentType, amount: number, placeholder: DateValue, displaySegments: DateSegmentType[]): IncompleteDate;
|
|
50
|
+
/**
|
|
51
|
+
* Converts the incomplete date to a full date value, using the provided value for any unset
|
|
52
|
+
* fields.
|
|
53
|
+
*/
|
|
54
|
+
toValue(value: DateValue): DateValue;
|
|
55
|
+
getSegmentLimits(type: string): {
|
|
56
|
+
value: number | null;
|
|
57
|
+
minValue: number;
|
|
58
|
+
maxValue: number;
|
|
59
|
+
} | undefined;
|
|
60
|
+
}
|
|
61
|
+
export {};
|
|
@@ -4,17 +4,24 @@
|
|
|
4
4
|
* Provides state management for calendar components.
|
|
5
5
|
* Based on @react-stately/calendar useCalendarState
|
|
6
6
|
*/
|
|
7
|
-
import { type Accessor } from
|
|
8
|
-
import { type CalendarDate, type DateValue } from
|
|
9
|
-
import { type MaybeAccessor } from
|
|
10
|
-
export type ValidationState =
|
|
11
|
-
export
|
|
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";
|
|
14
|
+
export type CalendarSelectionMode = "single" | "multiple";
|
|
15
|
+
export type CalendarValueType<T, M extends CalendarSelectionMode> = M extends "single" ? T : readonly T[];
|
|
16
|
+
export interface CalendarStateProps<T extends DateValue = DateValue, M extends CalendarSelectionMode = "single"> {
|
|
12
17
|
/** The current value (controlled). */
|
|
13
|
-
value?: MaybeAccessor<T | null>;
|
|
18
|
+
value?: MaybeAccessor<CalendarValueType<T | null, M> | undefined>;
|
|
14
19
|
/** The default value (uncontrolled). */
|
|
15
|
-
defaultValue?: T | null;
|
|
20
|
+
defaultValue?: CalendarValueType<T | null, M> | null;
|
|
16
21
|
/** Handler called when the value changes. */
|
|
17
|
-
onChange?: (value: T) => void;
|
|
22
|
+
onChange?: (value: CalendarValueType<T | null, M>) => void;
|
|
23
|
+
/** Whether single or multiple date selection is enabled. */
|
|
24
|
+
selectionMode?: MaybeAccessor<M>;
|
|
18
25
|
/** The minimum allowed date. */
|
|
19
26
|
minValue?: MaybeAccessor<DateValue | undefined>;
|
|
20
27
|
/** The maximum allowed date. */
|
|
@@ -26,17 +33,23 @@ export interface CalendarStateProps<T extends DateValue = DateValue> {
|
|
|
26
33
|
/** Whether dates outside the visible range are automatically focused. */
|
|
27
34
|
autoFocus?: boolean;
|
|
28
35
|
/** The date that is focused when the calendar first mounts. */
|
|
29
|
-
focusedValue?: MaybeAccessor<DateValue | undefined>;
|
|
36
|
+
focusedValue?: MaybeAccessor<DateValue | null | undefined>;
|
|
30
37
|
/** The default focused date (uncontrolled). */
|
|
31
38
|
defaultFocusedValue?: DateValue;
|
|
32
39
|
/** Handler called when the focused date changes. */
|
|
33
40
|
onFocusChange?: (date: CalendarDate) => void;
|
|
34
41
|
/** The locale to use for formatting. */
|
|
35
|
-
locale?: string
|
|
42
|
+
locale?: MaybeAccessor<string | undefined>;
|
|
43
|
+
/** Creates a calendar object for a locale calendar identifier. */
|
|
44
|
+
createCalendar?: (identifier: CalendarIdentifier) => InternationalizedCalendar;
|
|
36
45
|
/** Callback that is called for each date in the calendar to determine if it is unavailable. */
|
|
37
46
|
isDateUnavailable?: (date: DateValue) => boolean;
|
|
38
47
|
/** The number of months to display at once. */
|
|
39
48
|
visibleMonths?: number;
|
|
49
|
+
/** Controls whether paging advances by one month or by the visible month range. */
|
|
50
|
+
pageBehavior?: CalendarPageBehavior;
|
|
51
|
+
/** Determines how the visible months align around the initial focused date. */
|
|
52
|
+
selectionAlignment?: CalendarSelectionAlignment;
|
|
40
53
|
/** Whether to automatically focus the calendar when it is mounted. */
|
|
41
54
|
autoFocusOnMount?: boolean;
|
|
42
55
|
/** Controls which days are disabled. */
|
|
@@ -48,15 +61,21 @@ export interface CalendarStateProps<T extends DateValue = DateValue> {
|
|
|
48
61
|
/** The first day of the week (0 = Sunday, 1 = Monday, etc.). */
|
|
49
62
|
firstDayOfWeek?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
|
|
50
63
|
}
|
|
51
|
-
export interface CalendarState<T extends DateValue = DateValue> {
|
|
52
|
-
/**
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
|
|
64
|
+
export interface CalendarState<T extends DateValue = DateValue, M extends CalendarSelectionMode = "single"> {
|
|
65
|
+
/** Whether single or multiple selection is enabled. */
|
|
66
|
+
selectionMode: Accessor<CalendarSelectionMode>;
|
|
67
|
+
/** The currently selected date(s). */
|
|
68
|
+
value: Accessor<CalendarValueType<T | null, M>>;
|
|
69
|
+
/** Sets the selected date(s). */
|
|
70
|
+
setValue: (value: CalendarValueType<T | null, M>) => void;
|
|
56
71
|
/** The currently focused date. */
|
|
57
72
|
focusedDate: Accessor<CalendarDate>;
|
|
58
73
|
/** Sets the focused date. */
|
|
59
74
|
setFocusedDate: (date: CalendarDate) => void;
|
|
75
|
+
/** The minimum allowed date that a user may select. */
|
|
76
|
+
minValue: Accessor<DateValue | null>;
|
|
77
|
+
/** The maximum allowed date that a user may select. */
|
|
78
|
+
maxValue: Accessor<DateValue | null>;
|
|
60
79
|
/** Whether the calendar is disabled. */
|
|
61
80
|
isDisabled: Accessor<boolean>;
|
|
62
81
|
/** Whether the calendar is read-only. */
|
|
@@ -68,8 +87,14 @@ export interface CalendarState<T extends DateValue = DateValue> {
|
|
|
68
87
|
}>;
|
|
69
88
|
/** The timezone used for date calculations. */
|
|
70
89
|
timeZone: string;
|
|
90
|
+
/** The locale used for formatting and locale-specific week starts. */
|
|
91
|
+
locale: Accessor<string>;
|
|
92
|
+
/** The explicitly requested first weekday, or undefined for the locale default. */
|
|
93
|
+
firstDayOfWeek: Accessor<CalendarDayOfWeek | undefined>;
|
|
71
94
|
/** The validation state. */
|
|
72
95
|
validationState: Accessor<ValidationState | undefined>;
|
|
96
|
+
/** Whether the current value is invalid according to validation state. */
|
|
97
|
+
isValueInvalid: Accessor<boolean>;
|
|
73
98
|
/** Whether a date is selected. */
|
|
74
99
|
isSelected: (date: DateValue) => boolean;
|
|
75
100
|
/** Whether a date is focused. */
|
|
@@ -126,4 +151,4 @@ export interface CalendarState<T extends DateValue = DateValue> {
|
|
|
126
151
|
/**
|
|
127
152
|
* Provides state management for a calendar component.
|
|
128
153
|
*/
|
|
129
|
-
export declare function createCalendarState<T extends DateValue = CalendarDate>(props?: CalendarStateProps<T>): CalendarState<T>;
|
|
154
|
+
export declare function createCalendarState<T extends DateValue = CalendarDate, M extends CalendarSelectionMode = "single">(props?: CalendarStateProps<T, M>): CalendarState<T, M>;
|
|
@@ -3,19 +3,26 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Provides state management for date field components with segment-based editing.
|
|
5
5
|
* Based on @react-stately/datepicker useDateFieldState
|
|
6
|
+
*
|
|
7
|
+
* Editing is modeled with an {@link IncompleteDate} display value so that invalid
|
|
8
|
+
* intermediate dates (e.g. February 31st, produced by editing the day before the
|
|
9
|
+
* month) are held as-typed while the field is focused and only constrained on blur
|
|
10
|
+
* via `confirmPlaceholder`, matching upstream behavior. Out-of-range values are
|
|
11
|
+
* never snapped to `minValue`/`maxValue`; they are kept and reported as invalid.
|
|
6
12
|
*/
|
|
7
|
-
import { type Accessor } from
|
|
8
|
-
import { type
|
|
9
|
-
import { type MaybeAccessor } from
|
|
10
|
-
import type { ValidationState } from
|
|
11
|
-
|
|
13
|
+
import { type Accessor } from "solid-js";
|
|
14
|
+
import { type CalendarDateTime, type DateValue } from "@internationalized/date";
|
|
15
|
+
import { type MaybeAccessor } from "../utils";
|
|
16
|
+
import type { ValidationState } from "./createCalendarState";
|
|
17
|
+
import { type ValidationBehavior, type ValidationFunction, type ValidationResult } from "../form";
|
|
18
|
+
export type DateSegmentType = "year" | "month" | "day" | "hour" | "minute" | "second" | "dayPeriod" | "era" | "timeZoneName" | "literal";
|
|
12
19
|
export interface DateSegment {
|
|
13
20
|
/** The type of segment. */
|
|
14
21
|
type: DateSegmentType;
|
|
15
22
|
/** The text content of the segment. */
|
|
16
23
|
text: string;
|
|
17
24
|
/** The numeric value of the segment (if applicable). */
|
|
18
|
-
value?: number;
|
|
25
|
+
value?: number | null;
|
|
19
26
|
/** The minimum value for the segment. */
|
|
20
27
|
minValue?: number;
|
|
21
28
|
/** The maximum value for the segment. */
|
|
@@ -44,18 +51,26 @@ export interface DateFieldStateProps<T extends DateValue = DateValue> {
|
|
|
44
51
|
isReadOnly?: MaybeAccessor<boolean>;
|
|
45
52
|
/** Whether the field is required. */
|
|
46
53
|
isRequired?: MaybeAccessor<boolean>;
|
|
54
|
+
/** Whether the value is invalid (controlled). */
|
|
55
|
+
isInvalid?: boolean;
|
|
47
56
|
/** The locale to use for formatting. */
|
|
48
57
|
locale?: string;
|
|
49
58
|
/** The granularity of the date/time (day, hour, minute, second). */
|
|
50
|
-
granularity?:
|
|
59
|
+
granularity?: "day" | "hour" | "minute" | "second";
|
|
51
60
|
/** Whether to show the hour in 12 or 24 hour format. */
|
|
52
61
|
hourCycle?: 12 | 24;
|
|
53
62
|
/** Whether to hide the time zone. */
|
|
54
63
|
hideTimeZone?: boolean;
|
|
55
64
|
/** The placeholder date (determines segment structure). */
|
|
56
65
|
placeholderValue?: DateValue;
|
|
66
|
+
/** Whether to force leading zeroes in month/day segments. */
|
|
67
|
+
shouldForceLeadingZeros?: boolean;
|
|
57
68
|
/** Validation state. */
|
|
58
69
|
validationState?: MaybeAccessor<ValidationState | undefined>;
|
|
70
|
+
/** Validation behavior mode. */
|
|
71
|
+
validationBehavior?: ValidationBehavior;
|
|
72
|
+
/** Custom validation function. */
|
|
73
|
+
validate?: ValidationFunction<T>;
|
|
59
74
|
/** Description text. */
|
|
60
75
|
description?: string;
|
|
61
76
|
/** Error message. */
|
|
@@ -64,6 +79,8 @@ export interface DateFieldStateProps<T extends DateValue = DateValue> {
|
|
|
64
79
|
allowsNonContiguousRanges?: boolean;
|
|
65
80
|
/** Whether to create a date or datetime. */
|
|
66
81
|
createCalendar?: (name: string) => unknown;
|
|
82
|
+
/** Whether a date is unavailable. */
|
|
83
|
+
isDateUnavailable?: (date: DateValue) => boolean;
|
|
67
84
|
}
|
|
68
85
|
export interface DateFieldState<T extends DateValue = DateValue> {
|
|
69
86
|
/** The current value. */
|
|
@@ -95,15 +112,28 @@ export interface DateFieldState<T extends DateValue = DateValue> {
|
|
|
95
112
|
/** The validation state. */
|
|
96
113
|
validationState: Accessor<ValidationState | undefined>;
|
|
97
114
|
/** The granularity. */
|
|
98
|
-
granularity:
|
|
115
|
+
granularity: "day" | "hour" | "minute" | "second";
|
|
99
116
|
/** Whether the value is invalid. */
|
|
100
117
|
isInvalid: Accessor<boolean>;
|
|
118
|
+
/** Realtime validation results, including native and custom constraints. */
|
|
119
|
+
realtimeValidation: Accessor<ValidationResult>;
|
|
120
|
+
/** Currently displayed validation results. */
|
|
121
|
+
displayValidation: Accessor<ValidationResult>;
|
|
122
|
+
/** Updates the current validation result. */
|
|
123
|
+
updateValidation: (result: ValidationResult) => void;
|
|
124
|
+
/** Resets displayed validation to valid. */
|
|
125
|
+
resetValidation: () => void;
|
|
126
|
+
/** Commits realtime validation to displayed validation. */
|
|
127
|
+
commitValidation: () => void;
|
|
101
128
|
/** The locale. */
|
|
102
129
|
locale: string;
|
|
103
130
|
/** The time zone. */
|
|
104
131
|
timeZone: string;
|
|
132
|
+
/** The default value. */
|
|
133
|
+
defaultValue: T | null;
|
|
105
134
|
}
|
|
106
135
|
/**
|
|
107
136
|
* Provides state management for a date field component.
|
|
108
137
|
*/
|
|
109
|
-
export declare function createDateFieldState<T extends DateValue =
|
|
138
|
+
export declare function createDateFieldState<T extends DateValue = DateValue>(props?: DateFieldStateProps<T>): DateFieldState<T>;
|
|
139
|
+
export type { CalendarDateTime };
|