JSPM

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

A powerful, themeable expression builder for creating complex filter logic

Package Exports

  • @aftui/expresso
  • @aftui/expresso/dist/index.css
  • @aftui/expresso/dist/index.css.map
  • @aftui/expresso/dist/index.d.mts
  • @aftui/expresso/dist/index.d.ts
  • @aftui/expresso/dist/index.js
  • @aftui/expresso/dist/index.js.map
  • @aftui/expresso/dist/index.mjs
  • @aftui/expresso/dist/index.mjs.map
  • @aftui/expresso/package.json
  • @aftui/expresso/styles
  • @aftui/expresso/styles.css

Readme

Expresso

A powerful, themeable expression builder for creating complex filter logic 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 @aftui/expresso
# or
yarn add @aftui/expresso
# or
pnpm add @aftui/expresso

Peer Dependencies

This package requires React 19+ and several peer dependencies:

npm install react react-dom sonner lucide-react @radix-ui/react-dropdown-menu @radix-ui/react-label @radix-ui/react-popover @radix-ui/react-select @radix-ui/react-switch

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 */}
    </>
  );
}

Styling

Expresso uses Vanilla Extract for styling, providing a zero-runtime CSS-in-JS solution. All styles are bundled with the component, so no additional setup is required.

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 {
  Expresso,
  type JoinKeyExpression,
  type DropdownItem
} from '@aftui/expresso';
import { Toaster } from 'sonner';

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 (
    <>
      <Toaster />
      <Expresso
        fields={fields}
        onApply={handleApply}
        onCancel={() => console.log('Cancelled')}
      />
    </>
  );
}

Theming

Using Default Theme

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

Using Dark Theme

import { Expresso, darkTheme } from '@aftui/expresso';

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

Custom Theme

import {
  Expresso,
  type FilterBuilderThemeConfig
} from '@aftui/expresso';

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",
};

<Expresso
  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 '@aftui/expresso';

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

  return (
      <Expresso {...props} />
  );
}

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,
  OperatorConfig,
} from '@aftui/expresso';

Backward Compatibility

For backward compatibility, the AdvancedFilterBuilder component name is also exported as an alias to Expresso. However, we recommend using Expresso for new projects:

// New (recommended)
import { Expresso } from '@aftui/expresso';

// Old (still works)
import { AdvancedFilterBuilder } from '@aftui/expresso';

Browser Support

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

Repository

License

MIT

Contributing

Contributions are welcome! Please open an issue or pull request at the GitHub repository.