routie dev init since i didn't adhere to any proper guidance up until now
This commit is contained in:
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
|
||||
Reference in New Issue
Block a user