Skip to main content
Содержание гайда

Содержание гайда

Время на изучение: 12 мин
#automation#openglass#liquid#glass#react
Новичок12 мин

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)"]
Внимание

Импортировать модули напрямую из внутренних пакетов (например, @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 и отключает все эффекты прозрачности, выводя контрастные рамки и стандартные цвета текста по требованиям доступности.

Этот гайд полностью бесплатный. Если он сэкономил вам вечер — вы можете поддержать развитие проекта.
Поддержать автора