@phila/phila-ui-filter-chip
v1.0.0-beta.8
Published
Filter chips for faceted filtering
Readme
FilterChip Component
Component Status
| Component | Status |
| --------------- | ------------------------------------------------------------------ |
| FilterChip | |
| FilterChipGroup |
|
@phila/phila-ui-filter-chip — pill-shaped filter controls for faceted filtering. A chip is a toggle when no choices are provided, or a dropdown (with deferred Apply/Reset) when choices is present.
Installation
pnpm add @phila/phila-ui-filter-chipShared model
import type { FilterDefinition, FilterValues } from "@phila/phila-ui-core";
// Describes one filter axis.
interface FilterDefinition {
key: string; // unique key for FilterValues map
label: string; // chip label
choices?: FilterChoice[]; // present → dropdown; absent → toggle
multiple?: boolean; // dropdown only: checkbox (true) vs radio (false)
icon?: IconComponent;
excludeFromCount?: boolean; // leave out of the filter button's count (e.g. Sort)
}
// Holds the current value of every filter, keyed by FilterDefinition.key.
type FilterValues = Record<string, string | string[] | boolean>;FilterValues is the single object that represents your entire filter state. Toggle chips store a boolean; single-select dropdowns store a string; multi-select dropdowns store a string[].
FilterChip — toggle
<script setup lang="ts">
import { ref } from "vue";
import { FilterChip } from "@phila/phila-ui-filter-chip";
const openNow = ref(false);
</script>
<template>
<FilterChip text="Open Now" v-model:selected="openNow" />
</template>FilterChip — dropdown (single-select)
<script setup lang="ts">
import { ref } from "vue";
import { FilterChip } from "@phila/phila-ui-filter-chip";
import type { FilterChoice } from "@phila/phila-ui-core";
const districtChoices: FilterChoice[] = [
{ text: "Center City", value: "center-city" },
{ text: "North Philadelphia", value: "north-philly" },
{ text: "West Philadelphia", value: "west-philly" },
];
const district = ref("");
</script>
<template>
<FilterChip label="District" :choices="districtChoices" v-model="district" />
</template>Selections are deferred: the panel stays open while the user picks, and update:modelValue fires only when the user clicks Apply. Reset clears the value without closing.
FilterChip — dropdown (multi-select)
<template>
<FilterChip label="Neighborhoods" :choices="neighborhoodChoices" :multiple="true" v-model="selectedNeighborhoods" />
</template>FilterChipGroup — data-driven row
FilterChipGroup renders a row of chips from a filters array. The row never wraps: on hover-capable (mouse) devices, hovering reveals ‹/› buttons at the edges to scroll offscreen chips into view; on touch devices the row drag-scrolls instead (a drag suppresses the click that ends it).
With filterButton, a leading button (sliders icon + a count of total active selections) scrolls with the chips and emits open-filters when clicked — wire that to your app's own filter panel. A filter can opt out of the count with excludeFromCount (e.g. a Sort chip, which is ordering rather than filtering).
<script setup lang="ts">
import { ref } from "vue";
import { FilterChipGroup } from "@phila/phila-ui-filter-chip";
import type { FilterDefinition, FilterValues } from "@phila/phila-ui-core";
const filters: FilterDefinition[] = [
{ key: "openNow", label: "Open Now" }, // toggle
{ key: "accessible", label: "Accessible" }, // toggle
{
key: "district",
label: "District",
choices: [
{ text: "Center City", value: "center-city" },
{ text: "North Philadelphia", value: "north-philly" },
],
},
{
key: "amenities",
label: "Amenities",
multiple: true,
choices: [
{ text: "Parking", value: "parking" },
{ text: "Wi-Fi", value: "wifi" },
],
},
];
const values = ref<FilterValues>({});
</script>
<template>
<FilterChipGroup :filters="filters" v-model="values" />
</template>values updates whenever any chip is applied or toggled:
// Example shape after interaction:
{
openNow: true,
district: "center-city",
amenities: ["parking", "wifi"],
}FilterChipGroup props
| Prop | Type | Default | Description |
| -------------- | -------------------- | ---------- | -------------------------------------------------------------- |
| filters | FilterDefinition[] | — | Required. Ordered list of filter axes. |
| modelValue | FilterValues | {} | Current filter state (v-model). |
| label | string | — | Optional row label rendered above chips. |
| size | ComponentSize | "medium" | Chip size applied to all chips. |
| color | FilterChipColor | "blue" | Chip color applied to all chips. |
| filterButton | boolean | false | Show a leading sliders button with the active-selection count. |
FilterChipGroup events
| Event | Payload | Description |
| ------------------- | -------------- | ------------------------------------------------------------------ |
| update:modelValue | FilterValues | Next filter state when any chip is applied or toggled (v-model). |
| open-filters | — | The filterButton was clicked; open your app's filter panel. |
FilterChip props
| Prop | Type | Default | Description |
| ------------------------ | -------------------- | ---------- | -------------------------------------------------------------- |
| label | string | — | Chip label (also the group label in dropdown mode). |
| text | string | — | Alias of label for toggle mode. |
| size | ComponentSize | "medium" | Chip size. |
| color | FilterChipColor | "blue" | Chip color. |
| iconDefinition | IconDefinition | — | Optional leading FA icon shown inside the chip. |
| trailingIconDefinition | IconDefinition | — | Toggle mode: optional trailing icon (dropdown uses a chevron). |
| selected | boolean | false | Toggle mode: active state (v-model:selected). |
| choices | FilterChoice[] | — | Presence switches to dropdown mode. |
| multiple | boolean | false | Dropdown mode: multi-select (checkbox) vs single (radio). |
| modelValue | string \| string[] | — | Dropdown mode: bound value (v-model). |
| applyText | string | "Apply" | Label for the Apply button. |
| resetText | string | "Reset" | Label for the Reset button. |
A toggle chip with an iconDefinition but no label/text renders the icon centered as the chip's content (icon-only), rather than as a leading icon beside an empty label. Chip icons are a fixed size regardless of chip size; only the text scales.
FilterChip events
| Event | Payload | Description |
| ------------------- | -------------------- | ------------------------------------------- |
| update:selected | boolean | Toggle mode: fired on every click. |
| update:modelValue | string \| string[] | Dropdown mode: fired when Apply is clicked. |
| click | MouseEvent | Toggle mode: the raw click event. |
Building a custom filter panel
FilterDefinition and FilterValues are the same model that FilterChipGroup uses internally. An app can bind its own summary panel or drawer to the same values ref — the chip row and the panel are two views over one piece of state. No generic aggregating panel ships in this package.
Development
Install Dependencies
pnpm installBuild Library
pnpm buildType Check
pnpm type-checkLicense
MIT
