Contribuer à ui-layouts

Une correction de documentation fusionnée sur ui-layouts, une bibliothèque de composants React et Tailwind à plus de 3 600 étoiles, et ce qu'un contributeur en retire.
- Rôle
- ContributeurContribution open source
- Période
- déc. 2024
Brouillon
Cette page est publiée, mais certaines parties attendent encore confirmation.
Contexte et problème
Périmètre de cette page
Cette page documente une seule pull request fusionnée dans une bibliothèque maintenue par d'autres personnes. Les étoiles et les forks appartiennent au projet. Je la mentionne parce que le travail est public et facile à vérifier, et parce que le raisonnement derrière un petit changement est le même que celui que j'applique aux grands.
ui-layouts est une bibliothèque de composants open source pour React et Next.js, publiée par l'organisation ui-layouts et menée par son auteur, naymurdev. La description que le projet donne de lui-même, reprise par l'ancienne version de mon site, le présente comme des composants interactifs gratuits construits sur Tailwind CSS, avec Framer Motion et GSAP pour l'animation. Le site, ui-layouts.com, se qualifie de « Your Frontend Universe » : des composants à tendance créative, du genre qu'une équipe produit veut déposer dans une landing page sans écrire elle-même le code d'animation.
En décembre 2024, j'ai ouvert une pull request sur la page de documentation du composant spotlight cards, ce type de carte dont le halo suit le pointeur. Le titre de la pull request énonce son périmètre : corrections d'orthographe et de TypeScript. Des fautes d'orthographe, dans une bibliothèque vendue sur sa finition visuelle, coûtent de la confiance. Et un extrait TypeScript qui a besoin d'être corrigé est un extrait que le lecteur emporte dans son propre projet quand il le copie.
Le second problème est celui qui compte. Pour les bibliothèques de cette famille, la page de documentation est souvent aussi le mécanisme de livraison : on lit la page, on copie la source, on la colle dans sa base de code. Quand une bibliothèque est distribuée ainsi, il n'y a aucune version de paquet à figer et aucune étape de build entre l'auteur et vous. Une erreur de typage dans cet extrait atteint chaque lecteur qui le copie, et plus les réglages du compilateur du lecteur sont stricts, plus vite elle mord. La correction est triviale une fois qu'on la voit. Le coût de la laisser est payé par chaque visiteur.
Contraintes
J'étais invité dans le dépôt de quelqu'un d'autre. L'auteur détient l'autorité sur le design et la feuille de route (350 commits en septembre 2026, contre mon seul commit), donc la contribution utile était celle que le mainteneur pouvait relire en quelques minutes, sans ouvrir de discussion sur le design. Cela excluait tout remaniement du composant lui-même.
Les corrections devaient conserver la voix et les conventions de l'auteur. Une correction de documentation qui réécrit la prose à mon goût est un fardeau pour le relecteur et une perte pour le projet. Je me suis limité à ce qui était objectivement faux : l'orthographe, et le TypeScript à corriger.
MDX ajoutait une contrainte à part. Le code à l'intérieur d'un bloc délimité est du texte brut pour le compilateur du site de documentation, donc rien ne prévient personne quand il cesse d'être du TypeScript valide. La seule vérification est un humain qui le lit avec un compilateur dans la tête, ou qui le colle dans un éditeur avec les vérifications strictes activées. Avant qu'une PR de ce genre parte, l'extrait a sa place dans cet éditeur.
Mon rôle précis
Contributeur. J'ai forké ui-layouts/uilayouts, fait les corrections dans Spotlight-cards.mdx sur le fork, et ouvert la pull request #17, intitulée « Spotlight-cards.mdx updated with spelling and typescript corrections ». GitHub la date du 2024-12-20, et elle a été fusionnée. Le dépôt me liste parmi ses huit contributeurs avec ce seul commit.
Je n'ai pas écrit le composant spotlight cards, ni aucun autre composant de la bibliothèque. D'après ce que montre le dossier public, je ne suis ni mainteneur ni titulaire de droits d'écriture, et je n'ai pas pris part aux décisions du projet. Tout ce qui est visuel sur ui-layouts.com est le travail de l'auteur et des autres contributeurs.
Décisions clés et compromis
Corriger la documentation, laisser le composant tranquille
L'alternative aurait été une PR plus large touchant la source du composant, par exemple pour resserrer ses types de props à l'origine. La PR est restée dans la documentation. Un changement sur le composant affecte tous ceux qui l'ont déjà copié et demande l'accord de l'auteur sur l'API ; une relecture de cinq minutes devient une conversation de design. Le coût : un impact visible plus petit, et si le même problème existait dans la source du composant, il y est resté.
Une PR, un fichier, deux types de correction
J'aurais pu séparer l'orthographe et le TypeScript en deux PR, ce qui est plus propre en théorie. Elles sont parties ensemble parce que le titre nomme un seul fichier et que deux PR sur une même page, venant d'un nouveau contributeur, passent pour du bruit. Le coût : le relecteur alterne entre prose et code dans un même diff. Sur une seule page de documentation, c'est acceptable. Sur une surface plus grande, je séparerais.
Écrire les extraits de documentation pour le mode strict
Je ne vais pas exagérer ce que contenait une PR d'un seul fichier ; les corrections exactes sont dans le diff. Le principe derrière toute correction TypeScript dans une documentation est pourtant le même. Quand un extrait type un gestionnaire d'événement ou une ref de façon lâche, il fonctionne dans un projet avec strict: false et casse dans un projet avec strict: true. La bonne cible est le projet strict, parce que c'est là que vit le lecteur qui se soucie des types, et que le projet lâche accepte de toute façon le code plus strict. Une version générique de la forme que je vise dans ce type de composant ressemble à ceci. Elle est écrite pour cette page et illustre seulement le motif ; elle ne reproduit pas le diff de la PR :
import { useRef, type MouseEvent, type ReactNode } from 'react';
interface SpotlightCardProps {
children: ReactNode;
className?: string;
}
export function SpotlightCard({ children, className }: SpotlightCardProps) {
const ref = useRef<HTMLDivElement>(null);
function handleMouseMove(event: MouseEvent<HTMLDivElement>) {
const el = ref.current;
if (!el) return;
const rect = el.getBoundingClientRect();
el.style.setProperty('--x', `${event.clientX - rect.left}px`);
el.style.setProperty('--y', `${event.clientY - rect.top}px`);
}
return (
<div ref={ref} onMouseMove={handleMouseMove} className={className}>
{children}
</div>
);
}Typer le gestionnaire en MouseEvent<HTMLDivElement> et la ref en useRef<HTMLDivElement>(null) est ce qui permet à strict d'accepter la vérification de null et l'accès à clientX sans transtypage. Le compromis, c'est la verbosité sur une page censée paraître légère. J'accepte les mots en plus : un extrait qui compile vaut plus qu'un extrait qui se lit bien.
Préserver le ton de l'auteur
Une phrase maladroite mais correcte reste telle quelle. Ne corriger que ce qui est faux garde la PR relisible et respecte le fait que la documentation a un propriétaire. Le coût : des phrases que je formulerais autrement restent dans les mots de l'auteur.
Travailler depuis un fork
Standard pour une première contribution, et cela a gardé le dépôt du mainteneur libre de branches parasites. Le fork existe toujours sous mon compte comme copie de travail, avec un dernier push daté du 2025-02-21 ; personne ne devrait le lire comme une variante maintenue de la bibliothèque.
Ce que j'ai livré
Le livrable est petit et public : la pull request #17 sur ui-layouts/uilayouts, datée du 2024-12-20 et fusionnée, contenant le Spotlight-cards.mdx corrigé, orthographe réparée et TypeScript corrigé, comme le dit le titre. Un commit, un fichier nommé dans le titre.
À côté, un fork sous mon compte GitHub qui a servi de copie de travail pour la branche.
Une fois fusionnée, la page corrigée est ce que reçoit chaque lecteur suivant. C'est tout l'intérêt d'une correction de documentation : elle atteint chaque lecteur aussi longtemps que la page existe.
Résultats et chiffres
Chiffres publics, relevés le 28 septembre 2026 :
Les étoiles sont celles du projet, gagnées par son auteur et par les personnes qui ont construit les composants. Je les cite pour mesurer l'audience qu'atteint une correction de documentation, et pour aucune autre raison. Le 2026-09-28, le dépôt comptait aussi 214 forks et huit contributeurs sous licence MIT, avec une date de création au 2024-08-11 et un dernier push le 2026-08-23 : la bibliothèque était donc toujours active vingt mois après ma contribution.
Pour ma part, le chiffre est un : une pull request fusionnée et rien en attente. Il n'existe aucune métrique du nombre de lecteurs qui ont évité une erreur de compilation grâce à elle, et je n'en inventerai pas.
Ce que je ferais différemment
J'aurais cherché avec grep le même motif de typage dans les autres pages MDX avant d'ouvrir la PR. Une correction qui s'applique à une page d'un ensemble de documentation s'applique en général à plusieurs, et une PR de suivi qui les couvre aurait valu plus pour le mainteneur que la première.
J'aurais proposé, dans une issue d'abord, une petite vérification CI qui extrait les blocs tsx délimités de la documentation et les passe dans tsc --noEmit --strict. C'est quelques dizaines de lignes de script, et cela change une classe de bugs de documentation en une vérification qui passe au rouge plutôt qu'en une mauvaise après-midi pour un lecteur.
J'aurais aussi été plus clair, plus tôt, sur mon rôle sur mon propre site. La version précédente de ce portfolio listait ui-layouts parmi mes projets sans dire ce que j'y avais fait. Cette page est la correction : la bibliothèque est la leur, la contribution est la mienne, et les deux méritent d'être nommées séparément.