# Availability, Counts, and Options

> How option availability, dynamic counts, default selections, and unavailable selected values behave.

<!-- Sources: src/Components/Facets/Shared/FacetQueryProperties.php; src/Facets/FacetAvailabilityComputer.php; src/Facets/FacetRestEndpoint.php; client/src/domains/facets/availability/*.ts; client/src/domains/facets/behaviors/*.ts; tests/e2e/components/facets/availability.spec.ts; tests/e2e/components/facets/options-behavior.spec.ts -->

# Availability, Counts, and Options

Availability is the runtime metadata that tells option facets which values currently produce results. It is computed per target after a facet request and then applied by the client to Select, SearchSelect, Radio List, and Checkbox List controls.

## Options Behavior

`options_behavior` controls what happens to unavailable options.

| Value | Behavior |
| --- | --- |
| `all` | Keep every authored option visible and enabled. Counts can still update. |
| `disable` | Keep unavailable options visible, but mark them disabled and prevent selection. |
| `hide` | Hide unavailable options from the UI. |

The option behavior E2E scenario verifies all three modes across Select, SearchSelect, Radio List, and Checkbox List.

## Dynamic Counts

`show_counts` enables result counts on option values when availability data exists.

Counts are based on the current target scope and the other active filters. For example, after a search narrows results to one post, category options can update to `News category (1)` and `Guides category (0)`.

Count rendering depends on each option's `count_display`:

- `inline` appends the count to the label text.
- `span` writes the count into a separate counter span.

## Cross-Facet Behavior

Facet availability is cross-facet. A change in one control can change the option state of another control connected to the same target.

Example from E2E behavior:

```text
Search "Foo" narrows results to Alpha Foo.
Category "news" remains available with count 1.
Category "guides" becomes unavailable with count 0.
```

This works for single-mode facets and for mapped bundles. Mapped bundle availability is keyed by a generated control scope so each authored bundle can be counted independently.

## Selected Values That Become Unavailable

Select and SearchSelect can reset a selected value when that value becomes unavailable in `disable` or `hide` mode. The option behavior tests cover auto-reset for selected categories after a search makes the selected category unavailable.

Radio and checkbox behavior also syncs disabled, hidden, ARIA, and selected state through their runtimes so stale state is not left in the DOM after an update.

## Default Selections

Authored default options initialize controls only when there is no URL, runtime, or restored value already present.

- Select supports authored default options and has a built-in empty option using the `default_label`.
- Radio List supports default options and can also render a built-in reset option.
- Checkbox List supports multiple authored defaults.
- SearchSelect options do not expose `is_default` in the current PHP component.

Direct URL state wins over authored defaults. The URL parameter E2E suite verifies direct-link hydration for several facet families.

## Performance Boundary

Availability computation may fan out across descriptors, including mapped bundle descriptors. The endpoint limits expensive paths with query budgets, descriptor truncation metadata, and sampled post IDs. Authoring a large number of mapped bundles is supported, but it has a real availability cost because every bundle may need a count.

Use `show_counts` and `disable` or `hide` when users benefit from availability feedback. Leave `options_behavior` as `all` and `show_counts` as false when the UI does not need dynamic option state.
