@proyecto-viviana/solid-stately 0.6.0-rc.0 → 0.6.0-rc.2
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 +59 -29
- package/dist/calendar/createCalendarState.d.ts +3 -1
- package/dist/calendar/createCalendarState.d.ts.map +1 -1
- package/dist/calendar/createDatePickerState.d.ts +2 -0
- package/dist/calendar/createDatePickerState.d.ts.map +1 -1
- package/dist/calendar/createRangeCalendarState.d.ts +2 -0
- package/dist/calendar/createRangeCalendarState.d.ts.map +1 -1
- package/dist/calendar/createTimeFieldState.d.ts +1 -1
- package/dist/calendar/createTimeFieldState.d.ts.map +1 -1
- package/dist/checkbox/createCheckboxGroupState.d.ts +2 -0
- package/dist/checkbox/createCheckboxGroupState.d.ts.map +1 -1
- package/dist/collections/createListState.d.ts.map +1 -1
- package/dist/collections/createMenuState.d.ts +46 -2
- package/dist/collections/createMenuState.d.ts.map +1 -1
- package/dist/collections/createSelectionState.d.ts.map +1 -1
- package/dist/collections/index.d.ts +1 -1
- package/dist/collections/index.d.ts.map +1 -1
- package/dist/color/createColorAreaState.d.ts +4 -0
- package/dist/color/createColorAreaState.d.ts.map +1 -1
- package/dist/color/createColorFieldState.d.ts +2 -0
- package/dist/color/createColorFieldState.d.ts.map +1 -1
- package/dist/color/createColorSliderState.d.ts +2 -0
- package/dist/color/createColorSliderState.d.ts.map +1 -1
- package/dist/color/createColorWheelState.d.ts.map +1 -1
- package/dist/combobox/createComboBoxState.d.ts +90 -23
- package/dist/combobox/createComboBoxState.d.ts.map +1 -1
- package/dist/combobox/index.d.ts +1 -1
- package/dist/combobox/index.d.ts.map +1 -1
- package/dist/data/createAsyncList.d.ts.map +1 -1
- package/dist/data/createListData.d.ts.map +1 -1
- package/dist/data/createTreeData.d.ts.map +1 -1
- package/dist/dnd/createDraggableCollectionState.d.ts +5 -1
- package/dist/dnd/createDraggableCollectionState.d.ts.map +1 -1
- package/dist/dnd/createDroppableCollectionState.d.ts +6 -0
- package/dist/dnd/createDroppableCollectionState.d.ts.map +1 -1
- package/dist/form/createFormValidationState.d.ts.map +1 -1
- package/dist/grid/createGridState.d.ts +2 -2
- package/dist/grid/createGridState.d.ts.map +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1044 -478
- package/dist/index.js.map +1 -1
- package/dist/menu/index.d.ts +2 -1
- package/dist/menu/index.d.ts.map +1 -1
- package/dist/numberfield/createNumberFieldState.d.ts +6 -3
- package/dist/numberfield/createNumberFieldState.d.ts.map +1 -1
- package/dist/private/flags/flags.d.ts.map +1 -0
- package/dist/private/flags/flags.js +1 -1
- package/dist/private/flags/flags.js.map +1 -1
- package/dist/radio/createRadioGroupState.d.ts.map +1 -1
- package/dist/select/createSelectState.d.ts +85 -29
- package/dist/select/createSelectState.d.ts.map +1 -1
- package/dist/select/index.d.ts +1 -1
- package/dist/select/index.d.ts.map +1 -1
- package/dist/selection/SelectionManager.d.ts.map +1 -1
- package/dist/selection/createMultipleSelectionState.d.ts.map +1 -1
- package/dist/slider/createSliderState.d.ts +35 -9
- package/dist/slider/createSliderState.d.ts.map +1 -1
- package/dist/ssr/index.d.ts +0 -6
- package/dist/ssr/index.d.ts.map +1 -1
- package/dist/steplist/createStepListState.d.ts +8 -13
- package/dist/steplist/createStepListState.d.ts.map +1 -1
- package/dist/table/createTableColumnResizeState.d.ts.map +1 -1
- package/dist/table/createTableState.d.ts +2 -2
- package/dist/table/createTableState.d.ts.map +1 -1
- package/dist/table/createTreeGridState.d.ts +2 -2
- package/dist/table/createTreeGridState.d.ts.map +1 -1
- package/dist/table/types.d.ts +2 -2
- package/dist/table/types.d.ts.map +1 -1
- package/dist/tabs/createTabListState.d.ts.map +1 -1
- package/dist/textfield/createTextFieldState.d.ts.map +1 -1
- package/dist/toggle/createToggleGroupState.d.ts +0 -8
- package/dist/toggle/createToggleGroupState.d.ts.map +1 -1
- package/dist/toggle/createToggleState.d.ts.map +1 -1
- package/dist/tokenfield/TokenFieldValue.d.ts +28 -4
- package/dist/tokenfield/TokenFieldValue.d.ts.map +1 -1
- package/dist/tokenfield/index.d.ts +1 -1
- package/dist/tokenfield/index.d.ts.map +1 -1
- package/dist/tree/createTreeState.d.ts +2 -2
- package/dist/tree/createTreeState.d.ts.map +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/reactivity.d.ts +5 -0
- package/dist/utils/reactivity.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/calendar/createCalendarState.ts +139 -58
- package/src/calendar/createDatePickerState.ts +14 -11
- package/src/calendar/createRangeCalendarState.ts +43 -17
- package/src/calendar/createTimeFieldState.ts +1 -1
- package/src/checkbox/createCheckboxGroupState.ts +16 -0
- package/src/collections/createListState.ts +4 -4
- package/src/collections/createMenuState.ts +134 -4
- package/src/collections/createSelectionState.ts +2 -2
- package/src/collections/index.ts +4 -0
- package/src/color/createColorAreaState.ts +19 -0
- package/src/color/createColorFieldState.ts +76 -26
- package/src/color/createColorSliderState.ts +25 -2
- package/src/color/createColorWheelState.ts +9 -5
- package/src/combobox/createComboBoxState.ts +371 -121
- package/src/combobox/index.ts +4 -0
- package/src/data/createAsyncList.ts +19 -4
- package/src/data/createListData.ts +8 -2
- package/src/data/createTreeData.ts +11 -3
- package/src/dnd/createDraggableCollectionState.ts +8 -1
- package/src/dnd/createDroppableCollectionState.ts +10 -0
- package/src/form/createFormValidationState.ts +23 -5
- package/src/grid/createGridState.ts +15 -8
- package/src/index.ts +18 -2
- package/src/menu/index.ts +5 -0
- package/src/numberfield/createNumberFieldState.ts +97 -35
- package/src/radio/createRadioGroupState.ts +4 -1
- package/src/select/createSelectState.ts +253 -131
- package/src/select/index.ts +8 -1
- package/src/selection/SelectionManager.ts +3 -1
- package/src/selection/createMultipleSelectionState.ts +2 -2
- package/src/slider/createSliderState.ts +227 -103
- package/src/ssr/index.ts +11 -4
- package/src/steplist/createStepListState.ts +156 -123
- package/src/table/createTableColumnResizeState.ts +51 -11
- package/src/table/createTableState.ts +5 -4
- package/src/table/createTreeGridState.ts +3 -4
- package/src/table/types.ts +2 -2
- package/src/tabs/createTabListState.ts +8 -31
- package/src/textfield/createTextFieldState.ts +6 -3
- package/src/toggle/createToggleGroupState.ts +4 -2
- package/src/toggle/createToggleState.ts +5 -4
- package/src/tokenfield/TokenFieldValue.ts +75 -16
- package/src/tokenfield/index.ts +1 -0
- package/src/tree/createTreeState.ts +15 -8
- package/src/utils/index.ts +1 -0
- package/src/utils/reactivity.ts +8 -0
- package/dist/flags/flags.d.ts.map +0 -1
- /package/dist/{flags → private/flags}/flags.d.ts +0 -0
- /package/src/{flags → private/flags}/flags.ts +0 -0
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
* This is a 1:1 port of @react-stately/toggle's useToggleState.
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
|
-
import { Accessor } from "solid-js";
|
|
23
|
+
import { Accessor, untrack } from "solid-js";
|
|
24
24
|
import { access, createInternalSignal, readNow, type MaybeAccessor } from "../utils";
|
|
25
25
|
|
|
26
26
|
export interface ToggleStateOptions {
|
|
@@ -51,8 +51,9 @@ export interface ToggleState {
|
|
|
51
51
|
export function createToggleState(props: MaybeAccessor<ToggleStateOptions> = {}): ToggleState {
|
|
52
52
|
const getProps = () => access(props);
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
const
|
|
54
|
+
// Seeds the uncontrolled state once, by definition.
|
|
55
|
+
const initialDefaultSelected = untrack(() => getProps().defaultSelected);
|
|
56
|
+
const initialSelected = untrack(() => getProps().isSelected) ?? initialDefaultSelected ?? false;
|
|
56
57
|
|
|
57
58
|
const [internalSelected, setInternalSelected] = createInternalSignal(initialSelected);
|
|
58
59
|
|
|
@@ -88,7 +89,7 @@ export function createToggleState(props: MaybeAccessor<ToggleStateOptions> = {})
|
|
|
88
89
|
|
|
89
90
|
return {
|
|
90
91
|
isSelected,
|
|
91
|
-
defaultSelected:
|
|
92
|
+
defaultSelected: initialDefaultSelected ?? initialSelected,
|
|
92
93
|
setSelected,
|
|
93
94
|
toggle,
|
|
94
95
|
};
|
|
@@ -33,13 +33,66 @@ export interface Position {
|
|
|
33
33
|
offset: number;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
/** Represents a text selection in a TokenField. */
|
|
37
|
+
export class SelectedRange {
|
|
38
|
+
/** The anchor position. */
|
|
39
|
+
anchor: Position;
|
|
40
|
+
/** The current (i.e. caret) position. */
|
|
41
|
+
current: Position;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Creates a new selection range. If only a single position is provided, the selection is
|
|
45
|
+
* collapsed.
|
|
46
|
+
*/
|
|
47
|
+
constructor(anchor: Position, current: Position = anchor) {
|
|
48
|
+
this.anchor = anchor;
|
|
49
|
+
this.current = current;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Whether the selection is collapsed to a single caret position. */
|
|
53
|
+
get isCollapsed() {
|
|
54
|
+
return this.anchor.index === this.current.index && this.anchor.offset === this.current.offset;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** The side of the selection closest to the start of the value. */
|
|
58
|
+
get start() {
|
|
59
|
+
return compare(this.anchor, this.current) < 0 ? this.anchor : this.current;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** The side of the selection closest to the end of the value. */
|
|
63
|
+
get end() {
|
|
64
|
+
return compare(this.anchor, this.current) < 0 ? this.current : this.anchor;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Returns whether this selection is equal to another. */
|
|
68
|
+
isEqual(other: SelectedRange) {
|
|
69
|
+
if (this === other) {
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
return (
|
|
73
|
+
this.anchor.index === other.anchor.index &&
|
|
74
|
+
this.anchor.offset === other.anchor.offset &&
|
|
75
|
+
this.current.index === other.current.index &&
|
|
76
|
+
this.current.offset === other.current.offset
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function compare(a: Position, b: Position) {
|
|
82
|
+
if (a.index === b.index) {
|
|
83
|
+
return a.offset - b.offset;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return a.index - b.index;
|
|
87
|
+
}
|
|
88
|
+
|
|
36
89
|
enum Direction {
|
|
37
90
|
Forward = 1,
|
|
38
91
|
Backward = -1,
|
|
39
92
|
}
|
|
40
93
|
|
|
41
94
|
export interface TokenFieldValueOptions {
|
|
42
|
-
|
|
95
|
+
selectedRange?: SelectedRange | null;
|
|
43
96
|
}
|
|
44
97
|
|
|
45
98
|
/**
|
|
@@ -47,11 +100,12 @@ export interface TokenFieldValueOptions {
|
|
|
47
100
|
*/
|
|
48
101
|
export class TokenFieldValue<T = any> {
|
|
49
102
|
static readonly Direction = Direction;
|
|
103
|
+
static readonly SelectedRange = SelectedRange;
|
|
50
104
|
|
|
51
105
|
/** The text and token segments in the list. */
|
|
52
106
|
readonly segments: readonly TokenFieldSegment<T>[];
|
|
53
|
-
/** The
|
|
54
|
-
|
|
107
|
+
/** The selected range. */
|
|
108
|
+
selectedRange: SelectedRange;
|
|
55
109
|
// Linked list representing the undo/redo history.
|
|
56
110
|
private previous: this | null = null;
|
|
57
111
|
private next: this | null = null;
|
|
@@ -60,7 +114,11 @@ export class TokenFieldValue<T = any> {
|
|
|
60
114
|
/** Create a new list with the given segments. */
|
|
61
115
|
constructor(tokens: readonly TokenFieldSegment<T>[], options?: TokenFieldValueOptions) {
|
|
62
116
|
this.segments = tokens;
|
|
63
|
-
this.
|
|
117
|
+
this.selectedRange = options?.selectedRange ?? new SelectedRange({ index: 0, offset: 0 });
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
get caretPosition(): Position {
|
|
121
|
+
return this.selectedRange.current;
|
|
64
122
|
}
|
|
65
123
|
|
|
66
124
|
protected createFieldValue(segments: readonly TokenFieldSegment<T>[]): this {
|
|
@@ -71,23 +129,25 @@ export class TokenFieldValue<T = any> {
|
|
|
71
129
|
return new Constructor(segments);
|
|
72
130
|
}
|
|
73
131
|
|
|
74
|
-
/** Create a new list with the
|
|
75
|
-
|
|
76
|
-
if (
|
|
77
|
-
this.caretPosition.index === caretPosition.index &&
|
|
78
|
-
this.caretPosition.offset === caretPosition.offset
|
|
79
|
-
) {
|
|
132
|
+
/** Create a new list with the selected range set to the given range. */
|
|
133
|
+
withSelectedRange(selectedRange: SelectedRange): this {
|
|
134
|
+
if (this.selectedRange.isEqual(selectedRange)) {
|
|
80
135
|
return this;
|
|
81
136
|
}
|
|
82
137
|
|
|
83
138
|
let result = this.createFieldValue(this.segments);
|
|
84
|
-
result.
|
|
139
|
+
result.selectedRange = selectedRange;
|
|
85
140
|
result.previous = this.previous;
|
|
86
141
|
result.next = this.next;
|
|
87
142
|
result.isCoalescing = this.isCoalescing;
|
|
88
143
|
return result;
|
|
89
144
|
}
|
|
90
145
|
|
|
146
|
+
/** Create a new list with the caret position set to the given position. */
|
|
147
|
+
withCaretPosition(position: Position): this {
|
|
148
|
+
return this.withSelectedRange(new SelectedRange(position));
|
|
149
|
+
}
|
|
150
|
+
|
|
91
151
|
private splitSegment(
|
|
92
152
|
segment: TokenFieldSegment | undefined,
|
|
93
153
|
offset: number,
|
|
@@ -176,14 +236,14 @@ export class TokenFieldValue<T = any> {
|
|
|
176
236
|
appendSegments(newSegments, this.segments.slice(end.index + 1));
|
|
177
237
|
|
|
178
238
|
let segments = this.createFieldValue(newSegments);
|
|
179
|
-
segments.
|
|
239
|
+
segments.selectedRange = new SelectedRange(caret);
|
|
180
240
|
segments.isCoalescing = coalesce;
|
|
181
241
|
if (this.isCoalescing && coalesce && this.previous) {
|
|
182
242
|
segments.previous = this.previous;
|
|
183
243
|
segments.previous.next = segments;
|
|
184
244
|
} else {
|
|
185
245
|
segments.previous = this;
|
|
186
|
-
this.
|
|
246
|
+
this.selectedRange = new SelectedRange(start, end);
|
|
187
247
|
this.next = segments;
|
|
188
248
|
}
|
|
189
249
|
return segments;
|
|
@@ -306,8 +366,7 @@ export class TokenFieldValue<T = any> {
|
|
|
306
366
|
);
|
|
307
367
|
}
|
|
308
368
|
|
|
309
|
-
this.
|
|
310
|
-
return this;
|
|
369
|
+
return this.withSelectedRange(new SelectedRange(position));
|
|
311
370
|
}
|
|
312
371
|
|
|
313
372
|
/** Delete text to the next or previous line break. */
|
|
@@ -326,7 +385,7 @@ export class TokenFieldValue<T = any> {
|
|
|
326
385
|
);
|
|
327
386
|
}
|
|
328
387
|
|
|
329
|
-
return this;
|
|
388
|
+
return this.withSelectedRange(new SelectedRange(position));
|
|
330
389
|
}
|
|
331
390
|
|
|
332
391
|
/** Create a new list containing a subset of the segments. */
|
package/src/tokenfield/index.ts
CHANGED
|
@@ -20,19 +20,18 @@
|
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
22
|
import { createEffect, createMemo } from "solid-js";
|
|
23
|
-
import type { Accessor } from "solid-js";
|
|
24
23
|
import type { TreeState, TreeStateOptions, TreeCollection } from "./types";
|
|
25
24
|
import type { Key, FocusStrategy, Selection, SelectionBehavior } from "../collections/types";
|
|
26
|
-
import { createInternalSignal } from "../utils";
|
|
25
|
+
import { createInternalSignal, propsAccessor, type MaybeAccessor } from "../utils";
|
|
27
26
|
|
|
28
27
|
/**
|
|
29
28
|
* Creates state management for a tree component.
|
|
30
29
|
* Handles expansion, selection, focus management, and keyboard navigation state.
|
|
31
30
|
*/
|
|
32
31
|
export function createTreeState<T extends object, C extends TreeCollection<T> = TreeCollection<T>>(
|
|
33
|
-
options:
|
|
32
|
+
options: MaybeAccessor<TreeStateOptions<T, C>>,
|
|
34
33
|
): TreeState<T, C> {
|
|
35
|
-
const getOptions = (
|
|
34
|
+
const getOptions = propsAccessor(options);
|
|
36
35
|
|
|
37
36
|
// Disabled keys as a Set
|
|
38
37
|
const disabledKeys = createMemo(() => {
|
|
@@ -92,18 +91,26 @@ export function createTreeState<T extends object, C extends TreeCollection<T> =
|
|
|
92
91
|
const disallowEmptySelection = createMemo(() => getOptions().disallowEmptySelection ?? false);
|
|
93
92
|
const disabledBehavior = createMemo(() => getOptions().disabledBehavior ?? "all");
|
|
94
93
|
|
|
94
|
+
let lastSelectionBehavior = selectionBehaviorProp();
|
|
95
95
|
createEffect(selectionBehaviorProp, (behavior) => {
|
|
96
|
-
|
|
96
|
+
if (behavior !== lastSelectionBehavior) {
|
|
97
|
+
setSelectionBehaviorState(behavior);
|
|
98
|
+
lastSelectionBehavior = behavior;
|
|
99
|
+
}
|
|
97
100
|
});
|
|
98
101
|
|
|
99
102
|
createEffect(
|
|
100
103
|
() => ({
|
|
101
104
|
prop: selectionBehaviorProp(),
|
|
102
|
-
state: selectionBehaviorState(),
|
|
103
105
|
keys: selectedKeys(),
|
|
104
106
|
}),
|
|
105
|
-
({ prop,
|
|
106
|
-
if (
|
|
107
|
+
({ prop, keys }) => {
|
|
108
|
+
if (
|
|
109
|
+
prop === "replace" &&
|
|
110
|
+
selectionBehaviorState() === "toggle" &&
|
|
111
|
+
keys !== "all" &&
|
|
112
|
+
keys.size === 0
|
|
113
|
+
) {
|
|
107
114
|
setSelectionBehaviorState("replace");
|
|
108
115
|
}
|
|
109
116
|
},
|
package/src/utils/index.ts
CHANGED
package/src/utils/reactivity.ts
CHANGED
|
@@ -36,6 +36,14 @@ export function isAccessor<T>(value: MaybeAccessor<T>): value is Accessor<T> {
|
|
|
36
36
|
return typeof value === "function";
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
/**
|
|
40
|
+
* Resolve a props bag once. Later reads call the accessor directly, so a
|
|
41
|
+
* function-valued field such as `getKey` is never treated as the bag.
|
|
42
|
+
*/
|
|
43
|
+
export function propsAccessor<T extends object>(props: MaybeAccessor<T>): Accessor<T> {
|
|
44
|
+
return typeof props === "function" ? props : () => props;
|
|
45
|
+
}
|
|
46
|
+
|
|
39
47
|
/**
|
|
40
48
|
* Headless state is written from factory setup and from public setters that
|
|
41
49
|
* tests (and some call sites) invoke inside `createRoot` / a component body.
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"flags.d.ts","sourceRoot":"","sources":["../../src/flags/flags.ts"],"names":[],"mappings":"AAgBA,gFAAgF;AAChF,wBAAgB,eAAe,IAAI,IAAI,CAEtC;AAED,6DAA6D;AAC7D,wBAAgB,SAAS,IAAI,OAAO,CAEnC"}
|
|
File without changes
|
|
File without changes
|