@tensor_1/react 2.26.3 → 2.28.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 +74 -0
- package/dist/calendar-model.d.ts +4 -2
- package/dist/components/AppShell.d.ts +1 -1
- package/dist/components/AppShell.js +6 -2
- package/dist/components/Button.d.ts +28 -4
- package/dist/components/Button.js +19 -9
- package/dist/components/Card.d.ts +7 -1
- package/dist/components/Card.js +3 -3
- package/dist/components/Chip.d.ts +43 -0
- package/dist/components/Chip.js +73 -0
- package/dist/components/CollapsibleSection.d.ts +19 -1
- package/dist/components/CollapsibleSection.js +5 -2
- package/dist/components/CollapsibleSectionState.d.ts +11 -0
- package/dist/components/CollapsibleSectionState.js +67 -0
- package/dist/components/CommandPalette.d.ts +1 -1
- package/dist/components/CommandPalette.js +4 -1
- package/dist/components/DateRangePicker.js +3 -1
- package/dist/components/Dialogs.d.ts +54 -3
- package/dist/components/Dialogs.js +167 -6
- package/dist/components/Drawer.d.ts +6 -1
- package/dist/components/Drawer.js +5 -2
- package/dist/components/Kbd.d.ts +27 -0
- package/dist/components/Kbd.js +45 -0
- package/dist/components/Menu.d.ts +51 -0
- package/dist/components/Menu.js +177 -0
- package/dist/components/Modal.d.ts +1 -1
- package/dist/components/Modal.js +4 -1
- package/dist/components/Pagination.d.ts +36 -5
- package/dist/components/Pagination.js +59 -37
- package/dist/components/Peek.d.ts +1 -1
- package/dist/components/Peek.js +6 -1
- package/dist/components/SchedulingCalendar.d.ts +47 -2
- package/dist/components/SchedulingCalendar.js +69 -22
- package/dist/components/SearchSuggest.d.ts +1 -1
- package/dist/components/SearchSuggest.js +4 -1
- package/dist/components/Sidebar.d.ts +7 -2
- package/dist/components/Sidebar.js +15 -4
- package/dist/components/Stat.d.ts +16 -0
- package/dist/components/Stat.js +12 -5
- package/dist/components/Steps.d.ts +48 -0
- package/dist/components/Steps.js +42 -0
- package/dist/components/Toast.d.ts +15 -3
- package/dist/components/Toast.js +158 -9
- package/dist/components/Tooltip.d.ts +10 -4
- package/dist/components/Tooltip.js +2 -2
- package/dist/emoji.cjs +2 -2
- package/dist/index.cjs +2322 -1352
- package/dist/index.d.cts +703 -166
- package/dist/index.d.ts +11 -4
- package/dist/index.js +29 -2
- package/dist/labels-context.d.ts +72 -0
- package/dist/labels-context.js +23 -0
- package/dist/link.d.ts +20 -0
- package/dist/link.js +9 -0
- package/dist/toast-store.d.ts +98 -0
- package/dist/toast-store.js +110 -0
- package/package.json +1 -1
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Children, cloneElement, isValidElement } from "react";
|
|
3
|
+
import { cx } from "../cx.js";
|
|
4
|
+
import { renderUixLink } from "../link.js";
|
|
5
|
+
const DEFAULT_STEP_STATE_LABELS = {
|
|
6
|
+
complete: "Completed",
|
|
7
|
+
current: "Current step",
|
|
8
|
+
upcoming: "Not started",
|
|
9
|
+
waiting: "Waiting",
|
|
10
|
+
error: "Needs attention"
|
|
11
|
+
};
|
|
12
|
+
const CSS_STATE = { complete: "done", current: "active", upcoming: void 0, waiting: "waiting", error: "error" };
|
|
13
|
+
const Check = () => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 16 16", width: "12", height: "12", fill: "none", stroke: "currentColor", strokeWidth: 2.25, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: "M3.5 8.5l3 3 6-7" }) });
|
|
14
|
+
function Steps({ orientation = "horizontal", label, stateLabels, className, children, ...props }) {
|
|
15
|
+
const labels = { ...DEFAULT_STEP_STATE_LABELS, ...stateLabels };
|
|
16
|
+
const steps = Children.toArray(children).filter(isValidElement);
|
|
17
|
+
return /* @__PURE__ */ jsx("ol", { "aria-label": label, className: cx("uix-steps", "uix-steps--list", `uix-steps--${orientation}`, className), ...props, children: steps.map((step, index) => cloneElement(step, { index, last: index === steps.length - 1, stateLabels: labels })) });
|
|
18
|
+
}
|
|
19
|
+
function Step({ title, description, state = "upcoming", marker, href, renderLink, onSelect, index = 0, last = false, stateLabels = DEFAULT_STEP_STATE_LABELS, className, ...props }) {
|
|
20
|
+
const glyph = marker ?? (state === "complete" ? /* @__PURE__ */ jsx(Check, {}) : state === "error" ? "!" : index + 1);
|
|
21
|
+
const name = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
22
|
+
/* @__PURE__ */ jsx("span", { className: "uix-step__title", children: title }),
|
|
23
|
+
/* @__PURE__ */ jsxs("span", { className: "uix-visually-hidden", children: [
|
|
24
|
+
", ",
|
|
25
|
+
stateLabels[state]
|
|
26
|
+
] })
|
|
27
|
+
] });
|
|
28
|
+
const titled = href != null ? renderUixLink(renderLink, { href, className: "uix-step__action", children: name }) : onSelect ? /* @__PURE__ */ jsx("button", { type: "button", className: "uix-step__action", onClick: onSelect, children: name }) : /* @__PURE__ */ jsx("span", { className: "uix-step__action", children: name });
|
|
29
|
+
return /* @__PURE__ */ jsxs("li", { className: cx("uix-step", className), "data-state": CSS_STATE[state], "aria-current": state === "current" ? "step" : void 0, ...props, children: [
|
|
30
|
+
/* @__PURE__ */ jsx("span", { className: "uix-step__marker", "aria-hidden": "true", children: glyph }),
|
|
31
|
+
/* @__PURE__ */ jsxs("span", { className: "uix-step__text", children: [
|
|
32
|
+
titled,
|
|
33
|
+
description != null && /* @__PURE__ */ jsx("span", { className: "uix-step__desc", children: description })
|
|
34
|
+
] }),
|
|
35
|
+
!last && /* @__PURE__ */ jsx("span", { className: "uix-step__connector", "aria-hidden": "true", "data-done": state === "complete" || void 0 })
|
|
36
|
+
] });
|
|
37
|
+
}
|
|
38
|
+
export {
|
|
39
|
+
DEFAULT_STEP_STATE_LABELS,
|
|
40
|
+
Step,
|
|
41
|
+
Steps
|
|
42
|
+
};
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { HTMLAttributes, ReactNode } from 'react';
|
|
3
|
+
import { ToastStore } from '../toast-store.js';
|
|
3
4
|
|
|
4
|
-
type ToastTone = 'success' | 'danger' | 'info';
|
|
5
|
+
type ToastTone = 'success' | 'danger' | 'info' | 'warning';
|
|
5
6
|
interface ToastProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {
|
|
6
7
|
/** TENSOR RX-125 (UIX-04): translatable; English default. */
|
|
7
8
|
dismissLabel?: string;
|
|
@@ -9,15 +10,26 @@ interface ToastProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {
|
|
|
9
10
|
message?: ReactNode;
|
|
10
11
|
tone?: ToastTone;
|
|
11
12
|
icon?: ReactNode;
|
|
13
|
+
/** A button (or link) after the text, e.g. "Undo" or "Copy details" (HAR-1363). */
|
|
14
|
+
action?: ReactNode;
|
|
12
15
|
onClose?: () => void;
|
|
13
16
|
leaving?: boolean;
|
|
14
17
|
}
|
|
15
|
-
declare function Toast({ title, message, tone, icon, onClose, leaving, dismissLabel, className, ...props }: ToastProps): react.JSX.Element;
|
|
18
|
+
declare function Toast({ title, message, tone, icon, action, onClose, leaving, dismissLabel: dismissLabelProp, className, ...props }: ToastProps): react.JSX.Element;
|
|
16
19
|
interface ToasterProps extends HTMLAttributes<HTMLDivElement> {
|
|
17
20
|
/** TENSOR RX-125 (UIX-04): translatable; English default. */
|
|
18
21
|
regionLabel?: string;
|
|
22
|
+
/**
|
|
23
|
+
* The queue to render (HAR-1363). Default: the store behind the exported `toast()`.
|
|
24
|
+
* Children still render first, so a hand-managed `<Toast>` keeps working.
|
|
25
|
+
*/
|
|
26
|
+
store?: ToastStore;
|
|
27
|
+
/** At most this many store toasts on screen; later ones wait their turn. Default 3. */
|
|
28
|
+
limit?: number;
|
|
29
|
+
/** Corner of the viewport. Default `bottom-end`. */
|
|
30
|
+
position?: 'bottom-end' | 'bottom-start' | 'bottom-center' | 'top-end' | 'top-start' | 'top-center';
|
|
19
31
|
children?: ReactNode;
|
|
20
32
|
}
|
|
21
|
-
declare function Toaster({ children, regionLabel, className, ...props }: ToasterProps): react.JSX.Element;
|
|
33
|
+
declare function Toaster({ children, regionLabel: regionLabelProp, store, limit, position, className, onMouseEnter, onMouseLeave, onFocus, onBlur, onKeyDown, ...props }: ToasterProps): react.JSX.Element;
|
|
22
34
|
|
|
23
35
|
export { Toast, type ToastProps, type ToastTone, Toaster, type ToasterProps };
|
package/dist/components/Toast.js
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
|
|
2
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
4
4
|
import { cx } from "../cx.js";
|
|
5
|
+
import { useUixLabels } from "../labels-context.js";
|
|
6
|
+
import { toast as defaultToast } from "../toast-store.js";
|
|
5
7
|
const ToasterContext = createContext(null);
|
|
6
|
-
function Toast({ title, message, tone, icon, onClose, leaving, dismissLabel
|
|
8
|
+
function Toast({ title, message, tone, icon, action, onClose, leaving, dismissLabel: dismissLabelProp, className, ...props }) {
|
|
9
|
+
const uixLabels = useUixLabels();
|
|
10
|
+
const dismissLabel = dismissLabelProp ?? uixLabels.toast?.dismiss ?? "Dismiss";
|
|
7
11
|
const assertive = tone === "danger";
|
|
8
12
|
const toaster = useContext(ToasterContext);
|
|
9
13
|
const bodyRef = useRef(null);
|
|
@@ -39,12 +43,108 @@ function Toast({ title, message, tone, icon, onClose, leaving, dismissLabel = "D
|
|
|
39
43
|
title && /* @__PURE__ */ jsx("div", { className: "uix-toast__title", children: title }),
|
|
40
44
|
message && /* @__PURE__ */ jsx("div", { className: "uix-toast__msg", children: message })
|
|
41
45
|
] }),
|
|
42
|
-
|
|
46
|
+
action != null && /* @__PURE__ */ jsx("div", { className: "uix-toast__action-slot", children: action }),
|
|
47
|
+
onClose && /* @__PURE__ */ jsx("button", { type: "button", className: "uix-toast__close", onClick: handleClose, "aria-label": dismissLabel, children: "\xD7" })
|
|
43
48
|
]
|
|
44
49
|
}
|
|
45
50
|
);
|
|
46
51
|
}
|
|
47
|
-
|
|
52
|
+
const KIND_TONE = {
|
|
53
|
+
success: "success",
|
|
54
|
+
error: "danger",
|
|
55
|
+
warning: "warning",
|
|
56
|
+
info: "info",
|
|
57
|
+
loading: "info",
|
|
58
|
+
default: void 0
|
|
59
|
+
};
|
|
60
|
+
const svg = (path) => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 20 20", fill: "none", stroke: "currentColor", strokeWidth: 1.8, strokeLinecap: "round", strokeLinejoin: "round", children: path });
|
|
61
|
+
const KIND_GLYPH = {
|
|
62
|
+
success: svg(/* @__PURE__ */ jsxs(Fragment, { children: [
|
|
63
|
+
/* @__PURE__ */ jsx("circle", { cx: "10", cy: "10", r: "7.25" }),
|
|
64
|
+
/* @__PURE__ */ jsx("path", { d: "M6.75 10.25l2.25 2.25 4.25-4.75" })
|
|
65
|
+
] })),
|
|
66
|
+
error: svg(/* @__PURE__ */ jsxs(Fragment, { children: [
|
|
67
|
+
/* @__PURE__ */ jsx("circle", { cx: "10", cy: "10", r: "7.25" }),
|
|
68
|
+
/* @__PURE__ */ jsx("path", { d: "M10 6.25v4.5M10 13.5v.25" })
|
|
69
|
+
] })),
|
|
70
|
+
warning: svg(/* @__PURE__ */ jsxs(Fragment, { children: [
|
|
71
|
+
/* @__PURE__ */ jsx("path", { d: "M10 3.25l7.25 13H2.75z" }),
|
|
72
|
+
/* @__PURE__ */ jsx("path", { d: "M10 8.25v3.5M10 14v.25" })
|
|
73
|
+
] })),
|
|
74
|
+
info: svg(/* @__PURE__ */ jsxs(Fragment, { children: [
|
|
75
|
+
/* @__PURE__ */ jsx("circle", { cx: "10", cy: "10", r: "7.25" }),
|
|
76
|
+
/* @__PURE__ */ jsx("path", { d: "M10 9.25v4.5M10 6.5v.25" })
|
|
77
|
+
] })),
|
|
78
|
+
loading: /* @__PURE__ */ jsx("span", { className: "uix-spinner uix-toast__spinner" })
|
|
79
|
+
};
|
|
80
|
+
function StoreToast({ record, store }) {
|
|
81
|
+
const action = record.action && /* @__PURE__ */ jsx(
|
|
82
|
+
"button",
|
|
83
|
+
{
|
|
84
|
+
type: "button",
|
|
85
|
+
className: "uix-toast__action",
|
|
86
|
+
onClick: () => {
|
|
87
|
+
record.action.onClick();
|
|
88
|
+
store.dismiss(record.id, "action");
|
|
89
|
+
},
|
|
90
|
+
children: record.action.label
|
|
91
|
+
}
|
|
92
|
+
);
|
|
93
|
+
return /* @__PURE__ */ jsx(
|
|
94
|
+
Toast,
|
|
95
|
+
{
|
|
96
|
+
"data-toast-id": record.id,
|
|
97
|
+
tone: KIND_TONE[record.kind],
|
|
98
|
+
icon: record.icon ?? KIND_GLYPH[record.kind],
|
|
99
|
+
title: record.message,
|
|
100
|
+
message: record.description,
|
|
101
|
+
action,
|
|
102
|
+
leaving: record.leaving,
|
|
103
|
+
"aria-busy": record.kind === "loading" || void 0,
|
|
104
|
+
onClose: () => store.dismiss(record.id, "close")
|
|
105
|
+
}
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
function useToastTimers(store, visible, paused) {
|
|
109
|
+
const timers = useRef(/* @__PURE__ */ new Map());
|
|
110
|
+
useEffect(() => {
|
|
111
|
+
const now = Date.now();
|
|
112
|
+
const map = timers.current;
|
|
113
|
+
const live = new Map(visible.filter((r) => !r.leaving && r.duration != null).map((r) => [r.id, r]));
|
|
114
|
+
for (const [id, timer] of map) {
|
|
115
|
+
const record = live.get(id);
|
|
116
|
+
if (!record || record.version !== timer.version) {
|
|
117
|
+
if (timer.handle != null) clearTimeout(timer.handle);
|
|
118
|
+
map.delete(id);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
for (const record of live.values()) {
|
|
122
|
+
let timer = map.get(record.id);
|
|
123
|
+
if (!timer) {
|
|
124
|
+
timer = { version: record.version, remaining: record.duration, start: now };
|
|
125
|
+
map.set(record.id, timer);
|
|
126
|
+
}
|
|
127
|
+
if (paused) {
|
|
128
|
+
if (timer.handle != null) {
|
|
129
|
+
clearTimeout(timer.handle);
|
|
130
|
+
timer.handle = void 0;
|
|
131
|
+
timer.remaining -= now - timer.start;
|
|
132
|
+
}
|
|
133
|
+
} else if (timer.handle == null) {
|
|
134
|
+
timer.start = now;
|
|
135
|
+
const id = record.id;
|
|
136
|
+
timer.handle = window.setTimeout(() => store.dismiss(id, "timeout"), Math.max(0, timer.remaining));
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
useEffect(() => () => {
|
|
141
|
+
for (const timer of timers.current.values()) if (timer.handle != null) clearTimeout(timer.handle);
|
|
142
|
+
timers.current.clear();
|
|
143
|
+
}, []);
|
|
144
|
+
}
|
|
145
|
+
function Toaster({ children, regionLabel: regionLabelProp, store = defaultToast.store, limit = 3, position = "bottom-end", className, onMouseEnter, onMouseLeave, onFocus, onBlur, onKeyDown, ...props }) {
|
|
146
|
+
const uixLabels = useUixLabels();
|
|
147
|
+
const regionLabel = regionLabelProp ?? uixLabels.toaster?.region ?? "Notifications";
|
|
48
148
|
const [announced, setAnnounced] = useState("");
|
|
49
149
|
const clearTimer = useRef(null);
|
|
50
150
|
const announce = useCallback((text) => {
|
|
@@ -56,10 +156,59 @@ function Toaster({ children, regionLabel = "Notifications", className, ...props
|
|
|
56
156
|
if (clearTimer.current != null) clearTimeout(clearTimer.current);
|
|
57
157
|
}, []);
|
|
58
158
|
const ctx = useMemo(() => ({ announce }), [announce]);
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
]
|
|
159
|
+
const records = useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);
|
|
160
|
+
const visible = useMemo(() => records.slice(-Math.max(1, limit)), [records, limit]);
|
|
161
|
+
const [hovered, setHovered] = useState(false);
|
|
162
|
+
const [focused, setFocused] = useState(false);
|
|
163
|
+
const [hidden, setHidden] = useState(false);
|
|
164
|
+
useEffect(() => {
|
|
165
|
+
const sync = () => setHidden(document.visibilityState === "hidden");
|
|
166
|
+
sync();
|
|
167
|
+
document.addEventListener("visibilitychange", sync);
|
|
168
|
+
return () => document.removeEventListener("visibilitychange", sync);
|
|
169
|
+
}, []);
|
|
170
|
+
useToastTimers(store, visible, hovered || focused || hidden);
|
|
171
|
+
const handleKeyDown = (event) => {
|
|
172
|
+
onKeyDown?.(event);
|
|
173
|
+
if (event.defaultPrevented || event.key !== "Escape") return;
|
|
174
|
+
const id = event.target.closest("[data-toast-id]")?.dataset.toastId;
|
|
175
|
+
if (!id) return;
|
|
176
|
+
event.preventDefault();
|
|
177
|
+
event.stopPropagation();
|
|
178
|
+
store.dismiss(id, "close");
|
|
179
|
+
};
|
|
180
|
+
return /* @__PURE__ */ jsx(ToasterContext.Provider, { value: ctx, children: /* @__PURE__ */ jsxs(
|
|
181
|
+
"div",
|
|
182
|
+
{
|
|
183
|
+
className: cx("uix-toaster", className),
|
|
184
|
+
role: "region",
|
|
185
|
+
"aria-label": regionLabel,
|
|
186
|
+
"data-position": position === "bottom-end" ? void 0 : position,
|
|
187
|
+
onMouseEnter: (e) => {
|
|
188
|
+
setHovered(true);
|
|
189
|
+
onMouseEnter?.(e);
|
|
190
|
+
},
|
|
191
|
+
onMouseLeave: (e) => {
|
|
192
|
+
setHovered(false);
|
|
193
|
+
onMouseLeave?.(e);
|
|
194
|
+
},
|
|
195
|
+
onFocus: (e) => {
|
|
196
|
+
setFocused(true);
|
|
197
|
+
onFocus?.(e);
|
|
198
|
+
},
|
|
199
|
+
onBlur: (e) => {
|
|
200
|
+
if (!e.currentTarget.contains(e.relatedTarget)) setFocused(false);
|
|
201
|
+
onBlur?.(e);
|
|
202
|
+
},
|
|
203
|
+
onKeyDown: handleKeyDown,
|
|
204
|
+
...props,
|
|
205
|
+
children: [
|
|
206
|
+
/* @__PURE__ */ jsx("span", { className: "uix-visually-hidden", role: "status", "aria-live": "polite", children: announced }),
|
|
207
|
+
children,
|
|
208
|
+
visible.map((record) => /* @__PURE__ */ jsx(StoreToast, { record, store }, `${record.id}:${record.kind}`))
|
|
209
|
+
]
|
|
210
|
+
}
|
|
211
|
+
) });
|
|
63
212
|
}
|
|
64
213
|
export {
|
|
65
214
|
Toast,
|
|
@@ -2,9 +2,15 @@ import * as react from 'react';
|
|
|
2
2
|
import { HTMLAttributes, ReactNode } from 'react';
|
|
3
3
|
import { Placement } from '../overlay-position.js';
|
|
4
4
|
|
|
5
|
-
interface TooltipProps extends HTMLAttributes<HTMLSpanElement> {
|
|
6
|
-
/** Tooltip text. */
|
|
7
|
-
label
|
|
5
|
+
interface TooltipProps extends Omit<HTMLAttributes<HTMLSpanElement>, 'content'> {
|
|
6
|
+
/** Tooltip text. Pass this or `content`. */
|
|
7
|
+
label?: string;
|
|
8
|
+
/**
|
|
9
|
+
* Rich, non-interactive tooltip content, e.g. a short list (HAR-1349; TENSOR A3). It is
|
|
10
|
+
* still a `role="tooltip"` description: no links or buttons inside — use `InfoTip` or
|
|
11
|
+
* `Popover` for content the user must reach. Wins over `label` when both are set.
|
|
12
|
+
*/
|
|
13
|
+
content?: ReactNode;
|
|
8
14
|
/** Preferred placement. Default `'top'`. */
|
|
9
15
|
placement?: Placement;
|
|
10
16
|
children?: ReactNode;
|
|
@@ -17,6 +23,6 @@ interface TooltipProps extends HTMLAttributes<HTMLSpanElement> {
|
|
|
17
23
|
* (document-level, per WCAG 1.4.13), and hoverable: the bubble stays open while
|
|
18
24
|
* the pointer is over it (UIX-A11Y-1).
|
|
19
25
|
*/
|
|
20
|
-
declare function Tooltip({ label, placement, className, children, ...props }: TooltipProps): react.JSX.Element;
|
|
26
|
+
declare function Tooltip({ label, content, placement, className, children, ...props }: TooltipProps): react.JSX.Element;
|
|
21
27
|
|
|
22
28
|
export { Tooltip, type TooltipProps };
|
|
@@ -3,7 +3,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { cloneElement, isValidElement, useEffect, useId, useRef, useState } from "react";
|
|
4
4
|
import { cx } from "../cx.js";
|
|
5
5
|
import { useAnchoredPosition } from "../hooks/useAnchoredPosition.js";
|
|
6
|
-
function Tooltip({ label, placement = "top", className, children, ...props }) {
|
|
6
|
+
function Tooltip({ label, content, placement = "top", className, children, ...props }) {
|
|
7
7
|
const triggerRef = useRef(null);
|
|
8
8
|
const bubbleRef = useRef(null);
|
|
9
9
|
const closeTimer = useRef(null);
|
|
@@ -92,7 +92,7 @@ function Tooltip({ label, placement = "top", className, children, ...props }) {
|
|
|
92
92
|
onMouseEnter: cancelClose,
|
|
93
93
|
onMouseLeave: scheduleHide,
|
|
94
94
|
...bubbleAttr,
|
|
95
|
-
children: label
|
|
95
|
+
children: content ?? label
|
|
96
96
|
}
|
|
97
97
|
)
|
|
98
98
|
]
|
package/dist/emoji.cjs
CHANGED
|
@@ -939,7 +939,7 @@ function EditorIcon({ name, ...props }) {
|
|
|
939
939
|
// src/components/Tooltip.tsx
|
|
940
940
|
var import_react5 = require("react");
|
|
941
941
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
942
|
-
function Tooltip({ label, placement = "top", className, children, ...props }) {
|
|
942
|
+
function Tooltip({ label, content, placement = "top", className, children, ...props }) {
|
|
943
943
|
const triggerRef = (0, import_react5.useRef)(null);
|
|
944
944
|
const bubbleRef = (0, import_react5.useRef)(null);
|
|
945
945
|
const closeTimer = (0, import_react5.useRef)(null);
|
|
@@ -1028,7 +1028,7 @@ function Tooltip({ label, placement = "top", className, children, ...props }) {
|
|
|
1028
1028
|
onMouseEnter: cancelClose,
|
|
1029
1029
|
onMouseLeave: scheduleHide,
|
|
1030
1030
|
...bubbleAttr,
|
|
1031
|
-
children: label
|
|
1031
|
+
children: content ?? label
|
|
1032
1032
|
}
|
|
1033
1033
|
)
|
|
1034
1034
|
]
|