diff options
Diffstat (limited to 'src/components/BaseLine.vue')
| -rw-r--r-- | src/components/BaseLine.vue | 43 |
1 files changed, 25 insertions, 18 deletions
diff --git a/src/components/BaseLine.vue b/src/components/BaseLine.vue index 6f2dbc9..3f51a86 100644 --- a/src/components/BaseLine.vue +++ b/src/components/BaseLine.vue @@ -1,41 +1,45 @@ <template> -<div class="bg-stone-900 text-stone-50 flex relative" :class="{'flex-col': vert}" ref="rootRef"> +<div class="flex relative" :class="{'flex-col': vert}" + :style="{color: store.color.text, backgroundColor: store.color.bgDark}" ref="rootRef"> <div v-for="p in periods" :key="p.label" :style="periodStyles(p)"> <div :style="labelStyles">{{p.label}}</div> </div> <TransitionGroup name="fade"> - <div v-for="d in timelineData" :key="d.id" - class="absolute bg-yellow-200/30" :style="spanStyles(d)"> - {{d.id}} + <div v-for="range in timelineRanges" :key="range.id" class="absolute" :style="spanStyles(range)"> + {{range.id}} </div> </TransitionGroup> </div> </template> <script setup lang="ts"> -import {ref, computed, onMounted} from 'vue'; -import {MIN_DATE, MAX_DATE} from '../lib'; +import {ref, computed, onMounted, PropType, Ref} from 'vue'; +import {MIN_DATE, MAX_DATE, WRITING_MODE_HORZ, TimelineRange} from '../lib'; +import {useStore} from '../store'; // Refs const rootRef = ref(null as HTMLElement | null); +// Global store +const store = useStore(); + // Props const props = defineProps({ vert: {type: Boolean, required: true}, - timelineData: {type: Object, required: true}, + timelineRanges: {type: Object as PropType<TimelineRange[]>, required: true}, }); -// Static time periods to represent -const periods = ref([ +// Static time periods +type Period = {label: string, len: number}; +const periods: Ref<Period[]> = ref([ {label: 'One', len: 1}, {label: 'Two', len: 2}, {label: 'Three', len: 1}, ]); -// For size tracking +// For size tracking (used to prevent time spans shrinking below 1 pixel) const width = ref(0); const height = ref(0); -const WRITING_MODE_HORZ = window.getComputedStyle(document.body)['writing-mode'].startsWith('horizontal'); const resizeObserver = new ResizeObserver((entries) => { for (const entry of entries){ if (entry.contentBoxSize){ @@ -48,36 +52,36 @@ const resizeObserver = new ResizeObserver((entries) => { onMounted(() => resizeObserver.observe(rootRef.value as HTMLElement)); // Styles -function periodStyles(period){ +function periodStyles(period: Period){ return { outline: '1px solid gray', flexGrow: period.len, }; } -const labelStyles: Record<string,string> = computed(() => ({ +const labelStyles = computed((): Record<string, string> => ({ transform: props.vert ? 'rotate(90deg) translate(50%, 0)' : 'none', whiteSpace: 'nowrap', width: props.vert ? '40px' : 'auto', padding: props.vert ? '0' : '4px', })); -function spanStyles(d){ +function spanStyles(range: TimelineRange){ let styles: Record<string,string>; let availLen = props.vert ? height.value : width.value; - let startFrac = (d.start - MIN_DATE) / (MAX_DATE - MIN_DATE); - let lenFrac = (d.end - d.start) / (MAX_DATE - MIN_DATE); + let startFrac = (range.start - MIN_DATE) / (MAX_DATE - MIN_DATE); + let lenFrac = (range.end - range.start) / (MAX_DATE - MIN_DATE); let startPx = Math.max(0, availLen * startFrac); // Prevent negatives due to end-padding let lenPx = Math.min(availLen - startPx, availLen * lenFrac); lenPx = Math.max(1, lenPx); if (props.vert){ styles = { top: startPx + 'px', - left: 0, + left: '0', height: lenPx + 'px', width: '100%', } } else { styles = { - top: 0, + top: '0', left: startPx + 'px', height: '100%', width: lenPx + 'px', @@ -86,6 +90,9 @@ function spanStyles(d){ return { ...styles, transition: 'all 300ms ease-out', + color: 'black', + backgroundColor: store.color.alt, + opacity: 0.3, }; } </script> |
