@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.
- package/LICENSE +21 -0
- package/README.md +30 -283
- package/dist/autocomplete/createAutocompleteState.d.ts +3 -2
- package/dist/autocomplete/index.d.ts +1 -1
- package/dist/calendar/createCalendarState.d.ts +22 -7
- package/dist/calendar/createDateFieldState.d.ts +30 -7
- package/dist/calendar/createDatePickerState.d.ts +60 -0
- package/dist/calendar/createRangeCalendarState.d.ts +27 -8
- package/dist/calendar/createTimeFieldState.d.ts +34 -7
- package/dist/calendar/index.d.ts +7 -6
- package/dist/checkbox/createCheckboxGroupState.d.ts +12 -3
- package/dist/checkbox/index.d.ts +1 -1
- package/dist/collections/ListCollection.d.ts +1 -1
- package/dist/collections/createListState.d.ts +8 -8
- package/dist/collections/createMenuState.d.ts +7 -7
- package/dist/collections/createSelectionState.d.ts +5 -5
- package/dist/collections/index.d.ts +5 -5
- package/dist/collections/types.d.ts +23 -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 +20 -0
- package/dist/color/index.d.ts +6 -6
- package/dist/color/types.d.ts +4 -4
- package/dist/combobox/createComboBoxState.d.ts +27 -13
- package/dist/combobox/index.d.ts +1 -1
- package/dist/data/createAsyncList.d.ts +111 -0
- package/dist/data/createListData.d.ts +65 -0
- package/dist/data/createTreeData.d.ts +65 -0
- package/dist/data/index.d.ts +3 -0
- package/dist/datepicker/index.d.ts +8 -0
- package/dist/disclosure/createDisclosureState.d.ts +2 -2
- package/dist/disclosure/index.d.ts +1 -1
- package/dist/dnd/createDragState.d.ts +2 -2
- package/dist/dnd/createDraggableCollectionState.d.ts +2 -2
- package/dist/dnd/createDropState.d.ts +2 -2
- package/dist/dnd/createDroppableCollectionState.d.ts +3 -3
- package/dist/dnd/index.d.ts +5 -5
- package/dist/dnd/types.d.ts +16 -16
- package/dist/form/createFormValidationState.d.ts +3 -3
- package/dist/form/index.d.ts +1 -1
- package/dist/grid/createGridState.d.ts +2 -2
- package/dist/grid/index.d.ts +2 -2
- package/dist/grid/types.d.ts +17 -11
- package/dist/index.d.ts +31 -25
- package/dist/index.js +7990 -6264
- package/dist/index.js.map +1 -7
- package/dist/menu/index.d.ts +8 -0
- 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 +13 -4
- 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 +20 -3
- package/dist/select/index.d.ts +1 -1
- package/dist/selection/index.d.ts +11 -0
- package/dist/slider/createSliderState.d.ts +3 -3
- package/dist/slider/index.d.ts +2 -2
- package/dist/steplist/createStepListState.d.ts +48 -0
- package/dist/steplist/index.d.ts +1 -0
- package/dist/table/TableCollection.d.ts +3 -3
- package/dist/table/createTableColumnResizeState.d.ts +54 -0
- package/dist/table/createTableState.d.ts +2 -2
- package/dist/table/index.d.ts +5 -3
- package/dist/table/types.d.ts +10 -10
- package/dist/tabs/createTabListState.d.ts +5 -5
- package/dist/tabs/index.d.ts +1 -1
- package/dist/textfield/createTextFieldState.d.ts +2 -2
- package/dist/textfield/index.d.ts +1 -1
- package/dist/toast/createToastState.d.ts +15 -3
- package/dist/toast/index.d.ts +1 -1
- package/dist/toggle/createToggleGroupState.d.ts +45 -0
- package/dist/toggle/createToggleState.d.ts +2 -2
- package/dist/toggle/index.d.ts +2 -1
- package/dist/tooltip/createTooltipTriggerState.d.ts +2 -2
- package/dist/tooltip/index.d.ts +1 -1
- package/dist/tree/TreeCollection.d.ts +5 -4
- package/dist/tree/createTreeState.d.ts +2 -2
- package/dist/tree/index.d.ts +3 -3
- package/dist/tree/types.d.ts +19 -13
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/reactivity.d.ts +1 -1
- package/package.json +30 -30
- package/src/autocomplete/createAutocompleteState.d.ts +19 -17
- package/src/autocomplete/createAutocompleteState.ts +25 -32
- package/src/autocomplete/index.d.ts +6 -2
- package/src/autocomplete/index.ts +1 -1
- package/src/calendar/createCalendarState.d.ts +139 -117
- package/src/calendar/createCalendarState.ts +221 -74
- package/src/calendar/createDateFieldState.d.ts +130 -95
- package/src/calendar/createDateFieldState.ts +286 -151
- package/src/calendar/createDatePickerState.ts +347 -0
- package/src/calendar/createRangeCalendarState.d.ts +154 -129
- package/src/calendar/createRangeCalendarState.ts +293 -79
- package/src/calendar/createTimeFieldState.d.ts +81 -79
- package/src/calendar/createTimeFieldState.ts +187 -108
- package/src/calendar/index.d.ts +80 -7
- package/src/calendar/index.ts +21 -12
- package/src/checkbox/createCheckboxGroupState.d.ts +57 -55
- package/src/checkbox/createCheckboxGroupState.ts +57 -30
- 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 +152 -146
- package/src/collections/createListState.d.ts +73 -58
- package/src/collections/createListState.ts +267 -264
- package/src/collections/createMenuState.d.ts +36 -31
- package/src/collections/createMenuState.ts +112 -106
- package/src/collections/createSelectionState.d.ts +78 -65
- package/src/collections/createSelectionState.ts +340 -336
- package/src/collections/index.d.ts +38 -6
- package/src/collections/index.ts +41 -46
- package/src/collections/types.d.ts +101 -101
- package/src/collections/types.ts +181 -169
- package/src/color/Color.d.ts +20 -5
- package/src/color/Color.ts +1054 -951
- package/src/color/createColorAreaState.d.ts +67 -65
- package/src/color/createColorAreaState.ts +301 -293
- package/src/color/createColorFieldState.d.ts +46 -44
- package/src/color/createColorFieldState.ts +428 -292
- package/src/color/createColorSliderState.d.ts +58 -56
- package/src/color/createColorSliderState.ts +272 -241
- package/src/color/createColorWheelState.d.ts +42 -40
- package/src/color/createColorWheelState.ts +248 -211
- package/src/color/getColorChannels.ts +36 -0
- package/src/color/index.d.ts +36 -7
- package/src/color/index.ts +44 -47
- package/src/color/types.d.ts +68 -63
- package/src/color/types.ts +119 -127
- package/src/combobox/createComboBoxState.d.ts +107 -105
- package/src/combobox/createComboBoxState.ts +790 -703
- package/src/combobox/index.d.ts +10 -2
- package/src/combobox/index.ts +13 -13
- package/src/data/createAsyncList.ts +403 -0
- package/src/data/createListData.ts +298 -0
- package/src/data/createTreeData.ts +646 -0
- package/src/data/index.ts +25 -0
- package/src/datepicker/index.ts +32 -0
- package/src/disclosure/createDisclosureState.d.ts +47 -43
- package/src/disclosure/createDisclosureState.ts +9 -23
- 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 +151 -153
- package/src/dnd/createDraggableCollectionState.d.ts +52 -41
- package/src/dnd/createDraggableCollectionState.ts +158 -165
- package/src/dnd/createDropState.d.ts +64 -45
- package/src/dnd/createDropState.ts +202 -212
- package/src/dnd/createDroppableCollectionState.d.ts +88 -59
- package/src/dnd/createDroppableCollectionState.ts +354 -357
- package/src/dnd/index.d.ts +54 -6
- package/src/dnd/index.ts +63 -76
- package/src/dnd/types.d.ts +167 -156
- package/src/dnd/types.ts +316 -317
- package/src/form/createFormValidationState.d.ts +47 -45
- package/src/form/createFormValidationState.ts +356 -389
- package/src/form/index.d.ts +16 -2
- package/src/form/index.ts +15 -15
- package/src/grid/createGridState.d.ts +7 -4
- package/src/grid/createGridState.ts +44 -51
- package/src/grid/index.d.ts +3 -3
- package/src/grid/index.ts +2 -8
- package/src/grid/types.d.ts +136 -129
- package/src/grid/types.ts +24 -17
- package/src/index.d.ts +310 -26
- package/src/index.ts +87 -79
- package/src/menu/index.ts +17 -0
- package/src/numberfield/createNumberFieldState.d.ts +56 -54
- package/src/numberfield/createNumberFieldState.ts +422 -383
- package/src/numberfield/index.d.ts +6 -2
- package/src/numberfield/index.ts +5 -5
- package/src/overlays/createOverlayTriggerState.d.ts +22 -20
- package/src/overlays/createOverlayTriggerState.ts +66 -67
- package/src/overlays/index.d.ts +6 -2
- package/src/overlays/index.ts +5 -5
- package/src/radio/createRadioGroupState.d.ts +54 -52
- package/src/radio/createRadioGroupState.ts +66 -30
- 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 +56 -62
- 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 +290 -181
- package/src/select/index.d.ts +2 -2
- package/src/select/index.ts +1 -5
- package/src/selection/index.ts +27 -0
- package/src/slider/createSliderState.d.ts +60 -60
- package/src/slider/createSliderState.ts +233 -211
- package/src/slider/index.d.ts +3 -3
- package/src/slider/index.ts +2 -6
- package/src/ssr/index.d.ts +1 -1
- package/src/ssr/index.ts +2 -2
- package/src/steplist/createStepListState.ts +191 -0
- package/src/steplist/index.ts +5 -0
- package/src/table/TableCollection.d.ts +42 -40
- package/src/table/TableCollection.ts +61 -64
- package/src/table/createTableColumnResizeState.ts +242 -0
- package/src/table/createTableState.d.ts +7 -4
- package/src/table/createTableState.ts +10 -7
- package/src/table/index.d.ts +14 -4
- package/src/table/index.ts +10 -3
- package/src/table/types.d.ts +98 -92
- package/src/table/types.ts +17 -13
- package/src/tabs/createTabListState.d.ts +59 -57
- package/src/tabs/createTabListState.ts +58 -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 -81
- package/src/toast/createToastState.ts +56 -44
- package/src/toast/index.d.ts +12 -2
- package/src/toast/index.ts +1 -1
- package/src/toggle/createToggleGroupState.ts +117 -0
- 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 +6 -4
- package/src/tooltip/createTooltipTriggerState.d.ts +17 -17
- package/src/tooltip/createTooltipTriggerState.ts +184 -183
- package/src/tooltip/index.d.ts +7 -2
- package/src/tooltip/index.ts +6 -6
- package/src/tree/TreeCollection.d.ts +26 -23
- package/src/tree/TreeCollection.ts +215 -175
- package/src/tree/createTreeState.d.ts +7 -4
- package/src/tree/createTreeState.ts +390 -392
- package/src/tree/index.d.ts +10 -4
- package/src/tree/index.ts +13 -13
- package/src/tree/types.d.ts +131 -126
- package/src/tree/types.ts +183 -174
- 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
|
@@ -1,292 +1,428 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ColorField state management.
|
|
3
|
-
* Based on @react-stately/color useColorFieldState.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import {
|
|
7
|
-
import type { Color, ColorChannel, ColorFormat } from
|
|
8
|
-
import { normalizeColor, parseColor } from
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
|
|
32
|
-
/** Whether the
|
|
33
|
-
|
|
34
|
-
/** Whether the field is
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
|
|
59
|
-
*/
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
const
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
const
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
const
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
const
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
const
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
};
|
|
292
|
-
|
|
1
|
+
/**
|
|
2
|
+
* ColorField state management.
|
|
3
|
+
* Based on @react-stately/color useColorFieldState and useColorChannelFieldState.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { createEffect, createMemo, createSignal, type Accessor } from "solid-js";
|
|
7
|
+
import type { Color, ColorChannel, ColorChannelRange, ColorFormat, ColorSpace } from "./types";
|
|
8
|
+
import { createRGBColor, normalizeColor, parseColor } from "./Color";
|
|
9
|
+
|
|
10
|
+
const HEX_COLOR_MAX = 0xffffff;
|
|
11
|
+
const PARTIAL_HEX_PATTERN = /^#?[0-9a-f]{0,6}$/i;
|
|
12
|
+
|
|
13
|
+
export interface ColorFieldStateOptions {
|
|
14
|
+
/** The current color value (controlled). */
|
|
15
|
+
value?: Color | string | null;
|
|
16
|
+
/** The default color value (uncontrolled). */
|
|
17
|
+
defaultValue?: Color | string | null;
|
|
18
|
+
/** Handler called when the color changes. */
|
|
19
|
+
onChange?: (color: Color | null) => void;
|
|
20
|
+
/** The color channel to edit (for single channel mode). */
|
|
21
|
+
channel?: ColorChannel;
|
|
22
|
+
/** The color space to use for channel mode. */
|
|
23
|
+
colorSpace?: ColorSpace;
|
|
24
|
+
/** The color format for parsing/displaying in hex mode. */
|
|
25
|
+
colorFormat?: ColorFormat;
|
|
26
|
+
/** Locale used to format channel values. */
|
|
27
|
+
locale?: string;
|
|
28
|
+
/** Whether the field is disabled. */
|
|
29
|
+
isDisabled?: boolean;
|
|
30
|
+
/** Whether the field is read-only. */
|
|
31
|
+
isReadOnly?: boolean;
|
|
32
|
+
/** Whether the field is invalid. */
|
|
33
|
+
isInvalid?: boolean;
|
|
34
|
+
/** Whether the field is required. */
|
|
35
|
+
isRequired?: boolean;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface ColorFieldState {
|
|
39
|
+
/** The current color value (null if empty). */
|
|
40
|
+
readonly value: Color | null;
|
|
41
|
+
/** The color used for channel calculations. */
|
|
42
|
+
readonly colorValue: Color;
|
|
43
|
+
/** The current input text. */
|
|
44
|
+
readonly inputValue: string;
|
|
45
|
+
/** The numeric value exposed by channel fields. */
|
|
46
|
+
readonly numberValue: number;
|
|
47
|
+
/** The channel minimum value after formatting normalization. */
|
|
48
|
+
readonly minValue: number;
|
|
49
|
+
/** The channel maximum value after formatting normalization. */
|
|
50
|
+
readonly maxValue: number;
|
|
51
|
+
/** The channel keyboard step after formatting normalization. */
|
|
52
|
+
readonly step: number;
|
|
53
|
+
/** The channel page step after formatting normalization. */
|
|
54
|
+
readonly pageSize: number;
|
|
55
|
+
/** Number formatter options for channel fields. */
|
|
56
|
+
readonly formatOptions: Intl.NumberFormatOptions;
|
|
57
|
+
/** Whether the input is invalid. */
|
|
58
|
+
readonly isInvalid: boolean;
|
|
59
|
+
/** Whether the field is disabled. */
|
|
60
|
+
readonly isDisabled: boolean;
|
|
61
|
+
/** Whether the field is read-only. */
|
|
62
|
+
readonly isReadOnly: boolean;
|
|
63
|
+
/** Whether the field is required. */
|
|
64
|
+
readonly isRequired: boolean;
|
|
65
|
+
/** The color channel being edited (if single channel mode). */
|
|
66
|
+
readonly channel: ColorChannel | undefined;
|
|
67
|
+
|
|
68
|
+
/** Set the input text value. */
|
|
69
|
+
setInputValue(value: string): void;
|
|
70
|
+
/** Set the color value. */
|
|
71
|
+
setColorValue(value: Color | null): void;
|
|
72
|
+
/** Commit the current input value. */
|
|
73
|
+
commit(): void;
|
|
74
|
+
/** Increment the color value. */
|
|
75
|
+
increment(): void;
|
|
76
|
+
/** Decrement the color value. */
|
|
77
|
+
decrement(): void;
|
|
78
|
+
/** Increment by page size or to the maximum. */
|
|
79
|
+
incrementToMax(): void;
|
|
80
|
+
/** Decrement by page size or to the minimum. */
|
|
81
|
+
decrementToMin(): void;
|
|
82
|
+
/** Validate the current input or a candidate input. */
|
|
83
|
+
validate(value?: string): boolean;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function normalizeNullableColor(value: Color | string | null | undefined): Color | null {
|
|
87
|
+
if (value == null) {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
return normalizeColor(value);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function getDefaultValue(options: ColorFieldStateOptions): Color | null {
|
|
94
|
+
if (options.defaultValue !== undefined) {
|
|
95
|
+
return normalizeNullableColor(options.defaultValue);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (options.value !== undefined) {
|
|
99
|
+
return normalizeNullableColor(options.value);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function convertColor(color: Color, colorSpace: ColorSpace | undefined): Color {
|
|
106
|
+
return colorSpace ? color.toFormat(colorSpace) : color;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function getDisplayColor(color: Color | null, colorSpace: ColorSpace | undefined): Color {
|
|
110
|
+
return convertColor(color ?? createRGBColor(0, 0, 0), colorSpace);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function getChannelMultiplier(color: Color, channel: ColorChannel): number {
|
|
114
|
+
const range = color.getChannelRange(channel);
|
|
115
|
+
const formatOptions = color.getChannelFormatOptions(channel);
|
|
116
|
+
return formatOptions.style === "percent" && range.maxValue === 100 ? 100 : 1;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function getNormalizedRange(color: Color, channel: ColorChannel): ColorChannelRange {
|
|
120
|
+
const multiplier = getChannelMultiplier(color, channel);
|
|
121
|
+
const range = color.getChannelRange(channel);
|
|
122
|
+
|
|
123
|
+
return {
|
|
124
|
+
minValue: range.minValue / multiplier,
|
|
125
|
+
maxValue: range.maxValue / multiplier,
|
|
126
|
+
step: range.step / multiplier,
|
|
127
|
+
pageSize: range.pageSize / multiplier,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function formatColorValue(
|
|
132
|
+
color: Color | null,
|
|
133
|
+
channel: ColorChannel | undefined,
|
|
134
|
+
colorSpace: ColorSpace | undefined,
|
|
135
|
+
format: ColorFormat | undefined,
|
|
136
|
+
locale: string,
|
|
137
|
+
): string {
|
|
138
|
+
if (!color) {
|
|
139
|
+
return "";
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const displayColor = getDisplayColor(color, colorSpace);
|
|
143
|
+
|
|
144
|
+
if (channel) {
|
|
145
|
+
return displayColor.formatChannelValue(channel, locale);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return displayColor.toString(format ?? "hex");
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function normalizeHexInput(value: string): string {
|
|
152
|
+
return value.startsWith("#") ? value : `#${value}`;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function parseHexValue(value: string, format: ColorFormat | undefined): Color {
|
|
156
|
+
const color = parseColor(normalizeHexInput(value));
|
|
157
|
+
return format ? color.toFormat(format) : color;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function parseChannelValue(text: string, color: Color, channel: ColorChannel): number | null {
|
|
161
|
+
const trimmed = text.trim();
|
|
162
|
+
const hasPercent = trimmed.endsWith("%");
|
|
163
|
+
const parsed = Number.parseFloat(hasPercent ? trimmed.slice(0, -1) : trimmed);
|
|
164
|
+
|
|
165
|
+
if (Number.isNaN(parsed)) {
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const range = color.getChannelRange(channel);
|
|
170
|
+
const formatOptions = color.getChannelFormatOptions(channel);
|
|
171
|
+
const multiplier = getChannelMultiplier(color, channel);
|
|
172
|
+
const rawValue = hasPercent && formatOptions.style === "percent" ? parsed : parsed * multiplier;
|
|
173
|
+
|
|
174
|
+
return Math.min(range.maxValue, Math.max(range.minValue, rawValue));
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function hexIntToColor(value: number): Color {
|
|
178
|
+
const clamped = Math.min(HEX_COLOR_MAX, Math.max(0, Math.round(value)));
|
|
179
|
+
const red = (clamped >> 16) & 0xff;
|
|
180
|
+
const green = (clamped >> 8) & 0xff;
|
|
181
|
+
const blue = clamped & 0xff;
|
|
182
|
+
return createRGBColor(red, green, blue);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Creates state for a color field (text input for color values).
|
|
187
|
+
*/
|
|
188
|
+
export function createColorFieldState(options: Accessor<ColorFieldStateOptions>): ColorFieldState {
|
|
189
|
+
const getOptions = () => options();
|
|
190
|
+
const initialOptions = getOptions();
|
|
191
|
+
const initialValue = getDefaultValue(initialOptions);
|
|
192
|
+
|
|
193
|
+
const [internalValue, setInternalValue] = createSignal<Color | null>(initialValue);
|
|
194
|
+
const [inputValue, setInputValueInternal] = createSignal(
|
|
195
|
+
formatColorValue(
|
|
196
|
+
initialValue,
|
|
197
|
+
initialOptions.channel,
|
|
198
|
+
initialOptions.colorSpace,
|
|
199
|
+
initialOptions.colorFormat,
|
|
200
|
+
initialOptions.locale ?? "en-US",
|
|
201
|
+
),
|
|
202
|
+
);
|
|
203
|
+
const [invalidInput, setInvalidInput] = createSignal(false);
|
|
204
|
+
|
|
205
|
+
const channel = createMemo(() => getOptions().channel);
|
|
206
|
+
const colorSpace = createMemo(() => getOptions().colorSpace);
|
|
207
|
+
const locale = createMemo(() => getOptions().locale ?? "en-US");
|
|
208
|
+
|
|
209
|
+
const value = createMemo(() => {
|
|
210
|
+
const opts = getOptions();
|
|
211
|
+
if (opts.value !== undefined) {
|
|
212
|
+
return normalizeNullableColor(opts.value);
|
|
213
|
+
}
|
|
214
|
+
return internalValue();
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
const colorValue = createMemo(() => getDisplayColor(value(), colorSpace()));
|
|
218
|
+
const isDisabled = createMemo(() => getOptions().isDisabled ?? false);
|
|
219
|
+
const isReadOnly = createMemo(() => getOptions().isReadOnly ?? false);
|
|
220
|
+
const isRequired = createMemo(() => getOptions().isRequired ?? false);
|
|
221
|
+
const isInvalid = createMemo(() => (getOptions().isInvalid ?? false) || invalidInput());
|
|
222
|
+
|
|
223
|
+
const formatCurrentValue = (color: Color | null = value()) =>
|
|
224
|
+
formatColorValue(color, channel(), colorSpace(), getOptions().colorFormat, locale());
|
|
225
|
+
|
|
226
|
+
createEffect(() => {
|
|
227
|
+
setInputValueInternal(formatCurrentValue());
|
|
228
|
+
setInvalidInput(false);
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
const updateValue = (newColor: Color | null) => {
|
|
232
|
+
const opts = getOptions();
|
|
233
|
+
|
|
234
|
+
if (opts.value === undefined) {
|
|
235
|
+
setInternalValue(newColor);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
opts.onChange?.(newColor);
|
|
239
|
+
setInputValueInternal(formatCurrentValue(newColor));
|
|
240
|
+
setInvalidInput(false);
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
const setInputValue = (text: string) => {
|
|
244
|
+
setInputValueInternal(text);
|
|
245
|
+
setInvalidInput(false);
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
const setColorValue = (newColor: Color | null) => {
|
|
249
|
+
updateValue(newColor);
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
const commit = () => {
|
|
253
|
+
const text = inputValue().trim();
|
|
254
|
+
const opts = getOptions();
|
|
255
|
+
const chan = channel();
|
|
256
|
+
|
|
257
|
+
if (!text) {
|
|
258
|
+
updateValue(null);
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (chan) {
|
|
263
|
+
const displayColor = colorValue();
|
|
264
|
+
const rawValue = parseChannelValue(text, displayColor, chan);
|
|
265
|
+
if (rawValue == null) {
|
|
266
|
+
setInputValueInternal(formatCurrentValue());
|
|
267
|
+
setInvalidInput(false);
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
updateValue(displayColor.withChannelValue(chan, rawValue));
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
try {
|
|
276
|
+
updateValue(parseHexValue(text, opts.colorFormat));
|
|
277
|
+
} catch {
|
|
278
|
+
setInputValueInternal(formatCurrentValue());
|
|
279
|
+
setInvalidInput(false);
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
const incrementHex = (amount: number) => {
|
|
284
|
+
const currentColor = value();
|
|
285
|
+
if (!currentColor) {
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
const newColor = hexIntToColor(currentColor.toFormat("rgb").toHexInt() + amount);
|
|
290
|
+
updateValue(getOptions().colorFormat ? newColor.toFormat(getOptions().colorFormat!) : newColor);
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
const updateChannel = (amount: number | "min" | "max") => {
|
|
294
|
+
const chan = channel();
|
|
295
|
+
if (!chan) {
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
const displayColor = colorValue();
|
|
300
|
+
const range = displayColor.getChannelRange(chan);
|
|
301
|
+
const currentValue = displayColor.getChannelValue(chan);
|
|
302
|
+
const nextValue =
|
|
303
|
+
amount === "min"
|
|
304
|
+
? range.minValue
|
|
305
|
+
: amount === "max"
|
|
306
|
+
? range.maxValue
|
|
307
|
+
: Math.min(range.maxValue, Math.max(range.minValue, currentValue + amount));
|
|
308
|
+
|
|
309
|
+
updateValue(displayColor.withChannelValue(chan, nextValue));
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
const increment = () => {
|
|
313
|
+
const chan = channel();
|
|
314
|
+
if (!chan) {
|
|
315
|
+
incrementHex(1);
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
updateChannel(colorValue().getChannelRange(chan).step);
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
const decrement = () => {
|
|
323
|
+
const chan = channel();
|
|
324
|
+
if (!chan) {
|
|
325
|
+
incrementHex(-1);
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
updateChannel(-colorValue().getChannelRange(chan).step);
|
|
330
|
+
};
|
|
331
|
+
|
|
332
|
+
const incrementToMax = () => {
|
|
333
|
+
const chan = channel();
|
|
334
|
+
if (!chan) {
|
|
335
|
+
incrementHex(HEX_COLOR_MAX);
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
updateChannel("max");
|
|
340
|
+
};
|
|
341
|
+
|
|
342
|
+
const decrementToMin = () => {
|
|
343
|
+
const chan = channel();
|
|
344
|
+
if (!chan) {
|
|
345
|
+
incrementHex(-HEX_COLOR_MAX);
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
updateChannel("min");
|
|
350
|
+
};
|
|
351
|
+
|
|
352
|
+
const validate = (candidate?: string) => {
|
|
353
|
+
const text = (candidate ?? inputValue()).trim();
|
|
354
|
+
const chan = channel();
|
|
355
|
+
|
|
356
|
+
if (!text) {
|
|
357
|
+
return true;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
if (chan) {
|
|
361
|
+
return parseChannelValue(text, colorValue(), chan) != null;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
return PARTIAL_HEX_PATTERN.test(text);
|
|
365
|
+
};
|
|
366
|
+
|
|
367
|
+
return {
|
|
368
|
+
get value() {
|
|
369
|
+
return value();
|
|
370
|
+
},
|
|
371
|
+
get colorValue() {
|
|
372
|
+
return colorValue();
|
|
373
|
+
},
|
|
374
|
+
get inputValue() {
|
|
375
|
+
return inputValue();
|
|
376
|
+
},
|
|
377
|
+
get numberValue() {
|
|
378
|
+
const chan = channel();
|
|
379
|
+
if (!chan || value() === null) {
|
|
380
|
+
return Number.NaN;
|
|
381
|
+
}
|
|
382
|
+
return colorValue().getChannelValue(chan) / getChannelMultiplier(colorValue(), chan);
|
|
383
|
+
},
|
|
384
|
+
get minValue() {
|
|
385
|
+
const chan = channel();
|
|
386
|
+
return chan ? getNormalizedRange(colorValue(), chan).minValue : 0;
|
|
387
|
+
},
|
|
388
|
+
get maxValue() {
|
|
389
|
+
const chan = channel();
|
|
390
|
+
return chan ? getNormalizedRange(colorValue(), chan).maxValue : HEX_COLOR_MAX;
|
|
391
|
+
},
|
|
392
|
+
get step() {
|
|
393
|
+
const chan = channel();
|
|
394
|
+
return chan ? getNormalizedRange(colorValue(), chan).step : 1;
|
|
395
|
+
},
|
|
396
|
+
get pageSize() {
|
|
397
|
+
const chan = channel();
|
|
398
|
+
return chan ? getNormalizedRange(colorValue(), chan).pageSize : 0x100000;
|
|
399
|
+
},
|
|
400
|
+
get formatOptions() {
|
|
401
|
+
const chan = channel();
|
|
402
|
+
return chan ? colorValue().getChannelFormatOptions(chan) : {};
|
|
403
|
+
},
|
|
404
|
+
get isInvalid() {
|
|
405
|
+
return isInvalid();
|
|
406
|
+
},
|
|
407
|
+
get isDisabled() {
|
|
408
|
+
return isDisabled();
|
|
409
|
+
},
|
|
410
|
+
get isReadOnly() {
|
|
411
|
+
return isReadOnly();
|
|
412
|
+
},
|
|
413
|
+
get isRequired() {
|
|
414
|
+
return isRequired();
|
|
415
|
+
},
|
|
416
|
+
get channel() {
|
|
417
|
+
return channel();
|
|
418
|
+
},
|
|
419
|
+
setInputValue,
|
|
420
|
+
setColorValue,
|
|
421
|
+
commit,
|
|
422
|
+
increment,
|
|
423
|
+
decrement,
|
|
424
|
+
incrementToMax,
|
|
425
|
+
decrementToMin,
|
|
426
|
+
validate,
|
|
427
|
+
};
|
|
428
|
+
}
|