Filter v1.0
The <e-filter> component is a component that can be used for .
Usage
An e-filter has attributes that must be provided
<e-filter
filter=""
/>
Attributes : e-filter
| Value | Type | Optional | Default |
|---|---|---|---|
| filter | Filter | no | '' |
Attributes : filter
| Value | Type | Optional | Default |
|---|---|---|---|
| key | String | yes | '' |
| label | String | yes | '' |
| displayValue | String | yes | '' |
| value | String | no | '' |
| property | String | yes | '' |
| type | String | yes | '' |
| id | Number | yes | '' |
| icon | String | yes | '' |
| edit | Boolean | yes | false |
| required | Boolean | yes | false |
| options | any[] | yes | [] |
| defaultValue | any | yes | '' |
Examples
Below an interactive example of e-filter can be found.
example filter
Source Code
e-filter.vue
<script lang="ts" setup>
import { computed, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { getFilterIcon, FunctionModel, Filter } from 'types';
import EIcon from '../e-icon/e-icon.vue';
import EIconButton from '../e-icon-button/e-icon-button.vue';
export type Props = {
filter: Filter;
};
const props = withDefaults(defineProps<Props>(), {});
const emit = defineEmits<{
(e: 'filter:clicked', filter: Filter): void;
}>();
const { t, te } = useI18n({ useScope: 'global' });
const filterIconEnabled = ref(false);
const buttonFunction = computed(() => {
return {
key: 'filter-button',
disabled: false,
emitKey: props.filter.required ? 'reset' : 'delete',
title: props.filter.required ? t('filters.reset') : t('filters.remove'),
icon: props.filter.required ? 'reload' : 'close',
meta: {}
} as FunctionModel;
});
const filterLabel = computed(() => {
return props.filter.label || props.filter.key;
});
const displayText = computed(() => {
return props.filter.property
? `${filterLabel.value}.${props.filter.property}: ${props.filter.value}`
: `${filterLabel.value}: ${props.filter.value}`;
});
const displayValue = computed(() => {
if (te(props.filter.displayValue)) return t(props.filter.displayValue);
if (te(props.filter.value)) return t(props.filter.value);
return (props.filter.displayValue || props.filter.value).replaceAll('_', ' ');
});
const filterIcon = computed(() => {
if (props.filter.icon) return props.filter.icon;
// Check based on filter key (name)
return getFilterIcon(props.filter.key);
});
function filterClicked(filter: Filter) {
emit('filter:clicked', filter);
}
</script>
<template>
<div class="e-filter">
<e-icon
v-if="filterIcon"
class="e-filter-icon"
:alt="t('filters.icon-alt', [filterIcon])"
:icon="[filterIcon]"
/>
<img
v-else-if="filterIconEnabled"
class="e-filter-icon"
:alt="t('filters.icon-alt', [filter.type])"
src="https://cdn.econnect.eu/media/logos/icons/econnect.ico"
/>
<div
class="e-filter-content"
:title="displayText"
>
<h3
class="e-filter-type"
:title="filterLabel"
v-text="filterLabel"
/>
<label
class="e-filter-value"
:title="displayValue"
v-text="displayValue"
/>
</div>
<div class="e-filter-functions">
<e-icon-button
:func="buttonFunction"
@clicked="filterClicked(filter)"
/>
</div>
</div>
</template>
<style scoped lang="scss">
$gap-size: 5px;
$img-size: 30px;
$icon-size: 15px;
.e-filter {
align-items: center;
background-color: var(--e-white);
border-radius: 15px;
display: flex;
flex: 1 1 auto;
flex-direction: row;
gap: $gap-size;
height: 50px;
justify-content: space-between;
max-width: 230px;
min-width: calc($img-size + $icon-size);
position: relative;
padding: 0 10px;
img,
.e-icon {
max-width: $img-size;
max-height: $img-size;
}
.e-icon-button {
:deep(.e-icon) {
&:not(.reload) {
max-width: $icon-size;
max-height: $icon-size;
}
}
}
.e-filter-content {
align-items: center;
display: flex;
flex-direction: column;
width: 100%;
cursor: pointer;
height: 100%;
flex: 1 1 auto;
overflow: hidden;
white-space: nowrap;
.e-filter-type {
margin: 2px 0 0 0;
}
.e-filter-value {
display: inline-block;
width: 100%;
color: var(--e-foreground);
cursor: pointer;
font-family: var(--e-body-font-family);
font-weight: normal;
font-style: normal;
overflow: hidden;
text-overflow: ellipsis;
text-align: center;
}
&:hover {
.e-filter-value {
color: var(--e-accent);
}
}
}
.e-filter-functions {
display: flex;
gap: $gap-size;
:deep(.icon-button) {
svg {
height: $icon-size;
width: $icon-size;
}
}
}
}
</style>