Skip to content

Code Component Templates

Overview

Standardized code components that implement our brand system consistently across all digital touchpoints.

Component Structure

Base Component Template

/**
 * @component ComponentName
 * @description Brief description of component purpose
 * @version 1.0.0
 * @author Your Team
 * @example
 * <ComponentName
 *   variant="primary"
 *   size="medium"
 *   onClick={handleClick}
 * />
 */

import React from 'react';
import { styled } from '@emotion/styled';
import { ComponentProps } from './types';
import { useTheme } from '../../hooks/useTheme';
import { BRAND_TOKENS } from '../../constants/brand';

const StyledComponent = styled.div<ComponentProps>`
  /* Base styles using brand tokens */
  font-family: ${BRAND_TOKENS.typography.fontFamily};
  transition: all ${BRAND_TOKENS.animation.duration.fast} ${BRAND_TOKENS.animation.easing.default};

  /* Variant styles */
  ${props => props.variant === 'primary' && `
    background-color: ${BRAND_TOKENS.colors.primary};
    color: ${BRAND_TOKENS.colors.white};
  `}
`;

export const ComponentName: React.FC<ComponentProps> = ({
  variant = 'primary',
  size = 'medium',
  children,
  className,
  ...props
}) => {
  const theme = useTheme();

  return (
    <StyledComponent
      variant={variant}
      size={size}
      className={className}
      {...props}
    >
      {children}
    </StyledComponent>
  );
};

// Default props
ComponentName.defaultProps = {
  variant: 'primary',
  size: 'medium',
};

Common Components

1. Brand Button

// BrandButton.tsx
import React from 'react';
import { styled } from '@emotion/styled';
import { BRAND_TOKENS } from '../../constants/brand';

interface BrandButtonProps {
  variant?: 'primary' | 'secondary' | 'tertiary';
  size?: 'small' | 'medium' | 'large';
  fullWidth?: boolean;
  disabled?: boolean;
  loading?: boolean;
  icon?: React.ReactNode;
  children: React.ReactNode;
  onClick?: () => void;
}

const StyledButton = styled.button<BrandButtonProps>`
  /* Base styles */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: ${BRAND_TOKENS.spacing.xs};
  font-family: ${BRAND_TOKENS.typography.fontFamily};
  font-weight: ${BRAND_TOKENS.typography.fontWeight.medium};
  border: none;
  border-radius: ${BRAND_TOKENS.borderRadius.md};
  cursor: pointer;
  transition: all ${BRAND_TOKENS.animation.duration.fast} ${BRAND_TOKENS.animation.easing.default};

  /* Size variants */
  ${props => {
    switch (props.size) {
      case 'small':
        return `
          padding: ${BRAND_TOKENS.spacing.xs} ${BRAND_TOKENS.spacing.sm};
          font-size: ${BRAND_TOKENS.typography.fontSize.sm};
        `;
      case 'large':
        return `
          padding: ${BRAND_TOKENS.spacing.md} ${BRAND_TOKENS.spacing.xl};
          font-size: ${BRAND_TOKENS.typography.fontSize.lg};
        `;
      default:
        return `
          padding: ${BRAND_TOKENS.spacing.sm} ${BRAND_TOKENS.spacing.lg};
          font-size: ${BRAND_TOKENS.typography.fontSize.md};
        `;
    }
  }}

  /* Variant styles */
  ${props => {
    switch (props.variant) {
      case 'secondary':
        return `
          background-color: transparent;
          color: ${BRAND_TOKENS.colors.primary};
          border: 2px solid ${BRAND_TOKENS.colors.primary};

          &:hover:not(:disabled) {
            background-color: ${BRAND_TOKENS.colors.primary};
            color: ${BRAND_TOKENS.colors.white};
          }
        `;
      case 'tertiary':
        return `
          background-color: transparent;
          color: ${BRAND_TOKENS.colors.primary};

          &:hover:not(:disabled) {
            background-color: ${BRAND_TOKENS.colors.gray.light};
          }
        `;
      default:
        return `
          background-color: ${BRAND_TOKENS.colors.primary};
          color: ${BRAND_TOKENS.colors.white};

          &:hover:not(:disabled) {
            background-color: ${BRAND_TOKENS.colors.primary.dark};
          }
        `;
    }
  }}

  /* States */
  ${props => props.fullWidth && `width: 100%;`}

  &:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }

  &:focus-visible {
    outline: 2px solid ${BRAND_TOKENS.colors.primary};
    outline-offset: 2px;
  }
`;

export const BrandButton: React.FC<BrandButtonProps> = ({
  variant = 'primary',
  size = 'medium',
  fullWidth = false,
  disabled = false,
  loading = false,
  icon,
  children,
  onClick,
}) => {
  return (
    <StyledButton
      variant={variant}
      size={size}
      fullWidth={fullWidth}
      disabled={disabled || loading}
      onClick={onClick}
    >
      {loading ? <LoadingSpinner /> : icon}
      {children}
    </StyledButton>
  );
};

2. Brand Card

// BrandCard.tsx
const StyledCard = styled.div<{ elevation?: number }>`
  background-color: ${BRAND_TOKENS.colors.white};
  border-radius: ${BRAND_TOKENS.borderRadius.lg};
  box-shadow: ${props => BRAND_TOKENS.shadows[props.elevation || 1]};
  overflow: hidden;
  transition: box-shadow ${BRAND_TOKENS.animation.duration.normal} ${BRAND_TOKENS.animation.easing.default};

  &:hover {
    box-shadow: ${props => BRAND_TOKENS.shadows[props.elevation ? props.elevation + 1 : 2]};
  }
`;

const CardHeader = styled.div`
  padding: ${BRAND_TOKENS.spacing.lg};
  border-bottom: 1px solid ${BRAND_TOKENS.colors.gray.light};
`;

const CardBody = styled.div`
  padding: ${BRAND_TOKENS.spacing.lg};
`;

const CardFooter = styled.div`
  padding: ${BRAND_TOKENS.spacing.lg};
  border-top: 1px solid ${BRAND_TOKENS.colors.gray.light};
  background-color: ${BRAND_TOKENS.colors.gray.lightest};
`;

3. Brand Input

// BrandInput.tsx
const InputWrapper = styled.div`
  position: relative;
  width: 100%;
`;

const StyledInput = styled.input<{ hasError?: boolean }>`
  width: 100%;
  padding: ${BRAND_TOKENS.spacing.sm} ${BRAND_TOKENS.spacing.md};
  font-family: ${BRAND_TOKENS.typography.fontFamily};
  font-size: ${BRAND_TOKENS.typography.fontSize.md};
  border: 2px solid ${props =>
    props.hasError ? BRAND_TOKENS.colors.error : BRAND_TOKENS.colors.gray.medium
  };
  border-radius: ${BRAND_TOKENS.borderRadius.md};
  background-color: ${BRAND_TOKENS.colors.white};
  transition: all ${BRAND_TOKENS.animation.duration.fast} ${BRAND_TOKENS.animation.easing.default};

  &:focus {
    outline: none;
    border-color: ${props =>
      props.hasError ? BRAND_TOKENS.colors.error : BRAND_TOKENS.colors.primary
    };
    box-shadow: 0 0 0 3px ${props =>
      props.hasError ? BRAND_TOKENS.colors.error + '20' : BRAND_TOKENS.colors.primary + '20'
    };
  }

  &::placeholder {
    color: ${BRAND_TOKENS.colors.gray.medium};
  }

  &:disabled {
    background-color: ${BRAND_TOKENS.colors.gray.lightest};
    cursor: not-allowed;
  }
`;

4. Brand Badge

// BrandBadge.tsx
const StyledBadge = styled.span<{ variant: string }>`
  display: inline-flex;
  align-items: center;
  padding: ${BRAND_TOKENS.spacing.xxs} ${BRAND_TOKENS.spacing.xs};
  font-size: ${BRAND_TOKENS.typography.fontSize.xs};
  font-weight: ${BRAND_TOKENS.typography.fontWeight.medium};
  border-radius: ${BRAND_TOKENS.borderRadius.full};

  ${props => {
    const colors = {
      primary: { bg: BRAND_TOKENS.colors.primary + '20', text: BRAND_TOKENS.colors.primary },
      success: { bg: BRAND_TOKENS.colors.success + '20', text: BRAND_TOKENS.colors.success },
      warning: { bg: BRAND_TOKENS.colors.warning + '20', text: BRAND_TOKENS.colors.warning },
      error: { bg: BRAND_TOKENS.colors.error + '20', text: BRAND_TOKENS.colors.error },
      neutral: { bg: BRAND_TOKENS.colors.gray.light, text: BRAND_TOKENS.colors.gray.dark },
    };

    const color = colors[props.variant] || colors.neutral;
    return `
      background-color: ${color.bg};
      color: ${color.text};
    `;
  }}
`;

Brand Tokens

// constants/brand.ts
export const BRAND_TOKENS = {
  colors: {
    primary: {
      DEFAULT: '#2563EB',
      light: '#3B82F6',
      dark: '#1E40AF',
    },
    secondary: {
      DEFAULT: '#10B981',
      light: '#34D399',
      dark: '#059669',
    },
    gray: {
      lightest: '#F9FAFB',
      light: '#E5E7EB',
      medium: '#9CA3AF',
      dark: '#4B5563',
      darkest: '#1F2937',
    },
    white: '#FFFFFF',
    black: '#000000',
    error: '#EF4444',
    warning: '#F59E0B',
    success: '#10B981',
    info: '#3B82F6',
  },

  typography: {
    fontFamily: '\'Inter\', -apple-system, BlinkMacSystemFont, sans-serif',
    fontSize: {
      xs: '0.75rem',
      sm: '0.875rem',
      md: '1rem',
      lg: '1.125rem',
      xl: '1.25rem',
      '2xl': '1.5rem',
      '3xl': '1.875rem',
      '4xl': '2.25rem',
    },
    fontWeight: {
      light: 300,
      regular: 400,
      medium: 500,
      semibold: 600,
      bold: 700,
    },
    lineHeight: {
      tight: 1.25,
      normal: 1.5,
      relaxed: 1.75,
    },
  },

  spacing: {
    xxs: '0.25rem',
    xs: '0.5rem',
    sm: '0.75rem',
    md: '1rem',
    lg: '1.5rem',
    xl: '2rem',
    '2xl': '3rem',
    '3xl': '4rem',
  },

  borderRadius: {
    sm: '0.25rem',
    md: '0.375rem',
    lg: '0.5rem',
    xl: '0.75rem',
    full: '9999px',
  },

  shadows: {
    0: 'none',
    1: '0 1px 3px rgba(0, 0, 0, 0.1)',
    2: '0 4px 6px rgba(0, 0, 0, 0.1)',
    3: '0 10px 15px rgba(0, 0, 0, 0.1)',
    4: '0 20px 25px rgba(0, 0, 0, 0.1)',
  },

  animation: {
    duration: {
      fast: '150ms',
      normal: '300ms',
      slow: '500ms',
    },
    easing: {
      default: 'cubic-bezier(0.4, 0, 0.2, 1)',
      in: 'cubic-bezier(0.4, 0, 1, 1)',
      out: 'cubic-bezier(0, 0, 0.2, 1)',
      inOut: 'cubic-bezier(0.4, 0, 0.2, 1)',
    },
  },
};

Utility Components

Loading Spinner

const SpinnerKeyframes = keyframes`
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
`;

const LoadingSpinner = styled.div<{ size?: string }>`
  width: ${props => props.size || '20px'};
  height: ${props => props.size || '20px'};
  border: 2px solid ${BRAND_TOKENS.colors.gray.light};
  border-top-color: ${BRAND_TOKENS.colors.primary};
  border-radius: 50%;
  animation: ${SpinnerKeyframes} 0.8s linear infinite;
`;

Error Message

const ErrorMessage = styled.div`
  display: flex;
  align-items: center;
  gap: ${BRAND_TOKENS.spacing.xs};
  padding: ${BRAND_TOKENS.spacing.sm};
  background-color: ${BRAND_TOKENS.colors.error}20;
  color: ${BRAND_TOKENS.colors.error};
  border-radius: ${BRAND_TOKENS.borderRadius.md};
  font-size: ${BRAND_TOKENS.typography.fontSize.sm};

  svg {
    flex-shrink: 0;
  }
`;

Toast Notification

const Toast = styled.div<{ type: 'success' | 'error' | 'warning' | 'info' }>`
  position: fixed;
  bottom: ${BRAND_TOKENS.spacing.lg};
  right: ${BRAND_TOKENS.spacing.lg};
  padding: ${BRAND_TOKENS.spacing.md};
  background-color: ${BRAND_TOKENS.colors.white};
  border-radius: ${BRAND_TOKENS.borderRadius.lg};
  box-shadow: ${BRAND_TOKENS.shadows[3]};
  display: flex;
  align-items: center;
  gap: ${BRAND_TOKENS.spacing.sm};
  min-width: 300px;
  max-width: 500px;

  &::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 4px;
    background-color: ${props => BRAND_TOKENS.colors[props.type]};
    border-radius: ${BRAND_TOKENS.borderRadius.lg} 0 0 ${BRAND_TOKENS.borderRadius.lg};
  }
`;

Accessibility Patterns

Focus Management

// useFocusTrap.ts
export const useFocusTrap = (ref: RefObject<HTMLElement>) => {
  useEffect(() => {
    const element = ref.current;
    if (!element) return;

    const focusableElements = element.querySelectorAll(
      'a[href], button, textarea, input[type="text"], input[type="radio"], input[type="checkbox"], select'
    );

    const firstFocusable = focusableElements[0] as HTMLElement;
    const lastFocusable = focusableElements[focusableElements.length - 1] as HTMLElement;

    const handleKeyDown = (e: KeyboardEvent) => {
      if (e.key !== 'Tab') return;

      if (e.shiftKey && document.activeElement === firstFocusable) {
        lastFocusable.focus();
        e.preventDefault();
      } else if (!e.shiftKey && document.activeElement === lastFocusable) {
        firstFocusable.focus();
        e.preventDefault();
      }
    };

    element.addEventListener('keydown', handleKeyDown);
    firstFocusable?.focus();

    return () => element.removeEventListener('keydown', handleKeyDown);
  }, [ref]);
};

ARIA Patterns

// Accessible Modal
const Modal = ({ isOpen, onClose, title, children }) => {
  const modalRef = useRef(null);
  useFocusTrap(modalRef);

  return (
    <div
      role="dialog"
      aria-modal="true"
      aria-labelledby="modal-title"
      aria-hidden={!isOpen}
      ref={modalRef}
    >
      <h2 id="modal-title">{title}</h2>
      <button
        aria-label="Close modal"
        onClick={onClose}
      >
        <CloseIcon />
      </button>
      {children}
    </div>
  );
};

Testing Templates

Component Test

// BrandButton.test.tsx
import { render, screen, fireEvent } from '@testing-library/react';
import { BrandButton } from './BrandButton';

describe('BrandButton', () => {
  it('renders with correct text', () => {
    render(<BrandButton>Click me</BrandButton>);
    expect(screen.getByText('Click me')).toBeInTheDocument();
  });

  it('handles click events', () => {
    const handleClick = jest.fn();
    render(<BrandButton onClick={handleClick}>Click me</BrandButton>);
    fireEvent.click(screen.getByText('Click me'));
    expect(handleClick).toHaveBeenCalledTimes(1);
  });

  it('applies correct variant styles', () => {
    const { rerender } = render(<BrandButton variant="primary">Button</BrandButton>);
    expect(screen.getByText('Button')).toHaveStyle({
      backgroundColor: BRAND_TOKENS.colors.primary
    });

    rerender(<BrandButton variant="secondary">Button</BrandButton>);
    expect(screen.getByText('Button')).toHaveStyle({
      backgroundColor: 'transparent'
    });
  });
});

Component Library v2.0
Last Updated: January 2024
Design System: design.company.com