Skip to content

Commit 29c0389

Browse files
marcoambrosininextcloud-command
authored andcommitted
Create searchable list component
Signed-off-by: Marco <[email protected]> Signed-off-by: nextcloud-command <[email protected]>
1 parent 5263add commit 29c0389

1 file changed

Lines changed: 149 additions & 0 deletions

File tree

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
<!--
2+
- @copyright 2023 Marco Ambrosini <[email protected]>
3+
-
4+
- @author Marco Ambrosini <[email protected]>
5+
-
6+
- @license AGPL-3.0-or-later
7+
-
8+
- This program is free software: you can redistribute it and/or modify
9+
- it under the terms of the GNU Affero General Public License as
10+
- published by the Free Software Foundation, either version 3 of the
11+
- License, or (at your option) any later version.
12+
-
13+
- This program is distributed in the hope that it will be useful,
14+
- but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
- GNU Affero General Public License for more details.
17+
-
18+
- You should have received a copy of the GNU Affero General Public License
19+
- along with this program. If not, see <http://www.gnu.org/licenses/>.
20+
-
21+
-->
22+
23+
<template>
24+
<NcPopover>
25+
<template #trigger>
26+
<slot name="trigger" />
27+
</template>
28+
<div class="searchable-list__wrapper">
29+
<NcTextField :value.sync="searchTerm"
30+
:label="labelText"
31+
trailing-button-icon="close"
32+
:show-trailing-button="searchTerm !== ''"
33+
@trailing-button-click="clearSearch">
34+
<Magnify :size="20" />
35+
</NcTextField>
36+
<ul v-if="filteredList.length > 0" class="searchable-list__list">
37+
<li v-for="element in filteredList"
38+
:key="element"
39+
:title="element"
40+
role="button">
41+
<NcButton alignment="start"
42+
type="tertiary"
43+
:wide="true"
44+
@click="$emit(element)">
45+
<template #icon>
46+
<NcAvatar :display-name="element" :hide-favorite="false" />
47+
</template>
48+
{{ element }}
49+
</NcButton>
50+
</li>
51+
</ul>
52+
<div v-else class="searchable-list__empty-content">
53+
<NcEmptyContent :name="emptyContentText">
54+
<template #icon>
55+
<AlertCircleOutline />
56+
</template>
57+
</NcEmptyContent>
58+
</div>
59+
</div>
60+
</NcPopover>
61+
</template>
62+
63+
<script>
64+
import { NcPopover, NcTextField, NcAvatar, NcEmptyContent, NcButton } from '@nextcloud/vue'
65+
66+
import AlertCircleOutline from 'vue-material-design-icons/AlertCircleOutline.vue'
67+
import Magnify from 'vue-material-design-icons/Magnify.vue'
68+
69+
export default {
70+
name: 'SearchableList',
71+
72+
components: {
73+
NcPopover,
74+
NcTextField,
75+
Magnify,
76+
AlertCircleOutline,
77+
NcAvatar,
78+
NcEmptyContent,
79+
NcButton,
80+
},
81+
82+
props: {
83+
labelText: {
84+
type: String,
85+
default: 'this is a label',
86+
},
87+
88+
searchList: {
89+
type: Array,
90+
required: true,
91+
},
92+
93+
emptyContentText: {
94+
type: String,
95+
required: true,
96+
},
97+
},
98+
99+
data() {
100+
return {
101+
error: false,
102+
searchTerm: '',
103+
}
104+
},
105+
106+
computed: {
107+
filteredList() {
108+
return this.searchList.filter((element) => {
109+
return element.toLowerCase().includes(this.searchTerm.toLowerCase())
110+
})
111+
},
112+
},
113+
114+
methods: {
115+
clearSearch() {
116+
this.searchTerm = ''
117+
},
118+
},
119+
}
120+
</script>
121+
122+
<style lang="scss" scoped>
123+
124+
.searchable-list {
125+
&__wrapper {
126+
padding: calc(var(--default-grid-baseline) * 3);
127+
display: flex;
128+
flex-direction: column;
129+
align-items: center;
130+
width: 250px;
131+
}
132+
133+
&__list {
134+
width: 100%;
135+
max-height: 284px;
136+
overflow-y: auto;
137+
margin-top: var(--default-grid-baseline);
138+
padding: var(--default-grid-baseline);
139+
140+
:deep(.button-vue) {
141+
border-radius: var(--border-radius-large) !important;
142+
}
143+
}
144+
145+
&__empty-content {
146+
margin-top: calc(var(--default-grid-baseline) * 3);
147+
}
148+
}
149+
</style>

0 commit comments

Comments
 (0)