UNPKG

@gluestack-ui/core

Version:

Universal UI components for React Native, Expo, and Next.js

95 lines (93 loc) 3.47 kB
var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; import React, { useEffect } from 'react'; import { StyleSheet, View } from 'react-native'; const PortalContext = React.createContext(null); let globalOverlayCounter = 0; export function PortalProvider(props) { const [items, setItems] = React.useState([]); const setOverlayItem = (element) => { const overlayId = ++globalOverlayCounter; setItems((prev) => prev.concat([{ id: overlayId, node: element }])); return overlayId; }; const updateOverlayItem = (id, node) => { setItems((prev) => { const overlayItem = prev.find((item) => item.id == id); if (!overlayItem) { return prev.concat([{ id: id, node }]); } else { return prev.map((item) => { if (item.id === id) { return { id, node }; } return item; }); } }); }; const removeOverlayItem = (id) => { setItems((prev) => { const newItems = prev.filter((item) => item.id !== id); return newItems; }); }; return (<PortalContext.Provider value={{ items, setOverlayItem, removeOverlayItem, updateOverlayItem, isSSR: props === null || props === void 0 ? void 0 : props.isSSR, }}> {props.children} {items.map((item) => { return <React.Fragment key={item.id}>{item.node}</React.Fragment>; })} </PortalContext.Provider>); } function OverlayView(_a) { var { style } = _a, props = __rest(_a, ["style"]); return (<View pointerEvents="box-none" style={[StyleSheet.absoluteFill, style]} collapsable={false} {...props}/>); } export const OverlayProvider = PortalProvider; export function OverlayContainer(props) { const context = usePortalProvider(); const overlayId = React.useRef(undefined); const element = <OverlayView {...props}/>; useEffect(() => { if (overlayId.current === undefined) { overlayId.current = context === null || context === void 0 ? void 0 : context.setOverlayItem(element); } else { if (overlayId.current) { context === null || context === void 0 ? void 0 : context.updateOverlayItem(overlayId.current, element); } } }, [props]); useEffect(() => { return () => { if (overlayId.current) { context === null || context === void 0 ? void 0 : context.removeOverlayItem(overlayId.current); } }; }, []); if ((context === null || context === void 0 ? void 0 : context.isSSR) && !overlayId.current) { return <View style={{ display: 'none' }}>{element}</View>; } return null; } function usePortalProvider() { const context = React.useContext(PortalContext); return context; } //# sourceMappingURL=Portal.jsx.map