npm package: @sk2you/react-filter-ui
Description: A React filter component with advanced filtering capabilities
Author: Your Name
Latest version: 1.0.2

# React Filter UI

A flexible React component library for building advanced filtering interfaces. This package provides a user-friendly UI for filtering data based on configurable schemas.

## Features

- Dynamic field selection based on schema
- Multiple filter logic options (equals, contains, greater than, etc.)
- Special input handling for dates, numbers, booleans, and references
- Edit and remove existing filters
- Theme customization through color hooks
- MongoDB-compatible query generation

## Installation

```bash
npm install @sk2you/react-filter-ui
```

or 

```bash
yarn add @sk2you/react-filter-ui
```

## Basic Usage

```jsx
import React, { useState, useCallback } from 'react';
import { Filter } from '@sk2you/react-filter-ui';

const MyDataTable = () => {
  // State for search parameters
  const [searchJson, setSearchJson] = useState({
    page: 1,
    limit: 10,
    search: {}
  });
  
  // State for pagination
  const [pagination, setPagination] = useState({
    page: 1,
    limit: 10,
    total: 0
  });
  
  // Define your data schema for filterable fields
  const filterSchema = [
    {
      serverKey: 'name',
      fieldLabel: 'Name',
      dbType: 'string',
      inputType: 'text',
      status: true,
      enabled: true,
      required: false
    },
    {
      serverKey: 'age',
      fieldLabel: 'Age',
      dbType: 'number',
      inputType: 'number',
      status: true,
      enabled: true,
      required: false
    },
    {
      serverKey: 'isActive',
      fieldLabel: 'Active',
      dbType: 'boolean',
      inputType: 'switch',
      status: true,
      enabled: true,
      required: false
    },
    {
      serverKey: 'createdAt',
      fieldLabel: 'Created Date',
      dbType: 'date',
      inputType: 'date',
      status: true,
      enabled: true,
      required: false
    }
  ];
  
  // Function to load data based on filters
  const loadData = useCallback((paginationParams, searchParams) => {
    // Make API call to your backend with the search parameters
    console.log('Loading data with:', paginationParams, searchParams);
    
    // Example API call:
    // api.fetchData(searchParams).then(response => {
    //   setData(response.data);
    //   setPagination({
    //     page: response.page,
    //     limit: response.limit,
    //     total: response.total
    //   });
    // });
  }, []);
  
  // Handle filter changes
  const handleFilterChange = useCallback((updatedSearchJson) => {
    // Prepare the formatted search JSON
    const formattedSearchJson = {
      page: 1, // Always reset to page 1 when filters change
      limit: pagination.limit || 10,
      search: (updatedSearchJson?.search || {})
    };
    
    // Move nested payload.search to top-level if needed
    if (updatedSearchJson?.payload?.search) {
      formattedSearchJson.search = updatedSearchJson.payload.search;
    }
    
    // Update the state
    setSearchJson(formattedSearchJson);
    
    // Schedule the API call (the loadData function will handle deduplication)
    loadData(formattedSearchJson, formattedSearchJson);
  }, [loadData, pagination.limit]);
  
  return (
    <div>
      <h1>My Data Table</h1>
      
      {/* Filter component */}
      {filterSchema.length > 0 && (
        <Filter
          schema={filterSchema}
          searchJson={searchJson}
          loadData={loadData}
          paginationData={pagination}
          collectionName="Users"
          onFilterChange={handleFilterChange}
        />
      )}
      
      {/* Your data table component goes here */}
      <div className="table-container">
        {/* Table implementation */}
      </div>
    </div>
  );
};

export default MyDataTable;
```

## API Reference

### Filter Component

| Prop | Type | Description |
|------|------|-------------|
| `schema` | Array | Array of field objects defining which fields can be filtered |
| `searchJson` | Object | Current search parameters object |
| `loadData` | Function | Function to call when filters change to reload data |
| `paginationData` | Object | Pagination parameters like page, limit, total |
| `collectionName` | String | Name of the collection/table being filtered (displayed in UI) |
| `onFilterChange` | Function | Callback when filters change |

### Schema Format

Each field in the schema array should have the following properties:

```js
{
  serverKey: 'fieldName',        // Field key in the database
  fieldLabel: 'Field Label',     // Human-readable label
  dbType: 'string',              // Data type: 'string', 'number', 'date', 'boolean', 'ref' 
  inputType: 'text',             // UI input type
  status: true,                  // Whether field is available
  enabled: true,                 // Whether field is enabled
  required: false                // Whether field is required
}
```

### Generated Query Format

The component generates MongoDB-compatible queries in the format:

```js
{
  page: 1,
  limit: 10,
  search: {
    $and: [
      { fieldName: { $eq: "value" } },
      { age: { $gte: 21 } }
      // More conditions...
    ]
  }
}
```

## Customizing Colors

The component uses the `useColors` hook to support theming. You can customize the colors by storing primaryColor and secondaryColor in localStorage:

```js
// Example to set custom colors
const userData = {
  userData: {
    primaryColor: { hex: '#4a90e2' },
    secondaryColor: { hex: '#ffffff' }
  }
};

localStorage.setItem('imzUser', JSON.stringify(userData));
```

## Advanced Features

### Using FilterUI directly

For more control, you can use the FilterUI component directly:

```jsx
import { FilterUI } from '@sk2you/react-filter-ui';

// ...

<FilterUI
  schema={transformedSchema}
  activeFilters={activeFilters}
  setActiveFilters={setActiveFilters}
  onFilterChange={handleFilterChange}
  searchJson={searchJson}
  loadData={loadData}
  paginationData={pagination}
/>
```

### Using the utility functions

```jsx
import { 
  buildMongoQuery, 
  buildCompoundQuery,
  getLogicOptions,
  needsSpecialValueHandling 
} from '@sk2you/react-filter-ui';

// Build a MongoDB query for a field
const query = buildMongoQuery('age', '$gte', 18, schema.schema.fields);

// Combine multiple queries
const queries = [
  { name: { $eq: 'John' } },
  { age: { $gte: 18 } }
];
const compoundQuery = buildCompoundQuery(queries);
```

## License

MIT