Implement accessibility with external libraries
mainreact-modal-sheet does not include built-in accessibility features (like focus trapping or screen reader support) to avoid bloat and allow you to use your preferred tools (e.g., React Aria).
To make a sheet accessible, you should wrap the sheet components in an accessibility provider (like OverlayProvider and FocusScope from React Aria) and apply the appropriate props (like overlayProps and dialogProps) to the Sheet.Container.
import { Sheet } from 'react-modal-sheet';
import { useRef } from 'react';
import { useOverlayTriggerState } from 'react-stately';
import {
useOverlay,
useModal,
OverlayProvider,
FocusScope,
useButton,
useDialog,
} from 'react-aria';
function A11yExample() {
const sheetState = useOverlayTriggerState({});
const openButtonRef = useRef(null);
const openButton = useButton({ onPress: sheetState.open }, openButtonRef);
return (
<div>
<button {...openButton.buttonProps} ref={openButtonRef}>
Open sheet
</button>
<Sheet isOpen={sheetState.isOpen} onClose={sheetState.close}>
<OverlayProvider>
<FocusScope contain autoFocus restoreFocus>
<SheetComp sheetState={sheetState} />
</FocusScope>
</OverlayProvider>
</Sheet>
</div>
);
}
function SheetComp({ sheetState }) {
const containerRef = useRef(null);
const dialog = useDialog({}, containerRef);
const overlay = useOverlay(
{ onClose: sheetState.close, isOpen: true, isDismissable: true },
containerRef
);
const closeButtonRef = useRef(null);
const closeButton = useButton(
{ onPress: sheetState.close, 'aria-label': 'Close sheet' },
closeButtonRef
);
useModal();
const customHeader = (
<div>
<span {...dialog.titleProps}>Some title for sheet</span>
<button {...closeButton.buttonProps}>🅧</button>
</div>
);
return (
<>
<Sheet.Container
{...overlay.overlayProps}
{...dialog.dialogProps}
ref={containerRef}
>
<Sheet.Header>{customHeader}</Sheet.Header>
<Sheet.Content>{/*...*/}</Sheet.Content>
</Sheet.Container>
<Sheet.Backdrop />
</>
);
}