Dans l'épisode d'aujourd'hui, nous expliquerons comment implémenter le thème de vos applications à l'aide du fournisseur de thèmes de Material UI. Nous allons tout configurer depuis :
- Typographie
- Points d'arrêt
- Couleurs
- Boutons
- Comment structurer votre application
Commençons !
Table des matières :
- 🤔 Qu'est-ce qu'un thème ?
- Configuration du thème
- Configurer le thème
- Typographie
- Échelle de caractères
- Dimensionnement de la police
- Points d'arrêt
- Configuration
- Accéder aux points d'arrêt
- Requêtes média CSS
- Requêtes média JS
- Palette de couleurs
- Choisir vos couleurs
- Appliquer la palette
- Boutons
- Échafaudez votre application
- Barre d'applications
- Contenu du corps
- Navigation dans le menu principal
- 🙏 Fermeture
🤔 Qu'est-ce qu'un thème ?
Les thèmes sont importants car ils définissent l'apparence de votre application globale. Un bon moteur de thème permettra à l'équipe de développement de configurer les choses une fois de manière centralisée, plutôt que de façon répétitive.
Le thème spécifie la couleur des composants, l'obscurité des surfaces, le niveau d'ombre, l'opacité appropriée des éléments d'encre, etc.
Les thèmes vous permettent d'appliquer un ton cohérent à votre application. Il vous permet de personnaliser tous les aspects de conception de votre projet afin de répondre aux besoins spécifiques de votre entreprise ou de votre marque.
Pour favoriser une plus grande cohérence entre les applications, des types de thèmes clairs et sombres sont disponibles au choix. Par défaut, les composants utilisent le type de thème clair.
(@material-ui)
Voici un bon exemple où la responsable de la conception de GitHub, Diana Mounter, parle en profondeur des difficultés qu'elle a rencontrées pour créer un thème sombre et où la création d'un thème centralisé plus tôt aurait rendu leur vie beaucoup plus facile.
Configuration du thème
La première chose à faire est d'envelopper votre application avec le ThemeProvider
de MUI composant.
// src/app.tsx
import { CssBaseline, ThemeProvider } from '@material-ui/core';
export default function App() {
return (
<ThemeProvider> {/* Property 'theme' is missing... */}
<CssBaseline />
<h1>Design System</h1>
</ThemeProvider>
);
}
Ce qui précède encapsule maintenant chacun des composants enfants de votre application avec le fournisseur de thème, exposant ainsi votre thème via l'API de contexte de React, que nous apprendrons plus tard à utiliser.
Créons maintenant un nouveau dossier dans votre src
répertoire appelé theme
. C'est ici que nous pouvons stocker chacune de nos configurations de thème.
Créez le fichier suivant :
// src/theme/index.tsx
import { createMuiTheme } from '@material-ui/core';
export default createMuiTheme({
})
La sortie de createMuiTheme
créera un Theme
objet, que notre ThemeProvider
nouvellement ajouté Composant d'ordre supérieur (HoC) requis. Branchons-le.
// src/app.tsx
import { CssBaseline, ThemeProvider } from '@material-ui/core';
import Theme from './theme';
export default function App() {
return (
<ThemeProvider theme={Theme}>
<CssBaseline />
<h1>Design System</h1>
</ThemeProvider>
);
}
Configurer le thème
L'un des avantages vraiment intéressants de l'utilisation de MUI est que leurs définitions TypeScript sont bien documentées. Ceci est évident en utilisant le "Go to definition"
de VSCode sur n'importe lequel de leurs exports de module par exemple si nous avons plongé dans leur createMuiTheme
composant, vous verrez quelque chose comme ceci :
// node_modules/@material-ui/core/styles/createMuiTheme.d.ts
import { Breakpoints, BreakpointsOptions } from './createBreakpoints';
import { Mixins, MixinsOptions } from './createMixins';
import { Palette, PaletteOptions } from './createPalette';
import { Typography, TypographyOptions } from './createTypography';
import { Shadows } from './shadows';
import { Shape, ShapeOptions } from './shape';
import { Spacing, SpacingOptions } from './createSpacing';
import { Transitions, TransitionsOptions } from './transitions';
import { ZIndex, ZIndexOptions } from './zIndex';
import { Overrides } from './overrides';
import { ComponentsProps } from './props';
export type Direction = 'ltr' | 'rtl';
export interface ThemeOptions {
shape?: ShapeOptions;
breakpoints?: BreakpointsOptions;
direction?: Direction;
mixins?: MixinsOptions;
overrides?: Overrides;
palette?: PaletteOptions;
props?: ComponentsProps;
shadows?: Shadows;
spacing?: SpacingOptions;
transitions?: TransitionsOptions;
typography?: TypographyOptions | ((palette: Palette) => TypographyOptions);
zIndex?: ZIndexOptions;
unstable_strictMode?: boolean;
}
export interface Theme {
shape: Shape;
breakpoints: Breakpoints;
direction: Direction;
mixins: Mixins;
overrides?: Overrides;
palette: Palette;
props?: ComponentsProps;
shadows: Shadows;
spacing: Spacing;
transitions: Transitions;
typography: Typography;
zIndex: ZIndex;
unstable_strictMode?: boolean;
}
export default function createMuiTheme(options?: ThemeOptions, ...args: object[]): Theme;
Nous savons maintenant comment nous connecter à ce module et remplir le ThemeOptions
.
Typographie
Il est important d'utiliser la bonne typographie pour un support donné, que ce soit pour les appareils imprimés, numériques, basse/haute résolution.
Une typographie bien définie doit permettre à vos spectateurs de distinguer clairement le contenu et ses formalités. Par exemple, la taille de la police d'une balise H1 doit être visuellement plus grande que celle d'un H2, de même avec H2 vs H3 et ainsi de suite; c'est ce qu'on appelle la "mise à l'échelle des polices". En savoir plus sur le système de type.
Choisissons quelques polices à l'aide de Google Fonts, 1 en gras pour nos titres et une autre pour le reste de notre application.
Étape 1 :Trouvez la police d'en-tête souhaitée
Naviguez dans leur bibliothèque de polices jusqu'à ce que vous en trouviez une que vous aimez (je suis content de "Krona One"). Cliquez ensuite dans la case de la police pour naviguer et en savoir plus sur les détails de la police.
Étape 2 :Ajoutez la police à votre bac "Familles sélectionnées"
En procédant à la sélection de votre police, assurez-vous de cliquer sur "Sélectionner ce style" pour l'ajouter à votre plateau.
Étape 3 :Associez votre police à l'une de leurs suggestions
Une fonctionnalité intéressante fournie par Google Fonts est qu'ils vous donnent une liste d'associations suggestives pour la police que vous avez sélectionnée. Si aucun des appariements ne vous convient, revenez à la page d'accueil et trouvez une autre police. Une fois que vous êtes satisfait, assurez-vous de l'ajouter à votre plateau.
Étape 4 :Intégrez vos polices à votre application
Le plateau "Familles sélectionnées" vous permettra ensuite de revoir vos polices sélectionnées ainsi que de vous présenter comment les intégrer dans votre application. Dans ce cas, j'utiliserais leur proposition <link>
implémentation principalement parce qu'ils fournissent le <link rek="preconnect">
ligne.
Copiez et collez leur extrait de code dans le <head>
bloquer.
// public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="description" content="Web site created using create-react-app" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="msapplication-TileColor" content="#231f20">
<meta name="theme-color" content="#231f20">
<link rel="apple-touch-icon" sizes="76x76" href="/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/site.webmanifest">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#40bfb4">
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Jura&family=Krona+One&display=swap" rel="stylesheet">
<title>Design System | QuinTRON</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>
Cela indique au navigateur de demander nos polices Google lors du chargement initial de l'application. Les polices elles-mêmes ne seront apparentes qu'une fois que nous aurons lié les familles de polices CSS à notre code HTML. Pour ce faire, nous devrons étendre notre thème en ajoutant une configuration Typographie.
Le composant Typography de MUI permet la configuration des variantes suivantes (j'ai ajouté leur mappage d'éléments HTML par défaut sous forme de commentaires en ligne) :
export type Variant =
| 'h1' // maps to <h1>
| 'h2' // maps to <h2>
| 'h3' // maps to <h3>
| 'h4' // maps to <h4>
| 'h5' // maps to <h5>
| 'h6' // maps to <h6>
| 'subtitle1' // maps to <h6>
| 'subtitle2' // maps to <h6>
| 'body1' // maps to <p>
| 'body2' // maps to <p>
| 'caption' // maps to <span>
| 'button' // maps to <button>
| 'overline'; // maps to <span>
Vous pouvez également modifier les mappages HTML par défaut en implémentant l'exemple suivant :
// theme/index.tsx
const theme = createMuiTheme({
props: {
MuiTypography: {
variantMapping: {
body1: 'span', // traditionally set as <p>
body2: 'span', // traditionally set as <p>
}
}
}
});
Nous pouvons créer notre fichier Typographie pour configurer chacune des définitions de variantes.
// stc/theme/typography.tsx
import { TypographyOptions } from '@material-ui/core/styles/createTypography';
export const typography: TypographyOptions = {
h1: { fontFamily: "'Krona One', sans-serif" },
h2: { fontFamily: "'Krona One', sans-serif" },
h3: { fontFamily: "'Krona One', sans-serif" },
h4: { fontFamily: "'Krona One', sans-serif" },
h5: { fontFamily: "'Krona One', sans-serif" },
h6: { fontFamily: "'Krona One', sans-serif" },
subtitle1: { fontFamily: "'Jura', sans-serif" },
subtitle2: { fontFamily: "'Jura', sans-serif" },
body1: { fontFamily: "'Jura', sans-serif" },
body2: { fontFamily: "'Jura', sans-serif" },
caption: { fontFamily: "'Jura', sans-serif" },
button: { fontFamily: "'Jura', sans-serif" },
overline: { fontFamily: "'Jura', sans-serif" },
}
Ajoutez ensuite votre configuration Typographie au module Thème.
// src/theme/index.tsx
import { createMuiTheme } from '@material-ui/core';
import { typography } from './typography';
export default createMuiTheme({
typography
})
Votre police Google est désormais liée aux composants MUI Typography ! Ajoutons du contenu à notre application et testons son apparence.
// src/app.tsx
import { CssBaseline, ThemeProvider } from '@material-ui/core';
import Theme from './theme';
export default function App() {
return (
<ThemeProvider theme={Theme}>
<CssBaseline />
<h1>Heading 1</h1>
<h2>Heading 2</h2>
<h3>Heading 3</h3>
<h4>Heading 4</h4>
<h5>Heading 5</h5>
<h6>Heading 6</h6>
<p>Body content</p>
<button>Button label</button>
<caption>Caption text</caption>
</ThemeProvider>
);
}
Voici à quoi ressemble :
🤔 Hm, je ne vois pas ma police d'en-tête. Ah-huh, c'est parce que j'utilisais les balises HTML par défaut, pas le composant Typography de MUI. Convertissons-les comme ceci :
// src/app.tsx
import { Button, CssBaseline, ThemeProvider, Typography } from '@material-ui/core';
import Theme from './theme';
export default function App() {
return (
<ThemeProvider theme={Theme}>
<CssBaseline />
<Typography variant="h1">Heading 1</Typography>
<Typography variant="h2">Heading 2</Typography>
<Typography variant="h3">Heading 3</Typography>
<Typography variant="h4">Heading 4</Typography>
<Typography variant="h5">Heading 5</Typography>
<Typography variant="h6">Heading 6</Typography>
<Typography variant="body1">Body content 1</Typography>
<Typography variant="body2">Body content 2</Typography>
<Typography variant="subtitle1">Subtitle 1</Typography>
<Typography variant="subtitle2">Subtitle 2</Typography>
<Typography variant="caption">Caption text</Typography>
<Typography variant="overline">Overline text</Typography>
<Button variant="contained">Button Contained</Button>
<Button variant="outlined">Button Outlined</Button>
<Button variant="text">Button Text</Button>
</ThemeProvider>
);
}
Voici à quoi ressemble maintenant :
❤️ Voilà à quoi devraient ressembler les polices !
Échelle des types
La prochaine étape évidente consiste à implémenter la mise à l'échelle des polices dans l'ensemble de notre ensemble de typographies pour assurer la cohérence dans l'ensemble de l'application, pour toutes les tailles et résolutions d'écran.
Taille de la police
Il existe deux façons de définir la taille de la police de votre application :
-
Déclarer manuellement chacune des variantes de taille de police, pour chacun de vos points d'arrêt souhaités dans votre fichier Typography. 😱
-
Utilisation de l'astucieux
responsiveFontSizes
de MUI aide pour le faire pour nous! 🍾
Pour cet exemple, nous implémenterons l'option 2 car elle réduit la quantité de code personnalisé que nous devons maintenir et définit toutes les tailles de police pour nous pour chaque point d'arrêt. Une démo interactive sur le fonctionnement de cette fonctionnalité est disponible ici
Tout ce que nous avons à faire est d'envelopper notre thème avec leur fonction.
// theme/index.tsx
import { createMuiTheme, responsiveFontSizes } from '@material-ui/core';
import { typography } from './typography';
export default responsiveFontSizes(createMuiTheme({
typography
}))
Nos tailles de police sont désormais responsives ! Les captures d'écran suivantes illustrent l'évolution de la taille de police du H1 du mobile au bureau, chacune configurée par rapport aux points d'arrêt petit (sm), moyen (md) et grand (lg).
point d'arrêt:sm
point d'arrêt :md
point d'arrêt :lg
Si vous souhaitez modifier la force de la quantité de redimensionnement de la taille de la police entre les points d'arrêt, vous pouvez ajouter un factor
option au responsiveFontSizes
fonction.
// theme/index.tsx
import { createMuiTheme, responsiveFontSizes } from '@material-ui/core';
import { typography } from './typography';
export default responsiveFontSizes(createMuiTheme({
typography
}), {
factor: 1 // [default is 2] The higher the value, the less difference there is between font sizes on small screens. The lower the value, the bigger font sizes for small screens. The value must be greater than 1.
})
Points d'arrêt
Paramétrage
Le thème de MUI implémente les points d'arrêt par défaut suivants :
- xs, très petit :0px
- petit, petit :600 px
- dm, moyen :960px
- lg, grand :1 280 px
- xl, très grand :1 920 px
Personnellement, je n'ai jamais eu à modifier les paramètres de point d'arrêt, même si vous pouvez les reconfigurer.
Des informations sur la personnalisation des points d'arrêt sont disponibles ici.
Accéder aux points d'arrêt
Lorsque vous arriverez à l'étape de développement des composants, vous devrez éventuellement résoudre des problèmes de mise en page réactive pour rendre votre application accessible et aussi fluide que possible.
MUI vous offre de nombreuses façons de vous connecter à l'état du point d'arrêt du thème, que vous souhaitiez styliser statiquement votre composant et ses changements de point d'arrêt, ou observer les changements de point d'arrêt dans votre composant pour faire quelque chose de logique. Passons en revue quelques exemples.
Requêtes média CSS
Pour cet exemple, imaginez que vous avez un Card
composant qui a un titre, du texte, puis un appel à l'action Button
au fond. Vous êtes ensuite chargé de styliser le bouton par rapport à différents points d'arrêt.
Pseudo train de pensée
- [points d'arrêt égaux ou inférieurs à
sm
] le bouton doit s'étendre sur toute la largeur de la carte, - [points d'arrêt égaux ou supérieurs à
md
] le bouton doit s'ancrer à droite en utilisant sa largeur d'origine. - [points d'arrêt égaux ou supérieurs à
lg
] le bouton doit s'ancrer à droite en utilisant sa largeur d'origine et son rembourrage doit être plus grand.
Implémentation finale
// Example: CSS Media Queries
const styles = theme => ({
button: {
[theme.breakpoints.down('sm')]: {
width: '100%'
},
[theme.breakpoints.up('md')]: {
width: 'auto'
},
[theme.breakpoints.up('lg')]: {
paddingLeft: '4rem',
paddingRight: '4rem'
},
},
});
Quelques points à noter :
breakpoints
est une propriété exposée à partir de notretheme
injecté (via leThemeProvider
HoC)breakpoints
ont 4 fonctions que vous pouvez utiliser pour sélectionner vos points d'arrêt cibles :- theme.breakpoints.up(clé)
- theme.breakpoints.down(clé)
- theme.breakpoints.only(clé)
- theme.breakpoints.between(début, fin)
- Déclarez vos points d'arrêt du plus petit au plus grand afin de conserver le principe de conception Mobile-First de MUI. Si vous ne le faites pas, vous pourriez rencontrer un comportement inattendu.
Requêtes média JS
Pour cet exemple, imaginez que vous avez un Table
qui comporte de nombreuses colonnes et se lit de gauche à droite. Ce tableau se lit très bien sur des écrans plus grands, mais le concepteur a réajusté le tableau pour les écrans mobiles, d'où une deuxième interprétation du Table
doit être rendu dans ce cas.
Pseudo train de pensée
- [points d'arrêt égaux ou inférieurs à
sm
] devrait rendre leMobileTable
, sinon leLargerTable
doit être rendu.
Mise en œuvre finale
// Example: JS Media Queries
import { useTheme } from '@material-ui/core/styles';
import useMediaQuery from '@material-ui/core/useMediaQuery';
function TableWrapper() {
const theme = useTheme();
const mobileBreakpoint = useMediaQuery(theme.breakpoints.down('sm'));
if (mobileBreakpoint) {
return <MobileTable />
}
return <LargerTable />
}
Quelques points à noter :
- Le
useTheme
hook est défini de sorte que leTableWrapper
le composant a accès auTheme
de l'application . - Le
useMediaQuery
hook est défini et paramétré avec mon point d'arrêt souhaité pour le crochet à observer. Sa valeur initiale est soittrue
oufalse
, en fonction des dimensions calculées par les clients. useMediaQuery
observer l'événement Windows Resize et recalculer en interne la valeur des crochets si la valeur actuelle du point d'arrêt du thème change.- Rappelez-vous
breakpoints.down(key)
,breakpoints.up(key)
inclut lekey
dans le cadre de sa vérification booléenne.
En savoir plus sur useMediaQuery
.
Palette de couleurs
La couleur existe et la plupart ont la chance d'être témoins de sa gamme et de ses utilisations dans le monde. S'il est bien utilisé, il peut promouvoir votre marque et rappeler cognitivement aux gens votre marque, il peut indiquer un niveau de gravité et attirer l'œil. En fin de compte, la couleur a un sens.
Le thème de MUI vous permet de configurer une palette, qui est une "intention de couleur" de maquillage. Voici les intentions de couleurs et leurs utilisations.
- principal - utilisé pour représenter les principaux éléments d'interface pour un utilisateur. Il s'agit de la couleur qui s'affiche le plus souvent sur les écrans et les composants de votre application.
- secondaire - utilisé pour représenter des éléments d'interface secondaires pour un utilisateur. Il offre plus de façons d'accentuer et de distinguer votre produit. L'avoir est facultatif.
- erreur - utilisé pour représenter des éléments d'interface dont l'utilisateur doit être informé.
- avertissement - utilisé pour représenter des actions potentiellement dangereuses ou des messages importants.
- informations - utilisé pour présenter à l'utilisateur des informations neutres et pas nécessairement importantes.
- succès - utilisé pour indiquer la réussite d'une action déclenchée par un utilisateur. Si vous souhaitez en savoir plus sur la couleur, vous pouvez consulter la section couleur.
La capture d'écran suivante montre chaque intention de couleur et leurs valeurs par défaut :
Choisir vos couleurs
MUI est le cadeau qui ne cesse de donner ! L'équipe Material Design a créé un "outil de couleur" que vous pouvez utiliser pour brancher vos couleurs spécifiques et les voir visuellement par rapport aux composants de base de MUI. L'outil dispose également d'une fonctionnalité d'accessibilité que je vous encourage à utiliser car elle rendra compte de la lisibilité de vos couleurs.
Conception de matériaux :outil de couleur
Je continuerai à utiliser les couleurs de la marque Mechanical Rock :
- Primaire :#40BFB4
- Secondaire #E15554
L'outil calculera automatiquement les valeurs claires et foncées à partir de la couleur principale que vous avez fournie.
Appliquer la Palette
Une fois que vous avez finalisé vos couleurs primaires et secondaires, vous pouvez ensuite les configurer dans votre thème. Nous allons créer un nouveau fichier Palette pour gérer ce changement (comme nous l'avons fait pour Typographie).
// theme/palette.tsx
import { PaletteOptions } from '@material-ui/core/styles/createPalette';
export const palette: PaletteOptions = {
primary: {
// light: will be calculated from palette.primary.main,
main: '#40bfb4',
// dark: will be calculated from palette.primary.main,
// contrastText: will be calculated to contrast with palette.primary.main
},
secondary: {
// light: will be calculated from palette.primary.main,
main: '#e05450',
// dark: will be calculated from palette.secondary.main,
},
// Used by `getContrastText()` to maximize the contrast between
// the background and the text.
contrastThreshold: 3,
// Used by the functions below to shift a color's luminance by approximately
// two indexes within its tonal palette.
// E.g., shift from Red 500 to Red 300 or Red 700.
tonalOffset: 0.2,
}
Comme le suggèrent les commentaires dans l'extrait de code ci-dessus, vous pouvez laisser MUI calculer gratuitement les valeurs claires/foncées pour vous, sinon ajoutez-les manuellement pour chaque objet primaire et secondaire.
Même si les couleurs que vous avez choisies ont été déclarées éligibles dans "l'outil de couleur", il est toujours possible que votre texte de premier plan ne contraste pas bien avec les nuances d'arrière-plan de vos surfaces. Le contrastThreshold
La propriété vous permet d'amplifier ou d'adoucir le contraste de votre texte par rapport à la couleur d'arrière-plan.
Si vous souhaitez baisser les lumières ou rendre une couleur plus vive lors d'événements tels que le survol d'un bouton, vous pouvez ajuster la quantité par rapport au tonalOffset
propriété.
Ajoutons une section de couleur à notre application en procédant comme suit :
// src/ui/ColourPalette/index.tsx
import React from 'react';
import { Box, Grid, Typography } from '@material-ui/core';
function ColourBox({ intention, variant }: { intention: string; variant: string; }) {
const bgColor = `${intention}.${variant}`;
const color = intention === 'text' ? 'background.paper' : `${intention}.contrastText`;
return (
<Grid item xs={12} sm={4}>
<Box bgcolor={bgColor} color={color} p={4}>
<strong>{bgColor}</strong>
</Box>
</Grid>
)
}
const palette = [
{ intention: 'primary', variant: 'main' },
{ intention: 'secondary', variant: 'main' },
{ intention: 'error', variant: 'main' },
{ intention: 'warning', variant: 'main' },
{ intention: 'info', variant: 'main' },
{ intention: 'success', variant: 'main' },
{ intention: 'text', variant: 'primary' },
{ intention: 'text', variant: 'secondary' },
{ intention: 'text', variant: 'disabled' }
]
export default function ColourPalette() {
return (
<>
<Typography variant="h2">Colour Palette</Typography>
<br />
<Grid container spacing={1}>
{palette.map((p, i) => <ColourBox key={i} {...p} />)}
</Grid>
</>
)
}
Ajoutez ensuite la nouvelle section à notre application :
// src/app.tsx
import { CssBaseline, Divider, ThemeProvider } from '@material-ui/core';
import Theme from './theme';
import ColourPalette from './ui/ColourPalette';
import Typography from './ui/Typographies';
export default function App() {
return (
<ThemeProvider theme={Theme}>
<CssBaseline />
<Typography />
<Divider />
<ColourPalette />
</ThemeProvider>
);
}
Vous devriez finir par voir ceci :
Boutons
MUI propose 3 variantes de boutons, Contenu, Texte, Contour.
Bouton contenu
Les boutons Contenir doivent être utilisés pour les actions de l'utilisateur principal. Ils sont prononcés et surélevés en surface.
Bouton Texte
Les boutons de texte sont généralement utilisés pour des actions moins prononcées, y compris celles situées en Dialogs
et Cards
. Dans les cartes, les boutons de texte aident à maintenir l'accent sur le contenu de la carte.
Bouton avec contour
Les boutons soulignés sont des boutons moyennement accentués. Ils contiennent des actions qui sont importantes, mais qui ne sont pas l'action principale dans une application. Les boutons soulignés sont également une alternative moins accentuée aux boutons contenus, ou une alternative plus accentuée aux boutons de texte.
Ajoutons une section de boutons à notre application en procédant comme suit :
// ui/Buttons/index.tsx
import React from 'react';
import { Button, Container, Typography } from '@material-ui/core';
export default function Buttons() {
return (
<>
<Typography variant="h2">Buttons</Typography>
<br />
<Container maxWidth="xs">
<Typography variant="subtitle1" align="center">Contained</Typography>
<Button variant="contained" color="default">Default</Button>
<Button variant="contained" color="primary">Primary</Button>
<Button variant="contained" color="secondary">Secondary</Button>
<Button variant="contained" color="primary" disabled>Disabled</Button>
</Container>
<br />
<Container maxWidth="xs">
<Typography variant="subtitle1" align="center">Text</Typography>
<Button variant="text" color="default">Default</Button>
<Button variant="text" color="primary">Primary</Button>
<Button variant="text" color="secondary">Secondary</Button>
<Button variant="text" color="primary" disabled>Disabled</Button>
</Container>
<br />
<Container maxWidth="xs">
<Typography variant="subtitle1" align="center">Outlined</Typography>
<Button variant="outlined" color="default">Default</Button>
<Button variant="outlined" color="primary">Primary</Button>
<Button variant="outlined" color="secondary">Secondary</Button>
<Button variant="outlined" color="primary" disabled>Disabled</Button>
</Container>
</>
)
}
N'oubliez pas de l'ajouter à votre App.tsx
fichier pour voir le nouveau contenu !
Nous devrions voir quelque chose comme ceci :
Échafaudez votre application
Définir la mise en page initiale de votre application peut être intimidant. Même si la plupart des mises en page de sites Web sont assez cohérentes de nos jours, il existe plus d'une façon d'écorcher un chat ! Trop d'implémentations de sites Web manquent de HTML bien schématique, ce qui me fait penser qu'il y a un manque de connaissances sur ce sujet. Par exemple, les sites Web qui ont plusieurs balises H1, une hiérarchie d'en-tête brisée, un div
inutile utilisation qui devrait être remplacée par des balises mieux ciblées.
Avant de pouvoir commencer à construire notre mise en page, nous devons savoir où se trouvent les principaux points de repère. La navigation du menu principal sera-t-elle en haut de la page (sera-t-elle corrigée ?) ou sera-t-elle ancrée à gauche de la page ?
Quel type de contenu devez-vous afficher ? Contenu de type blog où le contenu est mieux présenté dans le canal central ou multimédia, où le contenu peut être en mosaïque.
Dans notre cas, l'échafaudage ressemblera à ceci pour mobile :
Et pour le bureau :
Barre d'applications
Créez un nouveau fichier pour gérer votre App Bar :
// src/components/AppBar/index.tsx
import React from 'react';
import { AppBar as MuiAppBar, IconButton, Toolbar, Typography } from '@material-ui/core';
import { MenuRounded } from '@material-ui/icons';
export default function AppBar() {
return (
<MuiAppBar color="primary" position="sticky">
<Toolbar>
<IconButton edge="start" aria-label="menu">
<MenuRounded />
</IconButton>
<Typography variant="h6">
Component Library
</Typography>
</Toolbar>
</MuiAppBar>
)
}
Quelques points à noter :
- Nous devons caster le
AppBar
importé module à un nouveau nomMuiAppBar
afin que nous puissions exporter notre propre version duAppBar
aller de l'avant. - Nous implémentons le
[position="sticky"]
prop contre leMuiAppBar
. C'est ainsi que l'AppBar restera en haut de la fenêtre d'affichage, même lorsque vous faites défiler au-delà de sa position initiale. - Nous implémentons le
[edge="start"]
prop contre leIconButton
. Cela appliquera du CSS pour ancrer l'icône à gauche, moins son décalage de marge d'origine.
Nous nous retrouvons avec ceci :
Contenu du corps
C'est là que la plupart de votre public passera son temps à découvrir, interagir ou rechercher des informations dans votre application. Le contenu du corps lui-même peut obtenir de nombreuses mises en page en interne, mais ce qui est important, sa couche abstraite doit être cohérente.
Créez un nouveau fichier pour gérer votre contenu corporel :
// src/components/BodyContent/index.tsx
import React from 'react';
import { Divider, makeStyles } from '@material-ui/core';
import ColourPalette from '../../ui/ColourPalette';
import Typographies from '../../ui/Typographies';
const useStyles = makeStyles(() => ({
root: {
margin: '0 auto',
maxWidth: '57rem',
padding: '2rem 0'
}
}))
export default function BodyContent() {
const classes = useStyles();
return (
<main className={classes.root}>
<Typographies />
<Divider />
<ColourPalette />
</main>
)
}
Quelques points à noter :
- Nous avons créé notre premier exemple CSS-in-JSS. Nous avons dû le faire pour définir certains styles par rapport à l'élément racine de ce composant,
<main>
.makeStyles
exporter les styles calculés en tant que crochet, lorsque nous avons attribué à une variable étendue nomméeuseStyles
.useStyles
est alors déclaré dans le corps de notreBodyContent
composant afin que nous y ayons accès. margin: '0 auto'
s'assurera que le<main>
le bloc est centré dans la pagemaxWidth: '57rem'
définira la largeur maximale du<main>
bloc, je me sentais représenté une bonne largeur de colonne lisible pour les écrans plus grands.padding: '2rem 0'
appliquera une gouttière cohérente de 2rem en haut et en bas du<main>
bloquer.- Nous avons depuis migré les composants Typographies et ColourPalette du
app.tsx
fichier dans ce fichier. - Notez l'utilisation du HTML
main
Étiquette. Il s'agit d'une balise plus précise à utiliser dans ce cas, car elle encapsule l'intention pour le reste du contenu.
Voici une capture d'écran de bureau montrant le modèle de boîte de notre <main>
élément:
Navigation dans le menu principal
Le menu principal est le principal moyen pour les utilisateurs de naviguer dans votre application. Il doit contenir toutes les zones principales de l'application et indiquer où l'utilisateur se situe actuellement dans la hiérarchie.
Créez un nouveau fichier pour gérer votre navigation dans le menu principal :
// src/components/MainMenu/index.tsx
import React from 'react';
import { Drawer, List, ListItem, ListItemText } from '@material-ui/core';
function MenuItems() {
return (
<List>
{['1', '2', '3'].map(item => (
<ListItem button key={item}>
<ListItemText primary={`Menu Item #${item}`} />
</ListItem>
))}
</List>
)
}
type Props = {
openMenu: boolean;
setOpenMenu: React.Dispatch<React.SetStateAction<boolean>>;
}
export default function MainMenu({ openMenu, setOpenMenu }: Props) {
return (
<nav aria-label="main menu navigation">
<Drawer
anchor="left"
disablePortal
onClose={() => setOpenMenu(false)}
open={openMenu}
variant="temporary"
>
<MenuItems />
</Drawer>
</nav>
);
}
Quelques points à noter :
- Nous utilisons le
Drawer
de MUI composant pour contenir le contenu de nos éléments de menu. [anchor="left"]
prop est utilisé pour déclarer d'où nous voudrions que la transition Menu it s'effectue.- J'ai personnellement déclaré
[disablePortal=true]
ici pour que le HTML vive à l'intérieur du<nav>
élément, le rendant ainsi plus accessible et schématiquement correct. - Le
onClose
la fonction de rappel n'est invoquée que si l'écouteur de clic d'arrière-plan est présent ; fixé par le[variant="temporary"]
propriété. [open=true]
fera la transition vers l'intérieur du menu et l'inverse fera la transition vers la sortie du menu.
Nous devons ensuite colocaliser le MainMenu
avec notre AppBar
composant car il a le Menu
bouton que nous devons câbler.
// src/components/AppBar/index.tsx
import React from 'react';
import { AppBar as MuiAppBar, IconButton, Toolbar, Typography } from '@material-ui/core';
import { MenuRounded } from '@material-ui/icons';
import MainMenu from '../MainMenu';
export default function AppBar() {
const [openMenu, setOpenMenu] = React.useState(false);
return (
<>
<MuiAppBar color="primary" position="sticky">
<Toolbar>
<IconButton
edge="start"
aria-label="menu"
onClick={() => setOpenMenu(state => !state)}
>
<MenuRounded />
</IconButton>
<Typography variant="h6">
Component Library
</Typography>
</Toolbar>
</MuiAppBar>
<MainMenu openMenu={openMenu} setOpenMenu={setOpenMenu} />
</>
)
}
On finit par ça :
🙏 Clôture
À ce stade, votre application doit être enveloppée avec un fournisseur de thèmes.
Vous devez avoir suffisamment de connaissances sur la façon de remplacer les styles des composants MUI ainsi que sur la façon de créer vos propres styles à côté de vos propres composants.
Vous êtes maintenant prêt à passer au prochain épisode dans lequel je vous expliquerai comment implémenter le routage dans votre application, en abordant les sujets suivants :
- Comment configurer le routage dans votre application,
- Routes avec paramètres,
- Acheminer les crochets,
- Transitions de routage
Ne soyez pas timide, contactez-nous !