3 min read

Facets

Facets

This component renders the list of facets stored in the Facets module. Facets can be rendered differently based on their purpose and this can be achieved using the exposed slots:

  • A default and required slot.
  • A custom slot for each facet with the facetId as its name. This allows each facet to be rendered differently based on its needs.

Props

Name Description Type Default
facetsIds Array of facets ids used to get the selected filters for those facets. Array
alwaysVisible Flag to render the component even if there are no filters selected. boolean false
animation Animation component that will be used to animate the facets. union 'ul'
renderableFacets Discriminates the facets rendered by this component. It expects a string containing facets
ids, comma separated. This property will include or exclude facets based on its value.
The default value is an empty string and the component will render all existing facets.
union

Slots

Name Description Bindings
(name - type - description)
slotNameById Customized Facet rendering. Specifying a slot with the facet's name will result in the facet Facet - Facet to render
selectedFilters Filter[] - List of selected filters of the given facet
slotNameByModelName Customized Facet rendering. Specifying a slot with the facet's modelName will result facet Facet - Facet to render
selectedFilters Filter[] - List of selected filters of the given facet
default (required) Default Facet rendering. This slot will be used by default for rendering facet Facet - Facet to render
selectedFilters Filter[] - List of selected filters of the given facet

Example

This component renders the list of facets stored in the Facets module. Facets can be rendered differently based on their purpose and this can be achieved using the exposed slots:

  • A default and required slot.
  • A custom slot for each facet with the facetId as its name. This allows each facet to be rendered differently based on its needs.

Below, there are some examples showing how to use the component with its different configurations.

Default usage

The default slot of this component is mandatory. If no other slot is defined, every Facet will be rendered as specified in the default slot.

<template>
  <Facets>
    <template #default="{ facet, selectedFilters }">
      <h1>{{ ${facet.label} }}</h1>
      <span v-if="selectedFilters.length > 0">{{ `${selectedFilters.length} selected` }}</span>
      <ul>
        <li v-for="filter in facet.filters" :key="filter.id">
          {{ filter.label }}
        </li>
      </ul>
    </template>
  </Facets>
</template>
<script>
  import { Facets } from '@empathyco/x-components/facets';
  export default {
    components: {
      Facets
    }
  };
</script>

Customized usage

Customized compositions for a specific Facet can be achieved by using a slot with the same id as the facet to customize. For example, the Facet with the id "color" requires a composition that differs from the rest of the Facets. Doing it in a slot with the name "color" will apply this customization just to the "color" Facet. The other facets will fallback to the composition of the default slot.

It is also possible to customize the Facet content by the facet "model name". For example, to configure different content for "Hierarchical Facets" the "hierarchical-facet" slot will apply that customization. This can be combined with the facets by facet id. If some hierarchical facet needs some different customization from the rest of the hierarchical, it can be achieve using the slot with the facet id.

<template>
  <Facets>
    <template #color="{ facet, selectedFilters }">
      <span v-if="selectedFilters.length > 0">{{ `${selectedFilters.length} colors chosen` }}</span>
      <ul v-for="filter in facet.filters" :key="filter.id">
        <li v-if="!filter.selected">
          {{ filter.label }}
        </li>
      </ul>
    </template>
    <template #hierarchical-facet="{ facet, selectedFilters }">
      <span v-if="selectedFilters.length > 0">{{ `${selectedFilters.length} colors chosen` }}</span>
      <ul v-for="filter in facet.filters" :key="filter.id">
        <li v-if="!filter.selected">
          {{ filter.label }}
          <ul v-for="childFilter in filter.children" :key="filter.id">
            <li v-if="!childFilter.selected">
              {{ childFilter.label }}
            </li>
          </ul>
        </li>
      </ul>
    </template>
    <template #default="{ facet }">
      <h1>{{ facet.label }}</h1>
      <ul>
        <li v-for="filter in facet.filters" :key="filter.id">
          {{ filter.label }}
        </li>
      </ul>
    </template>
  </Facets>
</template>
<script>
  import { Facets } from '@empathyco/x-components/facets';
  export default {
    components: {
      Facets
    }
  };
</script>

Render specific facets I

By default, this component will render all existing facets. However, it has the renderableFacets prop to filter which facets will be rendered. Its value is a string containing the different facets ids. This value is treated as an include or exclude list (to exclude a facet from being rendered, just prefix its id with a !). The component will only render included facets and discard excluded ones. In the following example, the component will only render color and category facets.

<template>
  <Facets renderableFacets="color, category">
    <template #default="{ facet }">
      <h1>{{ facet.label }}</h1>
      <ul>
        <li v-for="filter in facet.filters" :key="filter.id">
          {{ filter.label }}
        </li>
      </ul>
    </template>
  </Facets>
</template>
<script>
  import { Facets } from '@empathyco/x-components/facets';
  export default {
    components: {
      Facets
    }
  };
</script>

Render specific facets II

Exclude facets so the component does not render them. In the following example, the component will render every facet except color and price.

<template>
  <Facets renderableFacets="!color, !price">
    <template #default="{ facet }">
      <h1>{{ facet.label }}</h1>
      <ul>
        <li v-for="filter in facet.filters" :key="filter.id">
          {{ filter.label }}
        </li>
      </ul>
    </template>
  </Facets>
</template>
<script>
  import { Facets } from '@empathyco/x-components/facets';
  export default {
    components: {
      Facets
    }
  };
</script>

Integrating with the filters components

There are many components that will help you build your own awesome filters list. Facets just renders the list, but what to render for each facet is up to you. Below you can see an example. of the Facets component using the FiltersSearch MultiSelectFilters, SimpleFilter, Filters, HierarchicalFilter, NumberRangeFilter and BasePriceFilterLabel.

<template>
  <Facets>
    <template #default="{ facet, selectedFilters }">
      <h1>{{ facet.label }}</h1>
      <FiltersSearch :filters="facet.filters">
        <MultiSelectFilters v-slot="{ filter }">
          <SimpleFilter :filter="filter" />
        </MultiSelectFilters>
      </FiltersSearch>
    </template>
    <template #category="{ facet }">
      <h1>{{ facet.label }}</h1>
      <Filters v-slot="{ filter }" :filters="facet.filters">
        <HierarchicalFilter :filter="filter" />
      </Filters>
    </template>
    <template #price="{ facet }">
      <h1>{{ facet.label }}</h1>
      <Filters v-slot="{ filter }" :filters="facet.filters">
        <NumberRangeFilter :filter="filter">
          <BasePriceFilterLabel :filter="filter" />
        </NumberRangeFilter>
      </Filters>
    </template>
  </Facets>
</template>
<script>
  import {
    Facets,
    Filters,
    FiltersSearch,
    HierarchicalFilter,
    MultiSelectFilters,
    NumberRangeFilter,
    SimpleFilter
  } from '@empathyco/x-components/facets';
  import { BasePriceFilterLabel } from '@empathyco/x-components';
  export default {
    components: {
      Facets,
      MultiSelectFilters,
      FiltersSearch,
      SimpleFilter,
      Filters,
      HierarchicalFilter,
      NumberRangeFilter,
      BasePriceFilterLabel
    }
  };
</script>