Skip to content
WingoUI
ComponentsTemplatesDocsPricingAI agentsBlogChangelogContact
Components
Buttons & Actions
ButtonButton GroupCopy ButtonDelete ButtonTheme ToggleToggleToggle Group
Inputs
Avatar UploadCalendarCheckboxColor PickerComboboxCountry SelectCron PickerCurrency InputDate PickerDate Range PickerDate Time PickerDuration PickerEmail InputEmoji PickerFile UploadFilter BuilderInputInput GroupListboxMasked InputMention InputMonth PickerMulti SelectNumber InputOTP InputPassword InputPhone InputRadio GroupRatingSearch InputSegmented ControlSelectSignature PadSliderSwitchTag InputTextareaTime PickerTimezone SelectTree Select
Forms
Address InputBooking WidgetCSV ImportFieldForm WizardInline EditInvoice line itemsRich Text EditorSchema Builder
Navigation
Back To TopBounce SidebarBreadcrumbCommand MenuGlobal SearchGooey NavHook SidebarNav MenuNav TabsPaginationProximity SidebarScroll ProgressSidebarStepsTable Of ContentsTabsTopbarUser MenuWorkspace Switcher
Overlays
Alert DialogContext MenuDialogDrawerDropdown MenuFamily DrawerHover CardPopoverShare DialogSheetShortcuts DialogTooltipTour
Feedback
AlertBannerCookie ConsentEmoji ReactionEmpty StateNotification BellNotification CenterProgressRoute ProgressSetup ChecklistSkeletonSpinnerToast
Data Display
Approval FlowAvatarBadgeCalendar ViewCode BlockComment ThreadContact cardCountdownDescription ListDiff ViewerFile ListFile managerFolderGanttJSON ViewerKbdLog ViewerMarkdownPresenceSchedulerTagTimelineTree View
Tables & Lists
Audit LogData TableDeal PipelineEditable GridKanbanListMembers tablePermissions MatrixTableTask ListVirtual List
Charts & Stats
Animated CounterArea chartBar chartDonut chartFunnel chartGaugeGitHub ActivityHeatmap calendarLeaderboardLine chartRadar chartRadial barSparklineStat CardTrackerTrend badge
Layout
AccordionApp ShellCardCollapsibleDetail LayoutEntity HeaderPage HeaderScroll AreaSeparatorSettings LayoutSplit ViewToolbar
Media
Audio PlayerCarouselCSV ViewerDOCX EditorDOCX ViewerExcel ViewerFile SystemImage compareImage CropperImage GalleryImage LightboxLocation MapPDF ViewerPowerPoint ViewerQR CodeStep PlayerVideo Player
AI Kit
Agent Status CardChat MessageChat ThreadChat WidgetConversation ListFluid OrbGrid RevealMatrix OrbModel PickerPrompt InputReasoning IndicatorRule BuilderSuggestion ChipsTool Call TimelineUsage MeterVoice InputWorkflow Canvas
Text & Effects
Background PatternGravity LettersMarqueeTerminalText AnimateText Rotate
Mobile
Action SheetBottom Tab BarFABHaptic ButtonHero HeaderInstall PromptLarge Title HeaderNotification BannerOnboarding CarouselPicker WheelPull To RefreshSlide To ConfirmSticky CTA BarSwipe DeckSwipeable Tabs
Commerce
Cart drawerCategory pickerCheckout stepsCoupon inputFavorite buttonFilter panelListing cardListing gridOrder trackerPricePrice rangePricing tableProduct galleryQuantity stepperReviewsSeller card
Marketing Sections
App Download SectionBlog Cards SectionCTA SectionFAQ SectionFeature GridFeature ShowcaseHero SectionIntegrations SectionLogo CloudMarketing FooterMarketing HeaderMarketing SectionNewsletter SectionPricing SectionStats SectionSteps SectionTeam SectionTestimonials SectionTimeline SectionVideo Section
Blocks
Admin Dashboard PageAdmin ShellAI Chat PageAPI Keys PageAutomation Builder PageCheckout PageCRM Contact PageCRM Pipeline PageError PagesInbox PageInvoice PageKPI DashboardListing Detail PageLogin PageMarketplace Home PageMarketplace Search PageMarketplace ShellMobile App HomeOnboarding FlowOrder History PagePost Listing WizardPricing PageProfile PageRegister PageSettings PageUsers Admin Page
Templates
About PageAcademy PageAccessibility PageAffiliate PageAgency PageAI Product PageAppointment Booking PageBlog PageBlog Post PageBug Bounty PageCareers PageChangelog PageCommunity PageCompare PageContact PageCustomer Story PageCustomers PageDemo Booking PageDevelopers PageDocs Home PageDownload PageEnterprise PageEvents PageExperts PageFAQ PageFeature PageGlossary PageHelp Article PageHelp Center PageHome Services PageImpact PageIntegration Detail PageIntegrations PageJob Detail PageLanding PageLaunch PageLegal PageManifesto PagePortfolio PagePress PageProduct Tour PagePromo PageReal Estate PageReferral PageResearch Report PageRestaurant PageRoadmap PageROI Calculator PageSecurity PageSolutions PageStartups PageStatus PageStorefront PageSwitch PageTemplate Gallery PageTravel PageWaitlist PageYear in Review Page
Hooks & Utilities
AI ChatChart kitCommerceDate utilsFile exportFile typesFiltersForm validationHapticsInvoicingMotion presetsNavigationNumber formatRelative timeRomanian locationsSpreadsheetText matchTonesUIProvideruseClipboarduseConsentuseControllableStateuseCooldownuseDebounceuseKeyboardInsetuseLocaleuseLongPressuseMediaControlsuseMediaQueryuseOverflowItemsusePersistedStateuseScrollEdgesuseScrollStateuseSelectionuseShortcutuseStickToBottom
GalleryTheme

Hooks & Utilities

Filters

Hooks & Utilities

Filters TypeScript helper for React

File typesForm validation
Live props
Options
view
combinator
locale
  1. Home
  2. Components
  3. Hooks & Utilities
  4. Filters
Pro

Filters TypeScript helper for React

v1.0.0·Added in 1.0.0

The filter model behind React filter builders and saved views: typed fields, AND / OR groups, evaluation, sentences and URL strings.

Pick a saved view in the playground: its conditions show as chips, the sentence under them is describeFilter in the chosen locale, and the client list below is applyFilter over the twelve Northwind CRM customers. Switch the top-level combinator between AND and OR and watch the count change. Remove a chip with its × button (or Delete while it has focus) to see removeFilterNode; the url string at the bottom is serializeFilter and reads back with parseFilter.

Filters is a Pro React helper in the React hooks and utilities category, written in TypeScript for React 19. It installs as source with npx wingo-ui@latest add filters, together with Commerce, Date utils, Number format and Text match.

Add to a project

Requirements: React 19, in Next.js (App Router or Pages), Vite or React Router. Installation guide · Next.js setup · Vite setup

npx wingo-ui@latest add filters

Filters is part of Pro, with 298 more Pro items: $8 a month or $150 once. 14-day refund before you download any Pro item. See plans

Usage

Import applyFilter from @/lib/filters.

import { applyFilter, createFilterCondition, createFilterGroup, describeFilter, type FilterField } from "@/lib/filters"

type Client = { name: string; city: string; balance: number }
const fields: FilterField<Client>[] = [
  { id: "city", label: "City", type: "select", options: [{ value: "New York", label: "New York" }, { value: "London", label: "London" }] },
  { id: "balance", label: "Balance", type: "currency", currency: "USD" },
]

const filter = createFilterGroup("and", [
  createFilterCondition(fields[0], { value: ["New York", "London"] }),
  createFilterCondition(fields[1], { operator: "gte", value: 5000 }),
])

const rows: Client[] = [{ name: "Northwind Tech LLC", city: "New York", balance: 12480 }]
applyFilter(rows, filter, fields) // [Northwind Tech LLC]
describeFilter(filter, fields, { locale: "en-US" }) // "City is any of New York or London and Balance ≥ $5,000"

API

  • viewdefault "ny-london"
    string

    The demo's saved view (a FilterView): customers in New York or London, overdue customers, large balances or invoices in the last 7 days.

  • combinatordefault "and"
    "and" | "or"

    The root group's combinator. Nested groups keep their own.

  • localedefault "en-US"
    string

    describeFilter options.locale: money, numbers and dates in the sentence. The demo passes German operator labels for de-DE.

  • applyFilter
    <T>(rows: T[], filter: FilterNode | null, fields: FilterField<T>[], options?: { now?: Date | number }) => T[]

    The main helper: the rows that pass the filter. Text ignores case and accents ("zurich" finds Zürich), dates compare local days, incomplete conditions and unknown fields are skipped, and an empty group passes everything. The same code filters on a server.

Parts

  • evaluateFilter

    function

    Whether one row passes a filter. Takes (row, filter, fields, { now? }); the same rules as applyFilter, for a single record or a server check.

  • FILTER_OPERATORS

    constant

    The operators each field type allows. Text: contains, not-contains, is, is-not, starts-with, ends-with. Numbers: eq, neq, gt, gte, lt, lte, between. Dates: on, before, after, between, in-last, in-next. Select: is, is-not, any-of, none-of. Multi-select: any-of, all-of, none-of. Boolean: is-true, is-false. Every type: is-empty, is-not-empty.

  • DEFAULT_FILTER_OPERATOR

    constant

    The operator a new condition starts with for each field type, e.g. contains for text and any-of for select.

  • DEFAULT_FILTER_OPERATOR_LABELS

    constant

    English words for every operator ("is any of", "does not contain", "in the last"). Pass your own through describeFilter's labels to translate.

  • DEFAULT_FILTER_DESCRIBE_LABELS

    constant

    The English glue of a described filter: and, or, the joiner inside lists, days and the operator words. Spread it to translate.

  • operatorsFor

    function

    The operators a field offers: its own operators prop intersected with what its type allows.

  • operatorNeedsValue

    function

    Whether an operator takes a value; is-empty, is-true and the like do not.

  • operatorValueShape

    function

    Which value input an operator needs for a field type: "none", "single", "list", "range" or "days".

  • createFilterGroup

    function

    A new AND or OR group with a fresh id. Call it in event handlers, not during render.

  • createFilterCondition

    function

    A new condition for a field with a fresh id and the type's default operator (30 days for in-last). Pass overrides for operator or value.

  • createFilterId

    function

    A fresh node id with an optional prefix, for nodes you build by hand.

  • isFilterGroup

    function

    Type guard: whether a node is a group rather than a condition.

  • addFilterNode

    function

    Adds a condition or group to the root or to a nested group by id, returning a new tree.

  • updateFilterNode

    function

    Patches a condition or group by id anywhere in the tree, returning a new tree.

  • removeFilterNode

    function

    Removes a node by id, returning a new tree; a nested group left empty is removed too.

  • findFilterNode

    function

    Finds a node by id anywhere in the tree, or null.

  • isConditionComplete

    function

    Whether a condition has every value its operator needs. Incomplete conditions are skipped, so a chip being built never empties the list.

  • flattenConditions

    function

    Every complete condition in the tree as a flat list, optionally limited to known fields.

  • countActiveConditions

    function

    How many complete conditions filter the rows, for a "Filters 3" badge.

  • describeCondition

    function

    The three parts of a chip: { field, operator, value }, e.g. "City", "is any of", "New York or London". Values are formatted in the locale.

  • describeFilter

    function

    One sentence for the whole filter: "City is any of New York or London and (Balance ≥ $12,000 or Last invoice in the last 7 days)". Pass locale and labels for another language.

  • serializeFilter

    function

    A compact base64url string for ?filter= links and saved views. Node ids are not kept; they are made again on parse.

  • parseFilter

    function

    Reads a serializeFilter string back into a group, or null for a broken or hand-edited link.

  • FilterField

    type

    A field people can filter by: { id, label, type, accessor?, options?, operators?, currency?, placeholder?, group? }. The value comes from row[id] unless accessor says otherwise.

  • FilterCondition

    type

    { id, field, operator, value? }. Text takes a string, numbers a number or [min, max] with null for an open end, dates "2026-09-24" or [from, to], in-last a number of days, select a string or string[].

  • FilterGroup

    type

    { id, combinator: "and" | "or", conditions }, where conditions mixes conditions and nested groups.

  • FilterView

    type

    A saved view: { id, name, filter, readOnly?, pinned? }.

  • FilterOperator

    type

    Every operator name, from contains to in-next.

Examples

Search box

One contains condition through applyFilter; case and accents never matter.

Shareable link

serializeFilter for ?filter= URLs and parseFilter to read it back, with a safe null for broken links.

Operators by field type

FILTER_OPERATORS with the English words from DEFAULT_FILTER_OPERATOR_LABELS.

Dependencies

commercedate-utilsnumber-formattext-match

Files

  • lib/filters.ts

FAQ

Is the Filters helper free?

The preview, props and docs are free; copying the source needs a Pro plan. See plans.

How do I install Filters?

Run npx wingo-ui@latest add filters. It also adds the Wingo UI items it builds on (Commerce, Date utils, Number format and Text match). With shadcn, add the @wingo-ui registry with your API key, then run npx shadcn@latest add @wingo-ui/filters.

See also

Text matchlibData TableToolbar

Used in

Filter BuilderAudit LogRule BuilderUsers Admin Page

More React hooks and utilities

Form validationlibHapticslibInvoicinglibMotion presetslibNavigationlibNumber formatlib
All 36 React hooks and utilities
PreviousFile typesNext Form validation
Customers3 of 12
  • City is any of New York or London
  • (Balance ≥ $5,000 or Last invoice in the last 7 days)

City is any of New York or London and (Balance ≥ $5,000 or Last invoice in the last 7 days)

  • Northwind Tech LLCNew York · Active$12,480.00
  • North Studio LLCNew York · Active$9,870.00
  • Pixel StudioLondon · Active$3,450.00
?filter=WyJhIixbWyJjaXR5IiwiYW55LW9mIixbIk5ldyBZb3JrIiwiTG9uZG9uIl1dLFsibyIsW1siYmFsYW5jZSIsImd0ZSIsNTAwMF0sWyJsYXN0SW52b2ljZSIsImluLWxhc3QiLDddXV1dXQ