vueless 0.0.331 → 0.0.332

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.
@@ -0,0 +1,136 @@
1
+ <template>
2
+ <div>
3
+ <UInput
4
+ ref="rangeInputStartRef"
5
+ v-model="rangeStart"
6
+ :error="inputRangeFromError"
7
+ size="md"
8
+ v-bind="attrs.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="attrs.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";
27
+
28
+ import { dateIsOutOfRange, parseDate } from "../ui.form-calendar/utilCalendar.js";
29
+
30
+ import UInput from "../ui.form-input/UInput.vue";
31
+
32
+ import { INPUT_RANGE_TYPE, INPUT_RANGE_FORMAT } from "./constants.js";
33
+
34
+ const props = defineProps({
35
+ locale: {
36
+ type: Object,
37
+ required: true,
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
+ });
60
+
61
+ const localValue = defineModel("localValue", { required: true, type: Object });
62
+ const inputRangeFromError = defineModel("inputRangeFromError", { required: true, type: String });
63
+ const inputRangeToError = defineModel("inputRangeToError", { required: true, type: String });
64
+ const rangeStart = defineModel("rangeStart", { type: String, required: true });
65
+ const rangeEnd = defineModel("rangeEnd", { type: String, required: true });
66
+
67
+ function isGraterThanTo(value) {
68
+ if (!value) return false;
69
+
70
+ const parsedValue = parseDate(value, INPUT_RANGE_FORMAT, props.locale);
71
+ const parsedTo = parseDate(localValue.value.to, props.dateFormat, props.locale);
72
+
73
+ return parsedValue > parsedTo;
74
+ }
75
+
76
+ function isSmallerThanFrom(value) {
77
+ if (!value) return false;
78
+
79
+ const parsedValue = parseDate(value, INPUT_RANGE_FORMAT, props.locale);
80
+ const parsedFrom = parseDate(localValue.value.from, props.dateFormat, props.locale);
81
+
82
+ return parsedValue < parsedFrom;
83
+ }
84
+
85
+ function onInputRangeInput(value, type) {
86
+ const isInvalidDateFormat = isWrongDateFormat(value);
87
+
88
+ let error = "";
89
+
90
+ if (isInvalidDateFormat && value) {
91
+ error = props.locale.dateFormatWithDot;
92
+ } else if (isWrongMonthNumber(value) && value) {
93
+ error = props.locale.notCorrectMonthNumber;
94
+ } else if (isWrongDayNumber(value) && value) {
95
+ error = props.locale.notCorrectDayNumber;
96
+ } else if (isGraterThanTo(value) && type === INPUT_RANGE_TYPE.start) {
97
+ error = props.locale.fromDateGraterThanSecond;
98
+ } else if (isSmallerThanFrom(value) && type === INPUT_RANGE_TYPE.end) {
99
+ error = props.locale.toDateSmallerThanFirst;
100
+ }
101
+
102
+ if (type === INPUT_RANGE_TYPE.start) {
103
+ inputRangeFromError.value = error;
104
+ }
105
+
106
+ if (type === INPUT_RANGE_TYPE.end) {
107
+ inputRangeToError.value = error;
108
+ }
109
+
110
+ if (!isInvalidDateFormat) {
111
+ const parsedValue = parseDate(value || new Date(), INPUT_RANGE_FORMAT, props.locale);
112
+
113
+ const isOutOfRange = dateIsOutOfRange(
114
+ parsedValue,
115
+ props.minDate,
116
+ props.maxDate,
117
+ props.locale,
118
+ props.dateFormat,
119
+ );
120
+
121
+ if (type === INPUT_RANGE_TYPE.start && !error && !isOutOfRange) {
122
+ localValue.value = {
123
+ from: value ? parsedValue : "",
124
+ to: localValue.value.to,
125
+ };
126
+ }
127
+
128
+ if (type === INPUT_RANGE_TYPE.end && !error && !isOutOfRange) {
129
+ localValue.value = {
130
+ from: localValue.value.from,
131
+ to: value ? parsedValue : "",
132
+ };
133
+ }
134
+ }
135
+ }
136
+ </script>
@@ -0,0 +1,405 @@
1
+ <template>
2
+ <div v-bind="attrs.periodsRowAttrs">
3
+ <template v-for="periodButton in periods" :key="periodButton.name">
4
+ <UButton
5
+ v-if="periodButton.name !== period"
6
+ square
7
+ filled
8
+ no-ring
9
+ size="xs"
10
+ variant="thirdary"
11
+ :label="periodButton.title"
12
+ v-bind="attrs.periodButtonAttrs"
13
+ @click="onClickPeriodButton(periodButton.name)"
14
+ />
15
+
16
+ <UButton
17
+ v-else
18
+ square
19
+ filled
20
+ no-ring
21
+ size="xs"
22
+ variant="thirdary"
23
+ :label="periodButton.title"
24
+ v-bind="attrs.periodButtonActiveAttrs"
25
+ @click="onClickPeriodButton(periodButton.name)"
26
+ />
27
+ </template>
28
+ </div>
29
+
30
+ <div v-bind="attrs.periodsRowAttrs">
31
+ <UButton
32
+ v-if="customRangeButton.range.to && customRangeButton.range.from && PERIOD.custom !== period"
33
+ square
34
+ filled
35
+ no-ring
36
+ size="xs"
37
+ variant="thirdary"
38
+ v-bind="attrs.periodButtonAttrs"
39
+ @click="onClickCustomRangeButton"
40
+ >
41
+ {{ customRangeButton.label }}
42
+ <span
43
+ v-if="customRangeButton.description"
44
+ v-bind="attrs.customRangeDescription"
45
+ v-text="customRangeButton.description"
46
+ />
47
+ </UButton>
48
+
49
+ <UButton
50
+ v-if="customRangeButton.range.to && customRangeButton.range.from && PERIOD.custom === period"
51
+ square
52
+ filled
53
+ no-ring
54
+ size="xs"
55
+ variant="thirdary"
56
+ v-bind="attrs.periodButtonActiveAttrs"
57
+ @click="onClickCustomRangeButton"
58
+ >
59
+ {{ customRangeButton.label }}
60
+ <span
61
+ v-if="customRangeButton.description"
62
+ v-bind="attrs.customRangeDescription"
63
+ v-text="customRangeButton.description"
64
+ />
65
+ </UButton>
66
+
67
+ <UButton
68
+ v-if="PERIOD.ownRange !== period"
69
+ square
70
+ filled
71
+ no-ring
72
+ size="xs"
73
+ variant="thirdary"
74
+ :label="locale.ownRange"
75
+ :left-icon="config.defaults.ownRangeIcon"
76
+ v-bind="attrs.periodButtonAttrs"
77
+ @click="onClickOwnRange"
78
+ />
79
+
80
+ <UButton
81
+ v-else
82
+ square
83
+ filled
84
+ no-ring
85
+ size="xs"
86
+ variant="thirdary"
87
+ :label="locale.ownRange"
88
+ :left-icon="config.defaults.ownRangeIcon"
89
+ v-bind="attrs.periodButtonActiveAttrs"
90
+ @click="onClickOwnRange"
91
+ />
92
+ </div>
93
+
94
+ <template v-if="!isPeriod.ownRange && !isPeriod.custom">
95
+ <div v-bind="attrs.rangeSwitchWrapperAttrs">
96
+ <UButton
97
+ square
98
+ no-ring
99
+ size="xs"
100
+ color="gray"
101
+ variant="thirdary"
102
+ :left-icon="config.defaults.prevIcon"
103
+ v-bind="attrs.rangeSwitchButtonAttrs"
104
+ @click="emit('clickPrev')"
105
+ />
106
+
107
+ <div v-bind="attrs.rangeSwitchTitleAttrs">
108
+ {{ rangeSwitchTitle }}
109
+ </div>
110
+
111
+ <UButton
112
+ square
113
+ no-ring
114
+ size="xs"
115
+ color="gray"
116
+ variant="thirdary"
117
+ :left-icon="config.defaults.nextIcon"
118
+ v-bind="attrs.rangeSwitchButtonAttrs"
119
+ @click="emit('clickNext')"
120
+ />
121
+ </div>
122
+
123
+ <div v-if="isDatePeriodOutOfRange" v-bind="attrs.periodDateListAttrs">
124
+ <template v-for="(date, index) in periodDateList" :key="date.title">
125
+ <UButton
126
+ v-if="getDatePeriodState(date, index).isActive"
127
+ no-ring
128
+ size="sm"
129
+ variant="thirdary"
130
+ :disabled="isDatePeriodOutOfRange(date)"
131
+ v-bind="attrs.periodDateActiveAttrs"
132
+ :label="String(date.title)"
133
+ :class="{ 'rounded-dynamic': getDatePeriodState(date, index).isSingleItem }"
134
+ @click="selectDate(date), toggleMenu()"
135
+ />
136
+
137
+ <UButton
138
+ v-else-if="getDatePeriodState(date, index).isFirstInRange && !isListType"
139
+ no-ring
140
+ size="sm"
141
+ variant="thirdary"
142
+ :disabled="isDatePeriodOutOfRange(date)"
143
+ v-bind="attrs.firstPeriodGridDateAttrs"
144
+ :label="String(date.title)"
145
+ :class="{ 'rounded-dynamic': getDatePeriodState(date, index).isSingleItem }"
146
+ @click="selectDate(date), toggleMenu()"
147
+ />
148
+
149
+ <UButton
150
+ v-else-if="getDatePeriodState(date, index).isFirstInRange && isListType"
151
+ no-ring
152
+ size="sm"
153
+ variant="thirdary"
154
+ :disabled="isDatePeriodOutOfRange(date)"
155
+ v-bind="attrs.firstPeriodListDateAttrs"
156
+ :label="String(date.title)"
157
+ :class="{ 'rounded-dynamic': getDatePeriodState(date, index).isSingleItem }"
158
+ @click="selectDate(date), toggleMenu()"
159
+ />
160
+
161
+ <UButton
162
+ v-else-if="getDatePeriodState(date, index).isLastInRange && !isListType"
163
+ no-ring
164
+ size="sm"
165
+ variant="thirdary"
166
+ :disabled="isDatePeriodOutOfRange(date)"
167
+ v-bind="attrs.lastPeriodGridDateAttrs"
168
+ :label="String(date.title)"
169
+ :class="{ 'rounded-dynamic': getDatePeriodState(date, index).isSingleItem }"
170
+ @click="selectDate(date), toggleMenu()"
171
+ />
172
+
173
+ <UButton
174
+ v-else-if="getDatePeriodState(date, index).isLastInRange && isListType"
175
+ no-ring
176
+ size="sm"
177
+ variant="thirdary"
178
+ :disabled="isDatePeriodOutOfRange(date)"
179
+ v-bind="attrs.lastPeriodListDateAttrs"
180
+ :label="String(date.title)"
181
+ :class="{ 'rounded-dynamic': getDatePeriodState(date, index).isSingleItem }"
182
+ @click="selectDate(date), toggleMenu()"
183
+ />
184
+
185
+ <UButton
186
+ v-else-if="getDatePeriodState(date, index).isInRange"
187
+ no-ring
188
+ size="sm"
189
+ variant="thirdary"
190
+ :disabled="isDatePeriodOutOfRange(date)"
191
+ v-bind="attrs.periodDateInRangeAttrs"
192
+ :label="String(date.title)"
193
+ :class="{ 'rounded-dynamic': getDatePeriodState(date, index).isSingleItem }"
194
+ @click="selectDate(date), toggleMenu()"
195
+ />
196
+
197
+ <UButton
198
+ v-else
199
+ no-ring
200
+ size="sm"
201
+ variant="thirdary"
202
+ :disabled="isDatePeriodOutOfRange(date)"
203
+ v-bind="attrs.periodDateAttrs"
204
+ :label="String(date.title)"
205
+ @click="selectDate(date), toggleMenu()"
206
+ />
207
+ </template>
208
+ </div>
209
+ </template>
210
+ </template>
211
+
212
+ <script setup>
213
+ import { computed, inject } from "vue";
214
+
215
+ import {
216
+ getWeekDateList,
217
+ getYearDateList,
218
+ getQuartersDateList,
219
+ getMonthsDateList,
220
+ } from "./utilDateRange.js";
221
+
222
+ import UButton from "../ui.button/UButton.vue";
223
+
224
+ import { PERIOD } from "./constants.js";
225
+
226
+ const props = defineProps({
227
+ locale: {
228
+ type: Object,
229
+ required: true,
230
+ },
231
+
232
+ isPeriod: {
233
+ type: Object,
234
+ required: true,
235
+ },
236
+
237
+ customRangeButton: {
238
+ type: Object,
239
+ required: true,
240
+ },
241
+
242
+ dateFormat: {
243
+ type: [String, undefined],
244
+ default: undefined,
245
+ },
246
+
247
+ minDate: {
248
+ type: [String, Date],
249
+ default: undefined,
250
+ },
251
+
252
+ maxDate: {
253
+ type: [String, Date],
254
+ default: undefined,
255
+ },
256
+
257
+ config: {
258
+ type: Object,
259
+ required: true,
260
+ },
261
+
262
+ attrs: {
263
+ type: Object,
264
+ required: true,
265
+ },
266
+ });
267
+
268
+ const emit = defineEmits(["toggleMenu", "closeMenu", "clickPrev", "clickNext"]);
269
+
270
+ const localValue = defineModel("localValue", { required: true, type: Object });
271
+ const activeDate = defineModel("activeDate", { required: true, type: Object });
272
+ const periodDateList = defineModel("periodDateList", { required: true, type: Object });
273
+ const period = defineModel("period", { required: true, type: String });
274
+
275
+ const isDatePeriodOutOfRange = inject("isDatePeriodOutOfRange", null);
276
+
277
+ const periods = computed(() => [
278
+ { name: PERIOD.week, title: props.locale.week },
279
+ { name: PERIOD.month, title: props.locale.month },
280
+ { name: PERIOD.quarter, title: props.locale.quarter },
281
+ { name: PERIOD.year, title: props.locale.year },
282
+ ]);
283
+
284
+ const isListType = computed(() => props.isPeriod.quarter || props.isPeriod.week);
285
+
286
+ const rangeSwitchTitle = computed(() => {
287
+ if (props.isPeriod.month || props.isPeriod.quarter) {
288
+ return String(activeDate.value.getFullYear());
289
+ }
290
+
291
+ if (props.isPeriod.year) {
292
+ return `${periodDateList.value.at(0).title} – ${periodDateList.value.at(-1).title}`;
293
+ }
294
+
295
+ if (props.isPeriod.week) {
296
+ return `${props.locale.months.longhand[activeDate.value.getMonth()]} ${activeDate.value.getFullYear()}`;
297
+ }
298
+
299
+ return "";
300
+ });
301
+
302
+ function onClickPeriodButton(periodName) {
303
+ const localDate = localValue.value.from !== null ? localValue.value.from : new Date();
304
+
305
+ if (periodName === PERIOD.week) {
306
+ periodDateList.value = getWeekDateList(localDate, props.locale.months.shorthand);
307
+
308
+ period.value = PERIOD.week;
309
+ }
310
+
311
+ if (periodName === PERIOD.month) {
312
+ periodDateList.value = getMonthsDateList(localDate, props.locale.months.longhand);
313
+
314
+ period.value = PERIOD.month;
315
+ }
316
+
317
+ if (periodName === PERIOD.quarter) {
318
+ periodDateList.value = getQuartersDateList(localDate, props.locale.quarter);
319
+
320
+ period.value = PERIOD.quarter;
321
+ }
322
+
323
+ if (periodName === PERIOD.year) {
324
+ periodDateList.value = getYearDateList(localDate);
325
+
326
+ period.value = PERIOD.year;
327
+ }
328
+ }
329
+
330
+ function onClickOwnRange() {
331
+ period.value = PERIOD.ownRange;
332
+ }
333
+
334
+ function selectDate(date) {
335
+ localValue.value = {
336
+ from: date.startRange,
337
+ to: date.endRange,
338
+ };
339
+ }
340
+
341
+ function toggleMenu() {
342
+ emit("toggleMenu");
343
+ }
344
+
345
+ function onClickCustomRangeButton() {
346
+ selectCustomRange();
347
+
348
+ emit("closeMenu");
349
+ period.value = PERIOD.custom;
350
+ }
351
+
352
+ function selectCustomRange() {
353
+ localValue.value = {
354
+ from: props.customRangeButton.range.from,
355
+ to: props.customRangeButton.range.to,
356
+ };
357
+ }
358
+
359
+ function getDatePeriodState(date, index) {
360
+ const localStart = new Date(localValue.value.from);
361
+ const localEnd = new Date(localValue.value.to);
362
+
363
+ if (props.isPeriod.year) {
364
+ localStart.setMonth(0, 1);
365
+ localEnd.setMonth(11, 31);
366
+ }
367
+
368
+ localStart.setHours(0, 0, 0, 0);
369
+ localEnd.setHours(23, 59, 59, 999);
370
+
371
+ const startDateInRangeIndex = periodDateList.value.findIndex((periodDate) => {
372
+ return localStart <= periodDate.endRange && localStart >= periodDate.startRange;
373
+ });
374
+
375
+ const endDateInRangeIndex = periodDateList.value.findIndex((periodDate) => {
376
+ return localEnd >= periodDate.startRange && localEnd <= periodDate.endRange;
377
+ });
378
+
379
+ let isInRange = index >= startDateInRangeIndex && index <= endDateInRangeIndex;
380
+
381
+ if (!~startDateInRangeIndex || !~endDateInRangeIndex) {
382
+ isInRange =
383
+ (index >= startDateInRangeIndex && startDateInRangeIndex > -1) ||
384
+ (index <= endDateInRangeIndex && endDateInRangeIndex > -1);
385
+ }
386
+
387
+ if (
388
+ !~startDateInRangeIndex &&
389
+ periodDateList.value.at(0).startRange > localStart &&
390
+ !~endDateInRangeIndex &&
391
+ periodDateList.value.at(0).endRange < localEnd
392
+ ) {
393
+ isInRange = true;
394
+ }
395
+
396
+ const isSingleItem =
397
+ startDateInRangeIndex === endDateInRangeIndex && ~endDateInRangeIndex && ~startDateInRangeIndex;
398
+
399
+ const isFirstInRange = startDateInRangeIndex === index;
400
+ const isLastInRange = endDateInRangeIndex === index;
401
+ const isActive = localValue.value.from === date.startRange;
402
+
403
+ return { isInRange, isSingleItem, isFirstInRange, isLastInRange, isActive };
404
+ }
405
+ </script>
@@ -54,6 +54,7 @@ export default /*tw*/ {
54
54
  firstPeriodListDate: "rounded-b-none",
55
55
  lastPeriodListDate: "rounded-t-none",
56
56
  periodDateActive: "bg-gray-100",
57
+ customRangeDescription: "",
57
58
  rangeInputWrapper: "flex mt-4 -space-x-px group/range-input-wrapper",
58
59
  rangeInputFirst: "group/range-input-first",
59
60
  rangeInputLast: "group/range-input-last",
@@ -20,3 +20,10 @@ export const PERIOD = {
20
20
  ownRange: "ownRange",
21
21
  custom: "custom",
22
22
  };
23
+
24
+ export const INPUT_RANGE_FORMAT = "d.m.Y";
25
+
26
+ export const SHIFT_ACTION = {
27
+ prev: "prev",
28
+ next: "next",
29
+ };