@baseplate-dev/ui-components
Version:
Shared UI component library
78 lines • 6.94 kB
JavaScript
'use client';
import { jsx as _jsx } from "react/jsx-runtime";
import * as React from 'react';
import { DayPicker, getDefaultClassNames } from 'react-day-picker';
import { MdChevronLeft, MdChevronRight, MdExpandMore } from 'react-icons/md';
import { buttonVariants } from '#src/styles/button.js';
import { cn } from '#src/utils/index.js';
import { Button } from '../button/button.js';
/* eslint-disable react/prop-types -- needed for subcomponents */
/**
* A control that allows the user to select a date.
*
* https://ui.shadcn.com/docs/components/calendar
*/
function Calendar({ className, classNames, showOutsideDays = true, captionLayout = 'label', buttonVariant = 'ghost', formatters, components, ...props }) {
const defaultClassNames = getDefaultClassNames();
return (_jsx(DayPicker, { showOutsideDays: showOutsideDays, className: cn('group/calendar bg-background p-3 [--cell-size:--spacing(8)] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent', String.raw `rtl:**:[.rdp-button\_next>svg]:rotate-180`, String.raw `rtl:**:[.rdp-button\_previous>svg]:rotate-180`, className), captionLayout: captionLayout, formatters: {
formatMonthDropdown: (date) => date.toLocaleString('default', { month: 'short' }),
...formatters,
}, classNames: {
root: cn('w-fit', defaultClassNames.root),
months: cn('relative flex flex-col gap-4 md:flex-row', defaultClassNames.months),
month: cn('flex w-full flex-col gap-4', defaultClassNames.month),
nav: cn('absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1', defaultClassNames.nav),
button_previous: cn(buttonVariants({ variant: buttonVariant }), 'size-(--cell-size) p-0 select-none aria-disabled:opacity-50', defaultClassNames.button_previous),
button_next: cn(buttonVariants({ variant: buttonVariant }), 'size-(--cell-size) p-0 select-none aria-disabled:opacity-50', defaultClassNames.button_next),
month_caption: cn('flex h-(--cell-size) w-full items-center justify-center px-(--cell-size)', defaultClassNames.month_caption),
dropdowns: cn('flex h-(--cell-size) w-full items-center justify-center gap-1.5 text-sm font-medium', defaultClassNames.dropdowns),
dropdown_root: cn('relative rounded-md border border-input shadow-xs has-focus:border-ring has-focus:ring-[3px] has-focus:ring-ring/50', defaultClassNames.dropdown_root),
dropdown: cn('absolute inset-0 opacity-0', defaultClassNames.dropdown),
caption_label: cn('font-medium select-none', captionLayout === 'label'
? 'text-sm'
: 'flex h-8 items-center gap-1 rounded-md pr-1 pl-2 text-sm [&>svg]:size-3.5 [&>svg]:text-muted-foreground', defaultClassNames.caption_label),
table: 'w-full border-collapse',
weekdays: cn('flex', defaultClassNames.weekdays),
weekday: cn('flex-1 rounded-md text-[0.8rem] font-normal text-muted-foreground select-none', defaultClassNames.weekday),
week: cn('mt-2 flex w-full', defaultClassNames.week),
week_number_header: cn('w-(--cell-size) select-none', defaultClassNames.week_number_header),
week_number: cn('text-[0.8rem] text-muted-foreground select-none', defaultClassNames.week_number),
day: cn('group/day relative aspect-square h-full w-full p-0 text-center select-none [&:first-child[data-selected=true]_button]:rounded-l-md [&:last-child[data-selected=true]_button]:rounded-r-md', defaultClassNames.day),
range_start: cn('rounded-l-md bg-accent', defaultClassNames.range_start),
range_middle: cn('rounded-none', defaultClassNames.range_middle),
range_end: cn('rounded-r-md bg-accent', defaultClassNames.range_end),
today: cn('rounded-md bg-accent text-accent-foreground data-[selected=true]:rounded-none', defaultClassNames.today),
outside: cn('text-muted-foreground aria-selected:text-muted-foreground', defaultClassNames.outside),
disabled: cn('text-muted-foreground opacity-50', defaultClassNames.disabled),
hidden: cn('invisible', defaultClassNames.hidden),
...classNames,
}, components: {
Root: ({ className, rootRef, ...props }) => (_jsx("div", { "data-slot": "calendar", ref: rootRef, className: cn(className), ...props })),
Chevron: ({ className, orientation, ...props }) => {
if (orientation === 'left') {
return (_jsx(MdChevronLeft, { className: cn('size-4', className), ...props }));
}
if (orientation === 'right') {
return (_jsx(MdChevronRight, { className: cn('size-4', className), ...props }));
}
return (_jsx(MdExpandMore, { className: cn('size-4', className), ...props }));
},
DayButton: CalendarDayButton,
WeekNumber: ({ children, ...props }) => (_jsx("td", { ...props, children: _jsx("div", { className: "flex size-(--cell-size) items-center justify-center text-center", children: children }) })),
...components,
}, ...props }));
}
function CalendarDayButton({ className, day, modifiers, ...props }) {
const defaultClassNames = getDefaultClassNames();
const ref = React.useRef(null);
React.useEffect(() => {
if (modifiers.focused)
ref.current?.focus();
}, [modifiers.focused]);
return (_jsx(Button, { ref: ref, variant: "ghost", size: "icon", "data-day": day.date.toLocaleDateString(), "data-selected-single": modifiers.selected &&
!modifiers.range_start &&
!modifiers.range_end &&
!modifiers.range_middle, "data-range-start": modifiers.range_start, "data-range-end": modifiers.range_end, "data-range-middle": modifiers.range_middle, className: cn('flex aspect-square size-auto w-full min-w-(--cell-size) flex-col gap-1 leading-none font-normal group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-[3px] group-data-[focused=true]/day:ring-ring/50 data-[range-end=true]:rounded-md data-[range-end=true]:rounded-r-md data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground data-[range-middle=true]:rounded-none data-[range-middle=true]:bg-accent data-[range-middle=true]:text-accent-foreground data-[range-start=true]:rounded-md data-[range-start=true]:rounded-l-md data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground dark:hover:text-accent-foreground [&>span]:text-xs [&>span]:opacity-70', defaultClassNames.day, className), ...props }));
}
export { Calendar, CalendarDayButton };
//# sourceMappingURL=calendar.js.map