• English
  • Modal

    Display content or complete an action in a dialog.

    Edit content

    Live previewEdit content
    basic.tsx
    import { Button, Form, FormField, Input, Modal, Select } from '@sudden3/leaf-ui';
    import { useRef, useState } from 'react';
    export function ModalBasic() {
      const [open, setOpen] = useState(false);
      const formRef = useRef<HTMLFormElement>(null);
      return (
        <>
          <Button onClick={() => setOpen(true)}>Edit project</Button>
          <Modal
            open={open}
            title="Project settings"
            confirmText="Save"
            onClose={() => setOpen(false)}
            onConfirm={() => formRef.current?.requestSubmit()}
          >
            <Form
              ref={formRef}
              layout="vertical"
              onSubmit={(event) => {
                event.preventDefault();
                setOpen(false);
              }}
            >
              <FormField label="Project name" required>
                <Input name="name" defaultValue="Leaf UI" />
              </FormField>
              <FormField label="Owner">
                <Select
                  name="owner"
                  options={[
                    { value: 'design', label: 'Design team' },
                    { value: 'engineering', label: 'Engineering team' },
                  ]}
                />
              </FormField>
            </Form>
          </Modal>
        </>
      );
    }
    
    Live previewCustom footer
    footer.tsx
    import { Button, Modal } from '@sudden3/leaf-ui';
    import { useState } from 'react';
    export function ModalFooter() {
      const [open, setOpen] = useState(false);
      const [extra, setExtra] = useState(false);
      return (
        <>
          <Button variant="outline" onClick={() => setOpen(true)}>
            Custom footer
          </Button>
          <Modal
            open={open}
            title="More actions"
            onClose={() => setOpen(false)}
            footer={({ cancelButton, confirmButton }) => (
              <>
                <Button
                  variant="ghost"
                  style={{ marginRight: 'auto' }}
                  onClick={() => setExtra(!extra)}
                >
                  Details
                </Button>
                {cancelButton}
                {confirmButton}
              </>
            )}
          >
            <p>Extend the footer while keeping the default actions.</p>
            {extra && <p>Additional details are shown here.</p>}
          </Modal>
        </>
      );
    }
    
    PropertyTypeDefaultDescription
    openbooleanRequiredWhether the dialog is visible
    title / childrenReactNode—Title / content
    footerReactNode | ((actions: ModalFooterActions) => ReactNode)Cancel + OKCustom footer; null hides it; a function receives default buttons
    confirmText / cancelTextReactNodeLocale defaultButton labels
    confirmLoadingbooleanfalseConfirm loading state
    confirmButtonProps / cancelButtonPropsButtonProps—Customize the default buttons
    onConfirm() => void | Promise<void>—Application controls open; rejection displays an error
    onCancel() => void—Cancel or dismiss; falls back to onClose
    widthnumber | string480Width; numbers are pixels
    closable / maskClosable / keyboardbooleantrueClose button / backdrop dismissal / Escape dismissal
    onClose() => void—Requests closure; update open in the application
    afterClose() => void—Called after the closing animation finishes

    ModalFooterActions

    PropertyTypeDescription
    cancelButtonReactNodeDefault cancel button
    confirmButtonReactNodeDefault confirm button with loading state

    Types

    Import types when defining reusable component props or assembling options.

    import type { ModalProps, ModalFooterActions } from '@sudden3/leaf-ui';

    Usage notes

    Focus moves into the dialog when opened and returns to the trigger on dismissal. Tab stays within the dialog. Use maskClosable and keyboard to control backdrop and Escape dismissal. Supply aria-label when omitting title.

    Customize footer actions or place a Form inside the body. Picker overlays inside a dialog retain its regional theme.

    The default footer has Cancel followed by OK. With onConfirm, update open after the action; without it, OK calls onClose. Promises show loading and prevent duplicates. Submit forms with requestSubmit() in onConfirm or a submit type and form ID in confirmButtonProps. Native validation still applies. A footer function extends default buttons; footer= hides the footer.