// @flow strict import * as React from 'react'; import classify from '../../utils/classify'; import {UnstyledButton} from '../Button'; import css from './WeekdayPicker.module.css'; const DEFAULT_WEEKDAYS = [ {key: 'sun', label: 'S'}, {key: 'mon', label: 'M'}, {key: 'tue', label: 'T'}, {key: 'wed', label: 'W'}, {key: 'thu', label: 'T'}, {key: 'fri', label: 'F'}, {key: 'sat', label: 'S'}, ]; const WEEKEND_KEYS = ['sat', 'sun']; export const WEEKDAY_PICKER_SIZE = Object.freeze({ small: 'small', medium: 'medium', }); type ClassNames = $ReadOnly<{ wrapper?: string, button?: string, label?: string, helperText?: string, }>; type WeekdayPickerSize = $Values; type Weekday = { key: string, label: string, secondaryLabel?: string, }; export type WeekdayPickerProps = { size?: WeekdayPickerSize, selectedWeekDays?: Array, hiddenWeekDays?: Array, disabledWeekDays?: Array, customDayLabels?: Array, onChange?: ( selectedDays: Array, ?SyntheticEvent, ) => mixed, readOnly?: boolean, classNames?: ClassNames, showWeekends?: boolean, ariaLabel?: string, label?: React.Node, helperText?: React.Node, disableMultiSelect?: boolean, }; type DayButtonProps = { day: Weekday, isSelected: boolean, isDisabled: boolean, onClick?: ?(SyntheticEvent) => mixed, className?: string, size: WeekdayPickerSize, readOnly?: boolean, }; const DayButton = ({ day, isSelected, isDisabled, onClick, className, size, readOnly, }: DayButtonProps) => ( {day.secondaryLabel && (
{day.secondaryLabel}
)} {day.label}
); export const WeekdayPicker: React$AbstractComponent< WeekdayPickerProps, HTMLDivElement, > = React.forwardRef( ( { size = 'medium', selectedWeekDays = [], disabledWeekDays = [], hiddenWeekDays = [], customDayLabels = DEFAULT_WEEKDAYS, onChange, readOnly = false, classNames = {}, showWeekends = true, ariaLabel = 'Select weekdays', label, helperText, disableMultiSelect = false, }: WeekdayPickerProps, ref, ) => { const [selectedDays, setSelectedDays] = React.useState>(selectedWeekDays); const handleDayToggle = ( day: Weekday, event: SyntheticEvent, ) => { if (readOnly || disabledWeekDays.includes(day.key)) { return; } let updatedSelectedDays = selectedDays; if (disableMultiSelect) { if (selectedDays.some((selected) => selected.key === day.key)) { updatedSelectedDays = []; } else { updatedSelectedDays = [day]; } } else { const isSelected = selectedDays.some( (selected) => selected.key === day.key, ); if (isSelected) { updatedSelectedDays = selectedDays.filter( (selected) => selected.key !== day.key, ); } else { updatedSelectedDays = [...selectedDays, day]; } } setSelectedDays(updatedSelectedDays); onChange?.(updatedSelectedDays, event); }; return (
{!!label && (
{label}
)}
{customDayLabels.map((day) => { const isWeekend = WEEKEND_KEYS.includes(day.key); const isHidden = hiddenWeekDays.includes(day.key); if ((!showWeekends && isWeekend) || isHidden) { return null; } const isSelected = selectedDays.some( (selected) => selected.key === day.key, ); const isDisabled = disabledWeekDays.includes(day.key); return ( { if (isDisabled) { event.preventDefault(); } else { handleDayToggle(day, event); } }} className={classNames.button} size={size} readOnly={readOnly} /> ); })}
{!!helperText && (
{helperText}
)}
); }, );