@devalok/shilp-sutra 0.53.0 → 0.54.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/AGENTS.md +7 -1
- package/BREAKING.json +29 -0
- package/MIGRATION.md +55 -0
- package/dist/composed/avatar-group.d.ts +11 -9
- package/dist/composed/avatar-group.d.ts.map +1 -1
- package/dist/composed/avatar-group.js +108 -140
- package/dist/composed/avatar-group.js.map +1 -1
- package/dist/composed/bulk-action-bar.d.ts +19 -11
- package/dist/composed/bulk-action-bar.d.ts.map +1 -1
- package/dist/composed/bulk-action-bar.js +81 -110
- package/dist/composed/bulk-action-bar.js.map +1 -1
- package/dist/composed/error-boundary.d.ts +15 -3
- package/dist/composed/error-boundary.d.ts.map +1 -1
- package/dist/composed/error-boundary.js +43 -26
- package/dist/composed/error-boundary.js.map +1 -1
- package/dist/composed/loading-skeleton.d.ts +2 -0
- package/dist/composed/loading-skeleton.d.ts.map +1 -1
- package/dist/composed/loading-skeleton.js +79 -56
- package/dist/composed/loading-skeleton.js.map +1 -1
- package/dist/composed/master-detail.d.ts +21 -8
- package/dist/composed/master-detail.d.ts.map +1 -1
- package/dist/composed/master-detail.js +91 -77
- package/dist/composed/master-detail.js.map +1 -1
- package/dist/composed/page-skeletons.d.ts +6 -0
- package/dist/composed/page-skeletons.d.ts.map +1 -1
- package/dist/composed/page-skeletons.js +93 -71
- package/dist/composed/page-skeletons.js.map +1 -1
- package/dist/shell/index.d.ts +5 -3
- package/dist/shell/index.d.ts.map +1 -1
- package/dist/shell/index.js +2 -3
- package/dist/shell/notification-preferences.d.ts.map +1 -1
- package/dist/shell/notification-preferences.js +2 -0
- package/dist/shell/notification-preferences.js.map +1 -1
- package/dist/ui/combobox.d.ts +1 -1
- package/dist/ui/combobox.d.ts.map +1 -1
- package/dist/ui/combobox.js +133 -128
- package/dist/ui/combobox.js.map +1 -1
- package/dist/ui/file-upload.d.ts.map +1 -1
- package/dist/ui/file-upload.js +124 -138
- package/dist/ui/file-upload.js.map +1 -1
- package/dist/ui/form.d.ts +7 -0
- package/dist/ui/form.d.ts.map +1 -1
- package/dist/ui/form.js +4 -2
- package/dist/ui/form.js.map +1 -1
- package/dist/ui/icon-button.d.ts +2 -1
- package/dist/ui/icon-button.d.ts.map +1 -1
- package/dist/ui/icon-button.js +1 -1
- package/dist/ui/icon-button.js.map +1 -1
- package/dist/ui/label.d.ts.map +1 -1
- package/dist/ui/label.js +7 -6
- package/dist/ui/label.js.map +1 -1
- package/dist/ui/spinner.d.ts.map +1 -1
- package/dist/ui/spinner.js +50 -44
- package/dist/ui/spinner.js.map +1 -1
- package/dist/ui/switch.d.ts.map +1 -1
- package/dist/ui/switch.js +24 -24
- package/dist/ui/switch.js.map +1 -1
- package/dist/ui/table.js +1 -1
- package/dist/ui/table.js.map +1 -1
- package/docs/components/composed/bulk-action-bar.md +9 -3
- package/docs/components/composed/error-boundary.md +18 -2
- package/docs/components/composed/master-detail.md +12 -2
- package/docs/components/composed/page-skeletons.md +2 -2
- package/docs/components/composed/rich-chat-input.md +18 -6
- package/docs/components/composed/simple-tooltip.md +1 -1
- package/docs/components/shell/app-command-palette.md +2 -1
- package/docs/components/shell/bottom-navbar.md +4 -4
- package/docs/components/shell/command-registry.md +2 -2
- package/docs/components/shell/link-context.md +2 -2
- package/docs/components/shell/top-bar.md +1 -1
- package/docs/components/ui/search-input.md +2 -2
- package/docs/components/ui/slider.md +2 -2
- package/docs/components/ui/split-button.md +3 -3
- package/llms.txt +2 -2
- package/make-kit/Guidelines.md +1 -1
- package/make-kit/components/overview.md +2 -2
- package/make-kit/foundations/surfaces.md +1 -1
- package/mcp-manifest.json +403 -147
- package/package.json +1 -6
- package/skill/SKILL.md +1 -1
- package/skill/chat-skill/README.md +18 -0
- package/skill/chat-skill/SKILL.md +78 -0
- package/skill/chat-skill/chatgpt-instructions.md +26 -0
- package/skill/chat-skill/gemini-instructions.md +25 -0
- package/skill/references/components.md +2 -2
- package/dist/shell/sidebar.d.ts +0 -113
- package/dist/shell/sidebar.d.ts.map +0 -1
- package/dist/shell/sidebar.js +0 -293
- package/dist/shell/sidebar.js.map +0 -1
- package/docs/components/shell/sidebar.md +0 -103
|
@@ -8,152 +8,123 @@ import * as a from "react";
|
|
|
8
8
|
import { jsx as o, jsxs as s } from "react/jsx-runtime";
|
|
9
9
|
import { createPortal as c } from "react-dom";
|
|
10
10
|
import { IconX as l } from "@tabler/icons-react";
|
|
11
|
-
import { AnimatePresence as u, motion as d } from "framer-motion";
|
|
11
|
+
import { AnimatePresence as u, motion as d, useReducedMotion as f } from "framer-motion";
|
|
12
12
|
//#region src/composed/bulk-action-bar.tsx
|
|
13
|
-
var
|
|
14
|
-
let [
|
|
15
|
-
return c ? /* @__PURE__ */ s(d.div, {
|
|
16
|
-
ref: r,
|
|
17
|
-
initial: {
|
|
18
|
-
opacity: 0,
|
|
19
|
-
scale: .95
|
|
20
|
-
},
|
|
21
|
-
animate: {
|
|
22
|
-
opacity: 1,
|
|
23
|
-
scale: 1
|
|
24
|
-
},
|
|
25
|
-
exit: {
|
|
26
|
-
opacity: 0,
|
|
27
|
-
scale: .95
|
|
28
|
-
},
|
|
29
|
-
transition: e.snappy,
|
|
30
|
-
className: "flex items-center gap-ds-02",
|
|
31
|
-
tabIndex: n,
|
|
32
|
-
children: [
|
|
33
|
-
/* @__PURE__ */ o("span", {
|
|
34
|
-
className: "text-body-sm text-surface-fg-muted whitespace-nowrap",
|
|
35
|
-
children: t.confirmMessage ?? "Are you sure?"
|
|
36
|
-
}),
|
|
37
|
-
/* @__PURE__ */ o(i, {
|
|
38
|
-
variant: "solid",
|
|
39
|
-
size: "sm",
|
|
40
|
-
color: "error",
|
|
41
|
-
onClick: () => {
|
|
42
|
-
l(!1), t.onClick();
|
|
43
|
-
},
|
|
44
|
-
children: "Confirm"
|
|
45
|
-
}),
|
|
46
|
-
/* @__PURE__ */ o(i, {
|
|
47
|
-
variant: "ghost",
|
|
48
|
-
size: "sm",
|
|
49
|
-
onClick: () => l(!1),
|
|
50
|
-
children: "Cancel"
|
|
51
|
-
})
|
|
52
|
-
]
|
|
53
|
-
}) : /* @__PURE__ */ o(d.div, {
|
|
54
|
-
ref: r,
|
|
55
|
-
initial: {
|
|
56
|
-
opacity: 0,
|
|
57
|
-
scale: .95
|
|
58
|
-
},
|
|
59
|
-
animate: {
|
|
60
|
-
opacity: 1,
|
|
61
|
-
scale: 1
|
|
62
|
-
},
|
|
63
|
-
exit: {
|
|
64
|
-
opacity: 0,
|
|
65
|
-
scale: .95
|
|
66
|
-
},
|
|
67
|
-
transition: e.snappy,
|
|
68
|
-
tabIndex: n,
|
|
69
|
-
children: /* @__PURE__ */ o(i, {
|
|
70
|
-
variant: "ghost",
|
|
71
|
-
size: "sm",
|
|
72
|
-
color: t.color === "error" ? "error" : "accent",
|
|
73
|
-
disabled: t.disabled,
|
|
74
|
-
onClick: t.requiresConfirmation ? () => l(!0) : t.onClick,
|
|
75
|
-
startIcon: t.icon ?? void 0,
|
|
76
|
-
tabIndex: -1,
|
|
77
|
-
children: t.label
|
|
78
|
-
})
|
|
79
|
-
});
|
|
80
|
-
});
|
|
81
|
-
function p({ show: p, count: m, onClearSelection: h, actions: g, totalCount: _, onSelectAll: v, className: y }) {
|
|
82
|
-
let [b, x] = a.useState(!1), [S, C] = a.useState(0), w = a.useRef([]);
|
|
13
|
+
var p = a.forwardRef(function({ show: p, count: m, onClearSelection: h, actions: g, totalCount: _, onSelectAll: v, className: y, ...b }, x) {
|
|
14
|
+
let S = f(), [C, w] = a.useState(!1), [T, E] = a.useState(0), [D, O] = a.useState(null), k = a.useRef([]), A = a.useRef(null), j = _ != null && _ > m && !!v, M = +!!j, N = M + g.length + 1;
|
|
83
15
|
a.useEffect(() => {
|
|
84
|
-
|
|
16
|
+
w(!0);
|
|
17
|
+
}, []), a.useEffect(() => {
|
|
18
|
+
E(0), O(null);
|
|
85
19
|
}, [g.length]), a.useEffect(() => {
|
|
86
|
-
|
|
87
|
-
}, []);
|
|
88
|
-
|
|
20
|
+
D != null && A.current?.focus();
|
|
21
|
+
}, [D]);
|
|
22
|
+
let P = (e) => {
|
|
23
|
+
let t = (e + N) % N;
|
|
24
|
+
E(t), k.current[t]?.focus();
|
|
25
|
+
};
|
|
26
|
+
function F(e) {
|
|
89
27
|
if (e.key === "Escape") {
|
|
90
|
-
e.preventDefault(), h();
|
|
28
|
+
e.preventDefault(), D == null ? h() : (O(null), P(T));
|
|
91
29
|
return;
|
|
92
30
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
e.preventDefault();
|
|
97
|
-
let n = (S + 1) % t;
|
|
98
|
-
C(n), w.current[n]?.focus();
|
|
99
|
-
} else if (e.key === "ArrowLeft") {
|
|
100
|
-
e.preventDefault();
|
|
101
|
-
let n = (S - 1 + t) % t;
|
|
102
|
-
C(n), w.current[n]?.focus();
|
|
103
|
-
} else if (e.key === "Home") e.preventDefault(), C(0), w.current[0]?.focus();
|
|
104
|
-
else if (e.key === "End") {
|
|
105
|
-
e.preventDefault();
|
|
106
|
-
let n = t - 1;
|
|
107
|
-
C(n), w.current[n]?.focus();
|
|
108
|
-
}
|
|
109
|
-
}
|
|
31
|
+
if (D != null) return;
|
|
32
|
+
let t = e.currentTarget.dir === "rtl" || document.dir === "rtl", n = t ? "ArrowLeft" : "ArrowRight", r = t ? "ArrowRight" : "ArrowLeft";
|
|
33
|
+
e.key === n ? (e.preventDefault(), P(T + 1)) : e.key === r ? (e.preventDefault(), P(T - 1)) : e.key === "Home" ? (e.preventDefault(), P(0)) : e.key === "End" && (e.preventDefault(), P(N - 1));
|
|
110
34
|
}
|
|
111
|
-
|
|
112
|
-
|
|
35
|
+
if (!C) return null;
|
|
36
|
+
let I = S ? { duration: 0 } : e.smooth;
|
|
37
|
+
return c(/* @__PURE__ */ o(u, { children: p && /* @__PURE__ */ s(d.div, {
|
|
38
|
+
ref: x,
|
|
39
|
+
initial: S ? { opacity: 0 } : {
|
|
113
40
|
y: 100,
|
|
114
41
|
opacity: 0
|
|
115
42
|
},
|
|
116
|
-
animate: {
|
|
43
|
+
animate: S ? { opacity: 1 } : {
|
|
117
44
|
y: 0,
|
|
118
45
|
opacity: 1
|
|
119
46
|
},
|
|
120
|
-
exit: {
|
|
47
|
+
exit: S ? { opacity: 0 } : {
|
|
121
48
|
y: 100,
|
|
122
49
|
opacity: 0
|
|
123
50
|
},
|
|
124
|
-
transition:
|
|
125
|
-
className: t("fixed bottom-ds-06
|
|
51
|
+
transition: I,
|
|
52
|
+
className: t("fixed bottom-ds-06 start-1/2 z-sticky -translate-x-1/2", "flex items-center gap-ds-04 rounded-surface bg-surface-overlay px-ds-05 py-ds-03 shadow-floating", y),
|
|
126
53
|
role: "toolbar",
|
|
127
54
|
"aria-label": `${m} items selected`,
|
|
128
|
-
onKeyDown:
|
|
55
|
+
onKeyDown: F,
|
|
56
|
+
...b,
|
|
129
57
|
children: [
|
|
130
58
|
/* @__PURE__ */ s(r, {
|
|
131
59
|
variant: "solid",
|
|
132
60
|
size: "sm",
|
|
133
61
|
children: [m, " selected"]
|
|
134
62
|
}),
|
|
135
|
-
|
|
63
|
+
j && /* @__PURE__ */ s(i, {
|
|
64
|
+
ref: (e) => {
|
|
65
|
+
k.current[0] = e;
|
|
66
|
+
},
|
|
136
67
|
variant: "link",
|
|
137
68
|
size: "xs",
|
|
69
|
+
tabIndex: T === 0 ? 0 : -1,
|
|
138
70
|
onClick: v,
|
|
139
71
|
children: ["Select all ", _]
|
|
140
72
|
}),
|
|
141
73
|
/* @__PURE__ */ o("div", {
|
|
142
74
|
className: "flex items-center gap-ds-02",
|
|
143
|
-
children:
|
|
144
|
-
|
|
145
|
-
|
|
75
|
+
children: g.map((e, t) => {
|
|
76
|
+
let n = M + t;
|
|
77
|
+
return D === t ? /* @__PURE__ */ s("div", {
|
|
78
|
+
role: "group",
|
|
79
|
+
"aria-live": "assertive",
|
|
80
|
+
className: "flex items-center gap-ds-02",
|
|
81
|
+
children: [
|
|
82
|
+
/* @__PURE__ */ o("span", {
|
|
83
|
+
className: "whitespace-nowrap text-body-sm text-surface-fg-muted",
|
|
84
|
+
children: e.confirmMessage ?? "Are you sure?"
|
|
85
|
+
}),
|
|
86
|
+
/* @__PURE__ */ o(i, {
|
|
87
|
+
ref: A,
|
|
88
|
+
variant: "solid",
|
|
89
|
+
size: "sm",
|
|
90
|
+
color: e.color === "error" ? "error" : e.color ?? "accent",
|
|
91
|
+
onClick: () => {
|
|
92
|
+
O(null), e.onClick();
|
|
93
|
+
},
|
|
94
|
+
children: "Confirm"
|
|
95
|
+
}),
|
|
96
|
+
/* @__PURE__ */ o(i, {
|
|
97
|
+
variant: "ghost",
|
|
98
|
+
size: "sm",
|
|
99
|
+
onClick: () => {
|
|
100
|
+
O(null), P(n);
|
|
101
|
+
},
|
|
102
|
+
children: "Cancel"
|
|
103
|
+
})
|
|
104
|
+
]
|
|
105
|
+
}, e.label) : /* @__PURE__ */ o(i, {
|
|
146
106
|
ref: (e) => {
|
|
147
|
-
|
|
107
|
+
k.current[n] = e;
|
|
148
108
|
},
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
109
|
+
variant: "ghost",
|
|
110
|
+
size: "sm",
|
|
111
|
+
color: e.color ?? "accent",
|
|
112
|
+
disabled: e.disabled,
|
|
113
|
+
loading: e.loading,
|
|
114
|
+
startIcon: e.icon ?? void 0,
|
|
115
|
+
tabIndex: T === n ? 0 : -1,
|
|
116
|
+
onClick: e.requiresConfirmation ? () => O(t) : e.onClick,
|
|
117
|
+
children: e.label
|
|
118
|
+
}, e.label);
|
|
152
119
|
})
|
|
153
120
|
}),
|
|
154
121
|
/* @__PURE__ */ o(i, {
|
|
122
|
+
ref: (e) => {
|
|
123
|
+
k.current[N - 1] = e;
|
|
124
|
+
},
|
|
155
125
|
variant: "ghost",
|
|
156
126
|
size: "icon-sm",
|
|
127
|
+
tabIndex: T === N - 1 ? 0 : -1,
|
|
157
128
|
onClick: h,
|
|
158
129
|
"aria-label": "Clear selection",
|
|
159
130
|
children: /* @__PURE__ */ o(n, {
|
|
@@ -162,8 +133,8 @@ function p({ show: p, count: m, onClearSelection: h, actions: g, totalCount: _,
|
|
|
162
133
|
})
|
|
163
134
|
})
|
|
164
135
|
]
|
|
165
|
-
}) }), document.body)
|
|
166
|
-
}
|
|
136
|
+
}) }), document.body);
|
|
137
|
+
});
|
|
167
138
|
p.displayName = "BulkActionBar";
|
|
168
139
|
//#endregion
|
|
169
140
|
export { p as BulkActionBar };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bulk-action-bar.js","names":[],"sources":["../../src/composed/bulk-action-bar.tsx"],"sourcesContent":["'use client'\n\nimport { IconX } from '@tabler/icons-react'\nimport { AnimatePresence, motion } from 'framer-motion'\nimport * as React from 'react'\nimport { createPortal } from 'react-dom'\n\nimport { Badge } from '../ui/badge'\nimport { Button } from '../ui/button'\nimport { Icon } from '../ui/icon'\nimport type { IconInput } from '../ui/lib/icon-input'\nimport { springs } from '../ui/lib/motion'\nimport { cn } from '../ui/lib/utils'\n\n// ============================================================\n// Types\n// ============================================================\n\nexport interface BulkActionBarAction {\n label: string\n icon?: IconInput\n onClick: () => void\n color?: 'accent' | 'error'\n disabled?: boolean\n /** Show inline confirmation before executing the action */\n requiresConfirmation?: boolean\n /** Custom confirmation message @default 'Are you sure?' */\n confirmMessage?: string\n}\n\nexport interface BulkActionBarProps {\n show: boolean\n count: number\n onClearSelection: () => void\n actions: BulkActionBarAction[]\n /** Total number of items available for selection */\n totalCount?: number\n /** Called when user clicks \"Select all\" */\n onSelectAll?: () => void\n className?: string\n}\n\n// ============================================================\n// ActionButton — handles inline confirmation\n// ============================================================\n\nconst ActionButton = React.forwardRef<HTMLDivElement, { action: BulkActionBarAction; tabIndex?: number }>(function ActionButton({ action, tabIndex }, ref) {\n const [confirming, setConfirming] = React.useState(false)\n\n if (confirming) {\n return (\n <motion.div\n ref={ref}\n initial={{ opacity: 0, scale: 0.95 }}\n animate={{ opacity: 1, scale: 1 }}\n exit={{ opacity: 0, scale: 0.95 }}\n transition={springs.snappy}\n className=\"flex items-center gap-ds-02\"\n tabIndex={tabIndex}\n >\n <span className=\"text-body-sm text-surface-fg-muted whitespace-nowrap\">\n {action.confirmMessage ?? 'Are you sure?'}\n </span>\n <Button\n variant=\"solid\"\n size=\"sm\"\n color=\"error\"\n onClick={() => {\n setConfirming(false)\n action.onClick()\n }}\n >\n Confirm\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => setConfirming(false)}\n >\n Cancel\n </Button>\n </motion.div>\n )\n }\n\n return (\n <motion.div\n ref={ref}\n initial={{ opacity: 0, scale: 0.95 }}\n animate={{ opacity: 1, scale: 1 }}\n exit={{ opacity: 0, scale: 0.95 }}\n transition={springs.snappy}\n tabIndex={tabIndex}\n >\n <Button\n variant=\"ghost\"\n size=\"sm\"\n color={action.color === 'error' ? 'error' : 'accent'}\n disabled={action.disabled}\n onClick={action.requiresConfirmation ? () => setConfirming(true) : action.onClick}\n startIcon={action.icon ?? undefined}\n tabIndex={-1}\n >\n {action.label}\n </Button>\n </motion.div>\n )\n})\n\n// ============================================================\n// BulkActionBar\n// ============================================================\n\nfunction BulkActionBar({\n show,\n count,\n onClearSelection,\n actions,\n totalCount,\n onSelectAll,\n className,\n}: BulkActionBarProps) {\n const [mounted, setMounted] = React.useState(false)\n const [focusedIndex, setFocusedIndex] = React.useState(0)\n const actionRefs = React.useRef<(HTMLDivElement | null)[]>([])\n\n // Reset focused index when actions change\n React.useEffect(() => {\n setFocusedIndex(0)\n }, [actions.length])\n\n React.useEffect(() => {\n setMounted(true)\n }, [])\n\n function handleKeyDown(e: React.KeyboardEvent) {\n if (e.key === 'Escape') {\n e.preventDefault()\n onClearSelection()\n return\n }\n\n const count = actions.length\n if (count === 0) return\n\n if (e.key === 'ArrowRight') {\n e.preventDefault()\n const next = (focusedIndex + 1) % count\n setFocusedIndex(next)\n actionRefs.current[next]?.focus()\n } else if (e.key === 'ArrowLeft') {\n e.preventDefault()\n const prev = (focusedIndex - 1 + count) % count\n setFocusedIndex(prev)\n actionRefs.current[prev]?.focus()\n } else if (e.key === 'Home') {\n e.preventDefault()\n setFocusedIndex(0)\n actionRefs.current[0]?.focus()\n } else if (e.key === 'End') {\n e.preventDefault()\n const last = count - 1\n setFocusedIndex(last)\n actionRefs.current[last]?.focus()\n }\n }\n\n if (!mounted) return null\n\n return createPortal(\n <AnimatePresence>\n {show && (\n <motion.div\n initial={{ y: 100, opacity: 0 }}\n animate={{ y: 0, opacity: 1 }}\n exit={{ y: 100, opacity: 0 }}\n transition={springs.snappy}\n className={cn(\n 'fixed bottom-ds-06 left-1/2 z-sticky -translate-x-1/2',\n 'flex items-center gap-ds-04 rounded-surface bg-surface-overlay px-ds-05 py-ds-03 shadow-floating',\n className,\n )}\n role=\"toolbar\"\n aria-label={`${count} items selected`}\n onKeyDown={handleKeyDown}\n >\n <Badge variant=\"solid\" size=\"sm\">\n {count} selected\n </Badge>\n\n {totalCount != null && totalCount > count && onSelectAll && (\n <Button variant=\"link\" size=\"xs\" onClick={onSelectAll}>\n Select all {totalCount}\n </Button>\n )}\n\n <div className=\"flex items-center gap-ds-02\">\n <AnimatePresence mode=\"popLayout\">\n {actions.map((action, i) => (\n <ActionButton\n key={action.label}\n ref={(el: HTMLDivElement | null) => { actionRefs.current[i] = el }}\n action={action}\n tabIndex={i === focusedIndex ? 0 : -1}\n />\n ))}\n </AnimatePresence>\n </div>\n\n <Button\n variant=\"ghost\"\n size=\"icon-sm\"\n onClick={onClearSelection}\n aria-label=\"Clear selection\"\n >\n <Icon icon={IconX} size=\"sm\" />\n </Button>\n </motion.div>\n )}\n </AnimatePresence>,\n document.body,\n )\n}\n\nBulkActionBar.displayName = 'BulkActionBar'\n\nexport { BulkActionBar }\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"bulk-action-bar.js","names":[],"sources":["../../src/composed/bulk-action-bar.tsx"],"sourcesContent":["'use client'\n\nimport { IconX } from '@tabler/icons-react'\nimport { AnimatePresence, motion, useReducedMotion } from 'framer-motion'\nimport * as React from 'react'\nimport { createPortal } from 'react-dom'\n\nimport { Badge } from '../ui/badge'\nimport { Button } from '../ui/button'\nimport { Icon } from '../ui/icon'\nimport type { IconInput } from '../ui/lib/icon-input'\nimport { springs } from '../ui/lib/motion'\nimport { cn } from '../ui/lib/utils'\n\ntype ButtonColor = React.ComponentProps<typeof Button>['color']\n\nexport interface BulkActionBarAction {\n label: string\n icon?: IconInput\n onClick: () => void\n /** Any Button color. @default 'accent' (or 'error' for destructive). */\n color?: ButtonColor\n disabled?: boolean\n /** Show a pending spinner on the action (e.g. slow bulk op in flight). */\n loading?: boolean\n /** Show inline confirmation before executing the action. */\n requiresConfirmation?: boolean\n /** Custom confirmation message. @default 'Are you sure?' */\n confirmMessage?: string\n}\n\nexport interface BulkActionBarProps\n extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n // Keys whose types collide with framer-motion's HTMLMotionProps.\n 'children' | 'color' | 'onDrag' | 'onDragStart' | 'onDragEnd' | 'onAnimationStart' | 'onAnimationEnd' | 'onAnimationIteration' | 'style'\n > {\n show: boolean\n count: number\n onClearSelection: () => void\n actions: BulkActionBarAction[]\n /** Total items available for selection (enables \"Select all\"). */\n totalCount?: number\n /** Called when the user clicks \"Select all\". */\n onSelectAll?: () => void\n}\n\n/**\n * BulkActionBar — floating selection toolbar. Follows the ARIA toolbar model:\n * a single tab stop with roving focus (Arrow keys / Home / End) across ALL\n * controls (Select-all, actions, Clear), focus landing on the real buttons so\n * Enter/Space activate them. Arrow direction mirrors under `dir=\"rtl\"`. Escape\n * clears the selection (or cancels a pending confirmation).\n */\nconst BulkActionBar = React.forwardRef<HTMLDivElement, BulkActionBarProps>(\n function BulkActionBar(\n { show, count, onClearSelection, actions, totalCount, onSelectAll, className, ...props },\n forwardedRef,\n ) {\n const reduced = useReducedMotion()\n const [mounted, setMounted] = React.useState(false)\n const [focusedIndex, setFocusedIndex] = React.useState(0)\n const [confirming, setConfirming] = React.useState<number | null>(null)\n const controlRefs = React.useRef<Array<HTMLButtonElement | null>>([])\n const confirmRef = React.useRef<HTMLButtonElement | null>(null)\n\n const hasSelectAll = totalCount != null && totalCount > count && !!onSelectAll\n const selectAllOffset = hasSelectAll ? 1 : 0\n const total = selectAllOffset + actions.length + 1 // + Clear\n\n React.useEffect(() => { setMounted(true) }, [])\n React.useEffect(() => { setFocusedIndex(0); setConfirming(null) }, [actions.length])\n // Move focus to Confirm when a confirmation opens.\n React.useEffect(() => {\n if (confirming != null) confirmRef.current?.focus()\n }, [confirming])\n\n const focusAt = (i: number) => {\n const clamped = (i + total) % total\n setFocusedIndex(clamped)\n controlRefs.current[clamped]?.focus()\n }\n\n function handleKeyDown(e: React.KeyboardEvent<HTMLDivElement>) {\n if (e.key === 'Escape') {\n e.preventDefault()\n if (confirming != null) { setConfirming(null); focusAt(focusedIndex) }\n else onClearSelection()\n return\n }\n if (confirming != null) return // roving suspended during confirm\n const rtl = e.currentTarget.dir === 'rtl' || document.dir === 'rtl'\n const fwd = rtl ? 'ArrowLeft' : 'ArrowRight'\n const back = rtl ? 'ArrowRight' : 'ArrowLeft'\n if (e.key === fwd) { e.preventDefault(); focusAt(focusedIndex + 1) }\n else if (e.key === back) { e.preventDefault(); focusAt(focusedIndex - 1) }\n else if (e.key === 'Home') { e.preventDefault(); focusAt(0) }\n else if (e.key === 'End') { e.preventDefault(); focusAt(total - 1) }\n }\n\n if (!mounted) return null\n\n const slideTransition = reduced ? { duration: 0 } : springs.smooth\n\n return createPortal(\n <AnimatePresence>\n {show && (\n <motion.div\n ref={forwardedRef}\n initial={reduced ? { opacity: 0 } : { y: 100, opacity: 0 }}\n animate={reduced ? { opacity: 1 } : { y: 0, opacity: 1 }}\n exit={reduced ? { opacity: 0 } : { y: 100, opacity: 0 }}\n transition={slideTransition}\n className={cn(\n 'fixed bottom-ds-06 start-1/2 z-sticky -translate-x-1/2',\n 'flex items-center gap-ds-04 rounded-surface bg-surface-overlay px-ds-05 py-ds-03 shadow-floating',\n className,\n )}\n role=\"toolbar\"\n aria-label={`${count} items selected`}\n onKeyDown={handleKeyDown}\n {...props}\n >\n <Badge variant=\"solid\" size=\"sm\">{count} selected</Badge>\n\n {hasSelectAll && (\n <Button\n ref={(el) => { controlRefs.current[0] = el }}\n variant=\"link\"\n size=\"xs\"\n tabIndex={focusedIndex === 0 ? 0 : -1}\n onClick={onSelectAll}\n >\n Select all {totalCount}\n </Button>\n )}\n\n <div className=\"flex items-center gap-ds-02\">\n {actions.map((action, i) => {\n const controlIndex = selectAllOffset + i\n const isConfirming = confirming === i\n if (isConfirming) {\n return (\n <div\n key={action.label}\n role=\"group\"\n aria-live=\"assertive\"\n className=\"flex items-center gap-ds-02\"\n >\n <span className=\"whitespace-nowrap text-body-sm text-surface-fg-muted\">\n {action.confirmMessage ?? 'Are you sure?'}\n </span>\n <Button\n ref={confirmRef}\n variant=\"solid\"\n size=\"sm\"\n color={action.color === 'error' ? 'error' : (action.color ?? 'accent')}\n onClick={() => { setConfirming(null); action.onClick() }}\n >\n Confirm\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => { setConfirming(null); focusAt(controlIndex) }}\n >\n Cancel\n </Button>\n </div>\n )\n }\n return (\n <Button\n key={action.label}\n ref={(el) => { controlRefs.current[controlIndex] = el }}\n variant=\"ghost\"\n size=\"sm\"\n color={action.color ?? 'accent'}\n disabled={action.disabled}\n loading={action.loading}\n startIcon={action.icon ?? undefined}\n tabIndex={focusedIndex === controlIndex ? 0 : -1}\n onClick={action.requiresConfirmation ? () => setConfirming(i) : action.onClick}\n >\n {action.label}\n </Button>\n )\n })}\n </div>\n\n <Button\n ref={(el) => { controlRefs.current[total - 1] = el }}\n variant=\"ghost\"\n size=\"icon-sm\"\n tabIndex={focusedIndex === total - 1 ? 0 : -1}\n onClick={onClearSelection}\n aria-label=\"Clear selection\"\n >\n <Icon icon={IconX} size=\"sm\" />\n </Button>\n </motion.div>\n )}\n </AnimatePresence>,\n document.body,\n )\n },\n)\nBulkActionBar.displayName = 'BulkActionBar'\n\nexport { BulkActionBar }\n"],"mappings":";;;;;;;;;;;;AAsDA,IAAM,IAAgB,EAAM,WAC1B,SACE,EAAE,SAAM,UAAO,qBAAkB,YAAS,eAAY,gBAAa,cAAW,GAAG,KACjF,GACA;CACA,IAAM,IAAU,EAAiB,GAC3B,CAAC,GAAS,KAAc,EAAM,SAAS,EAAK,GAC5C,CAAC,GAAc,KAAmB,EAAM,SAAS,CAAC,GAClD,CAAC,GAAY,KAAiB,EAAM,SAAwB,IAAI,GAChE,IAAc,EAAM,OAAwC,CAAC,CAAC,GAC9D,IAAa,EAAM,OAAiC,IAAI,GAExD,IAAe,KAAc,QAAQ,IAAa,KAAS,CAAC,CAAC,GAC7D,IAAkB,MAClB,IAAQ,IAAkB,EAAQ,SAAS;CAKjD,AAHA,EAAM,gBAAgB;EAAE,EAAW,EAAI;CAAE,GAAG,CAAC,CAAC,GAC9C,EAAM,gBAAgB;EAAsB,AAApB,EAAgB,CAAC,GAAG,EAAc,IAAI;CAAE,GAAG,CAAC,EAAQ,MAAM,CAAC,GAEnF,EAAM,gBAAgB;EACpB,AAAI,KAAc,QAAM,EAAW,SAAS,MAAM;CACpD,GAAG,CAAC,CAAU,CAAC;CAEf,IAAM,KAAW,MAAc;EAC7B,IAAM,KAAW,IAAI,KAAS;EAE9B,AADA,EAAgB,CAAO,GACvB,EAAY,QAAQ,EAAQ,EAAE,MAAM;CACtC;CAEA,SAAS,EAAc,GAAwC;EAC7D,IAAI,EAAE,QAAQ,UAAU;GAEtB,AADA,EAAE,eAAe,GACb,KAAc,OACb,EAAiB,KADI,EAAc,IAAI,GAAG,EAAQ,CAAY;GAEnE;EACF;EACA,IAAI,KAAc,MAAM;EACxB,IAAM,IAAM,EAAE,cAAc,QAAQ,SAAS,SAAS,QAAQ,OACxD,IAAM,IAAM,cAAc,cAC1B,IAAO,IAAM,eAAe;EAClC,AAAI,EAAE,QAAQ,KAAO,EAAE,eAAe,GAAG,EAAQ,IAAe,CAAC,KACxD,EAAE,QAAQ,KAAQ,EAAE,eAAe,GAAG,EAAQ,IAAe,CAAC,KAC9D,EAAE,QAAQ,UAAU,EAAE,eAAe,GAAG,EAAQ,CAAC,KACjD,EAAE,QAAQ,UAAS,EAAE,eAAe,GAAG,EAAQ,IAAQ,CAAC;CACnE;CAEA,IAAI,CAAC,GAAS,OAAO;CAErB,IAAM,IAAkB,IAAU,EAAE,UAAU,EAAE,IAAI,EAAQ;CAE5D,OAAO,EACL,kBAAC,GAAD,EAAA,UACG,KACC,kBAAC,EAAO,KAAR;EACE,KAAK;EACL,SAAS,IAAU,EAAE,SAAS,EAAE,IAAI;GAAE,GAAG;GAAK,SAAS;EAAE;EACzD,SAAS,IAAU,EAAE,SAAS,EAAE,IAAI;GAAE,GAAG;GAAG,SAAS;EAAE;EACvD,MAAM,IAAU,EAAE,SAAS,EAAE,IAAI;GAAE,GAAG;GAAK,SAAS;EAAE;EACtD,YAAY;EACZ,WAAW,EACT,0DACA,oGACA,CACF;EACA,MAAK;EACL,cAAY,GAAG,EAAM;EACrB,WAAW;EACX,GAAI;YAdN;GAgBE,kBAAC,GAAD;IAAO,SAAQ;IAAQ,MAAK;cAA5B,CAAkC,GAAM,WAAgB;;GAEvD,KACC,kBAAC,GAAD;IACE,MAAM,MAAO;KAAE,EAAY,QAAQ,KAAK;IAAG;IAC3C,SAAQ;IACR,MAAK;IACL,UAAU,MAAiB,IAAI,IAAI;IACnC,SAAS;cALX,CAMC,eACa,CACN;;GAGV,kBAAC,OAAD;IAAK,WAAU;cACZ,EAAQ,KAAK,GAAQ,MAAM;KAC1B,IAAM,IAAe,IAAkB;KAgCvC,OA/BqB,MAAe,IAGhC,kBAAC,OAAD;MAEE,MAAK;MACL,aAAU;MACV,WAAU;gBAJZ;OAME,kBAAC,QAAD;QAAM,WAAU;kBACb,EAAO,kBAAkB;OACtB,CAAA;OACN,kBAAC,GAAD;QACE,KAAK;QACL,SAAQ;QACR,MAAK;QACL,OAAO,EAAO,UAAU,UAAU,UAAW,EAAO,SAAS;QAC7D,eAAe;SAAuB,AAArB,EAAc,IAAI,GAAG,EAAO,QAAQ;QAAE;kBACxD;OAEO,CAAA;OACR,kBAAC,GAAD;QACE,SAAQ;QACR,MAAK;QACL,eAAe;SAAuB,AAArB,EAAc,IAAI,GAAG,EAAQ,CAAY;QAAE;kBAC7D;OAEO,CAAA;MACL;QAxBE,EAAO,KAwBT,IAIP,kBAAC,GAAD;MAEE,MAAM,MAAO;OAAE,EAAY,QAAQ,KAAgB;MAAG;MACtD,SAAQ;MACR,MAAK;MACL,OAAO,EAAO,SAAS;MACvB,UAAU,EAAO;MACjB,SAAS,EAAO;MAChB,WAAW,EAAO,QAAQ,KAAA;MAC1B,UAAU,MAAiB,IAAe,IAAI;MAC9C,SAAS,EAAO,6BAA6B,EAAc,CAAC,IAAI,EAAO;gBAEtE,EAAO;KACF,GAZD,EAAO,KAYN;IAEZ,CAAC;GACE,CAAA;GAEL,kBAAC,GAAD;IACE,MAAM,MAAO;KAAE,EAAY,QAAQ,IAAQ,KAAK;IAAG;IACnD,SAAQ;IACR,MAAK;IACL,UAAU,MAAiB,IAAQ,IAAI,IAAI;IAC3C,SAAS;IACT,cAAW;cAEX,kBAAC,GAAD;KAAM,MAAM;KAAO,MAAK;IAAM,CAAA;GACxB,CAAA;EACE;IAEC,CAAA,GACjB,SAAS,IACX;AACF,CACF;AACA,EAAc,cAAc"}
|
|
@@ -3,16 +3,26 @@ import * as React from 'react';
|
|
|
3
3
|
export interface ErrorDisplayProps extends React.ComponentPropsWithoutRef<'div'> {
|
|
4
4
|
error: unknown;
|
|
5
5
|
onReset?: () => void;
|
|
6
|
+
/** Custom recovery actions. When set, replaces the default "Try Again" button. */
|
|
7
|
+
actions?: React.ReactNode;
|
|
8
|
+
/** Center in a full-viewport-height region (error page). @default true */
|
|
9
|
+
fullPage?: boolean;
|
|
10
|
+
/** Move focus to the recovery button on mount (set by ErrorBoundary on swap). @default false */
|
|
11
|
+
autoFocusReset?: boolean;
|
|
6
12
|
}
|
|
7
13
|
declare const ErrorDisplay: React.ForwardRefExoticComponent<ErrorDisplayProps & React.RefAttributes<HTMLDivElement>>;
|
|
8
14
|
interface ErrorBoundaryProps {
|
|
9
15
|
children: React.ReactNode;
|
|
10
|
-
/**
|
|
16
|
+
/** Called when the user clicks "Try Again" (after the boundary resets). */
|
|
11
17
|
onReset?: () => void;
|
|
12
|
-
/**
|
|
18
|
+
/** Called when an error is caught — wire your logger/Sentry here. */
|
|
19
|
+
onError?: (error: unknown, info: React.ErrorInfo) => void;
|
|
20
|
+
/** Auto-reset when any value in this array changes (react-error-boundary parity). */
|
|
21
|
+
resetKeys?: unknown[];
|
|
22
|
+
/** Custom fallback — receives the caught error + a reset callback. Defaults to ErrorDisplay. */
|
|
13
23
|
fallback?: (props: {
|
|
14
24
|
error: unknown;
|
|
15
|
-
onReset
|
|
25
|
+
onReset: () => void;
|
|
16
26
|
}) => React.ReactNode;
|
|
17
27
|
}
|
|
18
28
|
interface ErrorBoundaryState {
|
|
@@ -21,6 +31,8 @@ interface ErrorBoundaryState {
|
|
|
21
31
|
declare class ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> {
|
|
22
32
|
constructor(props: ErrorBoundaryProps);
|
|
23
33
|
static getDerivedStateFromError(error: unknown): ErrorBoundaryState;
|
|
34
|
+
componentDidCatch(error: unknown, info: React.ErrorInfo): void;
|
|
35
|
+
componentDidUpdate(prev: ErrorBoundaryProps): void;
|
|
24
36
|
private handleReset;
|
|
25
37
|
render(): string | number | bigint | boolean | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | React.JSX.Element | null | undefined;
|
|
26
38
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-boundary.d.ts","sourceRoot":"","sources":["../../src/composed/error-boundary.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAQ9B,MAAM,WAAW,iBAAkB,SAAQ,KAAK,CAAC,wBAAwB,CAAC,KAAK,CAAC;IAC9E,KAAK,EAAE,OAAO,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;
|
|
1
|
+
{"version":3,"file":"error-boundary.d.ts","sourceRoot":"","sources":["../../src/composed/error-boundary.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAQ9B,MAAM,WAAW,iBAAkB,SAAQ,KAAK,CAAC,wBAAwB,CAAC,KAAK,CAAC;IAC9E,KAAK,EAAE,OAAO,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,kFAAkF;IAClF,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,gGAAgG;IAChG,cAAc,CAAC,EAAE,OAAO,CAAA;CACzB;AAgDD,QAAA,MAAM,YAAY,0FAuDjB,CAAA;AAGD,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,2EAA2E;IAC3E,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,qEAAqE;IACrE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,SAAS,KAAK,IAAI,CAAA;IACzD,qFAAqF;IACrF,SAAS,CAAC,EAAE,OAAO,EAAE,CAAA;IACrB,gGAAgG;IAChG,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,IAAI,CAAA;KAAE,KAAK,KAAK,CAAC,SAAS,CAAA;CAC/E;AAED,UAAU,kBAAkB;IAC1B,KAAK,EAAE,OAAO,GAAG,IAAI,CAAA;CACtB;AAQD,cAAM,aAAc,SAAQ,KAAK,CAAC,SAAS,CAAC,kBAAkB,EAAE,kBAAkB,CAAC;gBACrE,KAAK,EAAE,kBAAkB;IAKrC,MAAM,CAAC,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,kBAAkB;IAInE,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,SAAS;IAIvD,kBAAkB,CAAC,IAAI,EAAE,kBAAkB;IAO3C,OAAO,CAAC,WAAW,CAGlB;IAED,MAAM;CASP;AAED,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,CAAA;AACtC,YAAY,EAAE,kBAAkB,EAAE,CAAA"}
|
|
@@ -19,9 +19,12 @@ function d(e) {
|
|
|
19
19
|
if (typeof e == "string") return e;
|
|
20
20
|
}
|
|
21
21
|
function f(e) {
|
|
22
|
-
|
|
22
|
+
return e instanceof Error ? e.stack : void 0;
|
|
23
23
|
}
|
|
24
|
-
function p(
|
|
24
|
+
function p() {
|
|
25
|
+
return typeof process < "u" && !!process.env && process.env.NODE_ENV === "development";
|
|
26
|
+
}
|
|
27
|
+
function m(e) {
|
|
25
28
|
switch (e) {
|
|
26
29
|
case 404: return {
|
|
27
30
|
icon: c,
|
|
@@ -53,71 +56,84 @@ function p(e) {
|
|
|
53
56
|
};
|
|
54
57
|
}
|
|
55
58
|
}
|
|
56
|
-
var
|
|
57
|
-
let
|
|
58
|
-
return
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
59
|
+
var h = r.forwardRef(function({ error: o, onReset: s, actions: c, fullPage: l = !0, autoFocusReset: h = !1, className: g, ..._ }, v) {
|
|
60
|
+
let y = u(o), b = d(o), x = f(o), S = p(), C = m(y), w = C.icon, T = r.useRef(null), E = S && b || C.message;
|
|
61
|
+
return r.useEffect(() => {
|
|
62
|
+
h && T.current?.focus();
|
|
63
|
+
}, [h]), /* @__PURE__ */ i("div", {
|
|
64
|
+
ref: v,
|
|
65
|
+
..._,
|
|
66
|
+
className: e("flex items-center justify-center p-ds-05", l && "min-h-[60vh]", g),
|
|
62
67
|
children: /* @__PURE__ */ a("div", {
|
|
68
|
+
role: "alert",
|
|
63
69
|
className: "flex w-full max-w-lg flex-col items-center gap-ds-06 rounded-overlay-lg bg-surface-raised p-ds-07 text-center shadow-raised",
|
|
64
70
|
children: [
|
|
65
71
|
/* @__PURE__ */ i("div", {
|
|
66
|
-
className: e("flex h-ds-lg w-ds-lg items-center justify-center rounded-bubble",
|
|
72
|
+
className: e("flex h-ds-lg w-ds-lg items-center justify-center rounded-bubble", C.bgClass),
|
|
67
73
|
children: /* @__PURE__ */ i(t, {
|
|
68
|
-
icon:
|
|
74
|
+
icon: w,
|
|
69
75
|
size: "2xl",
|
|
70
|
-
className:
|
|
76
|
+
className: C.iconClass
|
|
71
77
|
})
|
|
72
78
|
}),
|
|
73
79
|
/* @__PURE__ */ a("div", {
|
|
74
80
|
className: "flex flex-col gap-ds-03",
|
|
75
81
|
children: [
|
|
76
|
-
|
|
82
|
+
y && /* @__PURE__ */ a("span", {
|
|
77
83
|
className: "text-body-sm text-surface-fg-subtle",
|
|
78
|
-
children: ["Error ",
|
|
84
|
+
children: ["Error ", y]
|
|
79
85
|
}),
|
|
80
86
|
/* @__PURE__ */ i("h2", {
|
|
81
87
|
className: "text-heading-md font-semibold text-surface-fg",
|
|
82
|
-
children:
|
|
88
|
+
children: C.title
|
|
83
89
|
}),
|
|
84
90
|
/* @__PURE__ */ i("p", {
|
|
85
91
|
className: "text-body-lg text-surface-fg-subtle",
|
|
86
|
-
children:
|
|
92
|
+
children: E
|
|
87
93
|
})
|
|
88
94
|
]
|
|
89
95
|
}),
|
|
90
|
-
|
|
96
|
+
(c || s) && /* @__PURE__ */ i("div", {
|
|
91
97
|
className: "flex items-center gap-ds-04",
|
|
92
|
-
children: /* @__PURE__ */ i(n, {
|
|
98
|
+
children: c ?? /* @__PURE__ */ i(n, {
|
|
99
|
+
ref: T,
|
|
93
100
|
variant: "soft",
|
|
94
101
|
size: "md",
|
|
95
|
-
onClick:
|
|
102
|
+
onClick: s,
|
|
96
103
|
children: "Try Again"
|
|
97
104
|
})
|
|
98
105
|
}),
|
|
99
|
-
|
|
100
|
-
className: "w-full overflow-auto rounded-surface border border-card
|
|
106
|
+
S && x && /* @__PURE__ */ a("div", {
|
|
107
|
+
className: "w-full overflow-auto rounded-surface border border-card bg-surface-raised p-ds-05 text-left",
|
|
101
108
|
children: [/* @__PURE__ */ i("p", {
|
|
102
109
|
className: "text-body-sm mb-ds-03 font-semibold text-surface-fg",
|
|
103
110
|
children: "Stack Trace (development only)"
|
|
104
111
|
}), /* @__PURE__ */ i("pre", {
|
|
105
112
|
className: "whitespace-pre-wrap text-body-sm text-surface-fg-subtle",
|
|
106
|
-
children:
|
|
113
|
+
children: x
|
|
107
114
|
})]
|
|
108
115
|
})
|
|
109
116
|
]
|
|
110
117
|
})
|
|
111
118
|
});
|
|
112
119
|
});
|
|
113
|
-
|
|
114
|
-
|
|
120
|
+
h.displayName = "ErrorDisplay";
|
|
121
|
+
function g(e, t) {
|
|
122
|
+
return !e || !t ? !1 : e.length !== t.length || e.some((e, n) => !Object.is(e, t[n]));
|
|
123
|
+
}
|
|
124
|
+
var _ = class extends r.Component {
|
|
115
125
|
constructor(e) {
|
|
116
126
|
super(e), this.state = { error: null };
|
|
117
127
|
}
|
|
118
128
|
static getDerivedStateFromError(e) {
|
|
119
129
|
return { error: e };
|
|
120
130
|
}
|
|
131
|
+
componentDidCatch(e, t) {
|
|
132
|
+
this.props.onError?.(e, t);
|
|
133
|
+
}
|
|
134
|
+
componentDidUpdate(e) {
|
|
135
|
+
this.state.error !== null && g(e.resetKeys, this.props.resetKeys) && this.setState({ error: null });
|
|
136
|
+
}
|
|
121
137
|
handleReset = () => {
|
|
122
138
|
this.setState({ error: null }), this.props.onReset?.();
|
|
123
139
|
};
|
|
@@ -125,11 +141,12 @@ var h = class extends r.Component {
|
|
|
125
141
|
return this.state.error === null ? this.props.children : this.props.fallback ? this.props.fallback({
|
|
126
142
|
error: this.state.error,
|
|
127
143
|
onReset: this.handleReset
|
|
128
|
-
}) : /* @__PURE__ */ i(
|
|
144
|
+
}) : /* @__PURE__ */ i(h, {
|
|
129
145
|
error: this.state.error,
|
|
130
|
-
onReset: this.handleReset
|
|
146
|
+
onReset: this.handleReset,
|
|
147
|
+
autoFocusReset: !0
|
|
131
148
|
});
|
|
132
149
|
}
|
|
133
150
|
};
|
|
134
151
|
//#endregion
|
|
135
|
-
export {
|
|
152
|
+
export { _ as ErrorBoundary, h as ErrorDisplay };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-boundary.js","names":[],"sources":["../../src/composed/error-boundary.tsx"],"sourcesContent":["'use client'\n\nimport { IconAlertTriangle, IconBan, IconFileUnknown, IconServerOff } from '@tabler/icons-react'\nimport * as React from 'react'\n\nimport { Button } from '../ui/button'\nimport { Icon } from '../ui/icon'\nimport { cn } from '../ui/lib/utils'\n\ndeclare const process: { env: { NODE_ENV?: string } } | undefined\n\nexport interface ErrorDisplayProps extends React.ComponentPropsWithoutRef<'div'> {\n error: unknown\n onReset?: () => void\n}\n\nfunction getStatusFromError(error: unknown): number | undefined {\n if (\n error &&\n typeof error === 'object' &&\n 'status' in error &&\n typeof (error as Record<string, unknown>).status === 'number'\n ) {\n return (error as Record<string, unknown>).status as number\n }\n return undefined\n}\n\nfunction getMessageFromError(error: unknown): string | undefined {\n if (error instanceof Error) {\n return error.message\n }\n if (\n error &&\n typeof error === 'object' &&\n 'data' in error\n ) {\n const data = (error as Record<string, unknown>).data\n if (typeof data === 'string') return data\n if (data && typeof data === 'object' && 'message' in data) {\n return String((data as Record<string, unknown>).message)\n }\n }\n if (typeof error === 'string') {\n return error\n }\n return undefined\n}\n\nfunction getStackFromError(error: unknown): string | undefined {\n if (error instanceof Error) {\n return error.stack\n }\n return undefined\n}\n\nfunction getErrorConfig(status?: number) {\n switch (status) {\n case 404:\n return {\n icon: IconFileUnknown,\n title: 'Page not found',\n message:\n 'The page you are looking for does not exist or has been moved.',\n bgClass: 'bg-accent-2',\n iconClass: 'text-accent-11',\n }\n case 403:\n return {\n icon: IconBan,\n title: 'Access denied',\n message:\n 'You do not have permission to view this page. Contact your administrator if you believe this is a mistake.',\n bgClass: 'bg-warning-3',\n iconClass: 'text-warning-11',\n }\n case 500:\n return {\n icon: IconServerOff,\n title: 'Server error',\n message:\n 'Something went wrong on our end. Please try again later or contact support if the issue persists.',\n bgClass: 'bg-error-3',\n iconClass: 'text-error-11',\n }\n default:\n return {\n icon: IconAlertTriangle,\n title: 'Something went wrong',\n message:\n 'An unexpected error occurred. Please try again or go back to the home page.',\n bgClass: 'bg-accent-2',\n iconClass: 'text-accent-11',\n }\n }\n}\n\nconst ErrorDisplay = React.forwardRef<HTMLDivElement, ErrorDisplayProps>(\n function ErrorDisplay({ error, onReset, className, ...props }, ref) {\n const status = getStatusFromError(error)\n const message = getMessageFromError(error)\n const stack = getStackFromError(error)\n const isDev =\n typeof process !== 'undefined' &&\n process.env &&\n process.env.NODE_ENV === 'development'\n\n const errorConfig = getErrorConfig(status)\n const ErrorIcon = errorConfig.icon\n\n return (\n <div ref={ref} {...props} className={cn(\"flex min-h-[60vh] items-center justify-center p-ds-05\", className)}>\n <div\n className=\"flex w-full max-w-lg flex-col items-center gap-ds-06 rounded-overlay-lg bg-surface-raised p-ds-07 text-center shadow-raised\"\n >\n {/* Error Icon */}\n <div\n className={cn(\n 'flex h-ds-lg w-ds-lg items-center justify-center rounded-bubble',\n errorConfig.bgClass,\n )}\n >\n <Icon\n icon={ErrorIcon}\n size=\"2xl\"\n className={errorConfig.iconClass}\n />\n </div>\n\n {/* Error IconInfoCircle */}\n <div className=\"flex flex-col gap-ds-03\">\n {status && (\n <span className=\"text-body-sm text-surface-fg-subtle\">\n Error {status}\n </span>\n )}\n <h2 className=\"text-heading-md font-semibold text-surface-fg\">\n {errorConfig.title}\n </h2>\n <p className=\"text-body-lg text-surface-fg-subtle\">\n {message || errorConfig.message}\n </p>\n </div>\n\n {/* Actions */}\n {onReset && (\n <div className=\"flex items-center gap-ds-04\">\n <Button\n variant=\"soft\"\n size=\"md\"\n onClick={onReset}\n >\n Try Again\n </Button>\n </div>\n )}\n\n {/* Dev stack trace */}\n {isDev && stack && (\n <div className=\"w-full overflow-auto rounded-surface border border-card-strong bg-surface-raised p-ds-05 text-left\">\n <p className=\"text-body-sm mb-ds-03 font-semibold text-surface-fg\">\n Stack Trace (development only)\n </p>\n <pre className=\"whitespace-pre-wrap text-body-sm text-surface-fg-subtle\">\n {stack}\n </pre>\n </div>\n )}\n </div>\n </div>\n )\n},\n)\n\nErrorDisplay.displayName = 'ErrorDisplay'\n\ninterface ErrorBoundaryProps {\n children: React.ReactNode\n /** Optional callback when the user clicks \"Try Again\" */\n onReset?: () => void\n /** Optional custom fallback — receives the caught error. Defaults to ErrorDisplay. */\n fallback?: (props: { error: unknown; onReset?: () => void }) => React.ReactNode\n}\n\ninterface ErrorBoundaryState {\n error: unknown | null\n}\n\nclass ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> {\n constructor(props: ErrorBoundaryProps) {\n super(props)\n this.state = { error: null }\n }\n\n static getDerivedStateFromError(error: unknown): ErrorBoundaryState {\n return { error }\n }\n\n private handleReset = () => {\n this.setState({ error: null })\n this.props.onReset?.()\n }\n\n render() {\n if (this.state.error !== null) {\n if (this.props.fallback) {\n return this.props.fallback({ error: this.state.error, onReset: this.handleReset })\n }\n return <ErrorDisplay error={this.state.error} onReset={this.handleReset} />\n }\n return this.props.children\n }\n}\n\nexport { ErrorBoundary,ErrorDisplay }\nexport type { ErrorBoundaryProps }\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"error-boundary.js","names":[],"sources":["../../src/composed/error-boundary.tsx"],"sourcesContent":["'use client'\n\nimport { IconAlertTriangle, IconBan, IconFileUnknown, IconServerOff } from '@tabler/icons-react'\nimport * as React from 'react'\n\nimport { Button } from '../ui/button'\nimport { Icon } from '../ui/icon'\nimport { cn } from '../ui/lib/utils'\n\ndeclare const process: { env: { NODE_ENV?: string } } | undefined\n\nexport interface ErrorDisplayProps extends React.ComponentPropsWithoutRef<'div'> {\n error: unknown\n onReset?: () => void\n /** Custom recovery actions. When set, replaces the default \"Try Again\" button. */\n actions?: React.ReactNode\n /** Center in a full-viewport-height region (error page). @default true */\n fullPage?: boolean\n /** Move focus to the recovery button on mount (set by ErrorBoundary on swap). @default false */\n autoFocusReset?: boolean\n}\n\nfunction getStatusFromError(error: unknown): number | undefined {\n if (\n error &&\n typeof error === 'object' &&\n 'status' in error &&\n typeof (error as Record<string, unknown>).status === 'number'\n ) {\n return (error as Record<string, unknown>).status as number\n }\n return undefined\n}\n\nfunction getMessageFromError(error: unknown): string | undefined {\n if (error instanceof Error) return error.message\n if (error && typeof error === 'object' && 'data' in error) {\n const data = (error as Record<string, unknown>).data\n if (typeof data === 'string') return data\n if (data && typeof data === 'object' && 'message' in data) {\n return String((data as Record<string, unknown>).message)\n }\n }\n if (typeof error === 'string') return error\n return undefined\n}\n\nfunction getStackFromError(error: unknown): string | undefined {\n return error instanceof Error ? error.stack : undefined\n}\n\nfunction isDevEnv() {\n return typeof process !== 'undefined' && !!process.env && process.env.NODE_ENV === 'development'\n}\n\nfunction getErrorConfig(status?: number) {\n switch (status) {\n case 404:\n return { icon: IconFileUnknown, title: 'Page not found', message: 'The page you are looking for does not exist or has been moved.', bgClass: 'bg-accent-2', iconClass: 'text-accent-11' }\n case 403:\n return { icon: IconBan, title: 'Access denied', message: 'You do not have permission to view this page. Contact your administrator if you believe this is a mistake.', bgClass: 'bg-warning-3', iconClass: 'text-warning-11' }\n case 500:\n return { icon: IconServerOff, title: 'Server error', message: 'Something went wrong on our end. Please try again later or contact support if the issue persists.', bgClass: 'bg-error-3', iconClass: 'text-error-11' }\n default:\n return { icon: IconAlertTriangle, title: 'Something went wrong', message: 'An unexpected error occurred. Please try again or go back to the home page.', bgClass: 'bg-accent-2', iconClass: 'text-accent-11' }\n }\n}\n\nconst ErrorDisplay = React.forwardRef<HTMLDivElement, ErrorDisplayProps>(\n function ErrorDisplay({ error, onReset, actions, fullPage = true, autoFocusReset = false, className, ...props }, ref) {\n const status = getStatusFromError(error)\n const rawMessage = getMessageFromError(error)\n const stack = getStackFromError(error)\n const isDev = isDevEnv()\n const errorConfig = getErrorConfig(status)\n const ErrorIcon = errorConfig.icon\n const resetRef = React.useRef<HTMLButtonElement>(null)\n\n // Only surface the raw error message in development — in production it can leak\n // internal detail; users see the friendly, status-mapped copy instead.\n const shownMessage = isDev ? rawMessage || errorConfig.message : errorConfig.message\n\n React.useEffect(() => {\n if (autoFocusReset) resetRef.current?.focus()\n }, [autoFocusReset])\n\n return (\n <div ref={ref} {...props} className={cn('flex items-center justify-center p-ds-05', fullPage && 'min-h-[60vh]', className)}>\n {/* role=alert → assertive live region: AT announces the error on appearance. */}\n <div\n role=\"alert\"\n className=\"flex w-full max-w-lg flex-col items-center gap-ds-06 rounded-overlay-lg bg-surface-raised p-ds-07 text-center shadow-raised\"\n >\n <div className={cn('flex h-ds-lg w-ds-lg items-center justify-center rounded-bubble', errorConfig.bgClass)}>\n <Icon icon={ErrorIcon} size=\"2xl\" className={errorConfig.iconClass} />\n </div>\n\n <div className=\"flex flex-col gap-ds-03\">\n {status && <span className=\"text-body-sm text-surface-fg-subtle\">Error {status}</span>}\n <h2 className=\"text-heading-md font-semibold text-surface-fg\">{errorConfig.title}</h2>\n <p className=\"text-body-lg text-surface-fg-subtle\">{shownMessage}</p>\n </div>\n\n {(actions || onReset) && (\n <div className=\"flex items-center gap-ds-04\">\n {actions ?? (\n <Button ref={resetRef} variant=\"soft\" size=\"md\" onClick={onReset}>\n Try Again\n </Button>\n )}\n </div>\n )}\n\n {isDev && stack && (\n <div className=\"w-full overflow-auto rounded-surface border border-card bg-surface-raised p-ds-05 text-left\">\n <p className=\"text-body-sm mb-ds-03 font-semibold text-surface-fg\">Stack Trace (development only)</p>\n <pre className=\"whitespace-pre-wrap text-body-sm text-surface-fg-subtle\">{stack}</pre>\n </div>\n )}\n </div>\n </div>\n )\n },\n)\nErrorDisplay.displayName = 'ErrorDisplay'\n\ninterface ErrorBoundaryProps {\n children: React.ReactNode\n /** Called when the user clicks \"Try Again\" (after the boundary resets). */\n onReset?: () => void\n /** Called when an error is caught — wire your logger/Sentry here. */\n onError?: (error: unknown, info: React.ErrorInfo) => void\n /** Auto-reset when any value in this array changes (react-error-boundary parity). */\n resetKeys?: unknown[]\n /** Custom fallback — receives the caught error + a reset callback. Defaults to ErrorDisplay. */\n fallback?: (props: { error: unknown; onReset: () => void }) => React.ReactNode\n}\n\ninterface ErrorBoundaryState {\n error: unknown | null\n}\n\nfunction keysChanged(a: unknown[] | undefined, b: unknown[] | undefined) {\n if (!a || !b) return false\n if (a.length !== b.length) return true\n return a.some((v, i) => !Object.is(v, b[i]))\n}\n\nclass ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> {\n constructor(props: ErrorBoundaryProps) {\n super(props)\n this.state = { error: null }\n }\n\n static getDerivedStateFromError(error: unknown): ErrorBoundaryState {\n return { error }\n }\n\n componentDidCatch(error: unknown, info: React.ErrorInfo) {\n this.props.onError?.(error, info)\n }\n\n componentDidUpdate(prev: ErrorBoundaryProps) {\n // Auto-recover when the reset dependencies change.\n if (this.state.error !== null && keysChanged(prev.resetKeys, this.props.resetKeys)) {\n this.setState({ error: null })\n }\n }\n\n private handleReset = () => {\n this.setState({ error: null })\n this.props.onReset?.()\n }\n\n render() {\n if (this.state.error !== null) {\n if (this.props.fallback) {\n return this.props.fallback({ error: this.state.error, onReset: this.handleReset })\n }\n return <ErrorDisplay error={this.state.error} onReset={this.handleReset} autoFocusReset />\n }\n return this.props.children\n }\n}\n\nexport { ErrorBoundary, ErrorDisplay }\nexport type { ErrorBoundaryProps }\n"],"mappings":"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"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
export interface CardSkeletonProps extends React.ComponentPropsWithoutRef<'div'> {
|
|
3
3
|
className?: string;
|
|
4
|
+
/** Accessible label for the loading region. @default 'Loading' */
|
|
5
|
+
label?: string;
|
|
4
6
|
}
|
|
5
7
|
declare const CardSkeleton: React.ForwardRefExoticComponent<CardSkeletonProps & React.RefAttributes<HTMLDivElement>>;
|
|
6
8
|
export interface TableSkeletonProps extends CardSkeletonProps {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loading-skeleton.d.ts","sourceRoot":"","sources":["../../src/composed/loading-skeleton.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"loading-skeleton.d.ts","sourceRoot":"","sources":["../../src/composed/loading-skeleton.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAkB9B,MAAM,WAAW,iBAAkB,SAAQ,KAAK,CAAC,wBAAwB,CAAC,KAAK,CAAC;IAC9E,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,kEAAkE;IAClE,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,QAAA,MAAM,YAAY,0FA0BjB,CAAA;AAGD,MAAM,WAAW,kBAAmB,SAAQ,iBAAiB;IAC3D,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,QAAA,MAAM,aAAa,2FAsClB,CAAA;AAGD,MAAM,WAAW,kBAAmB,SAAQ,iBAAiB;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,QAAA,MAAM,aAAa,2FA0ClB,CAAA;AAGD,MAAM,WAAW,iBAAkB,SAAQ,iBAAiB;IAC1D,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB;AAED,QAAA,MAAM,YAAY,0FAyBjB,CAAA;AAGD,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,CAAA"}
|