Simplify modal rendering with dedicated DOM root

This commit is contained in:
Chris Wanstrath 2026-03-03 12:46:20 -08:00
parent 002f0a64ef
commit 577bec0d5c
4 changed files with 8 additions and 10 deletions

View File

@ -14,7 +14,6 @@ import {
import { AppDetail } from './AppDetail' import { AppDetail } from './AppDetail'
import { AppSelector } from './AppSelector' import { AppSelector } from './AppSelector'
import { DashboardLanding } from './DashboardLanding' import { DashboardLanding } from './DashboardLanding'
import { Modal } from './modal'
import { SettingsPage } from './SettingsPage' import { SettingsPage } from './SettingsPage'
import { Sidebar } from './Sidebar' import { Sidebar } from './Sidebar'
@ -55,7 +54,6 @@ export function Dashboard({ render }: { render: () => void }) {
<Styles /> <Styles />
{!isNarrow && <Sidebar render={render} />} {!isNarrow && <Sidebar render={render} />}
<MainContent render={render} /> <MainContent render={render} />
<Modal />
</Layout> </Layout>
) )
} }

View File

@ -1,19 +1,20 @@
import type { Child } from 'hono/jsx' import type { Child } from 'hono/jsx'
import { render } from 'hono/jsx/dom'
import { define } from '@because/forge' import { define } from '@because/forge'
import { theme } from '../themes' import { theme } from '../themes'
let modalTitle: string | null = null let modalTitle: string | null = null
let modalContent: (() => Child) | null = null let modalContent: (() => Child) | null = null
let renderFn: (() => void) | null = null
export const initModal = (render: () => void) => { const renderModal = () => {
renderFn = render const root = document.getElementById('modal')
if (root) render(<Modal />, root)
} }
export const openModal = (title: string, content: () => Child) => { export const openModal = (title: string, content: () => Child) => {
modalTitle = title modalTitle = title
modalContent = content modalContent = content
renderFn?.() renderModal()
requestAnimationFrame(() => { requestAnimationFrame(() => {
document.querySelector<HTMLInputElement>('[data-modal-body] input')?.focus() document.querySelector<HTMLInputElement>('[data-modal-body] input')?.focus()
}) })
@ -22,11 +23,11 @@ export const openModal = (title: string, content: () => Child) => {
export const closeModal = () => { export const closeModal = () => {
modalTitle = null modalTitle = null
modalContent = null modalContent = null
renderFn?.() renderModal()
} }
export const rerenderModal = () => { export const rerenderModal = () => {
renderFn?.() renderModal()
} }
// ESC key handler // ESC key handler

View File

@ -1,6 +1,5 @@
import { render as renderApp } from 'hono/jsx/dom' import { render as renderApp } from 'hono/jsx/dom'
import { Dashboard } from './components' import { Dashboard } from './components'
import { initModal } from './components/modal'
import { initRouter, navigate } from './router' import { initRouter, navigate } from './router'
import { apps, dashboardTab, getSelectedTab, selectedApp, setApps, setIsNarrow } from './state' import { apps, dashboardTab, getSelectedTab, selectedApp, setApps, setIsNarrow } from './state'
import { initToolIframes, updateToolIframes } from './tool-iframes' import { initToolIframes, updateToolIframes } from './tool-iframes'
@ -21,7 +20,6 @@ const render = () => {
} }
// Initialize render functions // Initialize render functions
initModal(render)
initUpdate(render) initUpdate(render)
initToolIframes() initToolIframes()

View File

@ -9,6 +9,7 @@ export const Shell = () => (
</head> </head>
<body> <body>
<div id="app"></div> <div id="app"></div>
<div id="modal"></div>
<div id="tool-iframes"></div> <div id="tool-iframes"></div>
<script type="module" src="/client/index.js"></script> <script type="module" src="/client/index.js"></script>
</body> </body>