'use client'; import { DateValue, getDayOfWeek, isWeekend } from '@internationalized/date'; import { Breakpoint } from '@westpac/style-config/constants'; import React, { useMemo, useRef } from 'react'; import { useButton, useDatePicker, useLocale } from 'react-aria'; import { useDatePickerState } from 'react-stately'; import { useBreakpoint } from '../../hook/breakpoints.hook.js'; import { resolveResponsiveVariant } from '../../utils/breakpoint.util.js'; import { Button } from '../button/index.js'; import { CalendarIcon } from '../icon/index.js'; import { Calendar } from './components/calendar/calendar.component.js'; import { DateField } from './components/date-field/date-field.component.js'; import { Dialog } from './components/dialog/dialog.component.js'; import { Popover } from './components/popover/popover.component.js'; import { styles as datePickerStyles } from './date-picker.styles.js'; import { type DatePickerProps } from './date-picker.types.js'; const BREAKPOINTS_DECRECENT = ['xl', 'lg', 'md', 'sm', 'xsl', 'initial'] as const; export function DatePicker({ size = 'medium', className, bottomSheetView = { initial: true, xsl: false }, block, isDateUnavailable, disableDaysOfWeek, disableWeekends, separator, portalContainer, placement = 'bottom left', ...props }: DatePickerProps) { const { locale } = useLocale(); const enhancedIsDateUnavailable = useMemo(() => { return disableDaysOfWeek || disableWeekends ? (date: DateValue) => { let conditions = [isDateUnavailable?.(date) || false]; if (disableDaysOfWeek) { conditions = [disableDaysOfWeek.indexOf(getDayOfWeek(date, locale)) !== -1, ...conditions]; } if (disableWeekends) { conditions = [isWeekend(date, locale), ...conditions]; } return conditions.some(condition => condition); } : isDateUnavailable; }, [disableDaysOfWeek, disableWeekends, isDateUnavailable, locale]); const state = useDatePickerState({ isDateUnavailable: enhancedIsDateUnavailable, ...props }); const breakpoint = useBreakpoint(); const resolvedSize = resolveResponsiveVariant(size, breakpoint); const resolvedBlock = resolveResponsiveVariant(block, breakpoint); const styles = datePickerStyles({ block: resolvedBlock, size: resolvedSize, isInvalid: state.isInvalid, isReadOnly: props.isReadOnly, isDisabled: props.isDisabled, }); const ref = useRef(null); const { groupProps, labelProps, fieldProps, buttonProps, dialogProps, calendarProps } = useDatePicker( { isDateUnavailable: enhancedIsDateUnavailable, ...props }, state, ref, ); const showAsBottomSheet: boolean = useMemo(() => { if (typeof bottomSheetView === 'boolean') { return bottomSheetView; } const currentBreakpointIndex = BREAKPOINTS_DECRECENT.findIndex(bp => bp === breakpoint); const finalBreakPoint = [breakpoint, ...BREAKPOINTS_DECRECENT.slice(currentBreakpointIndex)].find( currentBreakpoint => bottomSheetView[currentBreakpoint] !== undefined, ) as Breakpoint | 'initial'; return bottomSheetView[finalBreakPoint] || false; }, [bottomSheetView, breakpoint]); const buttonRef = useRef(null); const { buttonProps: newButtonProps } = useButton(buttonProps, buttonRef); const brandContainer = useMemo(() => { return ( document.querySelector('[data-brand]') || document.querySelector('[class^="theme-"], [class*=" theme-"]') || undefined ); }, []); return ( <> {props.label &&