# 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 до системы дизайн-токенов и практик оптимизации нагрузки на GPU.

---

## 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 -->|"Замкнутая геометрия (Скругленный прямоугольник, капсула)"| D["2. SVG / SDF Renderer (Физическое преломление по контуру)"]
    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` — базовые компоненты React, провайдеры и хуки.
> - `open-glass-ui/webgl` — подсистема аппаратных поверхностей WebGL2.
> - `open-glass-ui/core` — чистые математические утилиты для расчета контраста и генерации темы в Server Components.

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

Установите пакет через менеджер зависимостей:

```bash
npm install open-glass-ui
# или
pnpm add open-glass-ui
```

Импортируйте глобальные стили в точке входа приложения (`src/app/layout.tsx` или `src/main.tsx`):

```typescript
// Обязательный импорт стилей:
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`. По стандарту WCAG 2.2 AA контраст должен быть не ниже 4.5:1 для обычного текста и 3:1 для крупных заголовков.

---

## 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-метки, управление фокусом и состояниями

При интеграции компонентов строго соблюдайте следующие правила:
- **Обязательный `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 создана для бесшовной работы с Next.js App Router. Серверный код никогда не обращается к `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-поверхностях. Отрисовка с DPR 3+ на экранах Retina увеличивает нагрузку в 4 раза без заметной разницы для глаза.
- **Выборочное применение:** Используйте стекло только для верхних слоев (хедер, модальные окна, док). Для обычных списков контента используйте плоские фоны.
- **Оптимизация трекинга мыши:** Для эффектов движения курсора обновляйте CSS-переменные или `transform` через `ref`, не вызывая рендер React на каждый кадр.

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

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

---

## 8. Матрица типовых проблем и часто задаваемые вопросы (FAQ)

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

| Проблема / Ошибка | Первопричина | Решение проблемы |
| :--- | :--- | :--- |
| Эффект стекла отсутствует (серый фон) | Не подключен файл стилей `styles.css` | Добавьте `import "open-glass-ui/styles.css";` в корень проекта |
| Текст не читается на светлом фоне | Выбран слишком прозрачный материал `clear` | Переключите на `material="regular"` или `material="frosted"` для создания матовой подложки |
| Просадки FPS при прокрутке на телефонах | Слишком много вложенных поверхностей `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`.

> ❓ **Готова ли библиотека к использованию в продакшене?**  
> На данный момент библиотека находится в статусе pre-release. Архитектура и публичный API стабилизированы, однако перед обновлением минорных версий рекомендуется сверяться с журналом изменений (Changelog).

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