Skip to content

Latest commit

 

History

History
252 lines (217 loc) · 8.87 KB

File metadata and controls

252 lines (217 loc) · 8.87 KB

react-native-quick-filter — API Reference

All exports from react-native-quick-filter. See USAGE.md for guides.


Provider

<FilterProvider>

Owns the filter state and exposes it via context. Wrap the filter UI with it.

Prop Type Default Description
facets Facet[] — (required) All filter dimensions.
chips ChipSpec[] [] Chips for the bar.
selection Selection Controlled committed selection.
defaultSelection Selection empty Uncontrolled initial selection.
onSelectionChange (next: Selection) => void Called on every commit/instant change (pruned selection).
resolveResultCount (sel: Selection) => number | Promise<number> Live result count resolver (debounced).
applyMode 'instant' | 'deferred' per-kind Provider-level apply mode default.
defaultSide 'left' | 'right' 'right' Initial side stored in panel state.
resultCountDebounceMs number 250 Debounce before calling resolveResultCount.
children ReactNode

Hooks

All hooks must be used inside a <FilterProvider>.

useFilter()

Top-level state + global actions.

{
  selection: Selection;                 // committed
  activeCount: number;                  // number of active facets
  isFacetActive: (facetId: string) => boolean;
  facetCount: (facetId: string) => number;
  resultCount: ResultCountState;        // { count, status }
  openDropdownFacetId: string | null;
  panelOpen: boolean;
  panelSide: PanelSide;
  openDropdown: (facetId: string) => void;
  closeDropdown: () => void;
  openPanel: (side?: PanelSide) => void;
  closePanel: () => void;
  setPanelGroup: (facetId: string | null) => void;
  commitAll: () => void;
  clearAll: () => void;
  removeFacet: (facetId: string) => void;
}

useFacet(facetId)

Read/write surface for a single facet — the consumption point for panel bodies.

{
  facet: Facet;
  applyMode: ApplyMode;
  isOpen: boolean;                      // open in a dropdown/panel
  optionValue: string[];                // effective value (draft when open, else committed)
  rangeValue: RangeValue;
  count: number;                        // selection count for this facet
  isOptionSelected: (optionId: string) => boolean;
  toggleOption: (optionId: string) => void;
  setOptions: (optionIds: string[]) => void;
  setRange: (range: RangeValue) => void;
  selectAll: () => void;
  clearFacet: () => void;
  commit: () => void;                   // deferred → commit this facet
  searchQuery: string;
  setSearchQuery: (q: string) => void;
  visibleOptions: FacetOption[];        // filtered by searchQuery
}

useResultCount()

{ count: number | null; status: 'idle' | 'loading' | 'ready' }

useDropdown()

{
  openFacetId: string | null;
  isOpen: (facetId?: string) => boolean;
  open: (facetId: string) => void;
  close: () => void;
}

usePanel()

{
  isOpen: boolean;
  side: PanelSide;
  activeGroupId: string | null;
  open: (side?: PanelSide) => void;
  close: () => void;
  setGroup: (facetId: string | null) => void;
  commitAll: () => void;
}

useChip(spec)

Derived state + interaction for a single chip.

{
  label: string; kind: ChipKind; active: boolean; open: boolean;
  count: number; badge: number; removable: boolean; leadingIcon?: ReactNode;
  onPress: () => void; onRemove: () => void;
}

Components

<QuickFilterBar>

Prop Type Default
chips ChipSpec[] provider chips
renderChip (spec, index) => ReactNode built-in
pinActiveFirst boolean false
style / contentContainerStyle StyleProp<ViewStyle>

<FilterDropdown>

Prop Type Default
topOffset number 0
dimBackdrop boolean false
panelStyle StyleProp<ViewStyle>

<FilterSidePanel>

Prop Type Default
variant 'drilldown' | 'masterDetail' 'drilldown'
side 'left' | 'right' 'right'
title string i18n filter
groups string[] all facets
width number min(380, 86% screen)
swipeToClose boolean true
enableBackdropDismiss boolean true
animated boolean true
topInset / bottomInset number 0
footer (ctx: { commitAndClose }) => ReactNode ResultCountButton

<FilterSheet>

Prop Type Default
presentation 'sheet' | 'fullScreen' 'sheet'
title string i18n filter
groups string[] all facets
sectionMaxHeight number 280 (0 = unlimited)
topInset / bottomInset number 0
footer (ctx: { commitAndClose }) => ReactNode ResultCountButton

Other components

  • <QuickFilterChip spec testID? /> — kind-aware chip (used by the bar).
  • <Chip label active? open? leadingIcon? trailing? onRemove? onPress? testID? /> — presentational shell.
  • <SidePanelMasterList groups onSelect />, <SidePanelRail groups activeId onSelect width? />.
  • Bodies: <FacetBody facetId />, <CheckboxListBody facetId />, <RadioListBody facetId />, <RangeBody facetId />.
  • Atoms: <ResultCountButton onPress? template? style? />, <FilterFooter onClear? clearLabel? children? />, <Button label onPress? variant? disabled? style? />, <Checkbox checked />, <Radio selected />, <Badge count />, <SearchInput value onChangeText placeholder? />, <Chevron open? color? size? />.

Theme

  • <ThemeProvider scheme? theme? override? />scheme: 'light' | 'dark', theme: QuickFilterTheme (overrides scheme), override: { colors?, radius?, spacing?, chipActiveStyle? }.
  • useTheme(): QuickFilterTheme — defaults to light when no provider.
  • defaultLightTheme, defaultDarkTheme: QuickFilterTheme.
  • mergeTheme(base, override): QuickFilterTheme.

i18n

  • <StringsProvider strings? /> — partial dictionary; missing keys fall back to English.
  • useStrings(): QuickFilterStrings — defaults to English when no provider.
  • en, tr: QuickFilterStrings — built-in dictionaries.
  • formatNumber(n): string — Turkish-grouped number (tr-TR).

Types

type FacetKind = 'single' | 'multi' | 'range' | 'toggle';
type Presentation = 'dropdown' | 'sidePanel';
type ApplyMode = 'instant' | 'deferred';
type PanelSide = 'left' | 'right';
type ChipKind = 'action' | 'dropdown' | 'toggle' | 'segment';
type ChipBadge = 'activeCount' | 'facetCount' | 'none';
type ColorScheme = 'light' | 'dark';
type ChipActiveStyle = 'fill' | 'outline';
type SidePanelVariant = 'drilldown' | 'masterDetail';
type FilterSheetPresentation = 'sheet' | 'fullScreen';
type ResultCountStatus = 'idle' | 'loading' | 'ready';
type ResultCountResolver = (selection: Selection) => number | Promise<number>;

interface FacetOption { id: string; label: string; count?: number }
interface RangePreset { id: string; label: string; min?: number; max?: number }
interface Facet {
  id: string; label: string; kind: FacetKind;
  options?: FacetOption[]; searchable?: boolean; selectAll?: boolean; columns?: 1 | 2;
  min?: number; max?: number; step?: number; presets?: RangePreset[]; slider?: boolean;
  presentation?: Presentation; applyMode?: ApplyMode;
}
interface ChipSpec {
  facetId: string; kind: ChipKind; label?: string; optionId?: string;
  leadingIcon?: ReactNode; badge?: ChipBadge; removable?: boolean;
  pinActiveFirst?: boolean; opens?: Presentation;
}
interface RangeValue { min?: number; max?: number }
interface Selection {
  options: Record<string, string[]>;
  ranges: Record<string, RangeValue>;
}
interface ResultCountState { count: number | null; status: ResultCountStatus }

interface QuickFilterColors {
  accent: string; accentText: string; success: string; surface: string; surfaceAlt: string;
  border: string; text: string; textMuted: string; backdrop: string; chipBg: string;
  chipText: string; chipActiveBg: string; chipActiveBorder: string; badgeBg: string;
  badgeText: string; cta: string; ctaText: string;
}
interface QuickFilterTheme {
  scheme: ColorScheme; colors: QuickFilterColors;
  radius: { chip: number; panel: number; button: number };
  spacing: { chipGapX: number; chipPadX: number; chipPadY: number; panelPad: number };
  chipActiveStyle: ChipActiveStyle;
}
interface QuickFilterStrings {
  sort: string; filter: string; apply: string; clear: string; clearAll: string;
  selectAll: string; reset: string; close: string; back: string; priceMin: string; priceMax: string;
  searchPlaceholder: (label: string) => string;
  resultCount: (n: number) => string;
  facetCount: (n: number) => string;
  removeLabel: (label: string) => string;
}

// helper
const emptySelection: () => Selection;