# Filter Item

> Source: https://design.nanatec.co.ke/components/filter-item/
> Wraps one field component and reports its value to the surrounding filter — the bridge between any input and the aggregated filter value.
> Status: stable
> Since: v0.0.20

Wraps one field component and reports its value to the surrounding
[`nana-filter`](/components/filter/). The field is whatever you slot in —
`nana-input`, `nana-select`, `nana-combobox`, `nana-checkbox-group`,
`nana-date-range`, `nana-range`, `nana-switch`, or a native `input` / `select`.

Nothing about the field is re-implemented here. The item only reads its value,
decides whether that value narrows the result set, and renders a label for the
chip.

## Import

```js
import "@nana-tec/ui-components/filter-item";
```

Already registered if you imported `@nana-tec/ui-components/filter`.

## Basic usage

```html
<nana-filter-item name="status" label="Status" default-value="all">
  <nana-select value="all">
    <nana-option value="all">All</nana-option>
    <nana-option value="open">Open</nana-option>
  </nana-select>
</nana-filter-item>
```

## How the value is read

Values are read by duck-typing, not by tag name, so a field this library does
not ship works too — as long as it exposes `value` (or `checked`) and fires
`nana-change` or `change`.

| The slotted field | What the item reads |
|---|---|
| Has a boolean `checked` (switch, checkbox) | `checked` |
| Native `<input type="checkbox"\|"radio">` | `checked` |
| Anything else | `value` |

## When a filter counts as active

Only active filters reach the aggregated value and earn a chip. Empty strings,
empty arrays, `null`, and `false` are all inactive. A numeric `0` is **not** —
it is a real filter value.

The case that catches people out is a select whose default option means "no
filter". Set `default-value` and the item stays inactive until the user moves
off it:

```html
<!-- Without default-value this shows a "Status: All" chip immediately. -->
<nana-filter-item name="status" default-value="all">…</nana-filter-item>
```

`clear()` returns the field to `default-value` when one is set, and to an empty
value otherwise.

## Chip text

The chip resolves option labels rather than showing raw values, so a chip reads
**Open orders**, not `open_unassigned`. Arrays are joined; a `nana-date-range`
value is split back into two readable ends. Override any of it with `display`.

```html
<nana-filter-item name="tier" label="Tier" display="Enterprise only">…</nana-filter-item>
```

## Live filtering

`live` also reports mid-edit (`nana-input` / `input`), not just on commit. Pair
it with `debounce` on a search field so it filters as the user types without one
request per keystroke.

```html
<nana-filter label="Filters">
  <nana-filter-item name="q" label="Search" grow live debounce="250">
    <nana-input placeholder="Search orders" clearable></nana-input>
  </nana-filter-item>
</nana-filter>
```

## Values that are not filters

`no-chip` keeps an item out of the chip row, out of the active count, and out of
**Clear all**, while still contributing to the value. Column pickers and sort
selectors want this — they are part of the query, but the user does not mean to
discard them when clearing filters.

```html
<nana-filter-item name="columns" label="Visible columns" no-chip>
  <nana-checkbox-group orientation="horizontal">
    <nana-checkbox value="ref" checked>Ref</nana-checkbox>
    <nana-checkbox value="total">Total</nana-checkbox>
  </nana-checkbox-group>
</nana-filter-item>
```

## API

## Accessibility

The `label` is forwarded to the slotted field as an `aria-label`, but only when
that field has no accessible name of its own — a field with its own `label`
keeps it. `no-label` hides the label visually without removing it from the
accessibility tree or from the chip.
