npm package: @lettrlabs-software/lettrlabs-ui
Description: <div align="center">   <img src="https://img.shields.io/badge/React-18.2.0-blue.svg" alt="React Version" />   <img src="https://img.shields.io/badge/TypeScript-5.3.3-blue.svg" alt="TypeScript Version" />   <img src="https://img.shields.io/badge/Materia
Latest version: 0.0.265
Deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.

# lettrlabs-ui

<div align="center">
  <img src="https://img.shields.io/badge/React-18.2.0-blue.svg" alt="React Version" />
  <img src="https://img.shields.io/badge/TypeScript-5.3.3-blue.svg" alt="TypeScript Version" />
  <img src="https://img.shields.io/badge/Material%20UI-5.14.0-blue.svg" alt="Material UI Version" />
  <img src="https://img.shields.io/badge/Storybook-8.6.8-FF4785.svg" alt="Storybook Version" />
</div>
<br />
<div align="center">
  <img src="https://img.shields.io/badge/Status-Development-yellow.svg" alt="Status" />
  <img src="https://img.shields.io/badge/License-MIT-green.svg" alt="License" />
</div>

<br />

## 📋 Table of Contents

- [About](#-about)
- [Installation](#-installation)
- [Usage](#-usage)
- [Components](#-components)
- [Development](#-development)
- [Testing](#-testing)
- [Build](#-build)
- [Publishing to npm](#-publishing-to-npm)
- [Contributing](#-contributing)
- [License](#-license)

## 📖 About

Lettrui is a comprehensive React component library developed by Lettrlabs Software. Our mission is to provide modern, accessible, and high-quality UI components to accelerate web application development. Built with TypeScript and Material-UI, Lettrui offers a robust set of components designed for enterprise-grade applications.

### Key Features

- 🎨 **Material-UI Foundation**: Built on top of Material-UI for consistent design patterns
- 🔧 **TypeScript First**: Full TypeScript support with comprehensive type definitions
- 📱 **Responsive Design**: Mobile-first approach with responsive components
- ♿ **Accessibility**: WCAG compliant components with proper ARIA attributes
- 🎯 **Design System**: Consistent design tokens and CSS variables
- 📚 **Storybook Integration**: Comprehensive documentation and testing environment
- 🔄 **Data Conversion Utilities**: Built-in utilities for complex data transformations
- 🎛️ **Advanced Components**: Specialized components for complex UI patterns
- 🆕 **Recent Updates**: New components and enhanced functionality

## 🆕 Recent Updates

### New Components Added
- **HelpPopover**: Contextual help tooltips with 8 positioning options and smooth animations
- **EmptyState**: Clean empty state interface with call-to-action functionality
- **CardTypeSelector**: Card-based selector with gradient background and dropdown integration
- **Accordion**: Collapsible content sections with optional edit functionality
- **ReusableTable**: Comprehensive data table with pagination, sorting, status management, and actions
- **StatusDot**: Simple status indicator with colored dot and optional label
- **StatusSelector**: Interactive dropdown for status selection with custom icons and colors
- **Pagination**: Custom pagination component with alignment options and compact/full variants
- **Modal**: Comprehensive modal dialog with customizable actions and responsive design
- **CopyToClipboardField**: Input field with integrated copy-to-clipboard functionality and tooltip feedback
- **Toggle**: Custom toggle switch with specific styling for enabled, hovered, focused, and disabled states

### Enhanced Components
- **RoundedButton**: Now includes built-in PlusIcon support, replacing the deprecated PlusButton
- **FilterBuilder**: Updated to use RoundedButton with PlusIcon for better consistency
- **ReusableTable**: Enhanced with StatusSelector integration, custom pagination, and improved styling
- **Pagination**: Added alignment options (left/right) and improved responsive design
- **Drawer**: Enhanced with styled components, improved breadcrumb styling, and close button functionality
- **Design System**: Centralized font management with CSS variables

### Improvements
- ✅ **PlusButton Migration**: Seamlessly migrated to RoundedButton with PlusIcon
- ✅ **Tooltip Positioning**: Fixed positioning issues and added smooth transitions
- ✅ **Text Wrapping**: Automatic text wrapping for long tooltip messages
- ✅ **Font Consistency**: Unified font system across all components
- ✅ **Accessibility**: Enhanced keyboard navigation and ARIA support
- ✅ **StatusSelector Integration**: Seamlessly integrated into ReusableTable with custom icons
- ✅ **Custom Pagination**: Replaced Material-UI pagination with custom component
- ✅ **Icon Sizing**: Standardized icon sizes across StatusSelector (Active: 20px, Inactive/Testing: 24px)
- ✅ **Font Sizing**: Consistent 14px font size for status text across all components
- ✅ **Modal Component**: New comprehensive modal with customizable actions and responsive design
- ✅ **Drawer Enhancements**: Improved breadcrumb styling with proper color hierarchy and close button

## 🚀 Installation

```bash
npm install @lettrlabs-software/lettrui
```

or

```bash
yarn add @lettrlabs-software/lettrui
```

## 💻 Usage

```tsx
import { 
  Button, 
  RoundedInput, 
  Typograph, 
  FilterBuilder, 
  MultiselectTogglable,
  AttributeMapper,
  JSONUploader,
  RoundedButton,
  HelpPopover,
  EmptyState,
  CardTypeSelector,
  Accordion,
  ReusableTable,
  StatusDot,
  StatusSelector,
  Pagination,
  Modal,
  Drawer,
  CopyToClipboardField,
  Toggle
} from '@lettrlabs-software/lettrui';

function App() {
  const [filters, setFilters] = useState([]);
  const [selectedValues, setSelectedValues] = useState([]);
  const [mappings, setMappings] = useState([]);
  const [isEnabled, setIsEnabled] = useState(false);

  return (
    <div>
      <Typograph variant="h1">Welcome to Lettrui</Typograph>
      
      <RoundedInput 
        placeholder="Enter your name" 
        value={name}
        onChange={(e) => setName(e.target.value)}
      />
      
      <Button label="Submit" />
      
      <FilterBuilder
        filters={filters}
        onChange={setFilters}
      />
      
      <MultiselectTogglable
        selectedValues={selectedValues}
        onChange={setSelectedValues}
        placeholder="Select options..."
        options={[
          { value: 'option1', label: 'Option 1' },
          { value: 'option2', label: 'Option 2' }
        ]}
      />
      
      <AttributeMapper
        mappings={mappings}
        onChange={setMappings}
        jsonData={{ name: 'John', age: 30 }}
      />
      
      <JSONUploader
        onFileUpload={(file) => console.log('Uploaded:', file)}
        size="medium"
      />
      
      <RoundedButton
        kind="black"
        leadingIcon={<PlusIcon size={16} />}
        size="small"
        onClick={() => console.log('Add item')}
      >
        Add Item
      </RoundedButton>
      
      <HelpPopover
        message="This is a helpful tooltip message"
        tooltipPosition="left"
        showText={true}
        text="Help"
      />
      
      <EmptyState
        title="No data available"
        description="Start by adding some items to see them here"
        onCreate={() => console.log('Create new item')}
      />
      
      <CardTypeSelector
        title="Select Type"
        placeholder="Choose an option"
        items={[
          { label: 'Option 1', value: 'option1' },
          { label: 'Option 2', value: 'option2' }
        ]}
        onChange={(value) => console.log('Selected:', value)}
      />
      
      <Accordion
        title="Accordion Title"
        showEditButton={true}
        onEdit={() => console.log('Edit clicked')}
      >
        <p>Accordion content goes here</p>
      </Accordion>
      
      <ReusableTable
        data={[
          { id: '1', name: 'John Doe', email: 'john@example.com', status: 'Active' },
          { id: '2', name: 'Jane Smith', email: 'jane@example.com', status: 'Inactive' }
        ]}
        columns={[
          { field: 'name', headerName: 'Name', width: 200 },
          { field: 'email', headerName: 'Email', width: 250 },
          { field: 'status', headerName: 'Status', width: 120 }
        ]}
        onEdit={(row) => console.log('Edit:', row)}
        onDelete={(row) => console.log('Delete:', row)}
      />
      
      <StatusDot status="enabled" />
      <StatusDot status="disabled" />
      
      <StatusSelector
        value="Active"
        options={[
          { value: 'Active', label: 'Active', color: '#10B981', backgroundColor: '#10B981' },
          { value: 'Inactive', label: 'Inactive', color: '#6B7280', backgroundColor: '#6B7280' },
          { value: 'Testing', label: 'Testing', color: '#F59E0B', backgroundColor: '#F59E0B' }
        ]}
        onChange={(value) => console.log('Status changed:', value)}
      />
      
      <Pagination
        page={0}
        totalCount={100}
        rowsPerPage={10}
        onPageChange={(page) => console.log('Page:', page)}
        onRowsPerPageChange={(rowsPerPage) => console.log('Rows per page:', rowsPerPage)}
        alignment="right"
      />
      
      <Modal
        open={modalOpen}
        onClose={() => setModalOpen(false)}
        title="Confirm Action"
        content={<Typography>Are you sure you want to proceed?</Typography>}
        actions={[
          {
            label: 'Cancel',
            buttonType: 'outline',
            onClick: () => setModalOpen(false),
          },
          {
            label: 'Confirm',
            buttonType: 'primary',
            onClick: () => console.log('Confirmed'),
          },
        ]}
      />
      
      <Drawer
        open={drawerOpen}
        onClose={() => setDrawerOpen(false)}
        title="Settings"
        breadcrumbs={[
          { label: 'Home', href: '#' },
          { label: 'Settings' }
        ]}
        width={600}
        anchor="right"
      >
        <Typography>Drawer content goes here</Typography>
      </Drawer>
      
      <CopyToClipboardField
        value="https://app.lettrlabs.com/webhooks/3482093579287491"
        placeholder="Enter webhook URL"
        onCopy={() => console.log('URL copied!')}
      />
      
      <Toggle
        checked={isEnabled}
        onChange={(event, checked) => {
          setIsEnabled(checked);
          console.log('Toggle changed:', checked);
        }}
        label="Enable feature"
      />
    </div>
  );
}
```

## 🧩 Components

Our library includes the following components:

### Core Components
- **Badge**: Status indicators and labels with multiple sizes and variants
- **Button**: Versatile buttons with multiple variants and states
- **ButtonDropdownSelect**: Dropdown selection with customizable options and sizes
- **CopyToClipboardField**: Input field with integrated copy-to-clipboard functionality and tooltip feedback
- **DataContainer**: Container for displaying structured data
- **DataSummary**: Summary cards for displaying key metrics
- **DashboardHeader**: Header component for dashboard layouts
- **Drawer**: Slide-out panel for navigation and content
- **Dropdown**: Dropdown menus with customizable options
- **FullDatePicker**: Complete date selection component
- **ModalContent**: Modal dialog content wrapper
- **Pagination**: Navigation component for paginated content
- **RoundedButton**: Styled buttons with rounded corners
- **RoundedInput**: Input fields with rounded styling
- **RoundedMaskInput**: Input fields with input masking
- **RoundedSelect**: Select dropdowns with rounded styling
- **SelectButton**: Button-style select components
- **Slider**: Range selection controls
- **Tab**: Tabbed interface components with customizable content
- **Tabs**: Tab container with navigation
- **Toggle**: Custom toggle switch with specific styling for enabled, hovered, focused, and disabled states
- **Typograph**: Text components with various typography variants

### Advanced Components
- **Accordion**: Collapsible content sections with optional edit functionality
- **AttributeMapper**: Component for mapping attributes with value selection
- **CardTypeSelector**: Card-based selector with gradient background and dropdown
- **Drawer**: Slide-out panel with breadcrumb navigation and customizable content
- **EmptyState**: Empty state component with call-to-action functionality
- **FilterBuilder**: Advanced filter construction interface with conditions and groups
- **HelpPopover**: Contextual help tooltip with multiple positioning options
- **JSONUploader**: File upload component specifically for JSON files
- **Modal**: Comprehensive modal dialog with customizable actions and responsive design
- **MultiselectTogglable**: Multi-selection component with toggle functionality
- **Pagination**: Custom pagination component with alignment options and responsive design
- **Stepper**: Step-by-step navigation component
- **ReusableTable**: Comprehensive data table with pagination, sorting, and actions
- **StatusDot**: Simple status indicator with colored dot and optional label
- **StatusSelector**: Interactive dropdown for status selection with custom icons and colors

### Utility Components
- **IconSelector**: Component for selecting and displaying icons

### FilterBuilder Component

The FilterBuilder component provides an advanced interface for constructing complex filters with conditions and groups. It supports:

- Multiple filter conditions with various operators
- Grouping conditions with AND/OR logic
- Dynamic value input types (text/number based on operator)
- Add/remove conditions and groups
- Duplicate and delete functionality
- Real-time filter preview

Example usage:

```tsx
import { FilterBuilder } from '@lettrlabs-software/lettrlabs-ui';

function App() {
  const [filters, setFilters] = useState([]);

  return (
    <FilterBuilder
      filters={filters}
      onChange={setFilters}
    />
  );
}
```

### MultiselectTogglable Component

The MultiselectTogglable component provides a multi-selection interface with toggle functionality. It supports:

- Multiple value selection with chips
- Toggle popover on input click
- Add/remove values dynamically
- Custom placeholder text
- Disabled state support

Example usage:

```tsx
import { MultiselectTogglable } from '@lettrlabs-software/lettrlabs-ui';

function App() {
  const [selectedValues, setSelectedValues] = useState([]);

  return (
    <MultiselectTogglable
      selectedValues={selectedValues}
      onChange={setSelectedValues}
      placeholder="Select values..."
      options={[
        { value: 'option1', label: 'Option 1' },
        { value: 'option2', label: 'Option 2' }
      ]}
    />
  );
}
```

### AttributeMapper Component

The AttributeMapper component provides a mapping interface for attributes with value selection. It supports:

- Attribute-value pair mapping
- Integration with MultiselectTogglable for value selection
- Dynamic JSON data loading
- Custom attribute display

Example usage:

```tsx
import { AttributeMapper } from '@lettrlabs-software/lettrlabs-ui';

function App() {
  const [mappings, setMappings] = useState([]);

  return (
    <AttributeMapper
      mappings={mappings}
      onChange={setMappings}
      jsonData={{ name: 'John', age: 30 }}
    />
  );
}
```

### JSONUploader Component

The JSONUploader component provides a specialized file upload interface for JSON files. It supports:

- Drag and drop file upload
- JSON file validation
- Loading states
- Custom JSON icon design
- Multiple size variants

Example usage:

```tsx
import { JSONUploader } from '@lettrlabs-software/lettrlabs-ui';

function App() {
  const handleFileUpload = (file) => {
    console.log('Uploaded file:', file);
  };

  return (
    <JSONUploader
      onFileUpload={handleFileUpload}
      size="medium"
    />
  );
}
```

### RoundedButton Component

The RoundedButton component provides a versatile button with support for icons and multiple variants. It now includes built-in support for the plus icon, replacing the deprecated PlusButton component.

Features:
- Multiple variants: filled, outline, subtle, black, primary, secondary
- Three sizes: small, regular, large
- Leading and trailing icon support
- Built-in PlusIcon component
- Dynamic font sizing with maxWidth constraints
- Full accessibility support

Example usage:

```tsx
import { RoundedButton, PlusIcon } from '@lettrlabs-software/lettrlabs-ui';

function App() {
  return (
    <div>
      {/* Using the showPlusIcon prop */}
      <RoundedButton
        kind="black"
        showPlusIcon={true}
        size="small"
        onClick={() => console.log('Add item')}
      >
        Add Item
      </RoundedButton>
      
      {/* Using manual PlusIcon */}
      <RoundedButton
        kind="outline"
        leadingIcon={<PlusIcon size={16} />}
        size="regular"
        onClick={() => console.log('Create new')}
      >
        Create New
      </RoundedButton>
    </div>
  );
}
```

### HelpPopover Component

The HelpPopover component provides contextual help tooltips with flexible positioning and styling options.

Features:
- 8 positioning options: top, bottom, left, right, top-left, top-right, bottom-left, bottom-right
- Two icon types: question (default) and exclamation
- Two icon colors: default (purple) and gray
- Two sizes: small and medium
- Optional text display
- Automatic text wrapping for long messages
- Smooth fade-in transitions
- Full accessibility support

Example usage:

```tsx
import { HelpPopover } from '@lettrlabs-software/lettrlabs-ui';

function App() {
  return (
    <div>
      {/* Basic help with icon only */}
      <HelpPopover
        message="This explains how the feature works"
        tooltipPosition="right"
      />
      
      {/* Help with text */}
      <HelpPopover
        message="This is a detailed explanation of the functionality"
        tooltipPosition="left"
        showText={true}
        text="How it works"
        iconType="question"
        iconColor="default"
        size="md"
      />
      
      {/* Warning style */}
      <HelpPopover
        message="Warning: This action cannot be undone"
        tooltipPosition="top"
        showText={true}
        text="Important"
        iconType="exclamation"
        iconColor="default"
      />
    </div>
  );
}
```

### EmptyState Component

The EmptyState component provides a clean interface for displaying empty states with optional call-to-action functionality.

Features:
- Customizable title and description
- Optional create button with callback
- Clean, centered layout
- Responsive design
- Accessible markup

Example usage:

```tsx
import { EmptyState } from '@lettrlabs-software/lettrlabs-ui';

function App() {
  const handleCreate = async () => {
    // Your creation logic here
    const result = await createNewItem();
    return result;
  };

  return (
    <EmptyState
      title="No items found"
      description="Get started by creating your first item"
      onCreate={handleCreate}
      onCreated={(result) => console.log('Created:', result)}
    />
  );
}
```

### CardTypeSelector Component

The CardTypeSelector component provides a card-based interface for type selection with a gradient background and integrated dropdown.

Features:
- Gradient background design
- Integrated ButtonDropdownSelect
- Customizable title and placeholder
- Disabled state support
- Responsive design
- Full accessibility

Example usage:

```tsx
import { CardTypeSelector } from '@lettrlabs-software/lettrlabs-ui';

function App() {
  const options = [
    { label: 'Email', value: 'email' },
    { label: 'SMS', value: 'sms' },
    { label: 'Push', value: 'push' }
  ];

  return (
    <CardTypeSelector
      title="Select Notification Type"
      placeholder="Choose a type"
      items={options}
      onChange={(value, item, index) => {
        console.log('Selected:', value, item, index);
      }}
      disabled={false}
    />
  );
}
```

### Accordion Component

The Accordion component provides collapsible content sections with optional edit functionality.

Features:
- Smooth expand/collapse animations
- Optional edit button with callback
- Customizable icons
- Responsive design
- Keyboard navigation support
- Full accessibility

Example usage:

```tsx
import { Accordion } from '@lettrlabs-software/lettrlabs-ui';

function App() {
  return (
    <div>
      {/* Basic accordion */}
      <Accordion title="Basic Section">
        <p>This is the content of the accordion section.</p>
      </Accordion>
      
      {/* Accordion with edit button */}
      <Accordion
        title="Editable Section"
        showEditButton={true}
        onEdit={() => console.log('Edit clicked')}
      >
        <p>This section can be edited.</p>
      </Accordion>
    </div>
  );
}
```

### ReusableTable Component

The ReusableTable component provides a comprehensive data table with advanced features for displaying and managing tabular data. It's built on top of Material-UI components and styled with the design system.

#### Features

- **📊 Customizable Columns**: Define columns with custom render functions for complex data display
- **📄 Pagination**: Built-in pagination with customizable rows per page (10, 25, 50, 100)
- **🔄 Status Management**: Interactive status dropdowns with visual indicators and loading states
- **⚡ Action Buttons**: Edit and delete actions with tooltips and loading states
- **⏳ Loading States**: Overlay loading indicator and individual action loading
- **❌ Error Handling**: Error display and empty state messages
- **📱 Responsive Design**: Mobile-friendly table layout with responsive breakpoints
- **♿ Accessibility**: Full keyboard navigation and ARIA support
- **🎨 Custom Styling**: Material-UI styled components with design system integration
- **🔧 TypeScript**: Full TypeScript support with generic types

#### Basic Usage

```tsx
import { ReusableTable, ColumnDefinition } from '@lettrlabs-software/lettrlabs-ui';

interface UserData {
  id: string;
  name: string;
  email: string;
  status: 'Active' | 'Inactive' | 'Testing';
  role: string;
  lastLogin: string;
}

function App() {
  const [data, setData] = useState<UserData[]>([
    {
      id: '1',
      name: 'John Doe',
      email: 'john@example.com',
      status: 'Active',
      role: 'Admin',
      lastLogin: '2024-01-15'
    }
  ]);

  const columns: ColumnDefinition<UserData>[] = [
    {
      field: 'name',
      headerName: 'Name',
      width: 200,
      renderCell: (value, row) => (
        <div>
          <div style={{ fontWeight: 600 }}>{value}</div>
          <div style={{ fontSize: '12px', color: '#6B7280' }}>{row.email}</div>
        </div>
      )
    },
    {
      field: 'role',
      headerName: 'Role',
      width: 120
    },
    {
      field: 'status',
      headerName: 'Status',
      width: 140,
      renderCell: (value) => (
        <span style={{ 
          padding: '4px 8px',
          borderRadius: '12px',
          backgroundColor: value === 'Active' ? '#E5F3FF' : '#F3F4F6',
          color: value === 'Active' ? '#1E40AF' : '#6B7280',
          fontSize: '12px',
          fontWeight: 600
        }}>
          {value}
        </span>
      )
    },
    {
      field: 'lastLogin',
      headerName: 'Last Login',
      width: 150
    }
  ];

  return (
    <ReusableTable
      data={data}
      columns={columns}
      rowsPerPage={10}
      totalCount={data.length}
    />
  );
}
```

#### Advanced Usage with Actions

```tsx
function AdvancedTable() {
  const [data, setData] = useState<UserData[]>([]);
  const [loading, setLoading] = useState(false);
  const [updatingStatus, setUpdatingStatus] = useState(false);
  const [deleting, setDeleting] = useState(false);

  const handleStatusChange = async (row: UserData, newStatus: string) => {
    setUpdatingStatus(true);
    try {
      // API call to update status
      await updateUserStatus(row.id, newStatus);
      setData(prev => prev.map(item => 
        item.id === row.id 
          ? { ...item, status: newStatus as 'Active' | 'Inactive' | 'Testing' }
          : item
      ));
    } catch (error) {
      console.error('Failed to update status:', error);
    } finally {
      setUpdatingStatus(false);
    }
  };

  const handleEdit = (row: UserData) => {
    // Open edit modal or navigate to edit page
    console.log('Edit user:', row);
  };

  const handleDelete = async (row: UserData) => {
    if (window.confirm(`Are you sure you want to delete ${row.name}?`)) {
      setDeleting(true);
      try {
        // API call to delete user
        await deleteUser(row.id);
        setData(prev => prev.filter(item => item.id !== row.id));
      } catch (error) {
        console.error('Failed to delete user:', error);
      } finally {
        setDeleting(false);
      }
    }
  };

  const handlePageChange = (page: number) => {
    // Handle pagination
    console.log('Page changed:', page);
  };

  const handleRowsPerPageChange = (rowsPerPage: number) => {
    // Handle rows per page change
    console.log('Rows per page:', rowsPerPage);
  };

  return (
    <ReusableTable
      data={data}
      columns={columns}
      loading={loading}
      onStatusChange={handleStatusChange}
      onEdit={handleEdit}
      onDelete={handleDelete}
      statusOptions={[
        { label: 'Active', value: 'Active' },
        { label: 'Inactive', value: 'Inactive' },
        { label: 'Testing', value: 'Testing' }
      ]}
      rowsPerPage={10}
      totalCount={data.length}
      onPageChange={handlePageChange}
      onRowsPerPageChange={handleRowsPerPageChange}
      isUpdatingStatus={updatingStatus}
      isDeleting={deleting}
      emptyMessage="No users found. Create your first user to get started."
    />
  );
}
```

#### Column Definition

The `ColumnDefinition<T>` interface allows you to define how each column should be displayed:

```tsx
interface ColumnDefinition<T> {
  field: keyof T;                    // Field name from your data object
  headerName: string;                // Column header text
  width?: number | string;           // Column width (px or %)
  renderCell?: (value: any, row: T) => React.ReactNode; // Custom cell renderer
  align?: 'left' | 'center' | 'right'; // Text alignment
}
```

#### Custom Cell Rendering

You can create custom cell renderers for complex data display:

```tsx
const columns: ColumnDefinition<UserData>[] = [
  {
    field: 'avatar',
    headerName: 'User',
    width: 200,
    renderCell: (_, row) => (
      <div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
        <img 
          src={row.avatar} 
          alt={row.name}
          style={{ 
            width: '32px', 
            height: '32px', 
            borderRadius: '50%' 
          }} 
        />
        <div>
          <div style={{ fontWeight: 600 }}>{row.name}</div>
          <div style={{ fontSize: '12px', color: '#6B7280' }}>{row.email}</div>
        </div>
      </div>
    )
  },
  {
    field: 'status',
    headerName: 'Status',
    width: 120,
    align: 'center',
    renderCell: (value) => (
      <StatusDot 
        status={value === 'Active' ? 'enabled' : 'disabled'} 
        size="small" 
      />
    )
  },
  {
    field: 'actions',
    headerName: 'Actions',
    width: 100,
    align: 'right',
    renderCell: (_, row) => (
      <div style={{ display: 'flex', gap: '8px' }}>
        <button onClick={() => handleEdit(row)}>Edit</button>
        <button onClick={() => handleDelete(row)}>Delete</button>
      </div>
    )
  }
];
```

#### Props Reference

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `data` | `T[]` | `[]` | Array of data objects to display |
| `columns` | `ColumnDefinition<T>[]` | `[]` | Column definitions |
| `loading` | `boolean` | `false` | Shows loading overlay when true |
| `error` | `string \| null` | `null` | Error message to display |
| `emptyMessage` | `string` | `"No data found"` | Message when no data |
| `page` | `number` | `0` | Current page number (0-based) |
| `rowsPerPage` | `number` | `100` | Number of rows per page |
| `totalCount` | `number` | `0` | Total items for pagination |
| `onPageChange` | `(page: number) => void` | `undefined` | Page change callback |
| `onRowsPerPageChange` | `(rowsPerPage: number) => void` | `undefined` | Rows per page callback |
| `onStatusChange` | `(row: T, newStatus: string) => void` | `undefined` | Status change callback |
| `onEdit` | `(row: T) => void` | `undefined` | Edit button callback |
| `onDelete` | `(row: T) => void` | `undefined` | Delete button callback |
| `statusOptions` | `{label: string, value: string}[]` | `[]` | Status dropdown options |
| `isUpdatingStatus` | `boolean` | `false` | Status update loading state |
| `isDeleting` | `boolean` | `false` | Delete operation loading state |
| `getRowId` | `(row: T) => string \| number` | `(row) => row.id \|\| row.key \|\| Math.random()` | Row ID function |

#### Styling and Customization

The ReusableTable uses Material-UI styled components and can be customized through CSS:

```css
/* Custom table styling */
.reusable-table {
  border-radius: 12px;
  box-shadow: 0 0 25px 0 rgba(0, 0, 0, 0.05);
}

/* Custom cell styling */
.reusable-table .MuiTableCell-root {
  padding: 12px 16px;
  border-color: #DFDFDF;
}

/* Custom header styling */
.reusable-table .MuiTableHead-root {
  background-color: #F8F9FA;
}
```

#### Best Practices

1. **Performance**: Use `getRowId` to provide stable row identifiers for better React performance
2. **Accessibility**: Always provide meaningful `headerName` values for screen readers
3. **Responsive Design**: Use percentage widths for columns that need to be responsive
4. **Loading States**: Show loading indicators during async operations
5. **Error Handling**: Provide meaningful error messages and empty states
6. **Type Safety**: Use TypeScript interfaces for your data objects

#### Common Use Cases

- **User Management**: Display users with status, roles, and actions
- **Data Tables**: Show any tabular data with pagination
- **Admin Panels**: Manage resources with edit/delete actions
- **Reports**: Display data with custom formatting
- **Settings**: Manage configuration items with status indicators

### StatusDot Component

The StatusDot component provides a simple and clean way to display status indicators with colored dots and optional labels.

Features:
- **Multiple Status Types**: Supports enabled/disabled, active/inactive, online/offline states
- **Three Sizes**: Small, medium, and large variants
- **Custom Labels**: Optional custom label text or automatic status-based labels
- **Responsive Design**: Adapts to different screen sizes
- **Accessibility**: Focus styles and proper contrast
- **Hover Effects**: Subtle animations for better user experience

Example usage:

```tsx
import { StatusDot } from '@lettrlabs-software/lettrlabs-ui';

function App() {
  return (
    <div>
      {/* Basic usage */}
      <StatusDot status="enabled" />
      <StatusDot status="disabled" />
      
      {/* Different sizes */}
      <StatusDot status="enabled" size="small" />
      <StatusDot status="enabled" size="medium" />
      <StatusDot status="enabled" size="large" />
      
      {/* Custom labels */}
      <StatusDot status="enabled" label="Online" />
      <StatusDot status="disabled" label="Offline" />
      
      {/* Without labels */}
      <StatusDot status="enabled" showLabel={false} />
      
      {/* In a table */}
      <table>
        <tr>
          <td>User 1</td>
          <td><StatusDot status="enabled" size="small" /></td>
        </tr>
        <tr>
          <td>User 2</td>
          <td><StatusDot status="disabled" size="small" /></td>
        </tr>
      </table>
    </div>
  );
}
```

#### StatusDot Props

- **`status`**: Status type - 'enabled', 'disabled', 'active', 'inactive', 'online', 'offline'
- **`label`**: Custom label text (overrides default status-based label)
- **`size`**: Size variant - 'small', 'medium', 'large'
- **`showLabel`**: Whether to show the label text (default: true)
- **`className`**: Additional CSS class names

### StatusSelector Component

The StatusSelector component provides an interactive dropdown interface for status selection with custom icons, colors, and smooth animations.

#### Features

- **Custom Icons**: Support for SVG icons with customizable colors
- **Multiple Status Options**: Configurable status options with labels and colors
- **Smooth Animations**: Fade-in/out transitions and hover effects
- **Click Outside Detection**: Automatically closes when clicking outside
- **Keyboard Navigation**: Full keyboard support with Enter and Escape keys
- **Responsive Design**: Adapts to different screen sizes
- **Customizable Styling**: CSS variables for easy theming
- **TypeScript Support**: Full type safety with generic types

#### Basic Usage

```tsx
import { StatusSelector, StatusOption } from '@lettrlabs-software/lettrlabs-ui';

function App() {
  const [status, setStatus] = useState<'Active' | 'Inactive' | 'Testing'>('Active');

  const statusOptions: StatusOption[] = [
    {
      value: 'Active',
      label: 'Active',
      color: '#10B981',
      backgroundColor: '#10B981',
      icon: (
        <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none">
          <path d="M9 12L11 14L15 10M21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12Z" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
        </svg>
      )
    },
    {
      value: 'Inactive',
      label: 'Inactive',
      color: '#6B7280',
      backgroundColor: '#6B7280',
      icon: (
        <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
          <path d="M9.15375 15.75H14.8462C15.1022 15.75 15.3169 15.6634 15.4902 15.4902C15.6634 15.3169 15.75 15.1023 15.75 14.8463V9.15375C15.75 8.89775 15.6634 8.68308 15.4902 8.50975C15.3169 8.33658 15.1022 8.25 14.8462 8.25H9.15375C8.89775 8.25 8.68308 8.33658 8.50975 8.50975C8.33658 8.68308 8.25 8.89775 8.25 9.15375V14.8463C8.25 15.1023 8.33658 15.3169 8.50975 15.4902C8.68308 15.6634 8.89775 15.75 9.15375 15.75ZM12.0017 21.5C10.6877 21.5 9.45267 21.2507 8.2965 20.752C7.14033 20.2533 6.13467 19.5766 5.2795 18.7218C4.42433 17.8669 3.74725 16.8617 3.24825 15.706C2.74942 14.5503 2.5 13.3156 2.5 12.0017C2.5 10.6877 2.74933 9.45267 3.248 8.2965C3.74667 7.14033 4.42342 6.13467 5.27825 5.2795C6.13308 4.42433 7.13833 3.74725 8.294 3.24825C9.44967 2.74942 10.6844 2.5 11.9983 2.5C13.3123 2.5 14.5473 2.74933 15.7035 3.248C16.8597 3.74667 17.8653 4.42342 18.7205 5.27825C19.5757 6.13308 20.2528 7.13833 20.7518 8.294C21.2506 9.44967 21.5 10.6844 21.5 11.9983C21.5 13.3123 21.2507 14.5473 20.752 15.7035C20.2533 16.8597 19.5766 17.8653 18.7218 18.7205C17.8669 19.5757 16.8617 20.2528 15.706 20.7518C14.5503 21.2506 13.3156 21.5 12.0017 21.5Z" fill="#818DA0"/>
        </svg>
      )
    },
    {
      value: 'Testing',
      label: 'Testing',
      color: '#F59E0B',
      backgroundColor: '#F59E0B',
      icon: (
        <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
          <path d="M12 2L13.09 8.26L22 9L13.09 9.74L12 16L10.91 9.74L2 9L10.91 8.26L12 2Z" fill="currentColor"/>
        </svg>
      )
    }
  ];

  return (
    <StatusSelector
      value={status}
      options={statusOptions}
      onChange={(newValue) => {
        setStatus(newValue as 'Active' | 'Inactive' | 'Testing');
        console.log('Status changed to:', newValue);
      }}
    />
  );
}
```

#### Integration with ReusableTable

The StatusSelector is seamlessly integrated into the ReusableTable component for status management:

```tsx
import { ReusableTable, StatusSelector, StatusOption } from '@lettrlabs-software/lettrlabs-ui';

function UserTable() {
  const statusOptions: StatusOption[] = [
    {
      value: 'Active',
      label: 'Active',
      color: '#10B981',
      backgroundColor: '#10B981',
      icon: <ActiveIcon />
    },
    {
      value: 'Inactive',
      label: 'Inactive',
      color: '#6B7280',
      backgroundColor: '#6B7280',
      icon: <InactiveIcon />
    },
    {
      value: 'Testing',
      label: 'Testing',
      color: '#F59E0B',
      backgroundColor: '#F59E0B',
      icon: <TestingIcon />
    }
  ];

  const columns = [
    {
      field: 'status',
      headerName: 'Status',
      width: 120,
      renderCell: (value, row) => (
        <StatusSelector
          value={value as 'Active' | 'Inactive' | 'Testing'}
          options={statusOptions}
          onChange={(newValue) => {
            console.log(`Status changed for ${row.name}: ${newValue}`);
            // Handle status update logic here
          }}
        />
      )
    }
  ];

  return (
    <ReusableTable
      data={userData}
      columns={columns}
      // ... other props
    />
  );
}
```

#### StatusSelector Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `value` | `string` | `''` | Current selected value |
| `options` | `StatusOption[]` | `[]` | Array of status options |
| `onChange` | `(value: string) => void` | `undefined` | Callback when selection changes |
| `disabled` | `boolean` | `false` | Whether the selector is disabled |
| `className` | `string` | `''` | Additional CSS class names |

#### StatusOption Interface

```tsx
interface StatusOption {
  value: string;                    // Unique value for the option
  label: string;                    // Display label
  color: string;                    // Text and icon color
  backgroundColor: string;          // Background color
  icon: React.ReactNode;           // Custom icon component
}
```

#### Styling and Customization

The StatusSelector uses CSS variables for easy theming:

```css
/* Custom styling */
.status-selector {
  --status-selector-border-color: #D1D5DB;
  --status-selector-hover-border-color: #9CA3AF;
  --status-selector-focus-border-color: #3B82F6;
  --status-selector-background: #FFFFFF;
  --status-selector-text-color: #374151;
  --status-selector-font-size: 14px;
  --status-selector-font-weight: 600;
}
```

### Pagination Component

The Pagination component provides a comprehensive pagination interface with customizable alignment and responsive design.

#### Features

- **Alignment Options**: Left or right alignment for pagination controls
- **Responsive Design**: Adapts to different screen sizes
- **Rows Per Page**: Configurable rows per page options (10, 25, 50, 100)
- **Page Navigation**: Previous/Next buttons with page numbers
- **Compact Mode**: Optional compact display for space-constrained layouts
- **Accessibility**: Full keyboard navigation and ARIA support
- **TypeScript Support**: Full type safety with comprehensive interfaces

#### Basic Usage

```tsx
import { Pagination } from '@lettrlabs-software/lettrlabs-ui';

function App() {
  const [page, setPage] = useState(0);
  const [rowsPerPage, setRowsPerPage] = useState(10);
  const totalCount = 100;

  return (
    <Pagination
      page={page}
      totalCount={totalCount}
      rowsPerPage={rowsPerPage}
      onPageChange={(newPage) => setPage(newPage)}
      onRowsPerPageChange={(newRowsPerPage) => setRowsPerPage(newRowsPerPage)}
      alignment="right"
    />
  );
}
```

#### Integration with ReusableTable

The Pagination component is integrated into ReusableTable with customizable alignment:

```tsx
import { ReusableTable } from '@lettrlabs-software/lettrlabs-ui';

function DataTable() {
  return (
    <ReusableTable
      data={data}
      columns={columns}
      page={0}
      rowsPerPage={10}
      totalCount={data.length}
      onPageChange={(page) => console.log('Page:', page)}
      onRowsPerPageChange={(rowsPerPage) => console.log('Rows per page:', rowsPerPage)}
      paginationAlignment="right" // or "left"
    />
  );
}
```

#### Pagination Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `page` | `number` | `0` | Current page number (0-based) |
| `totalCount` | `number` | `0` | Total number of items |
| `rowsPerPage` | `number` | `10` | Number of rows per page |
| `onPageChange` | `(page: number) => void` | `undefined` | Callback when page changes |
| `onRowsPerPageChange` | `(rowsPerPage: number) => void` | `undefined` | Callback when rows per page changes |
| `alignment` | `'left' \| 'right'` | `'left'` | Alignment of pagination controls |
| `rowsPerPageOptions` | `number[]` | `[10, 25, 50, 100]` | Available rows per page options |
| `showRowsPerPage` | `boolean` | `true` | Whether to show rows per page selector |
| `compact` | `boolean` | `false` | Whether to use compact display |
| `className` | `string` | `''` | Additional CSS class names |

#### Advanced Usage

```tsx
function AdvancedPagination() {
  const [page, setPage] = useState(0);
  const [rowsPerPage, setRowsPerPage] = useState(25);
  const totalCount = 1000;

  const handlePageChange = (newPage: number) => {
    setPage(newPage);
    // Fetch new data for the page
    fetchData(newPage, rowsPerPage);
  };

  const handleRowsPerPageChange = (newRowsPerPage: number) => {
    setRowsPerPage(newRowsPerPage);
    setPage(0); // Reset to first page
    // Fetch new data with new page size
    fetchData(0, newRowsPerPage);
  };

  return (
    <div>
      {/* Left-aligned pagination */}
      <Pagination
        page={page}
        totalCount={totalCount}
        rowsPerPage={rowsPerPage}
        onPageChange={handlePageChange}
        onRowsPerPageChange={handleRowsPerPageChange}
        alignment="left"
        rowsPerPageOptions={[10, 25, 50, 100, 200]}
        showRowsPerPage={true}
      />
      
      {/* Right-aligned compact pagination */}
      <Pagination
        page={page}
        totalCount={totalCount}
        rowsPerPage={rowsPerPage}
        onPageChange={handlePageChange}
        onRowsPerPageChange={handleRowsPerPageChange}
        alignment="right"
        compact={true}
        showRowsPerPage={false}
      />
    </div>
  );
}
```

### Modal Component

The Modal component provides a comprehensive modal dialog interface with customizable actions, responsive design, and accessibility features.

#### Features

- **Customizable Actions**: Support for multiple action buttons with different styles
- **Responsive Design**: Adapts to different screen sizes with mobile-friendly layout
- **Accessibility**: Full keyboard navigation, ARIA support, and focus management
- **Flexible Content**: Accepts any React content for the modal body
- **Close Button**: Built-in close button (X) in the header
- **Backdrop**: Customizable backdrop with blur effect
- **Size Options**: Multiple max-width options (xs, sm, md, lg, xl)
- **TypeScript Support**: Full type safety with comprehensive interfaces

#### Basic Usage

```tsx
import { Modal } from '@lettrlabs-software/lettrlabs-ui';

function App() {
  const [open, setOpen] = useState(false);

  return (
    <Modal
      open={open}
      onClose={() => setOpen(false)}
      title="Confirm Action"
      content={<Typography>Are you sure you want to proceed?</Typography>}
      actions={[
        {
          label: 'Cancel',
          buttonType: 'outline',
          onClick: () => setOpen(false),
        },
        {
          label: 'Confirm',
          buttonType: 'primary',
          onClick: () => console.log('Confirmed'),
        },
      ]}
    />
  );
}
```

#### Advanced Usage with Disabled Actions

```tsx
function AdvancedModal() {
  const [open, setOpen] = useState(false);
  const [isLoading, setIsLoading] = useState(false);

  const handleSave = async () => {
    setIsLoading(true);
    try {
      // Simulate API call
      await new Promise(resolve => setTimeout(resolve, 2000));
      setOpen(false);
    } finally {
      setIsLoading(false);
    }
  };

  return (
    <Modal
      open={open}
      onClose={() => setOpen(false)}
      title="Save Changes"
      content={
        <Box>
          <Typography paragraph>
            You have unsaved changes. Do you want to save them before closing?
          </Typography>
          <Typography variant="body2" color="text.secondary">
            This action cannot be undone.
          </Typography>
        </Box>
      }
      actions={[
        {
          label: 'Discard',
          buttonType: 'outline',
          onClick: () => setOpen(false),
        },
        {
          label: 'Save',
          buttonType: 'primary',
          onClick: handleSave,
          disabled: isLoading,
        },
      ]}
      maxWidth="md"
    />
  );
}
```

#### Modal Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `open` | `boolean` | `false` | Controls whether the modal is open |
| `onClose` | `() => void` | `undefined` | Callback when modal should close |
| `title` | `string` | `''` | Modal title displayed in header |
| `content` | `React.ReactNode` | `undefined` | Content to display in modal body |
| `actions` | `ModalAction[]` | `[]` | Array of action buttons |
| `maxWidth` | `'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| false` | `'sm'` | Maximum width of the modal |
| `fullWidth` | `boolean` | `false` | Whether modal should take full width |

#### ModalAction Interface

```tsx
interface ModalAction {
  label: string;                    // Button text
  buttonType: 'filled' | 'outline' | 'subtle' | 'black' | 'primary' | 'secondary'; // Button style
  onClick: () => void;             // Click handler
  disabled?: boolean;              // Whether button is disabled
}
```

#### Size Variants

```tsx
// Small modal (default)
<Modal maxWidth="sm" ... />

// Medium modal
<Modal maxWidth="md" ... />

// Large modal
<Modal maxWidth="lg" ... />

// Extra large modal
<Modal maxWidth="xl" ... />

// Full width modal
<Modal fullWidth={true} maxWidth="lg" ... />
```

#### Styling and Customization

The Modal uses CSS variables for easy theming:

```css
/* Custom modal styling */
.modal .MuiDialog-paper {
  border-radius: 12px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
}

/* Custom backdrop */
.modal .MuiBackdrop-root {
  background-color: rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(2px);
}
```

#### Best Practices

1. **Accessibility**: Always provide meaningful titles and action labels
2. **Content**: Keep modal content concise and focused
3. **Actions**: Limit to 2-3 primary actions to avoid clutter
4. **Responsive**: Test on mobile devices for proper layout
5. **Loading States**: Show loading indicators for async actions
6. **Keyboard**: Ensure all actions are keyboard accessible

#### Common Use Cases

- **Confirmations**: "Are you sure?" dialogs with Cancel/Confirm actions
- **Forms**: Modal forms for creating/editing data
- **Information**: Displaying detailed information or help content
- **Settings**: Configuration panels and preferences
- **Alerts**: Important notifications requiring user acknowledgment

### Toggle Component

The Toggle component provides a custom toggle switch with specific styling for different states. It's built with a native HTML checkbox input for better accessibility and performance.

#### Features

- **Multiple States**: Default, hovered, focused, and disabled states with distinct styling
- **Custom Styling**: Specific dimensions, colors, and shadows for each state
- **Accessibility**: Built on native HTML checkbox for proper keyboard navigation and screen reader support
- **Loading State**: Optional loading indicator with spinner animation
- **Label Support**: Optional label text for better UX
- **TypeScript Support**: Full type safety with comprehensive interfaces

#### Basic Usage

```tsx
import { Toggle } from '@lettrlabs-software/lettrlabs-ui';

function App() {
  const [isEnabled, setIsEnabled] = useState(false);

  return (
    <Toggle
      checked={isEnabled}
      onChange={(event, checked) => {
        setIsEnabled(checked);
        console.log('Toggle changed:', checked);
      }}
    />
  );
}
```

#### Advanced Usage

```tsx
function AdvancedToggle() {
  const [settings, setSettings] = useState({
    notifications: true,
    darkMode: false,
    autoSave: true
  });

  const handleToggle = (field: string) => (event: React.ChangeEvent<HTMLInputElement>, checked: boolean) => {
    setSettings(prev => ({
      ...prev,
      [field]: checked
    }));
  };

  return (
    <div>
      {/* Basic toggle */}
      <Toggle
        checked={settings.notifications}
        onChange={handleToggle('notifications')}
        label="Enable notifications"
      />
      
      {/* Disabled toggle */}
      <Toggle
        checked={settings.darkMode}
        onChange={handleToggle('darkMode')}
        disabled={true}
        label="Dark mode (coming soon)"
      />
      
      {/* Loading toggle */}
      <Toggle
        checked={settings.autoSave}
        onChange={handleToggle('autoSave')}
        loading={true}
        label="Auto-save"
      />
    </div>
  );
}
```

#### Toggle Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `checked` | `boolean` | `false` | Whether the toggle is checked (on) or not |
| `onChange` | `(event: React.ChangeEvent<HTMLInputElement>, checked: boolean) => void` | `undefined` | Callback when toggle state changes |
| `disabled` | `boolean` | `false` | Whether the toggle is disabled |
| `loading` | `boolean` | `false` | Whether the toggle is in loading state |
| `label` | `string` | `undefined` | Optional label text for the toggle |
| `className` | `string` | `''` | Additional CSS class names |

#### State Styling

The Toggle component includes specific styling for different states:

- **Default (Unchecked)**: 40px × 20px, gray background with subtle shadow
- **Default (Checked)**: 40px × 20px, purple background (#5551FF) with shadow
- **Hovered**: Background changes to lighter purple (#726FF2)
- **Focused**: 41px × 20px with purple border (#D1D6FE) and shadow
- **Disabled**: Gray background (#D1D6FE) with no shadow

#### Styling and Customization

The Toggle uses CSS variables for easy theming:

```css
/* Custom toggle styling */
.toggle {
  --toggle-default-off-surface: #CDD1D9;
  --toggle-default-on-surface: #5551FF;
  --toggle-hovered-on-surface: #726FF2;
  --toggle-focused-on-stroke-outer: #D1D6FE;
  --toggle-focused-on-surface: #5551FF;
  --toggle-disabled-on-surface: #D1D6FE;
}
```

#### Best Practices

1. **Accessibility**: Always provide meaningful labels for screen readers
2. **Loading States**: Use loading state for async operations
3. **Visual Feedback**: The component provides clear visual feedback for all states
4. **Keyboard Navigation**: Full keyboard support with Tab and Space keys
5. **Mobile Friendly**: Touch-friendly design for mobile devices

#### Common Use Cases

- **Settings Toggles**: Enable/disable features in settings panels
- **Form Controls**: Binary choices in forms
- **Feature Flags**: Toggle experimental features
- **Preferences**: User preference controls
- **Admin Panels**: Enable/disable functionality

### CopyToClipboardField Component

The CopyToClipboardField component provides an input field with integrated copy-to-clipboard functionality, built on top of the RoundedInput design system. It's perfect for displaying URLs, tokens, or any text that users need to copy.

#### Features

- **Integrated Copy Button**: Built-in copy button with visual feedback
- **Tooltip Feedback**: Smart tooltip that shows "Copy to clipboard" and "Copied!" states
- **Keyboard Shortcuts**: Supports Ctrl+C (or Cmd+C) for copying when focused
- **Full Width Support**: Configurable fullWidth prop (default: true)
- **Multiple States**: Normal, focused, disabled, and read-only states
- **Accessibility**: Full keyboard navigation and ARIA support
- **Responsive Design**: Adapts to different screen sizes
- **Visual Feedback**: Icon changes from copy to check when copied

#### Basic Usage

```tsx
import { CopyToClipboardField } from '@lettrlabs-software/lettrlabs-ui';

function App() {
  const [webhookUrl, setWebhookUrl] = useState('https://app.lettrlabs.com/webhooks/3482093579287491');

  return (
    <CopyToClipboardField
      value={webhookUrl}
      onChange={setWebhookUrl}
      placeholder="Enter webhook URL"
      onCopy={() => console.log('URL copied!')}
    />
  );
}
```

#### Advanced Usage

```tsx
function AdvancedExample() {
  const [apiKey, setApiKey] = useState('sk_live_1234567890abcdef');
  const [copiedCount, setCopiedCount] = useState(0);

  const handleCopy = () => {
    setCopiedCount(prev => prev + 1);
    // Show success notification
    enqueueSnackbar('API key copied to clipboard!', { variant: 'success' });
  };

  return (
    <div>
      {/* Full width (default) */}
      <CopyToClipboardField
        value={apiKey}
        onChange={setApiKey}
        placeholder="Enter API key"
        onCopy={handleCopy}
        fullWidth={true}
      />
      
      {/* Not full width */}
      <CopyToClipboardField
        value={apiKey}
        onChange={setApiKey}
        placeholder="Enter API key"
        onCopy={handleCopy}
        fullWidth={false}
      />
      
      {/* Read-only mode */}
      <CopyToClipboardField
        value={apiKey}
        placeholder="API Key"
        readOnly={true}
        onCopy={handleCopy}
      />
      
      {/* Disabled state */}
      <CopyToClipboardField
        value={apiKey}
        placeholder="API Key"
        disabled={true}
        onCopy={handleCopy}
      />
      
      <p>Copy button clicked: {copiedCount} times</p>
    </div>
  );
}
```

#### Integration with Forms

```tsx
function WebhookForm() {
  const [formData, setFormData] = useState({
    name: '',
    webhookUrl: 'https://app.lettrlabs.com/webhooks/3482093579287491'
  });

  const handleInputChange = (field: string, value: string) => {
    setFormData(prev => ({
      ...prev,
      [field]: value
    }));
  };

  return (
    <form>
      <div style={{ marginBottom: '16px' }}>
        <label>Webhook Name</label>
        <RoundedInput
          value={formData.name}
          onChange={(e) => handleInputChange('name', e.target.value)}
          placeholder="Enter webhook name"
          name="name"
        />
      </div>
      
      <div style={{ marginBottom: '16px' }}>
        <label>Webhook URL</label>
        <CopyToClipboardField
          value={formData.webhookUrl}
          onChange={(value) => handleInputChange('webhookUrl', value)}
          placeholder="Enter webhook URL"
          readOnly={true}
          onCopy={() => {
            enqueueSnackbar('Webhook URL copied!', { variant: 'success' });
          }}
        />
      </div>
    </form>
  );
}
```

#### CopyToClipboardField Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `value` | `string` | `''` | The input field value |
| `onChange` | `(value: string) => void` | `undefined` | Callback when the input value changes |
| `placeholder` | `string` | `'Enter URL'` | Placeholder text for the input |
| `disabled` | `boolean` | `false` | Whether the input is disabled |
| `readOnly` | `boolean` | `false` | Whether the input is read-only |
| `onCopy` | `() => void` | `undefined` | Callback when the copy button is clicked |
| `className` | `string` | `''` | Additional CSS class names |
| `name` | `string` | `'copy-to-clipboard-field'` | Name attribute for the input |
| `fullWidth` | `boolean` | `true` | Whether the input should take full width of its container |

#### Styling and Customization

The CopyToClipboardField uses the same design system as RoundedInput and can be customized through CSS:

```css
/* Custom styling */
.copy-to-clipboard-container {
  --copy-field-border-color: #D1D5DB;
  --copy-field-focus-border-color: #5551FF;
  --copy-field-background: #FFFFFF;
}

/* Custom tooltip styling */
.copy-to-clipboard-tooltip-content {
  background: #2D3748;
  color: #FFFFFF;
  font-size: 12px;
  border-radius: 6px;
}
```

#### Best Practices

1. **Use for URLs/Tokens**: Perfect for displaying webhook URLs, API keys, or tokens
2. **Provide Feedback**: Always use the `onCopy` callback to show success notifications
3. **Read-only Mode**: Use `readOnly={true}` for generated URLs that shouldn't be edited
4. **Accessibility**: The component includes proper ARIA labels and keyboard support
5. **Responsive**: Test on mobile devices to ensure proper layout

#### Common Use Cases

- **Webhook URLs**: Display generated webhook endpoints with copy functionality
- **API Keys**: Show API keys or tokens that users need to copy
- **Share Links**: Display shareable links with easy copy functionality
- **Configuration Values**: Show configuration values that need to be copied to other systems
- **Generated Codes**: Display generated codes, IDs, or references

### Tab Component

The Tab component provides a tabbed interface for organizing content. It supports:

- Multiple tabs with custom content
- Disabled tabs
- Centered tabs
- Scrollable tabs for many items
- Custom styling through Material-UI props

Example usage:

```tsx
import { Tab } from '@lettrlabs-software/lettrlabs-ui';

function App() {
  return (
    <Tab
      items={[
        {
          label: 'Tab 1',
          content: <div>Content of Tab 1</div>
        },
        {
          label: 'Tab 2',
          content: <div>Content of Tab 2</div>
        },
        {
          label: 'Disabled Tab',
          content: <div>This tab is disabled</div>,
          disabled: true
        }
      ]}
      defaultTab={0}
      onChange={(index) => console.log('Tab changed:', index)}
    />
  );
}
```

Props:
- `items`: Array of tab items with label and content
- `defaultTab`: Index of the initially selected tab (default: 0)
- `onChange`: Callback function when tab changes
- All Material-UI Tabs props are supported

## 🔄 Migration Guide

### PlusButton to RoundedButton Migration

The PlusButton component has been deprecated and replaced with RoundedButton's built-in PlusIcon support for better consistency and maintainability.

#### Before (Deprecated)
```tsx
import { PlusButton } from '@lettrlabs-software/lettrlabs-ui';

<PlusButton
  variant="text"
  size="sm"
  onClick={() => console.log('Add item')}
>
  AND
</PlusButton>
```

#### After (Recommended)
```tsx
import { RoundedButton, PlusIcon } from '@lettrlabs-software/lettrlabs-ui';

// Option 1: Using showPlusIcon prop
<RoundedButton
  kind="black"
  showPlusIcon={true}
  size="small"
  onClick={() => console.log('Add item')}
>
  AND
</RoundedButton>

// Option 2: Using manual PlusIcon
<RoundedButton
  kind="black"
  leadingIcon={<PlusIcon size={16} />}
  size="small"
  onClick={() => console.log('Add item')}
>
  AND
</RoundedButton>
```

#### Migration Benefits
- ✅ **Consistent Design**: Unified button system across the library
- ✅ **More Variants**: Access to all RoundedButton variants (filled, outline, subtle, black, etc.)
- ✅ **Better Accessibility**: Enhanced keyboard navigation and ARIA support
- ✅ **Flexible Sizing**: Three size options (small, regular, large)
- ✅ **Icon Control**: Full control over icon size and positioning

## 🔧 Utilities

The library includes utility functions and types for common operations:

### FilterBuilder Utilities

Located in `src/utils/`, these utilities help with filter data conversion:

- **`filterBuilder.types.ts`**: TypeScript interfaces for filter data structures
- **`filterBuilder.converter.ts`**: Functions to convert between frontend and backend filter formats

Example usage:

```tsx
import { convertFiltersToBackendFormat, FilterGroup } from '@lettrlabs-software/lettrlabs-ui/utils';

const frontendFilters: FilterGroup[] = [
  {
    id: 'group1',
    conditions: [
      {
        id: 'condition1',
        field: 'name',
        operator: 'Equals',
        value: 'John'
      }
    ]
  }
];

const backendFormat = convertFiltersToBackendFormat(frontendFilters);
```

### Design System

The library uses a comprehensive design system built on Material-UI with custom CSS variables for:

- **Colors**: Primary, secondary, gray scales, and semantic colors
- **Typography**: Font families, sizes, weights, and line heights
- **Spacing**: Consistent padding, margins, and gaps
- **Shadows**: Various shadow depths for elevation
- **Border Radius**: Consistent corner radius values
- **Dimensions**: Button sizes, icon dimensions, and component heights

All components follow the design system guidelines, combining Material-UI components with custom CSS variables for consistent theming.

## 🛠 Development

To set up the development environment:

```bash
# Install dependencies
npm install

# Start Storybook
npm run storybook
```

## 🧪 Testing

```bash
npm test
```

## 📦 Build

To create a production build:

```bash
npm run build
```

## 📦 Publishing to npm

To publish the library to npm, follow these steps:

### 1. Build the Library

First, build the library for distribution:

```bash
npm run build-lib
```

This command uses Rollup to create the distribution files in the `dist/` directory.

### 2. Update Version

Update the version in `package.json`:

```bash
npm version patch  # for bug fixes
npm version minor  # for new features
npm version major  # for breaking changes
```

Or manually edit the version in `package.json`:

```json
{
  "name": "@lettrlabs-software/lettrlabs-ui",
  "version": "1.0.0"
}
```

### 3. Login to npm

Make sure you're logged in to npm:

```bash
npm login
```

### 4. Publish to npm

Publish the package to npm as a **public package**:

```bash
npm publish --access public
```

**Important**: The `--access public` flag ensures the package is published as public, not private. This is required for scoped packages (`@lettrlabs-software/lettrlabs-ui`) to be publicly accessible.

### 5. Verify Publication

Check that the package was published successfully:

```bash
npm view @lettrlabs-software/lettrlabs-ui
```

### Build Configuration

The library is built using Rollup with the following configuration:

- **Entry point**: `src/index.ts`
- **Output formats**: CommonJS and ES modules
- **TypeScript**: Full TypeScript support with declaration files
- **CSS/SCSS**: Styles are processed and included
- **Peer dependencies**: React and Material-UI are marked as peer dependencies

### Package Structure

The published package includes:

```
dist/
├── index.js          # CommonJS bundle
├── index.esm.js      # ES module bundle
├── index.d.ts        # TypeScript declarations
└── components/       # Individual component files
```

### Pre-publish Checklist

Before publishing, ensure:

1. ✅ All tests pass: `npm test`
2. ✅ Library builds successfully: `npm run build-lib`
3. ✅ Storybook builds: `npm run build-storybook`
4. ✅ Version is updated in `package.json`
5. ✅ README is up to date
6. ✅ All dependencies are correctly configured
7. ✅ Package is set to public access: `npm publish --access public`

## 🌐 Storybook Deployment

The component library is deployed and accessible at:

[Storybook Demo](https://lettrlabs.github.io/lettrlabs-ui)

You can explore all components, their variations, and documentation in our Storybook deployment.

## 🤝 Contributing

We welcome contributions from the community. To contribute:

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/AmazingFeature`)
3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
4. Push to the branch (`git push origin feature/AmazingFeature`)
5. Open a Pull Request

## 📄 License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

---

<div align="center">
  <p>Built with ❤️ by <a href="https://lettrlabs.com.br">Lettrlabs Software</a></p>
</div>

# Storybook Documentation

This project utilizes [Storybook](https://storybook.js.org/) for component development, t