Interface multiplateforme et mobile · Nouvelle ressource
Système de design Tamagui.
Explorez les véritables catégories de tokens v5 de Tamagui et ses thèmes bleus clair et sombre dans un tableau de suivi complet composé de composants natifs, avec validation, progression et récupération depuis un état vide.
Valeur réelle de la configuration v5. Un même libellé numérique désigne une valeur différente pour la taille, l’espacement et le rayon ; ne considérez pas $4 comme une valeur universelle en pixels.
size.$2
28
Valeur réelle de la configuration v5. Un même libellé numérique désigne une valeur différente pour la taille, l’espacement et le rayon ; ne considérez pas $4 comme une valeur universelle en pixels.
size.$3
36
Valeur réelle de la configuration v5. Un même libellé numérique désigne une valeur différente pour la taille, l’espacement et le rayon ; ne considérez pas $4 comme une valeur universelle en pixels.
size.$4
44
Valeur réelle de la configuration v5. Un même libellé numérique désigne une valeur différente pour la taille, l’espacement et le rayon ; ne considérez pas $4 comme une valeur universelle en pixels.
size.$5
52
Valeur réelle de la configuration v5. Un même libellé numérique désigne une valeur différente pour la taille, l’espacement et le rayon ; ne considérez pas $4 comme une valeur universelle en pixels.
size.$6
64
Valeur réelle de la configuration v5. Un même libellé numérique désigne une valeur différente pour la taille, l’espacement et le rayon ; ne considérez pas $4 comme une valeur universelle en pixels.
Valeur réelle de la configuration v5. Un même libellé numérique désigne une valeur différente pour la taille, l’espacement et le rayon ; ne considérez pas $4 comme une valeur universelle en pixels.
space.$1.5
4
Valeur réelle de la configuration v5. Un même libellé numérique désigne une valeur différente pour la taille, l’espacement et le rayon ; ne considérez pas $4 comme une valeur universelle en pixels.
space.$2
7
Valeur réelle de la configuration v5. Un même libellé numérique désigne une valeur différente pour la taille, l’espacement et le rayon ; ne considérez pas $4 comme une valeur universelle en pixels.
space.$2.5
10
Valeur réelle de la configuration v5. Un même libellé numérique désigne une valeur différente pour la taille, l’espacement et le rayon ; ne considérez pas $4 comme une valeur universelle en pixels.
space.$3
13
Valeur réelle de la configuration v5. Un même libellé numérique désigne une valeur différente pour la taille, l’espacement et le rayon ; ne considérez pas $4 comme une valeur universelle en pixels.
space.$3.5
16
Valeur réelle de la configuration v5. Un même libellé numérique désigne une valeur différente pour la taille, l’espacement et le rayon ; ne considérez pas $4 comme une valeur universelle en pixels.
space.$4
18
Valeur réelle de la configuration v5. Un même libellé numérique désigne une valeur différente pour la taille, l’espacement et le rayon ; ne considérez pas $4 comme une valeur universelle en pixels.
space.$5
24
Valeur réelle de la configuration v5. Un même libellé numérique désigne une valeur différente pour la taille, l’espacement et le rayon ; ne considérez pas $4 comme une valeur universelle en pixels.
space.$6
32
Valeur réelle de la configuration v5. Un même libellé numérique désigne une valeur différente pour la taille, l’espacement et le rayon ; ne considérez pas $4 comme une valeur universelle en pixels.
Valeur réelle de la configuration v5. Un même libellé numérique désigne une valeur différente pour la taille, l’espacement et le rayon ; ne considérez pas $4 comme une valeur universelle en pixels.
radius.1
3
Valeur réelle de la configuration v5. Un même libellé numérique désigne une valeur différente pour la taille, l’espacement et le rayon ; ne considérez pas $4 comme une valeur universelle en pixels.
radius.2
5
Valeur réelle de la configuration v5. Un même libellé numérique désigne une valeur différente pour la taille, l’espacement et le rayon ; ne considérez pas $4 comme une valeur universelle en pixels.
radius.3
7
Valeur réelle de la configuration v5. Un même libellé numérique désigne une valeur différente pour la taille, l’espacement et le rayon ; ne considérez pas $4 comme une valeur universelle en pixels.
radius.4
9
Valeur réelle de la configuration v5. Un même libellé numérique désigne une valeur différente pour la taille, l’espacement et le rayon ; ne considérez pas $4 comme une valeur universelle en pixels.
radius.5
10
Valeur réelle de la configuration v5. Un même libellé numérique désigne une valeur différente pour la taille, l’espacement et le rayon ; ne considérez pas $4 comme une valeur universelle en pixels.
radius.6
16
Valeur réelle de la configuration v5. Un même libellé numérique désigne une valeur différente pour la taille, l’espacement et le rayon ; ne considérez pas $4 comme une valeur universelle en pixels.
Rôle sémantique résolu à partir du thème bleu v5. Pour les états de survol, d’appui ou d’activation, le composant peut sélectionner un thème enfant plus spécifique.
light_blue.backgroundHover
hsla(210, 100%, 99%, 1)
Rôle sémantique résolu à partir du thème bleu v5. Pour les états de survol, d’appui ou d’activation, le composant peut sélectionner un thème enfant plus spécifique.
light_blue.backgroundPress
hsla(205, 92%, 95%, 1)
Rôle sémantique résolu à partir du thème bleu v5. Pour les états de survol, d’appui ou d’activation, le composant peut sélectionner un thème enfant plus spécifique.
light_blue.color
hsla(216, 71%, 23%, 1)
Rôle sémantique résolu à partir du thème bleu v5. Pour les états de survol, d’appui ou d’activation, le composant peut sélectionner un thème enfant plus spécifique.
light_blue.borderColor
hsla(203, 100%, 92%, 1)
Rôle sémantique résolu à partir du thème bleu v5. Pour les états de survol, d’appui ou d’activation, le composant peut sélectionner un thème enfant plus spécifique.
light_blue.borderColorFocus
hsla(203, 100%, 92%, 1)
Rôle sémantique résolu à partir du thème bleu v5. Pour les états de survol, d’appui ou d’activation, le composant peut sélectionner un thème enfant plus spécifique.
light_blue.placeholderColor
hsla(206, 100%, 50%, 1)
Rôle sémantique résolu à partir du thème bleu v5. Pour les états de survol, d’appui ou d’activation, le composant peut sélectionner un thème enfant plus spécifique.
Rôle sémantique résolu à partir du thème bleu v5. Pour les états de survol, d’appui ou d’activation, le composant peut sélectionner un thème enfant plus spécifique.
dark_blue.backgroundHover
hsla(212, 69%, 16%, 1)
Rôle sémantique résolu à partir du thème bleu v5. Pour les états de survol, d’appui ou d’activation, le composant peut sélectionner un thème enfant plus spécifique.
dark_blue.backgroundPress
hsla(215, 42%, 9%, 1)
Rôle sémantique résolu à partir du thème bleu v5. Pour les états de survol, d’appui ou d’activation, le composant peut sélectionner un thème enfant plus spécifique.
dark_blue.color
hsla(205, 100%, 88%, 1)
Rôle sémantique résolu à partir du thème bleu v5. Pour les états de survol, d’appui ou d’activation, le composant peut sélectionner un thème enfant plus spécifique.
dark_blue.borderColor
hsla(209, 100%, 19%, 1)
Rôle sémantique résolu à partir du thème bleu v5. Pour les états de survol, d’appui ou d’activation, le composant peut sélectionner un thème enfant plus spécifique.
dark_blue.borderColorFocus
hsla(209, 100%, 19%, 1)
Rôle sémantique résolu à partir du thème bleu v5. Pour les états de survol, d’appui ou d’activation, le composant peut sélectionner un thème enfant plus spécifique.
dark_blue.placeholderColor
hsla(206, 100%, 50%, 1)
Rôle sémantique résolu à partir du thème bleu v5. Pour les états de survol, d’appui ou d’activation, le composant peut sélectionner un thème enfant plus spécifique.
La pile de polices système v5 ne nécessite aucune requête de police distante.
body.$2
13px / 20px
La taille de police et la hauteur de ligne forment des rôles typographiques distincts, indépendants du jeton de taille de composant portant le même libellé.
body.$3
14px / 21px
La taille de police et la hauteur de ligne forment des rôles typographiques distincts, indépendants du jeton de taille de composant portant le même libellé.
body.$4
15px / 23px
La taille de police et la hauteur de ligne forment des rôles typographiques distincts, indépendants du jeton de taille de composant portant le même libellé.
body.$5
16px / 24px
La taille de police et la hauteur de ligne forment des rôles typographiques distincts, indépendants du jeton de taille de composant portant le même libellé.
body.$6
18px / 27px
La taille de police et la hauteur de ligne forment des rôles typographiques distincts, indépendants du jeton de taille de composant portant le même libellé.
body.$8
26px / 38px
La taille de police et la hauteur de ligne forment des rôles typographiques distincts, indépendants du jeton de taille de composant portant le même libellé.
Une seule instance de configuration en dehors de React ; getCSS() fournit CSS de thème pour le Web.
TamaguiProvider
config + defaultTheme
L’application choisit le mode clair ou sombre tout en préservant l’état du tableau.
Theme
name="blue"
Résout le thème enfant bleu correspondant à l’apparence actuelle.
Checkbox
checked + onCheckedChange
Le tableau considère comme terminée une ligne uniquement si sa valeur est strictement égale à true ; indeterminate ne signifie pas que la tâche est terminée.
Input
value + onChangeText
Saisie contrôlée, validation après suppression des espaces superflus et gestion explicite des doublons.
Progress
value from 0 to 100
L’indicateur est calculé à partir du nombre de lignes terminées divisé par le nombre total de lignes.
YStack / XStack
directional layout with token gap
Adaptez la mise en page à la lecture sans feuille de style d’imitation distincte.
03
Guide complet du système de design Tamagui
Un guide pratique pour choisir, appliquer et évaluer ce système dans une interface réelle.
DESIGN-tamagui.md
Des conseils complets, un point de départ pour la mise en œuvre et des liens vers les sources.
Configuration versionnée et CSS du système de design Tamagui
Utiliser le préréglage v5 indiqué
Cet exemple fixe les versions de tamagui et @tamagui/config à 2.7.7 et importe defaultConfig depuis @tamagui/config/v5. Le nom de la configuration est v5 ; il ne correspond pas à la version majeure du paquet npm. Confondre ces deux numéros conduirait à indiquer une mauvaise commande d’installation. createTamagui est exécuté une seule fois en dehors du composant, et le CSS qu’il génère est inséré avant le rendu du tableau afin que les variables de thème et les styles natifs disposent d’une véritable définition pour le Web.
Expliciter la petite surcharge de configuration
Le code source fourni définit onlyAllowShorthands sur false, car cet exemple pédagogique utilise des propriétés longues et explicites telles que padding et backgroundColor. Il s’agit d’un choix de l’application qui s’ajoute au préréglage. La base v5 n’inclut pas de moteur d’animation, et cet exemple n’en invente pas et ne prétend pas proposer de transitions animées. La progression et le comportement des cases à cocher restent simples et ne nécessitent aucune dépendance d’animation distincte.
Jetons de taille, d’espacement et de rayon du système de design Tamagui
Ne confondez pas les jetons portant le même libellé
Dans la configuration v5 figée, la taille $4 vaut 44, l’espacement $4 vaut 18 et le rayon 4 vaut 9. La taille d’un composant, l’écart de mise en page et le rayon d’un coin ne peuvent donc pas être convertis à l’aide d’une même règle de multiplication. La référence présente chaque catégorie séparément, et l’exemple utilise les valeurs adaptées à chacune au moyen de véritables propriétés Tamagui. C’est plus utile qu’une liste d’incréments génériques de 4 px, absents de cette configuration.
size.$4 = 44
space.$4 = 18
radius.4 = 9
Police de corps $4 : 15 px avec une hauteur de ligne de 23 px
Distinguez aussi l’échelle typographique
La police de corps $4 mesure 15 px avec une hauteur de ligne de 23 px, tandis que la taille de composant $4 reste à 44. v5 fournit la pile de polices système sans nécessiter de police téléchargée. H1, H2 et Text héritent de leur contexte typographique natif ; les valeurs explicites de fontSize et lineHeight dans le code source définissent la hiérarchie d’origine du tableau. La largeur extérieure de 880 px est un choix local de mise en page, pas un jeton Tamagui global.
Thèmes sémantiques et apparence du système de design Tamagui
Associer un thème bleu enfant au mode clair ou sombre
TamaguiProvider reçoit le defaultTheme choisi, et Theme name="blue" résout le thème enfant correspondant. Dans l’arborescence des composants, le code source utilise les rôles background, backgroundHover, color et borderColor plutôt que de répéter des valeurs hexadécimales littérales. Le tableau consigne les valeurs réelles de light_blue et dark_blue afin que le lecteur puisse comparer les valeurs résolues dans la configuration au lieu de supposer qu’il existe une seule palette de marque fixe.
Préserver l’état du tableau lors des changements d’apparence
Le booléen dark est indépendant des lignes, du brouillon de saisie et du filtre. Le changement d’apparence met à jour les composants natifs sans modifier le contenu du tableau. Les boutons et les cases à cocher peuvent sélectionner leurs propres valeurs de thème enfant, de sorte que leur couleur calculée ne soit pas nécessairement identique au jeton d’arrière-plan parent. Examinez l’état rendu avant d’aplatir la hiérarchie en CSS personnalisés.
Cases à cocher et progression calculée du système de design Tamagui
Conserver l’état d’avancement dans une seule collection de lignes
Chaque ligne possède un identifiant stable, un libellé explicite et un booléen done. Checkbox reçoit checked et onCheckedChange ; seule la valeur littérale true marque la ligne comme terminée. Checkbox.Indicator affiche la coche. Le texte adjacent et le nom accessible identifient la même habitude, tandis que le texte barré signale visuellement qu’elle est terminée. Le code source ne crée pas de compteur distinct susceptible de se désynchroniser des lignes.
Calculer la progression sur l’ensemble du tableau
Validation des saisies et gestion des doublons dans le système de design Tamagui
Ajouter un véritable champ de saisie contrôlé
Le champ de saisie conserve le brouillon actuel via value et onChangeText. L’action Ajouter une habitude supprime les espaces superflus et refuse une valeur vide en affichant un message, aria-invalid et une description de l’erreur. Après une soumission vide, le focus revient au champ de saisie. Une vérification insensible à la casse empêche l’ajout d’une deuxième ligne avec le même texte et conserve le brouillon pour qu’il puisse être corrigé. Ces règles sont propres au tableau d’origine, pas à la bibliothèque.
Mettre à jour le tableau uniquement après un ajout valide
Un brouillon valide ajoute une nouvelle ligne non terminée, efface le champ de saisie et supprime l’erreur. Le dénominateur de progression est immédiatement mis à jour, puisqu’il est calculé à partir de la nouvelle collection. L’ajout d’une habitude ne crée ni rappel ni compte. Le tableau est volontairement conservé dans l’état local React ; recharger le document rétablit l’exemple.
Vues filtrées et retour après un état vide du système de design Tamagui
Préciser la portée du filtre
L’option Afficher uniquement les éléments non terminés masque les lignes terminées sans les retirer de la collection. Si cette vue ne contient plus rien, un message d’état vide explique que la liste complète existe toujours et propose une action directe pour y revenir. Cet état vide résulte des choix de l’utilisateur : ce n’est pas un bouton décoratif qui remplace arbitrairement les cartes par des espaces réservés.
Distinguer la réinitialisation de l’apparence
Réinitialiser le tableau d’exemple restaure les trois lignes initiales, efface le brouillon et l’erreur, puis rétablit la liste complète. L’apparence actuelle reste inchangée. Comme chaque modification correspond à un état explicite, la réinitialisation ne nécessite ni de recharger le document ni d’abandonner le fournisseur configuré. La restauration du thème et celle du contenu peuvent être testées séparément.
Piles adaptatives et lecture accessible du système de design Tamagui
Laisser le contenu des piles déterminer leur hauteur
YStack organise le flux principal de lecture, et XStack aligne les commandes de l’en-tête, les lignes avec cases à cocher et les actions. Les groupes de commandes passent à la ligne au lieu d’imposer une largeur fixe pour ordinateur. Le conteneur extérieur est limité à 880px et utilise le véritable jeton d’espacement $4 pour le remplissage. Le texte de chaque ligne peut se rétrécir et passer à la ligne, tandis que les commandes restent accessibles à 280px comme dans les fenêtres de test plus larges.
Tester les interactions après la recomposition
Le test dans le navigateur ajoute une habitude, la marque comme terminée, filtre la liste et change l’apparence avant de mesurer le débordement. Une capture de la mise en page initiale ne permettrait pas de voir si une erreur, un libellé long ou un état filtré perturbe la composition étroite. Les sémantiques natives des cases à cocher et le texte visible ont été testés avec la progression calculée, au lieu de simplement supposer qu’ils fonctionnent parce qu’ils sont présents.
Build complet pour navigateur du système de design Tamagui
Fournir le fournisseur, CSS et les définitions de build
Les trois fichiers fournis suffisent pour l’étude web locale. Le JSX inclut le fournisseur, une configuration, le thème généré CSS et l’intégralité du tableau. build.mjs fixe la cible web et l’environnement de production, et fournit une valeur de repli vide pour process.env dans les autres lectures de variables d’environnement propres au navigateur. Sans cette dernière définition, ce bundle autonome peut échouer avec l’erreur process is not defined, même s’il compile.
Enregistrez tamagui.jsx, build.mjs et index.html dans le même dossier.
Installez les packages React et Tamagui aux versions spécifiées.
Créez le build et servez le dossier local.
Testez les ajouts vides ou en double, l’achèvement, les filtres, le thème et la réinitialisation.
Distinguer l’adoption native de l’adoption web
Exemples de composants du système de design Tamagui
tamagui.jsx
Configuration, CSS généré, composants natifs et état complet du tableau.
jsx
import React,{useState} from 'react';import{createRoot}from'react-dom/client';
import{createTamagui,TamaguiProvider,Theme,YStack,XStack,Text,H1,H2,Button,Input,Checkbox,Progress,Separator}from'tamagui';import{defaultConfig}from'@tamagui/config/v5';
const config=createTamagui({...defaultConfig,settings:{...defaultConfig.settings,onlyAllowShorthands:false}});const sheet=document.createElement('style');sheet.textContent=config.getCSS();document.head.append(sheet);
const initial=[{id:1,text:'Read ten pages',done:false},{id:2,text:'Step outside for a break',done:true},{id:3,text:'Write one useful note',done:false}];
function App(){const[dark,setDark]=useState(false),[rows,setRows]=useState(initial),[draft,setDraft]=useState(''),[error,setError]=useState(''),[filter,setFilter]=useState(false);const done=rows.filter(x=>x.done).length;let shown=rows.filter(x=>!filter||!x.done);function add(){let text=draft.trim();if(!text){setError('Write a small habit before adding it.');document.querySelector('#habit-input')?.focus();return}if(rows.some(x=>x.text.toLowerCase()===text.toLowerCase())){setError('That habit is already in this list.');return}setRows([...rows,{id:Date.now(),text,done:false}]);setDraft('');setError('')}return <TamaguiProvider config={config} defaultTheme={dark?'dark':'light'}><Theme name="blue"><YStack backgroundColor="$background" color="$color" padding="$4" gap="$4" maxWidth={880} margin="auto" width="100%" minHeight={0}><XStack justifyContent="space-between" alignItems="center" flexWrap="wrap" gap="$3"><Text fontSize="$2" fontWeight="700">TAMAGUI / ORIGINAL HABIT BOARD</Text><Button size="$3" onPress={()=>setDark(!dark)}>{dark?'Light appearance':'Dark appearance'}</Button></XStack><H1 fontSize="$8" lineHeight="$8">A little progress, every day.</H1><Text fontSize="$4" lineHeight="$5">A local board built with Tamagui 2.7.7 and its v5 blue theme. Your changes stay in this page; no account or daily reminder is connected.</Text><YStack backgroundColor="$backgroundHover" borderWidth={1} borderColor="$borderColor" borderRadius="$4" padding="$4" gap="$3"><XStack justifyContent="space-between" gap="$3" flexWrap="wrap"><H2 fontSize="$5">Today’s small steps</H2><Text id="progress-count" aria-live="polite">{done} of {rows.length} complete</Text></XStack><Progress value={rows.length?done/rows.length*100:0} size="$2" aria-label="Completed habits"><Progress.Indicator animation={undefined}/></Progress><Button size="$3" alignSelf="flex-start" onPress={()=>setFilter(!filter)}>{filter?'Show all habits':'Show unfinished only'}</Button><Separator/>{shown.length?shown.map(row=><XStack key={row.id} gap="$3" alignItems="center" paddingVertical="$2"><Checkbox id={'habit-'+row.id} checked={row.done} onCheckedChange={value=>setRows(rows.map(x=>x.id===row.id?{...x,done:value===true}:x))} aria-label={row.text} size="$4"><Checkbox.Indicator><Text fontWeight="700">✓</Text></Checkbox.Indicator></Checkbox><Text flex={1} fontSize="$4" lineHeight="$5" textDecorationLine={row.done?'line-through':'none'} opacity={row.done?.65:1}>{row.text}</Text></XStack>):<YStack gap="$3"><Text fontWeight="700">Nothing unfinished in this view</Text><Text>All your habits remain in the full list. You can revisit any completed item.</Text><Button onPress={()=>setFilter(false)}>Return to all habits</Button></YStack>}</YStack><YStack gap="$3"><Text htmlFor="habit-input" tag="label" fontWeight="700">Add one small habit</Text><Input id="habit-input" value={draft} onChangeText={v=>{setDraft(v);setError('')}} placeholder="For example, stretch for five minutes" aria-describedby={error?'habit-error':undefined} aria-invalid={!!error} onKeyPress={e=>{if(e.nativeEvent.key==='Enter')add()}}/><Text id="habit-error" color="$color" aria-live="polite">{error}</Text><XStack gap="$3" flexWrap="wrap"><Button theme="active" onPress={add}>Add habit</Button><Button onPress={()=>{setRows(initial);setDraft('');setError('');setFilter(false)}}>Reset sample board</Button></XStack></YStack><Text fontSize="$2" lineHeight="$3">Native Checkbox, Input, Button and Progress components; original board content and state. Theme changes preserve the current board.</Text></YStack></Theme></TamaguiProvider>}
createRoot(document.getElementById('root')).render(<App/>);
Implémentez le tableau d’habitudes web complet Tamagui 2.7.7 avec le preset v5. Distinguez les catégories de jetons de taille, d’espacement, de rayon et de police ; conservez le thème généré CSS, les thèmes enfants bleu clair et bleu foncé, les cases à cocher contrôlées, la validation après suppression des espaces superflus et celle des doublons, le dénominateur de progression basé sur toutes les lignes, le retour depuis la vue des éléments non terminés et la réinitialisation sans modification de l’apparence.
05
Sources et portée du système de design Tamagui
De véritables composants web Tamagui 2.7.7 utilisant le preset v5. Le tableau d’habitudes et ses règles d’état sont du code original OpenDesign ; aucune fonctionnalité de compte, de rappel ou d’appareil natif n’y est connectée.