Files
home_hub/design_system/package-smartphone/consigne_mobile.md
T
gilles 4518ed8311 chore(design): ajout du package design system smartphone
Contient les tokens, composants et exemples adaptés au mobile,
à utiliser comme référence lors du développement des vues smartphone.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-30 08:53:36 +02:00

8.0 KiB
Raw Blame History

Consignes mobile — mon design system

Tu es un agent IA qui produit du code mobile avec ce design system. Lis ce fichier ENTIER avant d'écrire la moindre ligne. Suis les règles à la lettre.


🎯 Identité

  • Cibles : iOS et Android via HTML/JS (Cordova, Capacitor, ou PWA)
  • Largeur ref : 390px (iPhone 14 / Galaxy S22)
  • Hit target min : 44 × 44px (Apple HIG / Material)
  • Style : Gruvbox seventies — orange brûlé, fond brun délavé en sombre / gris clair usé en clair

📁 Fichiers

Fichier Composants exposés sur window
components/ui-kit.jsx Icon, Tooltip, Button, IconButton, Toggle, StatusLed, Popup, BatteryGauge, RadialGauge, BigRadialGauge, TreeNav, Sparkline, LineChart
components/mobile-kit.jsx StatusBar, NavBar, TabBar, ListRow, ListSection, ActionCard, PrimaryButton, SegmentedControl, SearchBar
components/mobile-sheets.jsx BottomSheet, ActionSheet, AlertDialog, Toast, FAB, PullToRefresh
components/mobile-gestures.jsx useGesture, GestureZone, GESTURE_CATALOG
components/mobile-swipeable.jsx SwipeableRow
components/mobile-forms.jsx FormField, TextInput, DateInput, Dropdown, CheckboxItem, RadioGroup, MediaInsert, AvatarLogo, BiometricButton
components/mobile-apps.jsx Avatar, AvatarMenu, OnboardingSlider, ChatBubble, ChatComposer, CalendarMonth, MapView, FilterChips, QrScannerView, CameraView, FileExplorer

⚠️ Règles absolues

  1. Hit targets ≥ 44 × 44 px sur TOUT élément tactile. Pas de petits boutons.
  2. Pas de hover — c'est du tactile. Utilise la pression au touch via .touch-press.
  3. Tooltips sur tous les <IconButton> isolés (la prop label les active automatiquement).
  4. Toujours des polices natives mobile : Inter / JetBrains Mono / Share Tech Mono via tokens.
  5. Animations fluides : 180-300ms, easing cubic-bezier(.3,.7,.3,1.2) pour entrée, cubic-bezier(.3,.6,.3,1) pour mouvement.
  6. Toujours <TabBar> en bas comme navigation primaire (3-5 sections).
  7. JAMAIS de popup centrée modale standard — utilise BottomSheet, ActionSheet, AlertDialog ou Toast.
  8. Bouton Avatar en haut à droite de chaque écran principal pour accès rapide au menu utilisateur.
  9. Variables CSS uniquement — pas de hex en dur (color: var(--accent), jamais color: #fe8019).
  10. Smartphone d'abord — toute interaction doit fonctionner avec un seul pouce.

🧩 Cas → Composant à utiliser

Structure d'écran (toujours)

<div style={{ display: 'flex', flexDirection: 'column', height: '100%' }}>
  <StatusBar />
  <NavBar large title="Mon écran" right={<Avatar name="M" onClick={openMenu} />} />
  <div style={{ flex: 1, overflowY: 'auto', padding: 14 }}>
    {/* contenu */}
  </div>
</div>

Si la page fait partie d'une nav principale, ajoute <TabBar> après. Si elle a une action principale flottante, ajoute <FAB>.

Liste à actions cachées

<SwipeableRow
  onTap={() => open(item)}
  leftActions={[{ label: 'Suppr.', icon: 'close', color: 'var(--err)', onClick: del }]}   //  swipe gauche
  rightActions={[{ label: 'Lu', icon: 'play', color: 'var(--info)', onClick: read }]}     //  swipe droit
>
  <div>{contenu de la ligne}</div>
</SwipeableRow>

Champ texte typé

// Email
<TextInput value={...} onChange={...} keyboard="email" autocomplete="email" autocapitalize="off" />
// Mot de passe
<TextInput value={...} onChange={...} type="password" autocomplete="current-password" />
// OTP SMS
<TextInput value={...} onChange={...} keyboard="numeric" autocomplete="one-time-code" maxLength={6} />
// Recherche
<TextInput value={...} onChange={...} keyboard="search" enterHint="search" />

Confirmation destructive

<AlertDialog open={open} onClose={...}
  icon="alert" iconColor="var(--err)"
  title="Supprimer ?"
  message="Cette action est irréversible."
  actions={[
    { label: 'Annuler' },
    { label: 'Supprimer', danger: true, primary: true, onClick: del },
  ]} />

Choix dans une liste

<BottomSheet open={...} onClose={...} title="Choisir">
  <RadioGroup value={...} onChange={...} options={[...]} />
</BottomSheet>

Menu d'actions sur élément

<ActionSheet open={...} onClose={...} title="Actions"
  actions={[
    { label: 'Modifier', icon: 'cog' },
    { label: 'Partager', icon: 'download' },
    { label: 'Supprimer', icon: 'close', danger: true },
  ]} />

Feedback après action

<Toast open={msg !== null} onClose={() => setMsg(null)} message={msg} variant="ok" />

Menu utilisateur (avatar haut-droite)

<AvatarMenu open={...} onClose={...} name="Marc" email="marc@..."
  items={[
    { icon: 'user',  label: 'Mon profil' },
    { icon: 'cog',   label: 'Paramètres' },
    { icon: 'power', label: 'Se déconnecter', danger: true },
  ]} />

🚫 Anti-patterns

  • window.alert / confirm → utilise AlertDialog
  • <button> nu sans hit target → utilise IconButton ou PrimaryButton
  • Hover effects → pas d'hover sur mobile, utilise .touch-press
  • Popups centrées pour formulaire court → BottomSheet
  • Sidebars > 240px → utilise plutôt drawer ou TabBar
  • Tableaux denses → liste swipeable avec actions
  • Couleurs en dur → toujours var(--token)
  • Police arbitraire → var(--font-ui), var(--font-mono), var(--font-terminal)
  • Boutons texte sans icône pour actions critiques → ajoute toujours une icône
  • Inputs sans keyboard/autocomplete adaptés → frustre l'utilisateur

📐 Tailles

Élément Taille
StatusBar 44px
NavBar compact 52px
NavBar large ~90px
TabBar 70px (avec safe area)
ListRow min 52px
PrimaryButton lg 52px
IconButton 34px (def) / 26px (compact) / 44px (large)
FAB 56 × 56 ronde
Toggle 42 × 22
Radius cartes 10-14px
Radius boutons 8-12px
Avatar 36px (header) / 48-72px (profile)
Espacement standard 8 / 12 / 14 / 18 / 24px

💡 Détails à respecter

  • Safe area bottom : la TabBar a déjà un padding-bottom: 18px pour la home indicator iOS.
  • Backdrop-filter blur : utilisé sur NavBar/TabBar/AlertBg pour effet vitre.
  • SwipeableRow snap : ouvre/ferme à 50% de la largeur des actions.
  • AvatarMenu : un seul ouvert à la fois, ferme au clic extérieur (backdrop).
  • Toast : auto-ferme à 2.5s sauf prop duration différent.
  • PullToRefresh : seulement quand scrollTop === 0.

🌗 Dark / Light

Tout fonctionne automatiquement via data-theme="dark|light" sur un parent. Toujours tester les deux :

  • En sombre : tokens chauds bruns
  • En clair : gris clair usé (pas blanc pur), accent orange plus contrasté

🔚 En cas de doute

  • Composant pas sûr ? → examples/exemple-mobile-apps.html montre quasi tous les cas
  • Geste pas clair ? → onglet Gestes du smartphone dans exemple-mobile.html
  • Saisie spéciale ? → exemple-mobile-saisie.html + section "Antisèche"

Toujours préférer un composant existant à un custom. Quand tu doutes, demande.