- Jelly UI v1.1 est une bibliothèque de composants Web sans dépendances qui combine de vrais contrôles de formulaire avec des effets de physique soft body souples, et propose 40 éléments personnalisés
- L’installation se fait avec un seul script de module et prend en charge le mode sombre, le suivi automatique du thème du système d’exploitation, le changement de couleur d’accentuation et les dispositions RTL de droite à gauche
- Les boutons utilisent un
<button>natif, les sliders s’appuient sur une entréerangemasquée afin de conserver une sémantique native pour le clavier, les lecteurs d’écran et la participation aux formulaires - Des cases à cocher et champs de saisie jusqu’aux toasts, onglets et boîtes de dialogue, divers éléments appliquent des animations tactiles comme l’écrasement, l’étirement, les ondulations ou le rebond
- Avec des tokens de couleur WCAG AA et des patterns ARIA intégrés, il est possible de construire des interfaces produit accessibles tout en conservant des effets visuels fluides
Installation et thème
- Jelly UI peut s’utiliser sans dépendances, avec 40 éléments personnalisés et une seule balise
<script type="module"><script type="module" src="https://jelly-ui.com/package.js"></script> <jelly-theme mode="auto"> <jelly-button variant="mint">Publish</jelly-button> </jelly-theme> <jelly-theme>est un fournisseur de thème qui applique des design tokens à un sous-arbre donnémodeprend en chargeauto,light,dark, pour suivre les réglages du système ou forcer un thème précisaccentpermet de redéfinir la couleur d’accentuation
- Les variantes de couleur communes sont
azure,rose,amber,mint,graphite,platinum,white, et les tailles sont principalementsmall,medium,large
Boutons et éléments d’action
<jelly-button>est un bouton encapsulé qui inclut un vrai<button>natif en interne pour prendre en charge le clavier et les lecteurs d’écran- Il permet de configurer la couleur, la taille, les formes
pilletsquare, ainsi que l’état désactivé et la disposition en bloc
- Il permet de configurer la couleur, la taille, les formes
<jelly-icon-button>est un bouton carré ou circulaire conçu pour une seule icône- L’attribut
labeldéfinit le nom reconnu par les lecteurs d’écran
- L’attribut
Contrôles de saisie de formulaire
<jelly-checkbox>participe au formulaire, prend en chargecheckedet l’état indéterminé (indeterminate), et le carré gélatineux rebondit quand l’état change<jelly-input>est un champ de saisie sur une ligne pourtext,email,password- Quand il reçoit le focus, sa surface se soulève et une bordure apparaît, et une ondulation se propage depuis la position du curseur à chaque saisie
- Il prend en charge
disabledetreadonly
<jelly-label>se relie au contrôle viafor- Un clic donne le focus à la cible et le texte du label devient le nom accessible ; il est possible d’indiquer si le champ est requis ainsi que sa taille
<jelly-otp>est un champ de code à usage unique avec une case par chiffre- Il gère la saisie, le retour arrière, les touches fléchées et le collage, et permet de définir la longueur, la couleur, la taille et l’état désactivé
<jelly-radio>forme un groupe avec les éléments partageant le mêmenameà la même racine- Il prend en charge une navigation au clavier avec les flèches via
tabindexmobile en tenant compte de la direction du document
- Il prend en charge une navigation au clavier avec les flèches via
<jelly-radio-group>est un conteneurradiogroupétiqueté pourjelly-radio- Il fournit une légende, une disposition horizontale ou verticale, et la transmission de la taille aux éléments enfants
<jelly-range>est un slider à double poignée pour choisir une plage entre une valeur minimale et maximale- Les deux poignées utilisent
role="slider", le focus et ARIA, et les poignées gélatineuses s’écrasent pendant le glisser-déposer
- Les deux poignées utilisent
<jelly-segmented>est une piste en forme de pilule contenant des choix mutuellement exclusifs- L’indicateur de sélection se déplace entre les segments sous la forme d’une pilule gélatineuse qui s’incline et s’étire
<jelly-select>est une liste déroulante liée au formulaire qui utilise les patterns ARIAcomboboxetlistbox- Le déclencheur comme le panneau d’options sont tous deux composés de surfaces soft body
- Le panneau se déploie depuis le champ et, s’il manque de place en dessous, bascule vers le haut
<jelly-slider>est un slider pour sélectionner une valeur unique- Une entrée
rangenative masquée assure la sémantique et la participation au formulaire, tandis qu’une poignée gélatineuse écrasable est affichée à l’écran
- Une entrée
<jelly-switch>est un interrupteur glissable dont la poignée s’étire comme une goutte liquide, tandis que les couleurs des états on et off se croisent en transition<jelly-textarea>grandit automatiquement entre une hauteur minimale et maximale selon la saisie multiligne- La surface s’étire aussi pour suivre la hauteur, une ondulation naît à la position du curseur pendant la saisie, et
disabledainsi quereadonlysont pris en charge
- La surface s’étire aussi pour suivre la hauteur, une ondulation naît à la position du curseur pendant la saisie, et
États et retours visuels
<jelly-alert>est une bannière proposant quatre tonalitésinfo,success,warning,danger, ainsi qu’un bouton de fermeture optionnel<jelly-badge>est un petit élément utilisé pour les badges, tags et indicateurs d’état, qui rebondit quand le texte change- Il permet de configurer les styles plein et contour, les formes pilule et carrée, ainsi que les comportements
liveetinstant
- Il permet de configurer les styles plein et contour, les formes pilule et carrée, ainsi que les comportements
<jelly-progress>est une barre de progression dont l’avant du remplissage vacille au fur et à mesure de l’avancement- En mode indéterminé, une masse rebondit entre les deux extrémités
<jelly-skeleton>est un placeholder de chargement qui oscille doucement comme une respiration, plutôt qu’avec un effet scintillant- Il prend en charge les formes
line,rect,circle
- Il prend en charge les formes
<jelly-spinner>fournit un indicateurdotsen forme de masse visqueuse qui se déplace entre trois points, ainsi qu’un indicateurblobqui tourne en changeant de forme<jelly-toaster>gère des notifications toast qui apparaissent puis disparaissent depuis la direction de fin en ligne- Il s’utilise généralement via le helper
jellyToast('Saved!', { tone: 'success' }) - Si l’élément placé reçoit
position="bottom", la pile de notifications grandit vers le haut
- Il s’utilise généralement via le helper
Surfaces de contenu
<jelly-accordion>regroupe plusieurs éléments<jelly-collapsible>- En mode
single, quand un élément s’ouvre, les autres se referment en rebondissant
- En mode
<jelly-card>est un conteneur à surface gélatineuse placé sous le contenu- En ajoutant
squish, il s’écrase comme un coussin souple et agit comme un bouton
- En ajoutant
<jelly-chip>peut servir de label statique, de filtre activable ou de tag supprimable- Il permet de définir si l’élément est sélectionnable, sélectionné, supprimable ou désactivé
<jelly-collapsible>est une zone dépliable/repliable dont le panneau s’ouvre et se ferme avec un rebond via un bouton d’en-tête- Elle est conçue pour que la surface bouge, et non le texte
<jelly-divider>est un fin séparateur horizontal, vertical ou avec label<jelly-kbd>est une touche gélatineuse sur laquelle on peut appuyer visuellement- Si elle est liée à une vraie touche via
key, la touche s’enfonce aussi tant que cette touche est pressée n’importe où sur la page
- Si elle est liée à une vraie touche via
Navigation et mise en page
<jelly-resizable>est une grille de panneaux redimensionnable en faisant glisser un séparateur gélatineux ou au clavier- Elle prend en charge les directions
row,vertical,both
- Elle prend en charge les directions
<jelly-tabs>est une vue à onglets utilisant une vraie sémantiquetablist- L’indicateur de sélection en forme de pilule gélatineuse se déplace et les panneaux d’onglet apparaissent avec un rebond
Overlays
<jelly-dialog>est une boîte de dialogue modale qui apparaît avec un rebond gélatineux- Elle verrouille la page et rend le focus à sa position précédente après fermeture
- Elle peut être fermée avec la touche Escape, le bouton de fermeture ou un clic sur l’arrière-plan
<jelly-drawer>est un panneau flottant qui apparaît avec un effet de ressort en dépassant légèrement avant de revenir- Il peut s’ouvrir depuis le début en ligne, la fin en ligne ou le bas
<jelly-popover>est un panneau non modal qui s’ouvre au clic- Il est ancré au déclencheur et se ferme avec la touche Escape ou un clic extérieur
- Il prend en charge les positions
top,bottom,start,end
<jelly-tooltip>affiche une bulle thémée au-dessus du déclencheur au survol ou lors de la prise de focus au clavier- Il prend en charge quatre directions de placement et trois tailles
1 commentaires
Avis sur Hacker News
La fenêtre semblait un peu saccadée, alors j’ai creusé la cause : cette bibliothèque exécute une boucle d’animation
requestAnimationFrame(RAF) toutes les 8 ms sur tous les composants de la page et redessine l’ensemble du documentLe commentaire ci-dessus, « traiter ensemble les composants actifs dans une frame et s’arrêter à l’état inactif », semble lui aussi généré par une IA.
JellyEnginene calcule pas l’animation jelly uniquement lors des événements de pointeur ; il recalcule à chaque frame tous les composants actifs de la page. C’est le genre d’implémentation dont on se dit généralement : « il ne faut pas faire ça, c’est excessif »Set()actif et les retire une fois le mouvement arrêtéJe suis d’accord pour dire que le commentaire a l’air vaguement généré par IA, mais je n’ai pas trouvé de problème évident dans l’approche elle-même, et quand rien ne se passe, la boucle principale se termine en quelques microsecondes
J’aime bien, mais cela ne semble pas conforme aux pratiques UX standard
Si on maintient le clic puis qu’on déplace la souris hors de l’élément, cela ne devrait pas être considéré comme un clic. Actuellement, les boutons le comptent comme un clic, mais pas les cases à cocher, ce qui manque de cohérence
C’est sincèrement adorable, et j’aime aussi le fait que la fonctionnalité se réduise naturellement avec
@media (prefers-reduced-motion: reduce)En revanche, sur le site de démo, ce serait bien de permettre à l’utilisateur de passer outre sans modifier les réglages système, ou au moins d’afficher un message indiquant que les animations ne s’affichent pas
À chaque fois qu’une démo sympa comme celle-ci sort, il me faut un moment pour me souvenir de ce réglage, et entre-temps je clique en étant déçu, à me demander : « qu’est-ce qu’elle a de spécial ? »
Plus jeune, j’aurais adoré, mais aujourd’hui je passe plus de temps à retirer ce genre d’effets avec une feuille de style locale ou à utiliser le mode sombre et le mode lecture. Les temps ont bien changé
Ce serait bien d’avoir aussi un effet léger au survol. Certains contrôles, comme la barre de progression et les toasts, semblent ne pas avoir d’effet jelly
Les performances de la page de démo ne sont pas terribles non plus et j’ai l’impression qu’elle détourne le défilement, mais dans l’ensemble c’est mignon et ça irait bien à une UI de jeu
L’élément
Chipdevrait rester en place pendant la transition, mais quand on clique dessus il sort de ses limites, ce que je n’aime pasC’est mignon, mais la réactivité de certains contrôles est vraiment mauvaise. Si on fait glisser le curseur du slider d’avant en arrière, il est largement à la traîne par rapport au pointeur alors qu’il devrait le suivre comme s’il y était collé
En revanche, d’autres contrôles comme
jelly-resizablesuivent bien le curseur. Le contrôle"Placeholder"semble ne pas faire disparaître le texte indicatif quand on clique dessusJe me demande si quelqu’un se souvient d’un effet jelly similaire sur les bordures de page du site, du blog ou de la vitrine de Paul Neave vers 2007-2010. À l’époque, c’était fait en Flash
Paul Neave était un héros personnel à cette époque, et s’il lit ceci, j’espère qu’il va bien
J’ai du mal à trouver quoi que ce soit qui ressemble vraiment à des effets physiques dans ce système de design UI
C’est peut-être lié à mon type de daltonisme ou aux réglages de mon écran, mais le rouge et l’ambre se ressemblent trop et je n’arrivais même pas à distinguer si j’avais appuyé sur le bouton