goobs-frontend
Version:
A comprehensive React-based libary for building modern web applications
137 lines • 5.62 kB
TypeScript
import { default as React } from 'react';
import { DropdownOption } from '../../Field/Dropdown/SearchableSimple';
export interface FilterDropdownDef {
label: string;
value: string;
options: DropdownOption[];
onChange: (value: string) => void;
/**
* Render variant. Defaults to `'auto'` which picks based on options.length —
* `searchable` when ≥ 8 options, `simple` otherwise. Callers with strong
* UX opinions pass `'simple'` or `'searchable'` explicitly to override.
* - `'simple'` → goobs `<Dropdown>` (compact, no type-ahead)
* - `'searchable'` → goobs `<SearchableSimple>` (type-to-filter, better
* for long option lists like customers / categories)
*/
variant?: 'simple' | 'searchable' | 'auto';
placeholder?: string;
width?: string;
/** Stable test selector; defaults to kebab-case of `label`. */
dataField?: string;
}
export interface FilterChipOption {
label: string;
value: string;
/**
* Optional accent color for this chip when active. Forwarded as
* `styles.backgroundColor: alpha(color, 0.2)` / `styles.color: color`
* — used by callsites with semantic per-option theming (e.g.
* learning's level chips: beginner=green / intermediate=orange /
* advanced=red). Inactive chips fall back to the theme default.
*/
color?: string;
}
export interface FilterChipClusterDef {
/** Dimension label (e.g. "Status", "Type", "Category"). Rendered as the
* row label above the chip row. Also surfaced as `data-chip-field` on
* each chip in the cluster. */
label?: string;
options: FilterChipOption[];
selectedValues: string[];
onChange: (selected: string[]) => void;
/** When true (default), only one value at a time — clicking a chip
* REPLACES the selection. When false, multi-select — clicking toggles
* membership in `selectedValues`. */
exclusive?: boolean;
/** Stable test selector; defaults to kebab-case of `label`. */
dataField?: string;
}
export interface FilterDateRangeDef {
startLabel?: string;
endLabel?: string;
value?: {
start: Date | null;
end: Date | null;
};
onChange: (range: {
start: Date | null;
end: Date | null;
}) => void;
/** Stable test selector; defaults to kebab-case of `startLabel` (or "range"). */
dataField?: string;
}
export interface FilterToggleDef {
label: string;
value: boolean;
onChange: (value: boolean) => void;
dataField?: string;
}
export interface FilterButtonDef {
text: string;
onClick: () => void;
icon?: React.ReactNode;
disabled?: boolean;
/**
* Permission gate. When explicitly `false`, the button is omitted from
* the row (matches the common ThothOS `{canWrite && <button>}` pattern).
* Undefined / `true` → button renders. To render disabled, use the
* `disabled` prop.
*/
permission?: boolean;
/** goobs-frontend convention — emitted as `data-action` on the button. */
action?: string;
/** goobs-frontend convention — emitted as `data-subject` on the button. */
subject?: string;
}
export interface FilterSectionProps {
searchValue?: string;
onSearchChange?: (value: string) => void;
searchPlaceholder?: string;
searchDataField?: string;
/** Slot rendered INSIDE the filter surface, directly below the search row
* (above the dropdown / chip filters). Use for a section sub-nav (a chip
* `<Tabs>`) that should live inside the filter card rather than float above
* it. Optional. */
belowSearch?: React.ReactNode;
dropdowns?: FilterDropdownDef[];
chipClusters?: FilterChipClusterDef[];
dateRanges?: FilterDateRangeDef[];
toggles?: FilterToggleDef[];
buttons?: FilterButtonDef[];
/**
* Wrap the filter row in an accordion shell. Defaults to false (the row
* renders bare). When true, the row sits inside a toggleable panel with
* `initiallyOpen` controlling the starting state.
*/
collapsible?: boolean;
/** When `collapsible`, defaults to TRUE — filters are primary UI and
* shouldn't be hidden on first paint. (Contrast: `MetricsAccordion`
* defaults to false because the metric strip is read-only KPI data.) */
initiallyOpen?: boolean;
/** Accordion title when `collapsible`. Default `"Filters"`. */
title?: string;
styles?: {
theme?: 'sacred' | 'light';
};
/**
* Give the (non-collapsible) row a self-contained surface — padding, a
* subtle border, tinted background, and rounded corners — so it reads as
* one grouped card instead of a bare edge-to-edge row (matching the visual
* weight of MetricsAccordion beside it). Defaults to false (the unchanged
* bare row) so DataGrid and every existing callsite are byte-identical.
* Ignored in collapsible mode, which already renders the accordion panel
* surface.
*/
surface?: boolean;
/** Escape hatch — extra className merged onto the section root. */
className?: string;
/** Escape hatch — inline style merged onto the section root (e.g. a margin
* the host layout needs; the component itself ships `margin-bottom: 0`). */
style?: React.CSSProperties;
/** Stable test selector for the whole section. Surfaced as
* `data-filter-section-field` on the wrapper. */
dataField?: string;
}
export declare const FilterSection: React.FC<FilterSectionProps>;
export default FilterSection;
//# sourceMappingURL=index.d.ts.map