Filter Group
KFilterGroup is a component that provides an interface for displaying and applying filter values.
<KFilterGroup
v-model="selection"
:filters="filters"
/>Props
v-model
KFilterGroup uses v-model for data binding which tracks the filter selection state in a FilterGroupSelection. Each key in the selection state maps to a key in the filters prop.
type FilterGroupSelection = Record<string, FilterSelection | undefined>
interface FilterSelection {
operator: FilterOperator // 'eq' | 'neq' | 'contains' | 'exists' | 'lt' | 'lte' | 'gt' | 'gte'
value: string | string[] // the user's selection
text: string // the display string for that selection
}<template>
<KFilterGroup
v-model="selection"
:filters="filters"
/>
<KButton
:disabled="modelSelection?.status?.value === 'inprogress'"
@click="filterInProgress"
>
Add "In Progress" filter
</KButton>
<KButton
:disabled="selection?.name?.value === 'My name' && Object.keys(selection).length === 1"
@click="resetModelSelection"
>
Reset
</KButton>
</template>
<script setup lang="ts">
import type {
FilterGroupFilters,
FilterGroupSelection,
FilterSelection,
} from '@kong/kongponents'
const defaultNameSelection: FilterSelection = {
operator: 'eq',
text: 'My name',
value: 'My name',
}
const filters: FilterGroupFilters = { … } // see `filters` below
const selection = ref<FilterGroupSelection>({
name: defaultNameSelection,
})
const resetModelSelection = () => {
selection.value.name = defaultNameSelection,
}
const filterInProgress = () => {
selection.value = {
...selection.value,
status: {
operator: 'eq',
value: 'inprogress',
text: 'In Progress',
}
}
}
</script>filters
Prop for passing list of available filters. Accepts object of type FilterGroupFilters. See filter examples for each possible filter that can be used. Each filter must provide a label, all other properties are optional. Each key in the filters prop maps to a key in the v-model object.
export type FilterGroupFilters = Record<string, Filter>
export interface Filter {
label: string
operators?: FilterOperator[]
options?: FilterOption[]
multiple?: boolean
pinned?: boolean
placement?: PopPlacement
maxWidth?: number | string
}filter.label
Displayed in the filter selection dropdown, the filter pill, and the popover with the filter's content.
filter.operators
One or more of eq, neq, contains, exists, lt, lte, gt, gte. Renders an operator selection for the end user when more than one is provided. See operator usage.
| Operator | Displayed in dropdown | Displayed in pill |
|---|---|---|
eq | Equals | [label] = [value] |
neq | Not equals | [label] ≠ [value] |
contains | Contains | [label]: [value] |
exists | Exists | [label]: [value] |
lt | Less than | [label] < [value] |
lte | Less than or equal to | [label] ≤ [value] |
gt | Greater than | [label] > [value] |
gte | Greater than or equal to | [label] ≥ [value] |
filter.options
An array of { label: …, value: … } items. Used in select filters and multiselect filters.
filter.multiple
If options are set, this determines whether or not those options will be rendered as a select filter or a multiselect filter
filter.pinned
If true the filter will always be rendered as a pill regardless of whether it has a value or not and will never appear in the "Add filter" dropdown as it's always visible. If false, will only be rendered as a pill when it has a current value.
filter.placement
Where the filter's popover will be placed, defaults to bottom-start. See popover placement
filter.maxWidth
The max width of the filter's popover, defaults to 400px. See popover maxWidth
selectorLabel
Sets the text content in the filter selector. Defaults to 'Add filter'.
<KFilterGroup
v-model="selection"
:filters="filters"
selector-label="Custom filter selector"
/>groupLabel
The label to display at the beginning of the group. If set to an empty string nothing will be displayed. Defaults to 'Filters'.
<KFilterGroup
v-model="selection"
:filters="filters"
group-label=""
/>Slots
Filter Content
Custom content can be slotted into each filter. The corresponding filter key from the filters prop should be used to target the appropriate filter-* slot. When custom content is provided, KFilterGroup is no longer able to determine the user's selection for that filter, therefore the selection.* for that filter must be managed by the host app.
<template>
<KFilterGroup
v-model="selection"
:filters="filters"
@apply="onApply"
@clear="onClear"
@open="onOpen"
>
<template #filter-customNodes>
<KSlider
v-model="customNodes"
label="Value"
show-marks
:show-value="false"
/>
</template>
</KFilterGroup>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { FilterGroupFilters, FilterGroupSelection, FilterSelection } from '@kong/kongponents'
const selection = ref<FilterGroupSelection>({})
const filters: FilterGroupFilters = {
customNodes: {
label: 'Minimum nodes',
operators: ['eq'],
pinned: true,
},
}
const customNodes = ref<number>(0)
const onApply = (key: string) => {
if (key === 'customNodes') {
selection.value.customNodes = {
operator: 'eq',
value: customNodes.value.toString(),
text: customNodes.value.toString(),
}
}
}
const onClear = (key: string) => {
if (key === 'customNodes') {
delete selection.value.customNodes
}
}
const onOpen = (key: string) => {
if (key === 'customNodes') {
const currentValue = Number.parseInt(customNodesSelection.value?.customNodes?.value)
customNodes.value = Number.isNaN(currentValue) ? 0 : currentValue
}
}
</script>Events
apply
Emitted when the apply button is clicked. Event payload is the applied filter's key and the value of the entire KFilterGroup's selection (described in v-model).
clear
Emitted when the X icon is clicked in the filter pill. Event payload is the cleared filter's key and the value of the entire KFilterGroup's selection (described in v-model).
close
Emitted when the filter's popover content is closed (including when selection is applied). Event payload is the closed filter's key.
open
Emitted when the filter's popover content is opened. Event payload is the opened filter's key.
Filter Examples
KFilterGroup supports four filter types, determined by the filter configuration:
Select Filter
A select filter is rendered when options is provided and multiple is false or undefined.
<KFilterGroup
v-model="selection"
:filters="{
status: {
label: 'Status',
options: [
{ value: 'todo', label: 'Todo' },
{ value: 'inprogress', label: 'In Progress' },
{ value: 'done', label: 'Done' },
],
pinned: true,
},
}"
/>Multiselect Filter
A multiselect filter is rendered when multiple is true and options is provided.
<KFilterGroup
v-model="selection"
:filters="{
tag: {
label: 'Tag',
operators: ['contains'],
multiple: true,
options: [
{ value: 'foo', label: 'Foo' },
{ value: 'bar', label: 'Bar' },
{ value: 'baz', label: 'Baz' },
{ value: 'bat', label: 'Bat' },
],
pinned: true,
},
}"
/>Text Filter
A text filter is rendered when options is not provided.
<KFilterGroup
v-model="selection"
:filters="{
Name: {
label: 'Name',
pinned: true,
},
}"
/>Custom Filter
A custom filter is rendered when content is provided in the filter-* slot.
<KFilterGroup
v-model="selection"
:filters="{
created: {
label: 'Created',
pinned: true,
},
}"
>
<template #filter-created>
<MyCustomContent />
</template>
</KFilterGroup>Operator Usage
For any filter other than a Custom Filter, when more than one operator is set for a filter, an operator selection is rendered in the popover.
<KFilterGroup
v-model="selection"
:filters="{
created: {
label: 'Created',
operators: ['eq', 'neq', 'contains', 'exists', 'lt', 'lte', 'gt', 'gte'],
pinned: true,
},
}"
>
<template #filter-created>
<MyCustomContent />
</template>
</KFilterGroup>