Skip to content

Commit

Permalink
Create searchable list component
Browse files Browse the repository at this point in the history
Signed-off-by: Marco <marcoambrosini@icloud.com>
Signed-off-by: nextcloud-command <nextcloud-command@users.noreply.github.com>
  • Loading branch information
marcoambrosini authored and nextcloud-command committed Nov 10, 2023
1 parent 5263add commit 29c0389
Showing 1 changed file with 149 additions and 0 deletions.
149 changes: 149 additions & 0 deletions core/src/components/GlobalSearch/SearchableList.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
<!--
- @copyright 2023 Marco Ambrosini <marcoambrosini@proton.me>
-
- @author Marco Ambrosini <marcoambrosini@proton.me>
-
- @license AGPL-3.0-or-later
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as
- published by the Free Software Foundation, either version 3 of the
- License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-->

<template>
<NcPopover>
<template #trigger>
<slot name="trigger" />
</template>
<div class="searchable-list__wrapper">
<NcTextField :value.sync="searchTerm"
:label="labelText"
trailing-button-icon="close"
:show-trailing-button="searchTerm !== ''"
@trailing-button-click="clearSearch">
<Magnify :size="20" />
</NcTextField>
<ul v-if="filteredList.length > 0" class="searchable-list__list">
<li v-for="element in filteredList"
:key="element"
:title="element"
role="button">
<NcButton alignment="start"
type="tertiary"
:wide="true"
@click="$emit(element)">
<template #icon>
<NcAvatar :display-name="element" :hide-favorite="false" />
</template>
{{ element }}
</NcButton>
</li>
</ul>
<div v-else class="searchable-list__empty-content">
<NcEmptyContent :name="emptyContentText">
<template #icon>
<AlertCircleOutline />
</template>
</NcEmptyContent>
</div>
</div>
</NcPopover>
</template>

<script>
import { NcPopover, NcTextField, NcAvatar, NcEmptyContent, NcButton } from '@nextcloud/vue'

import AlertCircleOutline from 'vue-material-design-icons/AlertCircleOutline.vue'
import Magnify from 'vue-material-design-icons/Magnify.vue'

export default {
name: 'SearchableList',

components: {
NcPopover,
NcTextField,
Magnify,
AlertCircleOutline,
NcAvatar,
NcEmptyContent,
NcButton,
},

props: {
labelText: {
type: String,
default: 'this is a label',
},

searchList: {
type: Array,
required: true,
},

emptyContentText: {
type: String,
required: true,
},
},

data() {
return {
error: false,
searchTerm: '',
}
},

computed: {
filteredList() {
return this.searchList.filter((element) => {
return element.toLowerCase().includes(this.searchTerm.toLowerCase())
})
},
},

methods: {
clearSearch() {
this.searchTerm = ''
},
},
}
</script>

<style lang="scss" scoped>

.searchable-list {
&__wrapper {
padding: calc(var(--default-grid-baseline) * 3);
display: flex;
flex-direction: column;
align-items: center;
width: 250px;
}

&__list {
width: 100%;
max-height: 284px;
overflow-y: auto;
margin-top: var(--default-grid-baseline);
padding: var(--default-grid-baseline);

:deep(.button-vue) {
border-radius: var(--border-radius-large) !important;
}
}

&__empty-content {
margin-top: calc(var(--default-grid-baseline) * 3);
}
}
</style>

0 comments on commit 29c0389

Please sign in to comment.