Files
wasmeld/crates/wasmeld-console/web/src/pages/main.tsx
T
Maofeng 9ff3223c44 refactor(console-web): centralize page lifecycle and UI composition
Declare navigation, page metadata, lazy loaders, and keep-alive policy in one registry. Retain primary iframe pages until a continuous inactive TTL expires and expose typed show, hide, and unload events through the Page SDK.

Move business-aware components out of the UI primitive directory, migrate views and Host dialogs to variant primitives and local Tailwind classes, and remove the global component style layer. Keep native dialogs inside the overlay flex context so they remain centered.

Cover iframe expiration, lifecycle dispatch, UI dependency direction, and global style ownership with focused tests.
2026-07-30 15:16:02 +08:00

54 lines
1.7 KiB
TypeScript

import { AlertTriangle, LoaderCircle } from "lucide-solid";
import { lazy, Show, Suspense } from "solid-js";
import { render } from "solid-js/web";
import { createFrameBridge } from "../primitives/create-frame-bridge";
import "../styles/app.css";
import { isView, pageDefinition } from "./registry";
function FramePage() {
const requested = new URLSearchParams(window.location.search).get("view");
const view = isView(requested) ? requested : null;
return (
<Show
when={view}
fallback={
<main class="flex min-h-dvh items-center justify-center p-6 text-center text-coral-strong">
<div>
<AlertTriangle class="mx-auto mb-3" size={28} />
<strong class="block">未知页面</strong>
<span class="mt-1 block text-sm text-muted">{requested ?? "(empty)"}</span>
</div>
</main>
}
>
{(activeView) => {
const bridge = createFrameBridge(activeView());
const definition = pageDefinition(activeView());
const Page = lazy(definition.load);
document.title = `${definition.label} · Wasmeld`;
return (
<Suspense
fallback={
<main class="flex min-h-dvh items-center justify-center text-muted">
<LoaderCircle class="animate-spin" size={24} />
</main>
}
>
<Page
state={bridge.state}
active={bridge.active}
lifecycle={bridge.lifecycle}
command={bridge.command}
/>
</Suspense>
);
}}
</Show>
);
}
const root = document.getElementById("app");
if (!root) throw new Error("missing #app root");
render(() => <FramePage />, root);