@crossed/primitive
Version:
A universal & performant styling library for React Native, Next.js & React
153 lines (152 loc) • 4.02 kB
JavaScript
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