# OpenGlass UI: повний посібник із бібліотеки Liquid Glass для React

> Архітектура та впровадження OpenGlass UI: 40 нативних компонентів, рендерери CSS, SVG SDF і WebGL2, налаштування токенів, SSR у Next.js та WCAG 2.2.

OpenGlass UI — це сучасна React- та веб-бібліотека компонентів, створена для реалізації естетики «рідкого скла» (Liquid Glass) у цифрових інтерфейсах. На відміну від примітивних CSS-реалізацій із простим `backdrop-filter: blur()`, OpenGlass UI поєднує справжні фізичні моделі заломлення світла (рефракцію), підтримку підписаних полів відстаней (SDF, Signed Distance Fields), апаратне прискорення через WebGL2 та нативну доступність за стандартом WCAG 2.2.

Цей посібник охоплює архітектуру бібліотеки, принципи трирівневого рендерингу, практичну інтеграцію в Next.js App Router, систему дизайн-токенів та правила оптимізації продуктивності.

---

## 1. Концепція Liquid Glass та можливості OpenGlass UI

### 1.1. Філософія рідкого скла: поєднання нативного DOM та оптичних ефектів

Класичний гласморфізм часто критикують за високе навантаження на процесор і погану читабельність тексту. OpenGlass UI розв'язує цю проблему завдяки суворому розділенню шарів:
- **Семантичний каркас:** Усі 40 компонентів бібліотеки побудовані виключно на нативних HTML-тегах (`<button>`, `<input>`, `<dialog>`), зберігаючи клавіатурну навігацію та підтримку скрінрідерів.
- **Оптичні матеріали:** Шар візуального матеріалу підлаштовується під підкладку за допомогою адаптивного контрасту, тонування, фасок (bevel) та відблисків.
- **Ієрархія відкату (Graceful Degradation):** Якщо пристрій не підтримує апаратні обчислення або користувач увімкнув режим зниженої прозорості в системі, бібліотека непомітно перемикається на непрозорі CSS-матеріали без спотворення розмітки.

### 1.2. Порівняльна матриця трьох рендерерів: CSS, SVG-рефракція та WebGL2

OpenGlass UI пропонує три взаємодоповнюючі графічні конвеєри залежно від складності поверхні:

```mermaid
flowchart TD
    A["GlassSurface запит на рендеринг"] --> B{"Тип джерела та цільова форма"}
    B -->|"Довільний DOM / Контроли / Текст"| C["1. CSS Renderer (За замовчуванням: швидкий blur, border, shadow)"]
    B -->|"Замкнена геометрія DOM (Прямокутник, капсула)"| D["2. SVG / SDF Renderer (Справжнє заломлення світла через Displacement Map)"]
    B -->|"Динамічне медіа (Відео, Canvas, Зображення)"| E["3. WebGL2 Renderer (Апаратні лінзи з дисперсією IOR у реальному часі)"]
```

| Рендерер | Оптичні можливості | Навантаження на GPU | Підтримка браузерами | Оптимальна сфера використання |
| :--- | :--- | :--- | :--- | :--- |
| **CSS (Auto)** | Тонування, розмиття, межі, тіні | Мінімальне | 99.8% (Усі сучасні платформи) | Кнопки, поля форм, картки, навігація, списки |
| **SDF / SVG** | Заломлення світла по контуру фігури (IOR) | Помірне | Усі браузери з підтримкою SVG-фільтрів | Модальні вікна, плаваючі Dock-панелі, таби |
| **WebGL2** | Реалістична хроматична дисперсія, лінзи | Високе | Потрібна підтримка WebGL2 | Медіаплеєри, інтерактивні лінзи поверх 3D/відео |

---

## 2. Архітектура пакетів та встановлення

### 2.1. Модульна структура: фасад open-glass-ui та внутрішні пакети

Публічний фасад `open-glass-ui` об'єднує чотири внутрішні воркспейс-пакети, чітко розмежовуючи обов'язки компонентів:

```mermaid
flowchart LR
    A["open-glass-ui (Публічний npm-фасад)"] --> B["@open-glass-ui/core (Геометрія, математика SDF, токени без React)"]
    A --> C["@open-glass-ui/renderers (CSS-матеріали, шейдери WebGL2, SVG-хелпери)"]
    A --> D["@open-glass-ui/react (Провайдери стану, хуки, життєвий цикл SSR)"]
    A --> E["@open-glass-ui/recipes (40 готових UI-компонентів на нативному DOM)"]
```

> [!WARNING]
> Імпортувати компоненти напряму з внутрішніх пакетів (наприклад, `@open-glass-ui/core` або `@open-glass-ui/recipes`) суворо заборонено. Використовуйте лише публічні підшляхи фасаду:
> - `open-glass-ui` — основні React-компоненти, провайдери та хуки.
> - `open-glass-ui/webgl` — підсистема апаратних поверхонь WebGL2.
> - `open-glass-ui/core` — чисті утиліти математики теми, розрахунку контрасту та кольору для серверних компонентів.

### 2.2. Встановлення залежностей та базова конфігурація стилів

Встановіть бібліотеку за допомогою обраного пакетного менеджера:

```bash
npm install open-glass-ui
# або
pnpm add open-glass-ui
```

Підключіть глобальні стилі у точці входу вашого застосунку (наприклад, у `src/app/layout.tsx` або `src/main.tsx`):

```typescript
// Обов'язковий імпорт базових CSS-матеріалів:
import "open-glass-ui/styles.css";
import { Button, Glass, GlassSystemProvider } from "open-glass-ui";

export function RootApplication() {
  return (
    <GlassSystemProvider
      renderer="auto"
      quality="auto"
      motion="system"
      theme={{
        appearance: "system",
        defaultAppearance: "dark",
        theme: { preset: "neutral", contrast: "high", radius: "balanced" },
      }}
    >
      <main className="min-h-screen bg-slate-950 p-8">
        <Glass material="regular" interactive>
          <Button variant="primary">Розпочати роботу</Button>
        </Glass>
      </main>
    </GlassSystemProvider>
  );
}
```

---

## 3. Налаштування системи тем: палітри, контрастність та CSS-токени

### 3.1. Керування темами: пресети, режими appearance та радіуси заокруглення

Тема в OpenGlass UI базується на трьох взаємопов'язаних вимірах:
1. **Зовнішній вигляд (Appearance):** Приймає значення `light`, `dark` або `system`. При значенні `system` сервер віддає безпечний `defaultAppearance`, а на клієнті підхоплюється медіа-запит `prefers-color-scheme`.
2. **Палітра кольорів (Presets):** На вибір доступні готові вивірені схеми (`neutral`, `cobalt`, `teal`, `violet`, `coral`, `amber`) або власні значення через параметри `accent`, `secondary`, `tertiary`.
3. **Радіус заокруглення (Radius):** Варіанти `sharp` (мінімальне), `balanced` (стандартне, 12–16px) та `soft` (органічне, 24–28px).

### 3.2. Матриця семантичних токенів --ogui-* та перевірка контрастності (WCAG)

Усі компоненти оформлюються через стабільні CSS-змінні:

```css
/* Базові поверхні та межі */
--ogui-color-background: #090d16;
--ogui-color-surface: rgba(15, 23, 42, 0.65);
--ogui-color-border: rgba(255, 255, 255, 0.12);
--ogui-color-text: #f8fafc;
--ogui-color-muted: #94a3b8;

/* Акцентні стани та фокус */
--ogui-color-accent: #38bdf8;
--ogui-color-accent-ink: #031525;
--ogui-color-focus: #0284c7;

/* Радіуси та оптичні властивості матеріалу */
--ogui-radius-control: 8px;
--ogui-radius-surface: 16px;
--ogui-material-blur: 16px;
--ogui-material-bevel: 1px;
```

> 💡 **Правило перевірки контрастності:** Використовуйте експортовану функцію `contrastRatio(colorA, colorB)` із `open-glass-ui/core`. Контраст тексту має становити щонайменше 4.5:1 для звичайного тексту та 3:1 для великих заголовків за стандартом WCAG 2.2 AA.

---

## 4. Каталог компонентів: огляд 40 рецептів на нативному DOM

### 4.1. Категорії готових компонентів: контролі, оверлеї, навігація та форми

Пакет містить 40 готових компонентів із нативною розміркою:

| Категорія | Компоненти у складі бібліотеки |
| :--- | :--- |
| **Елементи дій та контролі** | `Button`, `IconButton`, `ToggleButton`, `SegmentedControl`, `Switch`, `Slider`, `Stepper` |
| **Навігація та контейнери** | `Toolbar`, `Dock`, `Tabs`, `Breadcrumbs`, `Pagination`, `Menu`, `MenuItem` |
| **Оверлеї та спливаючі вікна** | `Dialog`, `Drawer`, `Popover`, `Tooltip`, `Toast`, `Alert`, `Banner` |
| **Форми та введення даних** | `TextField`, `Textarea`, `NumberField`, `SearchField`, `Select`, `Checkbox`, `RadioGroup`, `FileDropzone` |
| **Відображення інформації** | `Card`, `Stat`, `Badge`, `Avatar`, `AvatarGroup`, `Accordion`, `Progress`, `Meter`, `Spinner`, `Skeleton`, `MediaControls` |

### 4.2. Стандарти доступності (a11y): ARIA-мітки, керування фокусом та станами

При використанні компонентів OpenGlass UI обов'язково дотримуйтесь правил доступності:
- **Обов'язковий `aria-label` для іконок:** `IconButton` та `SegmentedControl` вимагають явного текстового опису для скрінрідерів.
- **Повернення фокусу в діалогах:** У `Dialog` та `Drawer` фокус при закритті автоматично повертається на елемент виклику.
- **Подвійне кодування станів:** Не позначайте стан вибору, помилки або блокування лише прозорістю чи кольором. Завжди супроводжуйте його зміною піктограми або текстовим бейджем.

---

## 5. Робота з рендерерами: від базового CSS до опціонального WebGL2

### 5.1. Декларативна SVG/SDF-рефракція для замкнених геометричних фігур

Для плаваючих карток або панелей керування можна увімкнути справжню рефракцію світла за допомогою підписаних полів відстаней (SDF):

```typescript
import React from "react";
import { Glass, SdfFilterDefinition, useSdfFilter } from "open-glass-ui";

const panelGeometry = {
  kind: "rounded-rect",
  width: 360,
  height: 200,
  cornerRadius: 24,
} as const;

export function RefractedControlPanel({ children }: { children: React.ReactNode }) {
  const filter = useSdfFilter({
    id: "main-panel-filter",
    width: 360,
    height: 200,
    geometry: panelGeometry,
    quality: "medium",
  });

  return (
    <div className="relative inline-block">
      <SdfFilterDefinition filter={filter} />
      <Glass 
        renderer="sdf-svg" 
        filterId={filter.filterId} 
        geometry={panelGeometry}
        material="regular"
      >
        <div className="p-6 text-slate-100">
          {children}
        </div>
      </Glass>
    </div>
  );
}
```

### 5.2. Апаратні оптичні лінзи у WebGL2 поверх відео та canvas

Якщо на сторінці відтворюється відео, інтерактивна графіка або 3D-сцена, модуль `open-glass-ui/webgl` дозволяє накласти апаратну лінзу з фізичним показником заломлення (IOR):

```typescript
"use client";

import React, { useRef } from "react";
import { GlassProvider } from "open-glass-ui";
import { WebGLGlassSurface } from "open-glass-ui/webgl";

const opticalMaterial = {
  thickness: 0.62,
  ior: 1.48,           // Показник заломлення (коефіцієнт скла)
  dispersion: 0.015,   // Хроматична дисперсія по краях
  edgeStrength: 0.5,
  bevel: 0.7,
  frost: 0.2,
};

export function InteractiveVideoLens() {
  const videoRef = useRef<HTMLVideoElement>(null);

  return (
    <GlassProvider>
      <div className="relative overflow-hidden rounded-2xl">
        <video 
          ref={videoRef} 
          src="/ambient-flow.mp4" 
          autoPlay 
          loop 
          muted 
          playsInline 
          className="w-full h-auto block"
        />
        <WebGLGlassSurface
          sourceRef={videoRef}
          continuous
          maxDevicePixelRatio={2}
          lenses={[
            {
              x: 180,
              y: 120,
              width: 240,
              height: 120,
              radius: 0.4,
              material: opticalMaterial,
            },
          ]}
        />
      </div>
    </GlassProvider>
  );
}
```

---

## 6. Інтеграція в Next.js App Router та серверний рендеринг (SSR)

### 6.1. Гідратація без конфліктів: ізоляція клієнтських меж та core-утиліт

OpenGlass UI спроєктована з урахуванням сучасного серверного рендерингу. Сервер ніколи не намагається звернутися до `window`, `document` чи контексту WebGL.

Створіть кореневий провайдер у клієнтському компоненті:

```typescript
// src/components/providers/GlassRootProvider.tsx
"use client";

import React from "react";
import "open-glass-ui/styles.css";
import { GlassSystemProvider } from "open-glass-ui";

export function GlassRootProvider({ children }: { children: React.ReactNode }) {
  return (
    <GlassSystemProvider
      renderer="auto"
      quality="auto"
      theme={{
        appearance: "system",
        defaultAppearance: "dark",
      }}
    >
      {children}
    </GlassSystemProvider>
  );
}
```

А чисті функції для обчислення кольорів або схем тем імпортуйте у Server Components із `open-glass-ui/core`:

```typescript
// src/app/page.tsx (Server Component)
import { createGlassTheme } from "open-glass-ui/core";
import { GlassRootProvider } from "@/components/providers/GlassRootProvider";

export default function Page() {
  const staticTheme = createGlassTheme({ preset: "neutral", contrast: "high" });

  return (
    <GlassRootProvider>
      <h1 className="text-2xl font-bold">Серверний рендеринг готовий</h1>
    </GlassRootProvider>
  );
}
```

### 6.2. Уникнення розбіжностей верстки та робота з prefers-color-scheme

Щоб запобігти попередженням про гідратацію (Hydration Mismatch):
- Не використовуйте тернарні оператори залежно від `window.innerWidth` у початковому рендері.
- Використовуйте проп `defaultAppearance="dark"` для стабілізації початкового HTML між сервером та клієнтом.

---

## 7. Продуктивність та оптимізація графічного конвеєра

### 7.1. Зниження навантаження на GPU: обмеження DPR та селективне використання скла

Масове накладання шарів із розмиттям фону здатне перевантажити навіть дискретну відеокарту. Дотримуйтесь наступних рекомендацій:
- **Обмежуйте Device Pixel Ratio:** Завжди встановлюйте `maxDevicePixelRatio={2}` у налаштуваннях WebGL-поверхонь. Рендеринг на Retina-екранах із DPR 3+ споживає вчетверо більше відеопам'яті без помітної різниці в якості.
- **Точкове накладання матеріалу:** Застосовуйте скло лише для верхніх шарів навігації (Header, Dock, Modal). Звичайні контентні списки повинні мати класичний непрозорий або напівпрозорий CSS-фон.
- **Оновлення позиції курсору:** Для інтерактивних ефектів стеження за мишею змінюйте CSS-змінні або `transform` через `ref`, уникаючи виклику `setState` на кожен піксель руху.

### 7.2. Кешування карт відстаней (SDF) та оптимізація зміни розмірів (Resize)

Генерація SDF-карт для SVG-фільтрів є ресурсомісткою операцією. Хук `useSdfFilter` автоматично кешує карти за хешем геометричних параметрів. При зміні розміру вікна браузера бібліотека автоматично перемикається на низьку якість рендерингу, повертаючи максимальну чіткість лише після зупинки ресайзу.

---

## 8. Матриця типових проблем та поширені запитання (FAQ)

### 8.1. Діагностика збоїв рендерингу, падіння контрасту та витоків пам'яті

| Симптом / Помилка | Першопричина | Інженерне рішення |
| :--- | :--- | :--- |
| Ефект скла відсутній (білий/сірий фон) | Не підключено файл стилів `styles.css` | Додайте `import "open-glass-ui/styles.css";` у корінь проєкту |
| Текст стає нечитабельним на світлих фото | Використано надто прозорий матеріал `clear` | Перемкніть проп на `material="regular"` або `material="frosted"` для створення матової підкладки |
| Гальмування скролу на мобільних пристроях | Багато вкладених поверхонь із рендерером `sdf-svg` | Залиште `renderer="auto"` (CSS) для масових елементів інтерфейсу |
| Помилка `WebGL context lost` | Перевищено ліміт активних контекстів canvas | Обмежте кількість активних лінз до 6 на одне джерело `WebGLGlassSurface` |

### 8.2. Відповіді на часті запитання розробників щодо OpenGlass UI

> ❓ **Чи сумісна бібліотека з Tailwind CSS?**  
> Так. OpenGlass UI не блокує утиліти Tailwind. Ви можете безпечно комбінувати класи на зразок `className="flex items-center gap-4 p-6"` із пропсами `material` та `interactive`.

> ❓ **Чи готова бібліотека до використання у production?**  
> Наразі бібліотека має статус pre-release. Її архітектура та публічний API вже стабілізовані, проте перед оновленням мінорних версій рекомендується уважно переглядати журнал змін (Changelog).

> ❓ **Як поводиться інтерфейс, якщо у користувача увімкнено примусовий високий контраст у Windows?**  
> Бібліотека автоматично визначає медіа-запит `forced-colors: active` і вимикає всі напівпрозорі ефекти, відображаючи висококонтрастні суцільні рамки та стандартні системні кольори тексту відповідно до вимог доступності.