Skip to main content

Overview

AxModal is a styled wrapper around Ant Design’s Modal component, providing preset sizes, danger mode for destructive actions, and consistent styling with the design system.

Import

import AxModal from "@/components/AxModal"

Basic Usage

import { useState } from "react"
import AxModal from "@/components/AxModal"
import AxButton from "@/components/AxButton"

function Example() {
  const [open, setOpen] = useState(false)

  return (
    <>
      <AxButton onClick={() => setOpen(true)}>Open Modal</AxButton>
      <AxModal
        title="Confirm action"
        description="Are you sure you want to proceed?"
        open={open}
        onOk={() => setOpen(false)}
        onCancel={() => setOpen(false)}
      >
        This action will update your settings.
      </AxModal>
    </>
  )
}

Props

AxModal-specific Props

description
React.ReactNode
Short description rendered below the title in muted text. Provides additional context for the modal action.
danger
boolean
default:"false"
Danger mode — makes the primary action button red. Use for destructive confirmations like delete, cancel order, or withdraw bid.
size
'sm' | 'md' | 'lg'
default:"'md'"
Preset sizes:
  • sm: 380px — compact size for simple confirmations
  • md: 520px — standard size for forms and content
  • lg: 720px — wide size for tables, lists, and complex content
You can still override with the width prop for custom sizes.

Common Modal Props

open
boolean
required
Whether the modal is visible.
title
React.ReactNode
The modal title. Combined with description to form the header block.
width
number | string
Custom width of the modal. Overrides the size preset.
Custom footer content. When null, no footer is rendered. When undefined (default), renders OK/Cancel buttons using AxButton.
centered
boolean
default:"true"
Whether to center the modal vertically on the screen.
loading
boolean
Whether the modal is in loading state. Shows a loading spinner in the modal.
okText
React.ReactNode
default:"'OK'"
Text for the OK button.
cancelText
React.ReactNode
default:"'Cancel'"
Text for the Cancel button.
confirmLoading
boolean
Whether the OK button is in loading state. Use during async operations.
okButtonProps
ButtonProps
Props passed to the OK button. Note: variant, type, danger, and ghost props are controlled by the modal and cannot be overridden.
cancelButtonProps
ButtonProps
Props passed to the Cancel button. Note: variant, type, danger, and ghost props are controlled by the modal and cannot be overridden.
onOk
(e: React.MouseEvent) => void
Callback when the OK button is clicked.
onCancel
(e: React.MouseEvent) => void
Callback when the Cancel button or close icon is clicked, or when clicking the mask.
rootClassName
string
Additional class name for the modal’s root element.
closable
boolean
default:"true"
Whether to show the close icon in the top right corner.
mask
boolean
default:"true"
Whether to show the mask (backdrop).
maskClosable
boolean
default:"true"
Whether clicking the mask closes the modal.
keyboard
boolean
default:"true"
Whether the Escape key closes the modal.
destroyOnClose
boolean
default:"false"
Whether to unmount child components when the modal is closed.
afterClose
() => void
Callback executed after the modal is fully closed (animation complete).
afterOpenChange
(open: boolean) => void
Callback when the open state changes, fired after animation completes.
zIndex
number
default:"1000"
The z-index of the modal.

Examples

Sizes

AxModal provides three preset sizes optimized for different use cases:
// Small (380px) - simple confirmations
<AxModal
  size="sm"
  title="Delete item?"
  description="This action cannot be undone."
  danger
  okText="Delete"
  open={open}
  onOk={handleDelete}
  onCancel={() => setOpen(false)}
/>

// Medium (520px) - forms and standard content (default)
<AxModal
  size="md"
  title="Add delivery address"
  description="This address will be available for all future orders."
  open={open}
  onOk={handleSubmit}
  onCancel={() => setOpen(false)}
>
  <Form>...</Form>
</AxModal>

// Large (720px) - tables and complex content
<AxModal
  size="lg"
  title="Order summary"
  open={open}
  onCancel={() => setOpen(false)}
>
  <Table columns={columns} dataSource={data} />
</AxModal>

Danger Mode

Use danger mode for destructive actions:
<AxModal
  title="Cancel this order?"
  description="This action cannot be undone. The order will be permanently cancelled and all associated bids will be withdrawn."
  danger
  size="sm"
  okText="Yes, Cancel Order"
  cancelText="Keep Order"
  open={open}
  onOk={handleCancelOrder}
  onCancel={() => setOpen(false)}
>
  <Alert
    type="warning"
    showIcon
    message="2 suppliers have already submitted bids for this order."
  />
</AxModal>

Confirmation with Loading

Show loading state during async operations:
function ConfirmModal() {
  const [open, setOpen] = useState(false)
  const [loading, setLoading] = useState(false)

  const handleOk = async () => {
    setLoading(true)
    try {
      await saveChanges()
      setOpen(false)
    } finally {
      setLoading(false)
    }
  }

  return (
    <AxModal
      title="Save changes?"
      description="Your changes will be applied immediately."
      open={open}
      okText="Save"
      confirmLoading={loading}
      onOk={handleOk}
      onCancel={() => setOpen(false)}
    >
      This will update the medication details across all active orders.
    </AxModal>
  )
}

Form Modal

Use for input collection:
<AxModal
  title="Add delivery address"
  description="This address will be available for all future orders."
  open={open}
  okText="Add Address"
  onOk={handleSubmit}
  onCancel={() => setOpen(false)}
>
  <Flex vertical gap={16}>
    <AxInput label="Address Name" placeholder="e.g. Main Warehouse" />
    <Flex gap={12}>
      <Select placeholder="Select country" style={{ flex: 1 }} />
      <Select placeholder="Select city" style={{ flex: 1 }} />
    </Flex>
    <AxInput label="Address Line" placeholder="Street address, building, floor..." />
    <Checkbox>Use as billing address</Checkbox>
  </Flex>
</AxModal>

Success Modal

Provide feedback after an action:
<AxModal
  title={
    <div style={{ textAlign: "center" }}>
      <CheckCircleFilled style={{ fontSize: 40, color: "var(--success)", marginBottom: 12 }} />
      Order submitted successfully
    </div>
  }
  description={
    <span style={{ display: "block", textAlign: "center" }}>
      Your order has been received and is being reviewed by our team.
    </span>
  }
  open={open}
  size="sm"
  footer={
    <AxButton onClick={() => setOpen(false)} style={{ width: "100%" }}>
      View Your Orders
    </AxButton>
  }
  onCancel={() => setOpen(false)}
/>
Provide your own footer buttons:
<AxModal
  title="Supplier Details"
  open={open}
  footer={
    <Flex gap={8} justify="flex-end">
      <AxButton variant="secondary" onClick={() => setOpen(false)}>
        View Full Profile
      </AxButton>
      <AxButton onClick={() => setOpen(false)}>Got It</AxButton>
    </Flex>
  }
  onCancel={() => setOpen(false)}
>
  {/* Content */}
</AxModal>
Hide the footer entirely:
<AxModal
  title="Read-only information"
  open={open}
  footer={null}
  onCancel={() => setOpen(false)}
>
  {/* Content */}
</AxModal>

Accessibility

  • The modal automatically sets aria-describedby when a description is provided
  • Keyboard navigation is enabled by default (Escape to close)
  • Focus is trapped within the modal when open
  • The modal uses semantic HTML with proper ARIA attributes

Best Practices

  1. Use appropriate sizes: sm for confirmations, md for forms, lg for complex content
  2. Enable danger mode for destructive actions (delete, cancel, withdraw)
  3. Provide descriptions to give users context about the action
  4. Use confirmLoading to show feedback during async operations
  5. Keep content focused — modals should have a single clear purpose
  6. Consider alternatives — for extensive forms or content, consider using a drawer instead
  • AxDrawer — Side panel for forms and detail views
  • AxButton — Used for modal actions
  • AxCard — For content layout within modals

Build docs developers (and LLMs) love