JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 41
  • Score
    100M100P100Q75756F
  • License MIT

A powerful, themeable expression builder for creating complex filter logic

Package Exports

  • @aftui/expresso

Readme

Advanced Filter Builder

A powerful, themeable React component for building complex filter expressions with a visual drag-and-drop interface.

Features

  • 🎨 Fully Themeable - Injectable theme system with default light and dark themes
  • 🔧 Comprehensive Operators - Comparison, arithmetic, logical, and conditional expressions
  • 🎯 Drag & Drop - Intuitive interface for organizing expressions
  • 💾 Presets - Save and load frequently used configurations
  • 📋 Import/Export - Share expressions via JSON
  • ⏱️ Undo/Redo - Full history support with keyboard shortcuts
  • 🔍 Search - Find specific values within expressions
  • Validation - Real-time error detection

Installation

npm install @your-org/advanced-filter-builder
# or
yarn add @your-org/advanced-filter-builder
# or
pnpm add @your-org/advanced-filter-builder

Peer Dependencies

Make sure you have React 18+ and Sonner installed:

npm install react react-dom sonner

Important: This package uses Sonner for toast notifications. You must include the <Toaster /> component in your app:

import { Toaster } from 'sonner';

function App() {
  return (
    <>
      <Toaster />
      {/* Your app content */}
    </>
  );
}

Tailwind CSS Setup

This package requires Tailwind CSS. Add the package to your Tailwind content:

// tailwind.config.js
module.exports = {
  content: [
    './src/**/*.{js,jsx,ts,tsx}',
    './node_modules/@your-org/advanced-filter-builder/dist/**/*.{js,jsx,ts,tsx}',
  ],
  // ... rest of your config
}

SSR Frameworks (Astro, Next.js, Remix)

This component uses Radix UI which requires client-side rendering. When using with SSR frameworks:

Astro

---
import { Expresso } from '@aftui/expresso';
---

<Expresso
  client:only="react"
  fields={fields}
  onApply={handleApply}
/>

Next.js (App Router)

'use client' // Add this at the top of your component file

import { Expresso } from '@aftui/expresso'

Next.js (Pages Router)

import dynamic from 'next/dynamic'

const Expresso = dynamic(
  () => import('@aftui/expresso').then(mod => ({ default: mod.Expresso })),
  { ssr: false }
)

Quick Start

import {
  AdvancedFilterBuilder,
  type JoinKeyExpression,
  type DropdownItem
} from '@your-org/advanced-filter-builder';

function App() {
  const fields: DropdownItem[] = [
    { name: 'Price', key: 'price' },
    { name: 'Status', key: 'status' },
    { name: 'Category', key: 'category' },
  ];

  const handleApply = (expression: JoinKeyExpression | JoinKeyExpression[]) => {
    console.log('Filter expression:', expression);
    // Use the expression in your application
  };

  return (
    <AdvancedFilterBuilder
      fields={fields}
      onApply={handleApply}
      onCancel={() => console.log('Cancelled')}
    />
  );
}

Theming

Using Default Theme

<AdvancedFilterBuilder
  fields={fields}
  onApply={handleApply}
  onCancel={handleCancel}
/>

Using Dark Theme

import { AdvancedFilterBuilder, darkTheme } from '@your-org/advanced-filter-builder';

<AdvancedFilterBuilder
  fields={fields}
  onApply={handleApply}
  onCancel={handleCancel}
  theme={darkTheme}
/>

Custom Theme

import {
  AdvancedFilterBuilder,
  type FilterBuilderThemeConfig
} from '@your-org/advanced-filter-builder';

const customTheme: FilterBuilderThemeConfig = {
  theme: {
    primary: "222.2 47.4% 11.2%",
    accent: "142.1 76.2% 36.3%", // Green accent
    // ... other theme properties
  },
  radius: "0.75rem",
};

<AdvancedFilterBuilder
  theme={customTheme}
  {...otherProps}
/>

See THEMING.md for complete theming documentation.

Props

Prop Type Required Description
fields DropdownItem[] Yes Array of available fields
onApply (expression) => void Yes Callback when user applies filter
onCancel () => void Yes Callback when user cancels
defaultExpression JoinKeyExpression | JoinKeyExpression[] No Initial expression
operatorConfig OperatorConfig No Custom operator configuration
creationMetaData CreationMetaData No Metadata for new expressions
customCategoryContent Record<string, ReactNode> No Custom field category content
theme FilterBuilderThemeConfig No Custom theme

Expression Format

Expressions are structured JSON objects:

{
  "operator": "and",
  "expressions": [
    {
      "operator": "gt",
      "left": { "valueType": "EnrichmentField", "fieldId": "Price" },
      "right": { "valueType": "constant", "value": 100 }
    },
    {
      "operator": "eq",
      "left": { "valueType": "EnrichmentField", "fieldId": "Status" },
      "right": { "valueType": "constant", "value": "Active" }
    }
  ]
}

Optional: Section Dropdown

If you need the Section Dropdown feature (for enrichment fields with sections), wrap your app with FieldsProvider:

import { FieldsProvider } from '@your-org/advanced-filter-builder';

function App() {
  const enrichmentFields = [
    { Id: 1, Name: 'Field1', FriendlyName: 'Field 1', Key: 'field1', Section: 'General' },
    // ... more fields
  ];

  return (
    <FieldsProvider fields={enrichmentFields}>
      <AdvancedFilterBuilder {...props} />
    </FieldsProvider>
  );
}

If you don't use FieldsProvider, the Section Dropdown will simply not appear (graceful degradation).

TypeScript Support

This package is written in TypeScript and includes full type definitions.

import type {
  JoinKeyExpression,
  AnyExpressionType,
  DropdownItem,
  FilterBuilderThemeConfig,
} from '@your-org/advanced-filter-builder';

Browser Support

  • Chrome/Edge (latest)
  • Firefox (latest)
  • Safari (latest)

License

MIT

Contributing

Contributions are welcome! Please open an issue or PR.