Use HashRouter, add NavbarContext

This commit is contained in:
2025-08-30 11:15:18 -07:00
parent d1574d60da
commit 097d06e53b
5 changed files with 82 additions and 32 deletions
+10
View File
@@ -9,6 +9,7 @@
"version": "0.1.0",
"license": "ISC",
"dependencies": {
"@solidjs/router": "^0.15.3",
"codemirror": "^6.0.2",
"idb": "^8.0.3",
"lodash": "^4.17.21",
@@ -1177,6 +1178,15 @@
"win32"
]
},
"node_modules/@solidjs/router": {
"version": "0.15.3",
"resolved": "https://registry.npmjs.org/@solidjs/router/-/router-0.15.3.tgz",
"integrity": "sha512-iEbW8UKok2Oio7o6Y4VTzLj+KFCmQPGEpm1fS3xixwFBdclFVBvaQVeibl1jys4cujfAK5Kn6+uG2uBm3lxOMw==",
"license": "MIT",
"peerDependencies": {
"solid-js": "^1.8.6"
}
},
"node_modules/@types/babel__core": {
"version": "7.20.5",
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
+1
View File
@@ -21,6 +21,7 @@
"vite-plugin-solid": "^2.10.2"
},
"dependencies": {
"@solidjs/router": "^0.15.3",
"codemirror": "^6.0.2",
"idb": "^8.0.3",
"lodash": "^4.17.21",
+42 -12
View File
@@ -1,25 +1,55 @@
import { createSignal, Show } from 'solid-js';
import {
createContext,
createSignal,
Show,
useContext,
type Accessor,
type Setter,
} from 'solid-js';
import Chooser from './Chooser';
import Editor from './Editor';
import { HashRouter, Route, useNavigate } from '@solidjs/router';
function App() {
const [currentFile, setCurrentFile] = createSignal<string | null>(null);
interface NavbarProps {
fileId: Accessor<string | null>;
setFileId: Setter<string | null>;
}
const NavbarContext = createContext<NavbarProps>();
export function useNavbar(): NavbarProps {
const result = useContext(NavbarContext);
if (!result) {
throw new Error('NavbarContext not set');
}
return result;
}
function Layout(props: any) {
const navigate = useNavigate();
const [fileId, setFileId] = createSignal<string | null>(null);
return (
<NavbarContext.Provider value={{ fileId, setFileId }}>
<div class="app">
<div class="navbar">
<Show when={currentFile() !== null}>
<button onclick={() => setCurrentFile(null)}>Back</button>
<Show when={fileId() !== null}>
<button onclick={() => navigate('/')}>Back</button>
</Show>
<div class="title">{currentFile() ?? 'Choose a file'}</div>
<div class="title">{fileId() ?? 'Choose a file'}</div>
</div>
<Show
when={currentFile()}
fallback={<Chooser file={currentFile} setFile={setCurrentFile} />}
>
<Editor file={currentFile()!} />
</Show>
{props.children}
</div>
</NavbarContext.Provider>
);
}
function App() {
return (
<HashRouter root={Layout}>
<Route path="" component={Chooser} />
<Route path="doc/:id" component={Editor} />
</HashRouter>
);
}
+9 -8
View File
@@ -1,21 +1,22 @@
import { For, type Accessor, type Setter } from 'solid-js';
import { For, onMount } from 'solid-js';
import './Chooser.css';
import { useNavbar } from './App';
import { useNavigate } from '@solidjs/router';
interface ChooserProps {
file: Accessor<string | null>;
setFile: Setter<string | null>;
}
function Chooser() {
const navigate = useNavigate();
const { setFileId } = useNavbar();
onMount(() => setFileId(null));
function Chooser(props: ChooserProps) {
const files = ['foo', 'bar', 'baz'];
return (
<>
<For each={files}>
{(availableFile) => (
<button class="file" onclick={() => props.setFile(availableFile)}>
<button class="file" onclick={() => navigate(`doc/${availableFile}`)}>
{availableFile}
{availableFile === props.file() ? '(*)' : ''}
{/* {availableFile === props.file() ? '(*)' : ''} */}
</button>
)}
</For>
+16 -8
View File
@@ -6,19 +6,27 @@ import {
syntaxHighlighting,
} from '@codemirror/language';
import { yCollab } from 'y-codemirror.next';
import { createEffect, createResource, onCleanup, Show } from 'solid-js';
import {
createEffect,
createResource,
onCleanup,
onMount,
Show,
} from 'solid-js';
import { LocalDocument } from '../sync';
import { useNavbar } from './App';
import { useParams } from '@solidjs/router';
interface EditorProps {
file: string;
}
function Editor() {
const { id: fileId } = useParams();
const { setFileId } = useNavbar();
onMount(() => {
setFileId(fileId);
});
function Editor(props: EditorProps) {
let editorDiv;
let editorView: EditorView;
const [syncedDoc] = createResource(async () =>
LocalDocument.load(props.file)
);
const [syncedDoc] = createResource(async () => LocalDocument.load(fileId));
createEffect(() => {
const doc = syncedDoc();