| name | frontend-component-system |
| description | Build reusable React/Vue/vanilla JS components with D3.js visualizations and comprehensive testing |
Frontend Component System
A comprehensive skill for building production-ready frontend components with modern patterns, D3.js visualizations, and proper testing.
What This Skill Provides
Core Tools
- Component Scaffolder - Generate component boilerplates with tests
- D3 Component Generator - Create reusable D3.js visualization components
Reference Documentation
- Component Architecture Guide - Modern patterns and best practices
- D3.js Component Patterns - Reusable visualization components
- Testing Strategies - Vitest, Jest, and visual regression testing
When to Use This Skill
Perfect For:
- Building D3.js visualization components (e.g., network graphs, tree diagrams)
- Creating reusable React/Vue/vanilla JS components
- Setting up component testing infrastructure
- Standardizing component patterns across projects
Not For:
- Full application architecture (use a framework-specific skill)
- Backend API integration (that's a different concern)
Quick Start Workflows
Workflow 1: Create a New D3.js Component
# Generate a D3.js visualization component
python ~/my-skills/frontend-component-system/scripts/create_d3_component.py \
--name NetworkGraph \
--type force-directed \
--framework react \
--tests
# This creates:
# - components/NetworkGraph.jsx (React + D3 integration)
# - components/NetworkGraph.test.jsx (Vitest tests)
# - hooks/useD3.js (Custom D3 React hook)
# - utils/d3-helpers.js (Reusable D3 utilities)
D3.js Component Patterns
The useD3 Hook Pattern
For React + D3 integration:
// Custom hook for D3 lifecycle
import { useEffect, useRef } from 'react';
export const useD3 = (renderFn, dependencies) => {
const ref = useRef();
useEffect(() => {
if (ref.current) {
renderFn(d3.select(ref.current));
}
return () => {
// Cleanup D3 resources
d3.select(ref.current).selectAll('*').remove();
};
}, dependencies);
return ref;
};
Component Types Reference
1. D3.js Visualization Components
When to use:
- Data visualizations (charts, graphs, networks)
- Interactive visualizations with zoom/pan
- Real-time data updates
Example types:
- Force-directed graphs
- Tree diagrams
- Custom charts
2. Presentational Components
When to use:
- Pure UI without logic
- Highly reusable
- Design system components
Component Quality Checklist
Essentials (Required)
- Clear, descriptive name
- Prop types or TypeScript interfaces
- Default props for optional values
- Basic unit tests (>80% coverage)
- JSDoc comments for public API
Best Practices (Recommended)
- Memoization for expensive operations
- Accessibility attributes (ARIA, roles)
- Keyboard navigation support
- Error boundaries (React) or error handling
Testing Strategies
Unit Tests (Always)
// NetworkGraph.test.jsx
import { render, screen } from '@testing-library/react';
import { NetworkGraph } from './NetworkGraph';
describe('NetworkGraph', () => {
const mockData = {
nodes: [{ id: 1, name: 'Node 1' }],
links: []
};
it('renders SVG element', () => {
render(<NetworkGraph data={mockData} />);
expect(screen.getByRole('img')).toBeInTheDocument();
});
});
Real-World Examples
Example 1: Network Graph Visualization Component
Example implementation for a network graph component:
// NetworkGraph.jsx
import { useD3 } from '../hooks/useD3';
import { buildForceLayout } from '../utils/d3-force-utils';
export const KnowledgeMap = ({ concepts, connections }) => {
const ref = useD3(
(svg) => {
const { simulation, nodes, links } = buildForceLayout({
nodes: concepts,
links: connections
});
// Render nodes and links
// ...
},
[concepts, connections]
);
return <svg ref={ref} className="knowledge-map" />;
};
Common Pitfalls & Solutions
Pitfall 1: D3 + React Lifecycle Conflicts
Problem: D3 and React both want to control the DOM
Solution: Use the useD3 hook pattern:
- React owns the component lifecycle
- D3 owns the SVG rendering
- Never mix D3 selection and React JSX in same element
Pitfall 2: Memory Leaks in D3 Components
Problem: D3 event listeners and intervals not cleaned up
Solution:
useEffect(() => {
const svg = d3.select(ref.current);
const simulation = d3.forceSimulation(nodes);
return () => {
// Cleanup
simulation.stop();
svg.selectAll('*').remove();
};
}, [nodes]);
Additional Resources
Scripts
scripts/create_d3_component.py- Generate D3 visualization components
Reference Guides
reference/architecture.md- Component architecture patternsreference/d3-patterns.md- D3.js integration patterns
Examples
examples/force-directed-graph/- Complete force-directed graph example
Pro Tips
- Keep D3 and React Separate: Never mix D3 DOM manipulation with React JSX
- Test the Data Flow: Test how data flows through components
- Memoize Expensive Renders: Use React.memo for large D3 visualizations
- Accessibility First: Add ARIA labels and keyboard navigation from the start
Version: 1.0.0
Last Updated: October 2025