vant 4.8.11 → 4.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +7 -5
  2. package/es/calendar/Calendar.d.ts +16 -10
  3. package/es/calendar/Calendar.mjs +83 -53
  4. package/es/calendar/CalendarHeader.d.ts +16 -1
  5. package/es/calendar/CalendarHeader.mjs +71 -7
  6. package/es/calendar/CalendarMonth.d.ts +6 -24
  7. package/es/calendar/CalendarMonth.mjs +6 -4
  8. package/es/calendar/index.css +1 -1
  9. package/es/calendar/index.d.ts +11 -7
  10. package/es/calendar/types.d.ts +4 -0
  11. package/es/calendar/utils.d.ts +6 -0
  12. package/es/calendar/utils.mjs +20 -0
  13. package/es/highlight/Highlight.mjs +7 -0
  14. package/es/image-preview/ImagePreviewItem.mjs +2 -0
  15. package/es/index-bar/IndexBar.mjs +10 -2
  16. package/es/index.d.ts +1 -1
  17. package/es/index.mjs +1 -1
  18. package/es/picker-group/PickerGroup.d.ts +13 -0
  19. package/es/picker-group/PickerGroup.mjs +5 -4
  20. package/es/picker-group/index.d.ts +9 -0
  21. package/es/utils/basic.d.ts +1 -1
  22. package/lib/calendar/Calendar.d.ts +16 -10
  23. package/lib/calendar/Calendar.js +82 -52
  24. package/lib/calendar/CalendarHeader.d.ts +16 -1
  25. package/lib/calendar/CalendarHeader.js +68 -4
  26. package/lib/calendar/CalendarMonth.d.ts +6 -24
  27. package/lib/calendar/CalendarMonth.js +6 -4
  28. package/lib/calendar/index.css +1 -1
  29. package/lib/calendar/index.d.ts +11 -7
  30. package/lib/calendar/types.d.ts +4 -0
  31. package/lib/calendar/utils.d.ts +6 -0
  32. package/lib/calendar/utils.js +20 -0
  33. package/lib/highlight/Highlight.js +7 -0
  34. package/lib/image-preview/ImagePreviewItem.js +2 -0
  35. package/lib/index-bar/IndexBar.js +10 -2
  36. package/lib/index.css +1 -1
  37. package/lib/index.d.ts +1 -1
  38. package/lib/index.js +1 -1
  39. package/lib/picker-group/PickerGroup.d.ts +13 -0
  40. package/lib/picker-group/PickerGroup.js +4 -3
  41. package/lib/picker-group/index.d.ts +9 -0
  42. package/lib/utils/basic.d.ts +1 -1
  43. package/lib/vant.cjs.js +193 -66
  44. package/lib/vant.es.js +193 -66
  45. package/lib/vant.js +194 -67
  46. package/lib/vant.min.js +3 -3
  47. package/lib/web-types.json +1 -1
  48. package/package.json +15 -15
package/README.md CHANGED
@@ -10,15 +10,18 @@
10
10
  <img src="https://img.shields.io/npm/v/vant?style=flat-square" alt="npm version" />
11
11
  <img src="https://img.shields.io/codecov/c/github/youzan/vant/main.svg?style=flat-square&color=#4fc08d" alt="Coverage Status" />
12
12
  <img src="https://img.shields.io/npm/dm/vant.svg?style=flat-square&color=#4fc08d" alt="downloads" />
13
- <img src="https://img.badgesize.io/https://unpkg.com/vant/lib/vant.min.js?compression=gzip&style=flat-square&label=gzip%20size&color=#4fc08d" alt="Gzip Size" />
14
13
  </p>
15
14
 
16
15
  <p align="center">
17
- 🔥 <a href="https://vant-contrib.gitee.io/vant">文档网站(国内)</a>
16
+ <a href="https://vant-ui.github.io/vant">Documentation</a>
18
17
  &nbsp;
19
- 🌈 <a href="https://vant-ui.github.io/vant">文档网站(GitHub)</a>
18
+ ·
20
19
  &nbsp;
21
- 🇨🇳 <a href="./README.zh-CN.md">中文版介绍</a>
20
+ <a href="https://vant-ui.github.io/vant">文档站</a>
21
+ &nbsp;
22
+ ·
23
+ &nbsp;
24
+ <a href="./README.zh-CN.md">中文介绍</a>
22
25
  </p>
23
26
 
24
27
  ---
@@ -120,7 +123,6 @@ Vant 3/4 supports modern browsers and Chrome >= 51、iOS >= 10.0 (same as Vue 3)
120
123
  | --- | --- |
121
124
  | [3lang3/react-vant](https://github.com/3lang3/react-vant) | React mobile UI Components based on Vant |
122
125
  | [vant-aliapp](https://github.com/ant-move/Vant-Aliapp) | Alipay MiniProgram UI |
123
- | [taroify](https://gitee.com/mallfoundry/taroify) | Vant Taro |
124
126
  | [vant-theme](https://github.com/Aisen60/vant-theme) | Online theme preview built on Vant UI |
125
127
  | [@antmjs/vantui](https://github.com/antmjs/vantui) | Mobile UI Components based on Vant, supporting Taro and React |
126
128
  | [vant-playground](https://github.com/LadyChatterleyLover/vant-playground) | Vant Playground |
@@ -1,12 +1,16 @@
1
1
  import { type PropType, type ExtractPropTypes } from 'vue';
2
2
  import { PopupPosition } from '../popup';
3
- import type { CalendarType, CalendarDayItem } from './types';
3
+ import type { CalendarType, CalendarSwitchMode, CalendarDayItem } from './types';
4
4
  export declare const calendarProps: {
5
5
  show: BooleanConstructor;
6
6
  type: {
7
7
  type: PropType<CalendarType>;
8
8
  default: CalendarType;
9
9
  };
10
+ switchMode: {
11
+ type: PropType<CalendarSwitchMode>;
12
+ default: CalendarSwitchMode;
13
+ };
10
14
  title: StringConstructor;
11
15
  color: StringConstructor;
12
16
  round: {
@@ -74,12 +78,10 @@ export declare const calendarProps: {
74
78
  minDate: {
75
79
  type: DateConstructor;
76
80
  validator: (val: unknown) => val is Date;
77
- default: () => Date;
78
81
  };
79
82
  maxDate: {
80
83
  type: DateConstructor;
81
84
  validator: (val: unknown) => val is Date;
82
- default: () => Date;
83
85
  };
84
86
  firstDayOfWeek: {
85
87
  type: (NumberConstructor | StringConstructor)[];
@@ -94,6 +96,10 @@ declare const _default: import("vue").DefineComponent<{
94
96
  type: PropType<CalendarType>;
95
97
  default: CalendarType;
96
98
  };
99
+ switchMode: {
100
+ type: PropType<CalendarSwitchMode>;
101
+ default: CalendarSwitchMode;
102
+ };
97
103
  title: StringConstructor;
98
104
  color: StringConstructor;
99
105
  round: {
@@ -161,24 +167,26 @@ declare const _default: import("vue").DefineComponent<{
161
167
  minDate: {
162
168
  type: DateConstructor;
163
169
  validator: (val: unknown) => val is Date;
164
- default: () => Date;
165
170
  };
166
171
  maxDate: {
167
172
  type: DateConstructor;
168
173
  validator: (val: unknown) => val is Date;
169
- default: () => Date;
170
174
  };
171
175
  firstDayOfWeek: {
172
176
  type: (NumberConstructor | StringConstructor)[];
173
177
  default: number;
174
178
  validator: (val: number) => boolean;
175
179
  };
176
- }, () => import("vue/jsx-runtime").JSX.Element, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("select" | "update:show" | "confirm" | "clickDisabledDate" | "clickSubtitle" | "unselect" | "monthShow" | "overRange")[], "select" | "update:show" | "confirm" | "clickDisabledDate" | "clickSubtitle" | "unselect" | "monthShow" | "overRange", import("vue").PublicProps, Readonly<ExtractPropTypes<{
180
+ }, () => import("vue/jsx-runtime").JSX.Element, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("select" | "update:show" | "confirm" | "clickDisabledDate" | "clickSubtitle" | "panelChange" | "unselect" | "monthShow" | "overRange")[], "select" | "update:show" | "confirm" | "clickDisabledDate" | "clickSubtitle" | "panelChange" | "unselect" | "monthShow" | "overRange", import("vue").PublicProps, Readonly<ExtractPropTypes<{
177
181
  show: BooleanConstructor;
178
182
  type: {
179
183
  type: PropType<CalendarType>;
180
184
  default: CalendarType;
181
185
  };
186
+ switchMode: {
187
+ type: PropType<CalendarSwitchMode>;
188
+ default: CalendarSwitchMode;
189
+ };
182
190
  title: StringConstructor;
183
191
  color: StringConstructor;
184
192
  round: {
@@ -246,12 +254,10 @@ declare const _default: import("vue").DefineComponent<{
246
254
  minDate: {
247
255
  type: DateConstructor;
248
256
  validator: (val: unknown) => val is Date;
249
- default: () => Date;
250
257
  };
251
258
  maxDate: {
252
259
  type: DateConstructor;
253
260
  validator: (val: unknown) => val is Date;
254
- default: () => Date;
255
261
  };
256
262
  firstDayOfWeek: {
257
263
  type: (NumberConstructor | StringConstructor)[];
@@ -264,6 +270,7 @@ declare const _default: import("vue").DefineComponent<{
264
270
  onConfirm?: ((...args: any[]) => any) | undefined;
265
271
  onClickDisabledDate?: ((...args: any[]) => any) | undefined;
266
272
  onClickSubtitle?: ((...args: any[]) => any) | undefined;
273
+ onPanelChange?: ((...args: any[]) => any) | undefined;
267
274
  onUnselect?: ((...args: any[]) => any) | undefined;
268
275
  onMonthShow?: ((...args: any[]) => any) | undefined;
269
276
  onOverRange?: ((...args: any[]) => any) | undefined;
@@ -278,6 +285,7 @@ declare const _default: import("vue").DefineComponent<{
278
285
  closeOnClickOverlay: boolean;
279
286
  closeOnPopstate: boolean;
280
287
  safeAreaInsetTop: boolean;
288
+ switchMode: CalendarSwitchMode;
281
289
  poppable: boolean;
282
290
  maxRange: string | number;
283
291
  showMark: boolean;
@@ -286,8 +294,6 @@ declare const _default: import("vue").DefineComponent<{
286
294
  allowSameDay: boolean;
287
295
  showSubtitle: boolean;
288
296
  showRangePrompt: boolean;
289
- minDate: Date;
290
- maxDate: Date;
291
297
  firstDayOfWeek: string | number;
292
298
  }, {}>;
293
299
  export default _default;
@@ -1,7 +1,7 @@
1
1
  import { createVNode as _createVNode, mergeProps as _mergeProps } from "vue";
2
2
  import { ref, watch, computed, defineComponent } from "vue";
3
3
  import { pick, isDate, truthProp, numericProp, getScrollTop, makeStringProp, makeNumericProp } from "../utils/index.mjs";
4
- import { t, bem, name, getToday, cloneDate, cloneDates, getPrevDay, getNextDay, compareDay, calcDateNum, compareMonth, getDayByOffset } from "./utils.mjs";
4
+ import { t, bem, name, getToday, cloneDate, cloneDates, getPrevDay, getNextDay, compareDay, calcDateNum, compareMonth, getDayByOffset, getMonthByOffset } from "./utils.mjs";
5
5
  import { raf, useRect, onMountedOrActivated } from "@vant/use";
6
6
  import { useRefs } from "../composables/use-refs.mjs";
7
7
  import { useExpose } from "../composables/use-expose.mjs";
@@ -13,6 +13,7 @@ import CalendarHeader from "./CalendarHeader.mjs";
13
13
  const calendarProps = {
14
14
  show: Boolean,
15
15
  type: makeStringProp("single"),
16
+ switchMode: makeStringProp("none"),
16
17
  title: String,
17
18
  color: String,
18
19
  round: truthProp,
@@ -40,16 +41,11 @@ const calendarProps = {
40
41
  safeAreaInsetBottom: truthProp,
41
42
  minDate: {
42
43
  type: Date,
43
- validator: isDate,
44
- default: getToday
44
+ validator: isDate
45
45
  },
46
46
  maxDate: {
47
47
  type: Date,
48
- validator: isDate,
49
- default: () => {
50
- const now = getToday();
51
- return new Date(now.getFullYear(), now.getMonth() + 6, now.getDate());
52
- }
48
+ validator: isDate
53
49
  },
54
50
  firstDayOfWeek: {
55
51
  type: numericProp,
@@ -60,25 +56,36 @@ const calendarProps = {
60
56
  var stdin_default = defineComponent({
61
57
  name,
62
58
  props: calendarProps,
63
- emits: ["select", "confirm", "unselect", "monthShow", "overRange", "update:show", "clickSubtitle", "clickDisabledDate"],
59
+ emits: ["select", "confirm", "unselect", "monthShow", "overRange", "update:show", "clickSubtitle", "clickDisabledDate", "panelChange"],
64
60
  setup(props, {
65
61
  emit,
66
62
  slots
67
63
  }) {
68
- const limitDateRange = (date, minDate = props.minDate, maxDate = props.maxDate) => {
69
- if (compareDay(date, minDate) === -1) {
70
- return minDate;
64
+ const canSwitch = computed(() => props.switchMode !== "none");
65
+ const minDate = computed(() => {
66
+ if (!props.minDate && !canSwitch.value) {
67
+ return getToday();
68
+ }
69
+ return props.minDate;
70
+ });
71
+ const maxDate = computed(() => {
72
+ if (!props.maxDate && !canSwitch.value) {
73
+ return getMonthByOffset(getToday(), 6);
71
74
  }
72
- if (compareDay(date, maxDate) === 1) {
73
- return maxDate;
75
+ return props.maxDate;
76
+ });
77
+ const limitDateRange = (date, min = minDate.value, max = maxDate.value) => {
78
+ if (min && compareDay(date, min) === -1) {
79
+ return min;
80
+ }
81
+ if (max && compareDay(date, max) === 1) {
82
+ return max;
74
83
  }
75
84
  return date;
76
85
  };
77
86
  const getInitialDate = (defaultDate = props.defaultDate) => {
78
87
  const {
79
88
  type,
80
- minDate,
81
- maxDate,
82
89
  allowSameDay
83
90
  } = props;
84
91
  if (defaultDate === null) {
@@ -89,8 +96,10 @@ var stdin_default = defineComponent({
89
96
  if (!Array.isArray(defaultDate)) {
90
97
  defaultDate = [];
91
98
  }
92
- const start = limitDateRange(defaultDate[0] || now, minDate, allowSameDay ? maxDate : getPrevDay(maxDate));
93
- const end = limitDateRange(defaultDate[1] || now, allowSameDay ? minDate : getNextDay(minDate));
99
+ const min = minDate.value;
100
+ const max = maxDate.value;
101
+ const start = limitDateRange(defaultDate[0] || now, min, max ? allowSameDay ? max : getPrevDay(max) : void 0);
102
+ const end = limitDateRange(defaultDate[1] || (allowSameDay ? now : getNextDay(now)), min ? allowSameDay ? min : getNextDay(min) : void 0);
94
103
  return [start, end];
95
104
  }
96
105
  if (type === "multiple") {
@@ -104,23 +113,28 @@ var stdin_default = defineComponent({
104
113
  }
105
114
  return limitDateRange(defaultDate);
106
115
  };
116
+ const getInitialPanelDate = () => {
117
+ const date = Array.isArray(currentDate.value) ? currentDate.value[0] : currentDate.value;
118
+ return date ? date : limitDateRange(getToday());
119
+ };
107
120
  let bodyHeight;
108
121
  const bodyRef = ref();
109
- const subtitle = ref({
110
- textFn: () => "",
111
- date: void 0
112
- });
113
122
  const currentDate = ref(getInitialDate());
123
+ const currentPanelDate = ref(getInitialPanelDate());
124
+ const currentMonthRef = ref();
114
125
  const [monthRefs, setMonthRefs] = useRefs();
115
126
  const dayOffset = computed(() => props.firstDayOfWeek ? +props.firstDayOfWeek % 7 : 0);
116
127
  const months = computed(() => {
117
128
  const months2 = [];
118
- const cursor = new Date(props.minDate);
129
+ if (!minDate.value || !maxDate.value) {
130
+ return months2;
131
+ }
132
+ const cursor = new Date(minDate.value);
119
133
  cursor.setDate(1);
120
134
  do {
121
135
  months2.push(new Date(cursor));
122
136
  cursor.setMonth(cursor.getMonth() + 1);
123
- } while (compareMonth(cursor, props.maxDate) !== 1);
137
+ } while (compareMonth(cursor, maxDate.value) !== 1);
124
138
  return months2;
125
139
  });
126
140
  const buttonDisabled = computed(() => {
@@ -170,25 +184,26 @@ var stdin_default = defineComponent({
170
184
  monthRefs.value[index].setVisible(visible);
171
185
  });
172
186
  if (currentMonth) {
173
- subtitle.value = {
174
- textFn: currentMonth.getTitle,
175
- date: currentMonth.date
176
- };
187
+ currentMonthRef.value = currentMonth;
177
188
  }
178
189
  };
179
190
  const scrollToDate = (targetDate) => {
180
- raf(() => {
181
- months.value.some((month, index) => {
182
- if (compareMonth(month, targetDate) === 0) {
183
- if (bodyRef.value) {
184
- monthRefs.value[index].scrollToDate(bodyRef.value, targetDate);
191
+ if (canSwitch.value) {
192
+ currentPanelDate.value = targetDate;
193
+ } else {
194
+ raf(() => {
195
+ months.value.some((month, index) => {
196
+ if (compareMonth(month, targetDate) === 0) {
197
+ if (bodyRef.value) {
198
+ monthRefs.value[index].scrollToDate(bodyRef.value, targetDate);
199
+ }
200
+ return true;
185
201
  }
186
- return true;
187
- }
188
- return false;
202
+ return false;
203
+ });
204
+ onScroll();
189
205
  });
190
- onScroll();
191
- });
206
+ }
192
207
  };
193
208
  const scrollToCurrentDate = () => {
194
209
  if (props.poppable && !props.show) {
@@ -199,7 +214,7 @@ var stdin_default = defineComponent({
199
214
  if (isDate(targetDate)) {
200
215
  scrollToDate(targetDate);
201
216
  }
202
- } else {
217
+ } else if (!canSwitch.value) {
203
218
  raf(onScroll);
204
219
  }
205
220
  };
@@ -207,9 +222,11 @@ var stdin_default = defineComponent({
207
222
  if (props.poppable && !props.show) {
208
223
  return;
209
224
  }
210
- raf(() => {
211
- bodyHeight = Math.floor(useRect(bodyRef).height);
212
- });
225
+ if (!canSwitch.value) {
226
+ raf(() => {
227
+ bodyHeight = Math.floor(useRect(bodyRef).height);
228
+ });
229
+ }
213
230
  scrollToCurrentDate();
214
231
  };
215
232
  const reset = (date = getInitialDate()) => {
@@ -231,6 +248,12 @@ var stdin_default = defineComponent({
231
248
  }
232
249
  return true;
233
250
  };
251
+ const onPanelChange = (date) => {
252
+ currentPanelDate.value = date;
253
+ emit("panelChange", {
254
+ date
255
+ });
256
+ };
234
257
  const onConfirm = () => {
235
258
  var _a;
236
259
  return emit("confirm", (_a = currentDate.value) != null ? _a : cloneDates(currentDate.value));
@@ -322,12 +345,15 @@ var stdin_default = defineComponent({
322
345
  const renderMonth = (date, index) => {
323
346
  const showMonthTitle = index !== 0 || !props.showSubtitle;
324
347
  return _createVNode(CalendarMonth, _mergeProps({
325
- "ref": setMonthRefs(index),
348
+ "ref": canSwitch.value ? currentMonthRef : setMonthRefs(index),
326
349
  "date": date,
327
350
  "currentDate": currentDate.value,
328
351
  "showMonthTitle": showMonthTitle,
329
- "firstDayOfWeek": dayOffset.value
330
- }, pick(props, ["type", "color", "minDate", "maxDate", "showMark", "formatter", "rowHeight", "lazyRender", "showSubtitle", "allowSameDay"]), {
352
+ "firstDayOfWeek": dayOffset.value,
353
+ "lazyRender": canSwitch.value ? false : props.lazyRender,
354
+ "maxDate": maxDate.value,
355
+ "minDate": minDate.value
356
+ }, pick(props, ["type", "color", "showMark", "formatter", "rowHeight", "showSubtitle", "allowSameDay"]), {
331
357
  "onClick": onClickDay,
332
358
  "onClickDisabledDate": (item) => emit("clickDisabledDate", item)
333
359
  }), pick(slots, ["top-info", "bottom-info", "month-title"]));
@@ -362,25 +388,29 @@ var stdin_default = defineComponent({
362
388
  }]
363
389
  }, [renderFooterButton()]);
364
390
  const renderCalendar = () => {
365
- const subTitle = subtitle.value.textFn();
391
+ var _a, _b;
366
392
  return _createVNode("div", {
367
393
  "class": bem()
368
394
  }, [_createVNode(CalendarHeader, {
369
- "date": subtitle.value.date,
395
+ "date": (_a = currentMonthRef.value) == null ? void 0 : _a.date,
396
+ "maxDate": maxDate.value,
397
+ "minDate": minDate.value,
370
398
  "title": props.title,
371
- "subtitle": subTitle,
399
+ "subtitle": (_b = currentMonthRef.value) == null ? void 0 : _b.getTitle(),
372
400
  "showTitle": props.showTitle,
373
401
  "showSubtitle": props.showSubtitle,
402
+ "switchMode": props.switchMode,
374
403
  "firstDayOfWeek": dayOffset.value,
375
- "onClickSubtitle": (event) => emit("clickSubtitle", event)
376
- }, pick(slots, ["title", "subtitle"])), _createVNode("div", {
404
+ "onClickSubtitle": (event) => emit("clickSubtitle", event),
405
+ "onPanelChange": onPanelChange
406
+ }, pick(slots, ["title", "subtitle", "prev-month", "prev-year", "next-month", "next-year"])), _createVNode("div", {
377
407
  "ref": bodyRef,
378
408
  "class": bem("body"),
379
- "onScroll": onScroll
380
- }, [months.value.map(renderMonth)]), renderFooter()]);
409
+ "onScroll": canSwitch.value ? void 0 : onScroll
410
+ }, [canSwitch.value ? renderMonth(currentPanelDate.value, 0) : months.value.map(renderMonth)]), renderFooter()]);
381
411
  };
382
412
  watch(() => props.show, init);
383
- watch(() => [props.type, props.minDate, props.maxDate], () => reset(getInitialDate(currentDate.value)));
413
+ watch(() => [props.type, props.minDate, props.maxDate, props.switchMode], () => reset(getInitialDate(currentDate.value)));
384
414
  watch(() => props.defaultDate, (value = null) => {
385
415
  currentDate.value = value;
386
416
  scrollToCurrentDate();
@@ -1,20 +1,35 @@
1
+ import type { CalendarSwitchMode } from './types';
1
2
  declare const _default: import("vue").DefineComponent<{
2
3
  date: DateConstructor;
4
+ minDate: DateConstructor;
5
+ maxDate: DateConstructor;
3
6
  title: StringConstructor;
4
7
  subtitle: StringConstructor;
5
8
  showTitle: BooleanConstructor;
6
9
  showSubtitle: BooleanConstructor;
7
10
  firstDayOfWeek: NumberConstructor;
8
- }, () => import("vue/jsx-runtime").JSX.Element, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, "clickSubtitle"[], "clickSubtitle", import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
11
+ switchMode: {
12
+ type: import("vue").PropType<CalendarSwitchMode>;
13
+ default: CalendarSwitchMode;
14
+ };
15
+ }, () => import("vue/jsx-runtime").JSX.Element, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("clickSubtitle" | "panelChange")[], "clickSubtitle" | "panelChange", import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
9
16
  date: DateConstructor;
17
+ minDate: DateConstructor;
18
+ maxDate: DateConstructor;
10
19
  title: StringConstructor;
11
20
  subtitle: StringConstructor;
12
21
  showTitle: BooleanConstructor;
13
22
  showSubtitle: BooleanConstructor;
14
23
  firstDayOfWeek: NumberConstructor;
24
+ switchMode: {
25
+ type: import("vue").PropType<CalendarSwitchMode>;
26
+ default: CalendarSwitchMode;
27
+ };
15
28
  }>> & {
16
29
  onClickSubtitle?: ((...args: any[]) => any) | undefined;
30
+ onPanelChange?: ((...args: any[]) => any) | undefined;
17
31
  }, {
32
+ switchMode: CalendarSwitchMode;
18
33
  showTitle: boolean;
19
34
  showSubtitle: boolean;
20
35
  }, {}>;
@@ -1,23 +1,43 @@
1
1
  import { createVNode as _createVNode } from "vue";
2
- import { defineComponent } from "vue";
3
- import { createNamespace } from "../utils/index.mjs";
4
- import { t, bem } from "./utils.mjs";
2
+ import { computed, defineComponent } from "vue";
3
+ import { createNamespace, HAPTICS_FEEDBACK, makeStringProp } from "../utils/index.mjs";
4
+ import { t, bem, getPrevMonth, getPrevYear, getNextMonth, getNextYear } from "./utils.mjs";
5
+ import { Icon } from "../icon/index.mjs";
5
6
  const [name] = createNamespace("calendar-header");
6
7
  var stdin_default = defineComponent({
7
8
  name,
8
9
  props: {
9
10
  date: Date,
11
+ minDate: Date,
12
+ maxDate: Date,
10
13
  title: String,
11
14
  subtitle: String,
12
15
  showTitle: Boolean,
13
16
  showSubtitle: Boolean,
14
- firstDayOfWeek: Number
17
+ firstDayOfWeek: Number,
18
+ switchMode: makeStringProp("none")
15
19
  },
16
- emits: ["clickSubtitle"],
20
+ emits: ["clickSubtitle", "panelChange"],
17
21
  setup(props, {
18
22
  slots,
19
23
  emit
20
24
  }) {
25
+ const prevMonthDisabled = computed(() => {
26
+ const prevMonth = getPrevMonth(props.date);
27
+ return props.minDate && prevMonth < props.minDate;
28
+ });
29
+ const prevYearDisabled = computed(() => {
30
+ const prevYear = getPrevYear(props.date);
31
+ return props.minDate && prevYear < props.minDate;
32
+ });
33
+ const nextMonthDisabled = computed(() => {
34
+ const nextMonth = getNextMonth(props.date);
35
+ return props.maxDate && nextMonth > props.maxDate;
36
+ });
37
+ const nextYearDisabled = computed(() => {
38
+ const nextYear = getNextYear(props.date);
39
+ return props.maxDate && nextYear > props.maxDate;
40
+ });
21
41
  const renderTitle = () => {
22
42
  if (props.showTitle) {
23
43
  const text = props.title || t("title");
@@ -28,16 +48,60 @@ var stdin_default = defineComponent({
28
48
  }
29
49
  };
30
50
  const onClickSubtitle = (event) => emit("clickSubtitle", event);
51
+ const onPanelChange = (date) => emit("panelChange", date);
52
+ const renderAction = (isNext) => {
53
+ const showYearAction = props.switchMode === "year-month";
54
+ const monthSlot = slots[isNext ? "next-month" : "prev-month"];
55
+ const yearSlot = slots[isNext ? "next-year" : "prev-year"];
56
+ const monthDisabled = isNext ? nextMonthDisabled.value : prevMonthDisabled.value;
57
+ const yearDisabled = isNext ? nextYearDisabled.value : prevYearDisabled.value;
58
+ const monthIconName = isNext ? "arrow" : "arrow-left";
59
+ const yearIconName = isNext ? "arrow-double-right" : "arrow-double-left";
60
+ const onMonthChange = () => onPanelChange((isNext ? getNextMonth : getPrevMonth)(props.date));
61
+ const onYearChange = () => onPanelChange((isNext ? getNextYear : getPrevYear)(props.date));
62
+ const MonthAction = _createVNode("view", {
63
+ "class": bem("header-action", {
64
+ disabled: monthDisabled
65
+ }),
66
+ "onClick": monthDisabled ? void 0 : onMonthChange
67
+ }, [monthSlot ? monthSlot({
68
+ disabled: monthDisabled
69
+ }) : _createVNode(Icon, {
70
+ "class": {
71
+ [HAPTICS_FEEDBACK]: !monthDisabled
72
+ },
73
+ "name": monthIconName
74
+ }, null)]);
75
+ const YearAction = showYearAction && _createVNode("view", {
76
+ "class": bem("header-action", {
77
+ disabled: yearDisabled
78
+ }),
79
+ "onClick": yearDisabled ? void 0 : onYearChange
80
+ }, [yearSlot ? yearSlot({
81
+ disabled: yearDisabled
82
+ }) : _createVNode(Icon, {
83
+ "class": {
84
+ [HAPTICS_FEEDBACK]: !yearDisabled
85
+ },
86
+ "name": yearIconName
87
+ }, null)]);
88
+ return isNext ? [MonthAction, YearAction] : [YearAction, MonthAction];
89
+ };
31
90
  const renderSubtitle = () => {
32
91
  if (props.showSubtitle) {
33
92
  const title = slots.subtitle ? slots.subtitle({
34
93
  date: props.date,
35
94
  text: props.subtitle
36
95
  }) : props.subtitle;
96
+ const canSwitch = props.switchMode !== "none";
37
97
  return _createVNode("div", {
38
- "class": bem("header-subtitle"),
98
+ "class": bem("header-subtitle", {
99
+ "with-swicth": canSwitch
100
+ }),
39
101
  "onClick": onClickSubtitle
40
- }, [title]);
102
+ }, [canSwitch ? [renderAction(), _createVNode("div", {
103
+ "class": bem("header-subtitle-text")
104
+ }, [title]), renderAction(true)] : title]);
41
105
  }
42
106
  };
43
107
  const renderWeekDays = () => {
@@ -7,14 +7,8 @@ declare const calendarMonthProps: {
7
7
  };
8
8
  type: PropType<CalendarType>;
9
9
  color: StringConstructor;
10
- minDate: {
11
- type: DateConstructor;
12
- required: true;
13
- };
14
- maxDate: {
15
- type: DateConstructor;
16
- required: true;
17
- };
10
+ minDate: DateConstructor;
11
+ maxDate: DateConstructor;
18
12
  showMark: BooleanConstructor;
19
13
  rowHeight: (NumberConstructor | StringConstructor)[];
20
14
  formatter: PropType<(item: CalendarDayItem) => CalendarDayItem>;
@@ -33,14 +27,8 @@ declare const _default: import("vue").DefineComponent<{
33
27
  };
34
28
  type: PropType<CalendarType>;
35
29
  color: StringConstructor;
36
- minDate: {
37
- type: DateConstructor;
38
- required: true;
39
- };
40
- maxDate: {
41
- type: DateConstructor;
42
- required: true;
43
- };
30
+ minDate: DateConstructor;
31
+ maxDate: DateConstructor;
44
32
  showMark: BooleanConstructor;
45
33
  rowHeight: (NumberConstructor | StringConstructor)[];
46
34
  formatter: PropType<(item: CalendarDayItem) => CalendarDayItem>;
@@ -57,14 +45,8 @@ declare const _default: import("vue").DefineComponent<{
57
45
  };
58
46
  type: PropType<CalendarType>;
59
47
  color: StringConstructor;
60
- minDate: {
61
- type: DateConstructor;
62
- required: true;
63
- };
64
- maxDate: {
65
- type: DateConstructor;
66
- required: true;
67
- };
48
+ minDate: DateConstructor;
49
+ maxDate: DateConstructor;
68
50
  showMark: BooleanConstructor;
69
51
  rowHeight: (NumberConstructor | StringConstructor)[];
70
52
  formatter: PropType<(item: CalendarDayItem) => CalendarDayItem>;
@@ -12,8 +12,8 @@ const calendarMonthProps = {
12
12
  date: makeRequiredProp(Date),
13
13
  type: String,
14
14
  color: String,
15
- minDate: makeRequiredProp(Date),
16
- maxDate: makeRequiredProp(Date),
15
+ minDate: Date,
16
+ maxDate: Date,
17
17
  showMark: Boolean,
18
18
  rowHeight: numericProp,
19
19
  formatter: Function,
@@ -39,7 +39,9 @@ var stdin_default = defineComponent({
39
39
  const title = computed(() => formatMonthTitle(props.date));
40
40
  const rowHeight = computed(() => addUnit(props.rowHeight));
41
41
  const offset = computed(() => {
42
- const realDay = props.date.getDay();
42
+ const date = props.date.getDate();
43
+ const day = props.date.getDay();
44
+ const realDay = (day - date % 7 + 8) % 7;
43
45
  if (props.firstDayOfWeek) {
44
46
  return (realDay + 7 - props.firstDayOfWeek) % 7;
45
47
  }
@@ -99,7 +101,7 @@ var stdin_default = defineComponent({
99
101
  maxDate,
100
102
  currentDate
101
103
  } = props;
102
- if (compareDay(day, minDate) < 0 || compareDay(day, maxDate) > 0) {
104
+ if (minDate && compareDay(day, minDate) < 0 || maxDate && compareDay(day, maxDate) > 0) {
103
105
  return "disabled";
104
106
  }
105
107
  if (currentDate === null) {
@@ -1 +1 @@
1
- :root,:host{--van-calendar-background: var(--van-background-2);--van-calendar-popup-height: 80%;--van-calendar-header-shadow: 0 2px 10px rgba(125, 126, 128, .16);--van-calendar-header-title-height: 44px;--van-calendar-header-title-font-size: var(--van-font-size-lg);--van-calendar-header-subtitle-font-size: var(--van-font-size-md);--van-calendar-weekdays-height: 30px;--van-calendar-weekdays-font-size: var(--van-font-size-sm);--van-calendar-month-title-font-size: var(--van-font-size-md);--van-calendar-month-mark-color: rgba(242, 243, 245, .8);--van-calendar-month-mark-font-size: 160px;--van-calendar-day-height: 64px;--van-calendar-day-font-size: var(--van-font-size-lg);--van-calendar-day-margin-bottom: 4px;--van-calendar-range-edge-color: var(--van-white);--van-calendar-range-edge-background: var(--van-primary-color);--van-calendar-range-middle-color: var(--van-primary-color);--van-calendar-range-middle-background-opacity: .1;--van-calendar-selected-day-size: 54px;--van-calendar-selected-day-color: var(--van-white);--van-calendar-info-font-size: var(--van-font-size-xs);--van-calendar-info-line-height: var(--van-line-height-xs);--van-calendar-selected-day-background: var(--van-primary-color);--van-calendar-day-disabled-color: var(--van-text-color-3);--van-calendar-confirm-button-height: 36px;--van-calendar-confirm-button-margin: 7px 0}.van-theme-dark{--van-calendar-month-mark-color: rgba(100, 101, 102, .2);--van-calendar-day-disabled-color: var(--van-gray-7)}.van-calendar{display:flex;flex-direction:column;height:100%;background:var(--van-calendar-background)}.van-calendar__popup.van-popup--top,.van-calendar__popup.van-popup--bottom{height:var(--van-calendar-popup-height)}.van-calendar__popup.van-popup--left,.van-calendar__popup.van-popup--right{height:100%}.van-calendar__popup .van-popup__close-icon{top:11px}.van-calendar__header{flex-shrink:0;box-shadow:var(--van-calendar-header-shadow)}.van-calendar__month-title,.van-calendar__header-title,.van-calendar__header-subtitle{color:var(--van-text-color);height:var(--van-calendar-header-title-height);font-weight:var(--van-font-bold);line-height:var(--van-calendar-header-title-height);text-align:center}.van-calendar__header-title{font-size:var(--van-calendar-header-title-font-size)}.van-calendar__header-subtitle{font-size:var(--van-calendar-header-subtitle-font-size)}.van-calendar__month-title{font-size:var(--van-calendar-month-title-font-size)}.van-calendar__weekdays{display:flex}.van-calendar__weekday{flex:1;font-size:var(--van-calendar-weekdays-font-size);line-height:var(--van-calendar-weekdays-height);text-align:center}.van-calendar__body{flex:1;overflow:auto;-webkit-overflow-scrolling:touch}.van-calendar__days{position:relative;display:flex;flex-wrap:wrap;-webkit-user-select:none;user-select:none}.van-calendar__month-mark{position:absolute;top:50%;left:50%;z-index:0;color:var(--van-calendar-month-mark-color);font-size:var(--van-calendar-month-mark-font-size);transform:translate(-50%,-50%);pointer-events:none}.van-calendar__day,.van-calendar__selected-day{display:flex;align-items:center;justify-content:center;text-align:center}.van-calendar__day{position:relative;width:14.285%;height:var(--van-calendar-day-height);font-size:var(--van-calendar-day-font-size);margin-bottom:var(--van-calendar-day-margin-bottom);cursor:pointer}.van-calendar__day--end,.van-calendar__day--start,.van-calendar__day--start-end,.van-calendar__day--multiple-middle,.van-calendar__day--multiple-selected{color:var(--van-calendar-range-edge-color);background:var(--van-calendar-range-edge-background)}.van-calendar__day--start{border-radius:var(--van-radius-md) 0 0 var(--van-radius-md)}.van-calendar__day--end{border-radius:0 var(--van-radius-md) var(--van-radius-md) 0}.van-calendar__day--start-end,.van-calendar__day--multiple-selected{border-radius:var(--van-radius-md)}.van-calendar__day--middle{color:var(--van-calendar-range-middle-color)}.van-calendar__day--middle:after{position:absolute;top:0;right:0;bottom:0;left:0;background-color:currentColor;opacity:var(--van-calendar-range-middle-background-opacity);content:""}.van-calendar__day--disabled{color:var(--van-calendar-day-disabled-color);cursor:default}.van-calendar__top-info,.van-calendar__bottom-info{position:absolute;right:0;left:0;font-size:var(--van-calendar-info-font-size);line-height:var(--van-calendar-info-line-height)}@media (max-width: 350px){.van-calendar__top-info,.van-calendar__bottom-info{font-size:9px}}.van-calendar__top-info{top:6px}.van-calendar__bottom-info{bottom:6px}.van-calendar__selected-day{width:var(--van-calendar-selected-day-size);height:var(--van-calendar-selected-day-size);color:var(--van-calendar-selected-day-color);background:var(--van-calendar-selected-day-background);border-radius:var(--van-radius-md)}.van-calendar__footer{flex-shrink:0;padding-left:var(--van-padding-md);padding-right:var(--van-padding-md)}.van-calendar__confirm{height:var(--van-calendar-confirm-button-height);margin:var(--van-calendar-confirm-button-margin)}
1
+ :root,:host{--van-calendar-background: var(--van-background-2);--van-calendar-popup-height: 80%;--van-calendar-header-shadow: 0 2px 10px rgba(125, 126, 128, .16);--van-calendar-header-title-height: 44px;--van-calendar-header-title-font-size: var(--van-font-size-lg);--van-calendar-header-subtitle-font-size: var(--van-font-size-md);--van-calendar-header-action-width: 28px;--van-calendar-header-action-color: var(--van-text-color);--van-calendar-header-action-disabled-color: var(--van-text-color-3);--van-calendar-weekdays-height: 30px;--van-calendar-weekdays-font-size: var(--van-font-size-sm);--van-calendar-month-title-font-size: var(--van-font-size-md);--van-calendar-month-mark-color: rgba(242, 243, 245, .8);--van-calendar-month-mark-font-size: 160px;--van-calendar-day-height: 64px;--van-calendar-day-font-size: var(--van-font-size-lg);--van-calendar-day-margin-bottom: 4px;--van-calendar-range-edge-color: var(--van-white);--van-calendar-range-edge-background: var(--van-primary-color);--van-calendar-range-middle-color: var(--van-primary-color);--van-calendar-range-middle-background-opacity: .1;--van-calendar-selected-day-size: 54px;--van-calendar-selected-day-color: var(--van-white);--van-calendar-info-font-size: var(--van-font-size-xs);--van-calendar-info-line-height: var(--van-line-height-xs);--van-calendar-selected-day-background: var(--van-primary-color);--van-calendar-day-disabled-color: var(--van-text-color-3);--van-calendar-confirm-button-height: 36px;--van-calendar-confirm-button-margin: 7px 0}.van-theme-dark{--van-calendar-month-mark-color: rgba(100, 101, 102, .2);--van-calendar-day-disabled-color: var(--van-gray-7)}.van-calendar{display:flex;flex-direction:column;height:100%;background:var(--van-calendar-background)}.van-calendar__popup.van-popup--top,.van-calendar__popup.van-popup--bottom{height:var(--van-calendar-popup-height)}.van-calendar__popup.van-popup--left,.van-calendar__popup.van-popup--right{height:100%}.van-calendar__popup .van-popup__close-icon{top:11px}.van-calendar__header{flex-shrink:0;box-shadow:var(--van-calendar-header-shadow)}.van-calendar__month-title,.van-calendar__header-title,.van-calendar__header-subtitle{color:var(--van-text-color);height:var(--van-calendar-header-title-height);font-weight:var(--van-font-bold);line-height:var(--van-calendar-header-title-height);text-align:center}.van-calendar__header-title{font-size:var(--van-calendar-header-title-font-size)}.van-calendar__header-subtitle{font-size:var(--van-calendar-header-subtitle-font-size)}.van-calendar__header-subtitle--with-swicth{display:flex;align-items:center;padding:0 var(--van-padding-base)}.van-calendar__header-subtitle-text{flex:1}.van-calendar__header-action{display:flex;align-items:center;justify-content:center;min-width:var(--van-calendar-header-action-width);height:100%;color:var(--van-calendar-header-action-color);cursor:pointer}.van-calendar__header-action--disabled{color:var(--van-calendar-header-action-disabled-color);cursor:not-allowed}.van-calendar__month-title{font-size:var(--van-calendar-month-title-font-size)}.van-calendar__weekdays{display:flex}.van-calendar__weekday{flex:1;font-size:var(--van-calendar-weekdays-font-size);line-height:var(--van-calendar-weekdays-height);text-align:center}.van-calendar__body{flex:1;overflow:auto;-webkit-overflow-scrolling:touch}.van-calendar__days{position:relative;display:flex;flex-wrap:wrap;-webkit-user-select:none;user-select:none}.van-calendar__month-mark{position:absolute;top:50%;left:50%;z-index:0;color:var(--van-calendar-month-mark-color);font-size:var(--van-calendar-month-mark-font-size);transform:translate(-50%,-50%);pointer-events:none}.van-calendar__day,.van-calendar__selected-day{display:flex;align-items:center;justify-content:center;text-align:center}.van-calendar__day{position:relative;width:14.285%;height:var(--van-calendar-day-height);font-size:var(--van-calendar-day-font-size);margin-bottom:var(--van-calendar-day-margin-bottom);cursor:pointer}.van-calendar__day--end,.van-calendar__day--start,.van-calendar__day--start-end,.van-calendar__day--multiple-middle,.van-calendar__day--multiple-selected{color:var(--van-calendar-range-edge-color);background:var(--van-calendar-range-edge-background)}.van-calendar__day--start{border-radius:var(--van-radius-md) 0 0 var(--van-radius-md)}.van-calendar__day--end{border-radius:0 var(--van-radius-md) var(--van-radius-md) 0}.van-calendar__day--start-end,.van-calendar__day--multiple-selected{border-radius:var(--van-radius-md)}.van-calendar__day--middle{color:var(--van-calendar-range-middle-color)}.van-calendar__day--middle:after{position:absolute;top:0;right:0;bottom:0;left:0;background-color:currentColor;opacity:var(--van-calendar-range-middle-background-opacity);content:""}.van-calendar__day--disabled{color:var(--van-calendar-day-disabled-color);cursor:default}.van-calendar__top-info,.van-calendar__bottom-info{position:absolute;right:0;left:0;font-size:var(--van-calendar-info-font-size);line-height:var(--van-calendar-info-line-height)}@media (max-width: 350px){.van-calendar__top-info,.van-calendar__bottom-info{font-size:9px}}.van-calendar__top-info{top:6px}.van-calendar__bottom-info{bottom:6px}.van-calendar__selected-day{width:var(--van-calendar-selected-day-size);height:var(--van-calendar-selected-day-size);color:var(--van-calendar-selected-day-color);background:var(--van-calendar-selected-day-background);border-radius:var(--van-radius-md)}.van-calendar__footer{flex-shrink:0;padding-left:var(--van-padding-md);padding-right:var(--van-padding-md)}.van-calendar__confirm{height:var(--van-calendar-confirm-button-height);margin:var(--van-calendar-confirm-button-margin)}