Одно из лучших достоинств сайта Next.js — оптимальный и минималистичный дизайн. Он не содержит ничего лишнего и обеспечивает простую навигацию.
Однако воспроизвести их эстетику невероятно сложно. Стилизация и отзывчивый дизайн требуют написания тонн кода.
И вот тут самое время рассказать о библиотеке Geist UI, которая предоставляет набор компонентов, созданных на основе дизайна Vercel. С ее помощью вы также сможете менять темы, ограничиваясь лишь небольшими объемами кода.
Из статьи вы узнаете принципы использования пакета Geist UI. А итогом нашей работы станет следующий результат:
Начало
Инициализация проекта
Создаем проект React, выполняя команду терминала:
npx create-react-app geist-tutorial
Далее устанавливаем для приложения необходимые зависимости.
Установка модулей
Требуемые пакеты:
@geist-ui/react
: основная зависимость проекта.@geist-ui/react-icons
: обеспечивает доступ к набору иконок библиотеки.
Выполняем следующую команду и получаем эти зависимости:
npm i @geist-ui/react @geist-ui/react-icons
Стандартные компоненты
Текст
Компонент Text
позволяет отображать стандартный текст и присваивать ему стили.
В каталоге src
создаем файл TextExample.js
и прописываем такой код:
import { Text } from "@geist-ui/react";
export default function TextExample() {
return (
<div>
<Text>Standard Text page </Text>
<Text h1>Next.js</Text>
<Text size="2em">The React Framework for production </Text>
<Text b>Great for blogs</Text>
<Text blockquote> Incredibly easy</Text>
<Text type="success"> Try it out</Text>
</div>
);
}
- Строка 6: Создаем стандартный элемент
Text
без стиля. - Строка 7: Свойство
h1
дает указание React отобразить заголовокh1
. - Строка 8: Увеличиваем размер текста до
2em
. - Строка 11: Свойство
type
изменяет цветText
.
На последнем этапе нужно отобразить TextExample
в DOM. Для этого переходим в App.js
и пишем код:
import { GeistProvider, CssBaseline } from "@geist-ui/react";
import TextExample from "./TextExample";
function App() {
return (
<div className="App">
<GeistProvider>
<CssBaseline />
<TextExample />
</GeistProvider>
</div>
);
}
export default App;
- Строка 6: Обертываем пользовательским компонентом теги
GeistProvider
, таким образом применяя темы и стили к странице. - Строка 7: Элемент
CSSBaseline
нормализует стили. - Строка 8: Наконец, отображаем компонент
TextExample
.
Получаем следующий результат:
Выглядит отлично! Далее знакомимся с кнопками.
Кнопка
В каталоге src
создаем файл ButtonExample.js
, в котором прописываем код:
import { Button, Text } from "@geist-ui/react";
import { useState } from "react";
export default function ButtonExample() {
const [number, setNumber] = useState(0);
return (
<div>
<Text>{number}</Text>
<Button
size="small"
type={"success"}
onClick={() => setNumber((number) => number + 1)}
>
+
</Button>
<Button
size="large"
type={"error"}
ghost
onClick={() => setNumber((number) => number - 1)}
>
-
</Button>
</div>
);
}
- Строка 8: Отображаем значение хука
number
. - Lines 9–13: Отрисовываем компонент
Button
размераsmall
и меняем его цвет. При нажатии значение переменнойnumber
увеличивается. - Строка 16–21: Отрисовываем компонент
Button
размераlarge
и меняем его цвет. При нажатии значениеnumber
уменьшается.
Итоговый результат:
Отлично! Код работает. Можно отключить функцию нажатия кнопки через свойство disabled
:
<Button disabled> Click me</Button>
Далее займемся кодом для вывода изображений.
Изображения
Для этого пишем следующий код:
import { Image, Text } from "@geist-ui/react";
export default function ImageExample() {
return (
<div>
<Text>A keyboard:</Text>
<Image
width={540}
height={160}
src="https://wallpapercave.com/wp/wp4947509.jpg"
/>
</div>
);
}
- Строки 8–9: Свойства
width
иheight
изменяют размеры изображения.
По умолчанию при чрезмерно долгой загрузке React отобразит плейсхолдер skeleton
. С помощью Deelay возможна имитация разных типов интернет-соединения.
return (
<div>
<Text>A keyboard(delayed):</Text>
<Image
width={540}
height={160}
src="https://deelay.me/3000/https://wallpapercave.com/wp/wp4947509.jpg"
/>
</div>
);
- Строка 7: Выводим изображение через 3 секунды.
Полученный результат:
Компонент Display
позволяет добавлять подписи к изображениям.
import { Image, Text, Display } from "@geist-ui/react";
export default function ImageExample() {
return (
<div>
<Text>A keyboard:</Text>
<Display caption={<Text> A simple Windows keyboard</Text>}>
<Image
width={540}
height={160}
src="https://deelay.me/3000/https://wallpapercave.com/wp/wp4947509.jpg"
/>
</Display>
</div>
);
}
- Строка 7: С помощью свойства
caption
добавляем подпись.
Код превосходно работает!
Помимо этого, можно добавить к изображениям рамку в стиле браузера:
<Image.Browser url="https://medium.com/">
<Image
width={540}
height={160}
src="https://wallpapercave.com/wp/wp4947509.jpg"
/>
</Image.Browser>
Свойство url
в Image.Browser
инструктирует React — при нажатии пользователем на изображение перенаправить его к указанному URL.
Иконки
Компонент Geist Icon
отображает графику SVG, предоставляя удобный способ взаимодействия с данными.
Напишем код для отрисовки простой иконки:
import { Text } from "@geist-ui/react";
import * as Icon from "@geist-ui/react-icons";
export default function IconExample() {
return (
<div>
<Text>Go down</Text>
<Icon.ArrowDown size="8em" />
<Icon.ArrowUp color="blue" size="8em" />
<Text>
Follow us on :<Icon.Facebook />
</Text>
<Text>
Or <Icon.Instagram />
</Text>
</div>
);
}
- Строка 8: Отрисовываем иконку
ArrowDown
и увеличиваем ее размер до8em
. - Строка 9: Отрисовываем иконку
ArrowUp
и меняем ее цвет наblue
.
Получаем результат:
Используя свойство icon
, можно отрисовывать иконки в Button
:
<Button icon={<Icon.ArrowUp />} type="success">
Go up
</Button>
Спиннер загрузки
Показывает пользователю иконку “загрузки”, сообщая ему о том, что данные загружаются.
В каталоге src
создаем файл SpinnerExample.js
, где прописываем код:
import { Text, Spinner } from "@geist-ui/react";
import { useEffect, useState } from "react";
export default function SpinnerExample() {
const [loading, setLoading] = useState(true);
useEffect(() => {
setTimeout(() => setLoading(false), 2 * 1000);
}, []);
return (
<div>{loading ? <Spinner size="large" /> : <Text> Loaded!</Text>}</div>
);
}
- Строка 7: Через 2 секунды устанавливаем для хука
loading
значениеfalse
. - Строка 11: Используем условную отрисовку. Если
loading
—true
, отображаем иконкуSpinner
, в противном случае сообщаем пользователю о завершении загрузки приложения.
А вот и результат кода:
Данный раздел статьи исчерпан! Рассмотрим применение Geist для создания отзывчивых интерфейсов.
Отзывчивые макеты
Отзывчивый дизайн позволяет создавать веб-страницы, которые подстраиваются под устройство. При правильной настройке они будут великолепно смотреться на таких устройствах, как мобильные телефоны, планшеты и стационарные компьютеры.
Сначала познакомимся с элементом Grid
.
Grid-контейнеры
Grid-контейнер идентичен свойству grid
в CSS. Создаем файл GridExample.js
и пишем в нем код:
import { Text, Grid } from "@geist-ui/react";
function MockComponent({ number }) {
return (
<div style={{ backgroundColor: "blue", width: "100%", height: "100px" }}>
<Text>{number}</Text>
</div>
);
}
export default function GridExample() {
return (
<div>
<Grid.Container gap={3} justify="center">
<Grid sm={6} xs={2}>
<MockComponent number={1} />
</Grid>
<Grid sm={6} xs={2}>
<MockComponent number={2} />
</Grid>
<Grid sm={6} xs={2}>
<MockComponent number={3} />
</Grid>
</Grid.Container>
</div>
);
}
- Строка 14: Между элементами в
Grid
устанавливаем расстояние в 3 единицы. Свойствоjustify
выравнивает эти элементы по центру. - Строка 15: На маленьких экранах и побольше (контрольная точка прерывания
sm
) размер элемента составляет 6 единиц. В случае совсем маленького устройства (контрольная точка прерыванияxs
), уменьшаем элемент до 2 единиц. - Строка 16: Отрисовываем
MockComponent
в контейнереGrid
.
Поздравляю — отлично работающий код!
Если нужен гибкий макет, предлагаю для него несколько строк кода:
return (
<div>
<Grid.Container gap={3} justify="center">
<Grid sm={10} xs={2}>
<MockComponent number={1} />
</Grid>
<Grid sm={6} xs={2}>
<MockComponent number={2} />
</Grid>
<Grid sm={9} xs={2}>
<MockComponent number={3} />
</Grid>
<Grid xs>
<MockComponent number={4} />
</Grid>
</Grid.Container>
</div>
);
- Строка 13: Оставляем свойство
xs
пустым, тем самым обеспечивая автоматическое заполнение остающегося пространства.
Переходим к компоненту Spacer
.
Компонент Spacer
Рассмотрим данный фрагмент кода:
return (
<div>
<Button type="success" />
<Button type="error" />
</div>
);
Здесь мы отобразили две кнопки Buttons
разных цветов.
Вид будет намного лучше, если расположить их на разных строках. Для этого воспользуемся компонентом Spacer
:
import { Spacer, Button } from "@geist-ui/react";
export default function SpacerExample() {
return (
<div>
<Button type="success" />
<Spacer y={4} />
<Button type="error" />
</div>
);
}
- Строка 7: Между компонентами по оси
y
должно быть расстояние в 4 единицы.
Можно даже обеспечить расстояние между элементами по горизонтали, обернув их тегами Container
:
return (
<Container>
<Button type="success" />
<Spacer x={4} />
<Button type="error" />
</Container>
);
Дополнительные полезные функциональности
Сворачиваемый и раскрывающийся текст
Компонент Collapse
позволяет отображать большие объемы текста в секциях сворачивания/разворачивания. Для его отрисовки пишем следующий код:
import { Collapse, Text } from "@geist-ui/react";
export default function CollapseExample() {
return (
<div>
<Collapse.Group>
<Collapse title="How are you?">
<Text> I'm fine!</Text>
<Text b> How are you though?</Text>
</Collapse>
<Collapse title="What is your website">
<Text> It's on Medium</Text>
</Collapse>
</Collapse.Group>
</div>
);
}
- Строка 6: Отображаем
Collapse.Group
. Здесь мы объединим все секции. - Строка 7: Отрисовываем первый
Collapse
и указываем его название с помощью свойстваtitle
.
Можно добавить и подзаголовки:
return (
<div>
<Collapse.Group>
<Collapse title="How are you?" subtitle="The definite answer">
<Text> I'm fine!</Text>
<Text b> How are you though?</Text>
</Collapse>
<Collapse
title="What is your website"
subtitle={<Text b> The definite answer</Text>}
>
<Text> It's on Medium</Text>
</Collapse>
</Collapse.Group>
</div>
);
- Строки 4 и 10: Указываем подзаголовки, используя свойство
subtitle
.
Полученный результат:
Всплывающие сообщения
Хук useToasts
позволяет показывать всплывающие сообщения.
import { Button, useToasts } from "@geist-ui/react";
export default function ToastExample() {
const [toast, setToast] = useToasts();
const click = () => {
setToast({ text: "Lorem ipsum" });
};
return (
<div>
<Button onClick={() => click()}> Display</Button>
</div>
);
}
- Строка 12: При нажатии на кнопку вызывается метод
click
, что приводит к появлению всплывающего сообщения.
Можем поиграть с цветами этих сообщений:
import { Button, useToasts } from "@geist-ui/react";
export default function ToastExample() {
const [toast, setToast] = useToasts();
const click = (type) => {
setToast({ text: "Lorem ipsum", type });
};
return (
<div>
<Button onClick={() => click("secondary")}> Display</Button>
<Button onClick={() => click("error")}> Show error</Button>
</div>
);
}
- Строка 12: Отрисовываем сообщение типа
secondary
. - Строка 13: При нажатии на кнопку отображается сообщение типа
error
.
Смена тем
С Geist относительно легко менять темы. Прямо сейчас узнаем, как переключаться между светлой и темной.
В App.js
пишем следующий код:
import { GeistProvider, CssBaseline, Button } from "@geist-ui/react";
import ToastExample from "./ToastExample";
import { useState } from "react";
function App() {
const [theme, setTheme] = useState("light");
const changeTheme = () => {
setTheme((last) => (last === "dark" ? "light" : "dark"));
};
return (
<div className="App">
<GeistProvider themeType={theme}>
<CssBaseline />
<Button onClick={() => changeTheme()}> Change themes</Button>
<ToastExample />
</GeistProvider>
</div>
);
}
export default App;
- Строка 6: Создаем состояние
theme
. Его начальным значением будетlight
. - Строки 8–10: Если текущее значение
theme
—dark
, то меняем его наlight
и наоборот. - Строка 15: При нажатии вызывается метод
changeTheme
, а тема переключается.
Дополнительные ресурсы
Код GitHub
Материал для дальнейшего чтения
Заключение
Если вам нужен набор компонентов UI, которые и выглядят отлично, и ресурсов много не требуют, то библиотека Geist UI превосходно подходит для веб-приложения. К тому же вам не придется писать тонны кода для переключения тем — а это преимущество что надо.
Благодарю за внимание!
Читайте также:
- Знакомство с библиотекой Styled Components в React
- React и Firebase —это всё, что вам нужно для хостинга веб-приложений
- Экспорт данных в Excel с React
Читайте нас в Telegram, VK и Яндекс.Дзен
Перевод статьи Hussain Arif: Build Beautiful UIs in React With Geist UI