# 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 with render logic
├── 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
└── 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
{
  className?: string;                           // Additional CSS classes
  style?: React.CSSProperties;                  // Inline styles
  textColor?: ColorFieldValue;                  // Text color for button and menu items
  textColorHover?: 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')
  useDummyData?: boolean;                       // Use dummy data for testing (development only)
}
```

## Usage Examples

### Island Usage

The LanguageSwitcher component requires JavaScript for interactive state management and must be used within an Island component.

#### Island Component

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

export default function LanguageSwitcherIsland({
  textColor,
  textColorHover,
  menuBackgroundColor,
  menuBackgroundColorHover,
  languageSwitcherSelectText,
}) {
  return (
    <LanguageSwitcher
      textColor={textColor}
      textColorHover={textColorHover}
      menuBackgroundColor={menuBackgroundColor}
      menuBackgroundColorHover={menuBackgroundColorHover}
      languageSwitcherSelectText={languageSwitcherSelectText}
    />
  );
}
```

#### Module File

```tsx
import { Island } from '@hubspot/cms-components';
import LanguageSwitcherIsland from './islands/LanguageSwitcherIsland?island';

export const Component = ({ fieldValues }) => {
  return (
    <Island
      module={LanguageSwitcherIsland}
      textColor={fieldValues.textColor}
      textColorHover={fieldValues.textColorHover}
      menuBackgroundColor={fieldValues.menuBackgroundColor}
      menuBackgroundColorHover={fieldValues.menuBackgroundColorHover}
      languageSwitcherSelectText={fieldValues.languageSwitcherSelectText}
    />
  );
};
```

### Basic Language Switcher

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

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

### With Custom Header Text

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

### 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
  textColor={{ rgba: 'rgba(51, 71, 91, 1)' }}
  textColorHover={{ 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 { rbga, rgb, opacity, color, hex, css }. The LanguageSwitcher component will pull the rgba value from this final output.

```tsx
import { Island } from '@hubspot/cms-components';
import LanguageSwitcherIsland from './islands/LanguageSwitcherIsland?island';

export default function HeaderModule({ fieldValues }) {
  return (
    <header>
      <nav>
        {/* Other navigation items */}
        <Island
          module={LanguageSwitcherIsland}
          textColor={fieldValues.textColor}
          textColorHover={fieldValues.textColorHover}
          menuBackgroundColor={fieldValues.menuBackgroundColor}
          menuBackgroundColorHover={fieldValues.menuBackgroundColorHover}
          languageSwitcherSelectText={fieldValues.languageSwitcherSelectText}
        />
      </nav>
    </header>
  );
}
```

## Styling

### CSS Variables

The LanguageSwitcher component uses CSS variables for theming and customization:

**Base Styles:**
- `--hscl-languageSwitcher-textColor`: Text color for button, drawer header, and close button (default: currentColor)
- `--hscl-languageSwitcher-backgroundColor`: Background color for drawer header (default: #ffffff)

**Button Styles:**
- Button has 8px 12px padding with 8px gap between icon and text
- Globe icon size: 20px height
- Font size: 18px

**Drawer Styles:**
- Drawer width: 400px (responsive: 100% width on screens ≤400px)
- Header padding: 24px
- Header font size: 24px with font weight 600
- Options container padding: 24px

### Custom Styling Example

```tsx
<LanguageSwitcher
  style={{
    '--hscl-languageSwitcher-textColor': 'rgba(51, 71, 91, 1)',
    '--hscl-languageSwitcher-backgroundColor': 'rgba(255, 255, 255, 1)',
  } as React.CSSProperties}
/>
```

## 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

- **Use Islands for interactivity**: The LanguageSwitcher component is interactive and requires JavaScript, so it must be used within an Island component in modules
- **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**: While `useDummyData` prop exists for development, always test with actual HubSpot language variants in 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 { Island } from '@hubspot/cms-components';
import LanguageSwitcherIsland from './islands/LanguageSwitcherIsland?island';

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>
        <Island
          module={LanguageSwitcherIsland}
          textColor={fieldValues.textColor}
          menuBackgroundColor={fieldValues.menuBackgroundColor}
          languageSwitcherSelectText={fieldValues.languageSwitcherSelectText}
        />
      </nav>
    </header>
  );
}
```

### Footer Placement

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

### Mobile-First Navigation

```tsx
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' }}>
        <Island
          module={LanguageSwitcherIsland}
          textColor={fieldValues.textColor}
          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.
