Rencontre avec Polymer : un radial menu

Informatique
5 juillet 2016 par Eric Taix
Pas de commentaires sur cet article

Rencontre avec Polymer

Cette année, 9 développeurs sont partis à  DevoxxFR. Certains ont suivi une conférence sur Polymer avec Horacio Gonzalez (lien sur vidéo du talk) et ils nous ont fait une restitution en quelques minutes qui m’a donné envie de tester ce framework.

Le sujet

L’idée originale vient de notre UX Designer Laurent, qui nous avait fait rapidement la conception d’un menu radial il y a quelques temps : un simple bouton qui dévoile des sous-menus lorsque l’on clique dessus. C’est typiquement un bon choix de sujet : partir d’une idée de composant réutilisable et le polymériser…

Polymer : Les bases

Polymer c’est avant tout un développement orienté composant (appelé « Element »). Le but est de définir ses propres balises comme on pourrait le faire avec une directive AngularJS.
Cela fait tellement partie de la philosophie de Polymer que même le contenu de votre index.html est un élément : <skill-app>

Et oui c’est tout ! Un script qui contient la base pour les webcomponent et un import pour votre élément principal et c’est tout !

Création d’un élément, le itk-radial-menu

La création d’un élément n’est pas plus compliqué !

radial-menu

Tout élément Polymer comporte les éléments suivants:

1- L’import vers Polymer
2- La balise dom-module qui définit les contours de l’élément ainsi que son ID (l’ID doit être formé de la façon suivante <prefix>-<nom de l’élément>)
3- Un template (le code HTML ainsi que le style du composant)
4- Le code JavaScript du composant dans lequel est rappelé l’ID de l’élément

Les propriétés de l’élément

D’un point de vue fonctionnel, cet élément a besoin des propriétés suivantes:
1- D’un rayon sur lequel vont s’afficher les sous-menus
2- D’un angle de départ et d’un angle de fin (les sous-menus seront répartis selon ces 2 angles)
3- D’une liste de sous-menus (avec un icon et un titre)

Pour définir une propriété avec Polymer il faut rajouter l’attribut « properties » et définir chacune des propriétés:

Chaque propriété définit :
1- Son type : Number, String, Array, Object, Boolean
2- Sa valeur par défaut (optionnel)
3- Et d’autres choses comme par exemple un observer qui sera appelé à chaque modification de valeur (optionnel)

Tips: ATTENTION aux objets de type Array ou Object. Javascript utilise des références.
Typiquement si vous initialisez items  de la façon suivante : 

Alors toutes les instances de type itk-radial-menu vont partager le même tableau : il s’agira d’un singleton. Pour éviter cela il faut définir une fonction qui renvoie un nouveau tableau à chaque appel.

 

Les propriétés sont des caractéristiques dont on peut fixer la valeur à l’extérieur du composant. Ainsi lors de son utilisation du composant, il nous sera possible d’écrire (par convention une propriété en CamelCase est accessible à l’extérieur en utilisant le caractère ‘-‘ lorsqu’une majuscule est présente) :

Ici on fixe les valeurs sAngle et eAngle et on les passe aux propriétés start-angle et end-angle du composant. On notera la notation [[sAngle]] qui signifie que même si le composant itk-radial-menu modifie cette valeur, on ne souhaite pas répercuter ce changement dans sAngle. Si j’avais utilisé {{sAngle}}, un changement de valeur dans le composant aurait répercuté la valeur dans startAngle.
La propriété radius est utilisée avec une valeur constante. Quant à la propriété items c’est un tableau d’objets JSON qui est utilisé.

Le code HTML

Simple comme code ! Non ?

En fait il s’agit tout simplement d’une boucle ( is="dom-repeat" ) sur la propriété « items ». A l’intérieur du template, chaque élément sera accessible via la variable « menu » ( as='menu" ). Il est possible d’utiliser les attributs de la variable via la « notation « dot » (ie {{menu.title}} ).

Le code HTML utilise 2 tags non standards : paper-fab  et paper-icon . Il s’agit d’éléments prêts à l’emploi dans le catalogue de Polymer.
Pour pouvoir utiliser un élément externe (du catalogue Polymer ou d’ailleurs), il suffit d’installer l’élément dans son projet

Puis d’importer l’élément dans sa page

Méthodes de l’élément

Déclarer une méthode sur un composant est aussi simple que rajouter une fonction dans le code Javascript de l’élément

Par convention il est bien de spécifier les méthodes dites privées avec un ‘_’. Cette méthode permet de calculer la position des sous-menus en fonction du rayon et des 2 angles définis de façon dynamique en fonction de chaque élément. Elle est appelée dans le code HTML en se servant d’une variable toujours à disposition dans les templates dom-repeat : « index ».

Ouverture du menu

Notre élément commence à prendre forme mais les items du sous-menu ne sont pas visibles ! Il nous faut donc réagir au click sur le bouton principal pour ouvrir le menu.
Pour cela il faut rajouter la gestion de l’événement « on-tap » sur le bouton principal afin d’appeler une méthode de notre élément (on-tap est préférable à on-click pour gérer correctement les tablettes et smartphones).

Dans la méthode, on permute une classe CSS afin de faire jouer des transitions CSS

Note: Pour accéder facilement à un élément de notre DOM de l’élément qui comporte un ID, il suffit d’utiliser la notation  this.$.<id du noeud DOM>
A noter que cette notation ne marche que pour les éléments statiques. Pour les boucles qui construisent des noeuds dynamiquement, il est possible d’utiliser la notation   this.$$.<id du noeud DOM>  (je n’ai pas encore eu l’occasion de tester cette notation…).

Un peu de CSS

Maintenant, il ne reste qu’à enrober tout cela d’une pincée de CSS, ne serait-ce que pour les transitions.

Avoir un seul menu ouvert

Dernière fonctionnalité du composant, un seul menu ouvert même si plusieurs instances de itk-radial-menu cohabitent sur la même page !
Pour cela, chaque ouverture du menu va générer un événement « open ». Chaque élément ouvert qui recevra cet événement saura alors qu’il doit se fermer puisqu’un autre menu quelque part dans l’espace vient de s’ouvrir !

Pour cela on surcharge la méthode « ready » qui fait partie du cycle de vie de Polymer (cette méthode est appelée lorsque les propriétés de l’élément sont initialisées), dans laquelle on va déclarer le listener sur l’événement « open »

Et on déclenche l’événement à l’ouverture du menu

Conclusion

Voilà notre 1er composant prêt et opérationnel !

Alors qu’est ce que j’en pense au final ? Du bien, du très grand bien !
+ D’abord parce que le développement orienté composant est une bonne manière de voir les choses
+ Polymer est une implémentation des WebComponent qui va être implémentée dans tous les navigateurs
+ Polymer comble les manques encore non implémentés par les navigateurs grâce aux Polyfill
+ Facile à prendre en main
+ Les styles sont scopés à votre élément donc pas de collision
– Beaucoup de choses et malgré une documentation soignée, il ne faut pas faire l’impasse sur la lecture de la documentation: RTFM
– Ca reste du Javascript (le self, les observers, l’initialisation des Object ou Array, …)
– Le debug reste compliqué
– Pas d’information dans la console si vous avez oublié un import mais que vous utilisez un élément
– Le Tooling est en cours et cela commence à ressembler à quelque chose (comme dans le monde Javascript d’ailleurs)
– Pas d’erreur lorsque l’on tape quelque chose de faux (IntelliJ aide mais quand même…)

Il faudrait pousser les et développer des composants Polymer, les intégrer dans une application AngularJS / ReactJS pour voir si cela fonctionne vraiment bien et estimer le poids supplémentaire induit par cette utilisation.
Ceci dit je crois que les WebComponents sont un bon moyen de s’abstraire de frameworks de plus haut niveau et de pouvoir rapidement changer de technos. Polymer étant une implémentation et qui en plus comble le manque des navigateurs grâce aux Polyfill, je pense que c’est un bon choix aujourd’hui… Si vous avez des éléments dans ce sens ou dans le sens contraire, n’hésitez pas à faire un commentaire il est plus que bienvenu !

PS: Cet élément s’intègre dans une application plus vaste en cours de construction et qui va servir à gérer les compétences à ITK. Voici une petite animation de ce que cela donne.

skill-manager

 

Eric Taix Eric Taix
Co-leader of Montpellier Java User Group. Tech adict, I believe in communities, sharing knowledge. #java #android #dartlang lover.
Commentaires
Soyez le premier à réagir sur cet article !

UP