@proyecto-viviana/solid-stately 0.2.7 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (242) hide show
  1. package/README.md +30 -283
  2. package/dist/autocomplete/createAutocompleteState.d.ts +2 -2
  3. package/dist/autocomplete/index.d.ts +1 -1
  4. package/dist/calendar/createCalendarState.d.ts +22 -7
  5. package/dist/calendar/createDateFieldState.d.ts +30 -7
  6. package/dist/calendar/createDatePickerState.d.ts +60 -0
  7. package/dist/calendar/createRangeCalendarState.d.ts +27 -8
  8. package/dist/calendar/createTimeFieldState.d.ts +34 -7
  9. package/dist/calendar/index.d.ts +7 -6
  10. package/dist/checkbox/createCheckboxGroupState.d.ts +6 -6
  11. package/dist/checkbox/index.d.ts +1 -1
  12. package/dist/collections/ListCollection.d.ts +1 -1
  13. package/dist/collections/createListState.d.ts +8 -8
  14. package/dist/collections/createMenuState.d.ts +7 -7
  15. package/dist/collections/createSelectionState.d.ts +5 -5
  16. package/dist/collections/index.d.ts +5 -5
  17. package/dist/collections/types.d.ts +12 -12
  18. package/dist/color/Color.d.ts +1 -1
  19. package/dist/color/createColorAreaState.d.ts +4 -2
  20. package/dist/color/createColorFieldState.d.ts +38 -12
  21. package/dist/color/createColorSliderState.d.ts +9 -2
  22. package/dist/color/createColorWheelState.d.ts +13 -2
  23. package/dist/color/getColorChannels.d.ts +1 -1
  24. package/dist/color/index.d.ts +6 -6
  25. package/dist/color/types.d.ts +4 -4
  26. package/dist/combobox/createComboBoxState.d.ts +27 -13
  27. package/dist/combobox/index.d.ts +1 -1
  28. package/dist/data/createAsyncList.d.ts +4 -4
  29. package/dist/data/createListData.d.ts +2 -2
  30. package/dist/data/createTreeData.d.ts +6 -2
  31. package/dist/data/index.d.ts +3 -3
  32. package/dist/datepicker/index.d.ts +2 -4
  33. package/dist/disclosure/createDisclosureState.d.ts +2 -2
  34. package/dist/disclosure/index.d.ts +1 -1
  35. package/dist/dnd/createDragState.d.ts +2 -2
  36. package/dist/dnd/createDraggableCollectionState.d.ts +2 -2
  37. package/dist/dnd/createDropState.d.ts +2 -2
  38. package/dist/dnd/createDroppableCollectionState.d.ts +3 -3
  39. package/dist/dnd/index.d.ts +5 -5
  40. package/dist/dnd/types.d.ts +16 -16
  41. package/dist/form/createFormValidationState.d.ts +3 -3
  42. package/dist/form/index.d.ts +1 -1
  43. package/dist/grid/createGridState.d.ts +2 -2
  44. package/dist/grid/index.d.ts +2 -2
  45. package/dist/grid/types.d.ts +13 -11
  46. package/dist/index.d.ts +31 -30
  47. package/dist/index.js +7924 -7238
  48. package/dist/index.js.map +1 -1
  49. package/dist/menu/index.d.ts +2 -2
  50. package/dist/numberfield/createNumberFieldState.d.ts +2 -2
  51. package/dist/numberfield/index.d.ts +1 -1
  52. package/dist/overlays/createOverlayTriggerState.d.ts +2 -2
  53. package/dist/overlays/index.d.ts +1 -1
  54. package/dist/radio/createRadioGroupState.d.ts +7 -7
  55. package/dist/radio/index.d.ts +1 -1
  56. package/dist/searchfield/createSearchFieldState.d.ts +2 -2
  57. package/dist/searchfield/index.d.ts +2 -2
  58. package/dist/select/createSelectState.d.ts +8 -8
  59. package/dist/select/index.d.ts +1 -1
  60. package/dist/selection/index.d.ts +5 -5
  61. package/dist/slider/createSliderState.d.ts +3 -3
  62. package/dist/slider/index.d.ts +2 -2
  63. package/dist/steplist/createStepListState.d.ts +48 -0
  64. package/dist/steplist/index.d.ts +1 -0
  65. package/dist/table/TableCollection.d.ts +3 -3
  66. package/dist/table/createTableColumnResizeState.d.ts +54 -0
  67. package/dist/table/createTableState.d.ts +2 -2
  68. package/dist/table/index.d.ts +5 -3
  69. package/dist/table/types.d.ts +10 -10
  70. package/dist/tabs/createTabListState.d.ts +5 -5
  71. package/dist/tabs/index.d.ts +1 -1
  72. package/dist/textfield/createTextFieldState.d.ts +2 -2
  73. package/dist/textfield/index.d.ts +1 -1
  74. package/dist/toast/createToastState.d.ts +8 -2
  75. package/dist/toast/index.d.ts +1 -1
  76. package/dist/toggle/createToggleGroupState.d.ts +4 -4
  77. package/dist/toggle/createToggleState.d.ts +2 -2
  78. package/dist/toggle/index.d.ts +2 -2
  79. package/dist/tooltip/createTooltipTriggerState.d.ts +2 -2
  80. package/dist/tooltip/index.d.ts +1 -1
  81. package/dist/tree/TreeCollection.d.ts +2 -2
  82. package/dist/tree/createTreeState.d.ts +2 -2
  83. package/dist/tree/index.d.ts +3 -3
  84. package/dist/tree/types.d.ts +19 -13
  85. package/dist/utils/index.d.ts +1 -1
  86. package/dist/utils/reactivity.d.ts +1 -1
  87. package/package.json +29 -30
  88. package/src/autocomplete/createAutocompleteState.d.ts +19 -17
  89. package/src/autocomplete/createAutocompleteState.ts +24 -30
  90. package/src/autocomplete/index.d.ts +6 -2
  91. package/src/autocomplete/index.ts +1 -1
  92. package/src/calendar/createCalendarState.d.ts +139 -117
  93. package/src/calendar/createCalendarState.ts +221 -74
  94. package/src/calendar/createDateFieldState.d.ts +130 -95
  95. package/src/calendar/createDateFieldState.ts +263 -151
  96. package/src/calendar/createDatePickerState.ts +347 -0
  97. package/src/calendar/createRangeCalendarState.d.ts +154 -129
  98. package/src/calendar/createRangeCalendarState.ts +293 -79
  99. package/src/calendar/createTimeFieldState.d.ts +81 -79
  100. package/src/calendar/createTimeFieldState.ts +187 -108
  101. package/src/calendar/index.d.ts +80 -7
  102. package/src/calendar/index.ts +21 -12
  103. package/src/checkbox/createCheckboxGroupState.d.ts +57 -55
  104. package/src/checkbox/createCheckboxGroupState.ts +20 -29
  105. package/src/checkbox/index.d.ts +6 -2
  106. package/src/checkbox/index.ts +1 -1
  107. package/src/collections/ListCollection.d.ts +25 -22
  108. package/src/collections/ListCollection.ts +6 -6
  109. package/src/collections/createListState.d.ts +73 -58
  110. package/src/collections/createListState.ts +19 -18
  111. package/src/collections/createMenuState.d.ts +36 -31
  112. package/src/collections/createMenuState.ts +18 -12
  113. package/src/collections/createSelectionState.d.ts +78 -65
  114. package/src/collections/createSelectionState.ts +36 -32
  115. package/src/collections/index.d.ts +38 -6
  116. package/src/collections/index.ts +5 -10
  117. package/src/collections/types.d.ts +101 -101
  118. package/src/collections/types.ts +12 -12
  119. package/src/color/Color.d.ts +20 -5
  120. package/src/color/Color.ts +357 -254
  121. package/src/color/createColorAreaState.d.ts +67 -65
  122. package/src/color/createColorAreaState.ts +21 -13
  123. package/src/color/createColorFieldState.d.ts +46 -44
  124. package/src/color/createColorFieldState.ts +285 -149
  125. package/src/color/createColorSliderState.d.ts +58 -56
  126. package/src/color/createColorSliderState.ts +45 -14
  127. package/src/color/createColorWheelState.d.ts +42 -40
  128. package/src/color/createColorWheelState.ts +101 -64
  129. package/src/color/getColorChannels.ts +7 -5
  130. package/src/color/index.d.ts +36 -7
  131. package/src/color/index.ts +6 -9
  132. package/src/color/types.d.ts +68 -63
  133. package/src/color/types.ts +11 -19
  134. package/src/combobox/createComboBoxState.d.ts +107 -105
  135. package/src/combobox/createComboBoxState.ts +176 -89
  136. package/src/combobox/index.d.ts +10 -2
  137. package/src/combobox/index.ts +1 -1
  138. package/src/data/createAsyncList.ts +89 -63
  139. package/src/data/createListData.ts +67 -67
  140. package/src/data/createTreeData.ts +304 -91
  141. package/src/data/index.ts +3 -3
  142. package/src/datepicker/index.ts +6 -10
  143. package/src/disclosure/createDisclosureState.d.ts +47 -43
  144. package/src/disclosure/createDisclosureState.ts +7 -21
  145. package/src/disclosure/index.d.ts +10 -2
  146. package/src/disclosure/index.ts +1 -1
  147. package/src/dnd/createDragState.d.ts +51 -42
  148. package/src/dnd/createDragState.ts +12 -14
  149. package/src/dnd/createDraggableCollectionState.d.ts +52 -41
  150. package/src/dnd/createDraggableCollectionState.ts +14 -21
  151. package/src/dnd/createDropState.d.ts +64 -45
  152. package/src/dnd/createDropState.ts +22 -32
  153. package/src/dnd/createDroppableCollectionState.d.ts +88 -59
  154. package/src/dnd/createDroppableCollectionState.ts +40 -43
  155. package/src/dnd/index.d.ts +54 -6
  156. package/src/dnd/index.ts +5 -18
  157. package/src/dnd/types.d.ts +167 -156
  158. package/src/dnd/types.ts +20 -21
  159. package/src/form/createFormValidationState.d.ts +47 -45
  160. package/src/form/createFormValidationState.ts +30 -63
  161. package/src/form/index.d.ts +16 -2
  162. package/src/form/index.ts +1 -1
  163. package/src/grid/createGridState.d.ts +7 -4
  164. package/src/grid/createGridState.ts +44 -51
  165. package/src/grid/index.d.ts +3 -3
  166. package/src/grid/index.ts +2 -8
  167. package/src/grid/types.d.ts +136 -129
  168. package/src/grid/types.ts +20 -18
  169. package/src/index.d.ts +310 -26
  170. package/src/index.ts +48 -89
  171. package/src/menu/index.ts +2 -4
  172. package/src/numberfield/createNumberFieldState.d.ts +56 -54
  173. package/src/numberfield/createNumberFieldState.ts +26 -31
  174. package/src/numberfield/index.d.ts +6 -2
  175. package/src/numberfield/index.ts +1 -1
  176. package/src/overlays/createOverlayTriggerState.d.ts +22 -20
  177. package/src/overlays/createOverlayTriggerState.ts +3 -4
  178. package/src/overlays/index.d.ts +6 -2
  179. package/src/overlays/index.ts +1 -1
  180. package/src/radio/createRadioGroupState.d.ts +54 -52
  181. package/src/radio/createRadioGroupState.ts +27 -29
  182. package/src/radio/index.d.ts +7 -2
  183. package/src/radio/index.ts +1 -1
  184. package/src/searchfield/createSearchFieldState.d.ts +16 -14
  185. package/src/searchfield/createSearchFieldState.ts +5 -11
  186. package/src/searchfield/index.d.ts +3 -3
  187. package/src/searchfield/index.ts +2 -5
  188. package/src/select/createSelectState.d.ts +63 -61
  189. package/src/select/createSelectState.ts +27 -27
  190. package/src/select/index.d.ts +2 -2
  191. package/src/select/index.ts +1 -5
  192. package/src/selection/index.ts +6 -7
  193. package/src/slider/createSliderState.d.ts +60 -60
  194. package/src/slider/createSliderState.ts +55 -33
  195. package/src/slider/index.d.ts +3 -3
  196. package/src/slider/index.ts +2 -6
  197. package/src/ssr/index.d.ts +1 -1
  198. package/src/ssr/index.ts +2 -2
  199. package/src/steplist/createStepListState.ts +191 -0
  200. package/src/steplist/index.ts +5 -0
  201. package/src/table/TableCollection.d.ts +42 -40
  202. package/src/table/TableCollection.ts +61 -64
  203. package/src/table/createTableColumnResizeState.ts +242 -0
  204. package/src/table/createTableState.d.ts +7 -4
  205. package/src/table/createTableState.ts +10 -7
  206. package/src/table/index.d.ts +14 -4
  207. package/src/table/index.ts +10 -3
  208. package/src/table/types.d.ts +98 -92
  209. package/src/table/types.ts +17 -13
  210. package/src/tabs/createTabListState.d.ts +59 -57
  211. package/src/tabs/createTabListState.ts +24 -31
  212. package/src/tabs/index.d.ts +8 -2
  213. package/src/tabs/index.ts +1 -1
  214. package/src/textfield/createTextFieldState.d.ts +16 -14
  215. package/src/textfield/createTextFieldState.ts +7 -18
  216. package/src/textfield/index.d.ts +6 -2
  217. package/src/textfield/index.ts +1 -1
  218. package/src/toast/createToastState.d.ts +92 -86
  219. package/src/toast/createToastState.ts +48 -43
  220. package/src/toast/index.d.ts +12 -2
  221. package/src/toast/index.ts +1 -1
  222. package/src/toggle/createToggleGroupState.ts +11 -21
  223. package/src/toggle/createToggleState.d.ts +19 -19
  224. package/src/toggle/createToggleState.ts +2 -16
  225. package/src/toggle/index.d.ts +2 -2
  226. package/src/toggle/index.ts +2 -6
  227. package/src/tooltip/createTooltipTriggerState.d.ts +17 -17
  228. package/src/tooltip/createTooltipTriggerState.ts +12 -11
  229. package/src/tooltip/index.d.ts +7 -2
  230. package/src/tooltip/index.ts +1 -1
  231. package/src/tree/TreeCollection.d.ts +26 -23
  232. package/src/tree/TreeCollection.ts +29 -22
  233. package/src/tree/createTreeState.d.ts +7 -4
  234. package/src/tree/createTreeState.ts +39 -41
  235. package/src/tree/index.d.ts +10 -4
  236. package/src/tree/index.ts +3 -3
  237. package/src/tree/types.d.ts +131 -126
  238. package/src/tree/types.ts +22 -13
  239. package/src/utils/index.d.ts +2 -2
  240. package/src/utils/index.ts +1 -1
  241. package/src/utils/reactivity.d.ts +2 -2
  242. package/src/utils/reactivity.ts +3 -3
@@ -2,66 +2,68 @@
2
2
  * ColorSlider state management.
3
3
  * Based on @react-stately/color useColorSliderState.
4
4
  */
5
- import { type Accessor } from 'solid-js';
6
- import type { Color, ColorChannel } from './types';
5
+ import { type Accessor } from "solid-js";
6
+ import type { Color, ColorChannel } from "./types";
7
7
  export interface ColorSliderStateOptions {
8
- /** The current color value (controlled). */
9
- value?: Color | string;
10
- /** The default color value (uncontrolled). */
11
- defaultValue?: Color | string;
12
- /** Handler called when the color changes. */
13
- onChange?: (color: Color) => void;
14
- /** Handler called when dragging ends. */
15
- onChangeEnd?: (color: Color) => void;
16
- /** The color channel this slider controls. */
17
- channel: ColorChannel;
18
- /** Whether the slider is disabled. */
19
- isDisabled?: boolean;
20
- /** The locale for formatting. */
21
- locale?: string;
8
+ /** The current color value (controlled). */
9
+ value?: Color | string;
10
+ /** The default color value (uncontrolled). */
11
+ defaultValue?: Color | string;
12
+ /** Handler called when the color changes. */
13
+ onChange?: (color: Color) => void;
14
+ /** Handler called when dragging ends. */
15
+ onChangeEnd?: (color: Color) => void;
16
+ /** The color channel this slider controls. */
17
+ channel: ColorChannel;
18
+ /** Whether the slider is disabled. */
19
+ isDisabled?: boolean;
20
+ /** The locale for formatting. */
21
+ locale?: string;
22
22
  }
23
23
  export interface ColorSliderState {
24
- /** The current color value. */
25
- readonly value: Color;
26
- /** Whether the slider is being dragged. */
27
- readonly isDragging: boolean;
28
- /** The color channel being controlled. */
29
- readonly channel: ColorChannel;
30
- /** The step value for the channel. */
31
- readonly step: number;
32
- /** The page step value for the channel. */
33
- readonly pageSize: number;
34
- /** The minimum value for the channel. */
35
- readonly minValue: number;
36
- /** The maximum value for the channel. */
37
- readonly maxValue: number;
38
- /** Whether the slider is disabled. */
39
- readonly isDisabled: boolean;
40
- /** Get the current channel value. */
41
- getThumbValue(): number;
42
- /** Get the minimum percent. */
43
- getThumbMinValue(): number;
44
- /** Get the maximum percent. */
45
- getThumbMaxValue(): number;
46
- /** Get the thumb value as a percentage. */
47
- getThumbPercent(): number;
48
- /** Set the channel value. */
49
- setThumbValue(value: number): void;
50
- /** Set the thumb value from a percentage (0-1). */
51
- setThumbPercent(percent: number): void;
52
- /** Increment the channel value. */
53
- incrementThumb(stepSize?: number): void;
54
- /** Decrement the channel value. */
55
- decrementThumb(stepSize?: number): void;
56
- /** Set the dragging state. */
57
- setDragging(isDragging: boolean): void;
58
- /** Get the display color (with alpha = 1). */
59
- getDisplayColor(): Color;
60
- /** Get the formatted value label. */
61
- getThumbValueLabel(): string;
24
+ /** The current color value. */
25
+ readonly value: Color;
26
+ /** Whether the slider is being dragged. */
27
+ readonly isDragging: boolean;
28
+ /** The color channel being controlled. */
29
+ readonly channel: ColorChannel;
30
+ /** The step value for the channel. */
31
+ readonly step: number;
32
+ /** The page step value for the channel. */
33
+ readonly pageSize: number;
34
+ /** The minimum value for the channel. */
35
+ readonly minValue: number;
36
+ /** The maximum value for the channel. */
37
+ readonly maxValue: number;
38
+ /** Whether the slider is disabled. */
39
+ readonly isDisabled: boolean;
40
+ /** Get the current channel value. */
41
+ getThumbValue(): number;
42
+ /** Get the minimum percent. */
43
+ getThumbMinValue(): number;
44
+ /** Get the maximum percent. */
45
+ getThumbMaxValue(): number;
46
+ /** Get the thumb value as a percentage. */
47
+ getThumbPercent(): number;
48
+ /** Set the channel value. */
49
+ setThumbValue(value: number): void;
50
+ /** Set the thumb value from a percentage (0-1). */
51
+ setThumbPercent(percent: number): void;
52
+ /** Increment the channel value. */
53
+ incrementThumb(stepSize?: number): void;
54
+ /** Decrement the channel value. */
55
+ decrementThumb(stepSize?: number): void;
56
+ /** Set the dragging state. */
57
+ setDragging(isDragging: boolean): void;
58
+ /** Get the display color (with alpha = 1). */
59
+ getDisplayColor(): Color;
60
+ /** Get the formatted value label. */
61
+ getThumbValueLabel(): string;
62
62
  }
63
63
  /**
64
64
  * Creates state for a color slider.
65
65
  */
66
- export declare function createColorSliderState(options: Accessor<ColorSliderStateOptions>): ColorSliderState;
67
- //# sourceMappingURL=createColorSliderState.d.ts.map
66
+ export declare function createColorSliderState(
67
+ options: Accessor<ColorSliderStateOptions>,
68
+ ): ColorSliderState;
69
+ //# sourceMappingURL=createColorSliderState.d.ts.map
@@ -3,9 +3,11 @@
3
3
  * Based on @react-stately/color useColorSliderState.
4
4
  */
5
5
 
6
- import { createSignal, createMemo, type Accessor } from 'solid-js';
7
- import type { Color, ColorChannel } from './types';
8
- import { normalizeColor } from './Color';
6
+ import { createSignal, createMemo, type Accessor } from "solid-js";
7
+ import type { Color, ColorChannel, ColorSpace } from "./types";
8
+ import { normalizeColor } from "./Color";
9
+
10
+ export type ColorSliderOrientation = "horizontal" | "vertical";
9
11
 
10
12
  export interface ColorSliderStateOptions {
11
13
  /** The current color value (controlled). */
@@ -18,6 +20,10 @@ export interface ColorSliderStateOptions {
18
20
  onChangeEnd?: (color: Color) => void;
19
21
  /** The color channel this slider controls. */
20
22
  channel: ColorChannel;
23
+ /** The color space to use for channel values. */
24
+ colorSpace?: ColorSpace;
25
+ /** The slider orientation. */
26
+ orientation?: ColorSliderOrientation;
21
27
  /** Whether the slider is disabled. */
22
28
  isDisabled?: boolean;
23
29
  /** The locale for formatting. */
@@ -31,6 +37,8 @@ export interface ColorSliderState {
31
37
  readonly isDragging: boolean;
32
38
  /** The color channel being controlled. */
33
39
  readonly channel: ColorChannel;
40
+ /** The slider orientation. */
41
+ readonly orientation: ColorSliderOrientation;
34
42
  /** The step value for the channel. */
35
43
  readonly step: number;
36
44
  /** The page step value for the channel. */
@@ -70,10 +78,16 @@ export interface ColorSliderState {
70
78
  * Creates state for a color slider.
71
79
  */
72
80
  export function createColorSliderState(
73
- options: Accessor<ColorSliderStateOptions>
81
+ options: Accessor<ColorSliderStateOptions>,
74
82
  ): ColorSliderState {
75
83
  const getOptions = () => options();
76
84
 
85
+ const normalizeValue = (value: Color | string) => {
86
+ const color = normalizeColor(value);
87
+ const colorSpace = getOptions().colorSpace;
88
+ return colorSpace ? color.toFormat(colorSpace) : color;
89
+ };
90
+
77
91
  // Internal value state
78
92
  const [internalValue, setInternalValue] = createSignal<Color | null>(null);
79
93
  const [isDragging, setIsDragging] = createSignal(false);
@@ -82,7 +96,7 @@ export function createColorSliderState(
82
96
  const initValue = () => {
83
97
  const opts = getOptions();
84
98
  if (opts.defaultValue) {
85
- return normalizeColor(opts.defaultValue);
99
+ return normalizeValue(opts.defaultValue);
86
100
  }
87
101
  return null;
88
102
  };
@@ -99,14 +113,18 @@ export function createColorSliderState(
99
113
  const value = createMemo(() => {
100
114
  const opts = getOptions();
101
115
  if (opts.value !== undefined) {
102
- return normalizeColor(opts.value);
116
+ return normalizeValue(opts.value);
103
117
  }
104
- return internalValue() ?? normalizeColor('#ff0000');
118
+ const fallback = internalValue() ?? normalizeValue("#ff0000");
119
+ return opts.colorSpace ? fallback.toFormat(opts.colorSpace) : fallback;
105
120
  });
106
121
 
107
122
  const channel = createMemo(() => getOptions().channel);
123
+ const orientation = createMemo<ColorSliderOrientation>(
124
+ () => getOptions().orientation ?? "horizontal",
125
+ );
108
126
  const isDisabled = createMemo(() => getOptions().isDisabled ?? false);
109
- const locale = createMemo(() => getOptions().locale ?? 'en-US');
127
+ const locale = createMemo(() => getOptions().locale ?? "en-US");
110
128
 
111
129
  // Get channel range
112
130
  const channelRange = createMemo(() => value().getChannelRange(channel()));
@@ -119,16 +137,17 @@ export function createColorSliderState(
119
137
  // Update value
120
138
  const updateValue = (newColor: Color) => {
121
139
  const opts = getOptions();
140
+ const nextColor = opts.colorSpace ? newColor.toFormat(opts.colorSpace) : newColor;
122
141
 
123
142
  // Controlled mode
124
143
  if (opts.value !== undefined) {
125
- opts.onChange?.(newColor);
144
+ opts.onChange?.(nextColor);
126
145
  return;
127
146
  }
128
147
 
129
148
  // Uncontrolled mode
130
- setInternalValue(newColor);
131
- opts.onChange?.(newColor);
149
+ setInternalValue(nextColor);
150
+ opts.onChange?.(nextColor);
132
151
  };
133
152
 
134
153
  // Get thumb value
@@ -150,8 +169,14 @@ export function createColorSliderState(
150
169
 
151
170
  // Set thumb value
152
171
  const setThumbValue = (newValue: number) => {
153
- const clamped = Math.max(minValue(), Math.min(maxValue(), newValue));
154
- const rounded = Math.round(clamped / step()) * step();
172
+ const min = minValue();
173
+ const max = maxValue();
174
+ const stepValue = step();
175
+ const clamped = Math.max(min, Math.min(max, newValue));
176
+ const precision = `${stepValue}`.split(".")[1]?.length ?? 0;
177
+ const rounded = Number(
178
+ (Math.round((clamped - min) / stepValue) * stepValue + min).toFixed(precision),
179
+ );
155
180
  const newColor = value().withChannelValue(channel(), rounded);
156
181
  updateValue(newColor);
157
182
  };
@@ -190,7 +215,10 @@ export function createColorSliderState(
190
215
  // Get display color (alpha = 1)
191
216
  const getDisplayColor = () => {
192
217
  const v = value();
193
- return v.withChannelValue('alpha', 1);
218
+ if (channel() === "hue") {
219
+ return normalizeColor(`hsl(${v.getChannelValue("hue")}, 100%, 50%)`);
220
+ }
221
+ return v.withChannelValue("alpha", 1);
194
222
  };
195
223
 
196
224
  // Get formatted value label
@@ -211,6 +239,9 @@ export function createColorSliderState(
211
239
  get channel() {
212
240
  return channel();
213
241
  },
242
+ get orientation() {
243
+ return orientation();
244
+ },
214
245
  get step() {
215
246
  return step();
216
247
  },
@@ -2,50 +2,52 @@
2
2
  * ColorWheel state management.
3
3
  * Based on @react-stately/color useColorWheelState.
4
4
  */
5
- import { type Accessor } from 'solid-js';
6
- import type { Color } from './types';
5
+ import { type Accessor } from "solid-js";
6
+ import type { Color } from "./types";
7
7
  export interface ColorWheelStateOptions {
8
- /** The current color value (controlled). */
9
- value?: Color | string;
10
- /** The default color value (uncontrolled). */
11
- defaultValue?: Color | string;
12
- /** Handler called when the color changes. */
13
- onChange?: (color: Color) => void;
14
- /** Handler called when dragging ends. */
15
- onChangeEnd?: (color: Color) => void;
16
- /** Whether the wheel is disabled. */
17
- isDisabled?: boolean;
8
+ /** The current color value (controlled). */
9
+ value?: Color | string;
10
+ /** The default color value (uncontrolled). */
11
+ defaultValue?: Color | string;
12
+ /** Handler called when the color changes. */
13
+ onChange?: (color: Color) => void;
14
+ /** Handler called when dragging ends. */
15
+ onChangeEnd?: (color: Color) => void;
16
+ /** Whether the wheel is disabled. */
17
+ isDisabled?: boolean;
18
18
  }
19
19
  export interface ColorWheelState {
20
- /** The current color value. */
21
- readonly value: Color;
22
- /** Whether the wheel is being dragged. */
23
- readonly isDragging: boolean;
24
- /** Whether the wheel is disabled. */
25
- readonly isDisabled: boolean;
26
- /** Step value for hue changes. */
27
- readonly step: number;
28
- /** Page step value for hue changes. */
29
- readonly pageStep: number;
30
- /** Get the current hue value (0-360). */
31
- getHue(): number;
32
- /** Set the hue value. */
33
- setHue(value: number): void;
34
- /** Set hue from an angle in radians. */
35
- setHueFromAngle(angle: number): void;
36
- /** Get the thumb angle in radians (0 = right, increases counterclockwise). */
37
- getThumbAngle(): number;
38
- /** Increment hue value. */
39
- increment(stepSize?: number): void;
40
- /** Decrement hue value. */
41
- decrement(stepSize?: number): void;
42
- /** Set the dragging state. */
43
- setDragging(isDragging: boolean): void;
44
- /** Get the display color (with full saturation/brightness for wheel). */
45
- getDisplayColor(): Color;
20
+ /** The current color value. */
21
+ readonly value: Color;
22
+ /** Whether the wheel is being dragged. */
23
+ readonly isDragging: boolean;
24
+ /** Whether the wheel is disabled. */
25
+ readonly isDisabled: boolean;
26
+ /** Step value for hue changes. */
27
+ readonly step: number;
28
+ /** Page step value for hue changes. */
29
+ readonly pageStep: number;
30
+ /** Get the current hue value (0-360). */
31
+ getHue(): number;
32
+ /** Set the hue value. */
33
+ setHue(value: number): void;
34
+ /** Set hue from an angle in radians. */
35
+ setHueFromAngle(angle: number): void;
36
+ /** Get the thumb angle in radians (0 = right, increases counterclockwise). */
37
+ getThumbAngle(): number;
38
+ /** Increment hue value. */
39
+ increment(stepSize?: number): void;
40
+ /** Decrement hue value. */
41
+ decrement(stepSize?: number): void;
42
+ /** Set the dragging state. */
43
+ setDragging(isDragging: boolean): void;
44
+ /** Get the display color (with full saturation/brightness for wheel). */
45
+ getDisplayColor(): Color;
46
46
  }
47
47
  /**
48
48
  * Creates state for a color wheel (circular hue picker).
49
49
  */
50
- export declare function createColorWheelState(options: Accessor<ColorWheelStateOptions>): ColorWheelState;
51
- //# sourceMappingURL=createColorWheelState.d.ts.map
50
+ export declare function createColorWheelState(
51
+ options: Accessor<ColorWheelStateOptions>,
52
+ ): ColorWheelState;
53
+ //# sourceMappingURL=createColorWheelState.d.ts.map
@@ -3,9 +3,9 @@
3
3
  * Based on @react-stately/color useColorWheelState.
4
4
  */
5
5
 
6
- import { createSignal, createMemo, type Accessor } from 'solid-js';
7
- import type { Color, ColorChannel } from './types';
8
- import { normalizeColor } from './Color';
6
+ import { createSignal, createMemo, type Accessor } from "solid-js";
7
+ import type { Color } from "./types";
8
+ import { createHSLColor, normalizeColor } from "./Color";
9
9
 
10
10
  export interface ColorWheelStateOptions {
11
11
  /** The current color value (controlled). */
@@ -23,6 +23,8 @@ export interface ColorWheelStateOptions {
23
23
  export interface ColorWheelState {
24
24
  /** The current color value. */
25
25
  readonly value: Color;
26
+ /** The initial color value. */
27
+ readonly defaultValue: Color;
26
28
  /** Whether the wheel is being dragged. */
27
29
  readonly isDragging: boolean;
28
30
  /** Whether the wheel is disabled. */
@@ -34,12 +36,18 @@ export interface ColorWheelState {
34
36
 
35
37
  /** Get the current hue value (0-360). */
36
38
  getHue(): number;
39
+ /** Set the full color value. */
40
+ setValue(value: Color | string): void;
37
41
  /** Set the hue value. */
38
42
  setHue(value: number): void;
39
43
  /** Set hue from an angle in radians. */
40
44
  setHueFromAngle(angle: number): void;
45
+ /** Set hue from a point relative to the wheel center. */
46
+ setHueFromPoint(x: number, y: number, radius: number): void;
41
47
  /** Get the thumb angle in radians (0 = right, increases counterclockwise). */
42
48
  getThumbAngle(): number;
49
+ /** Get the thumb position relative to the wheel center. */
50
+ getThumbPosition(radius: number): { x: number; y: number };
43
51
  /** Increment hue value. */
44
52
  increment(stepSize?: number): void;
45
53
  /** Decrement hue value. */
@@ -53,113 +61,137 @@ export interface ColorWheelState {
53
61
  /**
54
62
  * Creates state for a color wheel (circular hue picker).
55
63
  */
56
- export function createColorWheelState(
57
- options: Accessor<ColorWheelStateOptions>
58
- ): ColorWheelState {
64
+ export function createColorWheelState(options: Accessor<ColorWheelStateOptions>): ColorWheelState {
59
65
  const getOptions = () => options();
66
+ const defaultColor = createHSLColor(0, 100, 50);
60
67
 
61
- // Internal value state
62
- const [internalValue, setInternalValue] = createSignal<Color | null>(null);
63
- const [isDragging, setIsDragging] = createSignal(false);
64
-
65
- // Initialize internal value
66
- const initValue = () => {
67
- const opts = getOptions();
68
- if (opts.defaultValue) {
69
- return normalizeColor(opts.defaultValue);
70
- }
71
- return null;
68
+ const normalizeWheelValue = (color: Color | string) => {
69
+ const value = normalizeColor(color);
70
+ return value.toFormat(value.getColorSpace() === "hsb" ? "hsb" : "hsl");
72
71
  };
73
72
 
74
- // Set initial value
75
- if (internalValue() === null) {
76
- const init = initValue();
77
- if (init) {
78
- setInternalValue(init);
79
- }
80
- }
73
+ const initialValue = normalizeWheelValue(getOptions().defaultValue ?? defaultColor);
74
+ const [internalValue, setInternalValue] = createSignal<Color>(initialValue);
75
+ const [isDragging, setIsDragging] = createSignal(false);
76
+ let valueRef = initialValue;
81
77
 
82
78
  // Controlled vs uncontrolled value
83
79
  const value = createMemo(() => {
84
80
  const opts = getOptions();
85
- if (opts.value !== undefined) {
86
- return normalizeColor(opts.value);
87
- }
88
- return internalValue() ?? normalizeColor('#ff0000');
81
+ const nextValue = opts.value !== undefined ? normalizeWheelValue(opts.value) : internalValue();
82
+ valueRef = nextValue;
83
+ return nextValue;
89
84
  });
90
85
 
91
86
  const isDisabled = createMemo(() => getOptions().isDisabled ?? false);
92
87
 
93
88
  // Hue step and page step
94
- const hueRange = createMemo(() => value().getChannelRange('hue'));
89
+ const hueRange = createMemo(() => value().getChannelRange("hue"));
95
90
  const step = createMemo(() => hueRange().step);
96
91
  const pageStep = createMemo(() => hueRange().pageSize);
97
92
 
98
93
  // Update value
99
94
  const updateValue = (newColor: Color) => {
100
95
  const opts = getOptions();
96
+ const nextColor = normalizeWheelValue(newColor);
97
+ valueRef = nextColor;
101
98
 
102
99
  // Controlled mode
103
100
  if (opts.value !== undefined) {
104
- opts.onChange?.(newColor);
101
+ opts.onChange?.(nextColor);
105
102
  return;
106
103
  }
107
104
 
108
105
  // Uncontrolled mode
109
- setInternalValue(newColor);
110
- opts.onChange?.(newColor);
106
+ setInternalValue(nextColor);
107
+ opts.onChange?.(nextColor);
111
108
  };
112
109
 
113
110
  // Get hue value (0-360)
114
- const getHue = () => value().getChannelValue('hue');
111
+ const getHue = () => value().getChannelValue("hue");
112
+
113
+ const setValue = (newValue: Color | string) => {
114
+ updateValue(normalizeWheelValue(newValue));
115
+ };
116
+
117
+ const roundToStep = (num: number, stepValue: number) => {
118
+ const rounded = Math.round(num / stepValue) * stepValue;
119
+ const precision = `${stepValue}`.split(".")[1]?.length ?? 0;
120
+ return Number(rounded.toFixed(precision));
121
+ };
122
+
123
+ const roundDown = (num: number) => {
124
+ const rounded = Math.floor(num);
125
+ return rounded === num ? num - 1 : rounded;
126
+ };
127
+
128
+ const mod = (n: number, m: number) => ((n % m) + m) % m;
129
+
130
+ const radToDeg = (rad: number) => (rad * 180) / Math.PI;
131
+ const degToRad = (deg: number) => (deg * Math.PI) / 180;
132
+
133
+ const cartesianToAngle = (x: number, y: number, radius: number) => {
134
+ const clampedX = Math.max(-radius, Math.min(radius, x));
135
+ const clampedY = Math.max(-radius, Math.min(radius, y));
136
+ return mod(radToDeg(Math.atan2(clampedY, clampedX)), 360);
137
+ };
138
+
139
+ const angleToCartesian = (angle: number, radius: number) => ({
140
+ x: radius * Math.cos(degToRad(angle)),
141
+ y: radius * Math.sin(degToRad(angle)),
142
+ });
115
143
 
116
144
  // Set hue value
117
145
  const setHue = (newValue: number) => {
118
- // Wrap hue to 0-360 range
119
- let hue = newValue % 360;
120
- if (hue < 0) hue += 360;
121
-
122
- // Round to step
146
+ const currentHue = getHue();
123
147
  const range = hueRange();
124
- const rounded = Math.round(hue / range.step) * range.step;
148
+ const hue = newValue > range.maxValue ? range.minValue : newValue;
149
+ const rounded = roundToStep(mod(hue, range.maxValue), range.step);
150
+ if (rounded === currentHue) return;
125
151
 
126
- const newColor = value().withChannelValue('hue', rounded);
152
+ const newColor = value().withChannelValue("hue", rounded);
127
153
  updateValue(newColor);
128
154
  };
129
155
 
130
156
  // Set hue from angle (radians, 0 = right, counterclockwise)
131
157
  const setHueFromAngle = (angle: number) => {
132
- // Convert angle to degrees (0-360)
133
- // angle 0 = right (3 o'clock) = hue 0
134
- // angle increases counterclockwise
135
- let degrees = (angle * 180) / Math.PI;
136
- degrees = 360 - degrees; // Convert to clockwise
137
- if (degrees < 0) degrees += 360;
138
- if (degrees >= 360) degrees -= 360;
158
+ setHue(mod(360 - radToDeg(angle), 360));
159
+ };
139
160
 
140
- setHue(degrees);
161
+ const setHueFromPoint = (x: number, y: number, radius: number) => {
162
+ setHue(cartesianToAngle(x, y, radius));
141
163
  };
142
164
 
143
165
  // Get thumb angle in radians
144
166
  const getThumbAngle = () => {
145
- const hue = getHue();
146
- // Convert hue to angle (radians)
147
- // hue 0 = angle 0 (right)
148
- // hue increases clockwise, angle increases counterclockwise
149
- const degrees = 360 - hue;
150
- return (degrees * Math.PI) / 180;
167
+ return degToRad(360 - getHue());
168
+ };
169
+
170
+ const getThumbPosition = (radius: number) => {
171
+ return angleToCartesian(getHue(), radius);
151
172
  };
152
173
 
153
174
  // Increment hue
154
175
  const increment = (stepSize?: number) => {
155
- const s = stepSize ?? step();
156
- setHue(getHue() + s);
176
+ const range = hueRange();
177
+ const s = Math.max(stepSize ?? range.step, range.step);
178
+ const nextValue = getHue() + s;
179
+ if (nextValue >= range.maxValue) {
180
+ setHue(range.minValue);
181
+ return;
182
+ }
183
+ setHue(roundToStep(mod(nextValue, range.maxValue), s));
157
184
  };
158
185
 
159
186
  // Decrement hue
160
187
  const decrement = (stepSize?: number) => {
161
- const s = stepSize ?? step();
162
- setHue(getHue() - s);
188
+ const range = hueRange();
189
+ const s = Math.max(stepSize ?? range.step, range.step);
190
+ if (getHue() === range.minValue) {
191
+ setHue(roundDown(range.maxValue / s) * s);
192
+ return;
193
+ }
194
+ setHue(roundToStep(mod(getHue() - s, range.maxValue), s));
163
195
  };
164
196
 
165
197
  // Set dragging state
@@ -169,24 +201,26 @@ export function createColorWheelState(
169
201
 
170
202
  // Call onChangeEnd when dragging ends
171
203
  if (wasDragging && !dragging) {
172
- getOptions().onChangeEnd?.(value());
204
+ getOptions().onChangeEnd?.(valueRef);
173
205
  }
174
206
  };
175
207
 
176
208
  // Get display color (full saturation and brightness for wheel preview)
177
209
  const getDisplayColor = () => {
178
- // For display, we want the color at full saturation and brightness
179
- // to show the pure hue on the wheel
180
210
  return value()
181
- .withChannelValue('saturation', 100)
182
- .withChannelValue('brightness', 100)
183
- .withChannelValue('alpha', 1);
211
+ .toFormat("hsl")
212
+ .withChannelValue("saturation", 100)
213
+ .withChannelValue("lightness", 50)
214
+ .withChannelValue("alpha", 1);
184
215
  };
185
216
 
186
217
  return {
187
218
  get value() {
188
219
  return value();
189
220
  },
221
+ get defaultValue() {
222
+ return initialValue;
223
+ },
190
224
  get isDragging() {
191
225
  return isDragging();
192
226
  },
@@ -200,9 +234,12 @@ export function createColorWheelState(
200
234
  return pageStep();
201
235
  },
202
236
  getHue,
237
+ setValue,
203
238
  setHue,
204
239
  setHueFromAngle,
240
+ setHueFromPoint,
205
241
  getThumbAngle,
242
+ getThumbPosition,
206
243
  increment,
207
244
  decrement,
208
245
  setDragging: setDraggingState,
@@ -4,12 +4,12 @@
4
4
  * Returns the three channels for a given color space.
5
5
  */
6
6
 
7
- import type { ColorChannel, ColorSpace } from './types';
7
+ import type { ColorChannel, ColorSpace } from "./types";
8
8
 
9
9
  const COLOR_SPACE_CHANNELS: Record<ColorSpace, [ColorChannel, ColorChannel, ColorChannel]> = {
10
- rgb: ['red', 'green', 'blue'],
11
- hsl: ['hue', 'saturation', 'lightness'],
12
- hsb: ['hue', 'saturation', 'brightness'],
10
+ rgb: ["red", "green", "blue"],
11
+ hsl: ["hue", "saturation", "lightness"],
12
+ hsb: ["hue", "saturation", "brightness"],
13
13
  };
14
14
 
15
15
  /**
@@ -25,7 +25,9 @@ const COLOR_SPACE_CHANNELS: Record<ColorSpace, [ColorChannel, ColorChannel, Colo
25
25
  * getColorChannels('hsb') // ['hue', 'saturation', 'brightness']
26
26
  * ```
27
27
  */
28
- export function getColorChannels(colorSpace: ColorSpace): [ColorChannel, ColorChannel, ColorChannel] {
28
+ export function getColorChannels(
29
+ colorSpace: ColorSpace,
30
+ ): [ColorChannel, ColorChannel, ColorChannel] {
29
31
  const channels = COLOR_SPACE_CHANNELS[colorSpace];
30
32
  if (!channels) {
31
33
  throw new Error(`Unknown color space: ${colorSpace}`);