# WidgetWiFi Component

## Описание

Смарт-виджет настройки WiFi (режимы STA / AP / STA+AP). В отличие от примитивов конструктора,
не привязывается к одной произвольной переменной устройства через Select — работает с
фиксированным набором полей, соответствующих реальной прошивочной конвенции (`main_config.c`,
группа `CFG`, ProdFactory-ESP): `WiFiMode`, `StaSSID`, `StaPSK`, `StaticIP`, `StaIP`, `StaMS`,
`StaGW`, `ApSSID`, `ApPSK`, `ApIP`, `ApMS`, `ApGW`. Компонент ничего не знает про
DeviceStore/WebSocket — только `value`/`onSave`, вся отправка на стороне вызывающего кода.

Поля редактируются локально и отправляются одним пакетом по кнопке "Сохранить". Переход в
режим AP (отключает STA) подтверждается отдельно — предупреждение появляется в момент нажатия
"Сохранить", а не при простом переключении сегмент-контрола, чтобы можно было спокойно открыть
секцию AP и заполнить SSID/пароль до реальной отправки.

## Пропсы

| Название         | Тип                                                            | По умолчанию       | Описание                                                                                                                                       |
| ---------------- | -------------------------------------------------------------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `wrapperClass`   | `string`                                                       | `""`               | CSS-классы для обёртки компонента                                                                                                              |
| `componentClass` | `string`                                                       | `""`               | "Мастер-цвет" виджета — роль вида `"bg-red"` (см. `optionsStore.COLOR_OPTIONS`); перекрашивает значок, сегмент-контролы и фокус-кольцо у полей |
| `label`          | `{ name?: string }`                                            | `{ name: "WiFi" }` | Заголовок карточки                                                                                                                             |
| `value`          | `IWidgetWiFiConfig`                                            | внутренний дефолт  | Текущая конфигурация WiFi                                                                                                                      |
| `allowedModes`   | `number[]`                                                     | `[1, 2, 3]`        | Какие режимы показывать в сегмент-контроле (1=STA, 2=AP, 3=STA+AP)                                                                             |
| `confirmOnAP`    | `boolean`                                                      | `true`             | Показывать предупреждение при сохранении чистого режима AP                                                                                     |
| `collapsed`      | `boolean`                                                      | `false`            | Свёрнуто ли тело виджета (заголовок остаётся); поддерживает двустороннее связывание (`$bindable`)                                              |
| `persistKey`     | `string`                                                       | `undefined`        | Ключ для сохранения состояния `collapsed` в `localStorage` — при заданном ключе сворачивание переживает перезагрузку страницы                 |
| `onScan`         | `() => Promise<{ id: string; name: string; value: string }[]>` | `undefined`        | Обработчик сканирования сетей (в проде — `Header: GET, Argument: APsList`)                                                                     |
| `onSave`         | `(config: IWidgetWiFiConfig) => void`                          | `undefined`        | Срабатывает при нажатии "Сохранить" — конфиг уходит одним пакетом                                                                              |

### IWidgetWiFiConfig

| Поле       | Тип      | Описание                                                   |
| ---------- | -------- | ---------------------------------------------------------- |
| `WiFiMode` | `number` | 0=NULL, 1=STA, 2=AP, 3=STA+AP (как `esp_wifi wifi_mode_t`) |
| `StaSSID`  | `string` | SSID сети в режиме клиента                                 |
| `StaPSK`   | `string` | Пароль сети в режиме клиента                               |
| `StaticIP` | `number` | 0=DHCP, 1=Static                                           |
| `StaIP`    | `string` | Статический IP клиента                                     |
| `StaMS`    | `string` | Маска подсети клиента                                      |
| `StaGW`    | `string` | Шлюз клиента                                               |
| `ApSSID`   | `string` | SSID точки доступа                                         |
| `ApPSK`    | `string` | Пароль точки доступа                                       |
| `ApIP`     | `string` | IP адрес точки доступа                                     |
| `ApMS`     | `string` | Маска подсети точки доступа                                |
| `ApGW`     | `string` | Шлюз точки доступа                                         |

## Примеры

```svelte
<script>
  import * as UI from "poe-svelte-ui-lib"

  const handleScan = async () => {
    /* Header: GET, Argument: APsList */
    return [{ id: "1", name: "MyNetwork", value: "MyNetwork" }]
  }

  const handleSave = (config) => {
    console.log("Отправка конфига одним пакетом:", config)
  }
</script>

<UI.WidgetWiFi label={{ name: "WiFi" }} onScan={handleScan} onSave={handleSave} />
```

## Конструктор свойств (WidgetWiFiProps.svelte)

### Пропсы конструктора

| Название           | Тип                                                                                             | Описание                                  |
| ------------------ | ----------------------------------------------------------------------------------------------- | ----------------------------------------- |
| `component`        | `UIComponent & { properties: Partial<IWidgetWiFiProps> }`                                       | Объект компонента с его свойствами        |
| `onPropertyChange` | `(updates: Partial<{ properties?: string \| object; name?: string; access?: string }>) => void` | Коллбэк для обновления свойств компонента |

Панель проще, чем у примитивов: не "к какой переменной привязать" (полей несколько, и они
фиксированы прошивочной конвенцией), а "как виджет себя ведёт" — заголовок, разрешённые режимы,
подтверждение при AP, мастер-цвет (через общий `WidgetAccentPicker.svelte`).

## Заметки

- Первый по-настоящему составной (multi-field) тип компонента конструктора — примитивы всегда
  привязаны к одной переменной устройства через `properties.id`.
- Чтение/батч-запись нескольких ключей `DeviceStore` реализуется на стороне приложения
  (`GUIPreview.svelte`), а не внутри библиотеки.
