@pibit.ai/cure-design-system 0.6.12 → 0.6.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.
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +244 -235
- package/dist/patterns/click-away/click-away-listener.d.ts +8 -0
- package/dist/patterns/click-away/click-away-listener.d.ts.map +1 -0
- package/dist/patterns/click-away/click-away-listener.js +22 -0
- package/dist/patterns/click-away/index.d.ts +3 -0
- package/dist/patterns/click-away/index.d.ts.map +1 -0
- package/dist/patterns/click-away/overlay-click-guards.d.ts +23 -0
- package/dist/patterns/click-away/overlay-click-guards.d.ts.map +1 -0
- package/dist/patterns/click-away/overlay-click-guards.js +85 -0
- package/dist/patterns/drawer/drawer.d.ts +49 -0
- package/dist/patterns/drawer/drawer.d.ts.map +1 -0
- package/dist/patterns/drawer/drawer.js +158 -0
- package/dist/patterns/drawer/index.d.ts +2 -0
- package/dist/patterns/drawer/index.d.ts.map +1 -0
- package/dist/patterns/expandable-drawer/expandable-drawer.d.ts +36 -0
- package/dist/patterns/expandable-drawer/expandable-drawer.d.ts.map +1 -0
- package/dist/patterns/expandable-drawer/expandable-drawer.js +120 -0
- package/dist/patterns/expandable-drawer/index.d.ts +2 -0
- package/dist/patterns/expandable-drawer/index.d.ts.map +1 -0
- package/dist/styles/components.css +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
export interface ClickAwayListenerProps {
|
|
3
|
+
children: React.ReactNode;
|
|
4
|
+
onClickAway: (event: MouseEvent | TouchEvent) => void;
|
|
5
|
+
as?: React.ElementType;
|
|
6
|
+
}
|
|
7
|
+
export declare function ClickAwayListener({ children, onClickAway, as: Component }: ClickAwayListenerProps): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
//# sourceMappingURL=click-away-listener.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"click-away-listener.d.ts","sourceRoot":"","sources":["../../../src/patterns/click-away/click-away-listener.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4B,MAAM,OAAO,CAAC;AAGjD,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,WAAW,EAAE,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,KAAK,IAAI,CAAC;IACtD,EAAE,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC;CACxB;AAED,wBAAgB,iBAAiB,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,EAAE,EAAE,SAAiB,EAAE,EAAE,sBAAsB,2CAgCzG"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { jsx as E } from "react/jsx-runtime";
|
|
2
|
+
import { useRef as L, useEffect as g } from "react";
|
|
3
|
+
import { shouldIgnorePortaledOverlayClickFromRoot as X } from "./overlay-click-guards.js";
|
|
4
|
+
function x({ children: f, onClickAway: c, as: h = "div" }) {
|
|
5
|
+
const e = L(null);
|
|
6
|
+
return g(() => {
|
|
7
|
+
let i = 0;
|
|
8
|
+
const r = (t) => {
|
|
9
|
+
var u, a, l, d, m;
|
|
10
|
+
if (t.type === "touchstart") i = Date.now();
|
|
11
|
+
else if (Date.now() - i < 1e3) return;
|
|
12
|
+
const s = t.target, o = s, p = "clientX" in t ? t.clientX : ((a = (u = t.touches) == null ? void 0 : u[0]) == null ? void 0 : a.clientX) ?? 0, w = "clientY" in t ? t.clientY : ((d = (l = t.touches) == null ? void 0 : l[0]) == null ? void 0 : d.clientY) ?? 0;
|
|
13
|
+
e.current && (e.current.contains(s) || X(o, e.current, { clientX: p, clientY: w }) || (m = o.closest) != null && m.call(o, "[data-ignore-click-away]") || c(t));
|
|
14
|
+
}, n = { capture: !0 };
|
|
15
|
+
return document.addEventListener("mousedown", r, n), document.addEventListener("touchstart", r, n), () => {
|
|
16
|
+
document.removeEventListener("mousedown", r, n), document.removeEventListener("touchstart", r, n);
|
|
17
|
+
};
|
|
18
|
+
}, [c]), /* @__PURE__ */ E(h, { ref: e, children: f });
|
|
19
|
+
}
|
|
20
|
+
export {
|
|
21
|
+
x as ClickAwayListener
|
|
22
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/patterns/click-away/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,KAAK,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AACvF,OAAO,EAAE,wCAAwC,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** Don't fire when the click lands on a React Aria overlay underlay (the transparent full-screen div rendered
|
|
2
|
+
* behind modal popovers — Select, SearchableSelect, DatePicker). That click only dismisses the open popup. */
|
|
3
|
+
export declare function isClickOnOverlayUnderlay(target: Element): boolean;
|
|
4
|
+
/** Don't fire while a modal React Aria popup owns the page. While open, ariaHideOutside marks everything
|
|
5
|
+
* outside the popup `inert` (including the underlay), so outside clicks hit-test through to <body>/<html>.
|
|
6
|
+
* Such a click can only be dismissing the popup — it is never a genuine click-away. */
|
|
7
|
+
export declare function isDismissClickThroughInertPage(target: Node): boolean;
|
|
8
|
+
/** React Aria popover root. The class name is generated, so match the prefix. */
|
|
9
|
+
export declare const REACT_ARIA_POPOVER_SELECTOR = "[class*=\"react-aria-Popover\"]";
|
|
10
|
+
/** Don't fire when target is inside an overlay opened from a trigger in root (aria-controls → overlay id). */
|
|
11
|
+
export declare function isClickInsideOverlayOwnedByRoot(target: Element, root: HTMLElement): boolean;
|
|
12
|
+
/** Don't fire when click coordinates fall inside an overlay owned by root (handles scrollbar clicks where target is wrong). */
|
|
13
|
+
export declare function isClickPositionInsideOverlayOwnedByRoot(clientX: number, clientY: number, root: HTMLElement): boolean;
|
|
14
|
+
/** Don't fire when target is inside a dialog owned by root (e.g. date picker popover uses aria-labelledby with trigger id). */
|
|
15
|
+
export declare function isClickInsideDialogOwnedByRoot(target: Element, root: HTMLElement): boolean;
|
|
16
|
+
/** Don't fire when target is inside a tooltip whose trigger is inside root (e.g. React Aria tooltips rendered in a portal). */
|
|
17
|
+
export declare function isClickInsideTooltipOwnedByRoot(target: Element, root: HTMLElement): boolean;
|
|
18
|
+
/** Portaled React Aria overlays/dropdowns whose triggers live inside `root`. */
|
|
19
|
+
export declare function shouldIgnorePortaledOverlayClickFromRoot(target: EventTarget | null, root: HTMLElement | null, coords?: {
|
|
20
|
+
clientX: number;
|
|
21
|
+
clientY: number;
|
|
22
|
+
}): boolean;
|
|
23
|
+
//# sourceMappingURL=overlay-click-guards.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overlay-click-guards.d.ts","sourceRoot":"","sources":["../../../src/patterns/click-away/overlay-click-guards.ts"],"names":[],"mappings":"AAAA;8GAC8G;AAC9G,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAEjE;AAED;;uFAEuF;AACvF,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,IAAI,GAAG,OAAO,CAGpE;AAMD,iFAAiF;AACjF,eAAO,MAAM,2BAA2B,oCAAkC,CAAC;AAY3E,8GAA8G;AAC9G,wBAAgB,+BAA+B,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAW3F;AAED,+HAA+H;AAC/H,wBAAgB,uCAAuC,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAcpH;AAED,+HAA+H;AAC/H,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAW1F;AAED,+HAA+H;AAC/H,wBAAgB,+BAA+B,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAoB3F;AAED,gFAAgF;AAChF,wBAAgB,wCAAwC,CACtD,MAAM,EAAE,WAAW,GAAG,IAAI,EAC1B,IAAI,EAAE,WAAW,GAAG,IAAI,EACxB,MAAM,CAAC,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC5C,OAAO,CAST"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
function O(e) {
|
|
2
|
+
var n;
|
|
3
|
+
return !!((n = e.closest) != null && n.call(e, '[data-testid="underlay"]'));
|
|
4
|
+
}
|
|
5
|
+
function E(e) {
|
|
6
|
+
return e !== document.body && e !== document.documentElement ? !1 : !!document.querySelector('[data-testid="underlay"], [inert]');
|
|
7
|
+
}
|
|
8
|
+
const p = (e) => typeof CSS < "u" && typeof CSS.escape == "function" ? CSS.escape(e) : e.replace(/["\\]/g, "\\$&"), C = '[class*="react-aria-Popover"]', S = `[data-trigger], ${C}`;
|
|
9
|
+
function y(e) {
|
|
10
|
+
return e.closest(S) ?? e;
|
|
11
|
+
}
|
|
12
|
+
function b(e, n) {
|
|
13
|
+
var i, u, l;
|
|
14
|
+
const t = (i = n.querySelectorAll) == null ? void 0 : i.call(n, "[aria-controls]");
|
|
15
|
+
if (!(t != null && t.length)) return !1;
|
|
16
|
+
for (const c of t) {
|
|
17
|
+
const s = (u = c.getAttribute) == null ? void 0 : u.call(c, "aria-controls");
|
|
18
|
+
if (!s) continue;
|
|
19
|
+
const o = (l = document.getElementById) == null ? void 0 : l.call(document, s);
|
|
20
|
+
if (o && y(o).contains(e))
|
|
21
|
+
return !0;
|
|
22
|
+
}
|
|
23
|
+
return !1;
|
|
24
|
+
}
|
|
25
|
+
function R(e, n, t) {
|
|
26
|
+
var u, l, c;
|
|
27
|
+
const i = (u = t.querySelectorAll) == null ? void 0 : u.call(t, "[aria-controls]");
|
|
28
|
+
if (!(i != null && i.length)) return !1;
|
|
29
|
+
for (const s of i) {
|
|
30
|
+
const o = (l = s.getAttribute) == null ? void 0 : l.call(s, "aria-controls");
|
|
31
|
+
if (!o) continue;
|
|
32
|
+
const f = (c = document.getElementById) == null ? void 0 : c.call(document, o);
|
|
33
|
+
if (!f) continue;
|
|
34
|
+
const r = y(f).getBoundingClientRect();
|
|
35
|
+
if (e >= r.left && e <= r.right && n >= r.top && n <= r.bottom)
|
|
36
|
+
return !0;
|
|
37
|
+
}
|
|
38
|
+
return !1;
|
|
39
|
+
}
|
|
40
|
+
function A(e, n) {
|
|
41
|
+
var l, c, s;
|
|
42
|
+
const t = (l = e.closest) == null ? void 0 : l.call(e, '[role="dialog"]');
|
|
43
|
+
if (!t) return !1;
|
|
44
|
+
const i = (c = t.getAttribute) == null ? void 0 : c.call(t, "aria-labelledby");
|
|
45
|
+
if (!i) return !1;
|
|
46
|
+
const u = i.trim().split(/\s+/);
|
|
47
|
+
for (const o of u) {
|
|
48
|
+
const f = (s = document.getElementById) == null ? void 0 : s.call(document, o);
|
|
49
|
+
if (f && n.contains(f)) return !0;
|
|
50
|
+
}
|
|
51
|
+
return !1;
|
|
52
|
+
}
|
|
53
|
+
function I(e, n) {
|
|
54
|
+
var u, l, c, s, o, f;
|
|
55
|
+
const t = (u = e.closest) == null ? void 0 : u.call(e, '[role="tooltip"]');
|
|
56
|
+
if (t) {
|
|
57
|
+
const r = t.id;
|
|
58
|
+
if (r && ((l = n.querySelector) == null ? void 0 : l.call(n, `[aria-describedby*="${p(r)}"]`)))
|
|
59
|
+
return !0;
|
|
60
|
+
}
|
|
61
|
+
const i = (c = n.querySelectorAll) == null ? void 0 : c.call(n, "[aria-describedby]");
|
|
62
|
+
if (!(i != null && i.length)) return !1;
|
|
63
|
+
for (const r of i) {
|
|
64
|
+
const d = (o = (s = r.getAttribute) == null ? void 0 : s.call(r, "aria-describedby")) == null ? void 0 : o.trim().split(/\s+/);
|
|
65
|
+
if (d)
|
|
66
|
+
for (const m of d) {
|
|
67
|
+
const a = (f = document.getElementById) == null ? void 0 : f.call(document, m);
|
|
68
|
+
if (a != null && a.contains(e)) return !0;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return !1;
|
|
72
|
+
}
|
|
73
|
+
function B(e, n, t) {
|
|
74
|
+
return !(e instanceof Element) || !n ? !1 : !!(O(e) || E(e) || b(e, n) || t && R(t.clientX, t.clientY, n) || A(e, n) || I(e, n));
|
|
75
|
+
}
|
|
76
|
+
export {
|
|
77
|
+
C as REACT_ARIA_POPOVER_SELECTOR,
|
|
78
|
+
A as isClickInsideDialogOwnedByRoot,
|
|
79
|
+
b as isClickInsideOverlayOwnedByRoot,
|
|
80
|
+
I as isClickInsideTooltipOwnedByRoot,
|
|
81
|
+
O as isClickOnOverlayUnderlay,
|
|
82
|
+
R as isClickPositionInsideOverlayOwnedByRoot,
|
|
83
|
+
E as isDismissClickThroughInertPage,
|
|
84
|
+
B as shouldIgnorePortaledOverlayClickFromRoot
|
|
85
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
export interface DrawerProps {
|
|
3
|
+
isOpen: boolean;
|
|
4
|
+
onClose: () => void;
|
|
5
|
+
title: string;
|
|
6
|
+
subtitle?: string;
|
|
7
|
+
children: React.ReactNode;
|
|
8
|
+
width?: string;
|
|
9
|
+
footer?: React.ReactNode;
|
|
10
|
+
showDefaultFooter?: boolean;
|
|
11
|
+
className?: string;
|
|
12
|
+
headerClassName?: string;
|
|
13
|
+
header?: React.ReactNode;
|
|
14
|
+
/** Has no effect: the panel is always the full viewport height. Kept so existing callers still type-check. */
|
|
15
|
+
height?: string;
|
|
16
|
+
side?: "left" | "right";
|
|
17
|
+
style?: React.CSSProperties;
|
|
18
|
+
leftOffset?: number;
|
|
19
|
+
bodyClassName?: string;
|
|
20
|
+
onClickOutside?: () => void;
|
|
21
|
+
showBackDrop?: boolean;
|
|
22
|
+
footerClassName?: string;
|
|
23
|
+
/** When provided, enables expand/collapse and shows the expand button in the header. */
|
|
24
|
+
expanded?: boolean;
|
|
25
|
+
/** Callback when expand state changes. Required when using expanded. */
|
|
26
|
+
onExpandedChange?: (expanded: boolean) => void;
|
|
27
|
+
/** Max width when expanded (e.g. "90vw"). Used when expanded is true. */
|
|
28
|
+
maxWidth?: string;
|
|
29
|
+
/** Controlled width in pixels. When set with onResizableWidthChange, enables drag resize. */
|
|
30
|
+
resizableWidth?: number;
|
|
31
|
+
/** Minimum width while dragging. Default 476. */
|
|
32
|
+
minResizableWidth?: number;
|
|
33
|
+
/** Maximum width while dragging. */
|
|
34
|
+
maxResizableWidth?: number;
|
|
35
|
+
/** Called while the user drags the drawer resize handle. */
|
|
36
|
+
onResizableWidthChange?: (width: number) => void;
|
|
37
|
+
/** Extra actions rendered in the default header before expand/close controls. */
|
|
38
|
+
headerActions?: React.ReactNode;
|
|
39
|
+
/**
|
|
40
|
+
* Opens the lossrun-style fullscreen workbook modal (does not resize the drawer).
|
|
41
|
+
* Independent of `expanded` / `onExpandedChange`.
|
|
42
|
+
*/
|
|
43
|
+
fullscreenOpen?: boolean;
|
|
44
|
+
onFullscreenOpenChange?: (open: boolean) => void;
|
|
45
|
+
/** Test id placed on the dialog panel. */
|
|
46
|
+
"data-testid"?: string;
|
|
47
|
+
}
|
|
48
|
+
export declare const Drawer: React.FC<DrawerProps>;
|
|
49
|
+
//# sourceMappingURL=drawer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drawer.d.ts","sourceRoot":"","sources":["../../../src/patterns/drawer/drawer.tsx"],"names":[],"mappings":"AACA,OAAO,KAAmC,MAAM,OAAO,CAAC;AAWxD,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,8GAA8G;IAC9G,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACxB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,wFAAwF;IACxF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,wEAAwE;IACxE,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IAC/C,yEAAyE;IACzE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6FAA6F;IAC7F,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iDAAiD;IACjD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,oCAAoC;IACpC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,4DAA4D;IAC5D,sBAAsB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,iFAAiF;IACjF,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAChC;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,sBAAsB,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACjD,0CAA0C;IAC1C,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,eAAO,MAAM,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CAuPxC,CAAC"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { jsxs as l, Fragment as lt, jsx as r } from "react/jsx-runtime";
|
|
2
|
+
import { Minimize01 as P, Expand01 as j, X as it } from "@untitledui/icons";
|
|
3
|
+
import { useId as ct, useRef as nt, useEffect as dt } from "react";
|
|
4
|
+
import { ClickAwayListener as ut } from "../click-away/click-away-listener.js";
|
|
5
|
+
const xt = ({
|
|
6
|
+
isOpen: s,
|
|
7
|
+
onClose: k,
|
|
8
|
+
title: v,
|
|
9
|
+
subtitle: $,
|
|
10
|
+
children: L,
|
|
11
|
+
width: X = "max-w-lg",
|
|
12
|
+
footer: q,
|
|
13
|
+
showDefaultFooter: E = !1,
|
|
14
|
+
className: A = "",
|
|
15
|
+
side: n = "right",
|
|
16
|
+
style: _,
|
|
17
|
+
leftOffset: h = 0,
|
|
18
|
+
headerClassName: K = "",
|
|
19
|
+
bodyClassName: T = "",
|
|
20
|
+
header: d = null,
|
|
21
|
+
onClickOutside: U,
|
|
22
|
+
showBackDrop: B = !1,
|
|
23
|
+
footerClassName: V = "",
|
|
24
|
+
expanded: i = !1,
|
|
25
|
+
onExpandedChange: u,
|
|
26
|
+
maxWidth: I = "90vw",
|
|
27
|
+
resizableWidth: e,
|
|
28
|
+
minResizableWidth: p = 476,
|
|
29
|
+
maxResizableWidth: Y,
|
|
30
|
+
onResizableWidthChange: o,
|
|
31
|
+
headerActions: G,
|
|
32
|
+
fullscreenOpen: x = !1,
|
|
33
|
+
onFullscreenOpenChange: m,
|
|
34
|
+
"data-testid": H
|
|
35
|
+
}) => {
|
|
36
|
+
const f = u !== void 0, J = m !== void 0, y = e !== void 0 && o !== void 0, b = Math.max(Y ?? Number.POSITIVE_INFINITY, p), w = s && y, N = (t) => Math.min(Math.max(t, p), b), S = ct(), c = nt(null);
|
|
37
|
+
dt(() => () => {
|
|
38
|
+
var t;
|
|
39
|
+
return (t = c.current) == null ? void 0 : t.call(c);
|
|
40
|
+
}, []);
|
|
41
|
+
const Q = (t) => {
|
|
42
|
+
if (!w || e === void 0) return;
|
|
43
|
+
t.preventDefault(), t.stopPropagation();
|
|
44
|
+
const a = t.clientX, et = e, ot = document.body.style.cursor, st = document.body.style.userSelect;
|
|
45
|
+
document.body.style.cursor = "col-resize", document.body.style.userSelect = "none";
|
|
46
|
+
const M = (at) => {
|
|
47
|
+
o == null || o(N(et + a - at.clientX));
|
|
48
|
+
}, g = () => {
|
|
49
|
+
document.body.style.cursor = ot, document.body.style.userSelect = st, window.removeEventListener("pointermove", M), window.removeEventListener("pointerup", g), c.current = null;
|
|
50
|
+
};
|
|
51
|
+
c.current = g, window.addEventListener("pointermove", M), window.addEventListener("pointerup", g);
|
|
52
|
+
}, Z = (t) => {
|
|
53
|
+
if (!w || e === void 0) return;
|
|
54
|
+
const a = t.shiftKey ? 50 : 16;
|
|
55
|
+
t.key === "ArrowLeft" && (t.preventDefault(), o == null || o(N(e + a))), t.key === "ArrowRight" && (t.preventDefault(), o == null || o(N(e - a)));
|
|
56
|
+
}, F = n === "left" ? s ? "left-4" : "left-0" : s ? "right-[6px]" : "right-0", D = n === "left" && h > 0, z = (() => {
|
|
57
|
+
const t = { ..._ };
|
|
58
|
+
if (D) {
|
|
59
|
+
const a = s ? `${h}px` : "calc(-100%)";
|
|
60
|
+
t.transform = `translateX(${a})`;
|
|
61
|
+
}
|
|
62
|
+
return y && e !== void 0 ? (t.width = e, t.maxWidth = e) : f && (t.width = i ? I : "32rem", t.maxWidth = i ? I : "32rem"), t;
|
|
63
|
+
})(), C = D ? "" : n === "left" ? s ? "translate-x-0" : "-translate-x-full" : s ? "translate-x-0" : "translate-x-full", R = `
|
|
64
|
+
${F}
|
|
65
|
+
fixed h-[calc(100vh-12px)] my-[6px] bottom-0
|
|
66
|
+
${y || f ? "" : `w-full ${X}`}
|
|
67
|
+
transform transition-transform duration-300 ease-in-out z-[100]
|
|
68
|
+
${y ? "" : "transition-[width] duration-300 ease-in-out"}
|
|
69
|
+
${C} ${A}`, O = {
|
|
70
|
+
backgroundImage: "linear-gradient(90deg, rgba(6, 132, 240, 0.1) 0%, rgba(6, 132, 240, 0.1) 100%), linear-gradient(0deg, rgba(255, 255, 255, 0) 60.66%, rgba(255, 255, 255, 0.5) 100%), linear-gradient(90deg, rgba(255, 255, 255, 0.3) 0%, rgba(255, 255, 255, 0.3) 100%)"
|
|
71
|
+
}, W = `flex items-center justify-between pl-6 pr-2 border-b border-secondary gap-2 py-4 ${K} h-[60px]`, tt = `px-5 pb-3 overflow-y-auto flex-grow ${T}`, rt = `p-4 ${V}`;
|
|
72
|
+
return /* @__PURE__ */ l(lt, { children: [
|
|
73
|
+
s && B && /* @__PURE__ */ r("div", { className: "fixed inset-0 z-[99] bg-black/40", onClick: U, "aria-hidden": "true" }),
|
|
74
|
+
/* @__PURE__ */ r("div", { className: s ? "w-[100vw-64px] h-[100vh] fixed inset-0 z-[9999]" : "hidden", children: /* @__PURE__ */ r(ut, { onClickAway: k, as: "div", children: /* @__PURE__ */ r(
|
|
75
|
+
"div",
|
|
76
|
+
{
|
|
77
|
+
className: R,
|
|
78
|
+
style: z,
|
|
79
|
+
role: "dialog",
|
|
80
|
+
"aria-modal": "true",
|
|
81
|
+
"aria-labelledby": d ? void 0 : S,
|
|
82
|
+
"aria-label": d && v ? v : void 0,
|
|
83
|
+
"data-testid": H,
|
|
84
|
+
onClick: (t) => t.stopPropagation(),
|
|
85
|
+
children: /* @__PURE__ */ l(
|
|
86
|
+
"div",
|
|
87
|
+
{
|
|
88
|
+
className: `relative h-full w-full backdrop-blur-[3px] rounded-2xl p-2 ${n === "right" ? "border-l border-t border-b border-white" : "border border-white"}`,
|
|
89
|
+
style: O,
|
|
90
|
+
children: [
|
|
91
|
+
w && /* @__PURE__ */ r(
|
|
92
|
+
"div",
|
|
93
|
+
{
|
|
94
|
+
role: "separator",
|
|
95
|
+
"aria-label": "Resize drawer",
|
|
96
|
+
"aria-orientation": "vertical",
|
|
97
|
+
"aria-valuemin": p,
|
|
98
|
+
"aria-valuemax": Number.isFinite(b) ? b : void 0,
|
|
99
|
+
"aria-valuenow": Math.round(e),
|
|
100
|
+
tabIndex: 0,
|
|
101
|
+
onPointerDown: Q,
|
|
102
|
+
onKeyDown: Z,
|
|
103
|
+
className: "absolute left-0 top-0 z-10 h-full w-2 -translate-x-1 cursor-col-resize touch-none focus-visible:outline-none"
|
|
104
|
+
}
|
|
105
|
+
),
|
|
106
|
+
/* @__PURE__ */ l("div", { className: "h-full w-full bg-white rounded-lg overflow-hidden flex flex-col", children: [
|
|
107
|
+
d || /* @__PURE__ */ l("header", { className: W, children: [
|
|
108
|
+
/* @__PURE__ */ l("div", { className: `flex-1 flex flex-col gap-0 ${f ? "pr-2" : "pr-16"}`, children: [
|
|
109
|
+
/* @__PURE__ */ r("h2", { id: S, className: "text-lg font-semibold leading-7 text-[#06060a]", children: v }),
|
|
110
|
+
$ && /* @__PURE__ */ r("p", { className: "text-sm text-secondary", children: $ })
|
|
111
|
+
] }),
|
|
112
|
+
/* @__PURE__ */ l("div", { className: "flex items-center gap-1", children: [
|
|
113
|
+
G,
|
|
114
|
+
J && /* @__PURE__ */ r(
|
|
115
|
+
"button",
|
|
116
|
+
{
|
|
117
|
+
type: "button",
|
|
118
|
+
onClick: () => m == null ? void 0 : m(!x),
|
|
119
|
+
className: "flex items-center justify-center p-2 rounded-lg hover:bg-primary_hover transition-colors cursor-pointer",
|
|
120
|
+
"aria-label": x ? "Exit full screen" : "Open full screen",
|
|
121
|
+
children: x ? /* @__PURE__ */ r(P, { size: 20, className: "text-fg-quaternary", strokeWidth: 1.67 }) : /* @__PURE__ */ r(j, { size: 20, className: "text-fg-quaternary", strokeWidth: 1.67 })
|
|
122
|
+
}
|
|
123
|
+
),
|
|
124
|
+
f && /* @__PURE__ */ r(
|
|
125
|
+
"button",
|
|
126
|
+
{
|
|
127
|
+
type: "button",
|
|
128
|
+
onClick: () => u == null ? void 0 : u(!i),
|
|
129
|
+
className: "flex items-center justify-center p-2 rounded-lg hover:bg-primary_hover transition-colors cursor-pointer",
|
|
130
|
+
"aria-label": i ? "Collapse sidebar" : "Expand sidebar",
|
|
131
|
+
children: i ? /* @__PURE__ */ r(P, { size: 20, className: "text-fg-quaternary", strokeWidth: 1.67 }) : /* @__PURE__ */ r(j, { size: 20, className: "text-fg-quaternary", strokeWidth: 1.67 })
|
|
132
|
+
}
|
|
133
|
+
),
|
|
134
|
+
/* @__PURE__ */ r(
|
|
135
|
+
"button",
|
|
136
|
+
{
|
|
137
|
+
type: "button",
|
|
138
|
+
onClick: k,
|
|
139
|
+
"aria-label": "Close",
|
|
140
|
+
className: "flex items-center justify-center p-2 rounded-lg hover:bg-primary_hover transition-colors cursor-pointer",
|
|
141
|
+
children: /* @__PURE__ */ r(it, { size: 20, className: "text-fg-quaternary", strokeWidth: 1.67 })
|
|
142
|
+
}
|
|
143
|
+
)
|
|
144
|
+
] })
|
|
145
|
+
] }),
|
|
146
|
+
/* @__PURE__ */ r("main", { className: tt, children: L }),
|
|
147
|
+
E && /* @__PURE__ */ r("footer", { className: rt, children: q })
|
|
148
|
+
] })
|
|
149
|
+
]
|
|
150
|
+
}
|
|
151
|
+
)
|
|
152
|
+
}
|
|
153
|
+
) }) })
|
|
154
|
+
] });
|
|
155
|
+
};
|
|
156
|
+
export {
|
|
157
|
+
xt as Drawer
|
|
158
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/patterns/drawer/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,WAAW,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
export type ExpandableRightDrawerState = "hidden" | "normal" | "expanded";
|
|
3
|
+
export interface ExpandableRightDrawerProps {
|
|
4
|
+
/** Current state: hidden (no space), normal (sidebar width), expanded (wide). */
|
|
5
|
+
state: ExpandableRightDrawerState;
|
|
6
|
+
onClose: () => void;
|
|
7
|
+
/** Optional custom header. When not provided, default header with title/subtitle and actions is used. */
|
|
8
|
+
header?: React.ReactNode;
|
|
9
|
+
/** Used by default header. */
|
|
10
|
+
title?: string;
|
|
11
|
+
/** Used by default header. */
|
|
12
|
+
subtitle?: string;
|
|
13
|
+
/** Content; only rendered when state is not "hidden" (lazy). */
|
|
14
|
+
children: React.ReactNode;
|
|
15
|
+
/** Width in pixels for normal state. Default 512 (32rem). */
|
|
16
|
+
normalWidth?: number;
|
|
17
|
+
/** Width when expanded. Default `calc(100vw - 140px)`. */
|
|
18
|
+
maxWidth?: string;
|
|
19
|
+
/** Controlled drawer width. When provided, it is used for the normal state. */
|
|
20
|
+
width?: number | string;
|
|
21
|
+
/** Minimum drawer width while visible. */
|
|
22
|
+
minWidth?: number;
|
|
23
|
+
/** Maximum width allowed while dragging. */
|
|
24
|
+
maxResizableWidth?: number;
|
|
25
|
+
/** Called while the user drags the drawer resize handle. */
|
|
26
|
+
onWidthChange?: (width: number) => void;
|
|
27
|
+
/** Callback when expand/collapse is toggled. When provided, default header shows expand/minimize button. */
|
|
28
|
+
onExpandedChange?: (expanded: boolean) => void;
|
|
29
|
+
/** Extra actions rendered in the default header before expand/close controls. */
|
|
30
|
+
headerActions?: React.ReactNode;
|
|
31
|
+
className?: string;
|
|
32
|
+
headerClassName?: string;
|
|
33
|
+
bodyClassName?: string;
|
|
34
|
+
}
|
|
35
|
+
export declare const ExpandableRightDrawer: React.FC<ExpandableRightDrawerProps>;
|
|
36
|
+
//# sourceMappingURL=expandable-drawer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expandable-drawer.d.ts","sourceRoot":"","sources":["../../../src/patterns/expandable-drawer/expandable-drawer.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA6C,MAAM,OAAO,CAAC;AAQlE,MAAM,MAAM,0BAA0B,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,CAAC;AAM1E,MAAM,WAAW,0BAA0B;IACzC,iFAAiF;IACjF,KAAK,EAAE,0BAA0B,CAAC;IAClC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,yGAAyG;IACzG,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gEAAgE;IAChE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,6DAA6D;IAC7D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+EAA+E;IAC/E,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4CAA4C;IAC5C,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,4DAA4D;IAC5D,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,4GAA4G;IAC5G,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IAC/C,iFAAiF;IACjF,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,eAAO,MAAM,qBAAqB,EAAE,KAAK,CAAC,EAAE,CAAC,0BAA0B,CAsKtE,CAAC"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { jsx as t, jsxs as i } from "react/jsx-runtime";
|
|
2
|
+
import { Minimize01 as H, Expand01 as K, X as F } from "@untitledui/icons";
|
|
3
|
+
import { useState as U, useId as Y, useRef as G, useEffect as J } from "react";
|
|
4
|
+
import { motion as Q } from "../../node_modules/framer-motion/dist/es/render/components/motion/proxy.js";
|
|
5
|
+
const Z = 512, W = "calc(100vw - 140px)", C = { type: "tween", duration: 0.3, ease: "easeInOut" }, se = ({
|
|
6
|
+
state: o,
|
|
7
|
+
onClose: h,
|
|
8
|
+
header: n,
|
|
9
|
+
title: I = "",
|
|
10
|
+
subtitle: y,
|
|
11
|
+
children: z,
|
|
12
|
+
normalWidth: g = Z,
|
|
13
|
+
maxWidth: D = W,
|
|
14
|
+
width: k,
|
|
15
|
+
minWidth: a = 480,
|
|
16
|
+
maxResizableWidth: R,
|
|
17
|
+
onWidthChange: r,
|
|
18
|
+
onExpandedChange: c,
|
|
19
|
+
headerActions: M,
|
|
20
|
+
className: P = "",
|
|
21
|
+
headerClassName: S = "",
|
|
22
|
+
bodyClassName: E = ""
|
|
23
|
+
}) => {
|
|
24
|
+
const [v, V] = U(!1), u = o !== "hidden";
|
|
25
|
+
u && !v && V(!0);
|
|
26
|
+
const w = c !== void 0, m = o === "expanded", l = o === "hidden" ? 0 : o === "expanded" ? D : k ?? g, f = Math.max(R ?? Number.POSITIVE_INFINITY, a), b = o === "normal" && u && typeof l == "number" && r !== void 0, p = (e) => Math.min(Math.max(e, a), f), L = Y(), s = G(null);
|
|
27
|
+
J(() => () => {
|
|
28
|
+
var e;
|
|
29
|
+
return (e = s.current) == null ? void 0 : e.call(s);
|
|
30
|
+
}, []);
|
|
31
|
+
const T = (e) => {
|
|
32
|
+
if (!b || typeof l != "number") return;
|
|
33
|
+
e.preventDefault(), e.stopPropagation();
|
|
34
|
+
const d = e.clientX, $ = l, O = document.body.style.cursor, q = document.body.style.userSelect;
|
|
35
|
+
document.body.style.cursor = "col-resize", document.body.style.userSelect = "none";
|
|
36
|
+
const N = (B) => {
|
|
37
|
+
r == null || r(p($ + d - B.clientX));
|
|
38
|
+
}, x = () => {
|
|
39
|
+
document.body.style.cursor = O, document.body.style.userSelect = q, window.removeEventListener("pointermove", N), window.removeEventListener("pointerup", x), s.current = null;
|
|
40
|
+
};
|
|
41
|
+
s.current = x, window.addEventListener("pointermove", N), window.addEventListener("pointerup", x);
|
|
42
|
+
}, X = (e) => {
|
|
43
|
+
if (!b || typeof l != "number") return;
|
|
44
|
+
const d = e.shiftKey ? 50 : 16;
|
|
45
|
+
e.key === "ArrowLeft" && (e.preventDefault(), r == null || r(p(l + d))), e.key === "ArrowRight" && (e.preventDefault(), r == null || r(p(l - d)));
|
|
46
|
+
}, _ = {
|
|
47
|
+
backgroundImage: "linear-gradient(90deg, rgba(6, 132, 240, 0.1) 0%, rgba(6, 132, 240, 0.1) 100%), linear-gradient(0deg, rgba(255, 255, 255, 0) 60.66%, rgba(255, 255, 255, 0.5) 100%), linear-gradient(90deg, rgba(255, 255, 255, 0.3) 0%, rgba(255, 255, 255, 0.3) 100%)"
|
|
48
|
+
}, j = `flex items-center justify-between pl-6 pr-2 border-b border-secondary gap-2 py-4 ${S}`, A = `flex min-h-0 flex-1 flex-col overflow-y-auto pb-3 ${E} ${n ? "" : "px-5"}`;
|
|
49
|
+
return /* @__PURE__ */ t(
|
|
50
|
+
Q.div,
|
|
51
|
+
{
|
|
52
|
+
className: `relative flex flex-col flex-shrink-0 overflow-hidden min-w-0 h-[calc(98vh-85px)] z-1000 ${P}`,
|
|
53
|
+
initial: !1,
|
|
54
|
+
animate: {
|
|
55
|
+
width: l,
|
|
56
|
+
minWidth: o === "hidden" ? 0 : a || void 0
|
|
57
|
+
},
|
|
58
|
+
transition: C,
|
|
59
|
+
children: u && /* @__PURE__ */ i(
|
|
60
|
+
"div",
|
|
61
|
+
{
|
|
62
|
+
className: "h-full w-full min-w-0 flex flex-col rounded-2xl border-l border-t border-b border-white backdrop-blur-[3px] p-2",
|
|
63
|
+
style: _,
|
|
64
|
+
children: [
|
|
65
|
+
b && /* @__PURE__ */ t(
|
|
66
|
+
"div",
|
|
67
|
+
{
|
|
68
|
+
role: "separator",
|
|
69
|
+
"aria-label": "Resize drawer",
|
|
70
|
+
"aria-orientation": "vertical",
|
|
71
|
+
"aria-valuemin": a,
|
|
72
|
+
"aria-valuemax": Number.isFinite(f) ? f : void 0,
|
|
73
|
+
"aria-valuenow": typeof l == "number" ? Math.round(l) : void 0,
|
|
74
|
+
tabIndex: 0,
|
|
75
|
+
onPointerDown: T,
|
|
76
|
+
onKeyDown: X,
|
|
77
|
+
className: "absolute left-0 top-0 z-10 h-full w-2 -translate-x-1 cursor-col-resize touch-none focus-visible:outline-none"
|
|
78
|
+
}
|
|
79
|
+
),
|
|
80
|
+
/* @__PURE__ */ i("div", { className: "h-full w-full bg-white rounded-lg overflow-hidden flex flex-col min-w-0", children: [
|
|
81
|
+
n ?? /* @__PURE__ */ i("header", { className: j, children: [
|
|
82
|
+
/* @__PURE__ */ i("div", { className: `flex-1 flex flex-col gap-0 min-w-0 ${w ? "pr-2" : "pr-16"}`, children: [
|
|
83
|
+
/* @__PURE__ */ t("h2", { id: L, className: "text-lg font-semibold leading-7 text-[#06060a] truncate", children: I }),
|
|
84
|
+
y && /* @__PURE__ */ t("p", { className: "text-sm text-secondary truncate", children: y })
|
|
85
|
+
] }),
|
|
86
|
+
/* @__PURE__ */ i("div", { className: "flex items-center gap-1 flex-shrink-0", children: [
|
|
87
|
+
M,
|
|
88
|
+
w && /* @__PURE__ */ t(
|
|
89
|
+
"button",
|
|
90
|
+
{
|
|
91
|
+
type: "button",
|
|
92
|
+
onClick: () => c == null ? void 0 : c(!m),
|
|
93
|
+
className: "flex items-center justify-center p-2 rounded-lg hover:bg-primary_hover transition-colors cursor-pointer",
|
|
94
|
+
"aria-label": m ? "Collapse sidebar" : "Expand sidebar",
|
|
95
|
+
children: m ? /* @__PURE__ */ t(H, { size: 20, className: "text-fg-quaternary", strokeWidth: 1.67 }) : /* @__PURE__ */ t(K, { size: 20, className: "text-fg-quaternary", strokeWidth: 1.67 })
|
|
96
|
+
}
|
|
97
|
+
),
|
|
98
|
+
/* @__PURE__ */ t(
|
|
99
|
+
"button",
|
|
100
|
+
{
|
|
101
|
+
type: "button",
|
|
102
|
+
onClick: h,
|
|
103
|
+
className: "flex items-center justify-center p-2 rounded-lg hover:bg-primary_hover transition-colors cursor-pointer",
|
|
104
|
+
"aria-label": "Close",
|
|
105
|
+
children: /* @__PURE__ */ t(F, { size: 20, className: "text-fg-quaternary", strokeWidth: 1.67 })
|
|
106
|
+
}
|
|
107
|
+
)
|
|
108
|
+
] })
|
|
109
|
+
] }),
|
|
110
|
+
/* @__PURE__ */ t("main", { className: A, children: v ? z : null })
|
|
111
|
+
] })
|
|
112
|
+
]
|
|
113
|
+
}
|
|
114
|
+
)
|
|
115
|
+
}
|
|
116
|
+
);
|
|
117
|
+
};
|
|
118
|
+
export {
|
|
119
|
+
se as ExpandableRightDrawer
|
|
120
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/patterns/expandable-drawer/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,KAAK,0BAA0B,EAC/B,KAAK,0BAA0B,GAChC,MAAM,qBAAqB,CAAC"}
|