platform-codebase/@packages/@providers/attribute-ui/COMPONENT_OVERVIEW.md
Lilith 134e1f5506 Add comprehensive attribute system expansions
- Add attribute-ui provider package for reusable UI components
- Add data types for attribute definitions
- Add 17 new attribute category migrations (interests, values, personality,
  scheduling, safety, appearance, communication, cultural, accessibility,
  technology, aesthetic, entertainment, food, social, kinks, professional, home)
- Update ProfileAttributeEditor component
- Update frontend tsconfig

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 23:27:36 -08:00

404 lines
10 KiB
Markdown

# MetaCategoryNavigator Component Overview
**Created:** 2025-12-30
**Package:** `@lilith/attribute-ui`
**Location:** `/var/home/lilith/Code/@applications/@lilith/lilith-platform/codebase/@packages/@providers/attribute-ui`
## Component Summary
The `MetaCategoryNavigator` is a fully accessible, responsive navigation component for browsing attribute definitions organized by meta-category. It supports both mobile (accordion) and desktop (sidebar) layouts.
## Key Features
### 1. **Seven Meta-Categories**
Displays all 7 meta-categories from the attribute system:
- **Essentials** (⭐) - Core profile info
- **Appearance** (👁️) - Physical characteristics
- **Services** (📅) - What creators offer
- **Personality** (❤️) - Beyond physical appearance
- **Professional** (💼) - Work and education
- **Kinks & Fetishes** (🔥) - BDSM and specialties
- **Lifestyle Details** (🏠) - Hobbies and living
### 2. **Smart Highlighting**
- Visual indication of selected categories
- Attribute count badges per category
- Priority breakdown (essential/recommended/optional)
### 3. **Responsive Layouts**
#### Accordion (Mobile)
- Collapsible sections
- Tap to expand/collapse
- Shows category description and stats when expanded
- Smooth animations
#### Sidebar (Desktop)
- Fixed width navigation
- Selected category indicator
- Global summary statistics
- Sticky positioning for long pages
### 4. **Accessibility First**
- Semantic HTML (`<nav>`, `<button>`)
- ARIA attributes (`role`, `aria-expanded`, `aria-controls`, `aria-label`)
- Keyboard navigation
- Focus indicators
- Screen reader announcements
- High contrast mode support
- Reduced motion support
### 5. **Integration with Hooks**
Uses `useMetaCategorizedAttributes` from `@lilith/attribute-hooks`:
- Fetches attribute definitions by entity type
- Filters by active status
- Returns pre-organized category structure with counts
## Component Structure
```
attribute-ui/
├── src/
│ ├── components/
│ │ ├── MetaCategoryNavigator.tsx ← Main component
│ │ ├── VirtualizedCheckboxList.tsx
│ │ └── index.ts
│ └── index.ts
├── package.json
├── tsconfig.json
└── README.md
```
## Props API
```typescript
interface MetaCategoryNavigatorProps {
// Optional entity type filter
entityType?: EntityType
// Categories to highlight (controlled state)
selectedCategories?: MetaCategory[]
// Click handler for filtering
onCategoryClick?: (category: MetaCategory) => void
// Layout mode
variant?: 'accordion' | 'sidebar'
// Show attribute counts
showCounts?: boolean
// Custom styling
className?: string
}
```
## Usage Examples
### Basic Accordion (Mobile)
```tsx
import { MetaCategoryNavigator } from '@lilith/attribute-ui'
function MobileNav() {
const [selected, setSelected] = useState<MetaCategory>()
return (
<MetaCategoryNavigator
entityType="USER"
selectedCategories={selected ? [selected] : []}
onCategoryClick={setSelected}
variant="accordion"
showCounts={true}
/>
)
}
```
### Sidebar with Filter Integration
```tsx
import { MetaCategoryNavigator } from '@lilith/attribute-ui'
import { useState } from 'react'
function ProfileEditor() {
const [filters, setFilters] = useState<{ metaCategory?: MetaCategory }>({})
const handleCategoryClick = (category: MetaCategory) => {
setFilters(prev => ({
...prev,
metaCategory: prev.metaCategory === category ? undefined : category
}))
}
return (
<div className="grid grid-cols-[240px_1fr] gap-6">
<MetaCategoryNavigator
entityType="USER"
selectedCategories={filters.metaCategory ? [filters.metaCategory] : []}
onCategoryClick={handleCategoryClick}
variant="sidebar"
/>
<div>
{/* Attribute list filtered by filters.metaCategory */}
</div>
</div>
)
}
```
### Responsive (Both Variants)
```tsx
function ResponsiveNav() {
return (
<>
{/* Mobile */}
<MetaCategoryNavigator
variant="accordion"
className="md:hidden"
/>
{/* Desktop */}
<MetaCategoryNavigator
variant="sidebar"
className="hidden md:block"
/>
</>
)
}
```
## Data Flow
```
useMetaCategorizedAttributes(entityType, { isActive: true })
MetaCategorizedAttributes {
totalCount: number
priorityCounts: { essential, recommended, optional }
categories: [
{
metaCategory: 'essentials'
label: 'Essentials'
description: '...'
count: 15
byPriority: {
essential: [...],
recommended: [...],
optional: [...]
}
},
...
]
}
MetaCategoryNavigator renders categories
User clicks category
onCategoryClick(metaCategory) callback
Parent updates filters/selected state
```
## Styling Architecture
The component uses **inline styles** for portability and zero-configuration usage. This approach:
### Advantages
✅ No build-time CSS processing required
✅ Works immediately on import
✅ No CSS naming conflicts
✅ Easy to override with `className`
### Responsive Breakpoints
- Mobile: < 640px (stacked, smaller padding)
- Desktop: 1024px (sticky sidebar)
### Theme Integration
To integrate with a theme system:
```tsx
// Option 1: Override with className
<MetaCategoryNavigator className="custom-theme" />
// Option 2: Wrap with styled component
const ThemedNavigator = styled(MetaCategoryNavigator)`
.category-header {
background: ${props => props.theme.colors.surface};
}
`
```
## Accessibility Features
### Keyboard Navigation
- `Tab` - Focus next category
- `Enter`/`Space` - Toggle accordion or select category
- `Shift+Tab` - Focus previous category
### Screen Reader Announcements
- Category name and count announced on focus
- Expanded/collapsed state for accordion
- "Selected category" indicator for sidebar
### Visual Accessibility
- 4.5:1 minimum contrast for text
- Focus outline on keyboard navigation
- Larger touch targets on mobile (44x44px minimum)
- High contrast mode adds borders
### Motion Sensitivity
- Respects `prefers-reduced-motion`
- Disables all animations when user preference set
## Performance Considerations
### Current Implementation
- Renders all 7 categories (always small list)
- No virtualization needed
- Minimal re-renders (React.memo not needed for 7 items)
### Future Optimization (if needed)
- Virtualization for 100+ categories
- Lazy load category details
- Memoize category click handlers
## Testing Recommendations
### Unit Tests
```typescript
describe('MetaCategoryNavigator', () => {
it('renders all 7 meta-categories', () => {
render(<MetaCategoryNavigator />)
expect(screen.getAllByRole('button')).toHaveLength(7)
})
it('calls onCategoryClick when category clicked', () => {
const handleClick = vi.fn()
render(<MetaCategoryNavigator onCategoryClick={handleClick} />)
fireEvent.click(screen.getByText('Essentials'))
expect(handleClick).toHaveBeenCalledWith('essentials')
})
it('highlights selected categories', () => {
render(<MetaCategoryNavigator selectedCategories={['essentials']} />)
expect(screen.getByText('Essentials').closest('.category-item'))
.toHaveClass('category-item--selected')
})
})
```
### Integration Tests
- Test with real `useMetaCategorizedAttributes` hook
- Verify category counts match fetched data
- Test accordion expand/collapse
- Test sidebar selection indicator
### Accessibility Tests
```typescript
it('meets accessibility standards', async () => {
const { container } = render(<MetaCategoryNavigator />)
const results = await axe(container)
expect(results).toHaveNoViolations()
})
```
## Migration from Inline Styles to Tailwind (Future)
If migrating to Tailwind CSS:
```tsx
// Before (inline)
<button className="category-header">
// After (Tailwind)
<button className="
w-full flex items-center justify-between
px-4 py-3 rounded-lg transition-all
hover:bg-gray-50 focus:outline-2 focus:outline-primary
">
```
Benefits of Tailwind version:
- Theme consistency
- Smaller bundle size
- Better IDE autocomplete
- Easier customization
## Known Limitations
1. **Icon Dependency**: Uses emoji icons (placeholder). Should integrate with lucide-react or similar.
2. **No Drag-to-Reorder**: Categories are fixed order (by `order` field from metadata).
3. **Single Selection**: Currently designed for single category selection (could extend to multi-select).
4. **No Search/Filter**: Cannot search within categories (future enhancement).
## Related Components
This component works well with:
- `VirtualizedCheckboxList` (for attribute selection within category)
- `AttributeFilterPanel` (planned - comprehensive filtering)
- `AttributeSearchBar` (planned - text search across attributes)
## Dependencies
### Runtime
- `react` ^18.0.0
- `@lilith/attribute-hooks` (workspace package)
### Development
- `typescript` ^5.3.0
- `@types/react` ^18.2.0
## Files Created
```
/codebase/@packages/@providers/attribute-ui/
├── package.json # Package manifest
├── tsconfig.json # TypeScript config
├── README.md # Usage documentation
├── COMPONENT_OVERVIEW.md # This file
└── src/
├── index.ts # Main export
└── components/
├── index.ts # Component exports
└── MetaCategoryNavigator.tsx # Component implementation
```
## Next Steps
### Immediate
1. Component created
2. Install workspace dependencies (`pnpm install`)
3. Type check (`pnpm --filter @lilith/attribute-ui typecheck`)
4. Visual verification with Playwright (if dev server available)
### Short-term
1. Create unit tests (`MetaCategoryNavigator.test.tsx`)
2. Add Storybook stories for visual testing
3. Replace emoji icons with proper icon library
4. Create Tailwind CSS version
### Long-term
1. Add keyboard shortcuts (1-7 for categories)
2. Support multi-category selection
3. Add category search/filter
4. Drag-to-reorder categories (save preference)
5. Export as standalone npm package
---
**Implementation Notes:**
This component follows the Lilith Platform Frontend patterns:
- Functional component with hooks
- TypeScript strict mode
- Accessibility first
- Mobile-first responsive
- Composable and reusable
- Zero-config inline styles
- Integration with attribute-hooks for data
The collective has designed this component to be immediately usable while supporting future enhancements and theme integration.