@epicbagel/saas-kit 1.2.3 → 1.3.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.
Files changed (58) hide show
  1. package/README.md +59 -0
  2. package/dist/chunk-2TKLS73N.js +121 -0
  3. package/dist/chunk-4UUTKR3V.cjs +53 -0
  4. package/dist/chunk-BTHYGHOH.cjs +143 -0
  5. package/dist/chunk-GRY77463.cjs +121 -0
  6. package/dist/chunk-HHV4G77I.js +55 -0
  7. package/dist/{chunk-KYQPX754.js → chunk-HRLP4BHJ.js} +7 -7
  8. package/dist/{chunk-N6V3DDKU.cjs → chunk-IH3COANJ.cjs} +7 -7
  9. package/dist/chunk-JTI4244T.js +143 -0
  10. package/dist/chunk-QEJ2STIV.js +53 -0
  11. package/dist/chunk-VLXPLKFR.cjs +55 -0
  12. package/dist/primitives/activity-feed.cjs +3 -3
  13. package/dist/primitives/activity-feed.js +4 -4
  14. package/dist/primitives/board-view.cjs +6 -6
  15. package/dist/primitives/board-view.js +5 -5
  16. package/dist/primitives/chat.cjs +14 -14
  17. package/dist/primitives/chat.js +12 -12
  18. package/dist/primitives/code-block.cjs +5 -50
  19. package/dist/primitives/code-block.js +5 -50
  20. package/dist/primitives/connection.cjs +6 -6
  21. package/dist/primitives/connection.js +7 -7
  22. package/dist/primitives/copy-button.cjs +3 -3
  23. package/dist/primitives/copy-button.js +2 -2
  24. package/dist/primitives/document-preview.cjs +54 -0
  25. package/dist/primitives/document-preview.d.cts +30 -0
  26. package/dist/primitives/document-preview.d.ts +30 -0
  27. package/dist/primitives/document-preview.js +54 -0
  28. package/dist/primitives/editable-list.cjs +1 -1
  29. package/dist/primitives/editable-list.js +1 -1
  30. package/dist/primitives/file-dropzone.cjs +3 -3
  31. package/dist/primitives/file-dropzone.js +2 -2
  32. package/dist/primitives/file-preview-internals.cjs +20 -0
  33. package/dist/primitives/file-preview-internals.d.cts +44 -0
  34. package/dist/primitives/file-preview-internals.d.ts +44 -0
  35. package/dist/primitives/file-preview-internals.js +20 -0
  36. package/dist/primitives/file-preview.cjs +327 -0
  37. package/dist/primitives/file-preview.d.cts +92 -0
  38. package/dist/primitives/file-preview.d.ts +92 -0
  39. package/dist/primitives/file-preview.js +327 -0
  40. package/dist/primitives/filter-bar.cjs +4 -4
  41. package/dist/primitives/filter-bar.js +3 -3
  42. package/dist/primitives/image.cjs +4 -48
  43. package/dist/primitives/image.js +3 -47
  44. package/dist/primitives/resource-list.cjs +6 -6
  45. package/dist/primitives/resource-list.js +5 -5
  46. package/dist/primitives/responsive-dialog.cjs +26 -142
  47. package/dist/primitives/responsive-dialog.js +13 -129
  48. package/dist/primitives/section.cjs +2 -2
  49. package/dist/primitives/section.js +3 -3
  50. package/dist/primitives/switch-field.cjs +2 -2
  51. package/dist/primitives/switch-field.js +3 -3
  52. package/package.json +21 -1
  53. package/dist/{chunk-6OTAGP2I.cjs → chunk-KADJ56AH.cjs} +2 -2
  54. package/dist/{chunk-EHKMVJ6O.js → chunk-M7FYGAGO.js} +3 -3
  55. package/dist/{chunk-PVZ4JGDU.js → chunk-MLHNYRFX.js} +6 -6
  56. package/dist/{chunk-PWOQMTPX.js → chunk-NW3OWKBN.js} +3 -3
  57. package/dist/{chunk-CYH63OCL.cjs → chunk-SGW4FWBX.cjs} +6 -6
  58. package/dist/{chunk-ENJNZ323.cjs → chunk-VKIGJNJR.cjs} +2 -2
package/README.md CHANGED
@@ -160,6 +160,65 @@ public in 1.1.0, and these were the decisions about its props then:
160
160
  scroller neither anchors it nor tracks it. It has no time marker, files or
161
161
  rich `content`, and the turns either side of it keep their time grouping.
162
162
 
163
+ ## File preview (1.3.0)
164
+
165
+ `primitives/file-preview` shows a file in a dialog without leaving the page:
166
+ the kit's large preview dialog on desktop and its near-full-height drawer on
167
+ mobile, with the file's name, a download action and a close button in the
168
+ header.
169
+
170
+ ```tsx
171
+ import { FilePreview } from "@epicbagel/saas-kit/primitives/file-preview";
172
+
173
+ <FilePreview
174
+ open={open}
175
+ onOpenChange={setOpen}
176
+ title={file.name}
177
+ mediaType={file.mediaType}
178
+ file={blob} // fetched by the app, with its own authentication
179
+ loading={!blob && !error}
180
+ error={error}
181
+ onDownload={download}
182
+ />
183
+ ```
184
+
185
+ - **Each type its own way.** A PDF opens in the browser's own viewer (no PDF
186
+ engine in the bundle), an image as an image, text (plain text, CSV, JSON,
187
+ code) as it is, Markdown rendered through `LazyMarkdown`, audio and video
188
+ in the browser's player. Office documents, archives and anything else say
189
+ "No preview for this file." and offer the download; `fallback` replaces
190
+ that message. An image, player or text that won't load says so, with the
191
+ download.
192
+ - **The app fetches.** The dialog is presentation only. Pass the file as a
193
+ `Blob` (`file`), fetched with whatever authentication the app needs, or a
194
+ short-lived, safe URL (`src`). Text and Markdown are read from the `Blob`,
195
+ or fetched from `src`, which must then allow it (the same origin, or
196
+ CORS). Nothing is read or fetched while the dialog is closed.
197
+ - **Safe by construction.** A `Blob` is shown through an object URL the
198
+ dialog revokes when it closes or the file changes. A PDF from a `Blob` is
199
+ always shown as `application/pdf`, whatever type the blob carries, so a
200
+ file can never render as a page of your origin; text is never
201
+ interpreted; a Markdown file's raw HTML is ignored and its links open in a
202
+ new tab. A `src` is framed as it is, so serve it with its real type.
203
+ - **Telling the type.** `filePreviewKind({ name, mediaType })` returns `pdf`,
204
+ `image`, `text`, `markdown`, `audio`, `video` or `none`, which is what the
205
+ dialog uses unless you pass `kind`. The media type decides when it says
206
+ something, and the extension when it is missing or generic
207
+ (`application/octet-stream`); text named `.md` is Markdown, and a name
208
+ that says text wins over a type with no preview (Windows reports a `.csv`
209
+ as `application/vnd.ms-excel`). Call it to choose between opening a
210
+ preview and downloading straight away.
211
+ - **Long text.** A text file over 500,000 characters shows its start, cut at
212
+ a line break, under `truncatedLabel`.
213
+ - **Copy.** `downloadLabel` ("Download file"), `loadingLabel` ("Loading
214
+ preview…"), `unavailableLabel` ("No preview for this file."),
215
+ `failedLabel` ("This file couldn't be shown here.") and `truncatedLabel`
216
+ can all be replaced; the close button's name ("Close preview") is fixed
217
+ for now.
218
+
219
+ `primitives/document-preview` is the same dialog with every `src` in the
220
+ browser's viewer, as it was in ui-kit; its API is unchanged.
221
+
163
222
  ## License
164
223
 
165
224
  MIT. Some components and styles are adapted from shadcn/ui, and the file
@@ -0,0 +1,121 @@
1
+ "use client";
2
+ import {
3
+ ResponsiveDialog,
4
+ ResponsiveDialogClose,
5
+ ResponsiveDialogContent,
6
+ ResponsiveDialogDescription,
7
+ ResponsiveDialogHeader,
8
+ ResponsiveDialogTitle
9
+ } from "./chunk-JTI4244T.js";
10
+ import {
11
+ Icon
12
+ } from "./chunk-KN4RPX35.js";
13
+ import {
14
+ Button
15
+ } from "./chunk-HQRWRRZJ.js";
16
+ import {
17
+ cn
18
+ } from "./chunk-G6SRSWXB.js";
19
+
20
+ // src/primitives/file-preview-internals.tsx
21
+ import { Download, Loader2, X } from "lucide-react";
22
+ import { jsx, jsxs } from "react/jsx-runtime";
23
+ function PreviewDialog({
24
+ open,
25
+ onOpenChange,
26
+ title,
27
+ onDownload,
28
+ downloading,
29
+ downloadLabel,
30
+ children
31
+ }) {
32
+ return /* @__PURE__ */ jsx(ResponsiveDialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs(ResponsiveDialogContent, { presentation: "preview", className: "h-[92dvh] outline-none", children: [
33
+ /* @__PURE__ */ jsxs(ResponsiveDialogHeader, { className: "shrink-0 border-b border-border", children: [
34
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [
35
+ /* @__PURE__ */ jsx(ResponsiveDialogTitle, { className: "min-w-0 flex-1 truncate text-left", children: title }),
36
+ onDownload && /* @__PURE__ */ jsx(
37
+ Button,
38
+ {
39
+ type: "button",
40
+ size: "icon-compact",
41
+ variant: "ghost",
42
+ onClick: onDownload,
43
+ disabled: downloading,
44
+ title: downloadLabel,
45
+ "aria-label": downloadLabel,
46
+ children: /* @__PURE__ */ jsx(Icon, { icon: downloading ? Loader2 : Download, size: "sm", spin: downloading })
47
+ }
48
+ ),
49
+ /* @__PURE__ */ jsx(ResponsiveDialogClose, { asChild: true, children: /* @__PURE__ */ jsx(
50
+ Button,
51
+ {
52
+ type: "button",
53
+ size: "icon-compact",
54
+ variant: "ghost",
55
+ title: "Close preview",
56
+ "aria-label": "Close preview",
57
+ children: /* @__PURE__ */ jsx(Icon, { icon: X, size: "sm" })
58
+ }
59
+ ) })
60
+ ] }),
61
+ /* @__PURE__ */ jsxs(ResponsiveDialogDescription, { className: "sr-only", children: [
62
+ "Preview of ",
63
+ title
64
+ ] })
65
+ ] }),
66
+ children
67
+ ] }) });
68
+ }
69
+ function PreviewStage({
70
+ layout = "center",
71
+ label,
72
+ children
73
+ }) {
74
+ const scrolls = layout === "scroll";
75
+ return /* @__PURE__ */ jsx(
76
+ "div",
77
+ {
78
+ "data-slot": "preview-stage",
79
+ role: scrolls ? "region" : void 0,
80
+ "aria-label": scrolls ? label : void 0,
81
+ tabIndex: scrolls ? 0 : void 0,
82
+ className: cn(
83
+ "min-h-0 flex-1",
84
+ scrolls ? "overflow-y-auto overscroll-contain bg-background p-4 outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring/50 sm:p-6" : "flex items-center justify-center overflow-hidden bg-muted"
85
+ ),
86
+ children
87
+ }
88
+ );
89
+ }
90
+ function PreviewLoading({ label }) {
91
+ return /* @__PURE__ */ jsxs("div", { role: "status", className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
92
+ /* @__PURE__ */ jsx(Icon, { icon: Loader2, size: "sm", spin: true }),
93
+ label
94
+ ] });
95
+ }
96
+ function PreviewNotice({
97
+ icon,
98
+ alert = false,
99
+ message,
100
+ children
101
+ }) {
102
+ return /* @__PURE__ */ jsxs(
103
+ "div",
104
+ {
105
+ role: alert ? "alert" : void 0,
106
+ className: "flex max-w-sm flex-col items-center gap-3 p-6 text-center text-sm text-muted-foreground",
107
+ children: [
108
+ /* @__PURE__ */ jsx(Icon, { icon, size: "lg" }),
109
+ /* @__PURE__ */ jsx("span", { children: message }),
110
+ children
111
+ ]
112
+ }
113
+ );
114
+ }
115
+
116
+ export {
117
+ PreviewDialog,
118
+ PreviewStage,
119
+ PreviewLoading,
120
+ PreviewNotice
121
+ };
@@ -0,0 +1,53 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }"use client";
2
+
3
+
4
+ var _chunkKWLSBTB2cjs = require('./chunk-KWLSBTB2.cjs');
5
+
6
+ // src/primitives/image.tsx
7
+ var _react = require('react');
8
+ var _jsxruntime = require('react/jsx-runtime');
9
+ var fitStyles = { cover: "object-cover", contain: "object-contain" };
10
+ var radiusStyles = { none: "", sm: "rounded-sm", md: "rounded-md", xl: "rounded-xl", full: "rounded-full" };
11
+ var Image = _react.forwardRef.call(void 0, function Image2({ fit = "cover", frameHeight, radius = "none", width = "auto", align = "start", border = false, shadow = "none", emphasis = "full", loadingIndicator = "none", className, onLoad, onError, src, ...props }, ref) {
12
+ const [loaded, setLoaded] = _react.useState.call(void 0, loadingIndicator === "none" || !src);
13
+ _react.useEffect.call(void 0, () => {
14
+ setLoaded(loadingIndicator === "none" || !src);
15
+ }, [loadingIndicator, src]);
16
+ const loading = loadingIndicator === "pulse" && !loaded;
17
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
18
+ "img",
19
+ {
20
+ ref,
21
+ className: _chunkKWLSBTB2cjs.cn.call(void 0,
22
+ fitStyles[fit],
23
+ radiusStyles[radius],
24
+ frameHeight === "sm" && "h-16",
25
+ frameHeight === "md" && "h-28",
26
+ width === "full" && "w-full",
27
+ width === "preview" && "w-full max-w-[380px]",
28
+ width === "preview-lg" && "w-full max-w-[440px]",
29
+ align === "center" && "mx-auto",
30
+ border && "border",
31
+ shadow === "subtle" && "shadow-xs",
32
+ loading && "animate-pulse bg-muted",
33
+ emphasis === "soft-until-parent-hover" && "transition-opacity duration-200 md:opacity-70 md:group-hover:opacity-100",
34
+ className
35
+ ),
36
+ src,
37
+ ...props,
38
+ "aria-busy": loading || void 0,
39
+ onLoad: (event) => {
40
+ setLoaded(true);
41
+ _optionalChain([onLoad, 'optionalCall', _ => _(event)]);
42
+ },
43
+ onError: (event) => {
44
+ setLoaded(true);
45
+ _optionalChain([onError, 'optionalCall', _2 => _2(event)]);
46
+ }
47
+ }
48
+ );
49
+ });
50
+
51
+
52
+
53
+ exports.Image = Image;
@@ -0,0 +1,143 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } }"use client";
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
+
11
+ var _chunk2BHI5ZWJcjs = require('./chunk-2BHI5ZWJ.cjs');
12
+
13
+
14
+
15
+
16
+
17
+
18
+
19
+
20
+
21
+ var _chunkWDXEJDMOcjs = require('./chunk-WDXEJDMO.cjs');
22
+
23
+
24
+ var _chunkKWLSBTB2cjs = require('./chunk-KWLSBTB2.cjs');
25
+
26
+ // src/primitives/responsive-dialog.tsx
27
+ var _react = require('react'); var React = _interopRequireWildcard(_react);
28
+ var _reactresponsive = require('react-responsive');
29
+ var _jsxruntime = require('react/jsx-runtime');
30
+ var DesktopContext = React.createContext(false);
31
+ var useIsDesktop = () => React.useContext(DesktopContext);
32
+ var DESKTOP_QUERY = { minWidth: 1024 };
33
+ var ResponsiveDialog = ({ children, ...props }) => {
34
+ const isDesktop = _reactresponsive.useMediaQuery.call(void 0, DESKTOP_QUERY);
35
+ const Root = isDesktop ? _chunkWDXEJDMOcjs.Dialog : _chunk2BHI5ZWJcjs.Drawer;
36
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DesktopContext.Provider, { value: isDesktop, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Root, { ...props, children }) });
37
+ };
38
+ ResponsiveDialog.displayName = "ResponsiveDialog";
39
+ var ResponsiveDialogTrigger = ({
40
+ children,
41
+ ...props
42
+ }) => {
43
+ const Trigger = useIsDesktop() ? _chunkWDXEJDMOcjs.DialogTrigger : _chunk2BHI5ZWJcjs.DrawerTrigger;
44
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Trigger, { ...props, children });
45
+ };
46
+ ResponsiveDialogTrigger.displayName = "ResponsiveDialogTrigger";
47
+ var ResponsiveDialogClose = ({
48
+ children,
49
+ ...props
50
+ }) => {
51
+ const Close = useIsDesktop() ? _chunkWDXEJDMOcjs.DialogClose : _chunk2BHI5ZWJcjs.DrawerClose;
52
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Close, { ...props, children });
53
+ };
54
+ ResponsiveDialogClose.displayName = "ResponsiveDialogClose";
55
+ var ResponsiveDialogContent = React.forwardRef(({ className, children, presentation = "default", ...props }, ref) => {
56
+ if (useIsDesktop()) {
57
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
58
+ _chunkWDXEJDMOcjs.DialogContent,
59
+ {
60
+ ref,
61
+ className: _chunkKWLSBTB2cjs.cn.call(void 0,
62
+ "flex max-h-[85vh] max-w-md flex-col gap-0 overflow-hidden p-0",
63
+ presentation === "preview" && "max-w-2xl sm:h-[85vh] [&>button:last-child]:hidden",
64
+ className
65
+ ),
66
+ ...props,
67
+ children
68
+ }
69
+ );
70
+ }
71
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
72
+ _chunk2BHI5ZWJcjs.DrawerContent,
73
+ {
74
+ ref,
75
+ className: _chunkKWLSBTB2cjs.cn.call(void 0, "max-h-[92vh]", className),
76
+ ...props,
77
+ children
78
+ }
79
+ );
80
+ });
81
+ ResponsiveDialogContent.displayName = "ResponsiveDialogContent";
82
+ var ResponsiveDialogHeader = ({
83
+ className,
84
+ visibility = "visible",
85
+ ...props
86
+ }) => {
87
+ const Header = useIsDesktop() ? _chunkWDXEJDMOcjs.DialogHeader : _chunk2BHI5ZWJcjs.DrawerHeader;
88
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
89
+ Header,
90
+ {
91
+ className: _chunkKWLSBTB2cjs.cn.call(void 0, useIsDesktop() && "p-4", visibility === "screen-reader" && "sr-only", className),
92
+ ...props
93
+ }
94
+ );
95
+ };
96
+ ResponsiveDialogHeader.displayName = "ResponsiveDialogHeader";
97
+ var ResponsiveDialogBody = ({
98
+ className,
99
+ ...props
100
+ }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: _chunkKWLSBTB2cjs.cn.call(void 0, "min-h-0 flex-1 overflow-y-auto px-4 pb-6", className), ...props });
101
+ ResponsiveDialogBody.displayName = "ResponsiveDialogBody";
102
+ var ResponsiveDialogFooter = ({
103
+ className,
104
+ layout = "auto",
105
+ ...props
106
+ }) => {
107
+ const isDesktop = useIsDesktop();
108
+ const Footer = isDesktop ? _chunkWDXEJDMOcjs.DialogFooter : _chunk2BHI5ZWJcjs.DrawerFooter;
109
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
110
+ Footer,
111
+ {
112
+ className: _chunkKWLSBTB2cjs.cn.call(void 0,
113
+ "mt-0 shrink-0 gap-2 border-t bg-background p-4",
114
+ layout === "fill" ? "flex-row space-x-0 [&>*]:min-w-0 [&>*]:flex-1" : isDesktop ? "flex-row justify-end space-x-0 [&>*]:flex-none" : "grid grid-cols-2 [&>*]:w-full",
115
+ className
116
+ ),
117
+ ...props
118
+ }
119
+ );
120
+ };
121
+ ResponsiveDialogFooter.displayName = "ResponsiveDialogFooter";
122
+ var ResponsiveDialogTitle = React.forwardRef(({ className, visuallyHidden = false, ...props }, ref) => {
123
+ const Title = useIsDesktop() ? _chunkWDXEJDMOcjs.DialogTitle : _chunk2BHI5ZWJcjs.DrawerTitle;
124
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Title, { ref, className: _chunkKWLSBTB2cjs.cn.call(void 0, visuallyHidden && "sr-only", className), ...props });
125
+ });
126
+ ResponsiveDialogTitle.displayName = "ResponsiveDialogTitle";
127
+ var ResponsiveDialogDescription = React.forwardRef(({ className, visuallyHidden = false, ...props }, ref) => {
128
+ const Description = useIsDesktop() ? _chunkWDXEJDMOcjs.DialogDescription : _chunk2BHI5ZWJcjs.DrawerDescription;
129
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Description, { ref, className: _chunkKWLSBTB2cjs.cn.call(void 0, visuallyHidden && "sr-only", className), ...props });
130
+ });
131
+ ResponsiveDialogDescription.displayName = "ResponsiveDialogDescription";
132
+
133
+
134
+
135
+
136
+
137
+
138
+
139
+
140
+
141
+
142
+
143
+ exports.ResponsiveDialog = ResponsiveDialog; exports.ResponsiveDialogTrigger = ResponsiveDialogTrigger; exports.ResponsiveDialogClose = ResponsiveDialogClose; exports.ResponsiveDialogContent = ResponsiveDialogContent; exports.ResponsiveDialogHeader = ResponsiveDialogHeader; exports.ResponsiveDialogBody = ResponsiveDialogBody; exports.ResponsiveDialogFooter = ResponsiveDialogFooter; exports.ResponsiveDialogTitle = ResponsiveDialogTitle; exports.ResponsiveDialogDescription = ResponsiveDialogDescription;
@@ -0,0 +1,121 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});"use client";
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+ var _chunkBTHYGHOHcjs = require('./chunk-BTHYGHOH.cjs');
10
+
11
+
12
+ var _chunkT2ZFSPE4cjs = require('./chunk-T2ZFSPE4.cjs');
13
+
14
+
15
+ var _chunkL4DH72UFcjs = require('./chunk-L4DH72UF.cjs');
16
+
17
+
18
+ var _chunkKWLSBTB2cjs = require('./chunk-KWLSBTB2.cjs');
19
+
20
+ // src/primitives/file-preview-internals.tsx
21
+ var _lucidereact = require('lucide-react');
22
+ var _jsxruntime = require('react/jsx-runtime');
23
+ function PreviewDialog({
24
+ open,
25
+ onOpenChange,
26
+ title,
27
+ onDownload,
28
+ downloading,
29
+ downloadLabel,
30
+ children
31
+ }) {
32
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkBTHYGHOHcjs.ResponsiveDialog, { open, onOpenChange, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkBTHYGHOHcjs.ResponsiveDialogContent, { presentation: "preview", className: "h-[92dvh] outline-none", children: [
33
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkBTHYGHOHcjs.ResponsiveDialogHeader, { className: "shrink-0 border-b border-border", children: [
34
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex min-w-0 items-center gap-2", children: [
35
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkBTHYGHOHcjs.ResponsiveDialogTitle, { className: "min-w-0 flex-1 truncate text-left", children: title }),
36
+ onDownload && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
37
+ _chunkL4DH72UFcjs.Button,
38
+ {
39
+ type: "button",
40
+ size: "icon-compact",
41
+ variant: "ghost",
42
+ onClick: onDownload,
43
+ disabled: downloading,
44
+ title: downloadLabel,
45
+ "aria-label": downloadLabel,
46
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkT2ZFSPE4cjs.Icon, { icon: downloading ? _lucidereact.Loader2 : _lucidereact.Download, size: "sm", spin: downloading })
47
+ }
48
+ ),
49
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkBTHYGHOHcjs.ResponsiveDialogClose, { asChild: true, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
50
+ _chunkL4DH72UFcjs.Button,
51
+ {
52
+ type: "button",
53
+ size: "icon-compact",
54
+ variant: "ghost",
55
+ title: "Close preview",
56
+ "aria-label": "Close preview",
57
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkT2ZFSPE4cjs.Icon, { icon: _lucidereact.X, size: "sm" })
58
+ }
59
+ ) })
60
+ ] }),
61
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkBTHYGHOHcjs.ResponsiveDialogDescription, { className: "sr-only", children: [
62
+ "Preview of ",
63
+ title
64
+ ] })
65
+ ] }),
66
+ children
67
+ ] }) });
68
+ }
69
+ function PreviewStage({
70
+ layout = "center",
71
+ label,
72
+ children
73
+ }) {
74
+ const scrolls = layout === "scroll";
75
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
76
+ "div",
77
+ {
78
+ "data-slot": "preview-stage",
79
+ role: scrolls ? "region" : void 0,
80
+ "aria-label": scrolls ? label : void 0,
81
+ tabIndex: scrolls ? 0 : void 0,
82
+ className: _chunkKWLSBTB2cjs.cn.call(void 0,
83
+ "min-h-0 flex-1",
84
+ scrolls ? "overflow-y-auto overscroll-contain bg-background p-4 outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring/50 sm:p-6" : "flex items-center justify-center overflow-hidden bg-muted"
85
+ ),
86
+ children
87
+ }
88
+ );
89
+ }
90
+ function PreviewLoading({ label }) {
91
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { role: "status", className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
92
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkT2ZFSPE4cjs.Icon, { icon: _lucidereact.Loader2, size: "sm", spin: true }),
93
+ label
94
+ ] });
95
+ }
96
+ function PreviewNotice({
97
+ icon,
98
+ alert = false,
99
+ message,
100
+ children
101
+ }) {
102
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
103
+ "div",
104
+ {
105
+ role: alert ? "alert" : void 0,
106
+ className: "flex max-w-sm flex-col items-center gap-3 p-6 text-center text-sm text-muted-foreground",
107
+ children: [
108
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkT2ZFSPE4cjs.Icon, { icon, size: "lg" }),
109
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: message }),
110
+ children
111
+ ]
112
+ }
113
+ );
114
+ }
115
+
116
+
117
+
118
+
119
+
120
+
121
+ exports.PreviewDialog = PreviewDialog; exports.PreviewStage = PreviewStage; exports.PreviewLoading = PreviewLoading; exports.PreviewNotice = PreviewNotice;
@@ -0,0 +1,55 @@
1
+ "use client";
2
+ import {
3
+ CopyButton
4
+ } from "./chunk-NW3OWKBN.js";
5
+ import {
6
+ cn
7
+ } from "./chunk-G6SRSWXB.js";
8
+
9
+ // src/primitives/code-block.tsx
10
+ import { jsx, jsxs } from "react/jsx-runtime";
11
+ var HEIGHTS = {
12
+ none: "",
13
+ sm: "max-h-40 overflow-y-auto",
14
+ md: "max-h-64 overflow-y-auto",
15
+ lg: "max-h-96 overflow-y-auto",
16
+ viewport: "min-h-[55vh] max-h-[65vh] overflow-y-auto"
17
+ };
18
+ function CodeBlock({
19
+ children,
20
+ copy,
21
+ copyLabel,
22
+ wrap = false,
23
+ maxHeight = "none",
24
+ className
25
+ }) {
26
+ const copyText = typeof copy === "string" ? copy : children;
27
+ return /* @__PURE__ */ jsxs("div", { className: cn("relative", className), children: [
28
+ /* @__PURE__ */ jsx(
29
+ "pre",
30
+ {
31
+ className: cn(
32
+ "rounded-md border border-border bg-muted/40 p-3 font-mono text-xs leading-relaxed",
33
+ wrap ? "whitespace-pre-wrap break-words" : "overflow-x-auto",
34
+ HEIGHTS[maxHeight],
35
+ copy ? "pr-12" : void 0
36
+ ),
37
+ children
38
+ }
39
+ ),
40
+ copy ? /* @__PURE__ */ jsx(
41
+ CopyButton,
42
+ {
43
+ text: copyText,
44
+ label: copyLabel,
45
+ size: "sm",
46
+ variant: "ghost",
47
+ className: "absolute right-1.5 top-1.5"
48
+ }
49
+ ) : null
50
+ ] });
51
+ }
52
+
53
+ export {
54
+ CodeBlock
55
+ };
@@ -7,16 +7,16 @@ import {
7
7
  } from "./chunk-J3GQXM37.js";
8
8
  import {
9
9
  FilterBar
10
- } from "./chunk-PVZ4JGDU.js";
10
+ } from "./chunk-MLHNYRFX.js";
11
+ import {
12
+ Heading
13
+ } from "./chunk-H2O6NMLZ.js";
11
14
  import {
12
15
  Tooltip,
13
16
  TooltipContent,
14
17
  TooltipProvider,
15
18
  TooltipTrigger
16
19
  } from "./chunk-ZRLUUZHK.js";
17
- import {
18
- Heading
19
- } from "./chunk-H2O6NMLZ.js";
20
20
  import {
21
21
  BoardColumnComponent,
22
22
  MobileBoardView
@@ -24,15 +24,15 @@ import {
24
24
  import {
25
25
  ScrollArea
26
26
  } from "./chunk-LELFPLTE.js";
27
- import {
28
- useIsMobile
29
- } from "./chunk-PIU5SSUV.js";
30
27
  import {
31
28
  Input
32
29
  } from "./chunk-QMA3WVB7.js";
33
30
  import {
34
31
  Button
35
32
  } from "./chunk-HQRWRRZJ.js";
33
+ import {
34
+ useIsMobile
35
+ } from "./chunk-PIU5SSUV.js";
36
36
  import {
37
37
  cn
38
38
  } from "./chunk-G6SRSWXB.js";
@@ -7,16 +7,16 @@ var _chunkPNWNU6JWcjs = require('./chunk-PNWNU6JW.cjs');
7
7
  var _chunkFNDBM67Kcjs = require('./chunk-FNDBM67K.cjs');
8
8
 
9
9
 
10
- var _chunkCYH63OCLcjs = require('./chunk-CYH63OCL.cjs');
10
+ var _chunkSGW4FWBXcjs = require('./chunk-SGW4FWBX.cjs');
11
11
 
12
12
 
13
+ var _chunkLELBCBDTcjs = require('./chunk-LELBCBDT.cjs');
13
14
 
14
15
 
15
16
 
16
- var _chunkU2NES7VRcjs = require('./chunk-U2NES7VR.cjs');
17
17
 
18
18
 
19
- var _chunkLELBCBDTcjs = require('./chunk-LELBCBDT.cjs');
19
+ var _chunkU2NES7VRcjs = require('./chunk-U2NES7VR.cjs');
20
20
 
21
21
 
22
22
 
@@ -26,15 +26,15 @@ var _chunkYYFVG5A6cjs = require('./chunk-YYFVG5A6.cjs');
26
26
  var _chunkXLIAY56Vcjs = require('./chunk-XLIAY56V.cjs');
27
27
 
28
28
 
29
- var _chunkR35FT53Gcjs = require('./chunk-R35FT53G.cjs');
30
-
31
-
32
29
  var _chunkPQUSJEXLcjs = require('./chunk-PQUSJEXL.cjs');
33
30
 
34
31
 
35
32
  var _chunkL4DH72UFcjs = require('./chunk-L4DH72UF.cjs');
36
33
 
37
34
 
35
+ var _chunkR35FT53Gcjs = require('./chunk-R35FT53G.cjs');
36
+
37
+
38
38
  var _chunkKWLSBTB2cjs = require('./chunk-KWLSBTB2.cjs');
39
39
 
40
40
  // src/primitives/resource-list.tsx
@@ -268,7 +268,7 @@ function ResourceList({
268
268
  const controlsVisible = !(hideControlsWhenEmpty && !loading && !error && _optionalChain([data, 'optionalAccess', _5 => _5.length]) === 0);
269
269
  const filterOnQuickRow = filterBarVisible && !toolbarHasOtherControls && hasQuickFilters;
270
270
  const filterBarNode = filterBarVisible ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
271
- _chunkCYH63OCLcjs.FilterBar,
271
+ _chunkSGW4FWBXcjs.FilterBar,
272
272
  {
273
273
  filters: filterSchema,
274
274
  onFiltersChange,