aboutsummaryrefslogtreecommitdiff
path: root/viewer/src/components
diff options
context:
space:
mode:
authorZéro~Informatique2022-09-03 04:41:03 +0200
committerZéro~Informatique2022-09-03 04:41:03 +0200
commite704198437fb589ec8c954d12700d2a1f911522c (patch)
tree2413a96880367c55e7f736e902bf2944d90ef0ec /viewer/src/components
parenta8452594c6571e8003baa2aca14747eeeee08152 (diff)
downloadldgallery-e704198437fb589ec8c954d12700d2a1f911522c.tar.gz
viewer: refactoring for tag and sort dropdowns
Diffstat (limited to 'viewer/src/components')
-rw-r--r--viewer/src/components/LdDropdown.vue92
1 files changed, 92 insertions, 0 deletions
diff --git a/viewer/src/components/LdDropdown.vue b/viewer/src/components/LdDropdown.vue
new file mode 100644
index 0000000..2ab3252
--- /dev/null
+++ b/viewer/src/components/LdDropdown.vue
@@ -0,0 +1,92 @@
1<template>
2 <div style="position:relative;">
3 <Transition name="fade">
4 <div
5 v-if="model"
6 ref="dropdown"
7 class="scrollbar"
8 :class="$style.dropdown"
9 v-bind="attrs"
10 >
11 <div
12 v-for="(option,idx) in props.list"
13 :key="listKey ? option[props.listKey] : idx"
14 :tabindex="props.tabindexRoot + idx"
15 @click="emit('select', option)"
16 @keypress.enter.space="emit('select', option)"
17 >
18 <slot
19 name="option"
20 :option="option"
21 />
22 </div>
23 <slot
24 v-if="!props.list.length"
25 name="empty"
26 />
27 </div>
28 </Transition>
29 </div>
30</template>
31
32<script setup lang="ts">
33import { onClickOutside, onKeyStroke, useVModel } from '@vueuse/core';
34import { ref, useAttrs, watch } from 'vue';
35
36const props = defineProps({
37 modelValue: { type: Boolean, required: true },
38 // Vue 3 currently won't allow generics in props
39 // eslint-disable-next-line @typescript-eslint/no-explicit-any
40 list: { type: Array<any>, required: true },
41 listKey: { type: [String, Number], default: null },
42 tabindexRoot: { type: Number, required: true },
43});
44const emit = defineEmits(['update:modelValue', 'select', 'opening', 'closing']);
45const model = useVModel(props, 'modelValue', emit);
46
47const attrs = useAttrs();
48
49const dropdown = ref();
50
51watch(() => model.value, value => {
52 if (value) emit('opening');
53 else emit('closing');
54});
55
56onClickOutside(dropdown, closeDropdown);
57onKeyStroke('Escape', closeDropdown);
58
59function closeDropdown() {
60 setTimeout(() => (model.value = false));
61}
62</script>
63<script lang="ts">
64export default {
65 inheritAttrs: false,
66};
67</script>
68
69<style lang="scss" module>
70@import "~@/assets/scss/theme";
71
72.dropdown {
73 position: absolute;
74 left: 0;
75 z-index: 99;
76 width: $layout-left;
77 color: $input-color;
78 background-color: $dropdown-item-color;
79 padding: 4px 0px;
80 > div {
81 padding: 4px 0;
82 margin: 2px; // For the focus border
83 cursor: pointer;
84 &:hover {
85 background-color: $dropdown-item-hover-color;
86 }
87 &:focus {
88 outline: solid 1px $button-active-color;
89 }
90 }
91}
92 </style>