routie dev init since i didn't adhere to any proper guidance up until now
This commit is contained in:
Generated
Vendored
+193
@@ -0,0 +1,193 @@
|
||||
import { validateTimestamp, validateWeekdays } from '../util/timestamp.js';
|
||||
import type { PropType } from 'vue';
|
||||
import type { CalendarFormatter, CalendarTimestamp } from '../types.js';
|
||||
import type { ColorValue } from '../../../composables/color.js';
|
||||
export declare const makeCalendarBaseProps: <Defaults extends {
|
||||
start?: unknown;
|
||||
end?: unknown;
|
||||
weekdays?: unknown;
|
||||
firstDayOfWeek?: unknown;
|
||||
firstDayOfYear?: unknown;
|
||||
weekdayFormat?: unknown;
|
||||
dayFormat?: unknown;
|
||||
locale?: unknown;
|
||||
now?: unknown;
|
||||
type?: unknown;
|
||||
} = {}>(defaults?: Defaults | undefined) => {
|
||||
start: unknown extends Defaults["start"] ? {
|
||||
type: (DateConstructor | NumberConstructor | StringConstructor)[];
|
||||
validate: typeof validateTimestamp;
|
||||
default: () => string;
|
||||
} : Omit<{
|
||||
type: (DateConstructor | NumberConstructor | StringConstructor)[];
|
||||
validate: typeof validateTimestamp;
|
||||
default: () => string;
|
||||
}, "default" | "type"> & {
|
||||
type: PropType<unknown extends Defaults["start"] ? string | number | Date : string | number | Date | Defaults["start"]>;
|
||||
default: unknown extends Defaults["start"] ? string | number | Date : Defaults["start"] | NonNullable<string | number | Date>;
|
||||
};
|
||||
end: unknown extends Defaults["end"] ? {
|
||||
type: (DateConstructor | NumberConstructor | StringConstructor)[];
|
||||
validate: typeof validateTimestamp;
|
||||
} : Omit<{
|
||||
type: (DateConstructor | NumberConstructor | StringConstructor)[];
|
||||
validate: typeof validateTimestamp;
|
||||
}, "default" | "type"> & {
|
||||
type: PropType<unknown extends Defaults["end"] ? string | number | Date : string | number | Date | Defaults["end"]>;
|
||||
default: unknown extends Defaults["end"] ? string | number | Date : Defaults["end"] | NonNullable<string | number | Date>;
|
||||
};
|
||||
weekdays: unknown extends Defaults["weekdays"] ? {
|
||||
type: PropType<number[] | string>;
|
||||
default: () => number[];
|
||||
validate: typeof validateWeekdays;
|
||||
} : Omit<{
|
||||
type: PropType<number[] | string>;
|
||||
default: () => number[];
|
||||
validate: typeof validateWeekdays;
|
||||
}, "default" | "type"> & {
|
||||
type: PropType<unknown extends Defaults["weekdays"] ? string | number[] : string | number[] | Defaults["weekdays"]>;
|
||||
default: unknown extends Defaults["weekdays"] ? string | number[] : Defaults["weekdays"] | NonNullable<string | number[]>;
|
||||
};
|
||||
firstDayOfWeek: unknown extends Defaults["firstDayOfWeek"] ? (NumberConstructor | StringConstructor)[] : {
|
||||
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"] ? (NumberConstructor | StringConstructor)[] : {
|
||||
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"] ? {
|
||||
type: PropType<CalendarFormatter>;
|
||||
default: null;
|
||||
} : Omit<{
|
||||
type: PropType<CalendarFormatter>;
|
||||
default: null;
|
||||
}, "default" | "type"> & {
|
||||
type: PropType<unknown extends Defaults["weekdayFormat"] ? CalendarFormatter : CalendarFormatter | Defaults["weekdayFormat"]>;
|
||||
default: unknown extends Defaults["weekdayFormat"] ? CalendarFormatter : CalendarFormatter | Defaults["weekdayFormat"];
|
||||
};
|
||||
dayFormat: unknown extends Defaults["dayFormat"] ? {
|
||||
type: PropType<CalendarFormatter>;
|
||||
default: null;
|
||||
} : Omit<{
|
||||
type: PropType<CalendarFormatter>;
|
||||
default: null;
|
||||
}, "default" | "type"> & {
|
||||
type: PropType<unknown extends Defaults["dayFormat"] ? CalendarFormatter : CalendarFormatter | Defaults["dayFormat"]>;
|
||||
default: unknown extends Defaults["dayFormat"] ? CalendarFormatter : CalendarFormatter | Defaults["dayFormat"];
|
||||
};
|
||||
locale: unknown extends Defaults["locale"] ? StringConstructor : {
|
||||
type: PropType<unknown extends Defaults["locale"] ? string : string | Defaults["locale"]>;
|
||||
default: unknown extends Defaults["locale"] ? string : string | Defaults["locale"];
|
||||
};
|
||||
now: unknown extends Defaults["now"] ? {
|
||||
type: StringConstructor;
|
||||
validator: typeof validateTimestamp;
|
||||
} : Omit<{
|
||||
type: StringConstructor;
|
||||
validator: typeof validateTimestamp;
|
||||
}, "default" | "type"> & {
|
||||
type: PropType<unknown extends Defaults["now"] ? string : string | Defaults["now"]>;
|
||||
default: unknown extends Defaults["now"] ? string : string | Defaults["now"];
|
||||
};
|
||||
type: unknown extends Defaults["type"] ? {
|
||||
type: PropType<'month' | 'week' | 'day' | '4day' | 'custom-weekly' | 'custom-daily' | 'category'>;
|
||||
default: string;
|
||||
} : Omit<{
|
||||
type: PropType<'month' | 'week' | 'day' | '4day' | 'custom-weekly' | 'custom-daily' | 'category'>;
|
||||
default: string;
|
||||
}, "default" | "type"> & {
|
||||
type: PropType<unknown extends Defaults["type"] ? "4day" | "category" | "custom-daily" | "custom-weekly" | "day" | "month" | "week" : "4day" | "category" | "custom-daily" | "custom-weekly" | "day" | "month" | "week" | Defaults["type"]>;
|
||||
default: unknown extends Defaults["type"] ? "4day" | "category" | "custom-daily" | "custom-weekly" | "day" | "month" | "week" : Defaults["type"] | NonNullable<"4day" | "category" | "custom-daily" | "custom-weekly" | "day" | "month" | "week">;
|
||||
};
|
||||
};
|
||||
export interface CalendarBaseProps {
|
||||
modelValue?: string | number | Date;
|
||||
categoryDays?: string | number;
|
||||
start: string | number | Date;
|
||||
end: string | number | Date | undefined;
|
||||
weekdays: string | number[];
|
||||
firstDayOfWeek: number | string | undefined;
|
||||
firstDayOfYear: number | string | undefined;
|
||||
weekdayFormat: CalendarFormatter | string | undefined;
|
||||
dayFormat: CalendarFormatter | string | undefined;
|
||||
locale: string | undefined;
|
||||
now: string | undefined;
|
||||
type: 'month' | 'week' | 'day' | '4day' | 'custom-weekly' | 'custom-daily' | 'category';
|
||||
}
|
||||
export declare function useCalendarBase(props: CalendarBaseProps): {
|
||||
times: {
|
||||
now: {
|
||||
date: string;
|
||||
time: string;
|
||||
year: number;
|
||||
month: number;
|
||||
day: number;
|
||||
weekday: number;
|
||||
hour: number;
|
||||
minute: number;
|
||||
hasDay: boolean;
|
||||
hasTime: boolean;
|
||||
past: boolean;
|
||||
present: boolean;
|
||||
future: boolean;
|
||||
category?: import("../types.js").CalendarCategory;
|
||||
};
|
||||
today: {
|
||||
date: string;
|
||||
time: string;
|
||||
year: number;
|
||||
month: number;
|
||||
day: number;
|
||||
weekday: number;
|
||||
hour: number;
|
||||
minute: number;
|
||||
hasDay: boolean;
|
||||
hasTime: boolean;
|
||||
past: boolean;
|
||||
present: boolean;
|
||||
future: boolean;
|
||||
category?: import("../types.js").CalendarCategory;
|
||||
};
|
||||
};
|
||||
locale: {
|
||||
name: string;
|
||||
decimalSeparator: import("vue").ShallowRef<string>;
|
||||
messages: import("vue").Ref<import("../../../types.js").LocaleMessages, import("../../../types.js").LocaleMessages>;
|
||||
current: import("vue").Ref<string, string>;
|
||||
fallback: import("vue").Ref<string, string>;
|
||||
t: (key: string, ...params: unknown[]) => string;
|
||||
n: (value: number) => string;
|
||||
provide: (props: import("../../../types.js").LocaleOptions) => import("../../../types.js").LocaleInstance;
|
||||
isRtl: import("vue").Ref<boolean, boolean>;
|
||||
rtl: import("vue").Ref<Record<string, boolean>, Record<string, boolean>>;
|
||||
rtlClasses: import("vue").Ref<string, string>;
|
||||
};
|
||||
parsedValue: import("vue").ComputedRef<CalendarTimestamp>;
|
||||
parsedWeekdays: import("vue").ComputedRef<number[]>;
|
||||
effectiveWeekdays: import("vue").ComputedRef<number[]>;
|
||||
weekdaySkips: import("vue").ComputedRef<number[]>;
|
||||
parsedStart: import("vue").ComputedRef<CalendarTimestamp>;
|
||||
parsedEnd: import("vue").ComputedRef<CalendarTimestamp>;
|
||||
days: import("vue").ComputedRef<CalendarTimestamp[]>;
|
||||
dayFormatter: import("vue").ComputedRef<CalendarFormatter>;
|
||||
weekdayFormatter: import("vue").ComputedRef<CalendarFormatter>;
|
||||
getColorProps: (colors: {
|
||||
background?: ColorValue;
|
||||
text?: ColorValue;
|
||||
}) => {
|
||||
class: string[];
|
||||
style: import("vue").CSSProperties;
|
||||
};
|
||||
getRelativeClasses: (timestamp: CalendarTimestamp, outside?: boolean) => {
|
||||
'v-present': boolean;
|
||||
'v-past': boolean;
|
||||
'v-future': boolean;
|
||||
'v-outside': boolean;
|
||||
};
|
||||
getWeekNumber: (timestamp: CalendarTimestamp) => number;
|
||||
getStartOfWeek: (timestamp: CalendarTimestamp) => CalendarTimestamp;
|
||||
getEndOfWeek: (timestamp: CalendarTimestamp) => CalendarTimestamp;
|
||||
getFormatter: (options: Intl.DateTimeFormatOptions) => CalendarFormatter;
|
||||
updateTimes: () => void;
|
||||
};
|
||||
Generated
Vendored
+160
@@ -0,0 +1,160 @@
|
||||
// Composables
|
||||
import { useTimes } from "./times.js";
|
||||
import { computeColor } from "../../../composables/color.js";
|
||||
import { useDate } from "../../../composables/date/index.js";
|
||||
import { provideLocale } from "../../../composables/locale.js"; // Utilities
|
||||
import { computed } from 'vue';
|
||||
import { createDayList, createNativeLocaleFormatter, getEndOfMonth, getEndOfWeek, getStartOfMonth, getStartOfWeek, getTimestampIdentifier, getWeekdaySkips, parseDate, parseTimestamp, validateTimestamp, validateWeekdays } from "../util/timestamp.js";
|
||||
import { propsFactory } from "../../../util/index.js"; // Types
|
||||
export const makeCalendarBaseProps = propsFactory({
|
||||
start: {
|
||||
type: [String, Number, Date],
|
||||
validate: validateTimestamp,
|
||||
default: () => parseDate(new Date()).date
|
||||
},
|
||||
end: {
|
||||
type: [String, Number, Date],
|
||||
validate: validateTimestamp
|
||||
},
|
||||
weekdays: {
|
||||
type: [Array, String],
|
||||
default: () => [0, 1, 2, 3, 4, 5, 6],
|
||||
validate: validateWeekdays
|
||||
},
|
||||
firstDayOfWeek: [Number, String],
|
||||
firstDayOfYear: [Number, String],
|
||||
weekdayFormat: {
|
||||
type: Function,
|
||||
default: null
|
||||
},
|
||||
dayFormat: {
|
||||
type: Function,
|
||||
default: null
|
||||
},
|
||||
locale: String,
|
||||
now: {
|
||||
type: String,
|
||||
validator: validateTimestamp
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'month'
|
||||
}
|
||||
}, 'VCalendar-base');
|
||||
export function useCalendarBase(props) {
|
||||
const {
|
||||
times,
|
||||
updateTimes
|
||||
} = useTimes({
|
||||
now: props.now
|
||||
});
|
||||
const locale = provideLocale(props);
|
||||
const adapter = useDate();
|
||||
const parsedStart = computed(() => {
|
||||
if (props.type === 'month') {
|
||||
return getStartOfMonth(parseTimestamp(props.start, true));
|
||||
}
|
||||
return parseTimestamp(props.start, true);
|
||||
});
|
||||
const parsedEnd = computed(() => {
|
||||
const start = parsedStart.value;
|
||||
const end = props.end ? parseTimestamp(props.end) || start : start;
|
||||
const value = getTimestampIdentifier(end) < getTimestampIdentifier(start) ? start : end;
|
||||
if (props.type === 'month') {
|
||||
return getEndOfMonth(value);
|
||||
}
|
||||
return value;
|
||||
});
|
||||
const parsedValue = computed(() => {
|
||||
return validateTimestamp(props.modelValue) ? parseTimestamp(props.modelValue, true) : parsedStart.value || times.today;
|
||||
});
|
||||
const parsedWeekdays = computed(() => {
|
||||
const weekdays = Array.isArray(props.weekdays) ? props.weekdays : (props.weekdays || '').split(',').map(x => parseInt(x, 10));
|
||||
const first = adapter.toJsDate(adapter.startOfWeek(adapter.date(), props.firstDayOfWeek)).getDay();
|
||||
return [...weekdays.toSorted().filter(v => v >= first), ...weekdays.toSorted().filter(v => v < first)];
|
||||
});
|
||||
const effectiveWeekdays = computed(() => {
|
||||
const start = parsedValue.value;
|
||||
const days = parseInt(String(props.categoryDays)) || 1;
|
||||
switch (props.type) {
|
||||
case 'day':
|
||||
return [start.weekday];
|
||||
case '4day':
|
||||
return [start.weekday, (start.weekday + 1) % 7, (start.weekday + 2) % 7, (start.weekday + 3) % 7];
|
||||
case 'category':
|
||||
return Array.from({
|
||||
length: days
|
||||
}, (_, i) => (start.weekday + i) % 7);
|
||||
default:
|
||||
return parsedWeekdays.value;
|
||||
}
|
||||
});
|
||||
const weekdaySkips = computed(() => {
|
||||
return getWeekdaySkips(parsedWeekdays.value);
|
||||
});
|
||||
const days = computed(() => {
|
||||
return createDayList(parsedStart.value, parsedEnd.value, times.today, weekdaySkips.value);
|
||||
});
|
||||
const dayFormatter = computed(() => {
|
||||
if (props.dayFormat) {
|
||||
return props.dayFormat;
|
||||
}
|
||||
return createNativeLocaleFormatter(locale.current.value, () => ({
|
||||
timeZone: 'UTC',
|
||||
day: 'numeric'
|
||||
}));
|
||||
});
|
||||
const weekdayFormatter = computed(() => {
|
||||
if (props.weekdayFormat) {
|
||||
return props.weekdayFormat;
|
||||
}
|
||||
return createNativeLocaleFormatter(locale.current.value, (_tms, short) => ({
|
||||
timeZone: 'UTC',
|
||||
weekday: short ? 'short' : 'long'
|
||||
}));
|
||||
});
|
||||
function getColorProps(colors) {
|
||||
return computeColor(colors);
|
||||
}
|
||||
function getRelativeClasses(timestamp, outside = false) {
|
||||
return {
|
||||
'v-present': timestamp.present,
|
||||
'v-past': timestamp.past,
|
||||
'v-future': timestamp.future,
|
||||
'v-outside': outside
|
||||
};
|
||||
}
|
||||
function getWeekNumber(timestamp) {
|
||||
return adapter.getWeek(adapter.date(timestamp.date), props.firstDayOfWeek, props.firstDayOfYear);
|
||||
}
|
||||
function _getStartOfWeek(timestamp) {
|
||||
return getStartOfWeek(timestamp, parsedWeekdays.value, times.today);
|
||||
}
|
||||
function _getEndOfWeek(timestamp) {
|
||||
return getEndOfWeek(timestamp, parsedWeekdays.value, times.today);
|
||||
}
|
||||
function getFormatter(options) {
|
||||
return createNativeLocaleFormatter(locale.current.value, () => options);
|
||||
}
|
||||
return {
|
||||
times,
|
||||
locale,
|
||||
parsedValue,
|
||||
parsedWeekdays,
|
||||
effectiveWeekdays,
|
||||
weekdaySkips,
|
||||
parsedStart,
|
||||
parsedEnd,
|
||||
days,
|
||||
dayFormatter,
|
||||
weekdayFormatter,
|
||||
getColorProps,
|
||||
getRelativeClasses,
|
||||
getWeekNumber,
|
||||
getStartOfWeek: _getStartOfWeek,
|
||||
getEndOfWeek: _getEndOfWeek,
|
||||
getFormatter,
|
||||
updateTimes
|
||||
};
|
||||
}
|
||||
//# sourceMappingURL=calendarBase.js.map
|
||||
Generated
Vendored
+1
File diff suppressed because one or more lines are too long
Generated
Vendored
+65
@@ -0,0 +1,65 @@
|
||||
@layer vuetify-components {
|
||||
.v-calendar-events .v-event-more {
|
||||
background-color: rgb(var(--v-theme-surface));
|
||||
color: rgb(var(--v-theme-on-surface));
|
||||
}
|
||||
.v-calendar-events .v-event-more.v-outside {
|
||||
background-color: rgb(var(--v-theme-surface-light));
|
||||
color: rgb(var(--v-theme-on-surface-light));
|
||||
}
|
||||
.v-calendar .v-event {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
line-height: 20px;
|
||||
margin-right: -1px;
|
||||
z-index: 1;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.v-calendar .v-event-more {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
z-index: 1;
|
||||
position: relative;
|
||||
}
|
||||
.v-calendar .v-event-timed-container {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin-right: 10px;
|
||||
pointer-events: none;
|
||||
}
|
||||
.v-calendar .v-event-timed {
|
||||
position: absolute;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
border: 1px solid rgb(var(--v-theme-surface));
|
||||
border-radius: 4px;
|
||||
pointer-events: all;
|
||||
}
|
||||
.v-calendar .v-event-summary {
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
width: 100%;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.v-calendar.v-calendar-events .v-calendar-weekly__head-weekday {
|
||||
margin-right: -1px;
|
||||
}
|
||||
.v-calendar.v-calendar-events .v-calendar-weekly__day {
|
||||
overflow: visible;
|
||||
margin-right: -1px;
|
||||
}
|
||||
}
|
||||
Generated
Vendored
+307
@@ -0,0 +1,307 @@
|
||||
|
||||
import type { PropType, VNode } from 'vue';
|
||||
import type { CalendarBaseProps } from './calendarBase.js';
|
||||
import type { CalendarCategory, CalendarDayBodySlotScope, CalendarDaySlotScope, CalendarEvent, CalendarEventCategoryFunction, CalendarEventColorFunction, CalendarEventNameFunction, CalendarEventOverlapMode, CalendarEventParsed, CalendarEventTimedFunction, CalendarEventVisual, CalendarTimestamp } from '../types.js';
|
||||
type VDailyEventsMap = {
|
||||
[date: string]: {
|
||||
parent: HTMLElement;
|
||||
more: HTMLElement | null;
|
||||
events: HTMLElement[];
|
||||
};
|
||||
};
|
||||
export interface VEventScopeInput {
|
||||
eventParsed: CalendarEventParsed;
|
||||
day: CalendarDaySlotScope;
|
||||
start: boolean;
|
||||
end: boolean;
|
||||
timed: boolean;
|
||||
}
|
||||
export declare const makeCalendarWithEventsProps: <Defaults extends {
|
||||
events?: unknown;
|
||||
eventStart?: unknown;
|
||||
eventEnd?: unknown;
|
||||
eventTimed?: unknown;
|
||||
eventCategory?: unknown;
|
||||
eventHeight?: unknown;
|
||||
eventColor?: unknown;
|
||||
eventTextColor?: unknown;
|
||||
eventName?: unknown;
|
||||
eventOverlapThreshold?: unknown;
|
||||
eventOverlapMode?: unknown;
|
||||
eventMore?: unknown;
|
||||
eventMoreText?: unknown;
|
||||
eventRipple?: unknown;
|
||||
eventMarginBottom?: unknown;
|
||||
} = {}>(defaults?: Defaults | undefined) => {
|
||||
events: unknown extends Defaults["events"] ? {
|
||||
type: PropType<CalendarEvent[]>;
|
||||
default: () => never[];
|
||||
} : Omit<{
|
||||
type: PropType<CalendarEvent[]>;
|
||||
default: () => never[];
|
||||
}, "default" | "type"> & {
|
||||
type: PropType<unknown extends Defaults["events"] ? CalendarEvent[] : CalendarEvent[] | Defaults["events"]>;
|
||||
default: unknown extends Defaults["events"] ? CalendarEvent[] : CalendarEvent[] | Defaults["events"];
|
||||
};
|
||||
eventStart: unknown extends Defaults["eventStart"] ? {
|
||||
type: StringConstructor;
|
||||
default: string;
|
||||
} : Omit<{
|
||||
type: StringConstructor;
|
||||
default: string;
|
||||
}, "default" | "type"> & {
|
||||
type: PropType<unknown extends Defaults["eventStart"] ? string : string | Defaults["eventStart"]>;
|
||||
default: unknown extends Defaults["eventStart"] ? string : string | Defaults["eventStart"];
|
||||
};
|
||||
eventEnd: unknown extends Defaults["eventEnd"] ? {
|
||||
type: StringConstructor;
|
||||
default: string;
|
||||
} : Omit<{
|
||||
type: StringConstructor;
|
||||
default: string;
|
||||
}, "default" | "type"> & {
|
||||
type: PropType<unknown extends Defaults["eventEnd"] ? string : string | Defaults["eventEnd"]>;
|
||||
default: unknown extends Defaults["eventEnd"] ? string : string | Defaults["eventEnd"];
|
||||
};
|
||||
eventTimed: unknown extends Defaults["eventTimed"] ? {
|
||||
type: PropType<string | CalendarEventTimedFunction>;
|
||||
default: string;
|
||||
} : Omit<{
|
||||
type: PropType<string | CalendarEventTimedFunction>;
|
||||
default: string;
|
||||
}, "default" | "type"> & {
|
||||
type: PropType<unknown extends Defaults["eventTimed"] ? string | CalendarEventTimedFunction : string | CalendarEventTimedFunction | Defaults["eventTimed"]>;
|
||||
default: unknown extends Defaults["eventTimed"] ? string | CalendarEventTimedFunction : Defaults["eventTimed"] | NonNullable<string | CalendarEventTimedFunction>;
|
||||
};
|
||||
eventCategory: unknown extends Defaults["eventCategory"] ? {
|
||||
type: PropType<string | CalendarEventCategoryFunction>;
|
||||
default: string;
|
||||
} : Omit<{
|
||||
type: PropType<string | CalendarEventCategoryFunction>;
|
||||
default: string;
|
||||
}, "default" | "type"> & {
|
||||
type: PropType<unknown extends Defaults["eventCategory"] ? string | CalendarEventCategoryFunction : string | CalendarEventCategoryFunction | Defaults["eventCategory"]>;
|
||||
default: unknown extends Defaults["eventCategory"] ? string | CalendarEventCategoryFunction : Defaults["eventCategory"] | NonNullable<string | CalendarEventCategoryFunction>;
|
||||
};
|
||||
eventHeight: unknown extends Defaults["eventHeight"] ? {
|
||||
type: NumberConstructor;
|
||||
default: number;
|
||||
} : Omit<{
|
||||
type: NumberConstructor;
|
||||
default: number;
|
||||
}, "default" | "type"> & {
|
||||
type: PropType<unknown extends Defaults["eventHeight"] ? number : number | Defaults["eventHeight"]>;
|
||||
default: unknown extends Defaults["eventHeight"] ? number : number | Defaults["eventHeight"];
|
||||
};
|
||||
eventColor: unknown extends Defaults["eventColor"] ? {
|
||||
type: PropType<string | CalendarEventColorFunction>;
|
||||
default: string;
|
||||
} : Omit<{
|
||||
type: PropType<string | CalendarEventColorFunction>;
|
||||
default: string;
|
||||
}, "default" | "type"> & {
|
||||
type: PropType<unknown extends Defaults["eventColor"] ? string | CalendarEventColorFunction : string | CalendarEventColorFunction | Defaults["eventColor"]>;
|
||||
default: unknown extends Defaults["eventColor"] ? string | CalendarEventColorFunction : Defaults["eventColor"] | NonNullable<string | CalendarEventColorFunction>;
|
||||
};
|
||||
eventTextColor: unknown extends Defaults["eventTextColor"] ? {
|
||||
type: PropType<string | CalendarEventColorFunction>;
|
||||
} : Omit<{
|
||||
type: PropType<string | CalendarEventColorFunction>;
|
||||
}, "default" | "type"> & {
|
||||
type: PropType<unknown extends Defaults["eventTextColor"] ? string | CalendarEventColorFunction : string | CalendarEventColorFunction | Defaults["eventTextColor"]>;
|
||||
default: unknown extends Defaults["eventTextColor"] ? string | CalendarEventColorFunction : Defaults["eventTextColor"] | NonNullable<string | CalendarEventColorFunction>;
|
||||
};
|
||||
eventName: unknown extends Defaults["eventName"] ? {
|
||||
type: PropType<string | CalendarEventNameFunction>;
|
||||
default: string;
|
||||
} : Omit<{
|
||||
type: PropType<string | CalendarEventNameFunction>;
|
||||
default: string;
|
||||
}, "default" | "type"> & {
|
||||
type: PropType<unknown extends Defaults["eventName"] ? string | CalendarEventNameFunction : string | CalendarEventNameFunction | Defaults["eventName"]>;
|
||||
default: unknown extends Defaults["eventName"] ? string | CalendarEventNameFunction : Defaults["eventName"] | NonNullable<string | CalendarEventNameFunction>;
|
||||
};
|
||||
eventOverlapThreshold: unknown extends Defaults["eventOverlapThreshold"] ? {
|
||||
type: (NumberConstructor | StringConstructor)[];
|
||||
default: number;
|
||||
} : Omit<{
|
||||
type: (NumberConstructor | StringConstructor)[];
|
||||
default: number;
|
||||
}, "default" | "type"> & {
|
||||
type: PropType<unknown extends Defaults["eventOverlapThreshold"] ? string | number : string | number | Defaults["eventOverlapThreshold"]>;
|
||||
default: unknown extends Defaults["eventOverlapThreshold"] ? string | number : Defaults["eventOverlapThreshold"] | NonNullable<string | number>;
|
||||
};
|
||||
eventOverlapMode: unknown extends Defaults["eventOverlapMode"] ? {
|
||||
type: PropType<'stack' | 'column' | CalendarEventOverlapMode>;
|
||||
default: string;
|
||||
validate: (mode: any) => boolean;
|
||||
} : Omit<{
|
||||
type: PropType<'stack' | 'column' | CalendarEventOverlapMode>;
|
||||
default: string;
|
||||
validate: (mode: any) => boolean;
|
||||
}, "default" | "type"> & {
|
||||
type: PropType<unknown extends Defaults["eventOverlapMode"] ? "column" | "stack" | CalendarEventOverlapMode : "column" | "stack" | CalendarEventOverlapMode | Defaults["eventOverlapMode"]>;
|
||||
default: unknown extends Defaults["eventOverlapMode"] ? "column" | "stack" | CalendarEventOverlapMode : Defaults["eventOverlapMode"] | NonNullable<"column" | "stack" | CalendarEventOverlapMode>;
|
||||
};
|
||||
eventMore: unknown extends Defaults["eventMore"] ? {
|
||||
type: BooleanConstructor;
|
||||
default: boolean;
|
||||
} : Omit<{
|
||||
type: BooleanConstructor;
|
||||
default: boolean;
|
||||
}, "default" | "type"> & {
|
||||
type: PropType<unknown extends Defaults["eventMore"] ? boolean : boolean | Defaults["eventMore"]>;
|
||||
default: unknown extends Defaults["eventMore"] ? boolean : boolean | Defaults["eventMore"];
|
||||
};
|
||||
eventMoreText: unknown extends Defaults["eventMoreText"] ? {
|
||||
type: StringConstructor;
|
||||
default: string;
|
||||
} : Omit<{
|
||||
type: StringConstructor;
|
||||
default: string;
|
||||
}, "default" | "type"> & {
|
||||
type: PropType<unknown extends Defaults["eventMoreText"] ? string : string | Defaults["eventMoreText"]>;
|
||||
default: unknown extends Defaults["eventMoreText"] ? string : string | Defaults["eventMoreText"];
|
||||
};
|
||||
eventRipple: unknown extends Defaults["eventRipple"] ? {
|
||||
type: (BooleanConstructor | ObjectConstructor)[];
|
||||
default: null;
|
||||
} : Omit<{
|
||||
type: (BooleanConstructor | ObjectConstructor)[];
|
||||
default: null;
|
||||
}, "default" | "type"> & {
|
||||
type: PropType<unknown extends Defaults["eventRipple"] ? boolean | Record<string, any> : boolean | Record<string, any> | Defaults["eventRipple"]>;
|
||||
default: unknown extends Defaults["eventRipple"] ? boolean | Record<string, any> : Defaults["eventRipple"] | NonNullable<boolean | Record<string, any>>;
|
||||
};
|
||||
eventMarginBottom: unknown extends Defaults["eventMarginBottom"] ? {
|
||||
type: NumberConstructor;
|
||||
default: number;
|
||||
} : Omit<{
|
||||
type: NumberConstructor;
|
||||
default: number;
|
||||
}, "default" | "type"> & {
|
||||
type: PropType<unknown extends Defaults["eventMarginBottom"] ? number : number | Defaults["eventMarginBottom"]>;
|
||||
default: unknown extends Defaults["eventMarginBottom"] ? number : number | Defaults["eventMarginBottom"];
|
||||
};
|
||||
};
|
||||
interface CalendarWithEventsProps extends CalendarBaseProps {
|
||||
events: CalendarEvent[];
|
||||
eventStart: string;
|
||||
eventEnd: string;
|
||||
eventTimed: string | CalendarEventTimedFunction;
|
||||
eventCategory: string | CalendarEventCategoryFunction;
|
||||
eventHeight: number;
|
||||
eventColor: string | CalendarEventColorFunction;
|
||||
eventTextColor: string | CalendarEventColorFunction | undefined;
|
||||
eventName: string | CalendarEventNameFunction;
|
||||
eventOverlapThreshold: string | number;
|
||||
eventOverlapMode: string | CalendarEventOverlapMode;
|
||||
eventMore: boolean;
|
||||
eventMoreText: string;
|
||||
eventRipple: boolean | object | null | undefined;
|
||||
eventMarginBottom: number;
|
||||
type: 'month' | 'week' | 'day' | '4day' | 'custom-weekly' | 'custom-daily' | 'category';
|
||||
}
|
||||
export declare function useCalendarWithEvents(props: CalendarWithEventsProps, slots: any, attrs: any): {
|
||||
times: {
|
||||
now: {
|
||||
date: string;
|
||||
time: string;
|
||||
year: number;
|
||||
month: number;
|
||||
day: number;
|
||||
weekday: number;
|
||||
hour: number;
|
||||
minute: number;
|
||||
hasDay: boolean;
|
||||
hasTime: boolean;
|
||||
past: boolean;
|
||||
present: boolean;
|
||||
future: boolean;
|
||||
category?: CalendarCategory;
|
||||
};
|
||||
today: {
|
||||
date: string;
|
||||
time: string;
|
||||
year: number;
|
||||
month: number;
|
||||
day: number;
|
||||
weekday: number;
|
||||
hour: number;
|
||||
minute: number;
|
||||
hasDay: boolean;
|
||||
hasTime: boolean;
|
||||
past: boolean;
|
||||
present: boolean;
|
||||
future: boolean;
|
||||
category?: CalendarCategory;
|
||||
};
|
||||
};
|
||||
locale: {
|
||||
name: string;
|
||||
decimalSeparator: import("vue").ShallowRef<string>;
|
||||
messages: import("vue").Ref<import("../../../types.js").LocaleMessages, import("../../../types.js").LocaleMessages>;
|
||||
current: import("vue").Ref<string, string>;
|
||||
fallback: import("vue").Ref<string, string>;
|
||||
t: (key: string, ...params: unknown[]) => string;
|
||||
n: (value: number) => string;
|
||||
provide: (props: import("../../../types.js").LocaleOptions) => import("../../../types.js").LocaleInstance;
|
||||
isRtl: import("vue").Ref<boolean, boolean>;
|
||||
rtl: import("vue").Ref<Record<string, boolean>, Record<string, boolean>>;
|
||||
rtlClasses: import("vue").Ref<string, string>;
|
||||
};
|
||||
parsedValue: import("vue").ComputedRef<CalendarTimestamp>;
|
||||
parsedWeekdays: import("vue").ComputedRef<number[]>;
|
||||
effectiveWeekdays: import("vue").ComputedRef<number[]>;
|
||||
weekdaySkips: import("vue").ComputedRef<number[]>;
|
||||
parsedStart: import("vue").ComputedRef<CalendarTimestamp>;
|
||||
parsedEnd: import("vue").ComputedRef<CalendarTimestamp>;
|
||||
days: import("vue").ComputedRef<CalendarTimestamp[]>;
|
||||
dayFormatter: import("vue").ComputedRef<import("../types.js").CalendarFormatter>;
|
||||
weekdayFormatter: import("vue").ComputedRef<import("../types.js").CalendarFormatter>;
|
||||
getColorProps: (colors: {
|
||||
background?: import("../../../composables/color.js").ColorValue;
|
||||
text?: import("../../../composables/color.js").ColorValue;
|
||||
}) => {
|
||||
class: string[];
|
||||
style: import("vue").CSSProperties;
|
||||
};
|
||||
getRelativeClasses: (timestamp: CalendarTimestamp, outside?: boolean) => {
|
||||
'v-present': boolean;
|
||||
'v-past': boolean;
|
||||
'v-future': boolean;
|
||||
'v-outside': boolean;
|
||||
};
|
||||
getWeekNumber: (timestamp: CalendarTimestamp) => number;
|
||||
getStartOfWeek: (timestamp: CalendarTimestamp) => CalendarTimestamp;
|
||||
getEndOfWeek: (timestamp: CalendarTimestamp) => CalendarTimestamp;
|
||||
getFormatter: (options: Intl.DateTimeFormatOptions) => import("../types.js").CalendarFormatter;
|
||||
updateTimes: () => void;
|
||||
noEvents: import("vue").ComputedRef<boolean>;
|
||||
parsedEvents: import("vue").ComputedRef<CalendarEventParsed[]>;
|
||||
parsedEventOverlapThreshold: import("vue").ComputedRef<number>;
|
||||
eventTimedFunction: import("vue").ComputedRef<CalendarEventTimedFunction>;
|
||||
eventCategoryFunction: import("vue").ComputedRef<CalendarEventCategoryFunction>;
|
||||
eventTextColorFunction: import("vue").ComputedRef<CalendarEventColorFunction>;
|
||||
eventNameFunction: import("vue").ComputedRef<CalendarEventNameFunction>;
|
||||
eventModeFunction: import("vue").ComputedRef<CalendarEventOverlapMode>;
|
||||
eventWeekdays: import("vue").ComputedRef<number[]>;
|
||||
categoryMode: import("vue").ComputedRef<boolean>;
|
||||
eventColorFunction: (e: CalendarEvent) => string | undefined;
|
||||
eventsRef: import("vue").Ref<HTMLElement[], HTMLElement[]>;
|
||||
updateEventVisibility: () => void;
|
||||
getEventsMap: () => VDailyEventsMap;
|
||||
genDayEvent: ({ event }: CalendarEventVisual, day: CalendarDaySlotScope) => VNode;
|
||||
genTimedEvent: ({ event, left, width }: CalendarEventVisual, day: CalendarDayBodySlotScope) => VNode | false;
|
||||
genEvent: (event: CalendarEventParsed, scopeInput: VEventScopeInput, timedEvent: boolean, data: Record<string, unknown>) => VNode;
|
||||
genName: (eventSummary: () => string | VNode) => VNode;
|
||||
genPlaceholder: (day: CalendarTimestamp) => VNode;
|
||||
genMore: (day: CalendarDaySlotScope) => VNode;
|
||||
getVisibleEvents: () => CalendarEventParsed[];
|
||||
isEventForCategory: (event: CalendarEventParsed, category: CalendarCategory) => boolean;
|
||||
getEventsForDay: (day: CalendarDaySlotScope) => CalendarEventParsed[];
|
||||
getEventsForDayAll: (day: CalendarDaySlotScope) => CalendarEventParsed[];
|
||||
getEventsForDayTimed: (day: CalendarDaySlotScope) => CalendarEventParsed[];
|
||||
getScopedSlots: () => any;
|
||||
};
|
||||
|
||||
Generated
Vendored
+473
@@ -0,0 +1,473 @@
|
||||
import { createElementVNode as _createElementVNode, createTextVNode as _createTextVNode, mergeProps as _mergeProps, withDirectives as _withDirectives } from "vue";
|
||||
// Styles
|
||||
import "./calendarWithEvents.css";
|
||||
|
||||
// Composables
|
||||
import { useCalendarBase } from "./calendarBase.js"; // Directives
|
||||
import vRipple from "../../../directives/ripple/index.js"; // Utilities
|
||||
import { computed, ref } from 'vue';
|
||||
import { CalendarEventOverlapModes } from "../modes/index.js";
|
||||
import { isEventHiddenOn, isEventOn, isEventOnDay, isEventOverlapping, isEventStart, parseEvent } from "../util/events.js";
|
||||
import { diffMinutes, getDayIdentifier } from "../util/timestamp.js";
|
||||
import { getPrefixedEventHandlers, propsFactory } from "../../../util/index.js"; // Types
|
||||
// Constants
|
||||
const WIDTH_FULL = 100;
|
||||
const WIDTH_START = 95;
|
||||
// const MINUTES_IN_DAY = 1440
|
||||
|
||||
// Prevent import from being erased
|
||||
void vRipple;
|
||||
export const makeCalendarWithEventsProps = propsFactory({
|
||||
events: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
eventStart: {
|
||||
type: String,
|
||||
default: 'start'
|
||||
},
|
||||
eventEnd: {
|
||||
type: String,
|
||||
default: 'end'
|
||||
},
|
||||
eventTimed: {
|
||||
type: [String, Function],
|
||||
default: 'timed'
|
||||
},
|
||||
eventCategory: {
|
||||
type: [String, Function],
|
||||
default: 'category'
|
||||
},
|
||||
eventHeight: {
|
||||
type: Number,
|
||||
default: 20
|
||||
},
|
||||
eventColor: {
|
||||
type: [String, Function],
|
||||
default: 'primary'
|
||||
},
|
||||
eventTextColor: {
|
||||
type: [String, Function]
|
||||
},
|
||||
eventName: {
|
||||
type: [String, Function],
|
||||
default: 'name'
|
||||
},
|
||||
eventOverlapThreshold: {
|
||||
type: [String, Number],
|
||||
default: 60
|
||||
},
|
||||
eventOverlapMode: {
|
||||
type: [String, Function],
|
||||
default: 'stack',
|
||||
validate: mode => mode in CalendarEventOverlapModes || typeof mode === 'function'
|
||||
},
|
||||
eventMore: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
eventMoreText: {
|
||||
type: String,
|
||||
default: '$vuetify.calendar.moreEvents'
|
||||
},
|
||||
eventRipple: {
|
||||
type: [Boolean, Object],
|
||||
default: null
|
||||
},
|
||||
eventMarginBottom: {
|
||||
type: Number,
|
||||
default: 1
|
||||
}
|
||||
}, 'VCalendar-events');
|
||||
export function useCalendarWithEvents(props, slots, attrs) {
|
||||
const base = useCalendarBase(props);
|
||||
const noEvents = computed(() => {
|
||||
return !Array.isArray(props.events) || props.events.length === 0;
|
||||
});
|
||||
const categoryMode = computed(() => {
|
||||
return props.type === 'category';
|
||||
});
|
||||
const eventTimedFunction = computed(() => {
|
||||
return typeof props.eventTimed === 'function' ? props.eventTimed : event => !!event[props.eventTimed];
|
||||
});
|
||||
const eventCategoryFunction = computed(() => {
|
||||
return typeof props.eventCategory === 'function' ? props.eventCategory : event => event[props.eventCategory];
|
||||
});
|
||||
const parsedEvents = computed(() => {
|
||||
if (!props.events) return [];
|
||||
return props.events.map((event, index) => parseEvent(event, index, props.eventStart || '', props.eventEnd || '', eventTimedFunction.value(event), categoryMode.value ? eventCategoryFunction.value(event) : false));
|
||||
});
|
||||
const parsedEventOverlapThreshold = computed(() => {
|
||||
return parseInt(String(props.eventOverlapThreshold || 0));
|
||||
});
|
||||
const eventTextColorFunction = computed(() => {
|
||||
return typeof props.eventTextColor === 'function' ? props.eventTextColor : () => props.eventTextColor;
|
||||
});
|
||||
const eventNameFunction = computed(() => {
|
||||
return typeof props.eventName === 'function' ? props.eventName : (event, timedEvent) => event.input[props.eventName] || '';
|
||||
});
|
||||
const eventModeFunction = computed(() => {
|
||||
return typeof props.eventOverlapMode === 'function' ? props.eventOverlapMode : CalendarEventOverlapModes[props.eventOverlapMode];
|
||||
});
|
||||
const eventWeekdays = computed(() => {
|
||||
return base.effectiveWeekdays.value;
|
||||
});
|
||||
function eventColorFunction(e) {
|
||||
return typeof props.eventColor === 'function' ? props.eventColor(e) : e.color || props.eventColor;
|
||||
}
|
||||
const eventsRef = ref([]);
|
||||
function updateEventVisibility() {
|
||||
if (noEvents.value || !props.eventMore) {
|
||||
return;
|
||||
}
|
||||
const eventHeight = props.eventHeight || 0;
|
||||
const eventsMap = getEventsMap();
|
||||
for (const date in eventsMap) {
|
||||
const {
|
||||
parent,
|
||||
events,
|
||||
more
|
||||
} = eventsMap[date];
|
||||
if (!more) {
|
||||
break;
|
||||
}
|
||||
const parentBounds = parent.getBoundingClientRect();
|
||||
const last = events.length - 1;
|
||||
const eventsSorted = events.map(event => ({
|
||||
event,
|
||||
bottom: event.getBoundingClientRect().bottom
|
||||
})).sort((a, b) => a.bottom - b.bottom);
|
||||
let hidden = 0;
|
||||
for (let i = 0; i <= last; i++) {
|
||||
const bottom = eventsSorted[i].bottom;
|
||||
const hide = i === last ? bottom > parentBounds.bottom : bottom + eventHeight > parentBounds.bottom;
|
||||
if (hide) {
|
||||
eventsSorted[i].event.style.display = 'none';
|
||||
hidden++;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: avoid direct DOM manipulation
|
||||
if (hidden) {
|
||||
more.style.display = '';
|
||||
more.innerHTML = base.locale.t(props.eventMoreText, hidden);
|
||||
} else {
|
||||
more.style.display = 'none';
|
||||
}
|
||||
}
|
||||
}
|
||||
function getEventsMap() {
|
||||
const eventsMap = {};
|
||||
const elements = eventsRef.value;
|
||||
if (!elements || !elements.length) {
|
||||
return eventsMap;
|
||||
}
|
||||
elements.forEach(el => {
|
||||
const date = el.getAttribute('data-date');
|
||||
if (el.parentElement && date) {
|
||||
if (!(date in eventsMap)) {
|
||||
eventsMap[date] = {
|
||||
parent: el.parentElement,
|
||||
more: null,
|
||||
events: []
|
||||
};
|
||||
}
|
||||
if (el.getAttribute('data-more')) {
|
||||
eventsMap[date].more = el;
|
||||
} else {
|
||||
eventsMap[date].events.push(el);
|
||||
el.style.display = '';
|
||||
}
|
||||
}
|
||||
});
|
||||
return eventsMap;
|
||||
}
|
||||
function genDayEvent({
|
||||
event
|
||||
}, day) {
|
||||
const eventHeight = props.eventHeight || 0;
|
||||
const eventMarginBottom = props.eventMarginBottom || 0;
|
||||
const dayIdentifier = getDayIdentifier(day);
|
||||
const week = day.week;
|
||||
const start = dayIdentifier === event.startIdentifier;
|
||||
let end = dayIdentifier === event.endIdentifier;
|
||||
let width = WIDTH_START;
|
||||
if (!categoryMode.value) {
|
||||
for (let i = day.index + 1; i < week.length; i++) {
|
||||
const weekdayIdentifier = getDayIdentifier(week[i]);
|
||||
if (event.endIdentifier >= weekdayIdentifier) {
|
||||
width += WIDTH_FULL;
|
||||
end = end || weekdayIdentifier === event.endIdentifier;
|
||||
} else {
|
||||
end = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
const scope = {
|
||||
eventParsed: event,
|
||||
day,
|
||||
start,
|
||||
end,
|
||||
timed: false
|
||||
};
|
||||
return genEvent(event, scope, false, {
|
||||
class: ['v-event', {
|
||||
'v-event-start': start,
|
||||
'v-event-end': end
|
||||
}],
|
||||
style: {
|
||||
height: `${eventHeight}px`,
|
||||
width: `${width}%`,
|
||||
marginBottom: `${eventMarginBottom}px`
|
||||
},
|
||||
'data-date': day.date
|
||||
});
|
||||
}
|
||||
function genTimedEvent({
|
||||
event,
|
||||
left,
|
||||
width
|
||||
}, day) {
|
||||
const startDelta = day.timeDelta(event.start, day);
|
||||
const endDelta = day.timeDelta(event.end, day);
|
||||
if (endDelta === false || startDelta === false || endDelta < 0 || startDelta >= 1 || isEventHiddenOn(event, day)) {
|
||||
return false;
|
||||
}
|
||||
const dayIdentifier = getDayIdentifier(day);
|
||||
const start = event.startIdentifier >= dayIdentifier;
|
||||
const end = event.endIdentifier > dayIdentifier;
|
||||
const top = day.timeToY(event.start, day);
|
||||
const bottom = day.timeToY(event.end, day);
|
||||
const height = Math.max(props.eventHeight || 0, bottom - top);
|
||||
const scope = {
|
||||
eventParsed: event,
|
||||
day,
|
||||
start,
|
||||
end,
|
||||
timed: true
|
||||
};
|
||||
return genEvent(event, scope, true, {
|
||||
class: 'v-event-timed',
|
||||
style: {
|
||||
top: `${top}px`,
|
||||
height: `${height}px`,
|
||||
left: `${left}%`,
|
||||
width: `${width}%`
|
||||
}
|
||||
});
|
||||
}
|
||||
function genEvent(event, scopeInput, timedEvent, data) {
|
||||
const slot = slots.event;
|
||||
const text = eventTextColorFunction.value(event.input);
|
||||
const background = eventColorFunction(event.input);
|
||||
const overlapsNoon = event.start.hour < 12 && event.end.hour >= 12;
|
||||
const singline = diffMinutes(event.start, event.end) <= parsedEventOverlapThreshold.value;
|
||||
const formatTime = (withTime, ampm) => {
|
||||
const formatter = base.getFormatter({
|
||||
timeZone: 'UTC',
|
||||
hour: 'numeric',
|
||||
minute: withTime.minute > 0 ? 'numeric' : undefined
|
||||
});
|
||||
return formatter(withTime, true);
|
||||
};
|
||||
const timeSummary = () => formatTime(event.start, overlapsNoon) + ' - ' + formatTime(event.end, true);
|
||||
const eventSummary = () => {
|
||||
const name = eventNameFunction.value(event, timedEvent);
|
||||
if (event.start.hasTime) {
|
||||
if (timedEvent) {
|
||||
const time = timeSummary();
|
||||
const delimiter = singline ? ', ' : _createElementVNode("br", null, null);
|
||||
return _createElementVNode("span", {
|
||||
"class": "v-event-summary"
|
||||
}, [_createElementVNode("strong", null, [name]), delimiter, time]);
|
||||
} else {
|
||||
const time = formatTime(event.start, true);
|
||||
return _createElementVNode("span", {
|
||||
"class": "v-event-summary"
|
||||
}, [_createElementVNode("strong", null, [time]), _createTextVNode(" "), name]);
|
||||
}
|
||||
}
|
||||
return _createElementVNode("span", {
|
||||
"class": "v-event-summary"
|
||||
}, [name]);
|
||||
};
|
||||
const scope = {
|
||||
...scopeInput,
|
||||
event: event.input,
|
||||
outside: scopeInput.day.outside,
|
||||
singline,
|
||||
overlapsNoon,
|
||||
formatTime,
|
||||
timeSummary,
|
||||
eventSummary
|
||||
};
|
||||
const events = getPrefixedEventHandlers(attrs, ':event', nativeEvent => ({
|
||||
...scope,
|
||||
nativeEvent
|
||||
}));
|
||||
return _withDirectives(_createElementVNode("div", _mergeProps(base.getColorProps({
|
||||
text,
|
||||
background
|
||||
}), events, data, {
|
||||
"ref_for": true,
|
||||
"ref": eventsRef
|
||||
}), [slot?.(scope) ?? genName(eventSummary)]), [[vRipple, props.eventRipple ?? true]]);
|
||||
}
|
||||
function genName(eventSummary) {
|
||||
return _createElementVNode("div", {
|
||||
"class": "pl-1"
|
||||
}, [eventSummary()]);
|
||||
}
|
||||
function genPlaceholder(day) {
|
||||
const height = (props.eventHeight || 0) + (props.eventMarginBottom || 0);
|
||||
return _createElementVNode("div", {
|
||||
"style": {
|
||||
height: `${height}px`
|
||||
},
|
||||
"data-date": day.date,
|
||||
"ref_for": true,
|
||||
"ref": eventsRef
|
||||
}, null);
|
||||
}
|
||||
function genMore(day) {
|
||||
const eventHeight = props.eventHeight || 0;
|
||||
const eventMarginBottom = props.eventMarginBottom || 0;
|
||||
const events = getPrefixedEventHandlers(attrs, ':more', nativeEvent => ({
|
||||
nativeEvent,
|
||||
...day
|
||||
}));
|
||||
return _withDirectives(_createElementVNode("div", _mergeProps({
|
||||
"class": ['v-event-more pl-1', {
|
||||
'v-outside': day.outside
|
||||
}],
|
||||
"data-date": day.date,
|
||||
"data-more": "1",
|
||||
"style": {
|
||||
display: 'none',
|
||||
height: `${eventHeight}px`,
|
||||
marginBottom: `${eventMarginBottom}px`
|
||||
},
|
||||
"ref_for": true,
|
||||
"ref": eventsRef
|
||||
}, events), null), [[vRipple, props.eventRipple ?? true]]);
|
||||
}
|
||||
function getVisibleEvents() {
|
||||
const days = base.days.value;
|
||||
const start = getDayIdentifier(days[0]);
|
||||
const end = getDayIdentifier(days[days.length - 1]);
|
||||
return parsedEvents.value.filter(event => isEventOverlapping(event, start, end));
|
||||
}
|
||||
function isEventForCategory(event, category) {
|
||||
return !categoryMode.value || typeof category === 'object' && category.categoryName && category.categoryName === event.category || typeof event.category === 'string' && category === event.category || typeof event.category !== 'string' && category === null;
|
||||
}
|
||||
function getEventsForDay(day) {
|
||||
const identifier = getDayIdentifier(day);
|
||||
const firstWeekday = eventWeekdays.value[0];
|
||||
return parsedEvents.value.filter(event => isEventStart(event, day, identifier, firstWeekday));
|
||||
}
|
||||
function getEventsForDayAll(day) {
|
||||
const identifier = getDayIdentifier(day);
|
||||
const firstWeekday = eventWeekdays.value[0];
|
||||
return parsedEvents.value.filter(event => event.allDay && (categoryMode.value ? isEventOn(event, identifier) : isEventStart(event, day, identifier, firstWeekday)) && isEventForCategory(event, day.category));
|
||||
}
|
||||
function getEventsForDayTimed(day) {
|
||||
return parsedEvents.value.filter(event => !event.allDay && isEventOnDay(event, day, day.intervalRange) && isEventForCategory(event, day.category));
|
||||
}
|
||||
function getScopedSlots() {
|
||||
if (noEvents.value) {
|
||||
return {
|
||||
...slots
|
||||
};
|
||||
}
|
||||
const mode = eventModeFunction.value(parsedEvents.value, eventWeekdays.value[0], parsedEventOverlapThreshold.value);
|
||||
const isNode = input => !!input;
|
||||
const getSlotChildren = (day, getter, mapper, timed) => {
|
||||
const events = getter(day);
|
||||
const visuals = mode(day, events, timed, categoryMode.value);
|
||||
if (timed) {
|
||||
return visuals.map(visual => mapper(visual, day)).filter(isNode);
|
||||
}
|
||||
const children = [];
|
||||
visuals.forEach((visual, index) => {
|
||||
while (children.length < visual.column) {
|
||||
children.push(genPlaceholder(day));
|
||||
}
|
||||
const mapped = mapper(visual, day);
|
||||
if (mapped) {
|
||||
children.push(mapped);
|
||||
}
|
||||
});
|
||||
return children;
|
||||
};
|
||||
return {
|
||||
...slots,
|
||||
day: day => {
|
||||
let children = getSlotChildren(day, getEventsForDay, genDayEvent, false);
|
||||
if (children && children.length > 0 && props.eventMore) {
|
||||
children.push(genMore(day));
|
||||
}
|
||||
if (slots.day) {
|
||||
const slot = slots.day(day);
|
||||
if (slot) {
|
||||
children = children ? children.concat(slot) : slot;
|
||||
}
|
||||
}
|
||||
return children;
|
||||
},
|
||||
'day-header': day => {
|
||||
let children = getSlotChildren(day, getEventsForDayAll, genDayEvent, false);
|
||||
if (slots['day-header']) {
|
||||
const slot = slots['day-header'](day);
|
||||
if (slot) {
|
||||
children = children ? children.concat(slot) : slot;
|
||||
}
|
||||
}
|
||||
return children;
|
||||
},
|
||||
'day-body': day => {
|
||||
const events = getSlotChildren(day, getEventsForDayTimed, genTimedEvent, true);
|
||||
let children = [_createElementVNode("div", {
|
||||
"class": "v-event-timed-container"
|
||||
}, [events])];
|
||||
if (slots['day-body']) {
|
||||
const slot = slots['day-body'](day);
|
||||
if (slot) {
|
||||
children = children.concat(slot);
|
||||
}
|
||||
}
|
||||
return children;
|
||||
}
|
||||
};
|
||||
}
|
||||
return {
|
||||
...base,
|
||||
noEvents,
|
||||
parsedEvents,
|
||||
parsedEventOverlapThreshold,
|
||||
eventTimedFunction,
|
||||
eventCategoryFunction,
|
||||
eventTextColorFunction,
|
||||
eventNameFunction,
|
||||
eventModeFunction,
|
||||
eventWeekdays,
|
||||
categoryMode,
|
||||
eventColorFunction,
|
||||
eventsRef,
|
||||
updateEventVisibility,
|
||||
getEventsMap,
|
||||
genDayEvent,
|
||||
genTimedEvent,
|
||||
genEvent,
|
||||
genName,
|
||||
genPlaceholder,
|
||||
genMore,
|
||||
getVisibleEvents,
|
||||
isEventForCategory,
|
||||
getEventsForDay,
|
||||
getEventsForDayAll,
|
||||
getEventsForDayTimed,
|
||||
getScopedSlots
|
||||
};
|
||||
}
|
||||
//# sourceMappingURL=calendarWithEvents.js.map
|
||||
Generated
Vendored
+1
File diff suppressed because one or more lines are too long
Generated
Vendored
+69
@@ -0,0 +1,69 @@
|
||||
@use '../../../styles/tools'
|
||||
@use '../../../styles/settings'
|
||||
@use '../variables' as *
|
||||
|
||||
@include tools.layer('components')
|
||||
.v-calendar-events
|
||||
.v-event-more
|
||||
background-color: $calendar-background
|
||||
color: $calendar-on-background
|
||||
|
||||
&.v-outside
|
||||
background-color: $calendar-outside-background
|
||||
color: $calendar-on-outside-background
|
||||
|
||||
.v-calendar
|
||||
.v-event
|
||||
position: relative
|
||||
overflow: hidden
|
||||
text-overflow: ellipsis
|
||||
white-space: nowrap
|
||||
font-size: $calendar-event-font-size
|
||||
cursor: pointer
|
||||
line-height: $calendar-event-line-height
|
||||
margin-right: -$calendar-line-width
|
||||
z-index: 1
|
||||
border-radius: $calendar-event-border-radius
|
||||
|
||||
.v-event-more
|
||||
overflow: hidden
|
||||
text-overflow: ellipsis
|
||||
white-space: nowrap
|
||||
font-size: $calendar-event-font-size
|
||||
cursor: pointer
|
||||
font-weight: bold
|
||||
z-index: 1
|
||||
position: relative
|
||||
|
||||
.v-event-timed-container
|
||||
position: absolute
|
||||
top: 0
|
||||
bottom: 0
|
||||
left: 0
|
||||
right: 0
|
||||
margin-right: $calendar-event-right-empty
|
||||
pointer-events: none
|
||||
|
||||
.v-event-timed
|
||||
position: absolute
|
||||
white-space: nowrap
|
||||
text-overflow: ellipsis
|
||||
font-size: $calendar-event-font-size
|
||||
cursor: pointer
|
||||
border: $calendar-event-border-width solid $calendar-background
|
||||
border-radius: $calendar-event-border-radius
|
||||
pointer-events: all
|
||||
|
||||
.v-event-summary
|
||||
display: inline-block
|
||||
overflow: hidden
|
||||
text-overflow: ellipsis
|
||||
width: 100%
|
||||
white-space: nowrap
|
||||
|
||||
&.v-calendar-events
|
||||
.v-calendar-weekly__head-weekday
|
||||
margin-right: -$calendar-line-width
|
||||
.v-calendar-weekly__day
|
||||
overflow: visible
|
||||
margin-right: -$calendar-line-width
|
||||
Generated
Vendored
+232
@@ -0,0 +1,232 @@
|
||||
import { validateNumber, validateTime } from '../util/timestamp.js';
|
||||
import type { PropType, StyleValue } from 'vue';
|
||||
import type { CalendarBaseProps } from './calendarBase.js';
|
||||
import type { CalendarDayBodySlotScope, CalendarFormatter, CalendarTimestamp } from '../types.js';
|
||||
import type { VTime } from '../util/timestamp.js';
|
||||
export declare const makeCalendarWithIntervalsProps: <Defaults extends {
|
||||
maxDays?: unknown;
|
||||
intervalHeight?: unknown;
|
||||
intervalWidth?: unknown;
|
||||
intervalMinutes?: unknown;
|
||||
firstInterval?: unknown;
|
||||
firstTime?: unknown;
|
||||
intervalCount?: unknown;
|
||||
intervalFormat?: unknown;
|
||||
intervalStyle?: unknown;
|
||||
showIntervalLabel?: unknown;
|
||||
} = {}>(defaults?: Defaults | undefined) => {
|
||||
maxDays: unknown extends Defaults["maxDays"] ? {
|
||||
type: NumberConstructor;
|
||||
default: number;
|
||||
} : Omit<{
|
||||
type: NumberConstructor;
|
||||
default: number;
|
||||
}, "default" | "type"> & {
|
||||
type: PropType<unknown extends Defaults["maxDays"] ? number : number | Defaults["maxDays"]>;
|
||||
default: unknown extends Defaults["maxDays"] ? number : number | Defaults["maxDays"];
|
||||
};
|
||||
intervalHeight: unknown extends Defaults["intervalHeight"] ? {
|
||||
type: (NumberConstructor | StringConstructor)[];
|
||||
default: number;
|
||||
validate: typeof validateNumber;
|
||||
} : Omit<{
|
||||
type: (NumberConstructor | StringConstructor)[];
|
||||
default: number;
|
||||
validate: typeof validateNumber;
|
||||
}, "default" | "type"> & {
|
||||
type: PropType<unknown extends Defaults["intervalHeight"] ? string | number : string | number | Defaults["intervalHeight"]>;
|
||||
default: unknown extends Defaults["intervalHeight"] ? string | number : Defaults["intervalHeight"] | NonNullable<string | number>;
|
||||
};
|
||||
intervalWidth: unknown extends Defaults["intervalWidth"] ? {
|
||||
type: (NumberConstructor | StringConstructor)[];
|
||||
default: number;
|
||||
validate: typeof validateNumber;
|
||||
} : Omit<{
|
||||
type: (NumberConstructor | StringConstructor)[];
|
||||
default: number;
|
||||
validate: typeof validateNumber;
|
||||
}, "default" | "type"> & {
|
||||
type: PropType<unknown extends Defaults["intervalWidth"] ? string | number : string | number | Defaults["intervalWidth"]>;
|
||||
default: unknown extends Defaults["intervalWidth"] ? string | number : Defaults["intervalWidth"] | NonNullable<string | number>;
|
||||
};
|
||||
intervalMinutes: unknown extends Defaults["intervalMinutes"] ? {
|
||||
type: (NumberConstructor | StringConstructor)[];
|
||||
default: number;
|
||||
validate: typeof validateNumber;
|
||||
} : Omit<{
|
||||
type: (NumberConstructor | StringConstructor)[];
|
||||
default: number;
|
||||
validate: typeof validateNumber;
|
||||
}, "default" | "type"> & {
|
||||
type: PropType<unknown extends Defaults["intervalMinutes"] ? string | number : string | number | Defaults["intervalMinutes"]>;
|
||||
default: unknown extends Defaults["intervalMinutes"] ? string | number : Defaults["intervalMinutes"] | NonNullable<string | number>;
|
||||
};
|
||||
firstInterval: unknown extends Defaults["firstInterval"] ? {
|
||||
type: (NumberConstructor | StringConstructor)[];
|
||||
default: number;
|
||||
validate: typeof validateNumber;
|
||||
} : Omit<{
|
||||
type: (NumberConstructor | StringConstructor)[];
|
||||
default: number;
|
||||
validate: typeof validateNumber;
|
||||
}, "default" | "type"> & {
|
||||
type: PropType<unknown extends Defaults["firstInterval"] ? string | number : string | number | Defaults["firstInterval"]>;
|
||||
default: unknown extends Defaults["firstInterval"] ? string | number : Defaults["firstInterval"] | NonNullable<string | number>;
|
||||
};
|
||||
firstTime: unknown extends Defaults["firstTime"] ? {
|
||||
type: PropType<VTime>;
|
||||
validate: typeof validateTime;
|
||||
} : Omit<{
|
||||
type: PropType<VTime>;
|
||||
validate: typeof validateTime;
|
||||
}, "default" | "type"> & {
|
||||
type: PropType<unknown extends Defaults["firstTime"] ? VTime : Defaults["firstTime"] | VTime>;
|
||||
default: unknown extends Defaults["firstTime"] ? VTime : Defaults["firstTime"] | NonNullable<VTime>;
|
||||
};
|
||||
intervalCount: unknown extends Defaults["intervalCount"] ? {
|
||||
type: (NumberConstructor | StringConstructor)[];
|
||||
default: number;
|
||||
validate: typeof validateNumber;
|
||||
} : Omit<{
|
||||
type: (NumberConstructor | StringConstructor)[];
|
||||
default: number;
|
||||
validate: typeof validateNumber;
|
||||
}, "default" | "type"> & {
|
||||
type: PropType<unknown extends Defaults["intervalCount"] ? string | number : string | number | Defaults["intervalCount"]>;
|
||||
default: unknown extends Defaults["intervalCount"] ? string | number : Defaults["intervalCount"] | NonNullable<string | number>;
|
||||
};
|
||||
intervalFormat: unknown extends Defaults["intervalFormat"] ? {
|
||||
type: PropType<CalendarFormatter>;
|
||||
default: null;
|
||||
} : Omit<{
|
||||
type: PropType<CalendarFormatter>;
|
||||
default: null;
|
||||
}, "default" | "type"> & {
|
||||
type: PropType<unknown extends Defaults["intervalFormat"] ? CalendarFormatter : CalendarFormatter | Defaults["intervalFormat"]>;
|
||||
default: unknown extends Defaults["intervalFormat"] ? CalendarFormatter : CalendarFormatter | Defaults["intervalFormat"];
|
||||
};
|
||||
intervalStyle: unknown extends Defaults["intervalStyle"] ? {
|
||||
type: PropType<(interval: CalendarTimestamp) => StyleValue>;
|
||||
default: null;
|
||||
} : Omit<{
|
||||
type: PropType<(interval: CalendarTimestamp) => StyleValue>;
|
||||
default: null;
|
||||
}, "default" | "type"> & {
|
||||
type: PropType<unknown extends Defaults["intervalStyle"] ? (interval: CalendarTimestamp) => StyleValue : ((interval: CalendarTimestamp) => StyleValue) | Defaults["intervalStyle"]>;
|
||||
default: unknown extends Defaults["intervalStyle"] ? (interval: CalendarTimestamp) => StyleValue : ((interval: CalendarTimestamp) => StyleValue) | Defaults["intervalStyle"];
|
||||
};
|
||||
showIntervalLabel: unknown extends Defaults["showIntervalLabel"] ? {
|
||||
type: PropType<(interval: CalendarTimestamp) => boolean>;
|
||||
default: null;
|
||||
} : Omit<{
|
||||
type: PropType<(interval: CalendarTimestamp) => boolean>;
|
||||
default: null;
|
||||
}, "default" | "type"> & {
|
||||
type: PropType<unknown extends Defaults["showIntervalLabel"] ? (interval: CalendarTimestamp) => boolean : ((interval: CalendarTimestamp) => boolean) | Defaults["showIntervalLabel"]>;
|
||||
default: unknown extends Defaults["showIntervalLabel"] ? (interval: CalendarTimestamp) => boolean : ((interval: CalendarTimestamp) => boolean) | Defaults["showIntervalLabel"];
|
||||
};
|
||||
};
|
||||
interface CalendarWithIntervalsProps extends CalendarBaseProps {
|
||||
maxDays: number;
|
||||
intervalHeight: string | number;
|
||||
intervalMinutes: string | number;
|
||||
firstInterval: string | number;
|
||||
firstTime: VTime | undefined;
|
||||
intervalCount: string | number;
|
||||
intervalFormat: CalendarFormatter | string | undefined;
|
||||
}
|
||||
export declare function useCalendarWithIntervals(props: CalendarWithIntervalsProps): {
|
||||
times: {
|
||||
now: {
|
||||
date: string;
|
||||
time: string;
|
||||
year: number;
|
||||
month: number;
|
||||
day: number;
|
||||
weekday: number;
|
||||
hour: number;
|
||||
minute: number;
|
||||
hasDay: boolean;
|
||||
hasTime: boolean;
|
||||
past: boolean;
|
||||
present: boolean;
|
||||
future: boolean;
|
||||
category?: import("../types.js").CalendarCategory;
|
||||
};
|
||||
today: {
|
||||
date: string;
|
||||
time: string;
|
||||
year: number;
|
||||
month: number;
|
||||
day: number;
|
||||
weekday: number;
|
||||
hour: number;
|
||||
minute: number;
|
||||
hasDay: boolean;
|
||||
hasTime: boolean;
|
||||
past: boolean;
|
||||
present: boolean;
|
||||
future: boolean;
|
||||
category?: import("../types.js").CalendarCategory;
|
||||
};
|
||||
};
|
||||
locale: {
|
||||
name: string;
|
||||
decimalSeparator: import("vue").ShallowRef<string>;
|
||||
messages: import("vue").Ref<import("../../../types.js").LocaleMessages, import("../../../types.js").LocaleMessages>;
|
||||
current: import("vue").Ref<string, string>;
|
||||
fallback: import("vue").Ref<string, string>;
|
||||
t: (key: string, ...params: unknown[]) => string;
|
||||
n: (value: number) => string;
|
||||
provide: (props: import("../../../types.js").LocaleOptions) => import("../../../types.js").LocaleInstance;
|
||||
isRtl: import("vue").Ref<boolean, boolean>;
|
||||
rtl: import("vue").Ref<Record<string, boolean>, Record<string, boolean>>;
|
||||
rtlClasses: import("vue").Ref<string, string>;
|
||||
};
|
||||
parsedValue: import("vue").ComputedRef<CalendarTimestamp>;
|
||||
parsedWeekdays: import("vue").ComputedRef<number[]>;
|
||||
effectiveWeekdays: import("vue").ComputedRef<number[]>;
|
||||
weekdaySkips: import("vue").ComputedRef<number[]>;
|
||||
parsedStart: import("vue").ComputedRef<CalendarTimestamp>;
|
||||
parsedEnd: import("vue").ComputedRef<CalendarTimestamp>;
|
||||
dayFormatter: import("vue").ComputedRef<CalendarFormatter>;
|
||||
weekdayFormatter: import("vue").ComputedRef<CalendarFormatter>;
|
||||
getColorProps: (colors: {
|
||||
background?: import("../../../composables/color.js").ColorValue;
|
||||
text?: import("../../../composables/color.js").ColorValue;
|
||||
}) => {
|
||||
class: string[];
|
||||
style: import("vue").CSSProperties;
|
||||
};
|
||||
getRelativeClasses: (timestamp: CalendarTimestamp, outside?: boolean) => {
|
||||
'v-present': boolean;
|
||||
'v-past': boolean;
|
||||
'v-future': boolean;
|
||||
'v-outside': boolean;
|
||||
};
|
||||
getWeekNumber: (timestamp: CalendarTimestamp) => number;
|
||||
getStartOfWeek: (timestamp: CalendarTimestamp) => CalendarTimestamp;
|
||||
getEndOfWeek: (timestamp: CalendarTimestamp) => CalendarTimestamp;
|
||||
getFormatter: (options: Intl.DateTimeFormatOptions) => CalendarFormatter;
|
||||
updateTimes: () => void;
|
||||
scrollAreaRef: import("vue").ShallowRef<HTMLElement | undefined, HTMLElement | undefined>;
|
||||
parsedFirstInterval: import("vue").ComputedRef<number>;
|
||||
parsedIntervalMinutes: import("vue").ComputedRef<number>;
|
||||
parsedIntervalCount: import("vue").ComputedRef<number>;
|
||||
parsedIntervalHeight: import("vue").ComputedRef<number>;
|
||||
parsedFirstTime: import("vue").ComputedRef<number | false>;
|
||||
firstMinute: import("vue").ComputedRef<number>;
|
||||
bodyHeight: import("vue").ComputedRef<number>;
|
||||
days: import("vue").ComputedRef<CalendarTimestamp[]>;
|
||||
intervals: import("vue").ComputedRef<CalendarTimestamp[][]>;
|
||||
intervalFormatter: import("vue").ComputedRef<CalendarFormatter>;
|
||||
showIntervalLabelDefault: (interval: CalendarTimestamp) => boolean;
|
||||
intervalStyleDefault: (_interval: CalendarTimestamp) => StyleValue;
|
||||
getTimestampAtEvent: (e: Event, day: CalendarTimestamp) => CalendarTimestamp;
|
||||
getSlotScope: (timestamp: CalendarTimestamp) => CalendarDayBodySlotScope;
|
||||
scrollToTime: (time: VTime) => boolean;
|
||||
minutesToPixels: (minutes: number) => number;
|
||||
timeToY: (time: VTime | CalendarTimestamp, targetDateOrClamp?: CalendarTimestamp | boolean) => number | false;
|
||||
timeDelta: (time: VTime | CalendarTimestamp, targetDate?: CalendarTimestamp) => number | false;
|
||||
};
|
||||
|
||||
Generated
Vendored
+208
@@ -0,0 +1,208 @@
|
||||
// Composables
|
||||
import { useCalendarBase } from "./calendarBase.js"; // Utilities
|
||||
import { computed, shallowRef } from 'vue';
|
||||
import { copyTimestamp, createDayList, createIntervalList, createNativeLocaleFormatter, getDayIdentifier, MINUTES_IN_DAY, parseTime, updateMinutes, validateNumber, validateTime } from "../util/timestamp.js";
|
||||
import { propsFactory } from "../../../util/index.js";
|
||||
import { Box, getTargetBox } from "../../../util/box.js"; // Types
|
||||
export const makeCalendarWithIntervalsProps = propsFactory({
|
||||
maxDays: {
|
||||
type: Number,
|
||||
default: 7
|
||||
},
|
||||
intervalHeight: {
|
||||
type: [Number, String],
|
||||
default: 48,
|
||||
validate: validateNumber
|
||||
},
|
||||
intervalWidth: {
|
||||
type: [Number, String],
|
||||
default: 60,
|
||||
validate: validateNumber
|
||||
},
|
||||
intervalMinutes: {
|
||||
type: [Number, String],
|
||||
default: 60,
|
||||
validate: validateNumber
|
||||
},
|
||||
firstInterval: {
|
||||
type: [Number, String],
|
||||
default: 0,
|
||||
validate: validateNumber
|
||||
},
|
||||
firstTime: {
|
||||
type: [Number, String, Object],
|
||||
validate: validateTime
|
||||
},
|
||||
intervalCount: {
|
||||
type: [Number, String],
|
||||
default: 24,
|
||||
validate: validateNumber
|
||||
},
|
||||
intervalFormat: {
|
||||
type: Function,
|
||||
default: null
|
||||
},
|
||||
intervalStyle: {
|
||||
type: Function,
|
||||
default: null
|
||||
},
|
||||
showIntervalLabel: {
|
||||
type: Function,
|
||||
default: null
|
||||
}
|
||||
}, 'VCalendar-intervals');
|
||||
export function useCalendarWithIntervals(props) {
|
||||
const base = useCalendarBase(props);
|
||||
const scrollAreaRef = shallowRef();
|
||||
const parsedFirstInterval = computed(() => {
|
||||
return parseInt(String(props.firstInterval || 0));
|
||||
});
|
||||
const parsedIntervalMinutes = computed(() => {
|
||||
return parseInt(String(props.intervalMinutes || 60));
|
||||
});
|
||||
const parsedIntervalCount = computed(() => {
|
||||
return parseInt(String(props.intervalCount || 24));
|
||||
});
|
||||
const parsedIntervalHeight = computed(() => {
|
||||
return parseFloat(String(props.intervalHeight || 48));
|
||||
});
|
||||
const parsedFirstTime = computed(() => {
|
||||
return parseTime(props.firstTime);
|
||||
});
|
||||
const firstMinute = computed(() => {
|
||||
const time = parsedFirstTime.value;
|
||||
return time !== false && time >= 0 && time <= MINUTES_IN_DAY ? time : parsedFirstInterval.value * parsedIntervalMinutes.value;
|
||||
});
|
||||
const bodyHeight = computed(() => {
|
||||
return parsedIntervalCount.value * parsedIntervalHeight.value;
|
||||
});
|
||||
const days = computed(() => {
|
||||
return createDayList(base.parsedStart.value, base.parsedEnd.value, base.times.today, base.weekdaySkips.value, props.maxDays);
|
||||
});
|
||||
const intervals = computed(() => {
|
||||
const daysValue = days.value;
|
||||
const first = firstMinute.value;
|
||||
const minutes = parsedIntervalMinutes.value;
|
||||
const count = parsedIntervalCount.value;
|
||||
const now = base.times.now;
|
||||
return daysValue.map(d => createIntervalList(d, first, minutes, count, now));
|
||||
});
|
||||
const intervalFormatter = computed(() => {
|
||||
if (props.intervalFormat) {
|
||||
return props.intervalFormat;
|
||||
}
|
||||
return createNativeLocaleFormatter(base.locale.current.value, (tms, short) => !short ? {
|
||||
timeZone: 'UTC',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit'
|
||||
} : tms.minute === 0 ? {
|
||||
timeZone: 'UTC',
|
||||
hour: 'numeric'
|
||||
} : {
|
||||
timeZone: 'UTC',
|
||||
hour: 'numeric',
|
||||
minute: '2-digit'
|
||||
});
|
||||
});
|
||||
function showIntervalLabelDefault(interval) {
|
||||
const first = intervals.value[0][0];
|
||||
const isFirst = first.hour === interval.hour && first.minute === interval.minute;
|
||||
return !isFirst;
|
||||
}
|
||||
function intervalStyleDefault(_interval) {
|
||||
return undefined;
|
||||
}
|
||||
function getTimestampAtEvent(e, day) {
|
||||
const timestamp = copyTimestamp(day);
|
||||
const bounds = new Box(e.currentTarget);
|
||||
const baseMinutes = firstMinute.value;
|
||||
const touchEvent = e;
|
||||
const mouseEvent = e;
|
||||
const touches = touchEvent.changedTouches || touchEvent.touches;
|
||||
const target = touches && touches[0] ? touches[0] : mouseEvent;
|
||||
const point = getTargetBox([target.clientX, target.clientY]);
|
||||
const addIntervals = (point.y - bounds.top) / parsedIntervalHeight.value;
|
||||
const addMinutes = Math.floor(addIntervals * parsedIntervalMinutes.value);
|
||||
const minutes = baseMinutes + addMinutes;
|
||||
return updateMinutes(timestamp, minutes, base.times.now);
|
||||
}
|
||||
function getSlotScope(timestamp) {
|
||||
const scope = copyTimestamp(timestamp);
|
||||
scope.timeToY = timeToY;
|
||||
scope.timeDelta = timeDelta;
|
||||
scope.minutesToPixels = minutesToPixels;
|
||||
scope.week = days.value;
|
||||
scope.intervalRange = [firstMinute.value, firstMinute.value + parsedIntervalCount.value * parsedIntervalMinutes.value];
|
||||
return scope;
|
||||
}
|
||||
function scrollToTime(time) {
|
||||
const y = timeToY(time);
|
||||
const pane = scrollAreaRef.value;
|
||||
if (y === false || !pane) {
|
||||
return false;
|
||||
}
|
||||
pane.scrollTop = y;
|
||||
return true;
|
||||
}
|
||||
function minutesToPixels(minutes) {
|
||||
return minutes / parsedIntervalMinutes.value * parsedIntervalHeight.value;
|
||||
}
|
||||
function timeToY(time, targetDateOrClamp = false) {
|
||||
const clamp = targetDateOrClamp !== false;
|
||||
const targetDate = typeof targetDateOrClamp !== 'boolean' ? targetDateOrClamp : undefined;
|
||||
let y = timeDelta(time, targetDate);
|
||||
if (y === false) return y;
|
||||
y *= bodyHeight.value;
|
||||
if (clamp) {
|
||||
if (y < 0) {
|
||||
y = 0;
|
||||
} else if (y > bodyHeight.value) {
|
||||
y = bodyHeight.value;
|
||||
}
|
||||
} else {
|
||||
if (y < 0) {
|
||||
y = y + bodyHeight.value;
|
||||
} else if (y > bodyHeight.value) {
|
||||
y = y - bodyHeight.value;
|
||||
}
|
||||
}
|
||||
return y;
|
||||
}
|
||||
function timeDelta(time, targetDate) {
|
||||
let minutes = parseTime(time);
|
||||
if (minutes === false) {
|
||||
return false;
|
||||
}
|
||||
const gap = parsedIntervalCount.value * parsedIntervalMinutes.value;
|
||||
if (targetDate && typeof time === 'object' && 'day' in time) {
|
||||
const a = getDayIdentifier(time);
|
||||
const b = getDayIdentifier(targetDate);
|
||||
minutes += (a - b) * gap;
|
||||
}
|
||||
const min = firstMinute.value;
|
||||
return (minutes - min) / gap;
|
||||
}
|
||||
return {
|
||||
...base,
|
||||
scrollAreaRef,
|
||||
parsedFirstInterval,
|
||||
parsedIntervalMinutes,
|
||||
parsedIntervalCount,
|
||||
parsedIntervalHeight,
|
||||
parsedFirstTime,
|
||||
firstMinute,
|
||||
bodyHeight,
|
||||
days,
|
||||
intervals,
|
||||
intervalFormatter,
|
||||
showIntervalLabelDefault,
|
||||
intervalStyleDefault,
|
||||
getTimestampAtEvent,
|
||||
getSlotScope,
|
||||
scrollToTime,
|
||||
minutesToPixels,
|
||||
timeToY,
|
||||
timeDelta
|
||||
};
|
||||
}
|
||||
//# sourceMappingURL=calendarWithIntervals.js.map
|
||||
Generated
Vendored
+1
File diff suppressed because one or more lines are too long
+45
@@ -0,0 +1,45 @@
|
||||
import type { CalendarTimestamp } from '../types.js';
|
||||
export declare function useTimes(props: {
|
||||
now: string | undefined;
|
||||
}): {
|
||||
times: {
|
||||
now: {
|
||||
date: string;
|
||||
time: string;
|
||||
year: number;
|
||||
month: number;
|
||||
day: number;
|
||||
weekday: number;
|
||||
hour: number;
|
||||
minute: number;
|
||||
hasDay: boolean;
|
||||
hasTime: boolean;
|
||||
past: boolean;
|
||||
present: boolean;
|
||||
future: boolean;
|
||||
category?: import("../types.js").CalendarCategory;
|
||||
};
|
||||
today: {
|
||||
date: string;
|
||||
time: string;
|
||||
year: number;
|
||||
month: number;
|
||||
day: number;
|
||||
weekday: number;
|
||||
hour: number;
|
||||
minute: number;
|
||||
hasDay: boolean;
|
||||
hasTime: boolean;
|
||||
past: boolean;
|
||||
present: boolean;
|
||||
future: boolean;
|
||||
category?: import("../types.js").CalendarCategory;
|
||||
};
|
||||
};
|
||||
parsedNow: import("vue").ComputedRef<CalendarTimestamp | null>;
|
||||
updateTimes: () => void;
|
||||
setPresent: () => void;
|
||||
getNow: () => CalendarTimestamp;
|
||||
updateDay: (now: CalendarTimestamp, target: CalendarTimestamp) => void;
|
||||
updateTime: (now: CalendarTimestamp, target: CalendarTimestamp) => void;
|
||||
};
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
// Utilities
|
||||
import { computed, reactive, watch } from 'vue';
|
||||
import { parseDate, parseTimestamp, validateTimestamp } from "../util/timestamp.js"; // Types
|
||||
export function useTimes(props) {
|
||||
const times = reactive({
|
||||
now: parseTimestamp('0000-00-00 00:00', true),
|
||||
today: parseTimestamp('0000-00-00', true)
|
||||
});
|
||||
const parsedNow = computed(() => {
|
||||
return props.now && validateTimestamp(props.now) ? parseTimestamp(props.now, true) : null;
|
||||
});
|
||||
function setPresent() {
|
||||
times.now.present = times.today.present = true;
|
||||
times.now.past = times.today.past = false;
|
||||
times.now.future = times.today.future = false;
|
||||
}
|
||||
function getNow() {
|
||||
return parseDate(new Date());
|
||||
}
|
||||
function updateDay(now, target) {
|
||||
if (now.date !== target.date) {
|
||||
target.year = now.year;
|
||||
target.month = now.month;
|
||||
target.day = now.day;
|
||||
target.weekday = now.weekday;
|
||||
target.date = now.date;
|
||||
}
|
||||
}
|
||||
function updateTime(now, target) {
|
||||
if (now.time !== target.time) {
|
||||
target.hour = now.hour;
|
||||
target.minute = now.minute;
|
||||
target.time = now.time;
|
||||
}
|
||||
}
|
||||
function updateTimes() {
|
||||
const now = parsedNow.value || getNow();
|
||||
updateDay(now, times.now);
|
||||
updateTime(now, times.now);
|
||||
updateDay(now, times.today);
|
||||
}
|
||||
watch(parsedNow, updateTimes);
|
||||
updateTimes();
|
||||
setPresent();
|
||||
return {
|
||||
times,
|
||||
parsedNow,
|
||||
updateTimes,
|
||||
setPresent,
|
||||
getNow,
|
||||
updateDay,
|
||||
updateTime
|
||||
};
|
||||
}
|
||||
//# sourceMappingURL=times.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"times.js","names":["computed","reactive","watch","parseDate","parseTimestamp","validateTimestamp","useTimes","props","times","now","today","parsedNow","setPresent","present","past","future","getNow","Date","updateDay","target","date","year","month","day","weekday","updateTime","time","hour","minute","updateTimes","value"],"sources":["../../../../src/components/VCalendar/composables/times.ts"],"sourcesContent":["// Utilities\nimport { computed, reactive, watch } from 'vue'\nimport {\n parseDate,\n parseTimestamp,\n validateTimestamp,\n} from '../util/timestamp'\n\n// Types\nimport type { CalendarTimestamp } from '../types'\n\nexport function useTimes (props: { now: string | undefined }) {\n const times = reactive({\n now: parseTimestamp('0000-00-00 00:00', true),\n today: parseTimestamp('0000-00-00', true),\n })\n\n const parsedNow = computed((): CalendarTimestamp | null => {\n return props.now && validateTimestamp(props.now) ? parseTimestamp(props.now, true) : null\n })\n\n function setPresent (): void {\n times.now.present = times.today.present = true\n times.now.past = times.today.past = false\n times.now.future = times.today.future = false\n }\n\n function getNow (): CalendarTimestamp {\n return parseDate(new Date())\n }\n\n function updateDay (now: CalendarTimestamp, target: CalendarTimestamp): void {\n if (now.date !== target.date) {\n target.year = now.year\n target.month = now.month\n target.day = now.day\n target.weekday = now.weekday\n target.date = now.date\n }\n }\n\n function updateTime (now: CalendarTimestamp, target: CalendarTimestamp): void {\n if (now.time !== target.time) {\n target.hour = now.hour\n target.minute = now.minute\n target.time = now.time\n }\n }\n\n function updateTimes (): void {\n const now: CalendarTimestamp = parsedNow.value || getNow()\n updateDay(now, times.now)\n updateTime(now, times.now)\n updateDay(now, times.today)\n }\n\n watch(parsedNow, updateTimes)\n\n updateTimes()\n setPresent()\n\n return {\n times,\n parsedNow,\n updateTimes,\n setPresent,\n getNow,\n updateDay,\n updateTime,\n }\n}\n"],"mappings":"AAAA;AACA,SAASA,QAAQ,EAAEC,QAAQ,EAAEC,KAAK,QAAQ,KAAK;AAAA,SAE7CC,SAAS,EACTC,cAAc,EACdC,iBAAiB,gCAGnB;AAGA,OAAO,SAASC,QAAQA,CAAEC,KAAkC,EAAE;EAC5D,MAAMC,KAAK,GAAGP,QAAQ,CAAC;IACrBQ,GAAG,EAAEL,cAAc,CAAC,kBAAkB,EAAE,IAAI,CAAC;IAC7CM,KAAK,EAAEN,cAAc,CAAC,YAAY,EAAE,IAAI;EAC1C,CAAC,CAAC;EAEF,MAAMO,SAAS,GAAGX,QAAQ,CAAC,MAAgC;IACzD,OAAOO,KAAK,CAACE,GAAG,IAAIJ,iBAAiB,CAACE,KAAK,CAACE,GAAG,CAAC,GAAGL,cAAc,CAACG,KAAK,CAACE,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI;EAC3F,CAAC,CAAC;EAEF,SAASG,UAAUA,CAAA,EAAU;IAC3BJ,KAAK,CAACC,GAAG,CAACI,OAAO,GAAGL,KAAK,CAACE,KAAK,CAACG,OAAO,GAAG,IAAI;IAC9CL,KAAK,CAACC,GAAG,CAACK,IAAI,GAAGN,KAAK,CAACE,KAAK,CAACI,IAAI,GAAG,KAAK;IACzCN,KAAK,CAACC,GAAG,CAACM,MAAM,GAAGP,KAAK,CAACE,KAAK,CAACK,MAAM,GAAG,KAAK;EAC/C;EAEA,SAASC,MAAMA,CAAA,EAAuB;IACpC,OAAOb,SAAS,CAAC,IAAIc,IAAI,CAAC,CAAC,CAAC;EAC9B;EAEA,SAASC,SAASA,CAAET,GAAsB,EAAEU,MAAyB,EAAQ;IAC3E,IAAIV,GAAG,CAACW,IAAI,KAAKD,MAAM,CAACC,IAAI,EAAE;MAC5BD,MAAM,CAACE,IAAI,GAAGZ,GAAG,CAACY,IAAI;MACtBF,MAAM,CAACG,KAAK,GAAGb,GAAG,CAACa,KAAK;MACxBH,MAAM,CAACI,GAAG,GAAGd,GAAG,CAACc,GAAG;MACpBJ,MAAM,CAACK,OAAO,GAAGf,GAAG,CAACe,OAAO;MAC5BL,MAAM,CAACC,IAAI,GAAGX,GAAG,CAACW,IAAI;IACxB;EACF;EAEA,SAASK,UAAUA,CAAEhB,GAAsB,EAAEU,MAAyB,EAAQ;IAC5E,IAAIV,GAAG,CAACiB,IAAI,KAAKP,MAAM,CAACO,IAAI,EAAE;MAC5BP,MAAM,CAACQ,IAAI,GAAGlB,GAAG,CAACkB,IAAI;MACtBR,MAAM,CAACS,MAAM,GAAGnB,GAAG,CAACmB,MAAM;MAC1BT,MAAM,CAACO,IAAI,GAAGjB,GAAG,CAACiB,IAAI;IACxB;EACF;EAEA,SAASG,WAAWA,CAAA,EAAU;IAC5B,MAAMpB,GAAsB,GAAGE,SAAS,CAACmB,KAAK,IAAId,MAAM,CAAC,CAAC;IAC1DE,SAAS,CAACT,GAAG,EAAED,KAAK,CAACC,GAAG,CAAC;IACzBgB,UAAU,CAAChB,GAAG,EAAED,KAAK,CAACC,GAAG,CAAC;IAC1BS,SAAS,CAACT,GAAG,EAAED,KAAK,CAACE,KAAK,CAAC;EAC7B;EAEAR,KAAK,CAACS,SAAS,EAAEkB,WAAW,CAAC;EAE7BA,WAAW,CAAC,CAAC;EACbjB,UAAU,CAAC,CAAC;EAEZ,OAAO;IACLJ,KAAK;IACLG,SAAS;IACTkB,WAAW;IACXjB,UAAU;IACVI,MAAM;IACNE,SAAS;IACTO;EACF,CAAC;AACH","ignoreList":[]}
|
||||
Reference in New Issue
Block a user