@skiddph/prui 0.7.0 → 0.9.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 +193 -0
- package/dist/core/date-picker.d.ts +62 -0
- package/dist/core/date-picker.js +314 -0
- package/dist/core/dialog.d.ts +15 -0
- package/dist/core/dialog.js +77 -60
- 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 +23 -1
- 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 +187 -98
- 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/time-picker.d.ts +68 -0
- package/dist/core/time-picker.js +305 -0
- 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 +160 -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 +89 -0
- package/dist/i18n.js +105 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +263 -155
- 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,16 @@
|
|
|
1
|
+
import { PropsMeta } from './props-meta';
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
export interface AccordionProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "onChange"> {
|
|
4
|
+
/** "single" keeps at most one item open; "multiple" allows any number. */
|
|
5
|
+
type?: "single" | "multiple";
|
|
6
|
+
value?: string[];
|
|
7
|
+
defaultValue?: string[];
|
|
8
|
+
onChange?: (openValues: string[]) => void;
|
|
9
|
+
}
|
|
10
|
+
export declare const Accordion: React.ForwardRefExoticComponent<AccordionProps & React.RefAttributes<HTMLDivElement>>;
|
|
11
|
+
export interface AccordionItemProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
12
|
+
value: string;
|
|
13
|
+
disabled?: boolean;
|
|
14
|
+
}
|
|
15
|
+
export declare const AccordionItem: React.ForwardRefExoticComponent<AccordionItemProps & React.RefAttributes<HTMLDivElement>>;
|
|
16
|
+
export declare const accordionPropsMeta: PropsMeta;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { jsx as y, jsxs as k } from "react/jsx-runtime";
|
|
2
|
+
import * as n from "react";
|
|
3
|
+
import { ChevronDown as M } from "lucide-react";
|
|
4
|
+
import { cn as x } from "./cn.js";
|
|
5
|
+
const N = n.createContext(null);
|
|
6
|
+
function O() {
|
|
7
|
+
const f = n.useContext(N);
|
|
8
|
+
if (!f) throw new Error("Accordion parts must be used inside <Accordion>");
|
|
9
|
+
return f;
|
|
10
|
+
}
|
|
11
|
+
const P = n.forwardRef(function({ type: r = "single", value: i, defaultValue: b, onChange: o, className: A, onKeyDown: l, children: h, ...w }, d) {
|
|
12
|
+
const [a, p] = n.useState(b ?? []), u = i !== void 0, s = u ? i : a, [j, R] = n.useState([]), v = n.useRef(/* @__PURE__ */ new Map()), I = (e) => {
|
|
13
|
+
u || p(e), o == null || o(e);
|
|
14
|
+
}, C = (e) => {
|
|
15
|
+
s.includes(e) ? I(s.filter((t) => t !== e)) : I(r === "single" ? [e] : [...s, e]);
|
|
16
|
+
}, E = n.useCallback((e, t) => {
|
|
17
|
+
t ? (v.current.set(e, t), R((c) => c.includes(e) ? c : [...c, e])) : (v.current.delete(e), R((c) => c.filter((m) => m !== e)));
|
|
18
|
+
}, []), D = (e) => {
|
|
19
|
+
if (l == null || l(e), e.defaultPrevented) return;
|
|
20
|
+
const t = j.map((g) => v.current.get(g)).filter((g) => !!g);
|
|
21
|
+
if (!t.length) return;
|
|
22
|
+
const c = t.indexOf(document.activeElement), m = e.key === "ArrowDown" ? 1 : e.key === "ArrowUp" ? -1 : 0;
|
|
23
|
+
if (m !== 0) {
|
|
24
|
+
e.preventDefault(), t[(c + m + t.length) % t.length].focus();
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
e.key === "Home" && (e.preventDefault(), t[0].focus()), e.key === "End" && (e.preventDefault(), t[t.length - 1].focus());
|
|
28
|
+
};
|
|
29
|
+
return /* @__PURE__ */ y(N.Provider, { value: { openItems: s, toggle: C, register: E }, children: /* @__PURE__ */ y(
|
|
30
|
+
"div",
|
|
31
|
+
{
|
|
32
|
+
ref: d,
|
|
33
|
+
onKeyDown: D,
|
|
34
|
+
className: x("prui-accordion flex flex-col gap-2", A),
|
|
35
|
+
"data-type": r,
|
|
36
|
+
...w,
|
|
37
|
+
children: h
|
|
38
|
+
}
|
|
39
|
+
) });
|
|
40
|
+
});
|
|
41
|
+
P.displayName = "Accordion";
|
|
42
|
+
const S = n.forwardRef(function({ value: r, disabled: i, className: b, children: o, ...A }, l) {
|
|
43
|
+
const { openItems: h, toggle: w, register: d } = O(), a = h.includes(r), p = n.useRef(null), u = `prui-accordion-panel-${r}`, s = `prui-accordion-header-${r}`;
|
|
44
|
+
return n.useEffect(() => (d(r, p.current), () => d(r, null)), [r, d]), /* @__PURE__ */ k(
|
|
45
|
+
"div",
|
|
46
|
+
{
|
|
47
|
+
ref: l,
|
|
48
|
+
"data-state": a ? "open" : "closed",
|
|
49
|
+
"data-disabled": i || void 0,
|
|
50
|
+
className: x(
|
|
51
|
+
"prui-accordion-item rounded-[var(--prui-radius)] border border-[var(--prui-line)] bg-[var(--prui-surface)]",
|
|
52
|
+
i && "opacity-50",
|
|
53
|
+
b
|
|
54
|
+
),
|
|
55
|
+
...A,
|
|
56
|
+
children: [
|
|
57
|
+
/* @__PURE__ */ k(
|
|
58
|
+
"button",
|
|
59
|
+
{
|
|
60
|
+
ref: p,
|
|
61
|
+
type: "button",
|
|
62
|
+
id: s,
|
|
63
|
+
"aria-expanded": a,
|
|
64
|
+
"aria-controls": u,
|
|
65
|
+
"aria-disabled": i,
|
|
66
|
+
disabled: i,
|
|
67
|
+
onClick: () => w(r),
|
|
68
|
+
className: x(
|
|
69
|
+
"flex w-full items-center justify-between gap-2 px-4 py-3 text-left text-sm font-medium text-[var(--prui-fg)]",
|
|
70
|
+
"cursor-pointer outline-none focus-visible:ring-2 focus-visible:ring-[var(--prui-brand)] rounded-[var(--prui-radius)]",
|
|
71
|
+
i && "cursor-not-allowed"
|
|
72
|
+
),
|
|
73
|
+
children: [
|
|
74
|
+
o instanceof Array ? o[0] : o,
|
|
75
|
+
/* @__PURE__ */ y(M, { className: x("h-4 w-4 shrink-0 text-[var(--prui-dim)] transition-transform", a && "rotate-180"), "aria-hidden": !0 })
|
|
76
|
+
]
|
|
77
|
+
}
|
|
78
|
+
),
|
|
79
|
+
/* @__PURE__ */ y(
|
|
80
|
+
"div",
|
|
81
|
+
{
|
|
82
|
+
id: u,
|
|
83
|
+
role: "region",
|
|
84
|
+
"aria-labelledby": s,
|
|
85
|
+
hidden: !a,
|
|
86
|
+
className: "prui-accordion-panel px-4 pb-3 text-sm text-[var(--prui-dim)]",
|
|
87
|
+
children: o instanceof Array ? o.slice(1) : null
|
|
88
|
+
}
|
|
89
|
+
)
|
|
90
|
+
]
|
|
91
|
+
}
|
|
92
|
+
);
|
|
93
|
+
});
|
|
94
|
+
S.displayName = "AccordionItem";
|
|
95
|
+
const H = {
|
|
96
|
+
name: "Accordion",
|
|
97
|
+
props: [
|
|
98
|
+
{ name: "type", type: "'single' | 'multiple'", default: "'single'", control: "select", options: ["single", "multiple"] },
|
|
99
|
+
{ name: "value", type: "string[]", default: "undefined", control: "object" },
|
|
100
|
+
{ name: "defaultValue", type: "string[]", default: "[]", control: "object" },
|
|
101
|
+
{ name: "onChange", type: "(openValues: string[]) => void", default: null, control: "none" }
|
|
102
|
+
]
|
|
103
|
+
};
|
|
104
|
+
export {
|
|
105
|
+
P as Accordion,
|
|
106
|
+
S as AccordionItem,
|
|
107
|
+
H as accordionPropsMeta
|
|
108
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { PropsMeta } from './props-meta';
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
/**
|
|
4
|
+
* Alert: an inline callout for status feedback. role maps automatically
|
|
5
|
+
* (alert for danger/warning, status otherwise) so screen readers announce
|
|
6
|
+
* with the right urgency. Optional dismiss button.
|
|
7
|
+
*/
|
|
8
|
+
export type AlertVariant = "neutral" | "info" | "success" | "warning" | "danger";
|
|
9
|
+
export interface AlertProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "title"> {
|
|
10
|
+
variant?: AlertVariant;
|
|
11
|
+
/** Bold first line. */
|
|
12
|
+
title?: React.ReactNode;
|
|
13
|
+
children?: React.ReactNode;
|
|
14
|
+
/** Show a dismiss button; onDismiss controls visibility. */
|
|
15
|
+
onDismiss?: () => void;
|
|
16
|
+
/** Hide the leading icon. */
|
|
17
|
+
hideIcon?: boolean;
|
|
18
|
+
}
|
|
19
|
+
export declare const Alert: React.ForwardRefExoticComponent<AlertProps & React.RefAttributes<HTMLDivElement>>;
|
|
20
|
+
export declare const alertPropsMeta: PropsMeta;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { jsxs as t, jsx as e } from "react/jsx-runtime";
|
|
2
|
+
import * as v from "react";
|
|
3
|
+
import { XCircle as g, AlertTriangle as x, CheckCircle2 as h, Info as i, X as w } from "lucide-react";
|
|
4
|
+
import { cn as l } from "./cn.js";
|
|
5
|
+
import { usePruiI18n as y } from "../i18n.js";
|
|
6
|
+
import { useReducedMotion as N } from "./overlay.js";
|
|
7
|
+
const s = {
|
|
8
|
+
neutral: { icon: i, box: "bg-[var(--prui-raise)] border-[var(--prui-line)] text-[var(--prui-fg)]" },
|
|
9
|
+
info: { icon: i, box: "bg-[var(--prui-brand)]/10 border-[var(--prui-brand)]/30 text-[var(--prui-brand)]" },
|
|
10
|
+
success: { icon: h, box: "bg-[var(--prui-ok)]/10 border-[var(--prui-ok)]/30 text-[var(--prui-ok)]" },
|
|
11
|
+
warning: { icon: x, box: "bg-[var(--prui-warn)]/10 border-[var(--prui-warn)]/30 text-[var(--prui-warn)]" },
|
|
12
|
+
danger: { icon: g, box: "bg-[var(--prui-danger)]/10 border-[var(--prui-danger)]/30 text-[var(--prui-danger)]" }
|
|
13
|
+
}, k = v.forwardRef(
|
|
14
|
+
({ className: u, variant: r = "neutral", title: a, children: n, onDismiss: o, hideIcon: c, ...d }, p) => {
|
|
15
|
+
const { t: m } = y(), b = N(), f = s[r].icon;
|
|
16
|
+
return /* @__PURE__ */ t(
|
|
17
|
+
"div",
|
|
18
|
+
{
|
|
19
|
+
ref: p,
|
|
20
|
+
role: r === "danger" || r === "warning" ? "alert" : "status",
|
|
21
|
+
"data-variant": r,
|
|
22
|
+
className: l(
|
|
23
|
+
"prui-alert flex items-start gap-3 rounded-[var(--prui-radius)] border px-4 py-3 text-sm",
|
|
24
|
+
b ? "" : "prui-anim-fade",
|
|
25
|
+
s[r].box,
|
|
26
|
+
u
|
|
27
|
+
),
|
|
28
|
+
...d,
|
|
29
|
+
children: [
|
|
30
|
+
c ? null : /* @__PURE__ */ e(f, { className: "mt-0.5 h-4 w-4 shrink-0", "aria-hidden": !0 }),
|
|
31
|
+
/* @__PURE__ */ t("div", { className: "min-w-0 flex-1", children: [
|
|
32
|
+
a ? /* @__PURE__ */ e("div", { className: "font-semibold", children: a }) : null,
|
|
33
|
+
n ? /* @__PURE__ */ e("div", { className: l("text-[var(--prui-fg)]", a && "mt-0.5"), children: n }) : null
|
|
34
|
+
] }),
|
|
35
|
+
o ? /* @__PURE__ */ e(
|
|
36
|
+
"button",
|
|
37
|
+
{
|
|
38
|
+
type: "button",
|
|
39
|
+
"aria-label": m.dismiss,
|
|
40
|
+
onClick: o,
|
|
41
|
+
className: "-m-1 rounded-[var(--prui-radius-1)] p-1 cursor-pointer opacity-70 transition-opacity hover:opacity-100 focus-visible:outline focus-visible:outline-2 focus-visible:outline-[var(--prui-brand)]",
|
|
42
|
+
children: /* @__PURE__ */ e(w, { className: "h-4 w-4", "aria-hidden": !0 })
|
|
43
|
+
}
|
|
44
|
+
) : null
|
|
45
|
+
]
|
|
46
|
+
}
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
);
|
|
50
|
+
k.displayName = "Alert";
|
|
51
|
+
const P = {
|
|
52
|
+
name: "Alert",
|
|
53
|
+
props: [
|
|
54
|
+
{ name: "variant", type: "'neutral' | 'info' | 'success' | 'warning' | 'danger'", default: "'neutral'", control: "select", options: ["neutral", "info", "success", "warning", "danger"] },
|
|
55
|
+
{ name: "title", type: "ReactNode", default: null, control: "text" },
|
|
56
|
+
{ name: "onDismiss", type: "() => void", default: null, control: "none" },
|
|
57
|
+
{ name: "hideIcon", type: "boolean", default: "false", control: "boolean" }
|
|
58
|
+
]
|
|
59
|
+
};
|
|
60
|
+
export {
|
|
61
|
+
k as Alert,
|
|
62
|
+
P as alertPropsMeta
|
|
63
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Anchor positioning for portaled floating surfaces (Tooltip, Popover,
|
|
4
|
+
* DatePicker, Combobox): position an absolutely-placed element relative to
|
|
5
|
+
* a trigger's bounding rect, flipping/clamping to the viewport. Re-computes
|
|
6
|
+
* on scroll and resize.
|
|
7
|
+
*/
|
|
8
|
+
export type AnchorSide = "top" | "bottom" | "left" | "right";
|
|
9
|
+
export type AnchorAlign = "start" | "center" | "end";
|
|
10
|
+
export interface AnchoredPosition {
|
|
11
|
+
top: number;
|
|
12
|
+
left: number;
|
|
13
|
+
/** The side actually used after viewport flipping. */
|
|
14
|
+
side: AnchorSide;
|
|
15
|
+
}
|
|
16
|
+
export declare function computePosition(anchor: DOMRect, floatingSize: {
|
|
17
|
+
width: number;
|
|
18
|
+
height: number;
|
|
19
|
+
}, side: AnchorSide, align?: AnchorAlign): AnchoredPosition;
|
|
20
|
+
/**
|
|
21
|
+
* Tracks a floating element's position against its anchor. Returns the ref
|
|
22
|
+
* for the floating element and the current position (null before measure).
|
|
23
|
+
* Recomputes on scroll/resize while active.
|
|
24
|
+
*/
|
|
25
|
+
export declare function useAnchoredPosition({ active, anchorRef, side, align, offsetHeight, offsetWidth, }: {
|
|
26
|
+
active: boolean;
|
|
27
|
+
anchorRef: React.RefObject<HTMLElement | null>;
|
|
28
|
+
side?: AnchorSide;
|
|
29
|
+
align?: AnchorAlign;
|
|
30
|
+
offsetHeight?: number;
|
|
31
|
+
offsetWidth?: number;
|
|
32
|
+
}): {
|
|
33
|
+
ref: (el: HTMLElement | null) => void;
|
|
34
|
+
position: AnchoredPosition | null;
|
|
35
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import * as m from "react";
|
|
2
|
+
const r = 8, s = 8;
|
|
3
|
+
function v(t, e, o, w = "start") {
|
|
4
|
+
const d = window.innerWidth, l = window.innerHeight;
|
|
5
|
+
let n = o, u, h;
|
|
6
|
+
const i = w === "start" ? 0 : w === "end" ? 1 : 0.5;
|
|
7
|
+
return o === "top" || o === "bottom" ? (o === "bottom" && t.bottom + r + e.height > l - s && (n = "top"), o === "top" && t.top - r - e.height < s && (n = "bottom"), u = n === "bottom" ? t.bottom + r : t.top - r - e.height, h = t.left + (t.width - e.width) * i) : (o === "right" && t.right + r + e.width > d - s && (n = "left"), o === "left" && t.left - r - e.width < s && (n = "right"), h = n === "right" ? t.right + r : t.left - r - e.width, u = t.top + (t.height - e.height) * i), h = Math.max(s, Math.min(h, d - e.width - s)), u = Math.max(s, Math.min(u, l - e.height - s)), { top: u, left: h, side: n };
|
|
8
|
+
}
|
|
9
|
+
function g({
|
|
10
|
+
active: t,
|
|
11
|
+
anchorRef: e,
|
|
12
|
+
side: o = "bottom",
|
|
13
|
+
align: w = "start",
|
|
14
|
+
offsetHeight: d,
|
|
15
|
+
offsetWidth: l
|
|
16
|
+
}) {
|
|
17
|
+
const [n, u] = m.useState(null), [h, c] = m.useState(null), i = m.useCallback(() => {
|
|
18
|
+
const f = e.current;
|
|
19
|
+
if (!f || !n) return;
|
|
20
|
+
const p = l ?? n.offsetWidth ?? 160, b = d ?? n.offsetHeight ?? 200;
|
|
21
|
+
c(v(f.getBoundingClientRect(), { width: p, height: b }, o, w));
|
|
22
|
+
}, [e, n, o, w, d, l]);
|
|
23
|
+
return m.useEffect(() => {
|
|
24
|
+
if (!t) {
|
|
25
|
+
c(null);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
if (i(), !(typeof window > "u"))
|
|
29
|
+
return window.addEventListener("scroll", i, !0), window.addEventListener("resize", i), () => {
|
|
30
|
+
window.removeEventListener("scroll", i, !0), window.removeEventListener("resize", i);
|
|
31
|
+
};
|
|
32
|
+
}, [t, i]), { ref: m.useCallback((f) => {
|
|
33
|
+
u(f);
|
|
34
|
+
}, []), position: h };
|
|
35
|
+
}
|
|
36
|
+
export {
|
|
37
|
+
v as computePosition,
|
|
38
|
+
g as useAnchoredPosition
|
|
39
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { PropsMeta } from './props-meta';
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
/**
|
|
4
|
+
* Breadcrumb: a nav/ol/li trail with separators and optional collapsed
|
|
5
|
+
* overflow. Current page carries aria-current="page".
|
|
6
|
+
*/
|
|
7
|
+
export interface BreadcrumbProps extends React.HTMLAttributes<HTMLElement> {
|
|
8
|
+
/** Accessible label for the nav landmark. */
|
|
9
|
+
label?: string;
|
|
10
|
+
/** Collapse the middle of long trails behind an ellipsis item. */
|
|
11
|
+
collapseAfter?: number;
|
|
12
|
+
/** What the ellipsis expands to. */
|
|
13
|
+
onExpand?: () => void;
|
|
14
|
+
children?: React.ReactNode;
|
|
15
|
+
}
|
|
16
|
+
export declare const Breadcrumb: React.ForwardRefExoticComponent<BreadcrumbProps & React.RefAttributes<HTMLElement>>;
|
|
17
|
+
export interface BreadcrumbItemProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
18
|
+
/** Route destination; omit for the current (plain text) page. */
|
|
19
|
+
href?: string;
|
|
20
|
+
/** Mark as the current page (adds aria-current). */
|
|
21
|
+
current?: boolean;
|
|
22
|
+
}
|
|
23
|
+
export declare const BreadcrumbItem: React.ForwardRefExoticComponent<BreadcrumbItemProps & React.RefAttributes<HTMLDivElement>>;
|
|
24
|
+
export declare const BreadcrumbEllipsis: {
|
|
25
|
+
({ onExpand }: {
|
|
26
|
+
onExpand?: () => void;
|
|
27
|
+
}): React.JSX.Element;
|
|
28
|
+
displayName: string;
|
|
29
|
+
};
|
|
30
|
+
export declare const breadcrumbPropsMeta: PropsMeta;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { jsx as e, jsxs as b } from "react/jsx-runtime";
|
|
2
|
+
import * as n from "react";
|
|
3
|
+
import { ChevronRight as v, MoreHorizontal as x } from "lucide-react";
|
|
4
|
+
import { Link as g } from "react-router-dom";
|
|
5
|
+
import { cn as p } from "./cn.js";
|
|
6
|
+
import { usePruiI18n as N } from "../i18n.js";
|
|
7
|
+
const y = n.forwardRef(function({ label: i, collapseAfter: r, onExpand: s, className: t, children: l, ...u }, h) {
|
|
8
|
+
const a = n.Children.toArray(l);
|
|
9
|
+
let m = a;
|
|
10
|
+
if (r != null && a.length > r + 1) {
|
|
11
|
+
const c = a.slice(0, 1), d = a.slice(a.length - r);
|
|
12
|
+
m = [
|
|
13
|
+
...c,
|
|
14
|
+
/* @__PURE__ */ e(f, { onExpand: s }, "ellipsis"),
|
|
15
|
+
...d
|
|
16
|
+
];
|
|
17
|
+
}
|
|
18
|
+
return /* @__PURE__ */ e("nav", { ref: h, "aria-label": i ?? "Breadcrumb", className: p("prui-breadcrumb", t), ...u, children: /* @__PURE__ */ e("ol", { className: "flex flex-wrap items-center gap-1.5 text-sm text-[var(--prui-dim)]", children: n.Children.map(m, (c, d) => /* @__PURE__ */ b("li", { className: "flex items-center gap-1.5", children: [
|
|
19
|
+
c,
|
|
20
|
+
d < m.length - 1 ? /* @__PURE__ */ e(v, { className: "h-3.5 w-3.5 shrink-0", "aria-hidden": !0 }) : null
|
|
21
|
+
] })) }) });
|
|
22
|
+
});
|
|
23
|
+
y.displayName = "Breadcrumb";
|
|
24
|
+
const B = n.forwardRef(function({ href: i, current: r, className: s, children: t, ...l }, u) {
|
|
25
|
+
return /* @__PURE__ */ e("div", { ref: u, className: p("prui-breadcrumb-item", s), ...l, children: i ? /* @__PURE__ */ e(
|
|
26
|
+
g,
|
|
27
|
+
{
|
|
28
|
+
to: i,
|
|
29
|
+
"aria-current": r ? "page" : void 0,
|
|
30
|
+
className: "cursor-pointer transition-colors hover:text-[var(--prui-fg)] focus-visible:outline focus-visible:outline-2 focus-visible:outline-[var(--prui-brand)] rounded-[var(--prui-radius-1)]",
|
|
31
|
+
children: t
|
|
32
|
+
}
|
|
33
|
+
) : /* @__PURE__ */ e("span", { "aria-current": r ? "page" : void 0, className: p(r && "font-medium text-[var(--prui-fg)]"), children: t }) });
|
|
34
|
+
});
|
|
35
|
+
B.displayName = "BreadcrumbItem";
|
|
36
|
+
const f = ({ onExpand: o }) => {
|
|
37
|
+
const { t: i } = N();
|
|
38
|
+
return /* @__PURE__ */ b(
|
|
39
|
+
"button",
|
|
40
|
+
{
|
|
41
|
+
type: "button",
|
|
42
|
+
"aria-label": "Show more breadcrumbs",
|
|
43
|
+
onClick: o,
|
|
44
|
+
className: "flex h-6 w-6 cursor-pointer items-center justify-center rounded-[var(--prui-radius-1)] text-[var(--prui-dim)] transition-colors hover:text-[var(--prui-fg)] focus-visible:outline focus-visible:outline-2 focus-visible:outline-[var(--prui-brand)]",
|
|
45
|
+
children: [
|
|
46
|
+
/* @__PURE__ */ e(x, { className: "h-4 w-4", "aria-hidden": !0 }),
|
|
47
|
+
/* @__PURE__ */ e("span", { className: "sr-only", children: i.of })
|
|
48
|
+
]
|
|
49
|
+
}
|
|
50
|
+
);
|
|
51
|
+
};
|
|
52
|
+
f.displayName = "BreadcrumbEllipsis";
|
|
53
|
+
const j = {
|
|
54
|
+
name: "Breadcrumb",
|
|
55
|
+
props: [
|
|
56
|
+
{ name: "label", type: "string", default: "'Breadcrumb'", control: "text" },
|
|
57
|
+
{ name: "collapseAfter", type: "number", default: "undefined", control: "number", description: "Collapse the middle items behind an ellipsis, keeping this many at the end." },
|
|
58
|
+
{ name: "onExpand", type: "() => void", default: null, control: "none" },
|
|
59
|
+
{ name: "children", type: "BreadcrumbItem[]", default: null, control: "none" }
|
|
60
|
+
]
|
|
61
|
+
};
|
|
62
|
+
export {
|
|
63
|
+
y as Breadcrumb,
|
|
64
|
+
f as BreadcrumbEllipsis,
|
|
65
|
+
B as BreadcrumbItem,
|
|
66
|
+
j as breadcrumbPropsMeta
|
|
67
|
+
};
|
package/dist/core/button.d.ts
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import { PropsMeta } from './props-meta';
|
|
2
2
|
import { SurfaceProps } from './surface';
|
|
3
3
|
import * as React from "react";
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Button variants. The shared PRUI vocabulary is
|
|
6
|
+
* primary / secondary / neutral / danger / success / warning (plus the
|
|
7
|
+
* stylistic ghost / outline / soft / link kept from the original API).
|
|
8
|
+
* Legacy names keep working: `default` = secondary, and soft-colored
|
|
9
|
+
* success/warning map to their token colors.
|
|
10
|
+
*/
|
|
11
|
+
export type ButtonVariant = "primary" | "secondary" | "default" | "neutral" | "ghost" | "danger" | "success" | "warning" | "outline" | "soft" | "link";
|
|
5
12
|
export type ButtonSize = "sm" | "md" | "lg" | "icon";
|
|
6
13
|
export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, SurfaceProps {
|
|
7
14
|
variant?: ButtonVariant;
|
package/dist/core/button.js
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
import { jsx as n, jsxs as j, Fragment as B } from "react/jsx-runtime";
|
|
2
|
-
import * as
|
|
2
|
+
import * as s from "react";
|
|
3
3
|
import { Loader2 as R } from "lucide-react";
|
|
4
4
|
import { cn as i } from "./cn.js";
|
|
5
5
|
import { resolveSurface as z, withSurface as E } from "./surface.js";
|
|
6
6
|
const F = {
|
|
7
7
|
primary: "bg-[var(--prui-s-bg,var(--prui-brand))] text-[var(--prui-s-fg,var(--prui-brand-fg))] hover:brightness-110 active:brightness-95",
|
|
8
|
+
secondary: "bg-[var(--prui-s-bg,var(--prui-raise))] text-[var(--prui-s-fg,var(--prui-fg))] border border-[var(--prui-line)] hover:border-[var(--prui-dim)]",
|
|
9
|
+
// legacy alias of secondary
|
|
8
10
|
default: "bg-[var(--prui-s-bg,var(--prui-raise))] text-[var(--prui-s-fg,var(--prui-fg))] border border-[var(--prui-line)] hover:border-[var(--prui-dim)]",
|
|
11
|
+
neutral: "bg-[var(--prui-s-bg,transparent)] text-[var(--prui-s-fg,var(--prui-fg))] border border-[var(--prui-line)] hover:bg-[var(--prui-raise)]",
|
|
9
12
|
ghost: "bg-[var(--prui-s-bg,transparent)] text-[var(--prui-s-fg,var(--prui-fg))] hover:bg-[var(--prui-raise)]",
|
|
10
13
|
danger: "bg-[var(--prui-s-bg,var(--prui-danger))] text-[var(--prui-s-fg,#fff)] hover:brightness-110 active:brightness-95",
|
|
14
|
+
success: "bg-[var(--prui-s-bg,var(--prui-ok))] text-[var(--prui-s-fg,#fff)] hover:brightness-110 active:brightness-95",
|
|
15
|
+
warning: "bg-[var(--prui-s-bg,var(--prui-warn))] text-[var(--prui-s-fg,#fff)] hover:brightness-110 active:brightness-95",
|
|
11
16
|
outline: "bg-[var(--prui-s-bg,transparent)] text-[var(--prui-s-fg,var(--prui-brand))] border border-[var(--prui-s-border,var(--prui-brand))] hover:bg-[var(--prui-brand)]/10",
|
|
12
17
|
soft: "bg-[var(--prui-brand)]/12 text-[var(--prui-s-fg,var(--prui-brand))] hover:bg-[var(--prui-brand)]/20",
|
|
13
18
|
link: "bg-transparent text-[var(--prui-s-fg,var(--prui-brand))] underline-offset-4 hover:underline p-0"
|
|
@@ -16,31 +21,31 @@ const F = {
|
|
|
16
21
|
md: "h-9 px-3.5 text-sm gap-2",
|
|
17
22
|
lg: "h-11 px-5 text-base gap-2",
|
|
18
23
|
icon: "h-9 w-9 p-0"
|
|
19
|
-
}, M =
|
|
20
|
-
({ className: u, style:
|
|
21
|
-
const
|
|
24
|
+
}, M = s.forwardRef(
|
|
25
|
+
({ className: u, style: p, variant: d = "default", size: f = "md", asChild: g = !1, loading: r = !1, disabled: b, unstyled: v, fullWidth: c, bg: m, fg: h, radius: x, texture: y, textureColor: w, elevation: N, children: e, ...o }, S) => {
|
|
26
|
+
const k = z({ bg: m, fg: h, radius: x, texture: y, textureColor: w, elevation: N }), C = i(
|
|
22
27
|
"prui-button inline-flex items-center justify-center whitespace-nowrap font-medium select-none",
|
|
23
28
|
"transition-[filter,background-color,border-color] duration-150 outline-none cursor-pointer",
|
|
24
29
|
"focus-visible:ring-2 focus-visible:ring-[var(--prui-brand)] focus-visible:ring-offset-1",
|
|
25
30
|
"disabled:pointer-events-none disabled:opacity-50",
|
|
26
|
-
|
|
31
|
+
c && "w-full",
|
|
27
32
|
"rounded-[var(--prui-s-radius,var(--prui-radius))]",
|
|
28
|
-
|
|
33
|
+
v ? [] : [F[d], L[f]],
|
|
29
34
|
u
|
|
30
|
-
),
|
|
31
|
-
if (
|
|
32
|
-
const
|
|
33
|
-
return
|
|
34
|
-
className: i(
|
|
35
|
-
style: { ...
|
|
36
|
-
...
|
|
37
|
-
children:
|
|
35
|
+
), a = E(C, p, k);
|
|
36
|
+
if (g && s.isValidElement(e)) {
|
|
37
|
+
const t = e;
|
|
38
|
+
return s.cloneElement(t, {
|
|
39
|
+
className: i(a.className, t.props.className),
|
|
40
|
+
style: { ...a.style ?? {}, ...t.props.style },
|
|
41
|
+
...o,
|
|
42
|
+
children: r ? /* @__PURE__ */ n(l, {}) : t.props.children
|
|
38
43
|
});
|
|
39
44
|
}
|
|
40
|
-
return /* @__PURE__ */ n("button", { ref: S, className:
|
|
45
|
+
return /* @__PURE__ */ n("button", { ref: S, className: a.className, style: a.style, disabled: b || r, "data-loading": r || void 0, ...o, children: r ? /* @__PURE__ */ j(B, { children: [
|
|
41
46
|
/* @__PURE__ */ n(l, {}),
|
|
42
|
-
|
|
43
|
-
] }) :
|
|
47
|
+
e
|
|
48
|
+
] }) : e });
|
|
44
49
|
}
|
|
45
50
|
);
|
|
46
51
|
M.displayName = "Button";
|
|
@@ -50,7 +55,7 @@ function l() {
|
|
|
50
55
|
const A = {
|
|
51
56
|
name: "Button",
|
|
52
57
|
props: [
|
|
53
|
-
{ name: "variant", type: "'primary' | '
|
|
58
|
+
{ name: "variant", type: "'primary' | 'secondary' | 'neutral' | 'ghost' | 'danger' | 'success' | 'warning' | 'outline' | 'soft' | 'link' | 'default'", default: "'default' (secondary)", control: "select", options: ["primary", "secondary", "neutral", "ghost", "danger", "success", "warning", "outline", "soft", "link", "default"] },
|
|
54
59
|
{ name: "size", type: "'sm' | 'md' | 'lg' | 'icon'", default: "'md'", control: "select", options: ["sm", "md", "lg", "icon"] },
|
|
55
60
|
{ name: "asChild", type: "boolean", default: "false", control: "boolean" },
|
|
56
61
|
{ name: "loading", type: "boolean", default: "false", control: "boolean" },
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { PropsMeta } from './props-meta';
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
/**
|
|
4
|
+
* Calendar: a month grid picker with full keyboard support on the grid
|
|
5
|
+
* (arrows move by day/week, Home/End jump to week edges, PageUp/PageDown
|
|
6
|
+
* change months, Enter/Space pick) and accessible table semantics
|
|
7
|
+
* (role=grid/gridcell/row, aria-selected, aria-current for today).
|
|
8
|
+
* Dates are plain "YYYY-MM-DD" strings — no date library.
|
|
9
|
+
*/
|
|
10
|
+
export interface CalendarProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "onSelect" | "value" | "defaultValue"> {
|
|
11
|
+
/** Selected day, "YYYY-MM-DD". */
|
|
12
|
+
value?: string;
|
|
13
|
+
defaultValue?: string;
|
|
14
|
+
onSelect?: (date: string) => void;
|
|
15
|
+
/** The month in view, "YYYY-MM"; omit to follow the selection/today. */
|
|
16
|
+
month?: string;
|
|
17
|
+
onMonthChange?: (month: string) => void;
|
|
18
|
+
min?: string;
|
|
19
|
+
max?: string;
|
|
20
|
+
disabled?: (date: string) => boolean;
|
|
21
|
+
/** Show the Today shortcut button. Default true. */
|
|
22
|
+
showToday?: boolean;
|
|
23
|
+
/** First day of week. Default 0 (Sunday). */
|
|
24
|
+
weekStartsOn?: 0 | 1;
|
|
25
|
+
}
|
|
26
|
+
export declare function toDateKey(d: Date): string;
|
|
27
|
+
export declare function fromDateKey(key: string): Date;
|
|
28
|
+
export declare const Calendar: React.ForwardRefExoticComponent<CalendarProps & React.RefAttributes<HTMLDivElement>>;
|
|
29
|
+
export declare const calendarPropsMeta: PropsMeta;
|