forked from nikita/muzika-gromche
104 lines
1.7 KiB
Vue
104 lines
1.7 KiB
Vue
<script setup lang="ts">
|
|
import { toPx } from '@/lib/vue'
|
|
|
|
const {
|
|
left,
|
|
width,
|
|
label,
|
|
position,
|
|
} = defineProps<{
|
|
left: number
|
|
width: string
|
|
label: string
|
|
position: 'top' | 'bottom'
|
|
}>()
|
|
</script>
|
|
|
|
<template>
|
|
<div
|
|
class="tw:absolute tw:h-full tw:top-0" :class="position" :style="{
|
|
left: toPx(left),
|
|
width,
|
|
}"
|
|
>
|
|
<div class="tick-major" />
|
|
|
|
<div class="tick tick-medium" />
|
|
|
|
<div
|
|
v-for="i in 8" :key="i"
|
|
class="tick tick-minor"
|
|
:style="{ left: `${10 * (i < 5 ? i : i + 1)}%` }"
|
|
/>
|
|
<div
|
|
v-for="i in 10" :key="i"
|
|
class="tick tick-patch"
|
|
:style="{ left: `${10 * i + 5}%` }"
|
|
/>
|
|
|
|
<span class="tw:absolute tw:left-2 tw:text-xs tw:text-gray-400 tw:select-none label">
|
|
{{ label }}
|
|
</span>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.tick-major {
|
|
position: absolute;
|
|
width: 1px;
|
|
height: 100%;
|
|
left: 0;
|
|
top: 0;
|
|
|
|
--gradient-direction: bottom;
|
|
background-image:
|
|
linear-gradient(to var(--gradient-direction),
|
|
#979797,
|
|
#97979700 70%);
|
|
}
|
|
|
|
.bottom .tick-major {
|
|
--gradient-direction: top;
|
|
}
|
|
|
|
.tick {
|
|
position: absolute;
|
|
width: 1px;
|
|
height: 100%;
|
|
top: 0;
|
|
border-top: 1px solid var(--timeline-header-tick-edge-color);
|
|
border-bottom: 1px solid var(--timeline-header-tick-edge-color);
|
|
}
|
|
|
|
.tick-medium {
|
|
left: 50%;
|
|
height: 50%;
|
|
background-color: #41434a;
|
|
}
|
|
|
|
.tick-minor {
|
|
height: 30%;
|
|
background-color: #35373d;
|
|
}
|
|
|
|
.tick-patch {
|
|
height: 20%;
|
|
background-color: #35373d;
|
|
}
|
|
|
|
.bottom .tick-medium,
|
|
.bottom .tick-minor,
|
|
.bottom .tick-patch {
|
|
top: unset;
|
|
bottom: 0;
|
|
}
|
|
|
|
.top .label {
|
|
top: calc(var(--tw-spacing) * 0.25);
|
|
}
|
|
|
|
.bottom .label {
|
|
bottom: calc(var(--tw-spacing) * 0.25);
|
|
}
|
|
</style>
|