Skip to content

Commit

Permalink
feat: make it possible to jump to another year
Browse files Browse the repository at this point in the history
closes #70
  • Loading branch information
simonwep committed Jan 10, 2025
1 parent b83d48d commit 6ee551c
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 5 deletions.
109 changes: 109 additions & 0 deletions src/app/components/base/text-wheel-select/TextWheelSelect.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
<template>
<span :class="$style.container">
<span :class="$style.placeholder">{{ value }}</span>
<span ref="textWheelSelect" :class="[$style.textWheelSelect, { [$style.open]: showList }]">
<button
v-for="v of values"
ref="items"
:key="v"
:data-value="v"
type="button"
:class="$style.value"
@click="select(v)"
>
{{ v }}
</button>
</span>
</span>
</template>

<script lang="ts" setup generic="T extends string | number">
import { computed, nextTick, ref, useTemplateRef, watch } from 'vue';
import { useOutOfElementClick } from '@composables';
const emit = defineEmits<{
change: (value: T) => void;
}>();
const props = defineProps<{
values: T[];
value: T;
}>();
const showList = ref(false);
const textWheelSelect = useTemplateRef('textWheelSelect');
const items = useTemplateRef('items');
const visibleItemsWhenOpen = computed(() => Math.min(3, props.values.length));
useOutOfElementClick([textWheelSelect, items], () => (showList.value = false));
const focusValue = () =>
items.value
.find((el: HTMLButtonElement) => el.dataset.value === String(props.value))
?.scrollIntoView({ block: 'start' });
const select = (v: T) => {
if (!showList.value) {
showList.value = true;
} else {
emit('change', v);
showList.value = false;
}
};
watch(() => props.value, focusValue);
watch(showList, () => nextTick(focusValue));
</script>

<style lang="scss" module>
.container {
display: flex;
align-items: center;
justify-content: center;
z-index: 1;
}
.placeholder {
visibility: hidden;
font-size: var(--font-size-xs);
}
.textWheelSelect {
overflow: auto;
height: 22px;
border-radius: var(--border-radius-l);
top: 0;
background: var(--c-primary);
position: absolute;
display: inline-grid;
grid-auto-flow: row;
-ms-overflow-style: none;
scrollbar-width: none;
&.open {
height: calc(22px * v-bind(visibleItemsWhenOpen));
.value {
padding: 0 7px;
}
}
}
.textWheelSelect::-webkit-scrollbar {
display: none;
}
.value {
all: unset;
cursor: pointer;
height: 22px;
padding: 0 3px;
font-size: var(--font-size-xs);
color: var(--c-text-light);
&.transition {
transition: transform var(--transition-s);
}
}
</style>
1 change: 1 addition & 0 deletions src/app/components/feature/Pane.vue
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ useScrollShadow(header, content, 'var(--app-scroll-box-shadow)');
background: var(--app-background);
animation: var(--animation-fade-in-right) var(--transition-s);
transition: all var(--transition-m);
z-index: 1;
.title {
display: flex;
Expand Down
35 changes: 33 additions & 2 deletions src/app/components/feature/YearToggle.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
<template>
<template v-if="state.years.length > 1">
<span v-if="multiYear" :class="$style.toggle">
<Button :icon="RiArrowLeftSLine" rounded @click="rotateYear(-1)" />
<TextWheelSelect :values="allYears" :value="state.activeYear" @change="changeYear" />
<Button :icon="RiArrowRightSLine" rounded @click="rotateYear(1)" />
</template>
</span>
<i18n-t tag="span" :keypath="keyPath" scope="global">
<template #year>
<TextWheel :values="allYears" :value="state.activeYear" />
Expand All @@ -13,6 +14,7 @@
<script lang="ts" setup>
import Button from '@components/base/button/Button.vue';
import TextWheel from '@components/base/text-wheel/TextWheel.vue';
import TextWheelSelect from '@components/base/text-wheel-select/TextWheelSelect.vue';
import { RiArrowLeftSLine, RiArrowRightSLine } from '@remixicon/vue';
import { useDataStore } from '@store/state';
import { computed } from 'vue';
Expand All @@ -23,6 +25,7 @@ defineProps<{
const { state, changeYear } = useDataStore();
const multiYear = computed(() => state.years.length > 1);
const allYears = computed(() => state.years.map((v) => v.year));
const rotateYear = (dir: -1 | 1) => {
Expand All @@ -33,3 +36,31 @@ const rotateYear = (dir: -1 | 1) => {
changeYear(newYear);
};
</script>

<style lang="scss" module>
.text {
display: flex;
align-items: center;
gap: 4px;
&.multiYear {
gap: 6px;
}
}
.toggle {
position: relative;
display: flex;
align-items: center;
background: var(--c-primary);
border-radius: 100px;
gap: 5px;
filter: drop-shadow(0 0 3px rgba(black, 0.15)); // TODO: What the fuck
.year {
all: unset;
font-size: var(--font-size-xs);
cursor: pointer;
}
}
</style>
4 changes: 1 addition & 3 deletions src/app/pages/dashboard/Dashboard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@
{{ t('page.dashboard.allTimeFromTo', { from: state.years[0].year, to: state.years.at(-1)?.year }) }}
</span>
</template>
<template v-else>
<YearToggle key-path="page.dashboard.budgetFor" />
</template>
<YearToggle v-else key-path="page.dashboard.budgetFor" />
</template>
<template #header>
<div :class="$style.viewButtons">
Expand Down

0 comments on commit 6ee551c

Please sign in to comment.