Cet article traite de la création d'un composant Snackbar avec Riot, en utilisant le CSS Material Design BeerCSS, et de l'exécution d'une action lors des événements d'entrée et de sélection.
Avant de commencer, assurez-vous d'avoir une application de base Riot, ou consultez mes articles précédents.
Les Snackbars communiquent des messages en bas de l'écran, qui sont minimalement interruptifs et ne nécessitent pas d'action de l'utilisateur. Ils peuvent contenir une seule action, telle que "Annuler", "Ouvrir", ou "En savoir plus".
Base du Composant Snackbar
L'objectif est de créer une application Riot avec une Snackbar apparaissant lorsqu'un bouton est cliqué, et de la faire disparaître automatiquement lorsque l'action est cliquée.
Tout d'abord, créez un nouveau fichier nommé c-snackbar.riot dans le dossier des composants. Le préfixe c-
signifie "composant", une convention de nommage utile et une bonne pratique.
Écrivez le code suivant dans ./components/c-snackbar.riot
. Le HTML provient de la documentation BeerCSS et j'ai ajouté la syntaxe RiotJS pour la logique :
<c-snackbar>
<div class="
snackbar
{ props?.active ? 'active ' : null }
{ props?.top ? 'top ' : null }
{ props?.bottom ? 'bottom ' : null }
{ props?.error ? 'error ' : null }
{ props?.primary ? 'primary ' : null }
{ props?.secondary ? 'secondary ' : null }
{ props?.tertiary ? 'tertiary ' : null }
">
<i if={ props?.icon }>{props.icon}</i>
<span class="max"><slot></slot></span>
<a if={ props?.action } onclick={ clicked } class="inverse-link">{ props?.action }</a>
</div>
<script>
export default {
clicked (e) {
e.preventDefault();
e.stopPropagation();
this.root.dispatchEvent(new Event("action"));
}
}
</script>
</c-snackbar>
Source Code: https://github.com/steevepay/riot-beercss/blob/main/components/c-snackbar.riot
Expliquons le code :
- Les balises
<c-snackbar>
et</c-snackbar>
définissent une balise racine personnalisée, portant le même nom que le fichier. Vous devez l'écrire ; sinon, cela pourrait créer des résultats inattendus. Utiliser la balise<div></div>
comme balise racine ou redéfinir des balises HTML natives est une mauvaise pratique, donc commencer parc-
est une bonne convention. - Le message est passé en tant que balise Slot
<slot></slot>
, une fonctionnalité centrale de Riot.js permettant d'injecter des modèles HTML personnalisés dans un composant enfant depuis son parent. Dans notre cas, seule une chaîne est injectée, sans HTML. - Les Snackbars peuvent afficher un bouton permettant aux utilisateurs d'agir (Call to action) sur un processus effectué par l'application : Si l'attribut
props.action
existe, le message est affiché à l'intérieur du bouton d'action. -
Lorsque le bouton d'action est cliqué : L'événement
click
est capturé et exécute la fonctionclicked
pour émettre un événement personnalisé nommé action. - Pour afficher la Snackbar, elle doit contenir la classe active : lorsque l'attribut props.active existe, il ajoute la classe active grâce à l'expression :
{ props?.active ? 'active ' : null }
. - Différents styles sont disponibles pour le composant, par exemple, primary est appliqué si
props?.primary
existe et est vrai.
Enfin, chargez et instanciez le composant c-snackbar.riot dans une page principale nommée index.riot:
<index-riot>
<div style="width:600px;padding:20px;">
<c-button onclick={ () => openSnack("default") } inverse={ true }>Default</c-button>
<c-button onclick={ () => openSnack("error") } error={ true }>Error</c-button>
<c-button onclick={ () => openSnack("primary") } primary={ true }>Primary</c-button>
<c-snackbar
active={ state.active }
onaction={ close }
error={ state.error }
icon={ state.icon }
action={ state.action }
primary={ state.primary }
>
{ state.message }
</c-snackbar>
</div>
<script>
import cButton from "../components/c-button.riot"
import cSnackbar from "../components/c-snackbar.riot"
export default {
components: {
cSnackbar,
cButton
},
state: {
active: false,
icon: null,
message: null,
error: null,
timeout: null
},
openSnack(type) {
if (this.state.active === true) {
return;
}
this.update({
active: true,
message: type === 'error' ? "Something went wrong." : "Email Archived.",
action: type === 'error' ? "Contact Support" : "Undo",
icon: type === 'error' ? 'error' : 'check',
error: type === 'error',
primary: type === 'primary'
})
clearTimeout(this.state.timeout)
this.state.timeout = setTimeout(() => {
this.update({ active: false })
}, 3000)
this.update();
},
close () {
this.update({ active: false })
}
}
</script>
</index-riot>
Source Code: https://github.com/steevepay/riot-beercss/blob/main/examples/index.snackbar.riot
Détails du code :
- Le composant est importé avec
import cSnackbar from "./components/c-snackbar.riot";
puis chargé dans l'objet Riotcomponents:{}
. Un composantButton
est également chargé dans la page : lorsqu'un clic se produit, il affiche letoaster
avec un message personnalisé ! - Le composant snackbar est instancié avec
<c-snackbar />
dans le HTML. - L'état du composant, tel que
active
, est stocké dans l'objet Riotstate:{}
sous la propriété booléenne state.active. La propriété est passée en tant qu'attribut, comme :<c-snackbar active={ state.active } />
. Pour rendre le toaster complètement interactif, d'autres états sont stockés : le message, l'icône et le libellé de l'action. - Lorsqu'un bouton est cliqué, la fonction openSnack est exécutée grâce à onclick={ () => openSnack("default") }. Un type est passé en premier argument pour sélectionner le type de Snackbar, le message, l'icône et l'action. À la fin, le toaster est affiché en mettant à jour state.active sur vrai.
- Pour faire disparaître automatiquement le toaster, un timeout est créé pour masquer le Snackbar en mettant à jour
state.active
surfalse
après 2 secondes. - L'événement personnalisé action est surveillé avec
onaction
: si un clic déclenche l'action du Snackbar, la fonctionclose
met à jourstate.active
pour la faire disparaître.
Tests du Composant Snackbar
Il existe deux méthodes pour tester le composant Snackbar, et elles sont couvertes dans deux articles différents :
- Test avec Vitest et Riot-SSR dans un environnement Node
- Test avec Vitest dans un environnement JsDom
Conclusion
Voilà 🎉 Nous avons créé un composant Snackbar Riot en utilisant des éléments Material Design avec BeerCSS. Le code source est disponible sur Github : https://github.com/steevepay/riot-beercss/blob/main/components/c-snackbar.riot
Bonne journée ! Santé 🍻
Top comments (0)