@tidbcloud/uikit 2.0.0 → 2.0.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/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # @tidbcloud/uikit
2
2
 
3
+ ## 2.0.2
4
+
5
+ ### Patch Changes
6
+
7
+ - tweak(TimeRangePicker): support empty value & clearable ([#442](https://github.com/tidbcloud/tidbcloud-uikit/pull/442))
8
+
9
+ ## 2.0.1
10
+
11
+ ### Patch Changes
12
+
13
+ - feat(uikit): bug fix of SearchArea component
14
+ - feat: fix input reset bug ([#440](https://github.com/tidbcloud/tidbcloud-uikit/pull/440))
15
+
3
16
  ## 2.0.0
4
17
 
5
18
  ### Major Changes
@@ -49,7 +49,9 @@ function FormItemRender(props) {
49
49
  {
50
50
  name,
51
51
  value: keyword,
52
- onChange: (e) => setKeyword(e.target.value),
52
+ onChange: (e) => {
53
+ setKeyword(e.target.value);
54
+ },
53
55
  placeholder: placeholder ?? "",
54
56
  onKeyDown: onKeyDownHandler,
55
57
  rightSection: !!keyword && /* @__PURE__ */ jsxRuntime.jsx(
@@ -59,6 +61,8 @@ function FormItemRender(props) {
59
61
  size: 14,
60
62
  onClick: () => {
61
63
  setKeyword("");
64
+ props.form.setValue(name, "");
65
+ triggerSubmit();
62
66
  }
63
67
  }
64
68
  ),
@@ -131,7 +135,7 @@ function FormItemRender(props) {
131
135
  return null;
132
136
  }
133
137
  }
134
- const DEFAULT_FORM_STATE_KEY = "__fs__";
138
+ const DEFAULT_FORM_STATE_KEY = "__fs";
135
139
  function SearchArea(props) {
136
140
  const { data, onSubmit, recoverFromURLEnabled, defaultValues, formStateQueryKey, ...rest } = props;
137
141
  const [resetSeed, setResetSeed] = React.useState(0);
@@ -158,6 +162,7 @@ function SearchArea(props) {
158
162
  data.map((x) => /* @__PURE__ */ jsxRuntime.jsx(
159
163
  FormItemRender,
160
164
  {
165
+ form,
161
166
  data: x,
162
167
  onSubmit: handleSubmit,
163
168
  defaultValue: state[x.name],
@@ -46,6 +46,6 @@ export interface SearchAreaProps<T extends FieldValues> extends FormProps<T> {
46
46
  /**
47
47
  * Please use `formStateQueryKey` instead if you have multiple <SearchArea /> components in the same page
48
48
  */
49
- export declare const DEFAULT_FORM_STATE_KEY = "__fs__";
49
+ export declare const DEFAULT_FORM_STATE_KEY = "__fs";
50
50
  export declare function SearchArea<T extends object>(props: SearchAreaProps<T>): import("react/jsx-runtime.js").JSX.Element;
51
51
  export {};
@@ -46,6 +46,6 @@ export interface SearchAreaProps<T extends FieldValues> extends FormProps<T> {
46
46
  /**
47
47
  * Please use `formStateQueryKey` instead if you have multiple <SearchArea /> components in the same page
48
48
  */
49
- export declare const DEFAULT_FORM_STATE_KEY = "__fs__";
49
+ export declare const DEFAULT_FORM_STATE_KEY = "__fs";
50
50
  export declare function SearchArea<T extends object>(props: SearchAreaProps<T>): import("react/jsx-runtime.js").JSX.Element;
51
51
  export {};
@@ -47,7 +47,9 @@ function FormItemRender(props) {
47
47
  {
48
48
  name,
49
49
  value: keyword,
50
- onChange: (e) => setKeyword(e.target.value),
50
+ onChange: (e) => {
51
+ setKeyword(e.target.value);
52
+ },
51
53
  placeholder: placeholder ?? "",
52
54
  onKeyDown: onKeyDownHandler,
53
55
  rightSection: !!keyword && /* @__PURE__ */ jsx(
@@ -57,6 +59,8 @@ function FormItemRender(props) {
57
59
  size: 14,
58
60
  onClick: () => {
59
61
  setKeyword("");
62
+ props.form.setValue(name, "");
63
+ triggerSubmit();
60
64
  }
61
65
  }
62
66
  ),
@@ -129,7 +133,7 @@ function FormItemRender(props) {
129
133
  return null;
130
134
  }
131
135
  }
132
- const DEFAULT_FORM_STATE_KEY = "__fs__";
136
+ const DEFAULT_FORM_STATE_KEY = "__fs";
133
137
  function SearchArea(props) {
134
138
  const { data, onSubmit, recoverFromURLEnabled, defaultValues, formStateQueryKey, ...rest } = props;
135
139
  const [resetSeed, setResetSeed] = useState(0);
@@ -156,6 +160,7 @@ function SearchArea(props) {
156
160
  data.map((x) => /* @__PURE__ */ jsx(
157
161
  FormItemRender,
158
162
  {
163
+ form,
159
164
  data: x,
160
165
  onSubmit: handleSubmit,
161
166
  defaultValue: state[x.name],
@@ -31,40 +31,36 @@ const AbsoluteTimeRangePicker = ({
31
31
  onCancel,
32
32
  onReturnClick
33
33
  }) => {
34
- const [start, setStart] = React.useState(() => new Date(value[0] * 1e3));
35
- const [end, setEnd] = React.useState(() => new Date(value[1] * 1e3));
36
- const startTime = dayjs(start).format("HH:mm:ss");
37
- const endTime = dayjs(end).format("HH:mm:ss");
38
- const startAfterEnd = React.useMemo(() => {
39
- return start.valueOf() > end.valueOf();
40
- }, [start, end]);
41
- const beyondMin = React.useMemo(() => {
42
- return minDateTime && start.valueOf() < minDateTime.valueOf();
43
- }, [minDateTime, start]);
44
- const beyondMax = React.useMemo(() => {
45
- return maxDateTime && end.valueOf() > maxDateTime.valueOf();
46
- }, [maxDateTime, end]);
47
- const beyondDuration = React.useMemo(() => {
48
- if (maxDuration !== void 0) {
49
- return end.valueOf() - start.valueOf() > maxDuration * 1e3;
50
- }
51
- return false;
52
- }, [maxDuration, start, end]);
34
+ const [start, setStart] = React.useState(() => value ? new Date(value[0] * 1e3) : null);
35
+ const [end, setEnd] = React.useState(() => value ? new Date(value[1] * 1e3) : null);
36
+ const startDate = start ? dayjs(start).format("MMM D, YYYY") : "-";
37
+ const endDate = end ? dayjs(end).format("MMM D, YYYY") : "-";
38
+ const startTime = start ? dayjs(start).format("HH:mm:ss") : "-";
39
+ const endTime = end ? dayjs(end).format("HH:mm:ss") : "-";
40
+ const isRangeComplete = !!start && !!end;
41
+ const startAfterEnd = isRangeComplete && start.valueOf() > end.valueOf();
42
+ const beyondMin = isRangeComplete && minDateTime && start.valueOf() < minDateTime.valueOf();
43
+ const beyondMax = isRangeComplete && maxDateTime && end.valueOf() > maxDateTime.valueOf();
44
+ const beyondDuration = isRangeComplete && !!maxDuration && end.valueOf() - start.valueOf() > maxDuration * 1e3;
53
45
  const [displayRangeDate, setDisplayRangeDate] = React.useState([start, end]);
54
46
  const updateRangeDate = (dates) => {
55
47
  setDisplayRangeDate(dates);
56
48
  const newStart = new Date(dates[0]);
57
- newStart.setHours(start.getHours());
58
- newStart.setMinutes(start.getMinutes());
59
- newStart.setSeconds(start.getSeconds());
49
+ if (start) {
50
+ newStart.setHours(start.getHours());
51
+ newStart.setMinutes(start.getMinutes());
52
+ newStart.setSeconds(start.getSeconds());
53
+ }
60
54
  setStart(newStart);
61
55
  let newEnd = new Date(dates[0]);
62
56
  if (dates[1]) {
63
57
  newEnd = new Date(dates[1]);
64
58
  }
65
- newEnd.setHours(end.getHours());
66
- newEnd.setMinutes(end.getMinutes());
67
- newEnd.setSeconds(end.getSeconds());
59
+ if (end) {
60
+ newEnd.setHours(end.getHours());
61
+ newEnd.setMinutes(end.getMinutes());
62
+ newEnd.setSeconds(end.getSeconds());
63
+ }
68
64
  setEnd(newEnd);
69
65
  };
70
66
  const updateTime = (v, setter) => {
@@ -78,22 +74,15 @@ const AbsoluteTimeRangePicker = ({
78
74
  });
79
75
  };
80
76
  const apply = () => onChange == null ? void 0 : onChange({ type: "absolute", value: [dayjs(start).unix(), dayjs(end).unix()] });
81
- return /* @__PURE__ */ jsxRuntime.jsxs(Box.Box, { p: 16, w: 280, m: -4, children: [
82
- /* @__PURE__ */ jsxRuntime.jsxs(Group.Group, { onClick: onReturnClick, sx: { cursor: "pointer" }, children: [
77
+ return /* @__PURE__ */ jsxRuntime.jsxs(Box.Box, { p: "md", w: 280, m: -4, children: [
78
+ /* @__PURE__ */ jsxRuntime.jsxs(Group.Group, { pb: "xs", mt: -4, onClick: onReturnClick, sx: { cursor: "pointer" }, children: [
83
79
  /* @__PURE__ */ jsxRuntime.jsx(index.IconChevronLeft, { size: 16 }),
84
80
  /* @__PURE__ */ jsxRuntime.jsx(index$1.Typography, { variant: "body-lg", children: "Back" })
85
81
  ] }),
86
82
  /* @__PURE__ */ jsxRuntime.jsxs(Group.Group, { gap: 0, pt: 8, justify: "space-between", children: [
87
83
  /* @__PURE__ */ jsxRuntime.jsx(index$1.Typography, { variant: "label-sm", children: "Start" }),
88
84
  /* @__PURE__ */ jsxRuntime.jsxs(Group.Group, { gap: 8, children: [
89
- /* @__PURE__ */ jsxRuntime.jsx(
90
- Input.Input,
91
- {
92
- w: 116,
93
- value: dayjs(start).format("MMM D, YYYY"),
94
- error: beyondMin || startAfterEnd || beyondDuration
95
- }
96
- ),
85
+ /* @__PURE__ */ jsxRuntime.jsx(Input.Input, { w: 116, value: startDate, error: beyondMin || startAfterEnd || beyondDuration }),
97
86
  /* @__PURE__ */ jsxRuntime.jsx(
98
87
  TimeInput.TimeInput,
99
88
  {
@@ -109,14 +98,7 @@ const AbsoluteTimeRangePicker = ({
109
98
  /* @__PURE__ */ jsxRuntime.jsxs(Group.Group, { gap: 0, pt: 8, justify: "space-between", children: [
110
99
  /* @__PURE__ */ jsxRuntime.jsx(index$1.Typography, { variant: "label-sm", children: "End" }),
111
100
  /* @__PURE__ */ jsxRuntime.jsxs(Group.Group, { gap: 8, children: [
112
- /* @__PURE__ */ jsxRuntime.jsx(
113
- Input.Input,
114
- {
115
- w: 116,
116
- value: dayjs(end).format("MMM D, YYYY"),
117
- error: beyondMax || startAfterEnd || beyondDuration
118
- }
119
- ),
101
+ /* @__PURE__ */ jsxRuntime.jsx(Input.Input, { w: 116, value: endDate, error: beyondMax || startAfterEnd || beyondDuration }),
120
102
  /* @__PURE__ */ jsxRuntime.jsx(
121
103
  TimeInput.TimeInput,
122
104
  {
@@ -157,7 +139,15 @@ const AbsoluteTimeRangePicker = ({
157
139
  ] }),
158
140
  /* @__PURE__ */ jsxRuntime.jsxs(Flex.Flex, { pt: 8, gap: "xs", justify: "flex-end", align: "flex-start", direction: "row", wrap: "wrap", children: [
159
141
  /* @__PURE__ */ jsxRuntime.jsx(index$2.Button, { size: "xs", variant: "default", onClick: onCancel, children: "Cancel" }),
160
- /* @__PURE__ */ jsxRuntime.jsx(index$2.Button, { size: "xs", onClick: apply, disabled: startAfterEnd || beyondMin || beyondMax || beyondDuration, children: "Apply" })
142
+ /* @__PURE__ */ jsxRuntime.jsx(
143
+ index$2.Button,
144
+ {
145
+ size: "xs",
146
+ onClick: apply,
147
+ disabled: !start || !end || startAfterEnd || beyondMin || beyondMax || beyondDuration,
148
+ children: "Apply"
149
+ }
150
+ )
161
151
  ] })
162
152
  ] });
163
153
  };
@@ -1,7 +1,7 @@
1
1
  import { MouseEventHandler } from 'react';
2
2
  import { AbsoluteTimeRange, TimeRangeValue } from './helpers.cjs';
3
3
  interface AbsoluteTimeRangePickerProps {
4
- value: TimeRangeValue;
4
+ value?: TimeRangeValue;
5
5
  minDateTime?: Date;
6
6
  maxDateTime?: Date;
7
7
  maxDuration?: number;
@@ -1,7 +1,7 @@
1
1
  import { MouseEventHandler } from 'react';
2
2
  import { AbsoluteTimeRange, TimeRangeValue } from './helpers.mjs';
3
3
  interface AbsoluteTimeRangePickerProps {
4
- value: TimeRangeValue;
4
+ value?: TimeRangeValue;
5
5
  minDateTime?: Date;
6
6
  maxDateTime?: Date;
7
7
  maxDuration?: number;
@@ -1,5 +1,5 @@
1
1
  import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
- import { useState, useMemo } from "react";
2
+ import { useState } from "react";
3
3
  import { IconChevronLeft, IconAlertCircle } from "../../icons/index.mjs";
4
4
  /* empty css */
5
5
  /* empty css */
@@ -29,40 +29,36 @@ const AbsoluteTimeRangePicker = ({
29
29
  onCancel,
30
30
  onReturnClick
31
31
  }) => {
32
- const [start, setStart] = useState(() => new Date(value[0] * 1e3));
33
- const [end, setEnd] = useState(() => new Date(value[1] * 1e3));
34
- const startTime = dayjs(start).format("HH:mm:ss");
35
- const endTime = dayjs(end).format("HH:mm:ss");
36
- const startAfterEnd = useMemo(() => {
37
- return start.valueOf() > end.valueOf();
38
- }, [start, end]);
39
- const beyondMin = useMemo(() => {
40
- return minDateTime && start.valueOf() < minDateTime.valueOf();
41
- }, [minDateTime, start]);
42
- const beyondMax = useMemo(() => {
43
- return maxDateTime && end.valueOf() > maxDateTime.valueOf();
44
- }, [maxDateTime, end]);
45
- const beyondDuration = useMemo(() => {
46
- if (maxDuration !== void 0) {
47
- return end.valueOf() - start.valueOf() > maxDuration * 1e3;
48
- }
49
- return false;
50
- }, [maxDuration, start, end]);
32
+ const [start, setStart] = useState(() => value ? new Date(value[0] * 1e3) : null);
33
+ const [end, setEnd] = useState(() => value ? new Date(value[1] * 1e3) : null);
34
+ const startDate = start ? dayjs(start).format("MMM D, YYYY") : "-";
35
+ const endDate = end ? dayjs(end).format("MMM D, YYYY") : "-";
36
+ const startTime = start ? dayjs(start).format("HH:mm:ss") : "-";
37
+ const endTime = end ? dayjs(end).format("HH:mm:ss") : "-";
38
+ const isRangeComplete = !!start && !!end;
39
+ const startAfterEnd = isRangeComplete && start.valueOf() > end.valueOf();
40
+ const beyondMin = isRangeComplete && minDateTime && start.valueOf() < minDateTime.valueOf();
41
+ const beyondMax = isRangeComplete && maxDateTime && end.valueOf() > maxDateTime.valueOf();
42
+ const beyondDuration = isRangeComplete && !!maxDuration && end.valueOf() - start.valueOf() > maxDuration * 1e3;
51
43
  const [displayRangeDate, setDisplayRangeDate] = useState([start, end]);
52
44
  const updateRangeDate = (dates) => {
53
45
  setDisplayRangeDate(dates);
54
46
  const newStart = new Date(dates[0]);
55
- newStart.setHours(start.getHours());
56
- newStart.setMinutes(start.getMinutes());
57
- newStart.setSeconds(start.getSeconds());
47
+ if (start) {
48
+ newStart.setHours(start.getHours());
49
+ newStart.setMinutes(start.getMinutes());
50
+ newStart.setSeconds(start.getSeconds());
51
+ }
58
52
  setStart(newStart);
59
53
  let newEnd = new Date(dates[0]);
60
54
  if (dates[1]) {
61
55
  newEnd = new Date(dates[1]);
62
56
  }
63
- newEnd.setHours(end.getHours());
64
- newEnd.setMinutes(end.getMinutes());
65
- newEnd.setSeconds(end.getSeconds());
57
+ if (end) {
58
+ newEnd.setHours(end.getHours());
59
+ newEnd.setMinutes(end.getMinutes());
60
+ newEnd.setSeconds(end.getSeconds());
61
+ }
66
62
  setEnd(newEnd);
67
63
  };
68
64
  const updateTime = (v, setter) => {
@@ -76,22 +72,15 @@ const AbsoluteTimeRangePicker = ({
76
72
  });
77
73
  };
78
74
  const apply = () => onChange == null ? void 0 : onChange({ type: "absolute", value: [dayjs(start).unix(), dayjs(end).unix()] });
79
- return /* @__PURE__ */ jsxs(Box, { p: 16, w: 280, m: -4, children: [
80
- /* @__PURE__ */ jsxs(Group, { onClick: onReturnClick, sx: { cursor: "pointer" }, children: [
75
+ return /* @__PURE__ */ jsxs(Box, { p: "md", w: 280, m: -4, children: [
76
+ /* @__PURE__ */ jsxs(Group, { pb: "xs", mt: -4, onClick: onReturnClick, sx: { cursor: "pointer" }, children: [
81
77
  /* @__PURE__ */ jsx(IconChevronLeft, { size: 16 }),
82
78
  /* @__PURE__ */ jsx(Typography, { variant: "body-lg", children: "Back" })
83
79
  ] }),
84
80
  /* @__PURE__ */ jsxs(Group, { gap: 0, pt: 8, justify: "space-between", children: [
85
81
  /* @__PURE__ */ jsx(Typography, { variant: "label-sm", children: "Start" }),
86
82
  /* @__PURE__ */ jsxs(Group, { gap: 8, children: [
87
- /* @__PURE__ */ jsx(
88
- Input,
89
- {
90
- w: 116,
91
- value: dayjs(start).format("MMM D, YYYY"),
92
- error: beyondMin || startAfterEnd || beyondDuration
93
- }
94
- ),
83
+ /* @__PURE__ */ jsx(Input, { w: 116, value: startDate, error: beyondMin || startAfterEnd || beyondDuration }),
95
84
  /* @__PURE__ */ jsx(
96
85
  TimeInput,
97
86
  {
@@ -107,14 +96,7 @@ const AbsoluteTimeRangePicker = ({
107
96
  /* @__PURE__ */ jsxs(Group, { gap: 0, pt: 8, justify: "space-between", children: [
108
97
  /* @__PURE__ */ jsx(Typography, { variant: "label-sm", children: "End" }),
109
98
  /* @__PURE__ */ jsxs(Group, { gap: 8, children: [
110
- /* @__PURE__ */ jsx(
111
- Input,
112
- {
113
- w: 116,
114
- value: dayjs(end).format("MMM D, YYYY"),
115
- error: beyondMax || startAfterEnd || beyondDuration
116
- }
117
- ),
99
+ /* @__PURE__ */ jsx(Input, { w: 116, value: endDate, error: beyondMax || startAfterEnd || beyondDuration }),
118
100
  /* @__PURE__ */ jsx(
119
101
  TimeInput,
120
102
  {
@@ -155,7 +137,15 @@ const AbsoluteTimeRangePicker = ({
155
137
  ] }),
156
138
  /* @__PURE__ */ jsxs(Flex, { pt: 8, gap: "xs", justify: "flex-end", align: "flex-start", direction: "row", wrap: "wrap", children: [
157
139
  /* @__PURE__ */ jsx(Button, { size: "xs", variant: "default", onClick: onCancel, children: "Cancel" }),
158
- /* @__PURE__ */ jsx(Button, { size: "xs", onClick: apply, disabled: startAfterEnd || beyondMin || beyondMax || beyondDuration, children: "Apply" })
140
+ /* @__PURE__ */ jsx(
141
+ Button,
142
+ {
143
+ size: "xs",
144
+ onClick: apply,
145
+ disabled: !start || !end || startAfterEnd || beyondMin || beyondMax || beyondDuration,
146
+ children: "Apply"
147
+ }
148
+ )
159
149
  ] })
160
150
  ] });
161
151
  };
@@ -12,8 +12,10 @@ const index$2 = require("../../primitive/Typography/index.cjs");
12
12
  const index = require("../../primitive/Button/index.cjs");
13
13
  const AbsoluteTimeRangePicker = require("./AbsoluteTimeRangePicker.cjs");
14
14
  const helpers = require("./helpers.cjs");
15
+ const useHover = require("../../node_modules/.pnpm/@mantine_hooks@7.15.2_react@18.3.1/node_modules/@mantine/hooks/esm/use-hover/use-hover.cjs");
15
16
  const Menu = require("../../node_modules/.pnpm/@mantine_core@7.15.2_patch_hash_jclkxeaefn6uz54h34k3r3yjsq_@mantine_hooks@7.15.2_react@18.3.1_szqfuioo5damkjdixckhzmwycq/node_modules/@mantine/core/esm/components/Menu/Menu.cjs");
16
17
  const Tooltip = require("../../node_modules/.pnpm/@mantine_core@7.15.2_patch_hash_jclkxeaefn6uz54h34k3r3yjsq_@mantine_hooks@7.15.2_react@18.3.1_szqfuioo5damkjdixckhzmwycq/node_modules/@mantine/core/esm/components/Tooltip/Tooltip.cjs");
18
+ const ActionIcon = require("../../node_modules/.pnpm/@mantine_core@7.15.2_patch_hash_jclkxeaefn6uz54h34k3r3yjsq_@mantine_hooks@7.15.2_react@18.3.1_szqfuioo5damkjdixckhzmwycq/node_modules/@mantine/core/esm/components/ActionIcon/ActionIcon.cjs");
17
19
  const Group = require("../../node_modules/.pnpm/@mantine_core@7.15.2_patch_hash_jclkxeaefn6uz54h34k3r3yjsq_@mantine_hooks@7.15.2_react@18.3.1_szqfuioo5damkjdixckhzmwycq/node_modules/@mantine/core/esm/components/Group/Group.cjs");
18
20
  const Box = require("../../node_modules/.pnpm/@mantine_core@7.15.2_patch_hash_jclkxeaefn6uz54h34k3r3yjsq_@mantine_hooks@7.15.2_react@18.3.1_szqfuioo5damkjdixckhzmwycq/node_modules/@mantine/core/esm/core/Box/Box.cjs");
19
21
  const Text = require("../../node_modules/.pnpm/@mantine_core@7.15.2_patch_hash_jclkxeaefn6uz54h34k3r3yjsq_@mantine_hooks@7.15.2_react@18.3.1_szqfuioo5damkjdixckhzmwycq/node_modules/@mantine/core/esm/components/Text/Text.cjs");
@@ -26,14 +28,18 @@ const TimeRangePicker = ({
26
28
  onChange,
27
29
  quickRanges = helpers.DEFAULT_QUICK_RANGES,
28
30
  loading,
31
+ placeholder,
32
+ clearable,
29
33
  timezone,
30
34
  sx
31
35
  }) => {
32
36
  const [opened, setOpened] = React.useState(false);
33
37
  const [customMode, setCustomMode] = React.useState(false);
34
- const isRelativeRange = (value == null ? void 0 : value.type) === "relative" || !value;
35
- const timeRangeValue = helpers.toTimeRangeValue(value ?? { type: "relative", value: 86400 });
36
- const duration = timeRangeValue[1] - timeRangeValue[0];
38
+ const isEmptyValue = !value;
39
+ const isRelativeRange = (value == null ? void 0 : value.type) === "relative";
40
+ const { hovered, ref: targetRef } = useHover.useHover();
41
+ const timeRangeValue = isEmptyValue ? void 0 : helpers.toTimeRangeValue(value);
42
+ const duration = isEmptyValue ? void 0 : timeRangeValue[1] - timeRangeValue[0];
37
43
  const selectedRelativeItem = React.useMemo(() => {
38
44
  if (!value || value.type === "absolute") {
39
45
  return;
@@ -41,6 +47,9 @@ const TimeRangePicker = ({
41
47
  return quickRanges.find((it) => it === value.value);
42
48
  }, [quickRanges, value]);
43
49
  const formattedAbsDateTime = React.useMemo(() => {
50
+ if (!timeRangeValue) {
51
+ return "";
52
+ }
44
53
  return `${helpers.timeFormatter(timeRangeValue[0], timezone ?? null, "MMM D, YYYY HH:mm")} - ${helpers.timeFormatter(
45
54
  timeRangeValue[1],
46
55
  timezone ?? null,
@@ -60,9 +69,10 @@ const TimeRangePicker = ({
60
69
  },
61
70
  onClose: () => setOpened(false),
62
71
  children: [
63
- /* @__PURE__ */ jsxRuntime.jsx(Menu.Menu.Target, { children: /* @__PURE__ */ jsxRuntime.jsx(Tooltip.Tooltip, { label: formattedAbsDateTime, disabled: isRelativeRange, withArrow: true, children: /* @__PURE__ */ jsxRuntime.jsx(
72
+ /* @__PURE__ */ jsxRuntime.jsx(Menu.Menu.Target, { children: /* @__PURE__ */ jsxRuntime.jsx(Tooltip.Tooltip, { label: formattedAbsDateTime, disabled: isRelativeRange || isEmptyValue, withArrow: true, children: /* @__PURE__ */ jsxRuntime.jsx(
64
73
  index.Button,
65
74
  {
75
+ ref: targetRef,
66
76
  variant: "default",
67
77
  bg: "carbon.0",
68
78
  styles: (theme) => ({
@@ -89,8 +99,19 @@ const TimeRangePicker = ({
89
99
  w: disableAbsoluteRanges ? 200 : 280,
90
100
  sx,
91
101
  loading,
102
+ rightSection: clearable && !!value && hovered ? /* @__PURE__ */ jsxRuntime.jsx(
103
+ ActionIcon.ActionIcon,
104
+ {
105
+ size: "xs",
106
+ onClick: (e) => {
107
+ e.stopPropagation();
108
+ onChange == null ? void 0 : onChange();
109
+ },
110
+ children: /* @__PURE__ */ jsxRuntime.jsx(index$1.IconX, { size: 16, color: "var(--mantine-color-carbon-7)!important" })
111
+ }
112
+ ) : /* @__PURE__ */ jsxRuntime.jsx(index$1.IconChevronSelectorVertical, { size: 16, color: "var(--mantine-color-carbon-7)!important" }),
92
113
  children: /* @__PURE__ */ jsxRuntime.jsxs(Group.Group, { w: "100%", gap: 0, children: [
93
- /* @__PURE__ */ jsxRuntime.jsx(Box.Box, { sx: { flex: "none" }, children: /* @__PURE__ */ jsxRuntime.jsx(DurationBadge, { children: helpers.formatDuration(duration, true) }) }),
114
+ /* @__PURE__ */ jsxRuntime.jsx(Box.Box, { sx: { flex: "none" }, children: /* @__PURE__ */ jsxRuntime.jsx(DurationBadge, { children: isEmptyValue ? "All" : helpers.formatDuration(duration, true) }) }),
94
115
  /* @__PURE__ */ jsxRuntime.jsx(
95
116
  Text.Text,
96
117
  {
@@ -102,7 +123,8 @@ const TimeRangePicker = ({
102
123
  textOverflow: "ellipsis",
103
124
  textAlign: "left"
104
125
  },
105
- children: isRelativeRange ? `Past ${helpers.formatDuration(duration)}` : formattedAbsDateTime
126
+ c: isEmptyValue ? "dimmed" : "carbon.8",
127
+ children: isEmptyValue ? placeholder || "Time Range" : isRelativeRange ? `Past ${helpers.formatDuration(duration)}` : formattedAbsDateTime
106
128
  }
107
129
  )
108
130
  ] })
@@ -1,9 +1,11 @@
1
1
  import { ButtonProps } from '../../primitive/index.cjs';
2
2
  import { TimeRange } from './helpers.cjs';
3
3
  export interface TimeRangePickerProps extends ButtonProps {
4
- value: TimeRange;
5
- onChange?: (value: TimeRange) => void;
4
+ value?: TimeRange;
5
+ onChange?: (value?: TimeRange) => void;
6
6
  loading?: boolean;
7
+ placeholder?: string;
8
+ clearable?: boolean;
7
9
  minDateTime?: () => Date;
8
10
  maxDateTime?: () => Date;
9
11
  maxDuration?: number;
@@ -11,5 +13,5 @@ export interface TimeRangePickerProps extends ButtonProps {
11
13
  disableAbsoluteRanges?: boolean;
12
14
  timezone?: number;
13
15
  }
14
- export declare const TimeRangePicker: ({ value, minDateTime, maxDateTime, maxDuration, disableAbsoluteRanges, onChange, quickRanges, loading, timezone, sx }: React.PropsWithChildren<TimeRangePickerProps>) => import("react/jsx-runtime.js").JSX.Element;
16
+ export declare const TimeRangePicker: ({ value, minDateTime, maxDateTime, maxDuration, disableAbsoluteRanges, onChange, quickRanges, loading, placeholder, clearable, timezone, sx }: React.PropsWithChildren<TimeRangePickerProps>) => import("react/jsx-runtime.js").JSX.Element;
15
17
  export * from './helpers.cjs';
@@ -1,9 +1,11 @@
1
1
  import { ButtonProps } from '../../primitive/index.mjs';
2
2
  import { TimeRange } from './helpers.mjs';
3
3
  export interface TimeRangePickerProps extends ButtonProps {
4
- value: TimeRange;
5
- onChange?: (value: TimeRange) => void;
4
+ value?: TimeRange;
5
+ onChange?: (value?: TimeRange) => void;
6
6
  loading?: boolean;
7
+ placeholder?: string;
8
+ clearable?: boolean;
7
9
  minDateTime?: () => Date;
8
10
  maxDateTime?: () => Date;
9
11
  maxDuration?: number;
@@ -11,5 +13,5 @@ export interface TimeRangePickerProps extends ButtonProps {
11
13
  disableAbsoluteRanges?: boolean;
12
14
  timezone?: number;
13
15
  }
14
- export declare const TimeRangePicker: ({ value, minDateTime, maxDateTime, maxDuration, disableAbsoluteRanges, onChange, quickRanges, loading, timezone, sx }: React.PropsWithChildren<TimeRangePickerProps>) => import("react/jsx-runtime.js").JSX.Element;
16
+ export declare const TimeRangePicker: ({ value, minDateTime, maxDateTime, maxDuration, disableAbsoluteRanges, onChange, quickRanges, loading, placeholder, clearable, timezone, sx }: React.PropsWithChildren<TimeRangePickerProps>) => import("react/jsx-runtime.js").JSX.Element;
15
17
  export * from './helpers.mjs';
@@ -1,6 +1,6 @@
1
1
  import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
2
  import { useState, useMemo } from "react";
3
- import { IconChevronRight } from "../../icons/index.mjs";
3
+ import { IconX, IconChevronSelectorVertical, IconChevronRight } from "../../icons/index.mjs";
4
4
  /* empty css */
5
5
  /* empty css */
6
6
  /* empty css */
@@ -11,8 +11,10 @@ import { Button } from "../../primitive/Button/index.mjs";
11
11
  import AbsoluteTimeRangePicker from "./AbsoluteTimeRangePicker.mjs";
12
12
  import { toTimeRangeValue, timeFormatter, formatDuration, DEFAULT_QUICK_RANGES } from "./helpers.mjs";
13
13
  import { DEFAULT_TIME_FORMAT, DEFAULT_TIME_FORMAT_WITH_TIMEZONE, DEFAULT_TIME_RANGE, addOffsetUTC, fromTimeRangeValue, getUTCString, toURLTimeRange, urlToTimeRange, urlToTimeRangeValue } from "./helpers.mjs";
14
+ import { useHover } from "../../node_modules/.pnpm/@mantine_hooks@7.15.2_react@18.3.1/node_modules/@mantine/hooks/esm/use-hover/use-hover.mjs";
14
15
  import { Menu } from "../../node_modules/.pnpm/@mantine_core@7.15.2_patch_hash_jclkxeaefn6uz54h34k3r3yjsq_@mantine_hooks@7.15.2_react@18.3.1_szqfuioo5damkjdixckhzmwycq/node_modules/@mantine/core/esm/components/Menu/Menu.mjs";
15
16
  import { Tooltip } from "../../node_modules/.pnpm/@mantine_core@7.15.2_patch_hash_jclkxeaefn6uz54h34k3r3yjsq_@mantine_hooks@7.15.2_react@18.3.1_szqfuioo5damkjdixckhzmwycq/node_modules/@mantine/core/esm/components/Tooltip/Tooltip.mjs";
17
+ import { ActionIcon } from "../../node_modules/.pnpm/@mantine_core@7.15.2_patch_hash_jclkxeaefn6uz54h34k3r3yjsq_@mantine_hooks@7.15.2_react@18.3.1_szqfuioo5damkjdixckhzmwycq/node_modules/@mantine/core/esm/components/ActionIcon/ActionIcon.mjs";
16
18
  import { Group } from "../../node_modules/.pnpm/@mantine_core@7.15.2_patch_hash_jclkxeaefn6uz54h34k3r3yjsq_@mantine_hooks@7.15.2_react@18.3.1_szqfuioo5damkjdixckhzmwycq/node_modules/@mantine/core/esm/components/Group/Group.mjs";
17
19
  import { Box } from "../../node_modules/.pnpm/@mantine_core@7.15.2_patch_hash_jclkxeaefn6uz54h34k3r3yjsq_@mantine_hooks@7.15.2_react@18.3.1_szqfuioo5damkjdixckhzmwycq/node_modules/@mantine/core/esm/core/Box/Box.mjs";
18
20
  import { Text } from "../../node_modules/.pnpm/@mantine_core@7.15.2_patch_hash_jclkxeaefn6uz54h34k3r3yjsq_@mantine_hooks@7.15.2_react@18.3.1_szqfuioo5damkjdixckhzmwycq/node_modules/@mantine/core/esm/components/Text/Text.mjs";
@@ -25,14 +27,18 @@ const TimeRangePicker = ({
25
27
  onChange,
26
28
  quickRanges = DEFAULT_QUICK_RANGES,
27
29
  loading,
30
+ placeholder,
31
+ clearable,
28
32
  timezone,
29
33
  sx
30
34
  }) => {
31
35
  const [opened, setOpened] = useState(false);
32
36
  const [customMode, setCustomMode] = useState(false);
33
- const isRelativeRange = (value == null ? void 0 : value.type) === "relative" || !value;
34
- const timeRangeValue = toTimeRangeValue(value ?? { type: "relative", value: 86400 });
35
- const duration = timeRangeValue[1] - timeRangeValue[0];
37
+ const isEmptyValue = !value;
38
+ const isRelativeRange = (value == null ? void 0 : value.type) === "relative";
39
+ const { hovered, ref: targetRef } = useHover();
40
+ const timeRangeValue = isEmptyValue ? void 0 : toTimeRangeValue(value);
41
+ const duration = isEmptyValue ? void 0 : timeRangeValue[1] - timeRangeValue[0];
36
42
  const selectedRelativeItem = useMemo(() => {
37
43
  if (!value || value.type === "absolute") {
38
44
  return;
@@ -40,6 +46,9 @@ const TimeRangePicker = ({
40
46
  return quickRanges.find((it) => it === value.value);
41
47
  }, [quickRanges, value]);
42
48
  const formattedAbsDateTime = useMemo(() => {
49
+ if (!timeRangeValue) {
50
+ return "";
51
+ }
43
52
  return `${timeFormatter(timeRangeValue[0], timezone ?? null, "MMM D, YYYY HH:mm")} - ${timeFormatter(
44
53
  timeRangeValue[1],
45
54
  timezone ?? null,
@@ -59,9 +68,10 @@ const TimeRangePicker = ({
59
68
  },
60
69
  onClose: () => setOpened(false),
61
70
  children: [
62
- /* @__PURE__ */ jsx(Menu.Target, { children: /* @__PURE__ */ jsx(Tooltip, { label: formattedAbsDateTime, disabled: isRelativeRange, withArrow: true, children: /* @__PURE__ */ jsx(
71
+ /* @__PURE__ */ jsx(Menu.Target, { children: /* @__PURE__ */ jsx(Tooltip, { label: formattedAbsDateTime, disabled: isRelativeRange || isEmptyValue, withArrow: true, children: /* @__PURE__ */ jsx(
63
72
  Button,
64
73
  {
74
+ ref: targetRef,
65
75
  variant: "default",
66
76
  bg: "carbon.0",
67
77
  styles: (theme) => ({
@@ -88,8 +98,19 @@ const TimeRangePicker = ({
88
98
  w: disableAbsoluteRanges ? 200 : 280,
89
99
  sx,
90
100
  loading,
101
+ rightSection: clearable && !!value && hovered ? /* @__PURE__ */ jsx(
102
+ ActionIcon,
103
+ {
104
+ size: "xs",
105
+ onClick: (e) => {
106
+ e.stopPropagation();
107
+ onChange == null ? void 0 : onChange();
108
+ },
109
+ children: /* @__PURE__ */ jsx(IconX, { size: 16, color: "var(--mantine-color-carbon-7)!important" })
110
+ }
111
+ ) : /* @__PURE__ */ jsx(IconChevronSelectorVertical, { size: 16, color: "var(--mantine-color-carbon-7)!important" }),
91
112
  children: /* @__PURE__ */ jsxs(Group, { w: "100%", gap: 0, children: [
92
- /* @__PURE__ */ jsx(Box, { sx: { flex: "none" }, children: /* @__PURE__ */ jsx(DurationBadge, { children: formatDuration(duration, true) }) }),
113
+ /* @__PURE__ */ jsx(Box, { sx: { flex: "none" }, children: /* @__PURE__ */ jsx(DurationBadge, { children: isEmptyValue ? "All" : formatDuration(duration, true) }) }),
93
114
  /* @__PURE__ */ jsx(
94
115
  Text,
95
116
  {
@@ -101,7 +122,8 @@ const TimeRangePicker = ({
101
122
  textOverflow: "ellipsis",
102
123
  textAlign: "left"
103
124
  },
104
- children: isRelativeRange ? `Past ${formatDuration(duration)}` : formattedAbsDateTime
125
+ c: isEmptyValue ? "dimmed" : "carbon.8",
126
+ children: isEmptyValue ? placeholder || "Time Range" : isRelativeRange ? `Past ${formatDuration(duration)}` : formattedAbsDateTime
105
127
  }
106
128
  )
107
129
  ] })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tidbcloud/uikit",
3
- "version": "2.0.0",
3
+ "version": "2.0.2",
4
4
  "description": "tidbcloud uikit",
5
5
  "type": "module",
6
6
  "main": "dist/primitive/index.cjs",