cynx-lib 1.3.77 → 1.3.79
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/package.json +1 -1
- package/ui/components/DatePicker.jsx +15 -14
- package/vue/components/DatePicker.vue +298 -75
package/package.json
CHANGED
|
@@ -97,8 +97,7 @@ export function DatePicker({
|
|
|
97
97
|
maxDate,
|
|
98
98
|
disabled,
|
|
99
99
|
size = 'md',
|
|
100
|
-
|
|
101
|
-
stepperPosition = 'off',
|
|
100
|
+
stepper = 'off',
|
|
102
101
|
locale = 'en',
|
|
103
102
|
style,
|
|
104
103
|
fullWidth = false,
|
|
@@ -833,12 +832,6 @@ export function DatePicker({
|
|
|
833
832
|
</button>
|
|
834
833
|
);
|
|
835
834
|
|
|
836
|
-
const actualPos = stepperPosition || 'around';
|
|
837
|
-
const showStepperEffective = showStepper && actualPos !== 'off';
|
|
838
|
-
const posMode = actualPos === 'left' || actualPos === 'start' ? 'left'
|
|
839
|
-
: actualPos === 'right' || actualPos === 'end' ? 'right'
|
|
840
|
-
: 'around';
|
|
841
|
-
|
|
842
835
|
return (
|
|
843
836
|
<div style={{
|
|
844
837
|
display: fullWidth || style?.display === 'flex' ? 'flex' : 'inline-flex',
|
|
@@ -864,15 +857,23 @@ export function DatePicker({
|
|
|
864
857
|
maxWidth: '100%',
|
|
865
858
|
minWidth: 0,
|
|
866
859
|
}}>
|
|
867
|
-
{
|
|
868
|
-
{
|
|
869
|
-
|
|
860
|
+
{stepper === 'around' && renderPrevBtn()}
|
|
861
|
+
{stepper === 'left' && (
|
|
862
|
+
<>
|
|
863
|
+
{renderPrevBtn()}
|
|
864
|
+
{renderNextBtn()}
|
|
865
|
+
</>
|
|
866
|
+
)}
|
|
870
867
|
|
|
871
868
|
{renderTriggerBtn()}
|
|
872
869
|
|
|
873
|
-
{
|
|
874
|
-
{
|
|
875
|
-
|
|
870
|
+
{stepper === 'around' && renderNextBtn()}
|
|
871
|
+
{stepper === 'right' && (
|
|
872
|
+
<>
|
|
873
|
+
{renderPrevBtn()}
|
|
874
|
+
{renderNextBtn()}
|
|
875
|
+
</>
|
|
876
|
+
)}
|
|
876
877
|
</div>
|
|
877
878
|
|
|
878
879
|
{/* Dropdown via portal */}
|
|
@@ -142,6 +142,8 @@ ensureStyles();
|
|
|
142
142
|
|
|
143
143
|
const props = withDefaults(
|
|
144
144
|
defineProps<{
|
|
145
|
+
type?: "date" | "month" | "year";
|
|
146
|
+
mode?: "date" | "month" | "year";
|
|
145
147
|
modelValue?: any;
|
|
146
148
|
value?: any;
|
|
147
149
|
label?: string;
|
|
@@ -151,8 +153,7 @@ const props = withDefaults(
|
|
|
151
153
|
maxDate?: any;
|
|
152
154
|
disabled?: boolean;
|
|
153
155
|
size?: "xs" | "sm" | "md" | "lg";
|
|
154
|
-
|
|
155
|
-
stepperPosition?: "off" | "around" | "left" | "right" | "start" | "end";
|
|
156
|
+
stepper?: "off" | "around" | "left" | "right";
|
|
156
157
|
locale?: "en" | "ru" | DatePickerLocale | string;
|
|
157
158
|
clearable?: boolean;
|
|
158
159
|
fullWidth?: boolean;
|
|
@@ -165,17 +166,18 @@ const props = withDefaults(
|
|
|
165
166
|
range?: boolean;
|
|
166
167
|
}>(),
|
|
167
168
|
{
|
|
169
|
+
type: "date",
|
|
170
|
+
mode: undefined,
|
|
168
171
|
modelValue: undefined,
|
|
169
172
|
value: undefined,
|
|
170
173
|
label: "",
|
|
171
|
-
placeholder:
|
|
174
|
+
placeholder: undefined,
|
|
172
175
|
badges: () => ({}),
|
|
173
176
|
minDate: undefined,
|
|
174
177
|
maxDate: undefined,
|
|
175
178
|
disabled: false,
|
|
176
179
|
size: "md",
|
|
177
|
-
|
|
178
|
-
stepperPosition: "off",
|
|
180
|
+
stepper: "off",
|
|
179
181
|
locale: "en",
|
|
180
182
|
clearable: true,
|
|
181
183
|
fullWidth: false,
|
|
@@ -198,10 +200,34 @@ const emit = defineEmits<{
|
|
|
198
200
|
(e: "clear"): void;
|
|
199
201
|
}>();
|
|
200
202
|
|
|
203
|
+
const emitValue = (val: any) => {
|
|
204
|
+
emit("update:modelValue", val);
|
|
205
|
+
emit("update:value", val);
|
|
206
|
+
emit("change", val);
|
|
207
|
+
};
|
|
208
|
+
|
|
201
209
|
const currentVal = computed(() => {
|
|
202
210
|
return props.modelValue !== undefined ? props.modelValue : props.value;
|
|
203
211
|
});
|
|
204
212
|
|
|
213
|
+
const pickerType = computed(() => props.type || props.mode || "date");
|
|
214
|
+
const initialView = computed<"day" | "month" | "year">(() => {
|
|
215
|
+
if (pickerType.value === "month") return "month";
|
|
216
|
+
if (pickerType.value === "year") return "year";
|
|
217
|
+
return "day";
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
const defaultPlaceholder = computed(() =>
|
|
221
|
+
pickerType.value === "month"
|
|
222
|
+
? "Select month"
|
|
223
|
+
: pickerType.value === "year"
|
|
224
|
+
? "Select year"
|
|
225
|
+
: "Select date"
|
|
226
|
+
);
|
|
227
|
+
const effectivePlaceholder = computed(() =>
|
|
228
|
+
props.placeholder !== undefined ? props.placeholder : defaultPlaceholder.value
|
|
229
|
+
);
|
|
230
|
+
|
|
205
231
|
const loc = computed<DatePickerLocale>(() => {
|
|
206
232
|
if (typeof props.locale === "object" && props.locale !== null) {
|
|
207
233
|
return props.locale;
|
|
@@ -211,7 +237,10 @@ const loc = computed<DatePickerLocale>(() => {
|
|
|
211
237
|
|
|
212
238
|
const s = computed(() => SIZES[props.size] || SIZES.md);
|
|
213
239
|
const open = ref(false);
|
|
214
|
-
const view = ref<"day" | "month" | "year">(
|
|
240
|
+
const view = ref<"day" | "month" | "year">(initialView.value);
|
|
241
|
+
watch(pickerType, (pt) => {
|
|
242
|
+
view.value = pt === "month" ? "month" : pt === "year" ? "year" : "day";
|
|
243
|
+
});
|
|
215
244
|
const cursor = ref<Date>(new Date());
|
|
216
245
|
const pos = ref({ top: 0, left: 0, width: 0 });
|
|
217
246
|
|
|
@@ -284,13 +313,13 @@ const handleWindowClick = (e: MouseEvent) => {
|
|
|
284
313
|
if (dropRef.value?.contains(target)) return;
|
|
285
314
|
if (target.closest?.(".cynx-timepicker-drop")) return;
|
|
286
315
|
open.value = false;
|
|
287
|
-
view.value =
|
|
316
|
+
view.value = initialView.value;
|
|
288
317
|
};
|
|
289
318
|
|
|
290
319
|
const handleKeyDown = (e: KeyboardEvent) => {
|
|
291
320
|
if (e.key === "Escape" && open.value) {
|
|
292
321
|
open.value = false;
|
|
293
|
-
view.value =
|
|
322
|
+
view.value = initialView.value;
|
|
294
323
|
}
|
|
295
324
|
};
|
|
296
325
|
|
|
@@ -319,7 +348,10 @@ onBeforeUnmount(() => {
|
|
|
319
348
|
|
|
320
349
|
const toggleOpen = () => {
|
|
321
350
|
if (props.disabled) return;
|
|
322
|
-
if (!open.value)
|
|
351
|
+
if (!open.value) {
|
|
352
|
+
calcPos();
|
|
353
|
+
view.value = initialView.value;
|
|
354
|
+
}
|
|
323
355
|
open.value = !open.value;
|
|
324
356
|
};
|
|
325
357
|
|
|
@@ -346,12 +378,10 @@ function pick(date: Date) {
|
|
|
346
378
|
rangeEnd.value = end;
|
|
347
379
|
|
|
348
380
|
const result = [formatDateStr(start), formatDateStr(end)];
|
|
349
|
-
|
|
350
|
-
emit("update:value", result);
|
|
351
|
-
emit("change", result);
|
|
381
|
+
emitValue(result);
|
|
352
382
|
|
|
353
383
|
open.value = false;
|
|
354
|
-
view.value =
|
|
384
|
+
view.value = initialView.value;
|
|
355
385
|
}
|
|
356
386
|
return;
|
|
357
387
|
}
|
|
@@ -362,18 +392,14 @@ function pick(date: Date) {
|
|
|
362
392
|
const strVal = `${y}-${m}-${d}`;
|
|
363
393
|
|
|
364
394
|
if (typeof currentVal.value === "string" || currentVal.value === undefined) {
|
|
365
|
-
|
|
366
|
-
emit("update:value", strVal);
|
|
367
|
-
emit("change", strVal);
|
|
395
|
+
emitValue(strVal);
|
|
368
396
|
} else {
|
|
369
|
-
|
|
370
|
-
emit("update:value", date);
|
|
371
|
-
emit("change", date);
|
|
397
|
+
emitValue(date);
|
|
372
398
|
}
|
|
373
399
|
|
|
374
400
|
if (!props.showTime) {
|
|
375
401
|
open.value = false;
|
|
376
|
-
view.value =
|
|
402
|
+
view.value = initialView.value;
|
|
377
403
|
}
|
|
378
404
|
}
|
|
379
405
|
|
|
@@ -383,27 +409,91 @@ function handleClear(e: MouseEvent) {
|
|
|
383
409
|
rangeStart.value = null;
|
|
384
410
|
rangeEnd.value = null;
|
|
385
411
|
}
|
|
386
|
-
|
|
387
|
-
emit("update:value", null);
|
|
388
|
-
emit("change", null);
|
|
412
|
+
emitValue(null);
|
|
389
413
|
emit("clear");
|
|
390
414
|
}
|
|
391
415
|
|
|
416
|
+
const isPrevDayDisabled = () => {
|
|
417
|
+
const minD = toDate(props.minDate);
|
|
418
|
+
if (!minD) return false;
|
|
419
|
+
const current = toDate(currentVal.value) || new Date();
|
|
420
|
+
if (pickerType.value === "year") {
|
|
421
|
+
return current.getFullYear() - 1 < minD.getFullYear();
|
|
422
|
+
}
|
|
423
|
+
if (pickerType.value === "month") {
|
|
424
|
+
const prevMonthEnd = new Date(current.getFullYear(), current.getMonth(), 0, 23, 59, 59, 999);
|
|
425
|
+
return prevMonthEnd < new Date(new Date(minD).setHours(0, 0, 0, 0));
|
|
426
|
+
}
|
|
427
|
+
const prev = new Date(current.getFullYear(), current.getMonth(), current.getDate() - 1);
|
|
428
|
+
return prev < new Date(new Date(minD).setHours(0, 0, 0, 0));
|
|
429
|
+
};
|
|
430
|
+
|
|
431
|
+
const isNextDayDisabled = () => {
|
|
432
|
+
const maxD = toDate(props.maxDate);
|
|
433
|
+
if (!maxD) return false;
|
|
434
|
+
const current = toDate(currentVal.value) || new Date();
|
|
435
|
+
if (pickerType.value === "year") {
|
|
436
|
+
return current.getFullYear() + 1 > maxD.getFullYear();
|
|
437
|
+
}
|
|
438
|
+
if (pickerType.value === "month") {
|
|
439
|
+
const nextMonthStart = new Date(current.getFullYear(), current.getMonth() + 1, 1);
|
|
440
|
+
return nextMonthStart > new Date(new Date(maxD).setHours(23, 59, 59, 999));
|
|
441
|
+
}
|
|
442
|
+
const next = new Date(current.getFullYear(), current.getMonth(), current.getDate() + 1);
|
|
443
|
+
return next > new Date(new Date(maxD).setHours(23, 59, 59, 999));
|
|
444
|
+
};
|
|
445
|
+
|
|
392
446
|
const changeDay = (delta: number) => {
|
|
393
447
|
if (props.disabled) return;
|
|
394
448
|
const current = toDate(currentVal.value) || new Date();
|
|
449
|
+
const minD = toDate(props.minDate);
|
|
450
|
+
const maxD = toDate(props.maxDate);
|
|
451
|
+
|
|
452
|
+
if (pickerType.value === "year") {
|
|
453
|
+
const next = new Date(current.getFullYear() + delta, 0, 1);
|
|
454
|
+
if (minD && next.getFullYear() < minD.getFullYear()) return;
|
|
455
|
+
if (maxD && next.getFullYear() > maxD.getFullYear()) return;
|
|
456
|
+
if (typeof currentVal.value === "number") {
|
|
457
|
+
emitValue(next.getFullYear());
|
|
458
|
+
} else if (typeof currentVal.value === "string") {
|
|
459
|
+
emitValue(`${next.getFullYear()}`);
|
|
460
|
+
} else {
|
|
461
|
+
emitValue(next);
|
|
462
|
+
}
|
|
463
|
+
return;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
if (pickerType.value === "month") {
|
|
467
|
+
const next = new Date(current.getFullYear(), current.getMonth() + delta, 1);
|
|
468
|
+
const nextEnd = new Date(next.getFullYear(), next.getMonth() + 1, 0, 23, 59, 59, 999);
|
|
469
|
+
if (minD && nextEnd < new Date(new Date(minD).setHours(0, 0, 0, 0))) return;
|
|
470
|
+
if (maxD && next > new Date(new Date(maxD).setHours(23, 59, 59, 999))) return;
|
|
471
|
+
if (typeof currentVal.value === "string") {
|
|
472
|
+
const y = next.getFullYear();
|
|
473
|
+
const m = pad(next.getMonth() + 1);
|
|
474
|
+
emitValue(`${y}-${m}`);
|
|
475
|
+
} else {
|
|
476
|
+
emitValue(next);
|
|
477
|
+
}
|
|
478
|
+
return;
|
|
479
|
+
}
|
|
480
|
+
|
|
395
481
|
const next = new Date(
|
|
396
482
|
current.getFullYear(),
|
|
397
483
|
current.getMonth(),
|
|
398
484
|
current.getDate() + delta
|
|
399
485
|
);
|
|
400
|
-
|
|
401
|
-
const minD = toDate(props.minDate);
|
|
402
|
-
const maxD = toDate(props.maxDate);
|
|
403
486
|
if (minD && next < new Date(new Date(minD).setHours(0, 0, 0, 0))) return;
|
|
404
487
|
if (maxD && next > new Date(new Date(maxD).setHours(23, 59, 59, 999))) return;
|
|
405
488
|
|
|
406
|
-
|
|
489
|
+
if (typeof currentVal.value === "string") {
|
|
490
|
+
const y = next.getFullYear();
|
|
491
|
+
const m = pad(next.getMonth() + 1);
|
|
492
|
+
const d = pad(next.getDate());
|
|
493
|
+
emitValue(`${y}-${m}-${d}`);
|
|
494
|
+
} else {
|
|
495
|
+
emitValue(next);
|
|
496
|
+
}
|
|
407
497
|
};
|
|
408
498
|
|
|
409
499
|
const isNavNextDisabled = () => {
|
|
@@ -458,9 +548,6 @@ function nav(dir: number) {
|
|
|
458
548
|
cursor.value = c;
|
|
459
549
|
}
|
|
460
550
|
|
|
461
|
-
function cycleView() {
|
|
462
|
-
view.value = view.value === "day" ? "month" : "year";
|
|
463
|
-
}
|
|
464
551
|
|
|
465
552
|
const valDate = computed(() => toDate(currentVal.value));
|
|
466
553
|
|
|
@@ -561,6 +648,21 @@ const formatted = computed(() => {
|
|
|
561
648
|
const vd = valDate.value;
|
|
562
649
|
const formattedTime =
|
|
563
650
|
props.showTime && props.timeValue ? ` ${props.timeValue}` : "";
|
|
651
|
+
|
|
652
|
+
if (pickerType.value === "year") {
|
|
653
|
+
return vd
|
|
654
|
+
? `${vd.getFullYear()}`
|
|
655
|
+
: currentVal.value !== null && currentVal.value !== undefined && currentVal.value !== ""
|
|
656
|
+
? `${currentVal.value}`
|
|
657
|
+
: null;
|
|
658
|
+
}
|
|
659
|
+
if (pickerType.value === "month") {
|
|
660
|
+
return vd
|
|
661
|
+
? `${loc.value.months[vd.getMonth()]} ${vd.getFullYear()}`
|
|
662
|
+
: typeof currentVal.value === "string" && currentVal.value
|
|
663
|
+
? `${currentVal.value}`
|
|
664
|
+
: null;
|
|
665
|
+
}
|
|
564
666
|
if (vd) {
|
|
565
667
|
const mName = loc.value.months[vd.getMonth()] || "";
|
|
566
668
|
return `${mName} ${vd.getDate()}, ${vd.getFullYear()}${formattedTime}`;
|
|
@@ -571,18 +673,6 @@ const formatted = computed(() => {
|
|
|
571
673
|
return null;
|
|
572
674
|
});
|
|
573
675
|
|
|
574
|
-
const headerLabel = computed(() => {
|
|
575
|
-
const y = cursor.value.getFullYear();
|
|
576
|
-
const m = cursor.value.getMonth();
|
|
577
|
-
if (view.value === "day") {
|
|
578
|
-
return `${loc.value.months[m]} ${y}`;
|
|
579
|
-
}
|
|
580
|
-
if (view.value === "month") {
|
|
581
|
-
return `${y}`;
|
|
582
|
-
}
|
|
583
|
-
const base = Math.floor(y / 12) * 12;
|
|
584
|
-
return `${base} – ${base + 11}`;
|
|
585
|
-
});
|
|
586
676
|
|
|
587
677
|
const daysCells = computed(() => {
|
|
588
678
|
const y = cursor.value.getFullYear();
|
|
@@ -644,15 +734,6 @@ const isYearDisabled = (yr: number) => {
|
|
|
644
734
|
return Boolean(disMin || disMax);
|
|
645
735
|
};
|
|
646
736
|
|
|
647
|
-
const showStepperEffective = computed(
|
|
648
|
-
() => props.showStepper && props.stepperPosition !== "off"
|
|
649
|
-
);
|
|
650
|
-
const posMode = computed(() => {
|
|
651
|
-
const p = props.stepperPosition;
|
|
652
|
-
if (p === "left" || p === "start") return "left";
|
|
653
|
-
if (p === "right" || p === "end") return "right";
|
|
654
|
-
return "around";
|
|
655
|
-
});
|
|
656
737
|
</script>
|
|
657
738
|
|
|
658
739
|
<template>
|
|
@@ -698,9 +779,9 @@ const posMode = computed(() => {
|
|
|
698
779
|
>
|
|
699
780
|
<!-- Left stepper buttons -->
|
|
700
781
|
<button
|
|
701
|
-
v-if="
|
|
782
|
+
v-if="props.stepper === 'around' || props.stepper === 'left'"
|
|
702
783
|
type="button"
|
|
703
|
-
:disabled="disabled ||
|
|
784
|
+
:disabled="disabled || isPrevDayDisabled()"
|
|
704
785
|
style="
|
|
705
786
|
display: flex;
|
|
706
787
|
align-items: center;
|
|
@@ -725,6 +806,34 @@ const posMode = computed(() => {
|
|
|
725
806
|
<ChevronLeft :size="s.iconSize + 2" />
|
|
726
807
|
</button>
|
|
727
808
|
|
|
809
|
+
<button
|
|
810
|
+
v-if="props.stepper === 'left'"
|
|
811
|
+
type="button"
|
|
812
|
+
:disabled="disabled || isNextDayDisabled()"
|
|
813
|
+
style="
|
|
814
|
+
display: flex;
|
|
815
|
+
align-items: center;
|
|
816
|
+
justify-content: center;
|
|
817
|
+
border-radius: var(--rads, 8px);
|
|
818
|
+
border: 1px solid var(--border, #e2e8f0);
|
|
819
|
+
background: var(--surface, #ffffff);
|
|
820
|
+
color: var(--muted, #797b8d);
|
|
821
|
+
box-shadow: var(--shadow, 0 1px 3px rgba(0,0,0,.08));
|
|
822
|
+
flex-shrink: 0;
|
|
823
|
+
cursor: pointer;
|
|
824
|
+
transition: all .15s;
|
|
825
|
+
"
|
|
826
|
+
:style="{
|
|
827
|
+
width: `${s.btnSize}px`,
|
|
828
|
+
height: `${s.btnSize}px`,
|
|
829
|
+
opacity: disabled ? 0.35 : 1,
|
|
830
|
+
}"
|
|
831
|
+
title="Next day (+1)"
|
|
832
|
+
@click.stop="changeDay(1)"
|
|
833
|
+
>
|
|
834
|
+
<ChevronRight :size="s.iconSize + 2" />
|
|
835
|
+
</button>
|
|
836
|
+
|
|
728
837
|
<!-- Trigger button -->
|
|
729
838
|
<button
|
|
730
839
|
ref="btnRef"
|
|
@@ -770,7 +879,7 @@ const posMode = computed(() => {
|
|
|
770
879
|
min-width: 0;
|
|
771
880
|
"
|
|
772
881
|
>
|
|
773
|
-
{{ formatted ||
|
|
882
|
+
{{ formatted || effectivePlaceholder }}
|
|
774
883
|
</span>
|
|
775
884
|
<span
|
|
776
885
|
v-if="currentVal && clearable"
|
|
@@ -794,9 +903,37 @@ const posMode = computed(() => {
|
|
|
794
903
|
|
|
795
904
|
<!-- Right stepper buttons -->
|
|
796
905
|
<button
|
|
797
|
-
v-if="
|
|
906
|
+
v-if="props.stepper === 'right'"
|
|
907
|
+
type="button"
|
|
908
|
+
:disabled="disabled || isPrevDayDisabled()"
|
|
909
|
+
style="
|
|
910
|
+
display: flex;
|
|
911
|
+
align-items: center;
|
|
912
|
+
justify-content: center;
|
|
913
|
+
border-radius: var(--rads, 8px);
|
|
914
|
+
border: 1px solid var(--border, #e2e8f0);
|
|
915
|
+
background: var(--surface, #ffffff);
|
|
916
|
+
color: var(--muted, #797b8d);
|
|
917
|
+
box-shadow: var(--shadow, 0 1px 3px rgba(0,0,0,.08));
|
|
918
|
+
flex-shrink: 0;
|
|
919
|
+
cursor: pointer;
|
|
920
|
+
transition: all .15s;
|
|
921
|
+
"
|
|
922
|
+
:style="{
|
|
923
|
+
width: `${s.btnSize}px`,
|
|
924
|
+
height: `${s.btnSize}px`,
|
|
925
|
+
opacity: disabled ? 0.35 : 1,
|
|
926
|
+
}"
|
|
927
|
+
title="Previous day (-1)"
|
|
928
|
+
@click.stop="changeDay(-1)"
|
|
929
|
+
>
|
|
930
|
+
<ChevronLeft :size="s.iconSize + 2" />
|
|
931
|
+
</button>
|
|
932
|
+
|
|
933
|
+
<button
|
|
934
|
+
v-if="props.stepper === 'around' || props.stepper === 'right'"
|
|
798
935
|
type="button"
|
|
799
|
-
:disabled="disabled ||
|
|
936
|
+
:disabled="disabled || isNextDayDisabled()"
|
|
800
937
|
style="
|
|
801
938
|
display: flex;
|
|
802
939
|
align-items: center;
|
|
@@ -876,23 +1013,84 @@ const posMode = computed(() => {
|
|
|
876
1013
|
<ChevronLeft :size="15" />
|
|
877
1014
|
</button>
|
|
878
1015
|
|
|
879
|
-
<
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
1016
|
+
<div style="display: flex; align-items: center; gap: 4px; min-width: 0;">
|
|
1017
|
+
<template v-if="view === 'day'">
|
|
1018
|
+
<button
|
|
1019
|
+
type="button"
|
|
1020
|
+
style="
|
|
1021
|
+
background: none;
|
|
1022
|
+
border: none;
|
|
1023
|
+
cursor: pointer;
|
|
1024
|
+
font-size: .82rem;
|
|
1025
|
+
font-weight: 700;
|
|
1026
|
+
color: var(--primary-text, #0f172a);
|
|
1027
|
+
padding: 4px 6px;
|
|
1028
|
+
border-radius: var(--radxs, 6px);
|
|
1029
|
+
font-family: var(--sans, inherit);
|
|
1030
|
+
transition: background .12s;
|
|
1031
|
+
"
|
|
1032
|
+
@click="view = 'month'"
|
|
1033
|
+
@mouseenter="(e: MouseEvent) => ((e.currentTarget as HTMLElement).style.background = 'var(--grey-1, #f5f5f8)')"
|
|
1034
|
+
@mouseleave="(e: MouseEvent) => ((e.currentTarget as HTMLElement).style.background = 'none')"
|
|
1035
|
+
>
|
|
1036
|
+
{{ loc.months[cursor.getMonth()] }}
|
|
1037
|
+
</button>
|
|
1038
|
+
<button
|
|
1039
|
+
type="button"
|
|
1040
|
+
style="
|
|
1041
|
+
background: none;
|
|
1042
|
+
border: none;
|
|
1043
|
+
cursor: pointer;
|
|
1044
|
+
font-size: .82rem;
|
|
1045
|
+
font-weight: 700;
|
|
1046
|
+
color: var(--primary-text, #0f172a);
|
|
1047
|
+
padding: 4px 6px;
|
|
1048
|
+
border-radius: var(--radxs, 6px);
|
|
1049
|
+
font-family: var(--sans, inherit);
|
|
1050
|
+
transition: background .12s;
|
|
1051
|
+
"
|
|
1052
|
+
@click="view = 'year'"
|
|
1053
|
+
@mouseenter="(e: MouseEvent) => ((e.currentTarget as HTMLElement).style.background = 'var(--grey-1, #f5f5f8)')"
|
|
1054
|
+
@mouseleave="(e: MouseEvent) => ((e.currentTarget as HTMLElement).style.background = 'none')"
|
|
1055
|
+
>
|
|
1056
|
+
{{ cursor.getFullYear() }}
|
|
1057
|
+
</button>
|
|
1058
|
+
</template>
|
|
1059
|
+
|
|
1060
|
+
<button
|
|
1061
|
+
v-else-if="view === 'month'"
|
|
1062
|
+
type="button"
|
|
1063
|
+
style="
|
|
1064
|
+
background: none;
|
|
1065
|
+
border: none;
|
|
1066
|
+
cursor: pointer;
|
|
1067
|
+
font-size: .82rem;
|
|
1068
|
+
font-weight: 700;
|
|
1069
|
+
color: var(--primary-text, #0f172a);
|
|
1070
|
+
padding: 4px 8px;
|
|
1071
|
+
border-radius: var(--radxs, 6px);
|
|
1072
|
+
font-family: var(--sans, inherit);
|
|
1073
|
+
transition: background .12s;
|
|
1074
|
+
"
|
|
1075
|
+
@click="view = 'year'"
|
|
1076
|
+
@mouseenter="(e: MouseEvent) => ((e.currentTarget as HTMLElement).style.background = 'var(--grey-1, #f5f5f8)')"
|
|
1077
|
+
@mouseleave="(e: MouseEvent) => ((e.currentTarget as HTMLElement).style.background = 'none')"
|
|
1078
|
+
>
|
|
1079
|
+
{{ cursor.getFullYear() }}
|
|
1080
|
+
</button>
|
|
1081
|
+
|
|
1082
|
+
<span
|
|
1083
|
+
v-else-if="view === 'year'"
|
|
1084
|
+
style="
|
|
1085
|
+
font-size: .82rem;
|
|
1086
|
+
font-weight: 700;
|
|
1087
|
+
color: var(--primary-text, #0f172a);
|
|
1088
|
+
padding: 4px 8px;
|
|
1089
|
+
"
|
|
1090
|
+
>
|
|
1091
|
+
{{ Math.floor(cursor.getFullYear() / 12) * 12 }} – {{ Math.floor(cursor.getFullYear() / 12) * 12 + 11 }}
|
|
1092
|
+
</span>
|
|
1093
|
+
</div>
|
|
896
1094
|
|
|
897
1095
|
<button
|
|
898
1096
|
type="button"
|
|
@@ -1039,7 +1237,18 @@ const posMode = computed(() => {
|
|
|
1039
1237
|
const c = new Date(cursor);
|
|
1040
1238
|
c.setMonth(idx);
|
|
1041
1239
|
cursor = c;
|
|
1042
|
-
|
|
1240
|
+
if (pickerType === 'month') {
|
|
1241
|
+
if (typeof currentVal === 'string') {
|
|
1242
|
+
const ym = `${c.getFullYear()}-${pad(idx + 1)}`;
|
|
1243
|
+
emitValue(ym);
|
|
1244
|
+
} else {
|
|
1245
|
+
emitValue(c);
|
|
1246
|
+
}
|
|
1247
|
+
open = false;
|
|
1248
|
+
view = 'month';
|
|
1249
|
+
} else {
|
|
1250
|
+
view = 'day';
|
|
1251
|
+
}
|
|
1043
1252
|
}
|
|
1044
1253
|
"
|
|
1045
1254
|
>
|
|
@@ -1082,7 +1291,21 @@ const posMode = computed(() => {
|
|
|
1082
1291
|
const c = new Date(cursor);
|
|
1083
1292
|
c.setFullYear(yr);
|
|
1084
1293
|
cursor = c;
|
|
1085
|
-
|
|
1294
|
+
if (pickerType === 'year') {
|
|
1295
|
+
if (typeof currentVal === 'number') {
|
|
1296
|
+
emitValue(yr);
|
|
1297
|
+
} else if (typeof currentVal === 'string') {
|
|
1298
|
+
emitValue(`${yr}`);
|
|
1299
|
+
} else {
|
|
1300
|
+
emitValue(c);
|
|
1301
|
+
}
|
|
1302
|
+
open = false;
|
|
1303
|
+
view = 'year';
|
|
1304
|
+
} else if (pickerType === 'month') {
|
|
1305
|
+
view = 'month';
|
|
1306
|
+
} else {
|
|
1307
|
+
view = 'day';
|
|
1308
|
+
}
|
|
1086
1309
|
}
|
|
1087
1310
|
"
|
|
1088
1311
|
>
|