@backmatter/studio 0.0.7 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunks/UiKitApp-b8qFsmA-.js +2401 -0
- package/dist/chunks/WorkspaceRoutes-BKKEkAq7.js +90126 -0
- package/dist/chunks/{dashboard-DCHRI0WD.js → dashboard-BNUcbYU0.js} +380 -382
- package/dist/chunks/{index-BS0-Bvbk.js → index-laWAz5_p.js} +111 -112
- package/dist/dashboard.js +2 -2
- package/dist/index.js +287 -146
- package/dist/site-widget.css +1615 -0
- package/dist/site-widget.js +30896 -630
- package/dist/studio.css +303 -98
- package/package.json +4 -4
- package/src/App.tsx +12 -29
- package/src/api.ts +55 -0
- package/src/chat/ChangeCard.tsx +2 -0
- package/src/chat/ChatMessage.tsx +73 -62
- package/src/chat/ChatPanel.tsx +110 -15
- package/src/chat/DocListCard.tsx +2 -0
- package/src/chat/LiveStatus.tsx +78 -8
- package/src/chat/Reveal.tsx +34 -0
- package/src/chat/Shimmer.tsx +65 -23
- package/src/chat/chat-helpers.ts +35 -0
- package/src/chat/motion.ts +73 -0
- package/src/chat/useStickToBottom.ts +129 -14
- package/src/chrome/AppShell.tsx +47 -10
- package/src/chrome/AppSidebar.tsx +9 -34
- package/src/chrome/ContentExplorerSidebar.tsx +149 -96
- package/src/chrome/UserMenu.tsx +3 -1
- package/src/chrome/content-tree-visibility.ts +55 -0
- package/src/chrome/explorer-icons.tsx +2 -4
- package/src/devbar-state.ts +125 -0
- package/src/index.css +3 -131
- package/src/pages/CliAuthorizePage.tsx +61 -28
- package/src/pages/MediaGalleryPage.tsx +144 -85
- package/src/pages/MediaLightbox.tsx +195 -96
- package/src/pages/SelectRepositoriesLink.tsx +28 -4
- package/src/pages/SettingsGeneralPage.tsx +25 -28
- package/src/pages/SettingsGithubPage.tsx +413 -124
- package/src/pages/SettingsUsagePage.tsx +23 -1
- package/src/pages/media-grid.ts +14 -1
- package/src/pages/ui-kit/UiKitApp.tsx +164 -0
- package/src/pages/ui-kit/buttons.tsx +30 -0
- package/src/pages/ui-kit/catalog.tsx +41 -0
- package/src/pages/ui-kit/colors.tsx +95 -0
- package/src/pages/ui-kit/devbar.tsx +160 -0
- package/src/pages/ui-kit/feedback.tsx +39 -0
- package/src/pages/ui-kit/fields.tsx +47 -0
- package/src/pages/ui-kit/lists.tsx +19 -0
- package/src/pages/ui-kit/overlays.tsx +39 -0
- package/src/pages/ui-kit/path.ts +9 -0
- package/src/pages/ui-kit/sections.tsx +32 -0
- package/src/pages/ui-kit/surfaces.tsx +121 -0
- package/src/pages/ui-kit/topic.tsx +112 -0
- package/src/pages/ui-kit/topics.ts +71 -0
- package/src/pages/ui-kit/type.tsx +55 -0
- package/src/preview-frame-radius.ts +51 -0
- package/src/preview-frame.tsx +93 -49
- package/src/shell-resets.css +155 -0
- package/src/site-bar.tsx +1791 -425
- package/src/site-dashboard-href.ts +21 -0
- package/src/site-devbar-overlay-inject.ts +15 -0
- package/src/site-devbar-overlay.css +217 -0
- package/src/site-pointer.ts +1 -1
- package/src/site-publish-menu.tsx +33 -0
- package/src/site-widget-styles.ts +7 -0
- package/src/site-widget.tsx +61 -21
- package/src/studio-prose-ui.css +39 -0
- package/src/theme/ThemeProvider.tsx +4 -1
- package/src/workspace-path.ts +18 -1
- package/dist/chunks/EmbedPublishPage-88VsmOhi.js +0 -149
- package/dist/chunks/UiKitPage-X4hkFL2d.js +0 -173
- package/dist/chunks/WorkspaceRoutes-DXzdWqN3.js +0 -59523
- package/dist/chunks/status-bar-action-wj1KZ51m.js +0 -30612
- package/src/pages/UiKitPage.tsx +0 -331
|
@@ -6,10 +6,11 @@ import {
|
|
|
6
6
|
IconSquareBehindSquare1,
|
|
7
7
|
IconTrashCanSimple,
|
|
8
8
|
} from "@central-icons-react/round-outlined-radius-2-stroke-1.5";
|
|
9
|
-
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
9
|
+
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
10
10
|
import { useOutletContext, useSearchParams } from "react-router";
|
|
11
11
|
import * as stylex from "@stylexjs/stylex";
|
|
12
|
-
import { deleteMedia, fetchMedia, uploadMedia } from "../api";
|
|
12
|
+
import { deleteMedia, describeMedia, fetchMedia, uploadMedia } from "../api";
|
|
13
|
+
import { Input } from "../ui/Input";
|
|
13
14
|
import { colors, radius, space, type, z } from "../styles/tokens.stylex";
|
|
14
15
|
import { Button } from "../ui/Button";
|
|
15
16
|
import { ConfirmDialog } from "../ui/ConfirmDialog";
|
|
@@ -19,10 +20,10 @@ import { canWriteContent } from "../workspace/permissions";
|
|
|
19
20
|
import type { WorkspaceOutletContext } from "../workspace/types";
|
|
20
21
|
import {
|
|
21
22
|
beginUploads,
|
|
23
|
+
describeMedia as rememberDescription,
|
|
22
24
|
emptyMediaGrid,
|
|
23
25
|
failUpload,
|
|
24
26
|
finishUpload,
|
|
25
|
-
gridLength,
|
|
26
27
|
lightboxImageId,
|
|
27
28
|
mediaIdAfterRemoval,
|
|
28
29
|
nextMediaIndex,
|
|
@@ -57,38 +58,69 @@ export function MediaGalleryPage({
|
|
|
57
58
|
const [deleteError, setDeleteError] = useState<string | null>(null);
|
|
58
59
|
const [selectedId, setSelectedId] = useState<string | null>(null);
|
|
59
60
|
const [settled, setSettled] = useState(false);
|
|
61
|
+
const urlQuery = searchParams.get("q") ?? "";
|
|
62
|
+
const [draft, setDraft] = useState(urlQuery);
|
|
63
|
+
const [query, setQuery] = useState(urlQuery);
|
|
60
64
|
const dragDepth = useRef(0);
|
|
61
65
|
const scroller = useRef<HTMLDivElement>(null);
|
|
62
|
-
const
|
|
66
|
+
const grid = useRef<HTMLDivElement>(null);
|
|
67
|
+
const [columns, setColumns] = useState(1);
|
|
63
68
|
const loadingPage = useRef(false);
|
|
69
|
+
const request = useRef(0);
|
|
70
|
+
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
const handle = window.setTimeout(() => setQuery(draft), 200);
|
|
73
|
+
return () => window.clearTimeout(handle);
|
|
74
|
+
}, [draft]);
|
|
75
|
+
|
|
76
|
+
useEffect(() => {
|
|
77
|
+
setSearchParams(
|
|
78
|
+
(current) => {
|
|
79
|
+
const next = new URLSearchParams(current);
|
|
80
|
+
if (query) next.set("q", query);
|
|
81
|
+
else next.delete("q");
|
|
82
|
+
if (next.get("q") === current.get("q")) return current;
|
|
83
|
+
return next;
|
|
84
|
+
},
|
|
85
|
+
{ replace: true },
|
|
86
|
+
);
|
|
87
|
+
}, [query, setSearchParams]);
|
|
64
88
|
|
|
65
89
|
const load = useCallback(
|
|
66
90
|
async (cursor?: string) => {
|
|
67
|
-
if (loadingPage.current) return;
|
|
91
|
+
if (cursor && loadingPage.current) return;
|
|
92
|
+
const ticket = ++request.current;
|
|
68
93
|
loadingPage.current = true;
|
|
94
|
+
if (!cursor) setState((current) => ({ ...current, nextCursor: null }));
|
|
69
95
|
try {
|
|
70
|
-
const page = await fetchMedia(workspace.id, { cursor });
|
|
96
|
+
const page = await fetchMedia(workspace.id, { query: query || undefined, cursor });
|
|
97
|
+
if (ticket !== request.current) return;
|
|
71
98
|
setState((current) => receivePage(current, page, cursor ? "append" : "replace"));
|
|
72
99
|
setError(null);
|
|
73
100
|
} catch (err) {
|
|
101
|
+
if (ticket !== request.current) return;
|
|
74
102
|
setError(err instanceof Error ? err.message : "Could not load media");
|
|
75
103
|
} finally {
|
|
76
|
-
|
|
77
|
-
|
|
104
|
+
if (ticket === request.current) {
|
|
105
|
+
loadingPage.current = false;
|
|
106
|
+
if (!cursor) setSettled(true);
|
|
107
|
+
}
|
|
78
108
|
}
|
|
79
109
|
},
|
|
80
|
-
[workspace.id],
|
|
110
|
+
[query, workspace.id],
|
|
81
111
|
);
|
|
82
112
|
|
|
83
113
|
useEffect(() => {
|
|
84
114
|
void load();
|
|
85
115
|
}, [load]);
|
|
86
116
|
|
|
87
|
-
|
|
117
|
+
const maybeLoadMore = useCallback(() => {
|
|
88
118
|
const node = scroller.current;
|
|
89
|
-
if (!node) return;
|
|
90
|
-
|
|
91
|
-
|
|
119
|
+
if (!node || !state.nextCursor) return;
|
|
120
|
+
if (node.scrollTop + node.clientHeight > node.scrollHeight - CELL * 2) {
|
|
121
|
+
void load(state.nextCursor);
|
|
122
|
+
}
|
|
123
|
+
}, [load, state.nextCursor]);
|
|
92
124
|
|
|
93
125
|
const uploadFiles = useCallback(
|
|
94
126
|
(files: File[]) => {
|
|
@@ -250,14 +282,8 @@ export function MediaGalleryPage({
|
|
|
250
282
|
void load(state.nextCursor);
|
|
251
283
|
}, [sharedId, browsable, state.nextCursor, load]);
|
|
252
284
|
|
|
253
|
-
const columns = Math.max(2, Math.floor((scroll.width - 24) / (CELL + 12)));
|
|
254
|
-
const count = gridLength(state);
|
|
255
|
-
const rows = Math.ceil(count / columns);
|
|
256
|
-
const startRow = Math.max(0, Math.floor(scroll.top / (CELL + 12)) - 1);
|
|
257
|
-
const endRow = Math.min(rows, Math.ceil((scroll.top + scroll.height) / (CELL + 12)) + 2);
|
|
258
|
-
|
|
259
285
|
const cells = useMemo(() => {
|
|
260
|
-
const out: Array<{ kind: "pending"; item: PendingUpload } | { kind: "media"; item: CatalogMedia }
|
|
286
|
+
const out: Array<{ kind: "pending"; item: PendingUpload } | { kind: "media"; item: CatalogMedia }> = [];
|
|
261
287
|
for (const item of state.pending) {
|
|
262
288
|
if (item.media) out.push({ kind: "media", item: item.media });
|
|
263
289
|
else out.push({ kind: "pending", item });
|
|
@@ -266,26 +292,24 @@ export function MediaGalleryPage({
|
|
|
266
292
|
if (state.pending.some((slot) => slot.media?.id === item.id)) continue;
|
|
267
293
|
out.push({ kind: "media", item });
|
|
268
294
|
}
|
|
269
|
-
while (out.length < count) out.push({ kind: "empty" });
|
|
270
295
|
return out;
|
|
271
|
-
}, [state.pending, state.loaded
|
|
272
|
-
|
|
273
|
-
const visible = [];
|
|
274
|
-
for (let row = startRow; row < endRow; row++) {
|
|
275
|
-
for (let column = 0; column < columns; column++) {
|
|
276
|
-
const index = row * columns + column;
|
|
277
|
-
if (index >= cells.length) break;
|
|
278
|
-
visible.push({ index, row, column, cell: cells[index]! });
|
|
279
|
-
}
|
|
280
|
-
}
|
|
296
|
+
}, [state.pending, state.loaded]);
|
|
281
297
|
|
|
282
|
-
|
|
283
|
-
const
|
|
284
|
-
|
|
285
|
-
if (
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
298
|
+
useLayoutEffect(() => {
|
|
299
|
+
const scrollNode = scroller.current;
|
|
300
|
+
const gridNode = grid.current;
|
|
301
|
+
if (!scrollNode) return;
|
|
302
|
+
const measure = () => {
|
|
303
|
+
const next = gridNode ? columnsInFirstRow(gridNode) : 1;
|
|
304
|
+
setColumns((current) => (current === next ? current : next));
|
|
305
|
+
maybeLoadMore();
|
|
306
|
+
};
|
|
307
|
+
measure();
|
|
308
|
+
const observer = new ResizeObserver(measure);
|
|
309
|
+
observer.observe(scrollNode);
|
|
310
|
+
if (gridNode) observer.observe(gridNode);
|
|
311
|
+
return () => observer.disconnect();
|
|
312
|
+
}, [maybeLoadMore, cells.length]);
|
|
289
313
|
|
|
290
314
|
useEffect(() => {
|
|
291
315
|
if (pick || sharedId) return;
|
|
@@ -343,21 +367,26 @@ export function MediaGalleryPage({
|
|
|
343
367
|
state.pending.length,
|
|
344
368
|
]);
|
|
345
369
|
|
|
346
|
-
|
|
370
|
+
useLayoutEffect(() => {
|
|
347
371
|
if (!selectedId || sharedId) return;
|
|
348
|
-
const
|
|
349
|
-
const node =
|
|
350
|
-
if (
|
|
351
|
-
const
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
if (top < node.scrollTop) node.scrollTop = top;
|
|
357
|
-
else if (bottom > node.scrollTop + node.clientHeight) node.scrollTop = bottom - node.clientHeight;
|
|
358
|
-
}, [browsable, columns, mediaPlaces, selectedId, sharedId, state.pending.length]);
|
|
372
|
+
const frame = scroller.current;
|
|
373
|
+
const node = grid.current?.querySelector("[aria-current='true']");
|
|
374
|
+
if (!frame || !(node instanceof HTMLElement)) return;
|
|
375
|
+
const item = node.getBoundingClientRect();
|
|
376
|
+
const bounds = frame.getBoundingClientRect();
|
|
377
|
+
if (item.top < bounds.top) frame.scrollTop -= bounds.top - item.top;
|
|
378
|
+
else if (item.bottom > bounds.bottom) frame.scrollTop += item.bottom - bounds.bottom;
|
|
379
|
+
}, [columns, selectedId, sharedId]);
|
|
359
380
|
|
|
360
381
|
const open = lightbox >= 0 ? browsable[lightbox] : undefined;
|
|
382
|
+
const saveText = useCallback(
|
|
383
|
+
async (text: { alt?: string; caption?: string }) => {
|
|
384
|
+
if (!open) return;
|
|
385
|
+
const result = await describeMedia(workspace.id, open.id, text);
|
|
386
|
+
setState((current) => rememberDescription(current, result.media));
|
|
387
|
+
},
|
|
388
|
+
[open, workspace.id],
|
|
389
|
+
);
|
|
361
390
|
const showEmpty =
|
|
362
391
|
settled && state.pending.length === 0 && state.loaded.length === 0 && state.total === 0;
|
|
363
392
|
|
|
@@ -367,22 +396,34 @@ export function MediaGalleryPage({
|
|
|
367
396
|
<Text as="h1" size="xl" weight="medium">
|
|
368
397
|
Media
|
|
369
398
|
</Text>
|
|
370
|
-
<
|
|
371
|
-
|
|
372
|
-
|
|
399
|
+
<div {...stylex.props(styles.toolbarActions)}>
|
|
400
|
+
<div {...stylex.props(styles.search)}>
|
|
401
|
+
<Input
|
|
402
|
+
aria-label="Search media"
|
|
403
|
+
placeholder="Search"
|
|
404
|
+
value={draft}
|
|
405
|
+
onChange={(event) => setDraft(event.target.value)}
|
|
406
|
+
/>
|
|
407
|
+
</div>
|
|
408
|
+
<Button variant="secondary" onClick={chooseFiles}>
|
|
409
|
+
Upload
|
|
410
|
+
</Button>
|
|
411
|
+
</div>
|
|
373
412
|
</div>
|
|
374
413
|
{error ? <Text tone="danger">{error}</Text> : null}
|
|
375
414
|
{rejected.length > 0 ? <Text tone="danger">{rejected.join(" · ")}</Text> : null}
|
|
376
415
|
<div
|
|
377
416
|
ref={scroller}
|
|
378
417
|
{...stylex.props(styles.scroller)}
|
|
379
|
-
onScroll={(
|
|
380
|
-
const node = event.currentTarget;
|
|
381
|
-
setScroll({ top: node.scrollTop, height: node.clientHeight, width: node.clientWidth });
|
|
418
|
+
onScroll={() => {
|
|
382
419
|
maybeLoadMore();
|
|
383
420
|
}}
|
|
384
421
|
>
|
|
385
|
-
{showEmpty ? (
|
|
422
|
+
{showEmpty && query ? (
|
|
423
|
+
<div {...stylex.props(styles.emptyState)}>
|
|
424
|
+
<Text tone="muted">No images match this search.</Text>
|
|
425
|
+
</div>
|
|
426
|
+
) : showEmpty ? (
|
|
386
427
|
<div
|
|
387
428
|
{...stylex.props(styles.emptyState)}
|
|
388
429
|
onDragOver={(event) => event.preventDefault()}
|
|
@@ -410,20 +451,14 @@ export function MediaGalleryPage({
|
|
|
410
451
|
</div>
|
|
411
452
|
</div>
|
|
412
453
|
) : (
|
|
413
|
-
<div {...stylex.props(styles.canvas)}
|
|
414
|
-
{
|
|
454
|
+
<div ref={grid} {...stylex.props(styles.canvas)}>
|
|
455
|
+
{cells.map((cell) => (
|
|
415
456
|
<div
|
|
416
|
-
key={cell.kind === "media" ? cell.item.id : cell.
|
|
457
|
+
key={cell.kind === "media" ? cell.item.id : cell.item.key}
|
|
417
458
|
{...stylex.props(styles.cell)}
|
|
418
|
-
style={{
|
|
419
|
-
width: CELL,
|
|
420
|
-
height: CELL,
|
|
421
|
-
transform: `translate(${column * (CELL + 12)}px, ${row * (CELL + 12)}px)`,
|
|
422
|
-
}}
|
|
423
459
|
>
|
|
424
|
-
{cell.kind === "empty" ? <div {...stylex.props(styles.empty)} /> : null}
|
|
425
460
|
{cell.kind === "pending" ? (
|
|
426
|
-
<figure {...stylex.props(styles.figure)}>
|
|
461
|
+
<figure {...stylex.props(styles.figure, styles.placed)}>
|
|
427
462
|
<img src={cell.item.previewUrl} alt="" {...stylex.props(styles.image, styles.dimmed)} />
|
|
428
463
|
{cell.item.status === "error" ? (
|
|
429
464
|
<figcaption {...stylex.props(styles.caption)}>{cell.item.error}</figcaption>
|
|
@@ -478,6 +513,8 @@ export function MediaGalleryPage({
|
|
|
478
513
|
onPrev={prevLightbox}
|
|
479
514
|
onNext={nextLightbox}
|
|
480
515
|
onDelete={canDelete ? () => requestDelete(open) : undefined}
|
|
516
|
+
canEdit={canDelete}
|
|
517
|
+
onDescribe={saveText}
|
|
481
518
|
/>
|
|
482
519
|
) : null}
|
|
483
520
|
<ConfirmDialog
|
|
@@ -519,10 +556,10 @@ function MediaHit({
|
|
|
519
556
|
<button
|
|
520
557
|
type="button"
|
|
521
558
|
aria-current={selected ? "true" : undefined}
|
|
522
|
-
{...stylex.props(styles.hit, selected && styles.selected)}
|
|
559
|
+
{...stylex.props(styles.hit, !menu && styles.placed, selected && styles.selected)}
|
|
523
560
|
onClick={onOpen}
|
|
524
561
|
>
|
|
525
|
-
<img src={item.thumbUrl} alt={item.filename} {...stylex.props(styles.image)} />
|
|
562
|
+
<img src={item.thumbUrl} alt={item.alt?.trim() || item.filename} {...stylex.props(styles.image)} />
|
|
526
563
|
</button>
|
|
527
564
|
);
|
|
528
565
|
if (!menu) return image;
|
|
@@ -572,6 +609,18 @@ function MediaHit({
|
|
|
572
609
|
);
|
|
573
610
|
}
|
|
574
611
|
|
|
612
|
+
function columnsInFirstRow(grid: HTMLElement): number {
|
|
613
|
+
const first = grid.children[0];
|
|
614
|
+
if (!(first instanceof HTMLElement)) return 1;
|
|
615
|
+
const top = first.offsetTop;
|
|
616
|
+
let count = 0;
|
|
617
|
+
for (const kid of grid.children) {
|
|
618
|
+
if (!(kid instanceof HTMLElement) || kid.offsetTop - top > 1) break;
|
|
619
|
+
count += 1;
|
|
620
|
+
}
|
|
621
|
+
return Math.max(1, count);
|
|
622
|
+
}
|
|
623
|
+
|
|
575
624
|
function gridKeyTarget(target: EventTarget | null, scroller: HTMLElement | null): boolean {
|
|
576
625
|
if (!(target instanceof HTMLElement)) return false;
|
|
577
626
|
if (target.closest("input, textarea, select, [contenteditable='true']")) return false;
|
|
@@ -594,6 +643,15 @@ const styles = stylex.create({
|
|
|
594
643
|
gap: space.lg,
|
|
595
644
|
padding: space.xl,
|
|
596
645
|
},
|
|
646
|
+
toolbarActions: {
|
|
647
|
+
display: "flex",
|
|
648
|
+
alignItems: "center",
|
|
649
|
+
gap: space.md,
|
|
650
|
+
minWidth: 0,
|
|
651
|
+
},
|
|
652
|
+
search: {
|
|
653
|
+
width: "220px",
|
|
654
|
+
},
|
|
597
655
|
scroller: {
|
|
598
656
|
flex: 1,
|
|
599
657
|
minHeight: 0,
|
|
@@ -645,28 +703,27 @@ const styles = stylex.create({
|
|
|
645
703
|
},
|
|
646
704
|
canvas: {
|
|
647
705
|
position: "relative",
|
|
706
|
+
display: "grid",
|
|
707
|
+
gridTemplateColumns: "repeat(auto-fill, minmax(168px, 1fr))",
|
|
708
|
+
gap: space.lg,
|
|
709
|
+
alignItems: "start",
|
|
648
710
|
},
|
|
649
711
|
cell: {
|
|
650
|
-
position: "
|
|
651
|
-
top: 0,
|
|
652
|
-
left: 0,
|
|
653
|
-
boxSizing: "border-box",
|
|
654
|
-
padding: 6,
|
|
655
|
-
},
|
|
656
|
-
empty: {
|
|
712
|
+
position: "relative",
|
|
657
713
|
width: "100%",
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
714
|
+
aspectRatio: "1",
|
|
715
|
+
minWidth: 0,
|
|
716
|
+
},
|
|
717
|
+
placed: {
|
|
718
|
+
position: "absolute",
|
|
719
|
+
inset: space.sm,
|
|
661
720
|
},
|
|
662
721
|
figure: {
|
|
663
|
-
position: "relative",
|
|
664
722
|
margin: 0,
|
|
665
|
-
height: "100%",
|
|
666
|
-
display: "flex",
|
|
667
|
-
flexDirection: "column",
|
|
668
723
|
},
|
|
669
724
|
hit: {
|
|
725
|
+
position: "absolute",
|
|
726
|
+
inset: 0,
|
|
670
727
|
display: "block",
|
|
671
728
|
width: "100%",
|
|
672
729
|
height: "100%",
|
|
@@ -683,9 +740,9 @@ const styles = stylex.create({
|
|
|
683
740
|
outlineOffset: 3,
|
|
684
741
|
},
|
|
685
742
|
menuHit: {
|
|
743
|
+
position: "absolute",
|
|
744
|
+
inset: space.sm,
|
|
686
745
|
display: "block",
|
|
687
|
-
width: "100%",
|
|
688
|
-
height: "100%",
|
|
689
746
|
},
|
|
690
747
|
menu: {
|
|
691
748
|
minWidth: "11rem",
|
|
@@ -697,6 +754,8 @@ const styles = stylex.create({
|
|
|
697
754
|
color: colors.danger,
|
|
698
755
|
},
|
|
699
756
|
image: {
|
|
757
|
+
position: "absolute",
|
|
758
|
+
inset: 0,
|
|
700
759
|
width: "100%",
|
|
701
760
|
height: "100%",
|
|
702
761
|
objectFit: "cover",
|