@skiddph/prui 0.7.0 → 0.8.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/dist/app/resource.d.ts +44 -1
- package/dist/app.js +1 -1
- package/dist/chunks/auth-shell-DQJ4UmUv.js +1208 -0
- package/dist/chunks/data-table-toolbar-B-5J2Ozl.js +736 -0
- package/dist/core/accordion.d.ts +16 -0
- package/dist/core/accordion.js +108 -0
- package/dist/core/alert.d.ts +20 -0
- package/dist/core/alert.js +63 -0
- package/dist/core/anchor.d.ts +35 -0
- package/dist/core/anchor.js +39 -0
- package/dist/core/breadcrumb.d.ts +30 -0
- package/dist/core/breadcrumb.js +67 -0
- package/dist/core/button.d.ts +8 -1
- package/dist/core/button.js +23 -18
- package/dist/core/calendar.d.ts +29 -0
- package/dist/core/calendar.js +180 -0
- package/dist/core/card.d.ts +5 -1
- package/dist/core/card.js +33 -29
- package/dist/core/checkbox.d.ts +19 -0
- package/dist/core/checkbox.js +55 -0
- package/dist/core/combobox.d.ts +32 -0
- package/dist/core/combobox.js +183 -0
- package/dist/core/date-picker.d.ts +41 -0
- package/dist/core/date-picker.js +202 -0
- package/dist/core/dialog.d.ts +8 -0
- package/dist/core/dialog.js +59 -61
- package/dist/core/drawer.d.ts +34 -0
- package/dist/core/drawer.js +129 -0
- package/dist/core/dropdown.d.ts +8 -4
- package/dist/core/dropdown.js +136 -51
- package/dist/core/file-upload.d.ts +28 -0
- package/dist/core/file-upload.js +111 -0
- package/dist/core/index.d.ts +21 -0
- package/dist/core/list-nav.d.ts +27 -0
- package/dist/core/list-nav.js +51 -0
- package/dist/core/modal.d.ts +14 -5
- package/dist/core/modal.js +163 -156
- package/dist/core/overlay.d.ts +93 -0
- package/dist/core/overlay.js +189 -0
- package/dist/core/popover.d.ts +29 -0
- package/dist/core/popover.js +124 -0
- package/dist/core/progress.d.ts +21 -0
- package/dist/core/progress.js +59 -0
- package/dist/core/radio.d.ts +20 -0
- package/dist/core/radio.js +115 -0
- package/dist/core/select.d.ts +6 -0
- package/dist/core/select.js +178 -97
- package/dist/core/skeleton.d.ts +20 -0
- package/dist/core/skeleton.js +41 -0
- package/dist/core/spinner.d.ts +15 -0
- package/dist/core/spinner.js +41 -0
- package/dist/core/tabs.js +82 -53
- package/dist/core/timeline.d.ts +22 -0
- package/dist/core/timeline.js +57 -0
- package/dist/core/toast.d.ts +36 -0
- package/dist/core/toast.js +123 -0
- package/dist/core/tooltip.d.ts +23 -0
- package/dist/core/tooltip.js +96 -0
- package/dist/core/tree-view.d.ts +34 -0
- package/dist/core/tree-view.js +133 -0
- package/dist/core.js +152 -62
- package/dist/data-table/data-table.d.ts +22 -1
- package/dist/data-table.js +1 -1
- package/dist/forms/form.d.ts +8 -0
- package/dist/forms.js +213 -200
- package/dist/i18n/index.d.ts +83 -0
- package/dist/i18n.js +99 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +256 -156
- package/dist/prui-utilities.css +1 -1
- package/dist/prui.css +111 -4
- package/dist/theme/base.css +110 -3
- package/dist/theme/index.d.ts +27 -0
- package/dist/theme.js +86 -58
- package/package.json +9 -2
- package/dist/chunks/auth-shell-BG5vx9eG.js +0 -1054
- package/dist/chunks/data-table-toolbar-BUy2EWPy.js +0 -581
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { jsxs as x, Fragment as $, jsx as a } from "react/jsx-runtime";
|
|
2
|
+
import * as s from "react";
|
|
3
|
+
import { CalendarDays as z } from "lucide-react";
|
|
4
|
+
import { cn as j } from "./cn.js";
|
|
5
|
+
import { useOverlayStack as E, useEscapeKey as F, Portal as T } from "./overlay.js";
|
|
6
|
+
import { useAnchoredPosition as H } from "./anchor.js";
|
|
7
|
+
import { Calendar as U } from "./calendar.js";
|
|
8
|
+
import { usePruiI18n as I } from "../i18n.js";
|
|
9
|
+
const K = s.forwardRef(function({ value: v, defaultValue: D, onChange: t, min: h, max: M, placeholder: R = "YYYY-MM-DD", disabled: b, className: k, ariaLabel: w }, l) {
|
|
10
|
+
const [g, N] = s.useState(D ?? ""), m = v !== void 0, f = m ? v : g, [r, o] = s.useState(!1), i = s.useRef(null), [u, y] = s.useState(""), { setElement: P, isTop: S } = E(r);
|
|
11
|
+
F(r, S, () => {
|
|
12
|
+
var e;
|
|
13
|
+
o(!1), (e = i.current) == null || e.focus();
|
|
14
|
+
});
|
|
15
|
+
const { ref: d, position: c } = H({ active: r, anchorRef: i, side: "bottom", align: "start", offsetHeight: 360 }), Y = (e) => {
|
|
16
|
+
var n;
|
|
17
|
+
m || N(e), t == null || t(e), o(!1), (n = i.current) == null || n.focus();
|
|
18
|
+
};
|
|
19
|
+
return /* @__PURE__ */ x($, { children: [
|
|
20
|
+
/* @__PURE__ */ a(
|
|
21
|
+
"input",
|
|
22
|
+
{
|
|
23
|
+
ref: (e) => {
|
|
24
|
+
i.current = e, typeof l == "function" ? l(e) : l && (l.current = e);
|
|
25
|
+
},
|
|
26
|
+
type: "text",
|
|
27
|
+
readOnly: !0,
|
|
28
|
+
role: "combobox",
|
|
29
|
+
"aria-expanded": r,
|
|
30
|
+
"aria-haspopup": "dialog",
|
|
31
|
+
"aria-label": w,
|
|
32
|
+
placeholder: R,
|
|
33
|
+
disabled: b,
|
|
34
|
+
value: u !== "" ? u : f,
|
|
35
|
+
onFocus: () => {
|
|
36
|
+
!b && !r && o(!0);
|
|
37
|
+
},
|
|
38
|
+
onClick: () => o(!0),
|
|
39
|
+
onChange: (e) => {
|
|
40
|
+
const n = e.target.value;
|
|
41
|
+
y(n), /^\d{4}-\d{2}-\d{2}$/.test(n) && (y(""), Y(n));
|
|
42
|
+
},
|
|
43
|
+
className: j(
|
|
44
|
+
"prui-date-picker flex h-9 w-full cursor-pointer items-center gap-2 border border-[var(--prui-line)]",
|
|
45
|
+
"bg-[var(--prui-background)] rounded-[var(--prui-radius)] px-3 text-sm text-[var(--prui-fg)] placeholder:text-[var(--prui-dim)]",
|
|
46
|
+
"outline-none transition-colors focus:border-[var(--prui-brand)] focus:ring-2 focus:ring-[var(--prui-brand)]/30",
|
|
47
|
+
"disabled:opacity-50 disabled:cursor-not-allowed",
|
|
48
|
+
k
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
),
|
|
52
|
+
/* @__PURE__ */ a(z, { className: "pointer-events-none -ml-7 h-4 w-4 text-[var(--prui-dim)]", "aria-hidden": !0 }),
|
|
53
|
+
r ? /* @__PURE__ */ a(T, { children: /* @__PURE__ */ a(
|
|
54
|
+
"div",
|
|
55
|
+
{
|
|
56
|
+
ref: (e) => {
|
|
57
|
+
d(e), P(e);
|
|
58
|
+
},
|
|
59
|
+
role: "dialog",
|
|
60
|
+
"aria-label": "Choose date",
|
|
61
|
+
className: "fixed z-[var(--prui-z-overlay)]",
|
|
62
|
+
style: { top: (c == null ? void 0 : c.top) ?? -9999, left: (c == null ? void 0 : c.left) ?? -9999 },
|
|
63
|
+
children: /* @__PURE__ */ a(U, { value: f, onSelect: Y, min: h, max: M, className: "shadow-[var(--prui-shadow-lg)]" })
|
|
64
|
+
}
|
|
65
|
+
) }) : null
|
|
66
|
+
] });
|
|
67
|
+
});
|
|
68
|
+
K.displayName = "DatePicker";
|
|
69
|
+
const q = s.forwardRef(function({ value: v, defaultValue: D, onChange: t, min: h, max: M, placeholder: R = "YYYY-MM-DD – YYYY-MM-DD", disabled: b, className: k, ariaLabel: w }, l) {
|
|
70
|
+
const { t: g } = I(), [N, m] = s.useState(D ?? {}), f = v !== void 0, r = f ? v : N, [o, i] = s.useState(!1), u = s.useRef(null), { setElement: y, isTop: P } = E(o);
|
|
71
|
+
F(o, P, () => {
|
|
72
|
+
var e;
|
|
73
|
+
i(!1), (e = u.current) == null || e.focus();
|
|
74
|
+
});
|
|
75
|
+
const { ref: S, position: d } = H({ active: o, anchorRef: u, side: "bottom", align: "start", offsetHeight: 360 }), c = (e) => {
|
|
76
|
+
var O;
|
|
77
|
+
const { from: n, to: A } = r;
|
|
78
|
+
let p;
|
|
79
|
+
if (!n || n && A)
|
|
80
|
+
p = { from: e };
|
|
81
|
+
else if (e < n)
|
|
82
|
+
p = { from: e };
|
|
83
|
+
else {
|
|
84
|
+
p = { from: n, to: e }, t == null || t(p), f || m(p), i(!1), (O = u.current) == null || O.focus();
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
f || m(p), t == null || t(p);
|
|
88
|
+
}, Y = r.from ? r.to ? `${r.from} – ${r.to}` : `${r.from} – …` : "";
|
|
89
|
+
return /* @__PURE__ */ x($, { children: [
|
|
90
|
+
/* @__PURE__ */ a(
|
|
91
|
+
"input",
|
|
92
|
+
{
|
|
93
|
+
ref: (e) => {
|
|
94
|
+
u.current = e, typeof l == "function" ? l(e) : l && (l.current = e);
|
|
95
|
+
},
|
|
96
|
+
type: "text",
|
|
97
|
+
readOnly: !0,
|
|
98
|
+
role: "combobox",
|
|
99
|
+
"aria-expanded": o,
|
|
100
|
+
"aria-haspopup": "dialog",
|
|
101
|
+
"aria-label": w,
|
|
102
|
+
placeholder: R,
|
|
103
|
+
disabled: b,
|
|
104
|
+
value: Y,
|
|
105
|
+
onClick: () => i(!0),
|
|
106
|
+
onFocus: () => {
|
|
107
|
+
!b && !o && i(!0);
|
|
108
|
+
},
|
|
109
|
+
className: j(
|
|
110
|
+
"prui-date-range-picker flex h-9 w-full cursor-pointer items-center border border-[var(--prui-line)]",
|
|
111
|
+
"bg-[var(--prui-background)] rounded-[var(--prui-radius)] px-3 text-sm text-[var(--prui-fg)] placeholder:text-[var(--prui-dim)]",
|
|
112
|
+
"outline-none transition-colors focus:border-[var(--prui-brand)] focus:ring-2 focus:ring-[var(--prui-brand)]/30",
|
|
113
|
+
"disabled:opacity-50 disabled:cursor-not-allowed",
|
|
114
|
+
k
|
|
115
|
+
)
|
|
116
|
+
}
|
|
117
|
+
),
|
|
118
|
+
/* @__PURE__ */ a(z, { className: "pointer-events-none -ml-7 h-4 w-4 text-[var(--prui-dim)]", "aria-hidden": !0 }),
|
|
119
|
+
o ? /* @__PURE__ */ a(T, { children: /* @__PURE__ */ a(
|
|
120
|
+
"div",
|
|
121
|
+
{
|
|
122
|
+
ref: (e) => {
|
|
123
|
+
S(e), y(e);
|
|
124
|
+
},
|
|
125
|
+
role: "dialog",
|
|
126
|
+
"aria-label": "Choose date range",
|
|
127
|
+
className: "fixed z-[var(--prui-z-overlay)]",
|
|
128
|
+
style: { top: (d == null ? void 0 : d.top) ?? -9999, left: (d == null ? void 0 : d.left) ?? -9999 },
|
|
129
|
+
children: /* @__PURE__ */ x("div", { className: "shadow-[var(--prui-shadow-lg)]", children: [
|
|
130
|
+
/* @__PURE__ */ a(
|
|
131
|
+
U,
|
|
132
|
+
{
|
|
133
|
+
value: r.to ?? r.from,
|
|
134
|
+
month: r.from ? `${r.from.slice(0, 7)}` : void 0,
|
|
135
|
+
onSelect: c,
|
|
136
|
+
min: h,
|
|
137
|
+
max: M,
|
|
138
|
+
showToday: !1,
|
|
139
|
+
className: "border-0 shadow-none",
|
|
140
|
+
"data-range-from": r.from ?? "",
|
|
141
|
+
"data-range-to": r.to ?? ""
|
|
142
|
+
}
|
|
143
|
+
),
|
|
144
|
+
/* @__PURE__ */ x("div", { className: "flex items-center justify-between gap-2 border-t border-[var(--prui-line)] px-3 py-2 text-xs text-[var(--prui-dim)]", children: [
|
|
145
|
+
/* @__PURE__ */ a("span", { "data-testid": "range-label", children: Y || g.today }),
|
|
146
|
+
/* @__PURE__ */ x("div", { className: "flex gap-2", children: [
|
|
147
|
+
/* @__PURE__ */ a(
|
|
148
|
+
"button",
|
|
149
|
+
{
|
|
150
|
+
type: "button",
|
|
151
|
+
onClick: () => {
|
|
152
|
+
f || m({}), t == null || t({});
|
|
153
|
+
},
|
|
154
|
+
className: "cursor-pointer rounded-[var(--prui-radius-1)] px-2 py-1 transition-colors hover:bg-[var(--prui-raise)]",
|
|
155
|
+
children: g.clear
|
|
156
|
+
}
|
|
157
|
+
),
|
|
158
|
+
/* @__PURE__ */ a(
|
|
159
|
+
"button",
|
|
160
|
+
{
|
|
161
|
+
type: "button",
|
|
162
|
+
onClick: () => {
|
|
163
|
+
var e;
|
|
164
|
+
i(!1), (e = u.current) == null || e.focus();
|
|
165
|
+
},
|
|
166
|
+
className: "cursor-pointer rounded-[var(--prui-radius-1)] bg-[var(--prui-brand)]/15 px-2 py-1 text-[var(--prui-brand)] transition-colors hover:bg-[var(--prui-brand)]/25",
|
|
167
|
+
children: g.apply
|
|
168
|
+
}
|
|
169
|
+
)
|
|
170
|
+
] })
|
|
171
|
+
] })
|
|
172
|
+
] })
|
|
173
|
+
}
|
|
174
|
+
) }) : null
|
|
175
|
+
] });
|
|
176
|
+
});
|
|
177
|
+
q.displayName = "DateRangePicker";
|
|
178
|
+
const Z = {
|
|
179
|
+
name: "DatePicker",
|
|
180
|
+
props: [
|
|
181
|
+
{ name: "value", type: "string 'YYYY-MM-DD'", default: "undefined", control: "date" },
|
|
182
|
+
{ name: "defaultValue", type: "string 'YYYY-MM-DD'", default: "undefined", control: "date" },
|
|
183
|
+
{ name: "onChange", type: "(date: string) => void", default: null, control: "none" },
|
|
184
|
+
{ name: "min", type: "string 'YYYY-MM-DD'", default: "undefined", control: "date" },
|
|
185
|
+
{ name: "max", type: "string 'YYYY-MM-DD'", default: "undefined", control: "date" }
|
|
186
|
+
]
|
|
187
|
+
}, _ = {
|
|
188
|
+
name: "DateRangePicker",
|
|
189
|
+
props: [
|
|
190
|
+
{ name: "value", type: "{ from?: string, to?: string }", default: "{}", control: "daterange" },
|
|
191
|
+
{ name: "defaultValue", type: "{ from?: string, to?: string }", default: "{}", control: "daterange" },
|
|
192
|
+
{ name: "onChange", type: "(range: DateRange) => void", default: null, control: "none" },
|
|
193
|
+
{ name: "min", type: "string 'YYYY-MM-DD'", default: "undefined", control: "date" },
|
|
194
|
+
{ name: "max", type: "string 'YYYY-MM-DD'", default: "undefined", control: "date" }
|
|
195
|
+
]
|
|
196
|
+
};
|
|
197
|
+
export {
|
|
198
|
+
K as DatePicker,
|
|
199
|
+
q as DateRangePicker,
|
|
200
|
+
Z as datePickerPropsMeta,
|
|
201
|
+
_ as dateRangePickerPropsMeta
|
|
202
|
+
};
|
package/dist/core/dialog.d.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { PropsMeta } from './props-meta';
|
|
2
2
|
import * as React from "react";
|
|
3
|
+
/**
|
|
4
|
+
* Dialog: the compound, declarative modal surface (<Dialog> + <DialogContent/
|
|
5
|
+
* Header/Title/Description/Footer>). Built on the shared overlay
|
|
6
|
+
* infrastructure: portaled, focus-trapped with focus restoration, topmost
|
|
7
|
+
* Escape, scroll-locked, background aria-hidden/inert while open.
|
|
8
|
+
*/
|
|
3
9
|
export interface DialogProps {
|
|
4
10
|
open?: boolean;
|
|
5
11
|
defaultOpen?: boolean;
|
|
@@ -16,6 +22,8 @@ export interface DialogContentProps extends React.HTMLAttributes<HTMLDivElement>
|
|
|
16
22
|
/** Accessibility label when no DialogTitle is rendered. */
|
|
17
23
|
ariaLabel?: string;
|
|
18
24
|
hideClose?: boolean;
|
|
25
|
+
/** Initial focus target: first focusable (default), the dialog itself, a specific element, or none. */
|
|
26
|
+
initialFocus?: React.RefObject<HTMLElement | null> | "first" | "container" | false;
|
|
19
27
|
}
|
|
20
28
|
export declare const DialogContent: React.ForwardRefExoticComponent<DialogContentProps & React.RefAttributes<HTMLDivElement>>;
|
|
21
29
|
export declare const DialogHeader: ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => React.JSX.Element;
|
package/dist/core/dialog.js
CHANGED
|
@@ -1,102 +1,100 @@
|
|
|
1
|
-
import { jsx as
|
|
2
|
-
import * as
|
|
3
|
-
import { X as
|
|
4
|
-
import { cn as
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import { jsx as t, jsxs as y } from "react/jsx-runtime";
|
|
2
|
+
import * as a from "react";
|
|
3
|
+
import { X as D } from "lucide-react";
|
|
4
|
+
import { cn as n } from "./cn.js";
|
|
5
|
+
import { useOverlay as h, Portal as w } from "./overlay.js";
|
|
6
|
+
import { usePruiI18n as N } from "../i18n.js";
|
|
7
|
+
const v = a.createContext(null);
|
|
8
|
+
function g() {
|
|
9
|
+
const e = a.useContext(v);
|
|
8
10
|
if (!e) throw new Error("Dialog parts must be used inside <Dialog>");
|
|
9
11
|
return e;
|
|
10
12
|
}
|
|
11
|
-
const
|
|
12
|
-
const [c, p] =
|
|
13
|
-
|
|
13
|
+
const I = ({ open: e, defaultOpen: o = !1, onOpenChange: r, children: i }) => {
|
|
14
|
+
const [c, p] = a.useState(o), s = e !== void 0, f = s ? e : c, d = a.useId(), l = (u) => {
|
|
15
|
+
s || p(u), r == null || r(u);
|
|
14
16
|
};
|
|
15
|
-
return /* @__PURE__ */
|
|
17
|
+
return /* @__PURE__ */ t(v.Provider, { value: { open: f, setOpen: l, labelId: d }, children: i });
|
|
16
18
|
};
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
-
({ className: e, children: o, ariaLabel:
|
|
20
|
-
const { open:
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
document.addEventListener("keydown", r);
|
|
27
|
-
const g = document.body.style.overflow;
|
|
28
|
-
return document.body.style.overflow = "hidden", () => {
|
|
29
|
-
document.removeEventListener("keydown", r), document.body.style.overflow = g;
|
|
30
|
-
};
|
|
31
|
-
}, [s, i]), s ? /* @__PURE__ */ a(
|
|
19
|
+
I.displayName = "Dialog";
|
|
20
|
+
const C = a.forwardRef(
|
|
21
|
+
({ className: e, children: o, ariaLabel: r, hideClose: i, initialFocus: c = "first", onClick: p, ...s }, f) => {
|
|
22
|
+
const { open: d, setOpen: l, labelId: u } = g(), { t: b } = N(), { ref: x } = h({
|
|
23
|
+
open: d,
|
|
24
|
+
onEscape: () => l(!1),
|
|
25
|
+
initialFocus: c
|
|
26
|
+
});
|
|
27
|
+
return d ? /* @__PURE__ */ t(w, { children: /* @__PURE__ */ t("div", { ref: x, children: /* @__PURE__ */ t(
|
|
32
28
|
"div",
|
|
33
29
|
{
|
|
34
|
-
className: "prui-dialog-overlay fixed inset-0 z-
|
|
35
|
-
style: { backgroundColor: "
|
|
36
|
-
onMouseDown: (
|
|
37
|
-
|
|
30
|
+
className: "prui-dialog-overlay fixed inset-0 z-[var(--prui-z-overlay)] flex items-center justify-center p-4",
|
|
31
|
+
style: { backgroundColor: "var(--prui-scrim)" },
|
|
32
|
+
onMouseDown: (m) => {
|
|
33
|
+
m.target === m.currentTarget && l(!1);
|
|
38
34
|
},
|
|
39
35
|
children: /* @__PURE__ */ y(
|
|
40
36
|
"div",
|
|
41
37
|
{
|
|
42
|
-
ref:
|
|
38
|
+
ref: f,
|
|
43
39
|
role: "dialog",
|
|
44
40
|
"aria-modal": "true",
|
|
45
|
-
"aria-label":
|
|
46
|
-
"aria-labelledby":
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
"
|
|
41
|
+
"aria-label": r,
|
|
42
|
+
"aria-labelledby": r ? void 0 : u,
|
|
43
|
+
tabIndex: -1,
|
|
44
|
+
className: n(
|
|
45
|
+
"prui-dialog-content relative z-[var(--prui-z-content)] w-full max-w-lg rounded-[var(--prui-radius)]",
|
|
46
|
+
"border border-[var(--prui-line)] bg-[var(--prui-surface)] shadow-[var(--prui-shadow-lg)]",
|
|
50
47
|
"max-h-[85vh] overflow-auto outline-none",
|
|
51
48
|
e
|
|
52
49
|
),
|
|
53
|
-
onClick:
|
|
54
|
-
...
|
|
50
|
+
onClick: p,
|
|
51
|
+
...s,
|
|
55
52
|
children: [
|
|
56
53
|
o,
|
|
57
|
-
|
|
54
|
+
i ? null : /* @__PURE__ */ t(
|
|
58
55
|
"button",
|
|
59
56
|
{
|
|
60
57
|
type: "button",
|
|
61
|
-
"aria-label":
|
|
62
|
-
onClick: () =>
|
|
58
|
+
"aria-label": b.close,
|
|
59
|
+
onClick: () => l(!1),
|
|
63
60
|
className: "absolute right-3 top-3 rounded-[var(--prui-radius-1)] p-1 text-[var(--prui-dim)] hover:text-[var(--prui-fg)] hover:bg-[var(--prui-raise)] cursor-pointer",
|
|
64
|
-
children: /* @__PURE__ */
|
|
61
|
+
children: /* @__PURE__ */ t(D, { className: "h-4 w-4", "aria-hidden": !0 })
|
|
65
62
|
}
|
|
66
63
|
)
|
|
67
64
|
]
|
|
68
65
|
}
|
|
69
66
|
)
|
|
70
67
|
}
|
|
71
|
-
) : null;
|
|
68
|
+
) }) }) : null;
|
|
72
69
|
}
|
|
73
70
|
);
|
|
74
|
-
|
|
75
|
-
const
|
|
76
|
-
({ className: e, ...o },
|
|
77
|
-
const { labelId:
|
|
78
|
-
return /* @__PURE__ */
|
|
71
|
+
C.displayName = "DialogContent";
|
|
72
|
+
const F = ({ className: e, ...o }) => /* @__PURE__ */ t("div", { className: n("prui-dialog-header flex flex-col gap-1 p-4 pb-2", e), ...o }), R = a.forwardRef(
|
|
73
|
+
({ className: e, ...o }, r) => {
|
|
74
|
+
const { labelId: i } = g();
|
|
75
|
+
return /* @__PURE__ */ t("h2", { ref: r, id: i, className: n("prui-dialog-title text-base font-semibold text-[var(--prui-fg)]", e), ...o });
|
|
79
76
|
}
|
|
80
77
|
);
|
|
81
|
-
|
|
82
|
-
const
|
|
83
|
-
({ className: e, ...o },
|
|
78
|
+
R.displayName = "DialogTitle";
|
|
79
|
+
const j = a.forwardRef(
|
|
80
|
+
({ className: e, ...o }, r) => /* @__PURE__ */ t("p", { ref: r, className: n("prui-dialog-description text-sm text-[var(--prui-dim)]", e), ...o })
|
|
84
81
|
);
|
|
85
|
-
|
|
86
|
-
const
|
|
82
|
+
j.displayName = "DialogDescription";
|
|
83
|
+
const M = ({ className: e, ...o }) => /* @__PURE__ */ t("div", { className: n("prui-dialog-footer flex items-center justify-end gap-2 p-4 pt-2", e), ...o }), H = {
|
|
87
84
|
name: "Dialog",
|
|
88
85
|
props: [
|
|
89
86
|
{ name: "open", type: "boolean", default: "undefined", control: "boolean" },
|
|
90
87
|
{ name: "defaultOpen", type: "boolean", default: "false", control: "boolean" },
|
|
91
|
-
{ name: "onOpenChange", type: "(open: boolean) => void", default: null, control: "none" }
|
|
88
|
+
{ name: "onOpenChange", type: "(open: boolean) => void", default: null, control: "none" },
|
|
89
|
+
{ name: "initialFocus", type: 'ref | "first" | "container" | false', default: '"first"', control: "none" }
|
|
92
90
|
]
|
|
93
91
|
};
|
|
94
92
|
export {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
93
|
+
I as Dialog,
|
|
94
|
+
C as DialogContent,
|
|
95
|
+
j as DialogDescription,
|
|
96
|
+
M as DialogFooter,
|
|
97
|
+
F as DialogHeader,
|
|
98
|
+
R as DialogTitle,
|
|
99
|
+
H as dialogPropsMeta
|
|
102
100
|
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { PropsMeta } from './props-meta';
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
/**
|
|
4
|
+
* Drawer: a side-anchored modal panel (left/right/top/bottom) built on the
|
|
5
|
+
* shared overlay infrastructure: portaled, focus-trapped, scroll-locked,
|
|
6
|
+
* background inert, topmost Escape, focus restoration, reduced motion.
|
|
7
|
+
* Sheet is the same surface preset to bottom (mobile-first) with a drag
|
|
8
|
+
* handle. Controlled and uncontrolled open.
|
|
9
|
+
*/
|
|
10
|
+
export type DrawerSide = "left" | "right" | "top" | "bottom";
|
|
11
|
+
export interface DrawerProps {
|
|
12
|
+
open?: boolean;
|
|
13
|
+
defaultOpen?: boolean;
|
|
14
|
+
onOpenChange?: (open: boolean) => void;
|
|
15
|
+
/** Anchor edge. Default right. */
|
|
16
|
+
side?: DrawerSide;
|
|
17
|
+
/** Panel width for left/right (any CSS length). Default 400px. */
|
|
18
|
+
size?: number | string;
|
|
19
|
+
children?: React.ReactNode;
|
|
20
|
+
/** Accessible label. */
|
|
21
|
+
ariaLabel?: string;
|
|
22
|
+
/** Hide the close button. */
|
|
23
|
+
hideClose?: boolean;
|
|
24
|
+
className?: string;
|
|
25
|
+
style?: React.CSSProperties;
|
|
26
|
+
}
|
|
27
|
+
export declare const Drawer: React.ForwardRefExoticComponent<DrawerProps & React.RefAttributes<HTMLDivElement>>;
|
|
28
|
+
/**
|
|
29
|
+
* Sheet: the bottom-anchored Drawer preset (mobile-first detail surface).
|
|
30
|
+
* Same overlay guarantees; size sets max height.
|
|
31
|
+
*/
|
|
32
|
+
export declare const Sheet: React.ForwardRefExoticComponent<Omit<DrawerProps, "side"> & React.RefAttributes<HTMLDivElement>>;
|
|
33
|
+
export declare const drawerPropsMeta: PropsMeta;
|
|
34
|
+
export declare const sheetPropsMeta: PropsMeta;
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { jsx as t, jsxs as Y } from "react/jsx-runtime";
|
|
2
|
+
import * as a from "react";
|
|
3
|
+
import { X as k } from "lucide-react";
|
|
4
|
+
import { cn as P } from "./cn.js";
|
|
5
|
+
import { useReducedMotion as j, useOverlay as A, Portal as E } from "./overlay.js";
|
|
6
|
+
import { usePruiI18n as F } from "../i18n.js";
|
|
7
|
+
const L = {
|
|
8
|
+
left: "left-0 top-0 h-full prui-drawer-panel",
|
|
9
|
+
right: "right-0 top-0 h-full prui-drawer-panel",
|
|
10
|
+
top: "left-0 top-0 w-full prui-drawer-panel",
|
|
11
|
+
bottom: "left-0 bottom-0 w-full prui-drawer-panel"
|
|
12
|
+
}, $ = {
|
|
13
|
+
left: "translateX(0)",
|
|
14
|
+
right: "translateX(0)",
|
|
15
|
+
top: "translateY(0)",
|
|
16
|
+
bottom: "translateY(0)"
|
|
17
|
+
}, q = {
|
|
18
|
+
left: "translateX(-100%)",
|
|
19
|
+
right: "translateX(100%)",
|
|
20
|
+
top: "translateY(-100%)",
|
|
21
|
+
bottom: "translateY(100%)"
|
|
22
|
+
}, h = a.forwardRef(function({ open: n, defaultOpen: i = !1, onOpenChange: s, side: r = "right", size: o, children: v, ariaLabel: w, hideClose: y, className: g, style: x }, S) {
|
|
23
|
+
const [N, D] = a.useState(i), m = n !== void 0, l = m ? n : N, [M, u] = a.useState(l), [p, d] = a.useState(!1), f = j(), { t: R } = F(), c = (e) => {
|
|
24
|
+
m || D(e), s == null || s(e);
|
|
25
|
+
};
|
|
26
|
+
a.useEffect(() => {
|
|
27
|
+
if (l) {
|
|
28
|
+
if (u(!0), f) {
|
|
29
|
+
d(!0);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const C = requestAnimationFrame(() => d(!0));
|
|
33
|
+
return () => cancelAnimationFrame(C);
|
|
34
|
+
}
|
|
35
|
+
if (d(!1), f) {
|
|
36
|
+
u(!1);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
const e = setTimeout(() => u(!1), 300);
|
|
40
|
+
return () => clearTimeout(e);
|
|
41
|
+
}, [l, f]);
|
|
42
|
+
const { ref: T } = A({
|
|
43
|
+
open: l,
|
|
44
|
+
onEscape: () => c(!1)
|
|
45
|
+
});
|
|
46
|
+
if (!M) return null;
|
|
47
|
+
const X = {
|
|
48
|
+
transform: p ? $[r] : q[r],
|
|
49
|
+
transition: "transform var(--prui-duration-slow) var(--prui-ease-out)",
|
|
50
|
+
...r === "left" || r === "right" ? { width: typeof o == "number" ? `${o}px` : o ?? "400px" } : { maxHeight: typeof o == "number" ? `${o}px` : o ?? "80vh" },
|
|
51
|
+
...x
|
|
52
|
+
};
|
|
53
|
+
return /* @__PURE__ */ t(E, { children: /* @__PURE__ */ t("div", { ref: T, children: /* @__PURE__ */ t(
|
|
54
|
+
"div",
|
|
55
|
+
{
|
|
56
|
+
className: "prui-drawer-overlay fixed inset-0 z-[var(--prui-z-modal)]",
|
|
57
|
+
style: {
|
|
58
|
+
backgroundColor: "var(--prui-scrim)",
|
|
59
|
+
opacity: p ? 1 : 0,
|
|
60
|
+
transition: "opacity var(--prui-duration-slow) var(--prui-ease-out)"
|
|
61
|
+
},
|
|
62
|
+
onMouseDown: (e) => {
|
|
63
|
+
e.target === e.currentTarget && c(!1);
|
|
64
|
+
},
|
|
65
|
+
children: /* @__PURE__ */ Y(
|
|
66
|
+
"div",
|
|
67
|
+
{
|
|
68
|
+
ref: S,
|
|
69
|
+
role: "dialog",
|
|
70
|
+
"aria-modal": "true",
|
|
71
|
+
"aria-label": w,
|
|
72
|
+
"data-state": p ? "open" : "closed",
|
|
73
|
+
className: P(
|
|
74
|
+
"absolute flex flex-col overflow-y-auto border border-[var(--prui-line)] bg-[var(--prui-surface)]",
|
|
75
|
+
"text-[var(--prui-fg)] shadow-[var(--prui-shadow-modal)] outline-none",
|
|
76
|
+
L[r],
|
|
77
|
+
g
|
|
78
|
+
),
|
|
79
|
+
style: X,
|
|
80
|
+
children: [
|
|
81
|
+
r === "bottom" ? /* @__PURE__ */ t("div", { "aria-hidden": !0, className: "mx-auto mt-2 mb-1 h-1 w-10 shrink-0 rounded-[var(--prui-radius-full)] bg-[var(--prui-line)]" }) : null,
|
|
82
|
+
v,
|
|
83
|
+
y ? null : /* @__PURE__ */ t(
|
|
84
|
+
"button",
|
|
85
|
+
{
|
|
86
|
+
type: "button",
|
|
87
|
+
"aria-label": R.close,
|
|
88
|
+
onClick: () => c(!1),
|
|
89
|
+
className: "absolute right-3 top-3 rounded-[var(--prui-radius-1)] p-1 text-[var(--prui-dim)] transition-colors hover:bg-[var(--prui-raise)] hover:text-[var(--prui-fg)] cursor-pointer",
|
|
90
|
+
children: /* @__PURE__ */ t(k, { className: "h-4 w-4", "aria-hidden": !0 })
|
|
91
|
+
}
|
|
92
|
+
)
|
|
93
|
+
]
|
|
94
|
+
}
|
|
95
|
+
)
|
|
96
|
+
}
|
|
97
|
+
) }) });
|
|
98
|
+
});
|
|
99
|
+
h.displayName = "Drawer";
|
|
100
|
+
const H = a.forwardRef(function(n, i) {
|
|
101
|
+
return /* @__PURE__ */ t(h, { ref: i, side: "bottom", ...n });
|
|
102
|
+
});
|
|
103
|
+
H.displayName = "Sheet";
|
|
104
|
+
const J = {
|
|
105
|
+
name: "Drawer",
|
|
106
|
+
props: [
|
|
107
|
+
{ name: "open", type: "boolean", default: "undefined", control: "boolean" },
|
|
108
|
+
{ name: "defaultOpen", type: "boolean", default: "false", control: "boolean" },
|
|
109
|
+
{ name: "onOpenChange", type: "(open: boolean) => void", default: null, control: "none" },
|
|
110
|
+
{ name: "side", type: "'left' | 'right' | 'top' | 'bottom'", default: "'right'", control: "select", options: ["left", "right", "top", "bottom"] },
|
|
111
|
+
{ name: "size", type: "number | string (CSS length)", default: "400px / 80vh", control: "text" },
|
|
112
|
+
{ name: "ariaLabel", type: "string", default: null, control: "text" },
|
|
113
|
+
{ name: "hideClose", type: "boolean", default: "false", control: "boolean" }
|
|
114
|
+
]
|
|
115
|
+
}, K = {
|
|
116
|
+
name: "Sheet",
|
|
117
|
+
props: [
|
|
118
|
+
{ name: "open", type: "boolean", default: "undefined", control: "boolean" },
|
|
119
|
+
{ name: "onOpenChange", type: "(open: boolean) => void", default: null, control: "none" },
|
|
120
|
+
{ name: "size", type: "number | string (max height)", default: "80vh", control: "text" },
|
|
121
|
+
{ name: "ariaLabel", type: "string", default: null, control: "text" }
|
|
122
|
+
]
|
|
123
|
+
};
|
|
124
|
+
export {
|
|
125
|
+
h as Drawer,
|
|
126
|
+
H as Sheet,
|
|
127
|
+
J as drawerPropsMeta,
|
|
128
|
+
K as sheetPropsMeta
|
|
129
|
+
};
|
package/dist/core/dropdown.d.ts
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { PropsMeta } from './props-meta';
|
|
2
2
|
import * as React from "react";
|
|
3
|
+
/**
|
|
4
|
+
* Dropdown: an anchored menu over a trigger. Full WAI-ARIA menu keyboard
|
|
5
|
+
* support: Enter/Space/ArrowDown open, ArrowUp/Down + Home/End move,
|
|
6
|
+
* printable-character typeahead selects, Escape (topmost overlay only)
|
|
7
|
+
* closes and restores focus to the trigger, Tab closes. Non-modal: no scroll
|
|
8
|
+
* lock and no background inertness.
|
|
9
|
+
*/
|
|
3
10
|
export interface DropdownItem {
|
|
4
11
|
label: string;
|
|
5
12
|
onSelect?: () => void;
|
|
@@ -17,8 +24,5 @@ export interface DropdownProps {
|
|
|
17
24
|
align?: "start" | "end";
|
|
18
25
|
className?: string;
|
|
19
26
|
}
|
|
20
|
-
export declare const Dropdown:
|
|
21
|
-
({ items, trigger, children, open: openProp, defaultOpen, onOpenChange, align, className, }: DropdownProps): React.JSX.Element;
|
|
22
|
-
displayName: string;
|
|
23
|
-
};
|
|
27
|
+
export declare const Dropdown: React.ForwardRefExoticComponent<DropdownProps & React.RefAttributes<HTMLDivElement>>;
|
|
24
28
|
export declare const dropdownPropsMeta: PropsMeta;
|