PronounsPage/components/FilterBar.vue
2024-11-07 13:59:07 +01:00

80 lines
2.5 KiB
Vue

<script setup lang="ts">
import type { Category } from '~/src/classes.ts';
const filter = defineModel<string>();
const filterCategory = defineModel<string>('category');
defineProps<{
categories?: Category[] | undefined;
submitButton?: boolean;
}>();
const emit = defineEmits<{
submitClicked: [];
}>();
const filterInput = useTemplateRef<HTMLInputElement>('filterInput');
const { $translator: translator } = useNuxtApp();
const allCategory: Category = { key: '', text: translator.translate('crud.all'), icon: 'clipboard-list' };
defineExpose({
focus: () => filterInput.value?.focus(),
});
</script>
<template>
<section class="sticky-top bg-white rounded">
<div class="input-group">
<span class="input-group-text">
<Icon v="filter" />
</span>
<input
ref="filterInput"
v-model="filter"
type="search"
class="form-control border-primary"
:placeholder="$t('crud.filterLong')"
>
<button v-if="filter" class="btn btn-outline-danger" @click="filter = ''; filterInput?.focus()">
<Icon v="times" />
</button>
<button
v-if="submitButton"
class="btn btn-success"
@click="emit('submitClicked')"
>
<Icon v="plus-circle" />
<T>nouns.submit.action</T>
</button>
</div>
<div
v-if="categories && categories.length > 0"
class="d-flex flex-wrap mt-1 border border-primary rounded overflow-hidden"
>
<button
v-for="category of [allCategory, ...categories]"
:key="category.text"
:class="[
'btn btn-sm btn-wrapped',
filterCategory === category.key ? 'btn-primary' : 'btn-outline-primary',
'flex-grow-1 d-flex justify-content-center align-items-center gap-1 rounded-0',
]"
@click="filterCategory = category.key"
>
<Icon v-if="category.icon" :v="category.icon" />
<Spelling :text="category.text" />
</button>
</div>
</section>
</template>
<style lang="scss" scoped>
.btn-wrapped {
margin-block-start: calc(-1 * var(--bs-btn-border-width));
margin-inline-start: calc(-1 * var(--bs-btn-border-width));
border-block-end: none;
border-inline-end: none;
}
</style>