FOSMVVM React View Generator
Generate React components that render FOSMVVM ViewModels.
Conceptual Foundation
For full architecture context, see FOSMVVMArchitecture.md | OpenClaw reference
In FOSMVVM, React components are thin rendering layers that display ViewModels:
CODEBLOCK0
Key principle: Components don't transform or compute data. They render what the ViewModel provides.
View-ViewModel Alignment
The component filename should match the ViewModel it renders.
CODEBLOCK1
This alignment provides:
- - Discoverability - Find the component for any ViewModel instantly
- Consistency - Same naming discipline as SwiftUI and Leaf
- Maintainability - Changes to ViewModel are reflected in component location
TDD Workflow
This skill generates tests FIRST, implementation SECOND in a single invocation:
CODEBLOCK2
Context-aware: Skill references conversation understanding of requirements. No file parsing or Q&A needed.
Core Components
1. viewModelComponent() Wrapper
Every component is wrapped with viewModelComponent():
CODEBLOCK3
Required:
- - Use
FOSMVVM.viewModelComponent() from global namespace (loaded via script tag) - Component function receives
{ viewModel } prop - No imports needed - FOSMVVM utilities loaded via
<script> tags
2. The .bind() Pattern
Parent components use .bind() to invoke ServerRequests:
CODEBLOCK4
The .bind() pattern:
- - Child components receive data via ServerRequest
- Parent specifies
requestType and INLINECODE6 - WASM bridge handles request → ViewModel → component rendering
- No fetch() calls, no hardcoded URLs
3. Error ViewModel Handling
Error ViewModels are rendered like any other ViewModel:
CODEBLOCK5
Key principles:
- - No generic error handling
- Each error type has its own ViewModel
- Component conditionally renders based on
errorType property - Error rendering is just data rendering
4. Navigation Intents (Not URLs)
Use navigation intents, not hardcoded paths:
CODEBLOCK6
Navigation patterns:
- - Use
FOSMVVM.Link from global namespace (loaded via script tag) - Use
intent property, not hardcoded paths - Router maps intents to routes
- Platform-independent navigation
Component Categories
Display-Only Components
Components that just render data (no user interactions):
CODEBLOCK7
Characteristics:
- - Just renders ViewModel properties
- No event handlers (onClick, onSubmit, etc.)
- May have conditional rendering based on ViewModel state
- No .bind() calls to child components
Interactive Components
Components with user actions that trigger ServerRequests:
CODEBLOCK8
List Components
Components that render collections:
CODEBLOCK9
Form Components
Components with validated input fields:
CODEBLOCK10
When to Use This Skill
- - Creating a new React component for a FOSMVVM app
- Building UI to render a ViewModel
- Migrating Leaf templates to React
- Following an implementation plan that requires new views
- Creating forms with validation
- Building list views that compose child components
What This Skill Generates
Two files per invocation:
| File | Location | Purpose |
|---|
| INLINECODE10 | INLINECODE11 | Jest + React Testing Library tests |
| INLINECODE12 |
src/components/{Feature}/ | React component |
Test file generated FIRST (tests fail initially)
Implementation file generated SECOND (tests pass)
Note: The corresponding ViewModel and ServerRequest should already exist (use other FOSMVVM generator skills).
Project Structure Configuration
| Placeholder | Description | Example |
|---|
| INLINECODE14 | View name (without "View" suffix) | INLINECODE15 , INLINECODE16 |
| INLINECODE17 |
Feature/module grouping |
Tasks,
Auth |
Pattern Implementation
This skill references conversation context to determine component structure:
Component Type Detection
From conversation context, the skill identifies:
- - ViewModel structure (from prior discussion or specifications read by Claude)
- ServerRequest details (from requirements already in context)
- Component category: Display-only, interactive, form, or list
- Error ViewModels to handle
Test Generation (FIRST)
Based on component type, generates .test.js with:
- - All components: Success ViewModel rendering, error ViewModel rendering
- Interactive: Button clicks, operation verification
- Form: Input changes, validation errors, submission
- List: Empty state, multiple items, child binding
Component Generation (SECOND)
Generates .jsx following patterns:
- 1. Import
viewModelComponent wrapper - Handle error ViewModels with conditional rendering
- Render success ViewModel
- Add interactions (if interactive)
- Add form state (if form)
- Add child
.bind() calls (if container) - Export wrapped component
Context Sources
Skill references information from:
- - Prior conversation: Requirements discussed with user
- Specification files: If Claude has read specifications into context
- ViewModel definitions: From codebase or discussion
Step 5: Verify Completeness
Check:
- - [ ]
.test.js file exists - [ ]
.jsx file exists - [ ] Component uses
FOSMVVM.viewModelComponent() wrapper - [ ] Component accesses FOSMVVM functions from global namespace
- [ ] Tests cover success and error ViewModels
- [ ] Tests cover user interactions (if applicable)
Key Patterns
Pattern: No Business Logic in Components
CODEBLOCK11
Pattern: No fetch() Calls
CODEBLOCK12
Pattern: Error ViewModels Are Data
CODEBLOCK13
Pattern: Navigation Intents
CODEBLOCK14
File Organization
CODEBLOCK15
Common Mistakes
Computing Data in Components
CODEBLOCK16
Making HTTP Requests Directly
CODEBLOCK17
Hardcoding Text
CODEBLOCK18
Using Hardcoded URLs
CODEBLOCK19
Not Wrapping with viewModelComponent()
CODEBLOCK20
Mismatched Filenames
CODEBLOCK21
File Templates
See reference.md for complete file templates.
Naming Conventions
| Concept | Convention | Example |
|---|
| Component file | INLINECODE27 | INLINECODE28 , INLINECODE29 |
| Test file |
{Name}View.test.js |
TaskListView.test.js |
| Component function |
{Name}View |
TaskListView,
SignInView |
| ViewModel prop |
viewModel | Always
viewModel |
Testing Patterns
Test: Rendering with Success ViewModel
CODEBLOCK22
Test: Rendering with Error ViewModel
CODEBLOCK23
Test: User Interaction
CODEBLOCK24
How to Use This Skill
Invocation:
CODEBLOCK25
Prerequisites:
- - ViewModel and ServerRequest details are understood from conversation
- Optionally, specification files have been read into context
- Component requirements (display-only, interactive, form, list) are clear from discussion
Output:
- -
{ComponentName}.test.js - Generated FIRST (tests fail) - INLINECODE38 - Generated SECOND (tests pass)
Workflow integration:
This skill is typically used after discussing requirements or reading specification files. The skill references that context automatically—no file paths or Q&A needed.
See Also
Version History
| Version | Date | Changes |
|---|
| 1.0 | 2026-01-23 | Initial skill for React view generation based on Kairos requirements |
FOSMVVM React 视图生成器
生成渲染 FOSMVVM ViewModel 的 React 组件。
概念基础
完整架构上下文请参见 FOSMVVMArchitecture.md | OpenClaw 参考
在 FOSMVVM 中,React 组件是显示 ViewModel 的薄渲染层:
┌─────────────────────────────────────────────────────────────┐
│ ViewModelView 模式 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ViewModel (数据) React 组件 │
│ ┌──────────────────┐ ┌──────────────────┐ │
│ │ title: String │────►│
{vm.title} │ │
│ │ items: [Item] │────►│ {vm.items.map()} │ │
│ │ isEnabled: Bool │────►│ disabled={!...} │ │
│ └──────────────────┘ └──────────────────┘ │
│ │
│ ServerRequest (操作) │
│ ┌──────────────────┐ ┌──────────────────┐ │
│ │ processRequest() │◄────│
│ │ │ │ requestType={} │ │
│ └──────────────────┘ └──────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
关键原则: 组件不转换或计算数据。它们渲染 ViewModel 提供的内容。
视图-ViewModel 对齐
组件文件名应与它渲染的 ViewModel 名称匹配。
src/
viewmodels/
{Feature}ViewModel.js ←──┐
{Entity}CardViewModel.js ←──┼── 相同名称
│
components/ │
{Feature}/ │
{Feature}View.jsx ────┤ (渲染 {Feature}ViewModel)
{Entity}CardView.jsx ────┘ (渲染 {Entity}CardViewModel)
这种对齐方式提供:
- - 可发现性 - 立即找到任何 ViewModel 对应的组件
- 一致性 - 与 SwiftUI 和 Leaf 相同的命名规范
- 可维护性 - ViewModel 的变更反映在组件位置中
TDD 工作流
此技能在单次调用中先生成测试,后生成实现:
- 1. 从对话上下文中引用 ViewModel 和 ServerRequest 详情
- 生成 .test.js 文件 → 测试失败(尚无实现)
- 生成 .jsx 文件 → 测试通过
- 验证完整性(两个文件都存在)
- 用户运行 npm test → 所有测试通过 ✓
上下文感知: 技能引用对话中对需求的理解。无需文件解析或问答。
核心组件
1. viewModelComponent() 包装器
每个组件都用 viewModelComponent() 包装:
jsx
const MyView = FOSMVVM.viewModelComponent(({ viewModel }) => {
return
{viewModel.title}
;
});
export default MyView;
必需:
- - 使用全局命名空间中的 FOSMVVM.viewModelComponent()(通过 script 标签加载)
- 组件函数接收 { viewModel } 属性
- 无需导入 - FOSMVVM 工具通过