# OpenGlass UI : Guide complet de la bibliothèque Liquid Glass pour React

> Architecture et implémentation d'OpenGlass UI : 40 composants natifs, moteurs de rendu CSS, SVG SDF et WebGL2, configuration des tokens, SSR dans Next.js et conformité WCAG 2.2.

OpenGlass UI est une bibliothèque de composants React et web moderne, conçue pour implémenter l’esthétique « Liquid Glass » (Verre Liquide) dans les interfaces numériques. Contrairement aux implémentations CSS primitives utilisant un simple `backdrop-filter: blur()`, OpenGlass UI combine de véritables modèles physiques de réfraction lumineuse, la prise en charge des Signed Distance Fields (SDF), une accélération matérielle via WebGL2 et une accessibilité native conforme au standard WCAG 2.2.

Ce guide couvre l’architecture de la bibliothèque, les principes du rendu à trois niveaux, l’intégration pratique dans Next.js App Router, le système de design tokens ainsi que les règles d’optimisation des performances.

---

## 1. Concept du Liquid Glass et capacités d’OpenGlass UI

### 1.1. Philosophie du verre liquide : combinaison du DOM natif et des effets optiques

Le glassmorphism classique est souvent critiqué pour sa forte charge processeur et sa mauvaise lisibilité du texte. OpenGlass UI résout ce problème grâce à une séparation stricte des couches :
- **Structure sémantique :** Les 40 composants de la bibliothèque sont construits exclusivement sur des balises HTML natives (`<button>`, `<input>`, `<dialog>`), préservant la navigation au clavier et la compatibilité avec les lecteurs d’écran.
- **Matériaux optiques :** La couche de matériau visuel s’adapte au fond sous-jacent grâce à un contraste adaptatif, une teinte, des biseautages (bevel) et des reflets.
- **Hiérarchie de dégradation (Graceful Degradation) :** Si l’appareil ne prend pas en charge les calculs matériels ou si l’utilisateur a activé le mode réduction de transparence dans son système, la bibliothèque bascule discrètement vers des matériaux CSS opaques sans altérer la mise en page.

### 1.2. Matrice comparative des trois moteurs de rendu : CSS, réfraction SVG et WebGL2

OpenGlass UI propose trois pipelines graphiques complémentaires selon la complexité de la surface :

```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 у реальному часі)"]
```

| Moteur de rendu | Capacités optiques | Charge GPU | Compatibilité navigateur | Cas d’usage optimal |
| :--- | :--- | :--- | :--- | :--- |
| **CSS (Auto)** | Teinte, flou, bordures, ombres | Minimale | 99,8 % (Toutes plateformes modernes) | Boutons, champs de formulaire, cartes, navigation, listes |
| **SDF / SVG** | Réfraction lumineuse le long du contour (IOR) | Modérée | Tous navigateurs supportant les filtres SVG | Fenêtres modales, panneaux Dock flottants, onglets |
| **WebGL2** | Dispersion chromatique réaliste, lentilles | Élevée | Support WebGL2 requis | Lecteurs multimédias, lentilles interactives sur 3D/vidéo |

---

## 2. Architecture des paquets et installation

### 2.1. Structure modulaire : façade open-glass-ui et paquets internes

La façade publique `open-glass-ui` regroupe quatre paquets internes workspace, délimitant clairement les responsabilités des composants :

```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]
> L’importation directe de composants depuis les paquets internes (par exemple, `@open-glass-ui/core` ou `@open-glass-ui/recipes`) est strictement interdite. Utilisez uniquement les sous-chemins publics de la façade :
> - `open-glass-ui` — Composants React principaux, providers et hooks.
> - `open-glass-ui/webgl` — Sous-système des surfaces matérielles WebGL2.
> - `open-glass-ui/core` — Utilitaires purs de mathématiques thématiques, calcul de contraste et couleur pour les composants serveur.

### 2.2. Installation des dépendances et configuration de base des styles

Installez la bibliothèque à l’aide du gestionnaire de paquets de votre choix :

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

Importez les styles globaux au point d’entrée de votre application (par exemple, dans `src/app/layout.tsx` ou `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. Configuration du système de thèmes : palettes, contraste et tokens CSS

### 3.1. Gestion des thèmes : presets, modes d’apparence et rayons d’arrondi

Le thème dans OpenGlass UI repose sur trois dimensions interdépendantes :
1. **Apparence (Appearance) :** Accepte les valeurs `light`, `dark` ou `system`. Avec la valeur `system`, le serveur renvoie un `defaultAppearance` sûr, tandis que le client récupère la media query `prefers-color-scheme`.
2. **Palette de couleurs (Presets) :** Des schémas pré-calibrés sont disponibles (`neutral`, `cobalt`, `teal`, `violet`, `coral`, `amber`) ou des valeurs personnalisées via les paramètres `accent`, `secondary`, `tertiary`.
3. **Rayon d’arrondi (Radius) :** Variantes `sharp` (minimal), `balanced` (standard, 12–16px) et `soft` (organique, 24–28px).

### 3.2. Matrice des tokens sémantiques --ogui-* et vérification du contraste (WCAG)

Tous les composants sont stylisés via des variables CSS stables :

```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;
```

> 💡 **Règle de vérification du contraste :** Utilisez la fonction exportée `contrastRatio(colorA, colorB)` issue de `open-glass-ui/core`. Le contraste du texte doit être d’au moins 4.5:1 pour le texte normal et de 3:1 pour les grands titres selon le standard WCAG 2.2 AA.

---

## 4. Catalogue de composants : aperçu des 40 recettes sur DOM natif

### 4.1. Catégories de composants prêts à l’emploi : contrôles, overlays, navigation et formulaires

Le paquet contient 40 composants prêts à l’emploi avec une structure native :

| Catégorie | Composants inclus dans la bibliothèque |
| :--- | :--- |
| **Éléments d’action et contrôles** | `Button`, `IconButton`, `ToggleButton`, `SegmentedControl`, `Switch`, `Slider`, `Stepper` |
| **Navigation et conteneurs** | `Toolbar`, `Dock`, `Tabs`, `Breadcrumbs`, `Pagination`, `Menu`, `MenuItem` |
| **Overlays et fenêtres surgissantes** | `Dialog`, `Drawer`, `Popover`, `Tooltip`, `Toast`, `Alert`, `Banner` |
| **Formulaires et saisie de données** | `TextField`, `Textarea`, `NumberField`, `SearchField`, `Select`, `Checkbox`, `RadioGroup`, `FileDropzone` |
| **Affichage d’informations** | `Card`, `Stat`, `Badge`, `Avatar`, `AvatarGroup`, `Accordion`, `Progress`, `Meter`, `Spinner`, `Skeleton`, `MediaControls` |

### 4.2. Standards d’accessibilité (a11y) : étiquettes ARIA, gestion du focus et des états

Lors de l’utilisation des composants OpenGlass UI, respectez impérativement les règles d’accessibilité :
- **`aria-label` obligatoire pour les icônes :** `IconButton` et `SegmentedControl` exigent une description textuelle explicite pour les lecteurs d’écran.
- **Retour du focus dans les dialogues :** Dans `Dialog` et `Drawer`, le focus revient automatiquement à l’élément déclencheur lors de la fermeture.
- **Double codage des états :** N’indiquez pas un état sélectionné, d’erreur ou désactivé uniquement par la transparence ou la couleur. Accompagnez toujours cela d’un changement d’icône ou d’un badge textuel.

---

## 5. Travail avec les moteurs de rendu : du CSS de base au WebGL2 optionnel

### 5.1. Réfraction SVG/SDF déclarative pour les formes géométriques fermées

Pour les cartes flottantes ou les panneaux de contrôle, vous pouvez activer une véritable réfraction lumineuse à l’aide des Signed Distance Fields (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. Lentilles optiques matérielles en WebGL2 sur vidéo et canvas

Si la page affiche une vidéo, des graphismes interactifs ou une scène 3D, le module `open-glass-ui/webgl` permet de superposer une lentille matérielle avec un indice de réfraction physique (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. Intégration dans Next.js App Router et rendu côté serveur (SSR)

### 6.1. Hydratation sans conflits : isolation des limites client et utilitaires core

OpenGlass UI est conçue en tenant compte du rendu serveur moderne. Le serveur ne tente jamais d’accéder à `window`, `document` ou au contexte WebGL.

Créez le provider racine dans un composant client :

```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>
  );
}
```

Et importez les fonctions pures pour le calcul des couleurs ou des schémas de thème dans les Server Components depuis `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. Éviter les divergences de markup et gérer prefers-color-scheme

Pour prévenir les avertissements d’hydratation (Hydration Mismatch) :
- N’utilisez pas d’opérateurs ternaires dépendant de `window.innerWidth` lors du premier rendu.
- Utilisez la prop `defaultAppearance="dark"` pour stabiliser le HTML initial entre le serveur et le client.

---

## 7. Performance et optimisation du pipeline graphique

### 7.1. Réduction de la charge GPU : limitation du DPR et usage sélectif du verre

L’application massive de couches avec flou d’arrière-plan peut saturer même une carte graphique dédiée. Suivez ces recommandations :
- **Limitez le Device Pixel Ratio :** Définissez toujours `maxDevicePixelRatio={2}` dans les paramètres des surfaces WebGL. Le rendu sur écrans Retina avec un DPR ≥ 3 consomme quatre fois plus de mémoire vidéo sans différence perceptible de qualité.
- **Application ciblée du matériau :** Appliquez le verre uniquement aux couches supérieures de navigation (Header, Dock, Modal). Les listes de contenu standard doivent conserver un fond CSS opaque ou semi-transparent classique.
- **Mise à jour de la position du curseur :** Pour les effets interactifs de suivi de souris, modifiez les variables CSS ou `transform` via `ref`, en évitant d’appeler `setState` à chaque pixel de mouvement.

### 7.2. Mise en cache des cartes de distance (SDF) et optimisation du redimensionnement (Resize)

La génération de cartes SDF pour les filtres SVG est une opération coûteuse. Le hook `useSdfFilter` met automatiquement en cache les cartes selon le hash des paramètres géométriques. Lors du redimensionnement de la fenêtre du navigateur, la bibliothèque bascule automatiquement vers une qualité de rendu inférieure, restaurant la netteté maximale uniquement après la fin du resize.

---

## 8. Matrice des problèmes courants et questions fréquentes (FAQ)

### 8.1. Diagnostic des échecs de rendu, chute de contraste et fuites de mémoire

| Symptôme / Erreur | Cause racine | Solution technique |
| :--- | :--- | :--- |
| Effet verre absent (fond blanc/gris) | Fichier de styles `styles.css` non importé | Ajoutez `import "open-glass-ui/styles.css";` à la racine du projet |
| Texte illisible sur photos claires | Matériau `clear` trop transparent utilisé | Changez la prop pour `material="regular"` ou `material="frosted"` afin de créer un fond mat |
| Ralentissement du scroll sur mobile | Nombreuses surfaces imbriquées avec le moteur `sdf-svg` | Gardez `renderer="auto"` (CSS) pour les éléments d’interface massifs |
| Erreur `WebGL context lost` | Limite de contextes canvas actifs dépassée | Limitez le nombre de lentilles actives à 6 par source `WebGLGlassSurface` |

### 8.2. Réponses aux questions fréquentes des développeurs concernant OpenGlass UI

> ❓ **La bibliothèque est-elle compatible avec Tailwind CSS ?**  
> Oui. OpenGlass UI n’entre pas en conflit avec les utilitaires Tailwind. Vous pouvez combiner en toute sécurité des classes comme `className="flex items-center gap-4 p-6"` avec les props `material` et `interactive`.

> ❓ **La bibliothèque est-elle prête pour la production ?**  
> Actuellement, la bibliothèque est en statut pre-release. Son architecture et son API publique sont stabilisées, mais il est recommandé de consulter attentivement le Changelog avant les mises à jour mineures.

> ❓ **Comment se comporte l’interface si l’utilisateur a activé le contraste élevé forcé sous Windows ?**  
> La bibliothèque détecte cette préférence système et applique automatiquement des matériaux opaques à fort contraste, garantissant la lisibilité tout en conservant la structure sémantique.