Atomic Design to metodologia organizacji komponentów stworzona przez Brada Frosta. Analogia kosmiczna jest idealna: zaczynamy od atomów (najmniejsze cząstki materii), łączymy je w molekuły, potem w organizmy, aż zbudujemy całe strony -- galaktyki naszej aplikacji.
Atomy to podstawowe elementy UI, które nie mają sensu rozbijać dalej:
1// atoms/Button.jsx
2function Button({ variant = 'primary', size = 'md', children, ...props }) {
3 return (
4 <button className={`btn btn-${variant} btn-${size}`} {...props}>
5 {children}
6 </button>
7 );
8}
9
10// atoms/Input.jsx
11function Input({ label, error, ...props }) {
12 return (
13 <div className="input-group">
14 {label && <label>{label}</label>}
15 <input className={`input ${error ? 'input-error' : ''}`} {...props} />
16 {error && <span className="error-text">{error}</span>}
17 </div>
18 );
19}
20
21// atoms/Badge.jsx
22function Badge({ children, color = 'blue' }) {
23 return <span className={`badge badge-${color}`}>{children}</span>;
24}
25
26// atoms/Avatar.jsx
27function Avatar({ src, name, size = 'md' }) {
28 return (
29 <img
30 className={`avatar avatar-${size}`}
31 src={src}
32 alt={name}
33 />
34 );
35}Molekuły łączą kilka atomów w funkcjonalną grupę:
1// molecules/SearchBar.jsx
2function SearchBar({ onSearch }) {
3 const [query, setQuery] = useState('');
4
5 return (
6 <div className="search-bar">
7 <Input
8 placeholder="Szukaj planety..."
9 value={query}
10 onChange={(e) => setQuery(e.target.value)}
11 />
12 <Button onClick={() => onSearch(query)}>Szukaj</Button>
13 </div>
14 );
15}
16
17// molecules/UserCard.jsx
18function UserCard({ user }) {
19 return (
20 <div className="user-card">
21 <Avatar src={user.avatar} name={user.name} />
22 <div>
23 <h4>{user.name}</h4>
24 <Badge color={user.role === 'captain' ? 'gold' : 'blue'}>
25 {user.role}
26 </Badge>
27 </div>
28 </div>
29 );
30}Organizmy to złożone elementy budowane z molekuł i atomów:
1// organisms/CrewPanel.jsx
2function CrewPanel({ crew, onSearch, onSelect }) {
3 const [filtered, setFiltered] = useState(crew);
4
5 const handleSearch = (query) => {
6 const results = crew.filter(m =>
7 m.name.toLowerCase().includes(query.toLowerCase())
8 );
9 setFiltered(results);
10 onSearch(query);
11 };
12
13 return (
14 <section className="crew-panel">
15 <h2>Zaloga</h2>
16 <SearchBar onSearch={handleSearch} />
17 <div className="crew-grid">
18 {filtered.map(member => (
19 <UserCard
20 key={member.id}
21 user={member}
22 onClick={() => onSelect(member)}
23 />
24 ))}
25 </div>
26 </section>
27 );
28}Templates definiują układ strony bez konkretnych danych:
1// templates/DashboardTemplate.jsx
2function DashboardTemplate({ header, sidebar, main, footer }) {
3 return (
4 <div className="dashboard-layout">
5 <header className="dash-header">{header}</header>
6 <div className="dash-body">
7 <aside className="dash-sidebar">{sidebar}</aside>
8 <main className="dash-main">{main}</main>
9 </div>
10 <footer className="dash-footer">{footer}</footer>
11 </div>
12 );
13}Pages łączą template z konkretnymi danymi:
1// pages/MissionDashboard.jsx
2function MissionDashboard() {
3 const { data: crew } = useFetch('/api/crew');
4 const { data: missions } = useFetch('/api/missions');
5
6 return (
7 <DashboardTemplate
8 header={<NavigationBar />}
9 sidebar={<CrewPanel crew={crew} />}
10 main={<MissionMap missions={missions} />}
11 footer={<StatusBar />}
12 />
13 );
14}1src/
2 components/
3 atoms/
4 Button.jsx
5 Input.jsx
6 Badge.jsx
7 molecules/
8 SearchBar.jsx
9 UserCard.jsx
10 organisms/
11 CrewPanel.jsx
12 NavigationBar.jsx
13 templates/
14 DashboardTemplate.jsx
15 pages/
16 MissionDashboard.jsxAtomic Design najlepiej działa w dużych projektach z wieloma stronami i komponentami. Jeśli budujesz prostą aplikację z kilkoma widokami, pełna hierarchia pięciu poziomów może być przesadą. W takim przypadku wystarczy prosty podział na
components/ i pages/.Jednak w projektach na skalę kosmicznej stacji -- z dziesiątkami ekranów, formularzami, dashboardami -- Atomic Design przynosi ogromne korzyści:
Button jest używany w dziesiątkach miejscJeśli nie jesteś pewien, na którym poziomie umieścić komponent, zadaj sobie pytanie: "Czy ten komponent ma sens sam w sobie, czy potrzebuje kontekstu?" Atom działa wszędzie. Molekuła potrzebuje atomów. Organizm potrzebuje molekuł i logiki biznesowej.