Components
Components
<ModalTarget>
The host where modals of one group are rendered. Mount one per group.
Props
interface ModalTargetProps extends ModalBehaviorOptions {
group: ModalGroup // required, type-checked against ModalGroupRegistry
enableInteractOutside?: boolean
disableCloseOnInteractOutside?: boolean
disableCloseOnInteractOverlay?: boolean
disableLockBodyScroll?: boolean
disableCloseOnEscape?: boolean
}
See Behavior options for what each flag does.
Slots
default— user content placed inside[data-modal-region]. Typically<ModalOverlay>. Active modals are rendered alongside automatically.
Emitted events
None.
Data attributes
[data-modal-region]— root element.position: fixed; inset: 0; pointer-events: none.
See Types for ModalTargetProps and ModalBehaviorOptions.
<ModalRoot>
Per-modal wrapper. Owns DialogRoot from reka-ui, computes dataState/instantEnter, exposes close intents to <ModalContent>.
Must contain <ModalContent> — without it, exit animations never finalize.
Props
Empty interface — all behavior options live on <ModalTarget> or in createModal({ groups }).
Slots
default— your modal markup. Must contain<ModalContent>.
Emitted events
None.
Throws
- If used outside a modal opened via
openModal/useModal. Exact message:[@kolirt/vue-modal] <ModalRoot> must be used inside a modal opened via openModal/useModal. - If rendered outside a
<ModalTarget>tree. Exact message:[@kolirt/vue-modal] <ModalRoot> must be rendered inside a <ModalTarget> tree.
Data attributes
[data-modal-root]— wrapperdivrendered inside reka-ui'sDialogRoot.position: absolute; inset: 0; pointer-events: auto.inheritAttrs: false;$attrs(includingclass,style) forward to thisdiv.
<ModalContent>
Required inside <ModalRoot>. Wraps reka-ui's DialogContent — focus trap and presence management.
Props
None. inheritAttrs: false; $attrs (including class, style, aria-*) forward to the inner DialogContent.
Slots
default— card markup.
Emitted events
None.
Data attributes
[data-modal-content]— root element.data-state="open" | "closed"— animation hook.data-instant=""— present for the lifetime of a modal opened withinstantEnter: true. Bundled CSS rule scoped to[data-state="open"]suppresses the enter animation; the close animation still runs because suppression doesn't apply whendata-state="closed".
Throws
- If used outside
<ModalRoot>. Exact message:[@kolirt/vue-modal] <ModalContent> must be used inside <ModalRoot>.
<ModalTitle>
Optional. Wraps reka-ui's DialogTitle. Auto-wires aria-labelledby on DialogContent.
<ModalContent>
<ModalTitle class="text-lg font-bold">Confirm</ModalTitle>
</ModalContent>
Props
None.
Slots
default— title text or markup.
Emitted events
None.
Data attributes
[data-modal-title]— anchor element.
Without a title, reka-ui logs an accessibility warning. Use <VisuallyHidden> from reka-ui if you don't want a visible heading.
<ModalDescription>
Optional. Wraps reka-ui's DialogDescription. Auto-wires aria-describedby.
<ModalContent>
<ModalTitle>Confirm</ModalTitle>
<ModalDescription>This action cannot be undone.</ModalDescription>
</ModalContent>
Props
None.
Slots
default— description text or markup.
Emitted events
None.
Data attributes
[data-modal-description]— anchor element.
If you don't include a description, suppress reka-ui's warning by passing :aria-describedby="undefined" on <ModalContent>.
<ModalOverlay>
Optional. The dimming layer. Place inside <ModalTarget> slot.
<ModalTarget group="default">
<ModalOverlay class="bg-black/50 data-[state=open]:animate-in data-[state=closed]:animate-out" />
</ModalTarget>
Props
None. inheritAttrs: false; $attrs flow to the inner [data-modal-overlay] div.
Slots
default— optional content rendered inside[data-modal-overlay]. Use it to add decorative elements (blur layers, gradients, noise textures, branding watermarks, animated backgrounds) on top of the dimming layer. The overlay itself haspointer-events: noneby default — setpointer-events: autoon slotted elements that need to receive interaction.
<ModalOverlay class="bg-black/50">
<div class="overlay-noise" />
<div class="overlay-gradient" />
</ModalOverlay>
Emitted events
None.
Data attributes
[data-modal-overlay]— anchor.data-state="open" | "closed"— driven by group activity (whether any modal is mounted). Distinct from<ModalContent>'sdata-statewhich tracks individual modal visibility.
Throws
- If used outside
<ModalTarget>. Exact message:[@kolirt/vue-modal] <ModalOverlay> must be used inside <ModalTarget>.
