@crossed/ui
Version:
A universal & performant styling library for React Native, Next.js & React
206 lines (205 loc) • 5.9 kB
JavaScript
import { jsx, jsxs } from "react/jsx-runtime";
import {
composeStyles,
createStyles,
inlineStyle,
isWeb,
useTheme
} from "@crossed/styled";
import { Floating, Sheet } from "../../overlay";
import { ChevronDown } from "@crossed/unicons";
import { FadeIn, FadeOut } from "react-native-reanimated";
import {
forwardRef,
useCallback,
useEffect,
useImperativeHandle,
useRef,
useTransition
} from "react";
import {
Calendar as CalendarComponent
} from "../Calendar";
import { Box } from "../../layout/Box";
import { useMedia } from "../../useMedia";
import { composeEventHandlers } from "@crossed/core";
import { Focus } from "./Focus";
import { XBox } from "../../layout";
const duration = 100;
const styles = createStyles(({ colors, space, boxShadow }) => ({
dynamic: (e) => {
const transform = [];
if (e.transform) {
const [x, y] = e.transform.replace("translate(", "").replace(")", "").replaceAll("px", "").replaceAll(" ", "").split(",");
transform.push({ translateX: Number(x) }, { translateY: Number(y) });
}
return Object.assign({}, e, { transform });
},
calendar: {
base: {
backgroundColor: colors.background.secondary,
borderWidth: 1,
borderColor: colors.border.secondary,
padding: space.md,
borderRadius: 16,
boxShadow,
position: "absolute",
width: 432
}
}
}));
const Calendar = forwardRef(
({
onDateSelected,
setFloating,
floatingStyles,
locale,
events,
firstDayOfWeek,
maxDate,
minDate,
monthsToDisplay,
selectedDate,
availableDates,
floatingProps,
shards
}, ref) => {
const [, setTransition] = useTransition();
const { colors } = useTheme();
const { md } = useMedia();
const open = useRef(false);
useImperativeHandle(
ref,
() => ({
open: () => {
var _a, _b;
(_a = floatingRef.current) == null ? void 0 : _a.open();
(_b = sheetRef.current) == null ? void 0 : _b.show();
},
close: () => {
var _a, _b;
(_a = floatingRef.current) == null ? void 0 : _a.close();
(_b = sheetRef.current) == null ? void 0 : _b.hide();
},
isOpen() {
return open.current;
}
}),
[]
);
const floatingRef = useRef(null);
const sheetRef = useRef(null);
const toggleOpen = useCallback((e) => {
open.current = e;
}, []);
const handleDateSelected = useCallback(
(e) => {
var _a, _b;
setTransition(() => {
onDateSelected == null ? void 0 : onDateSelected(e);
});
(_a = floatingRef.current) == null ? void 0 : _a.close();
(_b = sheetRef.current) == null ? void 0 : _b.hide();
},
[onDateSelected]
);
const handleClose = useCallback((e) => {
var _a;
if (e instanceof PointerEvent || e instanceof KeyboardEvent && e.key === "Escape") {
(_a = floatingRef.current) == null ? void 0 : _a.close();
}
}, []);
useEffect(() => {
if (isWeb && open.current) {
document.addEventListener("click", handleClose);
document.addEventListener("keyup", handleClose);
return () => {
document.removeEventListener("click", handleClose);
document.removeEventListener("keyup", handleClose);
};
}
return () => {
};
}, [open.current]);
const showFloating = isWeb && md;
const renderCalendar = /* @__PURE__ */ jsx(
CalendarComponent,
{
locale,
firstDayOfWeek,
availableDates,
events,
maxDate,
minDate,
monthsToDisplay,
selectedDate,
onDateSelected: handleDateSelected,
ref: setFloating,
style: composeStyles(
showFloating && styles.calendar,
showFloating && styles.dynamic(floatingStyles)
)
}
);
const renderIcon = /* @__PURE__ */ jsx(XBox, { children: /* @__PURE__ */ jsx(ChevronDown, { color: colors.text.secondary }) });
return showFloating ? /* @__PURE__ */ jsxs(
Floating,
{
...floatingProps,
ref: floatingRef,
onChange: composeEventHandlers(toggleOpen, floatingProps == null ? void 0 : floatingProps.onChange),
children: [
renderIcon,
/* @__PURE__ */ jsx(Floating.Portal, { children: /* @__PURE__ */ jsx(
Focus,
{
onEscapeKey: handleClose,
onClickOutside: handleClose,
shards,
returnFocus: false,
children: /* @__PURE__ */ jsx(
Floating.Content,
{
exiting: FadeOut.duration(duration),
entering: FadeIn.duration(duration),
style: composeStyles(
inlineStyle(({ boxShadow }) => ({
base: { zIndex: 100, position: "absolute" },
web: { base: { boxShadow } }
}))
),
children: renderCalendar
}
)
}
) })
]
}
) : /* @__PURE__ */ jsxs(Sheet, { ref: sheetRef, onOpenChange: toggleOpen, children: [
renderIcon,
/* @__PURE__ */ jsx(
Sheet.Content,
{
containerStyle: inlineStyle(() => ({ base: { height: void 0 } })),
children: /* @__PURE__ */ jsx(
Box,
{
style: inlineStyle(({ space }) => ({
base: {
height: void 0,
paddingHorizontal: space.xs,
paddingVertical: space.md
}
})),
children: renderCalendar
}
)
}
)
] });
}
);
export {
Calendar
};
//# sourceMappingURL=Calendar.js.map