@ztwoint/z-ui 0.1.146 → 0.1.148

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 (36) hide show
  1. package/dist/components/pdf-preview/components/pdf-error-state.d.ts +9 -0
  2. package/dist/components/pdf-preview/components/pdf-error-state.js +18 -0
  3. package/dist/components/pdf-preview/components/pdf-loading-state.d.ts +3 -0
  4. package/dist/components/pdf-preview/components/pdf-loading-state.js +34 -0
  5. package/dist/components/pdf-preview/components/pdf-toolbar.d.ts +16 -0
  6. package/dist/components/pdf-preview/components/pdf-toolbar.js +47 -0
  7. package/dist/components/pdf-preview/components/pdf-viewer.d.ts +22 -0
  8. package/dist/components/pdf-preview/components/pdf-viewer.js +6 -0
  9. package/dist/components/pdf-preview/index.d.ts +3 -0
  10. package/dist/components/pdf-preview/pdf-preview.const.d.ts +29 -0
  11. package/dist/components/pdf-preview/pdf-preview.const.js +29 -0
  12. package/dist/components/pdf-preview/pdf-preview.d.ts +16 -0
  13. package/dist/components/pdf-preview/pdf-preview.hook.d.ts +12 -0
  14. package/dist/components/pdf-preview/pdf-preview.hook.js +69 -0
  15. package/dist/components/pdf-preview/pdf-preview.js +77 -0
  16. package/dist/components/pdf-preview/pdf-preview.type.d.ts +81 -0
  17. package/dist/components/primitives/table-card/table-card.js +81 -76
  18. package/dist/components/primitives/table-card/table-card.type.d.ts +1 -0
  19. package/dist/components/table/components/cell/avatar-cell.js +3 -2
  20. package/dist/components/table/table-provider.js +1 -0
  21. package/dist/css/styles/tailwind.css +1 -1
  22. package/dist/index.d.ts +1 -0
  23. package/dist/index.js +56 -54
  24. package/dist/sample-resume.pdf +0 -0
  25. package/dist/types/components/pdf-preview/components/pdf-error-state.d.ts +9 -0
  26. package/dist/types/components/pdf-preview/components/pdf-loading-state.d.ts +3 -0
  27. package/dist/types/components/pdf-preview/components/pdf-toolbar.d.ts +16 -0
  28. package/dist/types/components/pdf-preview/components/pdf-viewer.d.ts +22 -0
  29. package/dist/types/components/pdf-preview/index.d.ts +3 -0
  30. package/dist/types/components/pdf-preview/pdf-preview.const.d.ts +29 -0
  31. package/dist/types/components/pdf-preview/pdf-preview.d.ts +16 -0
  32. package/dist/types/components/pdf-preview/pdf-preview.hook.d.ts +12 -0
  33. package/dist/types/components/pdf-preview/pdf-preview.type.d.ts +81 -0
  34. package/dist/types/components/primitives/table-card/table-card.type.d.ts +1 -0
  35. package/dist/types/index.d.ts +1 -0
  36. package/package.json +1 -1
@@ -0,0 +1,9 @@
1
+ import { PdfPreviewError } from '../pdf-preview.type';
2
+ import * as React from 'react';
3
+ interface PdfErrorStateProps {
4
+ error: PdfPreviewError;
5
+ onRetry: () => void;
6
+ }
7
+ /** Default error UI shown when PDF loading fails. Displays warning icon, error message, and a retry button. */
8
+ export declare const PdfErrorState: React.FC<PdfErrorStateProps>;
9
+ export {};
@@ -0,0 +1,18 @@
1
+ import { jsxs as a, jsx as e } from "react/jsx-runtime";
2
+ import { Button as l } from "../../button/button.js";
3
+ import s from "../../assets/icons/triangle-warning.js";
4
+ const n = ({ error: t, onRetry: r }) => /* @__PURE__ */ a(
5
+ "div",
6
+ {
7
+ "data-slot": "pdf-error-state",
8
+ className: "flex flex-1 flex-col items-center justify-center gap-3 p-6 text-center",
9
+ children: [
10
+ /* @__PURE__ */ e(s, { width: "2em", height: "2em", className: "text-text-danger-primary" }),
11
+ /* @__PURE__ */ e("p", { className: "text-sm text-text-neutral-primary", children: t.message || "Failed to load PDF" }),
12
+ /* @__PURE__ */ e(l, { onClick: r, variant: "stroke", shade: "neutral", size: "small", label: "Retry" })
13
+ ]
14
+ }
15
+ );
16
+ export {
17
+ n as PdfErrorState
18
+ };
@@ -0,0 +1,3 @@
1
+ import * as React from 'react';
2
+ /** Default loading spinner shown while the PDF source is being resolved/fetched. */
3
+ export declare const PdfLoadingState: React.FC;
@@ -0,0 +1,34 @@
1
+ import { jsx as t, jsxs as e } from "react/jsx-runtime";
2
+ const a = () => /* @__PURE__ */ t("div", { "data-slot": "pdf-loading-state", className: "flex flex-1 items-center justify-center", children: /* @__PURE__ */ e(
3
+ "svg",
4
+ {
5
+ className: "h-8 w-8 animate-spin text-text-neutral-secondary",
6
+ xmlns: "http://www.w3.org/2000/svg",
7
+ fill: "none",
8
+ viewBox: "0 0 24 24",
9
+ children: [
10
+ /* @__PURE__ */ t(
11
+ "circle",
12
+ {
13
+ className: "opacity-25",
14
+ cx: "12",
15
+ cy: "12",
16
+ r: "10",
17
+ stroke: "currentColor",
18
+ strokeWidth: "4"
19
+ }
20
+ ),
21
+ /* @__PURE__ */ t(
22
+ "path",
23
+ {
24
+ className: "opacity-75",
25
+ fill: "currentColor",
26
+ d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
27
+ }
28
+ )
29
+ ]
30
+ }
31
+ ) });
32
+ export {
33
+ a as PdfLoadingState
34
+ };
@@ -0,0 +1,16 @@
1
+ import * as React from 'react';
2
+ interface PdfToolbarProps {
3
+ title: string;
4
+ showDownload: boolean;
5
+ onDownload: () => void;
6
+ downloadDisabled?: boolean;
7
+ }
8
+ /**
9
+ * Toolbar displayed at the top of the PDF preview dialog.
10
+ * Contains:
11
+ * - DialogPrimitive.Title: serves as both the visible title and Radix's required accessible title
12
+ * - Download button (optional): triggers the parent's download handler
13
+ * - Close button: uses DialogPrimitive.Close to close the dialog via Radix
14
+ */
15
+ export declare const PdfToolbar: React.FC<PdfToolbarProps>;
16
+ export {};
@@ -0,0 +1,47 @@
1
+ import { jsxs as a, jsx as e } from "react/jsx-runtime";
2
+ import { Download as i } from "lucide-react";
3
+ import { Button as t } from "../../button/button.js";
4
+ import { Z2DialogTitle as m, Z2DialogClose as n } from "../../dialog/dialog.js";
5
+ import d from "../../assets/icons/x.js";
6
+ const b = ({
7
+ title: r,
8
+ showDownload: l,
9
+ onDownload: o,
10
+ downloadDisabled: s
11
+ }) => /* @__PURE__ */ a(
12
+ "div",
13
+ {
14
+ "data-slot": "pdf-toolbar",
15
+ className: "flex items-center justify-between border-b border-stroke-neutral-default px-4 py-2.5 gap-2",
16
+ children: [
17
+ /* @__PURE__ */ e(m, { className: "text-sm font-medium text-text-neutral-primary truncate", children: r }),
18
+ /* @__PURE__ */ a("div", { className: "flex items-center gap-1.5 shrink-0 ml-2", children: [
19
+ l && /* @__PURE__ */ e(
20
+ t,
21
+ {
22
+ onClick: o,
23
+ variant: "ghost",
24
+ shade: "neutral",
25
+ size: "small",
26
+ leftIcon: /* @__PURE__ */ e(i, { className: "w-3.5 h-3.5" }),
27
+ "aria-label": "Download PDF",
28
+ disabled: s
29
+ }
30
+ ),
31
+ /* @__PURE__ */ e(n, { asChild: !0, children: /* @__PURE__ */ e(
32
+ t,
33
+ {
34
+ variant: "ghost",
35
+ shade: "neutral",
36
+ size: "small",
37
+ leftIcon: /* @__PURE__ */ e(d, {}),
38
+ "aria-label": "Close"
39
+ }
40
+ ) })
41
+ ] })
42
+ ]
43
+ }
44
+ );
45
+ export {
46
+ b as PdfToolbar
47
+ };
@@ -0,0 +1,22 @@
1
+ import * as React from 'react';
2
+ interface PdfViewerProps {
3
+ url: string;
4
+ title: string;
5
+ className?: string;
6
+ }
7
+ /**
8
+ * Browser-native PDF renderer with a two-level fallback:
9
+ *
10
+ * 1. <object type="application/pdf"> — uses the browser's built-in PDF plugin
11
+ * (Chrome, Firefox, Edge all have mature viewers with zoom, search, print)
12
+ *
13
+ * 2. <iframe> — fallback rendered as <object>'s child if the plugin is unavailable
14
+ *
15
+ * Note: <iframe> does not support child fallback content (unlike <object>), so a
16
+ * download link inside <iframe> would be unreachable. If the browser can't render
17
+ * the PDF at all, the iframe will show a blank page or its own error.
18
+ *
19
+ * This approach adds zero JS bundle size since it relies entirely on browser capabilities.
20
+ */
21
+ export declare const PdfViewer: React.FC<PdfViewerProps>;
22
+ export {};
@@ -0,0 +1,6 @@
1
+ import { jsx as a } from "react/jsx-runtime";
2
+ import { cn as f } from "../../../lib/utils.js";
3
+ const o = ({ url: e, title: l, className: r }) => /* @__PURE__ */ a("div", { "data-slot": "pdf-viewer", className: f("flex-1 min-h-0", r), children: /* @__PURE__ */ a("object", { data: e, type: "application/pdf", className: "h-full w-full", "aria-label": l, children: /* @__PURE__ */ a("iframe", { src: e, title: l, className: "h-full w-full border-0" }) }) });
4
+ export {
5
+ o as PdfViewer
6
+ };
@@ -0,0 +1,3 @@
1
+ export { PdfPreview } from './pdf-preview';
2
+ export type { PdfPreviewProps, PdfPreviewError, PdfPreviewStatus } from './pdf-preview.type';
3
+ export type { PdfPreviewSize } from './pdf-preview.const';
@@ -0,0 +1,29 @@
1
+ /** Available dialog size options for the PDF preview modal. */
2
+ export declare const PDF_PREVIEW_SIZES: {
3
+ readonly SM: "sm";
4
+ readonly MD: "md";
5
+ readonly LG: "lg";
6
+ readonly XL: "xl";
7
+ readonly FULL: "full";
8
+ };
9
+ export type PdfPreviewSize = (typeof PDF_PREVIEW_SIZES)[keyof typeof PDF_PREVIEW_SIZES];
10
+ /** Default prop values used when the consumer doesn't provide them. */
11
+ export declare const PDF_PREVIEW_DEFAULTS: {
12
+ readonly size: PdfPreviewSize;
13
+ readonly showToolbar: true;
14
+ readonly showDownload: true;
15
+ };
16
+ /**
17
+ * CVA variants for the dialog content container.
18
+ * Each size sets a max width/height using min() to stay responsive,
19
+ * with a 2rem margin from viewport edges. 'full' takes up nearly the entire screen.
20
+ *
21
+ * Note: Z2DialogContent's base styles include `grid gap-4 max-w-[calc(100%-2rem)] sm:max-w-lg`
22
+ * which conflict with our layout. We override them here with:
23
+ * - `flex flex-col` → overrides `grid` (tailwind-merge handles display conflicts)
24
+ * - `max-w-none sm:max-w-none` → cancels the max-width caps so our w-[min(...)] sizing works
25
+ * - `gap-0` → removes the default gap between children
26
+ */
27
+ export declare const pdfDialogContentVariants: (props?: ({
28
+ size?: "sm" | "md" | "full" | "lg" | "xl" | null | undefined;
29
+ } & import('class-variance-authority/dist/types').ClassProp) | undefined) => string;
@@ -0,0 +1,29 @@
1
+ import { cva as c } from "class-variance-authority";
2
+ const e = {
3
+ LG: "lg"
4
+ }, m = {
5
+ size: e.LG,
6
+ showToolbar: !0,
7
+ showDownload: !0
8
+ }, a = c(
9
+ "flex flex-col max-w-none sm:max-w-none gap-0 overflow-hidden rounded-lg",
10
+ {
11
+ variants: {
12
+ size: {
13
+ sm: "w-[min(500px,calc(100vw-2rem))] h-[min(400px,calc(100vh-2rem))]",
14
+ md: "w-[min(680px,calc(100vw-2rem))] h-[min(560px,calc(100vh-2rem))]",
15
+ lg: "w-[min(900px,calc(100vw-2rem))] h-[min(700px,calc(100vh-2rem))]",
16
+ xl: "w-[min(1100px,calc(100vw-2rem))] h-[min(800px,calc(100vh-2rem))]",
17
+ full: "w-[calc(100vw-2rem)] h-[calc(100vh-2rem)]"
18
+ }
19
+ },
20
+ defaultVariants: {
21
+ size: "lg"
22
+ }
23
+ }
24
+ );
25
+ export {
26
+ m as PDF_PREVIEW_DEFAULTS,
27
+ e as PDF_PREVIEW_SIZES,
28
+ a as pdfDialogContentVariants
29
+ };
@@ -0,0 +1,16 @@
1
+ import { PdfPreviewProps } from './pdf-preview.type';
2
+ import * as React from 'react';
3
+ /**
4
+ * PdfPreview — A zero-dependency PDF preview dialog component.
5
+ *
6
+ * Uses the browser's built-in PDF renderer (<object> + <iframe> fallback)
7
+ * instead of pdf.js, resulting in zero additional bundle size.
8
+ *
9
+ * Supports:
10
+ * - Multiple source types: URL string, Blob, File, or async fetch function
11
+ * - Controlled & uncontrolled open state
12
+ * - Customizable loading/error states
13
+ * - `renderPdf` escape hatch for plugging in custom renderers (e.g. react-pdf)
14
+ */
15
+ declare const PdfPreview: React.FC<PdfPreviewProps>;
16
+ export { PdfPreview };
@@ -0,0 +1,12 @@
1
+ import { UsePdfPreviewProps, UsePdfPreviewReturn } from './pdf-preview.type';
2
+ /**
3
+ * Core hook that manages the entire PDF preview lifecycle:
4
+ * - Controlled/uncontrolled open state (like popconfirm.hook.ts pattern)
5
+ * - Lazy source resolution — async fetch only runs when dialog opens
6
+ * - Blob URL memory management — created on open, revoked on close/unmount
7
+ * - Status state machine: idle → loading → ready | error
8
+ * - Abort tracking to prevent stale state updates if dialog closes mid-fetch
9
+ */
10
+ export declare function usePdfPreview(props: UsePdfPreviewProps): UsePdfPreviewReturn & {
11
+ resolvedTitle: string;
12
+ };
@@ -0,0 +1,69 @@
1
+ import { useRef as c, useState as h, useCallback as R, useEffect as x } from "react";
2
+ function A(t) {
3
+ if (typeof t == "string")
4
+ try {
5
+ const n = new URL(t, "http://localhost").pathname.split("/").pop();
6
+ if (n && n.endsWith(".pdf")) return decodeURIComponent(n);
7
+ } catch {
8
+ }
9
+ return t instanceof File ? t.name : "PDF Preview";
10
+ }
11
+ function W(t) {
12
+ const { src: u, open: n, onOpenChange: a, onError: L, onLoad: P } = t, i = c(u);
13
+ i.current = u;
14
+ const f = c(P);
15
+ f.current = P;
16
+ const d = c(L);
17
+ d.current = L;
18
+ const [k, w] = h(!1), [O, p] = h("idle"), [S, b] = h(null), [j, g] = h(null), v = c(null), m = c(null), y = n !== void 0, C = y ? n : k, o = R(() => {
19
+ v.current && (URL.revokeObjectURL(v.current), v.current = null);
20
+ }, []), U = R(async () => {
21
+ var l, E, F;
22
+ (l = m.current) == null || l.abort();
23
+ const e = new AbortController();
24
+ m.current = e, p("loading"), g(null), b(null), o();
25
+ try {
26
+ let r;
27
+ if (typeof i.current == "function" ? r = await i.current(e.signal) : r = i.current, e.signal.aborted) return;
28
+ if (typeof r == "string")
29
+ b(r);
30
+ else {
31
+ const s = URL.createObjectURL(r);
32
+ v.current = s, b(s);
33
+ }
34
+ p("ready"), (E = f.current) == null || E.call(f);
35
+ } catch (r) {
36
+ if (e.signal.aborted) return;
37
+ const s = {
38
+ message: r instanceof Error ? r.message : "Failed to load PDF",
39
+ cause: r
40
+ };
41
+ g(s), p("error"), (F = d.current) == null || F.call(d, s);
42
+ }
43
+ }, [o]), D = R(
44
+ (e) => {
45
+ var l;
46
+ y || w(e), a == null || a(e), e || ((l = m.current) == null || l.abort(), p("idle"), b(null), g(null), o());
47
+ },
48
+ [y, a, o]
49
+ );
50
+ x(() => (C && U(), () => {
51
+ var e;
52
+ (e = m.current) == null || e.abort(), o();
53
+ }), [C, U, o]);
54
+ const I = R(() => {
55
+ U();
56
+ }, [U]), T = A(u);
57
+ return {
58
+ open: C,
59
+ handleOpenChange: D,
60
+ status: O,
61
+ resolvedUrl: S,
62
+ error: j,
63
+ retry: I,
64
+ resolvedTitle: T
65
+ };
66
+ }
67
+ export {
68
+ W as usePdfPreview
69
+ };
@@ -0,0 +1,77 @@
1
+ import { jsxs as P, jsx as o } from "react/jsx-runtime";
2
+ import * as v from "react";
3
+ import { cn as j } from "../../lib/utils.js";
4
+ import { Z2Dialog as L, Z2DialogTrigger as O, Z2DialogContent as U, Z2DialogTitle as W } from "../dialog/dialog.js";
5
+ import { PDF_PREVIEW_DEFAULTS as m, pdfDialogContentVariants as z } from "./pdf-preview.const.js";
6
+ import { usePdfPreview as A } from "./pdf-preview.hook.js";
7
+ import { PdfToolbar as F } from "./components/pdf-toolbar.js";
8
+ import { PdfViewer as I } from "./components/pdf-viewer.js";
9
+ import { PdfLoadingState as $ } from "./components/pdf-loading-state.js";
10
+ import { PdfErrorState as q } from "./components/pdf-error-state.js";
11
+ const B = ({
12
+ src: y,
13
+ title: w,
14
+ size: D = m.size,
15
+ open: C,
16
+ onOpenChange: E,
17
+ disabled: t = !1,
18
+ showToolbar: c = m.showToolbar,
19
+ showDownload: T = m.showDownload,
20
+ downloadFilename: u,
21
+ onDownload: l,
22
+ loadingContent: b,
23
+ errorContent: n,
24
+ renderPdf: g,
25
+ className: N,
26
+ viewerClassName: Z,
27
+ onError: k,
28
+ onLoad: x,
29
+ children: h
30
+ }) => {
31
+ const { open: f, handleOpenChange: d, status: a, resolvedUrl: e, error: s, retry: R, resolvedTitle: S } = A({
32
+ src: y,
33
+ open: C,
34
+ onOpenChange: E,
35
+ onError: k,
36
+ onLoad: x
37
+ }), i = w || S, V = v.useCallback(() => {
38
+ if (!e)
39
+ return;
40
+ l && l();
41
+ const r = document.createElement("a");
42
+ r.href = e;
43
+ const p = u || i || "document.pdf";
44
+ r.download = p.endsWith(".pdf") ? p : `${p}.pdf`, r.target = "_blank", r.rel = "noopener noreferrer", document.body.appendChild(r), r.click(), document.body.removeChild(r);
45
+ }, [l, e, u, i]), _ = () => a === "idle" || a === "loading" ? b || /* @__PURE__ */ o($, {}) : a === "error" && s ? n ? typeof n == "function" ? n(s) : n : /* @__PURE__ */ o(q, { error: s, onRetry: R }) : a === "ready" && e ? g ? g(e) : /* @__PURE__ */ o(I, { url: e, title: i, className: Z }) : null;
46
+ return v.useEffect(() => {
47
+ t && f && d(!1);
48
+ }, [t, f, d]), // Z2Dialog wraps Radix Dialog — manages focus trapping, escape key, and overlay click-to-close
49
+ /* @__PURE__ */ P(L, { open: t ? !1 : f, onOpenChange: t ? void 0 : d, children: [
50
+ h && /* @__PURE__ */ o(O, { asChild: !0, disabled: t, "data-slot": "pdf-preview-trigger", children: h }),
51
+ /* @__PURE__ */ P(
52
+ U,
53
+ {
54
+ "data-slot": "pdf-preview-content",
55
+ className: j(z({ size: D }), N),
56
+ "aria-describedby": void 0,
57
+ children: [
58
+ c && /* @__PURE__ */ o(
59
+ F,
60
+ {
61
+ title: i,
62
+ showDownload: T,
63
+ onDownload: V,
64
+ downloadDisabled: !e
65
+ }
66
+ ),
67
+ !c && /* @__PURE__ */ o(W, { className: "sr-only", children: i }),
68
+ _()
69
+ ]
70
+ }
71
+ )
72
+ ] });
73
+ };
74
+ B.displayName = "PdfPreview";
75
+ export {
76
+ B as PdfPreview
77
+ };
@@ -0,0 +1,81 @@
1
+ import { ReactNode } from 'react';
2
+ import { PdfPreviewSize } from './pdf-preview.const';
3
+ /**
4
+ * Represents an error that occurred while loading or processing a PDF.
5
+ * Used by error callbacks and the error state UI.
6
+ */
7
+ export interface PdfPreviewError {
8
+ message: string;
9
+ cause?: unknown;
10
+ }
11
+ /**
12
+ * State machine for the PDF loading lifecycle:
13
+ * idle → loading → ready | error
14
+ * Resets back to 'idle' when the dialog closes.
15
+ */
16
+ export type PdfPreviewStatus = 'idle' | 'loading' | 'ready' | 'error';
17
+ /**
18
+ * Props for the PdfPreview component.
19
+ *
20
+ * Supports both controlled (open/onOpenChange) and uncontrolled usage.
21
+ * The `src` prop accepts multiple source types to handle different use cases:
22
+ * - Static URL string (e.g. "/files/report.pdf")
23
+ * - Blob or File object (e.g. from a file input)
24
+ * - Async function that returns any of the above (e.g. server-side fetch)
25
+ */
26
+ export interface PdfPreviewProps {
27
+ /** PDF source — URL string, Blob, File, or async function returning any of those.
28
+ * Async functions receive an AbortSignal so the fetch can be cancelled when the dialog closes. */
29
+ src: string | Blob | File | ((signal: AbortSignal) => Promise<string | Blob | File>);
30
+ /** Dialog title. Auto-detected from filename if not provided */
31
+ title?: string;
32
+ /** Dialog size variant */
33
+ size?: PdfPreviewSize;
34
+ /** Controlled open state */
35
+ open?: boolean;
36
+ /** Callback when open state changes */
37
+ onOpenChange?: (open: boolean) => void;
38
+ /** Disable the trigger */
39
+ disabled?: boolean;
40
+ /** Show the toolbar (default: true) */
41
+ showToolbar?: boolean;
42
+ /** Show the download button in the toolbar (default: true) */
43
+ showDownload?: boolean;
44
+ /** Filename used when downloading */
45
+ downloadFilename?: string;
46
+ /** Custom download handler */
47
+ onDownload?: () => void;
48
+ /** Custom loading content */
49
+ loadingContent?: ReactNode;
50
+ /** Custom error content or render function */
51
+ errorContent?: ReactNode | ((error: PdfPreviewError) => ReactNode);
52
+ /** Escape hatch: render your own PDF viewer given the resolved URL */
53
+ renderPdf?: (resolvedUrl: string) => ReactNode;
54
+ /** Additional class name for the dialog content */
55
+ className?: string;
56
+ /** Additional class name for the PDF viewer area */
57
+ viewerClassName?: string;
58
+ /** Called when an error occurs */
59
+ onError?: (error: PdfPreviewError) => void;
60
+ /** Called when the PDF loads successfully */
61
+ onLoad?: () => void;
62
+ /** Click trigger element (rendered via Radix asChild) */
63
+ children?: ReactNode;
64
+ }
65
+ /** Props passed to the usePdfPreview hook for managing dialog state and PDF source resolution. */
66
+ export interface UsePdfPreviewProps {
67
+ src: PdfPreviewProps['src'];
68
+ open?: boolean;
69
+ onOpenChange?: (open: boolean) => void;
70
+ onError?: (error: PdfPreviewError) => void;
71
+ onLoad?: () => void;
72
+ }
73
+ /** Return value of usePdfPreview — provides state and handlers to the main component. */
74
+ export interface UsePdfPreviewReturn {
75
+ open: boolean;
76
+ handleOpenChange: (open: boolean) => void;
77
+ status: PdfPreviewStatus;
78
+ resolvedUrl: string | null;
79
+ error: PdfPreviewError | null;
80
+ retry: () => void;
81
+ }