Fermer

mai 5, 2022

Conception réactive avec KendoReact GridLayout & StackLayout

Conception réactive avec KendoReact GridLayout & StackLayout


Voyons comment concevoir une page de blog réactive pour une application React à l’aide des composants KendoReact GridLayout et StackLayout.

Pouvez-vous imaginer qu’il n’existait pas de site Web réactif à l’époque du développement Web ? De nos jours, de plus en plus d’utilisateurs visitent des sites Web en ligne via des appareils portables plutôt que des ordinateurs de bureau ou des ordinateurs portables. Par conséquent, les sites Web réactifs sont omniprésents de nos jours. La plupart du temps, c’est un incontournable, sinon un site Web ne serait pas accessible et facile à utiliser pour les utilisateurs de mobiles et de tablettes.

Dans cet article, je veux vous montrer comment implémenter un design réactif pour une page de blog en utilisant KendoRéagirc’est
Disposition de la grille et StackLayout Composants. Le blog sera composé d’articles de blog récents et en vedette. Ci-dessous, vous pouvez voir un court GIF de ce que nous allons créer dans ce tutoriel.

Gif de blog réactif

Vous pouvez trouver un exemple de code complet pour ce projet dans ce dépôt GitHub ainsi qu’un exemple interactif CodeSandbox ci-dessous :

Configuration du projet

Nous allons utiliser Vite pour échafauder rapidement un nouveau projet React. Si vous n’avez jamais entendu parler de Vite auparavant, vous voudrez peut-être consulter mon article à ce sujet—Qu’est-ce que Vite : le guide des outils de projet modernes et ultra-rapides.

Exécutez la commande ci-dessous dans votre terminal pour créer un nouveau projet de réaction.

$ npm init vite kendo-react-responsive-layouts -- --template react

Noter: KendoReact est une bibliothèque de composants d’interface utilisateur commerciale, et dans ce cadre, vous devrez fournir une clé de licence lorsque vous utilisez les composants dans vos projets React. Vous pouvez obtenir une clé de licence via un essai gratuit ou en possédant une licence commerciale. Pour plus d’informations, vous pouvez vous diriger vers Page de licence KendoReact.

Une fois la création du projet terminée, exécutez les commandes suivantes pour accéder au répertoire du projet et installer toutes les dépendances.

$ cd kendo-react-responsive-layouts-form && npm install

Enfin, vous pouvez démarrer le serveur de développement en exécutant le npm run dev commande.

Vous devriez voir le projet en cours d’exécution lors de la visite localhost:3000 dans votre navigateur. Ensuite, installons toutes les bibliothèques KendoReact dont nous aurons besoin pour ce projet.

$ npm install --save @progress/kendo-react-layout @progress/kendo-react-progressbars @progress/kendo-licensing @progress/kendo-react-intl @progress/kendo-theme-default

Une fois l’installation terminée, nettoyons le App composant et son fichier de styles. On peut commencer par renommer le App.css fichier à App.module.css et en remplaçant son contenu par le code ci-dessous.

src/App.module.css

.appContainer {
  max-width: 1180px;
  margin: 2rem auto;
  padding: 0 2rem;
}

Nous devons également mettre à jour le App.jsx dossier.

src/App.jsx

import styles from "./App.module.css";
import BlogPosts from "./components/BlogPosts";

function App() {
  return (
    <div className={styles.appContainer}>
      <BlogPosts />
    </div>
  );
}

export default App;

Dans le App composant, nous importons le BlogPosts composant, mais il n’existe pas encore, alors créons-le ensuite.

src/components/BlogPosts.jsx

import { useState, useEffect } from "react";
import styles from "./BlogPosts.module.css";

const BlogPosts = props => {
  return (
    <div>
      <div>
        <h1>Welcome to my blog</h1>
      </div>
    </div>
  );
};

export default BlogPosts;

Et voici les styles dont nous aurons besoin bientôt.

src/components/BlogPosts.module.css

.postCard {
  padding: 1rem;
  border: 1px solid #e4e4e7;
  border-radius: 5px;
  text-align: left;
}

.postHeading {
  margin-top: 0;
}

Enfin, nous devons inclure le thème KendoReact Default.

src/main.jsx

import React from "react";
import ReactDOM from "react-dom";
import "@progress/kendo-theme-default/dist/all.css";
import "./index.css";
import App from "./App";

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById("root")
);

C’est suffisant pour la configuration initiale. Voyons comment nous pouvons créer une mise en page de grille réactive avec le GridLayout composant.

Disposition de la grille

Notre site Web de blog est censé avoir des articles récents et en vedette. Nous allons les récupérer depuis l’API jsonplaceholder.

src/components/BlogPosts.jsx

import { useState, useEffect } from "react";
import styles from "./BlogPosts.module.css";

const BlogPosts = props => {
  const [posts, setPosts] = useState([]);
  const [featuredPosts, setFeaturedPosts] = useState([]);

  useEffect(() => {
    (async () => {
      const response = await fetch(
        "https://jsonplaceholder.typicode.com/posts"
      );
      const data = await response.json();
      const featuredPosts = data.slice(0, 5);
      const posts = data.slice(5, 17);
      setPosts(posts);
      setFeaturedPosts(featuredPosts);
    })();
  }, []);

  return (
    <div>
      <div>
        <h1>Welcome to my blog</h1>
      </div>
    </div>
  );
};

export default BlogPosts;

Vous pouvez utiliser React DevTools ou utiliser console.log pour vérifier si les messages ont été récupérés avec succès. Pour les besoins de ce didacticiel, les cinq premiers messages seront « en vedette » et les 12 suivants seront utilisés comme messages « récents ».

Puisque nous avons maintenant des messages récents et en vedette, nous pouvons utiliser le GridLayout composant pour créer une grille pour eux. Disons que les publications récentes seront dans la colonne de gauche qui occupera environ 70% de la largeur de l’écran, tandis que la colonne de droite pour les publications en vedette occupera 30%. Voici comment nous pouvons mettre cela en œuvre.

src/components/BlogPosts.jsx

Tout d’abord, ajoutez une nouvelle importation en haut du fichier.

import {
  GridLayout,
  GridLayoutItem,
} from "@progress/kendo-react-layout";

Ensuite, remplacez le JSX par le code ci-dessous.

<div>
  <h1>Welcome to my blog</h1>
  <div>
    <GridLayout
      gap={{
        rows: 20,
          cols: 40,
      }}
      cols={[
        {
          width: "70%",
        },
        {
          width: "30%",
        },
      ]}
      >
      <GridLayoutItem row={1} col={1}>
        <h2>Recent posts</h2>
        <GridLayout
          gap={{ rows: 20, cols: 20 }}
          cols={[
            {
              width: "repeat(3, 1fr)",
            },
          ]}
          >
          {posts.map((post, idx) => {
            const row = Math.floor(idx / 3) + 1;
            return (
              <GridLayoutItem
                className={styles.postCard}
                key={post.id}
                row={row}
                col={(idx % 3) + 1}
                >
                <h3 className={styles.postHeading}>{post.title}</h3>
                <p className={styles.postBody}>{post.body}</p>
              </GridLayoutItem>
            );
          })}
        </GridLayout>
      </GridLayoutItem>
      <GridLayoutItem row={1} col={2}>
        <h2>Featured posts</h2>
        <div>
          {featuredPosts.map(featuredPost => {
            return (
              <div className={styles.postCard} key={featuredPost.id}>
                <h3 className={styles.postHeading}>{featuredPost.title}</h3>
                <p className={styles.postBody}>{featuredPost.body}</p>
              </div>
            );
          })}
        </div>
      </GridLayoutItem>
    </GridLayout>
  </div>
</div>

Nous avons importé le GridLayout et GridLayoutItem composants de la bibliothèque KendoReact. Le premier est chargé d’organiser les enfants en lignes et en colonnes dans une structure de grille, tandis que le second est utilisé pour représenter les éléments de la grille. GridLayout de KendoReact est construit au-dessus de CSS Grid. Dans le code ci-dessus, nous utilisons le GridLayout composant deux fois. La première fois, il est utilisé pour créer une grille pour les messages récents et en vedette.

<GridLayout
	gap={{
    rows: 20,
    cols: 40,
  }}
	cols={[
    {
      width: "70%",
    },
    {
      width: "30%",
    },
	]}
>

Le GridLayout ici, le composant reçoit deux accessoires—gap et cols. Le gap prop est utilisé pour spécifier l’espace entre les lignes et les colonnes, tandis que le cols, comme vous pouvez probablement le deviner, pour structurer les colonnes dans la grille. Dans ce cas, il y aura deux colonnes avec 70% et 30% de largeur.

La deuxième GridLayout est responsable de la grille des articles du blog. La grille sera composée de trois colonnes également réparties.

<GridLayout
	gap={{ rows: 20, cols: 20 }}
	cols={[
		{
			width: "repeat(3, 1fr)",
		},
	]}
>

Nous n’avons transmis que deux accessoires au GridLayout composant, mais il y en a d’autres qui peuvent être passés. Vous pouvez trouver tous les accessoires acceptés ici.

Le GridLayoutItem est utilisé pour spécifier où un élément de grille doit être placé. Par exemple, l’élément de grille qui contient les articles de blog récents commence sur la première ligne et colonne. D’autre part, l’élément de grille qui contient les publications en vedette commence sur la première ligne mais la deuxième colonne.

{}
<GridLayoutItem row={1} col={1}>
  
</GridLayoutItem>
{}
<GridLayoutItem row={1} col={2}>

</GridLayoutItem>

Nous utilisons également le GridLayoutItem pour chacun des articles du blog. Puisque nous voulons avoir trois articles de blog à la suite, nous divisons l’index des articles pour déterminer dans quelle ligne chaque article de blog doit être placé. Pour la colonne, en revanche, l’opérateur modulo est utilisé.

{posts.map((post, idx) => {
  const row = Math.floor(idx / 3) + 1;
  const col = (idx % 3) + 1
  return (
    <GridLayoutItem
      className={styles.postCard}
      key={post.id}
      row={row}
      col={col}
      >
      <h3 className={styles.postHeading}>{post.title}</h3>
      <p className={styles.postBody}>{post.body}</p>
    </GridLayoutItem>
  );
})}

Vous pouvez trouver plus de détails sur le GridLayoutItem composant ici. L’image ci-dessous montre à quoi devrait ressembler l’interface utilisateur pour le moment.

Disposition des messages initiaux

Nous avons la disposition initiale des postes. Cependant, il y a encore des choses que nous devons faire. Par exemple, les messages présentés n’ont pas d’espace entre eux et l’interface utilisateur n’est pas du tout réactive. Occupons-nous ensuite de ces deux problèmes.

Disposition de la pile

Outre GridLayoutKendoReact offre également le StackLayout composant. En comparaison à GridLayoutla StackLayout ne peut être utilisé que pour les mises en page horizontales et verticales. Nous utiliserons StackLayout pour afficher les publications en vedette verticalement et ajouter de l’espace entre elles.

src/components/BlogPosts.jsx

Tout d’abord, mettez à jour les importations pour inclure le StackLayout composant.

import {
  GridLayout,
  GridLayoutItem,
  StackLayout,
} from "@progress/kendo-react-layout";

Ensuite, nous devons mettre à jour le JSX qui est responsable du rendu des publications en vedette.

<GridLayoutItem row={1} col={2}>
  <h2>Featured posts</h2>
  <StackLayout orientation="vertical" gap={20}>
    {featuredPosts.map(featuredPost => {
      return (
        <div className={styles.postCard} key={featuredPost.id}>
          <h3 className={styles.postHeading}>{featuredPost.title}</h3>
          <p className={styles.postBody}>{featuredPost.body}</p>
        </div>
      );
    })}
  </StackLayout>
</GridLayoutItem>

Nous avons remplacé le div élément avec le StackLayout composant qui reçoit gap et orientation accessoires. Si vous regardez à nouveau l’interface utilisateur, les publications en vedette seront toujours affichées verticalement, mais il devrait maintenant y avoir un espace entre elles.

Vous pouvez en savoir plus sur le StackLayout composant ici.

Rendre GridLayout et StackLayout réactifs

Le GridLayout et StackLayout les composants n’acceptent aucun accessoire de point d’arrêt qui modifierait automatiquement les colonnes et les lignes en fonction de la taille de l’écran. Cependant, nous pouvons simplement transmettre différents accessoires à ces composants en fonction de la taille de l’écran. Pour déterminer quels accessoires nous devons passer, nous profiterons de la use-breakpoint crochet. Tout d’abord, nous devons l’installer.

$ npm install --save use-breakpoint

Ensuite, nous devons définir des points d’arrêt d’écran. Nous en aurons trois : mobile, tablette et ordinateur de bureau.

src/constantes/breakpoints.js

export const BREAKPOINTS = {
  mobile: 0,
  tablet: 768,
  desktop: 1280,
};

Voici une partie intéressante. Nous devons fournir différentes valeurs en fonction de la taille de l’écran. Cependant, le faire à l’intérieur du JSX deviendrait très rapidement un gâchis massif avec beaucoup de if/else if/else instructions pour transmettre les valeurs appropriées. Au lieu de cela, pour garder le balisage propre, nous allons créer un objet de configuration qui contiendra toutes les valeurs de grille pour différentes tailles d’écran. Ci-dessous, vous pouvez voir le GRID_CONFIG.

src/constantes/gridConfig.js

export const GRID_CONFIG = {
  mobile: {
    outerGrid: {
      cols: [
        {
          width: "1fr",
        },
      ],
      rows: [
        {
          width: "repeat(2, 1fr)",
        },
      ],
    },
    mainContainer: {
      row: 2,
      col: 1,
    },
    featuredContainer: {
      row: 1,
      col: 1,
    },
    postsContainer: {
      cols: [
        {
          width: "1fr",
        },
      ],
    },
    postItem: {
      divider: 1,
    },
    featuredOrientation: "vertical",
  },
  tablet: {
    outerGrid: {
      cols: [
        {
          width: "100%",
        },
      ],
      rows: [
        {
          width: "repeat(2, 1fr)",
        },
      ],
    },
    mainContainer: {
      row: 2,
      col: 1,
    },
    featuredContainer: {
      row: 1,
      col: 1,
    },
    postsContainer: {
      cols: [
        {
          width: "1fr 1fr",
        },
      ],
    },
    postItem: {
      divider: 2,
    },
    featuredOrientation: "horizontal",
  },
  desktop: {
    outerGrid: {
      cols: [
        {
          width: "70%",
        },
        {
          width: "30%",
        },
      ],
      rows: [],
    },
    mainContainer: {
      row: 1,
      col: 1,
    },
    featuredContainer: {
      row: 1,
      col: 2,
    },
    postsContainer: {
      cols: [
        {
          width: "repeat(3, 1fr)",
        },
      ],
    },
    postItem: {
      divider: 3,
    },
    featuredOrientation: "vertical",
  },
};

Voici le résumé du GRID_CONFIG et ce que ça va faire :

  • outerGrid – les articles récents et en vedette seront dans une colonne sur mobile et tablette, mais dans deux colonnes sur ordinateur.
  • mainContainer – le conteneur des articles de blog récents sera sur la deuxième ligne sur mobile et tablette, mais sur la première ligne sur ordinateur.
  • featuredContainer – le conteneur d’articles de blog en vedette sera placé dans la première ligne et colonne sur mobile et tablette, mais dans la deuxième colonne sur ordinateur.
  • postsContainer – la grille des articles de blog récents aura une colonne sur mobile, deux colonnes sur tablette et trois colonnes sur ordinateur.
  • postItem – chaque article de blog récent utilise un séparateur différent pour calculer la position des lignes et des colonnes : un pour mobile, deux pour tablette et trois pour ordinateur.
  • featuredOrientation – sur mobile et desktop, la publication sélectionnée sera en orientation verticale mais horizontale sur une tablette.

Enfin, nous pouvons utiliser le GRID_CONFIG et BREAKPOINTS dans le BlogPosts composant.

src/components/BlogPosts.jsx

import { useState, useEffect } from "react";
import {
  GridLayout,
  GridLayoutItem,
  StackLayout,
} from "@progress/kendo-react-layout";
import useBreakpoint from "use-breakpoint";
import styles from "./BlogPosts.module.css";
import { GRID_CONFIG } from "../constants/gridConfig";
import { BREAKPOINTS } from "../constants/breakpoints";

const getGridConfig = (breakpoint, GRID_CONFIG) => GRID_CONFIG[breakpoint];

const BlogPosts = props => {
  const { breakpoint } = useBreakpoint(BREAKPOINTS, "desktop");
  const [posts, setPosts] = useState([]);
  const [featuredPosts, setFeaturedPosts] = useState([]);

  useEffect(() => {
    (async () => {
      const response = await fetch(
        "https://jsonplaceholder.typicode.com/posts"
      );
      const data = await response.json();
      const featuredPosts = data.slice(0, 5);
      const posts = data.slice(5, 17);
      setPosts(posts);
      setFeaturedPosts(featuredPosts);
    })();
  }, []);

  const {
    outerGrid,
    mainContainer,
    featuredContainer,
    postsContainer,
    postItem,
    featuredOrientation,
  } = getGridConfig(breakpoint, GRID_CONFIG);

  return (
    <div>
      <div>
        <h1>Welcome to my blog</h1>
        <div>
          <GridLayout
            gap={{
              rows: 20,
              cols: 40,
            }}
            rows={outerGrid.rows}
            cols={outerGrid.cols}
          >
            <GridLayoutItem row={mainContainer.row} col={mainContainer.col}>
              <h2>Recent posts</h2>
              <GridLayout
                gap={{ rows: 20, cols: 20 }}
                cols={postsContainer.cols}
              >
                {posts.map((post, idx) => {
                  const row = Math.floor(idx / postItem.divider) + 1;
                  return (
                    <GridLayoutItem
                      className={styles.postCard}
                      key={post.id}
                      row={row}
                      col={(idx % postItem.divider) + 1}
                    >
                      <h3 className={styles.postHeading}>{post.title}</h3>
                      <p className={styles.postBody}>{post.body}</p>
                    </GridLayoutItem>
                  );
                })}
              </GridLayout>
            </GridLayoutItem>
            <GridLayoutItem
              row={featuredContainer.row}
              col={featuredContainer.col}
            >
              <h2>Featured posts</h2>
              <StackLayout orientation={featuredOrientation} gap={20}>
                {(breakpoint === "desktop"
                  ? featuredPosts
                  : featuredPosts.slice(0, 3)
                ).map(featuredPost => {
                  return (
                    <div className={styles.postCard} key={featuredPost.id}>
                      <h3 className={styles.postHeading}>
                        {featuredPost.title}
                      </h3>
                      <p className={styles.postBody}>{featuredPost.body}</p>
                    </div>
                  );
                })}
              </StackLayout>
            </GridLayoutItem>
          </GridLayout>
        </div>
      </div>
    </div>
  );
};

export default BlogPosts;

Passons en revue les changements. Tout d’abord, nous importons useBreakpoint crochet, et GRID_CONFIG et BREAKPOINTS constantes.

Ensuite, nous avons le getGridConfig fonction qui renvoie la configuration pour la taille d’écran actuelle.

const getGridConfig = (breakpoint, GRID_CONFIG) => GRID_CONFIG[breakpoint];

Le useBreakpoint hook est utilisé pour obtenir le point d’arrêt actuellement actif, qu’il s’agisse d’un mobile, d’une tablette ou d’un ordinateur de bureau. La plupart des valeurs d’accessoires transmises à GridLayout, GridLayoutItem et StackLayout ont été remplacés.

const { breakpoint } = useBreakpoint(BREAKPOINTS, "desktop");

De plus, le getGridConfig La fonction est exécutée et les propriétés de configuration sont déstructurées.

const {
    outerGrid,
    mainContainer,
    featuredContainer,
    postsContainer,
    postItem,
    featuredOrientation,
  } = getGridConfig(breakpoint, GRID_CONFIG);

Enfin, les accessoires sont passés à GridLayout, GridLayoutItem et StackLayout les composants sont mis à jour pour utiliser les valeurs de GRID_CONFIG. De plus, cinq articles en vedette sont affichés sur le bureau, mais seulement trois sur des écrans plus petits.

{(breakpoint === "desktop"
  ? featuredPosts
  : featuredPosts.slice(0, 3)
 ).map(featuredPost => {
  return (
    <div className={styles.postCard} key={featuredPost.id}>
      <h3 className={styles.postHeading}>
        {featuredPost.title}
      </h3>
      <p className={styles.postBody}>{featuredPost.body}</p>
    </div>
  );
})}

Voilà pour les mises à jour. Si vous jetez un coup d’œil à l’interface utilisateur, vous devriez voir qu’elle se comporte exactement comme sur le GIF présenté précédemment.

Conclure

Nous avons expliqué comment créer une interface utilisateur réactive qui s’adapte à différentes tailles d’écran à l’aide de GridLayout, GridLayoutItem et StackLayout composants et en les combinant avec les use-breakpoint bibliothèque. Les articles de blog récents et de fonctionnalité sont affichés à différents endroits en fonction de la taille actuelle de l’écran.

KendoRéagir est un excellent outil pour développer des fonctionnalités complexes. Il fournit de nombreux composants riches en fonctionnalités prêts à l’emploi et nous permet de créer des fonctionnalités sophistiquées assez facilement et rapidement. Vous pouvez vérifier l’ensemble des fonctionnalités de la bibliothèque avec un essai gratuitqui vous donne également accès au support technique si jamais vous êtes bloqué.




Source link