import classNames from 'classnames'; import { JsxChildren } from 'dom-renderer'; import { computed, observable } from 'mobx'; import { WebCell, attribute, component, observer } from 'web-cell'; import { Day, TimeData, changeMonth, formatDate, splitArray } from 'web-utility'; import { Badge } from '../Reminder'; import { Button, ButtonProps } from '../Form/Button'; import { Table, TableProps } from '../Content'; export interface DateData { date: TimeData; content: JsxChildren; link?: string; } export interface MonthCalendarProps extends Omit, Pick { locale?: Navigator['language']; value?: DateData[]; onSelect?: (event: CustomEvent) => any; onChange?: (event: CustomEvent) => any; } export interface MonthCalendar extends WebCell {} @component({ tagName: 'month-calendar' }) @observer export class MonthCalendar extends HTMLElement implements WebCell { @attribute @observable accessor variant: MonthCalendarProps['variant'] = 'primary'; @attribute @observable accessor locale: Navigator['language']; @observable accessor value: DateData[] = []; @computed get weekFormatter() { const { locale = globalThis.navigator?.language } = this; return new Intl.DateTimeFormat(locale, { weekday: 'long' }); } @observable accessor currentDate = new Date(); @computed get dateGrid() { let startDate = new Date(this.currentDate); startDate.setDate(1); startDate = new Date(+startDate - startDate.getDay() * Day); const dateList = Array.from( new Array(42), (_, index) => new Date(+startDate + index * Day) ); return splitArray(dateList, 7); } changeMonth(delta: number) { this.currentDate = changeMonth(this.currentDate, delta); this.emit('change', this.currentDate); } renderDate = (date: Date) => { const { value } = this, dateText = formatDate(date, 'YYYY-MM-DD'); const list = value?.filter( ({ date }) => formatDate(date, 'YYYY-MM-DD') === dateText ); return ( {list?.map(item => typeof item.content === 'object' ? ( item.content ) : ( this.emit('select', item)} > {item.content} ) )} ); }; render() { const { style, variant, weekFormatter, currentDate, dateGrid } = this; return ( {dateGrid[0].map((date, index, { length }) => ( ))} {dateGrid.map(days => ( {days.map(this.renderDate)} ))}
{formatDate(currentDate, 'YYYY-MM')}
{weekFormatter.format(date)}
); } }