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
+122
View File
@@ -0,0 +1,122 @@
@layer vuetify-components {
.v-window {
overflow: hidden;
}
.v-window__container {
display: flex;
flex-direction: column;
height: inherit;
position: relative;
transition: 0.3s cubic-bezier(0.25, 0.8, 0.5, 1);
}
.v-window__controls {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 16px;
pointer-events: none;
}
.v-window__controls > * {
pointer-events: auto;
}
.v-window--show-arrows-on-hover {
overflow: hidden;
}
.v-window--show-arrows-on-hover .v-window__left {
transform: translateX(-200%);
}
:has(.v-window__controls--right).v-window--show-arrows-on-hover .v-window__left {
transform: translateX(200%);
}
.v-window--show-arrows-on-hover .v-window__right {
transform: translateX(200%);
}
:has(.v-window__controls--left).v-window--show-arrows-on-hover .v-window__right {
transform: translateX(-200%);
}
.v-window--show-arrows-on-hover:hover .v-window__left,
.v-window--show-arrows-on-hover:hover .v-window__right {
transform: translateX(0);
}
.v-window--vertical-arrows .v-window__controls {
flex-direction: column;
justify-content: center;
gap: 12px;
}
.v-window--vertical-arrows .v-window__controls--left {
align-items: start;
}
.v-window--vertical-arrows .v-window__controls--right {
align-items: end;
}
.v-window--vertical-arrows .v-window__controls .v-window__left .v-icon,
.v-window--vertical-arrows .v-window__controls .v-window__right .v-icon {
transform: rotate(90deg);
}
.v-window--crossfade > .v-window__container {
isolation: isolate;
}
.v-window--crossfade > .v-window__container > .v-window-item {
mix-blend-mode: plus-lighter;
}
}
@layer vuetify-overrides {
.v-window-item {
transition-duration: var(--v-window-transition-duration, revert-layer);
}
}
@layer vuetify-final.transitions {
.v-window-x-transition-enter-active, .v-window-x-transition-leave-active, .v-window-x-reverse-transition-enter-active, .v-window-x-reverse-transition-leave-active, .v-window-y-transition-enter-active, .v-window-y-transition-leave-active, .v-window-y-reverse-transition-enter-active, .v-window-y-reverse-transition-leave-active {
transition: 0.3s cubic-bezier(0.25, 0.8, 0.5, 1);
}
@media (prefers-reduced-motion: reduce) {
.v-window-x-transition-enter-active, .v-window-x-transition-leave-active, .v-window-x-reverse-transition-enter-active, .v-window-x-reverse-transition-leave-active, .v-window-y-transition-enter-active, .v-window-y-transition-leave-active, .v-window-y-reverse-transition-enter-active, .v-window-y-reverse-transition-leave-active {
transition-duration: 0s;
}
}
.v-window-x-transition-leave-from, .v-window-x-transition-leave-to, .v-window-x-reverse-transition-leave-from, .v-window-x-reverse-transition-leave-to, .v-window-y-transition-leave-from, .v-window-y-transition-leave-to, .v-window-y-reverse-transition-leave-from, .v-window-y-reverse-transition-leave-to {
position: absolute;
top: 0;
width: 100%;
}
.v-window-x-transition-enter-from {
transform: translateX(100%);
}
.v-window-x-transition-leave-to {
transform: translateX(-100%);
}
.v-window-x-reverse-transition-enter-from {
transform: translateX(-100%);
}
.v-window-x-reverse-transition-leave-to {
transform: translateX(100%);
}
.v-window-y-transition-enter-from {
transform: translateY(100%);
}
.v-window-y-transition-leave-to {
transform: translateY(-100%);
}
.v-window-y-reverse-transition-enter-from {
transform: translateY(-100%);
}
.v-window-y-reverse-transition-leave-to {
transform: translateY(100%);
}
.v-window-crossfade-transition-enter-active, .v-window-crossfade-transition-leave-active {
transition: 0.3s cubic-bezier(0.25, 0.8, 0.5, 1);
}
.v-window-crossfade-transition-leave-from, .v-window-crossfade-transition-leave-to {
position: absolute;
top: 0;
width: 100%;
}
.v-window-crossfade-transition-enter-from, .v-window-crossfade-transition-leave-to {
opacity: 0;
}
}
+440
View File
@@ -0,0 +1,440 @@
import type { ComputedRef, InjectionKey, PropType, Ref } from 'vue';
import type { GroupItemProvide, GroupProvide } from '../../composables/group.js';
import type { IconValue } from '../../composables/icons.js';
import type { TouchHandlers } from '../../directives/touch/index.js';
import type { GenericProps } from '../../util/index.js';
export type VWindowSlots = {
default: {
group: GroupProvide;
};
additional: {
group: GroupProvide;
};
prev: {
props: ControlProps;
};
next: {
props: ControlProps;
};
};
type WindowProvide = {
transition: ComputedRef<undefined | string>;
transitionCount: Ref<number>;
transitionHeight: Ref<undefined | string>;
isReversed: Ref<boolean>;
rootRef: Ref<HTMLElement | undefined>;
};
type ControlProps = {
icon: IconValue;
class: string;
onClick: () => void;
'aria-label': string;
};
export declare const VWindowSymbol: InjectionKey<WindowProvide>;
export declare const VWindowGroupSymbol: InjectionKey<GroupItemProvide>;
export declare const makeVWindowProps: <Defaults extends {
theme?: unknown;
class?: unknown;
style?: unknown;
tag?: unknown;
continuous?: unknown;
nextIcon?: unknown;
prevIcon?: unknown;
reverse?: unknown;
showArrows?: unknown;
verticalArrows?: unknown;
touch?: unknown;
direction?: unknown;
modelValue?: unknown;
disabled?: unknown;
selectedClass?: unknown;
mandatory?: unknown;
crossfade?: unknown;
transitionDuration?: unknown;
} = {}>(defaults?: Defaults | undefined) => {
theme: unknown extends Defaults["theme"] ? StringConstructor : {
type: PropType<unknown extends Defaults["theme"] ? string : string | Defaults["theme"]>;
default: unknown extends Defaults["theme"] ? string : string | Defaults["theme"];
};
class: unknown extends Defaults["class"] ? PropType<any> : {
type: PropType<unknown extends Defaults["class"] ? any : any>;
default: unknown extends Defaults["class"] ? any : any;
};
style: unknown extends Defaults["style"] ? {
type: PropType<import("vue").StyleValue>;
default: null;
} : Omit<{
type: PropType<import("vue").StyleValue>;
default: null;
}, "default" | "type"> & {
type: PropType<unknown extends Defaults["style"] ? import("vue").StyleValue : Defaults["style"] | import("vue").StyleValue>;
default: unknown extends Defaults["style"] ? import("vue").StyleValue : Defaults["style"] | NonNullable<import("vue").StyleValue>;
};
tag: unknown extends Defaults["tag"] ? {
type: PropType<string | import("../../util/index.js").JSXComponent>;
default: string;
} : Omit<{
type: PropType<string | import("../../util/index.js").JSXComponent>;
default: string;
}, "default" | "type"> & {
type: PropType<unknown extends Defaults["tag"] ? string | import("../../util/index.js").JSXComponent : string | Defaults["tag"] | import("../../util/index.js").JSXComponent>;
default: unknown extends Defaults["tag"] ? string | import("../../util/index.js").JSXComponent : Defaults["tag"] | NonNullable<string | import("../../util/index.js").JSXComponent>;
};
continuous: unknown extends Defaults["continuous"] ? BooleanConstructor : {
type: PropType<unknown extends Defaults["continuous"] ? boolean : boolean | Defaults["continuous"]>;
default: unknown extends Defaults["continuous"] ? boolean : boolean | Defaults["continuous"];
};
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>;
};
reverse: unknown extends Defaults["reverse"] ? BooleanConstructor : {
type: PropType<unknown extends Defaults["reverse"] ? boolean : boolean | Defaults["reverse"]>;
default: unknown extends Defaults["reverse"] ? boolean : boolean | Defaults["reverse"];
};
showArrows: unknown extends Defaults["showArrows"] ? {
type: (BooleanConstructor | StringConstructor)[];
validator: (v: any) => boolean;
} : Omit<{
type: (BooleanConstructor | StringConstructor)[];
validator: (v: any) => boolean;
}, "default" | "type"> & {
type: PropType<unknown extends Defaults["showArrows"] ? string | boolean : string | boolean | Defaults["showArrows"]>;
default: unknown extends Defaults["showArrows"] ? string | boolean : Defaults["showArrows"] | NonNullable<string | boolean>;
};
verticalArrows: unknown extends Defaults["verticalArrows"] ? PropType<"left" | "right" | boolean> : {
type: PropType<unknown extends Defaults["verticalArrows"] ? "left" | "right" | boolean : "left" | "right" | boolean | Defaults["verticalArrows"]>;
default: unknown extends Defaults["verticalArrows"] ? "left" | "right" | boolean : Defaults["verticalArrows"] | NonNullable<"left" | "right" | boolean>;
};
touch: unknown extends Defaults["touch"] ? {
type: PropType<boolean | TouchHandlers>;
default: undefined;
} : Omit<{
type: PropType<boolean | TouchHandlers>;
default: undefined;
}, "default" | "type"> & {
type: PropType<unknown extends Defaults["touch"] ? boolean | TouchHandlers : boolean | TouchHandlers | Defaults["touch"]>;
default: unknown extends Defaults["touch"] ? boolean | TouchHandlers : Defaults["touch"] | NonNullable<boolean | TouchHandlers>;
};
direction: unknown extends Defaults["direction"] ? {
type: PropType<'horizontal' | 'vertical'>;
default: string;
} : Omit<{
type: PropType<'horizontal' | 'vertical'>;
default: string;
}, "default" | "type"> & {
type: PropType<unknown extends Defaults["direction"] ? "horizontal" | "vertical" : "horizontal" | "vertical" | Defaults["direction"]>;
default: unknown extends Defaults["direction"] ? "horizontal" | "vertical" : Defaults["direction"] | NonNullable<"horizontal" | "vertical">;
};
modelValue: unknown extends Defaults["modelValue"] ? null : {
type: PropType<unknown extends Defaults["modelValue"] ? any : any>;
default: unknown extends Defaults["modelValue"] ? any : any;
};
disabled: unknown extends Defaults["disabled"] ? BooleanConstructor : {
type: PropType<unknown extends Defaults["disabled"] ? boolean : boolean | Defaults["disabled"]>;
default: unknown extends Defaults["disabled"] ? boolean : boolean | Defaults["disabled"];
};
selectedClass: unknown extends Defaults["selectedClass"] ? {
type: StringConstructor;
default: string;
} : Omit<{
type: StringConstructor;
default: string;
}, "default" | "type"> & {
type: PropType<unknown extends Defaults["selectedClass"] ? string : string | Defaults["selectedClass"]>;
default: unknown extends Defaults["selectedClass"] ? string : string | Defaults["selectedClass"];
};
mandatory: unknown extends Defaults["mandatory"] ? {
type: PropType<boolean | 'force'>;
default: 'force';
} : Omit<{
type: PropType<boolean | 'force'>;
default: 'force';
}, "default" | "type"> & {
type: PropType<unknown extends Defaults["mandatory"] ? "force" | boolean : "force" | boolean | Defaults["mandatory"]>;
default: unknown extends Defaults["mandatory"] ? "force" | boolean : Defaults["mandatory"] | NonNullable<"force" | boolean>;
};
crossfade: unknown extends Defaults["crossfade"] ? BooleanConstructor : {
type: PropType<unknown extends Defaults["crossfade"] ? boolean : boolean | Defaults["crossfade"]>;
default: unknown extends Defaults["crossfade"] ? boolean : boolean | Defaults["crossfade"];
};
transitionDuration: unknown extends Defaults["transitionDuration"] ? NumberConstructor : {
type: PropType<unknown extends Defaults["transitionDuration"] ? number : number | Defaults["transitionDuration"]>;
default: unknown extends Defaults["transitionDuration"] ? number : number | Defaults["transitionDuration"];
};
};
export declare const VWindow: {
new (...args: any[]): import("vue").CreateComponentPublicInstanceWithMixins<{
style: string | false | import("vue").StyleValue[] | import("vue").CSSProperties | null;
tag: string | import("../../util/index.js").JSXComponent;
continuous: boolean;
nextIcon: IconValue;
prevIcon: IconValue;
reverse: boolean;
direction: "horizontal" | "vertical";
disabled: boolean;
selectedClass: string;
mandatory: "force" | boolean;
crossfade: boolean;
} & {
theme?: string | undefined;
class?: any;
showArrows?: string | boolean | undefined;
verticalArrows?: "left" | "right" | boolean | undefined;
touch?: boolean | TouchHandlers | undefined;
transitionDuration?: number | undefined;
} & {}, {
group: GroupProvide;
}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, Omit<{
'update:modelValue': (value: any) => true;
}, "$children" | "modelValue" | "update:modelValue" | "v-slot:additional" | "v-slot:default" | "v-slot:next" | "v-slot:prev" | "v-slots">, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, {
style: import("vue").StyleValue;
tag: string | import("../../util/index.js").JSXComponent;
continuous: boolean;
nextIcon: IconValue;
prevIcon: IconValue;
reverse: boolean;
touch: boolean | TouchHandlers;
direction: "horizontal" | "vertical";
disabled: boolean;
selectedClass: string;
mandatory: "force" | boolean;
crossfade: boolean;
}, true, {}, import("vue").SlotsType<Partial<{
default: (arg: {
group: GroupProvide;
}) => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>[];
additional: (arg: {
group: GroupProvide;
}) => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>[];
prev: (arg: {
props: ControlProps;
}) => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>[];
next: (arg: {
props: ControlProps;
}) => 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: {};
}, {
style: string | false | import("vue").StyleValue[] | import("vue").CSSProperties | null;
tag: string | import("../../util/index.js").JSXComponent;
continuous: boolean;
nextIcon: IconValue;
prevIcon: IconValue;
reverse: boolean;
direction: "horizontal" | "vertical";
disabled: boolean;
selectedClass: string;
mandatory: "force" | boolean;
crossfade: boolean;
} & {
theme?: string | undefined;
class?: any;
showArrows?: string | boolean | undefined;
verticalArrows?: "left" | "right" | boolean | undefined;
touch?: boolean | TouchHandlers | undefined;
transitionDuration?: number | undefined;
} & {}, {
group: GroupProvide;
}, {}, {}, {}, {
style: import("vue").StyleValue;
tag: string | import("../../util/index.js").JSXComponent;
continuous: boolean;
nextIcon: IconValue;
prevIcon: IconValue;
reverse: boolean;
touch: boolean | TouchHandlers;
direction: "horizontal" | "vertical";
disabled: boolean;
selectedClass: string;
mandatory: "force" | boolean;
crossfade: boolean;
}>;
__isFragment?: never;
__isTeleport?: never;
__isSuspense?: never;
} & import("vue").ComponentOptionsBase<{
style: string | false | import("vue").StyleValue[] | import("vue").CSSProperties | null;
tag: string | import("../../util/index.js").JSXComponent;
continuous: boolean;
nextIcon: IconValue;
prevIcon: IconValue;
reverse: boolean;
direction: "horizontal" | "vertical";
disabled: boolean;
selectedClass: string;
mandatory: "force" | boolean;
crossfade: boolean;
} & {
theme?: string | undefined;
class?: any;
showArrows?: string | boolean | undefined;
verticalArrows?: "left" | "right" | boolean | undefined;
touch?: boolean | TouchHandlers | undefined;
transitionDuration?: number | undefined;
} & {}, {
group: GroupProvide;
}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, Omit<{
'update:modelValue': (value: any) => true;
}, "$children" | "modelValue" | "update:modelValue" | "v-slot:additional" | "v-slot:default" | "v-slot:next" | "v-slot:prev" | "v-slots">, string, {
style: import("vue").StyleValue;
tag: string | import("../../util/index.js").JSXComponent;
continuous: boolean;
nextIcon: IconValue;
prevIcon: IconValue;
reverse: boolean;
touch: boolean | TouchHandlers;
direction: "horizontal" | "vertical";
disabled: boolean;
selectedClass: string;
mandatory: "force" | boolean;
crossfade: boolean;
}, {}, string, import("vue").SlotsType<Partial<{
default: (arg: {
group: GroupProvide;
}) => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>[];
additional: (arg: {
group: GroupProvide;
}) => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>[];
prev: (arg: {
props: ControlProps;
}) => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>[];
next: (arg: {
props: ControlProps;
}) => 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 <T>(props: {
modelValue?: T;
'onUpdate:modelValue'?: (value: T) => void;
}, slots: VWindowSlots) => GenericProps<typeof props, typeof slots>) & import("../../util/index.js").FilterPropsOptions<{
theme: StringConstructor;
class: PropType<import("../../composables/component.js").ClassValue>;
style: {
type: PropType<import("vue").StyleValue>;
default: null;
};
tag: {
type: PropType<string | import("../../util/index.js").JSXComponent>;
default: string;
};
continuous: BooleanConstructor;
nextIcon: {
type: PropType<IconValue>;
default: string;
};
prevIcon: {
type: PropType<IconValue>;
default: string;
};
reverse: BooleanConstructor;
showArrows: {
type: (BooleanConstructor | StringConstructor)[];
validator: (v: any) => boolean;
};
verticalArrows: PropType<boolean | 'left' | 'right'>;
touch: {
type: PropType<boolean | TouchHandlers>;
default: undefined;
};
direction: {
type: PropType<'horizontal' | 'vertical'>;
default: string;
};
modelValue: null;
disabled: BooleanConstructor;
selectedClass: {
type: StringConstructor;
default: string;
};
mandatory: {
type: PropType<boolean | 'force'>;
default: 'force';
};
crossfade: BooleanConstructor;
transitionDuration: NumberConstructor;
}, import("vue").ExtractPropTypes<{
theme: StringConstructor;
class: PropType<import("../../composables/component.js").ClassValue>;
style: {
type: PropType<import("vue").StyleValue>;
default: null;
};
tag: {
type: PropType<string | import("../../util/index.js").JSXComponent>;
default: string;
};
continuous: BooleanConstructor;
nextIcon: {
type: PropType<IconValue>;
default: string;
};
prevIcon: {
type: PropType<IconValue>;
default: string;
};
reverse: BooleanConstructor;
showArrows: {
type: (BooleanConstructor | StringConstructor)[];
validator: (v: any) => boolean;
};
verticalArrows: PropType<boolean | 'left' | 'right'>;
touch: {
type: PropType<boolean | TouchHandlers>;
default: undefined;
};
direction: {
type: PropType<'horizontal' | 'vertical'>;
default: string;
};
modelValue: null;
disabled: BooleanConstructor;
selectedClass: {
type: StringConstructor;
default: string;
};
mandatory: {
type: PropType<boolean | 'force'>;
default: 'force';
};
crossfade: BooleanConstructor;
transitionDuration: NumberConstructor;
}>>;
export type VWindow = InstanceType<typeof VWindow>;
+259
View File
@@ -0,0 +1,259 @@
import { createVNode as _createVNode, createElementVNode as _createElementVNode, normalizeClass as _normalizeClass, normalizeStyle as _normalizeStyle, withDirectives as _withDirectives } from "vue";
// Styles
import "./VWindow.css";
// Components
import { VBtn } from "../VBtn/index.js"; // Composables
import { makeComponentProps } from "../../composables/component.js";
import { useGroup } from "../../composables/group.js";
import { useLocale, useRtl } from "../../composables/locale.js";
import { makeTagProps } from "../../composables/tag.js";
import { makeThemeProps, provideTheme } from "../../composables/theme.js"; // Directives
import vTouch from "../../directives/touch/index.js"; // Utilities
import { computed, nextTick, provide, ref, shallowRef, toRef, watch } from 'vue';
import { convertToUnit, genericComponent, IN_BROWSER, PREFERS_REDUCED_MOTION, propsFactory, useRender } from "../../util/index.js";
import { getScrollParent } from "../../util/getScrollParent.js"; // Types
export const VWindowSymbol = Symbol.for('vuetify:v-window');
export const VWindowGroupSymbol = Symbol.for('vuetify:v-window-group');
export const makeVWindowProps = propsFactory({
continuous: Boolean,
nextIcon: {
type: [Boolean, String, Function, Object],
default: '$next'
},
prevIcon: {
type: [Boolean, String, Function, Object],
default: '$prev'
},
reverse: Boolean,
showArrows: {
type: [Boolean, String],
validator: v => typeof v === 'boolean' || v === 'hover'
},
verticalArrows: [Boolean, String],
touch: {
type: [Object, Boolean],
default: undefined
},
direction: {
type: String,
default: 'horizontal'
},
modelValue: null,
disabled: Boolean,
selectedClass: {
type: String,
default: 'v-window-item--active'
},
// TODO: mandatory should probably not be exposed but do this for now
mandatory: {
type: [Boolean, String],
default: 'force'
},
crossfade: Boolean,
transitionDuration: Number,
...makeComponentProps(),
...makeTagProps(),
...makeThemeProps()
}, 'VWindow');
export const VWindow = genericComponent()({
name: 'VWindow',
directives: {
vTouch
},
props: makeVWindowProps(),
emits: {
'update:modelValue': value => true
},
setup(props, {
slots
}) {
const {
themeClasses
} = provideTheme(props);
const {
isRtl
} = useRtl();
const {
t
} = useLocale();
const group = useGroup(props, VWindowGroupSymbol);
const rootRef = ref();
const isRtlReverse = computed(() => isRtl.value ? !props.reverse : props.reverse);
const isReversed = shallowRef(false);
const transition = computed(() => {
if (props.crossfade) {
return 'v-window-crossfade-transition';
}
const axis = props.direction === 'vertical' ? 'y' : 'x';
const reverse = isRtlReverse.value ? !isReversed.value : isReversed.value;
const direction = reverse ? '-reverse' : '';
return `v-window-${axis}${direction}-transition`;
});
const transitionCount = shallowRef(0);
const transitionHeight = ref(undefined);
const activeIndex = computed(() => {
return group.items.value.findIndex(item => group.selected.value.includes(item.id));
});
// Fix for https://github.com/vuetifyjs/vuetify/issues/18447
watch(activeIndex, (newVal, oldVal) => {
let scrollableParent;
const savedScrollPosition = {
left: 0,
top: 0
};
if (IN_BROWSER && oldVal >= 0) {
scrollableParent = getScrollParent(rootRef.value);
savedScrollPosition.left = scrollableParent?.scrollLeft;
savedScrollPosition.top = scrollableParent?.scrollTop;
}
const itemsLength = group.items.value.length;
const lastIndex = itemsLength - 1;
if (itemsLength <= 2) {
isReversed.value = newVal < oldVal;
} else if (newVal === lastIndex && oldVal === 0) {
isReversed.value = false;
} else if (newVal === 0 && oldVal === lastIndex) {
isReversed.value = true;
} else {
isReversed.value = newVal < oldVal;
}
nextTick(() => {
if (!IN_BROWSER || !scrollableParent) return;
const currentScrollY = scrollableParent.scrollTop;
if (currentScrollY !== savedScrollPosition.top) {
scrollableParent.scrollTo({
...savedScrollPosition,
behavior: 'instant'
});
}
requestAnimationFrame(() => {
if (!scrollableParent) return;
const rafScrollY = scrollableParent.scrollTop;
if (rafScrollY !== savedScrollPosition.top) {
scrollableParent.scrollTo({
...savedScrollPosition,
behavior: 'instant'
});
}
});
});
}, {
flush: 'sync'
}); // Run synchronously before DOM updates
provide(VWindowSymbol, {
transition,
isReversed,
transitionCount,
transitionHeight,
rootRef
});
const canMoveBack = toRef(() => props.continuous || activeIndex.value !== 0);
const canMoveForward = toRef(() => props.continuous || activeIndex.value !== group.items.value.length - 1);
function prev() {
canMoveBack.value && group.prev();
}
function next() {
canMoveForward.value && group.next();
}
const arrows = computed(() => {
const arrows = [];
const prevProps = {
icon: isRtl.value ? props.nextIcon : props.prevIcon,
class: `v-window__${isRtlReverse.value ? 'right' : 'left'}`,
onClick: group.prev,
'aria-label': t('$vuetify.carousel.prev')
};
arrows.push(canMoveBack.value ? slots.prev ? slots.prev({
props: prevProps
}) : _createVNode(VBtn, prevProps, null) : _createElementVNode("div", null, null));
const nextProps = {
icon: isRtl.value ? props.prevIcon : props.nextIcon,
class: `v-window__${isRtlReverse.value ? 'left' : 'right'}`,
onClick: group.next,
'aria-label': t('$vuetify.carousel.next')
};
arrows.push(canMoveForward.value ? slots.next ? slots.next({
props: nextProps
}) : _createVNode(VBtn, nextProps, null) : _createElementVNode("div", null, null));
return arrows;
});
const touchOptions = computed(() => {
if (props.touch === false) return props.touch;
const options = {
left: () => {
isRtlReverse.value ? prev() : next();
},
right: () => {
isRtlReverse.value ? next() : prev();
},
start: ({
originalEvent
}) => {
originalEvent.stopPropagation();
}
};
return {
...options,
...(props.touch === true ? {} : props.touch)
};
});
function onKeyDown(e) {
if (props.direction === 'horizontal' && e.key === 'ArrowLeft' || props.direction === 'vertical' && e.key === 'ArrowUp') {
e.preventDefault();
prev();
nextTick(() => {
canMoveBack.value ? focusArrow(0) : focusArrow(1);
});
}
if (props.direction === 'horizontal' && e.key === 'ArrowRight' || props.direction === 'vertical' && e.key === 'ArrowDown') {
e.preventDefault();
next();
nextTick(() => {
canMoveForward.value ? focusArrow(1) : focusArrow(0);
});
}
}
function focusArrow(index) {
const arrow = arrows.value[index];
if (!arrow) return;
const arrowEl = Array.isArray(arrow) ? arrow[0] : arrow;
arrowEl.el?.focus();
}
useRender(() => _withDirectives(_createVNode(props.tag, {
"ref": rootRef,
"class": _normalizeClass(['v-window', {
'v-window--show-arrows-on-hover': props.showArrows === 'hover',
'v-window--vertical-arrows': !!props.verticalArrows,
'v-window--crossfade': !!props.crossfade
}, themeClasses.value, props.class]),
"style": _normalizeStyle([props.style, {
'--v-window-transition-duration': !PREFERS_REDUCED_MOTION() ? convertToUnit(props.transitionDuration, 'ms') : null
}])
}, {
default: () => [_createElementVNode("div", {
"class": "v-window__container",
"style": {
height: transitionHeight.value
}
}, [slots.default?.({
group
}), props.showArrows !== false && _createElementVNode("div", {
"class": _normalizeClass(['v-window__controls', {
'v-window__controls--left': props.verticalArrows === 'left' || props.verticalArrows === true
}, {
'v-window__controls--right': props.verticalArrows === 'right'
}]),
"onKeydown": onKeyDown
}, [arrows.value])]), slots.additional?.({
group
})]
}), [[vTouch, touchOptions.value]]));
return {
group
};
}
});
//# sourceMappingURL=VWindow.js.map
File diff suppressed because one or more lines are too long
+141
View File
@@ -0,0 +1,141 @@
@use 'sass:selector'
@use '../../styles/tools'
@use './variables' as *
@include tools.layer('components')
.v-window
overflow: hidden
&__container
display: flex
flex-direction: column
height: inherit
position: relative
transition: $window-transition
&__controls
position: absolute
left: 0
top: 0
width: 100%
height: 100%
display: flex
align-items: center
justify-content: space-between
padding: $window-controls-padding
pointer-events: none
> *
pointer-events: auto
&--show-arrows-on-hover
overflow: hidden
.v-window__left
transform: translateX(-200%)
@at-root #{selector.append(':has(.v-window__controls--right)', &)}
.v-window__left
transform: translateX(200%)
.v-window__right
transform: translateX(200%)
@at-root #{selector.append(':has(.v-window__controls--left)', &)}
.v-window__right
transform: translateX(-200%)
&:hover
.v-window__left,
.v-window__right
transform: translateX(0)
&--vertical-arrows
.v-window__controls
flex-direction: column
justify-content: center
gap: $window-controls-vertical-gap
&--left
align-items: start
&--right
align-items: end
.v-window__left,
.v-window__right
.v-icon
transform: rotate(90deg)
&--crossfade > .v-window__container
isolation: isolate
> .v-window-item
mix-blend-mode: $window-crossfade-blend-mode
@include tools.layer('overrides')
.v-window-item
transition-duration: var(--v-window-transition-duration, revert-layer)
@include tools.layer('transitions')
.v-window
&-x-transition,
&-x-reverse-transition,
&-y-transition,
&-y-reverse-transition
&-enter-active,
&-leave-active
transition: $window-transition
@media (prefers-reduced-motion: reduce)
transition-duration: 0s
&-leave-from,
&-leave-to
position: absolute
top: 0
width: 100%
&-x-transition
&-enter-from
transform: translateX(100%)
&-leave-to
transform: translateX(-100%)
&-x-reverse-transition
&-enter-from
transform: translateX(-100%)
&-leave-to
transform: translateX(100%)
&-y-transition
&-enter-from
transform: translateY(100%)
&-leave-to
transform: translateY(-100%)
&-y-reverse-transition
&-enter-from
transform: translateY(-100%)
&-leave-to
transform: translateY(100%)
.v-window
&-crossfade-transition
&-enter-active,
&-leave-active
transition: $window-transition
&-leave-from,
&-leave-to
position: absolute
top: 0
width: 100%
&-enter-from,
&-leave-to
opacity: 0
+226
View File
@@ -0,0 +1,226 @@
export declare const makeVWindowItemProps: <Defaults extends {
class?: unknown;
style?: unknown;
value?: unknown;
disabled?: unknown;
selectedClass?: unknown;
eager?: unknown;
reverseTransition?: unknown;
transition?: unknown;
} = {}>(defaults?: Defaults | undefined) => {
class: unknown extends Defaults["class"] ? import("vue").PropType<any> : {
type: import("vue").PropType<unknown extends Defaults["class"] ? any : any>;
default: unknown extends Defaults["class"] ? any : any;
};
style: unknown extends Defaults["style"] ? {
type: import("vue").PropType<import("vue").StyleValue>;
default: null;
} : Omit<{
type: import("vue").PropType<import("vue").StyleValue>;
default: null;
}, "default" | "type"> & {
type: import("vue").PropType<unknown extends Defaults["style"] ? import("vue").StyleValue : Defaults["style"] | import("vue").StyleValue>;
default: unknown extends Defaults["style"] ? import("vue").StyleValue : Defaults["style"] | NonNullable<import("vue").StyleValue>;
};
value: unknown extends Defaults["value"] ? null : {
type: import("vue").PropType<unknown extends Defaults["value"] ? any : any>;
default: unknown extends Defaults["value"] ? any : any;
};
disabled: unknown extends Defaults["disabled"] ? BooleanConstructor : {
type: import("vue").PropType<unknown extends Defaults["disabled"] ? boolean : boolean | Defaults["disabled"]>;
default: unknown extends Defaults["disabled"] ? boolean : boolean | Defaults["disabled"];
};
selectedClass: unknown extends Defaults["selectedClass"] ? StringConstructor : {
type: import("vue").PropType<unknown extends Defaults["selectedClass"] ? string : string | Defaults["selectedClass"]>;
default: unknown extends Defaults["selectedClass"] ? string : string | Defaults["selectedClass"];
};
eager: unknown extends Defaults["eager"] ? BooleanConstructor : {
type: import("vue").PropType<unknown extends Defaults["eager"] ? boolean : boolean | Defaults["eager"]>;
default: unknown extends Defaults["eager"] ? boolean : boolean | Defaults["eager"];
};
reverseTransition: unknown extends Defaults["reverseTransition"] ? {
type: (BooleanConstructor | StringConstructor)[];
default: undefined;
} : Omit<{
type: (BooleanConstructor | StringConstructor)[];
default: undefined;
}, "default" | "type"> & {
type: import("vue").PropType<unknown extends Defaults["reverseTransition"] ? string | boolean : string | boolean | Defaults["reverseTransition"]>;
default: unknown extends Defaults["reverseTransition"] ? string | boolean : Defaults["reverseTransition"] | NonNullable<string | boolean>;
};
transition: unknown extends Defaults["transition"] ? {
type: (BooleanConstructor | StringConstructor)[];
default: undefined;
} : Omit<{
type: (BooleanConstructor | StringConstructor)[];
default: undefined;
}, "default" | "type"> & {
type: import("vue").PropType<unknown extends Defaults["transition"] ? string | boolean : string | boolean | Defaults["transition"]>;
default: unknown extends Defaults["transition"] ? string | boolean : Defaults["transition"] | NonNullable<string | boolean>;
};
};
export declare const VWindowItem: {
new (...args: any[]): import("vue").CreateComponentPublicInstanceWithMixins<{
style: string | false | import("vue").StyleValue[] | import("vue").CSSProperties | null;
disabled: boolean;
eager: boolean;
} & {
class?: any;
value?: any;
selectedClass?: string | undefined;
reverseTransition?: string | boolean | undefined;
transition?: string | boolean | undefined;
} & {
$children?: {
default?: (() => import("vue").VNodeChild) | undefined;
} | {
$stable?: boolean;
} | (() => import("vue").VNodeChild) | import("vue").VNodeChild;
'v-slots'?: {
default?: false | (() => import("vue").VNodeChild) | undefined;
} | undefined;
} & {
"v-slot:default"?: false | (() => import("vue").VNodeChild) | undefined;
} & {
"onGroup:selected"?: ((val: {
value: boolean;
}) => any) | undefined;
}, {
groupItem: import("../../composables/group.js").GroupItemProvide;
}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
'group:selected': (val: {
value: boolean;
}) => true;
}, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, {
style: import("vue").StyleValue;
disabled: boolean;
eager: boolean;
reverseTransition: string | boolean;
transition: string | boolean;
}, true, {}, import("vue").SlotsType<Partial<{
default: () => 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: {};
}, {
style: string | false | import("vue").StyleValue[] | import("vue").CSSProperties | null;
disabled: boolean;
eager: boolean;
} & {
class?: any;
value?: any;
selectedClass?: string | undefined;
reverseTransition?: string | boolean | undefined;
transition?: string | boolean | undefined;
} & {
$children?: {
default?: (() => import("vue").VNodeChild) | undefined;
} | {
$stable?: boolean;
} | (() => import("vue").VNodeChild) | import("vue").VNodeChild;
'v-slots'?: {
default?: false | (() => import("vue").VNodeChild) | undefined;
} | undefined;
} & {
"v-slot:default"?: false | (() => import("vue").VNodeChild) | undefined;
} & {
"onGroup:selected"?: ((val: {
value: boolean;
}) => any) | undefined;
}, {
groupItem: import("../../composables/group.js").GroupItemProvide;
}, {}, {}, {}, {
style: import("vue").StyleValue;
disabled: boolean;
eager: boolean;
reverseTransition: string | boolean;
transition: string | boolean;
}>;
__isFragment?: never;
__isTeleport?: never;
__isSuspense?: never;
} & import("vue").ComponentOptionsBase<{
style: string | false | import("vue").StyleValue[] | import("vue").CSSProperties | null;
disabled: boolean;
eager: boolean;
} & {
class?: any;
value?: any;
selectedClass?: string | undefined;
reverseTransition?: string | boolean | undefined;
transition?: string | boolean | undefined;
} & {
$children?: {
default?: (() => import("vue").VNodeChild) | undefined;
} | {
$stable?: boolean;
} | (() => import("vue").VNodeChild) | import("vue").VNodeChild;
'v-slots'?: {
default?: false | (() => import("vue").VNodeChild) | undefined;
} | undefined;
} & {
"v-slot:default"?: false | (() => import("vue").VNodeChild) | undefined;
} & {
"onGroup:selected"?: ((val: {
value: boolean;
}) => any) | undefined;
}, {
groupItem: import("../../composables/group.js").GroupItemProvide;
}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
'group:selected': (val: {
value: boolean;
}) => true;
}, string, {
style: import("vue").StyleValue;
disabled: boolean;
eager: boolean;
reverseTransition: string | boolean;
transition: string | boolean;
}, {}, string, import("vue").SlotsType<Partial<{
default: () => 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<{
class: import("vue").PropType<any>;
style: {
type: import("vue").PropType<import("vue").StyleValue>;
default: null;
};
value: null;
disabled: BooleanConstructor;
selectedClass: StringConstructor;
eager: BooleanConstructor;
reverseTransition: {
type: (BooleanConstructor | StringConstructor)[];
default: undefined;
};
transition: {
type: (BooleanConstructor | StringConstructor)[];
default: undefined;
};
}, import("vue").ExtractPropTypes<{
class: import("vue").PropType<any>;
style: {
type: import("vue").PropType<import("vue").StyleValue>;
default: null;
};
value: null;
disabled: BooleanConstructor;
selectedClass: StringConstructor;
eager: BooleanConstructor;
reverseTransition: {
type: (BooleanConstructor | StringConstructor)[];
default: undefined;
};
transition: {
type: (BooleanConstructor | StringConstructor)[];
default: undefined;
};
}>>;
export type VWindowItem = InstanceType<typeof VWindowItem>;
+121
View File
@@ -0,0 +1,121 @@
import { vShow as _vShow, normalizeClass as _normalizeClass, normalizeStyle as _normalizeStyle, createElementVNode as _createElementVNode, withDirectives as _withDirectives, createVNode as _createVNode } from "vue";
// Composables
import { makeComponentProps } from "../../composables/component.js";
import { makeGroupItemProps, useGroupItem } from "../../composables/group.js";
import { makeLazyProps, useLazy } from "../../composables/lazy.js";
import { useSsrBoot } from "../../composables/ssrBoot.js";
import { MaybeTransition } from "../../composables/transition.js"; // Directives
import vTouch from "../../directives/touch/index.js"; // Utilities
import { computed, inject, nextTick, shallowRef } from 'vue';
import { convertToUnit, genericComponent, propsFactory, useRender } from "../../util/index.js"; // Types
import { VWindowGroupSymbol, VWindowSymbol } from "./VWindow.js";
export const makeVWindowItemProps = propsFactory({
reverseTransition: {
type: [Boolean, String],
default: undefined
},
transition: {
type: [Boolean, String],
default: undefined
},
...makeComponentProps(),
...makeGroupItemProps(),
...makeLazyProps()
}, 'VWindowItem');
export const VWindowItem = genericComponent()({
name: 'VWindowItem',
directives: {
vTouch
},
props: makeVWindowItemProps(),
emits: {
'group:selected': val => true
},
setup(props, {
slots
}) {
const window = inject(VWindowSymbol);
const groupItem = useGroupItem(props, VWindowGroupSymbol);
const {
isBooted
} = useSsrBoot();
if (!window || !groupItem) throw new Error('[Vuetify] VWindowItem must be used inside VWindow');
const isTransitioning = shallowRef(false);
const hasTransition = computed(() => isBooted.value && (window.isReversed.value ? props.reverseTransition !== false : props.transition !== false));
function onAfterTransition() {
if (!isTransitioning.value || !window) {
return;
}
// Finalize transition state.
isTransitioning.value = false;
if (window.transitionCount.value > 0) {
window.transitionCount.value -= 1;
// Remove container height if we are out of transition.
if (window.transitionCount.value === 0) {
window.transitionHeight.value = undefined;
}
}
}
function onBeforeTransition() {
if (isTransitioning.value || !window) {
return;
}
// Initialize transition state here.
isTransitioning.value = true;
if (window.transitionCount.value === 0) {
// Set initial height for height transition.
window.transitionHeight.value = convertToUnit(window.rootRef.value?.clientHeight);
}
window.transitionCount.value += 1;
}
function onTransitionCancelled() {
onAfterTransition(); // This should have the same path as normal transition end.
}
function onEnterTransition(el) {
if (!isTransitioning.value) {
return;
}
nextTick(() => {
// Do not set height if no transition or cancelled.
if (!hasTransition.value || !isTransitioning.value || !window) {
return;
}
// Set transition target height.
window.transitionHeight.value = convertToUnit(el.clientHeight);
});
}
const transition = computed(() => {
const name = window.isReversed.value ? props.reverseTransition : props.transition;
return !hasTransition.value ? false : {
name: typeof name !== 'string' ? window.transition.value : name,
onBeforeEnter: onBeforeTransition,
onAfterEnter: onAfterTransition,
onEnterCancelled: onTransitionCancelled,
onBeforeLeave: onBeforeTransition,
onAfterLeave: onAfterTransition,
onLeaveCancelled: onTransitionCancelled,
onEnter: onEnterTransition
};
});
const {
hasContent
} = useLazy(props, groupItem.isSelected);
useRender(() => _createVNode(MaybeTransition, {
"transition": transition.value,
"disabled": !isBooted.value
}, {
default: () => [_withDirectives(_createElementVNode("div", {
"class": _normalizeClass(['v-window-item', groupItem.selectedClass.value, props.class]),
"style": _normalizeStyle(props.style)
}, [hasContent.value && slots.default?.()]), [[_vShow, groupItem.isSelected.value]])]
}));
return {
groupItem
};
}
});
//# sourceMappingURL=VWindowItem.js.map
File diff suppressed because one or more lines are too long
+7
View File
@@ -0,0 +1,7 @@
@use '../../styles/settings';
// VWindow
$window-transition: .3s cubic-bezier(.25, .8, .50, 1) !default;
$window-controls-padding: 0 16px !default;
$window-controls-vertical-gap: 12px !default;
$window-crossfade-blend-mode: plus-lighter !default;
+2
View File
@@ -0,0 +1,2 @@
export { VWindow } from './VWindow.js';
export { VWindowItem } from './VWindowItem.js';
+3
View File
@@ -0,0 +1,3 @@
export { VWindow } from "./VWindow.js";
export { VWindowItem } from "./VWindowItem.js";
//# sourceMappingURL=index.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.js","names":["VWindow","VWindowItem"],"sources":["../../../src/components/VWindow/index.ts"],"sourcesContent":["export { VWindow } from './VWindow'\nexport { VWindowItem } from './VWindowItem'\n"],"mappings":"SAASA,OAAO;AAAA,SACPC,WAAW","ignoreList":[]}