{"version":3,"file":"calendar.cjs","sources":["../../../components/calendar/calendar.tsx"],"sourcesContent":["'use client';\n\nimport { cva, cx } from 'class-variance-authority';\nimport dayjs from 'dayjs';\nimport timezonePlugin from 'dayjs/plugin/timezone';\nimport utcPlugin from 'dayjs/plugin/utc';\nimport { ChangeEvent, ReactNode, useEffect, useRef, useState } from 'react';\nimport { DayPicker, DayPickerProps, DropdownProps } from 'react-day-picker';\nimport { ChevronLeftIcon, ChevronRightIcon } from '~/icons';\n\nimport { IconButton } from '../icon-button';\nimport { Select } from '../select';\nimport { Skeleton } from '../skeleton';\nimport { Tooltip } from '../tooltip';\nimport styles from './calendar.module.css';\n\n// `timezone` plugin depends on `utc`.\ndayjs.extend(utcPlugin);\ndayjs.extend(timezonePlugin);\n\ninterface OnDropdownOpen {\n  onDropdownOpen?: VoidFunction;\n}\n\nexport interface CalendarPropsExtended {\n  showTooltip?: boolean;\n  tooltipMessages?: Record<string, ReactNode>;\n  /*\n   * Record keys are tz-aware `DD-MM-YYYY`; function form gets raw `day.date`\n   * (consumer must apply `timeZone` themselves to stay consistent).\n   */\n  dateInfo?: Record<string, ReactNode> | ((date: Date) => ReactNode | null);\n  loadingData?: boolean;\n  timeZone?: string;\n}\n\nexport type CalendarProps = DayPickerProps &\n  OnDropdownOpen &\n  CalendarPropsExtended;\n\nconst root = cva(styles.calendarRoot);\n\ninterface DropDownComponentProps extends DropdownProps, OnDropdownOpen {\n  disabled?: boolean;\n}\n\nfunction DropDown({\n  options = [],\n  value,\n  onChange,\n  onDropdownOpen,\n  disabled\n}: DropDownComponentProps) {\n  const [open, setOpen] = useState(false);\n\n  /*\n   * Mirror the callback into a ref so the effect depends only on `open` —\n   * parents that re-create `onDropdownOpen` per render would otherwise cause\n   * a re-fire on every parent render where `open` is true.\n   */\n  const onDropdownOpenRef = useRef(onDropdownOpen);\n  useEffect(() => {\n    onDropdownOpenRef.current = onDropdownOpen;\n  });\n\n  useEffect(() => {\n    if (open) onDropdownOpenRef.current?.();\n  }, [open]);\n\n  function handleChange(value: string) {\n    if (onChange) {\n      onChange({ target: { value } } as ChangeEvent<HTMLSelectElement>);\n    }\n  }\n\n  return (\n    <Select\n      value={value?.toString()}\n      onValueChange={handleChange}\n      open={open}\n      onOpenChange={setOpen}\n    >\n      <Select.Trigger\n        className={styles.dropdownTrigger}\n        iconProps={{\n          className: styles.dropdownIcon\n        }}\n        size='small'\n        variant='text'\n        disabled={disabled}\n        data-slot='calendar-dropdown'\n      >\n        <Select.Value />\n      </Select.Trigger>\n      <Select.Content\n        className={styles.dropdownContent}\n        data-slot='calendar-dropdown-content'\n      >\n        {options.map(opt => (\n          <Select.Item\n            value={opt.value.toString()}\n            key={opt.value}\n            disabled={opt.disabled}\n          >\n            {opt.label}\n          </Select.Item>\n        ))}\n      </Select.Content>\n    </Select>\n  );\n}\n\nexport const Calendar = function ({\n  className,\n  classNames,\n  showOutsideDays = true,\n  onDropdownOpen,\n  showTooltip = false,\n  tooltipMessages = {},\n  dateInfo = {},\n  loadingData = false,\n  timeZone,\n  ...props\n}: CalendarProps) {\n  return (\n    <DayPicker\n      showOutsideDays={showOutsideDays}\n      timeZone={timeZone}\n      components={{\n        PreviousMonthButton: ({ children, ...props }) => (\n          <IconButton\n            {...props}\n            disabled={loadingData || props.disabled}\n            className={cx(props.className, loadingData && styles.disabled)}\n            size={3}\n            aria-label='Previous month'\n            data-slot='calendar-nav-previous'\n          >\n            <ChevronLeftIcon />\n          </IconButton>\n        ),\n        NextMonthButton: ({ children, ...props }) => (\n          <IconButton\n            {...props}\n            disabled={loadingData || props.disabled}\n            className={cx(props.className, loadingData && styles.disabled)}\n            size={3}\n            aria-label='Next month'\n            data-slot='calendar-nav-next'\n          >\n            <ChevronRightIcon />\n          </IconButton>\n        ),\n        Dropdown: (props: DropdownProps) => (\n          <DropDown\n            {...props}\n            onDropdownOpen={onDropdownOpen}\n            disabled={loadingData}\n          />\n        ),\n        DayButton: props => {\n          const { day, ...buttonProps } = props;\n          /*\n           * Format in the picker's zone so the key matches the rendered day\n           * (otherwise UTC-day grids miss messages keyed at UTC midnight when\n           * the browser is in a non-UTC zone).\n           */\n          const dateKey = timeZone\n            ? dayjs(day.date).tz(timeZone).format('DD-MM-YYYY')\n            : dayjs(day.date).format('DD-MM-YYYY');\n          const message = tooltipMessages[dateKey];\n\n          const dateComponent =\n            typeof dateInfo === 'function'\n              ? dateInfo(day.date)\n              : dateInfo[dateKey];\n          const hasDateInfo = Boolean(dateComponent);\n\n          return (\n            <Tooltip disabled={loadingData || !showTooltip || !message}>\n              <Tooltip.Trigger\n                render={\n                  <button\n                    {...buttonProps}\n                    disabled={loadingData || buttonProps.disabled}\n                    className={cx(\n                      buttonProps.className,\n                      hasDateInfo && styles.dayButtonWithInfo\n                    )}\n                    data-slot='calendar-day'\n                  >\n                    {hasDateInfo && (\n                      <div\n                        className={styles.dayInfo}\n                        data-slot='calendar-day-info'\n                      >\n                        {dateComponent}\n                      </div>\n                    )}\n                    <span\n                      className={styles.dayNumber}\n                      data-slot='calendar-day-number'\n                    >\n                      {buttonProps.children}\n                    </span>\n                  </button>\n                }\n              />\n              <Tooltip.Content side='top' data-slot='calendar-day-tooltip'>\n                {message}\n              </Tooltip.Content>\n            </Tooltip>\n          );\n        },\n        MonthGrid: props => (\n          <div className={styles.monthGridWrap} data-slot='calendar-month-grid'>\n            <table\n              {...props}\n              aria-busy={loadingData || undefined}\n              data-slot='calendar-grid-table'\n            />\n            <div\n              className={styles.monthGridSkeleton}\n              data-visible={loadingData || undefined}\n              aria-hidden='true'\n              data-slot='calendar-grid-skeleton'\n            >\n              <Skeleton\n                count={5}\n                height='18px'\n                width='252px'\n                style={{ marginBottom: 'var(--rs-space-6)' }}\n              />\n            </div>\n          </div>\n        )\n      }}\n      classNames={{\n        caption_label: styles.captionLabel,\n        button_previous: `${styles.navButton} ${styles.navButtonPrevious}`,\n        button_next: `${styles.navButton} ${styles.navButtonNext}`,\n        month_caption: styles.monthCaption,\n        months: styles.months,\n        nav: styles.nav,\n        day: styles.day,\n        today: styles.today,\n        outside: styles.outside,\n        week: styles.week,\n        weekdays: styles.week,\n        weekday: styles.weekday,\n        disabled: styles.disabled,\n        selected: styles.selected,\n        day_button: styles.dayButton,\n        range_middle: styles.rangeMiddle,\n        range_end: styles.rangeEnd,\n        range_start: styles.rangeStart,\n        hidden: styles.hidden,\n        dropdowns: styles.dropdowns,\n        ...classNames\n      }}\n      className={root({ className })}\n      data-slot='calendar'\n      mode='single'\n      {...props}\n    />\n  );\n};\n\nCalendar.displayName = 'Calendar';\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAgBA;AACA;AACA;AAsBA;AAMA;;AASE;;;;AAIG;AACH;;AAEE;AACF;;AAGE;AAAU;AACZ;;;;;;AAQA;;AAWO;AAwBT;AAEa;AAYX;;;;;;AAsCQ;;;;AAIG;;AAED;AACA;AACF;AAEA;AAEI;AACA;AACJ;;;AAsCF;AAsBD;;;;;;;;;;;;;;;;;;;;;AAsBC;AACD;AAOP;AAEA;;"}