@duskmoon-dev/components 0.3.1 → 0.4.0
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/README.md +61 -2
- package/dist/{chunk-r9wkv7xd.js → chunk-fwjzvsrx.js} +3 -3
- package/dist/classes/chat.d.ts +43 -0
- package/dist/classes/console-page.d.ts +16 -0
- package/dist/classes/dropdown.d.ts +5 -5
- package/dist/classes/fab.d.ts +11 -0
- package/dist/classes/index.d.ts +6 -0
- package/dist/classes/index.js +1443 -1210
- package/dist/classes/megamenu.d.ts +10 -0
- package/dist/classes/otp-input.d.ts +12 -0
- package/dist/classes/popover.d.ts +1 -3
- package/dist/classes/swap.d.ts +12 -0
- package/dist/classes/tree-select.d.ts +6 -6
- package/dist/components/anchor/index.js +2 -2
- package/dist/components/app/index.js +211 -151
- package/dist/components/avatar/Avatar.types.d.ts +1 -1
- package/dist/components/avatar/index.js +2 -1
- package/dist/components/badge/index.js +1 -1
- package/dist/components/button/Button.d.ts +1 -1
- package/dist/components/button/Button.types.d.ts +8 -0
- package/dist/components/button/index.js +253 -24
- package/dist/components/calendar/index.js +44 -19
- package/dist/components/cascader/index.js +2 -2
- package/dist/components/chat/Chat.d.ts +22 -0
- package/dist/components/chat/Chat.types.d.ts +73 -0
- package/dist/components/chat/index.d.ts +2 -0
- package/dist/components/chat/index.js +309 -0
- package/dist/components/color-picker/ColorPicker.types.d.ts +2 -1
- package/dist/components/color-picker/index.js +210 -13
- package/dist/components/config-provider/index.js +2 -2
- package/dist/components/console-page/ConsolePage.d.ts +2 -0
- package/dist/components/console-page/ConsolePage.types.d.ts +29 -0
- package/dist/components/console-page/index.d.ts +2 -0
- package/dist/components/console-page/index.js +205 -0
- package/dist/components/date-picker/DatePicker.types.d.ts +1 -0
- package/dist/components/date-picker/index.js +537 -35
- package/dist/components/date-picker/usePickerDropdown.d.ts +17 -0
- package/dist/components/dm-breadcrumb/index.js +18 -18
- package/dist/components/dm-date-picker/index.js +635 -133
- package/dist/components/dm-drawer/index.js +269 -40
- package/dist/components/dm-layout/index.js +575 -208
- package/dist/components/dm-menu/index.js +399 -32
- package/dist/components/dm-message/index.js +18 -18
- package/dist/components/dm-page-header/index.js +537 -247
- package/dist/components/dm-pagination/index.js +39 -39
- package/dist/components/dm-pro-table/index.js +2374 -1559
- package/dist/components/dm-provider/index.js +94 -94
- package/dist/components/dm-query/DmQuery.types.d.ts +1 -1
- package/dist/components/dm-query/index.js +955 -210
- package/dist/components/dm-search/DmSearch.types.d.ts +4 -0
- package/dist/components/dm-search/index.js +937 -183
- package/dist/components/dm-splitter/index.js +32 -32
- package/dist/components/dm-status/index.js +25 -25
- package/dist/components/dm-table/index.js +1430 -676
- package/dist/components/dm-tabs/index.js +34 -34
- package/dist/components/dm-toolbar/index.js +423 -133
- package/dist/components/dm-tree/index.js +92 -92
- package/dist/components/dm-truncate/index.js +145 -65
- package/dist/components/dropdown/Dropdown.types.d.ts +1 -1
- package/dist/components/dropdown/index.js +467 -177
- package/dist/components/fab/Fab.d.ts +4 -0
- package/dist/components/fab/Fab.types.d.ts +25 -0
- package/dist/components/fab/index.d.ts +2 -0
- package/dist/components/fab/index.js +480 -0
- package/dist/components/form/Form.types.d.ts +1 -0
- package/dist/components/form/index.js +16 -5
- package/dist/components/grid/index.js +2 -2
- package/dist/components/input/index.js +4 -4
- package/dist/components/markdown/index.js +1 -1
- package/dist/components/megamenu/Megamenu.d.ts +2 -0
- package/dist/components/megamenu/Megamenu.types.d.ts +32 -0
- package/dist/components/megamenu/index.d.ts +2 -0
- package/dist/components/megamenu/index.js +214 -0
- package/dist/components/message/index.js +5 -5
- package/dist/components/modal/index.js +128 -68
- package/dist/components/notification/index.js +2 -2
- package/dist/components/otp-input/OtpInput.d.ts +2 -0
- package/dist/components/otp-input/OtpInput.types.d.ts +16 -0
- package/dist/components/otp-input/index.d.ts +2 -0
- package/dist/components/otp-input/index.js +112 -0
- package/dist/components/popconfirm/index.js +297 -68
- package/dist/components/popover/index.js +24 -4
- package/dist/components/skeleton/index.js +5 -5
- package/dist/components/spin/index.js +2 -2
- package/dist/components/steps/index.js +2 -2
- package/dist/components/swap/Swap.d.ts +3 -0
- package/dist/components/swap/Swap.types.d.ts +22 -0
- package/dist/components/swap/index.d.ts +2 -0
- package/dist/components/swap/index.js +109 -0
- package/dist/components/table/index.js +2 -2
- package/dist/components/tabs/index.js +2 -2
- package/dist/components/tag/index.js +2 -2
- package/dist/components/time-picker/TimePicker.types.d.ts +1 -0
- package/dist/components/time-picker/index.js +167 -29
- package/dist/components/tooltip/Tooltip.types.d.ts +4 -0
- package/dist/components/tooltip/index.js +107 -27
- package/dist/components/tour/index.js +315 -86
- package/dist/components/tree-select/index.js +8 -8
- package/dist/components/typography/index.js +4 -4
- package/dist/components/upload/Upload.types.d.ts +1 -0
- package/dist/components/upload/index.js +7 -5
- package/dist/generated/version.d.ts +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.js +4023 -2134
- package/dist/infrastructure.js +11 -11
- package/dist/styles.css +13677 -9811
- package/dist/theme/index.js +3 -3
- package/dist/utils/index.js +5 -5
- package/package.json +30 -6
|
@@ -112,8 +112,8 @@ function getRecordKey(record, index, rowKey) {
|
|
|
112
112
|
return rowKey(record, index);
|
|
113
113
|
}
|
|
114
114
|
if (rowKey) {
|
|
115
|
-
const
|
|
116
|
-
return typeof
|
|
115
|
+
const key = record[rowKey];
|
|
116
|
+
return typeof key === "string" || typeof key === "number" ? key : index;
|
|
117
117
|
}
|
|
118
118
|
const key = record.key;
|
|
119
119
|
return typeof key === "string" || typeof key === "number" ? key : index;
|
|
@@ -12,6 +12,7 @@ export interface DisabledTimeConfig {
|
|
|
12
12
|
disabledSeconds?: (selectedHour: number, selectedMinute: number) => number[];
|
|
13
13
|
}
|
|
14
14
|
export interface TimePickerProps extends Omit<ComponentProps<"div">, "children" | "defaultValue" | "onBlur" | "onChange" | "onFocus"> {
|
|
15
|
+
inputProps?: ComponentProps<"input">;
|
|
15
16
|
value?: TimePickerValue;
|
|
16
17
|
defaultValue?: TimePickerValue;
|
|
17
18
|
format?: string;
|
|
@@ -1,7 +1,77 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
// src/components/time-picker/TimePicker.tsx
|
|
4
|
-
import { forwardRef, useState } from "react";
|
|
4
|
+
import { forwardRef, useState as useState2 } from "react";
|
|
5
|
+
|
|
6
|
+
// src/components/date-picker/usePickerDropdown.ts
|
|
7
|
+
import { useEffect, useId, useImperativeHandle, useRef, useState } from "react";
|
|
8
|
+
function usePickerDropdown({
|
|
9
|
+
open,
|
|
10
|
+
defaultOpen,
|
|
11
|
+
disabled,
|
|
12
|
+
onOpenChange,
|
|
13
|
+
ref
|
|
14
|
+
}) {
|
|
15
|
+
const rootRef = useRef(null);
|
|
16
|
+
const inputRef = useRef(null);
|
|
17
|
+
const skipFocus = useRef(false);
|
|
18
|
+
const panelId = useId();
|
|
19
|
+
const [innerOpen, setInnerOpen] = useState(Boolean(defaultOpen));
|
|
20
|
+
const visible = !disabled && (open ?? innerOpen);
|
|
21
|
+
useImperativeHandle(ref, () => rootRef.current, []);
|
|
22
|
+
function setVisible(next) {
|
|
23
|
+
if (disabled || next === visible)
|
|
24
|
+
return;
|
|
25
|
+
if (open === undefined)
|
|
26
|
+
setInnerOpen(next);
|
|
27
|
+
onOpenChange?.(next);
|
|
28
|
+
}
|
|
29
|
+
function closeAndFocus() {
|
|
30
|
+
skipFocus.current = true;
|
|
31
|
+
inputRef.current?.focus();
|
|
32
|
+
skipFocus.current = false;
|
|
33
|
+
setVisible(false);
|
|
34
|
+
}
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
function handleOutside(event) {
|
|
37
|
+
if (visible && !rootRef.current?.contains(event.target))
|
|
38
|
+
setVisible(false);
|
|
39
|
+
}
|
|
40
|
+
function handleKeyDown(event) {
|
|
41
|
+
if (event.defaultPrevented || !rootRef.current?.contains(event.target))
|
|
42
|
+
return;
|
|
43
|
+
if (event.key === "Escape" && visible) {
|
|
44
|
+
event.preventDefault();
|
|
45
|
+
closeAndFocus();
|
|
46
|
+
} else if (event.key === "ArrowDown" && event.target === inputRef.current) {
|
|
47
|
+
event.preventDefault();
|
|
48
|
+
setVisible(true);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
document.addEventListener("pointerdown", handleOutside);
|
|
52
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
53
|
+
return () => {
|
|
54
|
+
document.removeEventListener("pointerdown", handleOutside);
|
|
55
|
+
document.removeEventListener("keydown", handleKeyDown);
|
|
56
|
+
};
|
|
57
|
+
});
|
|
58
|
+
return {
|
|
59
|
+
rootRef,
|
|
60
|
+
inputRef,
|
|
61
|
+
panelId,
|
|
62
|
+
visible,
|
|
63
|
+
setVisible,
|
|
64
|
+
closeAndFocus,
|
|
65
|
+
onInputFocus: () => {
|
|
66
|
+
if (!skipFocus.current)
|
|
67
|
+
setVisible(true);
|
|
68
|
+
},
|
|
69
|
+
onRootBlur: (event) => {
|
|
70
|
+
if (!event.currentTarget.contains(event.relatedTarget))
|
|
71
|
+
setVisible(false);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
}
|
|
5
75
|
|
|
6
76
|
// ../../node_modules/.bun/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs
|
|
7
77
|
function r(e) {
|
|
@@ -113,10 +183,11 @@ function formatParts(parts, format, use12Hours) {
|
|
|
113
183
|
}
|
|
114
184
|
function displayValue(value, format, use12Hours) {
|
|
115
185
|
const parts = valueToParts(value);
|
|
116
|
-
return parts ? formatParts(parts, format, use12Hours) : "";
|
|
186
|
+
return parts ? formatParts(parts, format, use12Hours) : typeof value === "string" ? value : "";
|
|
117
187
|
}
|
|
118
188
|
function normalizedTimeString(value, format, use12Hours) {
|
|
119
|
-
|
|
189
|
+
const parts = valueToParts(value);
|
|
190
|
+
return parts ? formatParts(parts, format, use12Hours) : "";
|
|
120
191
|
}
|
|
121
192
|
function isDisabledTime(value, props) {
|
|
122
193
|
if (!value || !props.disabledTime) {
|
|
@@ -136,6 +207,7 @@ function nowValue() {
|
|
|
136
207
|
var TimePickerRoot = forwardRef(({
|
|
137
208
|
allowClear,
|
|
138
209
|
className,
|
|
210
|
+
inputProps,
|
|
139
211
|
defaultOpen,
|
|
140
212
|
defaultValue,
|
|
141
213
|
disabled,
|
|
@@ -156,16 +228,23 @@ var TimePickerRoot = forwardRef(({
|
|
|
156
228
|
}, ref) => {
|
|
157
229
|
const timeFormat = format ?? (use12Hours ? "h:mm:ss A" : "HH:mm:ss");
|
|
158
230
|
const isValueControlled = value !== undefined;
|
|
159
|
-
const
|
|
160
|
-
const
|
|
161
|
-
|
|
231
|
+
const [innerValue, setInnerValue] = useState2(defaultValue);
|
|
232
|
+
const dropdown = usePickerDropdown({
|
|
233
|
+
open,
|
|
234
|
+
defaultOpen,
|
|
235
|
+
disabled,
|
|
236
|
+
onOpenChange,
|
|
237
|
+
ref
|
|
238
|
+
});
|
|
162
239
|
const currentValue = isValueControlled ? value : innerValue;
|
|
163
|
-
const visible
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
240
|
+
const { visible, setVisible } = dropdown;
|
|
241
|
+
const parts = valueToParts(currentValue) ?? {
|
|
242
|
+
hour: 0,
|
|
243
|
+
minute: 0,
|
|
244
|
+
second: 0
|
|
245
|
+
};
|
|
246
|
+
function columnValue(part, value) {
|
|
247
|
+
return formatParts({ ...parts, [part]: value }, "HH:mm:ss");
|
|
169
248
|
}
|
|
170
249
|
function emitChange(nextValue) {
|
|
171
250
|
if (isDisabledTime(nextValue, { disabledTime, use12Hours })) {
|
|
@@ -178,7 +257,8 @@ var TimePickerRoot = forwardRef(({
|
|
|
178
257
|
}
|
|
179
258
|
return /* @__PURE__ */ jsxs("div", {
|
|
180
259
|
...props,
|
|
181
|
-
ref,
|
|
260
|
+
ref: dropdown.rootRef,
|
|
261
|
+
onBlur: dropdown.onRootBlur,
|
|
182
262
|
className: getTimePickerClasses({
|
|
183
263
|
size,
|
|
184
264
|
status,
|
|
@@ -188,18 +268,23 @@ var TimePickerRoot = forwardRef(({
|
|
|
188
268
|
}),
|
|
189
269
|
children: [
|
|
190
270
|
/* @__PURE__ */ jsx("input", {
|
|
271
|
+
...inputProps,
|
|
272
|
+
ref: dropdown.inputRef,
|
|
273
|
+
"aria-haspopup": "dialog",
|
|
274
|
+
"aria-controls": visible ? dropdown.panelId : undefined,
|
|
275
|
+
type: "text",
|
|
191
276
|
className: timePickerInputClass,
|
|
192
277
|
disabled,
|
|
193
278
|
value: displayValue(currentValue, timeFormat, use12Hours),
|
|
194
279
|
placeholder,
|
|
195
280
|
onFocus: (event) => {
|
|
196
281
|
onFocus?.(event);
|
|
197
|
-
|
|
282
|
+
dropdown.onInputFocus();
|
|
198
283
|
},
|
|
199
284
|
onBlur: (event) => {
|
|
200
285
|
onBlur?.(event);
|
|
201
|
-
setVisible(false);
|
|
202
286
|
},
|
|
287
|
+
onClick: () => setVisible(true),
|
|
203
288
|
onChange: (event) => emitChange(event.currentTarget.value || undefined)
|
|
204
289
|
}),
|
|
205
290
|
allowClear && currentValue && !disabled ? /* @__PURE__ */ jsx("button", {
|
|
@@ -210,23 +295,70 @@ var TimePickerRoot = forwardRef(({
|
|
|
210
295
|
onClick: () => emitChange(undefined),
|
|
211
296
|
children: "x"
|
|
212
297
|
}) : null,
|
|
213
|
-
/* @__PURE__ */ jsx("
|
|
298
|
+
/* @__PURE__ */ jsx("button", {
|
|
299
|
+
type: "button",
|
|
214
300
|
className: timePickerIconClass,
|
|
215
|
-
"aria-
|
|
216
|
-
|
|
301
|
+
"aria-label": "Open time picker",
|
|
302
|
+
"aria-haspopup": "dialog",
|
|
303
|
+
"aria-expanded": visible,
|
|
304
|
+
"aria-controls": visible ? dropdown.panelId : undefined,
|
|
305
|
+
disabled,
|
|
306
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
307
|
+
onClick: () => setVisible(!visible)
|
|
217
308
|
}),
|
|
218
|
-
|
|
309
|
+
visible ? /* @__PURE__ */ jsxs("div", {
|
|
310
|
+
id: dropdown.panelId,
|
|
311
|
+
role: "dialog",
|
|
312
|
+
"aria-label": "Choose time",
|
|
219
313
|
className: getTimePickerPanelClasses({ open: visible }),
|
|
220
|
-
children:
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
314
|
+
children: [
|
|
315
|
+
/* @__PURE__ */ jsx("div", {
|
|
316
|
+
className: "time-picker-columns",
|
|
317
|
+
children: ["hour", "minute", "second"].filter((part) => part === "hour" || timeFormat.includes(part === "minute" ? "m" : "s")).map((part) => /* @__PURE__ */ jsx("div", {
|
|
318
|
+
className: "time-picker-column",
|
|
319
|
+
role: "listbox",
|
|
320
|
+
"aria-label": `${part[0].toUpperCase()}${part.slice(1)}s`,
|
|
321
|
+
children: Array.from({ length: part === "hour" ? 24 : 60 }, (_, option) => /* @__PURE__ */ jsx("button", {
|
|
322
|
+
type: "button",
|
|
323
|
+
role: "option",
|
|
324
|
+
className: "time-picker-option",
|
|
325
|
+
"aria-label": `${part[0].toUpperCase()}${part.slice(1)} ${padTimePart(option)}`,
|
|
326
|
+
"aria-selected": parts[part] === option,
|
|
327
|
+
disabled: isDisabledTime(columnValue(part, option), {
|
|
328
|
+
disabledTime,
|
|
329
|
+
use12Hours
|
|
330
|
+
}),
|
|
331
|
+
onClick: () => emitChange(columnValue(part, option)),
|
|
332
|
+
children: part === "hour" && use12Hours ? `${option % 12 || 12} ${option < 12 ? "AM" : "PM"}` : padTimePart(option)
|
|
333
|
+
}, option))
|
|
334
|
+
}, part))
|
|
335
|
+
}),
|
|
336
|
+
/* @__PURE__ */ jsxs("div", {
|
|
337
|
+
className: timePickerFooterClass,
|
|
338
|
+
children: [
|
|
339
|
+
showNow ? /* @__PURE__ */ jsx("button", {
|
|
340
|
+
type: "button",
|
|
341
|
+
className: timePickerNowClass,
|
|
342
|
+
disabled: isDisabledTime(nowValue(), {
|
|
343
|
+
disabledTime,
|
|
344
|
+
use12Hours
|
|
345
|
+
}),
|
|
346
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
347
|
+
onClick: () => {
|
|
348
|
+
emitChange(nowValue());
|
|
349
|
+
dropdown.closeAndFocus();
|
|
350
|
+
},
|
|
351
|
+
children: "Now"
|
|
352
|
+
}) : null,
|
|
353
|
+
/* @__PURE__ */ jsx("button", {
|
|
354
|
+
type: "button",
|
|
355
|
+
className: "time-picker-confirm",
|
|
356
|
+
onClick: dropdown.closeAndFocus,
|
|
357
|
+
children: "Done"
|
|
358
|
+
})
|
|
359
|
+
]
|
|
228
360
|
})
|
|
229
|
-
|
|
361
|
+
]
|
|
230
362
|
}) : null
|
|
231
363
|
]
|
|
232
364
|
});
|
|
@@ -235,6 +367,7 @@ TimePickerRoot.displayName = "TimePicker";
|
|
|
235
367
|
var RangePicker = forwardRef(({
|
|
236
368
|
allowClear,
|
|
237
369
|
className,
|
|
370
|
+
inputProps,
|
|
238
371
|
defaultValue,
|
|
239
372
|
disabled,
|
|
240
373
|
disabledTime,
|
|
@@ -251,7 +384,7 @@ var RangePicker = forwardRef(({
|
|
|
251
384
|
}, ref) => {
|
|
252
385
|
const timeFormat = format ?? (use12Hours ? "h:mm:ss A" : "HH:mm:ss");
|
|
253
386
|
const isControlled = value !== undefined;
|
|
254
|
-
const [innerValue, setInnerValue] =
|
|
387
|
+
const [innerValue, setInnerValue] = useState2(defaultValue ?? [undefined, undefined]);
|
|
255
388
|
const currentValue = isControlled ? value : innerValue;
|
|
256
389
|
function emitChange(nextValue) {
|
|
257
390
|
if (nextValue.some((item) => isDisabledTime(item, { disabledTime, use12Hours }))) {
|
|
@@ -280,6 +413,8 @@ var RangePicker = forwardRef(({
|
|
|
280
413
|
}),
|
|
281
414
|
children: [
|
|
282
415
|
/* @__PURE__ */ jsx("input", {
|
|
416
|
+
...inputProps,
|
|
417
|
+
type: "text",
|
|
283
418
|
className: timePickerInputClass,
|
|
284
419
|
disabled,
|
|
285
420
|
value: displayValue(currentValue?.[0], timeFormat, use12Hours),
|
|
@@ -291,6 +426,9 @@ var RangePicker = forwardRef(({
|
|
|
291
426
|
children: separator
|
|
292
427
|
}),
|
|
293
428
|
/* @__PURE__ */ jsx("input", {
|
|
429
|
+
...inputProps,
|
|
430
|
+
id: inputProps?.id ? `${inputProps.id}-end` : undefined,
|
|
431
|
+
type: "text",
|
|
294
432
|
className: timePickerInputClass,
|
|
295
433
|
disabled,
|
|
296
434
|
value: displayValue(currentValue?.[1], timeFormat, use12Hours),
|
|
@@ -6,6 +6,10 @@ export interface TooltipProps extends Omit<ComponentProps<"span">, "title"> {
|
|
|
6
6
|
placement?: TooltipPlacement;
|
|
7
7
|
open?: boolean;
|
|
8
8
|
defaultOpen?: boolean;
|
|
9
|
+
/** Called when hover, focus, or dismissal requests a visibility change.
|
|
10
|
+
* Controlled tooltips use manual popovers and stay open until `open` changes. */
|
|
11
|
+
onOpenChange?: (open: boolean) => void;
|
|
12
|
+
/** @deprecated Native tooltips follow Core's arrowless automatic placement. */
|
|
9
13
|
arrow?: boolean;
|
|
10
14
|
size?: TooltipSize;
|
|
11
15
|
children: ReactNode;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
// src/components/tooltip/Tooltip.tsx
|
|
4
|
-
import { forwardRef, useState } from "react";
|
|
4
|
+
import React, { forwardRef, useEffect, useId, useRef, useState } from "react";
|
|
5
5
|
|
|
6
6
|
// ../../node_modules/.bun/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs
|
|
7
7
|
function r(e) {
|
|
@@ -32,7 +32,6 @@ function cn(...inputs) {
|
|
|
32
32
|
var tooltipWrapperClass = "tooltip-wrapper";
|
|
33
33
|
var tooltipBaseClass = "tooltip";
|
|
34
34
|
var tooltipShowClass = "tooltip-show";
|
|
35
|
-
var tooltipArrowClass = "tooltip-arrow";
|
|
36
35
|
var tooltipNoArrowClass = "tooltip-no-arrow";
|
|
37
36
|
var tooltipPlacementClasses = {
|
|
38
37
|
top: "tooltip-top",
|
|
@@ -62,10 +61,12 @@ var Tooltip = forwardRef(({
|
|
|
62
61
|
placement = "top",
|
|
63
62
|
open,
|
|
64
63
|
defaultOpen,
|
|
64
|
+
onOpenChange,
|
|
65
65
|
arrow = true,
|
|
66
66
|
size = "md",
|
|
67
67
|
className,
|
|
68
68
|
children,
|
|
69
|
+
style,
|
|
69
70
|
onBlur,
|
|
70
71
|
onFocus,
|
|
71
72
|
onMouseEnter,
|
|
@@ -75,54 +76,133 @@ var Tooltip = forwardRef(({
|
|
|
75
76
|
const [internalOpen, setInternalOpen] = useState(Boolean(defaultOpen));
|
|
76
77
|
const isControlled = open !== undefined;
|
|
77
78
|
const visible = isControlled ? open : internalOpen;
|
|
78
|
-
const
|
|
79
|
+
const reactId = useId();
|
|
80
|
+
const tooltipId = props.id !== undefined ? `${props.id}-tooltip` : `${reactId}-tooltip`;
|
|
81
|
+
const anchor = `--tooltip-${reactId.replace(/[^a-zA-Z0-9_-]/g, "")}`;
|
|
82
|
+
const surfaceRef = useRef(null);
|
|
83
|
+
const hoveredRef = useRef(false);
|
|
84
|
+
const focusedRef = useRef(false);
|
|
85
|
+
const interactionOpenRef = useRef(false);
|
|
86
|
+
const visibleRef = useRef(visible);
|
|
87
|
+
const controlledRef = useRef(isControlled);
|
|
88
|
+
const onOpenChangeRef = useRef(onOpenChange);
|
|
89
|
+
visibleRef.current = visible;
|
|
90
|
+
controlledRef.current = isControlled;
|
|
91
|
+
onOpenChangeRef.current = onOpenChange;
|
|
92
|
+
const hasTitle = Boolean(title);
|
|
93
|
+
useEffect(() => {
|
|
94
|
+
const surface = surfaceRef.current;
|
|
95
|
+
if (!surface)
|
|
96
|
+
return;
|
|
97
|
+
const tooltipSurface = surface;
|
|
98
|
+
function handleToggle(event) {
|
|
99
|
+
if (event.newState !== "closed" || !visibleRef.current || isControlled || isControlled !== controlledRef.current || tooltipSurface.matches(":popover-open")) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
hoveredRef.current = false;
|
|
103
|
+
focusedRef.current = false;
|
|
104
|
+
interactionOpenRef.current = false;
|
|
105
|
+
onOpenChangeRef.current?.(false);
|
|
106
|
+
setInternalOpen(false);
|
|
107
|
+
}
|
|
108
|
+
surface.addEventListener("toggle", handleToggle);
|
|
109
|
+
return () => surface.removeEventListener("toggle", handleToggle);
|
|
110
|
+
}, [hasTitle, isControlled]);
|
|
111
|
+
useEffect(() => {
|
|
112
|
+
const surface = surfaceRef.current;
|
|
113
|
+
if (!surface)
|
|
114
|
+
return;
|
|
115
|
+
if (visible && !surface.matches(":popover-open")) {
|
|
116
|
+
surface.showPopover();
|
|
117
|
+
} else if (!visible && surface.matches(":popover-open")) {
|
|
118
|
+
surface.hidePopover();
|
|
119
|
+
}
|
|
120
|
+
}, [visible, hasTitle, isControlled]);
|
|
121
|
+
useEffect(() => {
|
|
122
|
+
if (!isControlled || !visible || !hasTitle)
|
|
123
|
+
return;
|
|
124
|
+
const wrapper = surfaceRef.current?.parentElement;
|
|
125
|
+
if (!wrapper)
|
|
126
|
+
return;
|
|
127
|
+
const tooltipWrapper = wrapper;
|
|
128
|
+
function requestDismiss() {
|
|
129
|
+
hoveredRef.current = false;
|
|
130
|
+
focusedRef.current = false;
|
|
131
|
+
interactionOpenRef.current = false;
|
|
132
|
+
onOpenChangeRef.current?.(false);
|
|
133
|
+
}
|
|
134
|
+
function handlePointerDown(event) {
|
|
135
|
+
if (!tooltipWrapper.contains(event.target))
|
|
136
|
+
requestDismiss();
|
|
137
|
+
}
|
|
138
|
+
function handleKeyDown(event) {
|
|
139
|
+
if (event.key === "Escape")
|
|
140
|
+
requestDismiss();
|
|
141
|
+
}
|
|
142
|
+
document.addEventListener("pointerdown", handlePointerDown, true);
|
|
143
|
+
document.addEventListener("keydown", handleKeyDown, true);
|
|
144
|
+
return () => {
|
|
145
|
+
document.removeEventListener("pointerdown", handlePointerDown, true);
|
|
146
|
+
document.removeEventListener("keydown", handleKeyDown, true);
|
|
147
|
+
};
|
|
148
|
+
}, [isControlled, visible, hasTitle]);
|
|
149
|
+
function updateInteraction() {
|
|
150
|
+
const next = hoveredRef.current || focusedRef.current;
|
|
151
|
+
if (next === interactionOpenRef.current)
|
|
152
|
+
return;
|
|
153
|
+
interactionOpenRef.current = next;
|
|
154
|
+
onOpenChange?.(next);
|
|
155
|
+
if (!isControlled)
|
|
156
|
+
setInternalOpen(next);
|
|
157
|
+
}
|
|
79
158
|
function showTooltip(event) {
|
|
80
159
|
onMouseEnter?.(event);
|
|
81
|
-
|
|
82
|
-
|
|
160
|
+
hoveredRef.current = true;
|
|
161
|
+
updateInteraction();
|
|
83
162
|
}
|
|
84
163
|
function hideTooltip(event) {
|
|
85
164
|
onMouseLeave?.(event);
|
|
86
|
-
|
|
87
|
-
|
|
165
|
+
hoveredRef.current = false;
|
|
166
|
+
updateInteraction();
|
|
88
167
|
}
|
|
89
168
|
function focusTooltip(event) {
|
|
90
169
|
onFocus?.(event);
|
|
91
|
-
|
|
92
|
-
|
|
170
|
+
focusedRef.current = true;
|
|
171
|
+
updateInteraction();
|
|
93
172
|
}
|
|
94
173
|
function blurTooltip(event) {
|
|
95
174
|
onBlur?.(event);
|
|
96
|
-
if (
|
|
97
|
-
|
|
175
|
+
if (event.currentTarget.contains(event.relatedTarget))
|
|
176
|
+
return;
|
|
177
|
+
focusedRef.current = false;
|
|
178
|
+
updateInteraction();
|
|
179
|
+
}
|
|
180
|
+
let trigger = children;
|
|
181
|
+
if (hasTitle && React.isValidElement(children) && children.type !== React.Fragment) {
|
|
182
|
+
trigger = React.cloneElement(children, {
|
|
183
|
+
"aria-describedby": [children.props["aria-describedby"], tooltipId].filter(Boolean).join(" ")
|
|
184
|
+
});
|
|
98
185
|
}
|
|
99
186
|
return /* @__PURE__ */ jsxs("span", {
|
|
100
187
|
...props,
|
|
101
188
|
ref,
|
|
102
189
|
className: tooltipWrapperClass,
|
|
103
|
-
|
|
190
|
+
style: { ...style, anchorName: anchor },
|
|
191
|
+
"aria-describedby": hasTitle && trigger === children ? [props["aria-describedby"], tooltipId].filter(Boolean).join(" ") : props["aria-describedby"],
|
|
104
192
|
onMouseEnter: showTooltip,
|
|
105
193
|
onMouseLeave: hideTooltip,
|
|
106
194
|
onFocus: focusTooltip,
|
|
107
195
|
onBlur: blurTooltip,
|
|
108
196
|
children: [
|
|
109
|
-
|
|
110
|
-
|
|
197
|
+
trigger,
|
|
198
|
+
hasTitle ? /* @__PURE__ */ jsx("span", {
|
|
199
|
+
ref: surfaceRef,
|
|
111
200
|
id: tooltipId,
|
|
112
201
|
role: "tooltip",
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
arrow,
|
|
118
|
-
className
|
|
119
|
-
}),
|
|
120
|
-
children: [
|
|
121
|
-
title,
|
|
122
|
-
arrow ? /* @__PURE__ */ jsx("span", {
|
|
123
|
-
className: tooltipArrowClass
|
|
124
|
-
}) : null
|
|
125
|
-
]
|
|
202
|
+
popover: isControlled ? "manual" : "hint",
|
|
203
|
+
style: { positionAnchor: anchor },
|
|
204
|
+
className: getTooltipClasses({ placement, size, arrow, className }),
|
|
205
|
+
children: title
|
|
126
206
|
}) : null
|
|
127
207
|
]
|
|
128
208
|
});
|