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
+23
View File
@@ -0,0 +1,23 @@
@layer vuetify-components {
.v-menu > .v-overlay__content {
display: flex;
flex-direction: column;
}
.v-menu > .v-overlay__content {
border-radius: 4px;
}
.v-menu > .v-overlay__content > .v-card,
.v-menu > .v-overlay__content > .v-sheet,
.v-menu > .v-overlay__content > .v-list {
background: rgb(var(--v-theme-surface));
border-radius: inherit;
overflow: auto;
height: 100%;
}
.v-menu > .v-overlay__content > .v-card,
.v-menu > .v-overlay__content > .v-sheet,
.v-menu > .v-overlay__content > .v-list {
box-shadow: 0px 1px 3px 0px rgba(var(--v-shadow-color), var(--v-shadow-key-opacity, 0.3)), 0px 4px 8px 3px rgba(var(--v-shadow-color), var(--v-shadow-ambient-opacity, 0.15));
--v-elevation-overlay: color-mix(in srgb, var(--v-elevation-overlay-color) 6%, transparent);
}
}
File diff suppressed because it is too large Load Diff
+161
View File
@@ -0,0 +1,161 @@
import { createVNode as _createVNode, mergeProps as _mergeProps } from "vue";
// Styles
import "./VMenu.css";
// Components
import { VDialogTransition } from "../transitions/index.js";
import { VDefaultsProvider } from "../VDefaultsProvider/index.js";
import { VOverlay } from "../VOverlay/index.js";
import { makeVOverlayProps } from "../VOverlay/VOverlay.js"; // Composables
import { forwardRefs } from "../../composables/forwardRefs.js";
import { useRtl } from "../../composables/locale.js";
import { useProxiedModel } from "../../composables/proxiedModel.js";
import { useScopeId } from "../../composables/scopeId.js"; // Utilities
import { computed, inject, mergeProps, onBeforeUnmount, onDeactivated, provide, ref, shallowRef, toRef, useId, watch } from 'vue';
import { VMenuSymbol } from "./shared.js";
import { focusableChildren, focusChild, genericComponent, getNextElement, isClickInsideElement, omit, propsFactory, useRender } from "../../util/index.js"; // Types
export const makeVMenuProps = propsFactory({
// TODO
// disableKeys: Boolean,
id: String,
submenu: Boolean,
...omit(makeVOverlayProps({
captureFocus: true,
closeDelay: 250,
closeOnContentClick: true,
locationStrategy: 'connected',
location: undefined,
openDelay: 300,
scrim: false,
scrollStrategy: 'reposition',
transition: {
component: VDialogTransition
}
}), ['absolute'])
}, 'VMenu');
export const VMenu = genericComponent()({
name: 'VMenu',
props: makeVMenuProps(),
emits: {
'update:modelValue': value => true
},
setup(props, {
slots
}) {
const isActive = useProxiedModel(props, 'modelValue');
const {
scopeId
} = useScopeId();
const {
isRtl
} = useRtl();
const uid = useId();
const id = toRef(() => props.id || `v-menu-${uid}`);
const overlay = ref();
const parent = inject(VMenuSymbol, null);
const openChildren = shallowRef(new Set());
provide(VMenuSymbol, {
register() {
openChildren.value.add(uid);
},
unregister() {
openChildren.value.delete(uid);
},
closeParents(e) {
setTimeout(() => {
if (!openChildren.value.size && !props.persistent && (e == null || overlay.value?.contentEl && !isClickInsideElement(e, overlay.value.contentEl))) {
isActive.value = false;
parent?.closeParents();
}
}, 40);
}
});
onBeforeUnmount(() => parent?.unregister());
onDeactivated(() => isActive.value = false);
watch(isActive, val => {
val ? parent?.register() : parent?.unregister();
}, {
immediate: true
});
function onClickOutside(e) {
parent?.closeParents(e);
}
function onKeydown(e) {
if (props.disabled) return;
if (e.key === 'Tab' || e.key === 'Enter' && !props.closeOnContentClick) {
if (e.key === 'Enter' && (e.target instanceof HTMLTextAreaElement || e.target instanceof HTMLInputElement && !!e.target.closest('form'))) return;
if (e.key === 'Enter') e.preventDefault();
const nextElement = getNextElement(focusableChildren(overlay.value?.contentEl, false), e.shiftKey ? 'prev' : 'next', el => el.tabIndex >= 0);
if (!nextElement && !props.retainFocus) {
isActive.value = false;
overlay.value?.activatorEl?.focus();
}
} else if (props.submenu && e.key === (isRtl.value ? 'ArrowRight' : 'ArrowLeft')) {
isActive.value = false;
overlay.value?.activatorEl?.focus();
}
}
function onActivatorKeydown(e) {
if (props.disabled) return;
const el = overlay.value?.contentEl;
if (el && isActive.value) {
if (e.key === 'ArrowDown') {
e.preventDefault();
e.stopImmediatePropagation();
focusChild(el, 'next');
} else if (e.key === 'ArrowUp') {
e.preventDefault();
e.stopImmediatePropagation();
focusChild(el, 'prev');
} else if (props.submenu) {
if (e.key === (isRtl.value ? 'ArrowRight' : 'ArrowLeft')) {
isActive.value = false;
} else if (e.key === (isRtl.value ? 'ArrowLeft' : 'ArrowRight')) {
e.preventDefault();
focusChild(el, 'first');
}
}
} else if (props.submenu ? e.key === (isRtl.value ? 'ArrowLeft' : 'ArrowRight') : ['ArrowDown', 'ArrowUp'].includes(e.key)) {
isActive.value = true;
e.preventDefault();
setTimeout(() => setTimeout(() => onActivatorKeydown(e)));
}
}
const activatorProps = computed(() => mergeProps({
'aria-haspopup': 'menu',
'aria-expanded': String(isActive.value),
'aria-controls': id.value,
'aria-owns': id.value,
onKeydown: onActivatorKeydown
}, props.activatorProps));
useRender(() => {
const overlayProps = VOverlay.filterProps(props);
return _createVNode(VOverlay, _mergeProps({
"ref": overlay,
"id": id.value,
"class": ['v-menu', props.class],
"style": props.style
}, overlayProps, {
"modelValue": isActive.value,
"onUpdate:modelValue": $event => isActive.value = $event,
"absolute": true,
"activatorProps": activatorProps.value,
"location": props.location ?? (props.submenu ? 'end' : 'bottom'),
"onClick:outside": onClickOutside,
"onKeydown": onKeydown
}, scopeId), {
activator: slots.activator,
default: (...args) => _createVNode(VDefaultsProvider, {
"root": "VMenu"
}, {
default: () => [slots.default?.(...args)]
})
});
});
return forwardRefs({
id,
ΨopenChildren: openChildren
}, overlay);
}
});
//# sourceMappingURL=VMenu.js.map
File diff suppressed because one or more lines are too long
+19
View File
@@ -0,0 +1,19 @@
@use '../../styles/tools'
@use './variables' as *
@include tools.layer('components')
.v-menu
> .v-overlay__content
display: flex
flex-direction: column
@include tools.rounded($menu-content-border-radius)
> .v-card,
> .v-sheet,
> .v-list
background: rgb(var(--v-theme-surface))
border-radius: inherit
overflow: auto
height: 100%
@include tools.elevation($menu-elevation)
+4
View File
@@ -0,0 +1,4 @@
@use '../../styles/settings';
$menu-elevation: 3 !default;
$menu-content-border-radius: settings.$border-radius-root !default;
+1
View File
@@ -0,0 +1 @@
export { VMenu } from './VMenu.js';
+2
View File
@@ -0,0 +1,2 @@
export { VMenu } from "./VMenu.js";
//# sourceMappingURL=index.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.js","names":["VMenu"],"sources":["../../../src/components/VMenu/index.ts"],"sourcesContent":["export { VMenu } from './VMenu'\n"],"mappings":"SAASA,KAAK","ignoreList":[]}
+8
View File
@@ -0,0 +1,8 @@
import type { InjectionKey } from 'vue';
interface MenuProvide {
register(): void;
unregister(): void;
closeParents(e?: MouseEvent): void;
}
export declare const VMenuSymbol: InjectionKey<MenuProvide>;
+4
View File
@@ -0,0 +1,4 @@
// Types
export const VMenuSymbol = Symbol.for('vuetify:v-menu');
//# sourceMappingURL=shared.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"shared.js","names":["VMenuSymbol","Symbol","for"],"sources":["../../../src/components/VMenu/shared.ts"],"sourcesContent":["// Types\nimport type { InjectionKey } from 'vue'\n\ninterface MenuProvide {\n register (): void\n unregister (): void\n closeParents (e?: MouseEvent): void\n}\n\nexport const VMenuSymbol: InjectionKey<MenuProvide> = Symbol.for('vuetify:v-menu')\n"],"mappings":"AAAA;;AASA,OAAO,MAAMA,WAAsC,GAAGC,MAAM,CAACC,GAAG,CAAC,gBAAgB,CAAC","ignoreList":[]}