Skip to content

Product Filters

A side panel of product filters, built from a config so the same panel works for any catalog. Each filter is a section that opens and closes, with its own reset; the active filters show as chips under the header, with "Clear all". value is bindable and holds one entry per active filter, and onchange reports every change; the panel fetches nothing. Give it a height: the header stays put while the sections scroll. For a phone, pair it with ProductFiltersSheet, hiding the panel below the breakpoint with hidden md:flex (the panel sets flex itself, and hidden wins over it). Filter types: checkbox (a list with counts, search and "Show more"), radio (one choice), range (a two-handle slider with linked boxes, and a histogram if you pass one), rating (stars and up), swatch (colours) and switch (on/off options).

The whole panel

One section per filter in the config, each with its own Reset once it holds a choice, and the active filters as chips under the header with Clear all. Give it a height: the header stays put while the sections scroll.

Filters

$0.00 $150.00
Any
{}

Sections collapsed and expanded

Every section starts open. Bind open to the ids of the open sections to start some closed, or to remember them.

Filters

$0.00 $150.00
Any

Active chips

Ticked values get a chip each; a range, a rating and a single choice get one chip for the whole filter. Removing a chip removes only that choice.

Filters

4
Brand is Glam Brand is Luxe Price is between $20.00 – $80.00 Rating is at least 4★
$0.00 $150.00
& up

Checkbox list

A list with counts. Past five options the rest wait behind Show more, and past eight a search box appears.

Zero-count options

An option that would leave nothing is disabled, unless it is already chosen, so it can always be taken back. Here Tools and Clear have no products left.

Loading counts

loadingCounts swaps the numbers for placeholders while new counts are on their way. The options stay where they are and nothing is disabled, so the panel doesn't flicker on every change.

Filters

$0.00 $150.00
Any

No options

A filter with nothing to choose says so, rather than showing an empty section.

Filters

No options

Price range

Two handles with a box for each end. Dragging shows the numbers as they move and sets the filter when the handle is let go; a typed number is set on Enter, put in order and kept on the scale. Pass histogram, a count per equal slice of the scale, and bars above the slider show where the products are, lit inside the range — so the shopper can see a cut-off before dragging to it.

$0.00 $150.00

$20 – $80

Rating and on/off options

A rating filter means that many stars and up. On/off options, such as In stock, each switch on their own.

& up

Mobile sheet

On a phone the filters open in a sheet from a Filters button that shows how many are active. Choices made there are a draft until Apply; Cancel drops them. Pair it with the panel by breakpoint: md:hidden here, hidden md:flex on the panel.

Applied: {"category":"polish"}

API

ProductFilters

A side panel of product filters, built from a config so the same panel works for any catalog. Each filter is a section that opens and closes, with its own reset; the active filters show as chips under the header, with "Clear all". value is bindable and holds one entry per active filter, and onchange reports every change; the panel fetches nothing. Give it a height: the header stays put while the sections scroll. For a phone, pair it with ProductFiltersSheet, hiding the panel below the breakpoint with hidden md:flex (the panel sets flex itself, and hidden wins over it). Filter types: checkbox (a list with counts, search and "Show more"), radio (one choice), range (a two-handle slider with linked boxes, and a histogram if you pass one), rating (stars and up), swatch (colours) and switch (on/off options).

Prop Type Default Description
config required ProductFilter[]

The filters, in the order to show them.

value bindable Object<string, *> {}

One entry per active filter: a list of values for checkbox, swatch and switch, a value for radio, [min, max] for range and the minimum for rating. Two-way bindable via bind:value.

onchange (value: Object<string, *>) => void

Called with the new value after every change.

loadingCounts boolean false

Shows placeholders in place of the counts while they load, and disables nothing.

open bindable string[] config.map((filter) => filter.id)

The ids of the open sections; every section by default. Two-way bindable via bind:open.

class string

Additional Tailwind classes merged onto the panel. Give it a height.

ProductFiltersSheet

The product filters for a phone: a "Filters" button, with the number of active filters, that opens the panel in a sheet. Choices made in the sheet are a draft until Apply, which sets value and calls onchange once; Cancel or closing the sheet drops them. Show it below a breakpoint and the ProductFilters panel above it, such as class="md:hidden" here and class="hidden md:flex" there.

Prop Type Default Description
config required import('./product-filters.svelte').ProductFilter[]

The filters, in the order to show them.

value bindable Object<string, *> {}

The applied filters, in the same shape as ProductFilters. Two-way bindable via bind:value.

onchange (value: Object<string, *>) => void

Called once with the new value when Apply is pressed.

loadingCounts boolean false

Shows placeholders in place of the counts while they load.

class string

Additional Tailwind classes merged onto the button.

ProductFiltersCheckboxList

A filter as a list of checkboxes, each with its count. Long lists show the first few with "Show more", and a search box appears once there are enough options to need one. An option whose count is zero is disabled, unless it is already ticked, so it can always be unticked.

Prop Type Default Description
filter required {id: string, label: string, options: Array<string|{label: string, value: string}>, counts?: Object<string, number>}

The filter's config.

value string[] []

The ticked values.

onchange required (next: string[]) => void

Called with the ticked values after each tick.

loadingCounts boolean false

Shows placeholders in place of the counts, and disables nothing.

ProductFiltersRadio

A filter where one option is chosen, such as a category, with a count beside each. An option whose count is zero is disabled unless it is the one chosen.

Prop Type Default Description
filter required {id: string, label: string, options: Array<string|{label: string, value: string}>, counts?: Object<string, number>}

The filter's config.

value string ''

The chosen value.

onchange required (next: string) => void

Called with the newly chosen value.

loadingCounts boolean false

Shows placeholders in place of the counts, and disables nothing.

ProductFiltersRange

A filter for a range of numbers, such as price: a two-handle slider with a box for each end. Dragging shows the numbers as they move and sets the filter once the handle is let go; a typed number is set on Enter or when the box loses focus, put in order and kept on the scale. With a histogram, bars above the slider show how the products spread across the scale, and light up inside the range.

Prop Type Default Description
filter required {id: string, label: string, min: number, max: number, step?: number, format?: (number: number) => string, histogram?: number[]}

The filter's config.

value [number, number]

The chosen range; the whole scale when not set.

onchange required (next: [number, number]) => void

Called with the range, in order and on the scale.

ProductFiltersRating

A filter for a minimum rating: choosing four stars means four stars and up.

Prop Type Default Description
filter required {id: string, label: string, max?: number}

The filter's config.

value number 0

The minimum rating; none when not set.

onchange required (next: number) => void

Called with the newly chosen minimum.

ProductFiltersSwatches

A filter for colours, as round swatches that toggle. Several can be chosen. A colour whose count is zero is disabled unless it is already chosen.

Prop Type Default Description
filter required {id: string, label: string, options: Array<{label: string, value: string, color: string}>, counts?: Object<string, number>}

The filter's config.

value string[] []

The chosen colours' values.

onchange required (next: string[]) => void

Called with the chosen values after each toggle.

loadingCounts boolean false

Disables nothing while the counts load.

ProductFiltersSwitches

A filter made of independent on/off options, such as "In stock" and "Free shipping", each with its count. An option whose count is zero is disabled unless it is already on.

Prop Type Default Description
filter required {id: string, label: string, options: Array<string|{label: string, value: string}>, counts?: Object<string, number>}

The filter's config.

value string[] []

The options that are on.

onchange required (next: string[]) => void

Called with the options that are on after each switch.

loadingCounts boolean false

Shows placeholders in place of the counts, and disables nothing.

ProductFilter

Prop Type Default Description
id required string

Key of the filter in value.

type required 'checkbox'|'radio'|'range'|'rating'|'swatch'|'switch'

How the filter is chosen.

label required string

Section title, also used in the chips.

options Array<string|{label: string, value: string, color?: string}>

What can be chosen; color for swatches. Not used by range and rating.

counts Object<string, number>

How many products each option would leave; zero disables the option.

min number

Lowest value of a range.

max number

Highest value of a range, or the number of stars of a rating.

step number

Step of a range.

format (number: number) => string

How a range end reads in its chip and under its histogram, such as (n) => '$' + n.

histogram number[]

How many products fall in each equal slice of a range's scale, lowest first. Draws bars above the slider.