Modal
A native modal dialog with a small client boundary.
Usage
import { Modal } from '@fwenthehunter/friendly-ui/client';
<Modal title="Edit profile" trigger="Open profile" size="sm"
description="Update your public details.">
<p>Your content goes here.</p>
</Modal>Import from the explicit client entry point. The built-in trigger label opens an uncontrolled dialog; pass text or non-interactive content as trigger. A Server Component may render it with serializable props and server-rendered children.
The native dialog handles background inertness, focus containment, Escape, and focus return. A visible close button is always available. Overlay dismissal requires both pointer down and pointer up on the backdrop. Native form method="dialog" also closes it.
For your own trigger, control open and onOpenChange in a client wrapper. Use autoFocus on a suitable child to choose initial focus. You can override aria-describedby or aria-labelledby to refer to your own content.
Customize this component
- Choose a name.
- Add its CSS to your app’s theme.css, imported after the package styles.
- Pass the same name to the prop. No registration, provider, or package edits are needed. Built-in TypeScript suggestions remain available.
A custom name alone does not create styles: until its CSS is loaded, it inherits the component’s base appearance. The examples below are application styles, not additional package defaults.
Add a size
Keep a viewport margin so the dialog fits smaller screens. The selector excludes Drawer so its custom size stays independent. Native focus handling and dismissal are unchanged.
/* app/theme.css — import after @fwenthehunter/friendly-ui/styles.css */
@layer components {
.fui-modal:not(.fui-drawer)[data-size="wide"] {
width: calc(100% - 2rem);
max-width: 64rem;
}
}import { Modal } from "@fwenthehunter/friendly-ui/client";
<Modal size="wide" title="Project details" trigger="Open wide modal">
Your content
</Modal>Props
Components accept native HTML props, className, and style. Server-compatible primitives also forward React 19 refs; Modal manages its own dialog ref.
| Prop | Type | Default |
|---|---|---|
title | ReactNode (required) | — |
trigger | ReactNode, non-interactive label | — |
description | ReactNode | — |
open / defaultOpen | boolean | false |
onOpenChange | (open: boolean) => void | — |
size | sm | md | lg | full | custom string | md |
closeOnEscape / closeOnOverlay | boolean | true |
closeLabel | string | Close dialog |