vueless 0.0.492 → 0.0.494
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.
- package/constants.js +1 -1
- package/index.ts +2 -1
- package/package.json +1 -1
- package/preset-tailwind.js +1 -1
- package/types.ts +37 -0
- package/ui.form-calendar/UCalendar.vue +20 -11
- package/ui.form-calendar/UCalendarDayView.vue +1 -1
- package/ui.form-calendar/UCalendarMonthView.vue +1 -1
- package/ui.form-calendar/UCalendarYearView.vue +1 -1
- package/ui.form-calendar/config.ts +1 -0
- package/ui.form-calendar/constants.ts +0 -6
- package/ui.form-calendar/storybook/stories.ts +5 -3
- package/ui.form-calendar/types.ts +7 -2
- package/ui.form-calendar/useAttrs.ts +1 -1
- package/ui.form-calendar/utilDate.ts +2 -2
- package/ui.form-date-picker/UDatePicker.vue +18 -16
- package/ui.form-date-picker/storybook/stories.ts +6 -4
- package/ui.form-date-picker/types.ts +2 -6
- package/ui.form-date-picker/useAttrs.ts +1 -1
- package/ui.form-date-picker-range/UDatePickerRange.vue +371 -433
- package/ui.form-date-picker-range/UDatePickerRangeInputs.vue +67 -76
- package/ui.form-date-picker-range/UDatePickerRangePeriodMenu.vue +158 -205
- package/ui.form-date-picker-range/{constants.js → constants.ts} +17 -18
- package/ui.form-date-picker-range/storybook/Docs.mdx +16 -0
- package/ui.form-date-picker-range/storybook/stories.ts +237 -0
- package/ui.form-date-picker-range/types.ts +193 -0
- package/ui.form-date-picker-range/{useAttrs.js → useAttrs.ts} +21 -5
- package/ui.form-date-picker-range/useLocale.ts +65 -0
- package/ui.form-date-picker-range/{useUserFormat.js → useUserFormat.ts} +22 -8
- package/ui.form-date-picker-range/{utilDateRange.js → utilDateRange.ts} +14 -8
- package/ui.form-date-picker-range/{utilValidation.js → utilValidation.ts} +4 -4
- package/utils/theme.ts +19 -5
- package/web-types.json +158 -52
- package/ui.form-date-picker-range/useLocale.js +0 -63
- /package/ui.form-date-picker-range/{config.js → config.ts} +0 -0
|
@@ -1,90 +1,48 @@
|
|
|
1
|
-
<
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
ref="rangeInputStartRef"
|
|
5
|
-
v-model="rangeStart"
|
|
6
|
-
:error="inputRangeFromError"
|
|
7
|
-
size="md"
|
|
8
|
-
v-bind="rangeInputFirstAttrs"
|
|
9
|
-
:name="rangeInputName"
|
|
10
|
-
@input="onInputRangeInput($event, INPUT_RANGE_TYPE.start)"
|
|
11
|
-
/>
|
|
12
|
-
|
|
13
|
-
<UInput
|
|
14
|
-
ref="rangeInputEndRef"
|
|
15
|
-
v-model="rangeEnd"
|
|
16
|
-
:error="inputRangeToError"
|
|
17
|
-
size="md"
|
|
18
|
-
v-bind="rangeInputLastAttrs"
|
|
19
|
-
:name="rangeInputName"
|
|
20
|
-
@input="onInputRangeInput($event, INPUT_RANGE_TYPE.end)"
|
|
21
|
-
/>
|
|
22
|
-
</div>
|
|
23
|
-
</template>
|
|
24
|
-
|
|
25
|
-
<script setup>
|
|
26
|
-
import { isWrongDateFormat, isWrongMonthNumber, isWrongDayNumber } from "./utilValidation.js";
|
|
1
|
+
<script setup lang="ts" generic="TLocalValue extends RangeDate">
|
|
2
|
+
import { isWrongDateFormat, isWrongMonthNumber, isWrongDayNumber } from "./utilValidation.ts";
|
|
3
|
+
import { useTemplateRef } from "vue";
|
|
27
4
|
|
|
28
5
|
import { dateIsOutOfRange, parseDate } from "../ui.form-calendar/utilCalendar.ts";
|
|
29
6
|
|
|
30
7
|
import UInput from "../ui.form-input/UInput.vue";
|
|
31
8
|
|
|
32
|
-
import {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
dateFormat: {
|
|
41
|
-
type: [String, undefined],
|
|
42
|
-
default: undefined,
|
|
43
|
-
},
|
|
44
|
-
|
|
45
|
-
rangeInputName: {
|
|
46
|
-
type: String,
|
|
47
|
-
required: true,
|
|
48
|
-
},
|
|
49
|
-
|
|
50
|
-
config: {
|
|
51
|
-
type: Object,
|
|
52
|
-
required: true,
|
|
53
|
-
},
|
|
54
|
-
|
|
55
|
-
attrs: {
|
|
56
|
-
type: Object,
|
|
57
|
-
required: true,
|
|
58
|
-
},
|
|
59
|
-
});
|
|
9
|
+
import { InputRangeType, INPUT_RANGE_FORMAT } from "./constants.ts";
|
|
10
|
+
|
|
11
|
+
import type { UDatePickerRangeInputsProps } from "./types.ts";
|
|
12
|
+
import type { RangeDate } from "src/ui.form-calendar/types.ts";
|
|
13
|
+
|
|
14
|
+
type UInputRef = InstanceType<typeof UInput>;
|
|
15
|
+
|
|
16
|
+
const props = defineProps<UDatePickerRangeInputsProps>();
|
|
60
17
|
|
|
61
|
-
const
|
|
18
|
+
const rangeInputStartRef = useTemplateRef<UInputRef>("range-input-start");
|
|
19
|
+
const rangeInputEndRef = useTemplateRef<UInputRef>("range-input-end");
|
|
62
20
|
|
|
63
|
-
const localValue = defineModel("localValue", { required: true
|
|
64
|
-
const inputRangeFromError = defineModel("inputRangeFromError", { required: true
|
|
65
|
-
const inputRangeToError = defineModel("inputRangeToError", { required: true
|
|
66
|
-
const rangeStart = defineModel("rangeStart", {
|
|
67
|
-
const rangeEnd = defineModel("rangeEnd", {
|
|
21
|
+
const localValue = defineModel<TLocalValue>("localValue", { required: true });
|
|
22
|
+
const inputRangeFromError = defineModel<string>("inputRangeFromError", { required: true });
|
|
23
|
+
const inputRangeToError = defineModel<string>("inputRangeToError", { required: true });
|
|
24
|
+
const rangeStart = defineModel<string>("rangeStart", { required: true });
|
|
25
|
+
const rangeEnd = defineModel<string>("rangeEnd", { required: true });
|
|
68
26
|
|
|
69
|
-
function isGraterThanTo(value) {
|
|
27
|
+
function isGraterThanTo(value: string) {
|
|
70
28
|
if (!value) return false;
|
|
71
29
|
|
|
72
30
|
const parsedValue = parseDate(value, INPUT_RANGE_FORMAT, props.locale);
|
|
73
31
|
const parsedTo = parseDate(localValue.value.to, props.dateFormat, props.locale);
|
|
74
32
|
|
|
75
|
-
return parsedValue > parsedTo;
|
|
33
|
+
return parsedValue && parsedTo && parsedValue > parsedTo;
|
|
76
34
|
}
|
|
77
35
|
|
|
78
|
-
function isSmallerThanFrom(value) {
|
|
36
|
+
function isSmallerThanFrom(value: string) {
|
|
79
37
|
if (!value) return false;
|
|
80
38
|
|
|
81
39
|
const parsedValue = parseDate(value, INPUT_RANGE_FORMAT, props.locale);
|
|
82
40
|
const parsedFrom = parseDate(localValue.value.from, props.dateFormat, props.locale);
|
|
83
41
|
|
|
84
|
-
return parsedValue < parsedFrom;
|
|
42
|
+
return parsedValue && parsedFrom && parsedValue < parsedFrom;
|
|
85
43
|
}
|
|
86
44
|
|
|
87
|
-
function onInputRangeInput(value, type) {
|
|
45
|
+
function onInputRangeInput(value: string, type: `${InputRangeType}`) {
|
|
88
46
|
const isInvalidDateFormat = isWrongDateFormat(value);
|
|
89
47
|
|
|
90
48
|
let error = "";
|
|
@@ -95,22 +53,26 @@ function onInputRangeInput(value, type) {
|
|
|
95
53
|
error = props.locale.notCorrectMonthNumber;
|
|
96
54
|
} else if (isWrongDayNumber(value) && value) {
|
|
97
55
|
error = props.locale.notCorrectDayNumber;
|
|
98
|
-
} else if (isGraterThanTo(value) && type ===
|
|
56
|
+
} else if (isGraterThanTo(value) && type === InputRangeType.Start) {
|
|
99
57
|
error = props.locale.fromDateGraterThanSecond;
|
|
100
|
-
} else if (isSmallerThanFrom(value) && type ===
|
|
58
|
+
} else if (isSmallerThanFrom(value) && type === InputRangeType.End) {
|
|
101
59
|
error = props.locale.toDateSmallerThanFirst;
|
|
102
60
|
}
|
|
103
61
|
|
|
104
|
-
if (type ===
|
|
62
|
+
if (type === InputRangeType.Start) {
|
|
105
63
|
inputRangeFromError.value = error;
|
|
106
64
|
}
|
|
107
65
|
|
|
108
|
-
if (type ===
|
|
66
|
+
if (type === InputRangeType.End) {
|
|
109
67
|
inputRangeToError.value = error;
|
|
110
68
|
}
|
|
111
69
|
|
|
112
70
|
if (!isInvalidDateFormat) {
|
|
113
71
|
const parsedValue = parseDate(value || new Date(), INPUT_RANGE_FORMAT, props.locale);
|
|
72
|
+
const parsedDateFrom = parseDate(localValue.value.from, props.dateFormat, props.locale);
|
|
73
|
+
const parsedDateTo = parseDate(localValue.value.to, props.dateFormat, props.locale);
|
|
74
|
+
|
|
75
|
+
if (!parsedValue) return;
|
|
114
76
|
|
|
115
77
|
const isOutOfRange = dateIsOutOfRange(
|
|
116
78
|
parsedValue,
|
|
@@ -120,19 +82,48 @@ function onInputRangeInput(value, type) {
|
|
|
120
82
|
props.dateFormat,
|
|
121
83
|
);
|
|
122
84
|
|
|
123
|
-
if (type ===
|
|
85
|
+
if (type === InputRangeType.Start && !error && !isOutOfRange) {
|
|
124
86
|
localValue.value = {
|
|
125
87
|
from: value ? parsedValue : "",
|
|
126
|
-
to:
|
|
127
|
-
};
|
|
88
|
+
to: parsedDateTo,
|
|
89
|
+
} as TLocalValue;
|
|
128
90
|
}
|
|
129
91
|
|
|
130
|
-
if (type ===
|
|
92
|
+
if (type === InputRangeType.End && !error && !isOutOfRange) {
|
|
131
93
|
localValue.value = {
|
|
132
|
-
from:
|
|
133
|
-
to: value ? parsedValue :
|
|
134
|
-
};
|
|
94
|
+
from: parsedDateFrom,
|
|
95
|
+
to: value ? parsedValue : null,
|
|
96
|
+
} as TLocalValue;
|
|
135
97
|
}
|
|
136
98
|
}
|
|
137
99
|
}
|
|
100
|
+
|
|
101
|
+
defineExpose({
|
|
102
|
+
rangeInputEndRef,
|
|
103
|
+
rangeInputStartRef,
|
|
104
|
+
});
|
|
138
105
|
</script>
|
|
106
|
+
|
|
107
|
+
<template>
|
|
108
|
+
<div>
|
|
109
|
+
<UInput
|
|
110
|
+
ref="range-input-start"
|
|
111
|
+
v-model="rangeStart"
|
|
112
|
+
:error="inputRangeFromError"
|
|
113
|
+
size="md"
|
|
114
|
+
v-bind="attrs.rangeInputFirstAttrs.value"
|
|
115
|
+
:name="rangeInputName"
|
|
116
|
+
@input="onInputRangeInput($event, InputRangeType.Start)"
|
|
117
|
+
/>
|
|
118
|
+
|
|
119
|
+
<UInput
|
|
120
|
+
ref="range-input-end"
|
|
121
|
+
v-model="rangeEnd"
|
|
122
|
+
:error="inputRangeToError"
|
|
123
|
+
size="md"
|
|
124
|
+
v-bind="attrs.rangeInputLastAttrs.value"
|
|
125
|
+
:name="rangeInputName"
|
|
126
|
+
@input="onInputRangeInput($event, InputRangeType.End)"
|
|
127
|
+
/>
|
|
128
|
+
</div>
|
|
129
|
+
</template>
|
|
@@ -1,5 +1,137 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed, inject } from "vue";
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
getWeekDateList,
|
|
6
|
+
getYearDateList,
|
|
7
|
+
getQuartersDateList,
|
|
8
|
+
getMonthsDateList,
|
|
9
|
+
} from "./utilDateRange.ts";
|
|
10
|
+
|
|
11
|
+
import UButton from "../ui.button/UButton.vue";
|
|
12
|
+
|
|
13
|
+
import { Period } from "./constants.ts";
|
|
14
|
+
|
|
15
|
+
import type { UDatePickerRangePeriodMenuProps, IsDatePeriodOutOfRange } from "./types.ts";
|
|
16
|
+
import type { DatePeriodRange } from "./utilDateRange.ts";
|
|
17
|
+
|
|
18
|
+
const props = defineProps<UDatePickerRangePeriodMenuProps>();
|
|
19
|
+
|
|
20
|
+
const emit = defineEmits(["toggleMenu", "closeMenu", "clickPrev", "clickNext"]);
|
|
21
|
+
|
|
22
|
+
const localValue = defineModel("localValue", { required: true, type: Object });
|
|
23
|
+
const activeDate = defineModel("activeDate", { required: true, type: Object });
|
|
24
|
+
const periodDateList = defineModel<DatePeriodRange[]>("periodDateList");
|
|
25
|
+
const period = defineModel("period", { required: true, type: String });
|
|
26
|
+
|
|
27
|
+
const isDatePeriodOutOfRange = inject<IsDatePeriodOutOfRange | null>(
|
|
28
|
+
"isDatePeriodOutOfRange",
|
|
29
|
+
null,
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
const periods = computed(() => [
|
|
33
|
+
{ name: Period.Week, title: props.locale.week },
|
|
34
|
+
{ name: Period.Month, title: props.locale.month },
|
|
35
|
+
{ name: Period.Quarter, title: props.locale.quarter },
|
|
36
|
+
{ name: Period.Year, title: props.locale.year },
|
|
37
|
+
]);
|
|
38
|
+
|
|
39
|
+
const rangeSwitchTitle = computed(() => {
|
|
40
|
+
if (props.isPeriod.month || props.isPeriod.quarter) {
|
|
41
|
+
return String(activeDate.value.getFullYear());
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (props.isPeriod.year) {
|
|
45
|
+
return `${periodDateList.value?.at(0)?.title} – ${periodDateList.value?.at(-1)?.title}`;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (props.isPeriod.week) {
|
|
49
|
+
return `${props.locale.months.longhand[activeDate.value.getMonth()]} ${activeDate.value.getFullYear()}`;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return "";
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
function onClickPeriodButton(periodName: `${Period}`) {
|
|
56
|
+
const localDate = localValue.value.from !== null ? localValue.value.from : new Date();
|
|
57
|
+
|
|
58
|
+
if (periodName === Period.Week) {
|
|
59
|
+
periodDateList.value = getWeekDateList(localDate, props.locale.months.shorthand);
|
|
60
|
+
|
|
61
|
+
period.value = Period.Week;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (periodName === Period.Month) {
|
|
65
|
+
periodDateList.value = getMonthsDateList(localDate, props.locale.months.longhand);
|
|
66
|
+
|
|
67
|
+
period.value = Period.Month;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (periodName === Period.Quarter) {
|
|
71
|
+
periodDateList.value = getQuartersDateList(localDate, props.locale.quarter);
|
|
72
|
+
|
|
73
|
+
period.value = Period.Quarter;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (periodName === Period.Year) {
|
|
77
|
+
periodDateList.value = getYearDateList(localDate);
|
|
78
|
+
|
|
79
|
+
period.value = Period.Year;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function onClickOwnRange() {
|
|
84
|
+
period.value = Period.OwnRange;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function selectDate(date: DatePeriodRange) {
|
|
88
|
+
localValue.value = {
|
|
89
|
+
from: date.startRange,
|
|
90
|
+
to: date.endRange,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function toggleMenu() {
|
|
95
|
+
emit("toggleMenu");
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function onClickCustomRangeButton() {
|
|
99
|
+
selectCustomRange();
|
|
100
|
+
|
|
101
|
+
emit("closeMenu");
|
|
102
|
+
period.value = Period.Custom;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function selectCustomRange() {
|
|
106
|
+
localValue.value = {
|
|
107
|
+
from: props.customRangeButton.range.from,
|
|
108
|
+
to: props.customRangeButton.range.to,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function getDatePeriodState(date: DatePeriodRange) {
|
|
113
|
+
const localStart = new Date(localValue.value.from);
|
|
114
|
+
const localEnd = new Date(localValue.value.to);
|
|
115
|
+
|
|
116
|
+
if (props.isPeriod.year) {
|
|
117
|
+
localStart.setMonth(0, 1);
|
|
118
|
+
localEnd.setMonth(11, 31);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
localStart.setHours(0, 0, 0, 0);
|
|
122
|
+
localEnd.setHours(23, 59, 59, 999);
|
|
123
|
+
|
|
124
|
+
const isSelected =
|
|
125
|
+
localStart.getTime() - date.startRange.getTime() === 0 &&
|
|
126
|
+
localEnd.getTime() - date.endRange.getTime() === 0;
|
|
127
|
+
const isCurrentDate = date.startRange <= new Date() && new Date() <= date.endRange;
|
|
128
|
+
|
|
129
|
+
return { isSelected, isCurrentDate };
|
|
130
|
+
}
|
|
131
|
+
</script>
|
|
132
|
+
|
|
1
133
|
<template>
|
|
2
|
-
<div v-bind="periodRowAttrs">
|
|
134
|
+
<div v-bind="attrs.periodRowAttrs.value">
|
|
3
135
|
<template v-for="periodButton in periods" :key="periodButton.name">
|
|
4
136
|
<UButton
|
|
5
137
|
v-if="periodButton.name !== period"
|
|
@@ -10,7 +142,7 @@
|
|
|
10
142
|
color="grayscale"
|
|
11
143
|
variant="thirdary"
|
|
12
144
|
:label="periodButton.title"
|
|
13
|
-
v-bind="periodButtonAttrs"
|
|
145
|
+
v-bind="attrs.periodButtonAttrs.value"
|
|
14
146
|
@click="onClickPeriodButton(periodButton.name)"
|
|
15
147
|
/>
|
|
16
148
|
|
|
@@ -23,53 +155,53 @@
|
|
|
23
155
|
color="grayscale"
|
|
24
156
|
variant="thirdary"
|
|
25
157
|
:label="periodButton.title"
|
|
26
|
-
v-bind="periodButtonActiveAttrs"
|
|
158
|
+
v-bind="attrs.periodButtonActiveAttrs.value"
|
|
27
159
|
@click="onClickPeriodButton(periodButton.name)"
|
|
28
160
|
/>
|
|
29
161
|
</template>
|
|
30
162
|
</div>
|
|
31
163
|
|
|
32
|
-
<div v-bind="periodRowAttrs">
|
|
164
|
+
<div v-bind="attrs.periodRowAttrs.value">
|
|
33
165
|
<UButton
|
|
34
|
-
v-if="customRangeButton.range.to && customRangeButton.range.from &&
|
|
166
|
+
v-if="customRangeButton.range.to && customRangeButton.range.from && Period.Custom !== period"
|
|
35
167
|
square
|
|
36
168
|
filled
|
|
37
169
|
no-ring
|
|
38
170
|
size="xs"
|
|
39
171
|
color="grayscale"
|
|
40
172
|
variant="thirdary"
|
|
41
|
-
v-bind="periodButtonAttrs"
|
|
173
|
+
v-bind="attrs.periodButtonAttrs.value"
|
|
42
174
|
@click="onClickCustomRangeButton"
|
|
43
175
|
>
|
|
44
176
|
{{ customRangeButton.label }}
|
|
45
177
|
<span
|
|
46
178
|
v-if="customRangeButton.description"
|
|
47
|
-
v-bind="
|
|
179
|
+
v-bind="attrs.customRangeDescriptionAttrs.value"
|
|
48
180
|
v-text="customRangeButton.description"
|
|
49
181
|
/>
|
|
50
182
|
</UButton>
|
|
51
183
|
|
|
52
184
|
<UButton
|
|
53
|
-
v-if="customRangeButton.range.to && customRangeButton.range.from &&
|
|
185
|
+
v-if="customRangeButton.range.to && customRangeButton.range.from && Period.Custom === period"
|
|
54
186
|
square
|
|
55
187
|
filled
|
|
56
188
|
no-ring
|
|
57
189
|
size="xs"
|
|
58
190
|
color="grayscale"
|
|
59
191
|
variant="thirdary"
|
|
60
|
-
v-bind="periodButtonActiveAttrs"
|
|
192
|
+
v-bind="attrs.periodButtonActiveAttrs.value"
|
|
61
193
|
@click="onClickCustomRangeButton"
|
|
62
194
|
>
|
|
63
195
|
{{ customRangeButton.label }}
|
|
64
196
|
<span
|
|
65
197
|
v-if="customRangeButton.description"
|
|
66
|
-
v-bind="
|
|
198
|
+
v-bind="attrs.customRangeDescriptionAttrs.value"
|
|
67
199
|
v-text="customRangeButton.description"
|
|
68
200
|
/>
|
|
69
201
|
</UButton>
|
|
70
202
|
|
|
71
203
|
<UButton
|
|
72
|
-
v-if="
|
|
204
|
+
v-if="Period.OwnRange !== period"
|
|
73
205
|
square
|
|
74
206
|
filled
|
|
75
207
|
no-ring
|
|
@@ -77,8 +209,8 @@
|
|
|
77
209
|
color="grayscale"
|
|
78
210
|
variant="thirdary"
|
|
79
211
|
:label="locale.ownRange"
|
|
80
|
-
:left-icon="config.defaults
|
|
81
|
-
v-bind="periodButtonAttrs"
|
|
212
|
+
:left-icon="config.defaults?.ownRangeIcon"
|
|
213
|
+
v-bind="attrs.periodButtonAttrs.value"
|
|
82
214
|
@click="onClickOwnRange"
|
|
83
215
|
/>
|
|
84
216
|
|
|
@@ -91,26 +223,26 @@
|
|
|
91
223
|
color="grayscale"
|
|
92
224
|
variant="thirdary"
|
|
93
225
|
:label="locale.ownRange"
|
|
94
|
-
:left-icon="config.defaults
|
|
95
|
-
v-bind="periodButtonActiveAttrs"
|
|
226
|
+
:left-icon="config.defaults?.ownRangeIcon"
|
|
227
|
+
v-bind="attrs.periodButtonActiveAttrs.value"
|
|
96
228
|
@click="onClickOwnRange"
|
|
97
229
|
/>
|
|
98
230
|
</div>
|
|
99
231
|
|
|
100
232
|
<template v-if="!isPeriod.ownRange && !isPeriod.custom">
|
|
101
|
-
<div v-bind="rangeSwitchWrapperAttrs">
|
|
233
|
+
<div v-bind="attrs.rangeSwitchWrapperAttrs.value">
|
|
102
234
|
<UButton
|
|
103
235
|
square
|
|
104
236
|
no-ring
|
|
105
237
|
size="sm"
|
|
106
238
|
color="grayscale"
|
|
107
239
|
variant="thirdary"
|
|
108
|
-
:left-icon="config.defaults
|
|
109
|
-
v-bind="rangeSwitchButtonAttrs"
|
|
240
|
+
:left-icon="config.defaults?.prevIcon"
|
|
241
|
+
v-bind="attrs.rangeSwitchButtonAttrs.value"
|
|
110
242
|
@click="emit('clickPrev')"
|
|
111
243
|
/>
|
|
112
244
|
|
|
113
|
-
<div v-bind="rangeSwitchTitleAttrs">
|
|
245
|
+
<div v-bind="attrs.rangeSwitchTitleAttrs.value">
|
|
114
246
|
{{ rangeSwitchTitle }}
|
|
115
247
|
</div>
|
|
116
248
|
|
|
@@ -120,13 +252,13 @@
|
|
|
120
252
|
size="sm"
|
|
121
253
|
color="grayscale"
|
|
122
254
|
variant="thirdary"
|
|
123
|
-
:left-icon="config.defaults
|
|
124
|
-
v-bind="rangeSwitchButtonAttrs"
|
|
255
|
+
:left-icon="config.defaults?.nextIcon"
|
|
256
|
+
v-bind="attrs.rangeSwitchButtonAttrs.value"
|
|
125
257
|
@click="emit('clickNext')"
|
|
126
258
|
/>
|
|
127
259
|
</div>
|
|
128
260
|
|
|
129
|
-
<div v-if="isDatePeriodOutOfRange" v-bind="periodDateListAttrs">
|
|
261
|
+
<div v-if="isDatePeriodOutOfRange" v-bind="attrs.periodDateListAttrs.value">
|
|
130
262
|
<template v-for="date in periodDateList" :key="date.title">
|
|
131
263
|
<UButton
|
|
132
264
|
v-if="getDatePeriodState(date).isSelected && getDatePeriodState(date).isCurrentDate"
|
|
@@ -136,7 +268,7 @@
|
|
|
136
268
|
no-ring
|
|
137
269
|
filled
|
|
138
270
|
:disabled="isDatePeriodOutOfRange(date)"
|
|
139
|
-
v-bind="periodDateCurrentSelectedAttrs"
|
|
271
|
+
v-bind="attrs.periodDateCurrentSelectedAttrs.value"
|
|
140
272
|
:label="String(date.title)"
|
|
141
273
|
@click="selectDate(date), toggleMenu()"
|
|
142
274
|
/>
|
|
@@ -149,7 +281,7 @@
|
|
|
149
281
|
no-ring
|
|
150
282
|
filled
|
|
151
283
|
:disabled="isDatePeriodOutOfRange(date)"
|
|
152
|
-
v-bind="periodDateSelectedAttrs"
|
|
284
|
+
v-bind="attrs.periodDateSelectedAttrs.value"
|
|
153
285
|
:label="String(date.title)"
|
|
154
286
|
@click="selectDate(date), toggleMenu()"
|
|
155
287
|
/>
|
|
@@ -162,7 +294,7 @@
|
|
|
162
294
|
no-ring
|
|
163
295
|
filled
|
|
164
296
|
:disabled="isDatePeriodOutOfRange(date)"
|
|
165
|
-
v-bind="periodDateCurrentAttrs"
|
|
297
|
+
v-bind="attrs.periodDateCurrentAttrs.value"
|
|
166
298
|
:label="String(date.title)"
|
|
167
299
|
@click="selectDate(date), toggleMenu()"
|
|
168
300
|
/>
|
|
@@ -174,7 +306,7 @@
|
|
|
174
306
|
color="grayscale"
|
|
175
307
|
variant="thirdary"
|
|
176
308
|
:disabled="isDatePeriodOutOfRange(date)"
|
|
177
|
-
v-bind="periodDateAttrs"
|
|
309
|
+
v-bind="attrs.periodDateAttrs.value"
|
|
178
310
|
:label="String(date.title)"
|
|
179
311
|
@click="selectDate(date), toggleMenu()"
|
|
180
312
|
/>
|
|
@@ -182,182 +314,3 @@
|
|
|
182
314
|
</div>
|
|
183
315
|
</template>
|
|
184
316
|
</template>
|
|
185
|
-
|
|
186
|
-
<script setup>
|
|
187
|
-
import { computed, inject } from "vue";
|
|
188
|
-
|
|
189
|
-
import {
|
|
190
|
-
getWeekDateList,
|
|
191
|
-
getYearDateList,
|
|
192
|
-
getQuartersDateList,
|
|
193
|
-
getMonthsDateList,
|
|
194
|
-
} from "./utilDateRange.js";
|
|
195
|
-
|
|
196
|
-
import UButton from "../ui.button/UButton.vue";
|
|
197
|
-
|
|
198
|
-
import { PERIOD } from "./constants.js";
|
|
199
|
-
|
|
200
|
-
const props = defineProps({
|
|
201
|
-
locale: {
|
|
202
|
-
type: Object,
|
|
203
|
-
required: true,
|
|
204
|
-
},
|
|
205
|
-
|
|
206
|
-
isPeriod: {
|
|
207
|
-
type: Object,
|
|
208
|
-
required: true,
|
|
209
|
-
},
|
|
210
|
-
|
|
211
|
-
customRangeButton: {
|
|
212
|
-
type: Object,
|
|
213
|
-
required: true,
|
|
214
|
-
},
|
|
215
|
-
|
|
216
|
-
dateFormat: {
|
|
217
|
-
type: [String, undefined],
|
|
218
|
-
default: undefined,
|
|
219
|
-
},
|
|
220
|
-
|
|
221
|
-
minDate: {
|
|
222
|
-
type: [String, Date],
|
|
223
|
-
default: undefined,
|
|
224
|
-
},
|
|
225
|
-
|
|
226
|
-
maxDate: {
|
|
227
|
-
type: [String, Date],
|
|
228
|
-
default: undefined,
|
|
229
|
-
},
|
|
230
|
-
|
|
231
|
-
config: {
|
|
232
|
-
type: Object,
|
|
233
|
-
required: true,
|
|
234
|
-
},
|
|
235
|
-
|
|
236
|
-
attrs: {
|
|
237
|
-
type: Object,
|
|
238
|
-
required: true,
|
|
239
|
-
},
|
|
240
|
-
});
|
|
241
|
-
|
|
242
|
-
const emit = defineEmits(["toggleMenu", "closeMenu", "clickPrev", "clickNext"]);
|
|
243
|
-
|
|
244
|
-
const localValue = defineModel("localValue", { required: true, type: Object });
|
|
245
|
-
const activeDate = defineModel("activeDate", { required: true, type: Object });
|
|
246
|
-
const periodDateList = defineModel("periodDateList", { required: true, type: Object });
|
|
247
|
-
const period = defineModel("period", { required: true, type: String });
|
|
248
|
-
|
|
249
|
-
const isDatePeriodOutOfRange = inject("isDatePeriodOutOfRange", null);
|
|
250
|
-
|
|
251
|
-
const {
|
|
252
|
-
periodButtonAttrs,
|
|
253
|
-
periodRowAttrs,
|
|
254
|
-
periodButtonActiveAttrs,
|
|
255
|
-
customRangeDescription,
|
|
256
|
-
rangeSwitchWrapperAttrs,
|
|
257
|
-
rangeSwitchButtonAttrs,
|
|
258
|
-
rangeSwitchTitleAttrs,
|
|
259
|
-
periodDateListAttrs,
|
|
260
|
-
periodDateSelectedAttrs,
|
|
261
|
-
periodDateCurrentSelectedAttrs,
|
|
262
|
-
periodDateCurrentAttrs,
|
|
263
|
-
periodDateAttrs,
|
|
264
|
-
} = props.attrs;
|
|
265
|
-
|
|
266
|
-
const periods = computed(() => [
|
|
267
|
-
{ name: PERIOD.week, title: props.locale.week },
|
|
268
|
-
{ name: PERIOD.month, title: props.locale.month },
|
|
269
|
-
{ name: PERIOD.quarter, title: props.locale.quarter },
|
|
270
|
-
{ name: PERIOD.year, title: props.locale.year },
|
|
271
|
-
]);
|
|
272
|
-
|
|
273
|
-
const rangeSwitchTitle = computed(() => {
|
|
274
|
-
if (props.isPeriod.month || props.isPeriod.quarter) {
|
|
275
|
-
return String(activeDate.value.getFullYear());
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
if (props.isPeriod.year) {
|
|
279
|
-
return `${periodDateList.value.at(0).title} – ${periodDateList.value.at(-1).title}`;
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
if (props.isPeriod.week) {
|
|
283
|
-
return `${props.locale.months.longhand[activeDate.value.getMonth()]} ${activeDate.value.getFullYear()}`;
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
return "";
|
|
287
|
-
});
|
|
288
|
-
|
|
289
|
-
function onClickPeriodButton(periodName) {
|
|
290
|
-
const localDate = localValue.value.from !== null ? localValue.value.from : new Date();
|
|
291
|
-
|
|
292
|
-
if (periodName === PERIOD.week) {
|
|
293
|
-
periodDateList.value = getWeekDateList(localDate, props.locale.months.shorthand);
|
|
294
|
-
|
|
295
|
-
period.value = PERIOD.week;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
if (periodName === PERIOD.month) {
|
|
299
|
-
periodDateList.value = getMonthsDateList(localDate, props.locale.months.longhand);
|
|
300
|
-
|
|
301
|
-
period.value = PERIOD.month;
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
if (periodName === PERIOD.quarter) {
|
|
305
|
-
periodDateList.value = getQuartersDateList(localDate, props.locale.quarter);
|
|
306
|
-
|
|
307
|
-
period.value = PERIOD.quarter;
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
if (periodName === PERIOD.year) {
|
|
311
|
-
periodDateList.value = getYearDateList(localDate);
|
|
312
|
-
|
|
313
|
-
period.value = PERIOD.year;
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
function onClickOwnRange() {
|
|
318
|
-
period.value = PERIOD.ownRange;
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
function selectDate(date) {
|
|
322
|
-
localValue.value = {
|
|
323
|
-
from: date.startRange,
|
|
324
|
-
to: date.endRange,
|
|
325
|
-
};
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
function toggleMenu() {
|
|
329
|
-
emit("toggleMenu");
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
function onClickCustomRangeButton() {
|
|
333
|
-
selectCustomRange();
|
|
334
|
-
|
|
335
|
-
emit("closeMenu");
|
|
336
|
-
period.value = PERIOD.custom;
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
function selectCustomRange() {
|
|
340
|
-
localValue.value = {
|
|
341
|
-
from: props.customRangeButton.range.from,
|
|
342
|
-
to: props.customRangeButton.range.to,
|
|
343
|
-
};
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
function getDatePeriodState(date) {
|
|
347
|
-
const localStart = new Date(localValue.value.from);
|
|
348
|
-
const localEnd = new Date(localValue.value.to);
|
|
349
|
-
|
|
350
|
-
if (props.isPeriod.year) {
|
|
351
|
-
localStart.setMonth(0, 1);
|
|
352
|
-
localEnd.setMonth(11, 31);
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
localStart.setHours(0, 0, 0, 0);
|
|
356
|
-
localEnd.setHours(23, 59, 59, 999);
|
|
357
|
-
|
|
358
|
-
const isSelected = localStart - date.startRange === 0 && localEnd - date.endRange === 0;
|
|
359
|
-
const isCurrentDate = date.startRange <= new Date() && new Date() <= date.endRange;
|
|
360
|
-
|
|
361
|
-
return { isSelected, isCurrentDate };
|
|
362
|
-
}
|
|
363
|
-
</script>
|