Skip to content

Commit ccc37a6

Browse files
chore: Fix reactivity
1 parent 817c37b commit ccc37a6

15 files changed

Lines changed: 70 additions & 64 deletions

File tree

packages/viola/src/components/content-editor/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ export function EditArea() {
7676
}
7777

7878
export default function ContentEditor({ contentId }: { contentId: ContentId }) {
79-
const contentSnap = useSnapshot($content).valueOrThrow;
80-
const themeSnap = useSnapshot($theme).valueOrThrow;
79+
const contentSnap = useSnapshot($content).valueOrThrow();
80+
const themeSnap = useSnapshot($theme).valueOrThrow();
8181
const file = contentSnap.files.get(contentId);
8282
invariant(file, `Editor not found for contentId: ${contentId}`);
8383

packages/viola/src/components/iframe-sandbox.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ function init(iframe: HTMLIFrameElement, sandbox: Sandbox) {
6666
}
6767

6868
export function IframeSandbox() {
69-
const project = useSnapshot($project).valueOrThrow;
69+
const project = useSnapshot($project).valueOrThrow();
7070
const sandbox = use(project.sandboxPromise);
7171

7272
return createPortal(

packages/viola/src/components/panes/pane.bibliography.tsx

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,11 @@ function BookTitleInput({
4343
...props
4444
}: React.PropsWithChildren<React.ComponentProps<typeof Input>>) {
4545
const inputProps = useLiveInputField(
46-
() => $project.valueOrThrow.bibliography.title,
46+
() => $project.valueOrThrow().bibliography.title,
4747
{
4848
onSave: (value) => {
4949
const title = value.trim();
50-
$project.valueOrThrow.bibliography.title = title;
50+
$project.valueOrThrow().bibliography.title = title;
5151
return title;
5252
},
5353
},
@@ -66,11 +66,11 @@ function AuthorInput({
6666
...props
6767
}: React.PropsWithChildren<React.ComponentProps<typeof Input>>) {
6868
const inputProps = useLiveInputField(
69-
() => $project.valueOrThrow.bibliography.author,
69+
() => $project.valueOrThrow().bibliography.author,
7070
{
7171
onSave: (value) => {
7272
const author = value.trim();
73-
$project.valueOrThrow.bibliography.author = author;
73+
$project.valueOrThrow().bibliography.author = author;
7474
return author;
7575
},
7676
},
@@ -89,10 +89,10 @@ function UseTocSwitch({
8989
...props
9090
}: React.PropsWithChildren<React.ComponentProps<typeof Switch>>) {
9191
const inputProps = useLiveCheckboxField(
92-
() => $project.valueOrThrow.toc.enabled,
92+
() => $project.valueOrThrow().toc.enabled,
9393
{
9494
onSave: (value) => {
95-
$project.valueOrThrow.toc.enabled = value;
95+
$project.valueOrThrow().toc.enabled = value;
9696
},
9797
},
9898
);
@@ -109,13 +109,16 @@ function TocTitleInput({
109109
children,
110110
...props
111111
}: React.PropsWithChildren<React.ComponentProps<typeof Input>>) {
112-
const inputProps = useLiveInputField(() => $project.valueOrThrow.toc.title, {
113-
onSave: (value) => {
114-
const title = value.trim();
115-
$project.valueOrThrow.toc.title = title;
116-
return title;
112+
const inputProps = useLiveInputField(
113+
() => $project.valueOrThrow().toc.title,
114+
{
115+
onSave: (value) => {
116+
const title = value.trim();
117+
$project.valueOrThrow().toc.title = title;
118+
return title;
119+
},
117120
},
118-
});
121+
);
119122

120123
return (
121124
<label className="contents">
@@ -130,10 +133,10 @@ function TocSectionDepthSelect({
130133
...props
131134
}: React.PropsWithChildren<React.ComponentProps<typeof Select>>) {
132135
const inputProps = useLiveSelectField(
133-
() => `${$project.valueOrThrow.toc.sectionDepth}`,
136+
() => `${$project.valueOrThrow().toc.sectionDepth}`,
134137
{
135138
onSave: (value) => {
136-
$project.valueOrThrow.toc.sectionDepth = value ? Number(value) : 0;
139+
$project.valueOrThrow().toc.sectionDepth = value ? Number(value) : 0;
137140
},
138141
},
139142
);
@@ -160,7 +163,7 @@ function TocSectionDepthSelect({
160163
}
161164

162165
function Content(_: BibliographyPaneProperty) {
163-
const projectSnap = useSnapshot($project).valueOrThrow;
166+
const projectSnap = useSnapshot($project).valueOrThrow();
164167

165168
return (
166169
<div className="grid gap-4">

packages/viola/src/components/panes/pane.edit.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ export const Pane = createPane<EditPaneProperty>({
2525
const ContentEditor = lazy(() => import('../content-editor'));
2626

2727
function Title({ contentId }: EditPaneProperty) {
28-
const content = useSnapshot($content).valueOrThrow;
29-
const file = content.files.get(contentId);
28+
const content = useSnapshot($content).value();
29+
const file = content?.files.get(contentId);
3030
return file ? `Content Editor: File ${file.filename}` : `Content Editor`;
3131
}
3232

packages/viola/src/components/panes/pane.preview.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { use } from 'react';
2+
import { useSnapshot } from 'valtio';
23

34
import { $cli } from '../../stores/accessors';
45
import { createPane } from './util';
@@ -17,11 +18,12 @@ export const Pane = createPane<PreviewPaneProperty>({
1718
});
1819

1920
function Content(_: PreviewPaneProperty) {
20-
const url = use($cli.valueOrThrow.createViewerUrlPromise());
21+
const cliSnap = useSnapshot($cli).valueOrThrow();
22+
const url = use(cliSnap.createViewerUrlPromise());
2123

2224
return (
2325
<iframe
24-
ref={(el) => $cli.valueOrThrow.viewerIframeRef(el)}
26+
ref={(el) => cliSnap.viewerIframeRef(el)}
2527
title="Preview"
2628
src={url}
2729
className="size-full"

packages/viola/src/components/panes/pane.theme.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ function LoadingIcon({ className, ...props }: React.ComponentProps<'span'>) {
5656
}
5757

5858
function Content(_: ThemePaneProperty) {
59-
const themeSnap = useSnapshot($theme).valueOrThrow;
59+
const themeSnap = useSnapshot($theme).valueOrThrow();
6060
const usesCustomTheme = !officialThemes.some(
6161
(t) => t.packageName === themeSnap.packageName,
6262
);
@@ -70,8 +70,8 @@ function Content(_: ThemePaneProperty) {
7070

7171
useDebounce(
7272
() => {
73-
$theme.valueOrThrow.customCss = customCss;
74-
$sandbox.valueOrThrow.files['style.css'] = ref(
73+
$theme.valueOrThrow().customCss = customCss;
74+
$sandbox.valueOrThrow().files['style.css'] = ref(
7575
new Blob([customCss], { type: 'text/css' }),
7676
);
7777
},

packages/viola/src/components/side-menu.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ function ProjectDropdownMenu({ children }: React.PropsWithChildren) {
143143
}
144144

145145
function TopMenuSection() {
146-
const projectSnap = useSnapshot($project.valueOrThrow);
146+
const projectSnap = useSnapshot($project).valueOrThrow();
147147
return (
148148
<SidebarMenu>
149149
<div className={cn('flex items-center gap-0.5')}>
@@ -214,7 +214,7 @@ function FileTreeItem({
214214
name: string;
215215
}
216216
>) {
217-
const content = useSnapshot($content).valueOrThrow;
217+
const content = useSnapshot($content).valueOrThrow();
218218
const draggingContentId = useContext(DraggingContentContext);
219219
const sortable = typeof item === 'string' && useSortable({ id: item });
220220

@@ -270,7 +270,7 @@ function FileTreeItem({
270270

271271
function FileTreeDraggingItem() {
272272
const draggingContentId = useContext(DraggingContentContext);
273-
const content = useSnapshot($content).valueOrThrow;
273+
const content = useSnapshot($content).valueOrThrow();
274274
const file = draggingContentId && content.files.get(draggingContentId);
275275

276276
if (!file) {
@@ -316,7 +316,7 @@ function FileTreeGroup({ tree }: { tree: HierarchicalReadingOrder }) {
316316
}
317317

318318
function FileTree() {
319-
const content = useSnapshot($content).valueOrThrow;
319+
const content = useSnapshot($content).valueOrThrow();
320320
const sensors = useSensors(
321321
useSensor(MouseSensor, { activationConstraint: { distance: 5 } }),
322322
useSensor(TouchSensor, {

packages/viola/src/libs/editor.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,9 @@ async function _setupPersistence({
9090

9191
const saveContent = debounce(
9292
async ({ editor, contentId }: { editor: Editor; contentId: ContentId }) => {
93-
const file = $content.valueOrThrow.files.get(contentId);
93+
const $$content = $content.valueOrThrow();
94+
const $$sandbox = $sandbox.valueOrThrow();
95+
const file = $$content.files.get(contentId);
9496
if (!file) {
9597
return;
9698
}
@@ -101,11 +103,8 @@ const saveContent = debounce(
101103
.find((s) => s.trim())
102104
?.trim() || '';
103105
const markdown = editor.getMarkdown();
104-
$sandbox.valueOrThrow.files[
105-
join(
106-
$sandbox.valueOrThrow.vivliostyleConfig.entryContext || '',
107-
file.filename,
108-
)
106+
$$sandbox.files[
107+
join($$sandbox.vivliostyleConfig.entryContext || '', file.filename)
109108
] = ref(new Blob([markdown], { type: 'text/markdown' }));
110109
},
111110
1000,

packages/viola/src/routes/(main)/_layout/edit/$.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@ export const Route = createFileRoute('/(main)/_layout/edit/$')({
88
if (preload) {
99
return;
1010
}
11-
await $project.valueOrThrow.setupPromise;
12-
const result = $content.valueOrThrow.getFileByFilename(params._splat || '');
11+
await $project.valueOrThrow().setupPromise;
12+
const result = $content
13+
.valueOrThrow()
14+
.getFileByFilename(params._splat || '');
1315
const contentId = result?.[0];
1416
if (!contentId) {
1517
throw redirect({ to: '/' });

packages/viola/src/stores/accessors.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ function createProxyGetter<S extends unknown[], T>(
1414
) {
1515
const proxied = proxy({
1616
_dependencies: dependencies,
17-
get value() {
17+
value() {
1818
return getter(...this._dependencies);
1919
},
20-
get valueOrThrow() {
21-
const value = this.value;
20+
valueOrThrow() {
21+
const value = this.value();
2222
invariant(value, message);
2323
return value;
2424
},
@@ -36,24 +36,24 @@ export const $project = createProxyGetter(
3636

3737
export const $content = createProxyGetter(
3838
[$project],
39-
(project) => project.value?.content,
39+
(project) => project.value()?.content,
4040
'$content is not available',
4141
);
4242

4343
export const $sandbox = createProxyGetter(
4444
[$project],
45-
(project) => project.value?.sandbox,
45+
(project) => project.value()?.sandbox,
4646
'$sandbox is not available',
4747
);
4848

4949
export const $cli = createProxyGetter(
5050
[$sandbox],
51-
(sandbox) => sandbox.value?.cli,
51+
(sandbox) => sandbox.value()?.cli,
5252
'$cli is not available',
5353
);
5454

5555
export const $theme = createProxyGetter(
5656
[$project],
57-
(project) => project.value?.theme,
57+
(project) => project.value()?.theme,
5858
'$theme is not available',
5959
);

0 commit comments

Comments
 (0)