Reorganize documentation: move all docs to /docs subdirectories

Co-authored-by: johndoe6345789 <224850594+johndoe6345789@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-01-17 00:33:02 +00:00
parent dc73b3c3cd
commit 34ca7d2c20
49 changed files with 22 additions and 281 deletions

View File

@@ -0,0 +1,392 @@
# Complete Hook Library Reference
## Overview
The CodeForge hook library provides comprehensive, reusable React hooks organized by domain. All hooks are under 150 LOC, fully typed, and designed for composition.
## Organization
```
src/hooks/
├── data/ # Data management hooks
├── ui/ # UI state management hooks
├── forms/ # Form and validation hooks
├── feature-ideas/ # Feature-specific hooks
├── core/ # Core utility hooks
├── ai/ # AI integration hooks
└── orchestration/ # JSON orchestration hooks
```
## Data Management Hooks
### `useArray<T>(key, defaultValue)`
Enhanced array management with persistence.
**Features:**
- Add/remove items
- Update items with predicates
- Find and filter operations
- Auto-persists to KV store
**Example:**
```typescript
import { useArray } from '@/hooks/data'
const { items, add, remove, update, find, count } = useArray<Todo>('todos', [])
add({ id: '1', text: 'Learn hooks', done: false })
update(
(todo) => todo.id === '1',
(todo) => ({ ...todo, done: true })
)
remove((todo) => todo.done)
```
### `useCRUD<T>(items, setItems)`
Complete CRUD operations for entity management.
**Features:**
- Create, read, update, delete operations
- Selection management
- Duplicate functionality
- Type-safe operations
**Example:**
```typescript
import { useCRUD } from '@/hooks/data'
import { useKV } from '@github/spark/hooks'
const [tasks, setTasks] = useKV('tasks', [])
const {
create,
update,
remove,
selected,
setSelectedId
} = useCRUD(tasks, setTasks)
create({ id: '1', name: 'New Task', status: 'pending' })
update('1', { status: 'completed' })
setSelectedId('1')
```
### `useSearch<T>(items, searchKeys, debounceMs)`
Debounced search across multiple fields.
**Features:**
- Multi-field search
- Debounced input
- Type-safe key selection
- Performance optimized
**Example:**
```typescript
import { useSearch } from '@/hooks/data'
const { query, setQuery, results, isSearching } = useSearch(
users,
['name', 'email', 'role'],
300
)
// In your component
<Input value={query} onChange={(e) => setQuery(e.target.value)} />
{results.map(user => <UserCard key={user.id} user={user} />)}
```
### `useDebounce<T>(value, delay)`
Debounce any value changes.
**Example:**
```typescript
import { useDebounce } from '@/hooks/data'
const [input, setInput] = useState('')
const debouncedInput = useDebounce(input, 500)
useEffect(() => {
// API call with debounced value
fetchResults(debouncedInput)
}, [debouncedInput])
```
### `useSort<T>(items, defaultKey)`
Sort items by any key with direction toggle.
**Features:**
- String, number, and generic comparison
- Toggle ascending/descending
- Type-safe sort keys
**Example:**
```typescript
import { useSort } from '@/hooks/data'
const { sortedItems, sortKey, sortDirection, toggleSort } = useSort(
products,
'name'
)
<Button onClick={() => toggleSort('price')}>
Sort by Price {sortKey === 'price' && (sortDirection === 'asc' ? '↑' : '↓')}
</Button>
```
### `usePagination<T>(items, initialPageSize)`
Client-side pagination with full controls.
**Features:**
- Page navigation
- Dynamic page size
- Has next/prev indicators
- Total page calculation
**Example:**
```typescript
import { usePagination } from '@/hooks/data'
const {
items,
page,
totalPages,
nextPage,
prevPage,
goToPage,
hasNext,
hasPrev
} = usePagination(allItems, 20)
<Button onClick={prevPage} disabled={!hasPrev}>Previous</Button>
<span>Page {page} of {totalPages}</span>
<Button onClick={nextPage} disabled={!hasNext}>Next</Button>
```
## UI State Hooks
### `useDialog(initialOpen)`
Simple dialog/modal state management.
**Example:**
```typescript
import { useDialog } from '@/hooks/ui'
const { isOpen, open, close, toggle } = useDialog()
<Button onClick={open}>Open Dialog</Button>
<Dialog open={isOpen} onOpenChange={(open) => open ? open() : close()}>
...
</Dialog>
```
### `useTabs<T>(defaultTab)`
Type-safe tab navigation.
**Example:**
```typescript
import { useTabs } from '@/hooks/ui'
const { activeTab, switchTab, isActive } = useTabs<'overview' | 'details' | 'settings'>('overview')
<Tabs value={activeTab} onValueChange={switchTab}>
<TabsList>
<TabsTrigger value="overview">Overview</TabsTrigger>
<TabsTrigger value="details">Details</TabsTrigger>
</TabsList>
</Tabs>
```
### `useSelection<T>()`
Multi-select state management.
**Features:**
- Select/deselect individual items
- Select all/deselect all
- Toggle selection
- Selection count
**Example:**
```typescript
import { useSelection } from '@/hooks/ui'
const {
selectedIds,
toggle,
selectAll,
deselectAll,
isSelected,
count
} = useSelection()
<Checkbox
checked={isSelected(item.id)}
onCheckedChange={() => toggle(item.id)}
/>
{count > 0 && <Badge>{count} selected</Badge>}
```
### `useClipboard(successMessage)`
Copy to clipboard with feedback.
**Example:**
```typescript
import { useClipboard } from '@/hooks/ui'
const { copied, copy } = useClipboard('Copied to clipboard!')
<Button onClick={() => copy(codeSnippet)}>
{copied ? 'Copied!' : 'Copy'}
</Button>
```
## Form Hooks
### `useFormField<T>(initialValue, rules)`
Single form field with validation.
**Features:**
- Validation rules
- Touch state
- Error messages
- Reset functionality
**Example:**
```typescript
import { useFormField } from '@/hooks/forms'
const email = useFormField('', [
{
validate: (v) => v.includes('@'),
message: 'Invalid email'
},
{
validate: (v) => v.length > 0,
message: 'Email required'
}
])
<Input
value={email.value}
onChange={(e) => email.onChange(e.target.value)}
onBlur={email.onBlur}
/>
{email.touched && email.error && <span>{email.error}</span>}
```
### `useForm<T>(config)`
Complete form management with validation.
**Features:**
- Multi-field state
- Validation schema
- Async submit handling
- Touch tracking per field
**Example:**
```typescript
import { useForm } from '@/hooks/forms'
const form = useForm({
initialValues: {
name: '',
email: '',
message: ''
},
validate: (values) => {
const errors: Record<string, string> = {}
if (!values.email.includes('@')) {
errors.email = 'Invalid email'
}
return errors
},
onSubmit: async (values) => {
await api.submitForm(values)
toast.success('Form submitted!')
}
})
<form onSubmit={form.handleSubmit}>
<Input
value={form.values.email}
onChange={(e) => form.setValue('email', e.target.value)}
/>
{form.errors.email && <span>{form.errors.email}</span>}
<Button type="submit" disabled={form.isSubmitting}>
{form.isSubmitting ? 'Submitting...' : 'Submit'}
</Button>
</form>
```
## Hook Composition
Hooks are designed to be composed together:
```typescript
import { useArray, useSearch, useSort, usePagination } from '@/hooks/data'
import { useSelection } from '@/hooks/ui'
function useProductList() {
const { items, add, remove, update } = useArray<Product>('products', [])
const { results, query, setQuery } = useSearch(items, ['name', 'category'])
const { sortedItems, toggleSort } = useSort(results, 'name')
const { items: pagedItems, ...pagination } = usePagination(sortedItems, 10)
const selection = useSelection<Product>()
return {
products: pagedItems,
add,
remove,
update,
search: { query, setQuery },
sort: { toggleSort },
pagination,
selection,
}
}
```
## Best Practices
1. **Keep hooks focused**: One responsibility per hook
2. **Use composition**: Combine simple hooks for complex behavior
3. **Type everything**: Leverage TypeScript for safety
4. **Handle loading/error**: Always consider async states
5. **Memoize callbacks**: Use `useCallback` for stable references
6. **Document dependencies**: Clear about what causes re-renders
## Performance Tips
- Use `useCallback` and `useMemo` where appropriate
- Avoid creating new objects/arrays in render
- Leverage the functional update pattern for `setState`
- Consider `useTransition` for non-urgent updates
- Profile with React DevTools
## Testing Hooks
```typescript
import { renderHook, act } from '@testing-library/react'
import { useArray } from '@/hooks/data'
test('useArray adds items correctly', () => {
const { result } = renderHook(() => useArray('test-key', []))
act(() => {
result.current.add({ id: '1', name: 'Test' })
})
expect(result.current.items).toHaveLength(1)
expect(result.current.items[0].name).toBe('Test')
})
```

View File

@@ -0,0 +1,411 @@
# Hook Library Documentation
## Overview
The CodeForge hook library provides a comprehensive set of reusable React hooks organized by purpose. All business logic should be extracted into hooks, keeping components under 150 LOC and focused purely on presentation.
## Directory Structure
```
src/hooks/
├── core/ # Core utility hooks
├── ui/ # UI state management hooks
├── config/ # Configuration and page management hooks
├── features/ # Feature-specific business logic hooks
├── ai/ # AI-powered functionality hooks
└── validation/ # Validation and error checking hooks
```
## Core Hooks
### `use-kv-state.ts`
Enhanced wrapper around Spark's `useKV` with Zod validation support.
**Usage:**
```typescript
import { useKVState } from '@/hooks/core/use-kv-state'
import { z } from 'zod'
const UserSchema = z.object({
name: z.string(),
age: z.number().min(0),
})
const [user, setUser] = useKVState(
'user-data',
{ name: '', age: 0 },
UserSchema
)
// Invalid data is rejected automatically
setUser({ name: 'John', age: -5 }) // Logs error, keeps previous value
setUser({ name: 'John', age: 25 }) // Valid, updates state
```
### `use-debounced-save.ts`
Automatically debounces and saves values after a delay.
**Usage:**
```typescript
import { useDebouncedSave } from '@/hooks/core/use-debounced-save'
import { useKV } from '@github/spark/hooks'
const [code, setCode] = useState('')
const [, saveCode] = useKV('code-content', '')
useDebouncedSave(code, saveCode, 1000) // Saves 1s after last change
```
### `use-clipboard.ts`
Copy/paste operations with user feedback.
**Usage:**
```typescript
import { useClipboard } from '@/hooks/core/use-clipboard'
const { copy, paste, copied } = useClipboard()
<Button
onClick={() => copy(codeContent, 'Code copied!')}
disabled={copied}
>
{copied ? 'Copied!' : 'Copy Code'}
</Button>
```
## UI Hooks
### `use-dialog.ts`
Manage dialog open/closed state.
**Usage:**
```typescript
import { useDialog } from '@/hooks/ui/use-dialog'
const { open, openDialog, closeDialog, toggleDialog } = useDialog()
<Button onClick={openDialog}>Open Settings</Button>
<Dialog open={open} onOpenChange={closeDialog}>
{/* Dialog content */}
</Dialog>
```
### `use-selection.ts`
Multi-select state management.
**Usage:**
```typescript
import { useSelection } from '@/hooks/ui/use-selection'
const {
selected,
toggle,
selectAll,
clear,
isSelected,
count
} = useSelection<string>()
files.map(file => (
<Checkbox
checked={isSelected(file.id)}
onCheckedChange={() => toggle(file.id)}
/>
))
<Button onClick={() => selectAll(files.map(f => f.id))}>
Select All ({count} selected)
</Button>
```
### `use-confirmation.ts`
Confirmation dialog state and actions.
**Usage:**
```typescript
import { useConfirmation } from '@/hooks/ui/use-confirmation'
import { AlertDialog } from '@/components/ui/alert-dialog'
const { state, confirm, handleConfirm, handleCancel } = useConfirmation()
const deleteFile = (fileId: string) => {
confirm(
'Delete File?',
'This action cannot be undone.',
() => {
// Perform deletion
setFiles(files.filter(f => f.id !== fileId))
}
)
}
<AlertDialog open={state.open} onOpenChange={handleCancel}>
<AlertDialogContent>
<AlertDialogTitle>{state.title}</AlertDialogTitle>
<AlertDialogDescription>{state.description}</AlertDialogDescription>
<AlertDialogFooter>
<AlertDialogCancel onClick={handleCancel}>Cancel</AlertDialogCancel>
<AlertDialogAction onClick={handleConfirm}>Confirm</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
```
## Config Hooks
### `use-page-config.ts`
Load and manage page configurations from KV store.
**Usage:**
```typescript
import { usePageConfig, usePageRegistry } from '@/hooks/config/use-page-config'
// Get specific page config
const { pageConfig } = usePageConfig('code-editor')
console.log(pageConfig.title) // "Code Editor"
// Get all pages
const { pages, getPage } = usePageRegistry()
const dashboardPage = getPage('dashboard')
```
### `use-layout-state.ts`
Persist layout state (panel sizes, collapsed state) per page.
**Usage:**
```typescript
import { useLayoutState } from '@/hooks/config/use-layout-state'
const { layoutState, setPanelSizes, setCollapsed, setActivePanel } =
useLayoutState('code-editor')
<ResizablePanelGroup
onLayout={setPanelSizes}
defaultLayout={layoutState.panelSizes}
>
{/* Panels */}
</ResizablePanelGroup>
```
### `use-feature-flags.ts`
Runtime feature flag management.
**Usage:**
```typescript
import { useFeatureFlags } from '@/hooks/config/use-feature-flags'
const { isEnabled, enable, disable, toggle } = useFeatureFlags()
{isEnabled('ai-improve') && (
<Button onClick={handleAIImprove}>
AI Improve Code
</Button>
)}
<Switch
checked={isEnabled('dark-mode')}
onCheckedChange={() => toggle('dark-mode')}
/>
```
## Component Size Guidelines
### Rules
1. **Maximum 150 LOC** per component file
2. **Extract all business logic** into hooks
3. **Pure presentation** in components
4. **Compose smaller components** instead of conditional rendering
### Example: Breaking Down a Large Component
**Before (300+ LOC):**
```typescript
// ModelDesigner.tsx - 350 LOC
export function ModelDesigner() {
const [models, setModels] = useKV('models', [])
const [selectedModel, setSelectedModel] = useState(null)
const [showDialog, setShowDialog] = useState(false)
const handleAddModel = async () => {
// 50 lines of logic
}
const handleGenerateWithAI = async () => {
// 50 lines of AI logic
}
return (
<div>
{/* 200 lines of JSX */}
</div>
)
}
```
**After (<150 LOC each):**
```typescript
// hooks/features/use-model-manager.ts - 80 LOC
export function useModelManager() {
const [models, setModels] = useKV('models', [])
const [selectedModel, setSelectedModel] = useState(null)
const addModel = useCallback(async (model) => {
// Business logic
}, [])
const generateWithAI = useCallback(async (description) => {
// AI logic
}, [])
return { models, selectedModel, setSelectedModel, addModel, generateWithAI }
}
// components/ModelList.tsx - 80 LOC
export function ModelList({ models, onSelect, selected }) {
return (
<ScrollArea>
{models.map(model => (
<ModelCard
key={model.id}
model={model}
selected={selected?.id === model.id}
onClick={() => onSelect(model)}
/>
))}
</ScrollArea>
)
}
// components/ModelEditor.tsx - 120 LOC
export function ModelEditor({ model, onChange }) {
return (
<Card>
{/* Editing UI */}
</Card>
)
}
// ModelDesigner.tsx - 90 LOC
export function ModelDesigner() {
const { models, selectedModel, setSelectedModel, addModel, generateWithAI } =
useModelManager()
const { open, openDialog, closeDialog } = useDialog()
return (
<div className="flex gap-4">
<ModelList
models={models}
selected={selectedModel}
onSelect={setSelectedModel}
/>
{selectedModel && (
<ModelEditor
model={selectedModel}
onChange={handleChange}
/>
)}
<Dialog open={open} onOpenChange={closeDialog}>
{/* AI Dialog */}
</Dialog>
</div>
)
}
```
## JSON-Based Page Orchestration
### Page Config Schema
Pages can be defined in JSON and stored in the KV database:
```json
{
"id": "code-editor",
"title": "Code Editor",
"description": "Edit project files with AI assistance",
"icon": "Code",
"component": "CodeEditorPage",
"layout": {
"type": "split",
"direction": "horizontal",
"defaultSizes": [20, 80],
"panels": [
{
"id": "file-tree",
"component": "FileExplorer",
"minSize": 15,
"maxSize": 40
},
{
"id": "editor",
"component": "CodeEditor",
"minSize": 60
}
]
},
"features": [
{ "id": "ai-improve", "enabled": true },
{ "id": "ai-explain", "enabled": true }
],
"shortcuts": [
{ "key": "2", "ctrl": true, "action": "navigate" }
]
}
```
### Benefits
1. **Runtime Configuration**: Change page layouts without code changes
2. **User Customization**: Users can configure their own layouts
3. **Feature Flags**: Enable/disable features per page
4. **A/B Testing**: Test different layouts easily
5. **Persistence**: Layouts save automatically to KV store
## Migration Checklist
When refactoring a large component:
- [ ] Identify business logic vs presentation
- [ ] Extract business logic into hooks (`/hooks/features/`)
- [ ] Break JSX into smaller components (<150 LOC each)
- [ ] Create atomic components where applicable
- [ ] Add component to page config JSON
- [ ] Update component registry
- [ ] Test isolated components
- [ ] Update documentation
## Best Practices
1. **One Hook, One Responsibility**: Each hook should manage one concern
2. **Hooks Return Objects**: Return `{ value, actions }` for clarity
3. **Memoize Callbacks**: Use `useCallback` for functions passed as props
4. **Type Everything**: Full TypeScript types for all hooks
5. **Test Hooks**: Write unit tests for hook logic
6. **Document Hooks**: Add JSDoc comments explaining purpose and usage
7. **Validate with Zod**: Use schemas for complex data structures
8. **Handle Loading/Error States**: Return `{ data, loading, error }` pattern
## Next Steps
1. Extract business logic from top 5 largest components
2. Break down FeatureIdeaCloud (829 LOC) into 6 smaller components
3. Create remaining feature hooks (file-manager, workflow-manager, etc.)
4. Build PageOrchestrator component to render from JSON configs
5. Add UI for editing page layouts
6. Migrate all pages to JSON configuration system
## Resources
- [REFACTOR_PHASE2.md](./REFACTOR_PHASE2.md) - Complete refactoring plan
- [React Hooks Documentation](https://react.dev/reference/react/hooks)
- [Zod Documentation](https://zod.dev/)
- [Atomic Design Methodology](https://bradfrost.com/blog/post/atomic-web-design/)

View File

@@ -0,0 +1,760 @@
# Hook Library Reference
## Overview
The CodeForge hook library provides a comprehensive set of reusable hooks for managing application state, UI interactions, and business logic. All hooks follow React best practices and are fully typed with TypeScript.
## Table of Contents
1. [Data Management Hooks](#data-management-hooks)
2. [Core Utility Hooks](#core-utility-hooks)
3. [UI State Hooks](#ui-state-hooks)
4. [Form Hooks](#form-hooks)
5. [Canvas Hooks](#canvas-hooks)
6. [AI Hooks](#ai-hooks)
7. [Orchestration Hooks](#orchestration-hooks)
## Data Management Hooks
### useFiles
Manage project files with full CRUD operations.
```typescript
import { useFiles } from '@/hooks/data/use-files'
function MyComponent() {
const {
files, // ProjectFile[]
addFile, // (file: ProjectFile) => void
updateFile, // (id: string, updates: Partial<ProjectFile>) => void
deleteFile, // (id: string) => void
getFile, // (id: string) => ProjectFile | undefined
updateFileContent // (id: string, content: string) => void
} = useFiles()
// Usage
addFile({
id: 'new-file',
name: 'App.tsx',
path: '/src/App.tsx',
content: 'export default function App() {}',
language: 'typescript'
})
}
```
### useModels
Manage Prisma models.
```typescript
import { useModels } from '@/hooks/data/use-models'
function ModelDesigner() {
const {
models, // PrismaModel[]
addModel, // (model: PrismaModel) => void
updateModel, // (id: string, updates: Partial<PrismaModel>) => void
deleteModel, // (id: string) => void
getModel // (id: string) => PrismaModel | undefined
} = useModels()
// Add a new model
addModel({
id: 'user-model',
name: 'User',
fields: [
{ name: 'id', type: 'String', isId: true },
{ name: 'email', type: 'String', isUnique: true }
],
relations: []
})
}
```
### useComponents
Manage React components.
```typescript
import { useComponents } from '@/hooks/data/use-components'
function ComponentBuilder() {
const {
components, // ComponentNode[]
addComponent, // (component: ComponentNode) => void
updateComponent, // (id: string, updates: Partial<ComponentNode>) => void
deleteComponent, // (id: string) => void
getComponent // (id: string) => ComponentNode | undefined
} = useComponents()
}
```
### useWorkflows
Manage n8n-style workflows.
```typescript
import { useWorkflows } from '@/hooks/data/use-workflows'
function WorkflowDesigner() {
const {
workflows, // Workflow[]
addWorkflow, // (workflow: Workflow) => void
updateWorkflow, // (id: string, updates: Partial<Workflow>) => void
deleteWorkflow, // (id: string) => void
getWorkflow // (id: string) => Workflow | undefined
} = useWorkflows()
}
```
### useLambdas
Manage serverless functions.
```typescript
import { useLambdas } from '@/hooks/data/use-lambdas'
function LambdaDesigner() {
const {
lambdas, // Lambda[]
addLambda, // (lambda: Lambda) => void
updateLambda, // (id: string, updates: Partial<Lambda>) => void
deleteLambda, // (id: string) => void
getLambda // (id: string) => Lambda | undefined
} = useLambdas()
}
```
## Core Utility Hooks
### useKVState
Enhanced KV storage with validation and transformations.
```typescript
import { useKVState } from '@/hooks/core/use-kv-state'
function MyComponent() {
const [value, setValue] = useKVState({
key: 'my-data',
defaultValue: { count: 0 },
validate: (data) => data.count >= 0,
transform: (data) => ({ ...data, lastUpdated: Date.now() })
})
}
```
### useClipboard
Copy to clipboard with feedback.
```typescript
import { useClipboard } from '@/hooks/core/use-clipboard'
function CopyButton({ text }: { text: string }) {
const { copy, copied } = useClipboard()
return (
<button onClick={() => copy(text)}>
{copied ? 'Copied!' : 'Copy'}
</button>
)
}
```
### useDebouncedSave
Auto-save with debouncing.
```typescript
import { useDebouncedSave } from '@/hooks/core/use-debounced-save'
function Editor() {
const [content, setContent] = useState('')
useDebouncedSave(content, async (value) => {
await saveToServer(value)
}, 1000) // 1 second delay
return <textarea value={content} onChange={e => setContent(e.target.value)} />
}
```
## UI State Hooks
### useDialog
Manage dialog/modal state.
```typescript
import { useDialog } from '@/hooks/ui/use-dialog'
function MyComponent() {
const { isOpen, open, close, toggle } = useDialog()
return (
<>
<button onClick={open}>Open Dialog</button>
<Dialog open={isOpen} onOpenChange={close}>
{/* Dialog content */}
</Dialog>
</>
)
}
```
### useConfirmation
Confirm dangerous actions.
```typescript
import { useConfirmation } from '@/hooks/ui/use-confirmation'
function DeleteButton({ onDelete }: { onDelete: () => void }) {
const { confirm, ConfirmDialog } = useConfirmation({
title: 'Delete Item',
description: 'Are you sure? This cannot be undone.',
confirmText: 'Delete',
variant: 'destructive'
})
const handleDelete = async () => {
if (await confirm()) {
onDelete()
}
}
return (
<>
<button onClick={handleDelete}>Delete</button>
<ConfirmDialog />
</>
)
}
```
### useSelection
Manage item selection (single or multiple).
```typescript
import { useSelection } from '@/hooks/ui/use-selection'
function ItemList({ items }: { items: Item[] }) {
const {
selected, // Set<string>
isSelected, // (id: string) => boolean
toggle, // (id: string) => void
selectAll, // () => void
deselectAll, // () => void
selectedCount // number
} = useSelection({ multi: true })
return (
<div>
{items.map(item => (
<div
key={item.id}
onClick={() => toggle(item.id)}
className={isSelected(item.id) ? 'selected' : ''}
>
{item.name}
</div>
))}
</div>
)
}
```
### useModal
Enhanced modal with data passing.
```typescript
import { useModal } from '@/hooks/ui/use-modal'
function App() {
const { isOpen, data, open, close } = useModal<{ userId: string }>()
return (
<>
<button onClick={() => open({ userId: '123' })}>
Edit User
</button>
{isOpen && <UserModal userId={data?.userId} onClose={close} />}
</>
)
}
```
### useTabs
Manage tab state with URL sync.
```typescript
import { useTabs } from '@/hooks/ui/use-tabs'
function TabbedInterface() {
const { activeTab, setTab, tabs } = useTabs({
tabs: ['overview', 'details', 'settings'],
defaultTab: 'overview',
syncWithUrl: true
})
return (
<Tabs value={activeTab} onValueChange={setTab}>
{/* Tab content */}
</Tabs>
)
}
```
### usePanels
Manage resizable panel state.
```typescript
import { usePanels } from '@/hooks/ui/use-panels'
function SplitView() {
const { sizes, setSizes, collapsed, togglePanel } = usePanels({
defaultSizes: [30, 70],
minSizes: [20, 50]
})
return (
<ResizablePanelGroup sizes={sizes} onResize={setSizes}>
{/* Panels */}
</ResizablePanelGroup>
)
}
```
## Form Hooks
### useFormState
Comprehensive form state management.
```typescript
import { useFormState } from '@/hooks/forms/use-form-state'
function UserForm() {
const {
values, // Current form values
errors, // Validation errors
touched, // Touched fields
isValid, // Form validity
isDirty, // Form has changes
isSubmitting, // Submission state
setValue, // Set single field
setValues, // Set multiple fields
setError, // Set error
handleSubmit, // Submit handler
reset // Reset form
} = useFormState({
initialValues: {
name: '',
email: ''
},
validate: (values) => {
const errors: any = {}
if (!values.email) errors.email = 'Required'
return errors
},
onSubmit: async (values) => {
await saveUser(values)
}
})
return (
<form onSubmit={handleSubmit}>
<input
value={values.name}
onChange={e => setValue('name', e.target.value)}
/>
{errors.name && <span>{errors.name}</span>}
</form>
)
}
```
### useValidation
Reusable validation logic.
```typescript
import { useValidation } from '@/hooks/forms/use-validation'
function PasswordField() {
const { validate, errors, isValid } = useValidation({
rules: {
minLength: 8,
hasNumber: true,
hasSpecialChar: true
}
})
const handleChange = (value: string) => {
validate(value)
}
}
```
### useFieldArray
Manage dynamic form arrays.
```typescript
import { useFieldArray } from '@/hooks/forms/use-field-array'
function ContactsForm() {
const {
fields, // Array of field values
append, // Add new field
remove, // Remove field
move, // Reorder fields
update // Update specific field
} = useFieldArray({
name: 'contacts',
defaultValue: []
})
return (
<div>
{fields.map((field, index) => (
<div key={index}>
<input value={field.email} />
<button onClick={() => remove(index)}>Remove</button>
</div>
))}
<button onClick={() => append({ email: '' })}>
Add Contact
</button>
</div>
)
}
```
## Canvas Hooks
### useCanvas
Canvas drawing utilities.
```typescript
import { useCanvas } from '@/hooks/canvas/use-canvas'
function DrawingCanvas() {
const {
canvasRef,
ctx,
clear,
drawLine,
drawRect,
drawCircle,
getImageData,
setImageData
} = useCanvas({
width: 800,
height: 600
})
return <canvas ref={canvasRef} />
}
```
### useDragDrop
Drag and drop for canvas elements.
```typescript
import { useDragDrop } from '@/hooks/canvas/use-drag-drop'
function DraggableElements() {
const {
elements, // Array of positioned elements
draggedId, // Currently dragged element
handleMouseDown, // Start drag
handleMouseMove, // During drag
handleMouseUp, // End drag
updatePosition, // Programmatic position update
} = useDragDrop({
initialElements: [
{ id: '1', x: 100, y: 100, width: 50, height: 50 }
]
})
}
```
### useZoomPan
Zoom and pan for canvas views.
```typescript
import { useZoomPan } from '@/hooks/canvas/use-zoom-pan'
function ZoomableCanvas() {
const {
zoom, // Current zoom level
pan, // Pan offset { x, y }
zoomIn, // Increase zoom
zoomOut, // Decrease zoom
resetZoom, // Reset to default
setPan, // Set pan position
transform // CSS transform string
} = useZoomPan({
minZoom: 0.1,
maxZoom: 5,
defaultZoom: 1
})
return (
<div style={{ transform }}>
{/* Canvas content */}
</div>
)
}
```
### useConnections
Manage node connections (for diagrams/workflows).
```typescript
import { useConnections } from '@/hooks/canvas/use-connections'
function FlowDiagram() {
const {
connections, // Array of connections
addConnection, // Add new connection
removeConnection, // Remove connection
updateConnection, // Update connection
getConnections // Get connections for node
} = useConnections({
validate: (from, to) => from !== to // No self-connections
})
}
```
## AI Hooks
### useAIGenerate
Generate content with AI.
```typescript
import { useAIGenerate } from '@/hooks/ai/use-ai-generate'
function AIAssistant() {
const {
generate, // (prompt: string) => Promise<string>
isGenerating, // boolean
result, // Generated content
error // Error if any
} = useAIGenerate()
const handleGenerate = async () => {
const code = await generate('Create a React login form')
console.log(code)
}
}
```
### useAIComplete
AI code completion.
```typescript
import { useAIComplete } from '@/hooks/ai/use-ai-complete'
function CodeEditor() {
const {
complete, // (prefix: string) => Promise<string>
suggestions, // string[]
isCompleting, // boolean
acceptSuggestion // (index: number) => void
} = useAIComplete({
debounce: 300
})
}
```
### useAISuggestions
Get AI suggestions for improvements.
```typescript
import { useAISuggestions } from '@/hooks/ai/use-ai-suggestions'
function CodeReview() {
const {
getSuggestions, // (code: string) => Promise<Suggestion[]>
suggestions, // Suggestion[]
applySuggestion, // (id: string) => void
dismissSuggestion // (id: string) => void
} = useAISuggestions()
}
```
## Orchestration Hooks
### usePage
Execute a page schema.
```typescript
import { usePage } from '@/hooks/orchestration/use-page'
import pageSchema from '@/config/pages/my-page.json'
function DynamicPage() {
const {
context, // Data context
execute, // Execute action by ID
isExecuting, // boolean
handlers, // Action handlers map
schema // Page schema
} = usePage(pageSchema)
return <PageRenderer schema={schema} />
}
```
### useActions
Execute page actions.
```typescript
import { useActions } from '@/hooks/orchestration/use-actions'
function ActionButtons() {
const { execute, isExecuting, handlers } = useActions(
[
{
id: 'save',
type: 'update',
params: { target: 'Files' }
}
],
{ files: [], setFiles: () => {} }
)
return (
<button onClick={() => execute('save')} disabled={isExecuting}>
Save
</button>
)
}
```
## Hook Composition Patterns
### Combining Multiple Hooks
```typescript
function FeaturePage() {
const files = useFiles()
const models = useModels()
const { isOpen, open, close } = useDialog()
const { selected, toggle } = useSelection()
// Combine hooks to build complex features
const handleCreateModel = () => {
const model = createModelFromFiles(files.files)
models.addModel(model)
close()
}
}
```
### Custom Hook Composition
```typescript
function useProjectEditor() {
const files = useFiles()
const { isOpen, open, close } = useDialog()
const [activeFileId, setActiveFileId] = useState<string | null>(null)
const openFile = (id: string) => {
setActiveFileId(id)
open()
}
const saveFile = (content: string) => {
if (activeFileId) {
files.updateFileContent(activeFileId, content)
}
}
return {
files: files.files,
activeFile: files.getFile(activeFileId),
openFile,
saveFile,
isEditing: isOpen,
closeEditor: close
}
}
```
## Best Practices
### 1. Always Use Functional Updates
```typescript
// ❌ Bad - May cause data loss
setFiles([...files, newFile])
// ✅ Good - Always gets current state
setFiles(current => [...current, newFile])
```
### 2. Memoize Expensive Computations
```typescript
const filteredFiles = useMemo(() => {
return files.filter(f => f.name.includes(search))
}, [files, search])
```
### 3. Clean Up Side Effects
```typescript
useEffect(() => {
const subscription = subscribe()
return () => subscription.unsubscribe()
}, [])
```
### 4. Type Your Hooks
```typescript
function useTypedData<T>(key: string, defaultValue: T) {
const [data, setData] = useKV<T>(key, defaultValue)
return { data, setData }
}
```
### 5. Extract Reusable Logic
```typescript
// Extract common patterns into custom hooks
function useResource<T>(resourceName: string) {
const [items, setItems] = useKV<T[]>(`${resourceName}-items`, [])
const add = useCallback((item: T) => {
setItems(current => [...current, item])
}, [setItems])
return { items, add }
}
```
## Next Steps
- Explore `/src/hooks/` directory for implementations
- Check `../architecture/JSON_ORCHESTRATION_GUIDE.md` for page schemas
- See `REFACTOR_PHASE3.md` for architecture overview
- Read individual hook files for detailed implementation notes