@tidbcloud/uikit 2.0.0-beta.82 → 2.0.0-beta.83

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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @tidbcloud/uikit
2
2
 
3
+ ## 2.0.0-beta.83
4
+
5
+ ### Patch Changes
6
+
7
+ - fix DateTimePicker with refactored scroll picker
8
+
3
9
  ## 2.0.0-beta.82
4
10
 
5
11
  ### Patch Changes
@@ -14,6 +14,8 @@ const dayjs = require("dayjs");
14
14
  require("../../node_modules/.pnpm/dayjs@1.11.13/node_modules/dayjs/plugin/timezone.cjs");
15
15
  require("../../node_modules/.pnpm/dayjs@1.11.13/node_modules/dayjs/plugin/utc.cjs");
16
16
  const constant = require("./constant.cjs");
17
+ const Flex = require("../../node_modules/.pnpm/@mantine_core@7.13.2_patch_hash_v5k5cxye7xaihpcgowhgciky7a_@mantine_hooks@7.13.2_react@18.3.1_hlfamvk7n3o6ychyvm5cyru4yu/node_modules/@mantine/core/esm/components/Flex/Flex.cjs");
18
+ const useUncontrolled = require("../../node_modules/.pnpm/@mantine_hooks@7.13.2_react@18.3.1/node_modules/@mantine/hooks/esm/use-uncontrolled/use-uncontrolled.cjs");
17
19
  const ScrollArea = require("../../node_modules/.pnpm/@mantine_core@7.13.2_patch_hash_v5k5cxye7xaihpcgowhgciky7a_@mantine_hooks@7.13.2_react@18.3.1_hlfamvk7n3o6ychyvm5cyru4yu/node_modules/@mantine/core/esm/components/ScrollArea/ScrollArea.cjs");
18
20
  const Box = require("../../node_modules/.pnpm/@mantine_core@7.13.2_patch_hash_v5k5cxye7xaihpcgowhgciky7a_@mantine_hooks@7.13.2_react@18.3.1_hlfamvk7n3o6ychyvm5cyru4yu/node_modules/@mantine/core/esm/core/Box/Box.cjs");
19
21
  const createStyles = require("../../node_modules/.pnpm/@mantine_emotion@7.13.2_@emotion_cache@11.13.1_@emotion_react@11.13.3_@types_react@18.3.11_re_v5yho7ri2fgh4vhey6nnpomqsu/node_modules/@mantine/emotion/esm/create-styles.cjs");
@@ -129,18 +131,41 @@ const getTimeRange = ({
129
131
  }
130
132
  return { min, max };
131
133
  };
132
- const usePickerScrollColumn = ({ min, max, curr, open, render }) => {
133
- const { classes, cx } = useStyles();
134
+ const default2DigitRender = (val) => lodashEs.padStart(String(val), 2, "0");
135
+ function TimePickerScrollerColumn({
136
+ min,
137
+ max,
138
+ curr,
139
+ render = default2DigitRender,
140
+ onChange,
141
+ name,
142
+ currentValueChangedBy
143
+ }) {
144
+ const { classes, cx: clsx } = useStyles();
134
145
  const ref = React.useRef(null);
146
+ const numbers = React.useMemo(() => lodashEs.range(min, max + 1), [min, max]);
135
147
  const timeoutRef = React.useRef();
136
- const [val, setVal] = React.useState(curr);
137
- const handleClickCell = ahooks.useMemoizedFn((e, i) => {
138
- var _a;
139
- e.stopPropagation();
140
- e.preventDefault();
141
- (_a = ref.current) == null ? void 0 : _a.scrollTo({ top: i * constant.CellHeight, behavior: "smooth" });
148
+ const isArtificialScroll = React.useRef(false);
149
+ const [val, setVal] = useUncontrolled.useUncontrolled({
150
+ value: curr,
151
+ onChange
152
+ });
153
+ const adjustScrollTop = ahooks.useMemoizedFn((value) => {
154
+ if (currentValueChangedBy === "timeScroller") return;
155
+ const i = numbers.findIndex((i2) => i2 === value);
156
+ if (i !== -1 && ref.current) {
157
+ isArtificialScroll.current = true;
158
+ ref.current.scrollTop = i * constant.CellHeight;
159
+ window.requestAnimationFrame(() => {
160
+ setTimeout(() => {
161
+ isArtificialScroll.current = false;
162
+ }, 100);
163
+ });
164
+ }
142
165
  });
143
166
  const onScroll = ahooks.useMemoizedFn((position) => {
167
+ if (isArtificialScroll.current) return;
168
+ if (currentValueChangedBy) return;
144
169
  clearTimeout(timeoutRef.current);
145
170
  const i = position.y / constant.CellHeight;
146
171
  if (i === Math.floor(i)) {
@@ -158,62 +183,51 @@ const usePickerScrollColumn = ({ min, max, curr, open, render }) => {
158
183
  }, 300);
159
184
  }
160
185
  });
161
- const numbers = React.useMemo(() => lodashEs.range(min, max + 1), [min, max]);
162
- const content = React.useMemo(() => {
163
- return /* @__PURE__ */ jsxRuntime.jsxRuntimeExports.jsxs(
164
- ScrollArea.ScrollArea,
165
- {
166
- viewportRef: ref,
167
- type: "never",
168
- styles: {
169
- viewport: {
170
- scrollSnapPointsY: `repeat(${constant.CellHeight}px)`,
171
- scrollSnapType: "y mandatory"
172
- }
173
- },
174
- onScrollPositionChange: onScroll,
175
- children: [
176
- numbers.map((i, index) => /* @__PURE__ */ jsxRuntime.jsxRuntimeExports.jsx(
177
- "div",
178
- {
179
- className: cx(classes.cell, i === curr && classes.bold),
180
- onClick: (e) => handleClickCell(e, index),
181
- style: constant.CellStyle,
182
- children: render ? render(i) : i
183
- },
184
- i
185
- )),
186
- lodashEs.range(6).map((i) => /* @__PURE__ */ jsxRuntime.jsxRuntimeExports.jsx(Box.Box, { className: cx(classes.cell, classes.cellPlaceholder), style: constant.CellStyle }, i))
187
- ]
188
- }
189
- );
190
- }, [numbers, handleClickCell, onScroll, curr, render, classes]);
191
- const adjustScrollTop = ahooks.useMemoizedFn(() => {
186
+ const handleClickCell = ahooks.useMemoizedFn((e, i) => {
192
187
  var _a;
193
- const i = numbers.findIndex((i2) => i2 === val);
194
- if (i !== -1 && open) {
195
- const s = i * constant.CellHeight;
196
- (_a = ref.current) == null ? void 0 : _a.scrollTo({ top: s, behavior: "auto" });
197
- }
188
+ e.stopPropagation();
189
+ e.preventDefault();
190
+ (_a = ref.current) == null ? void 0 : _a.scrollTo({ top: i * constant.CellHeight, behavior: "smooth" });
198
191
  });
199
192
  React.useEffect(() => {
200
- const rIC = window.requestIdleCallback ?? window.setTimeout;
201
- rIC(() => {
202
- adjustScrollTop();
203
- });
204
- }, [open, val, adjustScrollTop]);
205
- React.useEffect(() => {
206
- if (numbers.findIndex((i) => i === curr) > -1) {
207
- setVal(curr);
193
+ adjustScrollTop(val);
194
+ }, [val]);
195
+ return /* @__PURE__ */ jsxRuntime.jsxRuntimeExports.jsxs(
196
+ ScrollArea.ScrollArea,
197
+ {
198
+ viewportRef: ref,
199
+ type: "never",
200
+ styles: {
201
+ viewport: {
202
+ scrollSnapPointsY: `repeat(${constant.CellHeight}px)`,
203
+ scrollSnapType: "y mandatory"
204
+ }
205
+ },
206
+ onScrollPositionChange: onScroll,
207
+ children: [
208
+ numbers.map((i, index) => /* @__PURE__ */ jsxRuntime.jsxRuntimeExports.jsx(
209
+ "div",
210
+ {
211
+ className: clsx(classes.cell, i === curr && classes.bold),
212
+ onClick: (e) => handleClickCell(e, index),
213
+ style: constant.CellStyle,
214
+ children: render ? render(i) : i
215
+ },
216
+ i
217
+ )),
218
+ lodashEs.range(6).map((i) => /* @__PURE__ */ jsxRuntime.jsxRuntimeExports.jsx(Box.Box, { className: clsx(classes.cell, classes.cellPlaceholder), style: constant.CellStyle }, i))
219
+ ]
208
220
  }
209
- }, [curr, numbers]);
210
- return {
211
- value: val,
212
- content
213
- };
214
- };
215
- const default2DigitRender = (val) => lodashEs.padStart(String(val), 2, "0");
216
- const useTimePickerScroll = (currentValue, open, start, end, utcOffset) => {
221
+ );
222
+ }
223
+ function TimeScollerPicker({
224
+ currentValue,
225
+ currentValueChangedBy,
226
+ start,
227
+ end,
228
+ utcOffset,
229
+ onChange
230
+ }) {
217
231
  const options = React.useMemo(
218
232
  () => ({
219
233
  hour: getTimeRange({ curr: currentValue, start, end, utcOffset, type: "hour" }),
@@ -222,43 +236,58 @@ const useTimePickerScroll = (currentValue, open, start, end, utcOffset) => {
222
236
  }),
223
237
  [currentValue, start, end, utcOffset]
224
238
  );
225
- const hour = usePickerScrollColumn({
226
- ...options.hour,
227
- curr: typeof utcOffset !== "undefined" ? currentValue.utcOffset(utcOffset ?? currentValue.utcOffset()).hour() : currentValue.hour(),
228
- open,
229
- render: default2DigitRender,
230
- title: "hour"
239
+ const hourValue = React.useMemo(() => {
240
+ return typeof utcOffset === "number" ? currentValue.utcOffset(utcOffset).hour() : currentValue.hour();
241
+ }, [currentValue, utcOffset]);
242
+ const minuteValue = React.useMemo(() => {
243
+ return typeof utcOffset === "number" ? currentValue.utcOffset(utcOffset).minute() : currentValue.minute();
244
+ }, [currentValue, utcOffset]);
245
+ const secondValue = React.useMemo(() => {
246
+ return typeof utcOffset === "number" ? currentValue.utcOffset(utcOffset).second() : currentValue.second();
247
+ }, [currentValue, utcOffset]);
248
+ const onHourChange = ahooks.useMemoizedFn((v) => {
249
+ onChange == null ? void 0 : onChange([v, minuteValue, secondValue]);
231
250
  });
232
- const minute = usePickerScrollColumn({
233
- ...options.minute,
234
- curr: currentValue.minute(),
235
- open,
236
- render: default2DigitRender,
237
- title: "minute"
251
+ const onMinuteChange = ahooks.useMemoizedFn((v) => {
252
+ onChange == null ? void 0 : onChange([hourValue, v, secondValue]);
238
253
  });
239
- const second = usePickerScrollColumn({
240
- ...options.second,
241
- curr: currentValue.second(),
242
- open,
243
- render: default2DigitRender,
244
- title: "second"
254
+ const onSecondChange = ahooks.useMemoizedFn((v) => {
255
+ onChange == null ? void 0 : onChange([hourValue, minuteValue, v]);
245
256
  });
246
- const content = React.useMemo(
247
- () => /* @__PURE__ */ jsxRuntime.jsxRuntimeExports.jsxs(jsxRuntime.jsxRuntimeExports.Fragment, { children: [
248
- hour.content,
249
- minute.content,
250
- second.content
251
- ] }),
252
- [hour.content, minute.content, second.content]
253
- );
254
- const value = React.useMemo(
255
- () => [hour.value, minute.value, second.value],
256
- [hour.value, minute.value, second.value]
257
- );
258
- return {
259
- content,
260
- value
261
- };
262
- };
263
- exports.getTimeRange = getTimeRange;
264
- exports.useTimePickerScroll = useTimePickerScroll;
257
+ return /* @__PURE__ */ jsxRuntime.jsxRuntimeExports.jsxs(Flex.Flex, { mah: "100%", gap: 8, children: [
258
+ /* @__PURE__ */ jsxRuntime.jsxRuntimeExports.jsx(
259
+ TimePickerScrollerColumn,
260
+ {
261
+ name: "hour",
262
+ min: options.hour.min,
263
+ max: options.hour.max,
264
+ curr: hourValue,
265
+ onChange: onHourChange,
266
+ currentValueChangedBy
267
+ }
268
+ ),
269
+ /* @__PURE__ */ jsxRuntime.jsxRuntimeExports.jsx(
270
+ TimePickerScrollerColumn,
271
+ {
272
+ name: "minute",
273
+ min: options.minute.min,
274
+ max: options.minute.max,
275
+ curr: minuteValue,
276
+ onChange: onMinuteChange,
277
+ currentValueChangedBy
278
+ }
279
+ ),
280
+ /* @__PURE__ */ jsxRuntime.jsxRuntimeExports.jsx(
281
+ TimePickerScrollerColumn,
282
+ {
283
+ name: "second",
284
+ min: options.second.min,
285
+ max: options.second.max,
286
+ curr: secondValue,
287
+ onChange: onSecondChange,
288
+ currentValueChangedBy
289
+ }
290
+ )
291
+ ] });
292
+ }
293
+ exports.TimeScollerPicker = TimeScollerPicker;
@@ -0,0 +1,10 @@
1
+ import { Dayjs } from 'dayjs';
2
+ export type CurrentValueChangedBy = 'calendar' | 'timeInput' | 'timeScroller';
3
+ export declare function TimeScollerPicker({ currentValue, currentValueChangedBy, start, end, utcOffset, onChange }: {
4
+ currentValue: Dayjs;
5
+ currentValueChangedBy: CurrentValueChangedBy | null;
6
+ start?: Date;
7
+ end?: Date;
8
+ utcOffset?: number;
9
+ onChange?: (v: [number, number, number]) => void;
10
+ }): import("react/jsx-runtime.js").JSX.Element;
@@ -0,0 +1,10 @@
1
+ import { Dayjs } from 'dayjs';
2
+ export type CurrentValueChangedBy = 'calendar' | 'timeInput' | 'timeScroller';
3
+ export declare function TimeScollerPicker({ currentValue, currentValueChangedBy, start, end, utcOffset, onChange }: {
4
+ currentValue: Dayjs;
5
+ currentValueChangedBy: CurrentValueChangedBy | null;
6
+ start?: Date;
7
+ end?: Date;
8
+ utcOffset?: number;
9
+ onChange?: (v: [number, number, number]) => void;
10
+ }): import("react/jsx-runtime.js").JSX.Element;
@@ -1,7 +1,7 @@
1
1
  import { j as jsxRuntimeExports } from "../../node_modules/.pnpm/react@18.3.1/node_modules/react/jsx-runtime.js";
2
2
  import { useMemoizedFn } from "ahooks";
3
3
  import { range, padStart } from "lodash-es";
4
- import { useMemo, useRef, useState, useEffect } from "react";
4
+ import { useMemo, useRef, useEffect } from "react";
5
5
  /* empty css */
6
6
  /* empty css */
7
7
  /* empty css */
@@ -12,6 +12,8 @@ import dayjs from "dayjs";
12
12
  import "../../node_modules/.pnpm/dayjs@1.11.13/node_modules/dayjs/plugin/timezone.js";
13
13
  import "../../node_modules/.pnpm/dayjs@1.11.13/node_modules/dayjs/plugin/utc.js";
14
14
  import { CellHeight, CellStyle } from "./constant.js";
15
+ import { Flex } from "../../node_modules/.pnpm/@mantine_core@7.13.2_patch_hash_v5k5cxye7xaihpcgowhgciky7a_@mantine_hooks@7.13.2_react@18.3.1_hlfamvk7n3o6ychyvm5cyru4yu/node_modules/@mantine/core/esm/components/Flex/Flex.js";
16
+ import { useUncontrolled } from "../../node_modules/.pnpm/@mantine_hooks@7.13.2_react@18.3.1/node_modules/@mantine/hooks/esm/use-uncontrolled/use-uncontrolled.js";
15
17
  import { ScrollArea } from "../../node_modules/.pnpm/@mantine_core@7.13.2_patch_hash_v5k5cxye7xaihpcgowhgciky7a_@mantine_hooks@7.13.2_react@18.3.1_hlfamvk7n3o6ychyvm5cyru4yu/node_modules/@mantine/core/esm/components/ScrollArea/ScrollArea.js";
16
18
  import { Box } from "../../node_modules/.pnpm/@mantine_core@7.13.2_patch_hash_v5k5cxye7xaihpcgowhgciky7a_@mantine_hooks@7.13.2_react@18.3.1_hlfamvk7n3o6ychyvm5cyru4yu/node_modules/@mantine/core/esm/core/Box/Box.js";
17
19
  import { createStyles } from "../../node_modules/.pnpm/@mantine_emotion@7.13.2_@emotion_cache@11.13.1_@emotion_react@11.13.3_@types_react@18.3.11_re_v5yho7ri2fgh4vhey6nnpomqsu/node_modules/@mantine/emotion/esm/create-styles.js";
@@ -127,18 +129,41 @@ const getTimeRange = ({
127
129
  }
128
130
  return { min, max };
129
131
  };
130
- const usePickerScrollColumn = ({ min, max, curr, open, render }) => {
131
- const { classes, cx } = useStyles();
132
+ const default2DigitRender = (val) => padStart(String(val), 2, "0");
133
+ function TimePickerScrollerColumn({
134
+ min,
135
+ max,
136
+ curr,
137
+ render = default2DigitRender,
138
+ onChange,
139
+ name,
140
+ currentValueChangedBy
141
+ }) {
142
+ const { classes, cx: clsx } = useStyles();
132
143
  const ref = useRef(null);
144
+ const numbers = useMemo(() => range(min, max + 1), [min, max]);
133
145
  const timeoutRef = useRef();
134
- const [val, setVal] = useState(curr);
135
- const handleClickCell = useMemoizedFn((e, i) => {
136
- var _a;
137
- e.stopPropagation();
138
- e.preventDefault();
139
- (_a = ref.current) == null ? void 0 : _a.scrollTo({ top: i * CellHeight, behavior: "smooth" });
146
+ const isArtificialScroll = useRef(false);
147
+ const [val, setVal] = useUncontrolled({
148
+ value: curr,
149
+ onChange
150
+ });
151
+ const adjustScrollTop = useMemoizedFn((value) => {
152
+ if (currentValueChangedBy === "timeScroller") return;
153
+ const i = numbers.findIndex((i2) => i2 === value);
154
+ if (i !== -1 && ref.current) {
155
+ isArtificialScroll.current = true;
156
+ ref.current.scrollTop = i * CellHeight;
157
+ window.requestAnimationFrame(() => {
158
+ setTimeout(() => {
159
+ isArtificialScroll.current = false;
160
+ }, 100);
161
+ });
162
+ }
140
163
  });
141
164
  const onScroll = useMemoizedFn((position) => {
165
+ if (isArtificialScroll.current) return;
166
+ if (currentValueChangedBy) return;
142
167
  clearTimeout(timeoutRef.current);
143
168
  const i = position.y / CellHeight;
144
169
  if (i === Math.floor(i)) {
@@ -156,62 +181,51 @@ const usePickerScrollColumn = ({ min, max, curr, open, render }) => {
156
181
  }, 300);
157
182
  }
158
183
  });
159
- const numbers = useMemo(() => range(min, max + 1), [min, max]);
160
- const content = useMemo(() => {
161
- return /* @__PURE__ */ jsxRuntimeExports.jsxs(
162
- ScrollArea,
163
- {
164
- viewportRef: ref,
165
- type: "never",
166
- styles: {
167
- viewport: {
168
- scrollSnapPointsY: `repeat(${CellHeight}px)`,
169
- scrollSnapType: "y mandatory"
170
- }
171
- },
172
- onScrollPositionChange: onScroll,
173
- children: [
174
- numbers.map((i, index) => /* @__PURE__ */ jsxRuntimeExports.jsx(
175
- "div",
176
- {
177
- className: cx(classes.cell, i === curr && classes.bold),
178
- onClick: (e) => handleClickCell(e, index),
179
- style: CellStyle,
180
- children: render ? render(i) : i
181
- },
182
- i
183
- )),
184
- range(6).map((i) => /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { className: cx(classes.cell, classes.cellPlaceholder), style: CellStyle }, i))
185
- ]
186
- }
187
- );
188
- }, [numbers, handleClickCell, onScroll, curr, render, classes]);
189
- const adjustScrollTop = useMemoizedFn(() => {
184
+ const handleClickCell = useMemoizedFn((e, i) => {
190
185
  var _a;
191
- const i = numbers.findIndex((i2) => i2 === val);
192
- if (i !== -1 && open) {
193
- const s = i * CellHeight;
194
- (_a = ref.current) == null ? void 0 : _a.scrollTo({ top: s, behavior: "auto" });
195
- }
186
+ e.stopPropagation();
187
+ e.preventDefault();
188
+ (_a = ref.current) == null ? void 0 : _a.scrollTo({ top: i * CellHeight, behavior: "smooth" });
196
189
  });
197
190
  useEffect(() => {
198
- const rIC = window.requestIdleCallback ?? window.setTimeout;
199
- rIC(() => {
200
- adjustScrollTop();
201
- });
202
- }, [open, val, adjustScrollTop]);
203
- useEffect(() => {
204
- if (numbers.findIndex((i) => i === curr) > -1) {
205
- setVal(curr);
191
+ adjustScrollTop(val);
192
+ }, [val]);
193
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
194
+ ScrollArea,
195
+ {
196
+ viewportRef: ref,
197
+ type: "never",
198
+ styles: {
199
+ viewport: {
200
+ scrollSnapPointsY: `repeat(${CellHeight}px)`,
201
+ scrollSnapType: "y mandatory"
202
+ }
203
+ },
204
+ onScrollPositionChange: onScroll,
205
+ children: [
206
+ numbers.map((i, index) => /* @__PURE__ */ jsxRuntimeExports.jsx(
207
+ "div",
208
+ {
209
+ className: clsx(classes.cell, i === curr && classes.bold),
210
+ onClick: (e) => handleClickCell(e, index),
211
+ style: CellStyle,
212
+ children: render ? render(i) : i
213
+ },
214
+ i
215
+ )),
216
+ range(6).map((i) => /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { className: clsx(classes.cell, classes.cellPlaceholder), style: CellStyle }, i))
217
+ ]
206
218
  }
207
- }, [curr, numbers]);
208
- return {
209
- value: val,
210
- content
211
- };
212
- };
213
- const default2DigitRender = (val) => padStart(String(val), 2, "0");
214
- const useTimePickerScroll = (currentValue, open, start, end, utcOffset) => {
219
+ );
220
+ }
221
+ function TimeScollerPicker({
222
+ currentValue,
223
+ currentValueChangedBy,
224
+ start,
225
+ end,
226
+ utcOffset,
227
+ onChange
228
+ }) {
215
229
  const options = useMemo(
216
230
  () => ({
217
231
  hour: getTimeRange({ curr: currentValue, start, end, utcOffset, type: "hour" }),
@@ -220,45 +234,60 @@ const useTimePickerScroll = (currentValue, open, start, end, utcOffset) => {
220
234
  }),
221
235
  [currentValue, start, end, utcOffset]
222
236
  );
223
- const hour = usePickerScrollColumn({
224
- ...options.hour,
225
- curr: typeof utcOffset !== "undefined" ? currentValue.utcOffset(utcOffset ?? currentValue.utcOffset()).hour() : currentValue.hour(),
226
- open,
227
- render: default2DigitRender,
228
- title: "hour"
237
+ const hourValue = useMemo(() => {
238
+ return typeof utcOffset === "number" ? currentValue.utcOffset(utcOffset).hour() : currentValue.hour();
239
+ }, [currentValue, utcOffset]);
240
+ const minuteValue = useMemo(() => {
241
+ return typeof utcOffset === "number" ? currentValue.utcOffset(utcOffset).minute() : currentValue.minute();
242
+ }, [currentValue, utcOffset]);
243
+ const secondValue = useMemo(() => {
244
+ return typeof utcOffset === "number" ? currentValue.utcOffset(utcOffset).second() : currentValue.second();
245
+ }, [currentValue, utcOffset]);
246
+ const onHourChange = useMemoizedFn((v) => {
247
+ onChange == null ? void 0 : onChange([v, minuteValue, secondValue]);
229
248
  });
230
- const minute = usePickerScrollColumn({
231
- ...options.minute,
232
- curr: currentValue.minute(),
233
- open,
234
- render: default2DigitRender,
235
- title: "minute"
249
+ const onMinuteChange = useMemoizedFn((v) => {
250
+ onChange == null ? void 0 : onChange([hourValue, v, secondValue]);
236
251
  });
237
- const second = usePickerScrollColumn({
238
- ...options.second,
239
- curr: currentValue.second(),
240
- open,
241
- render: default2DigitRender,
242
- title: "second"
252
+ const onSecondChange = useMemoizedFn((v) => {
253
+ onChange == null ? void 0 : onChange([hourValue, minuteValue, v]);
243
254
  });
244
- const content = useMemo(
245
- () => /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
246
- hour.content,
247
- minute.content,
248
- second.content
249
- ] }),
250
- [hour.content, minute.content, second.content]
251
- );
252
- const value = useMemo(
253
- () => [hour.value, minute.value, second.value],
254
- [hour.value, minute.value, second.value]
255
- );
256
- return {
257
- content,
258
- value
259
- };
260
- };
255
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(Flex, { mah: "100%", gap: 8, children: [
256
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
257
+ TimePickerScrollerColumn,
258
+ {
259
+ name: "hour",
260
+ min: options.hour.min,
261
+ max: options.hour.max,
262
+ curr: hourValue,
263
+ onChange: onHourChange,
264
+ currentValueChangedBy
265
+ }
266
+ ),
267
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
268
+ TimePickerScrollerColumn,
269
+ {
270
+ name: "minute",
271
+ min: options.minute.min,
272
+ max: options.minute.max,
273
+ curr: minuteValue,
274
+ onChange: onMinuteChange,
275
+ currentValueChangedBy
276
+ }
277
+ ),
278
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
279
+ TimePickerScrollerColumn,
280
+ {
281
+ name: "second",
282
+ min: options.second.min,
283
+ max: options.second.max,
284
+ curr: secondValue,
285
+ onChange: onSecondChange,
286
+ currentValueChangedBy
287
+ }
288
+ )
289
+ ] });
290
+ }
261
291
  export {
262
- getTimeRange,
263
- useTimePickerScroll
292
+ TimeScollerPicker
264
293
  };
@@ -15,8 +15,9 @@ const dayjs = require("dayjs");
15
15
  require("../../node_modules/.pnpm/dayjs@1.11.13/node_modules/dayjs/plugin/timezone.cjs");
16
16
  require("../../node_modules/.pnpm/dayjs@1.11.13/node_modules/dayjs/plugin/utc.cjs");
17
17
  const helpers = require("../TimeRangePicker/helpers.cjs");
18
- const usePickerScroll = require("./usePickerScroll.cjs");
18
+ const TimeScollerPicker = require("./TimeScollerPicker.cjs");
19
19
  const useDisclosure = require("../../node_modules/.pnpm/@mantine_hooks@7.13.2_react@18.3.1/node_modules/@mantine/hooks/esm/use-disclosure/use-disclosure.cjs");
20
+ const useUncontrolled = require("../../node_modules/.pnpm/@mantine_hooks@7.13.2_react@18.3.1/node_modules/@mantine/hooks/esm/use-uncontrolled/use-uncontrolled.cjs");
20
21
  const Popover = require("../../node_modules/.pnpm/@mantine_core@7.13.2_patch_hash_v5k5cxye7xaihpcgowhgciky7a_@mantine_hooks@7.13.2_react@18.3.1_hlfamvk7n3o6ychyvm5cyru4yu/node_modules/@mantine/core/esm/components/Popover/Popover.cjs");
21
22
  const TextInput = require("../../primitive/TextInput/TextInput.cjs");
22
23
  const Loader = require("../../node_modules/.pnpm/@mantine_core@7.13.2_patch_hash_v5k5cxye7xaihpcgowhgciky7a_@mantine_hooks@7.13.2_react@18.3.1_hlfamvk7n3o6ychyvm5cyru4yu/node_modules/@mantine/core/esm/components/Loader/Loader.cjs");
@@ -43,12 +44,29 @@ const DateTimePicker = ({
43
44
  size
44
45
  }) => {
45
46
  const [opened, { close, open }] = useDisclosure.useDisclosure(false);
46
- const [currentValue, setCurrentValue] = React.useState(
47
- defaultValue ? dayjs(defaultValue) : value ? dayjs(value) : dayjs()
48
- );
49
- const updateCurrentValue = ahooks.useMemoizedFn((val) => {
50
- setCurrentValue(val);
51
- onChange == null ? void 0 : onChange(val.toDate());
47
+ const [currentValue, setCurrentValue] = useUncontrolled.useUncontrolled({
48
+ value: value ? dayjs(value) : void 0,
49
+ defaultValue: defaultValue ? dayjs(defaultValue) : dayjs(),
50
+ onChange: (v) => {
51
+ onChange == null ? void 0 : onChange(v.toDate());
52
+ }
53
+ });
54
+ const [currentValueChangedBy, setCurrentValueChangedBy] = React.useState(null);
55
+ const updateCurrentValue = ahooks.useMemoizedFn((val, from) => {
56
+ let next = val;
57
+ if ((currentValue == null ? void 0 : currentValue.unix()) === next.unix()) {
58
+ return;
59
+ }
60
+ if (startDate && next.valueOf() < startDate.valueOf()) {
61
+ next = dayjs(startDate);
62
+ } else if (endDate && next.valueOf() > endDate.valueOf()) {
63
+ next = dayjs(endDate);
64
+ }
65
+ setCurrentValue(next);
66
+ setCurrentValueChangedBy(from);
67
+ setTimeout(() => {
68
+ setCurrentValueChangedBy(null);
69
+ }, 20);
52
70
  });
53
71
  const inputStr = currentValue.format(format);
54
72
  const utcStr = React.useMemo(() => {
@@ -56,40 +74,24 @@ const DateTimePicker = ({
56
74
  const m = utcOffset % 60;
57
75
  return `UTC${h >= 0 ? "+" : "-"}${Math.abs(h)}:${m < 10 ? "0" : ""}${m}`;
58
76
  }, [utcOffset]);
59
- const scroll = usePickerScroll.useTimePickerScroll(currentValue, opened, startDate, endDate, utcOffset);
60
77
  const calendarChange = ahooks.useMemoizedFn((v) => {
61
78
  let next = currentValue;
62
79
  next = next.utcOffset(utcOffset).year(v.getFullYear()).month(v.getMonth()).date(v.getDate());
63
- if ((currentValue == null ? void 0 : currentValue.unix()) !== next.unix()) {
64
- updateCurrentValue(next);
65
- }
80
+ updateCurrentValue(next, "calendar");
66
81
  });
67
82
  const timeInputChange = ahooks.useMemoizedFn((e) => {
68
83
  const originVal = e.currentTarget.value;
69
84
  const v = dayjs(originVal, "HH:mm:ss").toDate();
70
85
  let next = currentValue;
71
86
  next = next.utcOffset(utcOffset).hour(v.getHours()).minute(v.getMinutes()).second(v.getSeconds());
72
- if (startDate && next.valueOf() < startDate.valueOf()) {
73
- updateCurrentValue(dayjs(startDate));
74
- } else if (endDate && next.valueOf() > endDate.valueOf()) {
75
- updateCurrentValue(dayjs(endDate));
76
- } else if ((currentValue == null ? void 0 : currentValue.unix()) !== next.unix()) {
77
- updateCurrentValue(next);
78
- }
87
+ updateCurrentValue(next, "timeInput");
79
88
  });
80
- ahooks.useUpdateEffect(() => {
89
+ const timeScrollPickerChange = ahooks.useMemoizedFn((v) => {
90
+ const [h, m, s] = v;
81
91
  let next = currentValue;
82
- const [h, m, s] = scroll.value;
83
92
  next = next.utcOffset(utcOffset).hour(h).minute(m).second(s);
84
- if ((currentValue == null ? void 0 : currentValue.unix()) !== next.unix()) {
85
- updateCurrentValue(next);
86
- }
87
- }, [scroll.value]);
88
- ahooks.useUpdateEffect(() => {
89
- if (value && dayjs(value).unix() !== currentValue.unix()) {
90
- updateCurrentValue(dayjs(value));
91
- }
92
- }, [value]);
93
+ updateCurrentValue(next, "timeScroller");
94
+ });
93
95
  return /* @__PURE__ */ jsxRuntime.jsxRuntimeExports.jsxs(Popover.Popover, { position: "bottom-end", opened, withinPortal, shadow: "md", onClose: close, children: [
94
96
  /* @__PURE__ */ jsxRuntime.jsxRuntimeExports.jsx(Popover.Popover.Target, { children: /* @__PURE__ */ jsxRuntime.jsxRuntimeExports.jsx(
95
97
  TextInput.TextInput,
@@ -207,7 +209,17 @@ const DateTimePicker = ({
207
209
  }
208
210
  )
209
211
  ] }),
210
- /* @__PURE__ */ jsxRuntime.jsxRuntimeExports.jsx(Flex.Flex, { mah: "100%", gap: 8, children: scroll.content })
212
+ /* @__PURE__ */ jsxRuntime.jsxRuntimeExports.jsx(
213
+ TimeScollerPicker.TimeScollerPicker,
214
+ {
215
+ currentValue,
216
+ currentValueChangedBy,
217
+ onChange: timeScrollPickerChange,
218
+ start: startDate,
219
+ end: endDate,
220
+ utcOffset
221
+ }
222
+ )
211
223
  ]
212
224
  }
213
225
  )
@@ -1,5 +1,5 @@
1
1
  import { j as jsxRuntimeExports } from "../../node_modules/.pnpm/react@18.3.1/node_modules/react/jsx-runtime.js";
2
- import { useMemoizedFn, useUpdateEffect } from "ahooks";
2
+ import { useMemoizedFn } from "ahooks";
3
3
  import { useState, useMemo } from "react";
4
4
  import { IconClock } from "../../icons/index.js";
5
5
  /* empty css */
@@ -13,8 +13,9 @@ import dayjs from "dayjs";
13
13
  import "../../node_modules/.pnpm/dayjs@1.11.13/node_modules/dayjs/plugin/timezone.js";
14
14
  import "../../node_modules/.pnpm/dayjs@1.11.13/node_modules/dayjs/plugin/utc.js";
15
15
  import { DEFAULT_TIME_FORMAT } from "../TimeRangePicker/helpers.js";
16
- import { useTimePickerScroll } from "./usePickerScroll.js";
16
+ import { TimeScollerPicker } from "./TimeScollerPicker.js";
17
17
  import { useDisclosure } from "../../node_modules/.pnpm/@mantine_hooks@7.13.2_react@18.3.1/node_modules/@mantine/hooks/esm/use-disclosure/use-disclosure.js";
18
+ import { useUncontrolled } from "../../node_modules/.pnpm/@mantine_hooks@7.13.2_react@18.3.1/node_modules/@mantine/hooks/esm/use-uncontrolled/use-uncontrolled.js";
18
19
  import { Popover } from "../../node_modules/.pnpm/@mantine_core@7.13.2_patch_hash_v5k5cxye7xaihpcgowhgciky7a_@mantine_hooks@7.13.2_react@18.3.1_hlfamvk7n3o6ychyvm5cyru4yu/node_modules/@mantine/core/esm/components/Popover/Popover.js";
19
20
  import { TextInput } from "../../primitive/TextInput/TextInput.js";
20
21
  import { Loader } from "../../node_modules/.pnpm/@mantine_core@7.13.2_patch_hash_v5k5cxye7xaihpcgowhgciky7a_@mantine_hooks@7.13.2_react@18.3.1_hlfamvk7n3o6ychyvm5cyru4yu/node_modules/@mantine/core/esm/components/Loader/Loader.js";
@@ -41,12 +42,29 @@ const DateTimePicker = ({
41
42
  size
42
43
  }) => {
43
44
  const [opened, { close, open }] = useDisclosure(false);
44
- const [currentValue, setCurrentValue] = useState(
45
- defaultValue ? dayjs(defaultValue) : value ? dayjs(value) : dayjs()
46
- );
47
- const updateCurrentValue = useMemoizedFn((val) => {
48
- setCurrentValue(val);
49
- onChange == null ? void 0 : onChange(val.toDate());
45
+ const [currentValue, setCurrentValue] = useUncontrolled({
46
+ value: value ? dayjs(value) : void 0,
47
+ defaultValue: defaultValue ? dayjs(defaultValue) : dayjs(),
48
+ onChange: (v) => {
49
+ onChange == null ? void 0 : onChange(v.toDate());
50
+ }
51
+ });
52
+ const [currentValueChangedBy, setCurrentValueChangedBy] = useState(null);
53
+ const updateCurrentValue = useMemoizedFn((val, from) => {
54
+ let next = val;
55
+ if ((currentValue == null ? void 0 : currentValue.unix()) === next.unix()) {
56
+ return;
57
+ }
58
+ if (startDate && next.valueOf() < startDate.valueOf()) {
59
+ next = dayjs(startDate);
60
+ } else if (endDate && next.valueOf() > endDate.valueOf()) {
61
+ next = dayjs(endDate);
62
+ }
63
+ setCurrentValue(next);
64
+ setCurrentValueChangedBy(from);
65
+ setTimeout(() => {
66
+ setCurrentValueChangedBy(null);
67
+ }, 20);
50
68
  });
51
69
  const inputStr = currentValue.format(format);
52
70
  const utcStr = useMemo(() => {
@@ -54,40 +72,24 @@ const DateTimePicker = ({
54
72
  const m = utcOffset % 60;
55
73
  return `UTC${h >= 0 ? "+" : "-"}${Math.abs(h)}:${m < 10 ? "0" : ""}${m}`;
56
74
  }, [utcOffset]);
57
- const scroll = useTimePickerScroll(currentValue, opened, startDate, endDate, utcOffset);
58
75
  const calendarChange = useMemoizedFn((v) => {
59
76
  let next = currentValue;
60
77
  next = next.utcOffset(utcOffset).year(v.getFullYear()).month(v.getMonth()).date(v.getDate());
61
- if ((currentValue == null ? void 0 : currentValue.unix()) !== next.unix()) {
62
- updateCurrentValue(next);
63
- }
78
+ updateCurrentValue(next, "calendar");
64
79
  });
65
80
  const timeInputChange = useMemoizedFn((e) => {
66
81
  const originVal = e.currentTarget.value;
67
82
  const v = dayjs(originVal, "HH:mm:ss").toDate();
68
83
  let next = currentValue;
69
84
  next = next.utcOffset(utcOffset).hour(v.getHours()).minute(v.getMinutes()).second(v.getSeconds());
70
- if (startDate && next.valueOf() < startDate.valueOf()) {
71
- updateCurrentValue(dayjs(startDate));
72
- } else if (endDate && next.valueOf() > endDate.valueOf()) {
73
- updateCurrentValue(dayjs(endDate));
74
- } else if ((currentValue == null ? void 0 : currentValue.unix()) !== next.unix()) {
75
- updateCurrentValue(next);
76
- }
85
+ updateCurrentValue(next, "timeInput");
77
86
  });
78
- useUpdateEffect(() => {
87
+ const timeScrollPickerChange = useMemoizedFn((v) => {
88
+ const [h, m, s] = v;
79
89
  let next = currentValue;
80
- const [h, m, s] = scroll.value;
81
90
  next = next.utcOffset(utcOffset).hour(h).minute(m).second(s);
82
- if ((currentValue == null ? void 0 : currentValue.unix()) !== next.unix()) {
83
- updateCurrentValue(next);
84
- }
85
- }, [scroll.value]);
86
- useUpdateEffect(() => {
87
- if (value && dayjs(value).unix() !== currentValue.unix()) {
88
- updateCurrentValue(dayjs(value));
89
- }
90
- }, [value]);
91
+ updateCurrentValue(next, "timeScroller");
92
+ });
91
93
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(Popover, { position: "bottom-end", opened, withinPortal, shadow: "md", onClose: close, children: [
92
94
  /* @__PURE__ */ jsxRuntimeExports.jsx(Popover.Target, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(
93
95
  TextInput,
@@ -205,7 +207,17 @@ const DateTimePicker = ({
205
207
  }
206
208
  )
207
209
  ] }),
208
- /* @__PURE__ */ jsxRuntimeExports.jsx(Flex, { mah: "100%", gap: 8, children: scroll.content })
210
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
211
+ TimeScollerPicker,
212
+ {
213
+ currentValue,
214
+ currentValueChangedBy,
215
+ onChange: timeScrollPickerChange,
216
+ start: startDate,
217
+ end: endDate,
218
+ utcOffset
219
+ }
220
+ )
209
221
  ]
210
222
  }
211
223
  )
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tidbcloud/uikit",
3
- "version": "2.0.0-beta.82",
3
+ "version": "2.0.0-beta.83",
4
4
  "description": "tidbcloud uikit",
5
5
  "type": "module",
6
6
  "main": "dist/primitive/index.cjs",
@@ -1,29 +0,0 @@
1
- import { Dayjs } from 'dayjs';
2
- export declare const getTimeRange: ({ curr, type, start, end, utcOffset }: {
3
- curr: Dayjs;
4
- type: "year" | "month" | "day" | "hour" | "minute" | "second";
5
- start?: Date;
6
- end?: Date;
7
- utcOffset?: number;
8
- }) => Range;
9
- interface Options {
10
- max: number;
11
- min: number;
12
- /**
13
- * always use real value, not 0-indexed value
14
- */
15
- curr: number;
16
- open: boolean;
17
- render?: (val: number) => any;
18
- title?: string;
19
- }
20
- type Range = Pick<Options, 'max' | 'min'>;
21
- export declare const useDatePickerScroll: (currentValue: Dayjs, open: boolean, start?: Date, end?: Date, utcOffset?: number) => {
22
- content: import("react/jsx-runtime.js").JSX.Element;
23
- value: readonly [number, number, number];
24
- };
25
- export declare const useTimePickerScroll: (currentValue: Dayjs, open: boolean, start?: Date, end?: Date, utcOffset?: number) => {
26
- content: import("react/jsx-runtime.js").JSX.Element;
27
- value: readonly [number, number, number];
28
- };
29
- export {};
@@ -1,29 +0,0 @@
1
- import { Dayjs } from 'dayjs';
2
- export declare const getTimeRange: ({ curr, type, start, end, utcOffset }: {
3
- curr: Dayjs;
4
- type: "year" | "month" | "day" | "hour" | "minute" | "second";
5
- start?: Date;
6
- end?: Date;
7
- utcOffset?: number;
8
- }) => Range;
9
- interface Options {
10
- max: number;
11
- min: number;
12
- /**
13
- * always use real value, not 0-indexed value
14
- */
15
- curr: number;
16
- open: boolean;
17
- render?: (val: number) => any;
18
- title?: string;
19
- }
20
- type Range = Pick<Options, 'max' | 'min'>;
21
- export declare const useDatePickerScroll: (currentValue: Dayjs, open: boolean, start?: Date, end?: Date, utcOffset?: number) => {
22
- content: import("react/jsx-runtime.js").JSX.Element;
23
- value: readonly [number, number, number];
24
- };
25
- export declare const useTimePickerScroll: (currentValue: Dayjs, open: boolean, start?: Date, end?: Date, utcOffset?: number) => {
26
- content: import("react/jsx-runtime.js").JSX.Element;
27
- value: readonly [number, number, number];
28
- };
29
- export {};