Built a complete Netflix-style streaming interface for IndeeHub's decentralized media platform with real film content. Features: - Vue 3 + TypeScript + Vite setup with hot module reloading - Netflix-inspired UI with hero section and horizontal scrolling content rows - Glass morphism design system with custom Tailwind configuration - 20+ real IndeeHub films organized into 6 categories (Bitcoin, Documentaries, Drama, etc.) - Full-featured video player component with custom controls - Mobile-responsive design with bottom navigation - Nostr integration ready (nostr-tools, relay pool, NIP-71 support) - Pinia state management for content - MCP tools configured (Filesystem, Memory, Nostr, Puppeteer) Components: - Browse.vue: Main streaming interface with hero and content rows - ContentRow.vue: Horizontal scrolling film cards with navigation arrows - VideoPlayer.vue: Custom video player with play/pause, seek, volume, fullscreen - MobileNav.vue: Bottom tab navigation for mobile devices Tech Stack: - Frontend: Vue 3 (Composition API), TypeScript - Build: Vite 7 - Styling: Tailwind CSS with custom theme - State: Pinia 3 - Router: Vue Router 4.6 - Protocol: Nostr (nostr-tools 2.22) Design: - 4px grid spacing system - Glass morphism UI components - Netflix-style hero section with featured content - Smooth animations and hover effects - Mobile-first responsive breakpoints - Dark theme with custom color palette Content: - 20+ IndeeHub films with titles, descriptions, categories - Bitcoin documentaries: God Bless Bitcoin, Dirty Coin, Searching for Satoshi - Independent films and documentaries - Working Unsplash CDN images for thumbnails and backdrops Ready for deployment to Umbrel, Start9, and Archy nodes. Co-authored-by: Cursor <cursoragent@cursor.com>
80 lines
2.0 KiB
Plaintext
80 lines
2.0 KiB
Plaintext
---
|
|
description: Component composition patterns and architecture principles
|
|
alwaysApply: false
|
|
globs: **/*.{ts,tsx,js,jsx,vue,svelte}
|
|
---
|
|
|
|
# Component Architecture & Composition Patterns
|
|
|
|
## Core Philosophy
|
|
|
|
**Composition Over Configuration**
|
|
|
|
Build complex UIs from simple, focused components that compose well together.
|
|
|
|
### Key Tenets
|
|
|
|
- **Single Responsibility**: Each component does one thing well
|
|
- **Composition Slots**: Use children/slots instead of complex prop APIs
|
|
- **Default Props**: Provide sensible defaults for easy use
|
|
- **Prop Interfaces**: Clear contracts with TypeScript/PropTypes
|
|
- **Minimal State**: Keep component state local and minimal
|
|
|
|
## Anti-patterns to Avoid
|
|
|
|
- ❌ God components that do everything
|
|
- ❌ Prop drilling through many layers
|
|
- ❌ Hard-coded values instead of props
|
|
- ❌ Component logic mixed with layout
|
|
- ❌ Tight coupling between components
|
|
|
|
## Template Pattern
|
|
|
|
Create base templates that handle common layouts and let content be injected.
|
|
|
|
```jsx
|
|
const PageTemplate = ({ title, children }) => (
|
|
<div className="page-container">
|
|
<Header />
|
|
<main className="page-content">
|
|
{title && <h1>{title}</h1>}
|
|
{children}
|
|
</main>
|
|
<Footer />
|
|
</div>
|
|
);
|
|
```
|
|
|
|
## Container/Presenter Pattern
|
|
|
|
Split components into smart (containers) and dumb (presenters) components.
|
|
|
|
- **Container**: Handles data and logic
|
|
- **Presenter**: Pure presentation, receives data via props
|
|
|
|
## Prop Interface Design
|
|
|
|
```typescript
|
|
interface BaseComponentProps {
|
|
className?: string;
|
|
children?: React.ReactNode;
|
|
testId?: string;
|
|
}
|
|
|
|
interface ButtonProps extends BaseComponentProps {
|
|
variant?: 'primary' | 'secondary' | 'ghost';
|
|
size?: 'sm' | 'md' | 'lg';
|
|
disabled?: boolean;
|
|
loading?: boolean;
|
|
onClick?: (event: React.MouseEvent) => void;
|
|
}
|
|
```
|
|
|
|
### Prop Naming Conventions
|
|
|
|
- Boolean props: `isOpen`, `hasError`, `disabled`
|
|
- Handler props: `onClick`, `onClose`, `onChange`
|
|
- Render props: `renderHeader`, `renderItem`
|
|
- Data props: `items`, `data`, `value`
|
|
- Config props: `variant`, `size`, `theme`
|