Keep/docs/component-inventory.md
sepehr 640fcb26f7 fix: improve note interactions and markdown LaTeX support
## Bug Fixes

### Note Card Actions
- Fix broken size change functionality (missing state declaration)
- Implement React 19 useOptimistic for instant UI feedback
- Add startTransition for non-blocking updates
- Ensure smooth animations without page refresh
- All note actions now work: pin, archive, color, size, checklist

### Markdown LaTeX Rendering
- Add remark-math and rehype-katex plugins
- Support inline equations with dollar sign syntax
- Support block equations with double dollar sign syntax
- Import KaTeX CSS for proper styling
- Equations now render correctly instead of showing raw LaTeX

## Technical Details

- Replace undefined currentNote references with optimistic state
- Add optimistic updates before server actions for instant feedback
- Use router.refresh() in transitions for smart cache invalidation
- Install remark-math, rehype-katex, and katex packages

## Testing

- Build passes successfully with no TypeScript errors
- Dev server hot-reloads changes correctly
2026-01-09 22:13:49 +01:00

425 lines
10 KiB
Markdown

# Component Inventory - keep-notes
## Overview
Complete inventory of React components in the Memento web application. The application uses 20+ domain-specific components organized by functionality.
**Total Components:** 20+
**UI Library:** Radix UI
**Icons:** Lucide React
---
## Component Categories
### 1. Authentication Components
| Component | File | Purpose | Props |
|-----------|------|---------|-------|
| **LoginForm** | `login-form.tsx` | User login form | email, password, handleSubmit |
| **RegisterForm** | `register-form.tsx` | User registration | name, email, password, confirmPassword |
**Usage:** Used in `(auth)/login` and `(auth)/register` routes
---
### 2. Note Components
| Component | File | Purpose | Props |
|-----------|------|---------|-------|
| **NoteCard** | `note-card.tsx` | Individual note display | note, onPin, onArchive, onUpdate, onDelete |
| **NoteEditor** | `note-editor.tsx` | Rich note editor | note, onChange, onSave |
| **NoteInput** | `note-input.tsx` | Quick note creation | onCreate, autoFocus |
| **NoteActions** | `note-actions.tsx` | Note action menu | note, onEdit, onPin, onArchive, onDelete |
| **NoteChecklist** | `note-checklist.tsx` | Checklist items | items, onChange, onToggle |
| **NoteImages** | `note-images.tsx` | Image gallery | images, onAdd, onRemove |
| **EditorImages** | `editor-images.tsx` | Image upload/edit | images, onChange |
**Features:**
- Drag-and-drop support via @dnd-kit
- Color-coded backgrounds
- Markdown rendering support
- Checklist with checkbox items
- Image attachments (base64 or URL)
- Pin/unpin functionality
- Archive/unarchive
---
### 3. Label Components
| Component | File | Purpose | Props |
|-----------|------|---------|-------|
| **LabelBadge** | `label-badge.tsx` | Label display badge | label, onRemove, color |
| **LabelFilter** | `label-filter.tsx` | Filter by labels | labels, selectedLabels, onChange |
| **LabelSelector** | `label-selector.tsx` | Select labels for note | availableLabels, selectedLabels, onChange |
| **LabelManager** | `label-manager.tsx` | Manage user labels | labels, onCreate, onUpdate, onDelete |
| **LabelManagementDialog** | `label-management-dialog.tsx` | Label management modal | isOpen, onClose, labels |
| **GhostTags** | `ghost-tags.tsx` | Floating tag display | tags, onTagClick |
**Color Options:** red, orange, yellow, green, teal, blue, purple, pink, gray
---
### 4. Layout Components
| Component | File | Purpose | Props |
|-----------|------|---------|-------|
| **Header** | `header.tsx` | Application header | title, user |
| **HeaderWrapper** | `header-wrapper.tsx` | Header container with logic | children, user |
| **Sidebar** | `sidebar.tsx` | Navigation sidebar | isOpen, onClose |
| **MasonryGrid** | `masonry-grid.tsx` | Masonry grid layout | items, renderItem |
**Layout Libraries:**
- Muuri (masonry grid)
- react-grid-layout
- @dnd-kit (drag and drop)
---
### 5. Content Components
| Component | File | Purpose | Props |
|-----------|------|---------|-------|
| **MarkdownContent** | `markdown-content.tsx` | Markdown renderer | content, className |
**Features:**
- GitHub Flavored Markdown (GFM)
- Syntax highlighting (if configured)
- Safe rendering (sanitization)
---
### 6. User Components
| Component | File | Purpose | Props |
|-----------|------|---------|-------|
| **UserNav** | `user-nav.tsx` (inferred) | User navigation menu | user, onLogout |
**Features:**
- Profile settings access
- Logout functionality
- Theme toggle
---
### 7. Dialog/Modal Components
| Component | File | Purpose | Props |
|-----------|------|---------|-------|
| **ReminderDialog** | `reminder-dialog.tsx` | Set note reminders | note, onSave, onClose |
**Features:**
- Date/time picker
- Recurrence options
- Location-based reminders (future)
---
### 8. UI Primitives (Radix UI)
Located in `components/ui/` - Auto-generated or minimal wrappers around Radix UI:
| Component | Radix Primitive | Purpose |
|-----------|----------------|---------|
| Avatar | @radix-ui/react-avatar | User avatar display |
| Checkbox | @radix-ui/react-checkbox | Checkbox input |
| Dialog | @radix-ui/react-dialog | Modal dialogs |
| Dropdown Menu | @radix-ui/react-dropdown-menu | Dropdown menus |
| Popover | @radix-ui/react-popover | Floating content |
| Separator | @radix-ui/react-separator | Visual separators |
| Slot | @radix-ui/react-slot | Component composition |
| Tooltip | @radix-ui/react-tooltip | Hover tooltips |
**Usage:** Domain components compose these primitives
---
## Component Hierarchy
```
Layout Components
├── Header → HeaderWrapper
│ └── UserNav
├── Sidebar
└── MasonryGrid
└── NoteCard
├── NoteEditor
│ ├── NoteChecklist
│ ├── NoteImages
│ └── EditorImages
└── NoteActions
Label Management
├── LabelBadge
├── LabelFilter
├── LabelSelector
├── LabelManager → LabelManagementDialog
└── GhostTags
Authentication
├── LoginForm
└── RegisterForm
Content
└── MarkdownContent
```
---
## Component Patterns
### 1. Compound Components
**NoteEditor** contains:
- NoteChecklist (if type=checklist)
- NoteImages
- EditorImages
**HeaderWrapper** wraps:
- Header
- UserNav
### 2. Controlled Components
Most components are controlled (parent state):
- NoteCard receives note object and callbacks
- LabelFilter receives selected labels and onChange
- NoteEditor manages local state, calls onSave
### 3. Modal Pattern
Dialogs use Radix Dialog:
- LabelManagementDialog
- ReminderDialog
Pattern:
```tsx
{isOpen && (
<Dialog open={isOpen} onOpenChange={onClose}>
<DialogContent>{/* content */}</DialogContent>
</Dialog>
)}
```
---
## Component Communication
### Props Drilling
- Components receive data via props
- Callbacks passed for mutations
### Server Actions
- Note mutations via `app/actions/notes.ts`
- Label mutations via server actions
- Auth mutations via `app/actions/register.ts`
### Context Providers
- User session context (from NextAuth)
- Theme context (light/dark mode)
---
## Design System
### Colors
**Note Colors:** default, red, orange, yellow, green, teal, blue, purple, pink, gray
**Label Colors:** Same palette as notes
### Typography
- **Font:** System font stack (Tailwind default)
- **Sizes:** Based on Tailwind typography plugin
### Spacing
- **Gap:** Tailwind spacing scale
- **Padding:** Consistent 4px/8px/16px/24px increments
---
## Component State Management
### Local State
- Form inputs (controlled components)
- Modal open/closed state
- Temporary editing state
### Server State
- Notes list (fetched from API)
- User session (NextAuth)
- Labels (fetched from API)
### State Updates
1. User action → Server action / API call
2. Database update (Prisma)
3. Revalidate / refetch
4. Component re-render
**No Global State Library:** Uses React Context + hooks instead of Redux/Zustand
---
## Component Dependencies
### UI Libraries
- Radix UI (primitives)
- Tailwind CSS (styling)
- Lucide React (icons)
- @dnd-kit (drag and drop)
- Muuri (masonry layout)
- react-grid-layout (grid system)
- react-markdown (markdown rendering)
- react-masonry-css (alternative masonry)
### Custom Hooks
- Located in `hooks/`
- Used for:
- Form validation
- Local storage
- Debouncing
- Media queries
---
## Component Performance
### Optimizations
- React.memo (selective components)
- Lazy loading (dynamic imports)
- Image optimization (next/image)
- Code splitting (route-based)
### Masonry Grid
- Muuri for performant drag-and-drop
- Virtualization for large note lists
---
## Component Testing
### E2E Coverage
- Playwright tests in `tests/`
- Coverage: Component interactions
- Test file: `search-quality.spec.ts`
### Manual Testing
- Test UI in `npm run test:headed`
- Test reports: `playwright-report/`
---
## Component Styling
### CSS Strategy
- **Framework:** Tailwind CSS 4
- **Approach:** Utility-first
- **Custom CSS:** In `globals.css`
- **Component Styles:** Tailwind classes
### Responsive Design
- Mobile-first approach
- Breakpoints: sm, md, lg, xl
- Grid adapts to screen size
### Theme Support
- Light/dark mode via user preference
- Theme stored in `User.theme`
- CSS variables for theme colors
---
## Accessibility
### Radix UI Features
- Keyboard navigation
- ARIA attributes
- Focus management
- Screen reader support
### Custom A11y
- Alt text for images
- Semantic HTML
- Form labels
- Error messages
---
## Component Future Enhancements
**Potential Improvements:**
1. Add skeleton loaders
2. Implement error boundaries
3. Add undo/redo for note edits
4. Rich text editor (WYSIWYG)
5. Collaborative editing
6. Note templates
7. Color picker for custom colors
8. Drag-and-drop file upload
9. Voice input (Web Speech API)
10. Export/import notes
---
## Component Maintenance
**File Organization:**
- Domain-driven (note-*, label-*, auth-*)
- Co-located with related components
- Clear naming conventions
**Code Quality:**
- TypeScript for type safety
- Consistent prop interfaces
- Reusable UI primitives
- Minimal prop drilling (use context where appropriate)
---
## Component Usage Examples
### NoteCard
```tsx
<NoteCard
note={note}
onPin={() => handleTogglePin(note.id)}
onArchive={() => handleToggleArchive(note.id)}
onUpdate={(updates) => handleUpdateNote(note.id, updates)}
onDelete={() => handleDeleteNote(note.id)}
/>
```
### LabelSelector
```tsx
<LabelSelector
availableLabels={labels}
selectedLabels={note.labels || []}
onChange={(newLabels) => updateNoteLabels(note.id, newLabels)}
/>
```
### MasonryGrid
```tsx
<MasonryGrid
items={notes}
renderItem={(note) => <NoteCard key={note.id} note={note} />}
/>
```
---
## Summary
The Memento application uses a well-organized component architecture with:
- **20+ domain components** for notes, labels, auth, and layout
- **Radix UI primitives** for accessible, composable UI
- **Controlled components** with parent-managed state
- **Server actions** for mutations
- **No global state library** (Context + hooks instead)
- **Drag-and-drop** via @dnd-kit
- **Masonry layout** via Muuri
- **Responsive design** with Tailwind CSS