React sans create-react-app, suite

L’application de base Hello World! montrée dans l’article précédent fonctionne sans problème. Je change l’application App.js en ajoutant un composant tout prêt : React Color, une collection de composants React de type color pickers.

L'acropole d'Athènes au coucher du soleil, une capture d'écran de l'application et les textes React et color picker

Package react-color

On ajoute le package react-color.

La version ajoutée est la dernière 2.19.3.

On peut maintenant ajouter des color pickers dans l’application.

Exemple 1

Je change le code de App.js pour utiliser le composant SketchPicker :

On lance le live reload : yarn start

Cela compile bien, on se connecte à l’adresse http://xxx.xxx.xx.xx:2802/ dans un navigateur.

Pour obtenir une couleur précise au démarrage, on ajoute l’attribut color au composant SketchPicker : color="#07020802".

On obtient un joli color picker, la couleur #07020802 (violet) est présélectionnée. Le composant est englobé dans une division <div> portant la classe wrapper

Color picker, style photoshop. La couleur violette #07020802 est présélectionnée

Mais le curseur ne change pas de position sur le picker. J’ai eu beau chercher à résoudre ce problème, mais cela ne fonctionnait toujours pas. Pour être convaincu que je faisais quelque chose de travers, j’ai changé de version. La version installée était la dernière 2.19.3, je l’ai changée pour la 2.17.3.

Et là, oh miracle, le curseur bouge. Pour choisir la version, je suis allé sur page npm de react-color, et j’en ai choisi une assez téléchargée, je l’ai prise un peu au hasard mais la dernière version mineure d’une version majeure.

Et je me dis que peut-être la première installation s’était mal déroulée, et je réinstalle la version 2.19.3.

Eh non, même les curseurs des autres pickers ne fonctionnent pas non plus. Je repends la 2.17.3. Et là, cela fonctionne nickel.

Il y a quelque chose de surprenant là-dedans, je creuserai plus tard. Cela ne doit vraisemblablement être grand chose, mais bon… Sûrement, mon application doit prendre en charge le changement de couleur et l’appliquer à tous les pickers.

C’est bien cela, je repasse en version 2.19.3 et j’ajoute les props color et onChangeComplete pour prendre en charge le changement de couleur, et je définis la fonction de retour handleColorChange(e) :

Avec une fonction

J’essaie l’exemple 1 en définissant App à l’aide d’une fonction. Peut-être que le problème vient de là, ce serait étonnant, mais on ne sait jamais.

Je remplace App.js.

J’en profite pour écrire dans la console l’état de l’objet color. Cela se comporte encore très bien.

J’essai avec la dernière version. Et non, le curseur ne se déplace plus. L’objet json est cependant bien écrit dans la console.

Exemple 2

Je choisis d’ajouter plusieurs pickers que l’on mettra en forme. J’aime assez SketchPicker, SwatchesPicker et CirclePicker. Pour cela, on utilise l’écriture des styles avec SASS scss, il faut ajouter des packages pour que Babel et Webpack puissent transpiler les sources.

Configurer SCSS pour Webpack

  • sass : permet à Node d’utiliser DartSass, un compilateur Sass, node-sass, qui était précédemment utilisé a été déprécié,
  • sass-loader : permet à Webpack le chargement des SCSS pour les compiler,
  • style-loader : injecte le style dans le DOM, déjà installé,
  • css-loader: interprète les fichiers importés avec @import et @url() et retrouve leur chemin resolve, déjà installé,
  • mini-css-extract-plugin : extrait les styles du bundle JavaScript dans un fichier séparé, essentiel pour les versions de production.

Par défaut, Webpack intègre le style compilé dans le bundle JavaScript main.js. Cela fonctionne très bien pour les versions de développement. Pour la production, on utilisera le plugin Mini CSS Extract.

On change la configuration Webpack webpack.config.js

On reprend l’exemple 2. On ajoute les composants SketchPicker, SwatchesPicker et CirclePicker à l’application App.js, on en profite pour définir l’application avec une classe :

Le render() retourne un élément <div> parent des composants. On utilise className pour le nom de classe de la division, cela évite que Babel s’emmèle avec l’instruction class. Si l’on avait voulu retourner les composants pickers, les uns à la suite des autres sans utiliser de division parente, il aurait fallu employer le composant invisible Fragment de React que l’on importe en déstructurant. On importe par la même occasion Component.

On définit le fichier style.scss dans le répertoire scss. Je prévois un répertoire pour les styles car quand l’application s’etoffera, j’aurai un dossier pour regrouper les fichiers scss. On importe ensuite ./scss/style.scss dans l’application.

Exemple 3

On affichera un texte dans une division en choisissant la couleur et l’opacité du texte, ainsi que le fond background de la <div>. Ainsi, j’aurai un outil pour choisir les couleurs de mon éditeur syntaxique Sublime Text. Je rajouterai aussi le choix de la police de caractères.

Les noms des composants React doivent respecter l’écriture PascalCase, ils commencent par une majuscule et le début de chaque mot est en majuscule. Les éléments HTML sont en minuscules.

Je choisis d’appeler mon composant Preview.js que je crée dans un répertoire components dans src. Je choisis d’employer le composant Select de react-select que l’on installe.

Et l’on écrit le composant Preview.js :

Le changement de valeur de l’option du Select est pris en charge dans la méthode handleSelectChange(option) qui appelle une méthode de App.js pour changer l’état dans l’application. L’état de l’application sera objet contenant la valeur sélectionnée par le Select, la couleur du texte, la couleur du fond et la couleur courante (sélectionnée par l’un des pickers). La liste permet de voir que les couleurs changent lorsque l’on sélectionne une couleur et un champ d’application : le fond de la div ou la couleur du texte. App.js s’écrit ainsi, en changeant l’état en fonction de la valeur sélectionnée dans le Select :

L’exemple fonctionne. Je supprime la liste et j’applique un style online dans Preview.js à la division de prévisualisation, en fonction des valeurs de backgroundcolor et textcolor héritées de l’application :

React prop contentEditable

J’aimerai que l’utilisateur puisse changer le texte de la div preview. Si je change la prop contentEditable à true, React écrit dans la console :

Cela signifie que React n’a pas le contrôle du contenu, il faut donc s’assurer que ce qui est fait n’aura pas de mauvaise influence sur le code. Ce qui est notre cas, puisque la chaîne de caractères que pourra entrer l’utilisateur ne déclenche aucune action. Pour supprimer cet avertissement, il suffit de rajouter suppressContentEditableWarning dans les props de la div.

Dans des cas plus sophistiqués, il faudra contrôler l’entrée dans une action déclenchée par onChange.

Contrôle de la transparence alpha

Je souhaite aussi ajouter le réglage de la transparence alpha. La valeur color envoyée en argument lorsque la couleur change dans un picker est un objet de la forme :

La transparence est traitée à partir de la variable rgb.a dans les composants de React Color. Je change donc la méthode handleColorChange(val). L’objet val.rgb sera bien prise en compte dans les pickers, mais pas dans mon composant Preview. Je vais donc convertir cet objet val.rgb en couleur hexadécimale, avec les deux derniers caractères pour la transparence, puisque cela est compatible avec les dernières versions des navigateurs. Pour cela, j’écris la fonction de conversion RGBA2HexA que l’on utilisera pour affecter les variables textcolor et backgroundcolor.

On utilise cette méthode dans la méthode handleColorChange(color) et l’on ajoute le picker AlphaPicker pour bien régler la transparence. Apps.js devient :

Il ne reste plus qu’à mettre en forme la liste des couleurs du texte et du fond et d’ajouter un bouton pour copier la valeur correspondante dans le clipboard. On ajoute donc cela à Preview.js.

Copy to clipboard Presse_papier

Pour copier dans le presse-papier clipboard, que l’on soit en http ou https (lorsque l’objet navigator est disponible), le mieux est d’écrire la valeur à copier dans un élément de type input text ou textarea, d’utiliser la méthode select() et d’exécuter la commande copy sur le document.

Si l’on est sûr d’être en https, l’utilisation de l’objet navigator, avec la propriété clipboard et la méthode writeText() est possible.

J’écris donc un nouveau composant Input2Clipboard, dans le répertoire src/components et je l’utiliserai dans Preview.js. Les couleurs sont écrites dans un input readOnly et j’ajoute un icone J qui servira de bouton. Lorsque la copie est effectuée, le bouton est suivi pendant timeout millisecondes par la chaîne textCopied. On peut définir dans les props du composant textCopied, timeout et la couleur de l’icone iconFill. Bien-sûr, on peut penser à rajouter d’autres props, pour le moment cela me convient.

Si la page est servi en https, on peut utiliser navigator.clipboard.writeText(), sinon il faut sélectionner l’élément et lancer la commande copy, c’est pour cela que je choisis d’écrire la couleur dans un input. Il faut ensuite désélectionner la selection. Cela va assez vite pour que le processus ne soit pas visible par l’utilisateur.

Je modifie, complète le style scss :

J’utilise le composant créé dans Preview.js :

Et hop, on dispose de plusieurs color pickers pour sélectionner et copier les couleurs, en tenant compte de la transparence. Pratique pour concevoir un Color Scheme pour Sublime Text. Dans l’article suivant, on construit build l’application pour la production, utilisable dans une page html.

Soumettre un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables.