@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
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Raw multiple-selection + focus state for a collection.
|
|
3
|
+
*
|
|
4
|
+
* The lower of the two selection layers ported from upstream
|
|
5
|
+
* (`@react-stately/selection`'s `useMultipleSelectionState`): it owns the
|
|
6
|
+
* selected keys, focus, selection behavior, and disabled keys, but is NOT
|
|
7
|
+
* collection-aware. The collection-aware operations (toggle, extend, select
|
|
8
|
+
* all, range, etc.) live in {@link SelectionManager}, which is built on top of
|
|
9
|
+
* this state.
|
|
10
|
+
*
|
|
11
|
+
* Based on @react-stately/selection.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { createSignal, createMemo, createComputed, untrack, type Accessor } from "solid-js";
|
|
15
|
+
import { access, type MaybeAccessor } from "../utils";
|
|
16
|
+
import type { SelectionStateProps } from "../collections/createSelectionState";
|
|
17
|
+
import type {
|
|
18
|
+
DisabledBehavior,
|
|
19
|
+
FocusStrategy,
|
|
20
|
+
Key,
|
|
21
|
+
Selection,
|
|
22
|
+
SelectionBehavior,
|
|
23
|
+
SelectionMode,
|
|
24
|
+
} from "../collections/types";
|
|
25
|
+
import { Selection as SelectionClass } from "./Selection";
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* The raw state consumed by {@link SelectionManager}. Mirrors upstream's
|
|
29
|
+
* `MultipleSelectionState`: property reads (not Solid accessors) so the manager
|
|
30
|
+
* can read `state.selectionMode` etc. exactly as upstream does — the getters
|
|
31
|
+
* read the underlying signals, so reads inside reactive scopes still track.
|
|
32
|
+
*/
|
|
33
|
+
export interface MultipleSelectionState {
|
|
34
|
+
/** The type of selection that is allowed in the collection. */
|
|
35
|
+
readonly selectionMode: SelectionMode;
|
|
36
|
+
/** The selection behavior for the collection. */
|
|
37
|
+
readonly selectionBehavior: SelectionBehavior;
|
|
38
|
+
/** Sets the selection behavior for the collection. */
|
|
39
|
+
setSelectionBehavior(selectionBehavior: SelectionBehavior): void;
|
|
40
|
+
/** Whether the collection allows empty selection. */
|
|
41
|
+
readonly disallowEmptySelection: boolean;
|
|
42
|
+
/** Whether the collection is currently focused. */
|
|
43
|
+
readonly isFocused: boolean;
|
|
44
|
+
/** Sets whether the collection is focused. */
|
|
45
|
+
setFocused(isFocused: boolean): void;
|
|
46
|
+
/** The current focused key in the collection. */
|
|
47
|
+
readonly focusedKey: Key | null;
|
|
48
|
+
/** Whether the first or last child of the focused key should receive focus. */
|
|
49
|
+
readonly childFocusStrategy: FocusStrategy | null;
|
|
50
|
+
/** Sets the focused key, and optionally, whether the first or last child of that key should receive focus. */
|
|
51
|
+
setFocusedKey(key: Key | null, childFocusStrategy?: FocusStrategy): void;
|
|
52
|
+
/** The currently selected keys in the collection. */
|
|
53
|
+
readonly selectedKeys: Selection;
|
|
54
|
+
/** The last selection payload emitted through onSelectionChange. @internal */
|
|
55
|
+
readonly lastSelectionEvent: Selection | null;
|
|
56
|
+
/** Sets the selected keys in the collection. */
|
|
57
|
+
setSelectedKeys(keys: Selection): void;
|
|
58
|
+
/** Re-emits a selection payload without recomputing or mutating selection. @internal */
|
|
59
|
+
emitDuplicateSelectionEvent(keys?: Selection): void;
|
|
60
|
+
/** The currently disabled keys in the collection. */
|
|
61
|
+
readonly disabledKeys: Set<Key>;
|
|
62
|
+
/** Whether `disabledKeys` applies to all interactions, or only selection. */
|
|
63
|
+
readonly disabledBehavior: DisabledBehavior;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function equalSets(setA: Set<Key>, setB: Set<Key>): boolean {
|
|
67
|
+
if (setA.size !== setB.size) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
for (const item of setA) {
|
|
72
|
+
if (!setB.has(item)) {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function convertSelection(
|
|
81
|
+
selection: "all" | Iterable<Key> | null | undefined,
|
|
82
|
+
defaultValue: Selection,
|
|
83
|
+
): Selection;
|
|
84
|
+
function convertSelection(
|
|
85
|
+
selection: "all" | Iterable<Key> | null | undefined,
|
|
86
|
+
): Selection | undefined;
|
|
87
|
+
function convertSelection(
|
|
88
|
+
selection: "all" | Iterable<Key> | null | undefined,
|
|
89
|
+
defaultValue?: Selection,
|
|
90
|
+
): Selection | undefined {
|
|
91
|
+
if (!selection) {
|
|
92
|
+
return defaultValue;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return selection === "all" ? "all" : new SelectionClass(selection);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Manages raw state for multiple selection and focus in a collection.
|
|
100
|
+
*/
|
|
101
|
+
export function createMultipleSelectionState(
|
|
102
|
+
props: MaybeAccessor<SelectionStateProps> = {},
|
|
103
|
+
): MultipleSelectionState {
|
|
104
|
+
const getProps = () => access(props);
|
|
105
|
+
|
|
106
|
+
// Focus is a plain signal in Solid; upstream needs a ref + state pair only
|
|
107
|
+
// because React requires both a synchronous read and a re-render trigger.
|
|
108
|
+
const [isFocused, setIsFocused] = createSignal(false);
|
|
109
|
+
const [focusedKey, setFocusedKeySignal] = createSignal<Key | null>(null);
|
|
110
|
+
const [childFocusStrategy, setChildFocusStrategy] = createSignal<FocusStrategy | null>(null);
|
|
111
|
+
|
|
112
|
+
const defaultSelectedKeys = convertSelection(
|
|
113
|
+
getProps().defaultSelectedKeys,
|
|
114
|
+
new SelectionClass(),
|
|
115
|
+
);
|
|
116
|
+
const [uncontrolledSelectedKeys, setUncontrolledSelectedKeys] =
|
|
117
|
+
createSignal<Selection>(defaultSelectedKeys);
|
|
118
|
+
|
|
119
|
+
const selectedKeys = createMemo<Selection>(() => {
|
|
120
|
+
const p = getProps();
|
|
121
|
+
if (p.selectedKeys !== undefined) {
|
|
122
|
+
return convertSelection(p.selectedKeys, new SelectionClass());
|
|
123
|
+
}
|
|
124
|
+
return uncontrolledSelectedKeys();
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
// Selection behavior is seeded from the prop but kept in internal state so
|
|
128
|
+
// that `setSelectionBehavior` (e.g. the long-press-to-select touch flow) can
|
|
129
|
+
// override it. Two reactive rules mirror upstream's render-time logic.
|
|
130
|
+
const selectionBehaviorProp = (): SelectionBehavior => getProps().selectionBehavior ?? "toggle";
|
|
131
|
+
|
|
132
|
+
const [selectionBehavior, setSelectionBehaviorState] =
|
|
133
|
+
createSignal<SelectionBehavior>(selectionBehaviorProp());
|
|
134
|
+
|
|
135
|
+
// If the selectionBehavior prop is 'replace' but the current state is 'toggle'
|
|
136
|
+
// (e.g. due to a long press to enter selection mode on touch) and the
|
|
137
|
+
// selection becomes empty, reset the behavior back to 'replace'.
|
|
138
|
+
createComputed(() => {
|
|
139
|
+
const keys = selectedKeys();
|
|
140
|
+
if (
|
|
141
|
+
selectionBehaviorProp() === "replace" &&
|
|
142
|
+
untrack(selectionBehavior) === "toggle" &&
|
|
143
|
+
typeof keys === "object" &&
|
|
144
|
+
keys.size === 0
|
|
145
|
+
) {
|
|
146
|
+
setSelectionBehaviorState("replace");
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
// If the selectionBehavior prop changes, sync it into state.
|
|
151
|
+
let lastSelectionBehavior = selectionBehaviorProp();
|
|
152
|
+
createComputed(() => {
|
|
153
|
+
const prop = selectionBehaviorProp();
|
|
154
|
+
if (prop !== lastSelectionBehavior) {
|
|
155
|
+
setSelectionBehaviorState(prop);
|
|
156
|
+
lastSelectionBehavior = prop;
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
const disabledKeys = createMemo<Set<Key>>(() => {
|
|
161
|
+
const keys = getProps().disabledKeys;
|
|
162
|
+
return keys ? new Set<Key>(keys) : new Set<Key>();
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
let lastSelectionEvent: Selection | null = null;
|
|
166
|
+
|
|
167
|
+
const emitSelectionEvent = (keys: Selection) => {
|
|
168
|
+
lastSelectionEvent = keys;
|
|
169
|
+
getProps().onSelectionChange?.(keys);
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
const setSelectedKeys = (keys: Selection) => {
|
|
173
|
+
const p = getProps();
|
|
174
|
+
const current = selectedKeys();
|
|
175
|
+
const shouldUpdate =
|
|
176
|
+
p.allowDuplicateSelectionEvents ||
|
|
177
|
+
keys === "all" ||
|
|
178
|
+
current === "all" ||
|
|
179
|
+
!equalSets(keys, current);
|
|
180
|
+
|
|
181
|
+
if (!shouldUpdate) {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Uncontrolled: store internally. Controlled: only notify.
|
|
186
|
+
if (p.selectedKeys === undefined) {
|
|
187
|
+
setUncontrolledSelectedKeys(keys);
|
|
188
|
+
}
|
|
189
|
+
emitSelectionEvent(keys);
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
const emitDuplicateSelectionEvent = (keys?: Selection) => {
|
|
193
|
+
const eventKeys = keys ?? lastSelectionEvent;
|
|
194
|
+
if (eventKeys == null) {
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
emitSelectionEvent(eventKeys);
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
return {
|
|
201
|
+
get selectionMode() {
|
|
202
|
+
return getProps().selectionMode ?? "none";
|
|
203
|
+
},
|
|
204
|
+
get selectionBehavior() {
|
|
205
|
+
return selectionBehavior();
|
|
206
|
+
},
|
|
207
|
+
setSelectionBehavior(behavior: SelectionBehavior) {
|
|
208
|
+
setSelectionBehaviorState(behavior);
|
|
209
|
+
},
|
|
210
|
+
get disallowEmptySelection() {
|
|
211
|
+
return getProps().disallowEmptySelection ?? false;
|
|
212
|
+
},
|
|
213
|
+
get isFocused() {
|
|
214
|
+
return isFocused();
|
|
215
|
+
},
|
|
216
|
+
setFocused(f: boolean) {
|
|
217
|
+
setIsFocused(f);
|
|
218
|
+
},
|
|
219
|
+
get focusedKey() {
|
|
220
|
+
return focusedKey();
|
|
221
|
+
},
|
|
222
|
+
get childFocusStrategy() {
|
|
223
|
+
return childFocusStrategy();
|
|
224
|
+
},
|
|
225
|
+
setFocusedKey(key: Key | null, strategy: FocusStrategy = "first") {
|
|
226
|
+
setFocusedKeySignal(key);
|
|
227
|
+
setChildFocusStrategy(strategy);
|
|
228
|
+
},
|
|
229
|
+
get selectedKeys() {
|
|
230
|
+
return selectedKeys();
|
|
231
|
+
},
|
|
232
|
+
get lastSelectionEvent() {
|
|
233
|
+
return lastSelectionEvent;
|
|
234
|
+
},
|
|
235
|
+
setSelectedKeys,
|
|
236
|
+
emitDuplicateSelectionEvent,
|
|
237
|
+
get disabledKeys() {
|
|
238
|
+
return disabledKeys();
|
|
239
|
+
},
|
|
240
|
+
get disabledBehavior() {
|
|
241
|
+
return getProps().disabledBehavior ?? "all";
|
|
242
|
+
},
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// Re-export the accessor type for convenience where a reactive read is wanted.
|
|
247
|
+
export type { Accessor };
|
package/src/selection/index.ts
CHANGED
|
@@ -9,7 +9,13 @@ export {
|
|
|
9
9
|
createSelectionState,
|
|
10
10
|
type SelectionStateProps,
|
|
11
11
|
type SelectionState,
|
|
12
|
-
} from
|
|
12
|
+
} from "../collections/createSelectionState";
|
|
13
|
+
|
|
14
|
+
export {
|
|
15
|
+
SelectionManager,
|
|
16
|
+
type SelectionManagerOptions,
|
|
17
|
+
type LayoutDelegate,
|
|
18
|
+
} from "./SelectionManager";
|
|
13
19
|
|
|
14
20
|
export type {
|
|
15
21
|
Key,
|
|
@@ -18,11 +24,10 @@ export type {
|
|
|
18
24
|
SelectionBehavior,
|
|
19
25
|
DisabledBehavior,
|
|
20
26
|
FocusStrategy,
|
|
21
|
-
} from
|
|
27
|
+
} from "../collections/types";
|
|
22
28
|
|
|
23
|
-
export type MultipleSelectionStateProps =
|
|
24
|
-
|
|
29
|
+
export type MultipleSelectionStateProps =
|
|
30
|
+
import("../collections/createSelectionState").SelectionStateProps;
|
|
31
|
+
export type MultipleSelectionState = import("../collections/createSelectionState").SelectionState;
|
|
25
32
|
|
|
26
|
-
export {
|
|
27
|
-
createSelectionState as useMultipleSelectionState,
|
|
28
|
-
} from '../collections/createSelectionState';
|
|
33
|
+
export { createSelectionState as useMultipleSelectionState } from "../collections/createSelectionState";
|
|
@@ -2,71 +2,71 @@
|
|
|
2
2
|
* Creates state for a slider component.
|
|
3
3
|
* Based on @react-stately/slider useSliderState.
|
|
4
4
|
*/
|
|
5
|
-
import { type Accessor } from
|
|
6
|
-
import { type MaybeAccessor } from
|
|
7
|
-
export type SliderOrientation =
|
|
5
|
+
import { type Accessor } from "solid-js";
|
|
6
|
+
import { type MaybeAccessor } from "../utils";
|
|
7
|
+
export type SliderOrientation = "horizontal" | "vertical";
|
|
8
8
|
export interface SliderStateProps {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
9
|
+
/** The current value (controlled). */
|
|
10
|
+
value?: number;
|
|
11
|
+
/** The default value (uncontrolled). */
|
|
12
|
+
defaultValue?: number;
|
|
13
|
+
/** Handler called when the value changes. */
|
|
14
|
+
onChange?: (value: number) => void;
|
|
15
|
+
/** Handler called when the user stops dragging. */
|
|
16
|
+
onChangeEnd?: (value: number) => void;
|
|
17
|
+
/** The minimum value. */
|
|
18
|
+
minValue?: number;
|
|
19
|
+
/** The maximum value. */
|
|
20
|
+
maxValue?: number;
|
|
21
|
+
/** The step value. */
|
|
22
|
+
step?: number;
|
|
23
|
+
/** The orientation of the slider. */
|
|
24
|
+
orientation?: SliderOrientation;
|
|
25
|
+
/** Whether the slider is disabled. */
|
|
26
|
+
isDisabled?: boolean;
|
|
27
|
+
/** The locale for number formatting. */
|
|
28
|
+
locale?: string;
|
|
29
|
+
/** Number format options. */
|
|
30
|
+
formatOptions?: Intl.NumberFormatOptions;
|
|
31
31
|
}
|
|
32
32
|
export interface SliderState {
|
|
33
|
-
|
|
34
|
-
|
|
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
|
-
|
|
33
|
+
/** The current value. */
|
|
34
|
+
value: Accessor<number>;
|
|
35
|
+
/** Sets the value. */
|
|
36
|
+
setValue: (value: number) => void;
|
|
37
|
+
/** Sets the value by percent (0-1). */
|
|
38
|
+
setValuePercent: (percent: number) => void;
|
|
39
|
+
/** Gets the value as a percent (0-1). */
|
|
40
|
+
getValuePercent: Accessor<number>;
|
|
41
|
+
/** Gets the formatted value string. */
|
|
42
|
+
getFormattedValue: Accessor<string>;
|
|
43
|
+
/** Whether the thumb is being dragged. */
|
|
44
|
+
isDragging: Accessor<boolean>;
|
|
45
|
+
/** Sets the dragging state. */
|
|
46
|
+
setDragging: (dragging: boolean) => void;
|
|
47
|
+
/** Whether the slider is focused. */
|
|
48
|
+
isFocused: Accessor<boolean>;
|
|
49
|
+
/** Sets the focused state. */
|
|
50
|
+
setFocused: (focused: boolean) => void;
|
|
51
|
+
/** Increments the value by step. */
|
|
52
|
+
increment: (stepMultiplier?: number) => void;
|
|
53
|
+
/** Decrements the value by step. */
|
|
54
|
+
decrement: (stepMultiplier?: number) => void;
|
|
55
|
+
/** The minimum value. */
|
|
56
|
+
minValue: number;
|
|
57
|
+
/** The maximum value. */
|
|
58
|
+
maxValue: number;
|
|
59
|
+
/** The step value. */
|
|
60
|
+
step: number;
|
|
61
|
+
/** The page step (larger step for Page Up/Down). */
|
|
62
|
+
pageStep: number;
|
|
63
|
+
/** The orientation. */
|
|
64
|
+
orientation: SliderOrientation;
|
|
65
|
+
/** Whether the slider is disabled. */
|
|
66
|
+
isDisabled: boolean;
|
|
67
67
|
}
|
|
68
68
|
/**
|
|
69
69
|
* Provides state management for a slider component.
|
|
70
70
|
*/
|
|
71
71
|
export declare function createSliderState(props: MaybeAccessor<SliderStateProps>): SliderState;
|
|
72
|
-
//# sourceMappingURL=createSliderState.d.ts.map
|
|
72
|
+
//# sourceMappingURL=createSliderState.d.ts.map
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
* Based on @react-stately/slider useSliderState.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { type Accessor, createSignal, createMemo } from
|
|
7
|
-
import { access, type MaybeAccessor } from
|
|
6
|
+
import { type Accessor, createSignal, createMemo } from "solid-js";
|
|
7
|
+
import { access, type MaybeAccessor } from "../utils";
|
|
8
8
|
|
|
9
|
-
export type SliderOrientation =
|
|
9
|
+
export type SliderOrientation = "horizontal" | "vertical";
|
|
10
10
|
|
|
11
11
|
export interface SliderStateProps {
|
|
12
12
|
/** The current value (controlled). */
|
|
@@ -87,7 +87,7 @@ function clamp(value: number, min: number, max: number): number {
|
|
|
87
87
|
function snapToStep(value: number, min: number, max: number, step: number): number {
|
|
88
88
|
const snapped = Math.round((value - min) / step) * step + min;
|
|
89
89
|
// Handle floating point precision issues
|
|
90
|
-
const decimalPlaces = (step.toString().split(
|
|
90
|
+
const decimalPlaces = (step.toString().split(".")[1] || "").length;
|
|
91
91
|
const rounded = parseFloat(snapped.toFixed(decimalPlaces));
|
|
92
92
|
return clamp(rounded, min, max);
|
|
93
93
|
}
|
|
@@ -95,27 +95,37 @@ function snapToStep(value: number, min: number, max: number, step: number): numb
|
|
|
95
95
|
/**
|
|
96
96
|
* Provides state management for a slider component.
|
|
97
97
|
*/
|
|
98
|
-
export function createSliderState(
|
|
99
|
-
props: MaybeAccessor<SliderStateProps>
|
|
100
|
-
): SliderState {
|
|
98
|
+
export function createSliderState(props: MaybeAccessor<SliderStateProps>): SliderState {
|
|
101
99
|
const getProps = () => access(props);
|
|
102
100
|
|
|
103
|
-
|
|
104
|
-
const
|
|
105
|
-
const
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
const
|
|
101
|
+
const initialProps = getProps();
|
|
102
|
+
const initialMinValue = initialProps.minValue ?? DEFAULT_MIN;
|
|
103
|
+
const initialMaxValue = initialProps.maxValue ?? DEFAULT_MAX;
|
|
104
|
+
const initialStep = initialProps.step ?? DEFAULT_STEP;
|
|
105
|
+
|
|
106
|
+
const minValue = createMemo(() => getProps().minValue ?? DEFAULT_MIN);
|
|
107
|
+
const maxValue = createMemo(() => getProps().maxValue ?? DEFAULT_MAX);
|
|
108
|
+
const step = createMemo(() => getProps().step ?? DEFAULT_STEP);
|
|
109
|
+
const orientation = createMemo(() => getProps().orientation ?? "horizontal");
|
|
110
|
+
const isDisabled = createMemo(() => getProps().isDisabled ?? false);
|
|
111
|
+
const pageStep = createMemo(() =>
|
|
112
|
+
Math.max(
|
|
113
|
+
step(),
|
|
114
|
+
snapToStep((maxValue() - minValue()) / 10, 0, maxValue() - minValue(), step()),
|
|
115
|
+
),
|
|
116
|
+
);
|
|
112
117
|
|
|
113
118
|
// Controlled vs uncontrolled
|
|
114
119
|
const isControlled = () => getProps().value !== undefined;
|
|
115
120
|
|
|
116
121
|
// Internal signal for uncontrolled mode
|
|
117
122
|
const [internalValue, setInternalValue] = createSignal(
|
|
118
|
-
snapToStep(
|
|
123
|
+
snapToStep(
|
|
124
|
+
initialProps.defaultValue ?? initialMinValue,
|
|
125
|
+
initialMinValue,
|
|
126
|
+
initialMaxValue,
|
|
127
|
+
initialStep,
|
|
128
|
+
),
|
|
119
129
|
);
|
|
120
130
|
|
|
121
131
|
// Dragging and focus state
|
|
@@ -125,13 +135,13 @@ export function createSliderState(
|
|
|
125
135
|
// Current value accessor
|
|
126
136
|
const value = createMemo(() => {
|
|
127
137
|
const p = getProps();
|
|
128
|
-
const rawValue = isControlled() ? (p.value ?? minValue) : internalValue();
|
|
129
|
-
return snapToStep(rawValue, minValue, maxValue, step);
|
|
138
|
+
const rawValue = isControlled() ? (p.value ?? minValue()) : internalValue();
|
|
139
|
+
return snapToStep(rawValue, minValue(), maxValue(), step());
|
|
130
140
|
});
|
|
131
141
|
|
|
132
142
|
// Value as percent (0-1)
|
|
133
143
|
const getValuePercent = createMemo(() => {
|
|
134
|
-
return (value() - minValue) / (maxValue - minValue);
|
|
144
|
+
return (value() - minValue()) / (maxValue() - minValue());
|
|
135
145
|
});
|
|
136
146
|
|
|
137
147
|
// Formatted value
|
|
@@ -143,10 +153,10 @@ export function createSliderState(
|
|
|
143
153
|
|
|
144
154
|
// Set value function
|
|
145
155
|
const setValue = (newValue: number) => {
|
|
146
|
-
if (isDisabled) return;
|
|
156
|
+
if (isDisabled()) return;
|
|
147
157
|
|
|
148
158
|
const p = getProps();
|
|
149
|
-
const snappedValue = snapToStep(newValue, minValue, maxValue, step);
|
|
159
|
+
const snappedValue = snapToStep(newValue, minValue(), maxValue(), step());
|
|
150
160
|
|
|
151
161
|
if (!isControlled()) {
|
|
152
162
|
setInternalValue(snappedValue);
|
|
@@ -158,7 +168,7 @@ export function createSliderState(
|
|
|
158
168
|
// Set value by percent
|
|
159
169
|
const setValuePercent = (percent: number) => {
|
|
160
170
|
const clampedPercent = clamp(percent, 0, 1);
|
|
161
|
-
const newValue = clampedPercent * (maxValue - minValue) + minValue;
|
|
171
|
+
const newValue = clampedPercent * (maxValue() - minValue()) + minValue();
|
|
162
172
|
setValue(newValue);
|
|
163
173
|
};
|
|
164
174
|
|
|
@@ -175,13 +185,13 @@ export function createSliderState(
|
|
|
175
185
|
|
|
176
186
|
// Increment/decrement
|
|
177
187
|
const increment = (stepMultiplier = 1) => {
|
|
178
|
-
if (isDisabled) return;
|
|
179
|
-
setValue(value() + step * stepMultiplier);
|
|
188
|
+
if (isDisabled()) return;
|
|
189
|
+
setValue(value() + step() * stepMultiplier);
|
|
180
190
|
};
|
|
181
191
|
|
|
182
192
|
const decrement = (stepMultiplier = 1) => {
|
|
183
|
-
if (isDisabled) return;
|
|
184
|
-
setValue(value() - step * stepMultiplier);
|
|
193
|
+
if (isDisabled()) return;
|
|
194
|
+
setValue(value() - step() * stepMultiplier);
|
|
185
195
|
};
|
|
186
196
|
|
|
187
197
|
// Set focused state
|
|
@@ -201,11 +211,23 @@ export function createSliderState(
|
|
|
201
211
|
setFocused,
|
|
202
212
|
increment,
|
|
203
213
|
decrement,
|
|
204
|
-
minValue
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
214
|
+
get minValue() {
|
|
215
|
+
return minValue();
|
|
216
|
+
},
|
|
217
|
+
get maxValue() {
|
|
218
|
+
return maxValue();
|
|
219
|
+
},
|
|
220
|
+
get step() {
|
|
221
|
+
return step();
|
|
222
|
+
},
|
|
223
|
+
get pageStep() {
|
|
224
|
+
return pageStep();
|
|
225
|
+
},
|
|
226
|
+
get orientation() {
|
|
227
|
+
return orientation();
|
|
228
|
+
},
|
|
229
|
+
get isDisabled() {
|
|
230
|
+
return isDisabled();
|
|
231
|
+
},
|
|
210
232
|
};
|
|
211
233
|
}
|
package/src/slider/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { createSliderState } from
|
|
2
|
-
export type { SliderState, SliderStateProps, SliderOrientation
|
|
3
|
-
//# sourceMappingURL=index.d.ts.map
|
|
1
|
+
export { createSliderState } from "./createSliderState";
|
|
2
|
+
export type { SliderState, SliderStateProps, SliderOrientation } from "./createSliderState";
|
|
3
|
+
//# sourceMappingURL=index.d.ts.map
|
package/src/slider/index.ts
CHANGED
|
@@ -1,6 +1,2 @@
|
|
|
1
|
-
export { createSliderState } from
|
|
2
|
-
export type {
|
|
3
|
-
SliderState,
|
|
4
|
-
SliderStateProps,
|
|
5
|
-
SliderOrientation,
|
|
6
|
-
} from './createSliderState';
|
|
1
|
+
export { createSliderState } from "./createSliderState";
|
|
2
|
+
export type { SliderState, SliderStateProps, SliderOrientation } from "./createSliderState";
|
package/src/ssr/index.d.ts
CHANGED
package/src/ssr/index.ts
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* These utilities provide a consistent API matching React-Stately's patterns.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import { createUniqueId } from
|
|
9
|
-
import { isServer as _isServer } from
|
|
8
|
+
import { createUniqueId } from "solid-js";
|
|
9
|
+
import { isServer as _isServer } from "solid-js/web";
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Re-export isServer from solid-js/web for convenience.
|