@tanishqkancharla/diffmap 0.1.4 → 0.1.5
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/README.md +12 -4
- package/package.json +3 -3
- package/src/cli.test.ts +50 -0
- package/src/cli.ts +40 -5
- package/src/errors.ts +5 -0
- package/src/gist/GistApp.tsx +3 -2
- package/src/gist/GistStatus.tsx +2 -51
- package/src/host/HostHome.tsx +73 -0
- package/src/host/files.ts +10 -0
- package/src/host/home.md +194 -0
- package/src/host/home.test.ts +82 -0
- package/src/packageVersion.ts +7 -0
- package/src/serve.test.ts +306 -0
- package/src/serve.ts +14 -4
- package/src/update.test.ts +19 -0
- package/src/update.ts +285 -0
- package/src/viewer/CloseServerButton.tsx +16 -0
- package/src/viewer/FileExcerpt.tsx +25 -3
- package/src/viewer/HtmlPlaceholder.tsx +6 -1
- package/src/viewer/SourceDiffPanel.tsx +26 -7
- package/src/viewer/TableOfContents.tsx +230 -40
- package/src/viewer/TocButton.tsx +27 -0
- package/src/viewer/ViewerApp.tsx +182 -50
- package/src/viewer/sourceNavigation.ts +37 -3
- package/src/viewer/viewerMode.ts +1 -1
- package/vite.config.ts +1 -1
- package/src/viewer/Check.tsx +0 -24
- package/src/viewer/DoneButton.tsx +0 -32
package/src/viewer/ViewerApp.tsx
CHANGED
|
@@ -1,10 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
useCallback,
|
|
3
|
+
useEffect,
|
|
4
|
+
useRef,
|
|
5
|
+
useState,
|
|
6
|
+
type ReactNode,
|
|
7
|
+
} from "react";
|
|
2
8
|
import {
|
|
3
9
|
backgroundColor,
|
|
4
10
|
border,
|
|
5
11
|
colors,
|
|
6
12
|
flex,
|
|
7
13
|
flexItem,
|
|
14
|
+
H1,
|
|
15
|
+
P,
|
|
8
16
|
proseHtml,
|
|
9
17
|
proseMaxWidth,
|
|
10
18
|
spacing,
|
|
@@ -14,9 +22,15 @@ import { style, useStyles } from "purse-styles";
|
|
|
14
22
|
import type { ViewerDocument } from "../parseViewer.js";
|
|
15
23
|
import { ComarkView } from "./ComarkView.tsx";
|
|
16
24
|
import { SourceDiffPanel, type SourceSelection } from "./SourceDiffPanel.js";
|
|
17
|
-
import {
|
|
25
|
+
import { CloseServerButton } from "./CloseServerButton.tsx";
|
|
18
26
|
import { DiffButton } from "./DiffButton.tsx";
|
|
19
|
-
import {
|
|
27
|
+
import { TocButton } from "./TocButton.tsx";
|
|
28
|
+
import {
|
|
29
|
+
hasTableOfContents,
|
|
30
|
+
TableOfContents,
|
|
31
|
+
TOC_OPEN_MIN_WIDTH_PX,
|
|
32
|
+
TOC_SIDE_MARGIN_PX,
|
|
33
|
+
} from "./TableOfContents.tsx";
|
|
20
34
|
import { ViewerModeContext, type ViewerMode } from "./viewerMode.ts";
|
|
21
35
|
|
|
22
36
|
type ViewerMeta = {
|
|
@@ -32,9 +46,7 @@ export function ViewerApp(props: {
|
|
|
32
46
|
const viewerDocument = props.document;
|
|
33
47
|
const meta = useViewerMeta(props.mode === "local");
|
|
34
48
|
const [selection, setSelection] = useState<SourceSelection>();
|
|
35
|
-
const [showDiffPanel, setShowDiffPanel] = useState(
|
|
36
|
-
viewerDocument.sourceDiffs.length > 0,
|
|
37
|
-
);
|
|
49
|
+
const [showDiffPanel, setShowDiffPanel] = useState(false);
|
|
38
50
|
const hasSourceDiffs =
|
|
39
51
|
viewerDocument.sourceDiffs.length > 0 || viewerDocument.hasReferences;
|
|
40
52
|
const diffPanelOpen = hasSourceDiffs && showDiffPanel;
|
|
@@ -55,7 +67,64 @@ export function ViewerApp(props: {
|
|
|
55
67
|
const prose = useStyles(styles.prose);
|
|
56
68
|
const content = useStyles(proseHtml("md"), styles.content);
|
|
57
69
|
const closed = useStyles(styles.closed);
|
|
70
|
+
const closedCopy = useStyles(styles.closedCopy);
|
|
71
|
+
const stage = useStyles(styles.stage);
|
|
58
72
|
const articleRef = useRef<HTMLElement>(null);
|
|
73
|
+
const hasToc = hasTableOfContents(viewerDocument.headings);
|
|
74
|
+
const tocDismissed = useRef(false);
|
|
75
|
+
const tocPinned = useRef(false);
|
|
76
|
+
const tocFits = useRef(window.innerWidth >= TOC_OPEN_MIN_WIDTH_PX);
|
|
77
|
+
const remeasureToc = useRef<() => void>(() => {});
|
|
78
|
+
const [tocOpen, setTocOpen] = useState<TocMode | undefined>(() =>
|
|
79
|
+
hasToc && window.innerWidth >= TOC_OPEN_MIN_WIDTH_PX ? "space" : undefined,
|
|
80
|
+
);
|
|
81
|
+
const tocExpanded = tocOpen !== undefined;
|
|
82
|
+
const onDwellOpen = useCallback(() => {
|
|
83
|
+
setTocOpen((mode) =>
|
|
84
|
+
mode === "click" || mode === "space" ? mode : "dwell",
|
|
85
|
+
);
|
|
86
|
+
}, []);
|
|
87
|
+
const onDwellClose = useCallback(() => {
|
|
88
|
+
setTocOpen((mode) => {
|
|
89
|
+
if (mode === "click" || mode === "space") return mode;
|
|
90
|
+
if (tocFits.current && !tocDismissed.current) {
|
|
91
|
+
return tocPinned.current ? "click" : "space";
|
|
92
|
+
}
|
|
93
|
+
return undefined;
|
|
94
|
+
});
|
|
95
|
+
}, []);
|
|
96
|
+
|
|
97
|
+
useEffect(() => {
|
|
98
|
+
if (!hasToc) return;
|
|
99
|
+
const measure = () => {
|
|
100
|
+
const node = articleRef.current;
|
|
101
|
+
if (node !== null && node.clientWidth === 0) return;
|
|
102
|
+
const width = node?.clientWidth ?? window.innerWidth;
|
|
103
|
+
const next = width >= TOC_OPEN_MIN_WIDTH_PX;
|
|
104
|
+
const previous = tocFits.current;
|
|
105
|
+
tocFits.current = next;
|
|
106
|
+
if (previous === next) return;
|
|
107
|
+
if (!next) {
|
|
108
|
+
setTocOpen(undefined);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
setTocOpen((mode) => {
|
|
112
|
+
if (mode === "click" || mode === "dwell") return mode;
|
|
113
|
+
if (tocDismissed.current) return undefined;
|
|
114
|
+
return tocPinned.current ? "click" : "space";
|
|
115
|
+
});
|
|
116
|
+
};
|
|
117
|
+
remeasureToc.current = measure;
|
|
118
|
+
const observer = new ResizeObserver(measure);
|
|
119
|
+
const articleNode = articleRef.current;
|
|
120
|
+
if (articleNode) observer.observe(articleNode);
|
|
121
|
+
window.addEventListener("resize", measure);
|
|
122
|
+
return () => {
|
|
123
|
+
observer.disconnect();
|
|
124
|
+
window.removeEventListener("resize", measure);
|
|
125
|
+
remeasureToc.current = () => {};
|
|
126
|
+
};
|
|
127
|
+
}, [hasToc]);
|
|
59
128
|
|
|
60
129
|
useEffect(() => {
|
|
61
130
|
document.title = title;
|
|
@@ -68,7 +137,14 @@ export function ViewerApp(props: {
|
|
|
68
137
|
}, []);
|
|
69
138
|
|
|
70
139
|
if (shutDown) {
|
|
71
|
-
return
|
|
140
|
+
return (
|
|
141
|
+
<main className={closed}>
|
|
142
|
+
<div className={closedCopy}>
|
|
143
|
+
<H1>Closed spec</H1>
|
|
144
|
+
<P>The local server stopped.</P>
|
|
145
|
+
</div>
|
|
146
|
+
</main>
|
|
147
|
+
);
|
|
72
148
|
}
|
|
73
149
|
|
|
74
150
|
return (
|
|
@@ -76,18 +152,37 @@ export function ViewerApp(props: {
|
|
|
76
152
|
<div className={shell}>
|
|
77
153
|
<header className={header}>
|
|
78
154
|
<div className={heading}>
|
|
155
|
+
{hasToc && (
|
|
156
|
+
<TocButton
|
|
157
|
+
expanded={tocExpanded}
|
|
158
|
+
onClick={() => {
|
|
159
|
+
if (tocExpanded) {
|
|
160
|
+
tocDismissed.current = true;
|
|
161
|
+
tocPinned.current = false;
|
|
162
|
+
setTocOpen(undefined);
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
tocDismissed.current = false;
|
|
166
|
+
tocPinned.current = true;
|
|
167
|
+
setTocOpen("click");
|
|
168
|
+
}}
|
|
169
|
+
/>
|
|
170
|
+
)}
|
|
79
171
|
<div className={titleClass}>{title}</div>
|
|
80
172
|
</div>
|
|
81
173
|
<div className={actions}>
|
|
82
174
|
{hasSourceDiffs && (
|
|
83
175
|
<DiffButton
|
|
84
176
|
pressed={showDiffPanel}
|
|
85
|
-
onClick={() =>
|
|
177
|
+
onClick={() => {
|
|
178
|
+
setShowDiffPanel((open) => !open);
|
|
179
|
+
window.requestAnimationFrame(() => remeasureToc.current());
|
|
180
|
+
}}
|
|
86
181
|
/>
|
|
87
182
|
)}
|
|
88
183
|
{props.headerActions}
|
|
89
184
|
{props.mode === "local" && (
|
|
90
|
-
<
|
|
185
|
+
<CloseServerButton
|
|
91
186
|
onClick={() => {
|
|
92
187
|
setShutDown(true);
|
|
93
188
|
// oxlint-disable-next-line typescript/no-floating-promises -- React click callbacks cannot await the server shutdown request.
|
|
@@ -97,41 +192,53 @@ export function ViewerApp(props: {
|
|
|
97
192
|
)}
|
|
98
193
|
</div>
|
|
99
194
|
</header>
|
|
100
|
-
<div className={
|
|
101
|
-
<
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
195
|
+
<div className={stage}>
|
|
196
|
+
<div className={body} data-has-source-diffs={diffPanelOpen}>
|
|
197
|
+
<article ref={articleRef} className={article}>
|
|
198
|
+
<div className={prose} data-has-toc={hasToc ? "true" : "false"}>
|
|
199
|
+
<div className={content} data-diffmap-kind="page">
|
|
200
|
+
<ComarkView
|
|
201
|
+
document={viewerDocument}
|
|
202
|
+
selectedAnnotation={selection?.annotation}
|
|
203
|
+
onSelectAnnotation={(line) => {
|
|
204
|
+
setShowDiffPanel(true);
|
|
205
|
+
setSelection({
|
|
206
|
+
annotation: line,
|
|
207
|
+
reference: line.references[0]!,
|
|
208
|
+
});
|
|
209
|
+
window.requestAnimationFrame(() =>
|
|
210
|
+
remeasureToc.current(),
|
|
211
|
+
);
|
|
212
|
+
}}
|
|
213
|
+
/>
|
|
214
|
+
</div>
|
|
215
|
+
{hasToc && (
|
|
216
|
+
<TableOfContents
|
|
217
|
+
headings={viewerDocument.headings}
|
|
218
|
+
articleRef={articleRef}
|
|
219
|
+
open={tocExpanded}
|
|
220
|
+
onDwellOpen={onDwellOpen}
|
|
221
|
+
onDwellClose={onDwellClose}
|
|
222
|
+
/>
|
|
223
|
+
)}
|
|
119
224
|
</div>
|
|
120
|
-
</
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
225
|
+
</article>
|
|
226
|
+
{diffPanelOpen && (
|
|
227
|
+
<SourceDiffPanel
|
|
228
|
+
items={viewerDocument.sourceDiffs}
|
|
229
|
+
selection={selection}
|
|
230
|
+
onSelect={setSelection}
|
|
231
|
+
/>
|
|
232
|
+
)}
|
|
233
|
+
</div>
|
|
129
234
|
</div>
|
|
130
235
|
</div>
|
|
131
236
|
</ViewerModeContext.Provider>
|
|
132
237
|
);
|
|
133
238
|
}
|
|
134
239
|
|
|
240
|
+
type TocMode = "click" | "dwell" | "space";
|
|
241
|
+
|
|
135
242
|
function useViewerMeta(enabled: boolean) {
|
|
136
243
|
const [meta, setMeta] = useState<ViewerMeta>();
|
|
137
244
|
useEffect(() => {
|
|
@@ -161,7 +268,7 @@ const styles = {
|
|
|
161
268
|
backgroundColor: colors.gray[4],
|
|
162
269
|
}),
|
|
163
270
|
header: style(
|
|
164
|
-
flex({ direction: "row",
|
|
271
|
+
flex({ direction: "row", alignItems: "center", justifyContent: "between" }),
|
|
165
272
|
spacing.padding({ x: 6, y: 3 }),
|
|
166
273
|
flexItem({ size: "hug" }),
|
|
167
274
|
border(["bottom"], "border"),
|
|
@@ -170,8 +277,9 @@ const styles = {
|
|
|
170
277
|
backgroundColor: backgroundColor.app,
|
|
171
278
|
},
|
|
172
279
|
),
|
|
173
|
-
heading: style(flex({ direction: "
|
|
280
|
+
heading: style(flex({ direction: "row", alignItems: "center", gap: 3 }), {
|
|
174
281
|
minWidth: 0,
|
|
282
|
+
flex: "1 1 auto",
|
|
175
283
|
}),
|
|
176
284
|
title: style(text({ size: "md", fontWeight: 600, color: "highContrast" }), {
|
|
177
285
|
minWidth: 0,
|
|
@@ -179,38 +287,46 @@ const styles = {
|
|
|
179
287
|
textOverflow: "ellipsis",
|
|
180
288
|
whiteSpace: "nowrap",
|
|
181
289
|
}),
|
|
182
|
-
actions: style(flex({ direction: "row",
|
|
290
|
+
actions: style(flex({ direction: "row", alignItems: "center", gap: 3 }), {
|
|
183
291
|
flexShrink: 0,
|
|
184
292
|
}),
|
|
293
|
+
stage: style(flex({ direction: "column" }), {
|
|
294
|
+
position: "relative",
|
|
295
|
+
flex: "1 1 auto",
|
|
296
|
+
minWidth: 0,
|
|
297
|
+
minHeight: 0,
|
|
298
|
+
}),
|
|
185
299
|
body: style({
|
|
186
300
|
display: "grid",
|
|
187
|
-
gridTemplateColumns: "var(--diffmap-columns)",
|
|
188
301
|
gridTemplateRows: "minmax(0, 1fr)",
|
|
189
|
-
"--diffmap-columns": "minmax(0, max-content) minmax(0, 1fr)",
|
|
190
302
|
flex: "1 1 auto",
|
|
191
303
|
minHeight: 0,
|
|
192
304
|
minWidth: 0,
|
|
193
305
|
overflow: "hidden",
|
|
194
306
|
backgroundColor: backgroundColor.app,
|
|
307
|
+
"--diffmap-columns": "minmax(0, 1fr)",
|
|
308
|
+
"--diffmap-areas": '"article"',
|
|
309
|
+
gridTemplateColumns: "var(--diffmap-columns)",
|
|
310
|
+
gridTemplateAreas: "var(--diffmap-areas)",
|
|
195
311
|
"&[data-has-source-diffs='true']": {
|
|
196
|
-
"--diffmap-columns":
|
|
197
|
-
|
|
312
|
+
"--diffmap-columns": "minmax(0, 1fr) minmax(0, 1fr)",
|
|
313
|
+
"--diffmap-areas": '"article diff"',
|
|
198
314
|
},
|
|
199
315
|
"@media (max-width: 900px)": {
|
|
200
316
|
gridTemplateColumns: "minmax(0, 1fr)",
|
|
201
317
|
gridTemplateRows: "minmax(0, 1fr) auto",
|
|
318
|
+
gridTemplateAreas: '"article" "diff"',
|
|
202
319
|
},
|
|
203
320
|
}),
|
|
204
321
|
article: style(spacing.padding({ x: 12, y: 12 }), {
|
|
205
|
-
|
|
322
|
+
gridArea: "article",
|
|
206
323
|
flex: "1 1 auto",
|
|
207
324
|
minWidth: 0,
|
|
208
325
|
minHeight: 0,
|
|
209
326
|
overflowY: "auto",
|
|
210
327
|
backgroundColor: backgroundColor.app,
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
},
|
|
328
|
+
// Scrollport size for the sticky gutter rail (`100cqh`).
|
|
329
|
+
containerType: "size",
|
|
214
330
|
}),
|
|
215
331
|
prose: style({
|
|
216
332
|
display: "grid",
|
|
@@ -218,9 +334,13 @@ const styles = {
|
|
|
218
334
|
width: "100%",
|
|
219
335
|
maxWidth: "none",
|
|
220
336
|
minWidth: 0,
|
|
337
|
+
"&[data-has-toc='true']": {
|
|
338
|
+
gridTemplateColumns: `minmax(${String(TOC_SIDE_MARGIN_PX)}px, 1fr) minmax(0, ${proseMaxWidth}) minmax(${String(TOC_SIDE_MARGIN_PX)}px, 1fr)`,
|
|
339
|
+
},
|
|
221
340
|
}),
|
|
222
341
|
content: style({
|
|
223
342
|
gridColumn: "2 / 3",
|
|
343
|
+
gridRow: "1",
|
|
224
344
|
width: "100%",
|
|
225
345
|
maxWidth: "none",
|
|
226
346
|
minWidth: 0,
|
|
@@ -250,11 +370,23 @@ const styles = {
|
|
|
250
370
|
},
|
|
251
371
|
}),
|
|
252
372
|
closed: style(
|
|
253
|
-
|
|
254
|
-
|
|
373
|
+
flex({
|
|
374
|
+
direction: "column",
|
|
375
|
+
alignItems: "center",
|
|
376
|
+
justifyContent: "center",
|
|
377
|
+
}),
|
|
378
|
+
spacing.padding({ x: 12, y: 12 }),
|
|
255
379
|
{
|
|
256
380
|
minHeight: "100vh",
|
|
257
381
|
backgroundColor: backgroundColor.app,
|
|
258
382
|
},
|
|
259
383
|
),
|
|
384
|
+
closedCopy: style(
|
|
385
|
+
flex({ direction: "column", alignItems: "center", gap: 3 }),
|
|
386
|
+
{
|
|
387
|
+
width: "100%",
|
|
388
|
+
maxWidth: proseMaxWidth,
|
|
389
|
+
textAlign: "center",
|
|
390
|
+
},
|
|
391
|
+
),
|
|
260
392
|
};
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { useEffect, useState } from "react";
|
|
1
|
+
import { useEffect, useMemo, useState } from "react";
|
|
2
2
|
import type { CodeViewDiffItem, CodeViewLineSelection } from "@pierre/diffs";
|
|
3
3
|
import type { SourceReference } from "../annotations.js";
|
|
4
4
|
import type { SourceDefinition, DefinitionResponse } from "../definitions.js";
|
|
5
5
|
import { DiffmapDefinitionError } from "../errors.js";
|
|
6
6
|
import { useGitHubPin } from "../github/pin.ts";
|
|
7
7
|
import { fetchPinnedBlob, findSymbolLineRange } from "../github/fetchRepo.ts";
|
|
8
|
+
import { useHostFiles } from "../host/files.ts";
|
|
8
9
|
import { useViewerMode } from "./viewerMode.ts";
|
|
9
10
|
|
|
10
11
|
export async function requestSource(
|
|
@@ -46,10 +47,15 @@ export function useSourceReference(reference: SourceReference | undefined) {
|
|
|
46
47
|
result: SourceDefinition | Error;
|
|
47
48
|
}>();
|
|
48
49
|
const pin = useGitHubPin();
|
|
50
|
+
const hostFiles = useHostFiles();
|
|
49
51
|
const mode = useViewerMode();
|
|
52
|
+
const hostResult = useMemo(() => {
|
|
53
|
+
if (reference?.kind !== "file" || hostFiles === undefined) return undefined;
|
|
54
|
+
return readHostFileReference(hostFiles, reference);
|
|
55
|
+
}, [reference, hostFiles]);
|
|
50
56
|
useEffect(() => {
|
|
51
57
|
if (reference?.kind !== "file") return;
|
|
52
|
-
if (
|
|
58
|
+
if (hostFiles !== undefined) return;
|
|
53
59
|
let active = true;
|
|
54
60
|
if (pin !== undefined) {
|
|
55
61
|
// Pinned GitHub spec: load this path at the spec commit SHA, never main.
|
|
@@ -89,6 +95,7 @@ export function useSourceReference(reference: SourceReference | undefined) {
|
|
|
89
95
|
active = false;
|
|
90
96
|
};
|
|
91
97
|
}
|
|
98
|
+
if (mode !== "local") return;
|
|
92
99
|
const params = new URLSearchParams({ path: reference.path });
|
|
93
100
|
if (reference.symbol !== undefined) params.set("symbol", reference.symbol);
|
|
94
101
|
if (reference.start !== undefined)
|
|
@@ -101,10 +108,37 @@ export function useSourceReference(reference: SourceReference | undefined) {
|
|
|
101
108
|
return () => {
|
|
102
109
|
active = false;
|
|
103
110
|
};
|
|
104
|
-
}, [reference, pin, mode]);
|
|
111
|
+
}, [reference, pin, mode, hostFiles]);
|
|
112
|
+
if (hostResult !== undefined) return hostResult;
|
|
105
113
|
return resolution?.reference === reference ? resolution?.result : undefined;
|
|
106
114
|
}
|
|
107
115
|
|
|
116
|
+
function readHostFileReference(
|
|
117
|
+
files: Record<string, string>,
|
|
118
|
+
reference: Extract<SourceReference, { kind: "file" }>,
|
|
119
|
+
): SourceDefinition | Error {
|
|
120
|
+
const contents = files[reference.path];
|
|
121
|
+
if (contents === undefined) {
|
|
122
|
+
return new DiffmapDefinitionError({
|
|
123
|
+
reason: `No hosted file for ${reference.path}.`,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
const lineCount = Math.max(1, contents.split(/\r?\n/).length);
|
|
127
|
+
const range =
|
|
128
|
+
reference.symbol !== undefined
|
|
129
|
+
? findSymbolLineRange(contents, reference.symbol)
|
|
130
|
+
: {
|
|
131
|
+
start: reference.start ?? 1,
|
|
132
|
+
end: reference.end ?? lineCount,
|
|
133
|
+
};
|
|
134
|
+
return {
|
|
135
|
+
path: reference.path,
|
|
136
|
+
contents,
|
|
137
|
+
start: range.start,
|
|
138
|
+
end: range.end,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
108
142
|
export function matchingSourceDiff(
|
|
109
143
|
source: SourceDefinition,
|
|
110
144
|
items: CodeViewDiffItem[],
|
package/src/viewer/viewerMode.ts
CHANGED
package/vite.config.ts
CHANGED
package/src/viewer/Check.tsx
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import type { SVGProps } from "react";
|
|
2
|
-
|
|
3
|
-
export function Check(props: SVGProps<SVGSVGElement>) {
|
|
4
|
-
return (
|
|
5
|
-
<svg
|
|
6
|
-
focusable="false"
|
|
7
|
-
aria-hidden="true"
|
|
8
|
-
role="img"
|
|
9
|
-
width={24}
|
|
10
|
-
height={24}
|
|
11
|
-
fill="none"
|
|
12
|
-
viewBox="0 0 24 24"
|
|
13
|
-
{...props}
|
|
14
|
-
>
|
|
15
|
-
<path
|
|
16
|
-
stroke="currentColor"
|
|
17
|
-
strokeLinecap="round"
|
|
18
|
-
strokeLinejoin="round"
|
|
19
|
-
strokeWidth={1.5}
|
|
20
|
-
d="M5.75 12.5L10 16.75L18.25 7.25"
|
|
21
|
-
/>
|
|
22
|
-
</svg>
|
|
23
|
-
);
|
|
24
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { Button, background, colors, iconSizeValues, text } from "maui";
|
|
2
|
-
import { style, useStyles } from "purse-styles";
|
|
3
|
-
import { Check } from "./Check.tsx";
|
|
4
|
-
|
|
5
|
-
const checkIcon = style({
|
|
6
|
-
width: iconSizeValues.sm,
|
|
7
|
-
height: iconSizeValues.sm,
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
export function DoneButton(props: { onClick?: () => void }) {
|
|
11
|
-
const checkClass = useStyles(checkIcon);
|
|
12
|
-
const primaryClass = useStyles(primaryButtonClass);
|
|
13
|
-
return (
|
|
14
|
-
<Button className={primaryClass} onClick={props.onClick}>
|
|
15
|
-
<Check className={checkClass} />
|
|
16
|
-
Done
|
|
17
|
-
</Button>
|
|
18
|
-
);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const primaryButtonClass = style(
|
|
22
|
-
background.accent,
|
|
23
|
-
text({ size: "xs", fontWeight: 400, color: "onAccent" }),
|
|
24
|
-
{
|
|
25
|
-
"&:hover": {
|
|
26
|
-
backgroundColor: colors.accent[10],
|
|
27
|
-
},
|
|
28
|
-
"&:active": {
|
|
29
|
-
backgroundColor: colors.accent[11],
|
|
30
|
-
},
|
|
31
|
-
},
|
|
32
|
-
);
|