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(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 ( {children} ); });