CalendarHeader.mjs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. import { computed, defineComponent, createVNode as _createVNode } from "vue";
  2. import { createNamespace, HAPTICS_FEEDBACK, makeStringProp } from "../utils/index.mjs";
  3. import { t, bem, compareMonth, getPrevMonth, getPrevYear, getNextMonth, getNextYear } from "./utils.mjs";
  4. import { Icon } from "../icon/index.mjs";
  5. const [name] = createNamespace("calendar-header");
  6. var stdin_default = defineComponent({
  7. name,
  8. props: {
  9. date: Date,
  10. minDate: Date,
  11. maxDate: Date,
  12. title: String,
  13. subtitle: String,
  14. showTitle: Boolean,
  15. showSubtitle: Boolean,
  16. firstDayOfWeek: Number,
  17. switchMode: makeStringProp("none")
  18. },
  19. emits: ["clickSubtitle", "panelChange"],
  20. setup(props, {
  21. slots,
  22. emit
  23. }) {
  24. const prevMonthDisabled = computed(() => props.date && props.minDate && compareMonth(getPrevMonth(props.date), props.minDate) < 0);
  25. const prevYearDisabled = computed(() => props.date && props.minDate && compareMonth(getPrevYear(props.date), props.minDate) < 0);
  26. const nextMonthDisabled = computed(() => props.date && props.maxDate && compareMonth(getNextMonth(props.date), props.maxDate) > 0);
  27. const nextYearDisabled = computed(() => props.date && props.maxDate && compareMonth(getNextYear(props.date), props.maxDate) > 0);
  28. const renderTitle = () => {
  29. if (props.showTitle) {
  30. const text = props.title || t("title");
  31. const title = slots.title ? slots.title() : text;
  32. return _createVNode("div", {
  33. "class": bem("header-title")
  34. }, [title]);
  35. }
  36. };
  37. const onClickSubtitle = (event) => emit("clickSubtitle", event);
  38. const onPanelChange = (date) => emit("panelChange", date);
  39. const renderAction = (isNext) => {
  40. const showYearAction = props.switchMode === "year-month";
  41. const monthSlot = slots[isNext ? "next-month" : "prev-month"];
  42. const yearSlot = slots[isNext ? "next-year" : "prev-year"];
  43. const monthDisabled = isNext ? nextMonthDisabled.value : prevMonthDisabled.value;
  44. const yearDisabled = isNext ? nextYearDisabled.value : prevYearDisabled.value;
  45. const monthIconName = isNext ? "arrow" : "arrow-left";
  46. const yearIconName = isNext ? "arrow-double-right" : "arrow-double-left";
  47. const onMonthChange = () => onPanelChange((isNext ? getNextMonth : getPrevMonth)(props.date));
  48. const onYearChange = () => onPanelChange((isNext ? getNextYear : getPrevYear)(props.date));
  49. const MonthAction = _createVNode("view", {
  50. "class": bem("header-action", {
  51. disabled: monthDisabled
  52. }),
  53. "onClick": monthDisabled ? void 0 : onMonthChange
  54. }, [monthSlot ? monthSlot({
  55. disabled: monthDisabled
  56. }) : _createVNode(Icon, {
  57. "class": {
  58. [HAPTICS_FEEDBACK]: !monthDisabled
  59. },
  60. "name": monthIconName
  61. }, null)]);
  62. const YearAction = showYearAction && _createVNode("view", {
  63. "class": bem("header-action", {
  64. disabled: yearDisabled
  65. }),
  66. "onClick": yearDisabled ? void 0 : onYearChange
  67. }, [yearSlot ? yearSlot({
  68. disabled: yearDisabled
  69. }) : _createVNode(Icon, {
  70. "class": {
  71. [HAPTICS_FEEDBACK]: !yearDisabled
  72. },
  73. "name": yearIconName
  74. }, null)]);
  75. return isNext ? [MonthAction, YearAction] : [YearAction, MonthAction];
  76. };
  77. const renderSubtitle = () => {
  78. if (props.showSubtitle) {
  79. const title = slots.subtitle ? slots.subtitle({
  80. date: props.date,
  81. text: props.subtitle
  82. }) : props.subtitle;
  83. const canSwitch = props.switchMode !== "none";
  84. return _createVNode("div", {
  85. "class": bem("header-subtitle", {
  86. "with-switch": canSwitch
  87. }),
  88. "onClick": onClickSubtitle
  89. }, [canSwitch ? [renderAction(), _createVNode("div", {
  90. "class": bem("header-subtitle-text")
  91. }, [title]), renderAction(true)] : title]);
  92. }
  93. };
  94. const renderWeekDays = () => {
  95. const {
  96. firstDayOfWeek
  97. } = props;
  98. const weekdays = t("weekdays");
  99. const renderWeekDays2 = [...weekdays.slice(firstDayOfWeek, 7), ...weekdays.slice(0, firstDayOfWeek)];
  100. return _createVNode("div", {
  101. "class": bem("weekdays")
  102. }, [renderWeekDays2.map((text) => _createVNode("span", {
  103. "class": bem("weekday")
  104. }, [text]))]);
  105. };
  106. return () => _createVNode("div", {
  107. "class": bem("header")
  108. }, [renderTitle(), renderSubtitle(), renderWeekDays()]);
  109. }
  110. });
  111. export {
  112. stdin_default as default
  113. };