@econnect/webcomponents-library
Documentation
Styleguide
Documentation
Styleguide
  • Getting Started

    • Installation
    • Patch Notes
    • Styleguide
  • Styling

    • e-connect colors
  • UI Components

    • Form

      • Search Field
      • Form Field
      • Forms
    • Filter

      • Filter
      • Search Filter
    • Grid

      • Grid
      • Grid Row
    • Inputs

      • File Input
      • Input Checkbox
      • Input Dropdown
      • Input Date
      • Input Date Time
      • Input Date Time Local
      • Input File
      • Input Label
      • Input Multi Select
      • Input Number
      • Input Radio
      • Input Range
      • Input Select
      • Input Switch
      • Input Slider
      • Input Text
      • Input TextArea
      • Input Time
      • Input Time Range
    • Controls

      • Booleans
      • Button
      • Checkboxes
      • Date Displays
      • Dropdown Lists
      • Text Displays
    • Headers

      • e-header
    • Cards

      • e-card
    • Images

      • Icon
      • Images
      • Flag Image
      • Hamburger
    • Iframe
    • Pager
    • Settings
    • Document Validation
    • Navigation

      • Navigation
      • Navigation Menu
      • Navigation Footer
      • Navigation Button
      • Navigation Button Item
      • Navigation Search Item

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

ValueTypeOptionalDefault
filterFilterno''

Attributes : filter

ValueTypeOptionalDefault
keyStringyes''
labelStringyes''
displayValueStringyes''
valueStringno''
propertyStringyes''
typeStringyes''
idNumberyes''
iconStringyes''
editBooleanyesfalse
requiredBooleanyesfalse
optionsany[]yes[]
defaultValueanyyes''

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>
Last Updated:: 1/6/25, 2:32 PM
Contributors: Marcel Lommers
Next
Search Filter