@tour-kit/announcementsHeadless
HeadlessModal
HeadlessAnnouncementModal: unstyled dialog primitive with focus trap, backdrop click, and Escape key dismiss handling
domidex01Published
Unstyled modal component that provides state and behavior through render props.
Render Props
Prop
Type
Example
import { HeadlessModal } from '@tour-kit/announcements/headless';
<HeadlessModal
id="welcome"
render={({ isVisible, config, hide, dismiss, titleId, descriptionId }) => {
if (!isVisible) return null;
return (
<div className="modal-container">
<div className="overlay" onClick={hide} />
<div
role="dialog"
aria-modal="true"
aria-labelledby={titleId}
aria-describedby={descriptionId}
className="modal-content"
>
<h2 id={titleId}>{config.title}</h2>
<p id={descriptionId}>{config.description}</p>
<button onClick={hide}>Close</button>
<button onClick={() => dismiss()}>Don't Show Again</button>
</div>
</div>
);
}}
/>Related
<Modal>— styled counterpart with default backdrop, focus trap, and Escape handling.<HeadlessBanner>,<HeadlessSlideout>,<HeadlessToast>,<HeadlessSpotlight>— sibling headless primitives for the other display variants.- Headless overview — when to reach for headless vs. styled.
useAnnouncement— the hook this primitive exposes via render props.useFocusTrap— mandatory for custom modal implementations.- Accessibility guide —
role="dialog"andaria-modalrequirements.
Ship onboarding, not config.
npm i @tour-kit/core is free while you build. Every package works unlicensed in development, a one-time licence from $9.99 removes the production watermark when you ship.
Free in development, no signup, no credit card. Pay once, only when you ship.