| name | documentation_robotics_viewer-patterns |
| description | Show coding patterns for React Flow nodes, Zustand, and Tailwind |
| user_invocable | true |
| args | ["nodes|stores|styles|accessibility"] |
| generated | true |
| generation_timestamp | "2026-02-23T16:11:03.139Z" |
| generation_version | 2.0 |
| source_project | documentation_robotics_viewer |
| source_codebase_hash | 00a2f9723e9a7f64 |
Documentation Robotics Viewer - Patterns Reference
Quick-reference skill for documentation_robotics_viewer coding patterns and conventions.
Usage
/documentation_robotics_viewer-patterns [nodes|stores|styles|accessibility]
Args:
nodes - React Flow custom node pattern (CRITICAL - deviations cause rendering failures)
stores - Zustand state management pattern
styles - Tailwind CSS + Flowbite component pattern
accessibility - WCAG 2.1 AA compliance pattern
Default: Shows all patterns if no arg provided
Purpose
Displays established coding patterns from the documentation_robotics_viewer codebase to ensure consistency and prevent common issues. This skill helps developers:
- Create React Flow nodes correctly - Follow the strict pattern that prevents rendering failures
- Implement Zustand stores - Use the project's state management conventions
- Apply Tailwind styling - Follow Flowbite + dark mode patterns
- Meet accessibility standards - Implement WCAG 2.1 AA compliance
All patterns are extracted from production code in src/core/ and src/apps/embedded/.
Implementation
For nodes Pattern
Read these reference files:
src/core/nodes/motivation/GoalNode.tsx
src/core/nodes/business/BusinessFunctionNode.tsx
src/core/nodes/c4/ContainerNode.tsx
src/core/types/reactflow.ts
src/core/nodes/index.ts
src/core/services/nodeTransformer.ts
Display:
-
✅ Critical Node Requirements from CLAUDE.md:
- Export dimension constants (
YOUR_NODE_WIDTH, YOUR_NODE_HEIGHT)
- Use
memo() wrapper
- Include 4 Handles (top, bottom, left, right) with specific IDs
- Use inline styles (NOT Tailwind for nodes)
- Add
role="article" + aria-label for accessibility
- Set
displayName for React DevTools
-
📝 Registration Checklist:
- Add
YourNodeData interface in src/core/types/reactflow.ts
- Export node + dimensions in
src/core/nodes/<category>/index.ts
- Add to
nodeTypes map in src/core/nodes/index.ts
- Update
nodeTransformer.ts in 3 places:
getNodeTypeForElement() - Map element type to node type string
extractNodeData() - Map element properties to node data
precalculateDimensions() - Import and use dimension constants
-
🔍 Example from GoalNode.tsx:
export const GOAL_NODE_WIDTH = 180;
export const GOAL_NODE_HEIGHT = 100;
export const GoalNode = memo(({ data, id: _id }: { data: GoalNodeData; id?: string }) => {
return (
<div
role="article"
aria-label={`Goal: ${data.label}`}
style={{
width: GOAL_NODE_WIDTH,
height: GOAL_NODE_HEIGHT,
/* ... inline styles ... */
}}
>
<Handle type="target" position={Position.Top} id="top" />
<Handle type="source" position={Position.Bottom} id="bottom" />
<Handle type="target" position={Position.Left} id="left" />
<Handle type="source" position={Position.Right} id="right" />
{/* content */}
</div>
);
});
GoalNode.displayName = 'GoalNode';
-
⚠️ Common Pitfalls:
- Node not rendering → Check
nodeTransformer.ts mapping
- Dimension mismatch → Style must use exported constants
- Edges not connecting → Verify Handle IDs match edge definitions
For stores Pattern
Read these reference files:
src/core/stores/modelStore.ts
src/core/stores/layerStore.ts
src/core/stores/elementStore.ts
src/apps/embedded/stores/authStore.ts
src/apps/embedded/stores/viewPreferenceStore.ts
src/apps/embedded/stores/chatStore.ts
Display:
-
✅ Zustand Store Pattern (NO React Context):
import { create } from 'zustand';
interface YourStoreState {
data: YourData[];
isLoading: boolean;
error: string | null;
fetchData: () => Promise<void>;
setData: (data: YourData[]) => void;
reset: () => void;
}
export const useYourStore = create<YourStoreState>((set, get) => ({
data: [],
isLoading: false,
error: null,
fetchData: async () => {
set({ isLoading: true, error: null });
try {
const response = await fetch('/api/data');
const data = await response.json();
set({ data, isLoading: false });
} catch (err) {
set({ error: err.message, isLoading: false });
}
},
setData: (data) => set({ data }),
reset: () => set({ data: [], isLoading: false, error: null }),
}));
-
📂 Store Organization:
- Core stores (
src/core/stores/) - NO route/app dependencies
- App stores (
src/apps/embedded/stores/) - CAN use route context
- Separate stores by concern (auth, model, UI preferences, chat, etc.)
-
🎯 Usage in Components:
import { useYourStore } from '@/stores/yourStore';
function YourComponent() {
const data = useYourStore((state) => state.data);
const fetchData = useYourStore((state) => state.fetchData);
const { data, isLoading, error } = useYourStore();
}
-
⚙️ Store Features:
- Direct async support (no middleware needed)
- No Provider wrapping required
- Minimal boilerplate (3kb bundle)
- TypeScript type inference works automatically
For styles Pattern
Read these reference files:
src/apps/embedded/components/common/ErrorBoundary.tsx
src/apps/embedded/components/shared/ViewToggle.tsx
src/core/components/base/BaseControlPanel.tsx
tailwind.config.ts
src/theme/
Display:
-
✅ Tailwind + Flowbite Pattern:
import { Button, Card, Badge, Modal, ListItem } from 'flowbite-react';
function YourComponent() {
return (
<Card className="dark:bg-gray-800">
<h2 className="text-lg font-semibold text-gray-900 dark:text-white">
Title
</h2>
<Button color="blue" size="sm" className="dark:bg-blue-600">
Action
</Button>
<Badge color="success">Active</Badge>
</Card>
);
}
-
🎨 Styling Rules:
- ✅ ALWAYS use Tailwind utilities - NO new CSS modules (except node inline styles)
- ✅ ALWAYS use Flowbite components - Card, Badge, Button, Modal, etc.
- ❌ NEVER use dot notation -
List.Item → ListItem
- ✅ ALWAYS add dark mode variants -
dark:bg-gray-800, dark:text-white
- ✅ ALWAYS add data-testid - For E2E tests on app components
-
🌙 Dark Mode Pattern:
<div className="bg-white dark:bg-gray-900">
<h1 className="text-gray-900 dark:text-white">Heading</h1>
<p className="text-gray-600 dark:text-gray-400">Text</p>
<button className="bg-blue-600 hover:bg-blue-700 dark:bg-blue-500 dark:hover:bg-blue-600">
Button
</button>
</div>
-
🧪 Test Selectors:
<Card data-testid="business-function-card">
<Button data-testid="edit-function-btn">Edit</Button>
</Card>
For accessibility Pattern
Read these reference files:
src/core/nodes/motivation/GoalNode.tsx
src/core/nodes/business/BusinessFunctionNode.tsx
src/core/edges/ElbowEdge.tsx
documentation/ACCESSIBILITY.md
Display:
-
✅ WCAG 2.1 AA Compliance Requirements:
Nodes:
<div
role="article"
aria-label={`Goal: ${data.label}`}
style={{
border: `2px solid ${data.stroke}`,
backgroundColor: data.fill,
}}
>
{}
<Handle type="target" position={Position.Top} id="top" />
<Handle type="source" position={Position.Bottom} id="bottom" />
<Handle type="target" position={Position.Left} id="left" />
<Handle type="source" position={Position.Right} id="right" />
</div>
Edges:
<path
d={edgePath}
role="img"
aria-label={`Association: from ${sourceNode.label} to ${targetNode.label}`}
onClick={handleClick}
onKeyDown={handleKeyDown}
tabIndex={0}
className="stroke-gray-600 dark:stroke-gray-400"
/>
-
🎨 Color Contrast Standards:
- Text: Minimum 4.5:1 contrast ratio
- UI Components: Minimum 3:1 contrast ratio
- Architecture visualizations may use
reviewOnFail: true for violations (marked for manual review)
-
⌨️ Keyboard Navigation:
- All interactive elements must be keyboard accessible
- Tab order must be logical (top-to-bottom, left-to-right)
- Escape key closes modals/overlays
- Focus must be visible on all focusable elements
-
🧪 Testing Accessibility:
npm run storybook:dev
npm run test:storybook:a11y
npm test
-
📋 Accessibility Checklist:
Examples
Example 1: Creating a New Custom Node
/documentation_robotics_viewer-patterns nodes
cat src/core/nodes/motivation/GoalNode.tsx
npm run storybook:dev
npm run test:storybook:a11y
Example 2: Setting Up a New Zustand Store
/documentation_robotics_viewer-patterns stores
cat src/core/stores/modelStore.ts
npm test -- tests/unit/stores/yourStore.spec.ts
Example 3: Checking Styling Conventions
/documentation_robotics_viewer-patterns styles
npm run storybook:dev
npm test
Example 4: Ensuring Accessibility Compliance
/documentation_robotics_viewer-patterns accessibility
npm run test:storybook:a11y
cat documentation/ACCESSIBILITY.md
Related Files
- Documentation:
CLAUDE.md (main development guide)
- Accessibility:
documentation/ACCESSIBILITY.md
This skill was automatically generated on 2026-02-23.