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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@saichandan181/reusable-grid

v2.2.7

Published

A highly flexible and reusable grid component with Unisys design system, AI assistant with full-context analysis, pagination, search, sorting, and export capabilities. Fully themeable with 80+ CSS variables - customize colors, icons, fonts, spacing, and b

Readme

Unisys Reusable Grid

A powerful, flexible, and feature-rich React data grid component with built-in AI Assistant. Send raw grid data directly to any LLM for intelligent analysis. Perfect for displaying, analyzing, and managing datasets efficiently.

npm version npm downloads License: MIT


Features

  • AI Assistant - Send complete grid data to any LLM (OpenAI, Anthropic, Google Gemini, etc.) for intelligent analysis
  • Professional UI - Clean design with Lucide React icons and proper Markdown formatting
  • Direct LLM Integration - No complex setup, just send raw data to your preferred AI provider
  • Pagination - Navigate through data with configurable page sizes (10, 25, 50, 100)
  • Row Selection - Select individual rows or all rows at once
  • CRUD Operations - View, Edit, Delete functionality built-in
  • JSON Upload - Easy data import from JSON files
  • Export Data - Export to JSON, CSV, or Excel formats
  • Search - Filter data across all columns
  • Customizable Styling - Easily customize colors, fonts, and appearance
  • TypeScript Support - Full type definitions included
  • Responsive Design - Works on desktop, tablet, and mobile devices

Installation

npm install @saichandan181/reusable-grid

Required Dependencies

The package has the following peer dependencies:

npm install react react-dom

For AI Assistant features, you'll also need:

npm install @google/generative-ai

(Or use your preferred LLM provider's SDK)


Quick Start

Basic Grid Usage

import React, { useState } from 'react';
import { UnisysGrid } from '@saichandan181/reusable-grid';

function App() {
  const [data, setData] = useState([
    { id: 1, name: 'John Doe', email: '[email protected]', age: 30 },
    { id: 2, name: 'Jane Smith', email: '[email protected]', age: 25 },
    { id: 3, name: 'Bob Johnson', email: '[email protected]', age: 35 },
  ]);

  const columns = [
    { key: 'id', label: 'ID' },
    { key: 'name', label: 'Name' },
    { key: 'email', label: 'Email' },
    { key: 'age', label: 'Age' },
  ];

  return (
    <div style={{ padding: '20px' }}>
      <UnisysGrid
        data={data}
        columns={columns}
        onEdit={(row) => console.log('Edit:', row)}
        onDelete={(row) => console.log('Delete:', row)}
        onView={(row) => console.log('View:', row)}
      />
    </div>
  );
}

export default App;

Components

1. UnisysGrid

The main grid component for displaying tabular data.

Props

interface UnisysGridProps {
  data: GridRow[];                    // Array of data objects
  columns: Column[];                  // Column definitions
  onEdit?: (row: GridRow) => void;    // Edit callback
  onDelete?: (row: GridRow) => void;  // Delete callback
  onView?: (row: GridRow) => void;    // View callback
  onRowClick?: (row: GridRow) => void; // Row click callback
  enableSelection?: boolean;           // Enable row selection (default: false)
  customStyles?: {
    headerBackgroundColor?: string;
    headerTextColor?: string;
    rowBackgroundColor?: string;
    rowHoverBackgroundColor?: string;
    borderColor?: string;
  };
}

Example with Customization

import { UnisysGrid } from '@saichandan181/reusable-grid';

function MyGrid() {
  const data = [
    { id: 1, product: 'Laptop', price: 999, stock: 50 },
    { id: 2, product: 'Mouse', price: 25, stock: 200 },
    { id: 3, product: 'Keyboard', price: 75, stock: 100 },
  ];

  const columns = [
    { key: 'id', label: 'ID' },
    { key: 'product', label: 'Product Name' },
    { key: 'price', label: 'Price ($)' },
    { key: 'stock', label: 'In Stock' },
  ];

  const handleEdit = (row) => {
    console.log('Editing product:', row.product);
    // Open edit modal or form
  };

  const handleDelete = (row) => {
    if (window.confirm(`Delete ${row.product}?`)) {
      // Delete logic here
      console.log('Deleted:', row);
    }
  };

  return (
    <UnisysGrid
      data={data}
      columns={columns}
      onEdit={handleEdit}
      onDelete={handleDelete}
      onView={(row) => alert(JSON.stringify(row, null, 2))}
      enableSelection={true}
      customStyles={{
        headerBackgroundColor: '#003134',
        headerTextColor: '#FFFFFF',
        rowBackgroundColor: '#FFFFFF',
        rowHoverBackgroundColor: '#F3F4F6',
        borderColor: '#E5E7EB',
      }}
    />
  );
}

2. GridPagination

Pagination component for navigating through data.

Example

import { useState } from 'react';
import { UnisysGrid, GridPagination } from '@saichandan181/reusable-grid';

function PaginatedGrid() {
  const [data, setData] = useState([/* your data */]);
  const [currentPage, setCurrentPage] = useState(1);
  const [pageSize, setPageSize] = useState(10);

  const startIndex = (currentPage - 1) * pageSize;
  const endIndex = startIndex + pageSize;
  const paginatedData = data.slice(startIndex, endIndex);

  return (
    <div>
      <UnisysGrid
        data={paginatedData}
        columns={columns}
        onEdit={handleEdit}
        onDelete={handleDelete}
      />
      
      <GridPagination
        currentPage={currentPage}
        totalPages={Math.ceil(data.length / pageSize)}
        pageSize={pageSize}
        totalItems={data.length}
        onPageChange={setCurrentPage}
        onPageSizeChange={setPageSize}
      />
    </div>
  );
}

3. JsonDataUploader

Component for uploading JSON files.

Example

import { useState } from 'react';
import { JsonDataUploader, UnisysGrid } from '@saichandan181/reusable-grid';

function App() {
  const [data, setData] = useState([]);
  const [showUploader, setShowUploader] = useState(true);

  const handleDataLoaded = (uploadedData) => {
    setData(uploadedData);
    setShowUploader(false);
    console.log(`Loaded ${uploadedData.length} rows`);
  };

  return (
    <div>
      {showUploader && (
        <JsonDataUploader onDataLoaded={handleDataLoaded} />
      )}
      
      {data.length > 0 && (
        <UnisysGrid
          data={data}
          columns={Object.keys(data[0]).map(key => ({
            key,
            label: key.charAt(0).toUpperCase() + key.slice(1)
          }))}
        />
      )}
    </div>
  );
}

4. AIAssistant - LLM-Powered Data Analysis

Send your complete grid data directly to any LLM for intelligent analysis and insights.

Features

  • Send raw grid data to any LLM provider (OpenAI, Anthropic, Google Gemini, etc.)
  • Full dataset context for comprehensive analysis
  • Professional Markdown-formatted responses
  • Interactive chat interface
  • Automatic retry logic with exponential backoff
  • Quick suggestion buttons

Basic Example

import { useState } from 'react';
import { AIAssistant, JsonDataUploader } from '@saichandan181/reusable-grid';

function AIAnalysisApp() {
  const [data, setData] = useState([]);
  const [showAI, setShowAI] = useState(false);
  const [selectedRow, setSelectedRow] = useState(null);

  const handleDataLoaded = (uploadedData) => {
    setData(uploadedData);
  };

  const handleRowAI = (row) => {
    setSelectedRow(row);
    setShowAI(true);
  };

  return (
    <div>
      <JsonDataUploader onDataLoaded={handleDataLoaded} />
      
      {data.length > 0 && (
        <button onClick={() => handleRowAI(data[0])}>
          Analyze with AI
        </button>
      )}

      {showAI && selectedRow && (
        <AIAssistant
          row={selectedRow}
          allData={data}
          apiKey={process.env.REACT_APP_GEMINI_API_KEY}
          onClose={() => setShowAI(false)}
        />
      )}
    </div>
  );
}

Example Queries You Can Ask

// After opening AIAssistant, you can ask:

"Summarize this record"
"Compare this record with others in the dataset"
"What are the trends across all records?"
"Find similar records to this one"
"What makes this record unique?"
"Show me statistics for all records"
"Identify any anomalies or outliers"
"Analyze patterns in the data"

AIAssistant Props

interface AIAssistantProps {
  row: GridRow;           // Current selected row (required)
  allData: GridRow[];     // Complete dataset for context (required)
  apiKey: string;         // Your LLM API key (required)
  onClose: () => void;    // Close callback (required)
}

Complete Application Example

Here's a full application combining all features:

import React, { useState } from 'react';
import {
  UnisysGrid,
  GridPagination,
  JsonDataUploader,
  AIAssistant,
  useGridData,
} from '@saichandan181/reusable-grid';
import './App.css';

function App() {
  // State management
  const [showUploader, setShowUploader] = useState(true);
  const [showAI, setShowAI] = useState(false);
  const [selectedRow, setSelectedRow] = useState(null);
  
  // Use the grid data hook
  const {
    data,
    setData,
    currentPage,
    setCurrentPage,
    pageSize,
    setPageSize,
    searchTerm,
    setSearchTerm,
    filteredData,
    paginatedData,
    totalPages,
  } = useGridData([]);

  // Handle JSON upload
  const handleDataLoaded = (uploadedData) => {
    setData(uploadedData);
    setShowUploader(false);
    alert(`Successfully loaded ${uploadedData.length} rows!`);
  };

  // Generate columns from data
  const columns = data.length > 0
    ? Object.keys(data[0]).map(key => ({
        key,
        label: key.charAt(0).toUpperCase() + key.slice(1).replace(/([A-Z])/g, ' $1'),
      }))
    : [];

  // CRUD operations
  const handleEdit = (row) => {
    console.log('Edit:', row);
    // Implement edit logic
  };

  const handleDelete = (row) => {
    if (window.confirm('Are you sure you want to delete this row?')) {
      setData(data.filter(item => item.id !== row.id));
    }
  };

  const handleView = (row) => {
    setSelectedRow(row);
    alert(JSON.stringify(row, null, 2));
  };

  return (
    <div className="App">
      <header>
        <h1>Data Grid with AI Assistant</h1>
        <p>Upload JSON, view data, and analyze with AI</p>
      </header>

      {/* JSON Uploader */}
      {showUploader && (
        <JsonDataUploader onDataLoaded={handleDataLoaded} />
      )}

      {/* Main Content */}
      {data.length > 0 && (
        <>
          {/* Action Buttons */}
          <div style={{ marginBottom: '20px' }}>
            <button onClick={() => setShowUploader(true)}>
              Upload New Data
            </button>
            <button onClick={() => data.length > 0 && setShowAI(true)}>
              Analyze with AI
            </button>
            <button onClick={() => {
              const json = JSON.stringify(data, null, 2);
              const blob = new Blob([json], { type: 'application/json' });
              const url = URL.createObjectURL(blob);
              const a = document.createElement('a');
              a.href = url;
              a.download = 'data.json';
              a.click();
            }}>
              Export JSON
            </button>
          </div>

          {/* Search */}
          <input
            type="text"
            placeholder="Search..."
            value={searchTerm}
            onChange={(e) => setSearchTerm(e.target.value)}
            style={{
              padding: '10px',
              marginBottom: '20px',
              width: '300px',
              border: '1px solid #ccc',
              borderRadius: '4px',
            }}
          />

          {/* Grid */}
          <UnisysGrid
            data={paginatedData}
            columns={columns}
            onEdit={handleEdit}
            onDelete={handleDelete}
            onView={handleView}
            onRowClick={(row) => setSelectedRow(row)}
            enableSelection={true}
            customStyles={{
              headerBackgroundColor: '#003134',
              headerTextColor: '#FFFFFF',
              rowHoverBackgroundColor: '#F3F4F6',
            }}
          />

          {/* Pagination */}
          <GridPagination
            currentPage={currentPage}
            totalPages={totalPages}
            pageSize={pageSize}
            totalItems={filteredData.length}
            onPageChange={setCurrentPage}
            onPageSizeChange={(newSize) => {
              setPageSize(newSize);
              setCurrentPage(1);
            }}
          />
        </>
      )}

      {/* AI Assistant */}
      {showAI && selectedRow && (
        <AIAssistant
          row={selectedRow}
          allData={data}
          apiKey={process.env.REACT_APP_GEMINI_API_KEY || ''}
          onClose={() => setShowAI(false)}
        />
      )}
    </div>
  );
}

export default App;

Custom Styling

Theme Customization

const customTheme = {
  headerBackgroundColor: '#1e3a8a',  // Dark blue header
  headerTextColor: '#ffffff',         // White text
  rowBackgroundColor: '#ffffff',      // White rows
  rowHoverBackgroundColor: '#eff6ff', // Light blue hover
  borderColor: '#e5e7eb',             // Light gray borders
};

<UnisysGrid
  data={data}
  columns={columns}
  customStyles={customTheme}
/>

Custom CSS

/* Override grid styles */
.unisys-grid {
  font-family: 'Arial', sans-serif;
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.unisys-grid th {
  font-weight: 600;
  text-transform: uppercase;
  font-size: 12px;
}

.unisys-grid td {
  padding: 12px;
}

/* Custom button styles */
.unisys-grid button {
  margin: 0 4px;
  padding: 6px 12px;
  border-radius: 4px;
  transition: all 0.2s;
}

.unisys-grid button:hover {
  transform: translateY(-1px);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}

Hooks

useGridData

A custom hook for managing grid state.

import { useGridData } from '@saichandan181/reusable-grid';

function MyComponent() {
  const {
    data,              // Current data array
    setData,           // Update data
    currentPage,       // Current page number
    setCurrentPage,    // Change page
    pageSize,          // Items per page
    setPageSize,       // Change page size
    searchTerm,        // Search query
    setSearchTerm,     // Update search
    filteredData,      // Data after search filter
    paginatedData,     // Data for current page
    totalPages,        // Total number of pages
  } = useGridData(initialData);

  return (
    <div>
      {/* Use the values */}
      <p>Showing {paginatedData.length} of {filteredData.length} items</p>
    </div>
  );
}

TypeScript Support

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

import {
  GridRow,
  GridColumn,
  UnisysGridProps,
  GridPaginationProps,
  UseGridDataOptions,
} from '@saichandan181/reusable-grid';

// Define your data type
interface TeamData extends GridRow {
  id: number;
  teamName: string;
  budget: number;
  members: number;
  status: 'active' | 'inactive';
}

// Use with type safety
const data: TeamData[] = [
  { id: 1, teamName: 'Team A1', budget: 100000, members: 5, status: 'active' },
];

const columns: Column[] = [
  { key: 'teamName', label: 'Team Name' },
  { key: 'budget', label: 'Budget' },
];

API Key Setup

For RAG AI features, you need a Google Gemini API key.

Get Your API Key

  1. Go to Google AI Studio
  2. Create a new API key
  3. Add it to your project

Environment Variable (Recommended)

Create a .env file:

REACT_APP_GEMINI_API_KEY=your_api_key_here

Then use it:

<JsonRAG
  data={data}
  apiKey={process.env.REACT_APP_GEMINI_API_KEY || ''}
  // ... other props
/>

RAG AI Technical Details

How It Works

  1. Indexing: When you load data, all rows are converted to text and embedded
  2. Query: When you ask a question, it's also embedded
  3. Retrieval: Hybrid search finds the most relevant rows (semantic + keyword matching)
  4. Generation: Only the top relevant rows are sent to Gemini AI
  5. Response: AI analyzes and answers based on retrieved data

Embedding Options

Local Embeddings (Default - Free)

<JsonRAG
  embeddingProvider="local"  // Runs in browser, no API calls
  data={data}
  apiKey={apiKey}
/>
  • Free and fast
  • Runs entirely in browser
  • No additional API costs
  • Good for most use cases

Cloud Embeddings (Gemini)

<JsonRAG
  embeddingProvider="gemini"  // Uses Gemini Embedding API
  data={data}
  apiKey={apiKey}
/>
  • More accurate embeddings
  • Requires API calls for indexing
  • Better for complex semantic search

Token Efficiency

Traditional approach: Send all 500 rows = 35,000 tokens ❌
RAG approach: Send top 20 relevant rows = 1,400 tokens ✅
Savings: 25x reduction!


Browser Support

  • Chrome/Edge: ✅ Full support
  • Firefox: ✅ Full support
  • Safari: ✅ Full support
  • Mobile browsers: ✅ Responsive design

Styling and Branding

Custom Branding for Client Applications

Perfect for App Development Teams & Service Providers

The grid is designed for easy customization, making it ideal for development teams building applications for multiple clients. Apply client-specific branding without modifying the package source code.

🎨 NEW in v2.1.0: 80+ CSS Variables for Complete Theming

The package now includes 80+ CSS variables for comprehensive theme control:

  • All icon colors overridable (17+ icon-specific variables)
  • Full color control (grid, headers, rows, buttons, modals)
  • Typography customization (font families, sizes)
  • Spacing control (padding, margins, gaps)
  • Border radius (all corner rounding)
  • Dynamic theme switching support
  • Multi-tenant ready (per-client branding)

📚 Complete Documentation: See CSS_VARIABLES_GUIDE.md for:

  • Complete list of all 80+ CSS variables
  • Icon color customization table
  • 4 pre-built theme examples (Dark Mode, Corporate, Healthcare)
  • Dynamic theme switching code examples
  • Multi-tenant implementation strategies
  • Testing checklist and best practices

Quick Start: Override Icon Colors

/* Override all icon colors at once */
:root {
  --unisys-icon-color: #0066CC;              /* Grid action icons */
  --grid-search-icon-color: #0066CC;         /* Search icon */
  --grid-pagination-icon-color: #0066CC;     /* Pagination arrows */
  --ai-assistant-title-icon: #00A86B;        /* AI assistant icon */
  --json-uploader-icon-color: #0066CC;       /* Upload icon */
}

Quick Start: Apply a Complete Theme

/* Dark Mode Theme */
:root {
  --unisys-grid-bg: #1F2937;
  --unisys-grid-header-bg: #111827;
  --unisys-grid-row-bg: #374151;
  --unisys-icon-color: #9CA3AF;
  --unisys-text-color: #F9FAFB;
  --unisys-primary-color: #3B82F6;
}
/* Corporate Blue/Gold Theme */
:root {
  --unisys-primary-color: #0052CC;
  --unisys-accent-color: #FFAB00;
  --unisys-icon-color: #0052CC;
  --unisys-grid-header-bg: #0052CC;
  --unisys-grid-header-text: #FFFFFF;
}

See CSS_VARIABLES_GUIDE.md for more themes and complete variable reference.


🎨 Branding Customization Methods

Method 1: CSS Variables Override (Recommended ⭐ NEW)

Override CSS variables in your application's CSS file for instant theming:

/* client-branding.css */

/* Override Primary Brand Colors */
:root {
  --unisys-primary-color: #0066CC;        /* Your client's primary color */
  --unisys-primary-hover: #0052A3;        /* Darker shade for hover states */
  --unisys-accent-color: #00A86B;         /* Accent color */
  
  /* Override Icon Colors */
  --unisys-icon-color: #0066CC;           /* All grid icons */
  --unisys-icon-hover: #0052A3;           /* Icon hover state */
  --grid-search-icon-color: #0066CC;      /* Search icon */
  --ai-assistant-title-icon: #00A86B;     /* AI icon */
  
  /* Override Grid Colors */
  --unisys-grid-bg: #FFFFFF;
  --unisys-grid-header-bg: #F3F4F6;
  --unisys-grid-row-hover-bg: #E6F2FF;
  
  /* Override Checkbox Colors */
  --unisys-checkbox-checked-bg: #0066CC;
  --unisys-checkbox-checked-icon: #FFFFFF;
  
  /* Override Typography */
  --unisys-font-family: 'Inter', sans-serif;
  --unisys-font-size-base: 14px;
}

Benefits of CSS Variables:

  • ✅ Override any color without touching source code
  • ✅ Change entire theme with a few lines
  • ✅ Dynamic theme switching at runtime
  • ✅ Per-component or global overrides
  • ✅ No rebuild required

Method 1b: Legacy CSS Class Override

You can still override specific CSS classes (previous method):

/* client-branding.css */

/* Primary Brand Colors */
.unisys-grid-container {
  --primary-color: #0066CC;        /* Your client's primary color */
  --primary-hover: #0052A3;        /* Darker shade for hover states */
  --primary-light: #E6F2FF;        /* Light background */
  --secondary-color: #00A86B;      /* Accent color */
}

/* Override specific elements */
.unisys-grid {
  border: 1px solid var(--primary-color);
}

.unisys-grid-header {
  background-color: var(--primary-light);
}

.unisys-grid-header-cell {
  color: var(--primary-color);
}

.unisys-grid-row:hover {
  background-color: var(--primary-light);
}

.unisys-grid-row-selected {
  background-color: var(--secondary-color) !important;
}

/* Checkbox colors */
.unisys-checkbox-box {
  border-color: var(--primary-color);
}

.unisys-checkbox-box.checked {
  background-color: var(--primary-color);
}

/* Action buttons */
.unisys-action-button {
  color: var(--primary-color);
}

.unisys-action-button:hover {
  background-color: var(--primary-light);
  color: var(--primary-hover);
}

/* AI Assistant branding */
.ai-assistant-header {
  background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
}

.ai-assistant-title h2 {
  color: #ffffff;
}

.ai-message-user {
  background-color: var(--primary-color);
}

Usage in your application:

import '@saichandan181/reusable-grid/dist/index.css';
import './client-branding.css';  // Your custom branding

function App() {
  return <EnhancedUnisysGrid {...props} />;
}

Method 2: Inline Styles with className

Apply custom classes to the grid container:

<EnhancedUnisysGrid
  className="client-acme-branding"
  data={data}
  columns={columns}
/>
/* client-acme-branding.css */
.client-acme-branding .unisys-grid-header {
  background-color: #FF6B35;  /* ACME Corp orange */
}

.client-acme-branding .unisys-grid-row:hover {
  background-color: #FFF0E8;
}

Method 3: Dynamic Theme Switching

For multi-tenant applications, switch themes dynamically:

import { useState } from 'react';

function App() {
  const [theme, setTheme] = useState('client-a');

  const applyTheme = (themeName) => {
    setTheme(themeName);
    // Dynamically load theme CSS or apply inline styles
  };

  return (
    <div className={`app-container theme-${theme}`}>
      <button onClick={() => applyTheme('client-a')}>Client A Theme</button>
      <button onClick={() => applyTheme('client-b')}>Client B Theme</button>
      
      <EnhancedUnisysGrid
        data={data}
        columns={columns}
      />
    </div>
  );
}
/* themes.css */

/* Client A - Blue theme */
.theme-client-a .unisys-grid-header {
  background-color: #0066CC;
}
.theme-client-a .unisys-checkbox-box.checked {
  background-color: #0066CC;
}

/* Client B - Green theme */
.theme-client-b .unisys-grid-header {
  background-color: #00A86B;
}
.theme-client-b .unisys-checkbox-box.checked {
  background-color: #00A86B;
}

📋 Brandable Components

All these elements can be customized with your client's branding:

Grid Components:

  • Header background & text colors
  • Row hover & selected states
  • Border colors
  • Checkbox colors & states
  • Action button colors
  • Pagination controls
  • Search input styling

AI Assistant:

  • Modal header gradient
  • User message bubbles
  • Assistant message styling
  • Button colors
  • Loading indicators

Export & Upload:

  • Button styles
  • Dropdown menus
  • File upload areas

🎨 Complete Branding Example

Here's a full example for a fictional client "TechCorp":

/* techcorp-branding.css */

:root {
  --techcorp-primary: #6366F1;      /* Indigo */
  --techcorp-secondary: #10B981;    /* Green */
  --techcorp-accent: #F59E0B;       /* Amber */
  --techcorp-dark: #1F2937;         /* Dark gray */
  --techcorp-light: #F3F4F6;        /* Light gray */
}

/* Grid container */
.techcorp-grid .unisys-grid {
  border: 2px solid var(--techcorp-primary);
  border-radius: 12px;
}

/* Header */
.techcorp-grid .unisys-grid-header {
  background: linear-gradient(135deg, var(--techcorp-primary), var(--techcorp-secondary));
}

.techcorp-grid .unisys-grid-header-cell {
  color: #ffffff;
  font-weight: 600;
}

/* Rows */
.techcorp-grid .unisys-grid-row:hover {
  background-color: #EEF2FF;
  transform: scale(1.01);
  transition: all 0.2s ease;
}

.techcorp-grid .unisys-grid-row-selected {
  background-color: #DDD6FE !important;
  border-left: 4px solid var(--techcorp-primary);
}

/* Checkboxes */
.techcorp-grid .unisys-checkbox-box {
  border: 2px solid var(--techcorp-primary);
  border-radius: 6px;
}

.techcorp-grid .unisys-checkbox-box.checked {
  background-color: var(--techcorp-primary);
}

/* Action buttons */
.techcorp-grid .unisys-action-button {
  color: var(--techcorp-primary);
  border-radius: 8px;
  padding: 8px 12px;
}

.techcorp-grid .unisys-action-button:hover {
  background-color: var(--techcorp-primary);
  color: #ffffff;
}

/* AI Assistant */
.techcorp-grid .ai-assistant-header {
  background: linear-gradient(135deg, var(--techcorp-primary), var(--techcorp-accent));
}

.techcorp-grid .ai-message-user {
  background-color: var(--techcorp-primary);
  border-radius: 18px 18px 4px 18px;
}

.techcorp-grid .ai-message-assistant {
  background-color: var(--techcorp-light);
  border-left: 4px solid var(--techcorp-secondary);
}

/* Pagination */
.techcorp-grid .grid-pagination-button-active {
  background-color: var(--techcorp-primary);
  color: #ffffff;
}

/* Search */
.techcorp-grid .grid-search-input:focus {
  border-color: var(--techcorp-primary);
  box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);
}

Apply the theme:

<EnhancedUnisysGrid
  className="techcorp-grid"
  data={data}
  columns={columns}
/>

🔧 CSS Class Reference

Here are all the CSS classes you can target for branding:

Grid Structure:
├── .unisys-grid-container
├── .unisys-grid
├── .unisys-grid-header
├── .unisys-grid-header-cell
├── .unisys-grid-body
├── .unisys-grid-row
├── .unisys-grid-row-selected
├── .unisys-grid-row-even / .unisys-grid-row-odd
└── .unisys-grid-cell

Checkboxes:
├── .unisys-checkbox-wrapper
├── .unisys-checkbox-box
├── .unisys-checkbox-box.checked
└── .checkbox-icon

Actions:
├── .unisys-grid-actions
└── .unisys-action-button

AI Assistant:
├── .ai-assistant-overlay
├── .ai-assistant-modal
├── .ai-assistant-header
├── .ai-assistant-messages
├── .ai-message-user
├── .ai-message-assistant
└── .ai-assistant-input

Enhanced Grid:
├── .enhanced-grid-container
├── .enhanced-grid-toolbar
├── .enhanced-grid-export-button
└── .enhanced-grid-selected-count

Pagination:
├── .grid-pagination-container
├── .grid-pagination-button
└── .grid-pagination-button-active

Search:
├── .grid-search-container
└── .grid-search-input

💡 Best Practices for Client Branding

  1. Use CSS Variables - Easier to maintain and switch themes
  2. Scope Your Styles - Use unique class names per client to avoid conflicts
  3. Test Accessibility - Ensure sufficient color contrast (WCAG AA minimum)
  4. Document Themes - Keep a theme guide for each client
  5. Version Control - Store client themes separately from app code
  6. Performance - Keep custom CSS minimal, reuse variables

🚀 Quick Start for Development Teams

# 1. Install the package
npm install @saichandan181/reusable-grid

# 2. Create a themes folder in your project
mkdir src/themes

# 3. Create client-specific CSS files
src/themes/
  ├── client-a.css
  ├── client-b.css
  └── client-c.css

# 4. Import based on client context
import '@saichandan181/reusable-grid/dist/index.css';
import `./themes/${clientName}.css`;

📦 Multi-Tenant Application Example

import { useEffect } from 'react';

function App() {
  const clientId = useClientId(); // Your tenant identification logic

  useEffect(() => {
    // Dynamically load client theme
    const link = document.createElement('link');
    link.rel = 'stylesheet';
    link.href = `/themes/${clientId}.css`;
    document.head.appendChild(link);

    return () => {
      document.head.removeChild(link);
    };
  }, [clientId]);

  return (
    <EnhancedUnisysGrid
      data={data}
      columns={columns}
    />
  );
}

Result: Same grid component, different visual identity per client! 🎨


Performance

  • Large Datasets: Handles 1000+ rows smoothly with pagination
  • RAG Indexing: Fast local embeddings (500 rows in ~2-3 seconds)
  • Search: Instant filtering across all columns
  • Memory: Efficient data handling with virtualization support

Changelog

See CHANGELOG.md for version history and updates.

Latest: v1.2.4

  • Fixed Markdown rendering in AI responses
  • Professional UI with Lucide React icons
  • Hybrid search for better retrieval accuracy
  • Improved local embeddings

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.


License

MIT © Sai Chandan


Support


Keywords

react grid table data-grid rag ai gemini retrieval-augmented-generation semantic-search hybrid-search pagination crud json csv excel export typescript embeddings vector-search large-datasets data-analysis


Made with ❤️ for the React community