FilterChipGroup

One filter dimension as toggle chips with live result counts; zero-result options disable.

Usage

svelte
<script lang="ts">
  import { FilterChipGroup, toggleCounts } from "@milandekruijf/ui/svelte";

  const items = [
    { title: "Static i18n plumbing", tags: ["sveltekit", "i18n"] },
    { title: "Prerendered sitemap", tags: ["sveltekit", "seo"] },
  ];
  const options = ["i18n", "seo", "sveltekit"];

  let selected = $state<string[]>(["seo"]);
  const counts = $derived(toggleCounts(items, (i) => i.tags, selected, options));
  const visible = $derived(items.filter((i) => selected.every((t) => i.tags.includes(t))));
</script>

<FilterChipGroup
  title="Tags"
  {options}
  bind:value={selected}
  counts={counts.counts}
  resultCount={visible.length}
/>

Examples

Tags with counts

Tags

2 of 3 shown

<script lang="ts">
  import { css } from "@milandekruijf/pandacss/css";
  import { FilterChipGroup, toggleCounts } from "@milandekruijf/ui/svelte";

  const items = [
    { title: "Static i18n plumbing", tags: ["sveltekit", "i18n"] },
    { title: "Prerendered sitemap", tags: ["sveltekit", "seo"] },
    { title: "Adapter-static notes", tags: ["static-site"] },
  ];
  const options = ["i18n", "seo", "static-site", "sveltekit"];

  let selected = $state<string[]>(["sveltekit"]);
  const counts = $derived(
    toggleCounts(items, (item) => item.tags, selected, options),
  );
  const visible = $derived(
    items.filter((item) => selected.every((tag) => item.tags.includes(tag))),
  );
</script>

<div class={css({ display: "flex", flexDirection: "column", gap: 4, minW: 0 })}>
  <FilterChipGroup
    title="Tags"
    {options}
    bind:value={selected}
    counts={counts.counts}
    resultCount={visible.length}
  />
  <p class={css({ m: 0, color: "slate.11" })}>
    {visible.length} of {items.length} shown
  </p>
</div>

Props

PropTypeDefaultDescription
titlestring—
Group heading, e.g. “Tags”, “Topics”, “Languages”.
optionsstring[]—
Every available option, sorted for display.
valuestring[]—
Bindable selection (`bind:value`); works with the URL filter stores.
countsReadonlyMap<string, number>—
Count each option would yield after toggling it (see `toggleCounts`).
resultCountnumber—
Current result count, shown on selected chips.
class?string—
Extra classes merged on the group wrapper.

Options combine with AND. Zero-result options disable but stay toggle-offable while selected. Pair with `toggleCounts` (single dimension) or `dualToggleCounts` (two dimensions). Typically composed inside `FilterPanel`.