UIコンポーネントを新規作成・編集する際に使用。Emotion styled/テーマトークン/Atomic Designのルールを確認。
This skill provides comprehensive UI development guidelines for the ludiscan-webapp project. Follow these guidelines to maintain consistency, code quality, and accessibility.
ALWAYS use Emotion styled components - NEVER use inline HTML tags
const StyledDiv = styled.div...orconst StyledButton = styled(Component)...<div style={{...}}>Access theme via useSharedTheme() hook
import { useSharedTheme } from '@src/hooks/useSharedTheme';
const Component = () => {
const { theme } = useSharedTheme();
return <Text color={theme.colors.text.primary} />
}
Use theme tokens, not hardcoded values
theme.colors.**, theme.spacing.md, theme.typography.fontSize.base#C41E3A, 16px, 1remsrc/component/
├── atoms/ # Basic building blocks (Button, Text, Flex, etc.)
├── molecules/ # Simple combinations (TextField, Modal, Menu, etc.)
├── organisms/ # Complex components (Sidebar, Toolbar, etc.)
└── templates/ # Page layouts
When to use each level:
import styled from '@emotion/styled';
import type { FC } from 'react';
// 1. Type definitions
export type MyComponentProps = {
className?: string; // Always include!
// ... other props
};
// 2. Base component - handles logic
const Component: FC<MyComponentProps> = ({ className, ...props }) => {
return <div className={className}>...</div>;
};
// 3. Styled wrapper - handles styling
export const MyComponent = styled(Component)`
color: ${({ theme }) => theme.colors.text.primary};
padding: ${({ theme }) => theme.spacing.md};
`;
| Component | Import | Usage |
|---|---|---|
| Button | @src/component/atoms/Button |
<Button scheme="primary" onClick={...}> |
| Text | @src/component/atoms/Text |
<Text text="..." fontSize={...} color={...} /> |
| FlexRow/FlexColumn | @src/component/atoms/Flex |
<FlexRow gap={16} align="center"> |
| Modal | @src/component/molecules/Modal |
<Modal isOpen={...} onClose={...}> |
| TextField | @src/component/molecules/TextField |
<TextField value={...} onChange={...} /> |
| Category | Access | Example |
|---|---|---|
| Colors | theme.colors.* |
theme.colors.primary.main |
| Typography | theme.typography.* |
theme.typography.fontSize.lg |
| Spacing | theme.spacing.* |
theme.spacing.md (16px) |
| Borders | theme.borders.* |
theme.borders.radius.md |
| Shadows | theme.shadows.* |
theme.shadows.md |
| Type | Convention | Example |
|---|---|---|
| Components | PascalCase | UserProfile, HeatmapViewer |
| Props Types | ComponentNameProps |
ButtonProps, ModalProps |
| Boolean vars | is/has/should/can prefix |
isLoading, hasError |
| Event handlers | handle prefix |
handleClick, handleSubmit |
| Custom hooks | use prefix |
useAuth, useHeatmapData |
any type - use proper types or unknowndangerouslySetInnerHTML - XSS vulnerabilityclassName prop - required for styled component compatibility