Finish settings modal

This commit is contained in:
Robert Long
2021-12-06 17:34:10 -08:00
parent 4e2d1c5dcd
commit 94f42019df
28 changed files with 975 additions and 356 deletions

View File

@@ -1,10 +1,11 @@
import React, { useRef } from "react";
import React, { useRef, useMemo } from "react";
import {
useOverlay,
usePreventScroll,
useModal,
OverlayContainer,
} from "@react-aria/overlays";
import { useOverlayTriggerState } from "@react-stately/overlays";
import { useDialog } from "@react-aria/dialog";
import { FocusScope } from "@react-aria/focus";
import { useButton } from "@react-aria/button";
@@ -13,7 +14,7 @@ import styles from "./Modal.module.css";
import classNames from "classnames";
export function Modal(props) {
const { title, children } = props;
const { title, children, className } = props;
const modalRef = useRef();
const { overlayProps, underlayProps } = useOverlay(props, modalRef);
usePreventScroll();
@@ -33,7 +34,7 @@ export function Modal(props) {
{...dialogProps}
{...modalProps}
ref={modalRef}
className={styles.modal}
className={classNames(styles.modal, className)}
>
<div className={styles.modalHeader}>
<h3 {...titleProps}>{title}</h3>
@@ -60,3 +61,68 @@ export function ModalContent({ children, className, ...rest }) {
</div>
);
}
export function useModalTriggerState() {
const modalState = useOverlayTriggerState({});
const modalProps = useMemo(
() => ({ isOpen: modalState.isOpen, onClose: modalState.close }),
[modalState]
);
return { modalState, modalProps };
}
export function useToggleModalButton(modalState, ref) {
return useButton(
{
onPress: () => modalState.toggle(),
},
ref
);
}
export function useOpenModalButton(modalState, ref) {
return useButton(
{
onPress: () => modalState.open(),
},
ref
);
}
export function useCloseModalButton(modalState, ref) {
return useButton(
{
onPress: () => modalState.close(),
},
ref
);
}
export function ModalTrigger({ children }) {
const { modalState, modalProps } = useModalState();
const buttonRef = useRef();
const { buttonProps } = useToggleModalButton(modalState, buttonRef);
if (
!Array.isArray(children) ||
children.length > 2 ||
typeof children[1] !== "function"
) {
throw new Error(
"ModalTrigger must have two props. The first being a button and the second being a render prop."
);
}
const [modalTrigger, modal] = children;
return (
<>
<modalTrigger.type
{...modalTrigger.props}
{...buttonProps}
ref={buttonRef}
/>
{modalState.isOpen && modal(modalProps)}
</>
);
}