# FlagPicker Component

A comprehensive country flag picker component supporting all 249 ISO 3166-1 alpha-2 country codes.

## Features

- **Complete Coverage**: All 249 ISO 3166-1 alpha-2 country codes
- **Regional Filtering**: Browse by Africa, Americas, Asia, Europe, Oceania
- **Popular Flags**: Quick access to commonly used flags
- **Search**: Real-time fuzzy search by country name or code
- **Keyboard Navigation**: Full keyboard accessibility (Arrow keys, Home, End)
- **Preview**: Live preview of selected flag
- **Lazy Loading**: Efficient flag image loading
- **Dark Mode**: Full dark mode support
- **Responsive**: Mobile-friendly grid layout
- **Accessible**: WCAG 2.1 AA compliant

## Usage

### Basic Example

```javascript
import FlagPicker from './components/FlagPicker.js';

const picker = new FlagPicker({
    container: '#flag-picker-container',
    value: 'US',
    onChange: (code) => {
        console.log('Selected flag:', code);
    }
});
```

### Advanced Example

```javascript
const picker = new FlagPicker({
    container: document.querySelector('.my-container'),
    value: 'GB',
    placeholder: 'Find your country...',
    disabled: false,
    popularFlags: ['US', 'GB', 'FR', 'DE', 'ES', 'IT', 'PT', 'BR'],
    onChange: (code) => {
        // Update form field
        document.querySelector('#language_flag_code').value = code;

        // Update preview elsewhere
        updateFlagPreview(code);
    }
});
```

## API

### Constructor Options

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `container` | `string\|HTMLElement` | **Required** | CSS selector or DOM element for container |
| `value` | `string\|null` | `null` | Initial selected ISO code (e.g., 'US') |
| `onChange` | `Function` | `null` | Callback when flag is selected: `(code) => {}` |
| `placeholder` | `string` | `'Search by country...'` | Search input placeholder text |
| `disabled` | `boolean` | `false` | Initial disabled state |
| `popularFlags` | `Array<string>` | `[16 defaults]` | Array of popular flag codes |

### Methods

#### `getValue()`

Get the currently selected flag code.

```javascript
const code = picker.getValue(); // Returns 'US' or null
```

**Returns**: `string|null` - Selected country code or null

---

#### `setValue(code)`

Set the selected flag programmatically.

```javascript
picker.setValue('FR'); // Select France
picker.setValue(null); // Clear selection
```

**Parameters**:
- `code` (`string|null`): ISO 3166-1 alpha-2 country code or null

**Throws**: Warning if invalid code is provided

---

#### `disable()`

Disable the picker (prevents interaction).

```javascript
picker.disable();
```

---

#### `enable()`

Enable the picker.

```javascript
picker.enable();
```

---

#### `destroy()`

Destroy the picker and cleanup DOM.

```javascript
picker.destroy();
```

## Regions

Flags are organized into the following regions:

### Popular (16 flags)
Default: `US`, `GB`, `ES`, `FR`, `DE`, `IT`, `PT`, `BR`, `RU`, `CN`, `JP`, `KR`, `IN`, `MX`, `CA`, `AU`

### Africa (54 countries)
Algeria, Angola, Benin, Botswana, Burkina Faso, Burundi, Cameroon, Cape Verde, Central African Republic, Chad, Comoros, Congo, Congo (DRC), Côte d'Ivoire, Djibouti, Egypt, Equatorial Guinea, Eritrea, Ethiopia, Gabon, Gambia, Ghana, Guinea, Guinea-Bissau, Kenya, Lesotho, Liberia, Libya, Madagascar, Malawi, Mali, Mauritania, Mauritius, Mayotte, Morocco, Mozambique, Namibia, Niger, Nigeria, Réunion, Rwanda, Saint Helena, São Tomé and Príncipe, Senegal, Seychelles, Sierra Leone, Somalia, South Africa, South Sudan, Sudan, Swaziland, Tanzania, Togo, Tunisia, Uganda, Western Sahara, Zambia, Zimbabwe

### Americas (35 countries)
Anguilla, Antigua and Barbuda, Argentina, Aruba, Bahamas, Barbados, Belize, Bermuda, Bolivia, Bonaire, Brazil, Canada, Cayman Islands, Chile, Colombia, Costa Rica, Cuba, Curaçao, Dominica, Dominican Republic, Ecuador, El Salvador, Falkland Islands, French Guiana, Greenland, Grenada, Guadeloupe, Guatemala, Guyana, Haiti, Honduras, Jamaica, Martinique, Mexico, Montserrat, Nicaragua, Panama, Paraguay, Peru, Puerto Rico, Saint Barthélemy, Saint Kitts and Nevis, Saint Lucia, Saint Martin, Saint Pierre and Miquelon, Saint Vincent and the Grenadines, Suriname, Trinidad and Tobago, Turks and Caicos Islands, United States, Uruguay, Venezuela, Virgin Islands (British), Virgin Islands (U.S.)

### Asia (48 countries)
Afghanistan, Armenia, Azerbaijan, Bahrain, Bangladesh, Bhutan, Brunei, Cambodia, China, Christmas Island, Cocos Islands, Georgia, Hong Kong, India, Indonesia, Iran, Iraq, Israel, Japan, Jordan, Kazakhstan, Korea (North), Korea (South), Kuwait, Kyrgyzstan, Laos, Lebanon, Macao, Malaysia, Maldives, Mongolia, Myanmar, Nepal, Oman, Pakistan, Palestine, Philippines, Qatar, Saudi Arabia, Singapore, Sri Lanka, Syria, Taiwan, Tajikistan, Thailand, Timor-Leste, Turkey, Turkmenistan, United Arab Emirates, Uzbekistan, Vietnam, Yemen

### Europe (44 countries)
Åland Islands, Albania, Andorra, Austria, Belarus, Belgium, Bosnia and Herzegovina, Bulgaria, Croatia, Cyprus, Czech Republic, Denmark, Estonia, Faroe Islands, Finland, France, Germany, Gibraltar, Greece, Guernsey, Hungary, Iceland, Ireland, Isle of Man, Italy, Jersey, Kosovo, Latvia, Liechtenstein, Lithuania, Luxembourg, Macedonia, Malta, Moldova, Monaco, Montenegro, Netherlands, Norway, Poland, Portugal, Romania, Russia, San Marino, Serbia, Slovakia, Slovenia, Spain, Svalbard and Jan Mayen, Sweden, Switzerland, Ukraine, United Kingdom, Vatican City

### Oceania (14+ territories)
American Samoa, Antarctica, Australia, Bouvet Island, British Indian Ocean Territory, Cook Islands, Fiji, French Polynesia, French Southern Territories, Guam, Heard Island and McDonald Islands, Kiribati, Marshall Islands, Micronesia, Nauru, New Caledonia, New Zealand, Niue, Norfolk Island, Northern Mariana Islands, Palau, Papua New Guinea, Pitcairn, Samoa, Solomon Islands, South Georgia and the South Sandwich Islands, Tokelau, Tonga, Tuvalu, United States Minor Outlying Islands, Vanuatu, Wallis and Futuna

## Keyboard Navigation

| Key | Action |
|-----|--------|
| `Arrow Down` | Move focus down (8 flags) |
| `Arrow Up` | Move focus up (8 flags) |
| `Arrow Right` | Move focus right (1 flag) |
| `Arrow Left` | Move focus left (1 flag) |
| `Home` | Jump to first flag |
| `End` | Jump to last flag |
| `Enter` / `Space` | Select focused flag |
| `Tab` | Navigate between search and flags |

## Search

The search feature supports:

- **Country Name**: Partial matching (e.g., "united" finds "United States", "United Kingdom")
- **Country Code**: Partial matching (e.g., "us" finds "US", "au" finds "AU")
- **Case Insensitive**: Works with any capitalization
- **Debounced**: 300ms delay for performance

### Search Examples

```
"united"     → United States, United Kingdom, United Arab Emirates
"fr"         → France, French Guiana, French Polynesia, etc.
"island"     → Christmas Island, Falkland Islands, Cook Islands, etc.
"ko"         → Korea (North), Korea (South), Kosovo
```

## Flag Images

The component uses **CircleFlags** CDN for high-quality circular flag icons:

- **CDN URL**: `https://hatscripts.github.io/circle-flags/flags/{code}.svg`
- **Format**: SVG (scalable, crisp at any size)
- **Lazy Loading**: Images load only when visible
- **Fallback**: Shows country code text if image fails

### Using Local Flags

To use local flag images instead of CDN:

```javascript
// Modify createFlagElement() method in FlagPicker.js

const flagUrl = `/path/to/local/flags/${code.toLowerCase()}.svg`;
```

## Styling Customization

### CSS Variables

```scss
// Override in your theme
$primary-color: #0073aa;
$flag-size: 48px;
$flag-size-preview: 32px;
$border-radius-md: 6px;
```

### Custom Classes

Add custom classes to the container:

```javascript
const picker = new FlagPicker({
    container: '#my-picker'
});

picker.element.classList.add('my-custom-class');
```

## Validation

The component validates flag codes against the 249 ISO 3166-1 alpha-2 standard.

Valid codes match:
- **Exact match** against `COUNTRY_DATA` keys
- **Case insensitive** (automatically converted to uppercase)
- **2 letters** only (e.g., 'US', 'GB', 'FR')

Invalid codes:
- Console warning is logged
- Selection is not changed
- No error thrown (graceful degradation)

## Integration with LanguageManager

The FlagPicker is designed to work seamlessly with the LanguageManager:

```javascript
import FlagPicker from './components/FlagPicker.js';

// Create picker
const picker = new FlagPicker({
    container: '#language-flag-picker',
    value: languageData.flag_code, // From Language entity
    onChange: (code) => {
        // Update language flag
        languageManager.updateLanguage(languageId, {
            flag_code: code
        });
    }
});

// The LanguageManager will validate the code server-side
// using VALID_COUNTRY_CODES constant (same 249 codes)
```

## Browser Support

- **Modern Browsers**: Chrome 90+, Firefox 88+, Safari 14+, Edge 90+
- **Mobile**: iOS Safari 14+, Chrome Mobile 90+
- **Features Used**:
  - CSS Grid
  - ES6 Classes
  - Fetch API (for CDN images)
  - Intersection Observer (lazy loading)

## Performance

- **Initial Load**: ~5KB JS (minified + gzipped)
- **Country Data**: Embedded in component (~15KB uncompressed)
- **Flag Images**: Lazy-loaded from CDN as needed
- **Search**: Debounced (300ms) for optimal performance
- **Memory**: Lightweight, single picker instance

## Accessibility (WCAG 2.1 AA)

✅ **Keyboard Navigation**: Full keyboard support
✅ **Screen Readers**: ARIA labels and roles
✅ **Focus Indicators**: Visible focus states
✅ **Color Contrast**: Meets AA standards
✅ **Reduced Motion**: Respects prefers-reduced-motion
✅ **High Contrast**: Enhanced borders in high contrast mode

## Examples

### Example 1: Language Form

```html
<div class="form-field">
    <label for="flag-picker">Country Flag</label>
    <div id="flag-picker"></div>
    <input type="hidden" name="flag_code" id="flag_code" />
</div>

<script type="module">
import FlagPicker from './components/FlagPicker.js';

const picker = new FlagPicker({
    container: '#flag-picker',
    value: 'US',
    onChange: (code) => {
        document.getElementById('flag_code').value = code;
    }
});
</script>
```

### Example 2: Dynamic Enable/Disable

```javascript
const checkbox = document.querySelector('#use-flag');
const picker = new FlagPicker({
    container: '#flag-picker',
    disabled: !checkbox.checked
});

checkbox.addEventListener('change', (e) => {
    if (e.target.checked) {
        picker.enable();
    } else {
        picker.disable();
    }
});
```

### Example 3: Regional Default

```javascript
// Show European flags by default
const picker = new FlagPicker({
    container: '#flag-picker',
    value: 'DE'
});

// Programmatically switch to Europe tab
const europeTab = picker.element.querySelector('[data-region="Europe"]');
europeTab.click();
```

## Troubleshooting

### Flags not loading

**Problem**: Flag images show country codes instead of flags

**Solutions**:
1. Check internet connection (CDN requires network access)
2. Verify CDN is not blocked by firewall/adblocker
3. Use local flags instead of CDN
4. Check browser console for CORS errors

### Search not working

**Problem**: Search input doesn't filter flags

**Solutions**:
1. Verify `debounce` utility is imported correctly
2. Check console for JavaScript errors
3. Ensure search query is trimmed and lowercased
4. Try clearing browser cache

### Layout issues

**Problem**: Flags overlap or grid is broken

**Solutions**:
1. Check parent container has sufficient width
2. Verify SCSS is compiled and loaded
3. Check for CSS conflicts with other plugins
4. Test with browser DevTools to inspect grid

## License

Part of MultilingualPressZone plugin - GPL v2 or later

## Credits

- **Flag Icons**: [CircleFlags](https://github.com/HatScripts/circle-flags) by HatScripts (MIT License)
- **Country Data**: ISO 3166-1 standard
- **Component Design**: Inspired by modern UI/UX patterns

## Changelog

### 1.0.0 (2026-01-26)
- Initial release
- Support for all 249 ISO 3166-1 alpha-2 codes
- Regional filtering (Popular, All, Africa, Americas, Asia, Europe, Oceania)
- Search by country name or code
- Keyboard navigation
- Dark mode support
- Lazy loading
- Accessibility features
