Appearance
Filter Bar
FTFilterBar is the filter part of a list page toolbar. It holds:
- the Filter button: every filter the page offers (
FTFilterMenu); - the pinned filters: chips that always show, each opening only its own values;
- the added filters: filters with values that are not pinned, on a second row as "Field is value", with a remove button;
- Clear filters: after the added filters, or on the first row when only pinned filters have values.
The page owns the values and the pinned ids. The bar requests changes; the page applies them and passes them back.
Contract: src/components/FTFilterBar/contract.ts (status: draft). History: contract-log.md.
Basic usage
2
vue
<script setup lang="ts">
import { ref } from 'vue';
import { FTFilterBar } from '@fasttrack-solutions/vue-components-lib';
import type {
FTFilterMenuFilter,
FTFilterMenuValue,
} from '@fasttrack-solutions/vue-components-lib';
const pinned = ref<string[]>(['origin', 'status']);
const filters = ref<FTFilterMenuFilter[]>([
/* every filter, with its options and values */
]);
const update = (id: string, values: FTFilterMenuValue[]) => {
filters.value = filters.value.map((f) => (f.id === id ? { ...f, values } : f));
};
const togglePin = (id: string) => {
pinned.value = pinned.value.includes(id)
? pinned.value.filter((p) => p !== id)
: [...pinned.value, id];
};
const clear = () => {
filters.value = filters.value.map((f) => ({ ...f, values: [] }));
};
</script>
<template>
<FTFilterBar
:filters="filters"
:pinned="pinned"
pinnable
@update="update"
@toggle-pin="togglePin"
@clear="clear"
/>
</template><script setup lang="ts">
import { ref } from 'vue';
import { FTFilterBar } from '@fasttrack-solutions/vue-components-lib';
import type {
FTFilterMenuFilter,
FTFilterMenuValue,
} from '@fasttrack-solutions/vue-components-lib';
const pinned = ref<string[]>(['origin', 'status']);
const filters = ref<FTFilterMenuFilter[]>([
/* every filter, with its options and values */
]);
const update = (id: string, values: FTFilterMenuValue[]) => {
filters.value = filters.value.map((f) => (f.id === id ? { ...f, values } : f));
};
const togglePin = (id: string) => {
pinned.value = pinned.value.includes(id)
? pinned.value.filter((p) => p !== id)
: [...pinned.value, id];
};
const clear = () => {
filters.value = filters.value.map((f) => ({ ...f, values: [] }));
};
</script>
<template>
<FTFilterBar
:filters="filters"
:pinned="pinned"
pinnable
@update="update"
@toggle-pin="togglePin"
@clear="clear"
/>
</template>Chip text
| Selection | The pinned chip shows |
|---|---|
| None | The filter label |
| One value | Label: value |
| More values | The label and a count |
| Options with a colour | The selected colours as dots |
| Options with a logo | Up to five logos, then a 5+ count |
Props
| Prop | Type | Default | Description |
|---|---|---|---|
filters | FTFilterMenuFilter[] | required | Every filter, with its options and selected values |
pinned | string[] | [] | Ids of the filters that show as chips |
pinnable | boolean | false | The menus show the pin toggle |
searchable | boolean | false | Shows a search in the Filter menu. Pinned chips never show it |
disabled | boolean | false | Turns off every control and closes open menus, for example while a bulk action bar covers the toolbar |
label | string | 'Filter' | Name of the bar and of the Filter button |
clearLabel, isLabel, removeLabel | string | English text | Translated labels |
menuText | FTFilterBarMenuText | {} | Translated text for the menus: searchPlaceholder, allFiltersLabel, noMatchText, clearLabel, backLabel, pinLabel, unpinLabel, pinnedLabel |
Events
| Event | Payload | Description |
|---|---|---|
update | id, values | A selection change request for one filter |
toggle-pin | id | A pin change request |
clear | none | A request to clear every filter |
Slots
| Slot | Description |
|---|---|
end | Controls after the filters on the first row. They stay the page's: disabled does not reach them, so disable them yourself while a bulk bar covers the toolbar. |
CSS custom properties
| Property | Default |
|---|---|
--ft-filter-bar-control-height | calc(var(--spacing-xl) + var(--spacing-xs) + var(--spacing-2xs)) |
--ft-filter-bar-chip-bg | var(--color-mono-100) |
--ft-filter-bar-chip-border | var(--color-mono-300) |
--ft-filter-bar-chip-hover-bg | var(--color-mono-200) |
--ft-filter-bar-chip-hover-border | var(--color-mono-400) |
--ft-filter-bar-chip-on-bg | var(--color-brand-blue-100) |
--ft-filter-bar-chip-on | var(--color-brand-blue-500) |
--ft-filter-bar-chip-on-hover-bg | var(--color-brand-blue-200) |
--ft-filter-bar-chip-open-border | var(--color-brand-blue-600) |
--ft-filter-bar-chip-on-icon | var(--color-brand-blue-600) |