UNPKG

lightswind

Version:

A collection of beautifully crafted React Components, Blocks & Templates for Modern Developers. Create stunning web applications effortlessly by using our 160+ professional and animated react components.

76 lines (75 loc) 6.42 kB
// @ts-nocheck "use client"; import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import * as React from "react"; import { ChevronLeft, ChevronRight } from "lucide-react"; import { DayPicker } from "react-day-picker"; import { motion, AnimatePresence } from "framer-motion"; import { cn } from "../../lib/utils"; import { buttonVariants } from "./button"; function Calendar({ className, classNames, showOutsideDays = true, ...props }) { const [direction, setDirection] = React.useState(0); const [month, setMonth] = React.useState(props.month || props.defaultMonth || new Date()); return (_jsx(DayPicker, { showOutsideDays: showOutsideDays, month: month, onMonthChange: (newMonth) => { setDirection(newMonth > month ? 1 : -1); setMonth(newMonth); props.onMonthChange?.(newMonth); }, className: cn("p-4 bg-white/70 dark:bg-black/40 backdrop-blur-xl border border-gray-200 dark:border-gray-800 rounded-2xl shadow-2xl", className), classNames: { months: "relative", month: "space-y-4", month_caption: "flex justify-center pt-1 relative items-center h-10", caption_label: "text-sm font-bold tracking-tight text-foreground/90", nav: "flex items-center space-x-1", button_previous: cn(buttonVariants({ variant: "outline" }), "h-8 w-8 bg-background/50 p-0 opacity-70 hover:opacity-100 hover:bg-accent border-gray-200 dark:border-gray-800 rounded-full absolute left-1 top-1 z-20 transition-all active:scale-90"), button_next: cn(buttonVariants({ variant: "outline" }), "h-8 w-8 bg-background/50 p-0 opacity-70 hover:opacity-100 hover:bg-accent border-gray-200 dark:border-gray-800 rounded-full absolute right-1 top-1 z-20 transition-all active:scale-90"), month_grid: "w-full border-collapse space-y-1", weekdays: "flex justify-between", weekday: "text-muted-foreground/60 w-9 font-bold text-[0.65rem] uppercase tracking-[0.1em] text-center", week: "flex w-full mt-1 justify-between", day: "h-9 w-9 text-center text-sm p-0 relative focus-within:relative focus-within:z-20", day_button: cn(buttonVariants({ variant: "ghost" }), "h-9 w-9 p-0 font-medium transition-all duration-300 hover:bg-primary/10 dark:hover:bg-primary/20", "aria-selected:opacity-100 rounded-full relative overflow-visible"), selected: "text-primary-foreground", today: "text-primary font-bold after:content-[''] after:absolute after:bottom-1 after:left-1/2 after:-translate-x-1/2 after:w-1 after:h-1 after:bg-primary after:rounded-full", outside: "day-outside text-muted-foreground/30 opacity-40", disabled: "text-muted-foreground opacity-20 cursor-not-allowed", range_start: "day-range-start rounded-l-full", range_end: "day-range-end rounded-r-full", range_middle: "aria-selected:bg-primary/20 aria-selected:text-primary dark:aria-selected:bg-primary/20 dark:aria-selected:text-primary rounded-none", hidden: "invisible", ...classNames, }, components: { Chevron: ({ orientation }) => { const Icon = orientation === "left" ? ChevronLeft : ChevronRight; return (_jsx(motion.div, { whileHover: { scale: 1.2 }, whileTap: { scale: 0.8 }, className: "flex items-center justify-center", children: _jsx(Icon, { className: "h-4 w-4" }) })); }, Month: ({ children, ...props }) => (_jsx(AnimatePresence, { mode: "popLayout", custom: direction, initial: false, children: _jsx(motion.div, { custom: direction, initial: { opacity: 0, x: direction * 20, filter: "blur(4px)" }, animate: { opacity: 1, x: 0, filter: "blur(0px)" }, exit: { opacity: 0, x: -direction * 20, filter: "blur(4px)" }, transition: { type: "spring", stiffness: 400, damping: 30, mass: 1 }, className: "w-full h-full", children: children }, month.toISOString()) })), DayButton: ({ day, modifiers, ...buttonProps }) => { const isSelected = modifiers.selected; const isRangeStart = modifiers.range_start; const isRangeEnd = modifiers.range_end; const isRangeMiddle = modifiers.range_middle; const isRange = isRangeStart || isRangeEnd || isRangeMiddle; // Avoid jumping layout animations when a range is spanning const useLayoutAnim = isSelected && !isRange; // Filter out props that conflict with Framer Motion's motion.button const { onDrag, onDragStart, onDragEnd, onDragOver, onDragEnter, onDragLeave, onDragExit, className, ...validProps } = buttonProps; return (_jsxs("div", { className: "relative w-full h-full flex items-center justify-center", children: [useLayoutAnim && (_jsx(motion.div, { layoutId: "calendar-selection-pro", className: "absolute inset-0 bg-primary rounded-full shadow-lg shadow-primary/20", transition: { type: "spring", stiffness: 500, damping: 35, }, style: { zIndex: 0 } })), isRange && (isRangeStart || isRangeEnd) && (_jsx("div", { className: "absolute inset-0 bg-primary rounded-full shadow-lg shadow-primary/20 z-0" })), _jsx(motion.button, { ...validProps, className: cn(className, // Incorporate dynamically generated classes from RDP "z-10 relative overflow-visible flex items-center justify-center", // Ensure start/end of a range or single selection shows white text (useLayoutAnim || isRangeStart || isRangeEnd) && "text-primary-foreground focus:text-primary-foreground hover:text-primary-foreground focus:bg-transparent", // Ensure middle selections use theme colored text instead of turning white isRangeMiddle && "text-primary dark:text-primary font-medium"), whileHover: !isRange ? { scale: 1.1 } : undefined, whileTap: !isRange ? { scale: 0.9 } : undefined, children: day.date.getDate() })] })); } }, ...props })); } Calendar.displayName = "Calendar"; export { Calendar };