Claude
Skills
Sign in
Back

atomic-design-integration

Included with Lifetime
$97 forever

Use when integrating Atomic Design methodology with React, Vue, Angular, or other frameworks. Framework-specific implementation patterns.

Design

What this skill does


# Atomic Design: Framework Integration

Master the integration of Atomic Design methodology with modern frontend frameworks. This skill covers React, Vue, Angular, and general patterns for implementing atomic component hierarchies.

## React Integration

### Project Structure

```text
src/
  components/
    atoms/
      Button/
        Button.tsx
        Button.module.css
        Button.test.tsx
        Button.stories.tsx
        index.ts
      index.ts                 # Barrel export
    molecules/
      FormField/
        FormField.tsx
        FormField.module.css
        FormField.test.tsx
        index.ts
      index.ts
    organisms/
      Header/
        Header.tsx
        Header.module.css
        useHeader.ts           # Custom hook
        index.ts
      index.ts
    templates/
      MainLayout/
        MainLayout.tsx
        MainLayout.module.css
        index.ts
      index.ts
    index.ts                   # Main barrel export
  pages/                       # Next.js or page components
    HomePage/
      HomePage.tsx
      index.ts
```

### Barrel Exports Pattern

```typescript
// components/atoms/index.ts
export { Button } from './Button';
export type { ButtonProps } from './Button';

export { Input } from './Input';
export type { InputProps } from './Input';

export { Label } from './Label';
export type { LabelProps } from './Label';

export { Icon } from './Icon';
export type { IconProps } from './Icon';

// components/index.ts
export * from './atoms';
export * from './molecules';
export * from './organisms';
export * from './templates';
```

### Component Template (React/TypeScript)

```typescript
// components/atoms/Button/Button.tsx
import React, { forwardRef } from 'react';
import type { ButtonHTMLAttributes } from 'react';
import styles from './Button.module.css';
import { clsx } from 'clsx';

export type ButtonVariant = 'primary' | 'secondary' | 'tertiary';
export type ButtonSize = 'sm' | 'md' | 'lg';

export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
  variant?: ButtonVariant;
  size?: ButtonSize;
  fullWidth?: boolean;
  isLoading?: boolean;
  leftIcon?: React.ReactNode;
  rightIcon?: React.ReactNode;
}

export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
  (
    {
      variant = 'primary',
      size = 'md',
      fullWidth = false,
      isLoading = false,
      leftIcon,
      rightIcon,
      disabled,
      children,
      className,
      ...props
    },
    ref
  ) => {
    return (
      <button
        ref={ref}
        className={clsx(
          styles.button,
          styles[variant],
          styles[size],
          fullWidth && styles.fullWidth,
          isLoading && styles.loading,
          className
        )}
        disabled={disabled || isLoading}
        aria-busy={isLoading}
        {...props}
      >
        {isLoading ? (
          <span className={styles.spinner} aria-hidden="true" />
        ) : (
          <>
            {leftIcon && <span className={styles.leftIcon}>{leftIcon}</span>}
            {children}
            {rightIcon && <span className={styles.rightIcon}>{rightIcon}</span>}
          </>
        )}
      </button>
    );
  }
);

Button.displayName = 'Button';
```

### Custom Hooks with Atomic Design

```typescript
// organisms/Header/useHeader.ts
import { useState, useCallback } from 'react';

interface UseHeaderOptions {
  user?: { id: string; name: string };
  onLogout?: () => void;
}

export function useHeader({ user, onLogout }: UseHeaderOptions) {
  const [menuOpen, setMenuOpen] = useState(false);
  const [searchQuery, setSearchQuery] = useState('');

  const toggleMenu = useCallback(() => {
    setMenuOpen((prev) => !prev);
  }, []);

  const handleSearch = useCallback((query: string) => {
    setSearchQuery(query);
    // Could trigger search action here
  }, []);

  const handleLogout = useCallback(() => {
    setMenuOpen(false);
    onLogout?.();
  }, [onLogout]);

  return {
    menuOpen,
    toggleMenu,
    searchQuery,
    handleSearch,
    handleLogout,
    isAuthenticated: !!user,
  };
}
```

### Context for Design Tokens

```typescript
// contexts/ThemeContext.tsx
import React, { createContext, useContext, useState } from 'react';

interface Theme {
  colors: {
    primary: string;
    secondary: string;
    background: string;
    text: string;
  };
  spacing: {
    xs: string;
    sm: string;
    md: string;
    lg: string;
  };
}

const defaultTheme: Theme = {
  colors: {
    primary: '#2196f3',
    secondary: '#f50057',
    background: '#ffffff',
    text: '#212121',
  },
  spacing: {
    xs: '4px',
    sm: '8px',
    md: '16px',
    lg: '24px',
  },
};

const ThemeContext = createContext<{
  theme: Theme;
  setTheme: (theme: Theme) => void;
}>({
  theme: defaultTheme,
  setTheme: () => {},
});

export const ThemeProvider: React.FC<{ children: React.ReactNode }> = ({
  children,
}) => {
  const [theme, setTheme] = useState(defaultTheme);

  return (
    <ThemeContext.Provider value={{ theme, setTheme }}>
      {children}
    </ThemeContext.Provider>
  );
};

export const useTheme = () => useContext(ThemeContext);
```

## Vue Integration

### Project Structure (Vue 3)

```text
src/
  components/
    atoms/
      VButton/
        VButton.vue
        VButton.spec.ts
        index.ts
      VInput/
      index.ts
    molecules/
      VFormField/
        VFormField.vue
        useFormField.ts
        index.ts
      index.ts
    organisms/
      VHeader/
        VHeader.vue
        index.ts
      index.ts
    templates/
      MainLayout/
        MainLayout.vue
        index.ts
```

### Vue Component Template

```vue
<!-- components/atoms/VButton/VButton.vue -->
<template>
  <button
    :class="buttonClasses"
    :disabled="disabled || loading"
    :aria-busy="loading"
    v-bind="$attrs"
  >
    <span v-if="loading" class="spinner" aria-hidden="true" />
    <template v-else>
      <span v-if="$slots.leftIcon" class="left-icon">
        <slot name="leftIcon" />
      </span>
      <slot />
      <span v-if="$slots.rightIcon" class="right-icon">
        <slot name="rightIcon" />
      </span>
    </template>
  </button>
</template>

<script setup lang="ts">
import { computed } from 'vue';

export interface ButtonProps {
  variant?: 'primary' | 'secondary' | 'tertiary';
  size?: 'sm' | 'md' | 'lg';
  fullWidth?: boolean;
  loading?: boolean;
  disabled?: boolean;
}

const props = withDefaults(defineProps<ButtonProps>(), {
  variant: 'primary',
  size: 'md',
  fullWidth: false,
  loading: false,
  disabled: false,
});

const buttonClasses = computed(() => [
  'btn',
  `btn-${props.variant}`,
  `btn-${props.size}`,
  { 'btn-full': props.fullWidth, 'btn-loading': props.loading },
]);
</script>

<style scoped>
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  border: none;
  border-radius: 6px;
  font-weight: 500;
  cursor: pointer;
  transition: all 150ms ease;
}

.btn-primary {
  background-color: var(--color-primary);
  color: white;
}

.btn-sm {
  padding: 6px 12px;
  font-size: 14px;
}

.btn-md {
  padding: 8px 16px;
  font-size: 16px;
}

.btn-lg {
  padding: 12px 24px;
  font-size: 18px;
}

.btn-full {
  width: 100%;
}

.btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
</style>
```

### Vue Composables (Hooks)

```typescript
// components/organisms/VHeader/useHeader.ts
import { ref, computed } from 'vue';
import type { Ref } from 'vue';

interface User {
  id: string;
  name: string;
}

export function useHeader(user: Ref<User | null>) {
  const menuOpen = ref(false);
  const searchQuery = ref('');

  const isAuthenticated = computed(() => !!user.value);

  const toggleMenu = () => {
    menuOpen.value = !menuOpen.value;
  };

  const handleSearch = (query: string) => {
    searchQuery.value = query;
  };

  return {
    menuOpen,
    searchQuery,
    isAuthenticated,
    toggleMenu,
    handleSearch,
  };
}
```

## Angular Integration

### Project Structure (Angular)

```text

Related in Design