Modal Component
Availability and browser boundary
Modal and ModalManager are experimental root exports for Node-side code.
They are not exported by @tagna/udiot/browser in this release. Do not
import the root entry into a client bundle: it also re-exports Node-only code.
There is no supported public browser import for these modal classes yet.
Rendering a shell on the server does not hydrate it or recreate its instance in
the browser. In a page where the same instance rendered the markup, open()
shows it, and a closable modal closes with its close button or Escape (no
inline scripts, so a content security policy does not block it). Use an
application-owned dialog implementation for server-rendered pages. See
browser applications and
hydration boundaries.
Node-side shell rendering
This complete example tests HTML generation only, not browser interaction:
import assert from 'node:assert/strict';
import { Modal } from '@tagna/udiot';
const modal = new Modal({
title: 'Information',
content: '<p>Application-owned, trusted content.</p>',
closable: false,
});
const html = modal.render();
assert.ok(html.includes('Information'));
assert.ok(html.includes('display: none;'));
assert.equal(modal.isModalOpen(), false);
The shell is hidden initially. closable: false avoids emitting the built-in
close button, whose inline handler depends on an unavailable client manager.
The HTML alone is not a usable interactive dialog.
API and limitations
| API | Current behavior |
|---|---|
new Modal(options) |
Accepts title, content, footer, width, height, closable, overlay, onOpen and onClose options. |
render() |
Returns the hidden HTML shell and a style block. Does not access the DOM. |
open() / close() |
Access document and change overlay visibility. Not callable in a normal Node process. |
updateContent(html) |
Accesses document and assigns raw HTML to the body when found. |
isModalOpen() |
Returns an internal flag, not computed DOM visibility. |
setStyler(styler) |
Stores a styler; render() does not consume it. |
ModalManager |
Registers instances by key and forwards open/close/closeAll calls. Does not hydrate server markup. |
overlay is declared but not used to hide the backdrop. Every render includes
global class selectors and animation names; the styles are not isolated by
Shadow DOM. Generated element IDs are random, not a hydration identity contract.
content and footer are inserted as raw HTML. Only use trusted markup or
application-sanitized content; never interpolate untrusted values directly.
Title and dimension strings are HTML-escaped, but this does not validate CSS
values or sanitize body HTML.
The implementation does not provide focus trapping, Escape-key handling or a complete accessible dialog lifecycle. Do not treat server rendering as proof of browser support or accessibility compliance.