Files
directus/src/interfaces/icon/icon.vue
Jacob Rienstra 78951da9de Interface icon (#436)
* icon interface first pass

* icon test

* readme lol

* Fix top placement in attached mode

* Finish icon interface

* Add some padding

* Finishing touches

* Fix tests

Co-authored-by: rijkvanzanten <rijkvanzanten@me.com>
2020-04-30 23:55:11 -04:00

133 lines
2.5 KiB
Vue

<template>
<v-menu attached :disabled="disabled" close-on-content-click>
<template #activator="{ toggle, active }">
<v-input
:disabled="disabled"
:placeholder="value || $t('search_for_icon')"
v-model="searchQuery"
@focus="toggle(true)"
>
<template #prepend>
<v-icon :name="value" :class="{ active: value }" />
</template>
<template #append>
<v-icon name="expand_more" class="open-indicator" :class="{ open: active }" />
</template>
</v-input>
</template>
<div class="content" :class="width">
<template v-for="(group, index) in filteredIcons">
<div :key="'icon-group-' + group.name" class="icons" v-if="group.icons.length > 0">
<v-icon
v-for="icon in group.icons"
:key="icon"
:name="icon"
:class="{ active: icon === value }"
@click="setIcon(icon)"
/>
</div>
<v-divider
:key="'divider-' + group.name"
v-if="group.icons.length > 0 && index !== filteredIcons.length - 1"
/>
</template>
</div>
</v-menu>
</template>
<script lang="ts">
import icons from './icons.json';
import { defineComponent, ref, computed } from '@vue/composition-api';
export default defineComponent({
props: {
value: {
type: String,
default: 'search',
},
disabled: {
type: Boolean,
default: false,
},
width: {
type: String,
default: 'half',
},
},
setup(props, { emit }) {
const searchQuery = ref('');
const filteredIcons = computed(() => {
return icons.map((group) => {
if (searchQuery.value.length === 0) return group;
const icons = group.icons.filter((icon) =>
icon.includes(searchQuery.value.toLowerCase())
);
return {
...group,
icons: icons,
length: icons.length,
};
});
});
return {
icons,
setIcon,
searchQuery,
filteredIcons,
};
function setIcon(icon: string) {
emit('input', icon);
}
},
});
</script>
<style lang="scss" scoped>
.content {
padding: 8px;
.v-icon:hover {
color: var(--foreground-normal);
}
.v-icon.active {
color: var(--primary);
}
.v-divider {
--v-divider-color: var(--background-normal);
margin: 0 22px;
}
}
.icons {
display: grid;
grid-gap: 8px;
grid-template-columns: repeat(8, 1fr);
justify-content: center;
padding: 20px 0;
color: var(--foreground-subdued);
}
.full .icons {
grid-template-columns: repeat(18, 1fr);
}
.open-indicator {
transform: scaleY(1);
transition: transform var(--fast) var(--transition);
}
.open-indicator.open {
transform: scaleY(-1);
}
</style>