Skip to content

MazBottomSheet ​

MazBottomSheet is a standalone component like a simple dialog but anchored at the bottom of the screen. Full-width on mobile and constrained/centered on desktop, with a header (icon, title, close button), a footer and many replaceable slots. Useful for mobile UX.

Before use it, you should install the MazUi plugin in your project, follow instructions in Getting Started

TIP

This component uses the <Teleport to="body"> with MazBackdrop, so you can implement this component anywhere and it inherits all its props (persistent, closeOnEscape, etc.)

Basic usage ​

The sheet has a header (with the title and a close button) and an optional footer slot. It opens full-width on mobile and is constrained/centered on desktop (see Max width).

Swipe to close (iOS-like) ​

By default a drag handle (grab bar) is shown at the top of the sheet, and you can close the sheet by dragging that handle down - the sheet follows your pointer and either dismisses (past the threshold) or snaps back. This works with both touch and mouse.

Disable it with :swipe-to-close="false" (the handle is then hidden too), or replace the handle with the #handle slot. A persistent sheet never dismisses on swipe: it snaps back instead.

Header with an icon ​

Pass an icon (an icon value or a full MazIconProps object) to display it on the left of the title.

Replaceable slots ​

Everything in the header is replaceable: use #icon and #title to customize parts of the default header, or #header to replace the whole header (you get the close function as a binding).

Max width ​

On mobile the sheet is always full-width. From the tablet breakpoint and up, it is constrained to max-width and centered horizontally. The default max-width is 35rem; pass the max-width prop (a MazSizeUnit) to override it.

Without header ​

Hide the whole header with hide-header, or only the close button with hide-close-button.

Persistent ​

A persistent sheet cannot be closed by clicking outside or pressing escape, and the close button is removed. Provide your own action to close it.

Full example ​

avatar image

Nike Air Max

Premium Running Shoes

Price:$129.99

Accessibility ​

The bottom sheet is a modal dialog labelled by its title and described by its content. The focus is trapped inside while it is open, Esc closes it, and the rest of the page is inert (except the toasts and the live regions).

Props ​

NameDescriptionTypeRequiredDefaultPossible values
model-valuev-model Modal's model valuebooleanNo--
titleTitle of the bottom sheet in the headerstringNo--
iconIcon displayed on the left of the header. Accepts an icon value or a full MazIconProps object.MazIconLikeNo--
max-widthBottom sheet's max-width, applied from the tablet breakpoint and up (full-width below).``${number}rem|${number}px|${number}em|${number}vw|${number}vh|${number}vmin|${number}vmax|${number}%|${number}ch|${number}cm|${number}mm|${number}in|${number}ex|${number}pc|${number...`No"40rem"-
hide-close-buttonRemove the close button in the headerbooleanNofalse-
hide-headerRemove the whole headerbooleanNofalse-
paddingAdd the padding on the content areabooleanNotrue-
persistentPersistent bottom sheet (not closable by clicking outside and remove close button) Persistent dialog (not closable by clicking outside and remove close button)booleanNo--
swipe-to-closeShow the drag handle at the top and allow closing the sheet by swiping it down (iOS-like). The swipe never closes a persistent sheet (it snaps back instead).booleanNotrue-
teleport-selectorTeleport selectorstringNo--
before-closeFunction called before modal is close(() => void | Promise<void>)No--
close-on-escapePrevent close on escape keybooleanNotrue-
transition-nameTransition namestringNo--
backdrop-classBackdrop classClassValueNo--
backdrop-content-classBackdrop content classClassValueNo--
content-paddingAdd padding to the contentbooleanNo--
justifyJustify content"none" | "center" | "end" | "start" | "space-between" | "space-around"No-'none' | 'center' | 'end' | 'start' | 'space-between' | 'space-around'
alignAlign content"none" | "center" | "end" | "start"No-'none' | 'center' | 'end' | 'start'
variantVariant"bottom-sheet" | "dialog" | "drawer"No-'bottom-sheet' | 'dialog' | 'drawer'
aria-labelledbyID for aria-labelledbystringNo--
aria-describedbyID for aria-describedbystringNo--

Events ​

Event namePayloadDescription
update:model-valuevalue: booleanEmitted when the model value is updated
openvalue?: void | undefinedEmitted when the component is opened
closevalue?: void | undefinedEmitted when the component is closed

Slots ​

NameDescriptionBindings
handleDrag handle (grab bar) displayed at the top when swipeToClose is enabled-
headerHeader slotclose () => void - close function
iconIcon slot in the header-
titleTitle slot in the header-
defaultDefault contentclose () => void - close function
footerFooter slotclose () => void - close function

Expose ​

close ​

Close the bottom sheet