Files
archy/.cursor/rules/08-renderer-development.mdc
T
Dorian c28e6dd811 feat: initialize AIUI monorepo with project rules and core types
Foundation for the next-generation AI content surface UI:
- 16 Cursor rules files covering philosophy, Vue conventions, design system,
  content surfaces, plugin system, AI integration, renderers, security,
  Bitcoin-only policy, dev/prod modes, accessibility, performance, animation,
  mobile UX, and git workflow
- pnpm workspaces + Turborepo monorepo (@aiui/core, @aiui/app)
- Vue 3 + Vite + TypeScript + Tailwind CSS 4
- Core type system: plugins, renderers, messages, content blocks
- Plugin registry with renderer registration
- 50 mock film fixtures with search/filter utilities
- App shell with chat page layout
- Environment config templates

Made-with: Cursor
2026-03-02 14:15:39 +00:00

81 lines
2.6 KiB
Plaintext

---
description: How to build content renderers - interfaces, lazy loading, accessibility
globs: "**/renderers/**"
alwaysApply: false
---
# Renderer Development
## What is a Renderer?
A renderer is a set of Vue components that know how to display a specific content type across the five content surfaces (chat-preview, chat-play, panel-preview, panel-play, panel-edit).
## Renderer Registration
```typescript
import { registerRenderer } from '@aiui/core'
registerRenderer({
id: 'film',
name: 'Film',
contentType: 'application/x-aiui-film',
surfaces: ['chat-preview', 'panel-preview', 'panel-play'],
chatPreview: () => import('./FilmChatPreview.vue'),
panelPreview: () => import('./FilmGrid.vue'),
panelPlay: () => import('./FilmDetail.vue'),
})
```
## Content Type Detection
Renderers are matched to content by `contentType` field in the message data:
```typescript
interface ContentBlock {
contentType: string // e.g., 'application/x-aiui-film'
data: Record<string, unknown> // renderer-specific data
title?: string // human-readable title for panel tab
}
```
## Performance Rules
1. Chat surfaces (preview, play) must render with ZERO lazy-loaded heavy dependencies
2. Panel surfaces may lazy-load libraries (CodeMirror, pdf.js, etc.)
3. Use `defineAsyncComponent` for panel components
4. Show skeleton/placeholder while loading
5. Never block the main thread — use Web Workers for heavy parsing
## Data Contracts
Each renderer defines its expected data shape as a TypeScript interface:
```typescript
interface FilmRendererData {
films: Film[]
query?: string
filters?: FilmFilters
}
```
Document the interface. Validate incoming data. Show graceful error if data is malformed.
## Accessibility Requirements
- All renderers must be keyboard navigable
- Images need alt text
- Interactive elements need ARIA labels
- Media players need captions/transcripts when available
- Focus management when transitioning between surfaces
## Mobile Behavior
- Chat Preview: constrained to message bubble width
- Chat Play: full message width, max 200px height
- Panel surfaces on mobile: full-screen overlay with back gesture
- Touch targets: minimum 44x44px
- Swipe gestures where appropriate (image gallery, film cards)
## Renderer Checklist
- [ ] TypeScript data interface defined and exported
- [ ] All applicable surfaces implemented
- [ ] Lazy loading for heavy dependencies
- [ ] Skeleton/placeholder states
- [ ] Error state (malformed data)
- [ ] Empty state (no data)
- [ ] Keyboard navigation
- [ ] ARIA labels on interactive elements
- [ ] Mobile responsive
- [ ] Dark mode compatible
- [ ] Transition animations (per motion design rules)