64 lines
1.9 KiB
TypeScript
64 lines
1.9 KiB
TypeScript
import type { MotionProps } from "framer-motion";
|
|
import { m } from "framer-motion";
|
|
import { forwardRef } from "react";
|
|
|
|
import { classNames } from "@calcom/lib";
|
|
|
|
import { useBookerStore } from "../store";
|
|
import type { BookerAreas, BookerLayout } from "../types";
|
|
|
|
/**
|
|
* Define what grid area a section should be in.
|
|
* Value is either a string (in case it's always the same area), or an object
|
|
* looking like:
|
|
* {
|
|
* // Where default is the required default area.
|
|
* default: "calendar",
|
|
* // Any optional overrides for different layouts by their layout name.
|
|
* week_view: "main",
|
|
* }
|
|
*/
|
|
type GridArea = BookerAreas | ({ [key in BookerLayout]?: BookerAreas } & { default: BookerAreas });
|
|
|
|
type BookerSectionProps = {
|
|
children: React.ReactNode;
|
|
area: GridArea;
|
|
visible?: boolean;
|
|
className?: string;
|
|
} & MotionProps;
|
|
|
|
// This map with strings is needed so Tailwind generates all classnames,
|
|
// If we would concatenate them with JS, Tailwind would not generate them.
|
|
const gridAreaClassNameMap: { [key in BookerAreas]: string } = {
|
|
calendar: "[grid-area:calendar]",
|
|
main: "[grid-area:main]",
|
|
meta: "[grid-area:meta]",
|
|
timeslots: "[grid-area:timeslots]",
|
|
header: "[grid-area:header]",
|
|
};
|
|
|
|
/**
|
|
* Small helper compnent that renders a booker section in a specific grid area.
|
|
*/
|
|
export const BookerSection = forwardRef<HTMLDivElement, BookerSectionProps>(function BookerSection(
|
|
{ children, area, visible, className, ...props },
|
|
ref
|
|
) {
|
|
const layout = useBookerStore((state) => state.layout);
|
|
let gridClassName: string;
|
|
|
|
if (typeof area === "string") {
|
|
gridClassName = gridAreaClassNameMap[area];
|
|
} else {
|
|
gridClassName = gridAreaClassNameMap[area[layout] || area.default];
|
|
}
|
|
|
|
if (!visible && typeof visible !== "undefined") return null;
|
|
|
|
return (
|
|
<m.div ref={ref} className={classNames(gridClassName, className)} layout {...props}>
|
|
{children}
|
|
</m.div>
|
|
);
|
|
});
|