aboutsummaryrefslogtreecommitdiff
path: root/src/components/BaseLine.vue
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/BaseLine.vue')
-rw-r--r--src/components/BaseLine.vue43
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>