Skip to content

v3.36.0

Choose a tag to compare

@tjloong tjloong released this 13 Oct 10:21
· 8 commits to main since this release
89000db

New: WithUrlFilters — listing filters in the URL (#86)

An opt-in trait that keeps a listing's $filters in the query string (?status=approved&region=MY), so opening a record and coming back by the breadcrumb or Back restores the filters. Declare the filter keys and their defaults once; the trait writes the URL (replace, not push), and a filter at its default leaves the URL.

  • The declared keys are an allow-list, enforced on every update. Values from the URL are cleaned at mount: an undeclared key is dropped, and a wrong shape, invalid UTF-8, an over-long string (1000 bytes) or an over-long list (200) falls back to the default. A crafted link opens the listing, it never errors. A browser update with an undeclared or internal key, a wrong shape or a refused value gets a 403.
  • An optional isUrlFilterValid() hook adds app checks such as dates. A hook that throws counts as a refusal.
  • Internal keys (urlFiltersExcept()) never reach the URL and can't be set from the browser.
  • A prefix (urlFiltersPrefix()) keeps two listings on one page apart. A filter name that collides with page, tab, another query-string entry or a #[Url] property throws at mount.
  • Don't #[Locked] the property: the table controls bind to it.
  • Breadcrumbs must sit in @persist('breadcrumbs') for the crumb or Back to restore filters (see v3.35.6).

Requires the filter() hardening in v3.35.4+. Components that don't use the trait are unchanged. See the README section "Filters in the URL". (#99)