UNPKG

@spaced-out/ui-design-system

Version:
113 lines (103 loc) 2.83 kB
// @flow strict import * as React from 'react'; // $FlowFixMe[untyped-import] import moment from 'moment'; import type {DateRange} from '../../types'; import { formatIsoDate, getDaysInMonth, inDateRange, isEndOfRange, isStartDateEndDateSame, isStartOfRange, MARKERS, NAVIGATION_ACTION, WEEKDAYS, } from '../../utils'; import { getTranslation, isAfter, isBefore, isSame, } from '../../utils/date-range-picker'; import {BodySmall, TEXT_COLORS} from '../Text'; import {Day} from './Day'; import css from './Calendar.module.css'; type CalendarProps = { value: string, marker: $Values<typeof MARKERS>, minDate?: string, maxDate?: string, hoverDay: string, dateRange: DateRange, inHoverRange: (day: string) => boolean, handlers: { onDayClick: (day: string) => void, onDayHover: (day: string) => void, onMonthNavigate: ( marker: $Values<typeof MARKERS>, action: $Values<typeof NAVIGATION_ACTION>, ) => void, }, today: string, t: ?(key: string, fallback: string) => string, }; export const Calendar = ({ value, marker, minDate, maxDate = formatIsoDate(), handlers, hoverDay, dateRange, inHoverRange, today, t, }: CalendarProps): React.Node => ( <div className={css.calendar}> <div className={css.calendarRow}> {WEEKDAYS.map((day) => ( <BodySmall key={day} className={css.calendarRowItem} color={TEXT_COLORS.tertiary} > {getTranslation(t, day)} </BodySmall> ))} </div> {getDaysInMonth(value).map((week, index) => ( <div key={week[index]} className={css.calendarRow}> {week.map((date: string) => { const isRangeValid = isStartDateEndDateSame(dateRange); const isStart = isStartOfRange(dateRange, date); const isEnd = isEndOfRange(dateRange, date); const highlighted = inDateRange(dateRange, date) || inHoverRange(date); const {onDayClick, onDayHover} = handlers; const dateValue = moment.utc(date); return ( <Day key={date} date={date} filled={isStart || isEnd} onClick={() => onDayClick(date)} onHover={() => onDayHover(date)} outlined={isSame(date, today, 'd')} disabled={ (minDate && isBefore(date, minDate)) || isAfter(date, maxDate) || !isSame(date, value, 'month') } endOfRange={isEnd && !isRangeValid} highlighted={highlighted && !isRangeValid} startOfRange={isStart && !isRangeValid} value={dateValue.date()} hoverDay={hoverDay} /> ); })} </div> ))} </div> );