RouteDrawer - Admin Components

Note: This component is available since Medusa v2.21.0.

The RouteDrawer component renders a drawer that slides in from the side of the screen. The Medusa Admin uses it for edit forms, such as the form that edits a customer's details.

Code
import { RouteDrawer } from "@medusajs/dashboard/components"

Route Modals#

RouteDrawer is tied to a route, not to a trigger button. You render it as the root element of a UI route that is nested under the page it edits. When the user navigates to that route, the drawer opens. When the user closes the drawer, RouteDrawer navigates back to the previous route.

So, to open the drawer, link the user to the drawer's route. For example, link to /brands/:id/edit from the brand's details page.


Example#

Consider a UI route at src/admin/routes/brands/[id]/edit/page.tsx that edits a brand:

src/admin/routes/brands/[id]/edit/page.tsx
import { Heading } from "@medusajs/ui"
import { RouteDrawer } from "@medusajs/dashboard/components"
import { useParams } from "react-router-dom"

const BrandEdit = () => {
  const { id } = useParams()

  return (
    <RouteDrawer>
      <RouteDrawer.Header>
        <RouteDrawer.Title asChild>
          <Heading>Edit Brand</Heading>
        </RouteDrawer.Title>
      </RouteDrawer.Header>
      <EditBrandForm id={id!} />
    </RouteDrawer>
  )
}

export default BrandEdit

EditBrandForm renders the form's fields, as explained in the useRouteModal section.


Props#

RouteDrawer accepts the following props, in addition to its children:

prevstring | object | numberOptional
The route to navigate to when the drawer closes. Pass a string, such as "../..", or an object with the path's parts. You can also pass a number, such as -1, to go back that many entries in the browser's history instead of navigating to a route.

Default: ..


Sub-components#

Component

Description

RouteDrawer.Header

The drawer's header. Place the title and description in it.

RouteDrawer.Title

The drawer's title. Pass asChild to render your own heading element.

RouteDrawer.Description

An accessible description of the drawer's purpose.

RouteDrawer.Body

The drawer's scrollable content area.

RouteDrawer.Footer

The drawer's footer. Place the cancel and submit buttons in it.

RouteDrawer.Close

Closes the drawer when clicked, which navigates back to the prev route. Pass asChild to use your own button.

RouteDrawer.Form

Wraps a React Hook Form form. It provides the form's context to the fields, and shows a confirmation prompt if the user leaves the route while the form has unsaved changes.

RouteDrawer.Form Props#

formobject
The form instance returned by the useForm hook of React Hook Form. Refer to React Hook Form's documentation for all of its properties.
blockSearchParamsbooleanOptional
Whether to also show the unsaved-changes prompt when only the search parameters of the route change.

Default: false

onClose(isSubmitSuccessful: boolean) => voidOptional
A function to run when the user leaves the form's route. It receives whether the form was submitted successfully.

useRouteModal#

Use the useRouteModal hook in components rendered inside a RouteDrawer or a RouteFocusModal. It gives you access to the modal's route context.

Code
import { useRouteModal } from "@medusajs/dashboard/components"

The hook throws an error if you use it outside of a route modal.

Returned Values#

handleSuccess(path?: string) => void
Closes the modal after a successful submission, without showing the unsaved-changes prompt. Pass a path to navigate to a route other than prev.
setCloseOnEscape(value: boolean) => void
Controls whether the Escape key closes the modal. Pass false while the user edits an inline element, such as a cell in a data grid, then pass true again.

Example#

The form component uses handleSuccess to close the drawer after the brand is updated:

src/admin/routes/brands/[id]/edit/page.tsx
import { Button, Input, toast } from "@medusajs/ui"
import {
  RouteDrawer,
  useRouteModal,
} from "@medusajs/dashboard/components"
import { useForm } from "react-hook-form"

const EditBrandForm = ({ id }: { id: string }) => {
  const { handleSuccess } = useRouteModal()
  const form = useForm({
    defaultValues: {
      name: "",
    },
  })

  const handleSubmit = form.handleSubmit(async (data) => {
    await updateBrand(id, data)
    toast.success("Brand updated")
    handleSuccess()
  })

  return (
    <RouteDrawer.Form form={form}>
      <form onSubmit={handleSubmit}>
        <RouteDrawer.Body>
          <Input {...form.register("name")} />
        </RouteDrawer.Body>
        <RouteDrawer.Footer>
          <RouteDrawer.Close asChild>
            <Button variant="secondary" size="small">
              Cancel
            </Button>
          </RouteDrawer.Close>
          <Button type="submit" size="small">
            Save
          </Button>
        </RouteDrawer.Footer>
      </form>
    </RouteDrawer.Form>
  )
}
Found a problem with this page?Report Issue
Edited Nov 14·Edit this page