# Modal Modal dialog component built on the native HTML `` element. Supports both native dialog and Unpoly layer modes. Includes header, body, footer sections with close button support. ## Installation ```bash deno run -A jsr:@lockness/ui add modal ``` ## Usage ```tsx import { Modal, ModalTrigger, ModalContent, ModalHeader, ModalTitle, ModalDescription, ModalBody, ModalFooter, ModalClose, ModalCloseIcon } from '@lockness/ui/components' Open Modal Modal Title

Modal content goes here.

Cancel
``` ## Components ### Modal The main dialog container using the native `` element. ```tsx {/* Modal content */} ``` ### ModalTrigger Button or link that opens the modal. Supports both native dialog and Unpoly modes. ```tsx // Native dialog trigger Open Modal // Unpoly layer trigger (loads content from URL) Load Modal // With variant Open ``` ### ModalContent Wrapper for modal sections (header, body, footer). ```tsx {/* Modal sections */} ``` ### ModalHeader Top section containing title and close button. ```tsx Title ``` ### ModalTitle Main heading text for the modal. ```tsx Confirm Action ``` ### ModalDescription Subtitle or additional context text. ```tsx This action cannot be undone. ``` ### ModalBody Scrollable main content area. ```tsx

Your modal content here...

``` ### ModalFooter Bottom section for action buttons. ```tsx Cancel ``` ### ModalClose Button that closes the modal. ```tsx Cancel Done ``` ### ModalCloseIcon X button for the header area. ```tsx ``` ## Props ### ModalProps | Prop | Type | Default | Description | | -------- | --------- | ------------ | -------------------------------------- | | id | `string` | **required** | Unique identifier for the modal dialog | | children | `unknown` | - | Modal content | | class | `string` | - | Additional CSS class names | ### ModalTriggerProps | Prop | Type | Default | Description | | -------- | -------------------------------------------------- | ----------- | --------------------------------------------- | | targetId | `string` | - | ID of the target modal (for native dialog) | | href | `string` | - | URL to load in Unpoly layer (for Unpoly mode) | | variant | `'primary' \| 'secondary' \| 'outline' \| 'ghost'` | `'primary'` | Visual style variant | | children | `unknown` | - | Button content | | class | `string` | - | Additional CSS class names | ### ModalCloseProps | Prop | Type | Default | Description | | -------- | ---------------------- | --------- | -------------------------- | | size | `'sm' \| 'md' \| 'lg'` | `'sm'` | Button size | | children | `unknown` | `'Close'` | Button content | | class | `string` | - | Additional CSS class names | ## Complete Example ```tsx Delete Item
Delete Item This action cannot be undone.

Are you sure you want to delete this item? All associated data will be permanently removed.

Cancel
``` ## Unpoly Integration For dynamic content loading, use the `href` prop on ModalTrigger: ```tsx Edit Profile ``` This creates an Unpoly layer with: - `up-layer="new"` - Opens as new layer - `up-size="medium"` - Medium-sized modal - `up-dismissable="button"` - Close via button only ## Features - **Native Dialog**: Uses the HTML `` element for proper accessibility - **Backdrop Click**: Closes when clicking outside the modal - **Keyboard Support**: Escape key closes the modal - **Focus Management**: Proper focus trapping within modal - **Animations**: Fade-in and zoom animations on open - **Scrollable Content**: Body section scrolls for long content - **Max Height**: Limited to 90vh with overflow handling ## CSS Variables ```css @theme { --modal-header-padding-x: 1.5rem; --modal-header-padding-y: 1rem; --modal-body-padding-x: 1.5rem; --modal-body-padding-y: 1rem; --modal-footer-padding-x: 1.5rem; --modal-footer-padding-y: 1rem; --radius: 0.5rem; } ```