vueless 0.0.331 → 0.0.333

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.
@@ -49,7 +49,7 @@
49
49
  variant="thirdary"
50
50
  :left-icon="config.defaults.prevIcon"
51
51
  v-bind="shiftRangeButtonAttrs"
52
- @click="onClickShiftRange('prev')"
52
+ @click="onClickShiftRange(SHIFT_ACTION.prev)"
53
53
  />
54
54
 
55
55
  <UButton
@@ -76,7 +76,7 @@
76
76
  variant="thirdary"
77
77
  :left-icon="config.defaults.nextIcon"
78
78
  v-bind="shiftRangeButtonAttrs"
79
- @click="onClickShiftRange('next')"
79
+ @click="onClickShiftRange(SHIFT_ACTION.next)"
80
80
  />
81
81
  </div>
82
82
 
@@ -89,116 +89,39 @@
89
89
  v-bind="menuAttrs"
90
90
  @keydown.esc="deactivate"
91
91
  >
92
- <div v-bind="periodsRowAttrs">
93
- <UButton
94
- v-for="periodButton in periods"
95
- :key="periodButton.name"
96
- square
97
- filled
98
- no-ring
99
- size="xs"
100
- variant="thirdary"
101
- :label="periodButton.title"
102
- v-bind="periodButtonAttrs(getPeriodButtonsClasses(periodButton.name))"
103
- @click="onClickPeriodButton(periodButton.name)"
104
- />
105
- </div>
106
-
107
- <div v-bind="periodsRowAttrs">
108
- <UButton
109
- v-if="customRangeButton.range.to && customRangeButton.range.from"
110
- square
111
- filled
112
- no-ring
113
- size="xs"
114
- variant="thirdary"
115
- v-bind="periodButtonAttrs(getPeriodButtonsClasses(PERIOD.custom))"
116
- @click="onClickCustomRangeButton"
117
- >
118
- {{ customRangeButton.label }}
119
- <span v-if="customRangeButton.description" v-text="customRangeButton.description" />
120
- </UButton>
121
-
122
- <UButton
123
- square
124
- filled
125
- no-ring
126
- size="xs"
127
- variant="thirdary"
128
- :label="locale.ownRange"
129
- :left-icon="config.defaults.ownRangeIcon"
130
- v-bind="periodButtonAttrs(getPeriodButtonsClasses(PERIOD.ownRange))"
131
- @click="onClickOwnRange"
132
- />
133
- </div>
92
+ <UDatePickerRangePeriodMenu
93
+ v-model:local-value="localValue"
94
+ v-model:active-date="activeDate"
95
+ v-model:period-date-list="periodDateList"
96
+ v-model:period="period"
97
+ :config="config"
98
+ :is-period="isPeriod"
99
+ :custom-range-button="customRangeButton"
100
+ :locale="locale"
101
+ :attrs="periodDatesMenuAttrs"
102
+ :date-format="dateFormat"
103
+ :min-date="minDate"
104
+ :max-date="maxDate"
105
+ @toggle-menu="isShownMenu = !isShownMenu"
106
+ @close-menu="isShownMenu = false"
107
+ @click-prev="onClickShiftDatesList(SHIFT_ACTION.prev)"
108
+ @click-next="onClickShiftDatesList(SHIFT_ACTION.next)"
109
+ />
134
110
 
135
- <template v-if="!isPeriod.ownRange && !isPeriod.custom">
136
- <div v-bind="rangeSwitchWrapperAttrs">
137
- <UButton
138
- square
139
- no-ring
140
- size="xs"
141
- color="gray"
142
- variant="thirdary"
143
- :left-icon="config.defaults.prevIcon"
144
- v-bind="rangeSwitchButtonAttrs"
145
- @click="onClickShiftDatesList('prev')"
146
- />
147
-
148
- <div v-bind="rangeSwitchTitleAttrs">
149
- {{ rangeSwitchTitle }}
150
- </div>
151
-
152
- <UButton
153
- square
154
- no-ring
155
- size="xs"
156
- color="gray"
157
- variant="thirdary"
158
- :left-icon="config.defaults.nextIcon"
159
- v-bind="rangeSwitchButtonAttrs"
160
- @click="onClickShiftDatesList('next')"
161
- />
162
- </div>
163
-
164
- <div v-bind="periodDateListAttrs(getPeriodDateListClasses())">
165
- <UButton
166
- v-for="(date, index) in periodDateList"
167
- :key="date.title"
168
- no-ring
169
- size="sm"
170
- variant="thirdary"
171
- :disabled="isDatePeriodOutOfRange(date)"
172
- v-bind="periodDateAttrs(getPeriodDateClasses(date, index))"
173
- :label="String(date.title)"
174
- @click="selectDate(date), toggleMenu()"
175
- />
176
- </div>
177
- </template>
178
-
179
- <div v-if="isPeriod.ownRange" v-bind="rangeInputWrapperAttrs">
180
- <UInput
181
- ref="rangeInputStartRef"
182
- v-model="rangeStart"
183
- :error="inputRangeFromError"
184
- size="md"
185
- v-bind="rangeInputAttrs"
186
- :class="cx([rangeInputAttrs.class, config.rangeInputFirst])"
187
- :name="rangeInputName"
188
- @input="onInputRangeInput($event, INPUT_RANGE_TYPE.start)"
189
- />
190
-
191
- <UInput
192
- ref="rangeInputEndRef"
193
- v-model="rangeEnd"
194
- :error="inputRangeToError"
195
- size="md"
196
- v-bind="rangeInputAttrs"
197
- :class="cx([rangeInputAttrs.class, config.rangeInputLast])"
198
- :name="rangeInputName"
199
- @input="onInputRangeInput($event, INPUT_RANGE_TYPE.end)"
200
- />
201
- </div>
111
+ <UDatePickerRangeInputs
112
+ v-if="isPeriod.ownRange"
113
+ v-bind="rangeInputWrapperAttrs"
114
+ v-model:local-value="localValue"
115
+ v-model:input-range-from-error="inputRangeFromError"
116
+ v-model:input-range-to-error="inputRangeToError"
117
+ v-model:range-start="rangeStart"
118
+ v-model:range-end="rangeEnd"
119
+ :range-input-name="rangeInputName"
120
+ :locale="locale"
121
+ :date-format="dateFormat"
122
+ :config="config"
123
+ :attrs="rangeInputsAttrs"
124
+ />
202
125
 
203
126
  <div v-if="inputRangeToError || inputRangeFromError" v-bind="inputRangeErrorAttrs">
204
127
  {{ inputRangeToError || inputRangeFromError }}
@@ -221,23 +144,21 @@
221
144
  </template>
222
145
 
223
146
  <script setup>
224
- import { computed, watch, ref, nextTick } from "vue";
225
- import { merge } from "lodash-es";
147
+ import { computed, watch, ref, nextTick, provide } from "vue";
148
+ import { getRandomId, getDefault } from "../utils/utilUI.js";
226
149
 
227
150
  import UInput from "../ui.form-input/UInput.vue";
228
- import UButton from "../ui.button/UButton.vue";
229
151
  import UCalendar from "../ui.form-calendar/UCalendar.vue";
230
- import { LOCALE_TYPE } from "../ui.form-calendar/constants.js";
152
+ import UDatePickerRangePeriodMenu from "./UDatePickerRangePeriodMenu.vue";
153
+ import UDatePickerRangeInputs from "./UDatePickerRangeInputs.vue";
154
+ import UButton from "../ui.button/UButton.vue";
231
155
 
232
156
  import vClickOutside from "../directives/vClickOutside.js";
233
157
 
234
- import { getRandomId, getDefault, cx } from "../utils/utilUI.js";
235
-
236
158
  import {
237
159
  addDays,
238
160
  addMonths,
239
161
  addYears,
240
- getSortedLocale,
241
162
  getEndOfMonth,
242
163
  getEndOfQuarter,
243
164
  getEndOfWeek,
@@ -247,10 +168,9 @@ import {
247
168
  getStartOfWeek,
248
169
  getStartOfYear,
249
170
  getDatesDifference,
250
- isSameMonth,
251
171
  } from "../ui.form-calendar/utilDate.js";
252
172
 
253
- import { dateIsOutOfRange, formatDate, parseDate } from "../ui.form-calendar/utilCalendar.js";
173
+ import { formatDate, parseDate, dateIsOutOfRange } from "../ui.form-calendar/utilCalendar.js";
254
174
 
255
175
  import {
256
176
  getWeekDateList,
@@ -259,11 +179,10 @@ import {
259
179
  getMonthsDateList,
260
180
  } from "./utilDateRange.js";
261
181
 
262
- import { isWrongDateFormat, isWrongMonthNumber, isWrongDayNumber } from "./utilValidation.js";
263
182
  import useAttrs from "./useAttrs.js";
264
- import { useLocale } from "../composables/useLocale.js";
265
- import useBreakpoint from "../composables/useBreakpoint.js";
266
183
  import { useAutoPosition } from "../composables/useAutoPosition.js";
184
+ import { useLocale } from "./useLocale.js";
185
+ import { useUserFormat } from "./useUserFormat.js";
267
186
 
268
187
  import defaultConfig from "./config.js";
269
188
  import {
@@ -271,7 +190,8 @@ import {
271
190
  DATE_PICKER_BUTTON_TYPE,
272
191
  DATE_PICKER_INPUT_TYPE,
273
192
  PERIOD,
274
- INPUT_RANGE_TYPE,
193
+ INPUT_RANGE_FORMAT,
194
+ SHIFT_ACTION,
275
195
  } from "./constants.js";
276
196
 
277
197
  defineOptions({ inheritAttrs: false });
@@ -442,8 +362,6 @@ const props = defineProps({
442
362
  },
443
363
  });
444
364
 
445
- const inputRangeFormat = "d.m.Y";
446
-
447
365
  const emit = defineEmits([
448
366
  /**
449
367
  * Triggers when date picker range value changes.
@@ -469,48 +387,33 @@ const { isTop, isRight, adjustPositionY, adjustPositionX } = useAutoPosition(
469
387
  { x: "left", y: "bottom" },
470
388
  );
471
389
 
390
+ const { locale, userFormatLocale } = useLocale(props);
391
+
392
+ const isPeriod = computed(() => {
393
+ return {
394
+ week: period.value === PERIOD.week,
395
+ month: period.value === PERIOD.month,
396
+ quarter: period.value === PERIOD.quarter,
397
+ year: period.value === PERIOD.year,
398
+ ownRange: period.value === PERIOD.ownRange,
399
+ custom: period.value === PERIOD.custom,
400
+ };
401
+ });
402
+
472
403
  const {
473
404
  config,
474
405
  wrapperAttrs,
475
406
  calendarAttrs,
476
407
  inputAttrs,
477
408
  menuAttrs,
478
- periodsRowAttrs,
479
- periodButtonAttrs,
480
- periodDateAttrs,
481
- periodDateListAttrs,
482
- rangeSwitchWrapperAttrs,
483
- rangeSwitchButtonAttrs,
484
- rangeSwitchTitleAttrs,
485
409
  buttonWrapperAttrs,
486
410
  buttonAttrs,
487
411
  shiftRangeButtonAttrs,
488
- rangeInputAttrs,
489
412
  rangeInputWrapperAttrs,
490
413
  inputRangeErrorAttrs,
491
- } = useAttrs(props, { isShownMenu, isTop, isRight });
492
- const { tm } = useLocale();
493
-
494
- const i18nGlobal = tm(UDatePickerRange);
495
-
496
- const currentLocale = computed(() => merge(defaultConfig.i18n, i18nGlobal, props.config.i18n));
497
-
498
- const locale = computed(() => {
499
- const { months, weekdays } = currentLocale.value;
500
-
501
- // formatted locale
502
- return {
503
- ...currentLocale.value,
504
- months: {
505
- shorthand: getSortedLocale(months.shorthand, LOCALE_TYPE.month),
506
- longhand: getSortedLocale(months.longhand, LOCALE_TYPE.month),
507
- },
508
- weekdays: {
509
- shorthand: getSortedLocale(weekdays.shorthand, LOCALE_TYPE.day),
510
- longhand: getSortedLocale(weekdays.longhand, LOCALE_TYPE.day),
511
- },
512
- };
513
- });
414
+ periodDatesMenuAttrs,
415
+ rangeInputsAttrs,
416
+ } = useAttrs(props, { isShownMenu, isTop, isRight, isPeriod });
514
417
 
515
418
  const calendarValue = ref(props.modelValue);
516
419
  const activeDate = ref(
@@ -524,9 +427,9 @@ const rangeEnd = ref("");
524
427
  const inputRangeFromError = ref("");
525
428
  const inputRangeToError = ref("");
526
429
  const calendarInnerValue = ref({ from: "", to: "" });
527
- const periodDateList = ref(null);
430
+ const periodDateList = ref([]);
528
431
 
529
- const { isMobileBreakpoint } = useBreakpoint();
432
+ provide("isDatePeriodOutOfRange", (datePeriod) => isDatePeriodOutOfRange(datePeriod));
530
433
 
531
434
  const localValue = computed({
532
435
  get: () => {
@@ -558,79 +461,6 @@ const localValue = computed({
558
461
 
559
462
  const rangeInputName = computed(() => `rangeInput-${props.id}`);
560
463
 
561
- const userFormatLocale = computed(() => {
562
- const { months, weekdays } = currentLocale.value;
563
-
564
- const monthsLonghand =
565
- Boolean(props.config.i18n?.months?.userFormat) || Boolean(i18nGlobal?.months?.userFormat)
566
- ? months.userFormat
567
- : months.longhand;
568
-
569
- const weekdaysLonghand =
570
- Boolean(props.config.i18n?.weekdays?.userFormat) || Boolean(i18nGlobal?.weekdays?.userFormat)
571
- ? weekdays.userFormat
572
- : weekdays.longhand;
573
-
574
- // formatted locale
575
- return {
576
- ...currentLocale,
577
- months: {
578
- shorthand: getSortedLocale(months.shorthand, LOCALE_TYPE.month),
579
- longhand: getSortedLocale(monthsLonghand, LOCALE_TYPE.month),
580
- },
581
- weekdays: {
582
- shorthand: getSortedLocale(weekdays.shorthand, LOCALE_TYPE.day),
583
- longhand: getSortedLocale(weekdaysLonghand, LOCALE_TYPE.day),
584
- },
585
- };
586
- });
587
-
588
- const periods = computed(() => [
589
- {
590
- name: PERIOD.week,
591
- title: locale.value.week,
592
- },
593
- {
594
- name: PERIOD.month,
595
- title: locale.value.month,
596
- },
597
- {
598
- name: PERIOD.quarter,
599
- title: locale.value.quarter,
600
- },
601
- {
602
- name: PERIOD.year,
603
- title: locale.value.year,
604
- },
605
- ]);
606
-
607
- const isPeriod = computed(() => {
608
- return {
609
- week: period.value === PERIOD.week,
610
- month: period.value === PERIOD.month,
611
- quarter: period.value === PERIOD.quarter,
612
- year: period.value === PERIOD.year,
613
- ownRange: period.value === PERIOD.ownRange,
614
- custom: period.value === PERIOD.custom,
615
- };
616
- });
617
-
618
- const rangeSwitchTitle = computed(() => {
619
- if (isPeriod.value.month || isPeriod.value.quarter) {
620
- return String(activeDate.value.getFullYear());
621
- }
622
-
623
- if (isPeriod.value.year) {
624
- return `${periodDateList.value.at(0).title} – ${periodDateList.value.at(-1).title}`;
625
- }
626
-
627
- if (isPeriod.value.week) {
628
- return `${locale.value.months.longhand[activeDate.value.getMonth()]} ${activeDate.value.getFullYear()}`;
629
- }
630
-
631
- return "";
632
- });
633
-
634
464
  const isVariant = computed(() => ({
635
465
  button: props.variant === DATE_PICKER_BUTTON_TYPE,
636
466
  input: props.variant === DATE_PICKER_INPUT_TYPE,
@@ -650,80 +480,7 @@ const clickOutsideOptions = computed(() => {
650
480
  };
651
481
  });
652
482
 
653
- const userFormatDate = computed(() => {
654
- if ((!localValue.value.from && !localValue.value.to) || !localValue.value.from) return "";
655
-
656
- let title = "";
657
-
658
- const isDefaultTitle = isPeriod.value.week || isPeriod.value.custom || isPeriod.value.ownRange;
659
-
660
- const from = localValue.value.from;
661
- const to = localValue.value.to !== null ? localValue.value.to : null;
662
-
663
- if (isDefaultTitle) {
664
- let startMonthName = userFormatLocale.value.months.longhand[from.getMonth()];
665
- let startYear = from.getFullYear();
666
- let endMonthName = userFormatLocale.value.months.longhand[to?.getMonth()];
667
- let endYear = to?.getFullYear();
668
-
669
- if (startMonthName === endMonthName && endMonthName === endYear) {
670
- startMonthName = "";
671
- }
672
-
673
- if (startYear.year === endYear) {
674
- startYear = "";
675
- }
676
-
677
- const isDatesToSameMonth = isSameMonth(from, to);
678
- const isDatesToSameYear = from.getFullYear() === to.getFullYear();
679
-
680
- let fromTitle = `${from.getDate()} ${startMonthName} ${startYear}`;
681
-
682
- if (isDatesToSameMonth && isDatesToSameYear) {
683
- fromTitle = from.getDate();
684
- }
685
-
686
- if (!isDatesToSameMonth && isDatesToSameYear) {
687
- fromTitle = `${from.getDate()} ${startMonthName}`;
688
- }
689
-
690
- const toTitle = to ? `${to.getDate()} ${endMonthName} ${endYear}` : "";
691
-
692
- title = `${fromTitle} – ${toTitle}`;
693
- }
694
-
695
- if (isPeriod.value.month) {
696
- const startMonthName = userFormatLocale.value.months.longhand[from.getMonth()];
697
- const startYear = from.getFullYear();
698
-
699
- title = `${startMonthName} ${startYear}`;
700
- }
701
-
702
- if (isPeriod.value.quarter || isPeriod.value.year) {
703
- const startMonthName = userFormatLocale.value.months.longhand[from.getMonth()];
704
- const endMonthName = userFormatLocale.value.months.longhand[to?.getMonth()];
705
- const endYear = to?.getFullYear();
706
-
707
- const fromTitle = `${from.getDate()} ${startMonthName}`;
708
- const toTitle = to ? `${to.getDate()} ${endMonthName} ${endYear}` : "";
709
-
710
- title = `${fromTitle} – ${toTitle}`;
711
- }
712
-
713
- if (isMobileBreakpoint.value && !isPeriod.value.month && isVariant.value.button) {
714
- const startDay = String(from.getDate()).padStart(2, "0");
715
- const endDay = String(to?.getDate())?.padStart(2, "0");
716
- const startMonth = String(from.getMonth()).padStart(2, "0");
717
- const endMonth = String(to?.getMonth())?.padStart(2, "0");
718
-
719
- const fromTitle = `${startDay}.${startMonth}`;
720
- const toTitle = to ? `${endDay}.${endMonth} / ${to.getFullYear()}` : "";
721
-
722
- title = `${fromTitle} – ${toTitle}`;
723
- }
724
-
725
- return title;
726
- });
483
+ const { userFormatDate } = useUserFormat(localValue, userFormatLocale, isPeriod, isVariant);
727
484
 
728
485
  watch(
729
486
  calendarValue,
@@ -753,11 +510,11 @@ watch(
753
510
  const parsedDateTo = parseDate(props.modelValue.to, props.dateFormat, locale.value);
754
511
 
755
512
  rangeStart.value = props.modelValue.from
756
- ? formatDate(parsedDateFrom, inputRangeFormat, locale.value)
513
+ ? formatDate(parsedDateFrom, INPUT_RANGE_FORMAT, locale.value)
757
514
  : "";
758
515
 
759
516
  rangeEnd.value = props.modelValue.to
760
- ? formatDate(parsedDateTo, inputRangeFormat, locale.value)
517
+ ? formatDate(parsedDateTo, INPUT_RANGE_FORMAT, locale.value)
761
518
  : "";
762
519
 
763
520
  inputRangeFromError.value = "";
@@ -778,63 +535,6 @@ watch(period, () => {
778
535
  }
779
536
  });
780
537
 
781
- function onClickPeriodButton(periodName) {
782
- const localDate = localValue.value.from !== null ? localValue.value.from : new Date();
783
-
784
- if (periodName === PERIOD.week) {
785
- periodDateList.value = getWeekDateList(localDate, locale.value.months.shorthand);
786
-
787
- period.value = PERIOD.week;
788
- }
789
-
790
- if (periodName === PERIOD.month) {
791
- periodDateList.value = getMonthsDateList(localDate, locale.value.months.longhand);
792
-
793
- period.value = PERIOD.month;
794
- }
795
-
796
- if (periodName === PERIOD.quarter) {
797
- periodDateList.value = getQuartersDateList(localDate, locale.value.quarter);
798
-
799
- period.value = PERIOD.quarter;
800
- }
801
-
802
- if (periodName === PERIOD.year) {
803
- periodDateList.value = getYearDateList(localDate);
804
-
805
- period.value = PERIOD.year;
806
- }
807
- }
808
-
809
- function onClickOwnRange() {
810
- period.value = PERIOD.ownRange;
811
- }
812
-
813
- function selectDate(date) {
814
- localValue.value = {
815
- from: date.startRange,
816
- to: date.endRange,
817
- };
818
- }
819
-
820
- function toggleMenu() {
821
- isShownMenu.value = !isShownMenu.value;
822
- }
823
-
824
- function onClickCustomRangeButton() {
825
- selectCustomRange();
826
-
827
- isShownMenu.value = false;
828
- period.value = PERIOD.custom;
829
- }
830
-
831
- function selectCustomRange() {
832
- localValue.value = {
833
- from: props.customRangeButton.range.from,
834
- to: props.customRangeButton.range.to,
835
- };
836
- }
837
-
838
538
  function isDatePeriodOutOfRange(datePeriod) {
839
539
  return (
840
540
  dateIsOutOfRange(
@@ -847,104 +547,6 @@ function isDatePeriodOutOfRange(datePeriod) {
847
547
  );
848
548
  }
849
549
 
850
- function onClickShiftDatesList(action) {
851
- const defaultRange = action === "prev" ? -1 : 1;
852
- const yearRange = action === "prev" ? -12 : 12;
853
-
854
- if (isPeriod.value.week) {
855
- activeDate.value = addMonths(activeDate.value, defaultRange);
856
- periodDateList.value = getWeekDateList(activeDate.value, locale.value.months.shorthand);
857
- }
858
-
859
- if (isPeriod.value.month) {
860
- activeDate.value = addYears(activeDate.value, defaultRange);
861
- periodDateList.value = getMonthsDateList(activeDate.value, locale.value.months.longhand);
862
- }
863
-
864
- if (isPeriod.value.quarter) {
865
- activeDate.value = addYears(activeDate.value, defaultRange);
866
- periodDateList.value = getQuartersDateList(activeDate.value, locale.value.quarter);
867
- }
868
-
869
- if (isPeriod.value.year) {
870
- activeDate.value = addYears(activeDate.value, yearRange);
871
- periodDateList.value = getYearDateList(activeDate.value);
872
- }
873
- }
874
-
875
- function getPeriodButtonsClasses(periodName) {
876
- return period.value === periodName ? config.value.periodButtonActive : "";
877
- }
878
-
879
- function getPeriodDateClasses(date, index) {
880
- const localStart = new Date(localValue.value.from);
881
- const localEnd = new Date(localValue.value.to);
882
- const isListType = isPeriod.value.quarter || isPeriod.value.week;
883
- const firstInRangeClasses = cx([
884
- config.value.edgePeriodDate,
885
- isListType ? config.value.firstPeriodListDate : config.value.firstPeriodGridDate,
886
- ]);
887
- const lastInRangeClasses = cx([
888
- config.value.edgePeriodDate,
889
- isListType ? config.value.lastPeriodListDate : config.value.lastPeriodGridDate,
890
- ]);
891
-
892
- if (isPeriod.value.year) {
893
- localStart.setMonth(0, 1);
894
- localEnd.setMonth(11, 31);
895
- }
896
-
897
- localStart.setHours(0, 0, 0, 0);
898
- localEnd.setHours(23, 59, 59, 999);
899
-
900
- const startDateInRangeIndex = periodDateList.value.findIndex((periodDate) => {
901
- return localStart <= periodDate.endRange && localStart >= periodDate.startRange;
902
- });
903
-
904
- const endDateInRangeIndex = periodDateList.value.findIndex((periodDate) => {
905
- return localEnd >= periodDate.startRange && localEnd <= periodDate.endRange;
906
- });
907
-
908
- let isInRange = index >= startDateInRangeIndex && index <= endDateInRangeIndex;
909
-
910
- if (!~startDateInRangeIndex || !~endDateInRangeIndex) {
911
- isInRange =
912
- (index >= startDateInRangeIndex && startDateInRangeIndex > -1) ||
913
- (index <= endDateInRangeIndex && endDateInRangeIndex > -1);
914
- }
915
-
916
- if (
917
- !~startDateInRangeIndex &&
918
- periodDateList.value.at(0).startRange > localStart &&
919
- !~endDateInRangeIndex &&
920
- periodDateList.value.at(0).endRange < localEnd
921
- ) {
922
- isInRange = true;
923
- }
924
-
925
- const isSingleItem =
926
- startDateInRangeIndex === endDateInRangeIndex && ~endDateInRangeIndex && ~startDateInRangeIndex;
927
-
928
- if (isInRange) {
929
- return cx([
930
- config.value.periodDateInRange,
931
- startDateInRangeIndex === index && firstInRangeClasses,
932
- endDateInRangeIndex === index && lastInRangeClasses,
933
- isSingleItem && "rounded-dynamic",
934
- ]);
935
- }
936
-
937
- return localValue.value.from === date.startRange ? config.value.periodDateActive : "";
938
- }
939
-
940
- function getPeriodDateListClasses() {
941
- if (isPeriod.value.ownRange) return [];
942
- if (isPeriod.value.week) return config.value.periodDateWeekList;
943
- if (isPeriod.value.month) return config.value.periodDateMonthList;
944
- if (isPeriod.value.quarter) return config.value.periodDateQuarterList;
945
- if (isPeriod.value.year) return config.value.periodDateYearList;
946
- }
947
-
948
550
  function activate() {
949
551
  isShownMenu.value = true;
950
552
 
@@ -960,76 +562,6 @@ function deactivate() {
960
562
  isShownMenu.value = false;
961
563
  }
962
564
 
963
- function isGraterThanTo(value) {
964
- if (!value) return false;
965
-
966
- const parsedValue = parseDate(value, inputRangeFormat, locale.value);
967
- const parsedTo = parseDate(localValue.value.to, props.dateFormat, locale.value);
968
-
969
- return parsedValue > parsedTo;
970
- }
971
-
972
- function isSmallerThanFrom(value) {
973
- if (!value) return false;
974
-
975
- const parsedValue = parseDate(value, inputRangeFormat, locale.value);
976
- const parsedFrom = parseDate(localValue.value.from, props.dateFormat, locale.value);
977
-
978
- return parsedValue < parsedFrom;
979
- }
980
-
981
- function onInputRangeInput(value, type) {
982
- const isInvalidDateFormat = isWrongDateFormat(value);
983
-
984
- let error = "";
985
-
986
- if (isInvalidDateFormat && value) {
987
- error = locale.value.dateFormatWithDot;
988
- } else if (isWrongMonthNumber(value) && value) {
989
- error = locale.value.notCorrectMonthNumber;
990
- } else if (isWrongDayNumber(value) && value) {
991
- error = locale.value.notCorrectDayNumber;
992
- } else if (isGraterThanTo(value) && type === INPUT_RANGE_TYPE.start) {
993
- error = locale.value.fromDateGraterThanSecond;
994
- } else if (isSmallerThanFrom(value) && type === INPUT_RANGE_TYPE.end) {
995
- error = locale.value.toDateSmallerThanFirst;
996
- }
997
-
998
- if (type === INPUT_RANGE_TYPE.start) {
999
- inputRangeFromError.value = error;
1000
- }
1001
-
1002
- if (type === INPUT_RANGE_TYPE.end) {
1003
- inputRangeToError.value = error;
1004
- }
1005
-
1006
- if (!isInvalidDateFormat) {
1007
- const parsedValue = parseDate(value || new Date(), inputRangeFormat, locale.value);
1008
-
1009
- const isOutOfRange = dateIsOutOfRange(
1010
- parsedValue,
1011
- props.minDate,
1012
- props.maxDate,
1013
- locale.value,
1014
- props.dateFormat,
1015
- );
1016
-
1017
- if (type === INPUT_RANGE_TYPE.start && !error && !isOutOfRange) {
1018
- localValue.value = {
1019
- from: value ? parsedValue : "",
1020
- to: localValue.value.to,
1021
- };
1022
- }
1023
-
1024
- if (type === INPUT_RANGE_TYPE.end && !error && !isOutOfRange) {
1025
- localValue.value = {
1026
- from: localValue.value.from,
1027
- to: value ? parsedValue : "",
1028
- };
1029
- }
1030
- }
1031
- }
1032
-
1033
565
  setDefaultPeriodForButton();
1034
566
 
1035
567
  function setDefaultPeriodForButton() {
@@ -1069,80 +601,113 @@ function setDefaultPeriodForButton() {
1069
601
  }
1070
602
  }
1071
603
 
1072
- function onClickShiftRange(action) {
1073
- if (isPeriod.value.custom) {
1074
- period.value = PERIOD.ownRange;
604
+ function onClickShiftDatesList(action) {
605
+ const defaultRange = action === SHIFT_ACTION.prev ? -1 : 1;
606
+ const yearRange = action === SHIFT_ACTION.prev ? -12 : 12;
607
+
608
+ if (isPeriod.value.week) {
609
+ activeDate.value = addMonths(activeDate.value, defaultRange);
610
+ periodDateList.value = getWeekDateList(activeDate.value, locale.value.months.shorthand);
1075
611
  }
1076
612
 
1077
- const millisecondsPerSecond = 1000;
1078
- const secondsPerMinute = 60;
1079
- const minutesPerHour = 60;
1080
- const hoursPerDay = 24;
613
+ if (isPeriod.value.month) {
614
+ activeDate.value = addYears(activeDate.value, defaultRange);
615
+ periodDateList.value = getMonthsDateList(activeDate.value, locale.value.months.longhand);
616
+ }
1081
617
 
1082
- const millisecondsPerDay =
1083
- millisecondsPerSecond * secondsPerMinute * minutesPerHour * hoursPerDay;
618
+ if (isPeriod.value.quarter) {
619
+ activeDate.value = addYears(activeDate.value, defaultRange);
620
+ periodDateList.value = getQuartersDateList(activeDate.value, locale.value.quarter);
621
+ }
1084
622
 
1085
- const from = localValue.value.from;
1086
- const to = localValue.value.to ? localValue.value.to : addDays(from, 1);
1087
- const daysDifference = Math.ceil(Math.abs(getDatesDifference(from, to)) / millisecondsPerDay);
623
+ if (isPeriod.value.year) {
624
+ activeDate.value = addYears(activeDate.value, yearRange);
625
+ periodDateList.value = getYearDateList(activeDate.value);
626
+ }
627
+ }
1088
628
 
1089
- if (action === "next") {
1090
- if (isPeriod.value.ownRange) {
1091
- const nextDate = {
1092
- to: addDays(to, daysDifference),
1093
- from: addDays(from, daysDifference),
1094
- };
629
+ function shiftRangeNext(to, from, daysDifference) {
630
+ if (isPeriod.value.ownRange) {
631
+ const nextDate = {
632
+ to: addDays(to, daysDifference),
633
+ from: addDays(from, daysDifference),
634
+ };
1095
635
 
1096
- if (isDatePeriodOutOfRange(nextDate)) return;
636
+ if (isDatePeriodOutOfRange(nextDate)) return;
1097
637
 
1098
- localValue.value = nextDate;
1099
- } else {
1100
- let nextDate = periodDateList.value.find((item) => item.endRange > localValue.value.to);
638
+ localValue.value = nextDate;
1101
639
 
1102
- if (!nextDate) {
1103
- onClickShiftDatesList(action);
640
+ return;
641
+ }
1104
642
 
1105
- nextDate = periodDateList.value.find((item) => item.endRange > localValue.value.to);
1106
- }
643
+ let nextDate = periodDateList.value.find((item) => item.endRange > localValue.value.to);
1107
644
 
1108
- if (isDatePeriodOutOfRange(nextDate)) return;
645
+ if (!nextDate) {
646
+ onClickShiftDatesList(SHIFT_ACTION.next);
1109
647
 
1110
- localValue.value = {
1111
- from: nextDate.startRange,
1112
- to: nextDate.endRange,
1113
- };
1114
- }
1115
- } else {
1116
- if (isPeriod.value.ownRange) {
1117
- const previousDate = {
1118
- to: addDays(to, daysDifference * -1),
1119
- from: addDays(from, daysDifference * -1),
1120
- };
648
+ nextDate = periodDateList.value.find((item) => item.endRange > localValue.value.to);
649
+ }
1121
650
 
1122
- if (isDatePeriodOutOfRange(previousDate)) return;
651
+ if (isDatePeriodOutOfRange(nextDate)) return;
1123
652
 
1124
- localValue.value = previousDate;
1125
- } else {
1126
- const reverseDatesList = [...periodDateList.value].reverse();
653
+ localValue.value = {
654
+ from: nextDate.startRange,
655
+ to: nextDate.endRange,
656
+ };
657
+ }
1127
658
 
1128
- let previousDate = reverseDatesList.find((item) => item.endRange < localValue.value.to);
659
+ function shiftRangePrev(to, from, daysDifference) {
660
+ if (isPeriod.value.ownRange) {
661
+ const previousDate = {
662
+ to: addDays(to, daysDifference * -1),
663
+ from: addDays(from, daysDifference * -1),
664
+ };
1129
665
 
1130
- if (!previousDate) {
1131
- onClickShiftDatesList(action);
666
+ if (isDatePeriodOutOfRange(previousDate)) return;
1132
667
 
1133
- const reverseDatesList = [...periodDateList.value].reverse();
668
+ localValue.value = previousDate;
669
+ } else {
670
+ const reverseDatesList = [...periodDateList.value].reverse();
1134
671
 
1135
- previousDate = reverseDatesList.find((item) => item.endRange < localValue.value.to);
1136
- }
672
+ let previousDate = reverseDatesList.find((item) => item.endRange < localValue.value.to);
1137
673
 
1138
- if (isDatePeriodOutOfRange(previousDate)) return;
674
+ if (!previousDate) {
675
+ onClickShiftDatesList(SHIFT_ACTION.prev);
1139
676
 
1140
- localValue.value = {
1141
- from: previousDate.startRange,
1142
- to: previousDate.endRange,
1143
- };
677
+ const reverseDatesList = [...periodDateList.value].reverse();
678
+
679
+ previousDate = reverseDatesList.find((item) => item.endRange < localValue.value.to);
1144
680
  }
681
+
682
+ if (isDatePeriodOutOfRange(previousDate)) return;
683
+
684
+ localValue.value = {
685
+ from: previousDate.startRange,
686
+ to: previousDate.endRange,
687
+ };
688
+ }
689
+ }
690
+
691
+ function onClickShiftRange(action) {
692
+ if (isPeriod.value.custom) {
693
+ period.value = PERIOD.ownRange;
1145
694
  }
695
+
696
+ const millisecondsPerSecond = 1000;
697
+ const secondsPerMinute = 60;
698
+ const minutesPerHour = 60;
699
+ const hoursPerDay = 24;
700
+
701
+ const millisecondsPerDay =
702
+ millisecondsPerSecond * secondsPerMinute * minutesPerHour * hoursPerDay;
703
+
704
+ const from = localValue.value.from;
705
+ const to = localValue.value.to ? localValue.value.to : addDays(from, 1);
706
+ const daysDifference = Math.ceil(Math.abs(getDatesDifference(from, to)) / millisecondsPerDay);
707
+
708
+ action === SHIFT_ACTION.next
709
+ ? shiftRangeNext(to, from, daysDifference)
710
+ : shiftRangePrev(to, from, daysDifference);
1146
711
  }
1147
712
 
1148
713
  function onMouseoverCalendar() {