Tracking de l'application VApp (IHM du jeu)

This commit is contained in:
2025-05-11 18:04:12 +02:00
commit 89e9db9b62
17763 changed files with 3718499 additions and 0 deletions

View File

@ -0,0 +1,99 @@
.v-navigation-drawer {
-webkit-overflow-scrolling: touch;
background: rgb(var(--v-theme-surface));
display: flex;
flex-direction: column;
height: 100%;
max-width: 100%;
pointer-events: auto;
transition-duration: 0.2s;
transition-property: box-shadow, transform, visibility, width, height, left, right, top, bottom;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
position: absolute;
border-color: rgba(var(--v-border-color), var(--v-border-opacity));
border-style: solid;
border-width: 0;
box-shadow: 0px 0px 0px 0px var(--v-shadow-key-umbra-opacity, rgba(0, 0, 0, 0.2)), 0px 0px 0px 0px var(--v-shadow-key-penumbra-opacity, rgba(0, 0, 0, 0.14)), 0px 0px 0px 0px var(--v-shadow-key-ambient-opacity, rgba(0, 0, 0, 0.12));
background: rgb(var(--v-theme-surface));
color: rgba(var(--v-theme-on-surface), var(--v-high-emphasis-opacity));
}
.v-navigation-drawer--border {
border-width: thin;
box-shadow: none;
}
.v-navigation-drawer--rounded {
border-radius: 4px;
}
.v-navigation-drawer--top {
top: 0;
border-bottom-width: thin;
}
.v-navigation-drawer--bottom {
left: 0;
border-top-width: thin;
}
.v-navigation-drawer--left {
top: 0;
left: 0;
right: auto;
border-right-width: thin;
}
.v-navigation-drawer--right {
top: 0;
left: auto;
right: 0;
border-left-width: thin;
}
.v-navigation-drawer--floating {
border: none;
}
.v-navigation-drawer--temporary {
box-shadow: 0px 8px 10px -5px var(--v-shadow-key-umbra-opacity, rgba(0, 0, 0, 0.2)), 0px 16px 24px 2px var(--v-shadow-key-penumbra-opacity, rgba(0, 0, 0, 0.14)), 0px 6px 30px 5px var(--v-shadow-key-ambient-opacity, rgba(0, 0, 0, 0.12));
}
.v-navigation-drawer--sticky {
height: auto;
transition: box-shadow, transform, visibility, width, height, left, right;
}
.v-navigation-drawer .v-list {
overflow: hidden;
}
.v-navigation-drawer__content {
flex: 0 1 auto;
height: 100%;
max-width: 100%;
overflow-x: hidden;
overflow-y: auto;
}
.v-navigation-drawer__img {
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
z-index: -1;
}
.v-navigation-drawer__img img {
height: inherit;
object-fit: cover;
width: inherit;
}
.v-navigation-drawer__scrim {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: black;
opacity: 0.2;
transition: opacity 0.2s cubic-bezier(0.4, 0, 0.2, 1);
z-index: 1;
}
.v-navigation-drawer__prepend,
.v-navigation-drawer__append {
flex: none;
overflow: hidden;
}

View File

@ -0,0 +1,250 @@
import { mergeProps as _mergeProps, createVNode as _createVNode, Fragment as _Fragment } from "vue";
// Styles
import "./VNavigationDrawer.css";
// Composables
import { useSticky } from "./sticky.mjs";
import { useTouch } from "./touch.mjs";
import { useRtl } from "../../composables/index.mjs";
import { makeBorderProps, useBorder } from "../../composables/border.mjs";
import { useBackgroundColor } from "../../composables/color.mjs";
import { makeComponentProps } from "../../composables/component.mjs";
import { provideDefaults } from "../../composables/defaults.mjs";
import { makeDisplayProps, useDisplay } from "../../composables/display.mjs";
import { makeElevationProps, useElevation } from "../../composables/elevation.mjs";
import { makeLayoutItemProps, useLayoutItem } from "../../composables/layout.mjs";
import { useProxiedModel } from "../../composables/proxiedModel.mjs";
import { makeRoundedProps, useRounded } from "../../composables/rounded.mjs";
import { useRouter } from "../../composables/router.mjs";
import { useScopeId } from "../../composables/scopeId.mjs";
import { useSsrBoot } from "../../composables/ssrBoot.mjs";
import { makeTagProps } from "../../composables/tag.mjs";
import { makeThemeProps, provideTheme } from "../../composables/theme.mjs";
import { useToggleScope } from "../../composables/toggleScope.mjs"; // Utilities
import { computed, nextTick, onBeforeMount, ref, shallowRef, toRef, Transition, watch } from 'vue';
import { genericComponent, propsFactory, toPhysical, useRender } from "../../util/index.mjs"; // Types
const locations = ['start', 'end', 'left', 'right', 'top', 'bottom'];
export const makeVNavigationDrawerProps = propsFactory({
color: String,
disableResizeWatcher: Boolean,
disableRouteWatcher: Boolean,
expandOnHover: Boolean,
floating: Boolean,
modelValue: {
type: Boolean,
default: null
},
permanent: Boolean,
rail: {
type: Boolean,
default: null
},
railWidth: {
type: [Number, String],
default: 56
},
scrim: {
type: [Boolean, String],
default: true
},
image: String,
temporary: Boolean,
touchless: Boolean,
width: {
type: [Number, String],
default: 256
},
location: {
type: String,
default: 'start',
validator: value => locations.includes(value)
},
sticky: Boolean,
...makeBorderProps(),
...makeComponentProps(),
...makeDisplayProps(),
...makeElevationProps(),
...makeLayoutItemProps(),
...makeRoundedProps(),
...makeTagProps({
tag: 'nav'
}),
...makeThemeProps()
}, 'VNavigationDrawer');
export const VNavigationDrawer = genericComponent()({
name: 'VNavigationDrawer',
props: makeVNavigationDrawerProps(),
emits: {
'update:modelValue': val => true,
'update:rail': val => true
},
setup(props, _ref) {
let {
attrs,
emit,
slots
} = _ref;
const {
isRtl
} = useRtl();
const {
themeClasses
} = provideTheme(props);
const {
borderClasses
} = useBorder(props);
const {
backgroundColorClasses,
backgroundColorStyles
} = useBackgroundColor(toRef(props, 'color'));
const {
elevationClasses
} = useElevation(props);
const {
displayClasses,
mobile
} = useDisplay(props);
const {
roundedClasses
} = useRounded(props);
const router = useRouter();
const isActive = useProxiedModel(props, 'modelValue', null, v => !!v);
const {
ssrBootStyles
} = useSsrBoot();
const {
scopeId
} = useScopeId();
const rootEl = ref();
const isHovering = shallowRef(false);
const width = computed(() => {
return props.rail && props.expandOnHover && isHovering.value ? Number(props.width) : Number(props.rail ? props.railWidth : props.width);
});
const location = computed(() => {
return toPhysical(props.location, isRtl.value);
});
const isTemporary = computed(() => !props.permanent && (mobile.value || props.temporary));
const isSticky = computed(() => props.sticky && !isTemporary.value && location.value !== 'bottom');
useToggleScope(() => props.expandOnHover && props.rail != null, () => {
watch(isHovering, val => emit('update:rail', !val));
});
useToggleScope(() => !props.disableResizeWatcher, () => {
watch(isTemporary, val => !props.permanent && nextTick(() => isActive.value = !val));
});
useToggleScope(() => !props.disableRouteWatcher && !!router, () => {
watch(router.currentRoute, () => isTemporary.value && (isActive.value = false));
});
watch(() => props.permanent, val => {
if (val) isActive.value = true;
});
onBeforeMount(() => {
if (props.modelValue != null || isTemporary.value) return;
isActive.value = props.permanent || !mobile.value;
});
const {
isDragging,
dragProgress,
dragStyles
} = useTouch({
isActive,
isTemporary,
width,
touchless: toRef(props, 'touchless'),
position: location
});
const layoutSize = computed(() => {
const size = isTemporary.value ? 0 : props.rail && props.expandOnHover ? Number(props.railWidth) : width.value;
return isDragging.value ? size * dragProgress.value : size;
});
const {
layoutItemStyles,
layoutItemScrimStyles
} = useLayoutItem({
id: props.name,
order: computed(() => parseInt(props.order, 10)),
position: location,
layoutSize,
elementSize: width,
active: computed(() => isActive.value || isDragging.value),
disableTransitions: computed(() => isDragging.value),
absolute: computed(() =>
// eslint-disable-next-line @typescript-eslint/no-use-before-define
props.absolute || isSticky.value && typeof isStuck.value !== 'string')
});
const {
isStuck,
stickyStyles
} = useSticky({
rootEl,
isSticky,
layoutItemStyles
});
const scrimColor = useBackgroundColor(computed(() => {
return typeof props.scrim === 'string' ? props.scrim : null;
}));
const scrimStyles = computed(() => ({
...(isDragging.value ? {
opacity: dragProgress.value * 0.2,
transition: 'none'
} : undefined),
...layoutItemScrimStyles.value
}));
provideDefaults({
VList: {
bgColor: 'transparent'
}
});
function onMouseenter() {
isHovering.value = true;
}
function onMouseleave() {
isHovering.value = false;
}
useRender(() => {
const hasImage = slots.image || props.image;
return _createVNode(_Fragment, null, [_createVNode(props.tag, _mergeProps({
"ref": rootEl,
"onMouseenter": onMouseenter,
"onMouseleave": onMouseleave,
"class": ['v-navigation-drawer', `v-navigation-drawer--${location.value}`, {
'v-navigation-drawer--expand-on-hover': props.expandOnHover,
'v-navigation-drawer--floating': props.floating,
'v-navigation-drawer--is-hovering': isHovering.value,
'v-navigation-drawer--rail': props.rail,
'v-navigation-drawer--temporary': isTemporary.value,
'v-navigation-drawer--active': isActive.value,
'v-navigation-drawer--sticky': isSticky.value
}, themeClasses.value, backgroundColorClasses.value, borderClasses.value, displayClasses.value, elevationClasses.value, roundedClasses.value, props.class],
"style": [backgroundColorStyles.value, layoutItemStyles.value, dragStyles.value, ssrBootStyles.value, stickyStyles.value, props.style]
}, scopeId, attrs), {
default: () => [hasImage && _createVNode("div", {
"key": "image",
"class": "v-navigation-drawer__img"
}, [slots.image ? slots.image?.({
image: props.image
}) : _createVNode("img", {
"src": props.image,
"alt": ""
}, null)]), slots.prepend && _createVNode("div", {
"class": "v-navigation-drawer__prepend"
}, [slots.prepend?.()]), _createVNode("div", {
"class": "v-navigation-drawer__content"
}, [slots.default?.()]), slots.append && _createVNode("div", {
"class": "v-navigation-drawer__append"
}, [slots.append?.()])]
}), _createVNode(Transition, {
"name": "fade-transition"
}, {
default: () => [isTemporary.value && (isDragging.value || isActive.value) && !!props.scrim && _createVNode("div", _mergeProps({
"class": ['v-navigation-drawer__scrim', scrimColor.backgroundColorClasses.value],
"style": [scrimStyles.value, scrimColor.backgroundColorStyles.value],
"onClick": () => isActive.value = false
}, scopeId), null)]
})]);
});
return {
isStuck
};
}
});
//# sourceMappingURL=VNavigationDrawer.mjs.map

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,92 @@
@use '../../styles/tools'
@use './variables' as *
.v-navigation-drawer
-webkit-overflow-scrolling: $navigation-drawer-overflow-scrolling
background: $navigation-drawer-background
display: flex
flex-direction: column
height: $navigation-drawer-height
max-width: 100%
pointer-events: auto
transition-duration: $navigation-drawer-transition-duration
transition-property: $navigation-drawer-transition-property
transition-timing-function: $navigation-drawer-transition-timing-function
position: absolute
@include tools.border($navigation-drawer-border...)
@include tools.elevation($navigation-drawer-elevation)
@include tools.rounded($navigation-drawer-border-radius)
@include tools.theme($navigation-drawer-theme...)
&--rounded
@include tools.rounded($navigation-drawer-rounded-border-radius)
&--top
top: 0
border-bottom-width: $navigation-drawer-border-thin-width
&--bottom
left: 0
border-top-width: $navigation-drawer-border-thin-width
&--left
top: 0
left: 0
right: auto
border-right-width: $navigation-drawer-border-thin-width
&--right
top: 0
left: auto
right: 0
border-left-width: $navigation-drawer-border-thin-width
&--floating
border: none
&--temporary
@include tools.elevation($navigation-drawer-temporary-elevation)
&--sticky
height: auto
transition: box-shadow, transform, visibility, width, height, left, right
.v-list
overflow: hidden
.v-navigation-drawer__content
flex: 0 1 auto
height: $navigation-drawer-content-height
max-width: 100%
overflow-x: $navigation-drawer-content-overflow-x
overflow-y: $navigation-drawer-content-overflow-y
.v-navigation-drawer__img
height: 100%
left: 0
position: absolute
top: 0
width: 100%
z-index: -1
img
height: $navigation-drawer-img-height
object-fit: $navigation-drawer-img-object-fit
width: $navigation-drawer-img-width
.v-navigation-drawer__scrim
position: absolute
top: 0
left: 0
width: 100%
height: 100%
background: black
opacity: $navigation-drawer-scrim-opacity
transition: opacity $navigation-drawer-transition-duration $navigation-drawer-transition-timing-function
z-index: 1
.v-navigation-drawer__prepend,
.v-navigation-drawer__append
flex: none
overflow: hidden

View File

@ -0,0 +1,39 @@
@use 'sass:map';
@use '../../styles/settings';
// VNavigationDrawer
$navigation-drawer-background: rgb(var(--v-theme-surface)) !default;
$navigation-drawer-border-color: settings.$border-color-root !default;
$navigation-drawer-border-radius: map.get(settings.$rounded, '0') !default;
$navigation-drawer-border-style: settings.$border-style-root !default;
$navigation-drawer-border-thin-width: thin !default;
$navigation-drawer-border-width: 0 !default;
$navigation-drawer-color: rgba(var(--v-theme-on-surface), var(--v-high-emphasis-opacity)) !default;
$navigation-drawer-content-height: 100% !default;
$navigation-drawer-content-overflow-x: hidden !default;
$navigation-drawer-content-overflow-y: auto !default;
$navigation-drawer-elevation: 0 !default;
$navigation-drawer-height: 100% !default;
$navigation-drawer-img-height: inherit !default;
$navigation-drawer-img-object-fit: cover !default;
$navigation-drawer-img-width: inherit !default;
$navigation-drawer-overflow-scrolling: touch !default;
$navigation-drawer-rounded-border-radius: settings.$border-radius-root !default;
$navigation-drawer-temporary-elevation: 16 !default;
$navigation-drawer-transition-duration: 0.2s !default;
$navigation-drawer-transition-property: box-shadow, transform, visibility, width, height, left, right, top, bottom !default;
$navigation-drawer-transition-timing-function: settings.$standard-easing !default;
$navigation-drawer-scrim-opacity: .2 !default;
// Lists
$navigation-drawer-border: (
$navigation-drawer-border-color,
$navigation-drawer-border-style,
$navigation-drawer-border-width,
$navigation-drawer-border-thin-width
) !default;
$navigation-drawer-theme: (
$navigation-drawer-background,
$navigation-drawer-color
) !default;

View File

@ -0,0 +1,462 @@
import * as vue from 'vue';
import { ComponentPropsOptions, ExtractPropTypes, PropType } from 'vue';
interface FilterPropsOptions<PropsOptions extends Readonly<ComponentPropsOptions>, Props = ExtractPropTypes<PropsOptions>> {
filterProps<T extends Partial<Props>, U extends Exclude<keyof Props, Exclude<keyof Props, keyof T>>>(props: T): Partial<Pick<T, U>>;
}
declare const breakpoints: readonly ["sm", "md", "lg", "xl", "xxl"];
type Breakpoint = typeof breakpoints[number];
type DisplayBreakpoint = 'xs' | Breakpoint;
type VNavigationDrawerImageSlot = {
image: string | undefined;
};
declare const VNavigationDrawer: {
new (...args: any[]): vue.CreateComponentPublicInstance<{
absolute: boolean;
location: "end" | "start" | "left" | "top" | "bottom" | "right";
width: string | number;
order: string | number;
style: vue.StyleValue;
temporary: boolean;
tag: string;
sticky: boolean;
floating: boolean;
modelValue: boolean | null;
scrim: string | boolean;
touchless: boolean;
disableResizeWatcher: boolean;
disableRouteWatcher: boolean;
expandOnHover: boolean;
permanent: boolean;
rail: boolean | null;
railWidth: string | number;
} & {
name?: string | undefined;
border?: string | number | boolean | undefined;
color?: string | undefined;
image?: string | undefined;
class?: any;
elevation?: string | number | undefined;
theme?: string | undefined;
rounded?: string | number | boolean | undefined;
mobileBreakpoint?: number | DisplayBreakpoint | undefined;
} & {
$children?: vue.VNodeChild | (() => vue.VNodeChild) | {
default?: (() => vue.VNodeChild) | undefined;
prepend?: (() => vue.VNodeChild) | undefined;
append?: (() => vue.VNodeChild) | undefined;
image?: ((arg: VNavigationDrawerImageSlot) => vue.VNodeChild) | undefined;
};
'v-slots'?: {
default?: false | (() => vue.VNodeChild) | undefined;
prepend?: false | (() => vue.VNodeChild) | undefined;
append?: false | (() => vue.VNodeChild) | undefined;
image?: false | ((arg: VNavigationDrawerImageSlot) => vue.VNodeChild) | undefined;
} | undefined;
} & {
"v-slot:default"?: false | (() => vue.VNodeChild) | undefined;
"v-slot:prepend"?: false | (() => vue.VNodeChild) | undefined;
"v-slot:append"?: false | (() => vue.VNodeChild) | undefined;
"v-slot:image"?: false | ((arg: VNavigationDrawerImageSlot) => vue.VNodeChild) | undefined;
} & {
"onUpdate:modelValue"?: ((val: boolean) => any) | undefined;
"onUpdate:rail"?: ((val: boolean) => any) | undefined;
}, {
isStuck: vue.ShallowRef<boolean | "top" | "bottom">;
}, unknown, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {
'update:modelValue': (val: boolean) => true;
'update:rail': (val: boolean) => true;
}, vue.VNodeProps & vue.AllowedComponentProps & vue.ComponentCustomProps & {
absolute: boolean;
location: "end" | "start" | "left" | "top" | "bottom" | "right";
width: string | number;
order: string | number;
style: vue.StyleValue;
temporary: boolean;
tag: string;
sticky: boolean;
floating: boolean;
modelValue: boolean | null;
scrim: string | boolean;
touchless: boolean;
disableResizeWatcher: boolean;
disableRouteWatcher: boolean;
expandOnHover: boolean;
permanent: boolean;
rail: boolean | null;
railWidth: string | number;
} & {
name?: string | undefined;
border?: string | number | boolean | undefined;
color?: string | undefined;
image?: string | undefined;
class?: any;
elevation?: string | number | undefined;
theme?: string | undefined;
rounded?: string | number | boolean | undefined;
mobileBreakpoint?: number | DisplayBreakpoint | undefined;
} & {
$children?: vue.VNodeChild | (() => vue.VNodeChild) | {
default?: (() => vue.VNodeChild) | undefined;
prepend?: (() => vue.VNodeChild) | undefined;
append?: (() => vue.VNodeChild) | undefined;
image?: ((arg: VNavigationDrawerImageSlot) => vue.VNodeChild) | undefined;
};
'v-slots'?: {
default?: false | (() => vue.VNodeChild) | undefined;
prepend?: false | (() => vue.VNodeChild) | undefined;
append?: false | (() => vue.VNodeChild) | undefined;
image?: false | ((arg: VNavigationDrawerImageSlot) => vue.VNodeChild) | undefined;
} | undefined;
} & {
"v-slot:default"?: false | (() => vue.VNodeChild) | undefined;
"v-slot:prepend"?: false | (() => vue.VNodeChild) | undefined;
"v-slot:append"?: false | (() => vue.VNodeChild) | undefined;
"v-slot:image"?: false | ((arg: VNavigationDrawerImageSlot) => vue.VNodeChild) | undefined;
} & {
"onUpdate:modelValue"?: ((val: boolean) => any) | undefined;
"onUpdate:rail"?: ((val: boolean) => any) | undefined;
}, {
absolute: boolean;
location: "end" | "start" | "left" | "top" | "bottom" | "right";
width: string | number;
order: string | number;
style: vue.StyleValue;
temporary: boolean;
tag: string;
sticky: boolean;
rounded: string | number | boolean;
floating: boolean;
modelValue: boolean | null;
scrim: string | boolean;
touchless: boolean;
disableResizeWatcher: boolean;
disableRouteWatcher: boolean;
expandOnHover: boolean;
permanent: boolean;
rail: boolean | null;
railWidth: string | number;
}, true, {}, vue.SlotsType<Partial<{
default: () => vue.VNode<vue.RendererNode, vue.RendererElement, {
[key: string]: any;
}>[];
prepend: () => vue.VNode<vue.RendererNode, vue.RendererElement, {
[key: string]: any;
}>[];
append: () => vue.VNode<vue.RendererNode, vue.RendererElement, {
[key: string]: any;
}>[];
image: (arg: VNavigationDrawerImageSlot) => vue.VNode<vue.RendererNode, vue.RendererElement, {
[key: string]: any;
}>[];
}>>, {
P: {};
B: {};
D: {};
C: {};
M: {};
Defaults: {};
}, {
absolute: boolean;
location: "end" | "start" | "left" | "top" | "bottom" | "right";
width: string | number;
order: string | number;
style: vue.StyleValue;
temporary: boolean;
tag: string;
sticky: boolean;
floating: boolean;
modelValue: boolean | null;
scrim: string | boolean;
touchless: boolean;
disableResizeWatcher: boolean;
disableRouteWatcher: boolean;
expandOnHover: boolean;
permanent: boolean;
rail: boolean | null;
railWidth: string | number;
} & {
name?: string | undefined;
border?: string | number | boolean | undefined;
color?: string | undefined;
image?: string | undefined;
class?: any;
elevation?: string | number | undefined;
theme?: string | undefined;
rounded?: string | number | boolean | undefined;
mobileBreakpoint?: number | DisplayBreakpoint | undefined;
} & {
$children?: vue.VNodeChild | (() => vue.VNodeChild) | {
default?: (() => vue.VNodeChild) | undefined;
prepend?: (() => vue.VNodeChild) | undefined;
append?: (() => vue.VNodeChild) | undefined;
image?: ((arg: VNavigationDrawerImageSlot) => vue.VNodeChild) | undefined;
};
'v-slots'?: {
default?: false | (() => vue.VNodeChild) | undefined;
prepend?: false | (() => vue.VNodeChild) | undefined;
append?: false | (() => vue.VNodeChild) | undefined;
image?: false | ((arg: VNavigationDrawerImageSlot) => vue.VNodeChild) | undefined;
} | undefined;
} & {
"v-slot:default"?: false | (() => vue.VNodeChild) | undefined;
"v-slot:prepend"?: false | (() => vue.VNodeChild) | undefined;
"v-slot:append"?: false | (() => vue.VNodeChild) | undefined;
"v-slot:image"?: false | ((arg: VNavigationDrawerImageSlot) => vue.VNodeChild) | undefined;
} & {
"onUpdate:modelValue"?: ((val: boolean) => any) | undefined;
"onUpdate:rail"?: ((val: boolean) => any) | undefined;
}, {
isStuck: vue.ShallowRef<boolean | "top" | "bottom">;
}, {}, {}, {}, {
absolute: boolean;
location: "end" | "start" | "left" | "top" | "bottom" | "right";
width: string | number;
order: string | number;
style: vue.StyleValue;
temporary: boolean;
tag: string;
sticky: boolean;
rounded: string | number | boolean;
floating: boolean;
modelValue: boolean | null;
scrim: string | boolean;
touchless: boolean;
disableResizeWatcher: boolean;
disableRouteWatcher: boolean;
expandOnHover: boolean;
permanent: boolean;
rail: boolean | null;
railWidth: string | number;
}>;
__isFragment?: undefined;
__isTeleport?: undefined;
__isSuspense?: undefined;
} & vue.ComponentOptionsBase<{
absolute: boolean;
location: "end" | "start" | "left" | "top" | "bottom" | "right";
width: string | number;
order: string | number;
style: vue.StyleValue;
temporary: boolean;
tag: string;
sticky: boolean;
floating: boolean;
modelValue: boolean | null;
scrim: string | boolean;
touchless: boolean;
disableResizeWatcher: boolean;
disableRouteWatcher: boolean;
expandOnHover: boolean;
permanent: boolean;
rail: boolean | null;
railWidth: string | number;
} & {
name?: string | undefined;
border?: string | number | boolean | undefined;
color?: string | undefined;
image?: string | undefined;
class?: any;
elevation?: string | number | undefined;
theme?: string | undefined;
rounded?: string | number | boolean | undefined;
mobileBreakpoint?: number | DisplayBreakpoint | undefined;
} & {
$children?: vue.VNodeChild | (() => vue.VNodeChild) | {
default?: (() => vue.VNodeChild) | undefined;
prepend?: (() => vue.VNodeChild) | undefined;
append?: (() => vue.VNodeChild) | undefined;
image?: ((arg: VNavigationDrawerImageSlot) => vue.VNodeChild) | undefined;
};
'v-slots'?: {
default?: false | (() => vue.VNodeChild) | undefined;
prepend?: false | (() => vue.VNodeChild) | undefined;
append?: false | (() => vue.VNodeChild) | undefined;
image?: false | ((arg: VNavigationDrawerImageSlot) => vue.VNodeChild) | undefined;
} | undefined;
} & {
"v-slot:default"?: false | (() => vue.VNodeChild) | undefined;
"v-slot:prepend"?: false | (() => vue.VNodeChild) | undefined;
"v-slot:append"?: false | (() => vue.VNodeChild) | undefined;
"v-slot:image"?: false | ((arg: VNavigationDrawerImageSlot) => vue.VNodeChild) | undefined;
} & {
"onUpdate:modelValue"?: ((val: boolean) => any) | undefined;
"onUpdate:rail"?: ((val: boolean) => any) | undefined;
}, {
isStuck: vue.ShallowRef<boolean | "top" | "bottom">;
}, unknown, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {
'update:modelValue': (val: boolean) => true;
'update:rail': (val: boolean) => true;
}, string, {
absolute: boolean;
location: "end" | "start" | "left" | "top" | "bottom" | "right";
width: string | number;
order: string | number;
style: vue.StyleValue;
temporary: boolean;
tag: string;
sticky: boolean;
rounded: string | number | boolean;
floating: boolean;
modelValue: boolean | null;
scrim: string | boolean;
touchless: boolean;
disableResizeWatcher: boolean;
disableRouteWatcher: boolean;
expandOnHover: boolean;
permanent: boolean;
rail: boolean | null;
railWidth: string | number;
}, {}, string, vue.SlotsType<Partial<{
default: () => vue.VNode<vue.RendererNode, vue.RendererElement, {
[key: string]: any;
}>[];
prepend: () => vue.VNode<vue.RendererNode, vue.RendererElement, {
[key: string]: any;
}>[];
append: () => vue.VNode<vue.RendererNode, vue.RendererElement, {
[key: string]: any;
}>[];
image: (arg: VNavigationDrawerImageSlot) => vue.VNode<vue.RendererNode, vue.RendererElement, {
[key: string]: any;
}>[];
}>>> & vue.VNodeProps & vue.AllowedComponentProps & vue.ComponentCustomProps & FilterPropsOptions<{
theme: StringConstructor;
tag: Omit<{
type: StringConstructor;
default: string;
}, "type" | "default"> & {
type: PropType<string>;
default: string;
};
rounded: {
type: (StringConstructor | BooleanConstructor | NumberConstructor)[];
default: undefined;
};
name: {
type: StringConstructor;
};
order: {
type: (StringConstructor | NumberConstructor)[];
default: number;
};
absolute: BooleanConstructor;
elevation: {
type: (StringConstructor | NumberConstructor)[];
validator(v: any): boolean;
};
mobileBreakpoint: PropType<number | DisplayBreakpoint>;
class: PropType<any>;
style: {
type: PropType<vue.StyleValue>;
default: null;
};
border: (StringConstructor | BooleanConstructor | NumberConstructor)[];
color: StringConstructor;
disableResizeWatcher: BooleanConstructor;
disableRouteWatcher: BooleanConstructor;
expandOnHover: BooleanConstructor;
floating: BooleanConstructor;
modelValue: {
type: PropType<boolean | null>;
default: null;
};
permanent: BooleanConstructor;
rail: {
type: PropType<boolean | null>;
default: null;
};
railWidth: {
type: (StringConstructor | NumberConstructor)[];
default: number;
};
scrim: {
type: (StringConstructor | BooleanConstructor)[];
default: boolean;
};
image: StringConstructor;
temporary: BooleanConstructor;
touchless: BooleanConstructor;
width: {
type: (StringConstructor | NumberConstructor)[];
default: number;
};
location: {
type: PropType<"end" | "start" | "left" | "top" | "bottom" | "right">;
default: string;
validator: (value: any) => boolean;
};
sticky: BooleanConstructor;
}, vue.ExtractPropTypes<{
theme: StringConstructor;
tag: Omit<{
type: StringConstructor;
default: string;
}, "type" | "default"> & {
type: PropType<string>;
default: string;
};
rounded: {
type: (StringConstructor | BooleanConstructor | NumberConstructor)[];
default: undefined;
};
name: {
type: StringConstructor;
};
order: {
type: (StringConstructor | NumberConstructor)[];
default: number;
};
absolute: BooleanConstructor;
elevation: {
type: (StringConstructor | NumberConstructor)[];
validator(v: any): boolean;
};
mobileBreakpoint: PropType<number | DisplayBreakpoint>;
class: PropType<any>;
style: {
type: PropType<vue.StyleValue>;
default: null;
};
border: (StringConstructor | BooleanConstructor | NumberConstructor)[];
color: StringConstructor;
disableResizeWatcher: BooleanConstructor;
disableRouteWatcher: BooleanConstructor;
expandOnHover: BooleanConstructor;
floating: BooleanConstructor;
modelValue: {
type: PropType<boolean | null>;
default: null;
};
permanent: BooleanConstructor;
rail: {
type: PropType<boolean | null>;
default: null;
};
railWidth: {
type: (StringConstructor | NumberConstructor)[];
default: number;
};
scrim: {
type: (StringConstructor | BooleanConstructor)[];
default: boolean;
};
image: StringConstructor;
temporary: BooleanConstructor;
touchless: BooleanConstructor;
width: {
type: (StringConstructor | NumberConstructor)[];
default: number;
};
location: {
type: PropType<"end" | "start" | "left" | "top" | "bottom" | "right">;
default: string;
validator: (value: any) => boolean;
};
sticky: BooleanConstructor;
}>>;
type VNavigationDrawer = InstanceType<typeof VNavigationDrawer>;
export { VNavigationDrawer };

View File

@ -0,0 +1,2 @@
export { VNavigationDrawer } from "./VNavigationDrawer.mjs";
//# sourceMappingURL=index.mjs.map

View File

@ -0,0 +1 @@
{"version":3,"file":"index.mjs","names":["VNavigationDrawer"],"sources":["../../../src/components/VNavigationDrawer/index.ts"],"sourcesContent":["export { VNavigationDrawer } from './VNavigationDrawer'\n"],"mappings":"SAASA,iBAAiB"}

View File

@ -0,0 +1,73 @@
// Utilities
import { computed, onBeforeUnmount, onMounted, shallowRef, watch } from 'vue';
import { convertToUnit } from "../../util/index.mjs"; // Types
export function useSticky(_ref) {
let {
rootEl,
isSticky,
layoutItemStyles
} = _ref;
const isStuck = shallowRef(false);
const stuckPosition = shallowRef(0);
const stickyStyles = computed(() => {
const side = typeof isStuck.value === 'boolean' ? 'top' : isStuck.value;
return [isSticky.value ? {
top: 'auto',
bottom: 'auto',
height: undefined
} : undefined, isStuck.value ? {
[side]: convertToUnit(stuckPosition.value)
} : {
top: layoutItemStyles.value.top
}];
});
onMounted(() => {
watch(isSticky, val => {
if (val) {
window.addEventListener('scroll', onScroll, {
passive: true
});
} else {
window.removeEventListener('scroll', onScroll);
}
}, {
immediate: true
});
});
onBeforeUnmount(() => {
window.removeEventListener('scroll', onScroll);
});
let lastScrollTop = 0;
function onScroll() {
const direction = lastScrollTop > window.scrollY ? 'up' : 'down';
const rect = rootEl.value.getBoundingClientRect();
const layoutTop = parseFloat(layoutItemStyles.value.top ?? 0);
const top = window.scrollY - Math.max(0, stuckPosition.value - layoutTop);
const bottom = rect.height + Math.max(stuckPosition.value, layoutTop) - window.scrollY - window.innerHeight;
const bodyScroll = parseFloat(getComputedStyle(rootEl.value).getPropertyValue('--v-body-scroll-y')) || 0;
if (rect.height < window.innerHeight - layoutTop) {
isStuck.value = 'top';
stuckPosition.value = layoutTop;
} else if (direction === 'up' && isStuck.value === 'bottom' || direction === 'down' && isStuck.value === 'top') {
stuckPosition.value = window.scrollY + rect.top - bodyScroll;
isStuck.value = true;
} else if (direction === 'down' && bottom <= 0) {
stuckPosition.value = 0;
isStuck.value = 'bottom';
} else if (direction === 'up' && top <= 0) {
if (!bodyScroll) {
stuckPosition.value = rect.top + top;
isStuck.value = 'top';
} else if (isStuck.value !== 'top') {
stuckPosition.value = -top + bodyScroll + layoutTop;
isStuck.value = 'top';
}
}
lastScrollTop = window.scrollY;
}
return {
isStuck,
stickyStyles
};
}
//# sourceMappingURL=sticky.mjs.map

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,130 @@
// Composables
import { useVelocity } from "../../composables/touch.mjs"; // Utilities
import { computed, onBeforeUnmount, onMounted, shallowRef } from 'vue';
// Types
export function useTouch(_ref) {
let {
isActive,
isTemporary,
width,
touchless,
position
} = _ref;
onMounted(() => {
window.addEventListener('touchstart', onTouchstart, {
passive: true
});
window.addEventListener('touchmove', onTouchmove, {
passive: false
});
window.addEventListener('touchend', onTouchend, {
passive: true
});
});
onBeforeUnmount(() => {
window.removeEventListener('touchstart', onTouchstart);
window.removeEventListener('touchmove', onTouchmove);
window.removeEventListener('touchend', onTouchend);
});
const isHorizontal = computed(() => ['left', 'right'].includes(position.value));
const {
addMovement,
endTouch,
getVelocity
} = useVelocity();
let maybeDragging = false;
const isDragging = shallowRef(false);
const dragProgress = shallowRef(0);
const offset = shallowRef(0);
let start;
function getOffset(pos, active) {
return (position.value === 'left' ? pos : position.value === 'right' ? document.documentElement.clientWidth - pos : position.value === 'top' ? pos : position.value === 'bottom' ? document.documentElement.clientHeight - pos : oops()) - (active ? width.value : 0);
}
function getProgress(pos) {
let limit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
const progress = position.value === 'left' ? (pos - offset.value) / width.value : position.value === 'right' ? (document.documentElement.clientWidth - pos - offset.value) / width.value : position.value === 'top' ? (pos - offset.value) / width.value : position.value === 'bottom' ? (document.documentElement.clientHeight - pos - offset.value) / width.value : oops();
return limit ? Math.max(0, Math.min(1, progress)) : progress;
}
function onTouchstart(e) {
if (touchless.value) return;
const touchX = e.changedTouches[0].clientX;
const touchY = e.changedTouches[0].clientY;
const touchZone = 25;
const inTouchZone = position.value === 'left' ? touchX < touchZone : position.value === 'right' ? touchX > document.documentElement.clientWidth - touchZone : position.value === 'top' ? touchY < touchZone : position.value === 'bottom' ? touchY > document.documentElement.clientHeight - touchZone : oops();
const inElement = isActive.value && (position.value === 'left' ? touchX < width.value : position.value === 'right' ? touchX > document.documentElement.clientWidth - width.value : position.value === 'top' ? touchY < width.value : position.value === 'bottom' ? touchY > document.documentElement.clientHeight - width.value : oops());
if (inTouchZone || inElement || isActive.value && isTemporary.value) {
maybeDragging = true;
start = [touchX, touchY];
offset.value = getOffset(isHorizontal.value ? touchX : touchY, isActive.value);
dragProgress.value = getProgress(isHorizontal.value ? touchX : touchY);
endTouch(e);
addMovement(e);
}
}
function onTouchmove(e) {
const touchX = e.changedTouches[0].clientX;
const touchY = e.changedTouches[0].clientY;
if (maybeDragging) {
if (!e.cancelable) {
maybeDragging = false;
return;
}
const dx = Math.abs(touchX - start[0]);
const dy = Math.abs(touchY - start[1]);
const thresholdMet = isHorizontal.value ? dx > dy && dx > 3 : dy > dx && dy > 3;
if (thresholdMet) {
isDragging.value = true;
maybeDragging = false;
} else if ((isHorizontal.value ? dy : dx) > 3) {
maybeDragging = false;
}
}
if (!isDragging.value) return;
e.preventDefault();
addMovement(e);
const progress = getProgress(isHorizontal.value ? touchX : touchY, false);
dragProgress.value = Math.max(0, Math.min(1, progress));
if (progress > 1) {
offset.value = getOffset(isHorizontal.value ? touchX : touchY, true);
} else if (progress < 0) {
offset.value = getOffset(isHorizontal.value ? touchX : touchY, false);
}
}
function onTouchend(e) {
maybeDragging = false;
if (!isDragging.value) return;
addMovement(e);
isDragging.value = false;
const velocity = getVelocity(e.changedTouches[0].identifier);
const vx = Math.abs(velocity.x);
const vy = Math.abs(velocity.y);
const thresholdMet = isHorizontal.value ? vx > vy && vx > 400 : vy > vx && vy > 3;
if (thresholdMet) {
isActive.value = velocity.direction === ({
left: 'right',
right: 'left',
top: 'down',
bottom: 'up'
}[position.value] || oops());
} else {
isActive.value = dragProgress.value > 0.5;
}
}
const dragStyles = computed(() => {
return isDragging.value ? {
transform: position.value === 'left' ? `translateX(calc(-100% + ${dragProgress.value * width.value}px))` : position.value === 'right' ? `translateX(calc(100% - ${dragProgress.value * width.value}px))` : position.value === 'top' ? `translateY(calc(-100% + ${dragProgress.value * width.value}px))` : position.value === 'bottom' ? `translateY(calc(100% - ${dragProgress.value * width.value}px))` : oops(),
transition: 'none'
} : undefined;
});
return {
isDragging,
dragProgress,
dragStyles
};
}
function oops() {
throw new Error();
}
//# sourceMappingURL=touch.mjs.map

File diff suppressed because one or more lines are too long