List + filters
The workhorse data view: a filter row that narrows a collection, results rendered as esa-card entries, and pagination at the bottom. The filter legos emit events; the page owns the state and re-renders pills, results, and the count from it.
Populated
The three-band frame: filter row on top, results in the middle, pagination at the bottom. Pills restate the applied filters next to the dropdowns, and the count line ties the bands together — the dropdowns here are live.
Showing 6 of 23 applications
Carquinez Shoreline Restoration
Alhambra Creek Fish Passage Retrofit
Tomales Bay Eelgrass Expansion
San Pablo Baylands Levee Setback
Yolo Bypass Floodplain Reconnection
Mokelumne Riparian Buffer Planting
Empty result state
Filtered-to-zero is a normal outcome, not an error. The filter row stays exactly where it was — users need it to undo the dead end — and the results band swaps to esa-empty-state with a one-click way out.
Showing 0 of 23 applications
No applications match these filters
Status: Withdrawn in Alpine County turns up nothing. Widen a filter, or clear them all to get back to the full list.
Composition notes
- Filter state lives with the page, not inside any lego. Dropdowns, pills, and the clear button all emit bubbling events (
esa-filter-change,esa-filter-remove,esa-filter-clear); one page-level handler updates the single filter list and re-renders pills, count, and results from it. - Cards vs table: cards suit scannable summaries with mixed-importance fields, like this queue. When users compare many rows across uniform columns — sorting, bulk selection — reach for a data table instead; the filter row above it stays identical.
- Always design the empty state. Filtered-to-zero will happen on day one. Keep the filter row visible, say which filters caused it, and offer the clear action inside the
esa-empty-state— never a blank region. - Status is a pill, not a border. Each card carries its status as an
esa-pillin the header'sactionsslot, so state reads as content and re-skins with the theme. - Pagination follows the filtered set. Reset to the first page whenever a filter changes, and zero it out (or drop it, as here) when nothing matches.