@ai-matrx/media 0.2.3 → 0.4.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,289 @@
1
+ import * as react from 'react';
2
+ import { MediaRefLike } from './index.cjs';
3
+
4
+ /**
5
+ * src/viewers/types.ts — the viewer vocabulary.
6
+ *
7
+ * A "viewer" is a full-pane rendering of ONE file: what a file-preview pane,
8
+ * a file tab, or a binary-file fallback in a code editor shows. It is the
9
+ * layer above `/react`'s inline media elements.
10
+ */
11
+
12
+ /**
13
+ * The kinds the dispatcher understands. Ported from the matrx-frontend
14
+ * `PreviewKind` vocabulary so a host registry maps 1:1.
15
+ */
16
+ type MediaViewerKind = "image" | "svg" | "video" | "audio" | "pdf" | "markdown" | "data" | "spreadsheet" | "code" | "office" | "html" | "text" | "generic";
17
+ /**
18
+ * Where the viewer's bytes and display URL come from.
19
+ *
20
+ * - `ref` — the normal lane: identity in, everything through the MediaClient
21
+ * (`resolve()` for the display URL, `getBlob()` for bytes).
22
+ * - `blob` — bytes the host ALREADY has (a code editor that downloaded the
23
+ * file to decide it was binary). No MediaClient round-trip, and the URL is
24
+ * an object URL, so load recovery is off by construction (law 3 is not
25
+ * violated: a `blob:` URL is not a signed URL and never leaves the tab).
26
+ */
27
+ type MediaViewerSource = {
28
+ kind: "ref";
29
+ ref: MediaRefLike;
30
+ } | {
31
+ kind: "blob";
32
+ blob: Blob;
33
+ url: string;
34
+ };
35
+ /** Escape-hatch actions the generic card offers. */
36
+ interface MediaViewerGenericOptions {
37
+ onDownload?: (() => void) | undefined;
38
+ onViewAsText?: (() => void) | undefined;
39
+ viewAsTextLabel?: string | undefined;
40
+ viewAsTextPrimary?: boolean | undefined;
41
+ viewAsTextBusy?: boolean | undefined;
42
+ message?: string | undefined;
43
+ }
44
+ /** Rendered-vs-source mode for the markup viewers (SVG, HTML). */
45
+ type MediaViewerMarkupMode = "rendered" | "source";
46
+ /** Device-width simulation for the HTML viewer. */
47
+ type MediaViewerViewport = "auto" | "mobile" | "tablet" | "desktop";
48
+ /**
49
+ * Optional external control of the markup viewers. When a host mounts its own
50
+ * control rail (matrx-frontend's `FileViewerControlsProvider`), it drives the
51
+ * viewer through these props and the viewer hides its built-in toolbar. When
52
+ * absent, the viewer owns the state and renders its own toolbar — the C23
53
+ * default: capable standalone, steerable when the host has a rail.
54
+ */
55
+ interface MediaViewerMarkupControls {
56
+ mode?: MediaViewerMarkupMode | undefined;
57
+ onModeChange?: ((mode: MediaViewerMarkupMode) => void) | undefined;
58
+ viewport?: MediaViewerViewport | undefined;
59
+ /** Bump to force a clean re-mount of the rendered frame. */
60
+ reloadKey?: number | undefined;
61
+ }
62
+ /** The props EVERY viewer body (built-in or host-registered) receives. */
63
+ interface MediaViewerProps {
64
+ source: MediaViewerSource;
65
+ fileName: string;
66
+ fileSize?: number | null | undefined;
67
+ mimeType?: string | null | undefined;
68
+ className?: string | undefined;
69
+ /** Max bytes read for text-shaped viewers. Defaults to 1MB. */
70
+ maxBytes?: number | undefined;
71
+ /** Controlled 1-based page, for paged engines (PDF). */
72
+ pageNumber?: number | undefined;
73
+ onPageChange?: ((pageNumber: number) => void) | undefined;
74
+ /** Passthroughs for the generic (no-viewer) card. */
75
+ generic?: MediaViewerGenericOptions | undefined;
76
+ /** External control of the markup viewers (SVG / HTML). */
77
+ markupControls?: MediaViewerMarkupControls | undefined;
78
+ }
79
+ /** A viewer body. Structural so a host component satisfies it with no import. */
80
+ type MediaViewerComponent = (props: MediaViewerProps) => unknown;
81
+ /**
82
+ * The code-highlighting seam. A syntax highlighter (Prism, Shiki, Monaco) is
83
+ * a multi-hundred-kilobyte browser-only engine — C8 says a headless consumer
84
+ * must never be forced to carry it, so the package ships the code viewer's
85
+ * CHROME and an honest, capable un-highlighted default, and a host registers
86
+ * the engine. `language` is the package's detected Prism-style language id.
87
+ */
88
+ interface MediaCodeHighlighterProps {
89
+ code: string;
90
+ language: string;
91
+ }
92
+ type MediaCodeHighlighter = (props: MediaCodeHighlighterProps) => unknown;
93
+
94
+ interface MediaFileViewerProps extends MediaViewerProps {
95
+ /**
96
+ * The kind to render. Omit to let the package derive it from the file name
97
+ * and MIME type (`getPreviewKind`).
98
+ */
99
+ previewKind?: MediaViewerKind | undefined;
100
+ }
101
+ declare function MediaFileViewer({ previewKind, ...props }: MediaFileViewerProps): react.JSX.Element;
102
+
103
+ /**
104
+ * src/viewers/registry.ts — the heavy-engine seam.
105
+ *
106
+ * The package ships working bodies for every viewer kind it can render with
107
+ * DOM primitives alone (text, code chrome, svg, html, generic). The kinds
108
+ * whose rendering IS a multi-megabyte browser-only engine — PDF.js, a
109
+ * Markdown/KaTeX stack, SheetJS, a server-side Office extractor — ride this
110
+ * seam instead (C8 + the diff-package Monaco precedent): a host registers the
111
+ * engine once, and until it does, the dispatcher renders an ANNOUNCING
112
+ * default that names the missing engine and still offers download/open. A
113
+ * dead pane is never an outcome.
114
+ *
115
+ * MODULE-LEVEL MUTABLE STATE IS BANNED (the dual ESM/CJS bundle rule): with
116
+ * `splitting: false` and two formats, each loader graph instantiates its own
117
+ * copy of this module, so a plain module-scope Map would silently split the
118
+ * registry — a host registering through the CJS graph would be invisible to a
119
+ * component rendered from the ESM graph. The maps therefore live on
120
+ * `globalThis` under `Symbol.for` slots, and the tarball canary proves a
121
+ * registration made in one graph is visible from the other.
122
+ */
123
+
124
+ /**
125
+ * Register the viewer body for a kind. Registering a kind the package already
126
+ * renders REPLACES the built-in — that is the sanctioned host override (a
127
+ * feature-specific domain viewer implementing the same contract).
128
+ *
129
+ * Returns an unregister function so a test or a hot-reloading host can undo it.
130
+ */
131
+ declare function registerMediaViewer(kind: MediaViewerKind, viewer: MediaViewerComponent): () => void;
132
+ /** The registered viewer for a kind, or `null` when nothing is registered. */
133
+ declare function getMediaViewer(kind: MediaViewerKind): MediaViewerComponent | null;
134
+ /** Every kind a host has registered — for diagnostics and tests. */
135
+ declare function registeredMediaViewerKinds(): MediaViewerKind[];
136
+ /**
137
+ * Register the syntax-highlighting engine for the built-in code viewer.
138
+ * Without one the code viewer still renders — monospace, line-numbered,
139
+ * copyable, truncation-honest — it simply is not colored.
140
+ */
141
+ declare function registerMediaCodeHighlighter(highlighter: MediaCodeHighlighter): () => void;
142
+ declare function getMediaCodeHighlighter(): MediaCodeHighlighter | null;
143
+
144
+ declare function TextViewer({ source, className, maxBytes, }: MediaViewerProps): react.JSX.Element;
145
+
146
+ /** Filename → language id. Exported: hosts registering an engine reuse it. */
147
+ declare function detectCodeLanguage(fileName: string): string;
148
+ declare function CodeViewer({ source, fileName, className, maxBytes, }: MediaViewerProps): react.JSX.Element;
149
+
150
+ declare function SvgViewer(props: MediaViewerProps): react.JSX.Element;
151
+
152
+ declare function HtmlViewer(props: MediaViewerProps): react.JSX.Element;
153
+
154
+ declare function GenericViewer({ fileName, fileSize, generic, className, }: MediaViewerProps): react.JSX.Element;
155
+
156
+ declare function MediaViewerUnavailable({ kind, ...props }: MediaViewerProps & {
157
+ kind: MediaViewerKind;
158
+ }): react.JSX.Element;
159
+
160
+ /**
161
+ * src/viewers/preview-kind.ts — filename/MIME → viewer kind.
162
+ *
163
+ * The DEFAULT resolution, derived from the package's own file-kind registry
164
+ * (`getFileKindDetails`) so a fresh app gets correct dispatch with zero setup.
165
+ * A host with a richer registry of its own — matrx-frontend's `FILE_TYPES`
166
+ * carries preview/thumbnail/size-cap columns this package deliberately does
167
+ * not absorb (C8) — passes `previewKind` explicitly and this is never called.
168
+ */
169
+
170
+ declare function getPreviewKind(fileName: string, mimeType?: string | null): MediaViewerKind;
171
+
172
+ /**
173
+ * src/viewers/chrome.tsx — the shared viewer chrome.
174
+ *
175
+ * The five absorbed matrx-frontend previewers each hand-rolled the same
176
+ * error card, the same skeleton, and the same copy button. One copy here;
177
+ * one place to make them good.
178
+ */
179
+ /** The uniform loading bar every viewer shows while bytes are in flight. */
180
+ declare function ViewerSkeleton({ className, tone, }: {
181
+ className?: string | undefined;
182
+ tone?: "muted" | "plain" | undefined;
183
+ }): react.JSX.Element;
184
+ /**
185
+ * The honest failure card. It shows the REAL underlying message (HTTP
186
+ * 401/403/404/network) rather than a generic "Preview failed" — the original
187
+ * previewers' deliberate choice, kept: a user who can see the status can act
188
+ * on it, and a support thread starts with a fact instead of a shrug.
189
+ */
190
+ declare function ViewerError({ title, message, hint, className, }: {
191
+ title?: string | undefined;
192
+ message?: string | null | undefined;
193
+ hint?: string | undefined;
194
+ className?: string | undefined;
195
+ }): react.JSX.Element;
196
+ /**
197
+ * Copy-to-clipboard button with the settled-state flip. Swallows the
198
+ * clipboard rejection that non-secure contexts always throw — a failed copy
199
+ * is not an error worth a card, and the un-flipped button IS the signal.
200
+ */
201
+ declare function ViewerCopyButton({ text, className, }: {
202
+ text: string | null;
203
+ className?: string | undefined;
204
+ }): react.JSX.Element;
205
+ /** The strip above a text-shaped viewer: status on the left, copy on the right. */
206
+ declare function ViewerToolbar({ children, className, }: {
207
+ children?: React.ReactNode;
208
+ className?: string | undefined;
209
+ }): react.JSX.Element;
210
+
211
+ /**
212
+ * src/viewers/transparency-grid.ts — the alpha-channel checkerboard.
213
+ *
214
+ * Ships as inline style rather than a utility class: the matrx-frontend
215
+ * originals used two different mechanisms for the same thing (an inline
216
+ * gradient stack in ImagePreview, a `bg-checkerboard` utility in SvgPreview),
217
+ * and a utility class is exactly the kind of host-owned dependency C26 bans a
218
+ * package component from assuming. Sized in CSS pixels so the pattern reads
219
+ * the same at any zoom.
220
+ */
221
+ declare const TRANSPARENCY_GRID_STYLE: {
222
+ backgroundImage: string;
223
+ backgroundSize: string;
224
+ backgroundPosition: string;
225
+ };
226
+
227
+ /**
228
+ * src/viewers/use-viewer-bytes.ts — the ONE byte/text/URL machinery every
229
+ * viewer body shares.
230
+ *
231
+ * Four separate matrx-frontend previewers (Text, Code, the SVG source view,
232
+ * the HTML source view) each carried their own copy of "read the blob, cap it
233
+ * at N bytes, mark it truncated, surface the REAL backend error verbatim,
234
+ * cancel on unmount". Four copies is four places to drift; C22 says that
235
+ * machinery lives in the package exactly once.
236
+ */
237
+
238
+ interface ViewerBytesState {
239
+ blob: Blob | null;
240
+ loading: boolean;
241
+ /** The real underlying message (HTTP 401/403/404/network) — never generic. */
242
+ error: string | null;
243
+ }
244
+ /**
245
+ * Bytes for a viewer source. A `blob` source is already resolved; a `ref`
246
+ * source goes through `MediaClient.getBlob` (which is also what emits the
247
+ * terminal-failure diagnostics — see `useMediaBlob`).
248
+ *
249
+ * `useMediaBlob` is called UNCONDITIONALLY (with `null` for blob sources) so
250
+ * the hook order never changes with the source shape.
251
+ */
252
+ declare function useViewerBytes(source: MediaViewerSource): ViewerBytesState;
253
+ interface ViewerTextState {
254
+ text: string | null;
255
+ loading: boolean;
256
+ error: string | null;
257
+ /** True when the file exceeded `maxBytes` and only the head was read. */
258
+ truncated: boolean;
259
+ }
260
+ /**
261
+ * Bytes → text, capped. The cap is not a nicety: a 500MB log file decoded in
262
+ * full takes the tab down, which is how the original previewers were written
263
+ * and why the cap must travel with the package rather than be re-derived.
264
+ */
265
+ declare function useViewerText(source: MediaViewerSource, maxBytes?: number): ViewerTextState;
266
+ interface ViewerDisplayUrlState {
267
+ /**
268
+ * The URL a media element may bind. Durable by construction: it is either
269
+ * a `MediaClient.resolve()` result or the host's own object URL.
270
+ */
271
+ url: string | null;
272
+ /**
273
+ * Whether the client's ONE retry policy can rescue a load failure. False
274
+ * for object URLs and for resolutions the client marked unrecoverable
275
+ * (foreign links) — a session refresh cannot resurrect someone else's URL.
276
+ */
277
+ recoverable: boolean;
278
+ /** `resolve()` refused the ref — render the honest unavailable state. */
279
+ unavailable: boolean;
280
+ loading: boolean;
281
+ }
282
+ /**
283
+ * The display URL for a viewer source. Law 2: even for a `ref` carrying a
284
+ * caller-supplied URL, resolution goes through the client — the package never
285
+ * trusts a string it was handed.
286
+ */
287
+ declare function useViewerDisplayUrl(source: MediaViewerSource): ViewerDisplayUrlState;
288
+
289
+ export { CodeViewer, GenericViewer, HtmlViewer, type MediaCodeHighlighter, type MediaCodeHighlighterProps, MediaFileViewer, type MediaFileViewerProps, type MediaViewerComponent, type MediaViewerGenericOptions, type MediaViewerKind, type MediaViewerMarkupControls, type MediaViewerMarkupMode, type MediaViewerProps, type MediaViewerSource, MediaViewerUnavailable, type MediaViewerViewport, SvgViewer, TRANSPARENCY_GRID_STYLE, TextViewer, type ViewerBytesState, ViewerCopyButton, type ViewerDisplayUrlState, ViewerError, ViewerSkeleton, type ViewerTextState, ViewerToolbar, detectCodeLanguage, getMediaCodeHighlighter, getMediaViewer, getPreviewKind, registerMediaCodeHighlighter, registerMediaViewer, registeredMediaViewerKinds, useViewerBytes, useViewerDisplayUrl, useViewerText };
@@ -0,0 +1,289 @@
1
+ import * as react from 'react';
2
+ import { MediaRefLike } from './index.js';
3
+
4
+ /**
5
+ * src/viewers/types.ts — the viewer vocabulary.
6
+ *
7
+ * A "viewer" is a full-pane rendering of ONE file: what a file-preview pane,
8
+ * a file tab, or a binary-file fallback in a code editor shows. It is the
9
+ * layer above `/react`'s inline media elements.
10
+ */
11
+
12
+ /**
13
+ * The kinds the dispatcher understands. Ported from the matrx-frontend
14
+ * `PreviewKind` vocabulary so a host registry maps 1:1.
15
+ */
16
+ type MediaViewerKind = "image" | "svg" | "video" | "audio" | "pdf" | "markdown" | "data" | "spreadsheet" | "code" | "office" | "html" | "text" | "generic";
17
+ /**
18
+ * Where the viewer's bytes and display URL come from.
19
+ *
20
+ * - `ref` — the normal lane: identity in, everything through the MediaClient
21
+ * (`resolve()` for the display URL, `getBlob()` for bytes).
22
+ * - `blob` — bytes the host ALREADY has (a code editor that downloaded the
23
+ * file to decide it was binary). No MediaClient round-trip, and the URL is
24
+ * an object URL, so load recovery is off by construction (law 3 is not
25
+ * violated: a `blob:` URL is not a signed URL and never leaves the tab).
26
+ */
27
+ type MediaViewerSource = {
28
+ kind: "ref";
29
+ ref: MediaRefLike;
30
+ } | {
31
+ kind: "blob";
32
+ blob: Blob;
33
+ url: string;
34
+ };
35
+ /** Escape-hatch actions the generic card offers. */
36
+ interface MediaViewerGenericOptions {
37
+ onDownload?: (() => void) | undefined;
38
+ onViewAsText?: (() => void) | undefined;
39
+ viewAsTextLabel?: string | undefined;
40
+ viewAsTextPrimary?: boolean | undefined;
41
+ viewAsTextBusy?: boolean | undefined;
42
+ message?: string | undefined;
43
+ }
44
+ /** Rendered-vs-source mode for the markup viewers (SVG, HTML). */
45
+ type MediaViewerMarkupMode = "rendered" | "source";
46
+ /** Device-width simulation for the HTML viewer. */
47
+ type MediaViewerViewport = "auto" | "mobile" | "tablet" | "desktop";
48
+ /**
49
+ * Optional external control of the markup viewers. When a host mounts its own
50
+ * control rail (matrx-frontend's `FileViewerControlsProvider`), it drives the
51
+ * viewer through these props and the viewer hides its built-in toolbar. When
52
+ * absent, the viewer owns the state and renders its own toolbar — the C23
53
+ * default: capable standalone, steerable when the host has a rail.
54
+ */
55
+ interface MediaViewerMarkupControls {
56
+ mode?: MediaViewerMarkupMode | undefined;
57
+ onModeChange?: ((mode: MediaViewerMarkupMode) => void) | undefined;
58
+ viewport?: MediaViewerViewport | undefined;
59
+ /** Bump to force a clean re-mount of the rendered frame. */
60
+ reloadKey?: number | undefined;
61
+ }
62
+ /** The props EVERY viewer body (built-in or host-registered) receives. */
63
+ interface MediaViewerProps {
64
+ source: MediaViewerSource;
65
+ fileName: string;
66
+ fileSize?: number | null | undefined;
67
+ mimeType?: string | null | undefined;
68
+ className?: string | undefined;
69
+ /** Max bytes read for text-shaped viewers. Defaults to 1MB. */
70
+ maxBytes?: number | undefined;
71
+ /** Controlled 1-based page, for paged engines (PDF). */
72
+ pageNumber?: number | undefined;
73
+ onPageChange?: ((pageNumber: number) => void) | undefined;
74
+ /** Passthroughs for the generic (no-viewer) card. */
75
+ generic?: MediaViewerGenericOptions | undefined;
76
+ /** External control of the markup viewers (SVG / HTML). */
77
+ markupControls?: MediaViewerMarkupControls | undefined;
78
+ }
79
+ /** A viewer body. Structural so a host component satisfies it with no import. */
80
+ type MediaViewerComponent = (props: MediaViewerProps) => unknown;
81
+ /**
82
+ * The code-highlighting seam. A syntax highlighter (Prism, Shiki, Monaco) is
83
+ * a multi-hundred-kilobyte browser-only engine — C8 says a headless consumer
84
+ * must never be forced to carry it, so the package ships the code viewer's
85
+ * CHROME and an honest, capable un-highlighted default, and a host registers
86
+ * the engine. `language` is the package's detected Prism-style language id.
87
+ */
88
+ interface MediaCodeHighlighterProps {
89
+ code: string;
90
+ language: string;
91
+ }
92
+ type MediaCodeHighlighter = (props: MediaCodeHighlighterProps) => unknown;
93
+
94
+ interface MediaFileViewerProps extends MediaViewerProps {
95
+ /**
96
+ * The kind to render. Omit to let the package derive it from the file name
97
+ * and MIME type (`getPreviewKind`).
98
+ */
99
+ previewKind?: MediaViewerKind | undefined;
100
+ }
101
+ declare function MediaFileViewer({ previewKind, ...props }: MediaFileViewerProps): react.JSX.Element;
102
+
103
+ /**
104
+ * src/viewers/registry.ts — the heavy-engine seam.
105
+ *
106
+ * The package ships working bodies for every viewer kind it can render with
107
+ * DOM primitives alone (text, code chrome, svg, html, generic). The kinds
108
+ * whose rendering IS a multi-megabyte browser-only engine — PDF.js, a
109
+ * Markdown/KaTeX stack, SheetJS, a server-side Office extractor — ride this
110
+ * seam instead (C8 + the diff-package Monaco precedent): a host registers the
111
+ * engine once, and until it does, the dispatcher renders an ANNOUNCING
112
+ * default that names the missing engine and still offers download/open. A
113
+ * dead pane is never an outcome.
114
+ *
115
+ * MODULE-LEVEL MUTABLE STATE IS BANNED (the dual ESM/CJS bundle rule): with
116
+ * `splitting: false` and two formats, each loader graph instantiates its own
117
+ * copy of this module, so a plain module-scope Map would silently split the
118
+ * registry — a host registering through the CJS graph would be invisible to a
119
+ * component rendered from the ESM graph. The maps therefore live on
120
+ * `globalThis` under `Symbol.for` slots, and the tarball canary proves a
121
+ * registration made in one graph is visible from the other.
122
+ */
123
+
124
+ /**
125
+ * Register the viewer body for a kind. Registering a kind the package already
126
+ * renders REPLACES the built-in — that is the sanctioned host override (a
127
+ * feature-specific domain viewer implementing the same contract).
128
+ *
129
+ * Returns an unregister function so a test or a hot-reloading host can undo it.
130
+ */
131
+ declare function registerMediaViewer(kind: MediaViewerKind, viewer: MediaViewerComponent): () => void;
132
+ /** The registered viewer for a kind, or `null` when nothing is registered. */
133
+ declare function getMediaViewer(kind: MediaViewerKind): MediaViewerComponent | null;
134
+ /** Every kind a host has registered — for diagnostics and tests. */
135
+ declare function registeredMediaViewerKinds(): MediaViewerKind[];
136
+ /**
137
+ * Register the syntax-highlighting engine for the built-in code viewer.
138
+ * Without one the code viewer still renders — monospace, line-numbered,
139
+ * copyable, truncation-honest — it simply is not colored.
140
+ */
141
+ declare function registerMediaCodeHighlighter(highlighter: MediaCodeHighlighter): () => void;
142
+ declare function getMediaCodeHighlighter(): MediaCodeHighlighter | null;
143
+
144
+ declare function TextViewer({ source, className, maxBytes, }: MediaViewerProps): react.JSX.Element;
145
+
146
+ /** Filename → language id. Exported: hosts registering an engine reuse it. */
147
+ declare function detectCodeLanguage(fileName: string): string;
148
+ declare function CodeViewer({ source, fileName, className, maxBytes, }: MediaViewerProps): react.JSX.Element;
149
+
150
+ declare function SvgViewer(props: MediaViewerProps): react.JSX.Element;
151
+
152
+ declare function HtmlViewer(props: MediaViewerProps): react.JSX.Element;
153
+
154
+ declare function GenericViewer({ fileName, fileSize, generic, className, }: MediaViewerProps): react.JSX.Element;
155
+
156
+ declare function MediaViewerUnavailable({ kind, ...props }: MediaViewerProps & {
157
+ kind: MediaViewerKind;
158
+ }): react.JSX.Element;
159
+
160
+ /**
161
+ * src/viewers/preview-kind.ts — filename/MIME → viewer kind.
162
+ *
163
+ * The DEFAULT resolution, derived from the package's own file-kind registry
164
+ * (`getFileKindDetails`) so a fresh app gets correct dispatch with zero setup.
165
+ * A host with a richer registry of its own — matrx-frontend's `FILE_TYPES`
166
+ * carries preview/thumbnail/size-cap columns this package deliberately does
167
+ * not absorb (C8) — passes `previewKind` explicitly and this is never called.
168
+ */
169
+
170
+ declare function getPreviewKind(fileName: string, mimeType?: string | null): MediaViewerKind;
171
+
172
+ /**
173
+ * src/viewers/chrome.tsx — the shared viewer chrome.
174
+ *
175
+ * The five absorbed matrx-frontend previewers each hand-rolled the same
176
+ * error card, the same skeleton, and the same copy button. One copy here;
177
+ * one place to make them good.
178
+ */
179
+ /** The uniform loading bar every viewer shows while bytes are in flight. */
180
+ declare function ViewerSkeleton({ className, tone, }: {
181
+ className?: string | undefined;
182
+ tone?: "muted" | "plain" | undefined;
183
+ }): react.JSX.Element;
184
+ /**
185
+ * The honest failure card. It shows the REAL underlying message (HTTP
186
+ * 401/403/404/network) rather than a generic "Preview failed" — the original
187
+ * previewers' deliberate choice, kept: a user who can see the status can act
188
+ * on it, and a support thread starts with a fact instead of a shrug.
189
+ */
190
+ declare function ViewerError({ title, message, hint, className, }: {
191
+ title?: string | undefined;
192
+ message?: string | null | undefined;
193
+ hint?: string | undefined;
194
+ className?: string | undefined;
195
+ }): react.JSX.Element;
196
+ /**
197
+ * Copy-to-clipboard button with the settled-state flip. Swallows the
198
+ * clipboard rejection that non-secure contexts always throw — a failed copy
199
+ * is not an error worth a card, and the un-flipped button IS the signal.
200
+ */
201
+ declare function ViewerCopyButton({ text, className, }: {
202
+ text: string | null;
203
+ className?: string | undefined;
204
+ }): react.JSX.Element;
205
+ /** The strip above a text-shaped viewer: status on the left, copy on the right. */
206
+ declare function ViewerToolbar({ children, className, }: {
207
+ children?: React.ReactNode;
208
+ className?: string | undefined;
209
+ }): react.JSX.Element;
210
+
211
+ /**
212
+ * src/viewers/transparency-grid.ts — the alpha-channel checkerboard.
213
+ *
214
+ * Ships as inline style rather than a utility class: the matrx-frontend
215
+ * originals used two different mechanisms for the same thing (an inline
216
+ * gradient stack in ImagePreview, a `bg-checkerboard` utility in SvgPreview),
217
+ * and a utility class is exactly the kind of host-owned dependency C26 bans a
218
+ * package component from assuming. Sized in CSS pixels so the pattern reads
219
+ * the same at any zoom.
220
+ */
221
+ declare const TRANSPARENCY_GRID_STYLE: {
222
+ backgroundImage: string;
223
+ backgroundSize: string;
224
+ backgroundPosition: string;
225
+ };
226
+
227
+ /**
228
+ * src/viewers/use-viewer-bytes.ts — the ONE byte/text/URL machinery every
229
+ * viewer body shares.
230
+ *
231
+ * Four separate matrx-frontend previewers (Text, Code, the SVG source view,
232
+ * the HTML source view) each carried their own copy of "read the blob, cap it
233
+ * at N bytes, mark it truncated, surface the REAL backend error verbatim,
234
+ * cancel on unmount". Four copies is four places to drift; C22 says that
235
+ * machinery lives in the package exactly once.
236
+ */
237
+
238
+ interface ViewerBytesState {
239
+ blob: Blob | null;
240
+ loading: boolean;
241
+ /** The real underlying message (HTTP 401/403/404/network) — never generic. */
242
+ error: string | null;
243
+ }
244
+ /**
245
+ * Bytes for a viewer source. A `blob` source is already resolved; a `ref`
246
+ * source goes through `MediaClient.getBlob` (which is also what emits the
247
+ * terminal-failure diagnostics — see `useMediaBlob`).
248
+ *
249
+ * `useMediaBlob` is called UNCONDITIONALLY (with `null` for blob sources) so
250
+ * the hook order never changes with the source shape.
251
+ */
252
+ declare function useViewerBytes(source: MediaViewerSource): ViewerBytesState;
253
+ interface ViewerTextState {
254
+ text: string | null;
255
+ loading: boolean;
256
+ error: string | null;
257
+ /** True when the file exceeded `maxBytes` and only the head was read. */
258
+ truncated: boolean;
259
+ }
260
+ /**
261
+ * Bytes → text, capped. The cap is not a nicety: a 500MB log file decoded in
262
+ * full takes the tab down, which is how the original previewers were written
263
+ * and why the cap must travel with the package rather than be re-derived.
264
+ */
265
+ declare function useViewerText(source: MediaViewerSource, maxBytes?: number): ViewerTextState;
266
+ interface ViewerDisplayUrlState {
267
+ /**
268
+ * The URL a media element may bind. Durable by construction: it is either
269
+ * a `MediaClient.resolve()` result or the host's own object URL.
270
+ */
271
+ url: string | null;
272
+ /**
273
+ * Whether the client's ONE retry policy can rescue a load failure. False
274
+ * for object URLs and for resolutions the client marked unrecoverable
275
+ * (foreign links) — a session refresh cannot resurrect someone else's URL.
276
+ */
277
+ recoverable: boolean;
278
+ /** `resolve()` refused the ref — render the honest unavailable state. */
279
+ unavailable: boolean;
280
+ loading: boolean;
281
+ }
282
+ /**
283
+ * The display URL for a viewer source. Law 2: even for a `ref` carrying a
284
+ * caller-supplied URL, resolution goes through the client — the package never
285
+ * trusts a string it was handed.
286
+ */
287
+ declare function useViewerDisplayUrl(source: MediaViewerSource): ViewerDisplayUrlState;
288
+
289
+ export { CodeViewer, GenericViewer, HtmlViewer, type MediaCodeHighlighter, type MediaCodeHighlighterProps, MediaFileViewer, type MediaFileViewerProps, type MediaViewerComponent, type MediaViewerGenericOptions, type MediaViewerKind, type MediaViewerMarkupControls, type MediaViewerMarkupMode, type MediaViewerProps, type MediaViewerSource, MediaViewerUnavailable, type MediaViewerViewport, SvgViewer, TRANSPARENCY_GRID_STYLE, TextViewer, type ViewerBytesState, ViewerCopyButton, type ViewerDisplayUrlState, ViewerError, ViewerSkeleton, type ViewerTextState, ViewerToolbar, detectCodeLanguage, getMediaCodeHighlighter, getMediaViewer, getPreviewKind, registerMediaCodeHighlighter, registerMediaViewer, registeredMediaViewerKinds, useViewerBytes, useViewerDisplayUrl, useViewerText };