one
Version:
One is a React framework for web, iOS, and Android apps.
106 lines (103 loc) • 3.58 kB
JavaScript
import * as React from "react";
import { NativeSafeAreaProvider } from "./NativeSafeAreaProvider.mjs";
import { getWindowFrame } from "./getWindowFrame.mjs";
import { initialWindowMetrics } from "./InitialWindow.mjs";
import { feedTamaguiSafeArea } from "./tamaguiSafeArea.mjs";
import { jsx } from "react/jsx-runtime";
const isDev = process.env.NODE_ENV !== "production";
const SafeAreaInsetsContext = React.createContext(null);
if (isDev) {
SafeAreaInsetsContext.displayName = "SafeAreaInsetsContext";
}
const SafeAreaFrameContext = React.createContext(null);
if (isDev) {
SafeAreaFrameContext.displayName = "SafeAreaFrameContext";
}
const ZERO_INSETS = {
top: 0,
bottom: 0,
left: 0,
right: 0
};
function SafeAreaProvider({ children, initialMetrics, initialSafeAreaInsets, ...others }) {
const parentInsets = useParentSafeAreaInsets();
const parentFrame = useParentSafeAreaFrame();
const isRoot = parentInsets === null;
const [insets, setInsets] = React.useState(initialMetrics?.insets ?? initialSafeAreaInsets ?? parentInsets ?? ZERO_INSETS);
const [frame, setFrame] = React.useState(initialMetrics?.frame ?? parentFrame ?? getWindowFrame());
const onInsetsChange = React.useCallback((event) => {
const { nativeEvent: { frame: nextFrame, insets: nextInsets } } = event;
if (isRoot && nextFrame) {
feedTamaguiSafeArea({
insets: nextInsets,
frame: nextFrame
}, tamaguiHooks);
}
setFrame((curFrame) => {
if (nextFrame && (nextFrame.height !== curFrame.height || nextFrame.width !== curFrame.width || nextFrame.x !== curFrame.x || nextFrame.y !== curFrame.y)) {
return nextFrame;
}
return curFrame;
});
setInsets((curInsets) => {
if (!curInsets || nextInsets.bottom !== curInsets.bottom || nextInsets.left !== curInsets.left || nextInsets.right !== curInsets.right || nextInsets.top !== curInsets.top) {
return nextInsets;
}
return curInsets;
});
}, [isRoot]);
return /* @__PURE__ */ jsx(NativeSafeAreaProvider, {
onInsetsChange,
...others,
children: /* @__PURE__ */ jsx(SafeAreaFrameContext.Provider, {
value: frame,
children: /* @__PURE__ */ jsx(SafeAreaInsetsContext.Provider, {
value: insets,
children
})
})
});
}
function useParentSafeAreaInsets() {
return React.useContext(SafeAreaInsetsContext);
}
function useParentSafeAreaFrame() {
return React.useContext(SafeAreaFrameContext);
}
const NO_INSETS_ERROR = "No safe area value available. Make sure you are rendering `<SafeAreaProvider>` at the top of your app.";
function useSafeAreaInsets() {
const insets = React.useContext(SafeAreaInsetsContext);
if (insets == null) {
throw new Error(NO_INSETS_ERROR);
}
return insets;
}
function useSafeAreaFrame() {
const frame = React.useContext(SafeAreaFrameContext);
if (frame == null) {
throw new Error(NO_INSETS_ERROR);
}
return frame;
}
function withSafeAreaInsets(WrappedComponent) {
return React.forwardRef((props, ref) => {
const insets = useSafeAreaInsets();
return /* @__PURE__ */ jsx(WrappedComponent, {
...props,
insets,
ref
});
});
}
const tamaguiHooks = {
useSafeAreaInsets,
useSafeAreaFrame
};
feedTamaguiSafeArea(initialWindowMetrics, tamaguiHooks);
function useSafeArea() {
return useSafeAreaInsets();
}
const SafeAreaConsumer = SafeAreaInsetsContext.Consumer;
const SafeAreaContext = SafeAreaInsetsContext;
export { SafeAreaConsumer, SafeAreaContext, SafeAreaFrameContext, SafeAreaInsetsContext, SafeAreaProvider, useSafeArea, useSafeAreaFrame, useSafeAreaInsets, withSafeAreaInsets };
//# sourceMappingURL=SafeAreaContext.mjs.map