# LanguageSwitcher Component

A multilingual navigation component that displays the current page language and provides a slide-out drawer interface for selecting available language variants. Integrates with HubSpot's multi-language content system to enable seamless language switching across translated pages.

## Import path
```tsx
import LanguageSwitcher from '@hubspot/cms-component-library/LanguageSwitcher';
```

## Purpose

The LanguageSwitcher component provides an accessible interface for users to view and switch between available language variants of the current page. It displays a button showing the current language with a globe icon, and opens a slide-out drawer panel listing all available translations. The component automatically fetches language variants from HubSpot's CMS using the `useLanguageVariants` hook and handles navigation to the localized URLs. Use this component in global navigation areas like headers or footers to provide consistent language selection across multilingual sites.

## Component Structure

```
LanguageSwitcher/
├── index.tsx                                 # Main component (wrapper that delegates to Island)
├── types.ts                                  # TypeScript type definitions
├── ContentFields.tsx                         # HubSpot field definitions for content
├── StyleFields.tsx                           # HubSpot field definitions for styling
├── LanguageOptions.tsx                       # Language option list component
├── LanguageOptions.module.scss               # CSS module for language options
├── utils.tsx                                 # Utility functions for language display
├── _dummyData.tsx                            # Dummy translation data for development
├── index.module.scss                         # CSS module with design tokens
├── assets/
│   └── Globe.tsx                             # Globe SVG icon component
├── islands/
│   └── LanguageSwitcherIsland.tsx            # Client-side island with interactive UI
└── stories/
    ├── LanguageSwitcher.stories.tsx          # Component usage examples
    ├── LanguageSwitcherDecorator.tsx         # Storybook decorator
    └── LanguageSwitcherDecorator.module.css  # Decorator styles
```

## Components

### LanguageSwitcher (Main Component)

**Purpose:** Renders a button displaying the current page language that opens a drawer panel with all available language options.

**Props:**
```tsx
{
  translations?: LanguageVariant[];             // Language variants (if not provided, uses useLanguageVariants hook)
  className?: string;                           // Additional CSS classes
  style?: React.CSSProperties;                  // Inline styles
  color?: ColorFieldValue;                      // Text color for button and menu items
  colorHover?: ColorFieldValue;                 // Text color for menu items on hover
  menuBackgroundColor?: ColorFieldValue;        // Background color for the drawer
  menuBackgroundColorHover?: ColorFieldValue;   // Background color for menu items on hover
  languageSwitcherSelectText?: string;          // Header text in drawer (default: 'Select a language')
}
```

## Usage Examples

### Basic Usage

The LanguageSwitcher component automatically handles Island-ification internally. Simply import and use it with optional props:

```tsx
import LanguageSwitcher from '@hubspot/cms-component-library/LanguageSwitcher';

export default function MyComponent() {
  return <LanguageSwitcher />;
}
```

When used without a `translations` prop, it automatically calls `useLanguageVariants()` to fetch language data.

### With Custom Header Text

```tsx
<LanguageSwitcher languageSwitcherSelectText="Choose your language" />
```

### With Custom Translations

```tsx
<LanguageSwitcher translations={customLanguageVariants} />
```

### With Custom Colors

If passing in colors directly (without using a ColorField), like the below example, ensure rgba is an object key. This is because the component expects the rgba key for the color props.

```tsx
<LanguageSwitcher
  color={{ rgba: 'rgba(51, 71, 91, 1)' }}
  colorHover={{ rgba: 'rgba(0, 102, 204, 1)' }}
  menuBackgroundColor={{ rgba: 'rgba(255, 255, 255, 1)' }}
  menuBackgroundColorHover={{ rgba: 'rgba(245, 245, 245, 1)' }}
/>
```

### In Header Navigation

```tsx
<header style={{ display: 'flex', justifyContent: 'space-between', padding: '16px' }}>
  <div>
    <h1>My Website</h1>
  </div>
  <nav style={{ display: 'flex', gap: '24px', alignItems: 'center' }}>
    <a href="/about">About</a>
    <a href="/contact">Contact</a>
    <LanguageSwitcher />
  </nav>
</header>
```

## HubSpot CMS Integration

### Field Definitions

The LanguageSwitcher component provides field definitions for easy integration with HubSpot CMS modules.

#### ContentFields

Configurable props for customizing the drawer header text:

```tsx
<LanguageSwitcher.ContentFields
  languageSwitcherSelectTextLabel="Language selector text"
  languageSwitcherSelectTextName="languageSwitcherSelectText"
  languageSwitcherSelectTextDefault="Select a language"
/>
```

**Fields:**
- `languageSwitcherSelectText`: TextField for drawer header text

#### StyleFields

Configurable props for color customization:

```tsx
<LanguageSwitcher.StyleFields
  textColorLabel="Text color"
  textColorName="textColor"
  textColorDefault={{ color: '#000000', opacity: 100 }}
  textColorHoverLabel="Text color (hover)"
  textColorHoverName="textColorHover"
  textColorHoverDefault={{ color: '#000000', opacity: 100 }}
  menuBackgroundColorLabel="Menu background color"
  menuBackgroundColorName="menuBackgroundColor"
  menuBackgroundColorDefault={{ color: '#FFFFFF', opacity: 100 }}
  menuBackgroundColorHoverLabel="Menu background color (hover)"
  menuBackgroundColorHoverName="menuBackgroundColorHover"
  menuBackgroundColorHoverDefault={{ color: '#eaeaea', opacity: 100 }}
/>
```

**Fields:**
- `textColor`: ColorField for button and menu item text
- `textColorHover`: ColorField for menu item text on hover
- `menuBackgroundColor`: ColorField for drawer background
- `menuBackgroundColorHover`: ColorField for menu item background on hover

### Module Usage Example

If passing in colors using a ColorField, like the below example, pass in the entire field value. HubSpot will transform the field value from a default of { color: hex, opacity: number } to { rgba, rgb, opacity, color, hex, css }. The LanguageSwitcher component will pull the rgba value from this final output.

```tsx
import LanguageSwitcher from '@hubspot/cms-component-library/LanguageSwitcher';

export default function HeaderModule({ fieldValues }) {
  return (
    <header>
      <nav>
        {/* Other navigation items */}
        <LanguageSwitcher
          color={fieldValues.color}
          colorHover={fieldValues.colorHover}
          menuBackgroundColor={fieldValues.menuBackgroundColor}
          menuBackgroundColorHover={fieldValues.menuBackgroundColorHover}
          languageSwitcherSelectText={fieldValues.languageSwitcherSelectText}
        />
      </nav>
    </header>
  );
}
```

## Styling

All base styling uses hardcoded defaults in the CSS module. Colors are applied as inline styles via the `color`, `colorHover`, `menuBackgroundColor`, and `menuBackgroundColorHover` props. Hover and active states for language options use `--hs-languageSwitcher-*` CSS variables set internally by the component.

**Button Styles:**
- Button has 8px 12px padding with 8px gap between icon and text
- Globe icon size: 20px height
- Font size: 18px
- Text color: `currentColor` (overridden by `color` prop via inline style)

**Drawer Styles:**
- Drawer width: 400px (responsive: 100% width on screens ≤400px)
- Header padding: 24px
- Header font size: 24px with font weight 600
- Header background: `#ffffff` (overridden by `menuBackgroundColor` prop via inline style)
- Options container padding: 24px

**Language Options Styles:**
- Link font size: 18px (hardcoded)
- Link padding: 12px 16px
- Hover/active states use `--hs-languageSwitcher-color-hover` and `--hs-languageSwitcher-backgroundColor-hover` CSS variables (set by component from props)

### Custom Styling Example

```tsx
<LanguageSwitcher
  color={{ rgba: 'rgba(51, 71, 91, 1)' }}
  colorHover={{ rgba: 'rgba(0, 102, 204, 1)' }}
  menuBackgroundColor={{ rgba: 'rgba(255, 255, 255, 1)' }}
  menuBackgroundColorHover={{ rgba: 'rgba(245, 245, 245, 1)' }}
/>
```

## Accessibility

The LanguageSwitcher component follows accessibility best practices:

- **Semantic HTML**: Uses proper button elements and drawer component with role="dialog"
- **Keyboard Navigation**:
  - Button activates with Space or Enter keys
  - ESC key closes the drawer
  - Tab navigation works through language options
- **ARIA Attributes**:
  - `aria-expanded` on button indicates drawer state
  - `aria-label="Language selector"` on drawer provides context
  - `aria-label="Close language selector"` on close button
- **Screen Reader Support**:
  - Current language is announced on button
  - Language options are properly labeled with native names
  - Drawer state changes are announced
- **Visual Indicators**:
  - Globe icon provides visual language indication
  - Current language displayed prominently on button
  - Clear visual feedback for hover states
- **Focus Management**: Drawer overlay prevents focus from leaving the language selector when open
- **Color Contrast**: Customizable colors allow meeting WCAG AA standards

## Best Practices

- **Island-ification is handled internally**: The LanguageSwitcher component automatically handles Island-ification for interactive state, so you don't need to manually wrap it
- **Position prominently**: Place in global navigation (header or footer) where users expect language controls
- **Use native language names**: The component automatically displays language names in their native script (e.g., "Español" for Spanish, "Français" for French)
- **Customize header text**: Set `languageSwitcherSelectText` to match your site's primary language for consistency
- **Color coordination**: Match `textColor` and `menuBackgroundColor` to your site's theme
- **Color setting**: If using ColorFields, pass in the entire field value, as HubSpot transforms the user's color choice into an object with an rgba key. Otherwise, ensure the color object has an rgba key and value. The component expects an object with an rgba key.
- **Responsive design**: The drawer automatically adjusts to full width on mobile devices (≤400px)
- **Test with real translations**: Pass real HubSpot language variants via the `translations` prop, or rely on the default `useLanguageVariants()` hook for production
- **Provide clear visual feedback**: Use hover colors that provide sufficient contrast for user interaction
- **Consider placement**: Position near other utility navigation items (search, account, etc.)
- **Dark mode support**: Provide appropriate color values for dark backgrounds when needed

## Common Patterns

### Header Navigation Integration

```tsx
import LanguageSwitcher from '@hubspot/cms-component-library/LanguageSwitcher';

export default function SiteHeader({ fieldValues }) {
  return (
    <header style={{
      display: 'flex',
      justifyContent: 'space-between',
      padding: '16px 24px',
      alignItems: 'center'
    }}>
      <div>
        <h1>Website Name</h1>
      </div>
      <nav style={{ display: 'flex', gap: '24px', alignItems: 'center' }}>
        <a href="/about">About</a>
        <a href="/services">Services</a>
        <a href="/contact">Contact</a>
        <LanguageSwitcher
          color={fieldValues.color}
          menuBackgroundColor={fieldValues.menuBackgroundColor}
          languageSwitcherSelectText={fieldValues.languageSwitcherSelectText}
        />
      </nav>
    </header>
  );
}
```

### Footer Placement

```tsx
import LanguageSwitcher from '@hubspot/cms-component-library/LanguageSwitcher';

export default function SiteFooter({ fieldValues }) {
  return (
    <footer style={{ padding: '48px 24px', textAlign: 'center' }}>
      <div style={{ marginBottom: '24px' }}>
        <LanguageSwitcher
          color={fieldValues.footerTextColor}
          menuBackgroundColor={fieldValues.menuBackgroundColor}
          languageSwitcherSelectText={fieldValues.languageSwitcherSelectText}
        />
      </div>
      <p>© 2024 Company Name. All rights reserved.</p>
    </footer>
  );
}
```

### Mobile-First Navigation

```tsx
import LanguageSwitcher from '@hubspot/cms-component-library/LanguageSwitcher';

export default function MobileNav({ fieldValues }) {
  return (
    <nav style={{
      display: 'flex',
      flexDirection: 'column',
      gap: '16px',
      padding: '16px'
    }}>
      <a href="/">Home</a>
      <a href="/about">About</a>
      <a href="/contact">Contact</a>
      <div style={{ borderTop: '1px solid #eee', paddingTop: '16px' }}>
        <LanguageSwitcher
          color={fieldValues.color}
          menuBackgroundColor={fieldValues.menuBackgroundColor}
        />
      </div>
    </nav>
  );
}
```

## Related Components

- **Drawer**: Used internally for the language selection panel. The LanguageSwitcher uses Drawer with direction="right" and handles open/close state.
- **Button**: Used for the trigger button and close button within the drawer.
- **Divider**: Used to separate the drawer header from language options.
