@tidbcloud/uikit 2.0.1 → 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,11 @@
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
+
3
9
  ## 2.0.1
4
10
 
5
11
  ### Patch Changes
@@ -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.1",
3
+ "version": "2.0.2",
4
4
  "description": "tidbcloud uikit",
5
5
  "type": "module",
6
6
  "main": "dist/primitive/index.cjs",