mirror of
https://github.com/amir20/dozzle.git
synced 2025-12-21 13:23:07 +01:00
* feat: moves to tailwindcss and better component library * update styles * creates toggle component * adds drop down component * cleans up components * removes unused components * uses tailwind for scroll view * removes table component * improves animation * cleans up more styles * uses more tailwind * cleans up more styles with flex * more styles * removes bulma * adds colors * updates modules * fixes bugs * stops importing styles.scss * more clean up * cleans up headers * cleans up title * fixes title * fixes mobile-hidden * fixes shadow * fixes colors * add tailwindcss/nesting * adds more colors * fixes more colors * updates colors * fixes colors * colors * fixes menu on left * menu and modal * menu and modal * fuzzy search * fixes menu on left * remove logs * cleans up search * adds host to search * remove outline from inputs * cleans up left search icon * removes unused styles * fixes docker * removes sass! * cleans up styles * Fixe smobile menu * fixes mobile menu * fixes typecheck * fixes seconday color * adds drop down for container * cleans header css * updates css * fixes other layouts * updates some tests * fixes border * fixes home screen font * fixes top header * fixes tests * fixes fieldlist * fixes complex * cleans up more * removes index * fixes tests * fixes tests * resolves conflicts
116 lines
2.9 KiB
Vue
116 lines
2.9 KiB
Vue
<template>
|
|
<transition name="fadeout">
|
|
<div class="pointer-events-none relative inline-block" ref="root" v-show="!autoHide || show">
|
|
<svg width="100" height="100" viewBox="0 0 100 100" :class="{ indeterminate }">
|
|
<circle r="44" cx="50" cy="50" class="fill-base-darker stroke-primary" />
|
|
</svg>
|
|
<div class="absolute inset-0 flex items-center justify-center font-light">
|
|
<template v-if="indeterminate">
|
|
<div class="text-4xl">∞</div>
|
|
</template>
|
|
<template v-else-if="!isNaN(scrollProgress)">
|
|
<span class="text-4xl">
|
|
{{ Math.ceil(scrollProgress * 100) }}
|
|
</span>
|
|
<span> % </span>
|
|
</template>
|
|
</div>
|
|
</div>
|
|
</transition>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
const { indeterminate = false, autoHide = false } = defineProps<{
|
|
indeterminate?: boolean;
|
|
autoHide?: boolean;
|
|
}>();
|
|
|
|
const scrollProgress = ref(0);
|
|
const root = ref<HTMLElement>();
|
|
const store = useContainerStore();
|
|
const { activeContainers } = storeToRefs(store);
|
|
const scrollElement = ref<HTMLElement | Document>((root.value?.closest("[data-scrolling]") as HTMLElement) ?? document);
|
|
const { y: scrollY } = useScroll(scrollElement as Ref<HTMLElement | Document>, { throttle: 100 });
|
|
const show = autoResetRef(false, 2000);
|
|
|
|
onMounted(() => {
|
|
watch(
|
|
activeContainers,
|
|
() => {
|
|
scrollElement.value = (root.value?.closest("[data-scrolling]") as HTMLElement) ?? document;
|
|
},
|
|
{ immediate: true, flush: "post" },
|
|
);
|
|
});
|
|
|
|
watchPostEffect(() => {
|
|
const parent =
|
|
scrollElement.value === document
|
|
? (scrollElement.value as Document).documentElement
|
|
: (scrollElement.value as HTMLElement);
|
|
scrollProgress.value = Math.max(0, Math.min(1, scrollY.value / (parent.scrollHeight - parent.clientHeight)));
|
|
if (autoHide) {
|
|
show.value = true;
|
|
}
|
|
});
|
|
</script>
|
|
<style scoped lang="postcss">
|
|
svg {
|
|
filter: drop-shadow(0px 1px 1px rgba(0, 0, 0, 0.2));
|
|
margin-top: 5px;
|
|
&.indeterminate {
|
|
animation: 2s linear infinite svg-animation;
|
|
|
|
circle {
|
|
animation: 1.4s ease-in-out infinite both circle-animation;
|
|
}
|
|
}
|
|
circle {
|
|
fill-opacity: 0.75;
|
|
transition: stroke-dashoffset 250ms ease-out;
|
|
transform: rotate(-90deg);
|
|
transform-origin: 50% 50%;
|
|
stroke-dashoffset: calc(276.32px - v-bind(scrollProgress) * 276.32px);
|
|
stroke-dasharray: 276.32px 276.32px;
|
|
stroke-linecap: round;
|
|
stroke-width: 3;
|
|
will-change: stroke-dashoffset;
|
|
}
|
|
}
|
|
|
|
@keyframes svg-animation {
|
|
0% {
|
|
transform: rotateZ(0deg);
|
|
}
|
|
100% {
|
|
transform: rotateZ(360deg);
|
|
}
|
|
}
|
|
|
|
@keyframes circle-animation {
|
|
0%,
|
|
25% {
|
|
stroke-dashoffset: 275px;
|
|
transform: rotate(0);
|
|
}
|
|
50%,
|
|
75% {
|
|
stroke-dashoffset: 70px;
|
|
transform: rotate(45deg);
|
|
}
|
|
|
|
100% {
|
|
stroke-dashoffset: 275px;
|
|
transform: rotate(360deg);
|
|
}
|
|
}
|
|
|
|
.fadeout-leave-active {
|
|
@apply transition-opacity;
|
|
}
|
|
|
|
.fadeout-leave-to {
|
|
opacity: 0;
|
|
}
|
|
</style>
|