UNPKG

@crossed/primitive

Version:

A universal & performant styling library for React Native, Next.js & React

153 lines (152 loc) 4.02 kB
import { jsx } from "react/jsx-runtime"; import { cloneElement, createContext, isValidElement, useCallback, useContext, useId, useRef } from "react"; import { composeEventHandlers, useUncontrolled } from "@crossed/core"; import { Pressable, Text, View } from "react-native"; import { Portal } from "@gorhom/portal"; import { Focus, useEscape } from "./Focus"; export * from "./types"; const createModal = () => { const modalContext = createContext({}); const Modal2 = ({ children, open: openProps, defaultOpen = false, onOpenChange }) => { const titleIdRef = useRef(); const descriptionIdRef = useRef(); const [open, setOpen] = useUncontrolled({ value: openProps, defaultValue: defaultOpen, onChange: onOpenChange }); return /* @__PURE__ */ jsx( modalContext.Provider, { value: { open, setOpen, titleIdRef, descriptionIdRef }, children } ); }; const ModalContent2 = (props) => { const { titleIdRef, descriptionIdRef, setOpen } = useContext(modalContext); const escapeProps = useEscape(() => setOpen(false)); return /* @__PURE__ */ jsx( View, { role: "dialog", "aria-modal": true, "aria-labelledby": titleIdRef.current, "aria-describedby": descriptionIdRef.current, ...props, ...escapeProps } ); }; const ModalOverlay2 = ({ closeOnPress, ...props }) => { const { setOpen } = useContext(modalContext); const onPress = useCallback(() => { setOpen(false); }, [setOpen]); return /* @__PURE__ */ jsx( Pressable, { ...props, disabled: !closeOnPress, focusable: false, "aria-hidden": true, ...{ tabIndex: "-1" }, onPress: composeEventHandlers(props.onPress, onPress) } ); }; const ModalTitle2 = ({ nativeID, id: idProps, ...props }) => { const { titleIdRef } = useContext(modalContext); const localId = useId(); const id = idProps || nativeID || `modal-title${localId}`; titleIdRef.current = id; return /* @__PURE__ */ jsx(Text, { ...props, id }); }; const ModalBody2 = ({ nativeID, id: idProps, ...props }) => { const { descriptionIdRef } = useContext(modalContext); const localId = useId(); const id = idProps || nativeID || `modal-body${localId}`; descriptionIdRef.current = id; return /* @__PURE__ */ jsx(View, { ...props, id }); }; const ModalPortal2 = ({ children, ...props }) => { const context = useContext(modalContext); return /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(modalContext.Provider, { value: context, children: /* @__PURE__ */ jsx(Focus, { open: context.open, ...props, children }) }) }); }; const ModalTrigger2 = ({ children, asChild = false, ...props }) => { const { open, setOpen } = useContext(modalContext); const onPressOut = useCallback(() => { setOpen(!open); }, [open, setOpen]); return asChild && isValidElement(children) ? cloneElement(children, { role: "button", ...props, onPressOut: composeEventHandlers(props.onPressOut, onPressOut) }) : /* @__PURE__ */ jsx( Pressable, { role: "button", ...props, onPressOut: composeEventHandlers(props.onPressOut, onPressOut), onPress: composeEventHandlers(props.onPress, () => { }), children } ); }; return { modalContext, Modal: Modal2, ModalContent: ModalContent2, ModalOverlay: ModalOverlay2, ModalTitle: ModalTitle2, ModalTrigger: ModalTrigger2, ModalPortal: ModalPortal2, ModalBody: ModalBody2 }; }; const { Modal, ModalContent, ModalOverlay, ModalTitle, ModalTrigger, ModalPortal, ModalBody } = createModal(); export { Modal, ModalBody, ModalContent, ModalOverlay, ModalPortal, ModalTitle, ModalTrigger, createModal }; //# sourceMappingURL=index.js.map