# Function Declaration Patterns

This document establishes the standard function declaration patterns for the Component Library.

## The Rule

**React-related code uses arrow functions. Everything else uses traditional functions (or arrow functions if preferred).**

### What is "React-related"?

- React components (function components)
- Functions that return JSX
- React callbacks and event handlers
- Field components
- Helper functions within React components that work with JSX or React concepts

### What is "Everything else"?

- Pure utility functions that don't involve React or JSX
- Helper functions for data transformation, formatting, validation
- Functions that operate on plain JavaScript data structures

## ✅ Use Arrow Functions For

### React Components

```typescript
// Main components
const Button = ({
  variant = 'primary',
  children,
  ...rest
}: ButtonProps) => {
  return <button {...rest}>{children}</button>;
};

export default Button;
```

```typescript
// Field components
const ContentFields = ({
  fieldLabel = 'Field',
  fieldName = 'field',
  fieldDefault = 'Default',
}: ContentFieldsProps) => {
  return <TextField label={fieldLabel} name={fieldName} default={fieldDefault} />;
};

export default ContentFields;
```

```typescript
// Island components
const NavigationMenuIsland = ({
  justifyMenu = 'flex-start',
  ...rest
}: NavigationMenuProps) => {
  return <nav {...rest}>{/* JSX */}</nav>;
};

export default NavigationMenuIsland;
```

### Functions That Return JSX

```typescript
const ButtonComponent = ({ buttonType, ...rest }: ButtonProps) => {
  // Helper functions that return JSX use arrow functions
  const renderButton = ({ onClick, disabled, children }: ButtonAsButtonProps) => {
    return (
      <button onClick={onClick} disabled={disabled}>
        {children}
      </button>
    );
  };

  const renderLink = ({ href, children }: ButtonAsLinkProps) => {
    return <a href={href}>{children}</a>;
  };

  if (buttonType === 'button') return renderButton(rest);
  return renderLink(rest);
};
```

### React Callbacks and Event Handlers

```typescript
const Component = () => {
  // Event handlers and callbacks use arrow functions
  const handleClick = () => {
    console.log('clicked');
  };

  const handleKeyDown = (event: React.KeyboardEvent) => {
    if (event.key === 'Enter') {
      // handle enter
    }
  };

  const processData = (data: string) => {
    // processing logic
  };

  return <div onClick={handleClick} onKeyDown={handleKeyDown} />;
};
```

## ✅ Use Traditional Functions For (Optional)

Pure utility functions that don't involve React or JSX can use traditional function declarations if preferred:

```typescript
// Pure utility - no React, no JSX
function formatCurrency(amount: number): string {
  return new Intl.NumberFormat('en-US', {
    style: 'currency',
    currency: 'USD',
  }).format(amount);
}

// Data transformation - no React, no JSX
function sortByDate(items: Item[]): Item[] {
  return [...items].sort((a, b) => a.date.getTime() - b.date.getTime());
}

// Validation - no React, no JSX
function isValidEmail(email: string): boolean {
  return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}
```

**Note:** Arrow functions are also fine for these cases - use whichever you prefer for non-React utilities.

## Why This Pattern?

### Arrow Functions for React Code

1. **Avoids `this` issues**: Arrow functions don't bind their own `this`, preventing common React pitfalls
2. **Consistency**: All React components use the same pattern
3. **Modern convention**: Aligns with current React and TypeScript best practices
4. **Lexical scoping**: Better behavior with closures and event handlers

### Traditional Functions for Utilities

1. **Flexibility**: Use either arrow or traditional - whatever fits the use case
2. **Readability**: Traditional functions can be more readable for complex utility logic
3. **Hoisting**: Traditional functions are hoisted, which can be useful for utility organization

## Scope

This pattern applies to:

### Must Use Arrow Functions

- All React components (`*/index.tsx`)
- All Field components (`*Fields.tsx`)
- All Island components (`*/islands/*.tsx`)
- All helper functions within React components
- All functions that return JSX
- All React callbacks and event handlers

### Can Use Either

- Utility functions that don't involve React/JSX
- Data transformation functions
- Validation functions
- Pure JavaScript helpers

## Examples

### React Component with Helper Functions

```typescript
// Button/index.tsx
const ButtonComponent = ({
  buttonType = 'link',
  variant = 'primary',
  className = '',
  style = {},
  ...rest
}: ButtonProps) => {
  // Arrow function - returns JSX
  const renderButton = ({ onClick, disabled, children }: ButtonAsButtonProps) => {
    return (
      <button onClick={onClick} disabled={disabled}>
        {children}
      </button>
    );
  };

  // Arrow function - returns JSX
  const renderLink = ({ href, target, children }: ButtonAsLinkProps) => {
    return <a href={href} target={target}>{children}</a>;
  };

  if (buttonType === 'button') return renderButton(rest);
  return renderLink(rest);
};

export default ButtonComponent;
```

### Field Component

```typescript
// ContentFields.tsx
const ContentFields = ({
  fieldLabel = 'Field',
  fieldName = 'field',
  fieldDefault = 'Default',
}: ContentFieldsProps) => {
  return (
    <TextField
      label={fieldLabel}
      name={fieldName}
      default={fieldDefault}
    />
  );
};

export default ContentFields;
```

### Island Component

```typescript
// NavigationMenuIsland.tsx
const NavigationMenuIsland = ({
  justifyMenu = 'flex-start',
  className = '',
  ...rest
}: NavigationMenuProps) => {
  // Arrow function - React event handler
  const handleKeyDown = (event: React.KeyboardEvent) => {
    if (event.key === 'ArrowDown') {
      event.preventDefault();
      // handle navigation
    }
  };

  return (
    <nav onKeyDown={handleKeyDown} className={className} {...rest}>
      {/* JSX */}
    </nav>
  );
};

export default NavigationMenuIsland;
```

### Utility Functions (Non-React)

```typescript
// utils/transformMenuData.ts
// Arrow function is fine for utilities
export const addIdsToMenuItems = (items: MenuDataItem[]): EnrichedMenuDataItem[] => {
  return items.map(item => ({
    ...item,
    _id: crypto.randomUUID(),
  }));
};

// Traditional function is also fine
export function formatDate(date: Date): string {
  return date.toISOString().split('T')[0];
}
```

## Summary

- **React components, JSX-returning functions, React callbacks** → Always arrow functions
- **Pure utilities (no React/JSX)** → Either arrow or traditional (your choice)
- **When in doubt** → Use arrow functions

## Related Patterns

- [Component Structure](./component-structure.md) - General component patterns
- [TypeScript Patterns](./typescript-patterns.md) - Type definitions and patterns
- [Field Patterns](./field-patterns.md) - Field component patterns
