Skip to main content

Modal

Appears from the bottom of the screen and fills up the entire screen, requiring user action to clear it.

github
View source code
import { Modal } from '@uhg-abyss/mobile';
() => {
const [isVisible, setIsVisible] = useState(false);
return (
<React.Fragment>
<Modal heading="Enter heading here" isVisible={isVisible}>
<Modal.Section>
<Button
onPress={() => setIsVisible(false)}
variant="destructive"
size="small"
>
Click to close modal
</Button>
</Modal.Section>
</Modal>
<Button
onPress={() => setIsVisible(true)}
>
Toggle Modal
</Button>
</React.Fragment>
);
};

useState

Pass the value from the useState hook to the isVisible modal prop to set the open state of the modal.

Heading

Use the heading prop to set the heading of the modal. This is optional but highly encouraged for accessibility.

If the heading is long, it will automatically be placed at the top of the scroll content area rather than the header bar, with a compact version appearing in the header as the user scrolls.

Note

Use the forceHeadingBelow prop to prevent the heading from appearing in the header bar until the user scrolls, regardless of heading length. This is useful when targeting various devices and/or your header layout needs to remain consistent.

Scrollable

Use the scrollable prop to make the content scrollable. Setting the prop to false changes the Modal's content container from a ScrollView to a View. Defaults to true.

Action Buttons

Action Buttons can be placed on either the left or right side of the header using the actionLeft and actionRight props. Use the onActionLeftPress prop to fire a callback when the left action is pressed, and onActionRightPress prop to fire a callback when the right action is pressed.

If one of the actions is an icon, make sure to use the heading and isScreenReadable props on the icon for accessibility.

Use the footer prop to place content at the bottom of the modal.

Wrap content in a Modal.Section component to add padding to the content.

onClose
iOS

Use onClose to close the modal when swiping the modal down on iOS devices.

() => {
const [modalVisible, setModalVisible] = useState(false);
return (
<Modal
heading="Swipeable Modal"
isVisible={modalVisible}
actionLeft={
<IconSymbol
icon="close"
color="$semantic.color.icon.interactive.rest.primary"
title="Close"
isScreenReadable
/>
}
onActionLeftPress={() => setModalVisible(false)}
onClose={() => setModalVisible(false)}
>
<Modal.Section>
<Text>Swipe the modal down</Text>
</Modal.Section>
</Modal>
);
};

Advanced Layout

Layouts like BottomSheet and Modal can be used in combination with each other to create flows.

Prop NameTypeDefaultDescription
actionLeftnode-The action placed on the left side of the header
actionRightnode-The action placed on the right side of the header
childrennode-Content inside of the modal
footernode-Content inside the footer section of the modal
forceHeadingBelowbooleanfalseFlag to prevent the heading from appearing in the header bar until the user scrolls, regardless of heading length
headingstring-The heading of the modal
hideBorderbooleanfalseFlag to hide the header border
isVisibleboolean-Flag to check if modal is visible
onActionLeftPressfunction-Callback fired when the left action button is pressed
onActionRightPressfunction-Callback fired when the right action button is pressed
onClose
iOS
function-Callback fired when the modal is triggered to close
onDismiss
iOS
function-Callback fired when the modal is closed
scrollablebooleantrueFlag to make the content scrollable. Setting to false will turn the Modal's content container into a View
showsVerticalScrollIndicatorbooleanfalseFlag to show the vertical scroll indicator
stickernode-Content at the top of the modal that stays in the header and does not scroll

Modal.Section Props

Prop NameTypeDefaultDescription
childrennode-Content inside of the section

Class NameDescription
abyss-modal-rootModal root element
abyss-modal-headerModal header container
abyss-modal-action-left-buttonAction left container
abyss-modal-children-containerModal content
abyss-modal-action-right-buttonAction right container
abyss-modal-heading-containerModal heading container
abyss-modal-headingModal heading element
abyss-modal-long-headingModal heading element
abyss-modal-footerModal footer container

Modal.Section Classes

Class NameDescription
abyss-modal-section-rootModal section root element

Focus Guidance

Abyss does not control the focus of components on the screen when the Modal is toggled off. To meet accessibility guidelines, the focus must be set to the previous node when closed. The useSetFocus hook can be used for this.

For example, if a button is pressed to open a Modal, focus must return to that button once the Modal is closed, so that a screen reader or keyboard user may continue using the app where they left off.

Token NameValue
modal.color.surface.header
#FFFFFF
modal.color.surface.content
#FFFFFF
modal.color.border.header
#CBCCCD
modal.color.text.heading.sm
#323334
modal.color.text.heading.lg
#002677
modal.color.text.action.rest
#196ECF
modal.color.text.action.active
#004BA0
modal.color.icon.nav.rest
#002677
modal.color.icon.nav.active
#00184D
modal.color.icon.utility.rest
#4B4D4F
modal.color.icon.utility.active
#323334
modal.border-width.bottom.header
1
modal.sizing.all.icon.utility
24
modal.spacing.padding.all.content
16
modal.spacing.padding.horizontal.header
16
modal.spacing.padding.top.header
6
modal.spacing.padding.bottom.header
8
modal.spacing.gap.horizontal.header
18
modal.spacing.gap.vertical.header
24
Table of Contents