Add loaded dialog prototype - #9
Conversation
Roam prototype previewsThe preview deployment is ready. Paste a URL below into Load Developer Extensions from URL in Roam: |
| export default runExtension(async () => { | ||
| await renderAlert({ | ||
| content: "Loaded Dialog has loaded successfully.", | ||
| confirmText: "Got it", | ||
| }); | ||
| }); |
There was a problem hiding this comment.
🟡 Dialog can stay on screen after the extension is turned off
The confirmation dialog is opened without keeping any handle to close it (renderAlert(...) at prototypes/loaded-dialog/src/index.ts:6-9) and no cleanup step is returned, so a dialog still on screen when the extension is disabled or reloaded stays there forever.
Impact: A user who disables or reloads the extension while the dialog is open is left with a stuck dialog, and reloading repeatedly can stack leftover dialogs.
Overlay mount is never registered with the runExtension lifecycle
roamjs-components/components/SimpleAlert's render is built with createOverlayRender, which appends its own container to the document and returns an unmount function. The prototype discards that return value and, unlike the scaffold template (packages/extension-base/template/src/index.ts:17-21), does not return an unload handler from the runExtension callback, so nothing removes the container or unmounts the React tree at unload time. AGENTS.md requires "Dispose observers, listeners, commands, timers, and mounted UI when the extension unloads", and packages/extension-base/skills/react-rendering/SKILL.md:23 requires owned React roots/containers to be registered for cleanup. The PR description's claim that runExtension owns the mounted alert does not hold because the overlay is mounted outside the registry.
| export default runExtension(async () => { | |
| await renderAlert({ | |
| content: "Loaded Dialog has loaded successfully.", | |
| confirmText: "Got it", | |
| }); | |
| }); | |
| export default runExtension(async () => { | |
| const unmountAlert = renderAlert({ | |
| content: "Loaded Dialog has loaded successfully.", | |
| confirmText: "Got it", | |
| }); | |
| return { | |
| unload: () => { | |
| unmountAlert?.(); | |
| }, | |
| }; | |
| }); |
Was this helpful? React with 👍 or 👎 to provide feedback.
Summary
loaded-dialogRoam developer-extension prototypeWhy
This provides a minimal installable prototype that visibly confirms successful extension loading.
User impact
Loading the extension opens a dialog that says the extension loaded successfully and provides a single Got it action. The shared
runExtensionlifecycle owns and cleans up the mounted alert.Validation
pnpm testpnpm buildpnpm prepare:artifacts