@ai-matrx/media 0.1.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.
@@ -0,0 +1,310 @@
1
+ import * as react from 'react';
2
+ import react__default, { SVGProps, HTMLAttributes, InputHTMLAttributes, ReactNode } from 'react';
3
+ import { b as MediaRefLike, l as MediaUploadOptions, i as MediaUploadEntry, f as MediaActionKind } from './use-media-upload-VjUhqbyY.cjs';
4
+
5
+ /**
6
+ * src/react/cn.ts — conditional class join with last-wins Tailwind conflict
7
+ * merging. The originals used the app's `cn` (clsx + tailwind-merge); public
8
+ * `className` overrides depend on last-wins class-conflict merging, so a
9
+ * naive join would be a behavior divergence (the kit `./confirm` precedent —
10
+ * this is why `tailwind-merge` is a sanctioned runtime dep of `/react`).
11
+ */
12
+ type ClassValue = string | false | null | undefined | 0;
13
+ declare function cn(...inputs: ClassValue[]): string;
14
+
15
+ type MediaIconProps = SVGProps<SVGSVGElement>;
16
+ declare function ArchiveIcon(props: MediaIconProps): react.JSX.Element;
17
+ declare function BracesIcon(props: MediaIconProps): react.JSX.Element;
18
+ declare function CheckIcon(props: MediaIconProps): react.JSX.Element;
19
+ declare function CodeIcon(props: MediaIconProps): react.JSX.Element;
20
+ declare function CopyIcon(props: MediaIconProps): react.JSX.Element;
21
+ declare function DatabaseIcon(props: MediaIconProps): react.JSX.Element;
22
+ declare function DownloadIcon(props: MediaIconProps): react.JSX.Element;
23
+ declare function ExternalLinkIcon(props: MediaIconProps): react.JSX.Element;
24
+ declare function FileAudioIcon(props: MediaIconProps): react.JSX.Element;
25
+ declare function FileCodeIcon(props: MediaIconProps): react.JSX.Element;
26
+ declare function FileJsonIcon(props: MediaIconProps): react.JSX.Element;
27
+ declare function FileSpreadsheetIcon(props: MediaIconProps): react.JSX.Element;
28
+ declare function FileTextIcon(props: MediaIconProps): react.JSX.Element;
29
+ declare function FileTypeIcon(props: MediaIconProps): react.JSX.Element;
30
+ declare function FileVideoIcon(props: MediaIconProps): react.JSX.Element;
31
+ declare function FolderIcon(props: MediaIconProps): react.JSX.Element;
32
+ declare function FolderOpenIcon(props: MediaIconProps): react.JSX.Element;
33
+ declare function ImageIcon(props: MediaIconProps): react.JSX.Element;
34
+ declare function ImageOffIcon(props: MediaIconProps): react.JSX.Element;
35
+ declare function MusicIcon(props: MediaIconProps): react.JSX.Element;
36
+ declare function PackageBoxIcon(props: MediaIconProps): react.JSX.Element;
37
+ declare function PenToolIcon(props: MediaIconProps): react.JSX.Element;
38
+ declare function Share2Icon(props: MediaIconProps): react.JSX.Element;
39
+ declare function SubtitlesIcon(props: MediaIconProps): react.JSX.Element;
40
+ declare function UploadIcon(props: MediaIconProps): react.JSX.Element;
41
+ declare function VideoIcon(props: MediaIconProps): react.JSX.Element;
42
+ declare function VideoOffIcon(props: MediaIconProps): react.JSX.Element;
43
+ declare function VolumeXIcon(props: MediaIconProps): react.JSX.Element;
44
+ declare function XIcon(props: MediaIconProps): react.JSX.Element;
45
+ declare function AlertCircleIcon(props: MediaIconProps): react.JSX.Element;
46
+ declare function CheckCircle2Icon(props: MediaIconProps): react.JSX.Element;
47
+
48
+ /**
49
+ * src/react/file-icon.tsx — icon tile for any file or folder.
50
+ *
51
+ * Verbatim port of matrx-frontend `components/core/FileIcon/FileIcon.tsx`
52
+ * with two seam inversions: the registry lookup is the package's own
53
+ * `getFileKindDetails` (`/core`), and the glyphs are the package's own
54
+ * inlined SVGs (C19 — no lucide peer).
55
+ */
56
+ interface FileIconProps {
57
+ /** Either the filename (for files) or omitted for folders. */
58
+ fileName?: string | undefined;
59
+ /** Server MIME — when set, resolves audio/webm vs video/webm correctly. */
60
+ mimeType?: string | null | undefined;
61
+ /** If true, renders a folder icon. `open` picks the open-folder glyph. */
62
+ isFolder?: boolean | undefined;
63
+ open?: boolean | undefined;
64
+ /** Override the mapped color (useful for selected states). */
65
+ colorClass?: string | undefined;
66
+ className?: string | undefined;
67
+ size?: number | undefined;
68
+ }
69
+ declare function FileIcon({ fileName, mimeType, isFolder, open, colorClass, className, size, }: FileIconProps): react.JSX.Element;
70
+
71
+ /**
72
+ * src/react/inline-media-ref.tsx — the canonical inline media renderer.
73
+ *
74
+ * Verbatim behavior port of matrx-frontend
75
+ * `features/files/components/inline/InlineMediaRef.tsx` (849 LOC, 116
76
+ * importers) with only the coupling seams inverted:
77
+ *
78
+ * - URL resolution / public-CDN detection / auth-transport choice →
79
+ * `MediaClient.resolve` (`transport: "blob"` is the private-pixels lane;
80
+ * the Redux `useEnsureCloudFile`/`selectFileById` hydration lives behind
81
+ * the client now)
82
+ * - bearer-authenticated bytes → `MediaClient.getBlob` via `useMediaBlob`
83
+ * - session-refresh retry → `MediaClient.recoverLoadError` via
84
+ * `useMediaLoadRecovery`
85
+ * - `next/image` → the injected `MediaHostPorts.ImageComponent` (plain
86
+ * `<img>` default)
87
+ * - audio output sink + exclusive-playback join → the injected
88
+ * `MediaHostPorts.playbackSession` (inert default)
89
+ * - lucide icons → the package's own inlined SVGs (C19)
90
+ *
91
+ * Pass a `MediaRef` (or a fileId / EXTERNAL public URL string), get back a
92
+ * correctly-sized `<img>` / `<video>` / `<audio>`. There is NO `src` prop —
93
+ * durable refs are the only identity this component accepts (law 2/3).
94
+ */
95
+
96
+ type InlineMediaRefSize = "xs" | "sm" | "md" | "lg" | "xl" | "fill" | {
97
+ width: number;
98
+ height: number;
99
+ };
100
+ type InlineMediaRefFit = "cover" | "contain" | "fill";
101
+ interface InlineMediaRefProps {
102
+ /**
103
+ * Reference to the media: a {@link MediaRef}, a bare fileId string, an
104
+ * EXTERNAL public URL string, or null/undefined (renders the fallback).
105
+ *
106
+ * Named `ref` as a CONTENT prop, exactly like the original (React 19
107
+ * treats ref as a regular prop on function components) — the 116 existing
108
+ * call sites pass `ref={mediaRef}` and must keep working at the C9 swap.
109
+ * Use `mediaElementRef` for imperative access to the DOM node.
110
+ */
111
+ ref?: MediaRefLike | null | undefined;
112
+ /** Square dimension preset or explicit width/height. Default `"md"` (64×64). */
113
+ size?: InlineMediaRefSize | undefined;
114
+ /** CSS object-fit. Default `"cover"`. */
115
+ fit?: InlineMediaRefFit | undefined;
116
+ /** Rendered when the ref can't be resolved to a URL at all. Default `"icon"`. */
117
+ fallback?: "icon" | "skeleton" | null | undefined;
118
+ /** Override the icon shown in `fallback="icon"`. */
119
+ fallbackIcon?: react__default.ReactNode | undefined;
120
+ /**
121
+ * Rendered when the URL *was* resolved but the media element failed to
122
+ * load. Default `"info"` — an informative destructive-tinted panel with
123
+ * URL + copy button + alt text; compacts to icon-only below ~64px.
124
+ */
125
+ errorFallback?: "info" | "icon" | "skeleton" | null | undefined;
126
+ /** Alt text for `<img>`. Defaults to "" (decorative). */
127
+ alt?: string | undefined;
128
+ /** Force the media element type. Default: infer from `mime_type` / resolution. */
129
+ as?: "img" | "video" | "audio" | undefined;
130
+ controls?: boolean | undefined;
131
+ autoPlay?: boolean | undefined;
132
+ loop?: boolean | undefined;
133
+ muted?: boolean | undefined;
134
+ playsInline?: boolean | undefined;
135
+ preload?: "none" | "metadata" | "auto" | undefined;
136
+ /** Space-separated native controls to hide — forwarded to `<video controlsList>`. */
137
+ controlsList?: string | undefined;
138
+ rounded?: "none" | "sm" | "md" | "lg" | "full" | undefined;
139
+ /** Click handler — wires up cursor + role + keyboard activation. */
140
+ onClick?: ((event: react__default.MouseEvent | react__default.KeyboardEvent) => void) | undefined;
141
+ /**
142
+ * Fires after the client's ONE recovery attempt is exhausted (or the
143
+ * failure was unrecoverable). The internal error fallback still renders
144
+ * unless `errorFallback={null}`.
145
+ */
146
+ onError?: ((event: react__default.SyntheticEvent<HTMLImageElement | HTMLVideoElement | HTMLAudioElement>) => void) | undefined;
147
+ onLoad?: ((event: react__default.SyntheticEvent<HTMLImageElement | HTMLVideoElement | HTMLAudioElement>) => void) | undefined;
148
+ /**
149
+ * Forwarded to the underlying element for imperative DOM access. Not a
150
+ * React `forwardRef` — pass any ref-like value here instead. When
151
+ * supplied, the ImageComponent branch is skipped so the ref attaches to
152
+ * the real DOM node.
153
+ */
154
+ mediaElementRef?: react__default.Ref<HTMLImageElement | HTMLVideoElement | HTMLAudioElement> | undefined;
155
+ /**
156
+ * Canvas pixel reads: `crossOrigin` consumers route through the
157
+ * bearer-authenticated blob lane unless the resolution is a CORS-safe
158
+ * public CDN URL.
159
+ */
160
+ crossOrigin?: "anonymous" | "use-credentials" | undefined;
161
+ border?: "none" | "subtle" | undefined;
162
+ className?: string | undefined;
163
+ }
164
+ declare function InlineMediaRef({ ref: mediaRef, size, fit, fallback, fallbackIcon, errorFallback, alt, as, controls, autoPlay, loop, muted, playsInline, preload, controlsList, rounded, onClick, onError, onLoad, mediaElementRef, crossOrigin, border, className, }: InlineMediaRefProps): react__default.JSX.Element | null;
165
+
166
+ interface MediaThumbnailProps {
167
+ /** The file's durable ref (a MediaRef or bare fileId). */
168
+ mediaRef: MediaRefLike;
169
+ /** Display name — drives the icon fallback and alt text. */
170
+ fileName: string;
171
+ /** Server MIME, when known. */
172
+ mimeType?: string | null | undefined;
173
+ /** A known server-rendered thumbnail URL (`FileRecord.thumbnail_url`). */
174
+ thumbnailUrl?: string | null | undefined;
175
+ /** Pixel size for the icon fallback. Image/video fill their container. */
176
+ iconSize?: number | undefined;
177
+ /** Aspect ratio classes applied to the container, e.g. "aspect-[4/3]". */
178
+ className?: string | undefined;
179
+ /** Override the rounded corners of the container. */
180
+ rounded?: string | undefined;
181
+ /**
182
+ * Whether to fall back to a source-file URL when no rendered thumbnail is
183
+ * available. Disable in dense pickers to avoid a byte request per row.
184
+ */
185
+ allowSourceFallback?: boolean | undefined;
186
+ }
187
+ declare function MediaThumbnail({ mediaRef, fileName, mimeType, thumbnailUrl, iconSize, className, rounded, allowSourceFallback, }: MediaThumbnailProps): react.JSX.Element;
188
+
189
+ /**
190
+ * src/react/use-media-dropzone.ts — headless drag + paste + picker intake.
191
+ *
192
+ * Replaces the original's `react-dropzone` dependency with native DOM events
193
+ * (the package's `/react` entry carries no UI-library deps). The behavior
194
+ * contract is the original FileUploadDropzone's: drag-over highlight, hidden
195
+ * input picker (`openPicker`), clipboard paste of images with a brief
196
+ * highlight pulse, an optional window event that opens the picker, and
197
+ * accept/maxSize filtering (UI-only; the server enforces its own caps).
198
+ */
199
+
200
+ interface MediaDropzoneOptions {
201
+ /** Receives every accepted batch (drop, paste, or picker). */
202
+ onFiles: (files: File[]) => void;
203
+ /** Restrict accepted types, e.g. ["image/*", "application/pdf", ".csv"]. */
204
+ accept?: string[] | undefined;
205
+ /** Max size per file in bytes (UI-only filter). */
206
+ maxSize?: number | undefined;
207
+ /** Fires for files filtered out by accept/maxSize. */
208
+ onRejected?: ((rejected: Array<{
209
+ file: File;
210
+ reason: "type" | "size";
211
+ }>) => void) | undefined;
212
+ /** Enable clipboard paste (images only). Defaults true. */
213
+ enablePaste?: boolean | undefined;
214
+ /** Optional window event name that opens the native file picker. */
215
+ pickerEventName?: string | undefined;
216
+ disabled?: boolean | undefined;
217
+ multiple?: boolean | undefined;
218
+ }
219
+ interface MediaDropzoneState {
220
+ /** Spread onto the drop surface element. */
221
+ getRootProps: () => HTMLAttributes<HTMLElement>;
222
+ /** Spread onto a hidden `<input type="file">`. */
223
+ getInputProps: () => InputHTMLAttributes<HTMLInputElement> & {
224
+ ref: (node: HTMLInputElement | null) => void;
225
+ };
226
+ isDragActive: boolean;
227
+ /** Brief pulse after a successful clipboard paste. */
228
+ pasteHighlight: boolean;
229
+ openPicker: () => void;
230
+ }
231
+ declare function useMediaDropzone(options: MediaDropzoneOptions): MediaDropzoneState;
232
+
233
+ interface FileUploadDropzoneActions {
234
+ openLocalPicker: () => void;
235
+ uploadFiles: (files: File[]) => Promise<void>;
236
+ }
237
+ interface FileUploadDropzoneProps {
238
+ /** Upload options forwarded to the client (visibility, folder, metadata…). */
239
+ uploadOptions?: MediaUploadOptions | undefined;
240
+ /** Restrict accepted types (e.g. ["image/*"]). */
241
+ accept?: string[] | undefined;
242
+ /** Max size per file in bytes (UI-only; server enforces its own cap). */
243
+ maxSize?: number | undefined;
244
+ /** Enable paste from clipboard (images only). Defaults true. */
245
+ enablePaste?: boolean | undefined;
246
+ /** Rendering mode. */
247
+ mode?: "overlay" | "inline" | undefined;
248
+ /** Children render inside the drop surface. */
249
+ children?: ReactNode | ((actions: FileUploadDropzoneActions) => ReactNode) | undefined;
250
+ className?: string | undefined;
251
+ /** Host-shaped acquisition sources (Drive, local folder, existing files…). */
252
+ actions?: ReactNode | undefined;
253
+ /** Fires the moment an upload batch STARTS (before any network completes). */
254
+ onUploadStart?: ((files: File[]) => void) | undefined;
255
+ onUploaded?: ((fileIds: string[]) => void) | undefined;
256
+ onError?: ((message: string) => void) | undefined;
257
+ /** Reveal a finished file from the upload tray. */
258
+ onOpenFile?: ((fileId: string) => void) | undefined;
259
+ /** Optional window event name that opens the native file picker. */
260
+ pickerEventName?: string | undefined;
261
+ }
262
+ declare function FileUploadDropzone({ uploadOptions, accept, maxSize, enablePaste, mode, children, className, actions, onUploadStart, onUploaded, onError, onOpenFile, pickerEventName, }: FileUploadDropzoneProps): react.JSX.Element;
263
+
264
+ declare function formatFileSize(bytes: number): string;
265
+ interface UploadProgressListProps {
266
+ uploads: MediaUploadEntry[];
267
+ /** Remove an entry from the tray (wire to `useMediaUpload().clearEntry`). */
268
+ onDismiss: (id: string) => void;
269
+ /**
270
+ * Reveal a finished file — opens the preview pane / scrolls the row.
271
+ * When omitted, the "Open" affordance is hidden.
272
+ */
273
+ onOpenFile?: ((fileId: string) => void) | undefined;
274
+ className?: string | undefined;
275
+ }
276
+ declare function UploadProgressListImpl({ uploads, onDismiss, onOpenFile, className, }: UploadProgressListProps): react.JSX.Element | null;
277
+ declare const UploadProgressList: react.MemoExoticComponent<typeof UploadProgressListImpl>;
278
+
279
+ interface MediaActionToolbarProps {
280
+ mediaRef: MediaRefLike | null | undefined;
281
+ fileName?: string | undefined;
282
+ alt?: string | undefined;
283
+ /** Which actions to render, in order. Default: share, download, copy, open. */
284
+ actions?: MediaActionKind[] | undefined;
285
+ /** Hide unavailable actions instead of rendering them disabled. */
286
+ hideUnavailable?: boolean | undefined;
287
+ className?: string | undefined;
288
+ buttonClassName?: string | undefined;
289
+ }
290
+ declare function MediaActionToolbar({ mediaRef, fileName, alt, actions, hideUnavailable, className, buttonClassName, }: MediaActionToolbarProps): react.JSX.Element | null;
291
+
292
+ interface MediaLightboxProps {
293
+ open: boolean;
294
+ onClose: () => void;
295
+ mediaRef: MediaRefLike | null | undefined;
296
+ fileName?: string | undefined;
297
+ alt?: string | undefined;
298
+ /** Force the media element type (default: inferred from the resolution). */
299
+ as?: "img" | "video" | "audio" | undefined;
300
+ /** Toolbar actions to offer. Default: share, download, copy, open. */
301
+ actions?: MediaActionKind[] | undefined;
302
+ /** Hide unavailable toolbar actions instead of disabling them. */
303
+ hideUnavailableActions?: boolean | undefined;
304
+ /** Extra chrome rendered in the header row (left of the toolbar). */
305
+ headerExtra?: ReactNode | undefined;
306
+ className?: string | undefined;
307
+ }
308
+ declare function MediaLightbox({ open, onClose, mediaRef, fileName, alt, as, actions, hideUnavailableActions, headerExtra, className, }: MediaLightboxProps): react.JSX.Element | null;
309
+
310
+ export { AlertCircleIcon, ArchiveIcon, BracesIcon, CheckCircle2Icon, CheckIcon, CodeIcon, CopyIcon, DatabaseIcon, DownloadIcon, ExternalLinkIcon, FileAudioIcon, FileCodeIcon, FileIcon, type FileIconProps, FileJsonIcon, FileSpreadsheetIcon, FileTextIcon, FileTypeIcon, FileUploadDropzone, type FileUploadDropzoneActions, type FileUploadDropzoneProps, FileVideoIcon, FolderIcon, FolderOpenIcon, ImageIcon, ImageOffIcon, InlineMediaRef, type InlineMediaRefFit, type InlineMediaRefProps, type InlineMediaRefSize, MediaActionToolbar, type MediaActionToolbarProps, type MediaDropzoneOptions, type MediaDropzoneState, type MediaIconProps, MediaLightbox, type MediaLightboxProps, MediaThumbnail, type MediaThumbnailProps, MusicIcon, PackageBoxIcon, PenToolIcon, Share2Icon, SubtitlesIcon, UploadIcon, UploadProgressList, type UploadProgressListProps, VideoIcon, VideoOffIcon, VolumeXIcon, XIcon, cn, formatFileSize, useMediaDropzone };
@@ -0,0 +1,310 @@
1
+ import * as react from 'react';
2
+ import react__default, { SVGProps, HTMLAttributes, InputHTMLAttributes, ReactNode } from 'react';
3
+ import { b as MediaRefLike, l as MediaUploadOptions, i as MediaUploadEntry, f as MediaActionKind } from './use-media-upload-VjUhqbyY.js';
4
+
5
+ /**
6
+ * src/react/cn.ts — conditional class join with last-wins Tailwind conflict
7
+ * merging. The originals used the app's `cn` (clsx + tailwind-merge); public
8
+ * `className` overrides depend on last-wins class-conflict merging, so a
9
+ * naive join would be a behavior divergence (the kit `./confirm` precedent —
10
+ * this is why `tailwind-merge` is a sanctioned runtime dep of `/react`).
11
+ */
12
+ type ClassValue = string | false | null | undefined | 0;
13
+ declare function cn(...inputs: ClassValue[]): string;
14
+
15
+ type MediaIconProps = SVGProps<SVGSVGElement>;
16
+ declare function ArchiveIcon(props: MediaIconProps): react.JSX.Element;
17
+ declare function BracesIcon(props: MediaIconProps): react.JSX.Element;
18
+ declare function CheckIcon(props: MediaIconProps): react.JSX.Element;
19
+ declare function CodeIcon(props: MediaIconProps): react.JSX.Element;
20
+ declare function CopyIcon(props: MediaIconProps): react.JSX.Element;
21
+ declare function DatabaseIcon(props: MediaIconProps): react.JSX.Element;
22
+ declare function DownloadIcon(props: MediaIconProps): react.JSX.Element;
23
+ declare function ExternalLinkIcon(props: MediaIconProps): react.JSX.Element;
24
+ declare function FileAudioIcon(props: MediaIconProps): react.JSX.Element;
25
+ declare function FileCodeIcon(props: MediaIconProps): react.JSX.Element;
26
+ declare function FileJsonIcon(props: MediaIconProps): react.JSX.Element;
27
+ declare function FileSpreadsheetIcon(props: MediaIconProps): react.JSX.Element;
28
+ declare function FileTextIcon(props: MediaIconProps): react.JSX.Element;
29
+ declare function FileTypeIcon(props: MediaIconProps): react.JSX.Element;
30
+ declare function FileVideoIcon(props: MediaIconProps): react.JSX.Element;
31
+ declare function FolderIcon(props: MediaIconProps): react.JSX.Element;
32
+ declare function FolderOpenIcon(props: MediaIconProps): react.JSX.Element;
33
+ declare function ImageIcon(props: MediaIconProps): react.JSX.Element;
34
+ declare function ImageOffIcon(props: MediaIconProps): react.JSX.Element;
35
+ declare function MusicIcon(props: MediaIconProps): react.JSX.Element;
36
+ declare function PackageBoxIcon(props: MediaIconProps): react.JSX.Element;
37
+ declare function PenToolIcon(props: MediaIconProps): react.JSX.Element;
38
+ declare function Share2Icon(props: MediaIconProps): react.JSX.Element;
39
+ declare function SubtitlesIcon(props: MediaIconProps): react.JSX.Element;
40
+ declare function UploadIcon(props: MediaIconProps): react.JSX.Element;
41
+ declare function VideoIcon(props: MediaIconProps): react.JSX.Element;
42
+ declare function VideoOffIcon(props: MediaIconProps): react.JSX.Element;
43
+ declare function VolumeXIcon(props: MediaIconProps): react.JSX.Element;
44
+ declare function XIcon(props: MediaIconProps): react.JSX.Element;
45
+ declare function AlertCircleIcon(props: MediaIconProps): react.JSX.Element;
46
+ declare function CheckCircle2Icon(props: MediaIconProps): react.JSX.Element;
47
+
48
+ /**
49
+ * src/react/file-icon.tsx — icon tile for any file or folder.
50
+ *
51
+ * Verbatim port of matrx-frontend `components/core/FileIcon/FileIcon.tsx`
52
+ * with two seam inversions: the registry lookup is the package's own
53
+ * `getFileKindDetails` (`/core`), and the glyphs are the package's own
54
+ * inlined SVGs (C19 — no lucide peer).
55
+ */
56
+ interface FileIconProps {
57
+ /** Either the filename (for files) or omitted for folders. */
58
+ fileName?: string | undefined;
59
+ /** Server MIME — when set, resolves audio/webm vs video/webm correctly. */
60
+ mimeType?: string | null | undefined;
61
+ /** If true, renders a folder icon. `open` picks the open-folder glyph. */
62
+ isFolder?: boolean | undefined;
63
+ open?: boolean | undefined;
64
+ /** Override the mapped color (useful for selected states). */
65
+ colorClass?: string | undefined;
66
+ className?: string | undefined;
67
+ size?: number | undefined;
68
+ }
69
+ declare function FileIcon({ fileName, mimeType, isFolder, open, colorClass, className, size, }: FileIconProps): react.JSX.Element;
70
+
71
+ /**
72
+ * src/react/inline-media-ref.tsx — the canonical inline media renderer.
73
+ *
74
+ * Verbatim behavior port of matrx-frontend
75
+ * `features/files/components/inline/InlineMediaRef.tsx` (849 LOC, 116
76
+ * importers) with only the coupling seams inverted:
77
+ *
78
+ * - URL resolution / public-CDN detection / auth-transport choice →
79
+ * `MediaClient.resolve` (`transport: "blob"` is the private-pixels lane;
80
+ * the Redux `useEnsureCloudFile`/`selectFileById` hydration lives behind
81
+ * the client now)
82
+ * - bearer-authenticated bytes → `MediaClient.getBlob` via `useMediaBlob`
83
+ * - session-refresh retry → `MediaClient.recoverLoadError` via
84
+ * `useMediaLoadRecovery`
85
+ * - `next/image` → the injected `MediaHostPorts.ImageComponent` (plain
86
+ * `<img>` default)
87
+ * - audio output sink + exclusive-playback join → the injected
88
+ * `MediaHostPorts.playbackSession` (inert default)
89
+ * - lucide icons → the package's own inlined SVGs (C19)
90
+ *
91
+ * Pass a `MediaRef` (or a fileId / EXTERNAL public URL string), get back a
92
+ * correctly-sized `<img>` / `<video>` / `<audio>`. There is NO `src` prop —
93
+ * durable refs are the only identity this component accepts (law 2/3).
94
+ */
95
+
96
+ type InlineMediaRefSize = "xs" | "sm" | "md" | "lg" | "xl" | "fill" | {
97
+ width: number;
98
+ height: number;
99
+ };
100
+ type InlineMediaRefFit = "cover" | "contain" | "fill";
101
+ interface InlineMediaRefProps {
102
+ /**
103
+ * Reference to the media: a {@link MediaRef}, a bare fileId string, an
104
+ * EXTERNAL public URL string, or null/undefined (renders the fallback).
105
+ *
106
+ * Named `ref` as a CONTENT prop, exactly like the original (React 19
107
+ * treats ref as a regular prop on function components) — the 116 existing
108
+ * call sites pass `ref={mediaRef}` and must keep working at the C9 swap.
109
+ * Use `mediaElementRef` for imperative access to the DOM node.
110
+ */
111
+ ref?: MediaRefLike | null | undefined;
112
+ /** Square dimension preset or explicit width/height. Default `"md"` (64×64). */
113
+ size?: InlineMediaRefSize | undefined;
114
+ /** CSS object-fit. Default `"cover"`. */
115
+ fit?: InlineMediaRefFit | undefined;
116
+ /** Rendered when the ref can't be resolved to a URL at all. Default `"icon"`. */
117
+ fallback?: "icon" | "skeleton" | null | undefined;
118
+ /** Override the icon shown in `fallback="icon"`. */
119
+ fallbackIcon?: react__default.ReactNode | undefined;
120
+ /**
121
+ * Rendered when the URL *was* resolved but the media element failed to
122
+ * load. Default `"info"` — an informative destructive-tinted panel with
123
+ * URL + copy button + alt text; compacts to icon-only below ~64px.
124
+ */
125
+ errorFallback?: "info" | "icon" | "skeleton" | null | undefined;
126
+ /** Alt text for `<img>`. Defaults to "" (decorative). */
127
+ alt?: string | undefined;
128
+ /** Force the media element type. Default: infer from `mime_type` / resolution. */
129
+ as?: "img" | "video" | "audio" | undefined;
130
+ controls?: boolean | undefined;
131
+ autoPlay?: boolean | undefined;
132
+ loop?: boolean | undefined;
133
+ muted?: boolean | undefined;
134
+ playsInline?: boolean | undefined;
135
+ preload?: "none" | "metadata" | "auto" | undefined;
136
+ /** Space-separated native controls to hide — forwarded to `<video controlsList>`. */
137
+ controlsList?: string | undefined;
138
+ rounded?: "none" | "sm" | "md" | "lg" | "full" | undefined;
139
+ /** Click handler — wires up cursor + role + keyboard activation. */
140
+ onClick?: ((event: react__default.MouseEvent | react__default.KeyboardEvent) => void) | undefined;
141
+ /**
142
+ * Fires after the client's ONE recovery attempt is exhausted (or the
143
+ * failure was unrecoverable). The internal error fallback still renders
144
+ * unless `errorFallback={null}`.
145
+ */
146
+ onError?: ((event: react__default.SyntheticEvent<HTMLImageElement | HTMLVideoElement | HTMLAudioElement>) => void) | undefined;
147
+ onLoad?: ((event: react__default.SyntheticEvent<HTMLImageElement | HTMLVideoElement | HTMLAudioElement>) => void) | undefined;
148
+ /**
149
+ * Forwarded to the underlying element for imperative DOM access. Not a
150
+ * React `forwardRef` — pass any ref-like value here instead. When
151
+ * supplied, the ImageComponent branch is skipped so the ref attaches to
152
+ * the real DOM node.
153
+ */
154
+ mediaElementRef?: react__default.Ref<HTMLImageElement | HTMLVideoElement | HTMLAudioElement> | undefined;
155
+ /**
156
+ * Canvas pixel reads: `crossOrigin` consumers route through the
157
+ * bearer-authenticated blob lane unless the resolution is a CORS-safe
158
+ * public CDN URL.
159
+ */
160
+ crossOrigin?: "anonymous" | "use-credentials" | undefined;
161
+ border?: "none" | "subtle" | undefined;
162
+ className?: string | undefined;
163
+ }
164
+ declare function InlineMediaRef({ ref: mediaRef, size, fit, fallback, fallbackIcon, errorFallback, alt, as, controls, autoPlay, loop, muted, playsInline, preload, controlsList, rounded, onClick, onError, onLoad, mediaElementRef, crossOrigin, border, className, }: InlineMediaRefProps): react__default.JSX.Element | null;
165
+
166
+ interface MediaThumbnailProps {
167
+ /** The file's durable ref (a MediaRef or bare fileId). */
168
+ mediaRef: MediaRefLike;
169
+ /** Display name — drives the icon fallback and alt text. */
170
+ fileName: string;
171
+ /** Server MIME, when known. */
172
+ mimeType?: string | null | undefined;
173
+ /** A known server-rendered thumbnail URL (`FileRecord.thumbnail_url`). */
174
+ thumbnailUrl?: string | null | undefined;
175
+ /** Pixel size for the icon fallback. Image/video fill their container. */
176
+ iconSize?: number | undefined;
177
+ /** Aspect ratio classes applied to the container, e.g. "aspect-[4/3]". */
178
+ className?: string | undefined;
179
+ /** Override the rounded corners of the container. */
180
+ rounded?: string | undefined;
181
+ /**
182
+ * Whether to fall back to a source-file URL when no rendered thumbnail is
183
+ * available. Disable in dense pickers to avoid a byte request per row.
184
+ */
185
+ allowSourceFallback?: boolean | undefined;
186
+ }
187
+ declare function MediaThumbnail({ mediaRef, fileName, mimeType, thumbnailUrl, iconSize, className, rounded, allowSourceFallback, }: MediaThumbnailProps): react.JSX.Element;
188
+
189
+ /**
190
+ * src/react/use-media-dropzone.ts — headless drag + paste + picker intake.
191
+ *
192
+ * Replaces the original's `react-dropzone` dependency with native DOM events
193
+ * (the package's `/react` entry carries no UI-library deps). The behavior
194
+ * contract is the original FileUploadDropzone's: drag-over highlight, hidden
195
+ * input picker (`openPicker`), clipboard paste of images with a brief
196
+ * highlight pulse, an optional window event that opens the picker, and
197
+ * accept/maxSize filtering (UI-only; the server enforces its own caps).
198
+ */
199
+
200
+ interface MediaDropzoneOptions {
201
+ /** Receives every accepted batch (drop, paste, or picker). */
202
+ onFiles: (files: File[]) => void;
203
+ /** Restrict accepted types, e.g. ["image/*", "application/pdf", ".csv"]. */
204
+ accept?: string[] | undefined;
205
+ /** Max size per file in bytes (UI-only filter). */
206
+ maxSize?: number | undefined;
207
+ /** Fires for files filtered out by accept/maxSize. */
208
+ onRejected?: ((rejected: Array<{
209
+ file: File;
210
+ reason: "type" | "size";
211
+ }>) => void) | undefined;
212
+ /** Enable clipboard paste (images only). Defaults true. */
213
+ enablePaste?: boolean | undefined;
214
+ /** Optional window event name that opens the native file picker. */
215
+ pickerEventName?: string | undefined;
216
+ disabled?: boolean | undefined;
217
+ multiple?: boolean | undefined;
218
+ }
219
+ interface MediaDropzoneState {
220
+ /** Spread onto the drop surface element. */
221
+ getRootProps: () => HTMLAttributes<HTMLElement>;
222
+ /** Spread onto a hidden `<input type="file">`. */
223
+ getInputProps: () => InputHTMLAttributes<HTMLInputElement> & {
224
+ ref: (node: HTMLInputElement | null) => void;
225
+ };
226
+ isDragActive: boolean;
227
+ /** Brief pulse after a successful clipboard paste. */
228
+ pasteHighlight: boolean;
229
+ openPicker: () => void;
230
+ }
231
+ declare function useMediaDropzone(options: MediaDropzoneOptions): MediaDropzoneState;
232
+
233
+ interface FileUploadDropzoneActions {
234
+ openLocalPicker: () => void;
235
+ uploadFiles: (files: File[]) => Promise<void>;
236
+ }
237
+ interface FileUploadDropzoneProps {
238
+ /** Upload options forwarded to the client (visibility, folder, metadata…). */
239
+ uploadOptions?: MediaUploadOptions | undefined;
240
+ /** Restrict accepted types (e.g. ["image/*"]). */
241
+ accept?: string[] | undefined;
242
+ /** Max size per file in bytes (UI-only; server enforces its own cap). */
243
+ maxSize?: number | undefined;
244
+ /** Enable paste from clipboard (images only). Defaults true. */
245
+ enablePaste?: boolean | undefined;
246
+ /** Rendering mode. */
247
+ mode?: "overlay" | "inline" | undefined;
248
+ /** Children render inside the drop surface. */
249
+ children?: ReactNode | ((actions: FileUploadDropzoneActions) => ReactNode) | undefined;
250
+ className?: string | undefined;
251
+ /** Host-shaped acquisition sources (Drive, local folder, existing files…). */
252
+ actions?: ReactNode | undefined;
253
+ /** Fires the moment an upload batch STARTS (before any network completes). */
254
+ onUploadStart?: ((files: File[]) => void) | undefined;
255
+ onUploaded?: ((fileIds: string[]) => void) | undefined;
256
+ onError?: ((message: string) => void) | undefined;
257
+ /** Reveal a finished file from the upload tray. */
258
+ onOpenFile?: ((fileId: string) => void) | undefined;
259
+ /** Optional window event name that opens the native file picker. */
260
+ pickerEventName?: string | undefined;
261
+ }
262
+ declare function FileUploadDropzone({ uploadOptions, accept, maxSize, enablePaste, mode, children, className, actions, onUploadStart, onUploaded, onError, onOpenFile, pickerEventName, }: FileUploadDropzoneProps): react.JSX.Element;
263
+
264
+ declare function formatFileSize(bytes: number): string;
265
+ interface UploadProgressListProps {
266
+ uploads: MediaUploadEntry[];
267
+ /** Remove an entry from the tray (wire to `useMediaUpload().clearEntry`). */
268
+ onDismiss: (id: string) => void;
269
+ /**
270
+ * Reveal a finished file — opens the preview pane / scrolls the row.
271
+ * When omitted, the "Open" affordance is hidden.
272
+ */
273
+ onOpenFile?: ((fileId: string) => void) | undefined;
274
+ className?: string | undefined;
275
+ }
276
+ declare function UploadProgressListImpl({ uploads, onDismiss, onOpenFile, className, }: UploadProgressListProps): react.JSX.Element | null;
277
+ declare const UploadProgressList: react.MemoExoticComponent<typeof UploadProgressListImpl>;
278
+
279
+ interface MediaActionToolbarProps {
280
+ mediaRef: MediaRefLike | null | undefined;
281
+ fileName?: string | undefined;
282
+ alt?: string | undefined;
283
+ /** Which actions to render, in order. Default: share, download, copy, open. */
284
+ actions?: MediaActionKind[] | undefined;
285
+ /** Hide unavailable actions instead of rendering them disabled. */
286
+ hideUnavailable?: boolean | undefined;
287
+ className?: string | undefined;
288
+ buttonClassName?: string | undefined;
289
+ }
290
+ declare function MediaActionToolbar({ mediaRef, fileName, alt, actions, hideUnavailable, className, buttonClassName, }: MediaActionToolbarProps): react.JSX.Element | null;
291
+
292
+ interface MediaLightboxProps {
293
+ open: boolean;
294
+ onClose: () => void;
295
+ mediaRef: MediaRefLike | null | undefined;
296
+ fileName?: string | undefined;
297
+ alt?: string | undefined;
298
+ /** Force the media element type (default: inferred from the resolution). */
299
+ as?: "img" | "video" | "audio" | undefined;
300
+ /** Toolbar actions to offer. Default: share, download, copy, open. */
301
+ actions?: MediaActionKind[] | undefined;
302
+ /** Hide unavailable toolbar actions instead of disabling them. */
303
+ hideUnavailableActions?: boolean | undefined;
304
+ /** Extra chrome rendered in the header row (left of the toolbar). */
305
+ headerExtra?: ReactNode | undefined;
306
+ className?: string | undefined;
307
+ }
308
+ declare function MediaLightbox({ open, onClose, mediaRef, fileName, alt, as, actions, hideUnavailableActions, headerExtra, className, }: MediaLightboxProps): react.JSX.Element | null;
309
+
310
+ export { AlertCircleIcon, ArchiveIcon, BracesIcon, CheckCircle2Icon, CheckIcon, CodeIcon, CopyIcon, DatabaseIcon, DownloadIcon, ExternalLinkIcon, FileAudioIcon, FileCodeIcon, FileIcon, type FileIconProps, FileJsonIcon, FileSpreadsheetIcon, FileTextIcon, FileTypeIcon, FileUploadDropzone, type FileUploadDropzoneActions, type FileUploadDropzoneProps, FileVideoIcon, FolderIcon, FolderOpenIcon, ImageIcon, ImageOffIcon, InlineMediaRef, type InlineMediaRefFit, type InlineMediaRefProps, type InlineMediaRefSize, MediaActionToolbar, type MediaActionToolbarProps, type MediaDropzoneOptions, type MediaDropzoneState, type MediaIconProps, MediaLightbox, type MediaLightboxProps, MediaThumbnail, type MediaThumbnailProps, MusicIcon, PackageBoxIcon, PenToolIcon, Share2Icon, SubtitlesIcon, UploadIcon, UploadProgressList, type UploadProgressListProps, VideoIcon, VideoOffIcon, VolumeXIcon, XIcon, cn, formatFileSize, useMediaDropzone };