MDC-112 Web: intégration de MDC aux frameworks Web

MDC-112 Web:
intégration de MDC aux frameworks Web

À propos de cet atelier de programmation

subjectDernière mise à jour : oct. 11, 2020
account_circleRédigé par Liz Mitchell, Abhinay Omkar

1. Introduction

logo_components_color_2x_web_96dp.png

Material Components (MDC) aide les développeurs à implémenter Material Design. Conçu par une équipe d'ingénieurs et de spécialistes de l'expérience utilisateur chez Google, MDC propose des dizaines de composants d'interface utilisateur élégants et fonctionnels. Il est disponible pour Android, iOS, le Web et Flutter.material.io/develop.

MDC Web est conçu pour s'intégrer à n'importe quel framework d'interface, tout en respectant les principes de Material Design. L'atelier de programmation suivant vous explique comment créer un composant React qui utilise MDC Web comme base. Les principes appris dans cet atelier de programmation peuvent être appliqués à n'importe quel framework JavaScript.

Fonctionnement de MDC Web

La couche JavaScript de MDC Web comprend trois classes par composant: Component, Foundation et Adapter. Ce modèle offre à MDC Web la flexibilité nécessaire pour s'intégrer aux frameworks d'interface.

La fondation contient la logique métier qui implémente Material Design. L'élément Foundation ne fait référence à aucun élément HTML. Cela nous permet d'extraire la logique d'interaction HTML dans l'adaptateur. Foundation dispose d'un adaptateur.

L'adaptateur est une interface. La Foundation fait référence à l'interface de l'adaptateur pour implémenter la logique métier Material Design. Vous pouvez implémenter l'adaptateur dans différents frameworks tels qu'Angular ou React. Une implémentation d'un Adapter interagit avec la structure DOM.

Le composant a une fondation et son rôle est de

  1. Implémentez l'adaptateur en utilisant du code JavaScript non compatible avec le framework.
  2. Fournissez des méthodes publiques faisant office de proxy pour les méthodes de la Foundation.

Avantages de MDC Web

Chaque package de MDC Web est fourni avec un composant, une fondation et un adaptateur. Pour instancier un composant, vous devez transmettre l'élément racine à la méthode constructeur du composant. Le composant implémente un adaptateur qui interagit avec les éléments DOM et HTML. Le Component instancie ensuite la Foundation, qui appelle les méthodes Adapter.

Pour intégrer MDC Web dans un framework, vous devez créer votre propre composant dans le langage/la syntaxe de ce framework. Le composant du framework met en œuvre l'adaptateur de MDC Web et utilise la fondation de MDC Web.

Objectifs de l'atelier

Cet atelier de programmation explique comment créer un adaptateur personnalisé pour utiliser la logique Foundation afin d'obtenir un composant React Material Design. Il aborde les sujets avancés abordés sur la page Intégration dans Frameworks. Dans cet atelier de programmation, React est utilisé comme exemple de framework, mais cette approche peut être appliquée à n'importe quel autre framework.

Dans cet atelier de programmation, vous allez créer la barre d'application supérieure et recréer la page de démonstration de cette barre. La mise en page de la page de démonstration est déjà configurée. Vous pouvez donc commencer à travailler sur la barre d'application supérieure. La barre d'application supérieure inclura les éléments suivants:

  • Icône de navigation
  • Tâches
  • Quatre variantes sont disponibles: Court, Toujours réduite, Fixe et Proéminente.

Ce dont vous avez besoin:

  • Une version récente de Node.js (fournie avec npm, un gestionnaire de packages JavaScript)
  • L'exemple de code (à télécharger à l'étape suivante)
  • Connaissances de base de HTML, CSS, JavaScript et React
<ph type="x-smartling-placeholder">

Comment évalueriez-vous votre niveau d'expérience en développement Web ?

.

2. Configurer l&#39;environnement de développement

Télécharger l'application de départ de l'atelier de programmation

Elle se trouve dans le répertoire material-components-web-codelabs-master/mdc-112/starter.

… ou cloner l'atelier depuis GitHub

Pour cloner cet atelier de programmation à partir de GitHub, exécutez les commandes suivantes :

git clone https://github.com/material-components/material-components-web-codelabs
cd material
-components-web-codelabs/mdc-112/starter

Installer les dépendances du projet

Dans le répertoire de démarrage material-components-web-codelabs/mdc-112/starter, exécutez la commande suivante:

npm install

Vous verrez de nombreuses activités et, à la fin, votre terminal devrait indiquer une installation réussie:

22a33efc2a687408.png

Exécuter l'application de départ

Dans le même répertoire, exécutez la commande suivante:

npm start

webpack-dev-server va démarrer. Saisissez l'adresse http://localhost:8080/ dans votre navigateur pour afficher la page.

b55c66dd400cf34f.png

Opération réussie. Le code de démarrage de la page de démonstration de la fonctionnalité React de la barre d'application supérieure devrait s'exécuter dans votre navigateur. Vous devriez voir un mur de texte lorem ipsum, une zone Commandes (en bas à droite) et une barre d'application supérieure inachevée:

4ca3cf6d216f9290.png

Examiner le code et le projet

Si vous ouvrez votre éditeur de code, le répertoire du projet devrait ressembler à ceci:

e9a3270d6a67c589.png

Ouvrez le fichier App.js et examinez la méthode render, qui inclut le composant <TopAppBar>:

App.js

render() {
    const {isFixed, isShort, isRtl, isProminent, isAlwaysCollapsed, shouldReinit} = this.state;

    return (
      <section
        dir={isRtl ? 'rtl' : 'ltr'}
        className='mdc-typography'>
        {
          shouldReinit ? null :
          <TopAppBar
            navIcon={this.renderNavIcon()}
            short={isShort}
            prominent={isProminent}
            fixed={isFixed}
            alwaysCollapsed={isAlwaysCollapsed}
            title='Mountain View, CA'
            actionItems={this.actionItems}
          />
        }
        <div className={classnames('mdc-top-app-bar--fixed-adjust', {
          'mdc-top-app-bar--short-fixed-adjust': isShort || isAlwaysCollapsed,
          'mdc-top-app-bar--prominent-fixed-adjust': isProminent,
        })}>
          {this.renderDemoParagraphs()}
        </div>

        {this.renderControls()}
      </section>
    );
  }

Il s'agit du point d'entrée de TopAppBar dans l'application.

Ouvrez le fichier TopAppBar.js, qui est une classe React Component simple avec une méthode render:

TopAppBar.js

import React from 'react';

export default class TopAppBar extends React.Component {
 
render() {
   
return (
     
<header>
       
TOP APP BAR
     
</header>
   
);
 
}
}

3. Composition du composant

Dans React, la méthode render génère le code HTML du composant. Le composant Top App Bar affiche une balise <header /> et se compose de deux sections principales:

  1. Icône de navigation et section de titre
  2. Section des icônes d'action

Si vous avez des questions sur les éléments qui composent la barre d'application supérieure, consultez la documentation sur GitHub.

Modifiez la méthode render() dans TopAppBar.js pour qu'elle se présente comme suit:

  render() {
    const {
      title,
      navIcon,
    } = this.props;

    return (
      <header
        className={this.classes}
        style={this.getMergedStyles()}
        ref={this.topAppBarElement}
      >
        <div className='mdc-top-app-bar__row'>
          <section className='mdc-top-app-bar__section mdc-top-app-bar__section--align-start'>
            {navIcon ? navIcon : null}
            <span className="mdc-top-app-bar__title">
              {title}
            </span>
          </section>
          {this.renderActionItems()}
        </div>
      </header>
    );
  }

Ce code HTML comporte deux éléments de section. Le premier contient une icône et un titre de navigation. Le second contient des icônes d'action.

Ajoutez ensuite la méthode renderActionItems:

renderActionItems() {
  const {actionItems} = this.props;
  if (!actionItems) {
    return;
  }

  return (
    <section className='mdc-top-app-bar__section mdc-top-app-bar__section--align-end' role='toolbar'>
      {/* need to clone element to set key */}
      {actionItems.map((item, key) => React.cloneElement(item, {key}))}
    </section>
  );
}

Un développeur va importer TopAppBar dans son application React et transmettre les icônes d'action à l'élément TopAppBar. Vous trouverez un exemple de code pour initialiser un TopAppBar dans App.js.

La méthode getMergedStyles qui est utilisée dans la méthode render est manquante. Veuillez ajouter la méthode JavaScript suivante à la classe TopAppBar:

getMergedStyles = () => {
  const {style} = this.props;
  const {style: internalStyle} = this.state;
  return Object.assign({}, internalStyle, style);
}

this.classes est également manquant dans la méthode render, mais sera abordé dans une section ultérieure. Outre la méthode getter manquante, this.classes, il existe encore des éléments de TopAppBar que vous devez implémenter pour que la barre d'application supérieure s'affiche correctement.

Les éléments du composant React qui ne figurent toujours pas dans la barre d'application supérieure sont les suivants:

  • Une base initialisée
  • Méthodes de l'adaptateur à transmettre aux éléments de base
  • Balisage JSX
  • Gestion des variantes (fixe, courte, toujours réduite, visible)

La méthode

  1. Implémentez les méthodes Adapter.
  2. Initialisez l'élément Foundation dans componentDidMount.
  3. Appelez la méthode Foundation.destroy dans componentWillUnmount.
  4. Établissez la gestion des variantes à l'aide d'une méthode getter qui combine les noms de classe appropriés.

4. Implémenter les méthodes de l&#39;adaptateur

Le composant JS TopAppBar non compatible avec le framework implémente les méthodes Adapter suivantes (répertoriées en détail sur cette page):

  • hasClass()
  • addClass()
  • removeClass()
  • registerNavigationIconInteractionHandler()
  • deregisterNavigationIconInteractionHandler()
  • notifyNavigationIconClicked()
  • setStyle()
  • getTopAppBarHeight()
  • registerScrollHandler()
  • deregisterScrollHandler()
  • registerResizeHandler()
  • deregisterResizeHandler()
  • getViewportScrollY()
  • getTotalActionItems()

Étant donné que React comporte des événements synthétiques ainsi que différentes bonnes pratiques et modèles de codage, les méthodes Adapter doivent être réimplémentées.

Méthode Getter de l'adaptateur

Dans le fichier TopAppBar.js, ajoutez la méthode JavaScript suivante à TopAppBar:

get adapter() {
  const {actionItems} = this.props;

  return {
    hasClass: (className) => this.classes.split(' ').includes(className),
    addClass: (className) => this.setState({classList: this.state.classList.add(className)}),
    removeClass: (className) => {
      const {classList} = this.state;
      classList.delete(className);
      this.setState({classList});
    },
    setStyle: this.setStyle,
    getTopAppBarHeight: () => this.topAppBarElement.current.clientHeight,
    registerScrollHandler: (handler) => window.addEventListener('scroll', handler),
    deregisterScrollHandler: (handler) => window.removeEventListener('scroll', handler),
    registerResizeHandler: (handler) => window.addEventListener('resize', handler),
    deregisterResizeHandler: (handler) => window.removeEventListener('resize', handler),
    getViewportScrollY: () => window.pageYOffset,
    getTotalActionItems: () => actionItems && actionItems.length,
  };
}

Les API d'adaptation pour l'enregistrement des événements de défilement et de redimensionnement sont implémentées de la même manière que la version JS non-framework, car React ne comporte aucun événement synthétique pour le défilement ou le redimensionnement, et se réfère au système d'événements DOM natif. getViewPortScrollY doit également s'appliquer au DOM natif, car il s'agit d'une fonction sur l'objet window, qui ne se trouve pas dans l'API de React. Les implémentations d'adaptateur seront différentes pour chaque framework.

Vous remarquerez peut-être que this.setStyle est manquant, appelé par la méthode get adapter. Dans le fichier TopAppBar.js, ajoutez la méthode JavaScript manquante à la classe TopAppBar:

setStyle = (varName, value) => {
  const updatedStyle = Object.assign({}, this.state.style);
  updatedStyle[varName] = value;
  this.setState({style: updatedStyle});
}

Vous venez d'implémenter l'adaptateur. Notez qu'il est possible que des erreurs s'affichent dans votre console à ce stade, car l'implémentation complète n'est pas encore terminée. La section suivante vous explique comment ajouter et supprimer des classes CSS.

5. Implémenter des méthodes de composant

Gérer les variantes et les classes

React ne dispose pas d'une API pour gérer les classes. Pour imiter les méthodes d'ajout et de suppression de classes CSS du code JavaScript natif, ajoutez la variable d'état classList. Dans TopAppBar, trois extraits de code interagissent avec les classes CSS:

  1. <TopAppBar /> via la propriété className.
  2. La méthode Adapter via addClass ou removeClass.
  3. Codé en dur dans le composant React <TopAppBar />

Tout d'abord, ajoutez l'importation suivante en haut de TopAppBar.js, sous les importations existantes:

import classnames from 'classnames';

Ajoutez ensuite le code suivant dans la déclaration de classe du composant TopAppBar:

export default class TopAppBar extends React.Component {
  constructor(props) {
    super(props);
    this.topAppBarElement = React.createRef();
  }

  state = {
    classList: new Set(),
    style: {},
  };

  get classes() {
    const {classList} = this.state;
    const {
      alwaysCollapsed,
      className,
      short,
      fixed,
      prominent,
    } = this.props;

    return classnames('mdc-top-app-bar', Array.from(classList), className, {
      'mdc-top-app-bar--fixed': fixed,
      'mdc-top-app-bar--short': short,
      'mdc-top-app-bar--short-collapsed': alwaysCollapsed,
      'mdc-top-app-bar--prominent': prominent,
    });
  }

  ...
}

Si vous accédez à http://localhost:8080, les cases à cocher "Controls" (Commandes) devraient maintenant activer/désactiver les noms des classes dans le DOM.

Ce code permet à de nombreux développeurs d'utiliser TopAppBar. Les développeurs peuvent interagir avec l'API TopAppBar sans se soucier des détails d'implémentation des classes CSS.

Vous venez d'implémenter l'adaptateur. La section suivante vous explique comment instancier un élément Foundation.

Installer et désinstaller le composant

L'instanciation de la fondation se produit dans la méthode componentDidMount.

Commencez par importer les éléments de base de la barre d'application supérieure MDC en ajoutant l'importation suivante après les importations existantes dans TopAppBar.js:

import {MDCTopAppBarFoundation, MDCFixedTopAppBarFoundation, MDCShortTopAppBarFoundation} from '@material/top-app-bar';

Ajoutez ensuite le code JavaScript suivant à la classe TopAppBar:

export default class TopAppBar extends React.Component {
 
  ...

  foundation_ = null;

  componentDidMount() {
    this.initializeFoundation();
  }

  componentWillUnmount() {
    this.foundation_.destroy();
  }

  initializeFoundation = () => {
    if (this.props.short) {
      this.foundation_ = new MDCShortTopAppBarFoundation(this.adapter);
    } else if (this.props.fixed) {
      this.foundation_ = new MDCFixedTopAppBarFoundation(this.adapter);
    } else {
      this.foundation_ = new MDCTopAppBarFoundation(this.adapter);
    }

    this.foundation_.init();
  }
 
  ...

}

Une bonne pratique de codage React consiste à définir les propTypes et defaultProps. Ajoutez l'importation suivante après les importations existantes dans TopAppBar.js:

import PropTypes from 'prop-types';

Ajoutez ensuite le code suivant en bas de TopAppBar.js (après la classe Component):

import PropTypes from 'prop-types';

TopAppBar.propTypes = {
 
alwaysCollapsed: PropTypes.bool,
 
short: PropTypes.bool,
 
fixed: PropTypes.bool,
 
prominent: PropTypes.bool,
 
title: PropTypes.string,
 
actionItems: PropTypes.arrayOf(PropTypes.element),
 
navIcon: PropTypes.element,
};

TopAppBar.defaultProps = {
 
alwaysCollapsed: false,
 
short: false,
 
fixed: false,
 
prominent: false,
 
title: '',
 
actionItems: null,
 
navIcon: null,
};

Vous venez d'implémenter le composant React de la barre d'application supérieure. Si vous accédez à http://localhost:8080, vous pouvez tester la page de démonstration. La page de démonstration fonctionnera de la même manière que la page de démonstration de MDC Web. La page de démonstration doit se présenter comme suit:

3d983b98c2092e7a.png

6. Conclusion

Dans ce tutoriel, nous avons appris à encapsuler la Foundation de MDC Web pour l'utiliser dans une application React. Il existe sur GitHub et npm quelques bibliothèques qui encapsulent les composants Web MDC, comme décrit dans la section Intégration dans les frameworks. Nous vous recommandons d'utiliser la liste disponible ici. Cette liste inclut également d'autres frameworks en plus de React, tels qu'Angular et Vue.

Ce tutoriel explique notre décision de diviser le code Web MDC en trois parties : la fondation, l'adaptateur et le composant. Cette architecture permet aux composants de partager du code commun tout en travaillant avec tous les frameworks. Merci d'avoir essayé Material Components React. N'hésitez pas à consulter notre nouvelle bibliothèque MDC React. Nous espérons que cet atelier de programmation vous a plu.

<ph type="x-smartling-placeholder">

La réalisation de cet atelier de programmation m'a demandé un temps et des efforts raisonnables

Je souhaite continuer à utiliser Material Components

.