Loading...
Loading...
Use when applying Atomic Design methodology to organize UI components into quarks, atoms, molecules, organisms, templates, and pages. Core principles and hierarchy.
npx skill4agent add thebushidocollective/han atomic-design-fundamentalssrc/
quarks/ # Design tokens
index.ts
colors.ts
spacing.ts
typography.ts
shadows.ts
borders.ts
components/
atoms/
Button/
Button.tsx
Button.test.tsx
Button.stories.tsx
index.ts
Input/
Label/
Icon/
molecules/
SearchForm/
FormField/
Card/
organisms/
Header/
Footer/
ProductCard/
templates/
MainLayout/
DashboardLayout/
pages/
HomePage/
ProductPage/src/
quarks/
colors.ts
spacing.ts
typography.ts
components/
atoms/
Button.tsx
Input.tsx
Label.tsx
molecules/
SearchForm.tsx
FormField.tsx
organisms/
Header.tsx
Footer.tsx
templates/
MainLayout.tsx
pages/
HomePage.tsxsrc/
quarks/ # Shared design tokens
index.ts
colors.ts
spacing.ts
features/
products/
components/
atoms/
molecules/
organisms/
templates/
pages/
checkout/
components/
atoms/
molecules/
organisms/
shared/
components/
atoms/
molecules/# PascalCase for component files
Button.tsx
SearchForm.tsx
ProductCard.tsx
# Index files for clean imports
index.ts
# Test files
Button.test.tsx
Button.spec.tsx
# Story files (Storybook)
Button.stories.tsx// Atoms - simple, descriptive names
Button
Input
Label
Avatar
Icon
// Molecules - action or composition-based names
SearchForm
FormField
MediaObject
NavItem
// Organisms - section or feature-based names
Header
Footer
ProductCard
CommentSection
UserProfile
// Templates - layout-focused names
MainLayout
DashboardLayout
AuthLayout
// Pages - page-specific names
HomePage
ProductDetailPage
CheckoutPage// src/components/atoms/index.ts
export { Button } from './Button';
export { Input } from './Input';
export { Label } from './Label';
export { Icon } from './Icon';
// src/components/molecules/index.ts
export { SearchForm } from './SearchForm';
export { FormField } from './FormField';
// src/components/index.ts
export * from './atoms';
export * from './molecules';
export * from './organisms';// Clean imports from barrel files
import { Button, Input, Label } from '@/components/atoms';
import { SearchForm, FormField } from '@/components/molecules';
import { Header, Footer } from '@/components/organisms';
// Or from unified barrel
import { Button, SearchForm, Header } from '@/components';Quarks -> Used by: Atoms, Molecules, Organisms, Templates, Pages
Atoms -> Used by: Molecules, Organisms, Templates, Pages
Molecules -> Used by: Organisms, Templates, Pages
Organisms -> Used by: Templates, Pages
Templates -> Used by: Pages
Pages -> Not used by other components// Atom using quarks for styling
import { colors, spacing } from '@/quarks';
const Button = styled.button`
background: ${colors.primary[500]}; {/* Quark */}
padding: ${spacing.md}; {/* Quark */}
`;
// Molecule using atoms only
const SearchForm = () => (
<form>
<Input placeholder="Search..." /> {/* Atom */}
<Button>Search</Button> {/* Atom */}
</form>
);
// Organism using molecules and atoms
const Header = () => (
<header>
<Logo /> {/* Atom */}
<Navigation /> {/* Molecule */}
<SearchForm /> {/* Molecule */}
<UserMenu /> {/* Molecule */}
</header>
);
// Template using organisms
const MainLayout = ({ children }) => (
<div>
<Header /> {/* Organism */}
<main>{children}</main>
<Footer /> {/* Organism */}
</div>
);// BAD: Atom importing from molecule
// atoms/Button.tsx
import { FormField } from '../molecules'; // WRONG!
// BAD: Molecule importing from organism
// molecules/SearchForm.tsx
import { Header } from '../organisms'; // WRONG!
// BAD: Skipping levels without justification
// organisms/Header.tsx
import { MainLayout } from '../templates'; // WRONG!// design-tokens/colors.ts
export const colors = {
primary: {
50: '#e3f2fd',
100: '#bbdefb',
500: '#2196f3',
900: '#0d47a1',
},
neutral: {
0: '#ffffff',
100: '#f5f5f5',
900: '#212121',
},
};
// design-tokens/spacing.ts
export const spacing = {
xs: '4px',
sm: '8px',
md: '16px',
lg: '24px',
xl: '32px',
};
// design-tokens/typography.ts
export const typography = {
fontFamily: {
sans: 'Inter, system-ui, sans-serif',
mono: 'Fira Code, monospace',
},
fontSize: {
xs: '12px',
sm: '14px',
base: '16px',
lg: '18px',
xl: '24px',
},
};import { colors, spacing, typography } from '@/design-tokens';
const Button = styled.button`
background-color: ${colors.primary[500]};
padding: ${spacing.sm} ${spacing.md};
font-family: ${typography.fontFamily.sans};
font-size: ${typography.fontSize.base};
`;// 1. Define core atoms first
const Button = ({ variant, size, children }) => { ... };
const Input = ({ type, placeholder }) => { ... };
const Label = ({ htmlFor, children }) => { ... };
// 2. Compose into molecules
const FormField = ({ label, ...inputProps }) => (
<div>
<Label>{label}</Label>
<Input {...inputProps} />
</div>
);
// 3. Build organisms from molecules
const LoginForm = () => (
<form>
<FormField label="Email" type="email" />
<FormField label="Password" type="password" />
<Button>Login</Button>
</form>
);// Atoms receive primitive props
interface ButtonProps {
variant: 'primary' | 'secondary';
size: 'sm' | 'md' | 'lg';
disabled?: boolean;
onClick?: () => void;
children: React.ReactNode;
}
// Molecules receive atoms' props via spread
interface SearchFormProps {
onSubmit: (query: string) => void;
inputProps?: Partial<InputProps>;
buttonProps?: Partial<ButtonProps>;
}
// Organisms receive domain-specific props
interface HeaderProps {
user?: User;
onLogout: () => void;
navigation: NavItem[];
}// BAD: Atom with business logic
const PriceButton = ({ productId }) => {
const price = useProductPrice(productId); // WRONG!
return <Button>${price}</Button>;
};
// GOOD: Atom receives processed data
const PriceButton = ({ price, onClick }) => (
<Button onClick={onClick}>${price}</Button>
);
// Business logic lives in organisms or higher
const ProductCard = ({ productId }) => {
const { price } = useProduct(productId);
return <PriceButton price={price} onClick={handleBuy} />;
};/**
* Button - Atomic component for user actions
*
* @level Atom
* @example
* <Button variant="primary" size="md">Click me</Button>
*/
export const Button: React.FC<ButtonProps> = ({ ... }) => { ... };
/**
* SearchForm - Search input with submit button
*
* @level Molecule
* @composition Input, Button
* @example
* <SearchForm onSubmit={(query) => search(query)} />
*/
export const SearchForm: React.FC<SearchFormProps> = ({ ... }) => { ... };// BAD: Too granular - unnecessary atoms
const ButtonText = ({ children }) => <span>{children}</span>;
const ButtonContainer = ({ children }) => <div>{children}</div>;
// GOOD: Appropriate granularity
const Button = ({ children }) => (
<button className="btn">{children}</button>
);// BAD: Too much in one component
const MegaForm = () => (
<form>
<div><label>Name</label><input /></div>
<div><label>Email</label><input /></div>
<div><label>Message</label><textarea /></div>
<button>Submit</button>
</form>
);
// GOOD: Properly decomposed
const ContactForm = () => (
<form>
<FormField label="Name" type="text" />
<FormField label="Email" type="email" />
<TextAreaField label="Message" />
<Button type="submit">Submit</Button>
</form>
);// BAD: Atoms importing from molecules
// atoms/Icon.tsx
import { IconButton } from '../molecules'; // Creates circular dep!
// GOOD: Keep imports flowing downward
// molecules/IconButton.tsx
import { Icon } from '../atoms';
import { Button } from '../atoms';// BAD: Inconsistent naming patterns
atoms/btn.tsx
atoms/InputField.tsx
atoms/text-label.tsx
// GOOD: Consistent PascalCase
atoms/Button.tsx
atoms/Input.tsx
atoms/Label.tsxatomic-design-quarksatomic-design-atomsatomic-design-moleculesatomic-design-organismsatomic-design-templatesatomic-design-integration