@hsu-react/ui 2.5.3 → 2.5.4
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/es/components/Chart/Bubble/index.js +7 -2
- package/es/components/Chart/Common/index.js +7 -2
- package/es/components/Chart/Heatmap/index.js +7 -2
- package/es/components/Chart/Pie/Pie3D/index.js +8 -2
- package/es/components/Chart/Pie/index.js +7 -2
- package/es/components/Chat/ChatInput/index.js +7 -2
- package/es/components/Icon/index.js +8 -2
- package/es/components/Input/Number/index.js +28 -21
- package/es/components/Input/Password/index.js +44 -36
- package/es/components/Input/Search/index.js +44 -36
- package/es/components/Input/TextArea/index.js +64 -42
- package/es/components/Input/index.js +40 -34
- package/es/components/Select/_hooks/useSelectInputOptions.js +8 -2
- package/es/components/Slider/index.js +24 -15
- package/es/components/Upload/_hooks/useUploadFileList.js +8 -2
- package/es/components/Upload/_hooks/useUploadOperations.js +8 -2
- package/es/hooks/useLatestRef.d.ts +24 -0
- package/es/hooks/useLatestRef.js +29 -0
- package/lib/components/Chart/Bubble/index.js +6 -2
- package/lib/components/Chart/Common/index.js +6 -2
- package/lib/components/Chart/Heatmap/index.js +6 -2
- package/lib/components/Chart/Pie/Pie3D/index.js +7 -2
- package/lib/components/Chart/Pie/index.js +6 -2
- package/lib/components/Chat/ChatInput/index.js +6 -2
- package/lib/components/Icon/index.js +7 -2
- package/lib/components/Input/Number/index.js +27 -18
- package/lib/components/Input/Password/index.js +40 -26
- package/lib/components/Input/Search/index.js +42 -26
- package/lib/components/Input/TextArea/index.js +54 -26
- package/lib/components/Input/index.js +37 -24
- package/lib/components/Select/_hooks/useSelectInputOptions.js +7 -2
- package/lib/components/Slider/index.js +23 -11
- package/lib/components/Upload/_hooks/useUploadFileList.js +7 -2
- package/lib/components/Upload/_hooks/useUploadOperations.js +7 -2
- package/lib/hooks/useLatestRef.d.ts +24 -0
- package/lib/hooks/useLatestRef.js +35 -0
- package/package.json +9 -3
- package/src/__tests__/setup.ts +26 -0
- package/src/components/Chart/Bubble/index.tsx +7 -2
- package/src/components/Chart/Common/index.tsx +7 -2
- package/src/components/Chart/Heatmap/index.tsx +7 -2
- package/src/components/Chart/Pie/Pie3D/index.tsx +7 -2
- package/src/components/Chart/Pie/index.tsx +7 -2
- package/src/components/Chat/ChatInput/index.tsx +7 -2
- package/src/components/Icon/index.tsx +7 -2
- package/src/components/Input/Number/index.tsx +25 -23
- package/src/components/Input/Password/index.tsx +37 -26
- package/src/components/Input/Search/index.tsx +39 -26
- package/src/components/Input/TextArea/index.test.tsx +208 -0
- package/src/components/Input/TextArea/index.tsx +56 -30
- package/src/components/Input/index.test.tsx +189 -0
- package/src/components/Input/index.tsx +36 -29
- package/src/components/Select/_hooks/useSelectInputOptions.ts +6 -9
- package/src/components/Slider/index.tsx +22 -12
- package/src/components/Upload/_hooks/useUploadFileList.ts +6 -2
- package/src/components/Upload/_hooks/useUploadOperations.ts +7 -2
- package/src/hooks/useLatestRef.ts +31 -0
|
@@ -21,6 +21,7 @@ import React, { useCallback, useEffect, useMemo, useRef, useState } from "react"
|
|
|
21
21
|
import styles from "../index.module.scss";
|
|
22
22
|
import * as echarts from "echarts";
|
|
23
23
|
import { defaultBubbleColorList, drawCircles } from "../_utils/bubble";
|
|
24
|
+
import { useLatestRef } from "../../../hooks/useLatestRef";
|
|
24
25
|
|
|
25
26
|
// Extended data item type containing all properties the chart needs
|
|
26
27
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
@@ -276,7 +277,10 @@ var Bubble = function Bubble(props) {
|
|
|
276
277
|
chartInstanceRef.current.setOption(chartOption, true);
|
|
277
278
|
}
|
|
278
279
|
}, [chartOption, data]);
|
|
280
|
+
var onChartRef = useLatestRef(onChart);
|
|
279
281
|
|
|
282
|
+
// 回调 prop 不进依赖数组:消费方传内联箭头时每次渲染都是新引用,effect 会跟着
|
|
283
|
+
// 重跑并再调一次回调 —— 回调里 setState 就是死循环(详见 Input/TextArea 的说明)
|
|
280
284
|
// Initialize the chart
|
|
281
285
|
useEffect(function () {
|
|
282
286
|
if (!chartRef.current) return;
|
|
@@ -286,10 +290,11 @@ var Bubble = function Bubble(props) {
|
|
|
286
290
|
// Initialize or reuse the existing instance
|
|
287
291
|
var chart = chartInstanceRef.current;
|
|
288
292
|
if (!chart) {
|
|
293
|
+
var _onChartRef$current;
|
|
289
294
|
chart = echarts.init(chartRef.current);
|
|
290
295
|
chartInstanceRef.current = chart;
|
|
291
296
|
// Call the onChart callback on first initialization
|
|
292
|
-
|
|
297
|
+
(_onChartRef$current = onChartRef.current) === null || _onChartRef$current === void 0 || _onChartRef$current.call(onChartRef, chart);
|
|
293
298
|
}
|
|
294
299
|
|
|
295
300
|
// Resize first so echarts picks up the correct container size, then apply the option
|
|
@@ -313,7 +318,7 @@ var Bubble = function Bubble(props) {
|
|
|
313
318
|
(_chartInstanceRef$cur3 = chartInstanceRef.current) === null || _chartInstanceRef$cur3 === void 0 || _chartInstanceRef$cur3.off("click", onClick);
|
|
314
319
|
}
|
|
315
320
|
};
|
|
316
|
-
}, [chartOption, containerSize.width, containerSize.height, handleResize,
|
|
321
|
+
}, [chartOption, containerSize.width, containerSize.height, handleResize, onChartRef, onClick]);
|
|
317
322
|
|
|
318
323
|
// Dispose the chart instance when the component unmounts
|
|
319
324
|
useEffect(function () {
|
|
@@ -11,6 +11,7 @@ import React, { useCallback, useEffect, useMemo, useRef } from "react";
|
|
|
11
11
|
import useContainerReady from "../_hooks/useContainerReady";
|
|
12
12
|
import styles from "../index.module.scss";
|
|
13
13
|
import * as echarts from "echarts";
|
|
14
|
+
import { useLatestRef } from "../../../hooks/useLatestRef";
|
|
14
15
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
15
16
|
var Common = function Common(props) {
|
|
16
17
|
var className = props.className,
|
|
@@ -38,9 +39,13 @@ var Common = function Common(props) {
|
|
|
38
39
|
if (!el || el.clientWidth === 0 || el.clientHeight === 0) return;
|
|
39
40
|
(_chartInstanceRef$cur = chartInstanceRef.current) === null || _chartInstanceRef$cur === void 0 || _chartInstanceRef$cur.resize();
|
|
40
41
|
}, []);
|
|
42
|
+
var onChartRef = useLatestRef(onChart);
|
|
41
43
|
|
|
44
|
+
// 回调 prop 不进依赖数组:消费方传内联箭头时每次渲染都是新引用,effect 会跟着
|
|
45
|
+
// 重跑并再调一次回调 —— 回调里 setState 就是死循环(详见 Input/TextArea 的说明)
|
|
42
46
|
// Initialize the chart
|
|
43
47
|
useEffect(function () {
|
|
48
|
+
var _onChartRef$current;
|
|
44
49
|
if (!chartRef.current || !containerReady) return;
|
|
45
50
|
|
|
46
51
|
// Initialize or reuse an existing instance
|
|
@@ -54,7 +59,7 @@ var Common = function Common(props) {
|
|
|
54
59
|
chart.setOption(chartOption, true);
|
|
55
60
|
|
|
56
61
|
// Chart-ready callback (can be used for legend auto-scroll, etc.)
|
|
57
|
-
|
|
62
|
+
(_onChartRef$current = onChartRef.current) === null || _onChartRef$current === void 0 || _onChartRef$current.call(onChartRef, chart);
|
|
58
63
|
|
|
59
64
|
// Add resize listener
|
|
60
65
|
window.addEventListener("resize", handleResize);
|
|
@@ -69,7 +74,7 @@ var Common = function Common(props) {
|
|
|
69
74
|
return function () {
|
|
70
75
|
window.removeEventListener("resize", handleResize);
|
|
71
76
|
};
|
|
72
|
-
}, [chartOption, handleResize,
|
|
77
|
+
}, [chartOption, handleResize, onChartRef, containerReady]);
|
|
73
78
|
|
|
74
79
|
// Clean up resources on component unmount
|
|
75
80
|
useEffect(function () {
|
|
@@ -20,6 +20,7 @@ import * as echarts from "echarts";
|
|
|
20
20
|
import { createDefaultHeatmapXAxis, createDefaultHeatmapYAxis } from "../_utils/heatmap";
|
|
21
21
|
import { resolveChartChrome } from "../_utils/chartTheme";
|
|
22
22
|
import useIsDark from "../../../hooks/useIsDark";
|
|
23
|
+
import { useLatestRef } from "../../../hooks/useLatestRef";
|
|
23
24
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
24
25
|
var Heatmap = function Heatmap(props) {
|
|
25
26
|
var className = props.className,
|
|
@@ -192,7 +193,10 @@ var Heatmap = function Heatmap(props) {
|
|
|
192
193
|
if (!el || el.clientWidth === 0 || el.clientHeight === 0) return;
|
|
193
194
|
(_chartInstanceRef$cur = chartInstanceRef.current) === null || _chartInstanceRef$cur === void 0 || _chartInstanceRef$cur.resize();
|
|
194
195
|
}, []);
|
|
196
|
+
var onChartRef = useLatestRef(onChart);
|
|
195
197
|
|
|
198
|
+
// 回调 prop 不进依赖数组:消费方传内联箭头时每次渲染都是新引用,effect 会跟着
|
|
199
|
+
// 重跑并再调一次回调 —— 回调里 setState 就是死循环(详见 Input/TextArea 的说明)
|
|
196
200
|
// Initialize the chart
|
|
197
201
|
useEffect(function () {
|
|
198
202
|
if (!chartRef.current || !containerReady) return;
|
|
@@ -200,10 +204,11 @@ var Heatmap = function Heatmap(props) {
|
|
|
200
204
|
// Initialize or reuse the existing instance
|
|
201
205
|
var chart = chartInstanceRef.current;
|
|
202
206
|
if (!chart) {
|
|
207
|
+
var _onChartRef$current;
|
|
203
208
|
chart = echarts.init(chartRef.current);
|
|
204
209
|
chartInstanceRef.current = chart;
|
|
205
210
|
// Call the onChart callback on first initialization
|
|
206
|
-
|
|
211
|
+
(_onChartRef$current = onChartRef.current) === null || _onChartRef$current === void 0 || _onChartRef$current.call(onChartRef, chart);
|
|
207
212
|
}
|
|
208
213
|
|
|
209
214
|
// Apply the option
|
|
@@ -232,7 +237,7 @@ var Heatmap = function Heatmap(props) {
|
|
|
232
237
|
(_chartInstanceRef$cur3 = chartInstanceRef.current) === null || _chartInstanceRef$cur3 === void 0 || _chartInstanceRef$cur3.off("click", onClick);
|
|
233
238
|
}
|
|
234
239
|
};
|
|
235
|
-
}, [chartOption, handleResize,
|
|
240
|
+
}, [chartOption, handleResize, onChartRef, onClick, containerReady]);
|
|
236
241
|
|
|
237
242
|
// Clean up resources when the component unmounts
|
|
238
243
|
useEffect(function () {
|
|
@@ -8,6 +8,7 @@ import React, { useCallback, useEffect, useMemo, useRef } from "react";
|
|
|
8
8
|
import { useMouseOverHandler, useGlobalOutHandler } from "./_hooks";
|
|
9
9
|
import { getPie3DOption } from "./_utils/option";
|
|
10
10
|
import styles from "../../index.module.scss";
|
|
11
|
+
import { useLatestRef } from "../../../../hooks/useLatestRef";
|
|
11
12
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
12
13
|
var ChartPie3D = function ChartPie3D(props) {
|
|
13
14
|
var className = props.className,
|
|
@@ -89,13 +90,18 @@ var ChartPie3D = function ChartPie3D(props) {
|
|
|
89
90
|
yOffset: yOffset,
|
|
90
91
|
autoRotate: autoRotate
|
|
91
92
|
});
|
|
93
|
+
var onChartRef = useLatestRef(onChart);
|
|
94
|
+
|
|
95
|
+
// 回调 prop 不进依赖数组:消费方传内联箭头时每次渲染都是新引用,effect 会跟着
|
|
96
|
+
// 重跑并再调一次回调 —— 回调里 setState 就是死循环(详见 Input/TextArea 的说明)
|
|
92
97
|
useEffect(function () {
|
|
93
98
|
if (!chartRef.current || !containerReady) return;
|
|
94
99
|
var chart = chartInstanceRef.current;
|
|
95
100
|
if (!chart) {
|
|
101
|
+
var _onChartRef$current;
|
|
96
102
|
chart = echarts.init(chartRef.current);
|
|
97
103
|
chartInstanceRef.current = chart;
|
|
98
|
-
|
|
104
|
+
(_onChartRef$current = onChartRef.current) === null || _onChartRef$current === void 0 || _onChartRef$current.call(onChartRef, chart);
|
|
99
105
|
}
|
|
100
106
|
chart.setOption(chartOption, true);
|
|
101
107
|
optionRef.current = chartOption;
|
|
@@ -119,7 +125,7 @@ var ChartPie3D = function ChartPie3D(props) {
|
|
|
119
125
|
}
|
|
120
126
|
}
|
|
121
127
|
};
|
|
122
|
-
}, [chartOption, handleResize, handleMouseOver, handleGlobalOut,
|
|
128
|
+
}, [chartOption, handleResize, handleMouseOver, handleGlobalOut, onChartRef, onClick, containerReady]);
|
|
123
129
|
useEffect(function () {
|
|
124
130
|
return function () {
|
|
125
131
|
if (resizeObserverRef.current) {
|
|
@@ -19,6 +19,7 @@ import React, { useCallback, useEffect, useMemo, useRef } from "react";
|
|
|
19
19
|
import { autoScrollLegend } from "../chartUtils";
|
|
20
20
|
import styles from "../index.module.scss";
|
|
21
21
|
import ChartPie3D from "./Pie3D";
|
|
22
|
+
import { useLatestRef } from "../../../hooks/useLatestRef";
|
|
22
23
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
23
24
|
var ChartPie = function ChartPie(props) {
|
|
24
25
|
var className = props.className,
|
|
@@ -207,7 +208,10 @@ var ChartPie = function ChartPie(props) {
|
|
|
207
208
|
if (!el || el.clientWidth === 0 || el.clientHeight === 0) return;
|
|
208
209
|
(_chartInstanceRef$cur = chartInstanceRef.current) === null || _chartInstanceRef$cur === void 0 || _chartInstanceRef$cur.resize();
|
|
209
210
|
}, []);
|
|
211
|
+
var onChartRef = useLatestRef(onChart);
|
|
210
212
|
|
|
213
|
+
// 回调 prop 不进依赖数组:消费方传内联箭头时每次渲染都是新引用,effect 会跟着
|
|
214
|
+
// 重跑并再调一次回调 —— 回调里 setState 就是死循环(详见 Input/TextArea 的说明)
|
|
211
215
|
// Initialize the chart
|
|
212
216
|
useEffect(function () {
|
|
213
217
|
if (!chartRef.current || !containerReady) return;
|
|
@@ -215,10 +219,11 @@ var ChartPie = function ChartPie(props) {
|
|
|
215
219
|
// Initialize or reuse the existing instance
|
|
216
220
|
var chart = chartInstanceRef.current;
|
|
217
221
|
if (!chart) {
|
|
222
|
+
var _onChartRef$current;
|
|
218
223
|
chart = echarts.init(chartRef.current);
|
|
219
224
|
chartInstanceRef.current = chart;
|
|
220
225
|
// Call the onChart callback on first initialization
|
|
221
|
-
|
|
226
|
+
(_onChartRef$current = onChartRef.current) === null || _onChartRef$current === void 0 || _onChartRef$current.call(onChartRef, chart);
|
|
222
227
|
}
|
|
223
228
|
|
|
224
229
|
// Apply the option
|
|
@@ -268,7 +273,7 @@ var ChartPie = function ChartPie(props) {
|
|
|
268
273
|
legendScrollRef.current = null;
|
|
269
274
|
}
|
|
270
275
|
};
|
|
271
|
-
}, [chartOption, handleResize,
|
|
276
|
+
}, [chartOption, handleResize, onChartRef, onClick, enableLegendAutoScroll, seriesData, legendVisibleCount, legendScrollInterval, containerReady]);
|
|
272
277
|
|
|
273
278
|
// Clean up resources when the component unmounts
|
|
274
279
|
useEffect(function () {
|
|
@@ -18,6 +18,7 @@ import { useFileList } from "./_hooks";
|
|
|
18
18
|
import { FileList, AgentToggleButton, SendButton, StopButton, UploadButton } from "./_components";
|
|
19
19
|
import classNames from "classnames";
|
|
20
20
|
import Button from "../../Button";
|
|
21
|
+
import { useLatestRef } from "../../../hooks/useLatestRef";
|
|
21
22
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
22
23
|
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
23
24
|
import { Fragment as _Fragment } from "react/jsx-runtime";
|
|
@@ -82,7 +83,10 @@ var ChatInput = function ChatInput(props) {
|
|
|
82
83
|
var isControlled = externalAgentsState !== undefined;
|
|
83
84
|
// Use external state or internal state
|
|
84
85
|
var agentsState = isControlled ? externalAgentsState : internalAgentsState;
|
|
86
|
+
var onAgentsChangeRef = useLatestRef(onAgentsChange);
|
|
85
87
|
|
|
88
|
+
// 回调 prop 不进依赖数组:消费方传内联箭头时每次渲染都是新引用,effect 会跟着
|
|
89
|
+
// 重跑并再调一次回调 —— 回调里 setState 就是死循环(详见 Input/TextArea 的说明)
|
|
86
90
|
// When the model switches, sync the agents state (only in uncontrolled mode)
|
|
87
91
|
useEffect(function () {
|
|
88
92
|
if (isControlled) return; // In controlled mode, state is managed externally
|
|
@@ -91,10 +95,11 @@ var ChatInput = function ChatInput(props) {
|
|
|
91
95
|
return m.value === (modelConfig === null || modelConfig === void 0 ? void 0 : modelConfig.modelType);
|
|
92
96
|
});
|
|
93
97
|
if (currentModel !== null && currentModel !== void 0 && currentModel.agents && currentModel.agents.length > 0) {
|
|
98
|
+
var _onAgentsChangeRef$cu;
|
|
94
99
|
setInternalAgentsState(currentModel.agents);
|
|
95
|
-
|
|
100
|
+
(_onAgentsChangeRef$cu = onAgentsChangeRef.current) === null || _onAgentsChangeRef$cu === void 0 || _onAgentsChangeRef$cu.call(onAgentsChangeRef, currentModel.agents);
|
|
96
101
|
}
|
|
97
|
-
}, [modelConfig === null || modelConfig === void 0 ? void 0 : modelConfig.modelType, modelConfig === null || modelConfig === void 0 ? void 0 : modelConfig.modelList,
|
|
102
|
+
}, [modelConfig === null || modelConfig === void 0 ? void 0 : modelConfig.modelType, modelConfig === null || modelConfig === void 0 ? void 0 : modelConfig.modelList, onAgentsChangeRef, isControlled]);
|
|
98
103
|
|
|
99
104
|
// Based on the currently selected model, filter the feature configs supported by that model
|
|
100
105
|
var currentModel = modelConfig === null || modelConfig === void 0 ? void 0 : modelConfig.modelList.find(function (m) {
|
|
@@ -12,6 +12,7 @@ import * as AntdIcons from "@ant-design/icons";
|
|
|
12
12
|
import React, { useCallback, useEffect, useRef } from "react";
|
|
13
13
|
import classNames from "classnames";
|
|
14
14
|
import styles from "./index.module.scss";
|
|
15
|
+
import { useLatestRef } from "../../hooks/useLatestRef";
|
|
15
16
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
16
17
|
/** Check whether it is an AntD icon component name (e.g. "SettingOutlined") and return the corresponding component */
|
|
17
18
|
var getAntdIcon = function getAntdIcon(icon) {
|
|
@@ -46,9 +47,14 @@ var Icon = /*#__PURE__*/React.forwardRef(function (props, forwardedRef) {
|
|
|
46
47
|
forwardedRef.current = node;
|
|
47
48
|
}
|
|
48
49
|
}, [forwardedRef]);
|
|
50
|
+
var onRefRef = useLatestRef(onRef);
|
|
51
|
+
|
|
52
|
+
// 回调 prop 不进依赖数组:消费方传内联箭头时每次渲染都是新引用,effect 会跟着
|
|
53
|
+
// 重跑并再调一次回调 —— 回调里 setState 就是死循环(详见 Input/TextArea 的说明)
|
|
49
54
|
useEffect(function () {
|
|
50
|
-
|
|
51
|
-
|
|
55
|
+
var _onRefRef$current;
|
|
56
|
+
(_onRefRef$current = onRefRef.current) === null || _onRefRef$current === void 0 || _onRefRef$current.call(onRefRef, ref);
|
|
57
|
+
}, [onRefRef, ref]);
|
|
52
58
|
var mergedStyle = _objectSpread({
|
|
53
59
|
color: color,
|
|
54
60
|
fontSize: typeof fontSize === "number" ? "".concat(fontSize, "px") : fontSize
|
|
@@ -18,7 +18,7 @@ import React, { useEffect, useRef, useState } from "react";
|
|
|
18
18
|
import { CloseCircleFilled } from "@ant-design/icons";
|
|
19
19
|
import classNames from "classnames";
|
|
20
20
|
import styles from "./index.module.scss";
|
|
21
|
-
import {
|
|
21
|
+
import { useLatestRef } from "../../../hooks/useLatestRef";
|
|
22
22
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
23
23
|
import { Fragment as _Fragment } from "react/jsx-runtime";
|
|
24
24
|
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
@@ -40,6 +40,7 @@ var InputNumber = function InputNumber(props) {
|
|
|
40
40
|
// `getRef` keeps handing consumers an `HTMLInputElement` exactly as before.
|
|
41
41
|
var ref = useRef(null);
|
|
42
42
|
var wrapperRef = useRef(null);
|
|
43
|
+
var getRefRef = useLatestRef(getRef);
|
|
43
44
|
|
|
44
45
|
// On initialization, prefer value, then fall back to defaultValue
|
|
45
46
|
var initialValue = value !== undefined ? typeof value === "number" ? "".concat(value) : (_value$toString = value === null || value === void 0 ? void 0 : value.toString()) !== null && _value$toString !== void 0 ? _value$toString : "" : defaultValue !== undefined ? typeof defaultValue === "number" ? "".concat(defaultValue) : (_defaultValue$toStrin = defaultValue === null || defaultValue === void 0 ? void 0 : defaultValue.toString()) !== null && _defaultValue$toStrin !== void 0 ? _defaultValue$toStrin : "" : "";
|
|
@@ -47,19 +48,21 @@ var InputNumber = function InputNumber(props) {
|
|
|
47
48
|
_useState2 = _slicedToArray(_useState, 2),
|
|
48
49
|
_value = _useState2[0],
|
|
49
50
|
setValue = _useState2[1];
|
|
50
|
-
var _useState3 = useState(initialValue),
|
|
51
|
-
_useState4 = _slicedToArray(_useState3, 2),
|
|
52
|
-
lastValue = _useState4[0],
|
|
53
|
-
setLastValue = _useState4[1];
|
|
54
51
|
var prevValueRef = useRef(undefined);
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
52
|
+
// 最近一次通知出去的文本,代替原来那个用 state 记账的写法
|
|
53
|
+
var notifiedRef = useRef(initialValue);
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* `onChange` 是「用户改了输入」这个**事件**的通知,不是从 state 推导出来的结果,
|
|
57
|
+
* 所以在事件处理里发,不在 effect 里发。详见 `TextArea/index.tsx` 里那段说明——
|
|
58
|
+
* 旧写法(依赖数组里放 `onChange`、体内又调它、用 state 记「通知过没有」)
|
|
59
|
+
* 会让传内联箭头的消费方死循环。
|
|
60
|
+
*/
|
|
61
|
+
var notify = function notify(next) {
|
|
62
|
+
if (next === notifiedRef.current) return;
|
|
63
|
+
notifiedRef.current = next;
|
|
64
|
+
onChange === null || onChange === void 0 || onChange(next);
|
|
65
|
+
};
|
|
63
66
|
useEffect(function () {
|
|
64
67
|
// Update internal state only when the external value prop actually changes
|
|
65
68
|
if (prevValueRef.current !== value) {
|
|
@@ -76,30 +79,33 @@ var InputNumber = function InputNumber(props) {
|
|
|
76
79
|
// 表示的是同一个数,此时以用户正在敲的那份文本为准。
|
|
77
80
|
var sameNumber = value !== undefined && value !== null && _value !== "" && Number(value) === Number(_value);
|
|
78
81
|
if (sameNumber) {
|
|
79
|
-
//
|
|
80
|
-
|
|
82
|
+
// 只同步「已通知过的值」,不动正在编辑的文本
|
|
83
|
+
notifiedRef.current = _value;
|
|
81
84
|
} else if (value !== undefined && value !== null) {
|
|
82
85
|
var newValue = typeof value === "number" ? "".concat(value) : value === null || value === void 0 ? void 0 : value.toString();
|
|
86
|
+
// 外部把值改了,之前通知过什么就不作数了,重新以外部值为准
|
|
87
|
+
notifiedRef.current = newValue;
|
|
83
88
|
setValue(newValue);
|
|
84
|
-
setLastValue(newValue);
|
|
85
89
|
} else {
|
|
86
90
|
// Clear only on initialization or when explicitly set to undefined/null externally
|
|
91
|
+
notifiedRef.current = "";
|
|
87
92
|
setValue("");
|
|
88
|
-
setLastValue("");
|
|
89
93
|
}
|
|
90
94
|
}
|
|
91
95
|
// `_value` 是刻意不进依赖的:这个 effect 只该在**外部** value 变化时跑,
|
|
92
96
|
// 把它加进来会让每次键入都重跑一遍,等于绕过上面那个 prevValueRef 判断
|
|
93
97
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
94
98
|
}, [value]);
|
|
99
|
+
|
|
100
|
+
// 只在挂载时把 ref 交出去。`getRef` 进依赖数组同样会被内联箭头带着每次渲染重跑
|
|
95
101
|
useEffect(function () {
|
|
96
|
-
|
|
97
|
-
|
|
102
|
+
var _getRefRef$current;
|
|
103
|
+
(_getRefRef$current = getRefRef.current) === null || _getRefRef$current === void 0 || _getRefRef$current.call(getRefRef, ref.current);
|
|
104
|
+
}, [getRefRef]);
|
|
98
105
|
var handleClear = function handleClear(e) {
|
|
99
106
|
e.stopPropagation();
|
|
100
107
|
setValue("");
|
|
101
|
-
|
|
102
|
-
onChange === null || onChange === void 0 || onChange("");
|
|
108
|
+
notify("");
|
|
103
109
|
};
|
|
104
110
|
var showClear = allowClear && _value !== "" && _value !== undefined && !disabled;
|
|
105
111
|
var input = /*#__PURE__*/_jsx(AntdInputNumber, _objectSpread(_objectSpread({
|
|
@@ -108,6 +114,7 @@ var InputNumber = function InputNumber(props) {
|
|
|
108
114
|
onChange: function onChange(e) {
|
|
109
115
|
var newValue = e === null || e === undefined ? "" : (typeof e === "number" ? e : e || "").toString();
|
|
110
116
|
setValue(newValue);
|
|
117
|
+
notify(newValue);
|
|
111
118
|
},
|
|
112
119
|
className: classNames(styles.antdInput, className),
|
|
113
120
|
controls: false,
|
|
@@ -17,6 +17,7 @@ import AntdPassword from "antd/es/input/Password";
|
|
|
17
17
|
import React, { useEffect, useRef, useState } from "react";
|
|
18
18
|
import classNames from "classnames";
|
|
19
19
|
import styles from "./index.module.scss";
|
|
20
|
+
import { useLatestRef } from "../../../hooks/useLatestRef";
|
|
20
21
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
21
22
|
var Password = function Password(props) {
|
|
22
23
|
var _value$toString, _defaultValue$toStrin;
|
|
@@ -26,62 +27,69 @@ var Password = function Password(props) {
|
|
|
26
27
|
defaultValue = props.defaultValue,
|
|
27
28
|
className = props.className,
|
|
28
29
|
inputConfig = _objectWithoutProperties(props, _excluded);
|
|
29
|
-
var _useState = useState(false),
|
|
30
|
-
_useState2 = _slicedToArray(_useState, 2),
|
|
31
|
-
isComposing = _useState2[0],
|
|
32
|
-
setComposing = _useState2[1];
|
|
33
30
|
var ref = useRef(null);
|
|
31
|
+
var getRefRef = useLatestRef(getRef);
|
|
32
|
+
// 输入法组字期间不往外通知。放 ref 不放 state:它只决定「要不要发通知」,
|
|
33
|
+
// 不参与渲染,而且必须在同一次事件里立刻生效
|
|
34
|
+
var composingRef = useRef(false);
|
|
34
35
|
|
|
35
36
|
// On initialization, prefer value, then fall back to defaultValue
|
|
36
37
|
var initialValue = value !== undefined ? (_value$toString = value === null || value === void 0 ? void 0 : value.toString()) !== null && _value$toString !== void 0 ? _value$toString : "" : defaultValue !== undefined ? (_defaultValue$toStrin = defaultValue === null || defaultValue === void 0 ? void 0 : defaultValue.toString()) !== null && _defaultValue$toStrin !== void 0 ? _defaultValue$toStrin : "" : "";
|
|
37
|
-
var
|
|
38
|
-
|
|
39
|
-
_value =
|
|
40
|
-
setValue =
|
|
41
|
-
var _useState5 = useState(initialValue),
|
|
42
|
-
_useState6 = _slicedToArray(_useState5, 2),
|
|
43
|
-
lastValue = _useState6[0],
|
|
44
|
-
setLastValue = _useState6[1];
|
|
38
|
+
var _useState = useState(initialValue),
|
|
39
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
40
|
+
_value = _useState2[0],
|
|
41
|
+
setValue = _useState2[1];
|
|
45
42
|
var prevValueRef = useRef(undefined);
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
43
|
+
// 最近一次通知出去的原文。只用来去掉 compositionend 与 input 两个事件的重复通知
|
|
44
|
+
var notifiedRef = useRef(initialValue);
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* `onChange` 是「用户改了输入」这个**事件**的通知,不是从 state 推导出来的结果,
|
|
48
|
+
* 所以在事件处理里发,不在 effect 里发。详见 `TextArea/index.tsx` 里那段说明——
|
|
49
|
+
* 旧写法(依赖数组里放 `onChange`、体内又调它、用 state 记「通知过没有」)
|
|
50
|
+
* 会让传内联箭头的消费方死循环。
|
|
51
|
+
*/
|
|
52
|
+
var notify = function notify(next) {
|
|
53
|
+
if (next === notifiedRef.current) return;
|
|
54
|
+
notifiedRef.current = next;
|
|
55
|
+
// 全是空白等同于空
|
|
56
|
+
onChange === null || onChange === void 0 || onChange(next.trim() === "" ? "" : next);
|
|
57
|
+
};
|
|
54
58
|
useEffect(function () {
|
|
55
59
|
// Update internal state only when the external value prop actually changes
|
|
56
60
|
if (prevValueRef.current !== value) {
|
|
61
|
+
var _value$toString2;
|
|
57
62
|
prevValueRef.current = value;
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
setValue("");
|
|
64
|
-
setLastValue("");
|
|
65
|
-
}
|
|
63
|
+
|
|
64
|
+
// 外部把值改了,之前通知过什么就不作数了,重新以外部值为准
|
|
65
|
+
var next = value !== undefined ? (_value$toString2 = value === null || value === void 0 ? void 0 : value.toString()) !== null && _value$toString2 !== void 0 ? _value$toString2 : "" : "";
|
|
66
|
+
notifiedRef.current = next;
|
|
67
|
+
setValue(next);
|
|
66
68
|
}
|
|
67
69
|
}, [value]);
|
|
70
|
+
|
|
71
|
+
// 只在挂载时把 ref 交出去。`getRef` 进依赖数组同样会被内联箭头带着每次渲染重跑
|
|
68
72
|
useEffect(function () {
|
|
69
|
-
|
|
70
|
-
|
|
73
|
+
var _getRefRef$current;
|
|
74
|
+
(_getRefRef$current = getRefRef.current) === null || _getRefRef$current === void 0 || _getRefRef$current.call(getRefRef, ref.current);
|
|
75
|
+
}, [getRefRef]);
|
|
71
76
|
return /*#__PURE__*/_jsx(AntdPassword, _objectSpread({
|
|
72
77
|
className: classNames(styles.antdInput, className),
|
|
73
78
|
ref: ref,
|
|
74
79
|
onCompositionStart: function onCompositionStart() {
|
|
75
|
-
|
|
80
|
+
composingRef.current = true;
|
|
76
81
|
},
|
|
77
|
-
onCompositionEnd: function onCompositionEnd() {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
82
|
+
onCompositionEnd: function onCompositionEnd(e) {
|
|
83
|
+
composingRef.current = false;
|
|
84
|
+
// 组完字的那一下自己发通知。浏览器之间 compositionend 与 input 的先后
|
|
85
|
+
// 不一致,`notify` 里按原文去重,两种顺序都只会发出一次
|
|
86
|
+
notify(e.currentTarget.value);
|
|
81
87
|
},
|
|
82
88
|
value: _value,
|
|
83
89
|
onChange: function onChange(e) {
|
|
84
|
-
|
|
90
|
+
var next = e.target.value;
|
|
91
|
+
setValue(next);
|
|
92
|
+
if (!composingRef.current) notify(next);
|
|
85
93
|
}
|
|
86
94
|
}, inputConfig));
|
|
87
95
|
};
|
|
@@ -17,6 +17,7 @@ import React, { useEffect, useRef, useState } from "react";
|
|
|
17
17
|
import AntdSearch from "antd/es/input/Search";
|
|
18
18
|
import classNames from "classnames";
|
|
19
19
|
import styles from "./index.module.scss";
|
|
20
|
+
import { useLatestRef } from "../../../hooks/useLatestRef";
|
|
20
21
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
21
22
|
var Search = function Search(props) {
|
|
22
23
|
var _value$toString, _defaultValue$toStrin;
|
|
@@ -26,62 +27,69 @@ var Search = function Search(props) {
|
|
|
26
27
|
defaultValue = props.defaultValue,
|
|
27
28
|
className = props.className,
|
|
28
29
|
inputConfig = _objectWithoutProperties(props, _excluded);
|
|
29
|
-
var _useState = useState(false),
|
|
30
|
-
_useState2 = _slicedToArray(_useState, 2),
|
|
31
|
-
isComposing = _useState2[0],
|
|
32
|
-
setComposing = _useState2[1];
|
|
33
30
|
var ref = useRef(null);
|
|
31
|
+
var getRefRef = useLatestRef(getRef);
|
|
32
|
+
// 输入法组字期间不往外通知。放 ref 不放 state:它只决定「要不要发通知」,
|
|
33
|
+
// 不参与渲染,而且必须在同一次事件里立刻生效
|
|
34
|
+
var composingRef = useRef(false);
|
|
34
35
|
|
|
35
36
|
// On initialization, prefer value, then fall back to defaultValue
|
|
36
37
|
var initialValue = value !== undefined ? (_value$toString = value === null || value === void 0 ? void 0 : value.toString()) !== null && _value$toString !== void 0 ? _value$toString : "" : defaultValue !== undefined ? (_defaultValue$toStrin = defaultValue === null || defaultValue === void 0 ? void 0 : defaultValue.toString()) !== null && _defaultValue$toStrin !== void 0 ? _defaultValue$toStrin : "" : "";
|
|
37
|
-
var
|
|
38
|
-
|
|
39
|
-
_value =
|
|
40
|
-
setValue =
|
|
41
|
-
var _useState5 = useState(initialValue),
|
|
42
|
-
_useState6 = _slicedToArray(_useState5, 2),
|
|
43
|
-
lastValue = _useState6[0],
|
|
44
|
-
setLastValue = _useState6[1];
|
|
38
|
+
var _useState = useState(initialValue),
|
|
39
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
40
|
+
_value = _useState2[0],
|
|
41
|
+
setValue = _useState2[1];
|
|
45
42
|
var prevValueRef = useRef(undefined);
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
43
|
+
// 最近一次通知出去的原文。只用来去掉 compositionend 与 input 两个事件的重复通知
|
|
44
|
+
var notifiedRef = useRef(initialValue);
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* `onChange` 是「用户改了输入」这个**事件**的通知,不是从 state 推导出来的结果,
|
|
48
|
+
* 所以在事件处理里发,不在 effect 里发。详见 `TextArea/index.tsx` 里那段说明——
|
|
49
|
+
* 旧写法(依赖数组里放 `onChange`、体内又调它、用 state 记「通知过没有」)
|
|
50
|
+
* 会让传内联箭头的消费方死循环。
|
|
51
|
+
*/
|
|
52
|
+
var notify = function notify(next) {
|
|
53
|
+
if (next === notifiedRef.current) return;
|
|
54
|
+
notifiedRef.current = next;
|
|
55
|
+
// 全是空白等同于空
|
|
56
|
+
onChange === null || onChange === void 0 || onChange(next.trim() === "" ? "" : next);
|
|
57
|
+
};
|
|
54
58
|
useEffect(function () {
|
|
55
59
|
// Update internal state only when the external value prop actually changes
|
|
56
60
|
if (prevValueRef.current !== value) {
|
|
61
|
+
var _value$toString2;
|
|
57
62
|
prevValueRef.current = value;
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
setValue("");
|
|
64
|
-
setLastValue("");
|
|
65
|
-
}
|
|
63
|
+
|
|
64
|
+
// 外部把值改了,之前通知过什么就不作数了,重新以外部值为准
|
|
65
|
+
var next = value !== undefined ? (_value$toString2 = value === null || value === void 0 ? void 0 : value.toString()) !== null && _value$toString2 !== void 0 ? _value$toString2 : "" : "";
|
|
66
|
+
notifiedRef.current = next;
|
|
67
|
+
setValue(next);
|
|
66
68
|
}
|
|
67
69
|
}, [value]);
|
|
70
|
+
|
|
71
|
+
// 只在挂载时把 ref 交出去。`getRef` 进依赖数组同样会被内联箭头带着每次渲染重跑
|
|
68
72
|
useEffect(function () {
|
|
69
|
-
|
|
70
|
-
|
|
73
|
+
var _getRefRef$current;
|
|
74
|
+
(_getRefRef$current = getRefRef.current) === null || _getRefRef$current === void 0 || _getRefRef$current.call(getRefRef, ref.current);
|
|
75
|
+
}, [getRefRef]);
|
|
71
76
|
return /*#__PURE__*/_jsx(AntdSearch, _objectSpread({
|
|
72
77
|
ref: ref,
|
|
73
78
|
className: classNames(styles.antdInput, className),
|
|
74
79
|
onCompositionStart: function onCompositionStart() {
|
|
75
|
-
|
|
80
|
+
composingRef.current = true;
|
|
76
81
|
},
|
|
77
|
-
onCompositionEnd: function onCompositionEnd() {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
82
|
+
onCompositionEnd: function onCompositionEnd(e) {
|
|
83
|
+
composingRef.current = false;
|
|
84
|
+
// 组完字的那一下自己发通知。浏览器之间 compositionend 与 input 的先后
|
|
85
|
+
// 不一致,`notify` 里按原文去重,两种顺序都只会发出一次
|
|
86
|
+
notify(e.currentTarget.value);
|
|
81
87
|
},
|
|
82
88
|
value: _value,
|
|
83
89
|
onChange: function onChange(e) {
|
|
84
|
-
|
|
90
|
+
var next = e.target.value;
|
|
91
|
+
setValue(next);
|
|
92
|
+
if (!composingRef.current) notify(next);
|
|
85
93
|
}
|
|
86
94
|
}, inputConfig));
|
|
87
95
|
};
|