aboutsummaryrefslogtreecommitdiff
path: root/viewer/src/views/layout/top/LayoutCommandSort.vue
diff options
context:
space:
mode:
Diffstat (limited to 'viewer/src/views/layout/top/LayoutCommandSort.vue')
-rw-r--r--viewer/src/views/layout/top/LayoutCommandSort.vue117
1 files changed, 117 insertions, 0 deletions
diff --git a/viewer/src/views/layout/top/LayoutCommandSort.vue b/viewer/src/views/layout/top/LayoutCommandSort.vue
new file mode 100644
index 0000000..bb9744e
--- /dev/null
+++ b/viewer/src/views/layout/top/LayoutCommandSort.vue
@@ -0,0 +1,117 @@
1<!-- ldgallery - A static generator which turns a collection of tagged
2-- pictures into a searchable web gallery.
3--
4-- Copyright (C) 2019-2022 Guillaume FOUET
5-- 2020 Pacien TRAN-GIRARD
6--
7-- This program is free software: you can redistribute it and/or modify
8-- it under the terms of the GNU Affero General Public License as
9-- published by the Free Software Foundation, either version 3 of the
10-- License, or (at your option) any later version.
11--
12-- This program is distributed in the hope that it will be useful,
13-- but WITHOUT ANY WARRANTY; without even the implied warranty of
14-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15-- GNU Affero General Public License for more details.
16--
17-- You should have received a copy of the GNU Affero General Public License
18-- along with this program. If not, see <https://www.gnu.org/licenses/>.
19-->
20
21<template>
22 <LdLink
23 :title="t('command.sort.title')"
24 :tabindex="props.tabindex"
25 @click="openDropdown"
26 >
27 <fa-icon
28 :icon="faSortAmountDown"
29 size="lg"
30 />
31 <teleport to="body">
32 <Transition name="fade">
33 <div
34 v-if="showDropdown"
35 ref="dropdown"
36 :class="$style.dropdown"
37 >
38 <div
39 v-for="(sort,idx) in itemComparator.ITEM_SORTS"
40 :key="sort.name"
41 :tabindex="props.tabindex + idx + 1"
42 @click="selectedSort=sort"
43 @keypress.enter.space="selectedSort=sort"
44 >
45 <fa-icon :icon="sort.name == selectedSort.name ? faDotCircle : faCircle" />
46 <span v-text="sort.text" />
47 </div>
48 </div>
49 </Transition>
50 </teleport>
51 </LdLink>
52</template>
53
54<script setup lang="ts">
55import LdLink from '@/components/LdLink.vue';
56import { ItemSort, useItemComparator } from '@/services/itemComparator';
57import { useUiStore } from '@/store/uiStore';
58import { faCircle, faDotCircle, faSortAmountDown } from '@fortawesome/free-solid-svg-icons';
59import { onClickOutside, onKeyStroke } from '@vueuse/core';
60import { computed, ref } from 'vue';
61import { useI18n } from 'vue-i18n';
62
63const props = defineProps({
64 tabindex: { type: Number, required: true },
65});
66
67const { t } = useI18n();
68const uiStore = useUiStore();
69const itemComparator = useItemComparator();
70
71const selectedSort = computed({
72 get: () => uiStore.sort,
73 set: (newValue: ItemSort) => (uiStore.sort = newValue),
74});
75
76const showDropdown = ref(false);
77
78const dropdown = ref();
79onClickOutside(dropdown, closeDropdown);
80onKeyStroke('Escape', closeDropdown);
81
82function openDropdown() {
83 showDropdown.value = true;
84}
85function closeDropdown() {
86 setTimeout(() => (showDropdown.value = false));
87}
88</script>
89
90<style lang="scss" module>
91@import "~@/assets/scss/theme";
92
93.dropdown {
94 position: absolute;
95 top: $layout-top;
96 left: 0;
97 z-index: 10;
98 width: $layout-left;
99 color: $input-color;
100 background-color: $dropdown-item-color;
101 padding: 8px 0px;
102 cursor: pointer;
103 > div {
104 padding: 8px 14px;
105 margin: 2px; // For the focus border
106 > span {
107 padding-left: 12px;
108 }
109 &:hover {
110 background-color: $dropdown-item-hover-color;
111 }
112 &:focus {
113 outline: solid 1px $button-active-color;
114 }
115 }
116}
117</style>