UNPKG

naive-ui

Version:

A Vue 3 Component Library. Fairly Complete, Theme Customizable, Uses TypeScript, Fast

298 lines 10.4 kB
import { Fragment, computed, defineComponent, h, ref, toRef } from 'vue'; import { addMonths, format, getMonth, getYear, startOfDay, startOfMonth } from 'date-fns'; import { useMergedState } from 'vooks'; import { dateArray } from "../../date-picker/src/utils.mjs"; import { ChevronLeftIcon, ChevronRightIcon } from "../../_internal/icons/index.mjs"; import { NBaseIcon } from "../../_internal/index.mjs"; import { call, resolveSlotWithProps } from "../../_utils/index.mjs"; import { NButton } from "../../button/index.mjs"; import { NButtonGroup } from "../../button-group/index.mjs"; import { useConfig, useLocale, useTheme, useThemeClass } from "../../_mixins/index.mjs"; import { calendarLight } from "../styles/index.mjs"; import style from "./styles/index.cssr.mjs"; export const calendarProps = Object.assign(Object.assign({}, useTheme.props), { isDateDisabled: Function, value: Number, defaultValue: { type: Number, default: null }, onPanelChange: Function, 'onUpdate:value': [Function, Array], onUpdateValue: [Function, Array] }); export default defineComponent({ name: 'Calendar', props: calendarProps, setup(props) { var _a; const { mergedClsPrefixRef, inlineThemeDisabled } = useConfig(props); const themeRef = useTheme('Calendar', '-calendar', style, calendarLight, props, mergedClsPrefixRef); const { localeRef, dateLocaleRef } = useLocale('DatePicker'); const now = Date.now(); // ts => timestamp const monthTsRef = ref(startOfMonth((_a = props.defaultValue) !== null && _a !== void 0 ? _a : now).valueOf()); const uncontrolledValueRef = ref(props.defaultValue || null); const mergedValueRef = useMergedState(toRef(props, 'value'), uncontrolledValueRef); function doUpdateValue(value, time) { const { onUpdateValue, 'onUpdate:value': _onUpdateValue } = props; if (onUpdateValue) { call(onUpdateValue, value, time); } if (_onUpdateValue) { call(_onUpdateValue, value, time); } uncontrolledValueRef.value = value; } function handlePrevClick() { var _a; const monthTs = addMonths(monthTsRef.value, -1).valueOf(); monthTsRef.value = monthTs; (_a = props.onPanelChange) === null || _a === void 0 ? void 0 : _a.call(props, { year: getYear(monthTs), month: getMonth(monthTs) + 1 }); } function handleNextClick() { var _a; const monthTs = addMonths(monthTsRef.value, 1).valueOf(); monthTsRef.value = monthTs; (_a = props.onPanelChange) === null || _a === void 0 ? void 0 : _a.call(props, { year: getYear(monthTs), month: getMonth(monthTs) + 1 }); } function handleTodayClick() { var _a; const { value: monthTs } = monthTsRef; const oldYear = getYear(monthTs); const oldMonth = getMonth(monthTs); const newMonthTs = startOfMonth(now).valueOf(); monthTsRef.value = newMonthTs; const newYear = getYear(newMonthTs); const newMonth = getMonth(newMonthTs); if (oldYear !== newYear || oldMonth !== newMonth) { (_a = props.onPanelChange) === null || _a === void 0 ? void 0 : _a.call(props, { year: newYear, month: newMonth + 1 }); } } const cssVarsRef = computed(() => { const { common: { cubicBezierEaseInOut }, self: { borderColor, borderColorModal, borderColorPopover, borderRadius, titleFontSize, textColor, titleFontWeight, titleTextColor, dayTextColor, fontSize, lineHeight, dateColorCurrent, dateTextColorCurrent, cellColorHover, cellColor, cellColorModal, barColor, cellColorPopover, cellColorHoverModal, cellColorHoverPopover } } = themeRef.value; return { '--n-bezier': cubicBezierEaseInOut, '--n-border-color': borderColor, '--n-border-color-modal': borderColorModal, '--n-border-color-popover': borderColorPopover, '--n-border-radius': borderRadius, '--n-text-color': textColor, '--n-title-font-weight': titleFontWeight, '--n-title-font-size': titleFontSize, '--n-title-text-color': titleTextColor, '--n-day-text-color': dayTextColor, '--n-font-size': fontSize, '--n-line-height': lineHeight, '--n-date-color-current': dateColorCurrent, '--n-date-text-color-current': dateTextColorCurrent, '--n-cell-color': cellColor, '--n-cell-color-modal': cellColorModal, '--n-cell-color-popover': cellColorPopover, '--n-cell-color-hover': cellColorHover, '--n-cell-color-hover-modal': cellColorHoverModal, '--n-cell-color-hover-popover': cellColorHoverPopover, '--n-bar-color': barColor }; }); const themeClassHandle = inlineThemeDisabled ? useThemeClass('calendar', undefined, cssVarsRef, props) : undefined; return { mergedClsPrefix: mergedClsPrefixRef, locale: localeRef, dateLocale: dateLocaleRef, now, mergedValue: mergedValueRef, monthTs: monthTsRef, dateItems: computed(() => { return dateArray(monthTsRef.value, mergedValueRef.value, now, localeRef.value.firstDayOfWeek, true); }), doUpdateValue, handleTodayClick, handlePrevClick, handleNextClick, mergedTheme: themeRef, cssVars: inlineThemeDisabled ? undefined : cssVarsRef, themeClass: themeClassHandle === null || themeClassHandle === void 0 ? void 0 : themeClassHandle.themeClass, onRender: themeClassHandle === null || themeClassHandle === void 0 ? void 0 : themeClassHandle.onRender }; }, render() { const { isDateDisabled, mergedClsPrefix, monthTs, cssVars, mergedValue, mergedTheme, $slots, locale: { monthBeforeYear, today }, dateLocale: { locale }, handleTodayClick, handlePrevClick, handleNextClick, onRender } = this; onRender === null || onRender === void 0 ? void 0 : onRender(); const normalizedValue = mergedValue && startOfDay(mergedValue).valueOf(); const year = getYear(monthTs); const calendarMonth = getMonth(monthTs) + 1; return h("div", { class: [`${mergedClsPrefix}-calendar`, this.themeClass], style: cssVars }, h("div", { class: `${mergedClsPrefix}-calendar-header` }, h("div", { class: `${mergedClsPrefix}-calendar-header__title` }, resolveSlotWithProps($slots.header, { year, month: calendarMonth }, () => { const localeMonth = format(monthTs, 'MMMM', { locale }); return [monthBeforeYear ? `${localeMonth} ${year}` : `${year} ${localeMonth}`]; })), h("div", { class: `${mergedClsPrefix}-calendar-header__extra` }, h(NButtonGroup, null, { default: () => h(Fragment, null, h(NButton, { size: "small", onClick: handlePrevClick, theme: mergedTheme.peers.Button, themeOverrides: mergedTheme.peerOverrides.Button }, { icon: () => h(NBaseIcon, { clsPrefix: mergedClsPrefix, class: `${mergedClsPrefix}-calendar-prev-btn` }, { default: () => h(ChevronLeftIcon, null) }) }), h(NButton, { size: "small", onClick: handleTodayClick, theme: mergedTheme.peers.Button, themeOverrides: mergedTheme.peerOverrides.Button }, { default: () => today }), h(NButton, { size: "small", onClick: handleNextClick, theme: mergedTheme.peers.Button, themeOverrides: mergedTheme.peerOverrides.Button }, { icon: () => h(NBaseIcon, { clsPrefix: mergedClsPrefix, class: `${mergedClsPrefix}-calendar-next-btn` }, { default: () => h(ChevronRightIcon, null) }) })) }))), h("div", { class: `${mergedClsPrefix}-calendar-dates` }, this.dateItems.map(({ dateObject, ts, inCurrentMonth, isCurrentDate }, index) => { var _a; const { year, month, date } = dateObject; const fullDate = format(ts, 'yyyy-MM-dd'); // 'notInCurrentMonth' and 'disabled' are both disabled styles, but 'disabled''s cursor are not-allowed const notInCurrentMonth = !inCurrentMonth; const disabled = (isDateDisabled === null || isDateDisabled === void 0 ? void 0 : isDateDisabled(ts)) === true; const selected = normalizedValue === startOfDay(ts).valueOf(); return h("div", { key: `${calendarMonth}-${index}`, class: [`${mergedClsPrefix}-calendar-cell`, disabled && `${mergedClsPrefix}-calendar-cell--disabled`, notInCurrentMonth && `${mergedClsPrefix}-calendar-cell--other-month`, disabled && `${mergedClsPrefix}-calendar-cell--not-allowed`, isCurrentDate && `${mergedClsPrefix}-calendar-cell--current`, selected && `${mergedClsPrefix}-calendar-cell--selected`], onClick: () => { var _a; if (disabled) return; const monthTs = startOfMonth(ts).valueOf(); this.monthTs = monthTs; if (notInCurrentMonth) { (_a = this.onPanelChange) === null || _a === void 0 ? void 0 : _a.call(this, { year: getYear(monthTs), month: getMonth(monthTs) + 1 }); } this.doUpdateValue(ts, { year, month: month + 1, date }); } }, h("div", { class: `${mergedClsPrefix}-calendar-date` }, h("div", { class: `${mergedClsPrefix}-calendar-date__date`, title: fullDate }, date), index < 7 && h("div", { class: `${mergedClsPrefix}-calendar-date__day`, title: fullDate }, format(ts, 'EEE', { locale }))), (_a = $slots.default) === null || _a === void 0 ? void 0 : _a.call($slots, { year, month: month + 1, date }), h("div", { class: `${mergedClsPrefix}-calendar-cell__bar` })); }))); } });