Retour d'XP sur Chakra UI
Une lib de composants modulaire, accessible et typée
Godefroy de Compreignac, co-fondateur @ Lonestone
Meetup React Nantes - 31 mars 2022
Vous connaissez peut-être
Material UI
Ant Design
Semantic UI
Reakit
Element UI
Grommet
...
Ces libs sont très pratiques,
mais elles m'ont parfois
donné du fil à retordre...
Manque de modularité
-> Styling différent pour les composants custom
Manque de composants (Reakit)
-> Apport de composants avec un style différent ou une mauvaise accessibilité
Styling difficile à maintenir
avec CSS modules, CSS-in-JS (Material)
ou styled components
Personnalisation difficile des balises contenues dans certains composants (Ant Design)
-> Hacks bizarres pour personnaliser comme on veut
J'aime bien l'approche de Tailwind
qui aide à aller vite, mais :
- Pas de logique intégrée (@headlessui/react nécessaire)
- Pas d'autocomplétion sans extension d'éditeur
Et puis j'ai découvert Chakra UI
Un petit nouveau qui cartonne !

J'ai choisi Chakra pour développer
mon dernier SaaS :
Rolebase.io
(pas encore annoncé et pas de page
de présentation pour le moment)
➕
Développement commencé de plusieurs webapps avec Chakra chez Lonestone
Installation
npm i @chakra-ui/react @emotion/react@^11 @emotion/styled@^11 framer-motion@^6import { ChakraProvider } from '@chakra-ui/react'
ReactDOM.render(
<ChakraProvider>
<App />
</ChakraProvider>,
document.getElementById('root'),
)Chakra a besoin de emotion (styled) et de framer-motion,
mais on a rarement besoin de les utiliser explicitement.
FORMS
Button
Checkbox
Editable
Form Control
Icon Button
Input
Number Input
Pin Input
Radio
Range Slider
Select
Slider
Switch
Textarea
Composants principaux
LAYOUT
Aspect Ratio
Box
Center
Container
Flex
Grid
SimpleGrid
Stack
Wrap
DATA DISPLAY
Badge
Code
Divider
Kbd
List
Stat
Table
Tag
FEEDBACK
Alert
Circular Progress
Progress
Skeleton
Spinner
Toast
TYPOGRAPHY
Text
Heading
OVERLAY
Alert Dialog
Drawer
Menu
Modal
Popover
Tooltip
DISCLOSURE
Accordion
Tabs
Visually Hidden
NAVIGATION
Breadcrumb
Link
LinkOverlay
MEDIA AND ICONS
Avatar
Icon
Image
OTHER
Close Button
Portal
Show / Hide
Transitions
La brique de base, c'est <Box>.
Le style se fait par les props :
<Box padding="10px" background="#eee">
Lorem ipsum
</Box>Mais rien à voir avec style={{ ... }}
Des classes CSS sont automatiquement
gérées sous le capot par emotion.
On peut utiliser des raccourcis à la Tailwind :
<Box p="10px" bg="#eee">
Lorem ipsum
</Box>On trouve en général les raccourcis intuitivement :
- m = margin
- mt = margin-top
- mr = margin-right
- mb = margin-bottom
- ml = margin-left
- p = padding
- pt = t'as deviné...
- bg = background
- w = width
- h = height
Le typing est 👌👌👌

Les valeurs en dur, on va éviter !
On utilise autant que possible des valeurs du thème :
<Box p={3} bg="gray.200">
Lorem ipsum
</Box>-> Marges, couleurs, polices, radius, tout est configurable dans un thème centralisé et typé.
Il y aussi tout un tas de props pour styliser en fonction de pseudo-sélecteurs ou de l'état des composants :
_hover, _checked, _dark, _light...
<Box
p={3}
bg="gray.200"
_hover={{
bg: 'gray.300',
}}
>
Lorem ipsum
</Box>
Comment intégrer ça ?
import * as React from 'react'
import { Box, Center, Image, Flex, Badge, Text } from '@chakra-ui/react'
import { MdStar } from 'react-icons/md'
export default function Card() {
return (
<Center h="100vh">
<Box p="5" maxW="320px" borderWidth="1px">
<Image borderRadius="md" src="photo.jpg" />
<Flex align="baseline" mt={2}>
<Badge colorScheme="pink">Plus</Badge>
<Text
ml={2}
textTransform="uppercase"
fontSize="sm"
fontWeight="bold"
color="pink.800"
>
Verified • Cape Town
</Text>
</Flex>
<Text mt={2} fontSize="xl" fontWeight="semibold" lineHeight="short">
Modern, Chic Penthouse with Mountain, City & Sea Views
</Text>
<Text mt={2}>$119/night</Text>
<Flex mt={2} align="center">
<Box as={MdStar} color="orange.400" />
<Text ml={1} fontSize="sm">
<b>4.84</b> (190)
</Text>
</Flex>
</Box>
</Center>
)
}
Pour étendre le thème :
import { extendTheme } from '@chakra-ui/react'
const theme = extendTheme({
config: {
initialColorMode: 'light',
useSystemColorMode: false,
},
colors: {
black: '#37352f',
},
shadows: {
outline: '0 0 3px 0px #000',
},
components: {
Link: {
baseStyle: {
textDecoration: 'underline',
},
},
},
})
export default theme
<ChakraProvider theme={theme}>Et on le fournit au provider :
Le "color mode" pour faire un thème dark/light est facile à utiliser.
import { MenuItem, useColorMode } from '@chakra-ui/react'
import React from 'react'
import { FiMoon, FiSun } from 'react-icons/fi'
export default function ThemeToggle() {
const { colorMode, toggleColorMode } = useColorMode()
return (
<MenuItem
icon={colorMode === 'light' ? <FiSun /> : <FiMoon />}
onClick={toggleColorMode}
>
Thème clair/sombre
</MenuItem>
)
}

<Box
p={3}
bg="gray.200"
_dark={{
bg: 'gray.600',
}}
>
Lorem ipsum
</Box>Exemple de composant custom avec dark theme :
Des features bien pensées
et extensibles.
Par exemple pour les boutons :
<Stack direction='row' spacing={4}>
<Button colorScheme='green' variant='solid'>
Button
</Button>
<Button colorScheme='blue' variant='outline'>
Button
</Button>
<Button colorScheme='red' variant='ghost'>
Button
</Button>
<Button colorScheme='teal' leftIcon={<ArrowForwardIcon />}>
Button
</Button>
</Stack>
Comment étendre un composant ?
Une manière que j'aime bien :
import { Button, ButtonProps } from '@chakra-ui/react'
import { CircleWithRoleEntry } from '@shared/circle'
import React from 'react'
import CircleMemberLink from './CircleMemberLink'
interface Props extends ButtonProps {
circle: CircleWithRoleEntry
}
export default function CircleButton({ circle, ...buttonProps }: Props) {
return (
<CircleMemberLink circleId={circle.id} tabIndex={-1}>
<Button size="sm" borderRadius="full" {...buttonProps}>
{circle.role.name}
</Button>
</CircleMemberLink>
)
}
Quelques hooks inclus bien utiles
En particulier :
-
useDisclosure pour les modales
-
useDimensions pour observer les dimensions d'un élément
-
useBreakpointValue pour faire des variants en fonction de breakpoints
-
useMediaQuery pour détecter des tailles et types d'écran
- useOutsideClick pour détecter un click en dehors d'un élément
J'ai beaucoup aimé utiliser Chakra,
je trouve que j'obtiens du code :
- Concis
- Modulaire
- Bien typé
- Avec peu de redondance
et une UI :
- Cohérente
- Accessible

Il y a un kit Figma pour nos amis designers :
Merci !
Vous avez des questions ?
Je suis Godefroy de Compreignac, co-fondateur de Lonestone.
Si ça vous a plu, suivez-moi sur Twitter @Godefroy
et Linkedin, mettez un pouce bleu, postulez chez Lonestone
Slides : https://lone-stone.slides.com/lonestone/chakra-ui
Chakra UI : https://chakra-ui.com/
Sources Rolebase : https://github.com/lonestone/rolebase.io
Retour d'XP sur Chakra UI
By lonestone
Retour d'XP sur Chakra UI
- 332