@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
package/dist/index.js
CHANGED
|
@@ -145,7 +145,19 @@
|
|
|
145
145
|
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
146
146
|
* governing permissions and limitations under the License.
|
|
147
147
|
*/
|
|
148
|
+
/*
|
|
149
|
+
* Copyright 2023 Adobe. All rights reserved.
|
|
150
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
151
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
152
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
153
|
+
*
|
|
154
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
155
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
156
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
157
|
+
* governing permissions and limitations under the License.
|
|
158
|
+
*/
|
|
148
159
|
// Ported to SolidJS for Proyecto Viviana; based on packages/react-stately/src/menu/useMenuTriggerState.ts
|
|
160
|
+
// Ported to SolidJS for Proyecto Viviana; based on packages/react-stately/src/menu/useSubmenuTriggerState.ts
|
|
149
161
|
/*
|
|
150
162
|
* Copyright 2020 Adobe. All rights reserved.
|
|
151
163
|
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
@@ -683,6 +695,13 @@ function isAccessor(value) {
|
|
|
683
695
|
return typeof value === "function";
|
|
684
696
|
}
|
|
685
697
|
/**
|
|
698
|
+
* Resolve a props bag once. Later reads call the accessor directly, so a
|
|
699
|
+
* function-valued field such as `getKey` is never treated as the bag.
|
|
700
|
+
*/
|
|
701
|
+
function propsAccessor(props) {
|
|
702
|
+
return typeof props === "function" ? props : () => props;
|
|
703
|
+
}
|
|
704
|
+
/**
|
|
686
705
|
* Headless state is written from factory setup and from public setters that
|
|
687
706
|
* tests (and some call sites) invoke inside `createRoot` / a component body.
|
|
688
707
|
* Solid 2 throws on those writes unless the signal opts into `ownedWrite`.
|
|
@@ -737,12 +756,19 @@ function useContextOptional(context) {
|
|
|
737
756
|
//#endregion
|
|
738
757
|
//#region src/toggle/createToggleState.ts
|
|
739
758
|
/**
|
|
759
|
+
* Toggle state for Solid Stately
|
|
760
|
+
*
|
|
761
|
+
* Provides state management for toggle components like checkboxes and switches.
|
|
762
|
+
*
|
|
763
|
+
* This is a 1:1 port of @react-stately/toggle's useToggleState.
|
|
764
|
+
*/
|
|
765
|
+
/**
|
|
740
766
|
* Provides state management for toggle components like checkboxes and switches.
|
|
741
767
|
*/
|
|
742
768
|
function createToggleState(props = {}) {
|
|
743
769
|
const getProps = () => access(props);
|
|
744
|
-
const
|
|
745
|
-
const initialSelected =
|
|
770
|
+
const initialDefaultSelected = untrack(() => getProps().defaultSelected);
|
|
771
|
+
const initialSelected = untrack(() => getProps().isSelected) ?? initialDefaultSelected ?? false;
|
|
746
772
|
const [internalSelected, setInternalSelected] = createInternalSignal(initialSelected);
|
|
747
773
|
const isControlled = () => getProps().isSelected !== void 0;
|
|
748
774
|
const isSelected = () => {
|
|
@@ -762,13 +788,21 @@ function createToggleState(props = {}) {
|
|
|
762
788
|
}
|
|
763
789
|
return {
|
|
764
790
|
isSelected,
|
|
765
|
-
defaultSelected:
|
|
791
|
+
defaultSelected: initialDefaultSelected ?? initialSelected,
|
|
766
792
|
setSelected,
|
|
767
793
|
toggle
|
|
768
794
|
};
|
|
769
795
|
}
|
|
770
796
|
//#endregion
|
|
771
797
|
//#region src/toggle/createToggleGroupState.ts
|
|
798
|
+
/**
|
|
799
|
+
* Toggle group state for Solid Stately
|
|
800
|
+
*
|
|
801
|
+
* Provides state management for groups of toggle buttons with
|
|
802
|
+
* single or multiple selection.
|
|
803
|
+
*
|
|
804
|
+
* This is a port of @react-stately/toggle's useToggleGroupState.
|
|
805
|
+
*/
|
|
772
806
|
function toKeySet(keys) {
|
|
773
807
|
return new Set(keys ? Array.from(keys) : []);
|
|
774
808
|
}
|
|
@@ -777,7 +811,7 @@ function toKeySet(keys) {
|
|
|
777
811
|
*/
|
|
778
812
|
function createToggleGroupState(props = {}) {
|
|
779
813
|
const getProps = () => access(props);
|
|
780
|
-
const [internalSelectedKeys, setInternalSelectedKeys] = createInternalSignal(toKeySet(getProps().defaultSelectedKeys));
|
|
814
|
+
const [internalSelectedKeys, setInternalSelectedKeys] = createInternalSignal(toKeySet(untrack(() => getProps().defaultSelectedKeys)));
|
|
781
815
|
const isControlled = () => getProps().selectedKeys !== void 0;
|
|
782
816
|
const selectedKeys = () => isControlled() ? toKeySet(getProps().selectedKeys) : internalSelectedKeys();
|
|
783
817
|
function setSelectedKeys(keys) {
|
|
@@ -862,13 +896,23 @@ function createAutocompleteState(props = {}) {
|
|
|
862
896
|
//#endregion
|
|
863
897
|
//#region src/textfield/createTextFieldState.ts
|
|
864
898
|
/**
|
|
899
|
+
* TextField state for Solid Stately
|
|
900
|
+
*
|
|
901
|
+
* Provides state management for text input components.
|
|
902
|
+
*
|
|
903
|
+
* This is a port of @react-stately/utils's useControlledState pattern
|
|
904
|
+
* as used by @react-aria/textfield.
|
|
905
|
+
*/
|
|
906
|
+
/**
|
|
865
907
|
* Provides state management for text input components.
|
|
866
908
|
* Supports both controlled and uncontrolled modes.
|
|
867
909
|
*/
|
|
868
910
|
function createTextFieldState(props = {}) {
|
|
869
911
|
const getProps = () => access(props);
|
|
870
|
-
const
|
|
871
|
-
|
|
912
|
+
const [internalValue, setInternalValue] = createInternalSignal(untrack(() => {
|
|
913
|
+
const initialProps = getProps();
|
|
914
|
+
return initialProps.value ?? initialProps.defaultValue ?? "";
|
|
915
|
+
}));
|
|
872
916
|
const isControlled = () => getProps().value !== void 0;
|
|
873
917
|
const value = () => {
|
|
874
918
|
const p = getProps();
|
|
@@ -886,6 +930,42 @@ function createTextFieldState(props = {}) {
|
|
|
886
930
|
}
|
|
887
931
|
//#endregion
|
|
888
932
|
//#region src/tokenfield/TokenFieldValue.ts
|
|
933
|
+
/** Represents a text selection in a TokenField. */
|
|
934
|
+
var SelectedRange = class {
|
|
935
|
+
/** The anchor position. */
|
|
936
|
+
anchor;
|
|
937
|
+
/** The current (i.e. caret) position. */
|
|
938
|
+
current;
|
|
939
|
+
/**
|
|
940
|
+
* Creates a new selection range. If only a single position is provided, the selection is
|
|
941
|
+
* collapsed.
|
|
942
|
+
*/
|
|
943
|
+
constructor(anchor, current = anchor) {
|
|
944
|
+
this.anchor = anchor;
|
|
945
|
+
this.current = current;
|
|
946
|
+
}
|
|
947
|
+
/** Whether the selection is collapsed to a single caret position. */
|
|
948
|
+
get isCollapsed() {
|
|
949
|
+
return this.anchor.index === this.current.index && this.anchor.offset === this.current.offset;
|
|
950
|
+
}
|
|
951
|
+
/** The side of the selection closest to the start of the value. */
|
|
952
|
+
get start() {
|
|
953
|
+
return compare(this.anchor, this.current) < 0 ? this.anchor : this.current;
|
|
954
|
+
}
|
|
955
|
+
/** The side of the selection closest to the end of the value. */
|
|
956
|
+
get end() {
|
|
957
|
+
return compare(this.anchor, this.current) < 0 ? this.current : this.anchor;
|
|
958
|
+
}
|
|
959
|
+
/** Returns whether this selection is equal to another. */
|
|
960
|
+
isEqual(other) {
|
|
961
|
+
if (this === other) return true;
|
|
962
|
+
return this.anchor.index === other.anchor.index && this.anchor.offset === other.anchor.offset && this.current.index === other.current.index && this.current.offset === other.current.offset;
|
|
963
|
+
}
|
|
964
|
+
};
|
|
965
|
+
function compare(a, b) {
|
|
966
|
+
if (a.index === b.index) return a.offset - b.offset;
|
|
967
|
+
return a.index - b.index;
|
|
968
|
+
}
|
|
889
969
|
var Direction = /* @__PURE__ */ function(Direction) {
|
|
890
970
|
Direction[Direction["Forward"] = 1] = "Forward";
|
|
891
971
|
Direction[Direction["Backward"] = -1] = "Backward";
|
|
@@ -896,38 +976,43 @@ var Direction = /* @__PURE__ */ function(Direction) {
|
|
|
896
976
|
*/
|
|
897
977
|
var TokenFieldValue = class {
|
|
898
978
|
static Direction = Direction;
|
|
979
|
+
static SelectedRange = SelectedRange;
|
|
899
980
|
/** The text and token segments in the list. */
|
|
900
981
|
segments;
|
|
901
|
-
/** The
|
|
902
|
-
|
|
903
|
-
index: 0,
|
|
904
|
-
offset: 0
|
|
905
|
-
};
|
|
982
|
+
/** The selected range. */
|
|
983
|
+
selectedRange;
|
|
906
984
|
previous = null;
|
|
907
985
|
next = null;
|
|
908
986
|
isCoalescing = true;
|
|
909
987
|
/** Create a new list with the given segments. */
|
|
910
988
|
constructor(tokens, options) {
|
|
911
989
|
this.segments = tokens;
|
|
912
|
-
this.
|
|
990
|
+
this.selectedRange = options?.selectedRange ?? new SelectedRange({
|
|
913
991
|
index: 0,
|
|
914
992
|
offset: 0
|
|
915
|
-
};
|
|
993
|
+
});
|
|
994
|
+
}
|
|
995
|
+
get caretPosition() {
|
|
996
|
+
return this.selectedRange.current;
|
|
916
997
|
}
|
|
917
998
|
createFieldValue(segments) {
|
|
918
999
|
const Constructor = this.constructor;
|
|
919
1000
|
return new Constructor(segments);
|
|
920
1001
|
}
|
|
921
|
-
/** Create a new list with the
|
|
922
|
-
|
|
923
|
-
if (this.
|
|
1002
|
+
/** Create a new list with the selected range set to the given range. */
|
|
1003
|
+
withSelectedRange(selectedRange) {
|
|
1004
|
+
if (this.selectedRange.isEqual(selectedRange)) return this;
|
|
924
1005
|
let result = this.createFieldValue(this.segments);
|
|
925
|
-
result.
|
|
1006
|
+
result.selectedRange = selectedRange;
|
|
926
1007
|
result.previous = this.previous;
|
|
927
1008
|
result.next = this.next;
|
|
928
1009
|
result.isCoalescing = this.isCoalescing;
|
|
929
1010
|
return result;
|
|
930
1011
|
}
|
|
1012
|
+
/** Create a new list with the caret position set to the given position. */
|
|
1013
|
+
withCaretPosition(position) {
|
|
1014
|
+
return this.withSelectedRange(new SelectedRange(position));
|
|
1015
|
+
}
|
|
931
1016
|
splitSegment(segment, offset) {
|
|
932
1017
|
if (!segment) {
|
|
933
1018
|
let empty = this.createTextSegment("");
|
|
@@ -983,14 +1068,14 @@ var TokenFieldValue = class {
|
|
|
983
1068
|
if (endSplit) appendSegments(newSegments, [endSplit]);
|
|
984
1069
|
appendSegments(newSegments, this.segments.slice(end.index + 1));
|
|
985
1070
|
let segments = this.createFieldValue(newSegments);
|
|
986
|
-
segments.
|
|
1071
|
+
segments.selectedRange = new SelectedRange(caret);
|
|
987
1072
|
segments.isCoalescing = coalesce;
|
|
988
1073
|
if (this.isCoalescing && coalesce && this.previous) {
|
|
989
1074
|
segments.previous = this.previous;
|
|
990
1075
|
segments.previous.next = segments;
|
|
991
1076
|
} else {
|
|
992
1077
|
segments.previous = this;
|
|
993
|
-
this.
|
|
1078
|
+
this.selectedRange = new SelectedRange(start, end);
|
|
994
1079
|
this.next = segments;
|
|
995
1080
|
}
|
|
996
1081
|
return segments;
|
|
@@ -1060,15 +1145,14 @@ var TokenFieldValue = class {
|
|
|
1060
1145
|
delete(position, segmenter, direction, coalesce = true) {
|
|
1061
1146
|
let boundary = this.findBoundaryWithSegmenter(position, segmenter, direction);
|
|
1062
1147
|
if (boundary) return this.replaceRange(direction === -1 ? boundary : position, direction === -1 ? position : boundary, "", coalesce);
|
|
1063
|
-
this.
|
|
1064
|
-
return this;
|
|
1148
|
+
return this.withSelectedRange(new SelectedRange(position));
|
|
1065
1149
|
}
|
|
1066
1150
|
/** Delete text to the next or previous line break. */
|
|
1067
1151
|
deleteLine(position, direction, coalesce = true) {
|
|
1068
1152
|
if (this.segments.length === 0) return this;
|
|
1069
1153
|
let boundary = this.findLineBoundary(position, direction);
|
|
1070
1154
|
if (boundary) return this.replaceRange(direction === -1 ? boundary : position, direction === -1 ? position : boundary, "", coalesce);
|
|
1071
|
-
return this;
|
|
1155
|
+
return this.withSelectedRange(new SelectedRange(position));
|
|
1072
1156
|
}
|
|
1073
1157
|
/** Create a new list containing a subset of the segments. */
|
|
1074
1158
|
slice(start, end) {
|
|
@@ -1213,6 +1297,10 @@ const DEFAULT_VALIDATION_RESULT = {
|
|
|
1213
1297
|
};
|
|
1214
1298
|
/** Context for server-side validation errors. */
|
|
1215
1299
|
const FormValidationContext = createContext({});
|
|
1300
|
+
const validationErrorsSource = Symbol.for("proyecto-viviana.validationErrorsSource");
|
|
1301
|
+
function validationErrorsIdentity(errors) {
|
|
1302
|
+
return errors[validationErrorsSource] ?? errors;
|
|
1303
|
+
}
|
|
1216
1304
|
/** Private prop key for passing validation state to children. */
|
|
1217
1305
|
const privateValidationStateProp = "__formValidationState" + Date.now();
|
|
1218
1306
|
function asArray(v) {
|
|
@@ -1282,10 +1370,10 @@ function createFormValidationState(props) {
|
|
|
1282
1370
|
if (name) return Array.isArray(name) ? name.flatMap((n) => asArray(serverErrors[n])) : asArray(serverErrors[name]);
|
|
1283
1371
|
return [];
|
|
1284
1372
|
});
|
|
1285
|
-
const [lastServerErrors, setLastServerErrors] = createInternalSignal(serverErrors);
|
|
1373
|
+
const [lastServerErrors, setLastServerErrors] = createInternalSignal(validationErrorsIdentity(serverErrors));
|
|
1286
1374
|
const [isServerErrorCleared, setServerErrorCleared] = createInternalSignal(false);
|
|
1287
1375
|
createEffect(() => ({
|
|
1288
|
-
errors: serverErrors,
|
|
1376
|
+
errors: validationErrorsIdentity(serverErrors),
|
|
1289
1377
|
last: lastServerErrors()
|
|
1290
1378
|
}), ({ errors, last }) => {
|
|
1291
1379
|
if (errors !== last) {
|
|
@@ -1316,7 +1404,7 @@ function createFormValidationState(props) {
|
|
|
1316
1404
|
return controlledError() || serverError() || clientError() || builtinValidation() || currentValidity();
|
|
1317
1405
|
}),
|
|
1318
1406
|
updateValidation(value) {
|
|
1319
|
-
if (validationBehavior
|
|
1407
|
+
if (untrack(validationBehavior) === "aria" && !isEqualValidation(untrack(currentValidity), value)) setCurrentValidity(value);
|
|
1320
1408
|
else nextValidation = value;
|
|
1321
1409
|
},
|
|
1322
1410
|
resetValidation() {
|
|
@@ -1433,6 +1521,12 @@ function createCheckboxGroupState(props = {}) {
|
|
|
1433
1521
|
const snapshot = liveValue();
|
|
1434
1522
|
if (snapshot.includes(removeVal)) setValue(snapshot.filter((v) => v !== removeVal));
|
|
1435
1523
|
}
|
|
1524
|
+
const invalidValues = /* @__PURE__ */ new Map();
|
|
1525
|
+
function setInvalid(itemValue, result) {
|
|
1526
|
+
if (result.isInvalid) invalidValues.set(itemValue, result);
|
|
1527
|
+
else invalidValues.delete(itemValue);
|
|
1528
|
+
validation.updateValidation(mergeValidation(...invalidValues.values()));
|
|
1529
|
+
}
|
|
1436
1530
|
function toggleValue(toggleVal) {
|
|
1437
1531
|
const p = getProps();
|
|
1438
1532
|
if (p.isReadOnly || p.isDisabled) return;
|
|
@@ -1458,6 +1552,7 @@ function createCheckboxGroupState(props = {}) {
|
|
|
1458
1552
|
addValue,
|
|
1459
1553
|
removeValue,
|
|
1460
1554
|
toggleValue,
|
|
1555
|
+
setInvalid,
|
|
1461
1556
|
realtimeValidation: validation.realtimeValidation,
|
|
1462
1557
|
displayValidation: validation.displayValidation,
|
|
1463
1558
|
updateValidation: validation.updateValidation,
|
|
@@ -1494,9 +1589,14 @@ function createIsSSR() {
|
|
|
1494
1589
|
*
|
|
1495
1590
|
* @param defaultId - Optional default ID to use instead of generating one.
|
|
1496
1591
|
*/
|
|
1592
|
+
let fallbackIdCounter = 0;
|
|
1497
1593
|
function createId(defaultId) {
|
|
1498
|
-
const uniqueId = createUniqueId();
|
|
1499
1594
|
if (defaultId) return defaultId;
|
|
1595
|
+
let uniqueId;
|
|
1596
|
+
try {
|
|
1597
|
+
uniqueId = createUniqueId();
|
|
1598
|
+
} catch {}
|
|
1599
|
+
if (!uniqueId) uniqueId = `nh-${++fallbackIdCounter}`;
|
|
1500
1600
|
return `solid-stately-${uniqueId}`;
|
|
1501
1601
|
}
|
|
1502
1602
|
/**
|
|
@@ -1578,7 +1678,7 @@ function createRadioGroupState(props = {}) {
|
|
|
1578
1678
|
const state = {
|
|
1579
1679
|
name,
|
|
1580
1680
|
selectedValue,
|
|
1581
|
-
defaultSelectedValue: initialProps.defaultValue ?? null,
|
|
1681
|
+
defaultSelectedValue: initialProps.value !== void 0 ? initialProps.value : initialProps.defaultValue ?? null,
|
|
1582
1682
|
setSelectedValue,
|
|
1583
1683
|
lastFocusedValue,
|
|
1584
1684
|
setLastFocusedValue,
|
|
@@ -1831,7 +1931,7 @@ function getAncestors(collection, node) {
|
|
|
1831
1931
|
* Creates selection state for a collection.
|
|
1832
1932
|
*/
|
|
1833
1933
|
function createSelectionState(props = {}) {
|
|
1834
|
-
const getProps = (
|
|
1934
|
+
const getProps = propsAccessor(props);
|
|
1835
1935
|
const [internalBehavior, setInternalBehavior] = createInternalSignal("toggle");
|
|
1836
1936
|
const [internalSelectedKeys, setInternalSelectedKeys] = createInternalSignal(getInitialSelection$2(getProps().defaultSelectedKeys));
|
|
1837
1937
|
const [anchorKey, setAnchorKey] = createInternalSignal(null);
|
|
@@ -2031,7 +2131,7 @@ function convertSelection(selection, defaultValue) {
|
|
|
2031
2131
|
* Manages raw state for multiple selection and focus in a collection.
|
|
2032
2132
|
*/
|
|
2033
2133
|
function createMultipleSelectionState(props = {}) {
|
|
2034
|
-
const getProps = (
|
|
2134
|
+
const getProps = propsAccessor(props);
|
|
2035
2135
|
const [isFocused, setIsFocused] = createInternalSignal(false);
|
|
2036
2136
|
const [focusedKey, setFocusedKeySignal] = createInternalSignal(null);
|
|
2037
2137
|
const [childFocusStrategy, setChildFocusStrategy] = createInternalSignal(null);
|
|
@@ -2403,7 +2503,7 @@ var SelectionManager = class SelectionManager {
|
|
|
2403
2503
|
}
|
|
2404
2504
|
isDisabled(key) {
|
|
2405
2505
|
const item = this.collection.getItem(key);
|
|
2406
|
-
return this.state.disabledBehavior === "all" && (this.state.disabledKeys.has(key) || !!item?.props?.isDisabled) && item?.props?.disabledBehavior !== "selection";
|
|
2506
|
+
return this.state.disabledBehavior === "all" && (this.state.disabledKeys.has(key) || !!item?.props?.isDisabled || item?.isDisabled === true) && item?.props?.disabledBehavior !== "selection";
|
|
2407
2507
|
}
|
|
2408
2508
|
isLink(key) {
|
|
2409
2509
|
return !!this.collection.getItem(key)?.props?.href;
|
|
@@ -2445,7 +2545,7 @@ var SelectionManager = class SelectionManager {
|
|
|
2445
2545
|
* Creates state for a list component with selection.
|
|
2446
2546
|
*/
|
|
2447
2547
|
function createListState(props) {
|
|
2448
|
-
const getProps = (
|
|
2548
|
+
const getProps = propsAccessor(props);
|
|
2449
2549
|
const collection = createMemo(() => {
|
|
2450
2550
|
const p = getProps();
|
|
2451
2551
|
return new ListCollection((p.items ?? []).map((item, index) => {
|
|
@@ -2606,7 +2706,7 @@ function createFilteredListState(state, filterFn) {
|
|
|
2606
2706
|
* Creates state for a single-select list component.
|
|
2607
2707
|
*/
|
|
2608
2708
|
function createSingleSelectListState(props) {
|
|
2609
|
-
const getProps = (
|
|
2709
|
+
const getProps = propsAccessor(props);
|
|
2610
2710
|
const listState = createListState({
|
|
2611
2711
|
get items() {
|
|
2612
2712
|
return getProps().items;
|
|
@@ -2631,7 +2731,7 @@ function createSingleSelectListState(props) {
|
|
|
2631
2731
|
allowDuplicateSelectionEvents: true,
|
|
2632
2732
|
get selectedKeys() {
|
|
2633
2733
|
const key = getProps().selectedKey;
|
|
2634
|
-
return key != null ? [key] : [];
|
|
2734
|
+
return key !== void 0 ? key != null ? [key] : [] : void 0;
|
|
2635
2735
|
},
|
|
2636
2736
|
get defaultSelectedKeys() {
|
|
2637
2737
|
const key = getProps().defaultSelectedKey;
|
|
@@ -2671,6 +2771,8 @@ function createSingleSelectListState(props) {
|
|
|
2671
2771
|
*
|
|
2672
2772
|
* createMenuTriggerState is ported from
|
|
2673
2773
|
* packages/react-stately/src/menu/useMenuTriggerState.ts.
|
|
2774
|
+
* createSubmenuTriggerState is ported from
|
|
2775
|
+
* packages/react-stately/src/menu/useSubmenuTriggerState.ts.
|
|
2674
2776
|
* createMenuState is a local composition of the separately attributed list state.
|
|
2675
2777
|
*/
|
|
2676
2778
|
/**
|
|
@@ -2678,7 +2780,7 @@ function createSingleSelectListState(props) {
|
|
|
2678
2780
|
* Menus are single-select lists that support actions.
|
|
2679
2781
|
*/
|
|
2680
2782
|
function createMenuState(props) {
|
|
2681
|
-
const getProps = (
|
|
2783
|
+
const getProps = propsAccessor(props);
|
|
2682
2784
|
const listState = createListState({
|
|
2683
2785
|
get items() {
|
|
2684
2786
|
return getProps().items;
|
|
@@ -2733,11 +2835,29 @@ function createMenuState(props) {
|
|
|
2733
2835
|
}
|
|
2734
2836
|
/**
|
|
2735
2837
|
* Creates state for a menu trigger. Mirrors `@react-stately/menu` `useMenuTriggerState`:
|
|
2736
|
-
* overlay open state
|
|
2838
|
+
* overlay open state, the focus strategy passed through to `createMenu`, and the
|
|
2839
|
+
* expanded submenu stack.
|
|
2737
2840
|
*/
|
|
2738
2841
|
function createMenuTriggerState(props = {}) {
|
|
2739
2842
|
const overlay = createOverlayTriggerState(props);
|
|
2740
2843
|
const [focusStrategy, setFocusStrategy] = createInternalSignal(null);
|
|
2844
|
+
const [expandedKeysStack, setExpandedKeysStack] = createInternalSignal([]);
|
|
2845
|
+
const openSubmenu = (triggerKey, level) => {
|
|
2846
|
+
setExpandedKeysStack((oldStack) => {
|
|
2847
|
+
if (level > oldStack.length) return oldStack;
|
|
2848
|
+
return [...oldStack.slice(0, level), triggerKey];
|
|
2849
|
+
});
|
|
2850
|
+
};
|
|
2851
|
+
const closeSubmenu = (triggerKey, level) => {
|
|
2852
|
+
setExpandedKeysStack((oldStack) => {
|
|
2853
|
+
if (oldStack[level] !== triggerKey) return oldStack;
|
|
2854
|
+
return oldStack.slice(0, level);
|
|
2855
|
+
});
|
|
2856
|
+
};
|
|
2857
|
+
const close = () => {
|
|
2858
|
+
setExpandedKeysStack([]);
|
|
2859
|
+
overlay.close();
|
|
2860
|
+
};
|
|
2741
2861
|
return {
|
|
2742
2862
|
...overlay,
|
|
2743
2863
|
focusStrategy,
|
|
@@ -2749,7 +2869,46 @@ function createMenuTriggerState(props = {}) {
|
|
|
2749
2869
|
toggle(strategy = null) {
|
|
2750
2870
|
setFocusStrategy(strategy);
|
|
2751
2871
|
overlay.toggle();
|
|
2752
|
-
}
|
|
2872
|
+
},
|
|
2873
|
+
close,
|
|
2874
|
+
expandedKeysStack,
|
|
2875
|
+
openSubmenu,
|
|
2876
|
+
closeSubmenu
|
|
2877
|
+
};
|
|
2878
|
+
}
|
|
2879
|
+
/**
|
|
2880
|
+
* Creates state for a submenu trigger. Mirrors `@react-stately/menu`
|
|
2881
|
+
* `useSubmenuTriggerState`: open state is the root stack entry at this level.
|
|
2882
|
+
*/
|
|
2883
|
+
function createSubmenuTriggerState(props, state) {
|
|
2884
|
+
const getProps = propsAccessor(props);
|
|
2885
|
+
const submenuLevel = state.expandedKeysStack().length;
|
|
2886
|
+
const [focusStrategy, setFocusStrategy] = createInternalSignal(null);
|
|
2887
|
+
const isOpen = () => state.expandedKeysStack()[submenuLevel] === getProps().triggerKey;
|
|
2888
|
+
const open = (strategy) => {
|
|
2889
|
+
setFocusStrategy(strategy ?? null);
|
|
2890
|
+
state.openSubmenu(getProps().triggerKey, submenuLevel);
|
|
2891
|
+
};
|
|
2892
|
+
const close = () => {
|
|
2893
|
+
setFocusStrategy(null);
|
|
2894
|
+
state.closeSubmenu(getProps().triggerKey, submenuLevel);
|
|
2895
|
+
};
|
|
2896
|
+
const toggle = (strategy) => {
|
|
2897
|
+
setFocusStrategy(strategy ?? null);
|
|
2898
|
+
if (isOpen()) close();
|
|
2899
|
+
else open(strategy);
|
|
2900
|
+
};
|
|
2901
|
+
return {
|
|
2902
|
+
focusStrategy,
|
|
2903
|
+
isOpen,
|
|
2904
|
+
open,
|
|
2905
|
+
close,
|
|
2906
|
+
closeAll: () => state.close(),
|
|
2907
|
+
submenuLevel,
|
|
2908
|
+
setOpen() {},
|
|
2909
|
+
toggle,
|
|
2910
|
+
point: null,
|
|
2911
|
+
setPoint() {}
|
|
2753
2912
|
};
|
|
2754
2913
|
}
|
|
2755
2914
|
//#endregion
|
|
@@ -2773,18 +2932,22 @@ const dayOfWeekNames$1 = [
|
|
|
2773
2932
|
* Provides state management for a calendar component.
|
|
2774
2933
|
*/
|
|
2775
2934
|
function createCalendarState(props = {}) {
|
|
2935
|
+
const getProps = propsAccessor(props);
|
|
2776
2936
|
const timeZone = getLocalTimeZone$1();
|
|
2777
|
-
const locale = createMemo(() => access(
|
|
2778
|
-
const minValueState = createMemo(() => access(
|
|
2779
|
-
const maxValueState = createMemo(() => access(
|
|
2780
|
-
const selectionMode = createMemo(() => access(
|
|
2937
|
+
const locale = createMemo(() => access(getProps().locale) ?? "en-US");
|
|
2938
|
+
const minValueState = createMemo(() => access(getProps().minValue) ?? null);
|
|
2939
|
+
const maxValueState = createMemo(() => access(getProps().maxValue) ?? null);
|
|
2940
|
+
const selectionMode = createMemo(() => access(getProps().selectionMode) ?? "single");
|
|
2781
2941
|
const resolvedOptions = createMemo(() => new DateFormatter$1(locale()).resolvedOptions());
|
|
2782
|
-
const calendar = createMemo(() => (
|
|
2783
|
-
const visibleMonths = createMemo(() => Math.max(1, Number(access(
|
|
2784
|
-
const firstDayOfWeekName = () =>
|
|
2942
|
+
const calendar = createMemo(() => (getProps().createCalendar ?? createCalendar$1)(resolvedOptions().calendar));
|
|
2943
|
+
const visibleMonths = createMemo(() => Math.max(1, Number(access(getProps().visibleMonths) ?? 1)));
|
|
2944
|
+
const firstDayOfWeekName = () => {
|
|
2945
|
+
const firstDayOfWeek = getProps().firstDayOfWeek;
|
|
2946
|
+
return firstDayOfWeek == null ? void 0 : dayOfWeekNames$1[firstDayOfWeek];
|
|
2947
|
+
};
|
|
2785
2948
|
const toDisplayCalendarDate = (date) => toCalendar$1(toCalendarDate$3(date), calendar());
|
|
2786
2949
|
const selectionAlignmentOffset = () => {
|
|
2787
|
-
switch (
|
|
2950
|
+
switch (getProps().selectionAlignment) {
|
|
2788
2951
|
case "start": return 0;
|
|
2789
2952
|
case "end": return Math.max(visibleMonths() - 1, 0);
|
|
2790
2953
|
default: {
|
|
@@ -2794,9 +2957,26 @@ function createCalendarState(props = {}) {
|
|
|
2794
2957
|
}
|
|
2795
2958
|
}
|
|
2796
2959
|
};
|
|
2960
|
+
const rawAlignStart = (date) => startOfMonth$1(date);
|
|
2961
|
+
const rawAlignEnd = (date, months) => startOfMonth$1(date).subtract({ months: Math.max(months - 1, 0) });
|
|
2962
|
+
const constrainVisibleRangeStart = (date, aligned, months) => {
|
|
2963
|
+
const minValue = access(getProps().minValue);
|
|
2964
|
+
const maxValue = access(getProps().maxValue);
|
|
2965
|
+
let constrained = aligned;
|
|
2966
|
+
if (minValue && date.compare(toDisplayCalendarDate(minValue)) >= 0) {
|
|
2967
|
+
const minStart = rawAlignStart(toDisplayCalendarDate(minValue));
|
|
2968
|
+
if (minStart.compare(constrained) > 0) constrained = minStart;
|
|
2969
|
+
}
|
|
2970
|
+
if (maxValue && date.compare(toDisplayCalendarDate(maxValue)) <= 0) {
|
|
2971
|
+
const maxStart = rawAlignEnd(toDisplayCalendarDate(maxValue), months);
|
|
2972
|
+
if (maxStart.compare(constrained) < 0) constrained = maxStart;
|
|
2973
|
+
}
|
|
2974
|
+
return constrained;
|
|
2975
|
+
};
|
|
2797
2976
|
const alignVisibleRangeStart = (date) => {
|
|
2798
2977
|
const offset = selectionAlignmentOffset();
|
|
2799
|
-
|
|
2978
|
+
const aligned = rawAlignStart(offset > 0 ? date.subtract({ months: offset }) : date);
|
|
2979
|
+
return constrainVisibleRangeStart(date, aligned, visibleMonths());
|
|
2800
2980
|
};
|
|
2801
2981
|
const visibleRangeEnd = (start) => {
|
|
2802
2982
|
let end = endOfMonth$1(start);
|
|
@@ -2804,32 +2984,37 @@ function createCalendarState(props = {}) {
|
|
|
2804
2984
|
return end;
|
|
2805
2985
|
};
|
|
2806
2986
|
const constrainDate = (date) => {
|
|
2807
|
-
const minValue = access(
|
|
2808
|
-
const maxValue = access(
|
|
2987
|
+
const minValue = access(getProps().minValue);
|
|
2988
|
+
const maxValue = access(getProps().maxValue);
|
|
2809
2989
|
let constrained = date;
|
|
2810
2990
|
if (minValue && constrained.compare(toDisplayCalendarDate(minValue)) < 0) constrained = toDisplayCalendarDate(minValue);
|
|
2811
2991
|
if (maxValue && constrained.compare(toDisplayCalendarDate(maxValue)) > 0) constrained = toDisplayCalendarDate(maxValue);
|
|
2812
2992
|
return constrained;
|
|
2813
2993
|
};
|
|
2814
2994
|
const getInitialFocusedDate = () => {
|
|
2815
|
-
const controlledFocused = access(
|
|
2995
|
+
const controlledFocused = access(getProps().focusedValue);
|
|
2816
2996
|
if (controlledFocused) return toDisplayCalendarDate(controlledFocused);
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
const
|
|
2820
|
-
if (
|
|
2821
|
-
|
|
2822
|
-
|
|
2997
|
+
const defaultFocusedValue = getProps().defaultFocusedValue;
|
|
2998
|
+
if (defaultFocusedValue) return toDisplayCalendarDate(defaultFocusedValue);
|
|
2999
|
+
const controlledValue = access(getProps().value);
|
|
3000
|
+
if (controlledValue !== void 0) {
|
|
3001
|
+
const controlledFirst = Array.isArray(controlledValue) ? controlledValue[0] : controlledValue;
|
|
3002
|
+
if (controlledFirst) return toDisplayCalendarDate(controlledFirst);
|
|
3003
|
+
} else {
|
|
3004
|
+
const defaultValue = getProps().defaultValue;
|
|
3005
|
+
const defaultFirst = Array.isArray(defaultValue) ? defaultValue[0] : defaultValue;
|
|
3006
|
+
if (defaultFirst) return toDisplayCalendarDate(defaultFirst);
|
|
3007
|
+
}
|
|
2823
3008
|
return toCalendar$1(today$1(timeZone), calendar());
|
|
2824
3009
|
};
|
|
2825
3010
|
const initialFocusedDate = constrainDate(getInitialFocusedDate());
|
|
2826
|
-
const [internalValue, setInternalValue] = createInternalSignal(
|
|
3011
|
+
const [internalValue, setInternalValue] = createInternalSignal(getProps().defaultValue ?? null);
|
|
2827
3012
|
const [focusedDate, setFocusedDateInternal] = createInternalSignal(initialFocusedDate);
|
|
2828
3013
|
const [visibleRangeStart, setVisibleRangeStart] = createInternalSignal(alignVisibleRangeStart(initialFocusedDate));
|
|
2829
|
-
const [isFocused, setFocused] = createInternalSignal(
|
|
3014
|
+
const [isFocused, setFocused] = createInternalSignal(getProps().autoFocus ?? false);
|
|
2830
3015
|
const [isPaginating, setIsPaginating] = createInternalSignal(false);
|
|
2831
3016
|
const sourceValue = createMemo(() => {
|
|
2832
|
-
const controlled = access(
|
|
3017
|
+
const controlled = access(getProps().value);
|
|
2833
3018
|
return controlled !== void 0 ? controlled : internalValue();
|
|
2834
3019
|
});
|
|
2835
3020
|
const value = createMemo(() => {
|
|
@@ -2837,10 +3022,23 @@ function createCalendarState(props = {}) {
|
|
|
2837
3022
|
if (Array.isArray(currentValue)) return currentValue.map((v) => toDisplayCalendarDate(v));
|
|
2838
3023
|
return currentValue ? toDisplayCalendarDate(currentValue) : null;
|
|
2839
3024
|
});
|
|
2840
|
-
const isDisabled = createMemo(() => access(
|
|
2841
|
-
const isReadOnly = createMemo(() => access(
|
|
2842
|
-
const validationState = createMemo(() => access(
|
|
2843
|
-
const
|
|
3025
|
+
const isDisabled = createMemo(() => access(getProps().isDisabled) ?? false);
|
|
3026
|
+
const isReadOnly = createMemo(() => access(getProps().isReadOnly) ?? false);
|
|
3027
|
+
const validationState = createMemo(() => access(getProps().validationState));
|
|
3028
|
+
const isInvalidSelection = createMemo(() => {
|
|
3029
|
+
const current = value();
|
|
3030
|
+
if (current == null) return false;
|
|
3031
|
+
const dates = Array.isArray(current) ? current : [current];
|
|
3032
|
+
const min = access(getProps().minValue);
|
|
3033
|
+
const max = access(getProps().maxValue);
|
|
3034
|
+
const minCal = min != null ? toDisplayCalendarDate(min) : null;
|
|
3035
|
+
const maxCal = max != null ? toDisplayCalendarDate(max) : null;
|
|
3036
|
+
return dates.some((date) => {
|
|
3037
|
+
const cal = toDisplayCalendarDate(date);
|
|
3038
|
+
return Boolean(getProps().isDateUnavailable?.(cal)) || minCal != null && cal.compare(minCal) < 0 || maxCal != null && cal.compare(maxCal) > 0;
|
|
3039
|
+
});
|
|
3040
|
+
});
|
|
3041
|
+
const isValueInvalid = createMemo(() => Boolean(access(getProps().isInvalid)) || validationState() === "invalid" || isInvalidSelection());
|
|
2844
3042
|
const visibleRange = () => {
|
|
2845
3043
|
const start = visibleRangeStart();
|
|
2846
3044
|
return {
|
|
@@ -2849,11 +3047,11 @@ function createCalendarState(props = {}) {
|
|
|
2849
3047
|
};
|
|
2850
3048
|
};
|
|
2851
3049
|
const syncVisibleRangeForFocusedDate = (nextFocusedDate, range, months) => {
|
|
2852
|
-
if (nextFocusedDate.compare(range.start) < 0) setVisibleRangeStart(
|
|
2853
|
-
else if (nextFocusedDate.compare(range.end) > 0) setVisibleRangeStart(
|
|
3050
|
+
if (nextFocusedDate.compare(range.start) < 0) setVisibleRangeStart(constrainVisibleRangeStart(nextFocusedDate, rawAlignEnd(nextFocusedDate, months), months));
|
|
3051
|
+
else if (nextFocusedDate.compare(range.end) > 0) setVisibleRangeStart(constrainVisibleRangeStart(nextFocusedDate, rawAlignStart(nextFocusedDate), months));
|
|
2854
3052
|
};
|
|
2855
3053
|
createEffect(() => {
|
|
2856
|
-
const controlledFocused = access(
|
|
3054
|
+
const controlledFocused = access(getProps().focusedValue);
|
|
2857
3055
|
if (!controlledFocused) return null;
|
|
2858
3056
|
return {
|
|
2859
3057
|
nextFocusedDate: constrainDate(toDisplayCalendarDate(controlledFocused)),
|
|
@@ -2868,7 +3066,7 @@ function createCalendarState(props = {}) {
|
|
|
2868
3066
|
syncVisibleRangeForFocusedDate(nextFocusedDate, range, months);
|
|
2869
3067
|
});
|
|
2870
3068
|
createEffect(() => {
|
|
2871
|
-
if (access(
|
|
3069
|
+
if (access(getProps().focusedValue)) return null;
|
|
2872
3070
|
const currentFocusedDate = focusedDate();
|
|
2873
3071
|
const nextFocusedDate = constrainDate(currentFocusedDate);
|
|
2874
3072
|
if (nextFocusedDate.compare(currentFocusedDate) === 0 && isEqualCalendar(nextFocusedDate.calendar, currentFocusedDate.calendar)) return null;
|
|
@@ -2882,7 +3080,7 @@ function createCalendarState(props = {}) {
|
|
|
2882
3080
|
if (!data) return;
|
|
2883
3081
|
syncVisibleRangeForFocusedDate(data.nextFocusedDate, data.range, data.months);
|
|
2884
3082
|
setFocusedDateInternal(data.nextFocusedDate);
|
|
2885
|
-
|
|
3083
|
+
getProps().onFocusChange?.(data.nextFocusedDate);
|
|
2886
3084
|
});
|
|
2887
3085
|
createEffect(() => {
|
|
2888
3086
|
const currentFocusedDate = focusedDate();
|
|
@@ -2919,11 +3117,11 @@ function createCalendarState(props = {}) {
|
|
|
2919
3117
|
});
|
|
2920
3118
|
const normalizeValue = (newValue) => {
|
|
2921
3119
|
const constrained = constrainDate(newValue);
|
|
2922
|
-
const minBound = access(
|
|
2923
|
-
const prev = previousAvailableDate$1(constrained, minBound != null ? toDisplayCalendarDate(minBound) : minDate$1(constrained, visibleRange().start) ?? constrained,
|
|
3120
|
+
const minBound = access(getProps().minValue);
|
|
3121
|
+
const prev = previousAvailableDate$1(constrained, minBound != null ? toDisplayCalendarDate(minBound) : minDate$1(constrained, visibleRange().start) ?? constrained, getProps().isDateUnavailable);
|
|
2924
3122
|
if (!prev) return null;
|
|
2925
3123
|
const oldValue = sourceValue();
|
|
2926
|
-
return convertValue$
|
|
3124
|
+
return convertValue$5(prev, Array.isArray(oldValue) ? oldValue[0] ?? null : oldValue);
|
|
2927
3125
|
};
|
|
2928
3126
|
const setValue = (newValue) => {
|
|
2929
3127
|
if (isDisabled() || isReadOnly()) return;
|
|
@@ -2936,15 +3134,15 @@ function createCalendarState(props = {}) {
|
|
|
2936
3134
|
if (!localValue) return;
|
|
2937
3135
|
nextValue = localValue;
|
|
2938
3136
|
}
|
|
2939
|
-
if (access(
|
|
2940
|
-
if (!Object.is(oldValue, nextValue)
|
|
3137
|
+
if (access(getProps().value) === void 0) setInternalValue(() => nextValue);
|
|
3138
|
+
if (!Object.is(oldValue, nextValue)) getProps().onChange?.(nextValue);
|
|
2941
3139
|
};
|
|
2942
3140
|
const setFocusedDate = (date) => {
|
|
2943
3141
|
const constrained = constrainDate(date);
|
|
2944
3142
|
if (Object.is(constrained, focusedDate())) return;
|
|
2945
3143
|
syncVisibleRangeForFocusedDate(constrained, visibleRange(), visibleMonths());
|
|
2946
3144
|
setFocusedDateInternal(constrained);
|
|
2947
|
-
|
|
3145
|
+
getProps().onFocusChange?.(constrained);
|
|
2948
3146
|
};
|
|
2949
3147
|
const isSelected = (date) => {
|
|
2950
3148
|
const v = value();
|
|
@@ -2957,13 +3155,13 @@ function createCalendarState(props = {}) {
|
|
|
2957
3155
|
return isFocused() && isSameDay$1(toDisplayCalendarDate(date), focusedDate());
|
|
2958
3156
|
};
|
|
2959
3157
|
const isCellUnavailable = (date) => {
|
|
2960
|
-
return
|
|
3158
|
+
return getProps().isDateUnavailable?.(date) ?? false;
|
|
2961
3159
|
};
|
|
2962
3160
|
const isCellDisabled = (date) => {
|
|
2963
3161
|
if (isDisabled()) return true;
|
|
2964
|
-
if (
|
|
2965
|
-
const minValue = access(
|
|
2966
|
-
const maxValue = access(
|
|
3162
|
+
if (getProps().isDateDisabled?.(date)) return true;
|
|
3163
|
+
const minValue = access(getProps().minValue);
|
|
3164
|
+
const maxValue = access(getProps().maxValue);
|
|
2967
3165
|
const calDate = toDisplayCalendarDate(date);
|
|
2968
3166
|
const range = visibleRange();
|
|
2969
3167
|
if (calDate.compare(toDisplayCalendarDate(range.start)) < 0) return true;
|
|
@@ -3000,20 +3198,24 @@ function createCalendarState(props = {}) {
|
|
|
3000
3198
|
};
|
|
3001
3199
|
const focusPreviousPage = () => {
|
|
3002
3200
|
setIsPaginating(true);
|
|
3003
|
-
const pageMonths =
|
|
3004
|
-
const
|
|
3201
|
+
const pageMonths = getProps().pageBehavior === "single" ? 1 : visibleMonths();
|
|
3202
|
+
const currentFocused = focusedDate();
|
|
3203
|
+
const nextFocusedDate = constrainDate(currentFocused.subtract({ months: pageMonths }));
|
|
3204
|
+
const slidStart = startOfMonth$1(visibleRangeStart().subtract({ months: pageMonths }));
|
|
3005
3205
|
setFocusedDateInternal(nextFocusedDate);
|
|
3006
|
-
setVisibleRangeStart(
|
|
3007
|
-
|
|
3206
|
+
setVisibleRangeStart(constrainVisibleRangeStart(currentFocused, slidStart, pageMonths));
|
|
3207
|
+
getProps().onFocusChange?.(nextFocusedDate);
|
|
3008
3208
|
setIsPaginating(false);
|
|
3009
3209
|
};
|
|
3010
3210
|
const focusNextPage = () => {
|
|
3011
3211
|
setIsPaginating(true);
|
|
3012
|
-
const pageMonths =
|
|
3013
|
-
const
|
|
3212
|
+
const pageMonths = getProps().pageBehavior === "single" ? 1 : visibleMonths();
|
|
3213
|
+
const currentFocused = focusedDate();
|
|
3214
|
+
const nextFocusedDate = constrainDate(currentFocused.add({ months: pageMonths }));
|
|
3215
|
+
const slidStart = startOfMonth$1(visibleRangeStart().add({ months: pageMonths }));
|
|
3014
3216
|
setFocusedDateInternal(nextFocusedDate);
|
|
3015
|
-
setVisibleRangeStart(
|
|
3016
|
-
|
|
3217
|
+
setVisibleRangeStart(constrainVisibleRangeStart(currentFocused, slidStart, pageMonths));
|
|
3218
|
+
getProps().onFocusChange?.(nextFocusedDate);
|
|
3017
3219
|
setIsPaginating(false);
|
|
3018
3220
|
};
|
|
3019
3221
|
const focusPreviousSection = () => {
|
|
@@ -3048,7 +3250,7 @@ function createCalendarState(props = {}) {
|
|
|
3048
3250
|
const selectDate = (date) => {
|
|
3049
3251
|
if (isReadOnly() || isDisabled()) return;
|
|
3050
3252
|
if (selectionMode() === "multiple") {
|
|
3051
|
-
const current = access(
|
|
3253
|
+
const current = access(getProps().value) !== void 0 ? value() : readNow(internalValue);
|
|
3052
3254
|
const base = Array.isArray(current) ? current.map((v) => toDisplayCalendarDate(v)) : current != null ? [toDisplayCalendarDate(current)] : [];
|
|
3053
3255
|
const target = toDisplayCalendarDate(date);
|
|
3054
3256
|
const index = base.findIndex((d) => isSameDay$1(d, target));
|
|
@@ -3128,7 +3330,7 @@ function createCalendarState(props = {}) {
|
|
|
3128
3330
|
function toCalendarDate$3(date) {
|
|
3129
3331
|
return toCalendarDate$1(date);
|
|
3130
3332
|
}
|
|
3131
|
-
function convertValue$
|
|
3333
|
+
function convertValue$5(newValue, oldValue) {
|
|
3132
3334
|
const localValue = toCalendar$1(newValue, oldValue?.calendar ?? new GregorianCalendar$1());
|
|
3133
3335
|
if (oldValue && "hour" in oldValue) return oldValue.set(localValue);
|
|
3134
3336
|
return localValue;
|
|
@@ -4175,7 +4377,7 @@ function createDateFieldState(props = {}) {
|
|
|
4175
4377
|
if (access(props.value) === void 0) setInternalValue(() => v);
|
|
4176
4378
|
props.onChange?.(v);
|
|
4177
4379
|
};
|
|
4178
|
-
const calendarValue = createMemo(() => convertValue$
|
|
4380
|
+
const calendarValue = createMemo(() => convertValue$4(rawValue(), calendar()) ?? null);
|
|
4179
4381
|
const initialValue = untrack(calendarValue);
|
|
4180
4382
|
const [displayValue, setDisplayValue] = createInternalSignal(untrack(() => new IncompleteDate(calendar(), hourCycle(), untrack(calendarValue))));
|
|
4181
4383
|
let lastValue = untrack(calendarValue);
|
|
@@ -4477,13 +4679,13 @@ function getFormatOptions(fieldOptions, options) {
|
|
|
4477
4679
|
if (options.showEra && startIdx === 0) opts.era = "short";
|
|
4478
4680
|
return opts;
|
|
4479
4681
|
}
|
|
4480
|
-
function convertValue$
|
|
4682
|
+
function convertValue$4(value, calendar) {
|
|
4481
4683
|
if (value === null) return null;
|
|
4482
4684
|
if (!value) return void 0;
|
|
4483
4685
|
return toCalendar$1(value, calendar);
|
|
4484
4686
|
}
|
|
4485
4687
|
function createPlaceholderDate(placeholderValue, granularity, calendar, timeZone) {
|
|
4486
|
-
if (placeholderValue) return convertValue$
|
|
4688
|
+
if (placeholderValue) return convertValue$4(placeholderValue, calendar);
|
|
4487
4689
|
const date = toCalendar$1(now$1(timeZone ?? getLocalTimeZone$1()).set({
|
|
4488
4690
|
hour: 0,
|
|
4489
4691
|
minute: 0,
|
|
@@ -4601,8 +4803,8 @@ function createRangeCalendarState(props = {}) {
|
|
|
4601
4803
|
return end;
|
|
4602
4804
|
};
|
|
4603
4805
|
const rawAlignStart = (date) => startOfMonth$1(date);
|
|
4604
|
-
const rawAlignEnd = (date) => startOfMonth$1(date).subtract({ months: Math.max(
|
|
4605
|
-
const constrainVisibleRangeStart = (date, aligned) => {
|
|
4806
|
+
const rawAlignEnd = (date, months = visibleMonths()) => startOfMonth$1(date).subtract({ months: Math.max(months - 1, 0) });
|
|
4807
|
+
const constrainVisibleRangeStart = (date, aligned, months = visibleMonths()) => {
|
|
4606
4808
|
const minValue = access(props.minValue);
|
|
4607
4809
|
const maxValue = access(props.maxValue);
|
|
4608
4810
|
let constrained = aligned;
|
|
@@ -4611,7 +4813,7 @@ function createRangeCalendarState(props = {}) {
|
|
|
4611
4813
|
if (minStart.compare(constrained) > 0) constrained = minStart;
|
|
4612
4814
|
}
|
|
4613
4815
|
if (maxValue && date.compare(toDisplayCalendarDate(maxValue)) <= 0) {
|
|
4614
|
-
const maxStart = rawAlignEnd(toDisplayCalendarDate(maxValue));
|
|
4816
|
+
const maxStart = rawAlignEnd(toDisplayCalendarDate(maxValue), months);
|
|
4615
4817
|
if (maxStart.compare(constrained) < 0) constrained = maxStart;
|
|
4616
4818
|
}
|
|
4617
4819
|
return constrained;
|
|
@@ -4624,7 +4826,8 @@ function createRangeCalendarState(props = {}) {
|
|
|
4624
4826
|
return constrainVisibleRangeStart(date, rawAlignStart(date).subtract({ months: offset }));
|
|
4625
4827
|
};
|
|
4626
4828
|
const defaultSelectionAlignment = () => {
|
|
4627
|
-
const
|
|
4829
|
+
const controlled = access(props.value);
|
|
4830
|
+
const currentValue = controlled !== void 0 ? controlled : props.defaultValue;
|
|
4628
4831
|
if (!currentValue?.start || !currentValue?.end) return "center";
|
|
4629
4832
|
const start = alignCenter(toDisplayCalendarDate(currentValue.start));
|
|
4630
4833
|
const end = visibleRangeEndFromStart(start);
|
|
@@ -4642,8 +4845,9 @@ function createRangeCalendarState(props = {}) {
|
|
|
4642
4845
|
if (controlledFocused) return toDisplayCalendarDate(controlledFocused);
|
|
4643
4846
|
if (props.defaultFocusedValue) return toDisplayCalendarDate(props.defaultFocusedValue);
|
|
4644
4847
|
const controlledValue = access(props.value);
|
|
4645
|
-
if (controlledValue
|
|
4646
|
-
|
|
4848
|
+
if (controlledValue !== void 0) {
|
|
4849
|
+
if (controlledValue?.start) return toDisplayCalendarDate(controlledValue.start);
|
|
4850
|
+
} else if (props.defaultValue?.start) return toDisplayCalendarDate(props.defaultValue.start);
|
|
4647
4851
|
return toCalendar$1(today$1(timeZone), calendar());
|
|
4648
4852
|
};
|
|
4649
4853
|
const [internalValue, setInternalValue] = createInternalSignal(props.defaultValue ?? null);
|
|
@@ -4677,7 +4881,7 @@ function createRangeCalendarState(props = {}) {
|
|
|
4677
4881
|
const maxCal = max != null ? toDisplayCalendarDate(max) : null;
|
|
4678
4882
|
return isDateOutsideRange(toDisplayCalendarDate(v.start), minCal, maxCal) || isDateOutsideRange(toDisplayCalendarDate(v.end), minCal, maxCal);
|
|
4679
4883
|
});
|
|
4680
|
-
const isValueInvalid = createMemo(() => validationState() === "invalid" || isInvalidSelection());
|
|
4884
|
+
const isValueInvalid = createMemo(() => Boolean(access(props.isInvalid)) || validationState() === "invalid" || isInvalidSelection());
|
|
4681
4885
|
const highlightedRange = createMemo(() => {
|
|
4682
4886
|
const anchor = anchorDate();
|
|
4683
4887
|
if (!anchor) {
|
|
@@ -4778,8 +4982,8 @@ function createRangeCalendarState(props = {}) {
|
|
|
4778
4982
|
if (isDisabled() || isReadOnly()) return;
|
|
4779
4983
|
const oldValue = sourceValue();
|
|
4780
4984
|
const nextValue = newValue ? {
|
|
4781
|
-
start: convertValue$
|
|
4782
|
-
end: convertValue$
|
|
4985
|
+
start: convertValue$3(constrainDate(toDisplayCalendarDate(newValue.start)), oldValue?.start),
|
|
4986
|
+
end: convertValue$3(constrainDate(toDisplayCalendarDate(newValue.end)), oldValue?.end)
|
|
4783
4987
|
} : null;
|
|
4784
4988
|
if (access(props.value) === void 0) setInternalValue(() => nextValue);
|
|
4785
4989
|
if (!Object.is(oldValue, nextValue) && props.onChange) props.onChange(nextValue);
|
|
@@ -4844,16 +5048,20 @@ function createRangeCalendarState(props = {}) {
|
|
|
4844
5048
|
};
|
|
4845
5049
|
const focusPreviousPage = () => {
|
|
4846
5050
|
const pageMonths = access(props.pageBehavior) === "single" ? 1 : visibleMonths();
|
|
4847
|
-
const
|
|
5051
|
+
const currentFocused = focusedDate();
|
|
5052
|
+
const nextFocusedDate = constrainDate(currentFocused.subtract({ months: pageMonths }));
|
|
5053
|
+
const slidStart = startOfMonth$1(visibleRangeStart().subtract({ months: pageMonths }));
|
|
4848
5054
|
setFocusedDateInternal(nextFocusedDate);
|
|
4849
|
-
setVisibleRangeStart(
|
|
5055
|
+
setVisibleRangeStart(constrainVisibleRangeStart(currentFocused, slidStart, pageMonths));
|
|
4850
5056
|
props.onFocusChange?.(nextFocusedDate);
|
|
4851
5057
|
};
|
|
4852
5058
|
const focusNextPage = () => {
|
|
4853
5059
|
const pageMonths = access(props.pageBehavior) === "single" ? 1 : visibleMonths();
|
|
4854
|
-
const
|
|
5060
|
+
const currentFocused = focusedDate();
|
|
5061
|
+
const nextFocusedDate = constrainDate(currentFocused.add({ months: pageMonths }));
|
|
5062
|
+
const slidStart = startOfMonth$1(visibleRangeStart().add({ months: pageMonths }));
|
|
4855
5063
|
setFocusedDateInternal(nextFocusedDate);
|
|
4856
|
-
setVisibleRangeStart(
|
|
5064
|
+
setVisibleRangeStart(constrainVisibleRangeStart(currentFocused, slidStart, pageMonths));
|
|
4857
5065
|
props.onFocusChange?.(nextFocusedDate);
|
|
4858
5066
|
};
|
|
4859
5067
|
const focusPreviousSection = () => {
|
|
@@ -4936,7 +5144,14 @@ function createRangeCalendarState(props = {}) {
|
|
|
4936
5144
|
return week;
|
|
4937
5145
|
};
|
|
4938
5146
|
const focusNearestAvailableDate = (anchor) => {
|
|
4939
|
-
const
|
|
5147
|
+
const passedRange = getAvailableRange(anchor);
|
|
5148
|
+
const isDateInvalid = (candidate) => {
|
|
5149
|
+
if (isDateOutsideAllowedRange(candidate)) return true;
|
|
5150
|
+
const calDate = toDisplayCalendarDate(candidate);
|
|
5151
|
+
if (passedRange?.start && calDate.compare(passedRange.start) < 0) return true;
|
|
5152
|
+
if (passedRange?.end && calDate.compare(passedRange.end) > 0) return true;
|
|
5153
|
+
return false;
|
|
5154
|
+
};
|
|
4940
5155
|
let nextDay = anchor.add({ days: 1 });
|
|
4941
5156
|
if (isDateInvalid(nextDay)) nextDay = anchor.subtract({ days: 1 });
|
|
4942
5157
|
if (!isDateInvalid(nextDay)) {
|
|
@@ -5058,7 +5273,7 @@ function createRangeCalendarState(props = {}) {
|
|
|
5058
5273
|
function toCalendarDate$2(date) {
|
|
5059
5274
|
return toCalendarDate$1(date);
|
|
5060
5275
|
}
|
|
5061
|
-
function convertValue$
|
|
5276
|
+
function convertValue$3(newValue, oldValue) {
|
|
5062
5277
|
const localValue = toCalendar$1(newValue, oldValue?.calendar ?? new GregorianCalendar$1());
|
|
5063
5278
|
if (oldValue && "hour" in oldValue) return oldValue.set(localValue);
|
|
5064
5279
|
return localValue;
|
|
@@ -5122,7 +5337,7 @@ function nextUnavailableDate(anchorDate, isDateUnavailable, visibleMonths, dir)
|
|
|
5122
5337
|
* that already carry a date (`CalendarDateTime`/`ZonedDateTime`) pass through.
|
|
5123
5338
|
* Mirrors `@react-stately/datepicker`'s `convertValue`.
|
|
5124
5339
|
*/
|
|
5125
|
-
function convertValue(value, date = today$1(getLocalTimeZone$1())) {
|
|
5340
|
+
function convertValue$2(value, date = today$1(getLocalTimeZone$1())) {
|
|
5126
5341
|
if (!value) return null;
|
|
5127
5342
|
if ("day" in value) return value;
|
|
5128
5343
|
return toCalendarDateTime$1(date, value);
|
|
@@ -5146,20 +5361,20 @@ function createTimeFieldState(props = {}) {
|
|
|
5146
5361
|
const placeholderDate = createMemo(() => {
|
|
5147
5362
|
const current = v();
|
|
5148
5363
|
const zone = (current && "timeZone" in current ? current.timeZone : void 0) || defaultValueTimeZone;
|
|
5149
|
-
if (zone && placeholderValue) return toZoned$1(convertValue(placeholderValue), zone);
|
|
5150
|
-
return convertValue(placeholderValue);
|
|
5364
|
+
if (zone && placeholderValue) return toZoned$1(convertValue$2(placeholderValue), zone);
|
|
5365
|
+
return convertValue$2(placeholderValue);
|
|
5151
5366
|
});
|
|
5152
|
-
const minDate = createMemo(() => convertValue(access(props.minValue), day()) ?? void 0);
|
|
5153
|
-
const maxDate = createMemo(() => convertValue(access(props.maxValue), day()) ?? void 0);
|
|
5367
|
+
const minDate = createMemo(() => convertValue$2(access(props.minValue), day()) ?? void 0);
|
|
5368
|
+
const maxDate = createMemo(() => convertValue$2(access(props.maxValue), day()) ?? void 0);
|
|
5154
5369
|
const timeValue = createMemo(() => {
|
|
5155
5370
|
const current = value();
|
|
5156
5371
|
return current && "day" in current ? toTime$1(current) : current;
|
|
5157
5372
|
});
|
|
5158
5373
|
const dateTime = createMemo(() => {
|
|
5159
5374
|
const current = value();
|
|
5160
|
-
return current == null ? null : convertValue(current);
|
|
5375
|
+
return current == null ? null : convertValue$2(current);
|
|
5161
5376
|
});
|
|
5162
|
-
const defaultDateTime = props.defaultValue == null ? null : convertValue(props.defaultValue);
|
|
5377
|
+
const defaultDateTime = props.defaultValue == null ? null : convertValue$2(props.defaultValue);
|
|
5163
5378
|
const onChange = (newValue) => {
|
|
5164
5379
|
const converted = day() || defaultValueTimeZone ? newValue : newValue && toTime$1(newValue);
|
|
5165
5380
|
if (access(props.value) === void 0) setInternalValue(() => converted);
|
|
@@ -5274,16 +5489,16 @@ function createDatePickerState(props = {}) {
|
|
|
5274
5489
|
const isReadOnly = createMemo(() => access(props.isReadOnly) ?? false);
|
|
5275
5490
|
const validationState = createMemo(() => access(props.validationState));
|
|
5276
5491
|
const isOpen = () => access(props.isOpen) ?? readNow(internalOpen);
|
|
5277
|
-
const dateValue =
|
|
5278
|
-
const
|
|
5279
|
-
if (
|
|
5280
|
-
return
|
|
5281
|
-
}
|
|
5282
|
-
const timeValue =
|
|
5283
|
-
const
|
|
5284
|
-
if (
|
|
5285
|
-
return
|
|
5286
|
-
}
|
|
5492
|
+
const dateValue = () => {
|
|
5493
|
+
const committed = value();
|
|
5494
|
+
if (committed) return committed;
|
|
5495
|
+
return selectedDate();
|
|
5496
|
+
};
|
|
5497
|
+
const timeValue = () => {
|
|
5498
|
+
const committed = value();
|
|
5499
|
+
if (committed && "hour" in committed) return committed;
|
|
5500
|
+
return selectedTime();
|
|
5501
|
+
};
|
|
5287
5502
|
const getPlaceholderTime = () => {
|
|
5288
5503
|
const placeholder = props.placeholderValue;
|
|
5289
5504
|
if (placeholder && "hour" in placeholder) return placeholder;
|
|
@@ -5409,12 +5624,17 @@ function createDatePickerState(props = {}) {
|
|
|
5409
5624
|
* State management for select components.
|
|
5410
5625
|
* Based on @react-stately/select useSelectState.
|
|
5411
5626
|
*/
|
|
5627
|
+
function convertValue$1(value) {
|
|
5628
|
+
if (value === void 0) return void 0;
|
|
5629
|
+
if (value === null || typeof value === "string" || typeof value === "number") return value == null ? [] : [value];
|
|
5630
|
+
return value;
|
|
5631
|
+
}
|
|
5412
5632
|
/**
|
|
5413
5633
|
* Creates state for a select component.
|
|
5414
5634
|
* Combines list state with overlay trigger state for dropdown behavior.
|
|
5415
5635
|
*/
|
|
5416
5636
|
function createSelectState(props) {
|
|
5417
|
-
const getProps = (
|
|
5637
|
+
const getProps = propsAccessor(props);
|
|
5418
5638
|
const selectionMode = () => getProps().selectionMode ?? "single";
|
|
5419
5639
|
const overlayState = createOverlayTriggerState({
|
|
5420
5640
|
get isOpen() {
|
|
@@ -5427,61 +5647,85 @@ function createSelectState(props) {
|
|
|
5427
5647
|
return getProps().onOpenChange;
|
|
5428
5648
|
}
|
|
5429
5649
|
});
|
|
5430
|
-
const
|
|
5431
|
-
|
|
5432
|
-
|
|
5433
|
-
|
|
5434
|
-
|
|
5435
|
-
|
|
5436
|
-
|
|
5437
|
-
|
|
5438
|
-
|
|
5439
|
-
}
|
|
5440
|
-
return isControlledSingle() ? getProps().selectedKey ?? null : internalSelectedKey();
|
|
5650
|
+
const resolvedDefault = untrack(() => {
|
|
5651
|
+
const current = getProps();
|
|
5652
|
+
if (current.defaultValue !== void 0) return current.defaultValue;
|
|
5653
|
+
return (current.selectionMode ?? "single") === "single" ? current.defaultSelectedKey ?? null : [];
|
|
5654
|
+
});
|
|
5655
|
+
const controlledProp = () => {
|
|
5656
|
+
const current = getProps();
|
|
5657
|
+
if (current.value !== void 0) return current.value;
|
|
5658
|
+
if (selectionMode() === "single" && current.selectedKey !== void 0) return current.selectedKey ?? null;
|
|
5441
5659
|
};
|
|
5442
|
-
const
|
|
5443
|
-
|
|
5444
|
-
|
|
5445
|
-
|
|
5446
|
-
|
|
5447
|
-
|
|
5448
|
-
|
|
5449
|
-
|
|
5450
|
-
|
|
5451
|
-
|
|
5660
|
+
const [internalValue, setInternalValue] = createInternalSignal(resolvedDefault);
|
|
5661
|
+
const readControlled = () => {
|
|
5662
|
+
const controlled = controlledProp();
|
|
5663
|
+
return controlled === void 0 ? void 0 : controlled;
|
|
5664
|
+
};
|
|
5665
|
+
let valueRef = untrack(() => {
|
|
5666
|
+
const controlled = readControlled();
|
|
5667
|
+
return controlled !== void 0 ? controlled : internalValue();
|
|
5668
|
+
});
|
|
5669
|
+
let wroteThisTurn = false;
|
|
5670
|
+
const syncValueRef = () => {
|
|
5671
|
+
if (wroteThisTurn) return;
|
|
5672
|
+
const controlled = readControlled();
|
|
5673
|
+
valueRef = controlled !== void 0 ? controlled : untrack(internalValue);
|
|
5674
|
+
};
|
|
5675
|
+
const displayValue = () => {
|
|
5676
|
+
const controlled = readControlled();
|
|
5677
|
+
const raw = controlled !== void 0 ? controlled : internalValue();
|
|
5678
|
+
if (selectionMode() === "single" && raw !== null && typeof raw !== "string" && typeof raw !== "number") return raw[0] ?? null;
|
|
5679
|
+
return raw;
|
|
5680
|
+
};
|
|
5681
|
+
const setValue = (next) => {
|
|
5682
|
+
syncValueRef();
|
|
5683
|
+
if (selectionMode() === "single") {
|
|
5684
|
+
const key = typeof next === "string" || typeof next === "number" ? next : next === null ? null : next[0] ?? null;
|
|
5685
|
+
if (!Object.is(valueRef, key)) {
|
|
5686
|
+
valueRef = key;
|
|
5687
|
+
wroteThisTurn = true;
|
|
5688
|
+
queueMicrotask(() => {
|
|
5689
|
+
wroteThisTurn = false;
|
|
5690
|
+
});
|
|
5691
|
+
if (controlledProp() === void 0) setInternalValue(key);
|
|
5692
|
+
getProps().onChange?.(key);
|
|
5452
5693
|
getProps().onSelectionChange?.(key);
|
|
5453
5694
|
}
|
|
5454
5695
|
return;
|
|
5455
5696
|
}
|
|
5456
|
-
|
|
5457
|
-
|
|
5458
|
-
|
|
5459
|
-
|
|
5460
|
-
|
|
5461
|
-
|
|
5462
|
-
|
|
5463
|
-
|
|
5464
|
-
|
|
5465
|
-
}
|
|
5466
|
-
return internalSelectedKeys();
|
|
5697
|
+
const keys = typeof next === "string" || typeof next === "number" ? [next] : next === null ? [] : next;
|
|
5698
|
+
if (!Object.is(valueRef, keys)) {
|
|
5699
|
+
valueRef = keys;
|
|
5700
|
+
wroteThisTurn = true;
|
|
5701
|
+
queueMicrotask(() => {
|
|
5702
|
+
wroteThisTurn = false;
|
|
5703
|
+
});
|
|
5704
|
+
if (controlledProp() === void 0) setInternalValue(keys);
|
|
5705
|
+
getProps().onChange?.([...keys]);
|
|
5467
5706
|
}
|
|
5468
|
-
|
|
5469
|
-
return key != null ? /* @__PURE__ */ new Set([key]) : /* @__PURE__ */ new Set();
|
|
5470
|
-
});
|
|
5707
|
+
};
|
|
5471
5708
|
const setSelectedKeys = (keys) => {
|
|
5472
|
-
const next = new Set(keys);
|
|
5473
5709
|
if (selectionMode() === "multiple") {
|
|
5474
|
-
|
|
5475
|
-
getProps().onSelectionChangeKeys?.(next);
|
|
5476
|
-
getProps().onSelectionChange?.(next.size > 0 ? Array.from(next)[0] : null);
|
|
5710
|
+
setValue([...keys]);
|
|
5477
5711
|
return;
|
|
5478
5712
|
}
|
|
5479
|
-
|
|
5480
|
-
|
|
5713
|
+
let key = null;
|
|
5714
|
+
for (const item of keys) {
|
|
5715
|
+
key = item;
|
|
5716
|
+
break;
|
|
5717
|
+
}
|
|
5718
|
+
setValue(key);
|
|
5481
5719
|
};
|
|
5720
|
+
const initialDisplay = untrack(displayValue);
|
|
5721
|
+
const stateDefaultValue = resolvedDefault ?? initialDisplay;
|
|
5722
|
+
const defaultSelectedKey = untrack(() => getProps().defaultSelectedKey) ?? (untrack(() => getProps().selectionMode) === "single" ? initialDisplay : null);
|
|
5723
|
+
const shouldCloseOnSelect = () => getProps().shouldCloseOnSelect ?? selectionMode() === "single";
|
|
5482
5724
|
const validation = createFormValidationState({
|
|
5483
5725
|
get value() {
|
|
5484
|
-
|
|
5726
|
+
const display = displayValue();
|
|
5727
|
+
if (display !== null && typeof display !== "string" && typeof display !== "number" && display.length === 0) return null;
|
|
5728
|
+
return display;
|
|
5485
5729
|
},
|
|
5486
5730
|
get isInvalid() {
|
|
5487
5731
|
return getProps().isInvalid;
|
|
@@ -5523,41 +5767,34 @@ function createSelectState(props) {
|
|
|
5523
5767
|
},
|
|
5524
5768
|
allowDuplicateSelectionEvents: true,
|
|
5525
5769
|
get selectedKeys() {
|
|
5526
|
-
|
|
5527
|
-
if (keys === "all") return "all";
|
|
5528
|
-
return keys;
|
|
5770
|
+
return convertValue$1(displayValue()) ?? [];
|
|
5529
5771
|
},
|
|
5530
5772
|
onSelectionChange(keys) {
|
|
5531
|
-
if (selectionMode() === "multiple") {
|
|
5532
|
-
if (!isControlledMultiple()) setInternalSelectedKeys(keys);
|
|
5533
|
-
getProps().onSelectionChangeKeys?.(keys);
|
|
5534
|
-
if (keys !== "all") getProps().onSelectionChange?.(keys.size > 0 ? Array.from(keys)[0] : null);
|
|
5535
|
-
validation.commitValidation();
|
|
5536
|
-
return;
|
|
5537
|
-
}
|
|
5538
5773
|
if (keys === "all") return;
|
|
5539
|
-
|
|
5540
|
-
|
|
5541
|
-
overlayState.close();
|
|
5774
|
+
if (selectionMode() === "single") setValue(keys.values().next().value ?? null);
|
|
5775
|
+
else setValue([...keys]);
|
|
5776
|
+
if (shouldCloseOnSelect()) overlayState.close();
|
|
5542
5777
|
validation.commitValidation();
|
|
5543
5778
|
}
|
|
5544
5779
|
});
|
|
5780
|
+
const [focusStrategy, setFocusStrategy] = createInternalSignal(null);
|
|
5545
5781
|
const [isFocused, setFocused] = createInternalSignal(false);
|
|
5782
|
+
const selectedKey = () => listState.selectionManager.firstSelectedKey;
|
|
5783
|
+
const selectedKeys = () => new Set(convertValue$1(displayValue()) ?? []);
|
|
5546
5784
|
const selectedItem = createMemo(() => {
|
|
5547
5785
|
const key = selectedKey();
|
|
5548
5786
|
if (key == null) return null;
|
|
5549
5787
|
return listState.collection().getItem(key);
|
|
5550
5788
|
});
|
|
5551
5789
|
const selectedItems = createMemo(() => {
|
|
5552
|
-
const keys = selectedKeys();
|
|
5553
|
-
if (keys === "all") return Array.from(listState.collection());
|
|
5554
5790
|
const items = [];
|
|
5555
|
-
for (const key of
|
|
5791
|
+
for (const key of listState.selectionManager.selectedKeys) {
|
|
5556
5792
|
const item = listState.collection().getItem(key);
|
|
5557
5793
|
if (item) items.push(item);
|
|
5558
5794
|
}
|
|
5559
5795
|
return items;
|
|
5560
5796
|
});
|
|
5797
|
+
const canOpenMenu = () => listState.collection().size !== 0 || getProps().allowsEmptyCollection === true;
|
|
5561
5798
|
return {
|
|
5562
5799
|
realtimeValidation: validation.realtimeValidation,
|
|
5563
5800
|
displayValidation: validation.displayValidation,
|
|
@@ -5571,15 +5808,29 @@ function createSelectState(props) {
|
|
|
5571
5808
|
isFocused,
|
|
5572
5809
|
setFocused,
|
|
5573
5810
|
isOpen: overlayState.isOpen,
|
|
5574
|
-
open
|
|
5811
|
+
open(strategy = null) {
|
|
5812
|
+
if (!canOpenMenu()) return;
|
|
5813
|
+
setFocusStrategy(strategy);
|
|
5814
|
+
overlayState.open();
|
|
5815
|
+
},
|
|
5575
5816
|
close: overlayState.close,
|
|
5576
|
-
toggle
|
|
5817
|
+
toggle(strategy = null) {
|
|
5818
|
+
if (!canOpenMenu()) return;
|
|
5819
|
+
setFocusStrategy(strategy);
|
|
5820
|
+
overlayState.toggle();
|
|
5821
|
+
},
|
|
5822
|
+
focusStrategy,
|
|
5577
5823
|
selectionMode,
|
|
5824
|
+
shouldCloseOnSelect,
|
|
5825
|
+
value: () => displayValue(),
|
|
5826
|
+
defaultValue: stateDefaultValue,
|
|
5827
|
+
setValue,
|
|
5578
5828
|
selectedKey,
|
|
5829
|
+
defaultSelectedKey,
|
|
5830
|
+
setSelectedKey: setValue,
|
|
5579
5831
|
selectedKeys,
|
|
5580
5832
|
selectedItem,
|
|
5581
5833
|
selectedItems,
|
|
5582
|
-
setSelectedKey,
|
|
5583
5834
|
setSelectedKeys,
|
|
5584
5835
|
isKeyDisabled: (key) => listState.isDisabled(key),
|
|
5585
5836
|
get isDisabled() {
|
|
@@ -5599,6 +5850,7 @@ function createSelectState(props) {
|
|
|
5599
5850
|
* ComboBox combines a text input with a dropdown list, allowing users to
|
|
5600
5851
|
* either type to filter options or select from a list.
|
|
5601
5852
|
*/
|
|
5853
|
+
const EMPTY_COMBOBOX_KEYS = [];
|
|
5602
5854
|
/**
|
|
5603
5855
|
* Default filter function that does case-insensitive "contains" matching.
|
|
5604
5856
|
*/
|
|
@@ -5610,26 +5862,28 @@ const defaultContainsFilter = (textValue, inputValue) => {
|
|
|
5610
5862
|
* Combines list state with input value management and filtering.
|
|
5611
5863
|
*/
|
|
5612
5864
|
function createComboBoxState(props) {
|
|
5613
|
-
const getProps = (
|
|
5865
|
+
const getProps = propsAccessor(props);
|
|
5614
5866
|
const menuTrigger = () => getProps().menuTrigger ?? "input";
|
|
5615
5867
|
const allowsEmptyCollection = () => getProps().allowsEmptyCollection ?? false;
|
|
5616
5868
|
const allowsCustomValue = () => getProps().allowsCustomValue ?? false;
|
|
5617
5869
|
const shouldCloseOnBlur = () => getProps().shouldCloseOnBlur ?? true;
|
|
5618
|
-
const isMultiple = () => getProps().selectionMode === "multiple";
|
|
5870
|
+
const isMultiple = () => (getProps().selectionMode ?? "single") === "multiple";
|
|
5619
5871
|
const [focusStrategy, setFocusStrategy] = createInternalSignal(null);
|
|
5620
5872
|
const [showAllItems, setShowAllItems] = createInternalSignal(false);
|
|
5621
5873
|
let menuOpenTrigger = "focus";
|
|
5622
|
-
const
|
|
5623
|
-
|
|
5624
|
-
|
|
5625
|
-
|
|
5626
|
-
};
|
|
5627
|
-
const
|
|
5628
|
-
|
|
5629
|
-
getProps()
|
|
5630
|
-
|
|
5631
|
-
|
|
5632
|
-
|
|
5874
|
+
const controlledPropValue = () => {
|
|
5875
|
+
const propsNow = getProps();
|
|
5876
|
+
if (propsNow.value !== void 0) return propsNow.value;
|
|
5877
|
+
if (!isMultiple() && propsNow.selectedKey !== void 0) return propsNow.selectedKey;
|
|
5878
|
+
};
|
|
5879
|
+
const isValueControlled = () => controlledPropValue() !== void 0;
|
|
5880
|
+
const initialStoredValue = () => {
|
|
5881
|
+
const propsNow = getProps();
|
|
5882
|
+
if (propsNow.defaultValue !== void 0) return propsNow.defaultValue;
|
|
5883
|
+
if ((propsNow.selectionMode ?? "single") === "multiple") return [];
|
|
5884
|
+
return propsNow.defaultSelectedKey ?? null;
|
|
5885
|
+
};
|
|
5886
|
+
const [internalValue, setInternalValue] = createInternalSignal(initialStoredValue());
|
|
5633
5887
|
const isInputControlled = () => getProps().inputValue !== void 0;
|
|
5634
5888
|
const [internalInputValue, setInternalInputValue] = createInternalSignal(getProps().defaultInputValue ?? "");
|
|
5635
5889
|
let inputInitialized = false;
|
|
@@ -5641,13 +5895,77 @@ function createComboBoxState(props) {
|
|
|
5641
5895
|
getProps().onInputChange?.(value);
|
|
5642
5896
|
};
|
|
5643
5897
|
const [lastValue, setLastValue] = createInternalSignal(inputValue());
|
|
5898
|
+
const storedValue = () => {
|
|
5899
|
+
const controlled = controlledPropValue();
|
|
5900
|
+
return controlled !== void 0 ? controlled : internalValue();
|
|
5901
|
+
};
|
|
5902
|
+
const displayValue = () => {
|
|
5903
|
+
const current = storedValue();
|
|
5904
|
+
if (!isMultiple()) return isKeyList(current) ? current[0] ?? null : current;
|
|
5905
|
+
if (isKeyList(current)) return current;
|
|
5906
|
+
if (current == null) return EMPTY_COMBOBOX_KEYS;
|
|
5907
|
+
return [current];
|
|
5908
|
+
};
|
|
5644
5909
|
const selectedKey = () => {
|
|
5645
|
-
|
|
5910
|
+
if (isMultiple()) return null;
|
|
5911
|
+
const current = displayValue();
|
|
5912
|
+
return isKeyList(current) ? current[0] ?? null : current;
|
|
5646
5913
|
};
|
|
5647
|
-
const
|
|
5648
|
-
|
|
5649
|
-
|
|
5914
|
+
const selectedKeys = () => {
|
|
5915
|
+
const current = displayValue();
|
|
5916
|
+
if (isKeyList(current)) return new Set(current);
|
|
5917
|
+
return current == null ? /* @__PURE__ */ new Set() : /* @__PURE__ */ new Set([current]);
|
|
5918
|
+
};
|
|
5919
|
+
const setValue = (next) => {
|
|
5920
|
+
if (!isMultiple()) {
|
|
5921
|
+
const key = typeof next === "string" || typeof next === "number" ? next : next === null ? null : next[0] ?? null;
|
|
5922
|
+
const previous = untrack(selectedKey);
|
|
5923
|
+
if (!isValueControlled()) setInternalValue(key);
|
|
5924
|
+
getProps().onChange?.(key);
|
|
5925
|
+
if (key !== previous) getProps().onSelectionChange?.(key);
|
|
5926
|
+
return;
|
|
5927
|
+
}
|
|
5928
|
+
const keys = typeof next === "string" || typeof next === "number" ? [next] : next === null ? [] : [...next];
|
|
5929
|
+
if (!isValueControlled()) setInternalValue(keys);
|
|
5930
|
+
getProps().onChange?.([...keys]);
|
|
5650
5931
|
};
|
|
5932
|
+
const setSelectedKey = (key) => {
|
|
5933
|
+
setValue(key);
|
|
5934
|
+
};
|
|
5935
|
+
const defaultValue = (() => {
|
|
5936
|
+
const propsNow = getProps();
|
|
5937
|
+
return (propsNow.defaultValue !== void 0 ? propsNow.defaultValue : isMultiple() ? EMPTY_COMBOBOX_KEYS : propsNow.defaultSelectedKey ?? null) ?? untrack(displayValue);
|
|
5938
|
+
})();
|
|
5939
|
+
const defaultSelectedKey = getProps().defaultSelectedKey ?? (isMultiple() ? null : untrack(displayValue));
|
|
5940
|
+
const validationValue = createMemo(() => {
|
|
5941
|
+
const dVal = displayValue();
|
|
5942
|
+
if (isKeyList(dVal) && dVal.length === 0) return null;
|
|
5943
|
+
return {
|
|
5944
|
+
inputValue: inputValue(),
|
|
5945
|
+
value: isKeyList(dVal) ? [...dVal] : dVal,
|
|
5946
|
+
selectedKey: selectedKey()
|
|
5947
|
+
};
|
|
5948
|
+
});
|
|
5949
|
+
const validation = createFormValidationState({
|
|
5950
|
+
get value() {
|
|
5951
|
+
return validationValue();
|
|
5952
|
+
},
|
|
5953
|
+
get isInvalid() {
|
|
5954
|
+
return getProps().isInvalid;
|
|
5955
|
+
},
|
|
5956
|
+
get validationState() {
|
|
5957
|
+
return getProps().validationState;
|
|
5958
|
+
},
|
|
5959
|
+
get validate() {
|
|
5960
|
+
return getProps().validate;
|
|
5961
|
+
},
|
|
5962
|
+
get name() {
|
|
5963
|
+
return getProps().name;
|
|
5964
|
+
},
|
|
5965
|
+
get validationBehavior() {
|
|
5966
|
+
return getProps().validationBehavior ?? "native";
|
|
5967
|
+
}
|
|
5968
|
+
});
|
|
5651
5969
|
let listState;
|
|
5652
5970
|
const overlayState = createOverlayTriggerState({
|
|
5653
5971
|
get isOpen() {
|
|
@@ -5681,26 +5999,27 @@ function createComboBoxState(props) {
|
|
|
5681
5999
|
get selectionMode() {
|
|
5682
6000
|
return isMultiple() ? "multiple" : "single";
|
|
5683
6001
|
},
|
|
5684
|
-
disallowEmptySelection
|
|
6002
|
+
get disallowEmptySelection() {
|
|
6003
|
+
return !isMultiple();
|
|
6004
|
+
},
|
|
6005
|
+
allowDuplicateSelectionEvents: true,
|
|
5685
6006
|
get selectedKeys() {
|
|
5686
|
-
|
|
5687
|
-
const key = selectedKey();
|
|
5688
|
-
return key != null ? [key] : [];
|
|
6007
|
+
return convertValue(displayValue());
|
|
5689
6008
|
},
|
|
5690
6009
|
onSelectionChange(keys) {
|
|
5691
6010
|
if (keys === "all") return;
|
|
5692
6011
|
if (isMultiple()) {
|
|
5693
|
-
|
|
5694
|
-
setSelectedKeys(newKeys);
|
|
6012
|
+
setValue([...keys]);
|
|
5695
6013
|
return;
|
|
5696
6014
|
}
|
|
5697
6015
|
const key = keys.size > 0 ? Array.from(keys)[0] : null;
|
|
5698
6016
|
if (key === selectedKey()) {
|
|
6017
|
+
getProps().onSelectionChange?.(key);
|
|
5699
6018
|
resetInputValue();
|
|
5700
6019
|
closeMenu();
|
|
5701
6020
|
return;
|
|
5702
6021
|
}
|
|
5703
|
-
|
|
6022
|
+
setValue(key);
|
|
5704
6023
|
}
|
|
5705
6024
|
});
|
|
5706
6025
|
const originalCollection = listState.collection;
|
|
@@ -5729,18 +6048,21 @@ function createComboBoxState(props) {
|
|
|
5729
6048
|
return items;
|
|
5730
6049
|
});
|
|
5731
6050
|
if (!inputInitialized && !isInputControlled()) {
|
|
5732
|
-
|
|
5733
|
-
|
|
5734
|
-
|
|
5735
|
-
|
|
5736
|
-
|
|
5737
|
-
|
|
6051
|
+
if (getProps().defaultInputValue == null && !isMultiple()) {
|
|
6052
|
+
const key = selectedKey();
|
|
6053
|
+
if (key != null) {
|
|
6054
|
+
const item = originalCollection().getItem(key);
|
|
6055
|
+
if (item) {
|
|
6056
|
+
setInternalInputValue(item.textValue);
|
|
6057
|
+
setLastValue(item.textValue);
|
|
6058
|
+
}
|
|
5738
6059
|
}
|
|
5739
6060
|
}
|
|
5740
6061
|
inputInitialized = true;
|
|
5741
6062
|
}
|
|
5742
6063
|
const resetInputValue = () => {
|
|
5743
|
-
const
|
|
6064
|
+
const key = selectedKey();
|
|
6065
|
+
const textValue = key != null ? originalCollection().getItem(key)?.textValue ?? "" : "";
|
|
5744
6066
|
setLastValue(textValue);
|
|
5745
6067
|
setInputValue(textValue);
|
|
5746
6068
|
};
|
|
@@ -5779,14 +6101,25 @@ function createComboBoxState(props) {
|
|
|
5779
6101
|
overlayState.toggle();
|
|
5780
6102
|
};
|
|
5781
6103
|
const commitCustomValue = () => {
|
|
5782
|
-
|
|
6104
|
+
if (isMultiple()) {
|
|
6105
|
+
setLastValue(inputValue());
|
|
6106
|
+
closeMenu();
|
|
6107
|
+
return;
|
|
6108
|
+
}
|
|
6109
|
+
setValue(null);
|
|
5783
6110
|
closeMenu();
|
|
5784
6111
|
};
|
|
5785
|
-
const commitSelection = () => {
|
|
5786
|
-
if (
|
|
5787
|
-
|
|
5788
|
-
const
|
|
5789
|
-
|
|
6112
|
+
const commitSelection = (shouldForceSelectionChange = false) => {
|
|
6113
|
+
if (isValueControlled() && isInputControlled()) {
|
|
6114
|
+
const key = selectedKey();
|
|
6115
|
+
const itemText = key != null ? originalCollection().getItem(key)?.textValue ?? "" : "";
|
|
6116
|
+
if (shouldForceSelectionChange || isMultiple() || inputValue() !== itemText) {
|
|
6117
|
+
getProps().onSelectionChange?.(key);
|
|
6118
|
+
const current = displayValue();
|
|
6119
|
+
const changeValue = isKeyList(current) ? [...current] : current;
|
|
6120
|
+
getProps().onChange?.(changeValue);
|
|
6121
|
+
}
|
|
6122
|
+
setLastValue(itemText);
|
|
5790
6123
|
closeMenu();
|
|
5791
6124
|
} else {
|
|
5792
6125
|
resetInputValue();
|
|
@@ -5802,12 +6135,9 @@ function createComboBoxState(props) {
|
|
|
5802
6135
|
};
|
|
5803
6136
|
const commit = () => {
|
|
5804
6137
|
const focusedKey = listState.focusedKey();
|
|
5805
|
-
if (isMultiple()) {
|
|
5806
|
-
if (overlayState.isOpen() && focusedKey != null) select(focusedKey);
|
|
5807
|
-
return;
|
|
5808
|
-
}
|
|
5809
6138
|
if (overlayState.isOpen() && focusedKey != null) {
|
|
5810
|
-
if (selectedKey() === focusedKey) commitSelection();
|
|
6139
|
+
if (!isMultiple() && selectedKey() === focusedKey) commitSelection(true);
|
|
6140
|
+
else if (isMultiple()) select(focusedKey);
|
|
5811
6141
|
else listState.selectionManager.select(focusedKey);
|
|
5812
6142
|
} else commitValue();
|
|
5813
6143
|
};
|
|
@@ -5816,10 +6146,24 @@ function createComboBoxState(props) {
|
|
|
5816
6146
|
else commitSelection();
|
|
5817
6147
|
};
|
|
5818
6148
|
const [isFocused, setIsFocused] = createInternalSignal(false);
|
|
6149
|
+
let valueOnFocus = [untrack(inputValue), untrack(displayValue)];
|
|
6150
|
+
const hasMoved = (a, b) => {
|
|
6151
|
+
if (a === b) return false;
|
|
6152
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
6153
|
+
if (a.length !== b.length) return true;
|
|
6154
|
+
for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return true;
|
|
6155
|
+
return false;
|
|
6156
|
+
}
|
|
6157
|
+
return true;
|
|
6158
|
+
};
|
|
5819
6159
|
const setFocused = (focused) => {
|
|
5820
6160
|
if (focused) {
|
|
6161
|
+
valueOnFocus = [inputValue(), displayValue()];
|
|
5821
6162
|
if (menuTrigger() === "focus" && !getProps().isReadOnly) open(null, "focus");
|
|
5822
|
-
} else
|
|
6163
|
+
} else {
|
|
6164
|
+
if (shouldCloseOnBlur()) commitValue();
|
|
6165
|
+
if (inputValue() !== valueOnFocus[0] || hasMoved(displayValue(), valueOnFocus[1])) validation.commitValidation();
|
|
6166
|
+
}
|
|
5823
6167
|
setIsFocused(focused);
|
|
5824
6168
|
};
|
|
5825
6169
|
let lastDisplayValue = untrack(selectedKey);
|
|
@@ -5834,15 +6178,16 @@ function createComboBoxState(props) {
|
|
|
5834
6178
|
trigger: menuTrigger(),
|
|
5835
6179
|
showingAll: showAllItems(),
|
|
5836
6180
|
inputControlled: isInputControlled(),
|
|
5837
|
-
selectionControlled:
|
|
5838
|
-
|
|
6181
|
+
selectionControlled: isValueControlled(),
|
|
6182
|
+
multiple: isMultiple()
|
|
6183
|
+
}), ({ input, filtered, isOpen, last, focused, key, allowsEmpty, trigger, showingAll, inputControlled, selectionControlled, multiple }) => {
|
|
5839
6184
|
if (focused && (filtered.size > 0 || allowsEmpty) && !isOpen && input !== last && trigger !== "manual") open(null, "input");
|
|
5840
6185
|
if (!showingAll && !allowsEmpty && isOpen && filtered.size === 0) closeMenu();
|
|
5841
6186
|
if (key != null && key !== lastDisplayValue) closeMenu();
|
|
5842
6187
|
if (input !== last) {
|
|
5843
6188
|
listState.setFocusedKey(null);
|
|
5844
6189
|
setShowAllItems(false);
|
|
5845
|
-
if (input === "" && (!inputControlled || !selectionControlled))
|
|
6190
|
+
if (!multiple && input === "" && (!inputControlled || !selectionControlled)) setValue(null);
|
|
5846
6191
|
setLastValue(input);
|
|
5847
6192
|
}
|
|
5848
6193
|
lastDisplayValue = key;
|
|
@@ -5854,7 +6199,7 @@ function createComboBoxState(props) {
|
|
|
5854
6199
|
key,
|
|
5855
6200
|
textValue: (key != null ? originalCollection().getItem(key) : null)?.textValue ?? "",
|
|
5856
6201
|
inputControlled: isInputControlled(),
|
|
5857
|
-
selectionControlled:
|
|
6202
|
+
selectionControlled: isValueControlled()
|
|
5858
6203
|
};
|
|
5859
6204
|
}, (data) => {
|
|
5860
6205
|
if (!data) return;
|
|
@@ -5871,34 +6216,39 @@ function createComboBoxState(props) {
|
|
|
5871
6216
|
const current = new Set(selectedKeys());
|
|
5872
6217
|
if (current.has(key)) current.delete(key);
|
|
5873
6218
|
else current.add(key);
|
|
5874
|
-
|
|
6219
|
+
setValue([...current]);
|
|
5875
6220
|
} else {
|
|
5876
|
-
|
|
6221
|
+
setValue(key);
|
|
5877
6222
|
closeMenu();
|
|
5878
6223
|
}
|
|
5879
6224
|
};
|
|
6225
|
+
const setSelectedKeys = (keys) => {
|
|
6226
|
+
setValue([...keys]);
|
|
6227
|
+
};
|
|
5880
6228
|
const removeSelectedKey = (key) => {
|
|
5881
|
-
if (isMultiple())
|
|
5882
|
-
|
|
5883
|
-
current.delete(key);
|
|
5884
|
-
setSelectedKeys(current);
|
|
5885
|
-
}
|
|
6229
|
+
if (!isMultiple()) return;
|
|
6230
|
+
setValue([...selectedKeys()].filter((selected) => selected !== key));
|
|
5886
6231
|
};
|
|
5887
6232
|
const selectionMode = () => getProps().selectionMode ?? "single";
|
|
5888
|
-
const isSelected = (key) =>
|
|
5889
|
-
if (isMultiple()) return selectedKeys().has(key);
|
|
5890
|
-
return selectedKey() === key;
|
|
5891
|
-
};
|
|
6233
|
+
const isSelected = (key) => selectedKeys().has(key);
|
|
5892
6234
|
return {
|
|
6235
|
+
realtimeValidation: validation.realtimeValidation,
|
|
6236
|
+
displayValidation: validation.displayValidation,
|
|
6237
|
+
updateValidation: validation.updateValidation,
|
|
6238
|
+
resetValidation: validation.resetValidation,
|
|
6239
|
+
commitValidation: validation.commitValidation,
|
|
5893
6240
|
collection: displayedCollection,
|
|
5894
6241
|
isOpen: overlayState.isOpen,
|
|
5895
6242
|
open,
|
|
5896
6243
|
close: commitValue,
|
|
5897
6244
|
toggle,
|
|
5898
6245
|
selectedKey,
|
|
5899
|
-
defaultSelectedKey
|
|
6246
|
+
defaultSelectedKey,
|
|
5900
6247
|
selectedItem,
|
|
5901
6248
|
setSelectedKey,
|
|
6249
|
+
value: () => displayValue(),
|
|
6250
|
+
defaultValue,
|
|
6251
|
+
setValue,
|
|
5902
6252
|
selectedKeys,
|
|
5903
6253
|
setSelectedKeys,
|
|
5904
6254
|
selectedItems,
|
|
@@ -5929,6 +6279,14 @@ function createComboBoxState(props) {
|
|
|
5929
6279
|
}
|
|
5930
6280
|
};
|
|
5931
6281
|
}
|
|
6282
|
+
function isKeyList(value) {
|
|
6283
|
+
return value !== null && typeof value !== "string" && typeof value !== "number";
|
|
6284
|
+
}
|
|
6285
|
+
function convertValue(value) {
|
|
6286
|
+
if (value == null) return [];
|
|
6287
|
+
if (typeof value === "string" || typeof value === "number") return [value];
|
|
6288
|
+
return value;
|
|
6289
|
+
}
|
|
5932
6290
|
/**
|
|
5933
6291
|
* Filter a collection based on input value.
|
|
5934
6292
|
* RAC `useComboBoxState.ts:644-672` copies nodes into a new `ListCollection`,
|
|
@@ -5969,7 +6327,7 @@ function filterCollection(collection, inputValue, filter) {
|
|
|
5969
6327
|
* Creates state for a tab list component.
|
|
5970
6328
|
*/
|
|
5971
6329
|
function createTabListState(props) {
|
|
5972
|
-
const getProps = (
|
|
6330
|
+
const getProps = propsAccessor(props);
|
|
5973
6331
|
const collection = createMemo(() => {
|
|
5974
6332
|
const p = getProps();
|
|
5975
6333
|
return new ListCollection((p.items ?? []).map((item, index) => {
|
|
@@ -6041,32 +6399,13 @@ function createTabListState(props) {
|
|
|
6041
6399
|
setChildFocusStrategy(childStrategy ?? null);
|
|
6042
6400
|
};
|
|
6043
6401
|
let lastSelectedKey = selectedKey();
|
|
6044
|
-
let selectedToFocusedFrame = null;
|
|
6045
|
-
const copySelectedToFocusedKey = () => {
|
|
6046
|
-
selectedToFocusedFrame = null;
|
|
6047
|
-
const sel = selectedKey();
|
|
6048
|
-
if (sel !== null && focusedKey() === null || !isFocused() && sel !== lastSelectedKey) setFocusedKey(sel);
|
|
6049
|
-
lastSelectedKey = sel;
|
|
6050
|
-
};
|
|
6051
6402
|
createEffect(() => ({
|
|
6052
6403
|
sel: selectedKey(),
|
|
6053
6404
|
foc: focusedKey(),
|
|
6054
6405
|
focused: isFocused()
|
|
6055
6406
|
}), ({ sel, foc, focused }) => {
|
|
6056
|
-
if (sel !== null && foc === null)
|
|
6057
|
-
|
|
6058
|
-
lastSelectedKey = sel;
|
|
6059
|
-
return;
|
|
6060
|
-
}
|
|
6061
|
-
if (!focused && sel !== lastSelectedKey) {
|
|
6062
|
-
if (selectedToFocusedFrame != null) return;
|
|
6063
|
-
selectedToFocusedFrame = requestAnimationFrame(copySelectedToFocusedKey);
|
|
6064
|
-
}
|
|
6065
|
-
});
|
|
6066
|
-
onCleanup(() => {
|
|
6067
|
-
if (selectedToFocusedFrame == null) return;
|
|
6068
|
-
cancelAnimationFrame(selectedToFocusedFrame);
|
|
6069
|
-
selectedToFocusedFrame = null;
|
|
6407
|
+
if (sel !== null && foc === null || !focused && sel !== lastSelectedKey) setFocusedKey(sel);
|
|
6408
|
+
lastSelectedKey = sel;
|
|
6070
6409
|
});
|
|
6071
6410
|
createEffect(() => {
|
|
6072
6411
|
const p = getProps();
|
|
@@ -6131,12 +6470,38 @@ function clamp$2(value, min, max) {
|
|
|
6131
6470
|
return result;
|
|
6132
6471
|
}
|
|
6133
6472
|
/**
|
|
6134
|
-
*
|
|
6473
|
+
* Rounds to the decimal precision implied by a step, including exponential steps.
|
|
6135
6474
|
*/
|
|
6136
|
-
function
|
|
6137
|
-
|
|
6138
|
-
|
|
6139
|
-
|
|
6475
|
+
function roundToStepPrecision(value, step) {
|
|
6476
|
+
let roundedValue = value;
|
|
6477
|
+
let precision = 0;
|
|
6478
|
+
const stepString = step.toString();
|
|
6479
|
+
const eIndex = stepString.toLowerCase().indexOf("e-");
|
|
6480
|
+
if (eIndex > 0) precision = Math.abs(Math.floor(Math.log10(Math.abs(step)))) + eIndex;
|
|
6481
|
+
else {
|
|
6482
|
+
const pointIndex = stepString.indexOf(".");
|
|
6483
|
+
if (pointIndex >= 0) precision = stepString.length - pointIndex;
|
|
6484
|
+
}
|
|
6485
|
+
if (precision > 0) {
|
|
6486
|
+
const pow = Math.pow(10, precision);
|
|
6487
|
+
roundedValue = Math.round(roundedValue * pow) / pow;
|
|
6488
|
+
}
|
|
6489
|
+
return roundedValue;
|
|
6490
|
+
}
|
|
6491
|
+
/**
|
|
6492
|
+
* Snaps to the nearest step, then to the last in-range step when that exceeds max.
|
|
6493
|
+
* A negative halfway rounds away from the step base.
|
|
6494
|
+
*/
|
|
6495
|
+
function snapValueToStep(value, min, max, step) {
|
|
6496
|
+
const minNumber = Number(min);
|
|
6497
|
+
const maxNumber = Number(max);
|
|
6498
|
+
const remainder = (value - (isNaN(minNumber) ? 0 : minNumber)) % step;
|
|
6499
|
+
let snappedValue = roundToStepPrecision(Math.abs(remainder) * 2 >= step ? value + Math.sign(remainder) * (step - Math.abs(remainder)) : value - remainder, step);
|
|
6500
|
+
if (!isNaN(minNumber)) {
|
|
6501
|
+
if (snappedValue < minNumber) snappedValue = minNumber;
|
|
6502
|
+
else if (!isNaN(maxNumber) && snappedValue > maxNumber) snappedValue = minNumber + Math.floor(roundToStepPrecision((maxNumber - minNumber) / step, step)) * step;
|
|
6503
|
+
} else if (!isNaN(maxNumber) && snappedValue > maxNumber) snappedValue = Math.floor(roundToStepPrecision(maxNumber / step, step)) * step;
|
|
6504
|
+
return roundToStepPrecision(snappedValue, step);
|
|
6140
6505
|
}
|
|
6141
6506
|
function isValidStep(step) {
|
|
6142
6507
|
return step != null && !isNaN(step) && step > 0;
|
|
@@ -6180,7 +6545,7 @@ function createNumberFieldState(props) {
|
|
|
6180
6545
|
const applyConstraints = (value) => {
|
|
6181
6546
|
const p = getProps();
|
|
6182
6547
|
if (isNaN(value)) return NaN;
|
|
6183
|
-
if (hasCustomStep()) return
|
|
6548
|
+
if (hasCustomStep()) return snapValueToStep(value, p.minValue, p.maxValue, step());
|
|
6184
6549
|
return clamp$2(value, p.minValue, p.maxValue);
|
|
6185
6550
|
};
|
|
6186
6551
|
let initialNumberValue = NaN;
|
|
@@ -6262,11 +6627,11 @@ function createNumberFieldState(props) {
|
|
|
6262
6627
|
syncControlledValue();
|
|
6263
6628
|
setInputValueInternal(value);
|
|
6264
6629
|
};
|
|
6265
|
-
const commit = () => {
|
|
6630
|
+
const commit = (override) => {
|
|
6266
6631
|
ensureInitialized();
|
|
6267
6632
|
const p = getProps();
|
|
6268
|
-
const input = readNow(inputValue);
|
|
6269
|
-
if (input === ""
|
|
6633
|
+
const input = override === void 0 ? readNow(inputValue) : override;
|
|
6634
|
+
if (input === "") {
|
|
6270
6635
|
setNumberValue(NaN);
|
|
6271
6636
|
setInputValueInternal(p.value === void 0 ? "" : formatNumber(readNow(actualNumberValue)));
|
|
6272
6637
|
p.onChange?.(NaN);
|
|
@@ -6282,7 +6647,7 @@ function createNumberFieldState(props) {
|
|
|
6282
6647
|
parsed = constrainForCommit(parsed);
|
|
6283
6648
|
parsed = numberParser().parse(formatNumber(parsed));
|
|
6284
6649
|
setNumberValue(parsed);
|
|
6285
|
-
setInputValueInternal(formatNumber(parsed));
|
|
6650
|
+
setInputValueInternal(formatNumber(p.value === void 0 ? parsed : previous));
|
|
6286
6651
|
p.onChange?.(parsed);
|
|
6287
6652
|
if (parsed !== previous) validation.commitValidation();
|
|
6288
6653
|
};
|
|
@@ -6293,7 +6658,7 @@ function createNumberFieldState(props) {
|
|
|
6293
6658
|
const current = parsedInputValue();
|
|
6294
6659
|
if (isNaN(current)) return true;
|
|
6295
6660
|
if (p.maxValue == null) return true;
|
|
6296
|
-
return
|
|
6661
|
+
return snapValueToStep(current, p.minValue, p.maxValue, step()) > current || handleDecimalOperation("+", current, step()) <= p.maxValue;
|
|
6297
6662
|
});
|
|
6298
6663
|
const canDecrement = createMemo(() => {
|
|
6299
6664
|
ensureInitialized();
|
|
@@ -6302,15 +6667,20 @@ function createNumberFieldState(props) {
|
|
|
6302
6667
|
const current = parsedInputValue();
|
|
6303
6668
|
if (isNaN(current)) return true;
|
|
6304
6669
|
if (p.minValue == null) return true;
|
|
6305
|
-
return
|
|
6670
|
+
return snapValueToStep(current, p.minValue, p.maxValue, step()) < current || handleDecimalOperation("-", current, step()) >= p.minValue;
|
|
6306
6671
|
});
|
|
6307
6672
|
const safeNextStep = (operation, minOrMaxValue = 0) => {
|
|
6308
6673
|
const p = getProps();
|
|
6309
6674
|
const parsed = parsedInputValue();
|
|
6310
|
-
if (isNaN(parsed)) return
|
|
6311
|
-
const snapped =
|
|
6312
|
-
if (operation === "+" && snapped > parsed || operation === "-" && snapped < parsed) return
|
|
6313
|
-
return
|
|
6675
|
+
if (isNaN(parsed)) return snapValueToStep(isNaN(minOrMaxValue) ? 0 : minOrMaxValue, p.minValue, p.maxValue, step());
|
|
6676
|
+
const snapped = snapValueToStep(parsed, p.minValue, p.maxValue, step());
|
|
6677
|
+
if (operation === "+" && snapped > parsed || operation === "-" && snapped < parsed) return snapped;
|
|
6678
|
+
return snapValueToStep(handleDecimalOperation(operation, parsed, step()), p.minValue, p.maxValue, step());
|
|
6679
|
+
};
|
|
6680
|
+
const commitSteppedNumber = (next, refreshWhenUnchanged) => {
|
|
6681
|
+
const committed = readNow(actualNumberValue);
|
|
6682
|
+
setNumberValue(next);
|
|
6683
|
+
if (getProps().value === void 0 || refreshWhenUnchanged && next === committed) setInputValueInternal(formatNumber(next));
|
|
6314
6684
|
};
|
|
6315
6685
|
const increment = () => {
|
|
6316
6686
|
ensureInitialized();
|
|
@@ -6318,8 +6688,7 @@ function createNumberFieldState(props) {
|
|
|
6318
6688
|
const p = getProps();
|
|
6319
6689
|
if (p.isDisabled || p.isReadOnly) return;
|
|
6320
6690
|
const current = safeNextStep("+", p.minValue);
|
|
6321
|
-
|
|
6322
|
-
setInputValueInternal(formatNumber(current));
|
|
6691
|
+
commitSteppedNumber(current, true);
|
|
6323
6692
|
p.onChange?.(current);
|
|
6324
6693
|
validation.commitValidation();
|
|
6325
6694
|
};
|
|
@@ -6329,8 +6698,7 @@ function createNumberFieldState(props) {
|
|
|
6329
6698
|
const p = getProps();
|
|
6330
6699
|
if (p.isDisabled || p.isReadOnly) return;
|
|
6331
6700
|
const current = safeNextStep("-", p.maxValue);
|
|
6332
|
-
|
|
6333
|
-
setInputValueInternal(formatNumber(current));
|
|
6701
|
+
commitSteppedNumber(current, true);
|
|
6334
6702
|
p.onChange?.(current);
|
|
6335
6703
|
validation.commitValidation();
|
|
6336
6704
|
};
|
|
@@ -6340,9 +6708,8 @@ function createNumberFieldState(props) {
|
|
|
6340
6708
|
const p = getProps();
|
|
6341
6709
|
if (p.isDisabled || p.isReadOnly) return;
|
|
6342
6710
|
if (p.maxValue == null) return;
|
|
6343
|
-
const snapped =
|
|
6344
|
-
|
|
6345
|
-
setInputValueInternal(formatNumber(snapped));
|
|
6711
|
+
const snapped = snapValueToStep(p.maxValue, p.minValue, p.maxValue, step());
|
|
6712
|
+
commitSteppedNumber(snapped, false);
|
|
6346
6713
|
p.onChange?.(snapped);
|
|
6347
6714
|
validation.commitValidation();
|
|
6348
6715
|
};
|
|
@@ -6352,15 +6719,13 @@ function createNumberFieldState(props) {
|
|
|
6352
6719
|
const p = getProps();
|
|
6353
6720
|
if (p.isDisabled || p.isReadOnly) return;
|
|
6354
6721
|
if (p.minValue == null) return;
|
|
6355
|
-
|
|
6356
|
-
setInputValueInternal(formatNumber(p.minValue));
|
|
6722
|
+
commitSteppedNumber(p.minValue, false);
|
|
6357
6723
|
p.onChange?.(p.minValue);
|
|
6358
6724
|
validation.commitValidation();
|
|
6359
6725
|
};
|
|
6360
6726
|
const setNumberValuePublic = (value) => {
|
|
6361
6727
|
ensureInitialized();
|
|
6362
|
-
|
|
6363
|
-
setInputValueInternal(formatNumber(value));
|
|
6728
|
+
commitSteppedNumber(value, false);
|
|
6364
6729
|
getProps().onChange?.(value);
|
|
6365
6730
|
};
|
|
6366
6731
|
return {
|
|
@@ -6375,7 +6740,7 @@ function createNumberFieldState(props) {
|
|
|
6375
6740
|
return inputValue;
|
|
6376
6741
|
},
|
|
6377
6742
|
get numberValue() {
|
|
6378
|
-
return
|
|
6743
|
+
return parsedInputValue;
|
|
6379
6744
|
},
|
|
6380
6745
|
canIncrement,
|
|
6381
6746
|
canDecrement,
|
|
@@ -6448,75 +6813,144 @@ function snapToStep(value, min, max, step) {
|
|
|
6448
6813
|
const decimalPlaces = (step.toString().split(".")[1] || "").length;
|
|
6449
6814
|
return clamp$1(parseFloat(snapped.toFixed(decimalPlaces)), min, max);
|
|
6450
6815
|
}
|
|
6451
|
-
/**
|
|
6452
|
-
* Provides state management for a slider component.
|
|
6453
|
-
*/
|
|
6454
6816
|
function createSliderState(props) {
|
|
6455
6817
|
const getProps = () => access(props);
|
|
6456
6818
|
const initialProps = getProps();
|
|
6457
|
-
const
|
|
6458
|
-
const
|
|
6459
|
-
const
|
|
6460
|
-
const
|
|
6461
|
-
const
|
|
6462
|
-
const step = createMemo(() =>
|
|
6819
|
+
const arrayMode = Array.isArray(initialProps.value) || Array.isArray(initialProps.defaultValue);
|
|
6820
|
+
const initialArray = Array.isArray(initialProps.value) ? initialProps.value : initialProps.defaultValue;
|
|
6821
|
+
const initialCount = Array.isArray(initialArray) ? initialArray.length : 1;
|
|
6822
|
+
const finite = (value, fallback) => typeof value === "number" && Number.isFinite(value) ? value : fallback;
|
|
6823
|
+
const minValue = createMemo(() => arrayMode ? finite(getProps().minValue, DEFAULT_MIN) : getProps().minValue ?? DEFAULT_MIN);
|
|
6824
|
+
const step = createMemo(() => {
|
|
6825
|
+
const next = arrayMode ? finite(getProps().step, DEFAULT_STEP) : getProps().step ?? DEFAULT_STEP;
|
|
6826
|
+
return arrayMode && next <= 0 ? DEFAULT_STEP : next;
|
|
6827
|
+
});
|
|
6828
|
+
const maxValue = createMemo(() => {
|
|
6829
|
+
const next = arrayMode ? finite(getProps().maxValue, DEFAULT_MAX) : getProps().maxValue ?? DEFAULT_MAX;
|
|
6830
|
+
return arrayMode && next <= minValue() ? minValue() + step() : next;
|
|
6831
|
+
});
|
|
6463
6832
|
const orientation = createMemo(() => getProps().orientation ?? "horizontal");
|
|
6464
6833
|
const isDisabled = createMemo(() => getProps().isDisabled ?? false);
|
|
6465
6834
|
const pageStep = createMemo(() => Math.max(step(), snapToStep((maxValue() - minValue()) / 10, 0, maxValue() - minValue(), step())));
|
|
6466
6835
|
const isControlled = () => getProps().value !== void 0;
|
|
6467
|
-
const
|
|
6468
|
-
const
|
|
6469
|
-
|
|
6470
|
-
|
|
6471
|
-
|
|
6472
|
-
|
|
6473
|
-
|
|
6474
|
-
const
|
|
6475
|
-
|
|
6476
|
-
|
|
6477
|
-
|
|
6478
|
-
const
|
|
6479
|
-
|
|
6480
|
-
|
|
6481
|
-
|
|
6482
|
-
|
|
6836
|
+
const fallbackValues = () => Array.from({ length: initialCount }, (_, index) => index === 0 ? minValue() : maxValue());
|
|
6837
|
+
const normalize = (raw) => {
|
|
6838
|
+
const snapped = (raw === void 0 ? fallbackValues() : typeof raw === "number" ? [raw] : raw).map((item, index) => snapToStep(arrayMode ? finite(item, index === 0 ? minValue() : maxValue()) : item, minValue(), maxValue(), step()));
|
|
6839
|
+
return arrayMode ? snapped.sort((a, b) => a - b) : snapped;
|
|
6840
|
+
};
|
|
6841
|
+
const [internalValues, setInternalValues] = createInternalSignal(normalize(initialProps.defaultValue));
|
|
6842
|
+
const values = () => normalize(isControlled() ? getProps().value : internalValues());
|
|
6843
|
+
const initialValues = [...values()];
|
|
6844
|
+
const initialDefaultValues = normalize(initialProps.defaultValue ?? initialValues);
|
|
6845
|
+
const defaultValues = () => normalize(arrayMode ? getProps().defaultValue : initialDefaultValues);
|
|
6846
|
+
if (arrayMode) {
|
|
6847
|
+
const resetSnapshot = () => isControlled() ? void 0 : {
|
|
6848
|
+
defaults: normalize(getProps().defaultValue),
|
|
6849
|
+
min: minValue(),
|
|
6850
|
+
max: maxValue(),
|
|
6851
|
+
step: step()
|
|
6852
|
+
};
|
|
6853
|
+
let previousReset = resetSnapshot();
|
|
6854
|
+
createEffect(resetSnapshot, (next) => {
|
|
6855
|
+
const previous = previousReset;
|
|
6856
|
+
previousReset = next;
|
|
6857
|
+
if (next && (!previous || next.min !== previous.min || next.max !== previous.max || next.step !== previous.step || next.defaults.length !== previous.defaults.length || next.defaults.some((value, index) => value !== previous.defaults[index]))) setInternalValues(next.defaults);
|
|
6858
|
+
});
|
|
6859
|
+
}
|
|
6860
|
+
const [draggings, setDraggings] = createInternalSignal(initialValues.map(() => false));
|
|
6861
|
+
const [focusedThumb, setFocusedThumbValue] = createInternalSignal(void 0);
|
|
6862
|
+
const isDragging = () => draggings().some(Boolean);
|
|
6863
|
+
let pendingValues = [...initialValues];
|
|
6864
|
+
let hasPendingUpdate = false;
|
|
6865
|
+
let nonDraggingRenderedSnapshot;
|
|
6866
|
+
const validIndex = (index) => Number.isInteger(index) && index >= 0 && index < values().length;
|
|
6867
|
+
const getThumbValue = (index) => values()[index];
|
|
6868
|
+
const getThumbMinValue = (index) => index === 0 ? minValue() : values()[index - 1];
|
|
6869
|
+
const getThumbMaxValue = (index) => index === values().length - 1 ? maxValue() : values()[index + 1];
|
|
6870
|
+
const emit = (kind, next) => {
|
|
6483
6871
|
const p = getProps();
|
|
6484
|
-
|
|
6485
|
-
|
|
6486
|
-
|
|
6487
|
-
|
|
6488
|
-
|
|
6489
|
-
const
|
|
6490
|
-
|
|
6491
|
-
|
|
6492
|
-
|
|
6493
|
-
const
|
|
6494
|
-
|
|
6495
|
-
|
|
6496
|
-
|
|
6497
|
-
|
|
6498
|
-
|
|
6499
|
-
|
|
6500
|
-
|
|
6501
|
-
|
|
6502
|
-
if (
|
|
6503
|
-
|
|
6504
|
-
|
|
6505
|
-
const
|
|
6506
|
-
|
|
6507
|
-
|
|
6872
|
+
if (arrayMode) p[kind]?.([...next]);
|
|
6873
|
+
else p[kind]?.(next[0]);
|
|
6874
|
+
};
|
|
6875
|
+
const setThumbValue = (index, nextValue) => {
|
|
6876
|
+
if (isDisabled() || !validIndex(index)) return;
|
|
6877
|
+
const rendered = values();
|
|
6878
|
+
const retainNonDraggingProposal = arrayMode && isControlled() && nonDraggingRenderedSnapshot !== void 0 && rendered.length === nonDraggingRenderedSnapshot.length && rendered.every((item, i) => item === nonDraggingRenderedSnapshot[i]);
|
|
6879
|
+
const base = normalize(isDragging() || retainNonDraggingProposal ? pendingValues : rendered);
|
|
6880
|
+
const lower = index === 0 ? minValue() : base[index - 1];
|
|
6881
|
+
const upper = index === base.length - 1 ? maxValue() : base[index + 1];
|
|
6882
|
+
const snapped = clamp$1(snapToStep(nextValue, minValue(), maxValue(), step()), lower, upper);
|
|
6883
|
+
const next = [...base];
|
|
6884
|
+
next[index] = snapped;
|
|
6885
|
+
pendingValues = next;
|
|
6886
|
+
hasPendingUpdate = true;
|
|
6887
|
+
nonDraggingRenderedSnapshot = !isDragging() && arrayMode && isControlled() ? [...rendered] : void 0;
|
|
6888
|
+
const changed = next.some((item, i) => item !== rendered[i]);
|
|
6889
|
+
if (!isControlled() && (!arrayMode || changed)) setInternalValues(next);
|
|
6890
|
+
if (!arrayMode || changed) emit("onChange", next);
|
|
6891
|
+
};
|
|
6892
|
+
const setThumbPercent = (index, percent) => setThumbValue(index, clamp$1(percent, 0, 1) * (maxValue() - minValue()) + minValue());
|
|
6893
|
+
const getThumbPercent = (index) => (getThumbValue(index) - minValue()) / (maxValue() - minValue());
|
|
6894
|
+
const isThumbDragging = (index) => draggings()[index] ?? false;
|
|
6895
|
+
const setThumbDragging = (index, dragging) => {
|
|
6896
|
+
if (dragging && (!validIndex(index) || arrayMode && isDisabled())) return;
|
|
6897
|
+
const wasDragging = isThumbDragging(index);
|
|
6898
|
+
if (wasDragging === dragging) return;
|
|
6899
|
+
if (dragging && !isDragging()) {
|
|
6900
|
+
pendingValues = [...values()];
|
|
6901
|
+
hasPendingUpdate = false;
|
|
6902
|
+
nonDraggingRenderedSnapshot = void 0;
|
|
6903
|
+
}
|
|
6904
|
+
const next = [...draggings()];
|
|
6905
|
+
next[index] = dragging;
|
|
6906
|
+
setDraggings(next);
|
|
6907
|
+
if (wasDragging && !isDragging()) emit("onChangeEnd", normalize(hasPendingUpdate ? pendingValues : values()));
|
|
6908
|
+
};
|
|
6909
|
+
const setFocusedThumb = (index) => {
|
|
6910
|
+
if (index === void 0 || validIndex(index)) setFocusedThumbValue(index);
|
|
6911
|
+
};
|
|
6912
|
+
const incrementThumb = (index, stepSize = 1) => setThumbValue(index, getThumbValue(index) + Math.max(stepSize, step()));
|
|
6913
|
+
const decrementThumb = (index, stepSize = 1) => setThumbValue(index, getThumbValue(index) - Math.max(stepSize, step()));
|
|
6914
|
+
const formatter = createMemo(() => new Intl.NumberFormat(getProps().locale, getProps().formatOptions));
|
|
6915
|
+
function getFormattedValue(value = values()) {
|
|
6916
|
+
const items = typeof value === "number" ? [value] : value;
|
|
6917
|
+
if (items.length === 0) return "";
|
|
6918
|
+
if (items.length === 1) return formatter().format(items[0]);
|
|
6919
|
+
if (items.length === 2) return formatter().formatRange(items[0], items[1]);
|
|
6920
|
+
return new Intl.ListFormat(formatter().resolvedOptions().locale, { type: "unit" }).format(items.map((item) => formatter().format(item)));
|
|
6921
|
+
}
|
|
6922
|
+
const value = () => getThumbValue(0) ?? minValue();
|
|
6923
|
+
const setValue = (next) => setThumbValue(0, next);
|
|
6508
6924
|
return {
|
|
6925
|
+
values,
|
|
6926
|
+
defaultValues,
|
|
6927
|
+
getThumbValue,
|
|
6928
|
+
setThumbValue,
|
|
6929
|
+
setThumbPercent,
|
|
6930
|
+
getThumbPercent,
|
|
6931
|
+
getThumbMinValue,
|
|
6932
|
+
getThumbMaxValue,
|
|
6933
|
+
getThumbValueLabel: (index) => getFormattedValue(getThumbValue(index)),
|
|
6934
|
+
isThumbDragging,
|
|
6935
|
+
setThumbDragging,
|
|
6936
|
+
focusedThumb,
|
|
6937
|
+
setFocusedThumb,
|
|
6938
|
+
incrementThumb,
|
|
6939
|
+
decrementThumb,
|
|
6509
6940
|
value,
|
|
6510
6941
|
setValue,
|
|
6511
|
-
setValuePercent,
|
|
6512
|
-
getValuePercent,
|
|
6942
|
+
setValuePercent: (percent) => setThumbPercent(0, percent),
|
|
6943
|
+
getValuePercent: () => getThumbPercent(0),
|
|
6513
6944
|
getFormattedValue,
|
|
6514
6945
|
isDragging,
|
|
6515
|
-
setDragging,
|
|
6516
|
-
isFocused,
|
|
6517
|
-
setFocused
|
|
6518
|
-
|
|
6519
|
-
|
|
6946
|
+
setDragging: (dragging) => setThumbDragging(0, dragging),
|
|
6947
|
+
isFocused: () => focusedThumb() !== void 0,
|
|
6948
|
+
setFocused: (focused) => {
|
|
6949
|
+
if (focused) setFocusedThumb(0);
|
|
6950
|
+
else if (focusedThumb() === 0) setFocusedThumb(void 0);
|
|
6951
|
+
},
|
|
6952
|
+
increment: (multiplier = 1) => setValue(value() + step() * multiplier),
|
|
6953
|
+
decrement: (multiplier = 1) => setValue(value() - step() * multiplier),
|
|
6520
6954
|
get minValue() {
|
|
6521
6955
|
return minValue();
|
|
6522
6956
|
},
|
|
@@ -6991,7 +7425,7 @@ function createDisclosureGroupState(props = {}) {
|
|
|
6991
7425
|
* Handles row selection, focus management, and keyboard navigation state.
|
|
6992
7426
|
*/
|
|
6993
7427
|
function createGridState(options) {
|
|
6994
|
-
const getOptions = (
|
|
7428
|
+
const getOptions = propsAccessor(options);
|
|
6995
7429
|
const disabledKeys = createMemo(() => {
|
|
6996
7430
|
const keys = getOptions().disabledKeys;
|
|
6997
7431
|
return keys ? new Set(keys) : /* @__PURE__ */ new Set();
|
|
@@ -7014,15 +7448,18 @@ function createGridState(options) {
|
|
|
7014
7448
|
const disallowEmptySelection = createMemo(() => getOptions().disallowEmptySelection ?? false);
|
|
7015
7449
|
const disabledBehavior = createMemo(() => getOptions().disabledBehavior ?? "all");
|
|
7016
7450
|
const focusMode = createMemo(() => getOptions().focusMode ?? "row");
|
|
7451
|
+
let lastSelectionBehavior = selectionBehaviorProp();
|
|
7017
7452
|
createEffect(selectionBehaviorProp, (behavior) => {
|
|
7018
|
-
|
|
7453
|
+
if (behavior !== lastSelectionBehavior) {
|
|
7454
|
+
setSelectionBehaviorState(behavior);
|
|
7455
|
+
lastSelectionBehavior = behavior;
|
|
7456
|
+
}
|
|
7019
7457
|
});
|
|
7020
7458
|
createEffect(() => ({
|
|
7021
7459
|
prop: selectionBehaviorProp(),
|
|
7022
|
-
state: selectionBehaviorState(),
|
|
7023
7460
|
keys: selectedKeys()
|
|
7024
|
-
}), ({ prop,
|
|
7025
|
-
if (prop === "replace" &&
|
|
7461
|
+
}), ({ prop, keys }) => {
|
|
7462
|
+
if (prop === "replace" && selectionBehaviorState() === "toggle" && keys !== "all" && keys.size === 0) setSelectionBehaviorState("replace");
|
|
7026
7463
|
});
|
|
7027
7464
|
const setFocusedKey = (key, strategy = "first") => {
|
|
7028
7465
|
const collection = getOptions().collection;
|
|
@@ -7279,7 +7716,7 @@ const OPPOSITE_SORT_DIRECTION = {
|
|
|
7279
7716
|
* Extends grid state with sorting and table-specific features.
|
|
7280
7717
|
*/
|
|
7281
7718
|
function createTableState(options) {
|
|
7282
|
-
const getOptions = (
|
|
7719
|
+
const getOptions = propsAccessor(options);
|
|
7283
7720
|
const gridState = createGridState(() => ({
|
|
7284
7721
|
collection: getOptions().collection,
|
|
7285
7722
|
disabledKeys: getOptions().disabledKeys,
|
|
@@ -7321,7 +7758,7 @@ function createTableState(options) {
|
|
|
7321
7758
|
return gridState.disabledBehavior;
|
|
7322
7759
|
},
|
|
7323
7760
|
get isKeyboardNavigationDisabled() {
|
|
7324
|
-
return gridState.isKeyboardNavigationDisabled;
|
|
7761
|
+
return getOptions().collection.size === 0 || gridState.isKeyboardNavigationDisabled;
|
|
7325
7762
|
},
|
|
7326
7763
|
get focusedKey() {
|
|
7327
7764
|
return gridState.focusedKey;
|
|
@@ -7759,7 +8196,7 @@ function createTableCollection(options) {
|
|
|
7759
8196
|
* expanded rows in addition to the selection, sort and focus handled by the table state.
|
|
7760
8197
|
*/
|
|
7761
8198
|
function createTreeGridState(options) {
|
|
7762
|
-
const getOptions = (
|
|
8199
|
+
const getOptions = propsAccessor(options);
|
|
7763
8200
|
const [internalExpandedKeys, setInternalExpandedKeys] = createInternalSignal(getInitialExpanded(getOptions().UNSTABLE_defaultExpandedKeys));
|
|
7764
8201
|
const expandedKeys = () => {
|
|
7765
8202
|
const controlled = getOptions().UNSTABLE_expandedKeys;
|
|
@@ -7902,13 +8339,28 @@ function parseColumnDef(col, tableWidth) {
|
|
|
7902
8339
|
maxWidth
|
|
7903
8340
|
};
|
|
7904
8341
|
}
|
|
8342
|
+
function applyFractionalRemainder(widths, columns, originalWidth) {
|
|
8343
|
+
if (!(originalWidth - Math.floor(originalWidth) > 0) || columns.length === 0) return;
|
|
8344
|
+
const lastKey = columns[columns.length - 1].key;
|
|
8345
|
+
if (widths.has(lastKey)) {
|
|
8346
|
+
const tableFractionalWidth = originalWidth.toString().split(".")[1];
|
|
8347
|
+
if (tableFractionalWidth) {
|
|
8348
|
+
const columnWidth = Math.floor(widths.get(lastKey)).toString();
|
|
8349
|
+
widths.set(lastKey, Number(columnWidth + "." + tableFractionalWidth));
|
|
8350
|
+
}
|
|
8351
|
+
}
|
|
8352
|
+
}
|
|
7905
8353
|
/**
|
|
7906
8354
|
* Distribute `tableWidth` among columns:
|
|
7907
|
-
* 1.
|
|
7908
|
-
* 2.
|
|
8355
|
+
* 1. Floor tableWidth to integer before column sizing, matching upstream TableUtils.calculateColumnSizes.
|
|
8356
|
+
* 2. Fixed-width columns get their declared width (clamped to min/max).
|
|
8357
|
+
* 3. Remaining space is distributed among fractional columns proportionally with cascading rounding.
|
|
8358
|
+
* 4. Leftover sub-pixel width is added to the last column so widths sum exactly to tableWidth.
|
|
7909
8359
|
*/
|
|
7910
8360
|
function distributeWidths(columns, tableWidth) {
|
|
7911
|
-
const
|
|
8361
|
+
const originalWidth = tableWidth;
|
|
8362
|
+
const availableWidth = Math.max(0, Math.floor(tableWidth));
|
|
8363
|
+
const parsed = columns.map((c) => parseColumnDef(c, availableWidth));
|
|
7912
8364
|
let usedSpace = 0;
|
|
7913
8365
|
let totalFr = 0;
|
|
7914
8366
|
for (const p of parsed) if (p.fr > 0) totalFr += p.fr;
|
|
@@ -7916,16 +8368,22 @@ function distributeWidths(columns, tableWidth) {
|
|
|
7916
8368
|
const w = Math.max(p.minWidth, Math.min(p.maxWidth, p.fixedPx));
|
|
7917
8369
|
usedSpace += w;
|
|
7918
8370
|
}
|
|
7919
|
-
const remainingSpace = Math.max(0,
|
|
8371
|
+
const remainingSpace = Math.max(0, availableWidth - usedSpace);
|
|
7920
8372
|
const perFr = totalFr > 0 ? remainingSpace / totalFr : 0;
|
|
7921
8373
|
const widths = /* @__PURE__ */ new Map();
|
|
8374
|
+
let fpTotal = 0;
|
|
8375
|
+
let intTotal = 0;
|
|
7922
8376
|
for (const p of parsed) {
|
|
7923
|
-
let
|
|
7924
|
-
if (p.fr > 0)
|
|
7925
|
-
else
|
|
7926
|
-
|
|
7927
|
-
|
|
7928
|
-
|
|
8377
|
+
let targetSize;
|
|
8378
|
+
if (p.fr > 0) targetSize = p.fr * perFr;
|
|
8379
|
+
else targetSize = p.fixedPx;
|
|
8380
|
+
targetSize = Math.max(p.minWidth, Math.min(p.maxWidth, targetSize));
|
|
8381
|
+
const rounded = Math.round(targetSize + fpTotal) - intTotal;
|
|
8382
|
+
fpTotal += targetSize;
|
|
8383
|
+
intTotal += rounded;
|
|
8384
|
+
widths.set(p.key, rounded);
|
|
8385
|
+
}
|
|
8386
|
+
applyFractionalRemainder(widths, columns, originalWidth);
|
|
7929
8387
|
return widths;
|
|
7930
8388
|
}
|
|
7931
8389
|
/**
|
|
@@ -7946,6 +8404,7 @@ function createTableColumnResizeState(props) {
|
|
|
7946
8404
|
if (over.size === 0) return base;
|
|
7947
8405
|
const merged = new Map(base);
|
|
7948
8406
|
for (const [key, width] of over) if (merged.has(key)) merged.set(key, width);
|
|
8407
|
+
applyFractionalRemainder(merged, getProps().columns, getProps().tableWidth);
|
|
7949
8408
|
return merged;
|
|
7950
8409
|
});
|
|
7951
8410
|
const minWidthMap = createMemo(() => {
|
|
@@ -7976,13 +8435,14 @@ function createTableColumnResizeState(props) {
|
|
|
7976
8435
|
const updateResizedColumns = (key, width) => {
|
|
7977
8436
|
const minW = getColumnMinWidth(key);
|
|
7978
8437
|
const maxW = getColumnMaxWidth(key);
|
|
7979
|
-
const clampedWidth = Math.
|
|
8438
|
+
const clampedWidth = Math.max(minW, Math.min(maxW, Math.floor(width)));
|
|
7980
8439
|
const newOverrides = new Map(overrides());
|
|
7981
8440
|
newOverrides.set(key, clampedWidth);
|
|
7982
8441
|
setOverrides(newOverrides);
|
|
7983
8442
|
const base = initialWidths();
|
|
7984
8443
|
const merged = new Map(base);
|
|
7985
8444
|
for (const [k, w] of newOverrides) if (merged.has(k)) merged.set(k, w);
|
|
8445
|
+
applyFractionalRemainder(merged, getProps().columns, getProps().tableWidth);
|
|
7986
8446
|
return merged;
|
|
7987
8447
|
};
|
|
7988
8448
|
return {
|
|
@@ -8009,7 +8469,7 @@ function createTableColumnResizeState(props) {
|
|
|
8009
8469
|
* Handles expansion, selection, focus management, and keyboard navigation state.
|
|
8010
8470
|
*/
|
|
8011
8471
|
function createTreeState(options) {
|
|
8012
|
-
const getOptions = (
|
|
8472
|
+
const getOptions = propsAccessor(options);
|
|
8013
8473
|
const disabledKeys = createMemo(() => {
|
|
8014
8474
|
const keys = getOptions().disabledKeys;
|
|
8015
8475
|
return keys ? new Set(keys) : /* @__PURE__ */ new Set();
|
|
@@ -8040,15 +8500,18 @@ function createTreeState(options) {
|
|
|
8040
8500
|
const selectionBehavior = createMemo(() => selectionBehaviorState());
|
|
8041
8501
|
const disallowEmptySelection = createMemo(() => getOptions().disallowEmptySelection ?? false);
|
|
8042
8502
|
const disabledBehavior = createMemo(() => getOptions().disabledBehavior ?? "all");
|
|
8503
|
+
let lastSelectionBehavior = selectionBehaviorProp();
|
|
8043
8504
|
createEffect(selectionBehaviorProp, (behavior) => {
|
|
8044
|
-
|
|
8505
|
+
if (behavior !== lastSelectionBehavior) {
|
|
8506
|
+
setSelectionBehaviorState(behavior);
|
|
8507
|
+
lastSelectionBehavior = behavior;
|
|
8508
|
+
}
|
|
8045
8509
|
});
|
|
8046
8510
|
createEffect(() => ({
|
|
8047
8511
|
prop: selectionBehaviorProp(),
|
|
8048
|
-
state: selectionBehaviorState(),
|
|
8049
8512
|
keys: selectedKeys()
|
|
8050
|
-
}), ({ prop,
|
|
8051
|
-
if (prop === "replace" &&
|
|
8513
|
+
}), ({ prop, keys }) => {
|
|
8514
|
+
if (prop === "replace" && selectionBehaviorState() === "toggle" && keys !== "all" && keys.size === 0) setSelectionBehaviorState("replace");
|
|
8052
8515
|
});
|
|
8053
8516
|
const setFocusedKey = (key, strategy = "first") => {
|
|
8054
8517
|
setFocusedKeyInternal(key);
|
|
@@ -10558,6 +11021,14 @@ function createColorSliderState(options) {
|
|
|
10558
11021
|
const init = initValue();
|
|
10559
11022
|
if (init) setInternalValue(init);
|
|
10560
11023
|
}
|
|
11024
|
+
const initialOptions = getOptions();
|
|
11025
|
+
const resetColor = (color) => {
|
|
11026
|
+
const normalized = normalizeColor(color);
|
|
11027
|
+
return initialOptions.colorSpace ? normalized.toFormat(initialOptions.colorSpace) : normalized;
|
|
11028
|
+
};
|
|
11029
|
+
const initialDefault = initialOptions.defaultValue ? resetColor(initialOptions.defaultValue) : void 0;
|
|
11030
|
+
const firstColor = initialOptions.value !== void 0 ? resetColor(initialOptions.value) : void 0;
|
|
11031
|
+
const defaultThumbValue = (initialDefault ?? firstColor ?? resetColor("#ff0000")).getChannelValue(initialOptions.channel);
|
|
10561
11032
|
const value = createMemo(() => {
|
|
10562
11033
|
const opts = getOptions();
|
|
10563
11034
|
if (opts.value !== void 0) return normalizeValue(opts.value);
|
|
@@ -10631,7 +11102,9 @@ function createColorSliderState(options) {
|
|
|
10631
11102
|
};
|
|
10632
11103
|
const getDisplayColor = () => {
|
|
10633
11104
|
const v = value();
|
|
10634
|
-
|
|
11105
|
+
const current = channel();
|
|
11106
|
+
if (current === "hue") return normalizeColor(`hsl(${v.getChannelValue("hue")}, 100%, 50%)`);
|
|
11107
|
+
if (current === "alpha") return v;
|
|
10635
11108
|
return v.withChannelValue("alpha", 1);
|
|
10636
11109
|
};
|
|
10637
11110
|
const getThumbValueLabel = () => {
|
|
@@ -10668,6 +11141,7 @@ function createColorSliderState(options) {
|
|
|
10668
11141
|
get isDisabled() {
|
|
10669
11142
|
return isDisabled();
|
|
10670
11143
|
},
|
|
11144
|
+
defaultThumbValue,
|
|
10671
11145
|
getThumbValue,
|
|
10672
11146
|
getThumbMinValue,
|
|
10673
11147
|
getThumbMaxValue,
|
|
@@ -10698,6 +11172,9 @@ function createColorAreaState(options) {
|
|
|
10698
11172
|
return colorSpace ? color.toFormat(colorSpace) : color;
|
|
10699
11173
|
};
|
|
10700
11174
|
const [internalValue, setInternalValue] = createInternalSignal(null);
|
|
11175
|
+
const firstOptions = getOptions();
|
|
11176
|
+
const controlledInitial = firstOptions.value !== void 0 ? normalizeValue(firstOptions.value) : void 0;
|
|
11177
|
+
const initialValue = normalizeValue(firstOptions.defaultValue ?? "#ff0000");
|
|
10701
11178
|
const [isDragging, setIsDragging] = createInternalSignal(false);
|
|
10702
11179
|
const initValue = () => {
|
|
10703
11180
|
const opts = getOptions();
|
|
@@ -10745,6 +11222,9 @@ function createColorAreaState(options) {
|
|
|
10745
11222
|
};
|
|
10746
11223
|
const getXValue = () => value().getChannelValue(xChannel());
|
|
10747
11224
|
const getYValue = () => value().getChannelValue(yChannel());
|
|
11225
|
+
const setValue = (newValue) => {
|
|
11226
|
+
updateValue(normalizeValue(newValue));
|
|
11227
|
+
};
|
|
10748
11228
|
const setXValue = (newValue) => {
|
|
10749
11229
|
const range = xRange();
|
|
10750
11230
|
const clamped = Math.max(range.minValue, Math.min(range.maxValue, newValue));
|
|
@@ -10813,6 +11293,9 @@ function createColorAreaState(options) {
|
|
|
10813
11293
|
get value() {
|
|
10814
11294
|
return value();
|
|
10815
11295
|
},
|
|
11296
|
+
get defaultValue() {
|
|
11297
|
+
return controlledInitial ?? initialValue;
|
|
11298
|
+
},
|
|
10816
11299
|
get xChannel() {
|
|
10817
11300
|
return xChannel();
|
|
10818
11301
|
},
|
|
@@ -10844,6 +11327,7 @@ function createColorAreaState(options) {
|
|
|
10844
11327
|
getYValue,
|
|
10845
11328
|
setXValue,
|
|
10846
11329
|
setYValue,
|
|
11330
|
+
setValue,
|
|
10847
11331
|
setColorFromPoint,
|
|
10848
11332
|
getThumbPosition,
|
|
10849
11333
|
incrementX,
|
|
@@ -10870,7 +11354,9 @@ function createColorWheelState(options) {
|
|
|
10870
11354
|
const value = normalizeColor(color);
|
|
10871
11355
|
return value.toFormat(value.getColorSpace() === "hsb" ? "hsb" : "hsl");
|
|
10872
11356
|
};
|
|
10873
|
-
const
|
|
11357
|
+
const firstOptions = getOptions();
|
|
11358
|
+
const controlledInitial = firstOptions.value !== void 0 ? normalizeWheelValue(firstOptions.value) : void 0;
|
|
11359
|
+
const initialValue = normalizeWheelValue(firstOptions.defaultValue ?? defaultColor);
|
|
10874
11360
|
const [internalValue, setInternalValue] = createInternalSignal(initialValue);
|
|
10875
11361
|
const [isDragging, setIsDragging] = createInternalSignal(false);
|
|
10876
11362
|
let valueRef = initialValue;
|
|
@@ -10912,9 +11398,7 @@ function createColorWheelState(options) {
|
|
|
10912
11398
|
const radToDeg = (rad) => rad * 180 / Math.PI;
|
|
10913
11399
|
const degToRad = (deg) => deg * Math.PI / 180;
|
|
10914
11400
|
const cartesianToAngle = (x, y, radius) => {
|
|
10915
|
-
|
|
10916
|
-
const clampedY = Math.max(-radius, Math.min(radius, y));
|
|
10917
|
-
return mod(radToDeg(Math.atan2(clampedY, clampedX)), 360);
|
|
11401
|
+
return mod(radToDeg(Math.atan2(y / radius, x / radius)), 360);
|
|
10918
11402
|
};
|
|
10919
11403
|
const angleToCartesian = (angle, radius) => ({
|
|
10920
11404
|
x: radius * Math.cos(degToRad(angle)),
|
|
@@ -10973,7 +11457,7 @@ function createColorWheelState(options) {
|
|
|
10973
11457
|
return value();
|
|
10974
11458
|
},
|
|
10975
11459
|
get defaultValue() {
|
|
10976
|
-
return initialValue;
|
|
11460
|
+
return controlledInitial ?? initialValue;
|
|
10977
11461
|
},
|
|
10978
11462
|
get isDragging() {
|
|
10979
11463
|
return isDragging();
|
|
@@ -11075,9 +11559,13 @@ function createColorFieldState(options) {
|
|
|
11075
11559
|
const getOptions = () => options();
|
|
11076
11560
|
const initialOptions = getOptions();
|
|
11077
11561
|
const initialValue = getDefaultValue(initialOptions);
|
|
11562
|
+
const initialDefault = initialOptions.defaultValue !== void 0 ? normalizeNullableColor(initialOptions.defaultValue) : void 0;
|
|
11563
|
+
const firstColor = initialOptions.value !== void 0 ? normalizeNullableColor(initialOptions.value) : void 0;
|
|
11564
|
+
const defaultColorValue = initialDefault ?? firstColor ?? null;
|
|
11078
11565
|
const [internalValue, setInternalValue] = createInternalSignal(initialValue);
|
|
11079
11566
|
const [inputValue, setInputValueInternal] = createInternalSignal(formatColorValue(initialValue, initialOptions.channel, initialOptions.colorSpace, initialOptions.colorFormat, initialOptions.locale ?? "en-US"));
|
|
11080
11567
|
const [invalidInput, setInvalidInput] = createInternalSignal(false);
|
|
11568
|
+
let isChannelInputEdited = false;
|
|
11081
11569
|
const channel = createMemo(() => getOptions().channel);
|
|
11082
11570
|
const colorSpace = createMemo(() => getOptions().colorSpace);
|
|
11083
11571
|
const locale = createMemo(() => getOptions().locale ?? "en-US");
|
|
@@ -11093,6 +11581,7 @@ function createColorFieldState(options) {
|
|
|
11093
11581
|
const isInvalid = createMemo(() => (getOptions().isInvalid ?? false) || invalidInput());
|
|
11094
11582
|
const formatCurrentValue = (color = value()) => formatColorValue(color, channel(), colorSpace(), getOptions().colorFormat, locale());
|
|
11095
11583
|
createEffect(() => formatCurrentValue(), (formatted) => {
|
|
11584
|
+
isChannelInputEdited = false;
|
|
11096
11585
|
setInputValueInternal(formatted);
|
|
11097
11586
|
setInvalidInput(false);
|
|
11098
11587
|
});
|
|
@@ -11100,56 +11589,69 @@ function createColorFieldState(options) {
|
|
|
11100
11589
|
const opts = getOptions();
|
|
11101
11590
|
if (opts.value === void 0) setInternalValue(newColor);
|
|
11102
11591
|
opts.onChange?.(newColor);
|
|
11592
|
+
isChannelInputEdited = false;
|
|
11103
11593
|
setInputValueInternal(formatCurrentValue(newColor));
|
|
11104
11594
|
setInvalidInput(false);
|
|
11105
11595
|
};
|
|
11106
11596
|
const setInputValue = (text) => {
|
|
11597
|
+
isChannelInputEdited = true;
|
|
11107
11598
|
setInputValueInternal(text);
|
|
11108
11599
|
setInvalidInput(false);
|
|
11109
11600
|
};
|
|
11110
11601
|
const setColorValue = (newColor) => {
|
|
11111
11602
|
updateValue(newColor);
|
|
11112
11603
|
};
|
|
11604
|
+
const currentValue = () => {
|
|
11605
|
+
const opts = getOptions();
|
|
11606
|
+
return opts.value !== void 0 ? normalizeNullableColor(opts.value) : readNow(internalValue);
|
|
11607
|
+
};
|
|
11113
11608
|
const commit = () => {
|
|
11114
11609
|
const text = readNow(inputValue).trim();
|
|
11115
11610
|
const opts = getOptions();
|
|
11116
11611
|
const chan = channel();
|
|
11612
|
+
const current = currentValue();
|
|
11117
11613
|
if (!text) {
|
|
11118
|
-
updateValue(null);
|
|
11119
|
-
|
|
11120
|
-
|
|
11121
|
-
if (chan) {
|
|
11122
|
-
const displayColor = colorValue();
|
|
11614
|
+
if (current !== null) updateValue(null);
|
|
11615
|
+
} else if (chan) {
|
|
11616
|
+
const displayColor = getDisplayColor(current, colorSpace());
|
|
11123
11617
|
const rawValue = parseChannelValue(text, displayColor, chan);
|
|
11124
|
-
if (rawValue
|
|
11125
|
-
|
|
11126
|
-
|
|
11127
|
-
return;
|
|
11618
|
+
if (isChannelInputEdited && rawValue !== null) {
|
|
11619
|
+
const next = displayColor.withChannelValue(chan, rawValue);
|
|
11620
|
+
if (current === null || next.getChannelValue(chan) !== displayColor.getChannelValue(chan)) updateValue(next);
|
|
11128
11621
|
}
|
|
11129
|
-
|
|
11130
|
-
|
|
11131
|
-
|
|
11622
|
+
} else try {
|
|
11623
|
+
const next = parseHexValue(text, opts.colorFormat);
|
|
11624
|
+
if (current === null || next.toHexInt() !== current.toHexInt() || opts.colorFormat === "hexa" && next.getChannelValue("alpha") !== current.getChannelValue("alpha")) updateValue(next);
|
|
11625
|
+
} catch {}
|
|
11626
|
+
isChannelInputEdited = false;
|
|
11627
|
+
setInputValueInternal(formatCurrentValue(currentValue()));
|
|
11628
|
+
setInvalidInput(false);
|
|
11629
|
+
};
|
|
11630
|
+
const incrementHex = (amount) => {
|
|
11631
|
+
const text = readNow(inputValue);
|
|
11632
|
+
let parsed = null;
|
|
11132
11633
|
try {
|
|
11133
|
-
|
|
11634
|
+
parsed = parseColor(text.startsWith("#") ? text : `#${text}`);
|
|
11134
11635
|
} catch {
|
|
11135
|
-
|
|
11136
|
-
setInvalidInput(false);
|
|
11636
|
+
parsed = null;
|
|
11137
11637
|
}
|
|
11138
|
-
|
|
11139
|
-
|
|
11140
|
-
|
|
11141
|
-
|
|
11142
|
-
|
|
11143
|
-
updateValue(getOptions().colorFormat ? newColor.toFormat(getOptions().colorFormat) : newColor);
|
|
11638
|
+
const nextColor = hexIntToColor((parsed ?? hexIntToColor(0)).toFormat("rgb").toHexInt() + amount);
|
|
11639
|
+
const current = value();
|
|
11640
|
+
if (current && current.toFormat("rgb").toHexInt() === nextColor.toHexInt()) return;
|
|
11641
|
+
const format = getOptions().colorFormat;
|
|
11642
|
+
updateValue(format ? nextColor.toFormat(format) : nextColor);
|
|
11144
11643
|
};
|
|
11145
11644
|
const updateChannel = (amount) => {
|
|
11146
11645
|
const chan = channel();
|
|
11147
11646
|
if (!chan) return;
|
|
11148
|
-
const
|
|
11647
|
+
const current = currentValue();
|
|
11648
|
+
const displayColor = getDisplayColor(current, colorSpace());
|
|
11149
11649
|
const range = displayColor.getChannelRange(chan);
|
|
11150
|
-
const
|
|
11151
|
-
const nextValue = amount === "min" ? range.minValue : amount === "max" ? range.maxValue : Math.min(range.maxValue, Math.max(range.minValue,
|
|
11152
|
-
|
|
11650
|
+
const currentChannel = displayColor.getChannelValue(chan);
|
|
11651
|
+
const nextValue = amount === "min" ? range.minValue : amount === "max" ? range.maxValue : Math.min(range.maxValue, Math.max(range.minValue, currentChannel + amount));
|
|
11652
|
+
const next = displayColor.withChannelValue(chan, nextValue);
|
|
11653
|
+
if (current !== null && next.getChannelValue(chan) === currentChannel) return;
|
|
11654
|
+
updateValue(next);
|
|
11153
11655
|
};
|
|
11154
11656
|
const increment = () => {
|
|
11155
11657
|
const chan = channel();
|
|
@@ -11195,6 +11697,7 @@ function createColorFieldState(options) {
|
|
|
11195
11697
|
get colorValue() {
|
|
11196
11698
|
return colorValue();
|
|
11197
11699
|
},
|
|
11700
|
+
defaultColorValue,
|
|
11198
11701
|
get inputValue() {
|
|
11199
11702
|
return inputValue();
|
|
11200
11703
|
},
|
|
@@ -11572,6 +12075,9 @@ function createDraggableCollectionState(props) {
|
|
|
11572
12075
|
if (p.isSelected) return p.isSelected(key);
|
|
11573
12076
|
const selected = selectedKeySet(p.selectedKeys, p.collection);
|
|
11574
12077
|
return selected === "all" ? true : selected.has(key);
|
|
12078
|
+
},
|
|
12079
|
+
get collection() {
|
|
12080
|
+
return getProps().collection;
|
|
11575
12081
|
}
|
|
11576
12082
|
};
|
|
11577
12083
|
}
|
|
@@ -11781,7 +12287,10 @@ function createDroppableCollectionState(props) {
|
|
|
11781
12287
|
drop,
|
|
11782
12288
|
getDropOperation,
|
|
11783
12289
|
shouldAcceptItemDrop,
|
|
11784
|
-
isDropTargetFor
|
|
12290
|
+
isDropTargetFor,
|
|
12291
|
+
get collection() {
|
|
12292
|
+
return getProps().collection;
|
|
12293
|
+
}
|
|
11785
12294
|
};
|
|
11786
12295
|
}
|
|
11787
12296
|
/**
|
|
@@ -11910,8 +12419,11 @@ function createListData(options) {
|
|
|
11910
12419
|
},
|
|
11911
12420
|
insertBefore(key, ...values) {
|
|
11912
12421
|
setState((s) => {
|
|
11913
|
-
|
|
11914
|
-
if (index === -1)
|
|
12422
|
+
let index = s.items.findIndex((item) => getKey(item) === key);
|
|
12423
|
+
if (index === -1) {
|
|
12424
|
+
if (s.items.length === 0) index = 0;
|
|
12425
|
+
else return s;
|
|
12426
|
+
}
|
|
11915
12427
|
return insertItems(s, index, ...values);
|
|
11916
12428
|
});
|
|
11917
12429
|
},
|
|
@@ -12238,6 +12750,8 @@ function createTreeData(options) {
|
|
|
12238
12750
|
});
|
|
12239
12751
|
},
|
|
12240
12752
|
remove(...keys) {
|
|
12753
|
+
if (keys.length === 0) return;
|
|
12754
|
+
let nextMap;
|
|
12241
12755
|
setTreeState((state) => {
|
|
12242
12756
|
let { items, nodeMap } = state;
|
|
12243
12757
|
let newMap = new Map(nodeMap);
|
|
@@ -12247,15 +12761,16 @@ function createTreeData(options) {
|
|
|
12247
12761
|
newItems = result.items;
|
|
12248
12762
|
newMap = result.nodeMap;
|
|
12249
12763
|
}
|
|
12764
|
+
nextMap = newMap;
|
|
12250
12765
|
return {
|
|
12251
12766
|
items: newItems,
|
|
12252
12767
|
nodeMap: newMap
|
|
12253
12768
|
};
|
|
12254
12769
|
});
|
|
12255
12770
|
setSelectedKeys((sel) => {
|
|
12256
|
-
if (sel === "all") return sel;
|
|
12771
|
+
if (sel === "all" || !nextMap) return sel;
|
|
12257
12772
|
const newSel = new Set(sel);
|
|
12258
|
-
for (const key of
|
|
12773
|
+
for (const key of sel) if (!nextMap.has(key)) newSel.delete(key);
|
|
12259
12774
|
return newSel;
|
|
12260
12775
|
});
|
|
12261
12776
|
},
|
|
@@ -12611,8 +13126,11 @@ function createAsyncList(options) {
|
|
|
12611
13126
|
},
|
|
12612
13127
|
insertBefore(key, ...values) {
|
|
12613
13128
|
setState((s) => {
|
|
12614
|
-
|
|
12615
|
-
if (index === -1)
|
|
13129
|
+
let index = s.items.findIndex((item) => getKey(item) === key);
|
|
13130
|
+
if (index === -1) {
|
|
13131
|
+
if (s.items.length === 0) index = 0;
|
|
13132
|
+
else return s;
|
|
13133
|
+
}
|
|
12616
13134
|
return {
|
|
12617
13135
|
...s,
|
|
12618
13136
|
items: [
|
|
@@ -12625,8 +13143,11 @@ function createAsyncList(options) {
|
|
|
12625
13143
|
},
|
|
12626
13144
|
insertAfter(key, ...values) {
|
|
12627
13145
|
setState((s) => {
|
|
12628
|
-
|
|
12629
|
-
if (index === -1)
|
|
13146
|
+
let index = s.items.findIndex((item) => getKey(item) === key);
|
|
13147
|
+
if (index === -1) {
|
|
13148
|
+
if (s.items.length === 0) index = 0;
|
|
13149
|
+
else return s;
|
|
13150
|
+
}
|
|
12630
13151
|
return {
|
|
12631
13152
|
...s,
|
|
12632
13153
|
items: [
|
|
@@ -12659,6 +13180,7 @@ function createAsyncList(options) {
|
|
|
12659
13180
|
for (const key of keys) newSelection.delete(key);
|
|
12660
13181
|
selectedKeys = newSelection;
|
|
12661
13182
|
}
|
|
13183
|
+
if (s.cursor == null && items.length === 0) selectedKeys = /* @__PURE__ */ new Set();
|
|
12662
13184
|
return {
|
|
12663
13185
|
...s,
|
|
12664
13186
|
items,
|
|
@@ -12759,100 +13281,144 @@ function getColorChannels(colorSpace) {
|
|
|
12759
13281
|
* Creates state for a step list component.
|
|
12760
13282
|
*/
|
|
12761
13283
|
function createStepListState(props) {
|
|
12762
|
-
const
|
|
12763
|
-
const indexMap = createMemo(() => {
|
|
12764
|
-
const map = /* @__PURE__ */ new Map();
|
|
12765
|
-
const currentItems = items();
|
|
12766
|
-
for (let i = 0; i < currentItems.length; i++) map.set(currentItems[i].key, i);
|
|
12767
|
-
return map;
|
|
12768
|
-
});
|
|
12769
|
-
const disabledKeysSet = createMemo(() => new Set(props.disabledKeys ?? []));
|
|
12770
|
-
const isDisabled = () => props.isDisabled ?? false;
|
|
13284
|
+
const isListDisabled = () => props.isDisabled ?? false;
|
|
12771
13285
|
const isReadOnly = () => props.isReadOnly ?? false;
|
|
13286
|
+
const items = () => props.items ?? [];
|
|
12772
13287
|
const [lastCompletedStepInternal, setLastCompletedStepInternal] = createInternalSignal(props.defaultLastCompletedStep ?? null);
|
|
12773
13288
|
const lastCompletedStep = () => {
|
|
12774
13289
|
if (props.lastCompletedStep !== void 0) return props.lastCompletedStep;
|
|
12775
13290
|
return lastCompletedStepInternal();
|
|
12776
13291
|
};
|
|
13292
|
+
const isCompleted = (step) => {
|
|
13293
|
+
if (step == null) return false;
|
|
13294
|
+
const completed = lastCompletedStep();
|
|
13295
|
+
if (completed == null) return false;
|
|
13296
|
+
const { indexMap } = keyMaps();
|
|
13297
|
+
const stepIdx = indexMap.get(step);
|
|
13298
|
+
const completedIdx = indexMap.get(completed);
|
|
13299
|
+
if (stepIdx === void 0 || completedIdx === void 0) return false;
|
|
13300
|
+
return stepIdx <= completedIdx;
|
|
13301
|
+
};
|
|
13302
|
+
const isSelectable = (step) => {
|
|
13303
|
+
if (isListDisabled() || singleSelectListState.disabledKeys().has(step) || isReadOnly()) return false;
|
|
13304
|
+
if (isCompleted(step)) return true;
|
|
13305
|
+
const { keysLinkedList } = keyMaps();
|
|
13306
|
+
const prevStep = keysLinkedList.get(step);
|
|
13307
|
+
return prevStep !== void 0 && isCompleted(prevStep) || step === singleSelectListState.collection().getFirstKey();
|
|
13308
|
+
};
|
|
13309
|
+
const findInitialSelectedKey = () => {
|
|
13310
|
+
if (props.defaultSelectedKey !== void 0) return props.defaultSelectedKey;
|
|
13311
|
+
const currentItems = props.items ?? [];
|
|
13312
|
+
const disabled = new Set(props.disabledKeys ?? []);
|
|
13313
|
+
for (const item of currentItems) if (!disabled.has(item.key)) return item.key;
|
|
13314
|
+
return currentItems[0]?.key;
|
|
13315
|
+
};
|
|
13316
|
+
const singleSelectListState = createSingleSelectListState({
|
|
13317
|
+
get items() {
|
|
13318
|
+
return props.items ?? [];
|
|
13319
|
+
},
|
|
13320
|
+
getKey(item) {
|
|
13321
|
+
return item.key;
|
|
13322
|
+
},
|
|
13323
|
+
getTextValue(item) {
|
|
13324
|
+
return item.label ?? item.textValue ?? (item.key != null ? String(item.key) : "");
|
|
13325
|
+
},
|
|
13326
|
+
get disabledKeys() {
|
|
13327
|
+
return props.disabledKeys;
|
|
13328
|
+
},
|
|
13329
|
+
get selectedKey() {
|
|
13330
|
+
return props.selectedKey;
|
|
13331
|
+
},
|
|
13332
|
+
get defaultSelectedKey() {
|
|
13333
|
+
return findInitialSelectedKey();
|
|
13334
|
+
},
|
|
13335
|
+
onSelectionChange(key) {
|
|
13336
|
+
if (key != null) props.onSelectionChange?.(key);
|
|
13337
|
+
}
|
|
13338
|
+
});
|
|
13339
|
+
const keyMaps = createMemo(() => {
|
|
13340
|
+
const coll = singleSelectListState.collection();
|
|
13341
|
+
const indexMap = /* @__PURE__ */ new Map();
|
|
13342
|
+
const keysLinkedList = /* @__PURE__ */ new Map();
|
|
13343
|
+
let i = 0;
|
|
13344
|
+
let prev;
|
|
13345
|
+
for (const item of coll) {
|
|
13346
|
+
indexMap.set(item.key, i);
|
|
13347
|
+
keysLinkedList.set(item.key, prev?.key);
|
|
13348
|
+
prev = item;
|
|
13349
|
+
i++;
|
|
13350
|
+
}
|
|
13351
|
+
return {
|
|
13352
|
+
indexMap,
|
|
13353
|
+
keysLinkedList
|
|
13354
|
+
};
|
|
13355
|
+
});
|
|
12777
13356
|
const setLastCompletedStep = (key) => {
|
|
12778
|
-
|
|
12779
|
-
|
|
13357
|
+
if (key == null) {
|
|
13358
|
+
if (props.lastCompletedStep === void 0) setLastCompletedStepInternal(null);
|
|
13359
|
+
props.onLastCompletedStepChange?.(null);
|
|
13360
|
+
return;
|
|
13361
|
+
}
|
|
13362
|
+
const { indexMap } = keyMaps();
|
|
13363
|
+
const currentIndex = indexMap.get(key);
|
|
13364
|
+
const completed = lastCompletedStep();
|
|
13365
|
+
const prevIndex = completed !== null ? indexMap.get(completed) : -1;
|
|
12780
13366
|
if (currentIndex !== void 0 && (prevIndex === void 0 || currentIndex > (prevIndex ?? -1))) {
|
|
12781
13367
|
if (props.lastCompletedStep === void 0) setLastCompletedStepInternal(key);
|
|
12782
13368
|
props.onLastCompletedStepChange?.(key);
|
|
12783
13369
|
}
|
|
12784
13370
|
};
|
|
12785
|
-
const isCompleted = (key) => {
|
|
12786
|
-
const completed = lastCompletedStep();
|
|
12787
|
-
if (completed === null) return false;
|
|
12788
|
-
const keyIndex = indexMap().get(key);
|
|
12789
|
-
const completedIndex = indexMap().get(completed);
|
|
12790
|
-
if (keyIndex === void 0 || completedIndex === void 0) return false;
|
|
12791
|
-
return keyIndex <= completedIndex;
|
|
12792
|
-
};
|
|
12793
|
-
const isStepDisabled = (key) => {
|
|
12794
|
-
if (isDisabled()) return true;
|
|
12795
|
-
return disabledKeysSet().has(key);
|
|
12796
|
-
};
|
|
12797
|
-
const isSelectable = (key) => {
|
|
12798
|
-
if (isDisabled() || isReadOnly() || isStepDisabled(key)) return false;
|
|
12799
|
-
if (isCompleted(key)) return true;
|
|
12800
|
-
const keyIndex = indexMap().get(key);
|
|
12801
|
-
if (keyIndex === 0) return true;
|
|
12802
|
-
const currentItems = items();
|
|
12803
|
-
if (keyIndex !== void 0 && keyIndex > 0) {
|
|
12804
|
-
const prevKey = currentItems[keyIndex - 1].key;
|
|
12805
|
-
if (isCompleted(prevKey)) return true;
|
|
12806
|
-
}
|
|
12807
|
-
return false;
|
|
12808
|
-
};
|
|
12809
|
-
const findDefaultSelectedKey = () => {
|
|
12810
|
-
const currentItems = items();
|
|
12811
|
-
for (const item of currentItems) if (!isCompleted(item.key) && !isStepDisabled(item.key)) return item.key;
|
|
12812
|
-
for (const item of currentItems) if (!isStepDisabled(item.key)) return item.key;
|
|
12813
|
-
return currentItems.length > 0 ? currentItems[0].key : null;
|
|
12814
|
-
};
|
|
12815
|
-
const [selectedKeyInternal, setSelectedKeyInternal] = createInternalSignal(props.defaultSelectedKey ?? findDefaultSelectedKey());
|
|
12816
|
-
const selectedKey = () => {
|
|
12817
|
-
if (props.selectedKey !== void 0) return props.selectedKey;
|
|
12818
|
-
return selectedKeyInternal();
|
|
12819
|
-
};
|
|
12820
|
-
const setSelectedKey = (key) => {
|
|
12821
|
-
if (isReadOnly() || isDisabled()) return;
|
|
12822
|
-
if (!isSelectable(key)) return;
|
|
12823
|
-
const currentSelected = selectedKey();
|
|
12824
|
-
if (currentSelected !== null) {
|
|
12825
|
-
const currentIndex = indexMap().get(currentSelected);
|
|
12826
|
-
const newIndex = indexMap().get(key);
|
|
12827
|
-
if (currentIndex !== void 0 && newIndex !== void 0 && newIndex > currentIndex && !isCompleted(currentSelected)) setLastCompletedStep(currentSelected);
|
|
12828
|
-
}
|
|
12829
|
-
if (props.selectedKey === void 0) setSelectedKeyInternal(key);
|
|
12830
|
-
props.onSelectionChange?.(key);
|
|
12831
|
-
};
|
|
12832
13371
|
createEffect(() => {
|
|
12833
|
-
const selKey = selectedKey();
|
|
13372
|
+
const selKey = singleSelectListState.selectedKey();
|
|
12834
13373
|
if (selKey === null) return null;
|
|
12835
|
-
const
|
|
13374
|
+
const { indexMap, keysLinkedList } = keyMaps();
|
|
13375
|
+
const selIdx = indexMap.get(selKey);
|
|
12836
13376
|
if (selIdx === void 0 || selIdx <= 0) return null;
|
|
12837
13377
|
const completed = lastCompletedStep();
|
|
12838
|
-
if (selIdx <= (completed !== null ? indexMap
|
|
12839
|
-
return
|
|
13378
|
+
if (selIdx <= (completed !== null ? indexMap.get(completed) ?? -1 : -1) + 1) return null;
|
|
13379
|
+
return keysLinkedList.get(selKey) ?? null;
|
|
12840
13380
|
}, (prevKey) => {
|
|
12841
|
-
if (prevKey
|
|
13381
|
+
if (prevKey != null) setLastCompletedStep(prevKey);
|
|
13382
|
+
});
|
|
13383
|
+
createEffect(() => singleSelectListState.selectedKey(), (selKey) => {
|
|
13384
|
+
if (singleSelectListState.focusedKey() == null && selKey != null) singleSelectListState.setFocusedKey(selKey);
|
|
13385
|
+
});
|
|
13386
|
+
const setSelectedKey = (key) => {
|
|
13387
|
+
if (isListDisabled() || isReadOnly()) return;
|
|
13388
|
+
if (!isSelectable(key)) return;
|
|
13389
|
+
const { keysLinkedList } = keyMaps();
|
|
13390
|
+
const prevKey = keysLinkedList.get(key);
|
|
13391
|
+
if (prevKey && !isCompleted(prevKey)) setLastCompletedStep(prevKey);
|
|
13392
|
+
singleSelectListState.setSelectedKey(key);
|
|
13393
|
+
};
|
|
13394
|
+
singleSelectListState.selectionManager.canSelectItem = (key) => isSelectable(key);
|
|
13395
|
+
const origReplaceSelection = singleSelectListState.selectionManager.replaceSelection.bind(singleSelectListState.selectionManager);
|
|
13396
|
+
singleSelectListState.selectionManager.replaceSelection = (key) => {
|
|
13397
|
+
if (isListDisabled() || isReadOnly()) return;
|
|
13398
|
+
if (!isSelectable(key)) return;
|
|
13399
|
+
const { keysLinkedList } = keyMaps();
|
|
13400
|
+
const prevKey = keysLinkedList.get(key);
|
|
13401
|
+
if (prevKey && !isCompleted(prevKey)) setLastCompletedStep(prevKey);
|
|
13402
|
+
origReplaceSelection(key);
|
|
13403
|
+
};
|
|
13404
|
+
const isDisabledFn = ((key) => {
|
|
13405
|
+
if (key === void 0) return isListDisabled();
|
|
13406
|
+
return !isSelectable(key);
|
|
12842
13407
|
});
|
|
12843
13408
|
return {
|
|
12844
|
-
|
|
13409
|
+
...singleSelectListState,
|
|
13410
|
+
selectedKey: singleSelectListState.selectedKey,
|
|
12845
13411
|
lastCompletedStep,
|
|
12846
13412
|
items,
|
|
12847
13413
|
setSelectedKey,
|
|
12848
13414
|
setLastCompletedStep,
|
|
12849
13415
|
isCompleted,
|
|
12850
13416
|
isSelectable,
|
|
12851
|
-
isDisabled,
|
|
13417
|
+
isDisabled: isDisabledFn,
|
|
12852
13418
|
isReadOnly
|
|
12853
13419
|
};
|
|
12854
13420
|
}
|
|
12855
13421
|
//#endregion
|
|
12856
|
-
export { CalendarDateClass, CalendarDateTimeClass, DEFAULT_VALIDATION_RESULT, DIRECTORY_DRAG_TYPE, DateFormatter, FormValidationContext, GregorianCalendar, ListCollection, SelectionManager, TableCollection, TimeClass, Timer, ToastQueue, TokenFieldValue, TreeCollection, VALID_VALIDITY_STATE, ZonedDateTimeClass, access, canUseDOM, createAsyncList, createAutocompleteState, createCalendar, createCalendarState, createCheckboxGroupState, createColorAreaState, createColorFieldState, createColorSliderState, createColorWheelState, createComboBoxState, createDateFieldState, createDateFieldState as useDateFieldState, createDatePickerState, createDatePickerState as useDatePickerState, createDisclosureGroupState, createDisclosureState, createDragState, createDraggableCollectionState, createDropState, createDroppableCollectionState, createFilteredListState, createFormValidationState, createGridState, createHSBColor, createHSLColor, createId, createIsSSR, createListCollection, createListData, createListState, createMenuState, createMenuTriggerState, createMenuTriggerState as useMenuTriggerState, createNumberFieldState, createOverlayTriggerState, createRGBColor, createRadioGroupState, createRangeCalendarState, createRangeCalendarState as useDateRangePickerState, createSearchFieldState, createSelectState, createSelectionState, createSelectionState as useMultipleSelectionState, createSingleSelectListState, createSliderState, createStepListState, createTabListState, createTableCollection, createTableColumnResizeState, createTableState, createTextFieldState, createTimeFieldState, createTimeFieldState as useTimeFieldState, createToastQueue, createToastState, createToggleGroupState, createToggleState, createTokenFieldState, createTooltipTriggerState, createTreeCollection, createTreeData, createTreeGridState, createTreeState, defaultContainsFilter, endOfMonth, endOfWeek, endOfYear, getColorChannels, getDayOfWeek, getItemCount, getKeysForDrag, getLocalTimeZone, getWeeksInMonth, isAccessor, isSameDay, isSameMonth, isSameYear, isServer, isToday, isWeekend, maxDate, mergeValidation, minDate, normalizeColor, now, parseAbsolute, parseAbsoluteToLocal, parseColor, parseDate, parseDateTime, parseTime, parseZonedDateTime, privateValidationStateProp, radioGroupSyncVersion, resetTooltipState, startOfMonth, startOfWeek, startOfYear, toCalendar, toCalendarDate, toCalendarDateTime, toTime, toZoned, today };
|
|
13422
|
+
export { CalendarDateClass, CalendarDateTimeClass, DEFAULT_VALIDATION_RESULT, DIRECTORY_DRAG_TYPE, DateFormatter, FormValidationContext, GregorianCalendar, ListCollection, SelectionManager, TableCollection, TimeClass, Timer, ToastQueue, TokenFieldValue, TreeCollection, VALID_VALIDITY_STATE, ZonedDateTimeClass, access, canUseDOM, createAsyncList, createAutocompleteState, createCalendar, createCalendarState, createCheckboxGroupState, createColorAreaState, createColorFieldState, createColorSliderState, createColorWheelState, createComboBoxState, createDateFieldState, createDateFieldState as useDateFieldState, createDatePickerState, createDatePickerState as useDatePickerState, createDisclosureGroupState, createDisclosureState, createDragState, createDraggableCollectionState, createDropState, createDroppableCollectionState, createFilteredListState, createFormValidationState, createGridState, createHSBColor, createHSLColor, createId, createIsSSR, createListCollection, createListData, createListState, createMenuState, createMenuTriggerState, createMenuTriggerState as useMenuTriggerState, createNumberFieldState, createOverlayTriggerState, createRGBColor, createRadioGroupState, createRangeCalendarState, createRangeCalendarState as useDateRangePickerState, createSearchFieldState, createSelectState, createSelectionState, createSelectionState as useMultipleSelectionState, createSingleSelectListState, createSliderState, createStepListState, createSubmenuTriggerState, createSubmenuTriggerState as useSubmenuTriggerState, createTabListState, createTableCollection, createTableColumnResizeState, createTableState, createTextFieldState, createTimeFieldState, createTimeFieldState as useTimeFieldState, createToastQueue, createToastState, createToggleGroupState, createToggleState, createTokenFieldState, createTooltipTriggerState, createTreeCollection, createTreeData, createTreeGridState, createTreeState, defaultContainsFilter, endOfMonth, endOfWeek, endOfYear, getColorChannels, getDayOfWeek, getItemCount, getKeysForDrag, getLocalTimeZone, getWeeksInMonth, isAccessor, isSameDay, isSameMonth, isSameYear, isServer, isToday, isWeekend, maxDate, mergeValidation, minDate, normalizeColor, now, parseAbsolute, parseAbsoluteToLocal, parseColor, parseDate, parseDateTime, parseTime, parseZonedDateTime, privateValidationStateProp, radioGroupSyncVersion, resetTooltipState, startOfMonth, startOfWeek, startOfYear, toCalendar, toCalendarDate, toCalendarDateTime, toTime, toZoned, today };
|
|
12857
13423
|
|
|
12858
13424
|
//# sourceMappingURL=index.js.map
|