routie dev init since i didn't adhere to any proper guidance up until now

This commit is contained in:
2026-04-29 22:27:29 -06:00
commit e1dabb71e2
15301 changed files with 3562618 additions and 0 deletions
@@ -0,0 +1,26 @@
@layer vuetify-components {
.v-date-picker {
overflow: hidden;
width: 328px;
--v-date-picker-landscape-header-width: 170px;
}
.v-date-picker--show-week {
width: 368px;
}
.v-date-picker.v-picker--landscape:has(.v-picker__header-wrapper) {
width: calc(328px + var(--v-date-picker-landscape-header-width));
}
.v-date-picker.v-picker--landscape:has(.v-picker__header-wrapper) .v-picker__header-wrapper {
width: var(--v-date-picker-landscape-header-width);
}
.v-date-picker.v-picker--landscape:has(.v-picker__header-wrapper) .v-picker__header-wrapper .v-date-picker-header {
height: auto;
padding-inline: 24px;
}
.v-date-picker.v-picker--landscape:has(.v-picker__header-wrapper).v-picker--show-week {
width: calc(368px + var(--v-date-picker-landscape-header-width));
}
.v-date-picker > .v-picker__body {
flex-direction: column;
}
}
File diff suppressed because it is too large Load Diff
+384
View File
@@ -0,0 +1,384 @@
import { createElementVNode as _createElementVNode, createVNode as _createVNode, mergeProps as _mergeProps, Fragment as _Fragment } from "vue";
// Styles
import "./VDatePicker.css";
// Components
import { makeVDatePickerControlsProps, VDatePickerControls } from "./VDatePickerControls.js";
import { VDatePickerHeader } from "./VDatePickerHeader.js";
import { makeVDatePickerMonthProps, VDatePickerMonth } from "./VDatePickerMonth.js";
import { makeVDatePickerMonthsProps, VDatePickerMonths } from "./VDatePickerMonths.js";
import { makeVDatePickerYearsProps, VDatePickerYears } from "./VDatePickerYears.js";
import { VFadeTransition } from "../transitions/index.js";
import { VDefaultsProvider } from "../VDefaultsProvider/index.js";
import { makeVPickerProps, VPicker } from "../../labs/VPicker/VPicker.js"; // Composables
import { useCalendarRange } from "../../composables/calendar.js";
import { useDate } from "../../composables/date/index.js";
import { daysDiff } from "../../composables/date/date.js";
import { useLocale, useRtl } from "../../composables/locale.js";
import { useProxiedModel } from "../../composables/proxiedModel.js"; // Utilities
import { computed, shallowRef, toRef, watch } from 'vue';
import { convertToUnit, genericComponent, omit, propsFactory, useRender, wrapInArray } from "../../util/index.js"; // Types
// Types
export const makeVDatePickerProps = propsFactory({
// TODO: implement in v3.5
// calendarIcon: {
// type: String,
// default: '$calendar',
// },
// keyboardIcon: {
// type: String,
// default: '$edit',
// },
// inputMode: {
// type: String as PropType<'calendar' | 'keyboard'>,
// default: 'calendar',
// },
// inputText: {
// type: String,
// default: '$vuetify.datePicker.input.placeholder',
// },
// inputPlaceholder: {
// type: String,
// default: 'dd/mm/yyyy',
// },
header: {
type: String,
default: '$vuetify.datePicker.header'
},
headerColor: String,
headerDateFormat: {
type: String,
default: 'normalDateWithWeekday'
},
landscapeHeaderWidth: [Number, String],
...omit(makeVDatePickerControlsProps(), ['active', 'monthText', 'yearText']),
...makeVDatePickerMonthProps({
weeksInMonth: 'static'
}),
...omit(makeVDatePickerMonthsProps(), ['modelValue']),
...omit(makeVDatePickerYearsProps(), ['modelValue']),
...makeVPickerProps({
title: '$vuetify.datePicker.title'
}),
modelValue: null
}, 'VDatePicker');
export const VDatePicker = genericComponent()({
name: 'VDatePicker',
props: makeVDatePickerProps(),
emits: {
'update:modelValue': date => true,
'update:month': date => true,
'update:year': date => true,
// 'update:inputMode': (date: any) => true,
'update:viewMode': date => true
},
setup(props, {
emit,
slots
}) {
const adapter = useDate();
const {
t
} = useLocale();
const {
rtlClasses
} = useRtl();
const model = useProxiedModel(props, 'modelValue', undefined, v => wrapInArray(v).map(i => adapter.date(i)), v => props.multiple ? v : v[0]);
const viewMode = useProxiedModel(props, 'viewMode');
// const inputMode = useProxiedModel(props, 'inputMode')
const {
minDate,
maxDate,
clampDate
} = useCalendarRange(props);
const internal = computed(() => {
const today = adapter.date();
const value = model.value?.[0] ? adapter.date(model.value[0]) : clampDate(today);
return value && adapter.isValid(value) ? value : today;
});
const headerColor = toRef(() => props.headerColor ?? props.color);
const _month = useProxiedModel(props, 'month');
const month = computed({
get: () => Number(_month.value ?? adapter.getMonth(adapter.startOfMonth(internal.value))),
set: v => _month.value = v
});
const _year = useProxiedModel(props, 'year');
const year = computed({
get: () => Number(_year.value ?? adapter.getYear(adapter.startOfYear(adapter.setMonth(internal.value, month.value)))),
set: v => _year.value = v
});
const isReversing = shallowRef(false);
const header = computed(() => {
if (props.multiple === 'range' && model.value.length === 2) {
const [startDate, endDate] = model.value;
const daysBetween = adapter.getDiff(endDate, startDate, 'days') + 1;
return t('$vuetify.datePicker.itemsSelected', daysBetween);
}
if (props.multiple && model.value.length > 1) {
return t('$vuetify.datePicker.itemsSelected', model.value.length);
}
const formattedDate = model.value[0] && adapter.isValid(model.value[0]) ? adapter.format(adapter.date(model.value[0]), props.headerDateFormat) : t(props.header);
return props.landscape && formattedDate.split(' ').length === 3 ? formattedDate.replace(' ', '\n') : formattedDate;
});
const monthStart = toRef(() => {
let date = adapter.date();
date = adapter.setDate(date, 1);
date = adapter.setMonth(date, month.value);
date = adapter.setYear(date, year.value); // year is not always ISO
return date;
});
const monthYearText = toRef(() => adapter.format(monthStart.value, 'monthAndYear'));
const monthText = toRef(() => adapter.format(monthStart.value, 'monthShort'));
const yearText = toRef(() => adapter.format(monthStart.value, 'year'));
// const headerIcon = toRef(() => props.inputMode === 'calendar' ? props.keyboardIcon : props.calendarIcon)
const headerTransition = toRef(() => `date-picker-header${isReversing.value ? '-reverse' : ''}-transition`);
const disabled = computed(() => {
if (props.disabled) return true;
const targets = [];
if (viewMode.value !== 'month') {
targets.push(...['prev-month', 'next-month', 'prev-year', 'next-year']);
} else {
let _date = adapter.date();
_date = adapter.startOfMonth(_date);
_date = adapter.setMonth(_date, month.value);
_date = adapter.setYear(_date, year.value);
if (minDate.value) {
const prevMonthEnd = adapter.addDays(adapter.startOfMonth(_date), -1);
const prevYearEnd = adapter.addDays(adapter.startOfYear(_date), -1);
adapter.isAfter(minDate.value, prevMonthEnd) && targets.push('prev-month');
adapter.isAfter(minDate.value, prevYearEnd) && targets.push('prev-year');
}
if (maxDate.value) {
const nextMonthStart = adapter.addDays(adapter.endOfMonth(_date), 1);
const nextYearStart = adapter.addDays(adapter.endOfYear(_date), 1);
adapter.isAfter(nextMonthStart, maxDate.value) && targets.push('next-month');
adapter.isAfter(nextYearStart, maxDate.value) && targets.push('next-year');
}
}
return targets;
});
const allowedYears = computed(() => {
return props.allowedYears || isYearAllowed;
});
const allowedMonths = computed(() => {
return props.allowedMonths || isMonthAllowed;
});
function isAllowedInRange(start, end) {
const allowedDates = props.allowedDates;
if (typeof allowedDates !== 'function') return true;
const days = 1 + daysDiff(adapter, start, end);
for (let i = 0; i < days; i++) {
if (allowedDates(adapter.addDays(start, i))) return true;
}
return false;
}
function isYearAllowed(year) {
if (typeof props.allowedDates === 'function') {
const startOfYear = adapter.parseISO(`${year}-01-01`);
return isAllowedInRange(startOfYear, adapter.endOfYear(startOfYear));
}
if (Array.isArray(props.allowedDates) && props.allowedDates.length) {
for (const date of props.allowedDates) {
if (adapter.getYear(adapter.date(date)) === year) return true;
}
return false;
}
return true;
}
function isMonthAllowed(month) {
if (typeof props.allowedDates === 'function') {
const monthTwoDigits = String(month + 1).padStart(2, '0');
const startOfMonth = adapter.parseISO(`${year.value}-${monthTwoDigits}-01`);
return isAllowedInRange(startOfMonth, adapter.endOfMonth(startOfMonth));
}
if (Array.isArray(props.allowedDates) && props.allowedDates.length) {
for (const date of props.allowedDates) {
if (adapter.getYear(adapter.date(date)) === year.value && adapter.getMonth(adapter.date(date)) === month) return true;
}
return false;
}
return true;
}
// function onClickAppend () {
// inputMode.value = inputMode.value === 'calendar' ? 'keyboard' : 'calendar'
// }
function onClickNextMonth() {
if (month.value < 11) {
month.value++;
} else {
year.value++;
month.value = 0;
onUpdateYear();
}
onUpdateMonth();
}
function onClickPrevMonth() {
if (month.value > 0) {
month.value--;
} else {
year.value--;
month.value = 11;
onUpdateYear();
}
onUpdateMonth();
}
function onClickNextYear() {
year.value++;
if (maxDate.value) {
const monthTwoDigits = String(month.value + 1).padStart(2, '0');
const monthStart = adapter.parseISO(`${year.value}-${monthTwoDigits}-01`);
if (adapter.isAfter(monthStart, maxDate.value)) {
month.value = adapter.getMonth(maxDate.value);
}
}
onUpdateYear();
}
function onClickPrevYear() {
year.value--;
if (minDate.value) {
const monthTwoDigits = String(month.value + 1).padStart(2, '0');
const monthStart = adapter.endOfMonth(adapter.parseISO(`${year.value}-${monthTwoDigits}-01`));
if (adapter.isAfter(minDate.value, monthStart)) {
month.value = adapter.getMonth(minDate.value);
}
}
onUpdateYear();
}
function onClickDate() {
viewMode.value = 'month';
}
function onClickMonth() {
viewMode.value = viewMode.value === 'months' ? 'month' : 'months';
}
function onClickYear() {
viewMode.value = viewMode.value === 'year' ? 'month' : 'year';
}
function onUpdateMonth() {
if (viewMode.value === 'months') onClickMonth();
}
function onUpdateYear() {
if (viewMode.value === 'year') onClickYear();
}
watch(model, (val, oldVal) => {
const arrBefore = wrapInArray(oldVal);
const arrAfter = wrapInArray(val);
if (!arrAfter.length) return;
const before = adapter.date(arrBefore[arrBefore.length - 1]);
const after = adapter.date(arrAfter[arrAfter.length - 1]);
if (adapter.isSameDay(before, after)) return;
const newMonth = adapter.getMonth(after);
const newYear = adapter.getYear(after);
if (newMonth !== month.value) {
month.value = newMonth;
onUpdateMonth();
}
if (newYear !== year.value) {
year.value = newYear;
onUpdateYear();
}
isReversing.value = adapter.isBefore(before, after);
});
useRender(() => {
const pickerProps = VPicker.filterProps(props);
const datePickerControlsProps = omit(VDatePickerControls.filterProps(props), ['viewMode']);
const datePickerHeaderProps = VDatePickerHeader.filterProps(props);
const datePickerMonthProps = VDatePickerMonth.filterProps(props);
const datePickerMonthsProps = omit(VDatePickerMonths.filterProps(props), ['modelValue']);
const datePickerYearsProps = omit(VDatePickerYears.filterProps(props), ['modelValue']);
const headerProps = {
color: headerColor.value,
header: header.value,
transition: headerTransition.value
};
return _createVNode(VPicker, _mergeProps(pickerProps, {
"color": headerColor.value,
"class": ['v-date-picker', `v-date-picker--${viewMode.value}`, {
'v-date-picker--show-week': props.showWeek
}, rtlClasses.value, props.class],
"style": [{
'--v-date-picker-landscape-header-width': convertToUnit(props.landscapeHeaderWidth)
}, props.style]
}), {
title: () => slots.title?.() ?? _createElementVNode("div", {
"class": "v-date-picker__title"
}, [t(props.title)]),
header: () => slots.header ? _createVNode(VDefaultsProvider, {
"defaults": {
VDatePickerHeader: {
...headerProps
}
}
}, {
default: () => [slots.header?.(headerProps)]
}) : _createVNode(VDatePickerHeader, _mergeProps({
"key": "header"
}, datePickerHeaderProps, headerProps, {
"onClick": viewMode.value !== 'month' ? onClickDate : undefined
}), {
prepend: slots.prepend,
append: slots.append
}),
default: () => _createElementVNode(_Fragment, null, [_createVNode(VDatePickerControls, _mergeProps(datePickerControlsProps, {
"disabled": disabled.value,
"viewMode": viewMode.value,
"text": monthYearText.value,
"monthText": monthText.value,
"yearText": yearText.value,
"onClick:next": onClickNextMonth,
"onClick:prev": onClickPrevMonth,
"onClick:nextYear": onClickNextYear,
"onClick:prevYear": onClickPrevYear,
"onClick:month": onClickMonth,
"onClick:year": onClickYear
}), {
default: slots.controls
}), _createVNode(VFadeTransition, {
"hideOnLeave": true
}, {
default: () => [viewMode.value === 'months' ? _createVNode(VDatePickerMonths, _mergeProps({
"key": "date-picker-months"
}, datePickerMonthsProps, {
"modelValue": month.value,
"onUpdate:modelValue": [$event => month.value = $event, onUpdateMonth],
"min": minDate.value,
"max": maxDate.value,
"year": year.value,
"allowedMonths": allowedMonths.value
}), {
month: slots.month
}) : viewMode.value === 'year' ? _createVNode(VDatePickerYears, _mergeProps({
"key": "date-picker-years"
}, datePickerYearsProps, {
"modelValue": year.value,
"onUpdate:modelValue": [$event => year.value = $event, onUpdateYear],
"min": minDate.value,
"max": maxDate.value,
"allowedYears": allowedYears.value
}), {
year: slots.year
}) : _createVNode(VDatePickerMonth, _mergeProps({
"key": "date-picker-month"
}, datePickerMonthProps, {
"modelValue": model.value,
"onUpdate:modelValue": $event => model.value = $event,
"month": month.value,
"onUpdate:month": [$event => month.value = $event, onUpdateMonth],
"year": year.value,
"onUpdate:year": [$event => year.value = $event, onUpdateYear],
"min": minDate.value,
"max": maxDate.value
}), {
day: slots.day
})]
})]),
actions: slots.actions
});
});
return {};
}
});
//# sourceMappingURL=VDatePicker.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,27 @@
@use '../../styles/tools'
@use './variables' as *
@include tools.layer('components')
.v-date-picker
overflow: hidden
width: $date-picker-width
--v-date-picker-landscape-header-width: #{$date-picker-landscape-header-width}
&--show-week
width: $date-picker-show-week-width
&.v-picker--landscape:has(.v-picker__header-wrapper)
width: calc(#{$date-picker-width} + var(--v-date-picker-landscape-header-width))
.v-picker__header-wrapper
width: var(--v-date-picker-landscape-header-width)
.v-date-picker-header
height: auto
padding-inline: 24px
&.v-picker--show-week
width: calc(#{$date-picker-show-week-width} + var(--v-date-picker-landscape-header-width))
> .v-picker__body
flex-direction: column
@@ -0,0 +1,53 @@
@layer vuetify-components {
.v-date-picker-controls {
display: flex;
align-items: center;
justify-content: space-between;
font-size: 0.875rem;
height: var(--v-date-picker-controls-height, 56px);
padding: 4px 12px;
}
.v-date-picker-controls .v-btn {
text-transform: none;
font-weight: 400;
line-height: initial;
letter-spacing: initial;
}
.v-date-picker-controls .v-btn > .v-btn__append > .v-icon {
transition-property: transform;
transition-duration: 0.28s;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
}
.v-date-picker--months .v-date-picker-controls .v-date-picker-controls__only-month-btn > .v-btn__append > .v-icon {
transform: rotate(180deg);
}
.v-date-picker--year .v-date-picker-controls .v-date-picker-controls__mode-btn {
transform: rotate(180deg);
}
.v-date-picker--year .v-date-picker-controls .v-date-picker-controls__year-btn > .v-btn__append > .v-icon,
.v-date-picker--year .v-date-picker-controls .v-date-picker-controls__only-year-btn > .v-btn__append > .v-icon {
transform: rotate(180deg);
}
.v-date-picker-controls__date {
margin-inline-end: 4px;
}
.v-date-picker-controls__month, .v-date-picker-controls__year {
display: flex;
}
.v-locale--is-rtl.v-date-picker-controls__month, .v-locale--is-rtl.v-date-picker-controls__year, .v-locale--is-rtl .v-date-picker-controls__month, .v-locale--is-rtl .v-date-picker-controls__year {
flex-direction: row-reverse;
}
.v-date-picker-controls .v-date-picker-controls__month-btn, .v-date-picker-controls .v-date-picker-controls__year-btn {
padding: 0 12px;
}
.v-date-picker-controls .v-date-picker-controls__only-month-btn, .v-date-picker-controls .v-date-picker-controls__only-year-btn {
padding-inline: 12px 8px;
min-width: 40px;
}
.v-date-picker-controls .v-date-picker-controls__only-month-btn > .v-btn__append, .v-date-picker-controls .v-date-picker-controls__only-year-btn > .v-btn__append {
margin-inline: 4px -4px;
}
.v-date-picker__title {
display: inline-block;
}
}
@@ -0,0 +1,350 @@
import { IconValue } from '../../composables/icons.js';
import type { PropType } from 'vue';
type ControlVariant = 'docked' | 'modal';
export type VDatePickerControlsDefaultSlotProps = {
viewMode: 'month' | 'months' | 'year';
monthYearText: string;
monthText: string;
yearText: string;
disabled: string[];
openMonths: () => void;
openYears: () => void;
prevMonth: () => void;
nextMonth: () => void;
prevYear: () => void;
nextYear: () => void;
};
export declare const makeVDatePickerControlsProps: <Defaults extends {
active?: unknown;
controlHeight?: unknown;
controlVariant?: unknown;
noMonthPicker?: unknown;
disabled?: unknown;
nextIcon?: unknown;
prevIcon?: unknown;
modeIcon?: unknown;
text?: unknown;
monthText?: unknown;
yearText?: unknown;
viewMode?: unknown;
} = {}>(defaults?: Defaults | undefined) => {
active: unknown extends Defaults["active"] ? {
type: PropType<string | string[]>;
default: undefined;
} : Omit<{
type: PropType<string | string[]>;
default: undefined;
}, "default" | "type"> & {
type: PropType<unknown extends Defaults["active"] ? string | string[] : string | string[] | Defaults["active"]>;
default: unknown extends Defaults["active"] ? string | string[] : Defaults["active"] | NonNullable<string | string[]>;
};
controlHeight: unknown extends Defaults["controlHeight"] ? (NumberConstructor | StringConstructor)[] : {
type: PropType<unknown extends Defaults["controlHeight"] ? string | number : string | number | Defaults["controlHeight"]>;
default: unknown extends Defaults["controlHeight"] ? string | number : Defaults["controlHeight"] | NonNullable<string | number>;
};
controlVariant: unknown extends Defaults["controlVariant"] ? {
type: PropType<ControlVariant>;
default: string;
} : Omit<{
type: PropType<ControlVariant>;
default: string;
}, "default" | "type"> & {
type: PropType<unknown extends Defaults["controlVariant"] ? ControlVariant : Defaults["controlVariant"] | ControlVariant>;
default: unknown extends Defaults["controlVariant"] ? ControlVariant : Defaults["controlVariant"] | NonNullable<ControlVariant>;
};
noMonthPicker: unknown extends Defaults["noMonthPicker"] ? BooleanConstructor : {
type: PropType<unknown extends Defaults["noMonthPicker"] ? boolean : boolean | Defaults["noMonthPicker"]>;
default: unknown extends Defaults["noMonthPicker"] ? boolean : boolean | Defaults["noMonthPicker"];
};
disabled: unknown extends Defaults["disabled"] ? {
type: PropType<boolean | string | string[] | null>;
default: null;
} : Omit<{
type: PropType<boolean | string | string[] | null>;
default: null;
}, "default" | "type"> & {
type: PropType<unknown extends Defaults["disabled"] ? string | boolean | string[] | null : string | boolean | string[] | Defaults["disabled"] | null>;
default: unknown extends Defaults["disabled"] ? string | boolean | string[] | null : Defaults["disabled"] | NonNullable<string | boolean | string[] | null>;
};
nextIcon: unknown extends Defaults["nextIcon"] ? {
type: PropType<IconValue>;
default: string;
} : Omit<{
type: PropType<IconValue>;
default: string;
}, "default" | "type"> & {
type: PropType<unknown extends Defaults["nextIcon"] ? IconValue : Defaults["nextIcon"] | IconValue>;
default: unknown extends Defaults["nextIcon"] ? IconValue : Defaults["nextIcon"] | NonNullable<IconValue>;
};
prevIcon: unknown extends Defaults["prevIcon"] ? {
type: PropType<IconValue>;
default: string;
} : Omit<{
type: PropType<IconValue>;
default: string;
}, "default" | "type"> & {
type: PropType<unknown extends Defaults["prevIcon"] ? IconValue : Defaults["prevIcon"] | IconValue>;
default: unknown extends Defaults["prevIcon"] ? IconValue : Defaults["prevIcon"] | NonNullable<IconValue>;
};
modeIcon: unknown extends Defaults["modeIcon"] ? {
type: PropType<IconValue>;
default: string;
} : Omit<{
type: PropType<IconValue>;
default: string;
}, "default" | "type"> & {
type: PropType<unknown extends Defaults["modeIcon"] ? IconValue : Defaults["modeIcon"] | IconValue>;
default: unknown extends Defaults["modeIcon"] ? IconValue : Defaults["modeIcon"] | NonNullable<IconValue>;
};
text: unknown extends Defaults["text"] ? StringConstructor : {
type: PropType<unknown extends Defaults["text"] ? string : string | Defaults["text"]>;
default: unknown extends Defaults["text"] ? string : string | Defaults["text"];
};
monthText: unknown extends Defaults["monthText"] ? StringConstructor : {
type: PropType<unknown extends Defaults["monthText"] ? string : string | Defaults["monthText"]>;
default: unknown extends Defaults["monthText"] ? string : string | Defaults["monthText"];
};
yearText: unknown extends Defaults["yearText"] ? StringConstructor : {
type: PropType<unknown extends Defaults["yearText"] ? string : string | Defaults["yearText"]>;
default: unknown extends Defaults["yearText"] ? string : string | Defaults["yearText"];
};
viewMode: unknown extends Defaults["viewMode"] ? {
type: PropType<'month' | 'months' | 'year'>;
default: string;
} : Omit<{
type: PropType<'month' | 'months' | 'year'>;
default: string;
}, "default" | "type"> & {
type: PropType<unknown extends Defaults["viewMode"] ? "month" | "months" | "year" : "month" | "months" | "year" | Defaults["viewMode"]>;
default: unknown extends Defaults["viewMode"] ? "month" | "months" | "year" : Defaults["viewMode"] | NonNullable<"month" | "months" | "year">;
};
};
export declare const VDatePickerControls: {
new (...args: any[]): import("vue").CreateComponentPublicInstanceWithMixins<{
controlVariant: ControlVariant;
noMonthPicker: boolean;
disabled: string | boolean | string[] | null;
nextIcon: IconValue;
prevIcon: IconValue;
modeIcon: IconValue;
viewMode: "month" | "months" | "year";
} & {
active?: string | string[] | undefined;
controlHeight?: string | number | undefined;
text?: string | undefined;
monthText?: string | undefined;
yearText?: string | undefined;
} & {
$children?: {
default?: ((arg: VDatePickerControlsDefaultSlotProps) => import("vue").VNodeChild) | undefined;
} | {
$stable?: boolean;
} | ((arg: VDatePickerControlsDefaultSlotProps) => import("vue").VNodeChild) | import("vue").VNodeChild;
'v-slots'?: {
default?: false | ((arg: VDatePickerControlsDefaultSlotProps) => import("vue").VNodeChild) | undefined;
} | undefined;
} & {
"v-slot:default"?: false | ((arg: VDatePickerControlsDefaultSlotProps) => import("vue").VNodeChild) | undefined;
} & {
"onClick:month"?: (() => any) | undefined;
"onClick:next"?: (() => any) | undefined;
"onClick:next-year"?: (() => any) | undefined;
"onClick:prev"?: (() => any) | undefined;
"onClick:prev-year"?: (() => any) | undefined;
"onClick:year"?: (() => any) | undefined;
}, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
'click:year': () => true;
'click:month': () => true;
'click:prev': () => true;
'click:next': () => true;
'click:prev-year': () => true;
'click:next-year': () => true;
}, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, {
active: string | string[];
controlVariant: ControlVariant;
noMonthPicker: boolean;
disabled: string | boolean | string[] | null;
nextIcon: IconValue;
prevIcon: IconValue;
modeIcon: IconValue;
viewMode: "month" | "months" | "year";
}, true, {}, import("vue").SlotsType<Partial<{
default: (arg: VDatePickerControlsDefaultSlotProps) => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>[];
}>>, import("vue").GlobalComponents, import("vue").GlobalDirectives, string, {}, any, import("vue").ComponentProvideOptions, {
P: {};
B: {};
D: {};
C: {};
M: {};
Defaults: {};
}, {
controlVariant: ControlVariant;
noMonthPicker: boolean;
disabled: string | boolean | string[] | null;
nextIcon: IconValue;
prevIcon: IconValue;
modeIcon: IconValue;
viewMode: "month" | "months" | "year";
} & {
active?: string | string[] | undefined;
controlHeight?: string | number | undefined;
text?: string | undefined;
monthText?: string | undefined;
yearText?: string | undefined;
} & {
$children?: {
default?: ((arg: VDatePickerControlsDefaultSlotProps) => import("vue").VNodeChild) | undefined;
} | {
$stable?: boolean;
} | ((arg: VDatePickerControlsDefaultSlotProps) => import("vue").VNodeChild) | import("vue").VNodeChild;
'v-slots'?: {
default?: false | ((arg: VDatePickerControlsDefaultSlotProps) => import("vue").VNodeChild) | undefined;
} | undefined;
} & {
"v-slot:default"?: false | ((arg: VDatePickerControlsDefaultSlotProps) => import("vue").VNodeChild) | undefined;
} & {
"onClick:month"?: (() => any) | undefined;
"onClick:next"?: (() => any) | undefined;
"onClick:next-year"?: (() => any) | undefined;
"onClick:prev"?: (() => any) | undefined;
"onClick:prev-year"?: (() => any) | undefined;
"onClick:year"?: (() => any) | undefined;
}, {}, {}, {}, {}, {
active: string | string[];
controlVariant: ControlVariant;
noMonthPicker: boolean;
disabled: string | boolean | string[] | null;
nextIcon: IconValue;
prevIcon: IconValue;
modeIcon: IconValue;
viewMode: "month" | "months" | "year";
}>;
__isFragment?: never;
__isTeleport?: never;
__isSuspense?: never;
} & import("vue").ComponentOptionsBase<{
controlVariant: ControlVariant;
noMonthPicker: boolean;
disabled: string | boolean | string[] | null;
nextIcon: IconValue;
prevIcon: IconValue;
modeIcon: IconValue;
viewMode: "month" | "months" | "year";
} & {
active?: string | string[] | undefined;
controlHeight?: string | number | undefined;
text?: string | undefined;
monthText?: string | undefined;
yearText?: string | undefined;
} & {
$children?: {
default?: ((arg: VDatePickerControlsDefaultSlotProps) => import("vue").VNodeChild) | undefined;
} | {
$stable?: boolean;
} | ((arg: VDatePickerControlsDefaultSlotProps) => import("vue").VNodeChild) | import("vue").VNodeChild;
'v-slots'?: {
default?: false | ((arg: VDatePickerControlsDefaultSlotProps) => import("vue").VNodeChild) | undefined;
} | undefined;
} & {
"v-slot:default"?: false | ((arg: VDatePickerControlsDefaultSlotProps) => import("vue").VNodeChild) | undefined;
} & {
"onClick:month"?: (() => any) | undefined;
"onClick:next"?: (() => any) | undefined;
"onClick:next-year"?: (() => any) | undefined;
"onClick:prev"?: (() => any) | undefined;
"onClick:prev-year"?: (() => any) | undefined;
"onClick:year"?: (() => any) | undefined;
}, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
'click:year': () => true;
'click:month': () => true;
'click:prev': () => true;
'click:next': () => true;
'click:prev-year': () => true;
'click:next-year': () => true;
}, string, {
active: string | string[];
controlVariant: ControlVariant;
noMonthPicker: boolean;
disabled: string | boolean | string[] | null;
nextIcon: IconValue;
prevIcon: IconValue;
modeIcon: IconValue;
viewMode: "month" | "months" | "year";
}, {}, string, import("vue").SlotsType<Partial<{
default: (arg: VDatePickerControlsDefaultSlotProps) => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>[];
}>>, import("vue").GlobalComponents, import("vue").GlobalDirectives, string, import("vue").ComponentProvideOptions> & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps & import("../../util/index.js").FilterPropsOptions<{
active: {
type: PropType<string | string[]>;
default: undefined;
};
controlHeight: (NumberConstructor | StringConstructor)[];
controlVariant: {
type: PropType<ControlVariant>;
default: string;
};
noMonthPicker: BooleanConstructor;
disabled: {
type: PropType<boolean | string | string[] | null>;
default: null;
};
nextIcon: {
type: PropType<IconValue>;
default: string;
};
prevIcon: {
type: PropType<IconValue>;
default: string;
};
modeIcon: {
type: PropType<IconValue>;
default: string;
};
text: StringConstructor;
monthText: StringConstructor;
yearText: StringConstructor;
viewMode: {
type: PropType<'month' | 'months' | 'year'>;
default: string;
};
}, import("vue").ExtractPropTypes<{
active: {
type: PropType<string | string[]>;
default: undefined;
};
controlHeight: (NumberConstructor | StringConstructor)[];
controlVariant: {
type: PropType<ControlVariant>;
default: string;
};
noMonthPicker: BooleanConstructor;
disabled: {
type: PropType<boolean | string | string[] | null>;
default: null;
};
nextIcon: {
type: PropType<IconValue>;
default: string;
};
prevIcon: {
type: PropType<IconValue>;
default: string;
};
modeIcon: {
type: PropType<IconValue>;
default: string;
};
text: StringConstructor;
monthText: StringConstructor;
yearText: StringConstructor;
viewMode: {
type: PropType<'month' | 'months' | 'year'>;
default: string;
};
}>>;
export type VDatePickerControls = InstanceType<typeof VDatePickerControls>;
@@ -0,0 +1,222 @@
import { createVNode as _createVNode, Fragment as _Fragment, createElementVNode as _createElementVNode, normalizeClass as _normalizeClass } from "vue";
// Styles
import "./VDatePickerControls.css";
// Components
import { VBtn } from "../VBtn/index.js";
import { VDefaultsProvider } from "../VDefaultsProvider/index.js";
import { VSpacer } from "../VGrid/index.js"; // Composables
import { IconValue } from "../../composables/icons.js";
import { useLocale } from "../../composables/locale.js"; // Utilities
import { computed } from 'vue';
import { convertToUnit, genericComponent, propsFactory, useRender } from "../../util/index.js"; // Types
export const makeVDatePickerControlsProps = propsFactory({
active: {
type: [String, Array],
default: undefined
},
controlHeight: [Number, String],
controlVariant: {
type: String,
default: 'docked'
},
noMonthPicker: Boolean,
disabled: {
type: [Boolean, String, Array],
default: null
},
nextIcon: {
type: IconValue,
default: '$next'
},
prevIcon: {
type: IconValue,
default: '$prev'
},
modeIcon: {
type: IconValue,
default: '$subgroup'
},
text: String,
monthText: String,
yearText: String,
viewMode: {
type: String,
default: 'month'
}
}, 'VDatePickerControls');
export const VDatePickerControls = genericComponent()({
name: 'VDatePickerControls',
props: makeVDatePickerControlsProps(),
emits: {
'click:year': () => true,
'click:month': () => true,
'click:prev': () => true,
'click:next': () => true,
'click:prev-year': () => true,
'click:next-year': () => true
},
setup(props, {
emit,
slots
}) {
const {
t
} = useLocale();
const disableMonth = computed(() => {
return Array.isArray(props.disabled) ? props.disabled.includes('text') : !!props.disabled;
});
const disableYear = computed(() => {
return Array.isArray(props.disabled) ? props.disabled.includes('mode') : !!props.disabled;
});
const disablePrevMonth = computed(() => {
return Array.isArray(props.disabled) ? props.disabled.includes('prev-month') : !!props.disabled;
});
const disableNextMonth = computed(() => {
return Array.isArray(props.disabled) ? props.disabled.includes('next-month') : !!props.disabled;
});
const disablePrevYear = computed(() => {
return Array.isArray(props.disabled) ? props.disabled.includes('prev-year') : !!props.disabled;
});
const disableNextYear = computed(() => {
return Array.isArray(props.disabled) ? props.disabled.includes('next-year') : !!props.disabled;
});
function onClickPrevMonth() {
emit('click:prev');
}
function onClickNextMonth() {
emit('click:next');
}
function onClickPrevYear() {
emit('click:prev-year');
}
function onClickNextYear() {
emit('click:next-year');
}
function onClickYear() {
emit('click:year');
}
function onClickMonth() {
emit('click:month');
}
useRender(() => {
const innerDefaults = {
VBtn: {
density: 'comfortable',
variant: 'text'
}
};
const prevMonth = _createVNode(VBtn, {
"data-testid": "prev-month",
"disabled": disablePrevMonth.value,
"icon": props.prevIcon,
"aria-label": t('$vuetify.datePicker.ariaLabel.previousMonth'),
"onClick": onClickPrevMonth
}, null);
const nextMonth = _createVNode(VBtn, {
"data-testid": "next-month",
"disabled": disableNextMonth.value,
"icon": props.nextIcon,
"aria-label": t('$vuetify.datePicker.ariaLabel.nextMonth'),
"onClick": onClickNextMonth
}, null);
const prevYear = _createVNode(VBtn, {
"data-testid": "prev-year",
"disabled": disablePrevYear.value,
"icon": props.prevIcon,
"aria-label": t('$vuetify.datePicker.ariaLabel.previousYear'),
"onClick": onClickPrevYear
}, null);
const nextYear = _createVNode(VBtn, {
"data-testid": "next-year",
"disabled": disableNextYear.value,
"icon": props.nextIcon,
"aria-label": t('$vuetify.datePicker.ariaLabel.nextYear'),
"onClick": onClickNextYear
}, null);
const onlyMonthBtn = _createVNode(VBtn, {
"class": "v-date-picker-controls__only-month-btn",
"data-testid": "month-btn",
"density": "default",
"disabled": disableMonth.value,
"text": props.monthText,
"appendIcon": props.modeIcon,
"rounded": true,
"aria-label": t('$vuetify.datePicker.ariaLabel.selectMonth'),
"onClick": onClickMonth
}, null);
const onlyYearBtn = _createVNode(VBtn, {
"class": "v-date-picker-controls__only-year-btn",
"data-testid": "year-btn",
"density": "default",
"disabled": disableYear.value,
"text": props.yearText,
"appendIcon": props.modeIcon,
"rounded": true,
"aria-label": t('$vuetify.datePicker.ariaLabel.selectYear'),
"onClick": onClickYear
}, null);
const monthYearBtn = _createVNode(VBtn, {
"class": "v-date-picker-controls__year-btn",
"data-testid": "year-btn",
"density": "default",
"disabled": disableYear.value,
"text": props.text,
"appendIcon": props.modeIcon,
"rounded": true,
"aria-label": t('$vuetify.datePicker.ariaLabel.selectYear'),
"onClick": onClickYear
}, null);
const monthYearSplit = _createElementVNode(_Fragment, null, [_createVNode(VBtn, {
"class": "v-date-picker-controls__month-btn",
"data-testid": "month-btn",
"height": "36",
"disabled": disableMonth.value,
"text": props.text,
"rounded": true,
"aria-label": t('$vuetify.datePicker.ariaLabel.selectMonth'),
"onClick": onClickMonth
}, null), _createVNode(VBtn, {
"class": "v-date-picker-controls__mode-btn",
"data-testid": "year-btn",
"disabled": disableYear.value,
"icon": props.modeIcon,
"aria-label": t('$vuetify.datePicker.ariaLabel.selectYear'),
"onClick": onClickYear
}, null)]);
const slotProps = {
viewMode: props.viewMode,
disabled: Array.isArray(props.disabled) ? props.disabled : [],
monthYearText: props.text ?? '',
monthText: props.monthText ?? '',
yearText: props.yearText ?? '',
openMonths: onClickMonth,
openYears: onClickYear,
prevMonth: onClickPrevMonth,
nextMonth: onClickNextMonth,
prevYear: onClickPrevYear,
nextYear: onClickNextYear
};
const modalControls = _createElementVNode(_Fragment, null, [props.noMonthPicker ? monthYearBtn : monthYearSplit, _createVNode(VSpacer, null, null), _createElementVNode("div", {
"class": "v-date-picker-controls__month"
}, [prevMonth, nextMonth])]);
const dockedControls = _createElementVNode(_Fragment, null, [_createElementVNode("div", {
"class": "v-date-picker-controls__month"
}, [prevMonth, onlyMonthBtn, nextMonth]), _createVNode(VSpacer, null, null), _createElementVNode("div", {
"class": "v-date-picker-controls__year"
}, [prevYear, onlyYearBtn, nextYear])]);
return _createVNode(VDefaultsProvider, {
"defaults": innerDefaults
}, {
default: () => [_createElementVNode("div", {
"class": _normalizeClass(['v-date-picker-controls', `v-date-picker-controls--variant-${props.controlVariant}`]),
"style": {
'--v-date-picker-controls-height': convertToUnit(props.controlHeight)
}
}, [slots.default?.(slotProps) ?? _createElementVNode(_Fragment, null, [props.controlVariant === 'modal' && modalControls, props.controlVariant === 'docked' && dockedControls])])]
});
});
return {};
}
});
//# sourceMappingURL=VDatePickerControls.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,64 @@
@use '../../styles/settings'
@use '../../styles/tools'
@use './variables' as *
@include tools.layer('components')
.v-date-picker-controls
display: flex
align-items: center
justify-content: space-between
font-size: .875rem
height: $date-picker-controls-height
padding: $date-picker-controls-padding
.v-btn
text-transform: none
font-weight: 400
line-height: initial
letter-spacing: initial
> .v-btn__append > .v-icon
// matching VBtn for icon rotation
transition-property: transform
transition-duration: 0.28s
transition-timing-function: settings.$standard-easing
.v-date-picker--months &
.v-date-picker-controls__only-month-btn
> .v-btn__append > .v-icon
transform: rotate(180deg)
.v-date-picker--year &
.v-date-picker-controls__mode-btn
transform: rotate(180deg)
.v-date-picker-controls__year-btn,
.v-date-picker-controls__only-year-btn
> .v-btn__append > .v-icon
transform: rotate(180deg)
&__date
margin-inline-end: 4px
&__month,
&__year
display: flex
@include tools.rtl()
flex-direction: row-reverse
& &__month-btn,
& &__year-btn
padding: 0 12px
& &__only-month-btn,
& &__only-year-btn
padding-inline: $date-picker-controls-docked-toggle-btn-padding
// just lower than default
min-width: 40px
> .v-btn__append
margin-inline: $date-picker-controls-docked-toggle-append-margin-inline
.v-date-picker__title
display: inline-block
@@ -0,0 +1,58 @@
@layer vuetify-components {
.v-date-picker-header {
align-items: flex-end;
height: 70px;
display: grid;
grid-template-areas: "prepend content append";
grid-template-columns: min-content minmax(0, 1fr) min-content;
overflow: hidden;
padding-inline: 24px 12px;
padding-bottom: 12px;
}
.v-date-picker-header__append {
grid-area: append;
}
.v-date-picker-header__prepend {
grid-area: prepend;
padding-inline-start: 8px;
}
.v-date-picker-header__content {
align-items: center;
display: inline-flex;
font-size: 32px;
line-height: 40px;
grid-area: content;
justify-content: space-between;
white-space: pre-wrap;
}
.v-date-picker-header--clickable .v-date-picker-header__content {
cursor: pointer;
}
.v-date-picker-header--clickable .v-date-picker-header__content:not(:hover) {
opacity: 0.7;
}
.date-picker-header-transition-enter-active,
.date-picker-header-reverse-transition-enter-active {
transition-duration: 0.3s;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
}
.date-picker-header-transition-leave-active,
.date-picker-header-reverse-transition-leave-active {
transition-duration: 0.3s;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
}
.date-picker-header-transition-enter-from {
transform: translate(0, 100%);
}
.date-picker-header-transition-leave-to {
opacity: 0;
transform: translate(0, -100%);
}
.date-picker-header-reverse-transition-enter-from {
transform: translate(0, -100%);
}
.date-picker-header-reverse-transition-leave-to {
opacity: 0;
transform: translate(0, 100%);
}
}
@@ -0,0 +1,165 @@
import { IconValue } from '../../composables/icons.js';
export type VDatePickerHeaderSlots = {
prepend: never;
default: never;
append: never;
};
export declare const makeVDatePickerHeaderProps: <Defaults extends {
appendIcon?: unknown;
color?: unknown;
header?: unknown;
transition?: unknown;
onClick?: unknown;
} = {}>(defaults?: Defaults | undefined) => {
appendIcon: unknown extends Defaults["appendIcon"] ? import("vue").PropType<IconValue> : {
type: import("vue").PropType<unknown extends Defaults["appendIcon"] ? IconValue : Defaults["appendIcon"] | IconValue>;
default: unknown extends Defaults["appendIcon"] ? IconValue : Defaults["appendIcon"] | NonNullable<IconValue>;
};
color: unknown extends Defaults["color"] ? StringConstructor : {
type: import("vue").PropType<unknown extends Defaults["color"] ? string : string | Defaults["color"]>;
default: unknown extends Defaults["color"] ? string : string | Defaults["color"];
};
header: unknown extends Defaults["header"] ? StringConstructor : {
type: import("vue").PropType<unknown extends Defaults["header"] ? string : string | Defaults["header"]>;
default: unknown extends Defaults["header"] ? string : string | Defaults["header"];
};
transition: unknown extends Defaults["transition"] ? StringConstructor : {
type: import("vue").PropType<unknown extends Defaults["transition"] ? string : string | Defaults["transition"]>;
default: unknown extends Defaults["transition"] ? string : string | Defaults["transition"];
};
onClick: unknown extends Defaults["onClick"] ? import("vue").PropType<(args_0: MouseEvent) => void> : {
type: import("vue").PropType<unknown extends Defaults["onClick"] ? (args_0: MouseEvent) => void : ((args_0: MouseEvent) => void) | Defaults["onClick"]>;
default: unknown extends Defaults["onClick"] ? (args_0: MouseEvent) => void : ((args_0: MouseEvent) => void) | Defaults["onClick"];
};
};
export declare const VDatePickerHeader: {
new (...args: any[]): import("vue").CreateComponentPublicInstanceWithMixins<{} & {
appendIcon?: IconValue | undefined;
color?: string | undefined;
header?: string | undefined;
transition?: string | undefined;
onClick?: ((args_0: MouseEvent) => void) | undefined;
} & {
$children?: {
prepend?: (() => import("vue").VNodeChild) | undefined;
default?: (() => import("vue").VNodeChild) | undefined;
append?: (() => import("vue").VNodeChild) | undefined;
} | {
$stable?: boolean;
} | (() => import("vue").VNodeChild) | import("vue").VNodeChild;
'v-slots'?: {
prepend?: false | (() => import("vue").VNodeChild) | undefined;
default?: false | (() => import("vue").VNodeChild) | undefined;
append?: false | (() => import("vue").VNodeChild) | undefined;
} | undefined;
} & {
"v-slot:append"?: false | (() => import("vue").VNodeChild) | undefined;
"v-slot:default"?: false | (() => import("vue").VNodeChild) | undefined;
"v-slot:prepend"?: false | (() => import("vue").VNodeChild) | undefined;
} & {
onClick?: (() => any) | undefined;
"onClick:append"?: (() => any) | undefined;
}, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
click: () => true;
'click:append': () => true;
}, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, {}, true, {}, import("vue").SlotsType<Partial<{
prepend: () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>[];
default: () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>[];
append: () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>[];
}>>, import("vue").GlobalComponents, import("vue").GlobalDirectives, string, {}, any, import("vue").ComponentProvideOptions, {
P: {};
B: {};
D: {};
C: {};
M: {};
Defaults: {};
}, {} & {
appendIcon?: IconValue | undefined;
color?: string | undefined;
header?: string | undefined;
transition?: string | undefined;
onClick?: ((args_0: MouseEvent) => void) | undefined;
} & {
$children?: {
prepend?: (() => import("vue").VNodeChild) | undefined;
default?: (() => import("vue").VNodeChild) | undefined;
append?: (() => import("vue").VNodeChild) | undefined;
} | {
$stable?: boolean;
} | (() => import("vue").VNodeChild) | import("vue").VNodeChild;
'v-slots'?: {
prepend?: false | (() => import("vue").VNodeChild) | undefined;
default?: false | (() => import("vue").VNodeChild) | undefined;
append?: false | (() => import("vue").VNodeChild) | undefined;
} | undefined;
} & {
"v-slot:append"?: false | (() => import("vue").VNodeChild) | undefined;
"v-slot:default"?: false | (() => import("vue").VNodeChild) | undefined;
"v-slot:prepend"?: false | (() => import("vue").VNodeChild) | undefined;
} & {
onClick?: (() => any) | undefined;
"onClick:append"?: (() => any) | undefined;
}, {}, {}, {}, {}, {}>;
__isFragment?: never;
__isTeleport?: never;
__isSuspense?: never;
} & import("vue").ComponentOptionsBase<{} & {
appendIcon?: IconValue | undefined;
color?: string | undefined;
header?: string | undefined;
transition?: string | undefined;
onClick?: ((args_0: MouseEvent) => void) | undefined;
} & {
$children?: {
prepend?: (() => import("vue").VNodeChild) | undefined;
default?: (() => import("vue").VNodeChild) | undefined;
append?: (() => import("vue").VNodeChild) | undefined;
} | {
$stable?: boolean;
} | (() => import("vue").VNodeChild) | import("vue").VNodeChild;
'v-slots'?: {
prepend?: false | (() => import("vue").VNodeChild) | undefined;
default?: false | (() => import("vue").VNodeChild) | undefined;
append?: false | (() => import("vue").VNodeChild) | undefined;
} | undefined;
} & {
"v-slot:append"?: false | (() => import("vue").VNodeChild) | undefined;
"v-slot:default"?: false | (() => import("vue").VNodeChild) | undefined;
"v-slot:prepend"?: false | (() => import("vue").VNodeChild) | undefined;
} & {
onClick?: (() => any) | undefined;
"onClick:append"?: (() => any) | undefined;
}, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
click: () => true;
'click:append': () => true;
}, string, {}, {}, string, import("vue").SlotsType<Partial<{
prepend: () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>[];
default: () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>[];
append: () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>[];
}>>, import("vue").GlobalComponents, import("vue").GlobalDirectives, string, import("vue").ComponentProvideOptions> & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps & import("../../util/index.js").FilterPropsOptions<{
appendIcon: import("vue").PropType<IconValue>;
color: StringConstructor;
header: StringConstructor;
transition: StringConstructor;
onClick: import("vue").PropType<(args_0: MouseEvent) => void>;
}, import("vue").ExtractPropTypes<{
appendIcon: import("vue").PropType<IconValue>;
color: StringConstructor;
header: StringConstructor;
transition: StringConstructor;
onClick: import("vue").PropType<(args_0: MouseEvent) => void>;
}>>;
export type VDatePickerHeader = InstanceType<typeof VDatePickerHeader>;
@@ -0,0 +1,83 @@
import { createElementVNode as _createElementVNode, createVNode as _createVNode, normalizeClass as _normalizeClass, normalizeStyle as _normalizeStyle } from "vue";
// Styles
import "./VDatePickerHeader.css";
// Components
import { VBtn } from "../VBtn/index.js";
import { VDefaultsProvider } from "../VDefaultsProvider/index.js"; // Composables
import { useBackgroundColor } from "../../composables/color.js";
import { IconValue } from "../../composables/icons.js";
import { MaybeTransition } from "../../composables/transition.js"; // Utilities
import { EventProp, genericComponent, propsFactory, useRender } from "../../util/index.js"; // Types
export const makeVDatePickerHeaderProps = propsFactory({
appendIcon: IconValue,
color: String,
header: String,
transition: String,
onClick: EventProp()
}, 'VDatePickerHeader');
export const VDatePickerHeader = genericComponent()({
name: 'VDatePickerHeader',
props: makeVDatePickerHeaderProps(),
emits: {
click: () => true,
'click:append': () => true
},
setup(props, {
emit,
slots
}) {
const {
backgroundColorClasses,
backgroundColorStyles
} = useBackgroundColor(() => props.color);
function onClick() {
emit('click');
}
function onClickAppend() {
emit('click:append');
}
useRender(() => {
const hasContent = !!(slots.default || props.header);
const hasAppend = !!(slots.append || props.appendIcon);
return _createElementVNode("div", {
"class": _normalizeClass(['v-date-picker-header', {
'v-date-picker-header--clickable': !!props.onClick
}, backgroundColorClasses.value]),
"style": _normalizeStyle(backgroundColorStyles.value),
"onClick": onClick
}, [slots.prepend && _createElementVNode("div", {
"key": "prepend",
"class": "v-date-picker-header__prepend"
}, [slots.prepend()]), hasContent && _createVNode(MaybeTransition, {
"key": "content",
"name": props.transition
}, {
default: () => [_createElementVNode("div", {
"key": props.header,
"class": "v-date-picker-header__content"
}, [slots.default?.() ?? props.header])]
}), hasAppend && _createElementVNode("div", {
"class": "v-date-picker-header__append"
}, [!slots.append ? _createVNode(VBtn, {
"key": "append-btn",
"icon": props.appendIcon,
"variant": "text",
"onClick": onClickAppend
}, null) : _createVNode(VDefaultsProvider, {
"key": "append-defaults",
"disabled": !props.appendIcon,
"defaults": {
VBtn: {
icon: props.appendIcon,
variant: 'text'
}
}
}, {
default: () => [slots.append?.()]
})])]);
});
return {};
}
});
//# sourceMappingURL=VDatePickerHeader.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,62 @@
@use '../../styles/settings'
@use '../../styles/tools'
@use './variables' as *
@include tools.layer('components')
.v-date-picker-header
align-items: flex-end
height: $date-picker-header-height
display: grid
grid-template-areas: "prepend content append"
grid-template-columns: min-content minmax(0, 1fr) min-content
overflow: hidden
padding-inline: 24px 12px
padding-bottom: 12px
.v-date-picker-header__append
grid-area: append
.v-date-picker-header__prepend
grid-area: prepend
padding-inline-start: 8px
.v-date-picker-header__content
align-items: center
display: inline-flex
font-size: 32px
line-height: 40px
grid-area: content
justify-content: space-between
white-space: pre-wrap
.v-date-picker-header--clickable &
cursor: pointer
&:not(:hover)
opacity: .7
.date-picker-header-transition,
.date-picker-header-reverse-transition
&-enter-active
transition-duration: 0.3s
transition-timing-function: settings.$standard-easing
&-leave-active
transition-duration: 0.3s
transition-timing-function: settings.$standard-easing
.date-picker-header-transition
&-enter-from
transform: translate(0, 100%)
&-leave-to
opacity: 0
transform: translate(0, -100%)
.date-picker-header-reverse-transition
&-enter-from
transform: translate(0, -100%)
&-leave-to
opacity: 0
transform: translate(0, 100%)
@@ -0,0 +1,72 @@
@layer vuetify-components {
.v-date-picker-month {
display: flex;
justify-content: center;
padding: 0 12px 8px;
--v-date-picker-month-day-diff: 4px;
}
.v-date-picker-month__weeks {
display: flex;
flex-direction: column;
column-gap: 4px;
font-size: 0.875rem;
}
.v-date-picker-month__weekday {
font-size: 0.875rem;
}
.v-date-picker-month__days {
display: grid;
grid-template-columns: repeat(var(--v-date-picker-days-in-week), min-content);
column-gap: 4px;
justify-content: space-around;
width: 100%;
}
.v-date-picker-month__day {
align-items: center;
display: flex;
justify-content: center;
position: relative;
height: 40px;
width: 40px;
}
.v-date-picker-month__day--selected .v-btn {
background-color: rgb(var(--v-theme-surface-variant));
color: rgb(var(--v-theme-on-surface-variant));
}
.v-date-picker-month__day .v-btn.v-date-picker-month__day-btn {
--v-btn-height: 24px;
--v-btn-size: 0.875rem;
}
.v-date-picker-month__day--week {
font-size: var(--v-btn-size);
}
.v-date-picker-month__day--adjacent {
opacity: 0.5;
}
.v-date-picker-month__day--hide-adjacent {
opacity: 0;
}
.v-date-picker-month__events {
height: 8px;
left: 0;
text-indent: 0;
position: absolute;
text-align: center;
white-space: pre;
width: 100%;
}
.v-date-picker-month__events > div {
height: 8px;
margin: 0 1px;
width: 8px;
margin-bottom: -1px;
}
.v-date-picker-month__events .v-badge--dot .v-badge__badge {
border-radius: 4px;
height: 8px;
width: 8px;
}
.v-date-picker-month__day .v-date-picker-month__events {
bottom: 8px;
}
}
@@ -0,0 +1,447 @@
import type { PropType } from 'vue';
import type { GenericProps } from '../../util/index.js';
export type DatePickerEventColorValue = boolean | string | string[];
export type DatePickerEventColors = DatePickerEventColorValue | Record<string, DatePickerEventColorValue> | ((date: string) => DatePickerEventColorValue);
export type DatePickerEvents = string[] | ((date: string) => DatePickerEventColorValue) | Record<string, DatePickerEventColorValue>;
export type VDatePickerMonthSlots = {
day: {
props: {
onClick: () => void;
};
item: any;
i: number;
};
};
export declare const makeVDatePickerMonthProps: <Defaults extends {
allowedDates?: unknown;
disabled?: unknown;
modelValue?: unknown;
month?: unknown;
max?: unknown;
min?: unknown;
showAdjacentMonths?: unknown;
year?: unknown;
weekdays?: unknown;
weeksInMonth?: unknown;
firstDayOfWeek?: unknown;
firstDayOfYear?: unknown;
weekdayFormat?: unknown;
color?: unknown;
hideWeekdays?: unknown;
multiple?: unknown;
showWeek?: unknown;
readonly?: unknown;
transition?: unknown;
reverseTransition?: unknown;
events?: unknown;
eventColor?: unknown;
} = {}>(defaults?: Defaults | undefined) => {
allowedDates: unknown extends Defaults["allowedDates"] ? PropType<unknown[] | ((date: unknown) => boolean)> : {
type: PropType<unknown extends Defaults["allowedDates"] ? unknown[] | ((date: unknown) => boolean) : unknown[] | ((date: unknown) => boolean) | Defaults["allowedDates"]>;
default: unknown extends Defaults["allowedDates"] ? unknown[] | ((date: unknown) => boolean) : Defaults["allowedDates"] | NonNullable<unknown[] | ((date: unknown) => boolean)>;
};
disabled: unknown extends Defaults["disabled"] ? {
type: BooleanConstructor;
default: null;
} : Omit<{
type: BooleanConstructor;
default: null;
}, "default" | "type"> & {
type: PropType<unknown extends Defaults["disabled"] ? boolean : boolean | Defaults["disabled"]>;
default: unknown extends Defaults["disabled"] ? boolean : boolean | Defaults["disabled"];
};
modelValue: unknown extends Defaults["modelValue"] ? PropType<unknown[]> : {
type: PropType<unknown extends Defaults["modelValue"] ? unknown[] : unknown[] | Defaults["modelValue"]>;
default: unknown extends Defaults["modelValue"] ? unknown[] : unknown[] | Defaults["modelValue"];
};
month: unknown extends Defaults["month"] ? (NumberConstructor | StringConstructor)[] : {
type: PropType<unknown extends Defaults["month"] ? string | number : string | number | Defaults["month"]>;
default: unknown extends Defaults["month"] ? string | number : Defaults["month"] | NonNullable<string | number>;
};
max: unknown extends Defaults["max"] ? PropType<unknown> : {
type: PropType<unknown extends Defaults["max"] ? unknown : unknown>;
default: unknown extends Defaults["max"] ? unknown : {} | Defaults["max"];
};
min: unknown extends Defaults["min"] ? PropType<unknown> : {
type: PropType<unknown extends Defaults["min"] ? unknown : unknown>;
default: unknown extends Defaults["min"] ? unknown : {} | Defaults["min"];
};
showAdjacentMonths: unknown extends Defaults["showAdjacentMonths"] ? BooleanConstructor : {
type: PropType<unknown extends Defaults["showAdjacentMonths"] ? boolean : boolean | Defaults["showAdjacentMonths"]>;
default: unknown extends Defaults["showAdjacentMonths"] ? boolean : boolean | Defaults["showAdjacentMonths"];
};
year: unknown extends Defaults["year"] ? (NumberConstructor | StringConstructor)[] : {
type: PropType<unknown extends Defaults["year"] ? string | number : string | number | Defaults["year"]>;
default: unknown extends Defaults["year"] ? string | number : Defaults["year"] | NonNullable<string | number>;
};
weekdays: unknown extends Defaults["weekdays"] ? {
type: PropType<import("../../composables/calendar.js").CalendarWeekdays[]>;
default: () => number[];
} : Omit<{
type: PropType<import("../../composables/calendar.js").CalendarWeekdays[]>;
default: () => number[];
}, "default" | "type"> & {
type: PropType<unknown extends Defaults["weekdays"] ? import("../../composables/calendar.js").CalendarWeekdays[] : import("../../composables/calendar.js").CalendarWeekdays[] | Defaults["weekdays"]>;
default: unknown extends Defaults["weekdays"] ? import("../../composables/calendar.js").CalendarWeekdays[] : import("../../composables/calendar.js").CalendarWeekdays[] | Defaults["weekdays"];
};
weeksInMonth: unknown extends Defaults["weeksInMonth"] ? {
type: PropType<'dynamic' | 'static'>;
default: string;
} : Omit<{
type: PropType<'dynamic' | 'static'>;
default: string;
}, "default" | "type"> & {
type: PropType<unknown extends Defaults["weeksInMonth"] ? "dynamic" | "static" : "dynamic" | "static" | Defaults["weeksInMonth"]>;
default: unknown extends Defaults["weeksInMonth"] ? "dynamic" | "static" : Defaults["weeksInMonth"] | NonNullable<"dynamic" | "static">;
};
firstDayOfWeek: unknown extends Defaults["firstDayOfWeek"] ? {
type: (NumberConstructor | StringConstructor)[];
default: undefined;
} : Omit<{
type: (NumberConstructor | StringConstructor)[];
default: undefined;
}, "default" | "type"> & {
type: PropType<unknown extends Defaults["firstDayOfWeek"] ? string | number : string | number | Defaults["firstDayOfWeek"]>;
default: unknown extends Defaults["firstDayOfWeek"] ? string | number : Defaults["firstDayOfWeek"] | NonNullable<string | number>;
};
firstDayOfYear: unknown extends Defaults["firstDayOfYear"] ? {
type: (NumberConstructor | StringConstructor)[];
default: undefined;
} : Omit<{
type: (NumberConstructor | StringConstructor)[];
default: undefined;
}, "default" | "type"> & {
type: PropType<unknown extends Defaults["firstDayOfYear"] ? string | number : string | number | Defaults["firstDayOfYear"]>;
default: unknown extends Defaults["firstDayOfYear"] ? string | number : Defaults["firstDayOfYear"] | NonNullable<string | number>;
};
weekdayFormat: unknown extends Defaults["weekdayFormat"] ? PropType<"long" | "narrow" | "short" | undefined> : {
type: PropType<unknown extends Defaults["weekdayFormat"] ? "long" | "narrow" | "short" | undefined : "long" | "narrow" | "short" | Defaults["weekdayFormat"] | undefined>;
default: unknown extends Defaults["weekdayFormat"] ? "long" | "narrow" | "short" | undefined : Defaults["weekdayFormat"] | NonNullable<"long" | "narrow" | "short" | undefined>;
};
color: unknown extends Defaults["color"] ? StringConstructor : {
type: PropType<unknown extends Defaults["color"] ? string : string | Defaults["color"]>;
default: unknown extends Defaults["color"] ? string : string | Defaults["color"];
};
hideWeekdays: unknown extends Defaults["hideWeekdays"] ? BooleanConstructor : {
type: PropType<unknown extends Defaults["hideWeekdays"] ? boolean : boolean | Defaults["hideWeekdays"]>;
default: unknown extends Defaults["hideWeekdays"] ? boolean : boolean | Defaults["hideWeekdays"];
};
multiple: unknown extends Defaults["multiple"] ? PropType<number | "range" | boolean | (string & {})> : {
type: PropType<unknown extends Defaults["multiple"] ? number | "range" | boolean | (string & {}) : number | "range" | boolean | Defaults["multiple"] | (string & {})>;
default: unknown extends Defaults["multiple"] ? number | "range" | boolean | (string & {}) : Defaults["multiple"] | NonNullable<number | "range" | boolean | (string & {})>;
};
showWeek: unknown extends Defaults["showWeek"] ? BooleanConstructor : {
type: PropType<unknown extends Defaults["showWeek"] ? boolean : boolean | Defaults["showWeek"]>;
default: unknown extends Defaults["showWeek"] ? boolean : boolean | Defaults["showWeek"];
};
readonly: unknown extends Defaults["readonly"] ? BooleanConstructor : {
type: PropType<unknown extends Defaults["readonly"] ? boolean : boolean | Defaults["readonly"]>;
default: unknown extends Defaults["readonly"] ? boolean : boolean | Defaults["readonly"];
};
transition: unknown extends Defaults["transition"] ? {
type: StringConstructor;
default: string;
} : Omit<{
type: StringConstructor;
default: string;
}, "default" | "type"> & {
type: PropType<unknown extends Defaults["transition"] ? string : string | Defaults["transition"]>;
default: unknown extends Defaults["transition"] ? string : string | Defaults["transition"];
};
reverseTransition: unknown extends Defaults["reverseTransition"] ? {
type: StringConstructor;
default: string;
} : Omit<{
type: StringConstructor;
default: string;
}, "default" | "type"> & {
type: PropType<unknown extends Defaults["reverseTransition"] ? string : string | Defaults["reverseTransition"]>;
default: unknown extends Defaults["reverseTransition"] ? string : string | Defaults["reverseTransition"];
};
events: unknown extends Defaults["events"] ? {
type: PropType<DatePickerEvents | null>;
default: () => null;
} : Omit<{
type: PropType<DatePickerEvents | null>;
default: () => null;
}, "default" | "type"> & {
type: PropType<unknown extends Defaults["events"] ? DatePickerEvents | null : Defaults["events"] | DatePickerEvents | null>;
default: unknown extends Defaults["events"] ? DatePickerEvents | null : Defaults["events"] | NonNullable<DatePickerEvents | null>;
};
eventColor: unknown extends Defaults["eventColor"] ? {
type: PropType<DatePickerEventColors>;
default: () => null;
} : Omit<{
type: PropType<DatePickerEventColors>;
default: () => null;
}, "default" | "type"> & {
type: PropType<unknown extends Defaults["eventColor"] ? DatePickerEventColors : Defaults["eventColor"] | DatePickerEventColors>;
default: unknown extends Defaults["eventColor"] ? DatePickerEventColors : Defaults["eventColor"] | NonNullable<DatePickerEventColors>;
};
};
export declare const VDatePickerMonth: {
new (...args: any[]): import("vue").CreateComponentPublicInstanceWithMixins<{
disabled: boolean;
showAdjacentMonths: boolean;
weekdays: import("../../composables/calendar.js").CalendarWeekdays[];
weeksInMonth: "dynamic" | "static";
hideWeekdays: boolean;
showWeek: boolean;
readonly: boolean;
transition: string;
reverseTransition: string;
events: DatePickerEvents | null;
eventColor: DatePickerEventColors;
} & {
allowedDates?: unknown[] | ((date: unknown) => boolean) | undefined;
month?: string | number | undefined;
max?: unknown;
min?: unknown;
year?: string | number | undefined;
firstDayOfWeek?: string | number | undefined;
firstDayOfYear?: string | number | undefined;
weekdayFormat?: "long" | "narrow" | "short" | undefined;
color?: string | undefined;
multiple?: number | "range" | boolean | (string & {}) | undefined;
} & {
"onUpdate:month"?: ((date: number) => any) | undefined;
"onUpdate:year"?: ((date: number) => any) | undefined;
}, void, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, Omit<{
'update:modelValue': (date: unknown) => true;
'update:month': (date: number) => true;
'update:year': (date: number) => true;
}, "$children" | "modelValue" | "update:modelValue" | "v-slot:day" | "v-slots">, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, {
disabled: boolean;
showAdjacentMonths: boolean;
weekdays: import("../../composables/calendar.js").CalendarWeekdays[];
weeksInMonth: "dynamic" | "static";
firstDayOfWeek: string | number;
firstDayOfYear: string | number;
hideWeekdays: boolean;
showWeek: boolean;
readonly: boolean;
transition: string;
reverseTransition: string;
events: DatePickerEvents | null;
eventColor: DatePickerEventColors;
}, true, {}, import("vue").SlotsType<Partial<{
day: (arg: {
props: {
onClick: () => void;
};
item: any;
i: number;
}) => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>[];
}>>, import("vue").GlobalComponents, import("vue").GlobalDirectives, string, {}, any, import("vue").ComponentProvideOptions, {
P: {};
B: {};
D: {};
C: {};
M: {};
Defaults: {};
}, {
disabled: boolean;
showAdjacentMonths: boolean;
weekdays: import("../../composables/calendar.js").CalendarWeekdays[];
weeksInMonth: "dynamic" | "static";
hideWeekdays: boolean;
showWeek: boolean;
readonly: boolean;
transition: string;
reverseTransition: string;
events: DatePickerEvents | null;
eventColor: DatePickerEventColors;
} & {
allowedDates?: unknown[] | ((date: unknown) => boolean) | undefined;
month?: string | number | undefined;
max?: unknown;
min?: unknown;
year?: string | number | undefined;
firstDayOfWeek?: string | number | undefined;
firstDayOfYear?: string | number | undefined;
weekdayFormat?: "long" | "narrow" | "short" | undefined;
color?: string | undefined;
multiple?: number | "range" | boolean | (string & {}) | undefined;
} & {
"onUpdate:month"?: ((date: number) => any) | undefined;
"onUpdate:year"?: ((date: number) => any) | undefined;
}, {}, {}, {}, {}, {
disabled: boolean;
showAdjacentMonths: boolean;
weekdays: import("../../composables/calendar.js").CalendarWeekdays[];
weeksInMonth: "dynamic" | "static";
firstDayOfWeek: string | number;
firstDayOfYear: string | number;
hideWeekdays: boolean;
showWeek: boolean;
readonly: boolean;
transition: string;
reverseTransition: string;
events: DatePickerEvents | null;
eventColor: DatePickerEventColors;
}>;
__isFragment?: never;
__isTeleport?: never;
__isSuspense?: never;
} & import("vue").ComponentOptionsBase<{
disabled: boolean;
showAdjacentMonths: boolean;
weekdays: import("../../composables/calendar.js").CalendarWeekdays[];
weeksInMonth: "dynamic" | "static";
hideWeekdays: boolean;
showWeek: boolean;
readonly: boolean;
transition: string;
reverseTransition: string;
events: DatePickerEvents | null;
eventColor: DatePickerEventColors;
} & {
allowedDates?: unknown[] | ((date: unknown) => boolean) | undefined;
month?: string | number | undefined;
max?: unknown;
min?: unknown;
year?: string | number | undefined;
firstDayOfWeek?: string | number | undefined;
firstDayOfYear?: string | number | undefined;
weekdayFormat?: "long" | "narrow" | "short" | undefined;
color?: string | undefined;
multiple?: number | "range" | boolean | (string & {}) | undefined;
} & {
"onUpdate:month"?: ((date: number) => any) | undefined;
"onUpdate:year"?: ((date: number) => any) | undefined;
}, void, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, Omit<{
'update:modelValue': (date: unknown) => true;
'update:month': (date: number) => true;
'update:year': (date: number) => true;
}, "$children" | "modelValue" | "update:modelValue" | "v-slot:day" | "v-slots">, string, {
disabled: boolean;
showAdjacentMonths: boolean;
weekdays: import("../../composables/calendar.js").CalendarWeekdays[];
weeksInMonth: "dynamic" | "static";
firstDayOfWeek: string | number;
firstDayOfYear: string | number;
hideWeekdays: boolean;
showWeek: boolean;
readonly: boolean;
transition: string;
reverseTransition: string;
events: DatePickerEvents | null;
eventColor: DatePickerEventColors;
}, {}, string, import("vue").SlotsType<Partial<{
day: (arg: {
props: {
onClick: () => void;
};
item: any;
i: number;
}) => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>[];
}>>, import("vue").GlobalComponents, import("vue").GlobalDirectives, string, import("vue").ComponentProvideOptions> & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps & (new <TModel>(props: {
modelValue?: TModel;
'onUpdate:modelValue'?: (value: TModel) => void;
}, slots: VDatePickerMonthSlots) => GenericProps<typeof props, typeof slots>) & import("../../util/index.js").FilterPropsOptions<{
allowedDates: PropType<unknown[] | ((date: unknown) => boolean)>;
disabled: {
type: BooleanConstructor;
default: null;
};
modelValue: PropType<unknown[]>;
month: (NumberConstructor | StringConstructor)[];
max: PropType<unknown>;
min: PropType<unknown>;
showAdjacentMonths: BooleanConstructor;
year: (NumberConstructor | StringConstructor)[];
weekdays: {
type: PropType<import("../../composables/calendar.js").CalendarWeekdays[]>;
default: () => number[];
};
weeksInMonth: {
type: PropType<'dynamic' | 'static'>;
default: string;
};
firstDayOfWeek: {
type: (NumberConstructor | StringConstructor)[];
default: undefined;
};
firstDayOfYear: {
type: (NumberConstructor | StringConstructor)[];
default: undefined;
};
weekdayFormat: PropType<'long' | 'short' | 'narrow' | undefined>;
color: StringConstructor;
hideWeekdays: BooleanConstructor;
multiple: PropType<boolean | 'range' | number | (string & {})>;
showWeek: BooleanConstructor;
readonly: BooleanConstructor;
transition: {
type: StringConstructor;
default: string;
};
reverseTransition: {
type: StringConstructor;
default: string;
};
events: {
type: PropType<DatePickerEvents | null>;
default: () => null;
};
eventColor: {
type: PropType<DatePickerEventColors>;
default: () => null;
};
}, import("vue").ExtractPropTypes<{
allowedDates: PropType<unknown[] | ((date: unknown) => boolean)>;
disabled: {
type: BooleanConstructor;
default: null;
};
modelValue: PropType<unknown[]>;
month: (NumberConstructor | StringConstructor)[];
max: PropType<unknown>;
min: PropType<unknown>;
showAdjacentMonths: BooleanConstructor;
year: (NumberConstructor | StringConstructor)[];
weekdays: {
type: PropType<import("../../composables/calendar.js").CalendarWeekdays[]>;
default: () => number[];
};
weeksInMonth: {
type: PropType<'dynamic' | 'static'>;
default: string;
};
firstDayOfWeek: {
type: (NumberConstructor | StringConstructor)[];
default: undefined;
};
firstDayOfYear: {
type: (NumberConstructor | StringConstructor)[];
default: undefined;
};
weekdayFormat: PropType<'long' | 'short' | 'narrow' | undefined>;
color: StringConstructor;
hideWeekdays: BooleanConstructor;
multiple: PropType<boolean | 'range' | number | (string & {})>;
showWeek: BooleanConstructor;
readonly: BooleanConstructor;
transition: {
type: StringConstructor;
default: string;
};
reverseTransition: {
type: StringConstructor;
default: string;
};
events: {
type: PropType<DatePickerEvents | null>;
default: () => null;
};
eventColor: {
type: PropType<DatePickerEventColors>;
default: () => null;
};
}>>;
export type VDatePickerMonth = InstanceType<typeof VDatePickerMonth>;
@@ -0,0 +1,236 @@
import { createVNode as _createVNode, createElementVNode as _createElementVNode, createTextVNode as _createTextVNode, normalizeClass as _normalizeClass } from "vue";
// Styles
import "./VDatePickerMonth.css";
// Components
import { VBadge } from "../VBadge/index.js";
import { VBtn } from "../VBtn/index.js"; // Composables
import { makeCalendarProps, useCalendar } from "../../composables/calendar.js";
import { useDate } from "../../composables/date/date.js";
import { useLocale } from "../../composables/locale.js";
import { MaybeTransition } from "../../composables/transition.js"; // Utilities
import { computed, ref, shallowRef, toRef, watch } from 'vue';
import { genericComponent, omit, propsFactory, useRender, wrapInArray } from "../../util/index.js"; // Types
export const makeVDatePickerMonthProps = propsFactory({
color: String,
hideWeekdays: Boolean,
multiple: [Boolean, Number, String],
showWeek: Boolean,
readonly: Boolean,
transition: {
type: String,
default: 'picker-transition'
},
reverseTransition: {
type: String,
default: 'picker-reverse-transition'
},
events: {
type: [Array, Function, Object],
default: () => null
},
eventColor: {
type: [Array, Function, Object, String],
default: () => null
},
...omit(makeCalendarProps(), ['displayValue'])
}, 'VDatePickerMonth');
export const VDatePickerMonth = genericComponent()({
name: 'VDatePickerMonth',
props: makeVDatePickerMonthProps(),
emits: {
'update:modelValue': date => true,
'update:month': date => true,
'update:year': date => true
},
setup(props, {
emit,
slots
}) {
const daysRef = ref();
const {
t
} = useLocale();
const {
daysInMonth,
model,
weekNumbers,
weekdayLabels
} = useCalendar(props);
const adapter = useDate();
const rangeStart = shallowRef();
const rangeStop = shallowRef();
const isReverse = shallowRef(false);
const transition = toRef(() => {
return !isReverse.value ? props.transition : props.reverseTransition;
});
if (props.multiple === 'range' && model.value.length > 0) {
rangeStart.value = model.value[0];
if (model.value.length > 1) {
rangeStop.value = model.value[model.value.length - 1];
}
}
const atMax = computed(() => {
const max = ['number', 'string'].includes(typeof props.multiple) ? Number(props.multiple) : Infinity;
return model.value.length >= max;
});
watch(daysInMonth, (val, oldVal) => {
if (!oldVal) return;
isReverse.value = adapter.isBefore(val[0].date, oldVal[0].date);
});
function onRangeClick(value) {
const _value = adapter.startOfDay(value);
if (model.value.length === 0) {
rangeStart.value = undefined;
} else if (model.value.length === 1) {
rangeStart.value = model.value[0];
rangeStop.value = undefined;
}
if (!rangeStart.value) {
rangeStart.value = _value;
model.value = [rangeStart.value];
} else if (!rangeStop.value) {
if (adapter.isSameDay(_value, rangeStart.value)) {
rangeStart.value = undefined;
model.value = [];
return;
} else if (adapter.isBefore(_value, rangeStart.value)) {
rangeStop.value = adapter.endOfDay(rangeStart.value);
rangeStart.value = _value;
} else {
rangeStop.value = adapter.endOfDay(_value);
}
model.value = [rangeStart.value, rangeStop.value];
} else {
rangeStart.value = value;
rangeStop.value = undefined;
model.value = [rangeStart.value];
}
}
function getDateAriaLabel(item) {
const fullDate = adapter.format(item.date, 'fullDateWithWeekday');
const localeKey = item.isToday ? 'currentDate' : 'selectDate';
return t(`$vuetify.datePicker.ariaLabel.${localeKey}`, fullDate);
}
function onMultipleClick(value) {
const index = model.value.findIndex(selection => adapter.isSameDay(selection, value));
if (index === -1) {
model.value = [...model.value, value];
} else {
const value = [...model.value];
value.splice(index, 1);
model.value = value;
}
}
function onClick(value) {
if (props.multiple === 'range') {
onRangeClick(value);
} else if (props.multiple) {
onMultipleClick(value);
} else {
model.value = [value];
}
}
function getEventColors(date) {
const {
events,
eventColor
} = props;
let eventData;
let eventColors = [];
if (Array.isArray(events)) {
eventData = events.includes(date);
} else if (events instanceof Function) {
eventData = events(date) || false;
} else if (events) {
eventData = events[date] || false;
} else {
eventData = false;
}
if (!eventData) {
return [];
} else if (eventData !== true) {
eventColors = wrapInArray(eventData);
} else if (typeof eventColor === 'string') {
eventColors = [eventColor];
} else if (typeof eventColor === 'function') {
eventColors = wrapInArray(eventColor(date));
} else if (Array.isArray(eventColor)) {
eventColors = eventColor;
} else if (typeof eventColor === 'object' && eventColor !== null) {
eventColors = wrapInArray(eventColor[date]);
}
// Fallback to default color if no color is found
return !eventColors.length ? ['surface-variant'] : eventColors.filter(Boolean).map(color => typeof color === 'string' ? color : 'surface-variant');
}
function genEvents(date) {
const eventColors = getEventColors(date);
if (!eventColors.length) return null;
return _createElementVNode("div", {
"class": "v-date-picker-month__events"
}, [eventColors.map(color => _createVNode(VBadge, {
"dot": true,
"color": color
}, null))]);
}
useRender(() => _createElementVNode("div", {
"class": "v-date-picker-month",
"style": {
'--v-date-picker-days-in-week': props.weekdays.length
}
}, [props.showWeek && _createElementVNode("div", {
"key": "weeks",
"class": "v-date-picker-month__weeks"
}, [!props.hideWeekdays && _createElementVNode("div", {
"key": "hide-week-days",
"class": "v-date-picker-month__day"
}, [_createTextVNode("\xA0")]), weekNumbers.value.map(week => _createElementVNode("div", {
"class": _normalizeClass(['v-date-picker-month__day', 'v-date-picker-month__day--adjacent'])
}, [week]))]), _createVNode(MaybeTransition, {
"name": transition.value
}, {
default: () => [_createElementVNode("div", {
"ref": daysRef,
"key": daysInMonth.value[0].date?.toString(),
"class": "v-date-picker-month__days"
}, [!props.hideWeekdays && weekdayLabels.value.map(weekDay => _createElementVNode("div", {
"class": _normalizeClass(['v-date-picker-month__day', 'v-date-picker-month__weekday'])
}, [weekDay])), daysInMonth.value.map((item, i) => {
const slotProps = {
props: {
class: 'v-date-picker-month__day-btn',
color: item.isSelected || item.isToday ? props.color : undefined,
disabled: item.isDisabled,
readonly: props.readonly,
icon: true,
ripple: false,
variant: item.isSelected ? 'flat' : item.isToday ? 'outlined' : 'text',
'aria-label': getDateAriaLabel(item),
'aria-current': item.isToday ? 'date' : undefined,
onClick: () => onClick(item.date)
},
item,
i
};
const isSelected = props.multiple === 'range' && model.value.length === 2 ? adapter.isWithinRange(item.date, model.value) : model.value.some(selectedDate => adapter.isSameDay(selectedDate, item.date));
if (atMax.value && !isSelected) {
item.isDisabled = true;
}
return _createElementVNode("div", {
"class": _normalizeClass(['v-date-picker-month__day', {
'v-date-picker-month__day--adjacent': item.isAdjacent,
'v-date-picker-month__day--hide-adjacent': item.isHidden,
'v-date-picker-month__day--selected': isSelected,
'v-date-picker-month__day--week-end': item.isWeekEnd,
'v-date-picker-month__day--week-start': item.isWeekStart
}]),
"data-v-date": !item.isDisabled ? item.isoDate : undefined
}, [(props.showAdjacentMonths || !item.isAdjacent) && (slots.day?.(slotProps) ?? _createVNode(VBtn, slotProps.props, {
default: () => [item.localized, genEvents(item.isoDate)]
}))]);
})])]
})]));
}
});
//# sourceMappingURL=VDatePickerMonth.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,74 @@
@use '../../styles/tools'
@use './variables' as *
@include tools.layer('components')
.v-date-picker-month
display: flex
justify-content: center
padding: $date-picker-month-padding
--v-date-picker-month-day-diff: 4px
.v-date-picker-month__weeks
display: flex
flex-direction: column
column-gap: $date-picker-month-column-gap
font-size: $date-picker-month-font-size
.v-date-picker-month__weekday
font-size: $date-picker-month-font-size
.v-date-picker-month__days
display: grid
grid-template-columns: repeat(var(--v-date-picker-days-in-week), min-content)
column-gap: $date-picker-month-column-gap
justify-content: space-around
width: 100%
.v-date-picker-month__day
align-items: center
display: flex
justify-content: center
position: relative
height: $date-picker-month-day-size
width: $date-picker-month-day-size
&--selected
.v-btn
background-color: rgb(var(--v-theme-surface-variant))
color: rgb(var(--v-theme-on-surface-variant))
.v-btn.v-date-picker-month__day-btn
--v-btn-height: #{$date-picker-month-btn-height}
--v-btn-size: #{$date-picker-month-btn-size}
&--week
font-size: var(--v-btn-size)
.v-date-picker-month__day--adjacent
opacity: 0.5
.v-date-picker-month__day--hide-adjacent
opacity: 0
.v-date-picker-month__events
height: $date-picker-event-size
left: 0
text-indent: 0
position: absolute
text-align: center
white-space: pre
width: 100%
> div
height: $date-picker-event-size
margin: $date-picker-event-margin
width: $date-picker-event-size
margin-bottom: -1px
.v-badge--dot .v-badge__badge
border-radius: $date-picker-event-border-radius
height: $date-picker-event-size
width: $date-picker-event-size
.v-date-picker-month__day .v-date-picker-month__events
bottom: $date-picker-event-date-bottom
@@ -0,0 +1,21 @@
@layer vuetify-components {
.v-date-picker-months {
height: 288px;
}
.v-date-picker-months__content {
align-items: center;
display: grid;
flex: 1 1;
height: inherit;
justify-content: space-around;
grid-template-columns: repeat(2, 1fr);
grid-gap: 0px 24px;
padding-inline-start: 36px;
padding-inline-end: 36px;
}
.v-date-picker-months__content .v-btn {
text-transform: none;
padding-inline-start: 8px;
padding-inline-end: 8px;
}
}
@@ -0,0 +1,256 @@
import type { PropType } from 'vue';
export type VDatePickerMonthsSlots = {
month: {
month: {
text: string;
value: number;
};
i: number;
props: {
onClick: () => void;
};
};
};
export declare const makeVDatePickerMonthsProps: <Defaults extends {
color?: unknown;
height?: unknown;
min?: unknown;
max?: unknown;
modelValue?: unknown;
year?: unknown;
allowedMonths?: unknown;
} = {}>(defaults?: Defaults | undefined) => {
color: unknown extends Defaults["color"] ? StringConstructor : {
type: PropType<unknown extends Defaults["color"] ? string : string | Defaults["color"]>;
default: unknown extends Defaults["color"] ? string : string | Defaults["color"];
};
height: unknown extends Defaults["height"] ? (NumberConstructor | StringConstructor)[] : {
type: PropType<unknown extends Defaults["height"] ? string | number : string | number | Defaults["height"]>;
default: unknown extends Defaults["height"] ? string | number : Defaults["height"] | NonNullable<string | number>;
};
min: unknown extends Defaults["min"] ? PropType<unknown> : {
type: PropType<unknown extends Defaults["min"] ? unknown : unknown>;
default: unknown extends Defaults["min"] ? unknown : {} | Defaults["min"];
};
max: unknown extends Defaults["max"] ? PropType<unknown> : {
type: PropType<unknown extends Defaults["max"] ? unknown : unknown>;
default: unknown extends Defaults["max"] ? unknown : {} | Defaults["max"];
};
modelValue: unknown extends Defaults["modelValue"] ? NumberConstructor : {
type: PropType<unknown extends Defaults["modelValue"] ? number : number | Defaults["modelValue"]>;
default: unknown extends Defaults["modelValue"] ? number : number | Defaults["modelValue"];
};
year: unknown extends Defaults["year"] ? NumberConstructor : {
type: PropType<unknown extends Defaults["year"] ? number : number | Defaults["year"]>;
default: unknown extends Defaults["year"] ? number : number | Defaults["year"];
};
allowedMonths: unknown extends Defaults["allowedMonths"] ? PropType<number[] | ((date: number) => boolean)> : {
type: PropType<unknown extends Defaults["allowedMonths"] ? number[] | ((date: number) => boolean) : number[] | ((date: number) => boolean) | Defaults["allowedMonths"]>;
default: unknown extends Defaults["allowedMonths"] ? number[] | ((date: number) => boolean) : Defaults["allowedMonths"] | NonNullable<number[] | ((date: number) => boolean)>;
};
};
export declare const VDatePickerMonths: {
new (...args: any[]): import("vue").CreateComponentPublicInstanceWithMixins<{} & {
color?: string | undefined;
height?: string | number | undefined;
min?: unknown;
max?: unknown;
modelValue?: number | undefined;
year?: number | undefined;
allowedMonths?: number[] | ((date: number) => boolean) | undefined;
} & {
$children?: {
month?: ((arg: {
month: {
text: string;
value: number;
};
i: number;
props: {
onClick: () => void;
};
}) => import("vue").VNodeChild) | undefined;
} | {
$stable?: boolean;
} | {} | import("vue").VNodeChild;
'v-slots'?: {
month?: false | ((arg: {
month: {
text: string;
value: number;
};
i: number;
props: {
onClick: () => void;
};
}) => import("vue").VNodeChild) | undefined;
} | undefined;
} & {
"v-slot:month"?: false | ((arg: {
month: {
text: string;
value: number;
};
i: number;
props: {
onClick: () => void;
};
}) => import("vue").VNodeChild) | undefined;
} & {
"onUpdate:modelValue"?: ((date: any) => any) | undefined;
}, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
'update:modelValue': (date: any) => true;
}, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, {}, true, {}, import("vue").SlotsType<Partial<{
month: (arg: {
month: {
text: string;
value: number;
};
i: number;
props: {
onClick: () => void;
};
}) => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>[];
}>>, import("vue").GlobalComponents, import("vue").GlobalDirectives, string, {}, any, import("vue").ComponentProvideOptions, {
P: {};
B: {};
D: {};
C: {};
M: {};
Defaults: {};
}, {} & {
color?: string | undefined;
height?: string | number | undefined;
min?: unknown;
max?: unknown;
modelValue?: number | undefined;
year?: number | undefined;
allowedMonths?: number[] | ((date: number) => boolean) | undefined;
} & {
$children?: {
month?: ((arg: {
month: {
text: string;
value: number;
};
i: number;
props: {
onClick: () => void;
};
}) => import("vue").VNodeChild) | undefined;
} | {
$stable?: boolean;
} | {} | import("vue").VNodeChild;
'v-slots'?: {
month?: false | ((arg: {
month: {
text: string;
value: number;
};
i: number;
props: {
onClick: () => void;
};
}) => import("vue").VNodeChild) | undefined;
} | undefined;
} & {
"v-slot:month"?: false | ((arg: {
month: {
text: string;
value: number;
};
i: number;
props: {
onClick: () => void;
};
}) => import("vue").VNodeChild) | undefined;
} & {
"onUpdate:modelValue"?: ((date: any) => any) | undefined;
}, {}, {}, {}, {}, {}>;
__isFragment?: never;
__isTeleport?: never;
__isSuspense?: never;
} & import("vue").ComponentOptionsBase<{} & {
color?: string | undefined;
height?: string | number | undefined;
min?: unknown;
max?: unknown;
modelValue?: number | undefined;
year?: number | undefined;
allowedMonths?: number[] | ((date: number) => boolean) | undefined;
} & {
$children?: {
month?: ((arg: {
month: {
text: string;
value: number;
};
i: number;
props: {
onClick: () => void;
};
}) => import("vue").VNodeChild) | undefined;
} | {
$stable?: boolean;
} | {} | import("vue").VNodeChild;
'v-slots'?: {
month?: false | ((arg: {
month: {
text: string;
value: number;
};
i: number;
props: {
onClick: () => void;
};
}) => import("vue").VNodeChild) | undefined;
} | undefined;
} & {
"v-slot:month"?: false | ((arg: {
month: {
text: string;
value: number;
};
i: number;
props: {
onClick: () => void;
};
}) => import("vue").VNodeChild) | undefined;
} & {
"onUpdate:modelValue"?: ((date: any) => any) | undefined;
}, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
'update:modelValue': (date: any) => true;
}, string, {}, {}, string, import("vue").SlotsType<Partial<{
month: (arg: {
month: {
text: string;
value: number;
};
i: number;
props: {
onClick: () => void;
};
}) => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>[];
}>>, import("vue").GlobalComponents, import("vue").GlobalDirectives, string, import("vue").ComponentProvideOptions> & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps & import("../../util/index.js").FilterPropsOptions<{
color: StringConstructor;
height: (NumberConstructor | StringConstructor)[];
min: PropType<unknown>;
max: PropType<unknown>;
modelValue: NumberConstructor;
year: NumberConstructor;
allowedMonths: PropType<number[] | ((date: number) => boolean)>;
}, import("vue").ExtractPropTypes<{
color: StringConstructor;
height: (NumberConstructor | StringConstructor)[];
min: PropType<unknown>;
max: PropType<unknown>;
modelValue: NumberConstructor;
year: NumberConstructor;
allowedMonths: PropType<number[] | ((date: number) => boolean)>;
}>>;
export type VDatePickerMonths = InstanceType<typeof VDatePickerMonths>;
@@ -0,0 +1,98 @@
import { mergeProps as _mergeProps, createVNode as _createVNode, createElementVNode as _createElementVNode } from "vue";
// Styles
import "./VDatePickerMonths.css";
// Components
import { VBtn } from "../VBtn/index.js"; // Composables
import { useDate } from "../../composables/date/index.js";
import { useProxiedModel } from "../../composables/proxiedModel.js"; // Utilities
import { computed, watchEffect } from 'vue';
import { convertToUnit, createRange, genericComponent, propsFactory, useRender } from "../../util/index.js"; // Types
export const makeVDatePickerMonthsProps = propsFactory({
color: String,
height: [String, Number],
min: null,
max: null,
modelValue: Number,
year: Number,
allowedMonths: [Array, Function]
}, 'VDatePickerMonths');
export const VDatePickerMonths = genericComponent()({
name: 'VDatePickerMonths',
props: makeVDatePickerMonthsProps(),
emits: {
'update:modelValue': date => true
},
setup(props, {
emit,
slots
}) {
const adapter = useDate();
const model = useProxiedModel(props, 'modelValue');
const months = computed(() => {
let date = adapter.startOfYear(adapter.date());
if (props.year) {
date = adapter.setYear(date, props.year);
}
return createRange(12).map(i => {
const text = adapter.format(date, 'monthShort');
const label = adapter.format(date, 'month');
const isDisabled = !!(!isMonthAllowed(i) || props.min && adapter.isAfter(adapter.startOfMonth(adapter.date(props.min)), date) || props.max && adapter.isAfter(date, adapter.startOfMonth(adapter.date(props.max))));
date = adapter.getNextMonth(date);
return {
isDisabled,
text,
label,
value: i
};
});
});
watchEffect(() => {
model.value = model.value ?? adapter.getMonth(adapter.date());
});
function isMonthAllowed(month) {
if (Array.isArray(props.allowedMonths) && props.allowedMonths.length) {
return props.allowedMonths.includes(month);
}
if (typeof props.allowedMonths === 'function') {
return props.allowedMonths(month);
}
return true;
}
useRender(() => _createElementVNode("div", {
"class": "v-date-picker-months",
"style": {
height: convertToUnit(props.height)
}
}, [_createElementVNode("div", {
"class": "v-date-picker-months__content"
}, [months.value.map((month, i) => {
const btnProps = {
active: model.value === i,
ariaLabel: month.label,
color: model.value === i ? props.color : undefined,
disabled: month.isDisabled,
rounded: true,
text: month.text,
variant: model.value === month.value ? 'flat' : 'text',
onClick: () => onClick(i)
};
function onClick(i) {
if (model.value === i) {
emit('update:modelValue', model.value);
return;
}
model.value = i;
}
return slots.month?.({
month,
i,
props: btnProps
}) ?? _createVNode(VBtn, _mergeProps({
"key": "month"
}, btnProps), null);
})])]));
return {};
}
});
//# sourceMappingURL=VDatePickerMonths.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,22 @@
@use '../../styles/tools'
@use './variables' as *
@include tools.layer('components')
.v-date-picker-months
height: $date-picker-months-height
.v-date-picker-months__content
align-items: center
display: grid
flex: 1 1
height: inherit
justify-content: space-around
grid-template-columns: repeat(2, 1fr)
grid-gap: $date-picker-months-grid-gap
padding-inline-start: 36px
padding-inline-end: 36px
.v-btn
text-transform: none
padding-inline-start: 8px
padding-inline-end: 8px
@@ -0,0 +1,17 @@
@layer vuetify-components {
.v-date-picker-years {
height: 288px;
overflow-y: scroll;
}
.v-date-picker-years__content {
display: grid;
flex: 1 1;
justify-content: space-around;
grid-template-columns: repeat(3, 1fr);
gap: 8px 24px;
padding-inline: 32px;
}
.v-date-picker-years__content .v-btn {
padding-inline: 8px;
}
}
@@ -0,0 +1,306 @@
import type { PropType } from 'vue';
export type VDatePickerYearsSlots = {
year: {
year: {
text: string;
value: number;
};
i: number;
props: {
active: boolean;
color?: string;
rounded: boolean;
text: string;
variant: 'flat' | 'text';
onClick: () => void;
};
};
};
export declare const makeVDatePickerYearsProps: <Defaults extends {
color?: unknown;
height?: unknown;
min?: unknown;
max?: unknown;
modelValue?: unknown;
allowedYears?: unknown;
} = {}>(defaults?: Defaults | undefined) => {
color: unknown extends Defaults["color"] ? StringConstructor : {
type: PropType<unknown extends Defaults["color"] ? string : string | Defaults["color"]>;
default: unknown extends Defaults["color"] ? string : string | Defaults["color"];
};
height: unknown extends Defaults["height"] ? (NumberConstructor | StringConstructor)[] : {
type: PropType<unknown extends Defaults["height"] ? string | number : string | number | Defaults["height"]>;
default: unknown extends Defaults["height"] ? string | number : Defaults["height"] | NonNullable<string | number>;
};
min: unknown extends Defaults["min"] ? PropType<unknown> : {
type: PropType<unknown extends Defaults["min"] ? unknown : unknown>;
default: unknown extends Defaults["min"] ? unknown : {} | Defaults["min"];
};
max: unknown extends Defaults["max"] ? PropType<unknown> : {
type: PropType<unknown extends Defaults["max"] ? unknown : unknown>;
default: unknown extends Defaults["max"] ? unknown : {} | Defaults["max"];
};
modelValue: unknown extends Defaults["modelValue"] ? NumberConstructor : {
type: PropType<unknown extends Defaults["modelValue"] ? number : number | Defaults["modelValue"]>;
default: unknown extends Defaults["modelValue"] ? number : number | Defaults["modelValue"];
};
allowedYears: unknown extends Defaults["allowedYears"] ? PropType<number[] | ((date: number) => boolean)> : {
type: PropType<unknown extends Defaults["allowedYears"] ? number[] | ((date: number) => boolean) : number[] | ((date: number) => boolean) | Defaults["allowedYears"]>;
default: unknown extends Defaults["allowedYears"] ? number[] | ((date: number) => boolean) : Defaults["allowedYears"] | NonNullable<number[] | ((date: number) => boolean)>;
};
};
export declare const VDatePickerYears: {
new (...args: any[]): import("vue").CreateComponentPublicInstanceWithMixins<{} & {
color?: string | undefined;
height?: string | number | undefined;
min?: unknown;
max?: unknown;
modelValue?: number | undefined;
allowedYears?: number[] | ((date: number) => boolean) | undefined;
} & {
$children?: {
year?: ((arg: {
year: {
text: string;
value: number;
};
i: number;
props: {
active: boolean;
color?: string;
rounded: boolean;
text: string;
variant: 'flat' | 'text';
onClick: () => void;
};
}) => import("vue").VNodeChild) | undefined;
} | {
$stable?: boolean;
} | {} | import("vue").VNodeChild;
'v-slots'?: {
year?: false | ((arg: {
year: {
text: string;
value: number;
};
i: number;
props: {
active: boolean;
color?: string;
rounded: boolean;
text: string;
variant: 'flat' | 'text';
onClick: () => void;
};
}) => import("vue").VNodeChild) | undefined;
} | undefined;
} & {
"v-slot:year"?: false | ((arg: {
year: {
text: string;
value: number;
};
i: number;
props: {
active: boolean;
color?: string;
rounded: boolean;
text: string;
variant: 'flat' | 'text';
onClick: () => void;
};
}) => import("vue").VNodeChild) | undefined;
} & {
"onUpdate:modelValue"?: ((year: number) => any) | undefined;
}, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
'update:modelValue': (year: number) => true;
}, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, {}, true, {}, import("vue").SlotsType<Partial<{
year: (arg: {
year: {
text: string;
value: number;
};
i: number;
props: {
active: boolean;
color?: string;
rounded: boolean;
text: string;
variant: 'flat' | 'text';
onClick: () => void;
};
}) => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>[];
}>>, import("vue").GlobalComponents, import("vue").GlobalDirectives, string, {}, any, import("vue").ComponentProvideOptions, {
P: {};
B: {};
D: {};
C: {};
M: {};
Defaults: {};
}, {} & {
color?: string | undefined;
height?: string | number | undefined;
min?: unknown;
max?: unknown;
modelValue?: number | undefined;
allowedYears?: number[] | ((date: number) => boolean) | undefined;
} & {
$children?: {
year?: ((arg: {
year: {
text: string;
value: number;
};
i: number;
props: {
active: boolean;
color?: string;
rounded: boolean;
text: string;
variant: 'flat' | 'text';
onClick: () => void;
};
}) => import("vue").VNodeChild) | undefined;
} | {
$stable?: boolean;
} | {} | import("vue").VNodeChild;
'v-slots'?: {
year?: false | ((arg: {
year: {
text: string;
value: number;
};
i: number;
props: {
active: boolean;
color?: string;
rounded: boolean;
text: string;
variant: 'flat' | 'text';
onClick: () => void;
};
}) => import("vue").VNodeChild) | undefined;
} | undefined;
} & {
"v-slot:year"?: false | ((arg: {
year: {
text: string;
value: number;
};
i: number;
props: {
active: boolean;
color?: string;
rounded: boolean;
text: string;
variant: 'flat' | 'text';
onClick: () => void;
};
}) => import("vue").VNodeChild) | undefined;
} & {
"onUpdate:modelValue"?: ((year: number) => any) | undefined;
}, {}, {}, {}, {}, {}>;
__isFragment?: never;
__isTeleport?: never;
__isSuspense?: never;
} & import("vue").ComponentOptionsBase<{} & {
color?: string | undefined;
height?: string | number | undefined;
min?: unknown;
max?: unknown;
modelValue?: number | undefined;
allowedYears?: number[] | ((date: number) => boolean) | undefined;
} & {
$children?: {
year?: ((arg: {
year: {
text: string;
value: number;
};
i: number;
props: {
active: boolean;
color?: string;
rounded: boolean;
text: string;
variant: 'flat' | 'text';
onClick: () => void;
};
}) => import("vue").VNodeChild) | undefined;
} | {
$stable?: boolean;
} | {} | import("vue").VNodeChild;
'v-slots'?: {
year?: false | ((arg: {
year: {
text: string;
value: number;
};
i: number;
props: {
active: boolean;
color?: string;
rounded: boolean;
text: string;
variant: 'flat' | 'text';
onClick: () => void;
};
}) => import("vue").VNodeChild) | undefined;
} | undefined;
} & {
"v-slot:year"?: false | ((arg: {
year: {
text: string;
value: number;
};
i: number;
props: {
active: boolean;
color?: string;
rounded: boolean;
text: string;
variant: 'flat' | 'text';
onClick: () => void;
};
}) => import("vue").VNodeChild) | undefined;
} & {
"onUpdate:modelValue"?: ((year: number) => any) | undefined;
}, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
'update:modelValue': (year: number) => true;
}, string, {}, {}, string, import("vue").SlotsType<Partial<{
year: (arg: {
year: {
text: string;
value: number;
};
i: number;
props: {
active: boolean;
color?: string;
rounded: boolean;
text: string;
variant: 'flat' | 'text';
onClick: () => void;
};
}) => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>[];
}>>, import("vue").GlobalComponents, import("vue").GlobalDirectives, string, import("vue").ComponentProvideOptions> & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps & import("../../util/index.js").FilterPropsOptions<{
color: StringConstructor;
height: (NumberConstructor | StringConstructor)[];
min: PropType<unknown>;
max: PropType<unknown>;
modelValue: NumberConstructor;
allowedYears: PropType<number[] | ((date: number) => boolean)>;
}, import("vue").ExtractPropTypes<{
color: StringConstructor;
height: (NumberConstructor | StringConstructor)[];
min: PropType<unknown>;
max: PropType<unknown>;
modelValue: NumberConstructor;
allowedYears: PropType<number[] | ((date: number) => boolean)>;
}>>;
export type VDatePickerYears = InstanceType<typeof VDatePickerYears>;
@@ -0,0 +1,125 @@
import { mergeProps as _mergeProps, createVNode as _createVNode, createElementVNode as _createElementVNode, withDirectives as _withDirectives } from "vue";
// Styles
import "./VDatePickerYears.css";
// Components
import { VBtn } from "../VBtn/index.js"; // Composables
import { useDate } from "../../composables/date/index.js";
import { useProxiedModel } from "../../composables/proxiedModel.js"; // Directives
import vIntersect from "../../directives/intersect/index.js"; // Utilities
import { computed, shallowRef, watchEffect } from 'vue';
import { convertToUnit, createRange, genericComponent, propsFactory, templateRef, useRender } from "../../util/index.js"; // Types
// Types
export const makeVDatePickerYearsProps = propsFactory({
color: String,
height: [String, Number],
min: null,
max: null,
modelValue: Number,
allowedYears: [Array, Function]
}, 'VDatePickerYears');
export const VDatePickerYears = genericComponent()({
name: 'VDatePickerYears',
props: makeVDatePickerYearsProps(),
directives: {
vIntersect
},
emits: {
'update:modelValue': year => true
},
setup(props, {
emit,
slots
}) {
const adapter = useDate();
const model = useProxiedModel(props, 'modelValue');
const hasFocusedItem = shallowRef(false);
const years = computed(() => {
const year = adapter.getYear(adapter.date());
let min = year - 100;
let max = year + 52;
if (props.min) {
min = adapter.getYear(adapter.date(props.min));
}
if (props.max) {
max = adapter.getYear(adapter.date(props.max));
}
let date = adapter.startOfYear(adapter.date());
date = adapter.setYear(date, min);
return createRange(max - min + 1, min).map(i => {
const text = adapter.format(date, 'year');
date = adapter.setYear(date, adapter.getYear(date) + 1);
return {
text,
value: i,
isDisabled: !isYearAllowed(i)
};
});
});
watchEffect(() => {
model.value = model.value ?? adapter.getYear(adapter.date());
});
const containerRef = templateRef();
const yearRef = templateRef();
function focusSelectedYear() {
const container = containerRef.el;
const target = yearRef.el;
if (!container || !target) return;
const containerRect = container.getBoundingClientRect();
const targetRect = target.getBoundingClientRect();
container.scrollTop += targetRect.top - containerRect.top - container.clientHeight / 2 + targetRect.height / 2;
}
function isYearAllowed(year) {
if (Array.isArray(props.allowedYears) && props.allowedYears.length) {
return props.allowedYears.includes(year);
}
if (typeof props.allowedYears === 'function') {
return props.allowedYears(year);
}
return true;
}
useRender(() => _withDirectives(_createElementVNode("div", {
"class": "v-date-picker-years",
"ref": containerRef,
"style": {
height: convertToUnit(props.height)
}
}, [_createElementVNode("div", {
"class": "v-date-picker-years__content",
"onFocus": () => yearRef.el?.focus(),
"onFocusin": () => hasFocusedItem.value = true,
"onFocusout": () => hasFocusedItem.value = false,
"tabindex": hasFocusedItem.value ? -1 : 0
}, [years.value.map((year, i) => {
const btnProps = {
ref: model.value === year.value ? yearRef : undefined,
active: model.value === year.value,
color: model.value === year.value ? props.color : undefined,
rounded: true,
text: year.text,
disabled: year.isDisabled,
variant: model.value === year.value ? 'flat' : 'text',
onClick: () => {
if (model.value === year.value) {
emit('update:modelValue', model.value);
return;
}
model.value = year.value;
}
};
return slots.year?.({
year,
i,
props: btnProps
}) ?? _createVNode(VBtn, _mergeProps({
"key": "month"
}, btnProps), null);
})])]), [[vIntersect, {
handler: focusSelectedYear
}, null, {
once: true
}]]));
return {};
}
});
//# sourceMappingURL=VDatePickerYears.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,18 @@
@use '../../styles/tools'
@use './variables' as *
@include tools.layer('components')
.v-date-picker-years
height: $date-picker-years-height
overflow-y: scroll
.v-date-picker-years__content
display: grid
flex: 1 1
justify-content: space-around
grid-template-columns: repeat(3, 1fr)
gap: 8px 24px
padding-inline: $date-picker-years-padding-inline
.v-btn
padding-inline: 8px
@@ -0,0 +1,28 @@
$date-picker-width: 328px !default;
$date-picker-show-week-width: 368px !default;
$date-picker-landscape-header-width: 170px !default;
$date-picker-controls-height: var(--v-date-picker-controls-height, 56px) !default;
$date-picker-controls-padding: 4px 12px !default;
$date-picker-controls-docked-toggle-btn-padding: 12px 8px !default;
$date-picker-controls-docked-toggle-append-margin-inline: 4px -4px !default;
$date-picker-header-height: 70px !default;
$date-picker-month-btn-height: 24px !default;
$date-picker-month-btn-size: 0.875rem !default;
$date-picker-month-column-gap: 4px !default;
$date-picker-month-day-size: 40px !default;
$date-picker-month-font-size: 0.875rem !default;
$date-picker-month-padding: 0 12px 8px !default;
$date-picker-months-grid-gap: 0px 24px !default;
$date-picker-months-height: 288px !default;
$date-picker-years-height: 288px !default;
$date-picker-years-padding-inline: 32px !default;
$date-picker-event-size: 8px !default;
$date-picker-event-border-radius: 4px !default;
$date-picker-event-margin: 0 1px !default;
$date-picker-event-date-bottom: 8px !default;
+6
View File
@@ -0,0 +1,6 @@
export { VDatePicker } from './VDatePicker.js';
export { VDatePickerControls } from './VDatePickerControls.js';
export { VDatePickerHeader } from './VDatePickerHeader.js';
export { VDatePickerMonth } from './VDatePickerMonth.js';
export { VDatePickerMonths } from './VDatePickerMonths.js';
export { VDatePickerYears } from './VDatePickerYears.js';
+7
View File
@@ -0,0 +1,7 @@
export { VDatePicker } from "./VDatePicker.js";
export { VDatePickerControls } from "./VDatePickerControls.js";
export { VDatePickerHeader } from "./VDatePickerHeader.js";
export { VDatePickerMonth } from "./VDatePickerMonth.js";
export { VDatePickerMonths } from "./VDatePickerMonths.js";
export { VDatePickerYears } from "./VDatePickerYears.js";
//# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
{"version":3,"file":"index.js","names":["VDatePicker","VDatePickerControls","VDatePickerHeader","VDatePickerMonth","VDatePickerMonths","VDatePickerYears"],"sources":["../../../src/components/VDatePicker/index.ts"],"sourcesContent":["export { VDatePicker } from './VDatePicker'\nexport { VDatePickerControls } from './VDatePickerControls'\nexport { VDatePickerHeader } from './VDatePickerHeader'\nexport { VDatePickerMonth } from './VDatePickerMonth'\nexport { VDatePickerMonths } from './VDatePickerMonths'\nexport { VDatePickerYears } from './VDatePickerYears'\n"],"mappings":"SAASA,WAAW;AAAA,SACXC,mBAAmB;AAAA,SACnBC,iBAAiB;AAAA,SACjBC,gBAAgB;AAAA,SAChBC,iBAAiB;AAAA,SACjBC,gBAAgB","ignoreList":[]}