@versaur/react 1.0.12 → 1.0.14

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.
@@ -0,0 +1,129 @@
1
+ import { jsx as l } from "react/jsx-runtime";
2
+ import { iconStyles as T, buttonIconStyles as v } from "@versaur/core/primitive";
3
+ import { LoaderIcon as C } from "@versaur/icons";
4
+ import j, { forwardRef as B } from "react";
5
+ import { c as I } from "./cx-B9vmfsc1.js";
6
+ function E(e) {
7
+ return e.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
8
+ }
9
+ function A(e) {
10
+ const n = {};
11
+ for (const [o, t] of Object.entries(e)) {
12
+ if (t == null)
13
+ continue;
14
+ const r = E(o);
15
+ typeof t == "boolean" ? t && (n[`data-${r}`] = (!!t).toString()) : (typeof t == "string" || typeof t == "number") && (n[`data-${r}`] = String(t));
16
+ }
17
+ return n;
18
+ }
19
+ const p = j.forwardRef(function({ intent: n = "inherit", size: o = "inherit", as: t, className: r, ...d }, s) {
20
+ const a = A({ intent: n, size: o });
21
+ return /* @__PURE__ */ l(t, { ref: s, className: I(T.icon, r), ...a, ...d });
22
+ });
23
+ p.displayName = "Icon";
24
+ const N = B(
25
+ ({
26
+ as: e,
27
+ variant: n = "primary",
28
+ size: o = "medium",
29
+ loading: t = !1,
30
+ disabled: r = !1,
31
+ pressed: d = !1,
32
+ type: s = "button",
33
+ onClick: a,
34
+ iconProps: u = {},
35
+ "aria-label": b,
36
+ className: w,
37
+ ...h
38
+ }, y) => {
39
+ const c = A({
40
+ disabled: r || t,
41
+ loading: t,
42
+ size: o,
43
+ variant: n
44
+ }), f = (m) => {
45
+ if (r || t) {
46
+ m.preventDefault();
47
+ return;
48
+ }
49
+ a == null || a(m);
50
+ };
51
+ return /* @__PURE__ */ l(
52
+ "button",
53
+ {
54
+ ref: y,
55
+ type: s,
56
+ className: I(v["button-icon"], w),
57
+ "aria-label": b,
58
+ "aria-pressed": d ? "true" : void 0,
59
+ "aria-busy": t ? "true" : void 0,
60
+ "aria-disabled": r || t ? "true" : void 0,
61
+ ...c,
62
+ ...h,
63
+ onClick: f,
64
+ children: t ? /* @__PURE__ */ l(p, { as: C, "aria-label": "Loading", "data-loading-icon": "loader" }) : /* @__PURE__ */ l(p, { as: e, ...u })
65
+ }
66
+ );
67
+ }
68
+ );
69
+ N.displayName = "ButtonIcon";
70
+ const _ = 100, i = 16;
71
+ function F(e, n) {
72
+ let o = e.parentElement;
73
+ for (; o; ) {
74
+ const t = o.querySelector(`[data-tooltip-trigger="${n}"]`);
75
+ if (t) return t;
76
+ if (o === document.body) break;
77
+ o = o.parentElement;
78
+ }
79
+ return null;
80
+ }
81
+ function D(e, n, o = _, t) {
82
+ const r = window.innerWidth, d = window.innerHeight, s = {
83
+ top: e.top,
84
+ bottom: d - e.bottom,
85
+ left: e.left,
86
+ right: r - e.right
87
+ };
88
+ if (n) {
89
+ const a = e.left + e.width / 2, u = e.top + e.height / 2, b = [
90
+ // Bottom: check if tooltip fits below trigger
91
+ [
92
+ "bottom",
93
+ s.bottom,
94
+ e.bottom + n.height + i <= d && a - n.width / 2 >= i && a + n.width / 2 <= r - i
95
+ ],
96
+ // Top: check if tooltip fits above trigger
97
+ [
98
+ "top",
99
+ s.top,
100
+ e.top - n.height - i >= 0 && a - n.width / 2 >= i && a + n.width / 2 <= r - i
101
+ ],
102
+ // Right: check if tooltip fits to the right of trigger
103
+ [
104
+ "right",
105
+ s.right,
106
+ e.right + n.width + i <= r && u - n.height / 2 >= i && u + n.height / 2 <= d - i
107
+ ],
108
+ // Left: check if tooltip fits to the left of trigger
109
+ [
110
+ "left",
111
+ s.left,
112
+ e.left - n.width - i >= 0 && u - n.height / 2 >= i && u + n.height / 2 <= d - i
113
+ ]
114
+ ], h = (t ? b.filter(([c]) => t.includes(c)) : b).filter(([c, f, m]) => m);
115
+ return h.length > 0 ? h.find(([f]) => f === "bottom") ? "bottom" : h.reduce((f, m) => m[1] > f[1] ? m : f)[0] : (t ? Object.entries(s).filter(
116
+ ([c]) => t.includes(c)
117
+ ) : Object.entries(s)).reduce((c, f) => f[1] > c[1] ? f : c)[0];
118
+ }
119
+ return s.bottom >= o ? "bottom" : Object.entries(s).reduce(
120
+ (a, u) => u[1] > a[1] ? u : a
121
+ )[0];
122
+ }
123
+ export {
124
+ N as B,
125
+ p as I,
126
+ D as c,
127
+ F as f,
128
+ A as u
129
+ };
@@ -17,8 +17,8 @@ const c = t(
17
17
  );
18
18
  c.displayName = "OverlayFooter";
19
19
  export {
20
- v as O,
21
- c as a,
20
+ i as O,
21
+ v as a,
22
22
  d as b,
23
- i as c
23
+ c
24
24
  };
@@ -332,6 +332,7 @@ export declare interface HeadingProps extends HTMLAttributes<HTMLHeadingElement>
332
332
  weight?: Heading_2.Weight;
333
333
  /**
334
334
  * Text color intent
335
+ * @default 'default'
335
336
  */
336
337
  intent?: Heading_2.Intent;
337
338
  /**
@@ -498,6 +499,7 @@ export declare interface TextProps extends HTMLAttributes<HTMLElement> {
498
499
  weight?: Text_3.Weight;
499
500
  /**
500
501
  * Text color intent
502
+ * @default 'default'
501
503
  */
502
504
  intent?: Text_3.Intent;
503
505
  /**
@@ -528,10 +530,6 @@ declare interface TooltipGetTriggerPropsOptions {
528
530
  * Unique identifier matching the Tooltip's id
529
531
  */
530
532
  id: string;
531
- /**
532
- * Gap between tooltip and trigger in pixels
533
- */
534
- gap?: number;
535
533
  [key: string]: any;
536
534
  }
537
535
 
@@ -555,9 +553,11 @@ export declare interface TooltipProps extends HTMLAttributes<HTMLDivElement> {
555
553
  */
556
554
  gap?: number;
557
555
  /**
558
- * When to show tooltip: "focus", "hover", or "all"
556
+ * Tooltip interaction type:
557
+ * - "hover" (default): Show on hover, hide on hover away (100ms grace period)
558
+ * - "persisted": Show on click, persists until user clicks outside or presses Escape
559
559
  */
560
- triggerType?: "focus" | "hover" | "all";
560
+ type?: "hover" | "persisted";
561
561
  }
562
562
 
563
563
  /**
package/dist/primitive.js CHANGED
@@ -2,10 +2,9 @@ import { jsxs as x, jsx as c } from "react/jsx-runtime";
2
2
  import { buttonStyles as k, headingStyles as R, textStyles as w, avatarStyles as S, loaderStyles as K, badgeStyles as z, bannerStyles as A, dotStyles as C, kbdStyles as O } from "@versaur/core/primitive";
3
3
  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
- import { u as b } from "./use-data-attrs-iPFyfiKN.js";
5
+ import { u as b, I as B, B as F } from "./helpers-DTL6qrTe.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 { H as ot, T as nt } from "./tooltip-BMKVL6jz.js";
9
8
  const G = u(
10
9
  ({
11
10
  variant: a = "primary",
@@ -61,7 +60,7 @@ const G = u(
61
60
  );
62
61
  G.displayName = "Button";
63
62
  const J = u(
64
- ({ as: a = "h2", size: r, weight: t, intent: e, case: o, transform: s, children: n, className: l, ...d }, y) => {
63
+ ({ as: a = "h2", size: r, weight: t, intent: e = "default", case: o, transform: s, children: n, className: l, ...d }, y) => {
65
64
  const h = a, m = b({
66
65
  as: a,
67
66
  case: o,
@@ -75,7 +74,7 @@ const J = u(
75
74
  );
76
75
  J.displayName = "Heading";
77
76
  const M = u(
78
- ({ as: a = "p", size: r, weight: t, intent: e, case: o, transform: s, children: n, className: l, ...d }, y) => {
77
+ ({ as: a = "p", size: r, weight: t, intent: e = "default", case: o, transform: s, children: n, className: l, ...d }, y) => {
79
78
  const h = a, m = b({
80
79
  as: a,
81
80
  case: o,
@@ -112,7 +111,7 @@ const D = u(({ src: a, alt: r, onError: t, className: e, ...o }, s) => {
112
111
  );
113
112
  });
114
113
  D.displayName = "Avatar.Image";
115
- const st = Object.assign(L, {
114
+ const et = Object.assign(L, {
116
115
  Image: D
117
116
  }), P = u(
118
117
  ({ type: a = "spinner", size: r = "sm", children: t, className: e, ...o }, s) => {
@@ -191,17 +190,17 @@ const Z = u(
191
190
  );
192
191
  Z.displayName = "Kbd";
193
192
  export {
194
- st as Avatar,
193
+ et as Avatar,
195
194
  Q as Badge,
196
195
  V as Banner,
197
196
  G as Button,
198
197
  F as ButtonIcon,
199
198
  Y as Dot,
200
199
  J as Heading,
201
- nt as Hr,
200
+ ot as Hr,
202
201
  B as Icon,
203
202
  Z as Kbd,
204
203
  P as Loader,
205
204
  M as Text,
206
- lt as Tooltip
205
+ nt as Tooltip
207
206
  };
@@ -0,0 +1,170 @@
1
+ import { jsx as h } from "react/jsx-runtime";
2
+ import { hrStyles as k, tooltipStyles as L } from "@versaur/core/primitive";
3
+ import { forwardRef as f, useRef as v, useEffect as d } from "react";
4
+ import { u as y, f as x, c as A } from "./helpers-DTL6qrTe.js";
5
+ import { c as g } from "./cx-B9vmfsc1.js";
6
+ const N = f(
7
+ ({ orientation: e, variant: n, size: o, spacing: t, className: c, ...a }, s) => {
8
+ const r = y({
9
+ orientation: e,
10
+ size: o,
11
+ spacing: t,
12
+ variant: n
13
+ });
14
+ return /* @__PURE__ */ h(
15
+ "hr",
16
+ {
17
+ ref: s,
18
+ className: g(k.hr, c),
19
+ role: "separator",
20
+ "aria-orientation": e === "vertical" ? "vertical" : void 0,
21
+ ...r,
22
+ ...a
23
+ }
24
+ );
25
+ }
26
+ );
27
+ N.displayName = "Hr";
28
+ function R(...e) {
29
+ return (n) => {
30
+ e.forEach((o) => {
31
+ if (typeof o == "function")
32
+ o(n);
33
+ else if (o && "current" in o)
34
+ try {
35
+ o.current = n;
36
+ } catch {
37
+ }
38
+ });
39
+ };
40
+ }
41
+ function S(e, n, o) {
42
+ let t = null;
43
+ const c = () => new Promise((i) => {
44
+ e.matches(":popover-open") || e.showPopover(), requestAnimationFrame(() => {
45
+ const l = e.getBoundingClientRect(), u = { width: l.width, height: l.height }, m = o || A(n.getBoundingClientRect(), u);
46
+ i(m);
47
+ });
48
+ }), a = async () => {
49
+ r();
50
+ const i = await c();
51
+ e.dataset.placement = i;
52
+ }, s = (i) => {
53
+ t && (clearTimeout(t), t = null), i ? t = setTimeout(() => {
54
+ e.matches(":popover-open") && e.hidePopover(), t = null;
55
+ }, 100) : e.matches(":popover-open") && e.hidePopover();
56
+ }, r = () => {
57
+ t && (clearTimeout(t), t = null);
58
+ };
59
+ return { showTooltip: a, hideTooltip: s, cancelHide: r, cleanup: () => clearTimeout(t ?? void 0) };
60
+ }
61
+ function C({ id: e, tooltipRef: n, placement: o, type: t }) {
62
+ const c = v(null), a = v(null);
63
+ d(() => {
64
+ const s = n.current;
65
+ if (!s || !e)
66
+ return;
67
+ const r = x(s, e);
68
+ if (r)
69
+ return a.current = r, c.current = S(s, r, o), () => {
70
+ var i;
71
+ (i = c.current) == null || i.cleanup(), c.current = null;
72
+ };
73
+ }, [e, o, n]), d(() => {
74
+ if (t !== "hover" || !c.current || !a.current) return;
75
+ const s = a.current, r = c.current, i = n.current;
76
+ if (!i) return;
77
+ const l = () => {
78
+ r.showTooltip();
79
+ }, u = () => {
80
+ r.hideTooltip(!0);
81
+ }, m = () => {
82
+ r.cancelHide();
83
+ }, p = () => {
84
+ r.hideTooltip(!0);
85
+ };
86
+ return s.addEventListener("mouseenter", l), s.addEventListener("mouseleave", u), i.addEventListener("mouseenter", m), i.addEventListener("mouseleave", p), () => {
87
+ s.removeEventListener("mouseenter", l), s.removeEventListener("mouseleave", u), i.removeEventListener("mouseenter", m), i.removeEventListener("mouseleave", p);
88
+ };
89
+ }, [t, n]), d(() => {
90
+ if (t !== "persisted" || !c.current || !a.current) return;
91
+ const s = a.current, r = c.current, i = n.current;
92
+ if (!i) return;
93
+ const l = (p) => {
94
+ p.stopPropagation(), i.matches(":popover-open") ? r.hideTooltip(!1) : r.showTooltip();
95
+ }, u = (p) => {
96
+ const E = p.target;
97
+ i.matches(":popover-open") && !s.contains(E) && !i.contains(E) && r.hideTooltip(!1);
98
+ }, m = (p) => {
99
+ p.key === "Escape" && i.matches(":popover-open") && r.hideTooltip(!1);
100
+ };
101
+ return s.addEventListener("click", l), document.addEventListener("click", u), document.addEventListener("keydown", m), () => {
102
+ s.removeEventListener("click", l), document.removeEventListener("click", u), document.removeEventListener("keydown", m);
103
+ };
104
+ }, [t, n]);
105
+ }
106
+ const H = 8, P = f(
107
+ ({ id: e, children: n, placement: o, gap: t = H, type: c = "hover", style: a, className: s, ...r }, i) => {
108
+ const l = v(null), u = y({
109
+ placement: o
110
+ });
111
+ return C({
112
+ id: e,
113
+ placement: o,
114
+ tooltipRef: l,
115
+ type: c
116
+ }), /* @__PURE__ */ h(
117
+ "div",
118
+ {
119
+ ref: R(l, i),
120
+ id: e,
121
+ className: g(L.tooltip, s),
122
+ ...u,
123
+ style: {
124
+ "--_gap": `${t}px`,
125
+ positionAnchor: `--tooltip-${e}`,
126
+ ...a
127
+ },
128
+ ...r,
129
+ popover: "auto",
130
+ children: n
131
+ }
132
+ );
133
+ }
134
+ );
135
+ P.displayName = "Tooltip";
136
+ const w = f(
137
+ ({ children: e, maxWidth: n, maxLines: o = 2, style: t, className: c, ...a }, s) => {
138
+ const r = {
139
+ "--_lines": o,
140
+ "--_max-width": n,
141
+ ...t
142
+ };
143
+ return /* @__PURE__ */ h("div", { ref: s, className: g(L["tooltip-text"], c), style: r, ...a, children: e });
144
+ }
145
+ );
146
+ w.displayName = "Tooltip.Text";
147
+ function b(e) {
148
+ const { id: n, ...o } = e;
149
+ return {
150
+ "data-tooltip-trigger": n,
151
+ style: { anchorName: `--tooltip-${n}` },
152
+ ...Object.fromEntries(Object.entries(o).map(([t, c]) => [t, String(c)]))
153
+ };
154
+ }
155
+ function M(e) {
156
+ const { id: n } = e, o = document.getElementById(n);
157
+ o && o.matches(":popover-open") && requestAnimationFrame(() => {
158
+ const t = document.querySelector(`[data-tooltip-trigger="${n}"]`);
159
+ t && document.activeElement === t && t.blur(), o.matches(":popover-open") && o.hidePopover();
160
+ });
161
+ }
162
+ const T = P;
163
+ T.Text = w;
164
+ T.getTooltipTriggerProps = b;
165
+ T.close = M;
166
+ export {
167
+ N as H,
168
+ T,
169
+ R as c
170
+ };
package/dist/utils.d.ts CHANGED
@@ -4,6 +4,58 @@ import { HTMLAttributes } from 'react';
4
4
  import { ReactNode } from 'react';
5
5
  import { RefAttributes } from 'react';
6
6
 
7
+ /**
8
+ * Component that renders its children only when viewport is at desktop breakpoint
9
+ *
10
+ * @example
11
+ * ```tsx
12
+ * <DesktopBreakpoint>
13
+ * <DesktopSidebar />
14
+ * </DesktopBreakpoint>
15
+ * ```
16
+ */
17
+ export declare function DesktopBreakpoint({ children }: DesktopBreakpointProps): ReactNode;
18
+
19
+ export declare interface DesktopBreakpointProps {
20
+ /** Content to render when viewport is at desktop breakpoint (>= 1024px) */
21
+ children: ReactNode;
22
+ }
23
+
24
+ /**
25
+ * Component that renders its children only when viewport is at mobile breakpoint
26
+ *
27
+ * @example
28
+ * ```tsx
29
+ * <MobileBreakpoint>
30
+ * <MobileMenu />
31
+ * </MobileBreakpoint>
32
+ * ```
33
+ */
34
+ export declare function MobileBreakpoint({ children }: MobileBreakpointProps): ReactNode;
35
+
36
+ export declare interface MobileBreakpointProps {
37
+ /** Content to render when viewport is at mobile breakpoint (< 640px) */
38
+ children: ReactNode;
39
+ }
40
+
41
+ /**
42
+ * Component that renders its children only when viewport is mobile or tablet
43
+ * (exclusive: hides on desktop)
44
+ *
45
+ * @example
46
+ * ```tsx
47
+ * <MobileOrTabletBreakpoint>
48
+ * <CompactLayout />
49
+ * </MobileOrTabletBreakpoint>
50
+ * ```
51
+ */
52
+ export declare function MobileOrTabletBreakpoint({ children }: MobileOrTabletBreakpointProps): ReactNode;
53
+
54
+ export declare interface MobileOrTabletBreakpointProps {
55
+ /** Content to render when viewport is mobile or tablet (< 1024px) */
56
+ children: ReactNode;
57
+ }
58
+
7
59
  export declare const OverlayBody: ForwardRefExoticComponent<OverlayBodyProps & RefAttributes<HTMLDivElement>>;
8
60
 
9
61
  export declare interface OverlayBodyProps extends HTMLAttributes<HTMLDivElement> {
@@ -37,4 +89,39 @@ export declare interface OverlayTitleProps extends HTMLAttributes<HTMLHeadingEle
37
89
  as?: ElementType;
38
90
  }
39
91
 
92
+ /**
93
+ * Component that renders its children only when viewport is at tablet breakpoint
94
+ *
95
+ * @example
96
+ * ```tsx
97
+ * <TabletBreakpoint>
98
+ * <TabletLayout />
99
+ * </TabletBreakpoint>
100
+ * ```
101
+ */
102
+ export declare function TabletBreakpoint({ children }: TabletBreakpointProps): ReactNode;
103
+
104
+ export declare interface TabletBreakpointProps {
105
+ /** Content to render when viewport is at tablet breakpoint (< 1024px) */
106
+ children: ReactNode;
107
+ }
108
+
109
+ /**
110
+ * Component that renders its children only when viewport is tablet or desktop
111
+ * (exclusive: hides on mobile)
112
+ *
113
+ * @example
114
+ * ```tsx
115
+ * <TabletOrDesktopBreakpoint>
116
+ * <FullLayout />
117
+ * </TabletOrDesktopBreakpoint>
118
+ * ```
119
+ */
120
+ export declare function TabletOrDesktopBreakpoint({ children }: TabletOrDesktopBreakpointProps): ReactNode;
121
+
122
+ export declare interface TabletOrDesktopBreakpointProps {
123
+ /** Content to render when viewport is tablet or desktop (>= 640px) */
124
+ children: ReactNode;
125
+ }
126
+
40
127
  export { }
package/dist/utils.js CHANGED
@@ -1,7 +1,64 @@
1
- import { O as r, a as l, b as o, c as y } from "./overlay-parts-Zq9CuT31.js";
1
+ import { a as v, c as S, b as g, O as D } from "./overlay-parts-CFeD8VN0.js";
2
+ import { useState as l, useEffect as c } from "react";
3
+ import { getBreakpointPx as n } from "@versaur/core/utils";
4
+ function r(e) {
5
+ const [t, a] = l(!1);
6
+ return c(() => {
7
+ const o = window.matchMedia(e);
8
+ a(o.matches);
9
+ const i = (s) => {
10
+ a(s.matches);
11
+ };
12
+ return o.addEventListener("change", i), () => {
13
+ o.removeEventListener("change", i);
14
+ };
15
+ }, [e]), t;
16
+ }
17
+ function p() {
18
+ const e = n("mobile");
19
+ return r(`(max-width: ${parseInt(e) - 1}px)`);
20
+ }
21
+ function u() {
22
+ const e = n("mobile"), t = n("tablet");
23
+ return r(
24
+ `(min-width: ${parseInt(e)}px) and (max-width: ${parseInt(t) - 1}px)`
25
+ );
26
+ }
27
+ function b() {
28
+ const e = n("tablet");
29
+ return r(`(min-width: ${parseInt(e)}px)`);
30
+ }
31
+ function m() {
32
+ const e = n("tablet");
33
+ return r(`(max-width: ${parseInt(e) - 1}px)`);
34
+ }
35
+ function k() {
36
+ const e = n("mobile");
37
+ return r(`(min-width: ${parseInt(e)}px)`);
38
+ }
39
+ function h({ children: e }) {
40
+ return p() ? e : null;
41
+ }
42
+ function d({ children: e }) {
43
+ return u() ? e : null;
44
+ }
45
+ function x({ children: e }) {
46
+ return b() ? e : null;
47
+ }
48
+ function M({ children: e }) {
49
+ return m() ? e : null;
50
+ }
51
+ function O({ children: e }) {
52
+ return k() ? e : null;
53
+ }
2
54
  export {
3
- r as OverlayBody,
4
- l as OverlayFooter,
5
- o as OverlayHeader,
6
- y as OverlayTitle
55
+ x as DesktopBreakpoint,
56
+ h as MobileBreakpoint,
57
+ M as MobileOrTabletBreakpoint,
58
+ v as OverlayBody,
59
+ S as OverlayFooter,
60
+ g as OverlayHeader,
61
+ D as OverlayTitle,
62
+ d as TabletBreakpoint,
63
+ O as TabletOrDesktopBreakpoint
7
64
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@versaur/react",
3
- "version": "1.0.12",
3
+ "version": "1.0.14",
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.10",
53
53
  "@versaur/icons": "1.0.0"
54
54
  },
55
55
  "scripts": {