UNPKG

@yamada-ui/calendar

Version:

Yamada UI calendar component

1 lines 9.75 kB
{"version":3,"sources":["../src/use-month-list.tsx"],"sourcesContent":["import type { HTMLProps, PropGetter, RequiredPropGetter } from \"@yamada-ui/core\"\nimport type { KeyboardEvent, MouseEvent } from \"react\"\nimport {\n ariaAttr,\n dataAttr,\n handlerAll,\n isArray,\n isDisabled,\n mergeRefs,\n useUnmountEffect,\n useUpdateEffect,\n} from \"@yamada-ui/utils\"\nimport { createRef, useCallback, useRef } from \"react\"\nimport {\n disableAllTabIndex,\n getFocused,\n getFormattedLabel,\n getRangeMonths,\n isMonthInRange,\n onShouldFocus,\n} from \"./calendar-utils\"\nimport { useCalendarContext } from \"./use-calendar\"\n\nexport const useMonthList = () => {\n const {\n locale,\n maxDate,\n maxYear,\n minDate,\n minYear,\n month,\n monthFormat,\n monthRefs,\n setMonth,\n setType,\n setYear,\n value: selectedValue,\n year,\n yearFormat,\n __selectType,\n } = useCalendarContext()\n\n const multi = isArray(selectedValue)\n const beforeYear = useRef<null | number>(null)\n const rangeMonths = getRangeMonths(locale, monthFormat)\n const label = getFormattedLabel(year, locale, yearFormat)\n\n const onFocusPrev = useCallback(\n (targetMonth: number) => {\n if (targetMonth < 0) {\n if (year <= minYear) return\n\n setYear((prev) => {\n beforeYear.current = prev\n\n return prev - 1\n })\n } else {\n const ref = monthRefs.current.get(targetMonth)\n\n if (ref?.current) {\n ref.current.focus()\n ref.current.tabIndex = 0\n }\n }\n },\n [minYear, monthRefs, setYear, year],\n )\n\n const onFocusNext = useCallback(\n (targetMonth: number) => {\n if (11 < targetMonth) {\n if (maxYear <= year) return\n\n setYear((prev) => {\n beforeYear.current = prev\n\n return prev + 1\n })\n } else {\n const ref = monthRefs.current.get(targetMonth)\n\n if (ref?.current) {\n ref.current.focus()\n ref.current.tabIndex = 0\n }\n }\n },\n [maxYear, monthRefs, setYear, year],\n )\n\n const onKeyDown = useCallback(\n (ev: KeyboardEvent<HTMLDivElement>) => {\n const focusedMonth = getFocused(monthRefs) ?? 0\n\n const actions: { [key: string]: Function | undefined } = {\n ArrowDown: () =>\n focusedMonth + 3 <= 11 ? onFocusNext(focusedMonth + 3) : {},\n ArrowLeft: () => onFocusPrev(focusedMonth - 1),\n ArrowRight: () => onFocusNext(focusedMonth + 1),\n ArrowUp: () =>\n focusedMonth - 3 >= 0 ? onFocusPrev(focusedMonth - 3) : {},\n End: () => onFocusNext(11),\n Home: () => onFocusPrev(0),\n }\n\n const action = actions[ev.key]\n\n if (!action) return\n\n ev.preventDefault()\n ev.stopPropagation()\n\n disableAllTabIndex(monthRefs)\n action(ev)\n },\n [monthRefs, onFocusNext, onFocusPrev],\n )\n\n const onClick = useCallback(\n (ev: MouseEvent, month: number) => {\n ev.preventDefault()\n ev.stopPropagation()\n\n if (isDisabled(ev.target as HTMLElement)) return\n\n setMonth(new Date(year, month, 1))\n setType(\"date\", year, month)\n },\n [year, setMonth, setType],\n )\n\n const getIsSelectedYear = useCallback(() => {\n if (__selectType === \"date\") {\n return month.getFullYear() === year\n } else {\n const selectedYear = !multi\n ? selectedValue?.getFullYear()\n : selectedValue[0]?.getFullYear()\n\n return selectedYear === year\n }\n }, [__selectType, multi, month, selectedValue, year])\n\n const getIsSelected = useCallback(\n (value: number) => {\n if (__selectType === \"date\") {\n return month.getMonth() === value\n } else {\n const month = !multi\n ? selectedValue?.getMonth()\n : selectedValue[0]?.getMonth()\n\n return month === value\n }\n },\n [__selectType, multi, month, selectedValue],\n )\n\n useUpdateEffect(() => {\n if (typeof beforeYear.current !== \"number\") return\n\n onShouldFocus(monthRefs, () => false, beforeYear.current < year)\n\n beforeYear.current = null\n }, [year])\n\n useUnmountEffect(() => {\n monthRefs.current.clear()\n })\n\n const getGridProps: PropGetter = useCallback(\n (props = {}) => ({\n \"aria-label\": label,\n role: \"grid\",\n ...props,\n onKeyDown: handlerAll(onKeyDown, props.onKeyDown),\n }),\n [label, onKeyDown],\n )\n\n const getButtonProps: RequiredPropGetter<\n { value: number } & HTMLProps<\"button\">,\n HTMLProps<\"button\">\n > = useCallback(\n ({ value, ...props }, ref = null) => {\n const controlled = typeof beforeYear.current === \"number\"\n const selectedYear = getIsSelectedYear()\n const selected = selectedYear && getIsSelected(value)\n const disabled = !isMonthInRange({\n date: new Date(year, value),\n maxDate,\n minDate,\n })\n\n monthRefs.current.set(value, createRef<HTMLButtonElement>())\n\n let tabIndex = -1\n\n if (controlled) {\n tabIndex = -1\n } else if (!selectedYear && value === 0) {\n tabIndex = 0\n } else if (selected) {\n tabIndex = 0\n }\n\n return {\n ref: mergeRefs(ref, monthRefs.current.get(value)),\n disabled,\n ...props,\n \"aria-disabled\": ariaAttr(disabled),\n \"aria-selected\": ariaAttr(selected),\n \"data-disabled\": dataAttr(disabled),\n \"data-selected\": dataAttr(selected),\n \"data-value\": value,\n tabIndex,\n onClick: handlerAll(props.onClick, (ev) => onClick(ev, value)),\n }\n },\n [\n getIsSelectedYear,\n getIsSelected,\n year,\n minDate,\n maxDate,\n monthRefs,\n onClick,\n ],\n )\n\n return { label, rangeMonths, getButtonProps, getGridProps }\n}\n\nexport type UseMonthListReturn = ReturnType<typeof useMonthList>\n"],"mappings":";;;;;;;;;;;;;;AAEA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,WAAW,aAAa,cAAc;AAWxC,IAAM,eAAe,MAAM;AAChC,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,mBAAmB;AAEvB,QAAM,QAAQ,QAAQ,aAAa;AACnC,QAAM,aAAa,OAAsB,IAAI;AAC7C,QAAM,cAAc,eAAe,QAAQ,WAAW;AACtD,QAAM,QAAQ,kBAAkB,MAAM,QAAQ,UAAU;AAExD,QAAM,cAAc;AAAA,IAClB,CAAC,gBAAwB;AACvB,UAAI,cAAc,GAAG;AACnB,YAAI,QAAQ,QAAS;AAErB,gBAAQ,CAAC,SAAS;AAChB,qBAAW,UAAU;AAErB,iBAAO,OAAO;AAAA,QAChB,CAAC;AAAA,MACH,OAAO;AACL,cAAM,MAAM,UAAU,QAAQ,IAAI,WAAW;AAE7C,YAAI,2BAAK,SAAS;AAChB,cAAI,QAAQ,MAAM;AAClB,cAAI,QAAQ,WAAW;AAAA,QACzB;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAAC,SAAS,WAAW,SAAS,IAAI;AAAA,EACpC;AAEA,QAAM,cAAc;AAAA,IAClB,CAAC,gBAAwB;AACvB,UAAI,KAAK,aAAa;AACpB,YAAI,WAAW,KAAM;AAErB,gBAAQ,CAAC,SAAS;AAChB,qBAAW,UAAU;AAErB,iBAAO,OAAO;AAAA,QAChB,CAAC;AAAA,MACH,OAAO;AACL,cAAM,MAAM,UAAU,QAAQ,IAAI,WAAW;AAE7C,YAAI,2BAAK,SAAS;AAChB,cAAI,QAAQ,MAAM;AAClB,cAAI,QAAQ,WAAW;AAAA,QACzB;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAAC,SAAS,WAAW,SAAS,IAAI;AAAA,EACpC;AAEA,QAAM,YAAY;AAAA,IAChB,CAAC,OAAsC;AA5F3C;AA6FM,YAAM,gBAAe,gBAAW,SAAS,MAApB,YAAyB;AAE9C,YAAM,UAAmD;AAAA,QACvD,WAAW,MACT,eAAe,KAAK,KAAK,YAAY,eAAe,CAAC,IAAI,CAAC;AAAA,QAC5D,WAAW,MAAM,YAAY,eAAe,CAAC;AAAA,QAC7C,YAAY,MAAM,YAAY,eAAe,CAAC;AAAA,QAC9C,SAAS,MACP,eAAe,KAAK,IAAI,YAAY,eAAe,CAAC,IAAI,CAAC;AAAA,QAC3D,KAAK,MAAM,YAAY,EAAE;AAAA,QACzB,MAAM,MAAM,YAAY,CAAC;AAAA,MAC3B;AAEA,YAAM,SAAS,QAAQ,GAAG,GAAG;AAE7B,UAAI,CAAC,OAAQ;AAEb,SAAG,eAAe;AAClB,SAAG,gBAAgB;AAEnB,yBAAmB,SAAS;AAC5B,aAAO,EAAE;AAAA,IACX;AAAA,IACA,CAAC,WAAW,aAAa,WAAW;AAAA,EACtC;AAEA,QAAM,UAAU;AAAA,IACd,CAAC,IAAgBA,WAAkB;AACjC,SAAG,eAAe;AAClB,SAAG,gBAAgB;AAEnB,UAAI,WAAW,GAAG,MAAqB,EAAG;AAE1C,eAAS,IAAI,KAAK,MAAMA,QAAO,CAAC,CAAC;AACjC,cAAQ,QAAQ,MAAMA,MAAK;AAAA,IAC7B;AAAA,IACA,CAAC,MAAM,UAAU,OAAO;AAAA,EAC1B;AAEA,QAAM,oBAAoB,YAAY,MAAM;AApI9C;AAqII,QAAI,iBAAiB,QAAQ;AAC3B,aAAO,MAAM,YAAY,MAAM;AAAA,IACjC,OAAO;AACL,YAAM,eAAe,CAAC,QAClB,+CAAe,iBACf,mBAAc,CAAC,MAAf,mBAAkB;AAEtB,aAAO,iBAAiB;AAAA,IAC1B;AAAA,EACF,GAAG,CAAC,cAAc,OAAO,OAAO,eAAe,IAAI,CAAC;AAEpD,QAAM,gBAAgB;AAAA,IACpB,CAAC,UAAkB;AAjJvB;AAkJM,UAAI,iBAAiB,QAAQ;AAC3B,eAAO,MAAM,SAAS,MAAM;AAAA,MAC9B,OAAO;AACL,cAAMA,SAAQ,CAAC,QACX,+CAAe,cACf,mBAAc,CAAC,MAAf,mBAAkB;AAEtB,eAAOA,WAAU;AAAA,MACnB;AAAA,IACF;AAAA,IACA,CAAC,cAAc,OAAO,OAAO,aAAa;AAAA,EAC5C;AAEA,kBAAgB,MAAM;AACpB,QAAI,OAAO,WAAW,YAAY,SAAU;AAE5C,kBAAc,WAAW,MAAM,OAAO,WAAW,UAAU,IAAI;AAE/D,eAAW,UAAU;AAAA,EACvB,GAAG,CAAC,IAAI,CAAC;AAET,mBAAiB,MAAM;AACrB,cAAU,QAAQ,MAAM;AAAA,EAC1B,CAAC;AAED,QAAM,eAA2B;AAAA,IAC/B,CAAC,QAAQ,CAAC,OAAO;AAAA,MACf,cAAc;AAAA,MACd,MAAM;AAAA,MACN,GAAG;AAAA,MACH,WAAW,WAAW,WAAW,MAAM,SAAS;AAAA,IAClD;AAAA,IACA,CAAC,OAAO,SAAS;AAAA,EACnB;AAEA,QAAM,iBAGF;AAAA,IACF,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,SAAS;AACnC,YAAM,aAAa,OAAO,WAAW,YAAY;AACjD,YAAM,eAAe,kBAAkB;AACvC,YAAM,WAAW,gBAAgB,cAAc,KAAK;AACpD,YAAM,WAAW,CAAC,eAAe;AAAA,QAC/B,MAAM,IAAI,KAAK,MAAM,KAAK;AAAA,QAC1B;AAAA,QACA;AAAA,MACF,CAAC;AAED,gBAAU,QAAQ,IAAI,OAAO,UAA6B,CAAC;AAE3D,UAAI,WAAW;AAEf,UAAI,YAAY;AACd,mBAAW;AAAA,MACb,WAAW,CAAC,gBAAgB,UAAU,GAAG;AACvC,mBAAW;AAAA,MACb,WAAW,UAAU;AACnB,mBAAW;AAAA,MACb;AAEA,aAAO;AAAA,QACL,KAAK,UAAU,KAAK,UAAU,QAAQ,IAAI,KAAK,CAAC;AAAA,QAChD;AAAA,QACA,GAAG;AAAA,QACH,iBAAiB,SAAS,QAAQ;AAAA,QAClC,iBAAiB,SAAS,QAAQ;AAAA,QAClC,iBAAiB,SAAS,QAAQ;AAAA,QAClC,iBAAiB,SAAS,QAAQ;AAAA,QAClC,cAAc;AAAA,QACd;AAAA,QACA,SAAS,WAAW,MAAM,SAAS,CAAC,OAAO,QAAQ,IAAI,KAAK,CAAC;AAAA,MAC/D;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,OAAO,aAAa,gBAAgB,aAAa;AAC5D;","names":["month"]}