dorfteich/apps/web/src/editor/plugin-block-context.tsx
Claude Fable 5 36cdd4fbca Editor: confirm snapshots with a toast; wire ui.toast for plugins (#130)
Cmd/Ctrl+S used to snapshot silently. A new app-wide ToastProvider
(components/Toast.tsx) owns a bottom-center stack — permanent polite
live region, auto-dismiss after 2.5 s, click to dismiss early, error
variant. Both snapshot paths (the keyboard chords in PageEditorPage and
the save-version TopBar button) now confirm with the version name when
there is one, and their failure alert becomes an error toast.

The plugin host capability ui.toast (declared since #74, wired
nowhere) connects to the same stack: PluginBlockScope carries the
showToast handle, plugin-block passes it into the sandbox context.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fb2VzvcoBPHkjh8bZ6PzQn
2026-07-16 12:03:17 +02:00

26 lines
995 B
TypeScript

import { createContext, useContext } from 'react';
/**
* The page surface plugin blocks run against (issue #76). Provided by the
* page editor around its `EditorContent`, consumed by the `plugin_block`
* node views — the same React-context route the wikilink node view uses, so
* the TipTap extension needs no per-page configuration and the editor never
* rebuilds when plugin data loads.
*/
export interface PluginBlockScope {
pageId?: string;
pondId?: string;
/** Navigate to a page (backs the `ui.openPage` capability). */
openPage?: (pageId: string) => void;
/** Show a message in the app's toast stack (`ui.toast`, #130). */
toast?: (message: string) => void;
/** Scroll the content to a heading by outline id (`ui.scrollToHeading`, #77). */
scrollToHeading?: (headingId: string) => void;
}
export const PluginBlockContext = createContext<PluginBlockScope>({});
export function usePluginBlockScope(): PluginBlockScope {
return useContext(PluginBlockContext);
}