Système de composants thématisé · Nouvelle ressource

Système de design HeroUI.

Une référence HeroUI v3 avec de véritables variables sémantiques CSS, des commandes composées React, des surfaces claires et sombres, et une méthode d’export d’images opérationnelle.

Guide OpenDesign9 chapitres30 entrées de référenceGuide de l’application d’origine
01

Aperçu de l’interface du système de design HeroUI

Modifiez la qualité avec un curseur natif, activez ou désactivez les métadonnées, changez l’apparence et appliquez une recette locale. Aucun encodeur ni téléversement n’est simulé.

Studio d’exportation d’imagesOuvrir l’exemple complet
CSS compilé avec @heroui/react 3.2.6 et @heroui/styles 3.2.6 natifs ; illustrations et mise en page originales. · Référence de mise en œuvre
02

Référence de conception du système de design HeroUI

Thème par défaut de HeroUI 3.2.6, vérifié dans @heroui/styles/dist/themes/default/variables.css. Les valeurs OKLCH ci-dessous sont celles du package. Les couleurs des illustrations et la typographie relèvent des choix de l’application, pas des jetons de marque de HeroUI.

Surfaces sémantiques et contraste

Source
Nom / règleValeur / configurationUtilisation
--backgroundoklch(0.9702 0 0)Fond de page clair ; en mode sombre, devient oklch(12% 0.005 285.823).
--foregroundvar(--eclipse)Couleur de texte pour la lecture en mode clair ; en mode sombre, prend la valeur --snow.
--surfacevar(--white)Arrière-plan des cartes en mode clair ; en mode sombre, prend la valeur oklch(0.2103 0.0059 285.89).
--overlayvar(--white)Arrière-plan des couches flottantes, rôle distinct de celui de surface, même lorsque les valeurs en mode clair sont identiques.
--accentoklch(0.6204 0.195 253.83)Interrupteur sélectionné, remplissage du curseur et bouton principal.
--accent-foregroundvar(--snow)Texte sur l’accent plein.
--mutedoklch(0.5517 0.0138 285.94)Texte secondaire ; en mode sombre, prend la valeur oklch(70.5% 0.015 286.067).
--borderoklch(90% 0.004 286.32)Bordures en mode clair ; en mode sombre, prend la valeur oklch(28% 0.006 286.033).
--focusvar(--accent)Indication de focus clavier.
--field-backgroundvar(--white)Surfaces des champs en mode clair ; en mode sombre, suit la valeur eclipse.

Formes, espacements et états

Source
Nom / règleValeur / configurationUtilisation
--spacing0.25remUnité d’espacement de base ; 4px avec une racine de 16px.
--radius0.5remPrimitive de rayon par défaut ; 8px avec une racine de 16px.
--field-radiuscalc(var(--radius) * 1.5)Rayon par défaut des champs : 12px.
--border-width1pxÉpaisseur de bordure par défaut.
--field-border-width0pxPar défaut, les champs ne reposent pas sur une bordure de contour.
--disabled-opacity0.5Style visuel désactivé ; utiliser tout de même isDisabled sur le composant.
--ring-offset-width2pxEspace entre le contrôle et l’anneau de focus.
--tooltip-delay1500msDélai initial avant l’affichage de l’infobulle dans le package par défaut.
--tooltip-close-delay500msDélai avant la fermeture de l’infobulle.

Typographie et mise en page de l’application

Source
Nom / règleValeur / configurationUtilisation
body16px / 1.5, Arial, Helvetica, sans-serifChoix explicite d’une police pour l’aperçu ; ne représente pas une police obligatoire de HeroUI.
h132px / 1.15; 28px below 700pxÉchelle de titres d’origine de la page.
h224px / 1.25Titre des paramètres d’exportation.
helper text13px / inherited 1.5Explication de la qualité et résultat local.
desktop gap24pxGrille à deux colonnes pour l’illustration et les paramètres.
mobile breakpoint700pxRègle adaptative d’origine, et non jeton de point de rupture de HeroUI.
card radiuscalc(var(--radius) * 3)Composition applicative de 24px utilisant la primitive officielle.

Configuration des contrôles natifs

Source
Nom / règleValeur / configurationUtilisation
quality rangeminValue=10; maxValue=100; step=5Plage de valeurs de la recette d’encodage de l’application, et non valeur par défaut de HeroUI.
Slidervalue + onChangeLa valeur numérique contrôlée met à jour le résultat et la recette.
SwitchisSelected + onChangeLa valeur booléenne contrôlée préserve une source de vérité unique.
ButtononPressL’événement de pression Aria de React prend en charge l’activation au pointeur et au clavier.
03

Guide complet du système de design HeroUI

Un guide pratique pour choisir, appliquer et évaluer ce système dans une interface réelle.

DESIGN-heroui.md

Des conseils complets, un point de départ pour la mise en œuvre et des liens vers les sources.

Télécharger le guide

Le système de design HeroUI v3 et l’Export Studio

Composants React et feuille de style sémantique

Cet exemple cible HeroUI 3.2.6. Ses contrôles sont des composants React qui s’appuient sur le comportement de React Aria, tandis que la couche visuelle provient de @heroui/styles. Le guide de démarrage rapide officiel nécessite React 19 et Tailwind CSS v4. La configuration v3 n’enveloppe pas cette application dans l’ancien modèle HeroUIProvider. Mélanger des tutoriels v2 avec ce composant composé API est une cause fréquente de contrôles manquants ou mal stylés.

Extrait de ce guide OpenDesign

Cet exemple est un éditeur de recette d’exportation : l’illustration se trouve à gauche, et les contrôles de qualité et de métadonnées à droite. L’illustration est dessinée avec CSS d’origine. Il ne s’agit pas d’une image traitée par la bibliothèque. L’application d’une recette enregistre les paramètres sélectionnés dans l’état local de React ; aucun poids de fichier ni résultat de téléchargement fictif n’est volontairement affiché.

Consultez la spécification associée

Couleurs sémantiques et apparence du système de design HeroUI

Distinguer la zone de fond, les surfaces et les couches flottantes

Utilisez --background pour la zone de fond extérieure, --surface pour les cartes d’illustration et de paramètres, et --overlay pour une future fenêtre contextuelle ou boîte de dialogue. Il s’agit de rôles sémantiques, même lorsque deux d’entre eux donnent du blanc en mode clair. En mode sombre, la zone de fond et les surfaces en relief sont différentes. L’exemple applique la classe dark à document.documentElement afin que tous les éléments descendants partagent le même thème.

Le remplissage du curseur et l’interrupteur sélectionné utilisent le rôle d’accent. Les contrôles à accent plein l’associent à --accent-foreground. Le texte secondaire utilise --muted plutôt que de réduire l’opacité de toute une carte. L’illustration conserve sa palette chaude indépendante dans les deux modes, car elle fait partie du contenu et non des éléments d’interface interactifs.

Consultez la spécification associée

Typographie et espacement du système de design HeroUI

Préciser explicitement l’échelle de l’application

Le style de HeroUI s’intègre aux utilitaires Tailwind, mais cette page n’impose aucune police HeroUI. Le CSS d’origine choisit Arial/Helvetica, avec un corps de 16px et une hauteur de ligne de 1.5. Un titre de 32px passe à 28px dans la mise en page étroite ; le titre des paramètres est de 24px. Le tableau de référence distingue ces valeurs propres à l’application des variables du package.

La primitive officielle --spacing vaut 0.25rem. Cette composition utilise 16px à l’intérieur de la recette, 24px entre les colonnes et autour des cartes sur ordinateur, et 32px autour de la zone de fond sur ordinateur. Le rayon des champs dérive de la primitive officielle de rayon de 8px. Celui des cartes correspond volontairement à trois fois cette primitive : sa valeur de 24px est donc un dérivé propre à l’application, et non une valeur par défaut revendiquée pour Card.

Consultez la spécification associée

Créer un curseur complet avec le système de design HeroUI

Regrouper la structure et la gestion des valeurs

La racine Slider gère value, onChange, minValue, maxValue et step. Son Label fournit le nom accessible. Slider.Output lit cette même valeur, et Slider.Track contient Slider.Fill et Slider.Thumb. Sans ces éléments visibles, le comportement peut être présent sans que la piste ou la poignée attendue s’affiche. Cet exemple utilise un seul nombre, et non un tableau de plages.

La qualité est comprise entre 10 et 100, par incréments de cinq. Ces limites relèvent de décisions propres au produit. Par défaut, HeroUI utilise une plage de 0 à 100, avec un pas de un. Une valeur de qualité n’a pas de relation universelle fiable avec le nombre d’octets ; le texte d’aide explique donc le compromis sans inventer d’estimation de taille de fichier. Pour gérer plusieurs poignées, utilisez un tableau de nombres et attribuez à chacune l’index approprié.

  1. Placez le focus sur le curseur de qualité et utilisez une touche fléchée pour le modifier d’un pas.
  2. Vérifiez que la valeur affichée et la recette en cours sont mises à jour ensemble.
  3. Appliquez la recette, puis déplacez à nouveau le curseur pour distinguer le brouillon de l’instantané appliqué.

Consultez la spécification associée

Composer un réglage booléen avec le système de design HeroUI

Un interrupteur comporte des éléments de contrôle et de contenu

Le réglage des métadonnées utilise isSelected et onChange sur Switch. Dans l’implémentation 3.2.6 installée, Switch.Content enveloppe Switch.Control et Label ; Switch.Control contient Switch.Thumb. Description se place à côté de Switch.Content pour fournir une aide au niveau du champ. Cette structure correspond au code source installé, dont l’anatomie SwitchField/SwitchButton diffère de certains exemples de documentation v3 antérieurs. La description explique la signification de la valeur booléenne au lieu de s’appuyer sur la piste bleue de l’interrupteur sélectionné. Un seul état de métadonnées pilote à la fois le contrôle natif et le texte de la recette.

Gardez ce booléen distinct de l’opération d’application. La modification des métadonnées met immédiatement à jour le brouillon en cours ; le bouton Appliquer à l’aperçu enregistre un instantané. Réinitialiser rétablit la qualité à 80, supprime les métadonnées et efface cet instantané. Aucun indicateur d’état enregistré n’est réutilisé pour un autre brouillon. Si cette fonctionnalité était connectée à un encodeur, transmettez-lui l’objet appliqué au lieu de lire le texte ambigu du formulaire.

Consultez la spécification associée

Système de design HeroUI : composer des surfaces adaptatives

L’illustration reste un contenu, et non un élément décoratif placé derrière les commandes

Sur ordinateur, une grille de 1.05fr/1fr accorde un peu plus d’espace à l’illustration tout en préservant la lisibilité des paramètres. Au point de rupture initial de 700px, la grille passe sur une seule colonne, l’en-tête s’empile et le rapport de l’illustration passe de 4:5 à 4:3. Sa légende reste à l’extérieur de l’illustration afin de conserver une surface de lecture stable.

Toutes les commandes interactives reposent sur une surface sémantique unie. Les boutons passent à la ligne lorsque l’espace manque. La hauteur de l’aperçu dépend de son contenu plutôt que d’une hauteur minimale liée à la fenêtre d’affichage ; c’est important lorsque le document est intégré dans une iframe dont la taille est calculée automatiquement. Aucun conteneur défilant à hauteur fixe ne masque le formulaire ou son résultat.

Consultez la spécification associée

Système de design HeroUI : interactions, focus et résultats fidèles

Privilégiez les états natifs aux imitations visuelles

Le bouton utilise onPress plutôt qu’un événement personnalisé réservé au pointeur. Le curseur permet une manipulation au clavier et annonce les valeurs. Le commutateur expose son état booléen via l’implémentation native d’accessibilité. Une disposition personnalisée CSS ne supprime pas les styles de focus. Pour désactiver un composant, utilisez isDisabled plutôt que la seule opacité ; --disabled-opacity décrit uniquement son apparence.

Le paragraphe d’état utilise role=status afin qu’un instantané appliqué puisse être annoncé sans déplacer le focus clavier. Le bouton d’apparence sombre change de libellé pour décrire l’action suivante. L’illustration possède un libellé de région descriptif, et ses formes restent décoratives. Cette démo ne garantit aucune persistance après le rechargement de la page.

  • La qualité est une valeur numérique limitée, affichée à l’écran.
  • Les métadonnées sont booléennes et accompagnées d’un libellé et d’un texte explicatif.
  • Appliquer enregistre un instantané local ; Réinitialiser l’efface et rétablit le brouillon initial.

Consultez la spécification associée

Système de design HeroUI : installer et reproduire l’exemple

Choisissez un seul pipeline de styles

Dans une application Vite React, installez les paquets verrouillés HeroUI et Tailwind CSS v4 avec son plugin Vite. Dans la feuille de style principale, importez d’abord tailwindcss, puis @heroui/styles, et ajoutez ensuite la mise en page d’origine CSS. Effectuez le rendu de App avec React createRoot ; aucun fournisseur v2 n’est requis pour cette composition. Le bloc de configuration indique le point d’entrée et la configuration Vite. L’application App complète et la mise en page CSS sont disponibles ci-dessus.

L’exemple autonome téléchargeable utilise le fichier heroui.min.css précompilé du paquet et un bundle esbuild React, tous deux intégrés. L’aperçu ne dépend ainsi d’aucun CDN. Il présente les mêmes commandes natives, mais ne recommande pas d’importer à la fois les styles compilés et ceux générés par Tailwind HeroUI dans une même application de production. Choisissez un seul pipeline pour éviter les règles en double.

Consultez la spécification associée

Système de design HeroUI : étendre la recette sans inventer d’encodeur

Délimitez clairement les fonctionnalités disponibles

Pour ajouter une véritable conversion d’image, ajoutez un champ de sélection de fichier et un encodeur réel exécuté dans le navigateur ou sur le serveur, puis reliez-lui les états en attente, en échec et terminé. Un Slider ne fait que sélectionner une valeur ; il n’effectue aucune compression. Le bouton Appliquer ne doit pas devenir un bouton Télécharger tant qu’aucun fichier de sortie réel n’existe. Conservez l’image d’origine séparément afin que les modifications successives de la recette ne cumulent pas les pertes dues à l’encodage.

Pour appliquer un thème à l’application, remplacez ensemble les paires sémantiques et testez les apparences claire et sombre. Modifier uniquement --accent tout en conservant une couleur de premier plan inadaptée peut réduire le contraste du bouton. Pour une personnalisation plus poussée, ciblez les classes de composants documentées et leurs états data plutôt que de remplacer leur champ accessible par un div visuellement similaire.

Consultez la spécification associée

HeroUI Exemples de composants du système de design

Application complète de recette d’exportation

Les éléments composés Slider et Switch héritent du style officiel. Un instantané appliqué distinct permet de différencier l’état du brouillon de celui de la version appliquée.

jsx
import React,{useState,useEffect} from 'react';
import {Button,Switch,Label,Description,Slider} from '@heroui/react';
import './style.css';
export default function App(){
const[quality,setQuality]=useState(80),[metadata,setMetadata]=useState(false),[dark,setDark]=useState(false),[saved,setSaved]=useState(null);
useEffect(()=>{document.documentElement.classList.toggle('dark',dark)},[dark]);
return <main className='export-app'><header><div><p className='eyebrow'>HeroUI · Export studio</p><h1>Make room for the image.</h1><p className='muted'>Inspect a local export recipe before handing it to an encoder.</p></div><Button variant='secondary' onPress={()=>setDark(!dark)}>{dark?'Light appearance':'Dark appearance'}</Button></header><div className='export-grid'><section className='art-panel' aria-label='Original CSS artwork preview'><div className='art'><div className='sun'/><div className='hill one'/><div className='hill two'/><span>FIELD NOTES<br/>COLLECTION 07</span></div><div className='art-caption'><strong>Morning in the dunes</strong><span>1600 × 1200 · sample composition</span></div></section><section className='settings'><p className='eyebrow'>WEBP PRESET</p><h2>Export settings</h2><p className='muted'>The controls update a recipe. They do not encode or upload an image.</p><Slider value={quality} onChange={setQuality} minValue={10} maxValue={100} step={5}><div className='slider-heading'><Label>Image quality</Label><Slider.Output/></div><Slider.Track><Slider.Fill/><Slider.Thumb/></Slider.Track></Slider><p className='helper'>Higher quality may preserve fine texture. File size depends on the source image and encoder.</p><Switch isSelected={metadata} onChange={setMetadata}><Switch.Content><Switch.Control><Switch.Thumb/></Switch.Control><Label>Keep metadata</Label></Switch.Content><Description>Include source metadata in the recipe.</Description></Switch><div className='recipe'><p className='eyebrow'>CURRENT RECIPE</p><code>format: webp<br/>quality: {quality}<br/>metadata: {metadata?'keep':'strip'}</code></div><div className='actions'><Button onPress={()=>setSaved({quality,metadata})}>Apply to preview</Button><Button variant='tertiary' onPress={()=>{setQuality(80);setMetadata(false);setSaved(null)}}>Reset</Button></div><p role='status' className='status'>{saved?`Preview recipe applied: quality ${saved.quality}, metadata ${saved.metadata?'kept':'stripped'}. No file was generated.`:'Adjust quality with the arrow keys, then apply the recipe.'}</p></section></div><footer>Native HeroUI 3.2.6 controls and official compiled styles. Artwork and page layout are original CSS.</footer></main>;
}

Référence du code

  • Slider.Output reflète la valeur contrôlée.
  • Switch.Control et Switch.Thumb sont des éléments visibles indispensables à la structure du composant.
  • onPress applique une recette ; il ne prétend pas qu’une image a été encodée.

Mise en page d’origine CSS

Les références aux surfaces et aux rayons utilisent les variables HeroUI ; les couleurs de l’illustration, l’échelle typographique et le point de rupture sont des choix explicites propres à l’application.

css
*{box-sizing:border-box}body{margin:0;background:var(--background);color:var(--foreground);font-family:Arial,Helvetica,sans-serif;font-size:16px;line-height:1.5}.export-app{max-width:1120px;padding:32px;margin:auto}header{display:flex;justify-content:space-between;align-items:start;gap:24px;margin-bottom:28px}h1{font-size:32px;font-weight:700;letter-spacing:-.035em;line-height:1.15;margin:8px 0 12px}h2{font-size:24px;font-weight:650;line-height:1.25;margin:8px 0 12px}.eyebrow{font-size:11px;letter-spacing:.12em;font-weight:700}.muted,.helper,footer{color:var(--muted)}.muted{margin:0 0 24px}.export-grid{display:grid;grid-template-columns:1.05fr 1fr;gap:24px}.art-panel,.settings{background:var(--surface);border-radius:calc(var(--radius)*3);padding:24px;box-shadow:var(--surface-shadow)}.art{position:relative;aspect-ratio:4/5;background:#f0d8b8;border-radius:calc(var(--radius)*2);overflow:hidden}.sun{width:40%;aspect-ratio:1;background:#bf532f;position:absolute;top:13%;left:30%;border-radius:50%}.hill{position:absolute;width:180%;height:70%;border-radius:50%;transform:rotate(-24deg)}.one{top:50%;left:-60%;background:#c59162}.two{top:66%;left:-10%;background:#69402e}.art span{position:absolute;top:6%;left:8%;font-size:11px;letter-spacing:.2em;color:#563324}.art-caption{display:flex;flex-direction:column;gap:4px;margin-top:16px}.art-caption span{color:var(--muted);font-size:12px}.settings{display:flex;flex-direction:column;gap:16px}.settings .muted{margin-bottom:0}.slider-heading{display:flex;justify-content:space-between;gap:16px}.helper{font-size:13px;margin:0}.recipe{border:var(--border-width) solid var(--border);padding:16px;border-radius:var(--field-radius)}.recipe .eyebrow{margin-top:0}code{font-size:14px}.actions{display:flex;flex-wrap:wrap;gap:8px}.status{font-size:13px;margin:0}footer{font-size:12px;margin-top:20px}@media(max-width:700px){.export-app{padding:16px}header{flex-direction:column}h1{font-size:28px}.export-grid{grid-template-columns:1fr}.art{aspect-ratio:4/3}.art-panel,.settings{padding:20px}}

Référence du code

  • Chargez cette feuille CSS après la feuille de style officielle.
  • La classe dark de html modifie les valeurs sémantiques de l’ensemble du document.
04

HeroUI Configuration de l’agent IA du système de design

Point de départ de l’implémentation

Aperçu natif vérifié avec React 19 et HeroUI 3.2.6. L’application App et la mise en page CSS fournies sont complètes. Cette configuration Vite utilise le pipeline d’importation documenté de Tailwind v4 ; l’exemple hors ligne intègre plutôt la feuille de style officielle précompilée.

jsx
// In a Vite React 19 project:
// npm install @heroui/[email protected] @heroui/[email protected] tailwindcss@^4 @tailwindcss/vite@^4
// vite.config.js
import {defineConfig} from 'vite';
import react from '@vitejs/plugin-react';
import tailwindcss from '@tailwindcss/vite';
export default defineConfig({plugins:[react(),tailwindcss()]});

// globals.css: keep this import order
// @import "tailwindcss";
// @import "@heroui/styles";
// Paste the Original layout CSS after these imports.

// main.jsx
import React from 'react';
import {createRoot} from 'react-dom/client';
import './globals.css';
import App from './App.jsx';
createRoot(document.getElementById('root')).render(<App/>);
// App.jsx is the complete application above. Remove its './style.css'
// import when the same CSS is included in globals.css.

Un prompt pour votre projet

Prompt pour l’agent IA
Utilisez App.jsx, la feuille de style et l’intégration Tailwind fournis pour HeroUI 3.2.6 afin de créer le studio d’exportation d’images. Reliez l’état de qualité du Slider et l’état des métadonnées du Switch au récapitulatif de l’exportation ; conservez Switch.Content, Control et Thumb avec leurs libellés. Toute modification de la qualité ou des métadonnées doit invalider l’instantané enregistré. La commande d’apparence sombre doit modifier la même classe du document que celle utilisée par la feuille de style. Enregistrez une recette d’exportation explicitement locale ; ne laissez pas entendre qu’un fichier image a été traité ou téléchargé.
05

HeroUI Sources et périmètre du système de design

Référence HeroUI 3.2.6. Les variables officielles sont distinguées des choix d’origine en matière de typographie, d’illustration et de mise en page. L’aperçu natif ne modifie que des paramètres conservés en mémoire et n’effectue aucun encodage d’image.