@choice-ui/react 1.9.6 → 1.9.7
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/dist/components/numeric-input/dist/index.d.ts +2 -0
- package/dist/components/numeric-input/dist/index.js +40 -13
- package/dist/components/numeric-input/src/context/numeric-input-context.d.ts +1 -0
- package/dist/components/numeric-input/src/hooks/use-input-interactions.d.ts +3 -1
- package/dist/components/numeric-input/src/hooks/use-numeric-input.d.ts +1 -0
- package/dist/components/numeric-input/src/hooks/use-numeric-input.js +36 -13
- package/dist/components/numeric-input/src/numeric-input.d.ts +1 -0
- package/dist/components/numeric-input/src/numeric-input.js +4 -0
- package/package.json +1 -1
|
@@ -51,6 +51,7 @@ interface NumericInputContextValue {
|
|
|
51
51
|
max?: number;
|
|
52
52
|
min?: number;
|
|
53
53
|
onChange?: (value: NumericInputValue, detail: NumericChangeDetail) => void;
|
|
54
|
+
onChangeEnd?: (value: NumericInputValue, detail: NumericChangeDetail) => void;
|
|
54
55
|
onEmpty?: () => void;
|
|
55
56
|
onIsEditingChange?: (isEditing: boolean) => void;
|
|
56
57
|
onPressEnd?: PressMoveProps["onPressEnd"];
|
|
@@ -74,6 +75,7 @@ interface NumericInputProps extends NumericInputContextValue, Omit<HTMLProps<HTM
|
|
|
74
75
|
disabled?: boolean;
|
|
75
76
|
id?: string;
|
|
76
77
|
onChange?: (value: NumericInputValue, detail: NumericChangeDetail) => void;
|
|
78
|
+
onChangeEnd?: (value: NumericInputValue, detail: NumericChangeDetail) => void;
|
|
77
79
|
tooltip?: TooltipProps;
|
|
78
80
|
triggerRef?: React__default.RefObject<HTMLDivElement> | ((el: HTMLDivElement | null) => void);
|
|
79
81
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Tooltip } from "../../tooltip/dist/index.js";
|
|
2
|
-
import { forwardRef, useRef, useState, useMemo, createContext, cloneElement, memo,
|
|
2
|
+
import { forwardRef, useRef, useState, useMemo, createContext, cloneElement, memo, useCallback, useEffect, Children, isValidElement, useContext } from "react";
|
|
3
3
|
import { useEventCallback } from "usehooks-ts";
|
|
4
4
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
5
|
import { IconButton } from "../../icon-button/dist/index.js";
|
|
@@ -919,11 +919,15 @@ function useNumericInput(props) {
|
|
|
919
919
|
step = 1,
|
|
920
920
|
value,
|
|
921
921
|
onChange,
|
|
922
|
+
onChangeEnd,
|
|
922
923
|
onEmpty,
|
|
923
924
|
onPressEnd,
|
|
924
925
|
onPressStart
|
|
925
926
|
} = props;
|
|
926
927
|
const innerRef = useRef(null);
|
|
928
|
+
const dragHasChangedRef = useRef(false);
|
|
929
|
+
const dragEndValueRef = useRef(void 0);
|
|
930
|
+
const dragEndDetailRef = useRef(void 0);
|
|
927
931
|
const [isFocused, setIsFocused] = useState(false);
|
|
928
932
|
const [displayValue, setDisplayValue] = useState("");
|
|
929
933
|
const { shiftPressed, metaPressed } = useModifierKeys(disabled);
|
|
@@ -941,6 +945,10 @@ function useNumericInput(props) {
|
|
|
941
945
|
defaultValue: defaultValuePre,
|
|
942
946
|
allowEmpty: true
|
|
943
947
|
});
|
|
948
|
+
const mapResultToOutputValue = useCallback(
|
|
949
|
+
(result) => typeof value === "string" ? result.string : typeof value === "number" ? result.array[0] : Array.isArray(value) ? result.array : result.object,
|
|
950
|
+
[value]
|
|
951
|
+
);
|
|
944
952
|
useEffect(() => {
|
|
945
953
|
if (!innerValue) {
|
|
946
954
|
setDisplayValue("");
|
|
@@ -959,7 +967,7 @@ function useNumericInput(props) {
|
|
|
959
967
|
setDisplayValue(valuePre2.string);
|
|
960
968
|
}, [innerValue, expression, max, min, decimal, setValue]);
|
|
961
969
|
const updateValue = useCallback(
|
|
962
|
-
(updateFn) => {
|
|
970
|
+
(updateFn, options) => {
|
|
963
971
|
if (disabled || readOnly) return;
|
|
964
972
|
setValue((prev) => {
|
|
965
973
|
if (!prev) {
|
|
@@ -971,10 +979,13 @@ function useNumericInput(props) {
|
|
|
971
979
|
min,
|
|
972
980
|
decimal
|
|
973
981
|
});
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
982
|
+
const nextValue = mapResultToOutputValue(initialValue);
|
|
983
|
+
onChange == null ? void 0 : onChange(nextValue, initialValue);
|
|
984
|
+
if ((options == null ? void 0 : options.source) === "drag") {
|
|
985
|
+
dragHasChangedRef.current = true;
|
|
986
|
+
dragEndValueRef.current = nextValue;
|
|
987
|
+
dragEndDetailRef.current = initialValue;
|
|
988
|
+
}
|
|
978
989
|
return initialValue;
|
|
979
990
|
}
|
|
980
991
|
const valuePre2 = dealWithNumericInputValue({
|
|
@@ -998,15 +1009,18 @@ function useNumericInput(props) {
|
|
|
998
1009
|
return true;
|
|
999
1010
|
})();
|
|
1000
1011
|
if (hasChanged) {
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1012
|
+
const nextValue = mapResultToOutputValue(valuePre2);
|
|
1013
|
+
onChange == null ? void 0 : onChange(nextValue, valuePre2);
|
|
1014
|
+
if ((options == null ? void 0 : options.source) === "drag") {
|
|
1015
|
+
dragHasChangedRef.current = true;
|
|
1016
|
+
dragEndValueRef.current = nextValue;
|
|
1017
|
+
dragEndDetailRef.current = valuePre2;
|
|
1018
|
+
}
|
|
1005
1019
|
}
|
|
1006
1020
|
return valuePre2;
|
|
1007
1021
|
});
|
|
1008
1022
|
},
|
|
1009
|
-
[disabled, readOnly, setValue, max, min, decimal, onChange,
|
|
1023
|
+
[disabled, readOnly, setValue, max, min, decimal, onChange, expressionRef, mapResultToOutputValue]
|
|
1010
1024
|
);
|
|
1011
1025
|
const { inputHandlers } = useInputInteractions({
|
|
1012
1026
|
inputRef: innerRef,
|
|
@@ -1031,6 +1045,9 @@ function useNumericInput(props) {
|
|
|
1031
1045
|
const { isPressed: handlerPressed, pressMoveProps } = usePressMove({
|
|
1032
1046
|
disabled,
|
|
1033
1047
|
onPressStart: (e) => {
|
|
1048
|
+
dragHasChangedRef.current = false;
|
|
1049
|
+
dragEndValueRef.current = void 0;
|
|
1050
|
+
dragEndDetailRef.current = void 0;
|
|
1034
1051
|
const wasFocused = isFocused;
|
|
1035
1052
|
if (onPressStart && "nativeEvent" in e) {
|
|
1036
1053
|
onPressStart(e.nativeEvent);
|
|
@@ -1056,12 +1073,18 @@ function useNumericInput(props) {
|
|
|
1056
1073
|
onPressEnd(e.nativeEvent);
|
|
1057
1074
|
}
|
|
1058
1075
|
onPressEnd == null ? void 0 : onPressEnd(e);
|
|
1076
|
+
if (dragHasChangedRef.current && dragEndValueRef.current !== void 0 && dragEndDetailRef.current !== void 0) {
|
|
1077
|
+
onChangeEnd == null ? void 0 : onChangeEnd(dragEndValueRef.current, dragEndDetailRef.current);
|
|
1078
|
+
}
|
|
1079
|
+
dragHasChangedRef.current = false;
|
|
1080
|
+
dragEndValueRef.current = void 0;
|
|
1081
|
+
dragEndDetailRef.current = void 0;
|
|
1059
1082
|
},
|
|
1060
1083
|
onPressMoveLeft: (delta) => {
|
|
1061
|
-
updateValue((value2) => value2 - delta * getCurrentStep());
|
|
1084
|
+
updateValue((value2) => value2 - delta * getCurrentStep(), { source: "drag" });
|
|
1062
1085
|
},
|
|
1063
1086
|
onPressMoveRight: (delta) => {
|
|
1064
|
-
updateValue((value2) => value2 + delta * getCurrentStep());
|
|
1087
|
+
updateValue((value2) => value2 + delta * getCurrentStep(), { source: "drag" });
|
|
1065
1088
|
}
|
|
1066
1089
|
});
|
|
1067
1090
|
const inputProps = {
|
|
@@ -1104,6 +1127,7 @@ var NumericInputBase = forwardRef((props, ref) => {
|
|
|
1104
1127
|
selected = false,
|
|
1105
1128
|
tooltip,
|
|
1106
1129
|
onChange,
|
|
1130
|
+
onChangeEnd,
|
|
1107
1131
|
onEmpty,
|
|
1108
1132
|
onPressEnd,
|
|
1109
1133
|
onPressStart,
|
|
@@ -1127,6 +1151,7 @@ var NumericInputBase = forwardRef((props, ref) => {
|
|
|
1127
1151
|
step,
|
|
1128
1152
|
value,
|
|
1129
1153
|
onChange,
|
|
1154
|
+
onChangeEnd,
|
|
1130
1155
|
onEmpty,
|
|
1131
1156
|
onPressEnd,
|
|
1132
1157
|
onPressStart,
|
|
@@ -1167,6 +1192,7 @@ var NumericInputBase = forwardRef((props, ref) => {
|
|
|
1167
1192
|
expression,
|
|
1168
1193
|
// Event handling methods
|
|
1169
1194
|
onChange,
|
|
1195
|
+
onChangeEnd,
|
|
1170
1196
|
onEmpty,
|
|
1171
1197
|
onPressStart,
|
|
1172
1198
|
onPressEnd,
|
|
@@ -1191,6 +1217,7 @@ var NumericInputBase = forwardRef((props, ref) => {
|
|
|
1191
1217
|
decimal,
|
|
1192
1218
|
expression,
|
|
1193
1219
|
onChange,
|
|
1220
|
+
onChangeEnd,
|
|
1194
1221
|
onEmpty,
|
|
1195
1222
|
onPressStart,
|
|
1196
1223
|
onPressEnd,
|
|
@@ -11,6 +11,7 @@ export interface NumericInputContextValue {
|
|
|
11
11
|
max?: number;
|
|
12
12
|
min?: number;
|
|
13
13
|
onChange?: (value: NumericInputValue, detail: NumericChangeDetail) => void;
|
|
14
|
+
onChangeEnd?: (value: NumericInputValue, detail: NumericChangeDetail) => void;
|
|
14
15
|
onEmpty?: () => void;
|
|
15
16
|
onIsEditingChange?: (isEditing: boolean) => void;
|
|
16
17
|
onPressEnd?: PressMoveProps["onPressEnd"];
|
|
@@ -17,7 +17,9 @@ interface UseInputInteractionsProps<T extends NumericInputValue> {
|
|
|
17
17
|
setDisplayValue: (value: string) => void;
|
|
18
18
|
setIsFocused: (focused: boolean) => void;
|
|
19
19
|
setValue: (value: NumberResult | ((prev: NumberResult | undefined) => NumberResult)) => void;
|
|
20
|
-
updateValue: (updateFn?: (value: number) => number
|
|
20
|
+
updateValue: (updateFn?: (value: number) => number, options?: {
|
|
21
|
+
source?: "drag" | "keyboard";
|
|
22
|
+
}) => void;
|
|
21
23
|
value?: T;
|
|
22
24
|
}
|
|
23
25
|
/**
|
|
@@ -10,6 +10,7 @@ interface UseNumericInputProps<T extends NumericInputValue> extends Omit<HTMLPro
|
|
|
10
10
|
max?: number;
|
|
11
11
|
min?: number;
|
|
12
12
|
onChange?: (value: T, obj: NumberResult) => void;
|
|
13
|
+
onChangeEnd?: (value: T, obj: NumberResult) => void;
|
|
13
14
|
onEmpty?: () => void;
|
|
14
15
|
onPressEnd?: PressMoveProps["onPressEnd"];
|
|
15
16
|
onPressStart?: PressMoveProps["onPressStart"];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useRef, useState,
|
|
1
|
+
import { useRef, useState, useCallback, useEffect } from "react";
|
|
2
2
|
import { dealWithNumericInputValue } from "../utils/numeric-value-processor.js";
|
|
3
3
|
import { useInputInteractions } from "./use-input-interactions.js";
|
|
4
4
|
import { useNumericValueProcessing } from "./use-numeric-value-processing.js";
|
|
@@ -21,11 +21,15 @@ function useNumericInput(props) {
|
|
|
21
21
|
step = 1,
|
|
22
22
|
value,
|
|
23
23
|
onChange,
|
|
24
|
+
onChangeEnd,
|
|
24
25
|
onEmpty,
|
|
25
26
|
onPressEnd,
|
|
26
27
|
onPressStart
|
|
27
28
|
} = props;
|
|
28
29
|
const innerRef = useRef(null);
|
|
30
|
+
const dragHasChangedRef = useRef(false);
|
|
31
|
+
const dragEndValueRef = useRef(void 0);
|
|
32
|
+
const dragEndDetailRef = useRef(void 0);
|
|
29
33
|
const [isFocused, setIsFocused] = useState(false);
|
|
30
34
|
const [displayValue, setDisplayValue] = useState("");
|
|
31
35
|
const { shiftPressed, metaPressed } = useModifierKeys(disabled);
|
|
@@ -43,6 +47,10 @@ function useNumericInput(props) {
|
|
|
43
47
|
defaultValue: defaultValuePre,
|
|
44
48
|
allowEmpty: true
|
|
45
49
|
});
|
|
50
|
+
const mapResultToOutputValue = useCallback(
|
|
51
|
+
(result) => typeof value === "string" ? result.string : typeof value === "number" ? result.array[0] : Array.isArray(value) ? result.array : result.object,
|
|
52
|
+
[value]
|
|
53
|
+
);
|
|
46
54
|
useEffect(() => {
|
|
47
55
|
if (!innerValue) {
|
|
48
56
|
setDisplayValue("");
|
|
@@ -61,7 +69,7 @@ function useNumericInput(props) {
|
|
|
61
69
|
setDisplayValue(valuePre2.string);
|
|
62
70
|
}, [innerValue, expression, max, min, decimal, setValue]);
|
|
63
71
|
const updateValue = useCallback(
|
|
64
|
-
(updateFn) => {
|
|
72
|
+
(updateFn, options) => {
|
|
65
73
|
if (disabled || readOnly) return;
|
|
66
74
|
setValue((prev) => {
|
|
67
75
|
if (!prev) {
|
|
@@ -73,10 +81,13 @@ function useNumericInput(props) {
|
|
|
73
81
|
min,
|
|
74
82
|
decimal
|
|
75
83
|
});
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
84
|
+
const nextValue = mapResultToOutputValue(initialValue);
|
|
85
|
+
onChange == null ? void 0 : onChange(nextValue, initialValue);
|
|
86
|
+
if ((options == null ? void 0 : options.source) === "drag") {
|
|
87
|
+
dragHasChangedRef.current = true;
|
|
88
|
+
dragEndValueRef.current = nextValue;
|
|
89
|
+
dragEndDetailRef.current = initialValue;
|
|
90
|
+
}
|
|
80
91
|
return initialValue;
|
|
81
92
|
}
|
|
82
93
|
const valuePre2 = dealWithNumericInputValue({
|
|
@@ -100,15 +111,18 @@ function useNumericInput(props) {
|
|
|
100
111
|
return true;
|
|
101
112
|
})();
|
|
102
113
|
if (hasChanged) {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
114
|
+
const nextValue = mapResultToOutputValue(valuePre2);
|
|
115
|
+
onChange == null ? void 0 : onChange(nextValue, valuePre2);
|
|
116
|
+
if ((options == null ? void 0 : options.source) === "drag") {
|
|
117
|
+
dragHasChangedRef.current = true;
|
|
118
|
+
dragEndValueRef.current = nextValue;
|
|
119
|
+
dragEndDetailRef.current = valuePre2;
|
|
120
|
+
}
|
|
107
121
|
}
|
|
108
122
|
return valuePre2;
|
|
109
123
|
});
|
|
110
124
|
},
|
|
111
|
-
[disabled, readOnly, setValue, max, min, decimal, onChange,
|
|
125
|
+
[disabled, readOnly, setValue, max, min, decimal, onChange, expressionRef, mapResultToOutputValue]
|
|
112
126
|
);
|
|
113
127
|
const { inputHandlers } = useInputInteractions({
|
|
114
128
|
inputRef: innerRef,
|
|
@@ -133,6 +147,9 @@ function useNumericInput(props) {
|
|
|
133
147
|
const { isPressed: handlerPressed, pressMoveProps } = usePressMove({
|
|
134
148
|
disabled,
|
|
135
149
|
onPressStart: (e) => {
|
|
150
|
+
dragHasChangedRef.current = false;
|
|
151
|
+
dragEndValueRef.current = void 0;
|
|
152
|
+
dragEndDetailRef.current = void 0;
|
|
136
153
|
const wasFocused = isFocused;
|
|
137
154
|
if (onPressStart && "nativeEvent" in e) {
|
|
138
155
|
onPressStart(e.nativeEvent);
|
|
@@ -158,12 +175,18 @@ function useNumericInput(props) {
|
|
|
158
175
|
onPressEnd(e.nativeEvent);
|
|
159
176
|
}
|
|
160
177
|
onPressEnd == null ? void 0 : onPressEnd(e);
|
|
178
|
+
if (dragHasChangedRef.current && dragEndValueRef.current !== void 0 && dragEndDetailRef.current !== void 0) {
|
|
179
|
+
onChangeEnd == null ? void 0 : onChangeEnd(dragEndValueRef.current, dragEndDetailRef.current);
|
|
180
|
+
}
|
|
181
|
+
dragHasChangedRef.current = false;
|
|
182
|
+
dragEndValueRef.current = void 0;
|
|
183
|
+
dragEndDetailRef.current = void 0;
|
|
161
184
|
},
|
|
162
185
|
onPressMoveLeft: (delta) => {
|
|
163
|
-
updateValue((value2) => value2 - delta * getCurrentStep());
|
|
186
|
+
updateValue((value2) => value2 - delta * getCurrentStep(), { source: "drag" });
|
|
164
187
|
},
|
|
165
188
|
onPressMoveRight: (delta) => {
|
|
166
|
-
updateValue((value2) => value2 + delta * getCurrentStep());
|
|
189
|
+
updateValue((value2) => value2 + delta * getCurrentStep(), { source: "drag" });
|
|
167
190
|
}
|
|
168
191
|
});
|
|
169
192
|
const inputProps = {
|
|
@@ -13,6 +13,7 @@ export interface NumericInputProps extends NumericInputContextValue, Omit<HTMLPr
|
|
|
13
13
|
disabled?: boolean;
|
|
14
14
|
id?: string;
|
|
15
15
|
onChange?: (value: NumericInputValue, detail: NumericChangeDetail) => void;
|
|
16
|
+
onChangeEnd?: (value: NumericInputValue, detail: NumericChangeDetail) => void;
|
|
16
17
|
tooltip?: TooltipProps;
|
|
17
18
|
triggerRef?: React.RefObject<HTMLDivElement> | ((el: HTMLDivElement | null) => void);
|
|
18
19
|
}
|
|
@@ -35,6 +35,7 @@ const NumericInputBase = forwardRef((props, ref) => {
|
|
|
35
35
|
selected = false,
|
|
36
36
|
tooltip,
|
|
37
37
|
onChange,
|
|
38
|
+
onChangeEnd,
|
|
38
39
|
onEmpty,
|
|
39
40
|
onPressEnd,
|
|
40
41
|
onPressStart,
|
|
@@ -58,6 +59,7 @@ const NumericInputBase = forwardRef((props, ref) => {
|
|
|
58
59
|
step,
|
|
59
60
|
value,
|
|
60
61
|
onChange,
|
|
62
|
+
onChangeEnd,
|
|
61
63
|
onEmpty,
|
|
62
64
|
onPressEnd,
|
|
63
65
|
onPressStart,
|
|
@@ -98,6 +100,7 @@ const NumericInputBase = forwardRef((props, ref) => {
|
|
|
98
100
|
expression,
|
|
99
101
|
// Event handling methods
|
|
100
102
|
onChange,
|
|
103
|
+
onChangeEnd,
|
|
101
104
|
onEmpty,
|
|
102
105
|
onPressStart,
|
|
103
106
|
onPressEnd,
|
|
@@ -122,6 +125,7 @@ const NumericInputBase = forwardRef((props, ref) => {
|
|
|
122
125
|
decimal,
|
|
123
126
|
expression,
|
|
124
127
|
onChange,
|
|
128
|
+
onChangeEnd,
|
|
125
129
|
onEmpty,
|
|
126
130
|
onPressStart,
|
|
127
131
|
onPressEnd,
|
package/package.json
CHANGED