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, систему дизайн-токенів та правила оптимізації продуктивності.


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)"]
Увага

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

Цей гайд повністю безкоштовний. Якщо він зекономив вам вечір — ви можете підтримати розвиток проєкту.
Підтримати автора