@orz/ui-content 0.0.0-stage → 0.0.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/LICENSE +29 -0
- package/README.md +410 -2
- package/dist/attachment/card-content.d.ts +26 -0
- package/dist/attachment/card-content.d.ts.map +1 -0
- package/dist/attachment/card-content.js +49 -0
- package/dist/attachment/card-content.js.map +1 -0
- package/dist/attachment/deleted.d.ts +9 -0
- package/dist/attachment/deleted.d.ts.map +1 -0
- package/dist/attachment/deleted.js +11 -0
- package/dist/attachment/deleted.js.map +1 -0
- package/dist/attachment/document-card.d.ts +32 -0
- package/dist/attachment/document-card.d.ts.map +1 -0
- package/dist/attachment/document-card.js +38 -0
- package/dist/attachment/document-card.js.map +1 -0
- package/dist/attachment/icon.d.ts +13 -0
- package/dist/attachment/icon.d.ts.map +1 -0
- package/dist/attachment/icon.js +34 -0
- package/dist/attachment/icon.js.map +1 -0
- package/dist/attachment/image-canvas.d.ts +25 -0
- package/dist/attachment/image-canvas.d.ts.map +1 -0
- package/dist/attachment/image-canvas.js +301 -0
- package/dist/attachment/image-canvas.js.map +1 -0
- package/dist/attachment/image-look.d.ts +18 -0
- package/dist/attachment/image-look.d.ts.map +1 -0
- package/dist/attachment/image-look.js +86 -0
- package/dist/attachment/image-look.js.map +1 -0
- package/dist/attachment/image-zoom.d.ts +67 -0
- package/dist/attachment/image-zoom.d.ts.map +1 -0
- package/dist/attachment/image-zoom.js +108 -0
- package/dist/attachment/image-zoom.js.map +1 -0
- package/dist/attachment/index.d.ts +12 -0
- package/dist/attachment/index.d.ts.map +1 -0
- package/dist/attachment/index.js +12 -0
- package/dist/attachment/index.js.map +1 -0
- package/dist/attachment/link.d.ts +18 -0
- package/dist/attachment/link.d.ts.map +1 -0
- package/dist/attachment/link.js +30 -0
- package/dist/attachment/link.js.map +1 -0
- package/dist/attachment/list.d.ts +26 -0
- package/dist/attachment/list.d.ts.map +1 -0
- package/dist/attachment/list.js +53 -0
- package/dist/attachment/list.js.map +1 -0
- package/dist/attachment/media-content.d.ts +21 -0
- package/dist/attachment/media-content.d.ts.map +1 -0
- package/dist/attachment/media-content.js +133 -0
- package/dist/attachment/media-content.js.map +1 -0
- package/dist/attachment/media-player.d.ts +23 -0
- package/dist/attachment/media-player.d.ts.map +1 -0
- package/dist/attachment/media-player.js +137 -0
- package/dist/attachment/media-player.js.map +1 -0
- package/dist/attachment/use-media.d.ts +27 -0
- package/dist/attachment/use-media.d.ts.map +1 -0
- package/dist/attachment/use-media.js +133 -0
- package/dist/attachment/use-media.js.map +1 -0
- package/dist/attachment/viewer.d.ts +85 -0
- package/dist/attachment/viewer.d.ts.map +1 -0
- package/dist/attachment/viewer.js +245 -0
- package/dist/attachment/viewer.js.map +1 -0
- package/dist/file-kind.d.ts +61 -0
- package/dist/file-kind.d.ts.map +1 -0
- package/dist/file-kind.js +166 -0
- package/dist/file-kind.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/registry.d.ts +44 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +109 -0
- package/dist/registry.js.map +1 -0
- package/dist/source-text.d.ts +29 -0
- package/dist/source-text.d.ts.map +1 -0
- package/dist/source-text.js +101 -0
- package/dist/source-text.js.map +1 -0
- package/dist/title-bar.d.ts +23 -0
- package/dist/title-bar.d.ts.map +1 -0
- package/dist/title-bar.js +24 -0
- package/dist/title-bar.js.map +1 -0
- package/dist/types.d.ts +48 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +55 -3
- package/styles.css +4 -0
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Button } from "@orz/ui/components/button";
|
|
3
|
+
import { Dialog, DialogCloseButton, DialogContent, DialogTitle, } from "@orz/ui/components/dialog";
|
|
4
|
+
import { cn } from "@orz/ui/lib/utils";
|
|
5
|
+
import { ChevronLeftIcon, ChevronRightIcon, DownloadIcon, ExternalLinkIcon, FileIcon, MaximizeIcon, MinimizeIcon, } from "lucide-react";
|
|
6
|
+
import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, } from "react";
|
|
7
|
+
import { formatSize, isHtmlFile, isImageFile, isTextFile, TEXT_PREVIEW_HARD_MAX_BYTES, TEXT_PREVIEW_MAX_BYTES, textPreviewGate, } from "../file-kind.js";
|
|
8
|
+
import { Content, useContentDisplay } from "../registry.js";
|
|
9
|
+
import { ContentTitleBar } from "../title-bar.js";
|
|
10
|
+
import { DEFAULT_IMAGE_LOOK } from "./image-look.js";
|
|
11
|
+
// Long enough to cover a pointer crossing the image between two controls,
|
|
12
|
+
// short enough that leaving for good does not read as the viewer lagging.
|
|
13
|
+
const RELEASE_DELAY = 400;
|
|
14
|
+
const RELEASE_NOW = ["keydown", "pointerdown", "wheel"];
|
|
15
|
+
const AttachmentViewerContext = createContext(null);
|
|
16
|
+
const ViewerImageContext = createContext(null);
|
|
17
|
+
/** What the image renderer needs from the viewer around it; null outside one. */
|
|
18
|
+
export function useViewerImage() {
|
|
19
|
+
return useContext(ViewerImageContext);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Owns one viewer dialog for everything below it: link chips, inline images,
|
|
23
|
+
* list rows and document cards all open this one rather than mounting a
|
|
24
|
+
* dialog each. A nested provider shadows the outer one.
|
|
25
|
+
*/
|
|
26
|
+
export function AttachmentViewerProvider({ viewHref, group, textPreviewMaxBytes = TEXT_PREVIEW_MAX_BYTES, textPreviewHardMaxBytes = TEXT_PREVIEW_HARD_MAX_BYTES, imageLook, onImageLookChange, children, }) {
|
|
27
|
+
const [state, setState] = useState(null);
|
|
28
|
+
// Read at click time, so an inline `group` does not change `show` and
|
|
29
|
+
// re-render every chip that holds it.
|
|
30
|
+
const groupRef = useRef(group);
|
|
31
|
+
groupRef.current = group;
|
|
32
|
+
const open = useCallback((items, index) => setState({ items, index }), []);
|
|
33
|
+
const show = useCallback((file) => setState(groupRef.current?.(file) ?? { items: [file], index: 0 }), []);
|
|
34
|
+
const value = useMemo(() => ({
|
|
35
|
+
open,
|
|
36
|
+
show,
|
|
37
|
+
viewHref,
|
|
38
|
+
textPreviewMaxBytes,
|
|
39
|
+
textPreviewHardMaxBytes,
|
|
40
|
+
}), [open, show, viewHref, textPreviewMaxBytes, textPreviewHardMaxBytes]);
|
|
41
|
+
return (_jsxs(AttachmentViewerContext.Provider, { value: value, children: [children, _jsx(AttachmentViewer, { state: state, onNavigate: (index) => setState((prev) => (prev === null ? prev : { ...prev, index })), onClose: () => setState(null), imageLook: imageLook, onImageLookChange: onImageLookChange })] }));
|
|
42
|
+
}
|
|
43
|
+
/** The nearest provider's controls, or null outside one. */
|
|
44
|
+
export function useAttachmentViewer() {
|
|
45
|
+
return useContext(AttachmentViewerContext);
|
|
46
|
+
}
|
|
47
|
+
/** Where an anchor to this file points: the provider's `viewHref`, else the file's `url`. */
|
|
48
|
+
export function useViewHref(file) {
|
|
49
|
+
const viewer = useContext(AttachmentViewerContext);
|
|
50
|
+
return viewer?.viewHref?.(file) ?? file.url ?? "";
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Whether the viewer has something to draw for this file, which is what
|
|
54
|
+
* decides if a plain click on it is hijacked into the viewer. Text needs a
|
|
55
|
+
* known size — a file whose size the app does not know yet stays a link
|
|
56
|
+
* until it does; a size past the limits still opens the viewer, which says
|
|
57
|
+
* why it shows nothing. HTML has no size cap: the browser streams it into
|
|
58
|
+
* the iframe instead of this tab highlighting it.
|
|
59
|
+
*/
|
|
60
|
+
export function useCanPreview(file) {
|
|
61
|
+
const display = useContentDisplay(file, "viewer");
|
|
62
|
+
if (display === null)
|
|
63
|
+
return false;
|
|
64
|
+
if (isTextFile(file) && !isHtmlFile(file))
|
|
65
|
+
return file.size !== undefined;
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
function useGate(file) {
|
|
69
|
+
const viewer = useContext(AttachmentViewerContext);
|
|
70
|
+
if (!isTextFile(file) || isHtmlFile(file) || file.size === undefined) {
|
|
71
|
+
return "auto";
|
|
72
|
+
}
|
|
73
|
+
return textPreviewGate({ ...file, size: file.size }, {
|
|
74
|
+
max: viewer?.textPreviewMaxBytes,
|
|
75
|
+
hardMax: viewer?.textPreviewHardMaxBytes,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* A text file past the auto-preview size waits to be asked, and is then
|
|
80
|
+
* drawn: the code renderer draws text that large plain. Past the hard limit
|
|
81
|
+
* it never previews.
|
|
82
|
+
*/
|
|
83
|
+
function LargeTextPane({ gate, onPreview, }) {
|
|
84
|
+
const viewer = useContext(AttachmentViewerContext);
|
|
85
|
+
const hardMax = viewer?.textPreviewHardMaxBytes ?? TEXT_PREVIEW_HARD_MAX_BYTES;
|
|
86
|
+
return (_jsxs("div", { className: "flex flex-col items-center gap-3 py-16 text-sm text-muted-foreground", children: [_jsx(FileIcon, { className: "size-8" }), gate === "refuse" ? (_jsxs(_Fragment, { children: [_jsx("span", { className: "font-medium text-foreground", children: "This file is too large to preview." }), _jsxs("span", { children: ["Previews stop at ", formatSize(hardMax), "."] })] })) : (_jsxs(_Fragment, { children: [_jsx("span", { className: "font-medium text-foreground", children: "Large files aren't previewed automatically." }), _jsx(Button, { variant: "outline", size: "sm", onClick: onPreview, children: "Preview anyway" })] }))] }));
|
|
87
|
+
}
|
|
88
|
+
/** Paging can land on types that only download — say so instead of a blank pane. */
|
|
89
|
+
function DownloadOnlyPane({ file }) {
|
|
90
|
+
return (_jsxs("div", { className: "flex flex-col items-center gap-2 py-16 text-sm text-muted-foreground", children: [_jsx(FileIcon, { className: "size-8" }), _jsx("span", { className: "font-medium text-foreground", children: file.name }), _jsx("span", { children: "No inline preview for this file type." }), file.url !== undefined && (_jsxs("a", { href: file.url, download: file.name, className: "inline-flex items-center gap-1 font-medium text-foreground hover:underline", children: [_jsx(DownloadIcon, { className: "size-3.5" }), "Download"] }))] }));
|
|
91
|
+
}
|
|
92
|
+
function ViewerBody({ file, maximized, titleBar, }) {
|
|
93
|
+
const canPreview = useCanPreview(file);
|
|
94
|
+
const gate = useGate(file);
|
|
95
|
+
// For this opening only: the body is keyed by file.
|
|
96
|
+
const [asked, setAsked] = useState(false);
|
|
97
|
+
return (_jsx("div", { className: cn("min-h-0 overflow-auto", maximized ? "flex-1" : "max-h-[75vh]"),
|
|
98
|
+
// A renderer in "viewer" placement no longer knows the pane it is drawn
|
|
99
|
+
// in, so the pane hands down the height it may fill.
|
|
100
|
+
style: {
|
|
101
|
+
"--attachment-pane-height": maximized ? "100%" : "75vh",
|
|
102
|
+
}, children: !canPreview ? (_jsx(DownloadOnlyPane, { file: file })) : gate === "refuse" || (gate === "ask" && !asked) ? (_jsx(LargeTextPane, { gate: gate, onPreview: () => setAsked(true) })) : (_jsx(ContentTitleBar, { source: file, target: titleBar, children: _jsx(Content, { source: file, placement: "viewer" }) })) }));
|
|
103
|
+
}
|
|
104
|
+
function ViewerFooter({ file }) {
|
|
105
|
+
const viewer = useContext(AttachmentViewerContext);
|
|
106
|
+
const tab = viewer?.viewHref?.(file);
|
|
107
|
+
return (_jsxs("div", { className: "flex items-center justify-between gap-3 text-xs text-muted-foreground", children: [_jsx("span", { className: "truncate", children: [
|
|
108
|
+
file.mime,
|
|
109
|
+
file.size !== undefined ? formatSize(file.size) : undefined,
|
|
110
|
+
]
|
|
111
|
+
.filter(Boolean)
|
|
112
|
+
.join(" · ") }), _jsxs("span", { className: "flex shrink-0 items-center gap-3", children: [tab !== undefined && (_jsxs("a", { href: tab, target: "_blank", rel: "noopener noreferrer", className: "inline-flex items-center gap-1 font-medium hover:underline", children: [_jsx(ExternalLinkIcon, { className: "size-3.5" }), "Open in new tab"] })), file.url !== undefined && (_jsxs("a", { href: file.url, download: file.name, className: "inline-flex items-center gap-1 font-medium hover:underline", children: [_jsx(DownloadIcon, { className: "size-3.5" }), "Download"] }))] })] }));
|
|
113
|
+
}
|
|
114
|
+
function keepsArrowKeys(target) {
|
|
115
|
+
return (target instanceof HTMLElement &&
|
|
116
|
+
(target.isContentEditable ||
|
|
117
|
+
target.closest("input, textarea, select, video, audio") !== null));
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* The viewer dialog, controlled: one file at a time drawn by the registry in
|
|
121
|
+
* "viewer" placement, or a download pane when nothing can draw it. A set
|
|
122
|
+
* pages with ‹ › / arrow keys, and the controls live in the title bar, never
|
|
123
|
+
* floated over the content.
|
|
124
|
+
*/
|
|
125
|
+
export function AttachmentViewer({ state, onNavigate, onClose, imageLook, onImageLookChange, }) {
|
|
126
|
+
// "Maximize" fills the browser window without entering system fullscreen;
|
|
127
|
+
// the dialog stays a modal.
|
|
128
|
+
const [maximized, setMaximized] = useState(false);
|
|
129
|
+
const [titleBar, setTitleBar] = useState(null);
|
|
130
|
+
// Held here rather than in the image, so paging and reopening keep it.
|
|
131
|
+
const [ownLook, setOwnLook] = useState(DEFAULT_IMAGE_LOOK);
|
|
132
|
+
const look = imageLook ?? ownLook;
|
|
133
|
+
const lastHeight = useRef(null);
|
|
134
|
+
const file = state?.items[state.index];
|
|
135
|
+
const count = state?.items.length ?? 0;
|
|
136
|
+
const isImage = file !== undefined && isImageFile(file);
|
|
137
|
+
// Paging between images tweens from one's height to the next; from
|
|
138
|
+
// anything else, including a closed viewer, the image lands at once.
|
|
139
|
+
useEffect(() => {
|
|
140
|
+
if (!isImage)
|
|
141
|
+
lastHeight.current = null;
|
|
142
|
+
}, [isImage]);
|
|
143
|
+
// While the pointer is over − 100%▾ + or ‹ ›, the image keeps the height
|
|
144
|
+
// it had when the pointer arrived, and takes its own once the pointer
|
|
145
|
+
// leaves: the dialog is centred, so a height change slides the title bar
|
|
146
|
+
// out from under the pointer, and the next click on + lands on the image
|
|
147
|
+
// and toggles back to fit, or the next click on › misses. One region for
|
|
148
|
+
// both groups, so crossing the gap between them is not a leave. Listened
|
|
149
|
+
// to on the DOM rather than through React: the zoom controls are
|
|
150
|
+
// portalled in by the image renderer, so in React's tree they sit outside
|
|
151
|
+
// this region, while the zoom menu's items, portalled out to the body, sit
|
|
152
|
+
// inside it — and choosing Fit or 100% there should not be held. Leaving
|
|
153
|
+
// lets go only after RELEASE_DELAY, so a trip from one control to another
|
|
154
|
+
// the long way round, over the image, is not a leave either; a key, a
|
|
155
|
+
// press or a wheel in the meantime lets go at once, since the pointer is
|
|
156
|
+
// no longer travelling.
|
|
157
|
+
const [holdRegion, setHoldRegion] = useState(null);
|
|
158
|
+
const [held, setHeld] = useState(null);
|
|
159
|
+
useEffect(() => {
|
|
160
|
+
if (holdRegion === null)
|
|
161
|
+
return;
|
|
162
|
+
let pending;
|
|
163
|
+
const cancel = () => {
|
|
164
|
+
window.clearTimeout(pending);
|
|
165
|
+
pending = undefined;
|
|
166
|
+
for (const type of RELEASE_NOW)
|
|
167
|
+
window.removeEventListener(type, release, true);
|
|
168
|
+
};
|
|
169
|
+
const release = () => {
|
|
170
|
+
cancel();
|
|
171
|
+
setHeld(null);
|
|
172
|
+
};
|
|
173
|
+
const enter = (e) => {
|
|
174
|
+
if (e.pointerType !== "mouse")
|
|
175
|
+
return;
|
|
176
|
+
if (pending !== undefined)
|
|
177
|
+
cancel();
|
|
178
|
+
else
|
|
179
|
+
setHeld(lastHeight.current);
|
|
180
|
+
};
|
|
181
|
+
const leave = (e) => {
|
|
182
|
+
if (e.pointerType !== "mouse" || pending !== undefined)
|
|
183
|
+
return;
|
|
184
|
+
pending = window.setTimeout(release, RELEASE_DELAY);
|
|
185
|
+
for (const type of RELEASE_NOW)
|
|
186
|
+
window.addEventListener(type, release, {
|
|
187
|
+
capture: true,
|
|
188
|
+
passive: true,
|
|
189
|
+
});
|
|
190
|
+
};
|
|
191
|
+
holdRegion.addEventListener("pointerenter", enter);
|
|
192
|
+
holdRegion.addEventListener("pointerleave", leave);
|
|
193
|
+
return () => {
|
|
194
|
+
cancel();
|
|
195
|
+
holdRegion.removeEventListener("pointerenter", enter);
|
|
196
|
+
holdRegion.removeEventListener("pointerleave", leave);
|
|
197
|
+
};
|
|
198
|
+
}, [holdRegion]);
|
|
199
|
+
// Closing unmounts the region under the pointer, which never reports
|
|
200
|
+
// leaving it.
|
|
201
|
+
const open = file !== undefined;
|
|
202
|
+
useEffect(() => {
|
|
203
|
+
if (!open)
|
|
204
|
+
setHeld(null);
|
|
205
|
+
}, [open]);
|
|
206
|
+
const image = useMemo(() => ({
|
|
207
|
+
maximized,
|
|
208
|
+
look,
|
|
209
|
+
setLook: (next) => {
|
|
210
|
+
if (imageLook === undefined)
|
|
211
|
+
setOwnLook(next);
|
|
212
|
+
onImageLookChange?.(next);
|
|
213
|
+
},
|
|
214
|
+
lastHeight,
|
|
215
|
+
held,
|
|
216
|
+
}), [maximized, look, imageLook, onImageLookChange, held]);
|
|
217
|
+
const step = (delta) => {
|
|
218
|
+
if (state === null || count < 2)
|
|
219
|
+
return;
|
|
220
|
+
onNavigate((state.index + delta + count) % count);
|
|
221
|
+
};
|
|
222
|
+
return (_jsx(Dialog, { open: open, onOpenChange: (open) => {
|
|
223
|
+
if (!open)
|
|
224
|
+
onClose();
|
|
225
|
+
}, children: _jsx(DialogContent, { "aria-describedby": undefined, showCloseButton: false, onKeyDown: (e) => {
|
|
226
|
+
// A focused video seeks, and a field moves its caret, on the same
|
|
227
|
+
// keys: those belong to whatever the body drew.
|
|
228
|
+
if (e.defaultPrevented || keepsArrowKeys(e.target))
|
|
229
|
+
return;
|
|
230
|
+
if (e.key === "ArrowLeft")
|
|
231
|
+
step(-1);
|
|
232
|
+
if (e.key === "ArrowRight")
|
|
233
|
+
step(1);
|
|
234
|
+
}, className: cn("flex flex-col bg-background",
|
|
235
|
+
// Maximized: fill the viewport (clearing the centering translate)
|
|
236
|
+
// but stay a modal — Esc still closes it. sm:max-w-none is needed
|
|
237
|
+
// to beat the dialog's built-in sm:max-w-sm cap.
|
|
238
|
+
maximized
|
|
239
|
+
? "top-0 left-0 h-full w-full max-w-none translate-x-0 translate-y-0 rounded-none sm:max-w-none"
|
|
240
|
+
: "sm:max-w-5xl"), children: file && (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-center gap-1", children: [_jsx(DialogTitle, { className: "min-w-0 flex-1 truncate", children: file.name }), _jsxs("span", { ref: setHoldRegion,
|
|
241
|
+
// Alone, the renderer's controls need no box; an empty one
|
|
242
|
+
// would add a gap beside a lone file that shows none.
|
|
243
|
+
className: cn("items-center gap-1", count > 1 ? "flex" : "contents"), children: [_jsx("span", { ref: setTitleBar, className: "contents" }), count > 1 && (_jsxs(_Fragment, { children: [_jsx(Button, { variant: "ghost", size: "icon-sm", "aria-label": "previous attachment", onClick: () => step(-1), children: _jsx(ChevronLeftIcon, {}) }), _jsxs("span", { className: "text-xs whitespace-nowrap text-muted-foreground tabular-nums", children: [(state?.index ?? 0) + 1, " / ", count] }), _jsx(Button, { variant: "ghost", size: "icon-sm", "aria-label": "next attachment", onClick: () => step(1), children: _jsx(ChevronRightIcon, {}) })] }))] }), _jsx(Button, { variant: "ghost", size: "icon-sm", "aria-label": maximized ? "restore size" : "maximize", onClick: () => setMaximized((m) => !m), children: maximized ? _jsx(MinimizeIcon, {}) : _jsx(MaximizeIcon, {}) }), _jsx(DialogCloseButton, {})] }), _jsx(ViewerImageContext.Provider, { value: image, children: _jsx(ViewerBody, { file: file, maximized: maximized, titleBar: titleBar }, `${state?.index}:${file.url ?? file.name}`) }), _jsx(ViewerFooter, { file: file })] })) }) }));
|
|
244
|
+
}
|
|
245
|
+
//# sourceMappingURL=viewer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viewer.js","sourceRoot":"","sources":["../../src/attachment/viewer.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What kind of file a source is. Pure module (no React) so every renderer's `accepts` shares one
|
|
3
|
+
* answer — `hasGenericType`, "a declared content type outranks the filename", is the rule a second
|
|
4
|
+
* copy elsewhere would fork.
|
|
5
|
+
*/
|
|
6
|
+
/** Spelled as a file `ContentSource` spells it, so one passes straight in. */
|
|
7
|
+
export type FileLike = {
|
|
8
|
+
name: string;
|
|
9
|
+
mime?: string;
|
|
10
|
+
};
|
|
11
|
+
export declare function isImageFile(file: FileLike): boolean;
|
|
12
|
+
/** Text by declared type, or by filename when the type is generic. */
|
|
13
|
+
export declare function isTextFile(file: FileLike): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Files whose image-syntax reference embeds a document card rather than an
|
|
16
|
+
* `<img>`. Images keep winning ties like .svg, which is both.
|
|
17
|
+
*/
|
|
18
|
+
export declare function isTextEmbed(file: FileLike): boolean;
|
|
19
|
+
export declare function isMarkdownFile(file: FileLike): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* A unified diff, by declared type, or by filename when the type is generic: a `.patch` someone
|
|
22
|
+
* uploaded as text/plain keeps the plain text view it asked for.
|
|
23
|
+
*/
|
|
24
|
+
export declare function isPatchFile(file: FileLike): boolean;
|
|
25
|
+
export declare function isHtmlFile(file: FileLike): boolean;
|
|
26
|
+
/** PDF by declared type, or by filename when the type is generic. */
|
|
27
|
+
export declare function isPdfFile(file: FileLike): boolean;
|
|
28
|
+
/** Archive by declared type, or by filename when the type is generic. */
|
|
29
|
+
export declare function isArchiveFile(file: FileLike): boolean;
|
|
30
|
+
/** Audio by declared type, or by filename when the type is generic. */
|
|
31
|
+
export declare function isAudioFile(file: FileLike): boolean;
|
|
32
|
+
/** Video by declared type, or by filename when the type is generic. */
|
|
33
|
+
export declare function isVideoFile(file: FileLike): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Highlighting a multi-megabyte file would freeze the tab (T-31), so bigger
|
|
36
|
+
* text files only preview when asked, and then as plain text.
|
|
37
|
+
*/
|
|
38
|
+
export declare const TEXT_PREVIEW_MAX_BYTES: number;
|
|
39
|
+
/**
|
|
40
|
+
* Past this nothing previews. Measured in Chromium under load: plain text at
|
|
41
|
+
* 10 MiB blocked the tab for 1.5 s in its longest task, at 20 MiB for 2.9 s,
|
|
42
|
+
* at 50 MiB for 6.9 s.
|
|
43
|
+
*/
|
|
44
|
+
export declare const TEXT_PREVIEW_HARD_MAX_BYTES: number;
|
|
45
|
+
export type TextPreviewLimits = {
|
|
46
|
+
/** Previews on its own up to this. Default `TEXT_PREVIEW_MAX_BYTES`. */
|
|
47
|
+
max?: number;
|
|
48
|
+
/** Never previews past this. Default `TEXT_PREVIEW_HARD_MAX_BYTES`. */
|
|
49
|
+
hardMax?: number;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Whether a text file of this size previews on its own, waits to be asked,
|
|
53
|
+
* or never previews. A patch skips the asking: its view is virtualized per
|
|
54
|
+
* file, and a 20 MiB one blocked the tab for 0.6 s at most where the code
|
|
55
|
+
* view took 10 s or more over 1 MiB of highlighted text.
|
|
56
|
+
*/
|
|
57
|
+
export declare function textPreviewGate(file: FileLike & {
|
|
58
|
+
size: number;
|
|
59
|
+
}, { max, hardMax, }?: TextPreviewLimits): "auto" | "ask" | "refuse";
|
|
60
|
+
export declare function formatSize(bytes: number): string;
|
|
61
|
+
//# sourceMappingURL=file-kind.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-kind.d.ts","sourceRoot":"","sources":["../src/file-kind.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,8EAA8E;AAC9E,MAAM,MAAM,QAAQ,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAmCvD,wBAAgB,WAAW,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAMnD;AAED,sEAAsE;AACtE,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAKlD;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAEnD;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAItD;AAKD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAInD;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAIlD;AAED,qEAAqE;AACrE,wBAAgB,SAAS,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAIjD;AA8BD,yEAAyE;AACzE,wBAAgB,aAAa,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAIrD;AAED,uEAAuE;AACvE,wBAAgB,WAAW,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAInD;AAED,uEAAuE;AACvE,wBAAgB,WAAW,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAInD;AAED;;;GAGG;AACH,eAAO,MAAM,sBAAsB,QAAc,CAAC;AAElD;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,QAAmB,CAAC;AAE5D,MAAM,MAAM,iBAAiB,GAAG;IAC9B,wEAAwE;IACxE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,QAAQ,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,EACjC,EACE,GAA4B,EAC5B,OAAqC,GACtC,GAAE,iBAAsB,GACxB,MAAM,GAAG,KAAK,GAAG,QAAQ,CAI3B;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAUhD"}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What kind of file a source is. Pure module (no React) so every renderer's `accepts` shares one
|
|
3
|
+
* answer — `hasGenericType`, "a declared content type outranks the filename", is the rule a second
|
|
4
|
+
* copy elsewhere would fork.
|
|
5
|
+
*/
|
|
6
|
+
const IMAGE_EXTENSION = /\.(png|jpe?g|gif|webp|avif|svg)$/i;
|
|
7
|
+
// Text formats the CLI/browser labels with an application/* type.
|
|
8
|
+
const TEXT_APPLICATION_TYPES = new Set([
|
|
9
|
+
"application/json",
|
|
10
|
+
"application/ld+json",
|
|
11
|
+
"application/x-ndjson",
|
|
12
|
+
"application/xml",
|
|
13
|
+
"application/yaml",
|
|
14
|
+
"application/x-yaml",
|
|
15
|
+
"application/toml",
|
|
16
|
+
"application/javascript",
|
|
17
|
+
"application/x-javascript",
|
|
18
|
+
"application/typescript",
|
|
19
|
+
"application/sql",
|
|
20
|
+
"application/x-sh",
|
|
21
|
+
]);
|
|
22
|
+
// The CLI's extension→mime table only covers a handful of formats, so code
|
|
23
|
+
// files usually upload as application/octet-stream and only the filename
|
|
24
|
+
// says they are text.
|
|
25
|
+
const TEXT_EXTENSION = /\.(txt|log|md|markdown|csv|tsv|json|jsonc|json5|jsonl|ndjson|ya?ml|toml|ini|cfg|conf|env|xml|html?|css|scss|less|diff|patch|ts|tsx|mts|cts|js|jsx|mjs|cjs|py|rb|rs|go|java|kt|kts|c|h|cpp|hpp|cc|hh|cs|php|swift|scala|clj|ex|exs|erl|hs|ml|lua|pl|r|jl|nix|zig|sql|graphql|proto|sh|bash|zsh|fish|ps1|bat|cmd|vue|svelte|astro|tex|lock|mmd|mermaid)$/i;
|
|
26
|
+
/** The bare type: `Text/HTML; charset=utf-8` and `text/html` are one type. */
|
|
27
|
+
function mimeOf(file) {
|
|
28
|
+
return (file.mime ?? "").split(";")[0]?.trim().toLowerCase() ?? "";
|
|
29
|
+
}
|
|
30
|
+
function hasGenericType(mime) {
|
|
31
|
+
return mime === "" || mime === "application/octet-stream";
|
|
32
|
+
}
|
|
33
|
+
export function isImageFile(file) {
|
|
34
|
+
const type = mimeOf(file);
|
|
35
|
+
if (type.startsWith("image/"))
|
|
36
|
+
return true;
|
|
37
|
+
// Uploads that arrived without a real content type (the CLI sent
|
|
38
|
+
// application/octet-stream until T-27's hotfix) fall back to the filename.
|
|
39
|
+
return hasGenericType(type) && IMAGE_EXTENSION.test(file.name);
|
|
40
|
+
}
|
|
41
|
+
/** Text by declared type, or by filename when the type is generic. */
|
|
42
|
+
export function isTextFile(file) {
|
|
43
|
+
const type = mimeOf(file);
|
|
44
|
+
if (type.startsWith("text/"))
|
|
45
|
+
return true;
|
|
46
|
+
if (TEXT_APPLICATION_TYPES.has(type))
|
|
47
|
+
return true;
|
|
48
|
+
return hasGenericType(type) && TEXT_EXTENSION.test(file.name);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Files whose image-syntax reference embeds a document card rather than an
|
|
52
|
+
* `<img>`. Images keep winning ties like .svg, which is both.
|
|
53
|
+
*/
|
|
54
|
+
export function isTextEmbed(file) {
|
|
55
|
+
return !isImageFile(file) && isTextFile(file);
|
|
56
|
+
}
|
|
57
|
+
export function isMarkdownFile(file) {
|
|
58
|
+
return (mimeOf(file) === "text/markdown" || /\.(md|markdown)$/i.test(file.name));
|
|
59
|
+
}
|
|
60
|
+
// What browsers on Linux declare for .patch and .diff, from shared-mime-info.
|
|
61
|
+
const PATCH_TYPES = new Set(["text/x-patch", "text/x-diff"]);
|
|
62
|
+
/**
|
|
63
|
+
* A unified diff, by declared type, or by filename when the type is generic: a `.patch` someone
|
|
64
|
+
* uploaded as text/plain keeps the plain text view it asked for.
|
|
65
|
+
*/
|
|
66
|
+
export function isPatchFile(file) {
|
|
67
|
+
const type = mimeOf(file);
|
|
68
|
+
if (PATCH_TYPES.has(type))
|
|
69
|
+
return true;
|
|
70
|
+
return hasGenericType(type) && /\.(patch|diff)$/i.test(file.name);
|
|
71
|
+
}
|
|
72
|
+
export function isHtmlFile(file) {
|
|
73
|
+
const type = mimeOf(file);
|
|
74
|
+
if (type === "text/html" || type === "application/xhtml+xml")
|
|
75
|
+
return true;
|
|
76
|
+
return hasGenericType(type) && /\.(html?|xhtml)$/i.test(file.name);
|
|
77
|
+
}
|
|
78
|
+
/** PDF by declared type, or by filename when the type is generic. */
|
|
79
|
+
export function isPdfFile(file) {
|
|
80
|
+
const type = mimeOf(file);
|
|
81
|
+
if (type === "application/pdf")
|
|
82
|
+
return true;
|
|
83
|
+
return hasGenericType(type) && /\.pdf$/i.test(file.name);
|
|
84
|
+
}
|
|
85
|
+
// Archive types as the CLI, the browser and the common upload tools spell
|
|
86
|
+
// them; the same format arrives under several names depending on which one
|
|
87
|
+
// did the labelling.
|
|
88
|
+
const ARCHIVE_TYPES = new Set([
|
|
89
|
+
"application/zip",
|
|
90
|
+
"application/x-zip-compressed",
|
|
91
|
+
"application/gzip",
|
|
92
|
+
"application/x-gzip",
|
|
93
|
+
"application/x-tar",
|
|
94
|
+
"application/x-7z-compressed",
|
|
95
|
+
"application/vnd.rar",
|
|
96
|
+
"application/x-rar-compressed",
|
|
97
|
+
"application/x-bzip2",
|
|
98
|
+
"application/x-xz",
|
|
99
|
+
"application/zstd",
|
|
100
|
+
]);
|
|
101
|
+
const ARCHIVE_EXTENSION = /\.(zip|tar|gz|tgz|bz2|tbz|tbz2|xz|txz|7z|rar|zst)$/i;
|
|
102
|
+
const AUDIO_EXTENSION = /\.(mp3|wav|ogg|oga|m4a|aac|flac|opus|wma|aif|aiff)$/i;
|
|
103
|
+
/**
|
|
104
|
+
* `ts` is deliberately missing: it is MPEG transport stream and TypeScript
|
|
105
|
+
* both, and TEXT_EXTENSION claims it. A source file the CLI uploaded as
|
|
106
|
+
* application/octet-stream must not come back as a video.
|
|
107
|
+
*/
|
|
108
|
+
const VIDEO_EXTENSION = /\.(mp4|m4v|webm|mov|mkv|avi|wmv|flv|mpg|mpeg)$/i;
|
|
109
|
+
/** Archive by declared type, or by filename when the type is generic. */
|
|
110
|
+
export function isArchiveFile(file) {
|
|
111
|
+
const type = mimeOf(file);
|
|
112
|
+
if (ARCHIVE_TYPES.has(type))
|
|
113
|
+
return true;
|
|
114
|
+
return hasGenericType(type) && ARCHIVE_EXTENSION.test(file.name);
|
|
115
|
+
}
|
|
116
|
+
/** Audio by declared type, or by filename when the type is generic. */
|
|
117
|
+
export function isAudioFile(file) {
|
|
118
|
+
const type = mimeOf(file);
|
|
119
|
+
if (type.startsWith("audio/"))
|
|
120
|
+
return true;
|
|
121
|
+
return hasGenericType(type) && AUDIO_EXTENSION.test(file.name);
|
|
122
|
+
}
|
|
123
|
+
/** Video by declared type, or by filename when the type is generic. */
|
|
124
|
+
export function isVideoFile(file) {
|
|
125
|
+
const type = mimeOf(file);
|
|
126
|
+
if (type.startsWith("video/"))
|
|
127
|
+
return true;
|
|
128
|
+
return hasGenericType(type) && VIDEO_EXTENSION.test(file.name);
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Highlighting a multi-megabyte file would freeze the tab (T-31), so bigger
|
|
132
|
+
* text files only preview when asked, and then as plain text.
|
|
133
|
+
*/
|
|
134
|
+
export const TEXT_PREVIEW_MAX_BYTES = 1024 * 1024;
|
|
135
|
+
/**
|
|
136
|
+
* Past this nothing previews. Measured in Chromium under load: plain text at
|
|
137
|
+
* 10 MiB blocked the tab for 1.5 s in its longest task, at 20 MiB for 2.9 s,
|
|
138
|
+
* at 50 MiB for 6.9 s.
|
|
139
|
+
*/
|
|
140
|
+
export const TEXT_PREVIEW_HARD_MAX_BYTES = 10 * 1024 * 1024;
|
|
141
|
+
/**
|
|
142
|
+
* Whether a text file of this size previews on its own, waits to be asked,
|
|
143
|
+
* or never previews. A patch skips the asking: its view is virtualized per
|
|
144
|
+
* file, and a 20 MiB one blocked the tab for 0.6 s at most where the code
|
|
145
|
+
* view took 10 s or more over 1 MiB of highlighted text.
|
|
146
|
+
*/
|
|
147
|
+
export function textPreviewGate(file, { max = TEXT_PREVIEW_MAX_BYTES, hardMax = TEXT_PREVIEW_HARD_MAX_BYTES, } = {}) {
|
|
148
|
+
if (file.size > hardMax)
|
|
149
|
+
return "refuse";
|
|
150
|
+
if (file.size <= max || isPatchFile(file))
|
|
151
|
+
return "auto";
|
|
152
|
+
return "ask";
|
|
153
|
+
}
|
|
154
|
+
export function formatSize(bytes) {
|
|
155
|
+
if (bytes < 1024)
|
|
156
|
+
return `${bytes} B`;
|
|
157
|
+
const units = ["KB", "MB", "GB"];
|
|
158
|
+
let value = bytes / 1024;
|
|
159
|
+
let i = 0;
|
|
160
|
+
while (value >= 1024 && i < units.length - 1) {
|
|
161
|
+
value /= 1024;
|
|
162
|
+
i++;
|
|
163
|
+
}
|
|
164
|
+
return `${value >= 10 ? Math.round(value) : value.toFixed(1)} ${units[i]}`;
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=file-kind.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-kind.js","sourceRoot":"","sources":["../src/file-kind.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { type FileLike, formatSize, isArchiveFile, isAudioFile, isHtmlFile, isImageFile, isMarkdownFile, isPatchFile, isPdfFile, isTextEmbed, isTextFile, isVideoFile, TEXT_PREVIEW_HARD_MAX_BYTES, TEXT_PREVIEW_MAX_BYTES, type TextPreviewLimits, textPreviewGate, } from "./file-kind.ts";
|
|
2
|
+
export { Content, ContentFallback, ContentRenderers, useContentDepth, useContentDisplay, useContentDisplayOf, useContentMaxDepth, } from "./registry.tsx";
|
|
3
|
+
export { type SourceText, useSourceText } from "./source-text.ts";
|
|
4
|
+
export { ContentTitleBar, useContentTitleBar } from "./title-bar.tsx";
|
|
5
|
+
export type { ContentDisplay, ContentProps, ContentRenderer, ContentSource, Placement, } from "./types.ts";
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,QAAQ,EACb,UAAU,EACV,aAAa,EACb,WAAW,EACX,UAAU,EACV,WAAW,EACX,cAAc,EACd,WAAW,EACX,SAAS,EACT,WAAW,EACX,UAAU,EACV,WAAW,EACX,2BAA2B,EAC3B,sBAAsB,EACtB,KAAK,iBAAiB,EACtB,eAAe,GAChB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,OAAO,EACP,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,KAAK,UAAU,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACtE,YAAY,EACV,cAAc,EACd,YAAY,EACZ,eAAe,EACf,aAAa,EACb,SAAS,GACV,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { formatSize, isArchiveFile, isAudioFile, isHtmlFile, isImageFile, isMarkdownFile, isPatchFile, isPdfFile, isTextEmbed, isTextFile, isVideoFile, TEXT_PREVIEW_HARD_MAX_BYTES, TEXT_PREVIEW_MAX_BYTES, textPreviewGate, } from "./file-kind.js";
|
|
2
|
+
export { Content, ContentFallback, ContentRenderers, useContentDepth, useContentDisplay, useContentDisplayOf, useContentMaxDepth, } from "./registry.js";
|
|
3
|
+
export { useSourceText } from "./source-text.js";
|
|
4
|
+
export { ContentTitleBar, useContentTitleBar } from "./title-bar.js";
|
|
5
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,UAAU,EACV,aAAa,EACb,WAAW,EACX,UAAU,EACV,WAAW,EACX,cAAc,EACd,WAAW,EACX,SAAS,EACT,WAAW,EACX,UAAU,EACV,WAAW,EACX,2BAA2B,EAC3B,sBAAsB,EAEtB,eAAe,GAChB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,OAAO,EACP,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,eAAgB,CAAC;AACxB,OAAO,EAAmB,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,gBAAiB,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import type { ContentDisplay, ContentProps, ContentRenderer, ContentSource, Placement } from "./types.ts";
|
|
3
|
+
/**
|
|
4
|
+
* The fallback, as a component, for renderers that decide to step aside: a plain `<pre><code>`
|
|
5
|
+
* for inline text, and a download link (or the bare name when there is no `url`) for a file.
|
|
6
|
+
*/
|
|
7
|
+
export declare function ContentFallback({ source, className }: ContentProps): import("react").JSX.Element;
|
|
8
|
+
/**
|
|
9
|
+
* Registers renderers for every `<Content>` below. The list is ordered and the first renderer
|
|
10
|
+
* that accepts a source draws it, so a narrow renderer goes before a broad one. A nested provider
|
|
11
|
+
* puts its renderers in front of the outer ones.
|
|
12
|
+
*
|
|
13
|
+
* Keep `renderers` stable (a module constant or a memo): a new array rebuilds every `Next`, and
|
|
14
|
+
* React remounts whatever the renderers drew.
|
|
15
|
+
*/
|
|
16
|
+
export declare function ContentRenderers({ renderers, maxDepth, children, }: {
|
|
17
|
+
renderers: readonly ContentRenderer[];
|
|
18
|
+
/** Read by renderers that limit nesting (`useContentMaxDepth`); `<Content>` does not enforce it. */
|
|
19
|
+
maxDepth?: number;
|
|
20
|
+
children?: ReactNode;
|
|
21
|
+
}): import("react").JSX.Element;
|
|
22
|
+
/**
|
|
23
|
+
* Draws a source with the first registered renderer that accepts it, or the fallback.
|
|
24
|
+
*
|
|
25
|
+
* A file source a renderer draws raises `useContentDepth()` by one for everything below it, once
|
|
26
|
+
* per `<Content>`: a renderer that wraps the file and hands it on through `Next` does not count
|
|
27
|
+
* it twice.
|
|
28
|
+
*/
|
|
29
|
+
export declare function Content(props: ContentProps): import("react").JSX.Element;
|
|
30
|
+
/**
|
|
31
|
+
* How the renderer that would draw this source lays out, without rendering anything: `"block"`,
|
|
32
|
+
* `"inline"`, or `null` when nothing registered accepts it.
|
|
33
|
+
*/
|
|
34
|
+
export declare function useContentDisplay(source: ContentSource, placement: Placement): ContentDisplay | null;
|
|
35
|
+
/**
|
|
36
|
+
* `useContentDisplay` as a function, for a caller that asks about a varying number of sources in
|
|
37
|
+
* one render, such as a paragraph checking each of its images.
|
|
38
|
+
*/
|
|
39
|
+
export declare function useContentDisplayOf(): (source: ContentSource, placement: Placement) => ContentDisplay | null;
|
|
40
|
+
/** How many file sources, each drawn by a renderer, enclose this point. */
|
|
41
|
+
export declare function useContentDepth(): number;
|
|
42
|
+
/** The nearest `<ContentRenderers maxDepth>`, for renderers that limit nesting. */
|
|
43
|
+
export declare function useContentMaxDepth(): number | undefined;
|
|
44
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.tsx"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,SAAS,EAIf,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EACV,cAAc,EACd,YAAY,EACZ,eAAe,EACf,aAAa,EACb,SAAS,EACV,MAAM,YAAY,CAAC;AASpB;;;GAGG;AACH,wBAAgB,eAAe,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,YAAY,+BAsBlE;AAqCD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,SAAS,EACT,QAAQ,EACR,QAAQ,GACT,EAAE;IACD,SAAS,EAAE,SAAS,eAAe,EAAE,CAAC;IACtC,oGAAoG;IACpG,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB,+BAoBA;AAUD;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,YAAY,+BAa1C;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,aAAa,EACrB,SAAS,EAAE,SAAS,GACnB,cAAc,GAAG,IAAI,CAEvB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,CACrC,MAAM,EAAE,aAAa,EACrB,SAAS,EAAE,SAAS,KACjB,cAAc,GAAG,IAAI,CASzB;AAED,2EAA2E;AAC3E,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,mFAAmF;AACnF,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,SAAS,CAEvD"}
|