webapp - ESLint + Prettier with pre-commit hooks (#54)

resolves #47

Co-authored-by: johba <johba@harb.eth>
Reviewed-on: https://codeberg.org/johba/harb/pulls/54
This commit is contained in:
johba 2025-10-03 16:51:44 +02:00
parent 2acb619a11
commit f8927b426e
83 changed files with 7137 additions and 5113 deletions

View file

@ -1,163 +1,141 @@
<template>
<div class="o-select" @click="clickSelect" ref="componentRef">
<f-input hide-details :clearable="props.clearable" :label="props.label" :selectedable="false"
:focus="showList" :modelValue="`${year} % yearly`" readonly>
<template #info v-if="slots.info">
<slot name="info"></slot>
</template>
<template #suffix>
<Icon class="toggle-collapse" v-if="showList" icon="mdi:chevron-down"></Icon>
<Icon class="toggle-collapse" v-else icon="mdi:chevron-up"></Icon>
</template>
</f-input>
<div class="select-list-wrapper" v-show="showList" ref="selectList" >
<div class="select-list-inner" @click.stop>
<div class="select-list-item" v-for="(item, index) in props.items" :key="item.year" :class="{'active': year === item.year, 'hovered': activeIndex === index}"
@click.stop="clickItem(item)" @mouseenter="mouseEnter($event, index)" @mouseleave="mouseLeave($event, index)">
<div class="circle">
<div class="active" v-if="year === item.year"></div>
<div class="hovered" v-else-if="activeIndex === index"></div>
</div>
<div class="yearly">
<div class="value">{{ item.year }} %</div>
<div class="label">yearly</div>
</div>
<div class="daily">
<div class="value">{{ item.daily.toFixed(4) }} %</div>
<div class="label">daily</div>
</div>
</div>
</div>
<div class="o-select" @click="clickSelect" ref="componentRef">
<FInput
hide-details
:clearable="props.clearable"
:label="props.label ?? undefined"
:selectedable="false"
:focus="showList"
:modelValue="`${year} % yearly`"
readonly
>
<template #info v-if="slots.info">
<slot name="info"></slot>
</template>
<template #suffix>
<Icon class="toggle-collapse" v-if="showList" icon="mdi:chevron-down"></Icon>
<Icon class="toggle-collapse" v-else icon="mdi:chevron-up"></Icon>
</template>
</FInput>
<div class="select-list-wrapper" v-show="showList" ref="selectList">
<div class="select-list-inner" @click.stop>
<div
class="select-list-item"
v-for="(item, index) in props.items"
:key="item.year"
:class="{ active: year === item.year, hovered: activeIndex === index }"
@click.stop="clickItem(item)"
@mouseenter="mouseEnter($event, index)"
@mouseleave="mouseLeave($event, index)"
>
<div class="circle">
<div class="active" v-if="year === item.year"></div>
<div class="hovered" v-else-if="activeIndex === index"></div>
</div>
<div class="yearly">
<div class="value">{{ item.year }} %</div>
<div class="label">yearly</div>
</div>
<div class="daily">
<div class="value">{{ item.daily.toFixed(4) }} %</div>
<div class="label">daily</div>
</div>
</div>
</div>
</div>
<slot :style="[!props.editor ? {display: 'none'} : {}]"></slot>
</div>
<slot :style="[!props.editor ? { display: 'none' } : {}]"></slot>
</template>
<script setup lang="ts">
import { ref, computed, onMounted, getCurrentInstance, type ComputedRef, useSlots } from "vue"
import FInput from "@/components/fcomponents/FInput.vue"
import useClickOutside from "@/composables/useClickOutside"
import {Icon} from "@iconify/vue";
const emit = defineEmits(['update:modelValue'])
const slots = useSlots();
import { ref, computed, onMounted, useSlots, withDefaults } from 'vue';
import FInput from '@/components/fcomponents/FInput.vue';
import useClickOutside from '@/composables/useClickOutside';
import { Icon } from '@iconify/vue';
interface Item {
year: number;
daily: number;
year: number;
daily: number;
}
const props = defineProps({
items: {
type: [Array<Item>],
required: false,
default: []
},
clearable: {
type: Boolean,
required: false,
default: false
},
itemTitle: {
type: String,
required: false,
default: "label"
},
itemValue: {
type: String,
required: false,
default: "value"
},
label: {
type: String,
required: false,
default: null
},
modelValue: {
type: Number,
required: false,
default: null
},
value: {
type: String,
required: false,
default: null
},
editor: {
type: Boolean,
required: false,
default: false
}
interface Props {
items?: Item[];
clearable?: boolean;
itemTitle?: string;
itemValue?: string;
label?: string | null;
modelValue?: number | null;
value?: string | null;
editor?: boolean;
}
const props = withDefaults(defineProps<Props>(), {
items: () => [],
clearable: false,
itemTitle: 'label',
itemValue: 'value',
label: null,
modelValue: null,
value: null,
editor: false,
});
const showList = ref(<boolean>false);
const slotElements = ref(<any[]>[])
const componentRef = ref(<any>null);
const selectList = ref();
const activeIndex= ref();
interface Emits {
(e: 'update:modelValue', value: number): void;
}
const emit = defineEmits<Emits>();
const slots = useSlots();
const showList = ref<boolean>(false);
const _slotElements = ref<unknown[]>([]);
const componentRef = ref<HTMLElement | null>(null);
const selectList = ref<HTMLElement | null>(null);
const activeIndex = ref();
useClickOutside(componentRef, () => {
showList.value = false
})
showList.value = false;
});
const year= computed({
const year = computed({
// getter
get() {
return props.modelValue || props.items[0].year
return props.modelValue || props.items[0].year;
},
// setter
set(newValue: number) {
emit("update:modelValue", newValue)
emit('update:modelValue', newValue);
},
});
}
})
function mouseEnter(event:MouseEvent , index:number){
const target = event. target as HTMLElement;
activeIndex.value = index;
target.classList.add("active")
function mouseEnter(event: MouseEvent, index: number) {
const target = event.target as HTMLElement;
activeIndex.value = index;
target.classList.add('active');
}
function mouseLeave(event:MouseEvent, index:number){
const elements = selectList.value.querySelectorAll('.select-list-item');
elements.forEach((element:HTMLElement) => {
element.classList.remove("active")
});
function mouseLeave(_event: MouseEvent, _index: number) {
const elements = selectList.value?.querySelectorAll('.select-list-item');
elements?.forEach(element => {
(element as HTMLElement).classList.remove('active');
});
}
onMounted(() => {
})
onMounted(() => {});
function clickSelect(event: any) {
showList.value = !showList.value;
function clickSelect(_event: unknown) {
showList.value = !showList.value;
}
function clickItem(item: any) {
console.log("item", item);
year.value = item.year
showList.value = false;
console.log("showList.value", showList.value);
// emit('input', item)
function clickItem(item: { year: number }) {
// console.log("item", item);
year.value = item.year;
showList.value = false;
// console.log("showList.value", showList.value);
// emit('input', item)
}
</script>
<style lang="sass">
.o-select
position: relative
@ -228,7 +206,4 @@ function clickItem(item: any) {
&::-webkit-scrollbar-thumb
border-radius: 10px
background-color: lightgrey
</style>
</style>