StackedFocusModal - Admin Components
The StackedFocusModal component renders a full-screen modal above a route modal. The Medusa Admin uses it for selections that need a lot of space, such as the table that adds countries to a region.
Stacked Modals#
Render a StackedFocusModal inside a RouteFocusModal or a RouteDrawer, which both provide the stacked modal context. Unlike route modals, a StackedFocusModal is not tied to a route. The user opens it with a trigger, and the parent modal stays mounted underneath.
Every StackedFocusModal requires an id prop. The parent modal uses the ID to track which stacked modal is open, so you can render more than one stacked modal in the same form.
Use a StackedFocusModal when the content needs the full screen, such as a data table. For narrower content, use the StackedDrawer.
Example#
The following UI route renders a inside a to select products:
1import { Button, Heading } from "@medusajs/ui"2import {3 RouteFocusModal,4 StackedFocusModal,5} from "@medusajs/dashboard/components"6 7const STACKED_MODAL_ID = "select-products"8 9const BrandProducts = () => {10 return (11 <RouteFocusModal>12 <RouteFocusModal.Header />13 <RouteFocusModal.Body>14 <StackedFocusModal id={STACKED_MODAL_ID}>15 <StackedFocusModal.Trigger asChild>16 <Button variant="secondary" size="small">17 Add Products18 </Button>19 </StackedFocusModal.Trigger>20 <StackedFocusModal.Content>21 <StackedFocusModal.Header>22 <StackedFocusModal.Title asChild>23 <Heading>Add Products</Heading>24 </StackedFocusModal.Title>25 </StackedFocusModal.Header>26 <StackedFocusModal.Body>27 <ProductTable />28 </StackedFocusModal.Body>29 <StackedFocusModal.Footer>30 <StackedFocusModal.Close asChild>31 <Button variant="secondary" size="small">32 Cancel33 </Button>34 </StackedFocusModal.Close>35 </StackedFocusModal.Footer>36 </StackedFocusModal.Content>37 </StackedFocusModal>38 </RouteFocusModal.Body>39 </RouteFocusModal>40 )41}42 43export default BrandProducts
To close the modal from your own code, such as after the user confirms the selection, use the useStackedModal hook. Refer to the Stacked Drawer documentation for the hook's returned values.
Props#
Sub-components#
Component | Description |
|---|---|
| Opens the modal when clicked. Pass |
| The modal's content. It renders a transparent overlay so that the parent modal stays visible. |
| The modal's header. It renders the close button, so render it even when it has no children. |
| The modal's title. Pass |
| An accessible description of the modal's purpose. |
| The modal's scrollable content area. |
| The modal's footer. Place the cancel and confirm buttons in it. |
| Closes the modal when clicked, keeping the parent modal open. Pass |
useStackedModal#
StackedFocusModal shares the useStackedModal hook with the StackedDrawer. The hook returns getIsOpen and setIsOpen to read and change a stacked modal's open state by its ID, and register and unregister that the components call for you.
1import { Button } from "@medusajs/ui"2import { useStackedModal } from "@medusajs/dashboard/components"3 4const ProductTable = () => {5 const { setIsOpen } = useStackedModal()6 7 const handleSave = () => {8 setIsOpen("select-products", false)9 }10 11 return (12 <Button size="small" onClick={handleSave}>13 Save14 </Button>15 )16}