@versaur/react 1.0.12 → 1.0.13

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.
@@ -528,10 +528,6 @@ declare interface TooltipGetTriggerPropsOptions {
528
528
  * Unique identifier matching the Tooltip's id
529
529
  */
530
530
  id: string;
531
- /**
532
- * Gap between tooltip and trigger in pixels
533
- */
534
- gap?: number;
535
531
  [key: string]: any;
536
532
  }
537
533
 
@@ -555,9 +551,11 @@ export declare interface TooltipProps extends HTMLAttributes<HTMLDivElement> {
555
551
  */
556
552
  gap?: number;
557
553
  /**
558
- * When to show tooltip: "focus", "hover", or "all"
554
+ * Tooltip interaction type:
555
+ * - "hover" (default): Show on hover, hide on hover away (100ms grace period)
556
+ * - "persisted": Show on click, persists until user clicks outside or presses Escape
559
557
  */
560
- triggerType?: "focus" | "hover" | "all";
558
+ type?: "hover" | "persisted";
561
559
  }
562
560
 
563
561
  /**
package/dist/primitive.js CHANGED
@@ -4,8 +4,8 @@ import { LoaderIcon as T, UserIcon as U, XIcon as X } from "@versaur/icons";
4
4
  import { forwardRef as u, useState as q } from "react";
5
5
  import { u as b } from "./use-data-attrs-iPFyfiKN.js";
6
6
  import { c as p } from "./cx-B9vmfsc1.js";
7
- import { I as B, B as F } from "./tooltip-Zuq8gd0f.js";
8
- import { H as nt, T as lt } from "./tooltip-Zuq8gd0f.js";
7
+ import { I as B, B as F } from "./tooltip-_eEMRSo8.js";
8
+ import { H as nt, T as lt } from "./tooltip-_eEMRSo8.js";
9
9
  const G = u(
10
10
  ({
11
11
  variant: a = "primary",
@@ -0,0 +1,268 @@
1
+ import { jsx as f } from "react/jsx-runtime";
2
+ import { iconStyles as _, hrStyles as k, buttonIconStyles as F, tooltipStyles as A } from "@versaur/core/primitive";
3
+ import B, { forwardRef as E, useRef as b, useEffect as y } from "react";
4
+ import { u as w } from "./use-data-attrs-iPFyfiKN.js";
5
+ import { c as T } from "./cx-B9vmfsc1.js";
6
+ import { LoaderIcon as C } from "@versaur/icons";
7
+ const L = B.forwardRef(function({ intent: t = "inherit", size: n = "inherit", as: o, className: c, ...a }, s) {
8
+ const r = w({ intent: t, size: n });
9
+ return /* @__PURE__ */ f(o, { ref: s, className: T(_.icon, c), ...r, ...a });
10
+ });
11
+ L.displayName = "Icon";
12
+ const H = E(
13
+ ({ orientation: e, variant: t, size: n, spacing: o, className: c, ...a }, s) => {
14
+ const r = w({
15
+ orientation: e,
16
+ size: n,
17
+ spacing: o,
18
+ variant: t
19
+ });
20
+ return /* @__PURE__ */ f(
21
+ "hr",
22
+ {
23
+ ref: s,
24
+ className: T(k.hr, c),
25
+ role: "separator",
26
+ "aria-orientation": e === "vertical" ? "vertical" : void 0,
27
+ ...r,
28
+ ...a
29
+ }
30
+ );
31
+ }
32
+ );
33
+ H.displayName = "Hr";
34
+ const M = E(
35
+ ({
36
+ as: e,
37
+ variant: t = "primary",
38
+ size: n = "medium",
39
+ loading: o = !1,
40
+ disabled: c = !1,
41
+ pressed: a = !1,
42
+ type: s = "button",
43
+ onClick: r,
44
+ iconProps: i = {},
45
+ "aria-label": l,
46
+ className: u,
47
+ ...p
48
+ }, d) => {
49
+ const h = w({
50
+ disabled: c || o,
51
+ loading: o,
52
+ size: n,
53
+ variant: t
54
+ }), g = (v) => {
55
+ if (c || o) {
56
+ v.preventDefault();
57
+ return;
58
+ }
59
+ r == null || r(v);
60
+ };
61
+ return /* @__PURE__ */ f(
62
+ "button",
63
+ {
64
+ ref: d,
65
+ type: s,
66
+ className: T(F["button-icon"], u),
67
+ "aria-label": l,
68
+ "aria-pressed": a ? "true" : void 0,
69
+ "aria-busy": o ? "true" : void 0,
70
+ "aria-disabled": c || o ? "true" : void 0,
71
+ ...h,
72
+ ...p,
73
+ onClick: g,
74
+ children: o ? /* @__PURE__ */ f(L, { as: C, "aria-label": "Loading", "data-loading-icon": "loader" }) : /* @__PURE__ */ f(L, { as: e, ...i })
75
+ }
76
+ );
77
+ }
78
+ );
79
+ M.displayName = "ButtonIcon";
80
+ function $(...e) {
81
+ return (t) => {
82
+ e.forEach((n) => {
83
+ if (typeof n == "function")
84
+ n(t);
85
+ else if (n && "current" in n)
86
+ try {
87
+ n.current = t;
88
+ } catch {
89
+ }
90
+ });
91
+ };
92
+ }
93
+ const j = 100, m = 16;
94
+ function q(e, t) {
95
+ let n = e.parentElement;
96
+ for (; n; ) {
97
+ const o = n.querySelector(`[data-tooltip-trigger="${t}"]`);
98
+ if (o) return o;
99
+ if (n === document.body) break;
100
+ n = n.parentElement;
101
+ }
102
+ return null;
103
+ }
104
+ function D(e, t, n = j) {
105
+ const o = window.innerWidth, c = window.innerHeight, a = {
106
+ top: e.top,
107
+ bottom: c - e.bottom,
108
+ left: e.left,
109
+ right: o - e.right
110
+ };
111
+ if (a.bottom >= n)
112
+ return "bottom";
113
+ if (t) {
114
+ const s = e.left + e.width / 2, r = e.top + e.height / 2, i = [], l = e.bottom + t.height + m <= c && s - t.width / 2 >= m && s + t.width / 2 <= o - m;
115
+ i.push(["bottom", a.bottom, l]);
116
+ const u = e.top - t.height - m >= 0 && s - t.width / 2 >= m && s + t.width / 2 <= o - m;
117
+ i.push(["top", a.top, u]);
118
+ const p = e.right + t.width + m <= o && r - t.height / 2 >= m && r + t.height / 2 <= c - m;
119
+ i.push(["right", a.right, p]);
120
+ const d = e.left - t.width - m >= 0 && r - t.height / 2 >= m && r + t.height / 2 <= c - m;
121
+ i.push(["left", a.left, d]);
122
+ const h = i.filter(([g, v, x]) => x);
123
+ if (h.length > 0)
124
+ return h.reduce(
125
+ (g, v) => v[1] > g[1] ? v : g
126
+ )[0];
127
+ }
128
+ return Object.entries(a).reduce(
129
+ (s, r) => r[1] > s[1] ? r : s
130
+ )[0];
131
+ }
132
+ function O(e, t, n) {
133
+ let o = null;
134
+ const c = () => new Promise((i) => {
135
+ requestAnimationFrame(() => {
136
+ const l = e.getBoundingClientRect(), u = { width: l.width, height: l.height }, p = n || D(t.getBoundingClientRect(), u);
137
+ i(p);
138
+ });
139
+ }), a = async () => {
140
+ r();
141
+ const i = await c();
142
+ e.dataset.placement = i, e.matches(":popover-open") || e.showPopover();
143
+ }, s = (i) => {
144
+ o && (clearTimeout(o), o = null), i ? o = setTimeout(() => {
145
+ e.matches(":popover-open") && e.hidePopover(), o = null;
146
+ }, 100) : e.matches(":popover-open") && e.hidePopover();
147
+ }, r = () => {
148
+ o && (clearTimeout(o), o = null);
149
+ };
150
+ return { showTooltip: a, hideTooltip: s, cancelHide: r, cleanup: () => clearTimeout(o ?? void 0) };
151
+ }
152
+ function G({
153
+ id: e,
154
+ tooltipRef: t,
155
+ placement: n,
156
+ type: o
157
+ }) {
158
+ const c = b(null), a = b(null);
159
+ y(() => {
160
+ const s = t.current;
161
+ if (!s || !e)
162
+ return;
163
+ const r = q(s, e);
164
+ if (r)
165
+ return a.current = r, c.current = O(s, r, n), () => {
166
+ var i;
167
+ (i = c.current) == null || i.cleanup(), c.current = null;
168
+ };
169
+ }, [e, n, t]), y(() => {
170
+ if (o !== "hover" || !c.current || !a.current) return;
171
+ const s = a.current, r = c.current, i = t.current;
172
+ if (!i) return;
173
+ const l = () => {
174
+ r.showTooltip();
175
+ }, u = () => {
176
+ r.hideTooltip(!0);
177
+ }, p = () => {
178
+ r.cancelHide();
179
+ }, d = () => {
180
+ r.hideTooltip(!0);
181
+ };
182
+ return s.addEventListener("mouseenter", l), s.addEventListener("mouseleave", u), i.addEventListener("mouseenter", p), i.addEventListener("mouseleave", d), () => {
183
+ s.removeEventListener("mouseenter", l), s.removeEventListener("mouseleave", u), i.removeEventListener("mouseenter", p), i.removeEventListener("mouseleave", d);
184
+ };
185
+ }, [o, t]), y(() => {
186
+ if (o !== "persisted" || !c.current || !a.current) return;
187
+ const s = a.current, r = c.current, i = t.current;
188
+ if (!i) return;
189
+ const l = (d) => {
190
+ d.stopPropagation(), i.matches(":popover-open") ? r.hideTooltip(!1) : r.showTooltip();
191
+ }, u = (d) => {
192
+ const h = d.target;
193
+ i.matches(":popover-open") && !s.contains(h) && !i.contains(h) && r.hideTooltip(!1);
194
+ }, p = (d) => {
195
+ d.key === "Escape" && i.matches(":popover-open") && r.hideTooltip(!1);
196
+ };
197
+ return s.addEventListener("click", l), document.addEventListener("click", u), document.addEventListener("keydown", p), () => {
198
+ s.removeEventListener("click", l), document.removeEventListener("click", u), document.removeEventListener("keydown", p);
199
+ };
200
+ }, [o, t]);
201
+ }
202
+ const U = 8, I = E(
203
+ ({ id: e, children: t, placement: n, gap: o = U, type: c = "hover", style: a, className: s, ...r }, i) => {
204
+ const l = b(null), u = w({
205
+ placement: n
206
+ });
207
+ return G({
208
+ id: e,
209
+ placement: n,
210
+ tooltipRef: l,
211
+ type: c
212
+ }), /* @__PURE__ */ f(
213
+ "div",
214
+ {
215
+ ref: $(l, i),
216
+ id: e,
217
+ className: T(A.tooltip, s),
218
+ ...u,
219
+ style: {
220
+ "--_gap": `${o}px`,
221
+ positionAnchor: `--tooltip-${e}`,
222
+ ...a
223
+ },
224
+ ...r,
225
+ popover: "auto",
226
+ children: t
227
+ }
228
+ );
229
+ }
230
+ );
231
+ I.displayName = "Tooltip";
232
+ const N = E(
233
+ ({ children: e, maxWidth: t, maxLines: n = 2, style: o, className: c, ...a }, s) => {
234
+ const r = {
235
+ "--_lines": n,
236
+ "--_max-width": t,
237
+ ...o
238
+ };
239
+ return /* @__PURE__ */ f("div", { ref: s, className: T(A["tooltip-text"], c), style: r, ...a, children: e });
240
+ }
241
+ );
242
+ N.displayName = "Tooltip.Text";
243
+ function W(e) {
244
+ const { id: t, ...n } = e;
245
+ return {
246
+ "data-tooltip-trigger": t,
247
+ style: { anchorName: `--tooltip-${t}` },
248
+ ...Object.fromEntries(Object.entries(n).map(([o, c]) => [o, String(c)]))
249
+ };
250
+ }
251
+ function X(e) {
252
+ const { id: t } = e, n = document.getElementById(t);
253
+ n && n.matches(":popover-open") && requestAnimationFrame(() => {
254
+ const o = document.querySelector(`[data-tooltip-trigger="${t}"]`);
255
+ o && document.activeElement === o && o.blur(), n.matches(":popover-open") && n.hidePopover();
256
+ });
257
+ }
258
+ const P = I;
259
+ P.Text = N;
260
+ P.getTooltipTriggerProps = W;
261
+ P.close = X;
262
+ export {
263
+ M as B,
264
+ H,
265
+ L as I,
266
+ P as T,
267
+ $ as c
268
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@versaur/react",
3
- "version": "1.0.12",
3
+ "version": "1.0.13",
4
4
  "description": "React components for Versaur Design System",
5
5
  "repository": {
6
6
  "type": "git",
@@ -49,7 +49,7 @@
49
49
  "peerDependencies": {
50
50
  "react": "^18.0.0 || ^19.0.0",
51
51
  "react-dom": "^18.0.0 || ^19.0.0",
52
- "@versaur/core": "0.0.8",
52
+ "@versaur/core": "0.0.9",
53
53
  "@versaur/icons": "1.0.0"
54
54
  },
55
55
  "scripts": {
@@ -1,210 +0,0 @@
1
- import { jsx as u } from "react/jsx-runtime";
2
- import { iconStyles as _, hrStyles as j, buttonIconStyles as H, tooltipStyles as x } from "@versaur/core/primitive";
3
- import M, { forwardRef as b, useEffect as k, useRef as D } from "react";
4
- import { u as T } from "./use-data-attrs-iPFyfiKN.js";
5
- import { c as f } from "./cx-B9vmfsc1.js";
6
- import { LoaderIcon as F } from "@versaur/icons";
7
- const y = M.forwardRef(function({ intent: a = "inherit", size: n = "inherit", as: i, className: o, ...t }, e) {
8
- const r = T({ intent: a, size: n });
9
- return /* @__PURE__ */ u(i, { ref: e, className: f(_.icon, o), ...r, ...t });
10
- });
11
- y.displayName = "Icon";
12
- const O = b(
13
- ({ orientation: s, variant: a, size: n, spacing: i, className: o, ...t }, e) => {
14
- const r = T({
15
- orientation: s,
16
- size: n,
17
- spacing: i,
18
- variant: a
19
- });
20
- return /* @__PURE__ */ u(
21
- "hr",
22
- {
23
- ref: e,
24
- className: f(j.hr, o),
25
- role: "separator",
26
- "aria-orientation": s === "vertical" ? "vertical" : void 0,
27
- ...r,
28
- ...t
29
- }
30
- );
31
- }
32
- );
33
- O.displayName = "Hr";
34
- const U = b(
35
- ({
36
- as: s,
37
- variant: a = "primary",
38
- size: n = "medium",
39
- loading: i = !1,
40
- disabled: o = !1,
41
- pressed: t = !1,
42
- type: e = "button",
43
- onClick: r,
44
- iconProps: p = {},
45
- "aria-label": c,
46
- className: m,
47
- ...v
48
- }, h) => {
49
- const E = T({
50
- disabled: o || i,
51
- loading: i,
52
- size: n,
53
- variant: a
54
- }), L = (d) => {
55
- if (o || i) {
56
- d.preventDefault();
57
- return;
58
- }
59
- r == null || r(d);
60
- };
61
- return /* @__PURE__ */ u(
62
- "button",
63
- {
64
- ref: h,
65
- type: e,
66
- className: f(H["button-icon"], m),
67
- "aria-label": c,
68
- "aria-pressed": t ? "true" : void 0,
69
- "aria-busy": i ? "true" : void 0,
70
- "aria-disabled": o || i ? "true" : void 0,
71
- ...E,
72
- ...v,
73
- onClick: L,
74
- children: i ? /* @__PURE__ */ u(y, { as: F, "aria-label": "Loading", "data-loading-icon": "loader" }) : /* @__PURE__ */ u(y, { as: s, ...p })
75
- }
76
- );
77
- }
78
- );
79
- U.displayName = "ButtonIcon";
80
- function C({ id: s, tooltipRef: a, placement: n, gap: i, triggerType: o }) {
81
- k(() => {
82
- const t = a.current;
83
- if (!t || !s)
84
- return;
85
- let e = null;
86
- if (t.parentElement && (e = t.parentElement.querySelector(`[data-tooltip-trigger="${s}"]`)), !e) {
87
- let l = t.parentElement;
88
- for (; l && !e && (e = l.querySelector(`[data-tooltip-trigger="${s}"]`), !(e || l.classList.contains("sbdocs-story") || l.classList.contains("docblock-storylet"))); )
89
- l = l.parentElement;
90
- }
91
- if (e || (e = document.querySelector(`[data-tooltip-trigger="${s}"]`)), !e)
92
- return;
93
- let r = null;
94
- const p = () => {
95
- const l = e.getBoundingClientRect(), B = window.innerWidth, $ = window.innerHeight, q = 100, A = {
96
- top: l.top,
97
- bottom: $ - l.bottom,
98
- left: l.left,
99
- right: B - l.right
100
- };
101
- return A.bottom >= q ? "bottom" : Object.entries(A).reduce((I, N) => N[1] > I[1] ? N : I)[0];
102
- }, c = () => {
103
- r && (clearTimeout(r), r = null);
104
- const l = n || p();
105
- t.dataset.placement = l, t.matches(":popover-open") || t.showPopover();
106
- }, m = () => {
107
- r && clearTimeout(r), r = setTimeout(() => {
108
- t.matches(":popover-open") && t.hidePopover(), r = null;
109
- }, 100);
110
- }, v = () => {
111
- (o === "hover" || o === "all") && c();
112
- }, h = () => {
113
- (o === "hover" || o === "all") && m();
114
- }, E = () => {
115
- (o === "focus" || o === "all") && c();
116
- }, L = () => {
117
- o === "hover" && t.hidePopover();
118
- }, d = () => {
119
- o === "focus" && (t.matches(":popover-open") ? t.hidePopover() : c());
120
- }, S = () => {
121
- r && (clearTimeout(r), r = null);
122
- }, w = () => {
123
- (o === "hover" || o === "all") && m();
124
- };
125
- return e.addEventListener("mouseenter", v), e.addEventListener("mouseleave", h), e.addEventListener("focus", E), e.addEventListener("blur", L), e.addEventListener("click", d), t.addEventListener("mouseenter", S), t.addEventListener("mouseleave", w), () => {
126
- r && clearTimeout(r), e.removeEventListener("mouseenter", v), e.removeEventListener("mouseleave", h), e.removeEventListener("focus", E), e.removeEventListener("blur", L), e.removeEventListener("click", d), t.removeEventListener("mouseenter", S), t.removeEventListener("mouseleave", w);
127
- };
128
- }, [s, i, o]);
129
- }
130
- function G(...s) {
131
- return (a) => {
132
- s.forEach((n) => {
133
- if (typeof n == "function")
134
- n(a);
135
- else if (n && "current" in n)
136
- try {
137
- n.current = a;
138
- } catch {
139
- }
140
- });
141
- };
142
- }
143
- const W = 8, g = b(
144
- ({ id: s, children: a, placement: n, gap: i = W, triggerType: o = "all", style: t, className: e, ...r }, p) => {
145
- const c = D(null), m = T({
146
- placement: n
147
- });
148
- return C({
149
- gap: i,
150
- id: s,
151
- placement: n,
152
- tooltipRef: c,
153
- triggerType: o
154
- }), /* @__PURE__ */ u(
155
- "div",
156
- {
157
- ref: G(c, p),
158
- id: s,
159
- className: f(x.tooltip, e),
160
- ...m,
161
- style: {
162
- "--_gap": `${i}px`,
163
- positionAnchor: `--tooltip-${s}`,
164
- ...t
165
- },
166
- ...r,
167
- popover: "auto",
168
- children: a
169
- }
170
- );
171
- }
172
- );
173
- g.displayName = "Tooltip";
174
- const R = b(
175
- ({ children: s, maxWidth: a, maxLines: n = 2, style: i, className: o, ...t }, e) => {
176
- const r = {
177
- "--_lines": n,
178
- "--_max-width": a,
179
- ...i
180
- };
181
- return /* @__PURE__ */ u("div", { ref: e, className: f(x["tooltip-text"], o), style: r, ...t, children: s });
182
- }
183
- );
184
- R.displayName = "Tooltip.Text";
185
- function z(s) {
186
- const { id: a, triggerType: n = "all", ...i } = s, o = {
187
- "data-tooltip-trigger": a,
188
- style: { anchorName: `--tooltip-${a}` },
189
- ...Object.fromEntries(Object.entries(i).map(([t, e]) => [t, String(e)]))
190
- };
191
- return n !== "focus" && (o.popoverTarget = a), o;
192
- }
193
- function J(s) {
194
- const { id: a } = s, n = document.getElementById(a);
195
- n && n.matches(":popover-open") && requestAnimationFrame(() => {
196
- const i = document.querySelector(`[data-tooltip-trigger="${a}"]`);
197
- i && document.activeElement === i && i.blur(), n.matches(":popover-open") && n.hidePopover();
198
- });
199
- }
200
- const P = g;
201
- P.Text = R;
202
- P.getTooltipTriggerProps = z;
203
- P.close = J;
204
- export {
205
- U as B,
206
- O as H,
207
- y as I,
208
- P as T,
209
- G as c
210
- };