Un composant sans tête est-il simplement un composant sans style, ou y a-t-il plus que cela ?
Le web sépare déjà le style du contenu en exigeant que les styles soient définis
en CSS au lieu de HTML. Cette architecture permet à chaque page web d'adopter une
norme de conception sans définir de styles spécifiques à la page.
À mesure que le Web évoluait vers une plate-forme d'applications, les développeurs cherchaient des moyens de créer
leurs bases de code croissantes plus maintenables. De nos jours, la stratégie de facto pour
organiser le code de l'application consiste à définir des composants petits et légers qui peuvent
être composés ensemble. Ainsi, le composant est devenu l'unité de composition dans
développement Web moderne.
Les composants définissent souvent à la fois leur HTML et leur CSS dans l'intérêt de l'encapsulation.
Même si cela les rend plus faciles à composer, ils peuvent être plus difficiles à composer
intégrer de manière cohérente dans un système de conception existant. C'est particulièrement vrai
pour les composants tiers importés de fournisseurs externes.
Les composants sans tête résolvent ce défi en réintroduisant une séparation entre
contenu et style. Cependant, maintenant, la séparation se fait le long de la limite du composant comme
opposé entre HTML et CSS. Ils sont essentiels pour créer un excellent composant sans tête
consiste à concevoir l'interface du composant de telle sorte qu'un développeur puisse
appliquer clairement et facilement leurs propres styles.
Dans le sens le plus élémentaire, un composant sans tête est simplement un composant sans style.
Les développeurs doivent être capables d'appliquer leur propre CSS aux éléments HTML que le
le composant définit.
Pour les composants simples, il peut simplement s'agir de transmettre le nom de classe
prop à l'élément racine afin que les développeurs puissent utiliser des sélecteurs de classe dans leur
CSS.
Si votre composant a la même sémantique qu'un élément HTML natif, vous pouvez utiliser
le type ComponentProps de React pour garantir que tous les accessoires pertinents sont
transmissible. N'oubliez pas d'omettre tous les accessoires dont vous ne voulez pas que l'utilisateur
votre composant pour pouvoir remplacer.
import { type ComponentProps } from 'react' function SubmitButton({ ...props }: Omit<ComponentProps<'button'>, 'type'>) { return <button type="submit" {...props} /> }
Pour les composants qui contiennent un ou plusieurs éléments enfants, les développeurs le feront probablement
je veux styliser chaque élément individuellement.
Une stratégie pour soutenir cela est de s'appuyer sur
Combinateurs CSS.
Par exemple, un composant de galerie sans tête pourrait avoir le style suivant :
/* Root container */ .gallery { } /* Gallery items container */ .gallery > ul { } /* Gallery item */ .gallery > ul > li { } /* Next and Previous buttons */ .gallery button { }
Mais cette approche crée un énorme problème car désormais la structure HTML interne de
le composant fait partie de son API publique. Cela vous évite de modifier le
structure plus tard sans potentiellement casser le code en aval.
Une meilleure stratégie consiste à prédéfinir des classes pour chaque élément enfant majeur. Par ici
les développeurs peuvent utiliser des sélecteurs de classe sans dépendre d'un code HTML particulier
structure :
.xyz-gallery { } .xyz-gallery-next-button { } .xyz-gallery-previous-button { } .xyz-gallery-items-container { } .xyz-gallery-item { }
Pensez à préfixer vos cours pour qu'ils n'entrent pas en conflit avec le
les propres styles du développeur.
Fournir des classes prédéfinies est peut-être le moyen le plus rapide de permettre aux développeurs de
stylisez votre composant. Cependant, un inconvénient de cette approche est que le
La structure HTML ne peut pas être personnalisée.
Cela n’a peut-être pas d’importance. Après tout, le HTML brut est déjà assez flexible dans sa manière de le faire
peut être rendu. Cependant, parfois, les développeurs recherchent du HTML supplémentaire pour obtenir
pour réaliser certaines conceptions. Si vous consultez le code source de presque tout
site Web, vous pouvez vous attendre à voir une multitude de
Vous pouvez prendre en charge de tels cas d'utilisation en divisant votre composant sans tête en
plusieurs composants liés. De cette façon, les développeurs sont libres d'ajouter les leurs
éléments de présentation au composant. Par exemple, un développeur pourrait intégrer le Next et
Boutons précédents de l'exemple de galerie dans un conteneur flexbox personnalisé :
<Gallery> <GalleryItems className='gallery-items-container'> {data.map((item) => ( <GalleryItem key={item.id}>{item.content}</GalleryItem> ))} </GalleryItems> <div className='gallery-buttons-container'> <GalleryPreviousButton> <GalleryNextButton> </div> </Gallery>
.gallery-items-container { } .gallery-buttons-container { display: flex; gap: 0.5rem; justify-content: flex-end; }
Ces types de composants sont généralement implémentés à l'aide
contexte à passer
données entre eux. Ils nécessitent plus de travail pour concevoir, mettre en œuvre et
document. Cependant, la polyvalence qui en résulte signifie souvent que l'effort supplémentaire est
ça vaut le coup.
Un petit nombre de cas d'utilisation nécessitent qu'un composant headless gère la mise en page
de ses composants enfants. Un exemple pourrait être une vue arborescente hiérarchique qui
permet de réorganiser ses éléments par glisser-déposer. Un autre cas d'utilisation pourrait être de
permettre aux applications d'une seule page de remplacer l'élément d'ancrage par défaut par un
composant de lien personnalisé qui facilite le routage côté client.
An advanced strategy for allowing developers to define custom layouts is to
allow the actual child component being rendered to be overriden via props:
<TreeView nodes={[...]} components={{ CustomRow, CustomDragPreview: (props) => <div className="drag-preview" {...props} /> }} />
This grants the developer full control over what is rendered in each child
component, while allowing the headless component to manage its overall
structure.
You can even allow developers to customise the root element of your component
via a prop. For example, this button component allows a developer to render it
as something else:
import { type ElementType } from 'react' function HeadlessButton({ as, ...props }: { as?: ElementType }) { const Component = as ?? 'button' return <Component {...props} /> }
For example, in order for assistive technology to treat the button like a link,
the developer can specify that an anchor element should be used to render the
button:
<HeadlessButton as="a">Actually a link</HeadlessButton>
Headless components are much more than components that don't contain any
styles. Great headless components are fully extensible and allow the developer
to customise the entire internal HTML structure.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!