Components

Modal

A native modal dialog with a small client boundary.

Preview

Edit your profile

Update the name people see.

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

  1. Choose a name.
  2. Add its CSS to your app’s theme.css, imported after the package styles.
  3. 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>

Project details

Your content

Props

Components accept native HTML props, className, and style. Server-compatible primitives also forward React 19 refs; Modal manages its own dialog ref.

PropTypeDefault
titleReactNode (required)—
triggerReactNode, non-interactive label—
descriptionReactNode—
open / defaultOpenbooleanfalse
onOpenChange(open: boolean) => void—
sizesm | md | lg | full | custom stringmd
closeOnEscape / closeOnOverlaybooleantrue
closeLabelstringClose dialog