name: create-component-mui description: "Scaffold a new React component using Material UI primitives with typed props and a colocated test. Use when the user says 'create component', 'new card', 'new widget', 'add a UI element', 'build X component'. Don't use for full pages — use create-page-mui. Don't use for data hooks — use frontend-hooks-react-query." metadata: skill_type: micro stack: react-mui
Create Component (MUI)
Instructions
- Identify the feature name (e.g.,
users) and component name in PascalCase (e.g.,UserCard).
- Identify the feature name (e.g.,
- Determine the target path:
src/features/{feature}/components/{ComponentName}/.
- Determine the target path:
- Create the component file
{ComponentName}.tsx:
- Create the component file
import { Card, CardContent, Stack, Typography } from '@mui/material';
export interface {ComponentName}Props {
title: string;
description?: string;
// prefer discriminated unions over boolean flags
}
export function {ComponentName}({ title, description }: {ComponentName}Props) {
return (
<Card variant="outlined">
<CardContent>
<Stack spacing={1}>
<Typography variant="subtitle1" fontWeight={500}>{title}</Typography>
{description && (
<Typography variant="body2" color="text.secondary">{description}</Typography>
)}
</Stack>
</CardContent>
</Card>
);
}
- Create
index.tsthat re-exports the component and its props type:
export { {ComponentName} } from './{ComponentName}'; export type { {ComponentName}Props } from './{ComponentName}';- Create
- Create the test file
{ComponentName}.test.tsx:
- Create the test file
import { render, screen } from '@testing-library/react';
import { ThemeProvider, createTheme } from '@mui/material/styles';
import { {ComponentName} } from './{ComponentName}';
const theme = createTheme();
function renderWithProviders(ui: React.ReactNode) {
return render(<ThemeProvider theme={theme}>{ui}</ThemeProvider>);
}
describe('{ComponentName}', () => {
it('renders with required props', () => {
renderWithProviders(<{ComponentName} title="Test" />);
expect(screen.getByText('Test')).toBeInTheDocument();
});
});
- Run the tests:
npm test -- --testPathPattern={ComponentName}.
- Run the tests:
Critical
- Use MUI primitives (
Card,Stack,Box,Typography,Button) over raw HTML — raw HTML ignores the design system and causes visual inconsistency. - Tests MUST wrap components in
<ThemeProvider>— raw render crashes on theme context access and produces misleading failures. - Use
Typographywithvariantfor all text (h1,body1,caption) — raw<p>and<h1>tags bypass the design system's type scale. - No business logic in components — components that fetch data or run business rules become untestable and tightly coupled to the backend.
Examples
User says: "Create an OrderCard component."
Actions:
- Feature:
orders, component:OrderCard. - Path:
src/features/orders/components/OrderCard/. - Create
OrderCard.tsxwithOrderCardProps { orderId: string; total: number; status: string }. - Use
Card,CardContent,Stack,Typography,Chipfrom MUI. - Create
index.tsre-exporting component and props. - Create
OrderCard.test.tsxwithThemeProviderwrapper.
Result: OrderCard/ directory with component, barrel export, and passing test.
Troubleshooting
MUI styles not applied → Component renders but looks unstyled → Ensure ThemeProvider wraps the app root. In tests, use the renderWithProviders helper with createTheme().
MUI icons not rendering → @mui/icons-material not installed → Run npm install @mui/icons-material. Import icons individually: import CheckIcon from '@mui/icons-material/Check'.
Props type not available to consumers → Only the component is exported → Add export type { {ComponentName}Props } to index.ts.
See also
create-page-mui— create a page that uses this componentfrontend-hooks-react-query— create data hooks the page will callenforce-boundary— verify components don't import from wrong layers