# @lilith/attribute-ui React UI components for attribute navigation and filtering with virtualization support for large datasets. ## Features - **VirtualizedCheckboxList**: Windowed checkbox list using `@tanstack/react-virtual` for rendering 200+ enum options efficiently - **MetaCategoryNavigator**: Navigation component for attribute meta-categories - Built with TypeScript for full type safety - Tailwind CSS support for easy styling customization - Accessibility-first design with ARIA labels and keyboard navigation ## Components ### VirtualizedCheckboxList A high-performance checkbox list component that uses windowing to efficiently render large lists of options (200+ items). **Features:** - ✅ Virtualized rendering for optimal performance with large datasets - ✅ Built-in search/filter functionality - ✅ Select All / Clear All actions - ✅ Selected count display - ✅ Accessible keyboard navigation - ✅ Tailwind CSS styling - ✅ TypeScript support **Basic Usage:** ```tsx import { VirtualizedCheckboxList } from '@lilith/attribute-ui'; import { useState } from 'react'; function AttributeSelector() { const [selectedValues, setSelectedValues] = useState([]); const options = [ { label: 'Option 1', value: 'opt1' }, { label: 'Option 2', value: 'opt2' }, // ... 200+ more options ]; return ( ); } ``` **With Enum Values from AttributeDefinition:** ```tsx import { VirtualizedCheckboxList, CheckboxOption } from '@lilith/attribute-ui'; import { useAttributeDefinitions } from '@lilith/attribute-hooks'; import { useState, useMemo } from 'react'; function EnumAttributeSelector({ attributeCode }: { attributeCode: string }) { const [selectedValues, setSelectedValues] = useState([]); const { data: definitions } = useAttributeDefinitions({ entityType: 'user' }); const options: CheckboxOption[] = useMemo(() => { const definition = definitions?.find((def) => def.code === attributeCode); if (!definition?.enumValues) return []; return definition.enumValues.map((value) => ({ label: value, value: value, })); }, [definitions, attributeCode]); return ( ); } ``` **Advanced Customization:** ```tsx ``` **Props:** | Prop | Type | Default | Description | |------|------|---------|-------------| | `options` | `CheckboxOption[]` | required | Array of checkbox options with `label` and `value` | | `selectedValues` | `string[]` | required | Currently selected values | | `onSelectionChange` | `(values: string[]) => void` | required | Callback when selection changes | | `itemHeight` | `number` | `40` | Height of each item in pixels | | `containerHeight` | `number` | `400` | Total height of scrollable container in pixels | | `searchPlaceholder` | `string` | `"Search..."` | Placeholder text for search input | | `selectAllLabel` | `string` | `"Select All"` | Label for "Select All" button | | `clearAllLabel` | `string` | `"Clear All"` | Label for "Clear All" button | | `className` | `string` | `""` | Additional CSS classes for container | | `showSelectedCount` | `boolean` | `true` | Whether to show selected count | **Types:** ```typescript interface CheckboxOption { label: string; value: string; } interface VirtualizedCheckboxListProps { options: CheckboxOption[]; selectedValues: string[]; onSelectionChange: (selectedValues: string[]) => void; itemHeight?: number; containerHeight?: number; searchPlaceholder?: string; selectAllLabel?: string; clearAllLabel?: string; className?: string; showSelectedCount?: boolean; } ``` **Performance:** The component is optimized for large datasets: - **Windowing**: Only renders visible items + overscan buffer (default: 5 items) - **Memoization**: Filtered options and callbacks are memoized to prevent unnecessary re-renders - **Virtual scrolling**: Handles 200+ items with smooth scrolling performance - **Search optimization**: Case-insensitive filtering with instant feedback --- ### MetaCategoryNavigator Browseable navigation for attributes organized by meta-category. Supports accordion (mobile) and sidebar (desktop) layouts with highlighting for active filters and attribute counts. **Features:** - 7 meta-categories with icons and descriptions - Attribute counts per category and priority - Mobile-first responsive design - Accessible keyboard navigation - Support for `prefers-reduced-motion` and `prefers-contrast` - Click handlers for category filtering **Usage:** ```tsx import { MetaCategoryNavigator } from '@lilith/attribute-ui' function ProfileEditor() { const [selectedCategory, setSelectedCategory] = useState() return (
{/* Mobile: Accordion */} {/* Desktop: Sidebar */}
{/* Filtered attributes based on selectedCategory */}
) } ``` **Props:** | Prop | Type | Default | Description | |------|------|---------|-------------| | `entityType` | `EntityType` | `undefined` | Entity type to fetch attributes for (optional for all) | | `selectedCategories` | `MetaCategory[]` | `[]` | Currently selected meta-categories for highlighting | | `onCategoryClick` | `(category: MetaCategory) => void` | `undefined` | Callback when category is clicked | | `variant` | `'accordion' \| 'sidebar'` | `'accordion'` | Layout variant | | `showCounts` | `boolean` | `true` | Show attribute counts | | `className` | `string` | `''` | Custom className for styling | **Meta-Categories:** 1. **Essentials** (⭐) - Core profile info (demographics, verification, pricing) 2. **Appearance** (👁️) - Physical characteristics and style 3. **Services** (📅) - What you offer and when 4. **Personality** (❤️) - Who you are beyond looks 5. **Professional** (💼) - Work and education 6. **Kinks & Fetishes** (🔥) - BDSM, fetishes, specialties 7. **Lifestyle Details** (🏠) - Living, hobbies, entertainment **Accessibility:** - Semantic HTML (`