import "./filter_chip.css"; import type * as React from "react"; import { type ReactNode } from "react"; import { useRender } from "@base-ui/react/use-render"; import { type ColumnFilterValue, type FilterableColumn } from "./column_filter"; import { type StyleProps } from "./style_props"; import type { PopoverSide, PopoverAlign } from "./popover"; interface FilterChipBase extends StyleProps { /** Tooltip on the pill's × (pass a translated string). */ clearLabel?: string; side?: PopoverSide; align?: PopoverAlign; /** Optional controlled popover state — for an editor that closes on Save. */ open?: boolean; onOpenChange?: (open: boolean) => void; /** A custom popover footer (e.g. Cancel / Save) — for an editor that commits * rather than applying live. Reach for it only when the editor NEEDS a * commit: one that already carries bottom actions gets a second bordered * band from this. */ footer?: ReactNode; /** Names the TRIGGER, so a driver reaches this facet rather than whichever * other control on the band shares its word. */ testID?: string; ref?: React.Ref; render?: useRender.RenderProp; } /** The facet the caller DRAWS — its own words and its own editor. */ interface FilterChipComposedProps extends FilterChipBase { /** The dimension name — shown alone when inactive ("Owner"), prefixed when * active ("Owner: Maria, James"). */ label: string; /** The active selection preview, after "Label: ". A string ("Maria, James", * "≥ 10" — build with `rangeSummary` / `selectSummary`), OR a node to render the * selection RICHLY in the trigger (member avatars, colour dots). Empty / * undefined renders the inactive pill (label + chevron, no clear). */ summary?: ReactNode; /** Clears the dimension — renders the × on the pill whenever a summary is * present. The × is the ONLY clear: the editor inside brings its own bottom * actions. */ onClear?: () => void; /** The editor revealed on press. `FilterChip` owns the pill + popover chrome; * the consumer owns the value and applies it. Pass a render function to * receive `close` — the one editor that closes on action is single-select; * range/stepper/multi stay open and dismiss on outside-press. */ children: ReactNode | ((api: { close: () => void; }) => ReactNode); column?: never; value?: never; onChange?: never; } /** ONE COLUMN of a register, where the column's `type` picks the editor — text * contains, a number's two bounds, a multi-select over its options — and the * words come off the column. The value is the caller's; turn it into query * conditions with `columnFilterToConditions`. */ interface FilterChipColumnProps extends FilterChipBase { column: FilterableColumn; value: ColumnFilterValue | undefined; onChange: (value: ColumnFilterValue | undefined) => void; label?: never; summary?: never; onClear?: never; children?: never; } export type FilterChipProps = FilterChipComposedProps | FilterChipColumnProps; /** * A short summary of a multi-select for a `FilterChip` preview — "Maria, James" * up to `max` labels, else "N selected", and `undefined` when nothing is * chosen. The select sibling of `rangeSummary`. */ export declare function selectSummary(selected: string[], options: { value: string; label: string; }[], opts?: { max?: number; }): string | undefined; /** * A toolbar filter pill: inactive reads "Label ⌄", active reads "Label: summary" * with an × to clear. It adds NO bottom band of its own — the editor inside * brings whatever actions it has. With `footer` (+ controlled * `open`/`onOpenChange`) the same shell wraps a non-filter VALUE pill. Pass a * `column` instead of the words and the editor and the pill draws a REGISTER's * column: the column's `type` picks the control and the operators, and * `columnFilterToConditions` (`@lotics/ui/column_filter`) turns the value it * hands back into query conditions. * * Inside a COLLAPSED `FilterBand` the same component re-presents itself as a * full-width disclosure ROW: `header` / `value` / `body` are that shape's parts, * and they render only there. */ export declare function FilterChip(props: FilterChipProps): React.JSX.Element; export {};