@particle-academy/react-fancy 5.19.0 → 5.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{AudioViewer.types-VWhRx6XG.d.cts → AudioViewer.types-CyhmQVQd.d.cts} +13 -0
- package/dist/{AudioViewer.types-VWhRx6XG.d.ts → AudioViewer.types-CyhmQVQd.d.ts} +13 -0
- package/dist/{VideoViewer.types-CTwS6PcM.d.cts → VideoViewer.types-_AwQ8DQr.d.cts} +13 -0
- package/dist/{VideoViewer.types-CTwS6PcM.d.ts → VideoViewer.types-_AwQ8DQr.d.ts} +13 -0
- package/dist/audio-viewer.cjs +2 -2
- package/dist/audio-viewer.d.cts +1 -1
- package/dist/audio-viewer.d.ts +1 -1
- package/dist/audio-viewer.js +1 -1
- package/dist/{chunk-3GRC5J2L.cjs → chunk-3MHVFEIP.cjs} +4 -2
- package/dist/chunk-3MHVFEIP.cjs.map +1 -0
- package/dist/{chunk-EIBW5YLS.js → chunk-74ZN5CNE.js} +4 -2
- package/dist/chunk-74ZN5CNE.js.map +1 -0
- package/dist/{chunk-KE7KXY5C.cjs → chunk-BWTFK2GV.cjs} +6 -6
- package/dist/{chunk-KE7KXY5C.cjs.map → chunk-BWTFK2GV.cjs.map} +1 -1
- package/dist/chunk-FWCREAIT.js +121 -0
- package/dist/chunk-FWCREAIT.js.map +1 -0
- package/dist/chunk-HPNIEYSJ.cjs +131 -0
- package/dist/chunk-HPNIEYSJ.cjs.map +1 -0
- package/dist/{chunk-3ETOEEVN.cjs → chunk-I462NM2A.cjs} +4 -2
- package/dist/chunk-I462NM2A.cjs.map +1 -0
- package/dist/{chunk-J3XS4HHX.js → chunk-QWSTG5MF.js} +4 -4
- package/dist/{chunk-J3XS4HHX.js.map → chunk-QWSTG5MF.js.map} +1 -1
- package/dist/{chunk-JKO2Y5SH.js → chunk-YVDAXYHP.js} +4 -2
- package/dist/chunk-YVDAXYHP.js.map +1 -0
- package/dist/editor.cjs +1 -1
- package/dist/editor.js +1 -1
- package/dist/{index-B71wa9AW.d.cts → index-CgPpIw_O.d.cts} +2 -2
- package/dist/{index-bIntFOl5.d.ts → index-IeivGsNg.d.ts} +2 -2
- package/dist/index.cjs +38 -10
- package/dist/index.d.cts +75 -4
- package/dist/index.d.ts +75 -4
- package/dist/index.js +4 -4
- package/dist/media-viewer.cjs +4 -4
- package/dist/media-viewer.d.cts +3 -3
- package/dist/media-viewer.d.ts +3 -3
- package/dist/media-viewer.js +3 -3
- package/dist/mobile-menu.cjs +1 -1
- package/dist/mobile-menu.js +1 -1
- package/dist/sidebar.cjs +1 -1
- package/dist/sidebar.js +1 -1
- package/dist/video-viewer.cjs +2 -2
- package/dist/video-viewer.d.cts +1 -1
- package/dist/video-viewer.d.ts +1 -1
- package/dist/video-viewer.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-3ETOEEVN.cjs.map +0 -1
- package/dist/chunk-3GRC5J2L.cjs.map +0 -1
- package/dist/chunk-EIBW5YLS.js.map +0 -1
- package/dist/chunk-G34OBTU3.cjs +0 -27
- package/dist/chunk-G34OBTU3.cjs.map +0 -1
- package/dist/chunk-JKO2Y5SH.js.map +0 -1
- package/dist/chunk-RNPFSVFN.js +0 -24
- package/dist/chunk-RNPFSVFN.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/VideoViewer/VideoViewer.tsx"],"names":["forwardRef","useState","jsx","cn","jsxs"],"mappings":";;;;;;AAYO,IAAM,WAAA,GAAcA,gBAAA;AAAA,EACzB,CACE;AAAA,IACE,GAAA;AAAA,IACA,MAAA;AAAA,IACA,QAAA,GAAW,IAAA;AAAA,IACX,QAAA,GAAW,KAAA;AAAA,IACX,IAAA,GAAO,KAAA;AAAA,IACP,OAAA,GAAU,UAAA;AAAA,IACV,KAAA,GAAQ,KAAA;AAAA,IACR,GAAA,GAAM,SAAA;AAAA,IACN,OAAA;AAAA,IACA,SAAA;AAAA,IACA;AAAA,KAEF,GAAA,KACG;AACH,IAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAIC,eAAS,KAAK,CAAA;AAE5C,IAAA,uBACEC,cAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,+BAAA,EAA8B,EAAA;AAAA,QAC9B,SAAA,EAAWC,oBAAA;AAAA,UACT,+EAAA;AAAA,UACA;AAAA,SACF;AAAA,QACA,KAAA;AAAA,QAEC,QAAA,EAAA,OAAA,mBACCC,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,uFAAA,EACb,QAAA,EAAA;AAAA,0BAAAF,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,aAAA,EAAc,QAAA,EAAA,qBAAA,EAAwB,CAAA;AAAA,0BACtDA,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,wCAAA,EAA0C,QAAA,EAAA,GAAA,EAAI;AAAA,SAAA,EAChE,CAAA,mBAEAA,cAAA;AAAA,UAAC,OAAA;AAAA,UAAA;AAAA,YACC,GAAA;AAAA,YACA,OAAA;AAAA,YACA,MAAA;AAAA,YACA,QAAA;AAAA,YACA,QAAA;AAAA,YACA,IAAA;AAAA,YACA,KAAA;AAAA,YACA,WAAA,EAAW,IAAA;AAAA,YACX,SAAS,MAAM;AACb,cAAA,UAAA,CAAW,IAAI,CAAA;AACf,cAAA,OAAA,IAAU;AAAA,YACZ,CAAA;AAAA,YACA,SAAA,EAAWC,oBAAA;AAAA,cACT,uBAAA;AAAA,cACA,GAAA,KAAQ,UAAU,4BAAA,GAA+B;AAAA;AACnD;AAAA;AACF;AAAA,KAEJ;AAAA,EAEJ;AACF;AAEA,WAAA,CAAY,WAAA,GAAc,aAAA","file":"chunk-I462NM2A.cjs","sourcesContent":["import { forwardRef, useState } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport type { VideoViewerProps } from \"./VideoViewer.types\";\n\n/**\n * A standalone video viewer — native controls, optional poster, fit-to-box, and\n * dark-aware framing. Renders for video sources inside `<MediaViewer>`.\n *\n * ```tsx\n * <VideoViewer src=\"/clip.mp4\" poster=\"/clip.jpg\" style={{ height: 360 }} />\n * ```\n */\nexport const VideoViewer = forwardRef<HTMLDivElement, VideoViewerProps>(\n (\n {\n src,\n poster,\n controls = true,\n autoPlay = false,\n loop = false,\n preload = \"metadata\",\n muted = false,\n fit = \"contain\",\n onError,\n className,\n style,\n },\n ref,\n ) => {\n const [errored, setErrored] = useState(false);\n\n return (\n <div\n ref={ref}\n data-react-fancy-video-viewer=\"\"\n className={cn(\n \"relative flex items-center justify-center overflow-hidden rounded-md bg-black\",\n className,\n )}\n style={style}\n >\n {errored ? (\n <div className=\"flex flex-col items-center justify-center gap-1 p-4 text-center text-sm text-zinc-400\">\n <span className=\"font-medium\">Couldn't load video</span>\n <span className=\"max-w-full truncate text-xs opacity-70\">{src}</span>\n </div>\n ) : (\n <video\n src={src}\n preload={preload}\n poster={poster}\n controls={controls}\n autoPlay={autoPlay}\n loop={loop}\n muted={muted}\n playsInline\n onError={() => {\n setErrored(true);\n onError?.();\n }}\n className={cn(\n \"max-h-full max-w-full\",\n fit === \"cover\" ? \"h-full w-full object-cover\" : \"object-contain\",\n )}\n />\n )}\n </div>\n );\n },\n);\n\nVideoViewer.displayName = \"VideoViewer\";\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { VideoViewer } from './chunk-
|
|
1
|
+
import { VideoViewer } from './chunk-YVDAXYHP.js';
|
|
2
2
|
import { PdfViewer } from './chunk-DZD2RJVD.js';
|
|
3
3
|
import { ImageViewer } from './chunk-A3CNYKT3.js';
|
|
4
|
-
import { AudioViewer } from './chunk-
|
|
4
|
+
import { AudioViewer } from './chunk-74ZN5CNE.js';
|
|
5
5
|
import { cn } from './chunk-DSUHZO6T.js';
|
|
6
6
|
import { forwardRef } from 'react';
|
|
7
7
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
@@ -226,5 +226,5 @@ var MediaViewer = forwardRef(
|
|
|
226
226
|
MediaViewer.displayName = "MediaViewer";
|
|
227
227
|
|
|
228
228
|
export { MediaViewer, resolveMediaType };
|
|
229
|
-
//# sourceMappingURL=chunk-
|
|
230
|
-
//# sourceMappingURL=chunk-
|
|
229
|
+
//# sourceMappingURL=chunk-QWSTG5MF.js.map
|
|
230
|
+
//# sourceMappingURL=chunk-QWSTG5MF.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/media-type.ts","../src/components/MediaViewer/MediaFallback.tsx","../src/components/MediaViewer/MediaViewer.tsx"],"names":["jsx"],"mappings":"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","file":"chunk-J3XS4HHX.js","sourcesContent":["/**\n * Resolve what kind of media a source is, from its MIME type (preferred) or its\n * URL — a file extension, or the type embedded in a `data:` URI.\n *\n * Shared by `<MediaViewer>` to pick the right per-type viewer, and exported so\n * downstream packages (e.g. fancy-code's file viewer) can make the same\n * text-vs-media decision without re-deriving the table.\n */\n\nexport type MediaKind = \"image\" | \"video\" | \"audio\" | \"pdf\" | \"unknown\";\n\nexport interface ResolveMediaTypeInput {\n /** MIME type — preferred when known (e.g. `\"image/png\"`, `\"video/mp4\"`). */\n mime?: string | null;\n /**\n * Source URL — used to sniff the kind from a file extension, or from the type\n * embedded in a `data:` URI, when no `mime` is given. `http(s):` / `data:` /\n * `blob:` are all accepted (a bare `blob:` URL carries no type, so pass\n * `mime` alongside it).\n */\n src?: string | null;\n}\n\nconst IMAGE_EXTS = new Set([\n \"png\", \"jpg\", \"jpeg\", \"jfif\", \"pjpeg\", \"gif\", \"webp\", \"avif\", \"bmp\", \"ico\",\n \"cur\", \"svg\", \"svgz\", \"apng\", \"tif\", \"tiff\", \"heic\", \"heif\",\n]);\nconst VIDEO_EXTS = new Set([\n \"mp4\", \"m4v\", \"webm\", \"ogv\", \"ogm\", \"mov\", \"mkv\", \"avi\", \"wmv\", \"flv\", \"3gp\",\n \"3g2\", \"mpg\", \"mpeg\",\n]);\nconst AUDIO_EXTS = new Set([\n \"mp3\", \"wav\", \"wave\", \"ogg\", \"oga\", \"m4a\", \"m4b\", \"aac\", \"flac\", \"opus\",\n \"weba\", \"mid\", \"midi\", \"aiff\", \"aif\",\n]);\n\n/** Map a (possibly parameterized) MIME type to a media kind. */\nfunction mimeToKind(mime: string): MediaKind {\n // Strip any parameters (`; charset=…`) and normalize.\n const m = mime.toLowerCase().split(\";\")[0].trim();\n if (!m) return \"unknown\";\n if (m === \"application/pdf\" || m === \"application/x-pdf\") return \"pdf\";\n if (m.startsWith(\"image/\")) return \"image\";\n if (m.startsWith(\"video/\")) return \"video\";\n if (m.startsWith(\"audio/\")) return \"audio\";\n // `application/ogg` is audio in practice; treat it as such.\n if (m === \"application/ogg\") return \"audio\";\n return \"unknown\";\n}\n\n/** Map a bare file extension (no leading dot) to a media kind. */\nfunction extToKind(ext: string): MediaKind {\n const e = ext.toLowerCase();\n if (e === \"pdf\") return \"pdf\";\n if (IMAGE_EXTS.has(e)) return \"image\";\n if (VIDEO_EXTS.has(e)) return \"video\";\n if (AUDIO_EXTS.has(e)) return \"audio\";\n return \"unknown\";\n}\n\n/** Pull the file extension out of a URL, ignoring its query/hash. */\nfunction extFromSrc(src: string): string | null {\n const clean = src.split(/[?#]/, 1)[0];\n const lastSeg = clean.split(\"/\").pop() ?? \"\";\n const dot = lastSeg.lastIndexOf(\".\");\n if (dot <= 0 || dot === lastSeg.length - 1) return null;\n return lastSeg.slice(dot + 1);\n}\n\n/** Extract the MIME type embedded in a `data:` URI, if present. */\nfunction mimeFromDataUri(src: string): string | null {\n if (!/^data:/i.test(src)) return null;\n const header = src.slice(5).split(\",\", 1)[0]; // text after `data:`, before the comma\n const mt = header.split(\";\")[0].trim();\n return mt || null;\n}\n\n/**\n * Resolve a {@link MediaKind} from a MIME type and/or source URL. MIME wins\n * when it's conclusive; otherwise the `src` is sniffed (a `data:` URI's\n * embedded type first, then the file extension). Returns `\"unknown\"` when\n * nothing matches — callers treat that as \"not previewable media\" (e.g. text).\n */\nexport function resolveMediaType({ mime, src }: ResolveMediaTypeInput): MediaKind {\n if (mime) {\n const k = mimeToKind(mime);\n if (k !== \"unknown\") return k;\n }\n if (src) {\n const dataMime = mimeFromDataUri(src);\n if (dataMime) {\n const k = mimeToKind(dataMime);\n if (k !== \"unknown\") return k;\n }\n const ext = extFromSrc(src);\n if (ext) return extToKind(ext);\n }\n return \"unknown\";\n}\n","import { cn } from \"../../utils/cn\";\n\ninterface MediaFallbackProps {\n src: string;\n mime?: string;\n label?: string;\n className?: string;\n}\n\n/** Filename guess from a URL, ignoring query/hash and `data:`/`blob:` URLs. */\nfunction basename(src: string): string | null {\n if (/^(data|blob):/i.test(src)) return null;\n const seg = src.split(/[?#]/, 1)[0].split(\"/\").pop();\n return seg ? decodeURIComponent(seg) : null;\n}\n\n/**\n * Shown by `<MediaViewer>` when a source isn't a previewable media type — a\n * small themed card naming the file and offering a download.\n */\nexport function MediaFallback({ src, mime, label, className }: MediaFallbackProps) {\n const name = label || basename(src);\n return (\n <div\n data-react-fancy-media-fallback=\"\"\n className={cn(\n \"flex flex-col items-center justify-center gap-2 rounded-lg border border-zinc-200 bg-white p-6 text-center dark:border-zinc-700 dark:bg-zinc-900\",\n className,\n )}\n >\n <span className=\"text-sm font-medium text-zinc-700 dark:text-zinc-200\">\n No preview available\n </span>\n {(name || mime) && (\n <span className=\"max-w-full truncate text-xs text-zinc-500 dark:text-zinc-400\">\n {name}\n {name && mime ? \" · \" : \"\"}\n {mime}\n </span>\n )}\n <a\n href={src}\n download={name ?? undefined}\n className=\"text-xs font-medium text-blue-600 hover:underline dark:text-blue-400\"\n >\n Download\n </a>\n </div>\n );\n}\n","import { forwardRef } from \"react\";\nimport { resolveMediaType } from \"../../utils/media-type\";\nimport { ImageViewer } from \"../ImageViewer\";\nimport { VideoViewer } from \"../VideoViewer\";\nimport { AudioViewer } from \"../AudioViewer\";\nimport { PdfViewer } from \"../PdfViewer\";\nimport { MediaFallback } from \"./MediaFallback\";\nimport type { MediaViewerProps } from \"./MediaViewer.types\";\n\n/**\n * Renders the right viewer for a media file, picked from its `mime` (preferred)\n * or `src` — image, video, audio, or PDF — and a download fallback for anything\n * else. SVG renders through `<ImageViewer>`. The single entry point for showing\n * a file from a tree/workspace when you don't know its type ahead of time.\n *\n * ```tsx\n * <MediaViewer src={url} mime=\"image/png\" alt=\"logo.png\" style={{ height: 320 }} />\n * ```\n */\nexport const MediaViewer = forwardRef<HTMLDivElement, MediaViewerProps>(\n (\n {\n src,\n mime,\n alt,\n kind,\n imageProps,\n videoProps,\n audioProps,\n pdfProps,\n fallback,\n onError,\n className,\n style,\n },\n ref,\n ) => {\n const resolved = kind ?? resolveMediaType({ mime, src });\n\n switch (resolved) {\n case \"image\":\n return (\n <ImageViewer\n ref={ref}\n src={src}\n alt={alt ?? \"\"}\n onError={onError}\n className={className}\n style={style}\n {...imageProps}\n />\n );\n case \"video\":\n return (\n <VideoViewer\n ref={ref}\n src={src}\n onError={onError}\n className={className}\n style={style}\n {...videoProps}\n />\n );\n case \"audio\":\n return (\n <AudioViewer\n ref={ref}\n src={src}\n title={alt}\n onError={onError}\n className={className}\n style={style}\n {...audioProps}\n />\n );\n case \"pdf\":\n return (\n <PdfViewer\n ref={ref}\n src={src}\n title={alt}\n className={className}\n style={style}\n {...pdfProps}\n />\n );\n default:\n return (\n <div\n ref={ref}\n data-react-fancy-media-viewer=\"\"\n className={className}\n style={style}\n >\n {fallback ?? <MediaFallback src={src} mime={mime} label={alt} />}\n </div>\n );\n }\n },\n);\n\nMediaViewer.displayName = \"MediaViewer\";\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils/media-type.ts","../src/components/MediaViewer/MediaFallback.tsx","../src/components/MediaViewer/MediaViewer.tsx"],"names":["jsx"],"mappings":"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","file":"chunk-QWSTG5MF.js","sourcesContent":["/**\n * Resolve what kind of media a source is, from its MIME type (preferred) or its\n * URL — a file extension, or the type embedded in a `data:` URI.\n *\n * Shared by `<MediaViewer>` to pick the right per-type viewer, and exported so\n * downstream packages (e.g. fancy-code's file viewer) can make the same\n * text-vs-media decision without re-deriving the table.\n */\n\nexport type MediaKind = \"image\" | \"video\" | \"audio\" | \"pdf\" | \"unknown\";\n\nexport interface ResolveMediaTypeInput {\n /** MIME type — preferred when known (e.g. `\"image/png\"`, `\"video/mp4\"`). */\n mime?: string | null;\n /**\n * Source URL — used to sniff the kind from a file extension, or from the type\n * embedded in a `data:` URI, when no `mime` is given. `http(s):` / `data:` /\n * `blob:` are all accepted (a bare `blob:` URL carries no type, so pass\n * `mime` alongside it).\n */\n src?: string | null;\n}\n\nconst IMAGE_EXTS = new Set([\n \"png\", \"jpg\", \"jpeg\", \"jfif\", \"pjpeg\", \"gif\", \"webp\", \"avif\", \"bmp\", \"ico\",\n \"cur\", \"svg\", \"svgz\", \"apng\", \"tif\", \"tiff\", \"heic\", \"heif\",\n]);\nconst VIDEO_EXTS = new Set([\n \"mp4\", \"m4v\", \"webm\", \"ogv\", \"ogm\", \"mov\", \"mkv\", \"avi\", \"wmv\", \"flv\", \"3gp\",\n \"3g2\", \"mpg\", \"mpeg\",\n]);\nconst AUDIO_EXTS = new Set([\n \"mp3\", \"wav\", \"wave\", \"ogg\", \"oga\", \"m4a\", \"m4b\", \"aac\", \"flac\", \"opus\",\n \"weba\", \"mid\", \"midi\", \"aiff\", \"aif\",\n]);\n\n/** Map a (possibly parameterized) MIME type to a media kind. */\nfunction mimeToKind(mime: string): MediaKind {\n // Strip any parameters (`; charset=…`) and normalize.\n const m = mime.toLowerCase().split(\";\")[0].trim();\n if (!m) return \"unknown\";\n if (m === \"application/pdf\" || m === \"application/x-pdf\") return \"pdf\";\n if (m.startsWith(\"image/\")) return \"image\";\n if (m.startsWith(\"video/\")) return \"video\";\n if (m.startsWith(\"audio/\")) return \"audio\";\n // `application/ogg` is audio in practice; treat it as such.\n if (m === \"application/ogg\") return \"audio\";\n return \"unknown\";\n}\n\n/** Map a bare file extension (no leading dot) to a media kind. */\nfunction extToKind(ext: string): MediaKind {\n const e = ext.toLowerCase();\n if (e === \"pdf\") return \"pdf\";\n if (IMAGE_EXTS.has(e)) return \"image\";\n if (VIDEO_EXTS.has(e)) return \"video\";\n if (AUDIO_EXTS.has(e)) return \"audio\";\n return \"unknown\";\n}\n\n/** Pull the file extension out of a URL, ignoring its query/hash. */\nfunction extFromSrc(src: string): string | null {\n const clean = src.split(/[?#]/, 1)[0];\n const lastSeg = clean.split(\"/\").pop() ?? \"\";\n const dot = lastSeg.lastIndexOf(\".\");\n if (dot <= 0 || dot === lastSeg.length - 1) return null;\n return lastSeg.slice(dot + 1);\n}\n\n/** Extract the MIME type embedded in a `data:` URI, if present. */\nfunction mimeFromDataUri(src: string): string | null {\n if (!/^data:/i.test(src)) return null;\n const header = src.slice(5).split(\",\", 1)[0]; // text after `data:`, before the comma\n const mt = header.split(\";\")[0].trim();\n return mt || null;\n}\n\n/**\n * Resolve a {@link MediaKind} from a MIME type and/or source URL. MIME wins\n * when it's conclusive; otherwise the `src` is sniffed (a `data:` URI's\n * embedded type first, then the file extension). Returns `\"unknown\"` when\n * nothing matches — callers treat that as \"not previewable media\" (e.g. text).\n */\nexport function resolveMediaType({ mime, src }: ResolveMediaTypeInput): MediaKind {\n if (mime) {\n const k = mimeToKind(mime);\n if (k !== \"unknown\") return k;\n }\n if (src) {\n const dataMime = mimeFromDataUri(src);\n if (dataMime) {\n const k = mimeToKind(dataMime);\n if (k !== \"unknown\") return k;\n }\n const ext = extFromSrc(src);\n if (ext) return extToKind(ext);\n }\n return \"unknown\";\n}\n","import { cn } from \"../../utils/cn\";\n\ninterface MediaFallbackProps {\n src: string;\n mime?: string;\n label?: string;\n className?: string;\n}\n\n/** Filename guess from a URL, ignoring query/hash and `data:`/`blob:` URLs. */\nfunction basename(src: string): string | null {\n if (/^(data|blob):/i.test(src)) return null;\n const seg = src.split(/[?#]/, 1)[0].split(\"/\").pop();\n return seg ? decodeURIComponent(seg) : null;\n}\n\n/**\n * Shown by `<MediaViewer>` when a source isn't a previewable media type — a\n * small themed card naming the file and offering a download.\n */\nexport function MediaFallback({ src, mime, label, className }: MediaFallbackProps) {\n const name = label || basename(src);\n return (\n <div\n data-react-fancy-media-fallback=\"\"\n className={cn(\n \"flex flex-col items-center justify-center gap-2 rounded-lg border border-zinc-200 bg-white p-6 text-center dark:border-zinc-700 dark:bg-zinc-900\",\n className,\n )}\n >\n <span className=\"text-sm font-medium text-zinc-700 dark:text-zinc-200\">\n No preview available\n </span>\n {(name || mime) && (\n <span className=\"max-w-full truncate text-xs text-zinc-500 dark:text-zinc-400\">\n {name}\n {name && mime ? \" · \" : \"\"}\n {mime}\n </span>\n )}\n <a\n href={src}\n download={name ?? undefined}\n className=\"text-xs font-medium text-blue-600 hover:underline dark:text-blue-400\"\n >\n Download\n </a>\n </div>\n );\n}\n","import { forwardRef } from \"react\";\nimport { resolveMediaType } from \"../../utils/media-type\";\nimport { ImageViewer } from \"../ImageViewer\";\nimport { VideoViewer } from \"../VideoViewer\";\nimport { AudioViewer } from \"../AudioViewer\";\nimport { PdfViewer } from \"../PdfViewer\";\nimport { MediaFallback } from \"./MediaFallback\";\nimport type { MediaViewerProps } from \"./MediaViewer.types\";\n\n/**\n * Renders the right viewer for a media file, picked from its `mime` (preferred)\n * or `src` — image, video, audio, or PDF — and a download fallback for anything\n * else. SVG renders through `<ImageViewer>`. The single entry point for showing\n * a file from a tree/workspace when you don't know its type ahead of time.\n *\n * ```tsx\n * <MediaViewer src={url} mime=\"image/png\" alt=\"logo.png\" style={{ height: 320 }} />\n * ```\n */\nexport const MediaViewer = forwardRef<HTMLDivElement, MediaViewerProps>(\n (\n {\n src,\n mime,\n alt,\n kind,\n imageProps,\n videoProps,\n audioProps,\n pdfProps,\n fallback,\n onError,\n className,\n style,\n },\n ref,\n ) => {\n const resolved = kind ?? resolveMediaType({ mime, src });\n\n switch (resolved) {\n case \"image\":\n return (\n <ImageViewer\n ref={ref}\n src={src}\n alt={alt ?? \"\"}\n onError={onError}\n className={className}\n style={style}\n {...imageProps}\n />\n );\n case \"video\":\n return (\n <VideoViewer\n ref={ref}\n src={src}\n onError={onError}\n className={className}\n style={style}\n {...videoProps}\n />\n );\n case \"audio\":\n return (\n <AudioViewer\n ref={ref}\n src={src}\n title={alt}\n onError={onError}\n className={className}\n style={style}\n {...audioProps}\n />\n );\n case \"pdf\":\n return (\n <PdfViewer\n ref={ref}\n src={src}\n title={alt}\n className={className}\n style={style}\n {...pdfProps}\n />\n );\n default:\n return (\n <div\n ref={ref}\n data-react-fancy-media-viewer=\"\"\n className={className}\n style={style}\n >\n {fallback ?? <MediaFallback src={src} mime={mime} label={alt} />}\n </div>\n );\n }\n },\n);\n\nMediaViewer.displayName = \"MediaViewer\";\n"]}
|
|
@@ -9,6 +9,7 @@ var VideoViewer = forwardRef(
|
|
|
9
9
|
controls = true,
|
|
10
10
|
autoPlay = false,
|
|
11
11
|
loop = false,
|
|
12
|
+
preload = "metadata",
|
|
12
13
|
muted = false,
|
|
13
14
|
fit = "contain",
|
|
14
15
|
onError,
|
|
@@ -33,6 +34,7 @@ var VideoViewer = forwardRef(
|
|
|
33
34
|
"video",
|
|
34
35
|
{
|
|
35
36
|
src,
|
|
37
|
+
preload,
|
|
36
38
|
poster,
|
|
37
39
|
controls,
|
|
38
40
|
autoPlay,
|
|
@@ -56,5 +58,5 @@ var VideoViewer = forwardRef(
|
|
|
56
58
|
VideoViewer.displayName = "VideoViewer";
|
|
57
59
|
|
|
58
60
|
export { VideoViewer };
|
|
59
|
-
//# sourceMappingURL=chunk-
|
|
60
|
-
//# sourceMappingURL=chunk-
|
|
61
|
+
//# sourceMappingURL=chunk-YVDAXYHP.js.map
|
|
62
|
+
//# sourceMappingURL=chunk-YVDAXYHP.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/VideoViewer/VideoViewer.tsx"],"names":[],"mappings":";;;;AAYO,IAAM,WAAA,GAAc,UAAA;AAAA,EACzB,CACE;AAAA,IACE,GAAA;AAAA,IACA,MAAA;AAAA,IACA,QAAA,GAAW,IAAA;AAAA,IACX,QAAA,GAAW,KAAA;AAAA,IACX,IAAA,GAAO,KAAA;AAAA,IACP,OAAA,GAAU,UAAA;AAAA,IACV,KAAA,GAAQ,KAAA;AAAA,IACR,GAAA,GAAM,SAAA;AAAA,IACN,OAAA;AAAA,IACA,SAAA;AAAA,IACA;AAAA,KAEF,GAAA,KACG;AACH,IAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAS,KAAK,CAAA;AAE5C,IAAA,uBACE,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,+BAAA,EAA8B,EAAA;AAAA,QAC9B,SAAA,EAAW,EAAA;AAAA,UACT,+EAAA;AAAA,UACA;AAAA,SACF;AAAA,QACA,KAAA;AAAA,QAEC,QAAA,EAAA,OAAA,mBACC,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,uFAAA,EACb,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,aAAA,EAAc,QAAA,EAAA,qBAAA,EAAwB,CAAA;AAAA,0BACtD,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,wCAAA,EAA0C,QAAA,EAAA,GAAA,EAAI;AAAA,SAAA,EAChE,CAAA,mBAEA,GAAA;AAAA,UAAC,OAAA;AAAA,UAAA;AAAA,YACC,GAAA;AAAA,YACA,OAAA;AAAA,YACA,MAAA;AAAA,YACA,QAAA;AAAA,YACA,QAAA;AAAA,YACA,IAAA;AAAA,YACA,KAAA;AAAA,YACA,WAAA,EAAW,IAAA;AAAA,YACX,SAAS,MAAM;AACb,cAAA,UAAA,CAAW,IAAI,CAAA;AACf,cAAA,OAAA,IAAU;AAAA,YACZ,CAAA;AAAA,YACA,SAAA,EAAW,EAAA;AAAA,cACT,uBAAA;AAAA,cACA,GAAA,KAAQ,UAAU,4BAAA,GAA+B;AAAA;AACnD;AAAA;AACF;AAAA,KAEJ;AAAA,EAEJ;AACF;AAEA,WAAA,CAAY,WAAA,GAAc,aAAA","file":"chunk-YVDAXYHP.js","sourcesContent":["import { forwardRef, useState } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport type { VideoViewerProps } from \"./VideoViewer.types\";\n\n/**\n * A standalone video viewer — native controls, optional poster, fit-to-box, and\n * dark-aware framing. Renders for video sources inside `<MediaViewer>`.\n *\n * ```tsx\n * <VideoViewer src=\"/clip.mp4\" poster=\"/clip.jpg\" style={{ height: 360 }} />\n * ```\n */\nexport const VideoViewer = forwardRef<HTMLDivElement, VideoViewerProps>(\n (\n {\n src,\n poster,\n controls = true,\n autoPlay = false,\n loop = false,\n preload = \"metadata\",\n muted = false,\n fit = \"contain\",\n onError,\n className,\n style,\n },\n ref,\n ) => {\n const [errored, setErrored] = useState(false);\n\n return (\n <div\n ref={ref}\n data-react-fancy-video-viewer=\"\"\n className={cn(\n \"relative flex items-center justify-center overflow-hidden rounded-md bg-black\",\n className,\n )}\n style={style}\n >\n {errored ? (\n <div className=\"flex flex-col items-center justify-center gap-1 p-4 text-center text-sm text-zinc-400\">\n <span className=\"font-medium\">Couldn't load video</span>\n <span className=\"max-w-full truncate text-xs opacity-70\">{src}</span>\n </div>\n ) : (\n <video\n src={src}\n preload={preload}\n poster={poster}\n controls={controls}\n autoPlay={autoPlay}\n loop={loop}\n muted={muted}\n playsInline\n onError={() => {\n setErrored(true);\n onError?.();\n }}\n className={cn(\n \"max-h-full max-w-full\",\n fit === \"cover\" ? \"h-full w-full object-cover\" : \"object-contain\",\n )}\n />\n )}\n </div>\n );\n },\n);\n\nVideoViewer.displayName = \"VideoViewer\";\n"]}
|
package/dist/editor.cjs
CHANGED
package/dist/editor.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode, CSSProperties } from 'react';
|
|
3
3
|
import { I as ImageViewerProps } from './ImageViewer.types-BaqlDeuo.cjs';
|
|
4
|
-
import { V as VideoViewerProps } from './VideoViewer.types-
|
|
5
|
-
import { A as AudioViewerProps } from './AudioViewer.types-
|
|
4
|
+
import { V as VideoViewerProps } from './VideoViewer.types-_AwQ8DQr.cjs';
|
|
5
|
+
import { A as AudioViewerProps } from './AudioViewer.types-CyhmQVQd.cjs';
|
|
6
6
|
import { P as PdfViewerProps } from './PdfViewer.types-_u6vboSl.cjs';
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode, CSSProperties } from 'react';
|
|
3
3
|
import { I as ImageViewerProps } from './ImageViewer.types-BaqlDeuo.js';
|
|
4
|
-
import { V as VideoViewerProps } from './VideoViewer.types-
|
|
5
|
-
import { A as AudioViewerProps } from './AudioViewer.types-
|
|
4
|
+
import { V as VideoViewerProps } from './VideoViewer.types-_AwQ8DQr.js';
|
|
5
|
+
import { A as AudioViewerProps } from './AudioViewer.types-CyhmQVQd.js';
|
|
6
6
|
import { P as PdfViewerProps } from './PdfViewer.types-_u6vboSl.js';
|
|
7
7
|
|
|
8
8
|
/**
|
package/dist/index.cjs
CHANGED
|
@@ -55,8 +55,8 @@ var chunk6BW5BQMN_cjs = require('./chunk-6BW5BQMN.cjs');
|
|
|
55
55
|
var chunkPPLR2DNC_cjs = require('./chunk-PPLR2DNC.cjs');
|
|
56
56
|
require('./chunk-YLGTDBB2.cjs');
|
|
57
57
|
var chunkORPYY2MO_cjs = require('./chunk-ORPYY2MO.cjs');
|
|
58
|
-
var
|
|
59
|
-
var
|
|
58
|
+
var chunkBWTFK2GV_cjs = require('./chunk-BWTFK2GV.cjs');
|
|
59
|
+
var chunkI462NM2A_cjs = require('./chunk-I462NM2A.cjs');
|
|
60
60
|
var chunkJHEM6IGT_cjs = require('./chunk-JHEM6IGT.cjs');
|
|
61
61
|
var chunkEERAEPQO_cjs = require('./chunk-EERAEPQO.cjs');
|
|
62
62
|
var chunkKUKYJZIU_cjs = require('./chunk-KUKYJZIU.cjs');
|
|
@@ -71,7 +71,7 @@ var chunk5HOQ2PHR_cjs = require('./chunk-5HOQ2PHR.cjs');
|
|
|
71
71
|
var chunkF6NEPU67_cjs = require('./chunk-F6NEPU67.cjs');
|
|
72
72
|
var chunkORFHF6PT_cjs = require('./chunk-ORFHF6PT.cjs');
|
|
73
73
|
var chunkWT72KW5M_cjs = require('./chunk-WT72KW5M.cjs');
|
|
74
|
-
var
|
|
74
|
+
var chunkHPNIEYSJ_cjs = require('./chunk-HPNIEYSJ.cjs');
|
|
75
75
|
var chunkT6YELZPJ_cjs = require('./chunk-T6YELZPJ.cjs');
|
|
76
76
|
var chunkMDUSUJWY_cjs = require('./chunk-MDUSUJWY.cjs');
|
|
77
77
|
var chunk6FBFE66M_cjs = require('./chunk-6FBFE66M.cjs');
|
|
@@ -106,7 +106,7 @@ var chunkKC6QBKKB_cjs = require('./chunk-KC6QBKKB.cjs');
|
|
|
106
106
|
var chunk2PELJ4VA_cjs = require('./chunk-2PELJ4VA.cjs');
|
|
107
107
|
var chunkCZZH45GQ_cjs = require('./chunk-CZZH45GQ.cjs');
|
|
108
108
|
var chunkJPTWZ3RF_cjs = require('./chunk-JPTWZ3RF.cjs');
|
|
109
|
-
var
|
|
109
|
+
var chunk3MHVFEIP_cjs = require('./chunk-3MHVFEIP.cjs');
|
|
110
110
|
var chunkIF25CE6S_cjs = require('./chunk-IF25CE6S.cjs');
|
|
111
111
|
var chunkJ2DI6RMR_cjs = require('./chunk-J2DI6RMR.cjs');
|
|
112
112
|
require('./chunk-KJ22KE56.cjs');
|
|
@@ -390,15 +390,15 @@ Object.defineProperty(exports, "Marquee", {
|
|
|
390
390
|
});
|
|
391
391
|
Object.defineProperty(exports, "MediaViewer", {
|
|
392
392
|
enumerable: true,
|
|
393
|
-
get: function () { return
|
|
393
|
+
get: function () { return chunkBWTFK2GV_cjs.MediaViewer; }
|
|
394
394
|
});
|
|
395
395
|
Object.defineProperty(exports, "resolveMediaType", {
|
|
396
396
|
enumerable: true,
|
|
397
|
-
get: function () { return
|
|
397
|
+
get: function () { return chunkBWTFK2GV_cjs.resolveMediaType; }
|
|
398
398
|
});
|
|
399
399
|
Object.defineProperty(exports, "VideoViewer", {
|
|
400
400
|
enumerable: true,
|
|
401
|
-
get: function () { return
|
|
401
|
+
get: function () { return chunkI462NM2A_cjs.VideoViewer; }
|
|
402
402
|
});
|
|
403
403
|
Object.defineProperty(exports, "PdfViewer", {
|
|
404
404
|
enumerable: true,
|
|
@@ -512,13 +512,41 @@ Object.defineProperty(exports, "useEditor", {
|
|
|
512
512
|
enumerable: true,
|
|
513
513
|
get: function () { return chunkWT72KW5M_cjs.useEditor; }
|
|
514
514
|
});
|
|
515
|
+
Object.defineProperty(exports, "THEME_STORAGE_KEY", {
|
|
516
|
+
enumerable: true,
|
|
517
|
+
get: function () { return chunkHPNIEYSJ_cjs.THEME_STORAGE_KEY; }
|
|
518
|
+
});
|
|
519
|
+
Object.defineProperty(exports, "getThemePreference", {
|
|
520
|
+
enumerable: true,
|
|
521
|
+
get: function () { return chunkHPNIEYSJ_cjs.getThemePreference; }
|
|
522
|
+
});
|
|
523
|
+
Object.defineProperty(exports, "initTheme", {
|
|
524
|
+
enumerable: true,
|
|
525
|
+
get: function () { return chunkHPNIEYSJ_cjs.initTheme; }
|
|
526
|
+
});
|
|
527
|
+
Object.defineProperty(exports, "resolveTheme", {
|
|
528
|
+
enumerable: true,
|
|
529
|
+
get: function () { return chunkHPNIEYSJ_cjs.resolveTheme; }
|
|
530
|
+
});
|
|
531
|
+
Object.defineProperty(exports, "setThemePreference", {
|
|
532
|
+
enumerable: true,
|
|
533
|
+
get: function () { return chunkHPNIEYSJ_cjs.setThemePreference; }
|
|
534
|
+
});
|
|
535
|
+
Object.defineProperty(exports, "subscribeTheme", {
|
|
536
|
+
enumerable: true,
|
|
537
|
+
get: function () { return chunkHPNIEYSJ_cjs.subscribeTheme; }
|
|
538
|
+
});
|
|
515
539
|
Object.defineProperty(exports, "useId", {
|
|
516
540
|
enumerable: true,
|
|
517
|
-
get: function () { return
|
|
541
|
+
get: function () { return chunkHPNIEYSJ_cjs.useId; }
|
|
518
542
|
});
|
|
519
543
|
Object.defineProperty(exports, "useNodeRegistry", {
|
|
520
544
|
enumerable: true,
|
|
521
|
-
get: function () { return
|
|
545
|
+
get: function () { return chunkHPNIEYSJ_cjs.useNodeRegistry; }
|
|
546
|
+
});
|
|
547
|
+
Object.defineProperty(exports, "useTheme", {
|
|
548
|
+
enumerable: true,
|
|
549
|
+
get: function () { return chunkHPNIEYSJ_cjs.useTheme; }
|
|
522
550
|
});
|
|
523
551
|
Object.defineProperty(exports, "usePanZoom", {
|
|
524
552
|
enumerable: true,
|
|
@@ -738,7 +766,7 @@ Object.defineProperty(exports, "useAccordionSection", {
|
|
|
738
766
|
});
|
|
739
767
|
Object.defineProperty(exports, "AudioViewer", {
|
|
740
768
|
enumerable: true,
|
|
741
|
-
get: function () { return
|
|
769
|
+
get: function () { return chunk3MHVFEIP_cjs.AudioViewer; }
|
|
742
770
|
});
|
|
743
771
|
Object.defineProperty(exports, "Autocomplete", {
|
|
744
772
|
enumerable: true,
|
package/dist/index.d.cts
CHANGED
|
@@ -77,7 +77,7 @@ export { Kanban, KanbanCardMoveHandler, KanbanCardProps, KanbanColumnHandleProps
|
|
|
77
77
|
export { DropPosition, TreeNav, TreeNavContextValue, TreeNavProps, TreeNodeData, TreeNodeProps, useTreeNav } from './tree-nav.cjs';
|
|
78
78
|
export { FileBrowser, FileBrowserContextValue, FileBrowserNewFolder, FileBrowserNodeProps, FileBrowserPathBarProps, FileBrowserProps, FileBrowserProvider, FileBrowserRow, FileBrowserToolbarProps, FileBrowserTreeProps, FileEntry, FileKind, FileLoadStatus, FileSelectMode, FileSnapshotNode, FileSort, FileSortDirection, FileSortField, useFileBrowser, validateFolderName } from './file-browser.cjs';
|
|
79
79
|
import { ClassValue } from 'clsx';
|
|
80
|
-
export { M as MediaKind, a as MediaViewer, b as MediaViewerProps, R as ResolveMediaTypeInput, r as resolveMediaType } from './index-
|
|
80
|
+
export { M as MediaKind, a as MediaViewer, b as MediaViewerProps, R as ResolveMediaTypeInput, r as resolveMediaType } from './index-CgPpIw_O.cjs';
|
|
81
81
|
import { P as Placement } from './types-8Sv0rCjw.cjs';
|
|
82
82
|
export { A as ActionColor, B as ButtonColor, C as Color, S as Size, V as Variant } from './types-8Sv0rCjw.cjs';
|
|
83
83
|
import { RefObject } from 'react';
|
|
@@ -90,9 +90,9 @@ export { MagicWand, MagicWandAction, MagicWandAppearance, MagicWandProps, MagicW
|
|
|
90
90
|
export { ImageViewer } from './image-viewer.cjs';
|
|
91
91
|
export { I as ImageViewerProps, a as ImageViewerViewport } from './ImageViewer.types-BaqlDeuo.cjs';
|
|
92
92
|
export { VideoViewer } from './video-viewer.cjs';
|
|
93
|
-
export { V as VideoViewerProps } from './VideoViewer.types-
|
|
93
|
+
export { V as VideoViewerProps } from './VideoViewer.types-_AwQ8DQr.cjs';
|
|
94
94
|
export { AudioViewer } from './audio-viewer.cjs';
|
|
95
|
-
export { A as AudioViewerProps } from './AudioViewer.types-
|
|
95
|
+
export { A as AudioViewerProps } from './AudioViewer.types-CyhmQVQd.cjs';
|
|
96
96
|
export { PdfViewer } from './pdf-viewer.cjs';
|
|
97
97
|
export { P as PdfViewerProps } from './PdfViewer.types-_u6vboSl.cjs';
|
|
98
98
|
export { J as JSON_FIELD_TYPES, a as JsonArray, b as JsonEditor, c as JsonEditorActivity, d as JsonEditorEdit, e as JsonEditorIssue, f as JsonEditorNode, g as JsonEditorPendingEdit, h as JsonEditorProps, i as JsonFieldType, j as JsonKeyMapEntry, k as JsonKeyRule, l as JsonObject, m as JsonPath, n as JsonPrimitive, o as JsonValue, P as ParsedKeyMap, p as applyJsonEdit, q as describeEdit, r as findJsonConflicts, s as getAtPath, t as inferType, u as parseKeyMap, v as parsePath, w as pathToString, x as resolveKeyRule, y as typeMatches } from './index-BypPN_6l.cjs';
|
|
@@ -200,4 +200,75 @@ interface UseNodeRegistryReturn {
|
|
|
200
200
|
}
|
|
201
201
|
declare function useNodeRegistry(): UseNodeRegistryReturn;
|
|
202
202
|
|
|
203
|
-
|
|
203
|
+
/**
|
|
204
|
+
* Light / dark / **system** theming.
|
|
205
|
+
*
|
|
206
|
+
* `styles.css` in this package defines the dark contract — it redefines the
|
|
207
|
+
* whole `--color-secondary-*` scale under `:where(.dark)` so that "900" always
|
|
208
|
+
* means strongest foreground and "50" always means faintest surface. This module
|
|
209
|
+
* is the other half of that contract: the thing that decides when `.dark` is on.
|
|
210
|
+
*
|
|
211
|
+
* It lives here rather than in each app because every consumer was hand-rolling
|
|
212
|
+
* it, and every hand-rolled copy had the same two holes:
|
|
213
|
+
*
|
|
214
|
+
* - **No live listener.** The OS preference was read once at boot, so changing
|
|
215
|
+
* the system theme with the page open did nothing. That is a default, not a
|
|
216
|
+
* "system" mode.
|
|
217
|
+
* - **No way back.** Choosing light or dark wrote to storage forever, so
|
|
218
|
+
* "follow my system" was unreachable after a single click.
|
|
219
|
+
*
|
|
220
|
+
* Both are fixed by treating **"system" as the absence of a stored choice**
|
|
221
|
+
* rather than as a third stored value.
|
|
222
|
+
*
|
|
223
|
+
* Every export is safe to call during SSR, where it is a no-op that resolves to
|
|
224
|
+
* `"light"`. Pair it with `useTheme`, which deliberately renders `system/light`
|
|
225
|
+
* on the server and syncs in an effect — this project has paid for hydration
|
|
226
|
+
* mismatches caused by reading the real theme during render.
|
|
227
|
+
*/
|
|
228
|
+
type ThemePreference = "light" | "dark" | "system";
|
|
229
|
+
type ResolvedTheme = "light" | "dark";
|
|
230
|
+
/**
|
|
231
|
+
* Deliberately the key the showcase already used, so adopting this module keeps
|
|
232
|
+
* a returning visitor's saved choice instead of silently resetting it.
|
|
233
|
+
*/
|
|
234
|
+
declare const THEME_STORAGE_KEY = "fancy-ui.theme";
|
|
235
|
+
type ThemeListener = (resolved: ResolvedTheme, preference: ThemePreference) => void;
|
|
236
|
+
/** The stored choice, or `"system"` when there isn't one. */
|
|
237
|
+
declare function getThemePreference(): ThemePreference;
|
|
238
|
+
/** What is actually on screen, as opposed to what the user asked for. */
|
|
239
|
+
declare function resolveTheme(preference?: ThemePreference): ResolvedTheme;
|
|
240
|
+
/**
|
|
241
|
+
* Choose a theme. `"system"` REMOVES the stored value rather than storing the
|
|
242
|
+
* string — an absent choice is what lets the OS keep speaking for the user.
|
|
243
|
+
*/
|
|
244
|
+
declare function setThemePreference(preference: ThemePreference): void;
|
|
245
|
+
/** Observe theme changes. Returns an unsubscribe. */
|
|
246
|
+
declare function subscribeTheme(listener: ThemeListener): () => void;
|
|
247
|
+
/**
|
|
248
|
+
* Apply the current theme and start following the OS. Call once, as early as
|
|
249
|
+
* possible — before first paint if you want to avoid a flash of the wrong
|
|
250
|
+
* theme. Returns a disposer; calling it again is harmless.
|
|
251
|
+
*/
|
|
252
|
+
declare function initTheme(options?: {
|
|
253
|
+
storageKey?: string;
|
|
254
|
+
}): () => void;
|
|
255
|
+
|
|
256
|
+
type UseThemeResult = {
|
|
257
|
+
/** What the user asked for, including `"system"`. */
|
|
258
|
+
preference: ThemePreference;
|
|
259
|
+
/** What is actually on screen. */
|
|
260
|
+
resolved: ResolvedTheme;
|
|
261
|
+
setPreference: (preference: ThemePreference) => void;
|
|
262
|
+
};
|
|
263
|
+
/**
|
|
264
|
+
* Read and set the theme from a component, re-rendering when it changes —
|
|
265
|
+
* including when the OS theme changes underneath a `"system"` preference.
|
|
266
|
+
*
|
|
267
|
+
* The initial state is deliberately `system` / `light` rather than the real
|
|
268
|
+
* theme: the server has neither storage nor an OS preference, so reading the
|
|
269
|
+
* truth during render is exactly the hydration mismatch this project has
|
|
270
|
+
* already chased down more than once. The effect syncs immediately on mount.
|
|
271
|
+
*/
|
|
272
|
+
declare function useTheme(): UseThemeResult;
|
|
273
|
+
|
|
274
|
+
export { type NodeRect, Placement, type ResolvedTheme, THEME_STORAGE_KEY, type ThemePreference, type UseThemeResult, cn, getThemePreference, initTheme, resolveTheme, sanitizeHref, sanitizeHtml, setThemePreference, subscribeTheme, useAnimation, useControllableState, useEscapeKey, useFloatingPosition, useFocusTrap, useId, useNodeRegistry, useOutsideClick, usePanZoom, useTheme };
|
package/dist/index.d.ts
CHANGED
|
@@ -77,7 +77,7 @@ export { Kanban, KanbanCardMoveHandler, KanbanCardProps, KanbanColumnHandleProps
|
|
|
77
77
|
export { DropPosition, TreeNav, TreeNavContextValue, TreeNavProps, TreeNodeData, TreeNodeProps, useTreeNav } from './tree-nav.js';
|
|
78
78
|
export { FileBrowser, FileBrowserContextValue, FileBrowserNewFolder, FileBrowserNodeProps, FileBrowserPathBarProps, FileBrowserProps, FileBrowserProvider, FileBrowserRow, FileBrowserToolbarProps, FileBrowserTreeProps, FileEntry, FileKind, FileLoadStatus, FileSelectMode, FileSnapshotNode, FileSort, FileSortDirection, FileSortField, useFileBrowser, validateFolderName } from './file-browser.js';
|
|
79
79
|
import { ClassValue } from 'clsx';
|
|
80
|
-
export { M as MediaKind, a as MediaViewer, b as MediaViewerProps, R as ResolveMediaTypeInput, r as resolveMediaType } from './index-
|
|
80
|
+
export { M as MediaKind, a as MediaViewer, b as MediaViewerProps, R as ResolveMediaTypeInput, r as resolveMediaType } from './index-IeivGsNg.js';
|
|
81
81
|
import { P as Placement } from './types-8Sv0rCjw.js';
|
|
82
82
|
export { A as ActionColor, B as ButtonColor, C as Color, S as Size, V as Variant } from './types-8Sv0rCjw.js';
|
|
83
83
|
import { RefObject } from 'react';
|
|
@@ -90,9 +90,9 @@ export { MagicWand, MagicWandAction, MagicWandAppearance, MagicWandProps, MagicW
|
|
|
90
90
|
export { ImageViewer } from './image-viewer.js';
|
|
91
91
|
export { I as ImageViewerProps, a as ImageViewerViewport } from './ImageViewer.types-BaqlDeuo.js';
|
|
92
92
|
export { VideoViewer } from './video-viewer.js';
|
|
93
|
-
export { V as VideoViewerProps } from './VideoViewer.types-
|
|
93
|
+
export { V as VideoViewerProps } from './VideoViewer.types-_AwQ8DQr.js';
|
|
94
94
|
export { AudioViewer } from './audio-viewer.js';
|
|
95
|
-
export { A as AudioViewerProps } from './AudioViewer.types-
|
|
95
|
+
export { A as AudioViewerProps } from './AudioViewer.types-CyhmQVQd.js';
|
|
96
96
|
export { PdfViewer } from './pdf-viewer.js';
|
|
97
97
|
export { P as PdfViewerProps } from './PdfViewer.types-_u6vboSl.js';
|
|
98
98
|
export { J as JSON_FIELD_TYPES, a as JsonArray, b as JsonEditor, c as JsonEditorActivity, d as JsonEditorEdit, e as JsonEditorIssue, f as JsonEditorNode, g as JsonEditorPendingEdit, h as JsonEditorProps, i as JsonFieldType, j as JsonKeyMapEntry, k as JsonKeyRule, l as JsonObject, m as JsonPath, n as JsonPrimitive, o as JsonValue, P as ParsedKeyMap, p as applyJsonEdit, q as describeEdit, r as findJsonConflicts, s as getAtPath, t as inferType, u as parseKeyMap, v as parsePath, w as pathToString, x as resolveKeyRule, y as typeMatches } from './index-BfFk-CIv.js';
|
|
@@ -200,4 +200,75 @@ interface UseNodeRegistryReturn {
|
|
|
200
200
|
}
|
|
201
201
|
declare function useNodeRegistry(): UseNodeRegistryReturn;
|
|
202
202
|
|
|
203
|
-
|
|
203
|
+
/**
|
|
204
|
+
* Light / dark / **system** theming.
|
|
205
|
+
*
|
|
206
|
+
* `styles.css` in this package defines the dark contract — it redefines the
|
|
207
|
+
* whole `--color-secondary-*` scale under `:where(.dark)` so that "900" always
|
|
208
|
+
* means strongest foreground and "50" always means faintest surface. This module
|
|
209
|
+
* is the other half of that contract: the thing that decides when `.dark` is on.
|
|
210
|
+
*
|
|
211
|
+
* It lives here rather than in each app because every consumer was hand-rolling
|
|
212
|
+
* it, and every hand-rolled copy had the same two holes:
|
|
213
|
+
*
|
|
214
|
+
* - **No live listener.** The OS preference was read once at boot, so changing
|
|
215
|
+
* the system theme with the page open did nothing. That is a default, not a
|
|
216
|
+
* "system" mode.
|
|
217
|
+
* - **No way back.** Choosing light or dark wrote to storage forever, so
|
|
218
|
+
* "follow my system" was unreachable after a single click.
|
|
219
|
+
*
|
|
220
|
+
* Both are fixed by treating **"system" as the absence of a stored choice**
|
|
221
|
+
* rather than as a third stored value.
|
|
222
|
+
*
|
|
223
|
+
* Every export is safe to call during SSR, where it is a no-op that resolves to
|
|
224
|
+
* `"light"`. Pair it with `useTheme`, which deliberately renders `system/light`
|
|
225
|
+
* on the server and syncs in an effect — this project has paid for hydration
|
|
226
|
+
* mismatches caused by reading the real theme during render.
|
|
227
|
+
*/
|
|
228
|
+
type ThemePreference = "light" | "dark" | "system";
|
|
229
|
+
type ResolvedTheme = "light" | "dark";
|
|
230
|
+
/**
|
|
231
|
+
* Deliberately the key the showcase already used, so adopting this module keeps
|
|
232
|
+
* a returning visitor's saved choice instead of silently resetting it.
|
|
233
|
+
*/
|
|
234
|
+
declare const THEME_STORAGE_KEY = "fancy-ui.theme";
|
|
235
|
+
type ThemeListener = (resolved: ResolvedTheme, preference: ThemePreference) => void;
|
|
236
|
+
/** The stored choice, or `"system"` when there isn't one. */
|
|
237
|
+
declare function getThemePreference(): ThemePreference;
|
|
238
|
+
/** What is actually on screen, as opposed to what the user asked for. */
|
|
239
|
+
declare function resolveTheme(preference?: ThemePreference): ResolvedTheme;
|
|
240
|
+
/**
|
|
241
|
+
* Choose a theme. `"system"` REMOVES the stored value rather than storing the
|
|
242
|
+
* string — an absent choice is what lets the OS keep speaking for the user.
|
|
243
|
+
*/
|
|
244
|
+
declare function setThemePreference(preference: ThemePreference): void;
|
|
245
|
+
/** Observe theme changes. Returns an unsubscribe. */
|
|
246
|
+
declare function subscribeTheme(listener: ThemeListener): () => void;
|
|
247
|
+
/**
|
|
248
|
+
* Apply the current theme and start following the OS. Call once, as early as
|
|
249
|
+
* possible — before first paint if you want to avoid a flash of the wrong
|
|
250
|
+
* theme. Returns a disposer; calling it again is harmless.
|
|
251
|
+
*/
|
|
252
|
+
declare function initTheme(options?: {
|
|
253
|
+
storageKey?: string;
|
|
254
|
+
}): () => void;
|
|
255
|
+
|
|
256
|
+
type UseThemeResult = {
|
|
257
|
+
/** What the user asked for, including `"system"`. */
|
|
258
|
+
preference: ThemePreference;
|
|
259
|
+
/** What is actually on screen. */
|
|
260
|
+
resolved: ResolvedTheme;
|
|
261
|
+
setPreference: (preference: ThemePreference) => void;
|
|
262
|
+
};
|
|
263
|
+
/**
|
|
264
|
+
* Read and set the theme from a component, re-rendering when it changes —
|
|
265
|
+
* including when the OS theme changes underneath a `"system"` preference.
|
|
266
|
+
*
|
|
267
|
+
* The initial state is deliberately `system` / `light` rather than the real
|
|
268
|
+
* theme: the server has neither storage nor an OS preference, so reading the
|
|
269
|
+
* truth during render is exactly the hydration mismatch this project has
|
|
270
|
+
* already chased down more than once. The effect syncs immediately on mount.
|
|
271
|
+
*/
|
|
272
|
+
declare function useTheme(): UseThemeResult;
|
|
273
|
+
|
|
274
|
+
export { type NodeRect, Placement, type ResolvedTheme, THEME_STORAGE_KEY, type ThemePreference, type UseThemeResult, cn, getThemePreference, initTheme, resolveTheme, sanitizeHref, sanitizeHtml, setThemePreference, subscribeTheme, useAnimation, useControllableState, useEscapeKey, useFloatingPosition, useFocusTrap, useId, useNodeRegistry, useOutsideClick, usePanZoom, useTheme };
|
package/dist/index.js
CHANGED
|
@@ -53,8 +53,8 @@ export { DisplayValue } from './chunk-K7JGOQJG.js';
|
|
|
53
53
|
export { Field } from './chunk-3DJGPNUI.js';
|
|
54
54
|
import './chunk-GFYSELJF.js';
|
|
55
55
|
export { Marquee } from './chunk-ATFXU6R6.js';
|
|
56
|
-
export { MediaViewer, resolveMediaType } from './chunk-
|
|
57
|
-
export { VideoViewer } from './chunk-
|
|
56
|
+
export { MediaViewer, resolveMediaType } from './chunk-QWSTG5MF.js';
|
|
57
|
+
export { VideoViewer } from './chunk-YVDAXYHP.js';
|
|
58
58
|
export { PdfViewer } from './chunk-DZD2RJVD.js';
|
|
59
59
|
export { Menu, useMenu } from './chunk-IGYIMS6J.js';
|
|
60
60
|
export { MobileMenu, useMobileMenu } from './chunk-F6SCZCJE.js';
|
|
@@ -69,7 +69,7 @@ export { ContextMenu, useContextMenu } from './chunk-NLJGNPNN.js';
|
|
|
69
69
|
export { Drawer, useDrawer } from './chunk-PRDWJ4AR.js';
|
|
70
70
|
export { Dropdown, useDropdown } from './chunk-JIYP73OJ.js';
|
|
71
71
|
export { Editor, useEditor } from './chunk-RID7CYGD.js';
|
|
72
|
-
export { useId, useNodeRegistry } from './chunk-
|
|
72
|
+
export { THEME_STORAGE_KEY, getThemePreference, initTheme, resolveTheme, setThemePreference, subscribeTheme, useId, useNodeRegistry, useTheme } from './chunk-FWCREAIT.js';
|
|
73
73
|
export { usePanZoom } from './chunk-CPY7NHXM.js';
|
|
74
74
|
export { Emoji } from './chunk-O4MKOSU2.js';
|
|
75
75
|
export { EmojiSelect } from './chunk-GKGL7F36.js';
|
|
@@ -104,7 +104,7 @@ export { Card } from './chunk-NH7NRRII.js';
|
|
|
104
104
|
export { Carousel, useCarousel } from './chunk-HG6XUJOT.js';
|
|
105
105
|
export { Accordion, useAccordion } from './chunk-AKIUDPJU.js';
|
|
106
106
|
export { AccordionPanel, AccordionPanelContent, AccordionPanelSection, AccordionPanelTrigger, useAccordionPanel, useAccordionSection } from './chunk-IF5LOWUL.js';
|
|
107
|
-
export { AudioViewer } from './chunk-
|
|
107
|
+
export { AudioViewer } from './chunk-74ZN5CNE.js';
|
|
108
108
|
export { Autocomplete } from './chunk-RM4QWJS3.js';
|
|
109
109
|
export { useFloatingPosition } from './chunk-MQ6VGG62.js';
|
|
110
110
|
import './chunk-OL53XYHF.js';
|
package/dist/media-viewer.cjs
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
require('./chunk-
|
|
3
|
+
var chunkBWTFK2GV_cjs = require('./chunk-BWTFK2GV.cjs');
|
|
4
|
+
require('./chunk-I462NM2A.cjs');
|
|
5
5
|
require('./chunk-JHEM6IGT.cjs');
|
|
6
6
|
require('./chunk-AC7M7JDO.cjs');
|
|
7
7
|
require('./chunk-T6YELZPJ.cjs');
|
|
8
|
-
require('./chunk-
|
|
8
|
+
require('./chunk-3MHVFEIP.cjs');
|
|
9
9
|
require('./chunk-3Z6ALUWP.cjs');
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
Object.defineProperty(exports, "MediaViewer", {
|
|
14
14
|
enumerable: true,
|
|
15
|
-
get: function () { return
|
|
15
|
+
get: function () { return chunkBWTFK2GV_cjs.MediaViewer; }
|
|
16
16
|
});
|
|
17
17
|
//# sourceMappingURL=media-viewer.cjs.map
|
|
18
18
|
//# sourceMappingURL=media-viewer.cjs.map
|
package/dist/media-viewer.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { a as MediaViewer, b as MediaViewerProps } from './index-
|
|
1
|
+
export { a as MediaViewer, b as MediaViewerProps } from './index-CgPpIw_O.cjs';
|
|
2
2
|
import 'react';
|
|
3
3
|
import './ImageViewer.types-BaqlDeuo.cjs';
|
|
4
|
-
import './VideoViewer.types-
|
|
5
|
-
import './AudioViewer.types-
|
|
4
|
+
import './VideoViewer.types-_AwQ8DQr.cjs';
|
|
5
|
+
import './AudioViewer.types-CyhmQVQd.cjs';
|
|
6
6
|
import './PdfViewer.types-_u6vboSl.cjs';
|
package/dist/media-viewer.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { a as MediaViewer, b as MediaViewerProps } from './index-
|
|
1
|
+
export { a as MediaViewer, b as MediaViewerProps } from './index-IeivGsNg.js';
|
|
2
2
|
import 'react';
|
|
3
3
|
import './ImageViewer.types-BaqlDeuo.js';
|
|
4
|
-
import './VideoViewer.types-
|
|
5
|
-
import './AudioViewer.types-
|
|
4
|
+
import './VideoViewer.types-_AwQ8DQr.js';
|
|
5
|
+
import './AudioViewer.types-CyhmQVQd.js';
|
|
6
6
|
import './PdfViewer.types-_u6vboSl.js';
|
package/dist/media-viewer.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export { MediaViewer } from './chunk-
|
|
2
|
-
import './chunk-
|
|
1
|
+
export { MediaViewer } from './chunk-QWSTG5MF.js';
|
|
2
|
+
import './chunk-YVDAXYHP.js';
|
|
3
3
|
import './chunk-DZD2RJVD.js';
|
|
4
4
|
import './chunk-A3CNYKT3.js';
|
|
5
5
|
import './chunk-CPY7NHXM.js';
|
|
6
|
-
import './chunk-
|
|
6
|
+
import './chunk-74ZN5CNE.js';
|
|
7
7
|
import './chunk-DSUHZO6T.js';
|
|
8
8
|
//# sourceMappingURL=media-viewer.js.map
|
|
9
9
|
//# sourceMappingURL=media-viewer.js.map
|
package/dist/mobile-menu.cjs
CHANGED
package/dist/mobile-menu.js
CHANGED
package/dist/sidebar.cjs
CHANGED
package/dist/sidebar.js
CHANGED
package/dist/video-viewer.cjs
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkI462NM2A_cjs = require('./chunk-I462NM2A.cjs');
|
|
4
4
|
require('./chunk-3Z6ALUWP.cjs');
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
Object.defineProperty(exports, "VideoViewer", {
|
|
9
9
|
enumerable: true,
|
|
10
|
-
get: function () { return
|
|
10
|
+
get: function () { return chunkI462NM2A_cjs.VideoViewer; }
|
|
11
11
|
});
|
|
12
12
|
//# sourceMappingURL=video-viewer.cjs.map
|
|
13
13
|
//# sourceMappingURL=video-viewer.cjs.map
|
package/dist/video-viewer.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import { V as VideoViewerProps } from './VideoViewer.types-
|
|
2
|
+
import { V as VideoViewerProps } from './VideoViewer.types-_AwQ8DQr.cjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* A standalone video viewer — native controls, optional poster, fit-to-box, and
|