react-qif
TypeScript icon, indicating that this package has built-in type declarations

2.0.5 • Public • Published

🎯 Qif

Powerful filtering system for React.js applications

NPM Size GitHub contributors GitHub license PRs Welcome

✨ Features

  • 🔄 Centralized State System - Efficient application state management
  • 🎨 Headless UI - Flexible, unstyled components for full customization
  • 🧩 Composable Components - Build complex UIs with simple, reusable parts
  • 🔗 URL Sync - Built on nuqs for robust URL state management
  • 🛠️ Developer-Friendly API - Intuitive design for seamless development
  • Performance Optimized - Smooth handling of large datasets

📦 Installation

# Using npm
npm install react-qif nuqs

# Using yarn
yarn add react-qif nuqs

🚀 Quick Start

import { useFilters, FiltersProvider, useFiltersContext } from 'react-qif';
import { parseAsString } from 'nuqs';

type FiltersType = {
  search: string;
  category: string;
};

const App = () => {
  const filtersInstance = useFilters({
    parsers: {
      search: parseAsString.withDefault(''),
      category: parseAsString.withDefault('test')
    }
  });

  return (
    <FiltersProvider instance={filtersInstance}>
      <SearchFilter />
    </FiltersProvider>
  );
};

const SearchFilter = () => {
  const { getValue, setValue } = useFiltersContext<FiltersType>();

  return (
    <input
      value={getValue('search') || ''}
      onChange={(e) => setValue('search', e.target.value)}
    />
  );
};

🔧 Setup

1. Configure NuqsAdapter

For Next.js:

import { NuqsAdapter } from 'nuqs/adapters/next';

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <NuqsAdapter>{children}</NuqsAdapter>
      </body>
    </html>
  );
}

For React:

import { NuqsAdapter } from 'nuqs/adapters/react';

createRoot(document.getElementById('root')!).render(
  <StrictMode>
    <NuqsAdapter>
      <App />
    </NuqsAdapter>
  </StrictMode>
);

📚 API Reference

FiltersProvider Props

  • instance: Filter instance created by useFilters
  • children: React nodes

useFilters Hook Options

interface UseFiltersOptions<T extends FiltersValue> {
    syncWithSearchParams?: boolean;
    parsers: UseQueryStatesKeysMap<T>;
}

useFiltersContext Hook

Returns an object with the following methods:

  • register(name, defaultValue): Register a filter with default value
  • unregister(name): Remove a filter
  • setValue(name, value): Update filter value
  • getValue(name): Get current filter value
  • reset(): Reset all filters to defaults
  • isResetDisabled: Check if reset is available

🔄 Client-Side Filtering

Unlike nuqs, Qif also supports client-side filtering. By setting syncWithSearchParams to false, no parameters will be added to the URL. This is useful for temporary filters or when you don't want to persist the filter state in the URL.

Client-Side Example

const App = () => {
  const filtersInstance = useFilters({
    syncWithSearchParams: false, // Disable URL synchronization
    parsers: {
      search: parseAsString.withDefault(''),
      category: parseAsString.withDefault('all')
    }
  });

  return (
    <FiltersProvider instance={filtersInstance}>
      <ProductFilters />
      <ProductList />
    </FiltersProvider>
  );
};

const ProductFilters = () => {
  const { getValue, setValue } = useFiltersContext();

  return (
    <div className="filters">
      <input
        value={getValue('search') || ''}
        onChange={(e) => setValue('search', e.target.value)}
        placeholder="Search products..."
      />
      
      <select
        value={getValue('category') || 'all'}
        onChange={(e) => setValue('category', e.target.value)}
      >
        <option value="all">All Categories</option>
        <option value="electronics">Electronics</option>
        <option value="clothing">Clothing</option>
      </select>
    </div>
  );
};

const ProductList = () => {
  const { getValue } = useFiltersContext();
  const searchTerm = getValue('search') as string;
  const category = getValue('category') as string;

  // Filter your products based on searchTerm and category
  const filteredProducts = products.filter(product => {
    const matchesSearch = product.name.toLowerCase().includes(searchTerm.toLowerCase());
    const matchesCategory = category === 'all' || product.category === category;
    return matchesSearch && matchesCategory;
  });

  return (
    <div className="products">
      {filteredProducts.map(product => (
        <ProductCard key={product.id} product={product} />
      ))}
    </div>
  );
};

This example demonstrates:

  • Client-side filtering without URL parameter synchronization
  • Multiple filter types (search input and category select)
  • Real-time filtering of product list
  • Type-safe filter values with TypeScript

🤝 Contributing

Contributions, issues and feature requests are welcome! Feel free to check issues page.

📄 License

MIT © Hasan Ardestani

/react-qif/

    Package Sidebar

    Install

    npm i react-qif

    Weekly Downloads

    340

    Version

    2.0.5

    License

    MIT

    Unpacked Size

    11 kB

    Total Files

    7

    Last publish

    Collaborators

    • hsnards