Design system
Le design commun
Les couleurs, les polices, les icônes et les composants partagés avec le web sont présentés dans la section Design. Cette page explique comment le mobile les implémente.
L'interface reproduit exactement la maquette Figma (page « Mockups », cadres « App (iOS) 390 px »). Les couleurs, polices et tailles viennent des variables Figma, avec les mêmes noms.
Les couleurs : src/theme/colors.ts
| Nom | Valeur | Usage |
|---|---|---|
textDefault | #111827 | Texte principal |
textSubtle | #374151 | Texte secondaire |
textMuted | #4b5563 | Légendes, valeurs dans les listes |
textOnBrand | #ffffff | Texte sur fond vert |
surfaceCard | #ffffff | Cartes, listes, barre d'onglets |
surfacePage | #f5f5f4 | Fond des pages de réglages |
borderDefault | #e5e7eb | Séparateurs |
borderStrong | #9ca3af | Bordures de champs |
brandPrimary | #144545 | La couleur TimeManager : boutons, onglet actif, liens |
brandPrimaryPressed | #0f3535 | Bouton principal appuyé |
brandPrimarySoft | #e8eded | Fonds légers (avatars) |
brandAccent | #e8c18e | Sable : pauses, bouton Pause en cours |
brandAccentStrong | #7a4f1a | Anneau du bouton Pause |
brandWork | #2e8a82 | Temps travaillé dans la frise et les graphiques |
brandTrack | #dce3e1 | Fond des barres et de l'anneau |
chartGrid | rgba(17,24,39,0.1) | Grille des graphiques |
feedbackDangerStrong | #b91c1c | Bouton Service en cours, actions destructrices |
feedbackDangerText | #b91c1c | Messages d'erreur |
feedbackDangerBorder | #fecaca | Bordure des boutons de danger |
Pas de mode sombre : la maquette n'en a pas, et app.json force le mode clair.
Les utiliser
// directement par leur nom, dans les composants du kit
<Text color="textMuted">...</Text>
<Icon name="bell" color={colors.brandPrimary} />
// dans un style
const { colors } = useTheme();
<View style={{ backgroundColor: colors.surfacePage }} />Le type ColorName liste tous les noms : une faute de frappe est refusée par TypeScript.
Pourquoi useTheme() ?
Aujourd'hui il renvoie toujours les mêmes couleurs. Mais tous les composants passent par lui : si un jour la maquette ajoute un mode sombre, il suffira de changer ce seul hook.
Les polices : src/theme/typography.ts
| Nom | Police | Usage |
|---|---|---|
light | Inter 300 | L'heure en grand sur Clock |
regular | Inter 400 | Texte courant |
medium | Inter 500 | Libellés, onglets |
semibold | Inter 600 | Titres de barre, libellés importants |
bold | Inter 700 | Grands titres (connexion, présentation), chiffres clés des équipes et des graphiques |
mono | Share Tech Mono 400 | Initiales des avatars et de l'en-tête de profil |
<Text size={17} weight="semibold">Titre</Text>Les composants du kit : src/components/ui/
Tous les écrans sont construits avec ces briques. Elles ne font aucune requête : elles affichent ce qu'on leur donne.
Texte et icônes
| Composant | Rôle | Props principales |
|---|---|---|
Text | Tout texte de l'app | size, weight, color, align, lineHeight |
Icon | Une icône Uicons (Flaticon) dessinée en SVG | name, size, color |
Logo | Le logo TimeManager | size |
Avatar | Les initiales dans un rond | initials, variant (nav, row, stack, invited, mini) |
Status | Un statut avec icône et couleur (jamais la couleur seule) | kind : complete, overtime, missingClockOut, corrected, pending, approved... |
Les tracés des 44 icônes sont dans icon-paths.ts. Pour en ajouter une, on copie le tracé SVG depuis Uicons.
Actions
| Composant | Rôle | Props principales |
|---|---|---|
Button | Bouton | label, variant (primary, secondary, danger, accent), size (default, large), icon, disabled |
TextLink | Lien texte souligné | label, onPress, icon |
AddRow | Ligne « + Ajouter... » dans une liste | label, onPress |
Checkbox | Case à cocher | label, checked, onChange |
SegmentedControl | Choix entre 2 ou 3 options (périodes) | options, value, onChange |
Listes façon réglages iOS : group.tsx
<Group label="Profil" footer="Seul le GM peut changer l'email.">
<NavRow label="Prénom" value="Elias" onPress={...} />
<DetailRow title="Email" detail="elias@example.com" />
<InputRow label="Mot de passe" secureTextEntry />
</Group>| Composant | Rôle |
|---|---|
Group | Une carte blanche arrondie avec un titre au-dessus et une note en dessous |
NavRow | Une ligne avec libellé, valeur et chevron, qui ouvre quelque chose |
ValueRow | Une ligne libellé et valeur, non cliquable |
DetailRow | Une ligne sur deux niveaux (titre et détail), avec badge ou éléments à gauche et à droite |
InputRow | Un champ de saisie dans une ligne |
TextAreaRow | Un champ multiligne (raison d'une correction) |
Structure d'écran
| Composant | Rôle |
|---|---|
Screen (src/components/screen.tsx) | Le cadre de chaque écran : fond, en-tête, défilement |
AppBar | La barre du haut : titre, flèche retour (back), bouton d'action à droite |
<Screen background="surfacePage" header={<AppBar title="Compte" bordered />}>
...
</Screen>Feuilles qui montent du bas
| Composant | Rôle |
|---|---|
Sheet | La feuille de base, avec titre et fermeture |
OptionSheet | Choisir une option dans une liste (langue, manager) |
ActionSheet | Confirmer une action, souvent destructrice |
TextInputSheet | Modifier un texte (prénom, nom d'équipe) |
DateTimeSheet | Choisir un jour et une heure |
DaySheet | Choisir un jour |
<ActionSheet
visible={sheet === 'delete'}
message={t('account.deleteIntro')}
actions={[{ label: t('account.delete'), destructive: true, onPress: deleteAccount }]}
cancelLabel={t('common.cancel')}
onClose={close}
/>Formulaires d'authentification
| Composant | Rôle |
|---|---|
TextField | Champ avec libellé au-dessus (écrans de connexion) |
AuthCard | La mise en page des écrans publics : logo, titre, intro, contenu |
PasswordRules | Les règles de mot de passe cochées en direct |
Retour d'information
| Composant | Rôle |
|---|---|
Toast | Bandeau vert en haut pendant 4 s. Voir État global. |
Les graphiques : src/components/charts/
Dessinés directement en SVG, sans bibliothèque.
| Composant | Graphique |
|---|---|
BarChart | Heures par jour, avec la ligne de l'objectif |
LineChart | Heures par semaine, avec la ligne de l'objectif |
DoughnutChart | Anneau : part de l'objectif atteinte |
ChartCard | La carte autour d'un graphique (titre, sous-titre) |
Legend | La légende |
axis.tsx | Les libellés des axes |
Les composants métier
| Composant | Rôle |
|---|---|
clock/clock-button.tsx | Le bouton à maintenir. Voir Exemple complet : pointer. |
clock/day-timeline.tsx | La frise de 6 h à 20 h : travail en vert, pauses en sable |
dashboard-view.tsx | Le tableau de bord complet, pour soi ou pour un membre |
team/teams-list.tsx | La liste des équipes |
team/team-detail.tsx | Le détail d'une équipe : période, moyenne, membres |
team/member-records.tsx | Les absences et les semaines d'un membre |
navigation/tab-bar.tsx | La barre d'onglets |
profile-header.tsx | L'en-tête de Compte |
role-line.tsx | La ligne « rôle » sur la fiche d'un utilisateur |
Accessibilité
- Chaque élément cliquable a un
accessibilityRole(button,link,tab) et unaccessibilityLabelquand le texte ne suffit pas. - Les statuts ont toujours une icône et un texte, jamais la couleur seule.
- Le bouton de pointage peut être déclenché d'un double tap avec VoiceOver ou TalkBack.
- Les toasts sont annoncés par le lecteur d'écran.
- Les contrastes reprennent ceux validés sur le web (rouge
#b91c1cà 6,47:1).