npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@shefing/quickfilter

v1.0.92

Published

⚡ **Lightning-fast and intuitive filtering that your users will love!**

Readme

🚀 QuickFilter Plugin for PayloadCMS

Lightning-fast and intuitive filtering that your users will love!

Transform your PayloadCMS admin experience with instant, intuitive filters that appear right where you need them. Say goodbye to clunky filter forms and welcome to seamless data exploration!

✨ Features

| Feature | Description | Icon | | ---------------------------- | -------------------------------------------------- | -------------------------------------------------------------------- | | ⚡ Instant Filtering | Apply filters immediately without page reloads | Instant | | 🎛️ Multiple Filter Types | Date, select, checkbox, and small select filters | Types | | 📱 Responsive Layout | Configurable row-based layout with custom widths | Responsive | | 🌍 Internationalization | Full i18n support with RTL language compatibility | i18n | | 📅 Smart Date Filtering | Predefined ranges + custom date picker | Dates |

🎥 See It In Action

https://github.com/user-attachments/assets/e609ca50-26fc-46c3-98fe-1651d2bacc7b


📋 Requirements

  • ✅ PayloadCMS 3.0+
  • ✅ React 18+
  • ✅ TypeScript (recommended)
  • ✅ Tailwind CSS (for styling)

🚨 Important: Make sure your project has Tailwind CSS configured, as the plugin uses Tailwind classes for styling. Add the following path to your tailwind.config.js under the content array:

// tailwind.config.js

module.exports = {
  content: [
    './src/**/*.{js,ts,jsx,tsx}', // your app paths
    './node_modules/@shefing/quickfilter/**/*.{js,ts,jsx,tsx}', // ✅ required for QuickFilter
  ],
  // ...rest of your config
  // Here we scope the Tailwind not to intefere with the Admin UI  
    plugins: [
        scopedPreflightStyles({
            isolationStrategy: isolateInsideOfContainer(['.useTw']),
        }),
    ],
};

⚡ Quick Start (2 minutes!)

pnpm add @shefing/quickfilter
// payload.config.ts

import { CollectionQuickFilterPlugin } from '@shefing/quickfilter';

export default buildConfig({
  plugins: [CollectionQuickFilterPlugin({})],
});
export const Users: CollectionConfig = {
  slug: 'users',
  custom: {
    filterList: [
      ['status', 'role'], // First row with two filters
      ['createdAt'], // Second row with one filter
      [
        { name: 'department', width: '300px' }, // Custom width
        'isActive',
      ],
      // 🆕 Virtual field example (Payload 3.56.0+)
      { name: 'orders.status', width: '250px' }, // ⚡ Using "collectionName.fieldName" format
    ],
  },
  // ... rest of your collection config
};

⚙️ Collections Configuration

Transform any collection into a filtering powerhouse! Just add a filterList to your collection's custom property:

export const Users: CollectionConfig = {
  slug: 'users',
  custom: {
    filterList: [
      ['status', 'role'], // First row with two filters
      ['createdAt'], // Second row with one filter
      [
        { name: 'department', width: '300px' }, // Custom width
        'isActive',
      ],
    ],
  },
  fields: [
    {
      name: 'status',
      type: 'select',
      options: [
        { label: 'Active', value: 'active' },
        { label: 'Inactive', value: 'inactive' },
      ],
    },
    {
      name: 'role',
      type: 'select',
      options: [
        { label: 'Admin', value: 'admin' },
        { label: 'User', value: 'user' },
        { label: 'Editor', value: 'editor' },
      ],
    },
    {
      name: 'createdAt',
      type: 'date',
    },
    {
      name: 'isActive',
      type: 'checkbox',
    },
  ],
};

🎨 Filter Configuration Options

📐 Row Layout Magic

filterList: [
  // 🔥 Mix and match however you want!
  ['status', 'role', 'department'], // 3 filters in one row
  ['createdAt'], // Single filter gets full width
  [{ name: 'tags', width: '400px' }], // Custom width for long lists
  ['isActive', 'isVerified'], // Two checkboxes side by side
];

| Format | Example | Result | | ---------------- | ------------------------------------------------ | ---------------------------- | | 📝 String | 'fieldName' | Default width (230px) | | 🎛️ Object | { name: 'field', width: '300px' } | Custom width | | 📊 Mixed Row | ['field1', { name: 'field2', width: '400px' }] | Different widths in same row |

🎯 Supported Field Types

{
  name: 'createdAt',
  type: 'date'
}

✨ What you get:

  • 🕐 Predefined time ranges: Yesterday, Last Week, Last Month, Last 7 Days, Last 30 Days, Last Year, Last 2 Years, All Past
  • 🔮 Future options: Today, This Week, This Month, Next 7 Days, Next 30 Days, Today And Future, All Future
  • 🎯 Custom range: Pick any from/to dates
  • 🌍 Localized: Date formats adapt to user's language

Date Filter Preview

{
  name: 'status',
  type: 'select',
  options: [
    { label: 'Published', value: 'published' },
    { label: 'Draft', value: 'draft' },
    { label: 'Archived', value: 'archived' }
  ]
}

🧠 Smart behavior:

  • 🔘 ≤3 options: Compact button-style selector
  • 📝 >3 options: Full dropdown with search
  • Multi-select: Choose multiple values
  • 🔍 Search: Find options in large lists quickly

Select Filter Types

{
  name: 'isActive',
  type: 'checkbox'
}

🎛️ Three states:

  • Checked: Show only true values
  • Unchecked: Show only false values
  • Undefined: Show all (default)

Perfect for boolean fields like active/inactive, published/unpublished, etc.

🎮 Usage

🖥️ User Interface

The magic happens right above your collection table! Here's what your users will see:

┌─────────────────────────────────────┐
│ 🔍 Quick Filters                   │  ← Clean button when no filters active
└─────────────────────────────────────┘

┌─────────────────────────────────────┐
│ 🔍 2 Active filters: Status • Role │  ← Shows count and field names
└─────────────────────────────────────┘

Collapsed States

┌─────────────────────────────────────────────────────────────┐
│ 🔍 2 Active filters: Status • Role                      ❌ │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  Status ▼        Role ▼           Department ▼             │
│  [Published]     [Admin    ]      [Engineering    ]        │
│                                                             │
│  Created Date ▼                                            │
│  [Last Week ▼]                                             │
│                                                             │
└─────────────────────────────────────────────────────────────┘

✨ What users love:

  • 👀 Visual feedback: See exactly which filters are active
  • 🧹 One-click clear: Remove all filters instantly with the ❌ button
  • 💾 Persistent: Filters stay active when you refresh or navigate back
  • Instant results: Table updates immediately as you change filters

🎯 Filter Types in Detail

🧠 Smart Behavior:

// 🔘 Small lists (≤3 options) = Button style
[Active] [Inactive] [Pending]

// 📝 Large lists (>3 options) = Dropdown with search
┌─────────────────────────┐
│ 🔍 Search options...    │
├─────────────────────────┤
│ ✅ Published            │
│ ✅ Draft                │
│ ⬜ Archived             │
│ ⬜ Under Review         │
└─────────────────────────┘

Select Filter Types

🎛️ The Three States:

| State | Visual | Behavior | Use Case | | -------------------- | ------ | ------------------------ | -------------------------- | | ✅ Checked | [✓] | Show only true values | "Show only active users" | | ❌ Unchecked | [ ] | Show only false values | "Show only inactive users" | | ➖ Undefined | [-] | Show all values | "Show everyone" (default) |

Perfect for boolean fields like:

  • 🟢 Active/Inactive
  • 📝 Published/Unpublished
  • ✅ Verified/Unverified
  • 🔒 Public/Private

🆚 Why Choose QuickFilter Over Regular PayloadCMS Filters?

🚀 1. User Experience Revolution

| Aspect | QuickFilter Experience | Regular Filter Experience | | ----------------- | ------------------------------------------- | ------------------------------------------ | | 🎯 Simplicity | Click and filter | Navigate to filter page, fill form, submit | | ⚡ Speed | Instant results as you click | Wait for page reload every time | | 👀 Clarity | 🔍 3 Active filters: Status • Role • Date | Guess what filters are active |

2. Performance That Scales

🎯 What we support:

  • ⌨️ Full keyboard navigation: Tab through all filters
  • 🔊 Screen reader friendly: Proper ARIA labels and descriptions
  • 🌍 RTL languages: Native Hebrew/Arabic support
  • 🎨 High contrast: Works with accessibility themes
  • 📱 Touch friendly: Perfect for mobile and tablet users

🌍 Internationalization

🗣️ Built-in Language Support

The plugin speaks your users' language! Full translations included for:

| Language | Code | RTL Support | Status | | -------------- | ---- | ----------- | ----------- | | 🇺🇸 English | en | - | ✅ Complete | | 🇮🇱 Hebrew | he | ✅ Yes | ✅ Complete | | 🇸🇦 Arabic | ar | ✅ Yes | ✅ Complete | | 🇫🇷 French | fr | - | ✅ Complete | | 🇪🇸 Spanish | es | - | ✅ Complete | | 🇨🇳 Chinese | zh | - | ✅ Complete |

🔧 Adding Custom Languages

// In labels.ts, add your language
export const PLUGIN_LABELS = {
  // ... existing languages
  de: {
    quickFilters: 'Schnellfilter',
    clearFilters: 'Filter löschen',
    activeFilterSingular: 'Aktiver Filter auf Spalte',
    activeFilterPlural: 'Aktive Filter auf Spalten',
    custom: 'Benutzerdefiniert',
    all: 'Alle',
    yes: 'Ja',
    no: 'Nein',
    // ... add all other translations
  },
  ja: {
    quickFilters: 'クイックフィルター',
    clearFilters: 'フィルターをクリア',
    // ... Japanese translations
  },
};

🔧 Advanced Configuration

🎨 Custom Filter Widths

filterList: [
  [
    { name: 'longFieldName', width: '400px' }, // Wide for long option lists
    { name: 'shortField', width: '150px' }, // Narrow for simple fields
  ],
  [
    { name: 'description', width: '100%' }, // Full width for text fields
    'status', // Default width (230px)
  ],
];

📏 Width Options:

  • '150px' - Compact for simple fields
  • '230px' - Default width (when not specified)
  • '400px' - Wide for complex selects
  • '100%' - Full row width
  • '50%' - Half row width

🎛️ Conditional Plugin Loading

// Disable in development
CollectionQuickFilterPlugin({
  disabled: process.env.NODE_ENV === 'development',
});

// Enable only for specific environments
CollectionQuickFilterPlugin({
  disabled: !['production', 'staging'].includes(process.env.NODE_ENV),
});

// Feature flag support
CollectionQuickFilterPlugin({
  disabled: !process.env.ENABLE_QUICK_FILTERS,
});

🎯 Use Cases:

  • 🧪 Testing: Disable during development
  • 🚀 Gradual rollout: Enable for specific environments
  • 🎚️ Feature flags: Toggle via environment variables

🧭 Default Filter from navigation in both Navigator and Dashboard

The NavDefaultFilter/DashBoard component allows you to apply default filters to collection views directly from the navigation menu or the dashboard. This means users will see filtered data immediately when they click on a collection.

// payload.config.ts
export default buildConfig({
  admin: {
    components: {
      Nav: '@shefing/quickfilter/nav',
      views: {
        dashboard: {
          Component: '@shefing/quickfilter/Dashboard',
        },
      },
    },
  },
  // ... rest of your config
});

🎯 Collection Configuration Examples:

  1. Filter to show only today's and future meetings:
export const Meetings: CollectionConfig = {
  slug: 'meetings',
  custom: {
    defaultFilter: {
      'meetingDate': 'todayAndFuture'
    },
  },
  // ... rest of your collection config
};
  1. Filter to show only unhandled items:
export const Tasks: CollectionConfig = {
  slug: 'tasks',
  custom: {
    filterList: [['type', 'createdAt', 'meetingDate', 'holdingsLimit', 'handled', 'acquireTask']],
    defaultFilter: {
      'handled': {
        equals: false
      }
    }
  },
  // ... rest of your collection config
};

✨ Benefits:

  • 🎯 Context-aware navigation: Users see the most relevant data immediately
  • ⏱️ Time-saving: No need to manually apply filters after navigation
  • 🧠 Smart defaults: Configure different default views for different collections
  • 🔄 Consistent experience: Both Nav and Dashboard components are aligned with default filters for all collections

Contributing

The plugin is designed to be extensible. To add new filter types:

  1. Create a new component in filters/components/
  2. Add type definitions in filters/types/filters-type.ts
  3. Update FilterField.tsx to handle the new type
  4. Add translations in labels.ts

License

This plugin is licensed under the Apache License, Version 2.0.