npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@phila/phila-ui-filter-chip

v1.1.1

Published

Filter chips for faceted filtering

Readme

FilterChip Component

Component Status

| Component | Status | | --------------- | ------------------------------------------------------------------ | | FilterChip | In Progress | | FilterChipGroup | In Progress |

@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-chip @phila/phila-ui-core
# or
npm install @phila/phila-ui-filter-chip @phila/phila-ui-core

Import core styles in your main entry file (e.g., main.js|ts):

import "@phila/phila-ui-core/styles/template-light.css";

Shared 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;
  iconColor?: string; // CSS color for the leading icon, independent of text color
  excludeFromCount?: boolean; // leave out of the filter button's count (e.g. Sort)
  showActions?: boolean; // dropdown only: show Reset/Apply (deferred). Default false = live apply.
}

// 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. In practice, dropdown filters (single- and multi-select alike) store a Record<string, boolean> map of every choice value → selected — not the string/string[] the type declares. The type is shared/aspirational; the runtime shape (confirmed in FilterChip.vue/FilterChipGroup.vue) is always the full map. Treat the examples below, not the FilterValues type signature, as the source of truth for dropdown filters.

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)

modelValue is a map of every choice's value → selected, not the selected value itself — same shape whether multiple is true or false:

<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<Record<string, boolean>>({});
</script>

<template>
  <FilterChip label="District" :choices="districtChoices" v-model="district" />
</template>

By default (showActions unset/false), selections apply liveupdate:modelValue fires on every toggle and the panel stays open. Set show-actions to defer instead: the panel then shows Reset/Apply buttons, and update:modelValue only fires when Apply is clicked (Reset clears the value without closing).

FilterChip — dropdown (multi-select)

<script setup lang="ts">
const selectedNeighborhoods = ref<Record<string, boolean>>({});
</script>

<template>
  <FilterChip
    label="Neighborhoods"
    :choices="neighborhoodChoices"
    :multiple="true"
    v-model="selectedNeighborhoods"
    show-actions
  />
</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. Toggle filters store a plain boolean; dropdown filters (single- or multi-select) store a full map of every choice → selected:

// Example shape after interaction:
{
  openNow: true,
  district: { "center-city": true, "north-philly": false },
  amenities: { parking: true, wifi: true },
}

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. | | filterButtonText | string | "Filters" | Label for the leading filter button. The active-selection count is appended automatically. | | applyText | string | "Apply" | Reset/Apply label forwarded to every chip's dropdown footer (for localization). | | resetText | string | "Reset" | Reset/Apply label forwarded to every chip's dropdown footer (for localization). | | elevated | boolean | false | Applies a drop-shadow to each chip (for floating the row over a map). |

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. | | dropdown-close | key: string | A chip's dropdown panel closed; payload is that filter's key. |

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. | | icon | IconComponent | — | Optional leading icon, from @phila/phila-ui-core/icons. | | iconColor | string | — | CSS color for the leading icon, independent of the chip's text color. | | trailingIcon | IconComponent | — | Toggle mode: optional trailing icon (dropdown mode always uses a chevron instead). | | 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 | Record<string, boolean> | — | Dropdown mode: map of every choice's value → selected (v-model) — see Shared model. | | showActions | boolean | false | Dropdown mode: show Reset/Apply buttons (deferred). Default false applies live on every toggle. | | applyText | string | "Apply" | Label for the Apply button. | | resetText | string | "Reset" | Label for the Reset button. |

A toggle chip with an icon 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 | Record<string, boolean> | Dropdown mode: fired live on every toggle, or only on Apply if showActions is true. | | click | MouseEvent | Toggle mode: the raw click event. | | close | — | Dropdown mode: fired when the dropdown panel closes. |

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 install

Run Demo

pnpm dev

Run lint

pnpm lint

Build Library

pnpm build

Type Check

pnpm type-check

Publishing to NPM

Follow the release instructions using changesets.

License

MIT