@crossed/ui
Version:
A universal & performant styling library for React Native, Next.js & React
147 lines (146 loc) • 4.07 kB
JavaScript
import { jsx } from "react/jsx-runtime";
import {
forwardRef,
memo,
useEffect,
useRef
} from "react";
import { Sheet } from "./Sheet/index";
import { composeRefs, createScope, withStaticProperties } from "@crossed/core";
import {
composeStyles,
createStyles,
inlineStyle,
isWeb
} from "@crossed/styled";
import { Floating, useFloatingContext } from "./Floating";
import { autoUpdate, offset, useFloating } from "@floating-ui/react";
import { flip } from "@floating-ui/dom";
import { FadeIn, FadeOut } from "react-native-reanimated";
import { useMedia } from "../useMedia";
import { FocusOn } from "react-focus-on";
const [PopoverConfigProvider, usePopoverConfig] = createScope({});
const useFloatinCompat = isWeb ? (placement, offSetValue) => useFloating({
placement,
middleware: [flip({ crossAxis: true }), offset(offSetValue)],
whileElementsMounted: autoUpdate
}) : () => ({
refs: {},
floatingStyles: {}
});
const stylesDyn = createStyles(() => ({ dyn: (e) => e }));
const [FloatingUiProvider, useFloatingUi] = createScope(
{}
);
const Root = memo(
({
children,
placement = "bottom-end",
triggerStrategy = "onPress",
offsetValue = 10,
...props
}) => {
const { refs, floatingStyles } = useFloatinCompat(placement, offsetValue);
const { md } = useMedia();
return /* @__PURE__ */ jsx(
PopoverConfigProvider,
{
showSheet: !isWeb || !md,
triggerStrategy,
children: /* @__PURE__ */ jsx(
Floating,
{
triggerStrategy: !md && triggerStrategy === "onPointerEnter" ? "onPress" : triggerStrategy,
removeScroll: false,
...props,
children: /* @__PURE__ */ jsx(
FloatingUiProvider,
{
refs,
floatingStyles,
children
}
)
}
)
}
);
}
);
const Trigger = memo(
forwardRef((props, ref) => {
const { refs } = useFloatingUi();
return /* @__PURE__ */ jsx(
Floating.Trigger,
{
...props,
ref: composeRefs(ref, refs.setReference)
}
);
})
);
const Content = memo(
forwardRef(({ children, style }, ref) => {
const { showSheet } = usePopoverConfig();
return showSheet ? /* @__PURE__ */ jsx(ContentNative, { children, style }) : /* @__PURE__ */ jsx(ContentWeb, { ref, children, style });
})
);
const ContentWeb = memo(
forwardRef(({ children, style }, ref) => {
const { refs, floatingStyles } = useFloatingUi();
const { onClose, open } = useFloatingContext();
const { triggerStrategy } = usePopoverConfig();
return /* @__PURE__ */ jsx(Floating.Portal, { children: /* @__PURE__ */ jsx(
FocusOn,
{
onClickOutside: onClose,
onEscapeKey: onClose,
enabled: open && triggerStrategy === "onPress",
children: /* @__PURE__ */ jsx(
Floating.Content,
{
entering: FadeIn,
exiting: FadeOut,
ref: composeRefs(ref, refs.setFloating),
style: composeStyles(
inlineStyle(() => ({
base: { position: "absolute" }
})),
stylesDyn.dyn(floatingStyles),
style
),
children
}
)
}
) });
})
);
const ContentNative = ({
children
}) => {
const { open, onClose } = useFloatingContext();
const refSheet = useRef(null);
useEffect(() => {
var _a, _b;
if (open) {
(_a = refSheet.current) == null ? void 0 : _a.show();
} else {
(_b = refSheet.current) == null ? void 0 : _b.hide();
}
}, [open]);
return /* @__PURE__ */ jsx(Sheet, { ref: refSheet, children: /* @__PURE__ */ jsx(Sheet.Content, { onClose, children: /* @__PURE__ */ jsx(Sheet.Padded, { children }) }) });
};
const Popover = withStaticProperties(Root, {
Trigger,
Content
});
export {
Content,
Popover,
PopoverConfigProvider,
Root,
Trigger,
usePopoverConfig
};
//# sourceMappingURL=Popover.js.map