forked from Temzasse/react-modal-sheet
-
Notifications
You must be signed in to change notification settings - Fork 0
/
A11ySheet.tsx
73 lines (63 loc) · 1.51 KB
/
A11ySheet.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import * as React from 'react';
import { OverlayTriggerState } from 'react-stately';
import {
FocusScope,
useDialog,
useOverlay,
useModal,
OverlayProvider,
} from 'react-aria';
import Sheet from '../../../src';
type SheetProps = {
state: OverlayTriggerState;
label: string;
};
const A11ySheet = ({
state,
label,
children,
...rest
}: React.PropsWithChildren<SheetProps>) => {
return (
<Sheet {...rest} isOpen={state.isOpen} onClose={state.close}>
<OverlayProvider>
<FocusScope contain autoFocus restoreFocus>
<A11ySheetContent state={state} label={label}>
{children}
</A11ySheetContent>
</FocusScope>
</OverlayProvider>
</Sheet>
);
};
const A11ySheetContent = ({
state,
label,
children,
}: React.PropsWithChildren<SheetProps>) => {
const a11yProps = useA11ySheet(state, label);
return (
<>
<Sheet.Container {...a11yProps}>
<Sheet.Header />
<Sheet.Content>{children}</Sheet.Content>
</Sheet.Container>
<Sheet.Backdrop />
</>
);
};
const useA11ySheet = (state: OverlayTriggerState, label: string) => {
const ref = React.useRef<HTMLDivElement>(null);
const dialog = useDialog({ 'aria-label': label }, ref);
const overlay = useOverlay(
{ onClose: state.close, isOpen: true, isDismissable: true },
ref
);
useModal();
return {
ref,
...overlay.overlayProps,
...dialog.dialogProps,
} as any; // HACK: fix type conflicts with Framer Motion
};
export default A11ySheet;