/** * @grove-dev/ui — filter primitive (V1, typed against `IndexRecord`). * * V0 worked on the `DirectoryRecord` (item + health + decision * triplet) and operated on `taxonomy.category`, `health.health.status`, * `curation.scores`. V1 replaced all of that with a discriminated * `IndexRecord` union: `kind: "project" | "resource" | "entity"`, * with each kind carrying only the fields it actually has. This * module ports the V0 filter semantics — text search, stack/ * platform/category/label/license/status/lens, maintained toggle, * hideArchived — to the V1 shape. * * The `IndexFilters` shape mirrors `@grove-dev/astro`'s * `IndexFilters` (formerly `ItemsFilters` before the V0→V1 rename) * so a consumer can build a filter * object once and pass it through both layers. */ import type { IndexRecord } from "@grove-dev/core"; import { type SortValue, type LensId } from "./constants.js"; /** URL-driven filter state for the directory index. */ export interface IndexFilters { q?: string; /** Stack names — match against `project.stack` + `project.stacks[]`. */ stacks?: string[]; /** Platform names — match against `project.platforms[]`. */ platforms?: string[]; /** Category name (single) — matches `record.category`. */ categories?: string[]; /** Curation labels (multi) — matches `curation.labels[]`. */ labels?: string[]; /** GitHub-derived license (single) — matches `project.github.license`. */ licenses?: string[]; /** Health statuses (multi) — matches `project.health.status`. */ statuses?: string[]; /** A curated lens id (single) — matches `curation.lenses[]`. */ lens?: LensId; /** Sort order. Single value, defaults to "recently-updated". */ sort?: SortValue; /** 1-based page number. */ page?: number; } /** Filter chip — key/value/label tuple for active-filter rendering. */ export interface FilterChip { key: keyof IndexFilters; label: string; value: string; } /** * Return the subset of records that match all active filters (AND * across dimensions, OR within a dimension). `q` is a case-insensitive * substring search across name, owner, description, and category. * Other dimensions are exact match. */ export declare function filterRecords(records: IndexRecord[], f: IndexFilters): IndexRecord[]; /** * `True` if any filter is active (i.e. the result list isn't "all * records"). Used by the UI to show a "Clear all" affordance and * by the search URL helper to decide whether to add a marker. */ export declare function hasAnyFilter(f: IndexFilters): boolean; /** * Build a flat list of "active filter" chips for display + removal. * Multi-value keys (stacks, platforms, etc.) emit one chip per * value. The `key` is the field in `IndexFilters`; `value` is the * specific value to remove; `label` is the user-facing string. */ export declare function activeFilterChips(f: IndexFilters): FilterChip[]; /** True if the record is a "maintained" project (active or mature). */ export declare function isMaintained(record: IndexRecord): boolean; //# sourceMappingURL=filter.d.ts.map