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,26 @@
.v-infinite-scroll--horizontal {
display: flex;
flex-direction: row;
overflow-x: auto;
}
.v-infinite-scroll--horizontal .v-infinite-scroll-intersect {
height: 100%;
width: 1px;
}
.v-infinite-scroll--vertical {
display: flex;
flex-direction: column;
overflow-y: auto;
}
.v-infinite-scroll--vertical .v-infinite-scroll-intersect {
height: 1px;
width: 100%;
}
.v-infinite-scroll__side {
align-items: center;
display: flex;
justify-content: center;
padding: 8px;
}

View File

@@ -0,0 +1,240 @@
import { createVNode as _createVNode, createTextVNode as _createTextVNode } from "vue";
// Styles
import "./VInfiniteScroll.css";
// Components
import { VBtn } from "../VBtn/index.mjs";
import { VProgressCircular } from "../VProgressCircular/index.mjs"; // Composables
import { makeDimensionProps, useDimension } from "../../composables/dimensions.mjs";
import { useIntersectionObserver } from "../../composables/intersectionObserver.mjs";
import { useLocale } from "../../composables/locale.mjs";
import { makeTagProps } from "../../composables/tag.mjs"; // Utilities
import { computed, nextTick, onMounted, ref, shallowRef, watch } from 'vue';
import { convertToUnit, defineComponent, genericComponent, propsFactory, useRender } from "../../util/index.mjs"; // Types
export const makeVInfiniteScrollProps = propsFactory({
color: String,
direction: {
type: String,
default: 'vertical',
validator: v => ['vertical', 'horizontal'].includes(v)
},
side: {
type: String,
default: 'end',
validator: v => ['start', 'end', 'both'].includes(v)
},
mode: {
type: String,
default: 'intersect',
validator: v => ['intersect', 'manual'].includes(v)
},
margin: [Number, String],
loadMoreText: {
type: String,
default: '$vuetify.infiniteScroll.loadMore'
},
emptyText: {
type: String,
default: '$vuetify.infiniteScroll.empty'
},
...makeDimensionProps(),
...makeTagProps()
}, 'VInfiniteScroll');
export const VInfiniteScrollIntersect = defineComponent({
name: 'VInfiniteScrollIntersect',
props: {
side: {
type: String,
required: true
},
rootRef: null,
rootMargin: String
},
emits: {
intersect: (side, isIntersecting) => true
},
setup(props, _ref) {
let {
emit
} = _ref;
const {
intersectionRef,
isIntersecting
} = useIntersectionObserver(entries => {}, props.rootMargin ? {
rootMargin: props.rootMargin
} : undefined);
watch(isIntersecting, async val => {
emit('intersect', props.side, val);
});
useRender(() => _createVNode("div", {
"class": "v-infinite-scroll-intersect",
"ref": intersectionRef
}, [_createTextVNode("\xA0")]));
return {};
}
});
export const VInfiniteScroll = genericComponent()({
name: 'VInfiniteScroll',
props: makeVInfiniteScrollProps(),
emits: {
load: options => true
},
setup(props, _ref2) {
let {
slots,
emit
} = _ref2;
const rootEl = ref();
const startStatus = shallowRef('ok');
const endStatus = shallowRef('ok');
const margin = computed(() => convertToUnit(props.margin));
const isIntersecting = shallowRef(false);
function setScrollAmount(amount) {
if (!rootEl.value) return;
const property = props.direction === 'vertical' ? 'scrollTop' : 'scrollLeft';
rootEl.value[property] = amount;
}
function getScrollAmount() {
if (!rootEl.value) return 0;
const property = props.direction === 'vertical' ? 'scrollTop' : 'scrollLeft';
return rootEl.value[property];
}
function getScrollSize() {
if (!rootEl.value) return 0;
const property = props.direction === 'vertical' ? 'scrollHeight' : 'scrollWidth';
return rootEl.value[property];
}
function getContainerSize() {
if (!rootEl.value) return 0;
const property = props.direction === 'vertical' ? 'clientHeight' : 'clientWidth';
return rootEl.value[property];
}
onMounted(() => {
if (!rootEl.value) return;
if (props.side === 'start') {
setScrollAmount(getScrollSize());
} else if (props.side === 'both') {
setScrollAmount(getScrollSize() / 2 - getContainerSize() / 2);
}
});
function setStatus(side, status) {
if (side === 'start') {
startStatus.value = status;
} else if (side === 'end') {
endStatus.value = status;
}
}
function getStatus(side) {
return side === 'start' ? startStatus.value : endStatus.value;
}
let previousScrollSize = 0;
function handleIntersect(side, _isIntersecting) {
isIntersecting.value = _isIntersecting;
if (isIntersecting.value) {
intersecting(side);
}
}
function intersecting(side) {
if (props.mode !== 'manual' && !isIntersecting.value) return;
const status = getStatus(side);
if (!rootEl.value || status === 'loading') return;
previousScrollSize = getScrollSize();
setStatus(side, 'loading');
function done(status) {
setStatus(side, status);
nextTick(() => {
if (status === 'empty' || status === 'error') return;
if (status === 'ok' && side === 'start') {
setScrollAmount(getScrollSize() - previousScrollSize + getScrollAmount());
}
if (props.mode !== 'manual') {
nextTick(() => {
window.requestAnimationFrame(() => {
window.requestAnimationFrame(() => {
window.requestAnimationFrame(() => {
intersecting(side);
});
});
});
});
}
});
}
emit('load', {
side,
done
});
}
const {
t
} = useLocale();
function renderSide(side, status) {
if (props.side !== side && props.side !== 'both') return;
const onClick = () => intersecting(side);
const slotProps = {
side,
props: {
onClick,
color: props.color
}
};
if (status === 'error') return slots.error?.(slotProps);
if (status === 'empty') return slots.empty?.(slotProps) ?? _createVNode("div", null, [t(props.emptyText)]);
if (props.mode === 'manual') {
if (status === 'loading') {
return slots.loading?.(slotProps) ?? _createVNode(VProgressCircular, {
"indeterminate": true,
"color": props.color
}, null);
}
return slots['load-more']?.(slotProps) ?? _createVNode(VBtn, {
"variant": "outlined",
"color": props.color,
"onClick": onClick
}, {
default: () => [t(props.loadMoreText)]
});
}
return slots.loading?.(slotProps) ?? _createVNode(VProgressCircular, {
"indeterminate": true,
"color": props.color
}, null);
}
const {
dimensionStyles
} = useDimension(props);
useRender(() => {
const Tag = props.tag;
const hasStartIntersect = props.side === 'start' || props.side === 'both';
const hasEndIntersect = props.side === 'end' || props.side === 'both';
const intersectMode = props.mode === 'intersect';
return _createVNode(Tag, {
"ref": rootEl,
"class": ['v-infinite-scroll', `v-infinite-scroll--${props.direction}`, {
'v-infinite-scroll--start': hasStartIntersect,
'v-infinite-scroll--end': hasEndIntersect
}],
"style": dimensionStyles.value
}, {
default: () => [_createVNode("div", {
"class": "v-infinite-scroll__side"
}, [renderSide('start', startStatus.value)]), rootEl.value && hasStartIntersect && intersectMode && _createVNode(VInfiniteScrollIntersect, {
"key": "start",
"side": "start",
"onIntersect": handleIntersect,
"rootRef": rootEl.value,
"rootMargin": margin.value
}, null), slots.default?.(), rootEl.value && hasEndIntersect && intersectMode && _createVNode(VInfiniteScrollIntersect, {
"key": "end",
"side": "end",
"onIntersect": handleIntersect,
"rootRef": rootEl.value,
"rootMargin": margin.value
}, null), _createVNode("div", {
"class": "v-infinite-scroll__side"
}, [renderSide('end', endStatus.value)])]
});
});
}
});
//# sourceMappingURL=VInfiniteScroll.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,25 @@
@use './variables' as *
.v-infinite-scroll--horizontal
display: flex
flex-direction: row
overflow-x: auto
.v-infinite-scroll-intersect
height: 100%
width: 1px
.v-infinite-scroll--vertical
display: flex
flex-direction: column
overflow-y: auto
.v-infinite-scroll-intersect
height: 1px
width: 100%
.v-infinite-scroll__side
align-items: center
display: flex
justify-content: center
padding: $infinite-scroll-side-padding

View File

@@ -0,0 +1,3 @@
@use '../../styles/settings';
$infinite-scroll-side-padding: 8px !default;

View File

@@ -0,0 +1,332 @@
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>>;
}
type InfiniteScrollSide = 'start' | 'end' | 'both';
type InfiniteScrollStatus = 'ok' | 'empty' | 'loading' | 'error';
type InfiniteScrollSlot = {
side: InfiniteScrollSide;
props: Record<string, any>;
};
declare const VInfiniteScroll: {
new (...args: any[]): vue.CreateComponentPublicInstance<{
direction: "horizontal" | "vertical";
tag: string;
mode: "manual" | "intersect";
side: InfiniteScrollSide;
loadMoreText: string;
emptyText: string;
} & {
height?: string | number | undefined;
width?: string | number | undefined;
color?: string | undefined;
margin?: string | number | undefined;
maxHeight?: string | number | undefined;
maxWidth?: string | number | undefined;
minHeight?: string | number | undefined;
minWidth?: string | number | undefined;
} & {
$children?: vue.VNodeChild | (() => vue.VNodeChild) | {
default?: (() => vue.VNodeChild) | undefined;
loading?: ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
error?: ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
empty?: ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
'load-more'?: ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
};
'v-slots'?: {
default?: false | (() => vue.VNodeChild) | undefined;
loading?: false | ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
error?: false | ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
empty?: false | ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
'load-more'?: false | ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
} | undefined;
} & {
"v-slot:default"?: false | (() => vue.VNodeChild) | undefined;
"v-slot:loading"?: false | ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
"v-slot:error"?: false | ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
"v-slot:empty"?: false | ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
"v-slot:load-more"?: false | ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
} & {
onLoad?: ((options: {
side: InfiniteScrollSide;
done: (status: InfiniteScrollStatus) => void;
}) => any) | undefined;
}, void, unknown, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {
load: (options: {
side: InfiniteScrollSide;
done: (status: InfiniteScrollStatus) => void;
}) => true;
}, vue.VNodeProps & vue.AllowedComponentProps & vue.ComponentCustomProps & {
direction: "horizontal" | "vertical";
tag: string;
mode: "manual" | "intersect";
side: InfiniteScrollSide;
loadMoreText: string;
emptyText: string;
} & {
height?: string | number | undefined;
width?: string | number | undefined;
color?: string | undefined;
margin?: string | number | undefined;
maxHeight?: string | number | undefined;
maxWidth?: string | number | undefined;
minHeight?: string | number | undefined;
minWidth?: string | number | undefined;
} & {
$children?: vue.VNodeChild | (() => vue.VNodeChild) | {
default?: (() => vue.VNodeChild) | undefined;
loading?: ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
error?: ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
empty?: ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
'load-more'?: ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
};
'v-slots'?: {
default?: false | (() => vue.VNodeChild) | undefined;
loading?: false | ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
error?: false | ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
empty?: false | ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
'load-more'?: false | ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
} | undefined;
} & {
"v-slot:default"?: false | (() => vue.VNodeChild) | undefined;
"v-slot:loading"?: false | ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
"v-slot:error"?: false | ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
"v-slot:empty"?: false | ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
"v-slot:load-more"?: false | ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
} & {
onLoad?: ((options: {
side: InfiniteScrollSide;
done: (status: InfiniteScrollStatus) => void;
}) => any) | undefined;
}, {
direction: "horizontal" | "vertical";
tag: string;
mode: "manual" | "intersect";
side: InfiniteScrollSide;
loadMoreText: string;
emptyText: string;
}, true, {}, vue.SlotsType<Partial<{
default: () => vue.VNode<vue.RendererNode, vue.RendererElement, {
[key: string]: any;
}>[];
loading: (arg: InfiniteScrollSlot) => vue.VNode<vue.RendererNode, vue.RendererElement, {
[key: string]: any;
}>[];
error: (arg: InfiniteScrollSlot) => vue.VNode<vue.RendererNode, vue.RendererElement, {
[key: string]: any;
}>[];
empty: (arg: InfiniteScrollSlot) => vue.VNode<vue.RendererNode, vue.RendererElement, {
[key: string]: any;
}>[];
'load-more': (arg: InfiniteScrollSlot) => vue.VNode<vue.RendererNode, vue.RendererElement, {
[key: string]: any;
}>[];
}>>, {
P: {};
B: {};
D: {};
C: {};
M: {};
Defaults: {};
}, {
direction: "horizontal" | "vertical";
tag: string;
mode: "manual" | "intersect";
side: InfiniteScrollSide;
loadMoreText: string;
emptyText: string;
} & {
height?: string | number | undefined;
width?: string | number | undefined;
color?: string | undefined;
margin?: string | number | undefined;
maxHeight?: string | number | undefined;
maxWidth?: string | number | undefined;
minHeight?: string | number | undefined;
minWidth?: string | number | undefined;
} & {
$children?: vue.VNodeChild | (() => vue.VNodeChild) | {
default?: (() => vue.VNodeChild) | undefined;
loading?: ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
error?: ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
empty?: ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
'load-more'?: ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
};
'v-slots'?: {
default?: false | (() => vue.VNodeChild) | undefined;
loading?: false | ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
error?: false | ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
empty?: false | ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
'load-more'?: false | ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
} | undefined;
} & {
"v-slot:default"?: false | (() => vue.VNodeChild) | undefined;
"v-slot:loading"?: false | ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
"v-slot:error"?: false | ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
"v-slot:empty"?: false | ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
"v-slot:load-more"?: false | ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
} & {
onLoad?: ((options: {
side: InfiniteScrollSide;
done: (status: InfiniteScrollStatus) => void;
}) => any) | undefined;
}, {}, {}, {}, {}, {
direction: "horizontal" | "vertical";
tag: string;
mode: "manual" | "intersect";
side: InfiniteScrollSide;
loadMoreText: string;
emptyText: string;
}>;
__isFragment?: undefined;
__isTeleport?: undefined;
__isSuspense?: undefined;
} & vue.ComponentOptionsBase<{
direction: "horizontal" | "vertical";
tag: string;
mode: "manual" | "intersect";
side: InfiniteScrollSide;
loadMoreText: string;
emptyText: string;
} & {
height?: string | number | undefined;
width?: string | number | undefined;
color?: string | undefined;
margin?: string | number | undefined;
maxHeight?: string | number | undefined;
maxWidth?: string | number | undefined;
minHeight?: string | number | undefined;
minWidth?: string | number | undefined;
} & {
$children?: vue.VNodeChild | (() => vue.VNodeChild) | {
default?: (() => vue.VNodeChild) | undefined;
loading?: ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
error?: ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
empty?: ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
'load-more'?: ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
};
'v-slots'?: {
default?: false | (() => vue.VNodeChild) | undefined;
loading?: false | ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
error?: false | ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
empty?: false | ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
'load-more'?: false | ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
} | undefined;
} & {
"v-slot:default"?: false | (() => vue.VNodeChild) | undefined;
"v-slot:loading"?: false | ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
"v-slot:error"?: false | ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
"v-slot:empty"?: false | ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
"v-slot:load-more"?: false | ((arg: InfiniteScrollSlot) => vue.VNodeChild) | undefined;
} & {
onLoad?: ((options: {
side: InfiniteScrollSide;
done: (status: InfiniteScrollStatus) => void;
}) => any) | undefined;
}, void, unknown, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {
load: (options: {
side: InfiniteScrollSide;
done: (status: InfiniteScrollStatus) => void;
}) => true;
}, string, {
direction: "horizontal" | "vertical";
tag: string;
mode: "manual" | "intersect";
side: InfiniteScrollSide;
loadMoreText: string;
emptyText: string;
}, {}, string, vue.SlotsType<Partial<{
default: () => vue.VNode<vue.RendererNode, vue.RendererElement, {
[key: string]: any;
}>[];
loading: (arg: InfiniteScrollSlot) => vue.VNode<vue.RendererNode, vue.RendererElement, {
[key: string]: any;
}>[];
error: (arg: InfiniteScrollSlot) => vue.VNode<vue.RendererNode, vue.RendererElement, {
[key: string]: any;
}>[];
empty: (arg: InfiniteScrollSlot) => vue.VNode<vue.RendererNode, vue.RendererElement, {
[key: string]: any;
}>[];
'load-more': (arg: InfiniteScrollSlot) => vue.VNode<vue.RendererNode, vue.RendererElement, {
[key: string]: any;
}>[];
}>>> & vue.VNodeProps & vue.AllowedComponentProps & vue.ComponentCustomProps & FilterPropsOptions<{
tag: {
type: StringConstructor;
default: string;
};
height: (StringConstructor | NumberConstructor)[];
maxHeight: (StringConstructor | NumberConstructor)[];
maxWidth: (StringConstructor | NumberConstructor)[];
minHeight: (StringConstructor | NumberConstructor)[];
minWidth: (StringConstructor | NumberConstructor)[];
width: (StringConstructor | NumberConstructor)[];
color: StringConstructor;
direction: {
type: PropType<"horizontal" | "vertical">;
default: string;
validator: (v: any) => boolean;
};
side: {
type: PropType<InfiniteScrollSide>;
default: string;
validator: (v: any) => boolean;
};
mode: {
type: PropType<"manual" | "intersect">;
default: string;
validator: (v: any) => boolean;
};
margin: (StringConstructor | NumberConstructor)[];
loadMoreText: {
type: StringConstructor;
default: string;
};
emptyText: {
type: StringConstructor;
default: string;
};
}, vue.ExtractPropTypes<{
tag: {
type: StringConstructor;
default: string;
};
height: (StringConstructor | NumberConstructor)[];
maxHeight: (StringConstructor | NumberConstructor)[];
maxWidth: (StringConstructor | NumberConstructor)[];
minHeight: (StringConstructor | NumberConstructor)[];
minWidth: (StringConstructor | NumberConstructor)[];
width: (StringConstructor | NumberConstructor)[];
color: StringConstructor;
direction: {
type: PropType<"horizontal" | "vertical">;
default: string;
validator: (v: any) => boolean;
};
side: {
type: PropType<InfiniteScrollSide>;
default: string;
validator: (v: any) => boolean;
};
mode: {
type: PropType<"manual" | "intersect">;
default: string;
validator: (v: any) => boolean;
};
margin: (StringConstructor | NumberConstructor)[];
loadMoreText: {
type: StringConstructor;
default: string;
};
emptyText: {
type: StringConstructor;
default: string;
};
}>>;
type VInfiniteScroll = InstanceType<typeof VInfiniteScroll>;
export { VInfiniteScroll };

View File

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

View File

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