@localzet/ui-kit
v1.0.9
Published
UI Kit библиотека компонентов на основе Mantine для проектов Localzet
Downloads
347
Maintainers
Readme
@localzet/ui-kit
UI Kit библиотека компонентов на основе Mantine для проектов Localzet. Единая система дизайна и компонентов, собранная из лучших практик проектов ЛК (frontend) и Агрегатор (kimai-aggregator).
Установка
npm install @localzet/ui-kit
# или
yarn add @localzet/ui-kit
# или
pnpm add @localzet/ui-kitТребования
- React 18.2.0 или выше
- @mantine/core ^8.3.6
- @mantine/hooks ^8.3.6
Быстрый старт
1. Импортируйте стили Mantine
В вашем главном файле приложения (например, main.tsx или App.tsx) импортируйте необходимые стили Mantine:
import '@mantine/core/styles.css'
import '@mantine/dates/styles.css'
import '@mantine/charts/styles.css'
import '@mantine/notifications/styles.css'
import '@mantine/nprogress/styles.css'
// ... другие стили Mantine, которые вы используете2. Импортируйте глобальные стили UI-Kit
import '@localzet/ui-kit/styles'3. Настройте MantineProvider с темой
import { MantineProvider } from '@mantine/core'
import { theme } from '@localzet/ui-kit'
function App() {
return (
<MantineProvider theme={theme} defaultColorScheme="dark">
{/* Ваше приложение */}
</MantineProvider>
)
}Структура
UI-Kit разделен на несколько категорий:
- Components (
@localzet/ui-kit) - Основные UI компоненты - Layouts (
@localzet/ui-kit) - Компоненты для структуры страниц - Theme (
@localzet/ui-kit/theme) - Тема Mantine
Компоненты
LoadingScreen
Компонент для отображения экрана загрузки с прогресс-баром.
import { LoadingScreen } from '@localzet/ui-kit'
function MyComponent() {
return (
<LoadingScreen
height="100dvh"
text="Загрузка..."
value={75}
/>
)
}Props:
height?: string- Высота контейнера (по умолчанию:'100dvh')text?: string- Текст для отображенияvalue?: number- Значение прогресса от 0 до 100 (по умолчанию:100)
PageHeader
Компонент заголовка страницы с иконкой, заголовком, описанием и действиями.
import { PageHeader } from '@localzet/ui-kit'
import { IconSettings } from '@tabler/icons-react'
import { Button } from '@mantine/core'
function MyPage() {
return (
<PageHeader
icon={<IconSettings />}
title="Настройки"
description="Управление настройками приложения"
actions={
<>
<Button variant="light">Сохранить</Button>
<Button>Отмена</Button>
</>
}
/>
)
}Props:
icon: ReactNode- Иконка для отображенияtitle: ReactNode- Заголовокdescription?: string- Описание под заголовкомactions?: ReactNode- Действия (кнопки и т.д.)- Все остальные props передаются в
Cardиз Mantine
CopyableField
Поле ввода с возможностью копирования значения в буфер обмена.
import { CopyableField } from '@localzet/ui-kit'
function MyComponent() {
return (
<CopyableField
label="API ключ"
value="sk-1234567890abcdef"
size="md"
/>
)
}Props:
label?: string- Метка поляvalue: number | string- Значение для копированияleftSection?: ReactNode- Левая секция (иконка и т.д.)size?: 'lg' | 'md' | 'sm' | 'xl' | 'xs'- Размер поля
InfoField
Компонент для отображения пары "метка-значение".
import { InfoField } from '@localzet/ui-kit'
function MyComponent() {
return (
<InfoField
label="Статус"
value="Активен"
/>
)
}Props:
label: string- Меткаvalue: ReactNode- Значение (может быть любым React-элементом)
ModalFooter
Футер для модальных окон с адаптивной версткой.
import { Modal, Button } from '@mantine/core'
import { ModalFooter } from '@localzet/ui-kit'
function MyModal() {
return (
<Modal opened={opened} onClose={close}>
<Modal.Body>Содержимое модалки</Modal.Body>
<ModalFooter>
<Button variant="light">Отмена</Button>
<Button>Сохранить</Button>
</ModalFooter>
</Modal>
)
}Props:
children: ReactNode- Содержимое футера (обычно кнопки)
DrawerFooter
Футер для Drawer с адаптивной версткой.
import { Drawer, Button } from '@mantine/core'
import { DrawerFooter } from '@localzet/ui-kit'
function MyDrawer() {
return (
<Drawer opened={opened} onClose={close}>
<Drawer.Body>Содержимое drawer</Drawer.Body>
<DrawerFooter>
<Button variant="light">Отмена</Button>
<Button>Сохранить</Button>
</DrawerFooter>
</Drawer>
)
}Props:
children: ReactNode- Содержимое футера
StickyHeader
Липкий заголовок, который остается видимым при прокрутке.
import { StickyHeader } from '@localzet/ui-kit'
function MyComponent() {
return (
<StickyHeader offset={10}>
<h1>Заголовок</h1>
</StickyHeader>
)
}Props:
offset?: number- Отступ в пикселях для активации (по умолчанию:2)- Все остальные props передаются в
Boxиз Mantine
SettingsCard
Набор компонентов для создания карточек настроек.
import {
SettingsCardContainer,
SettingsCardHeader,
SettingsCardContent,
SettingsCardBottom
} from '@localzet/ui-kit'
import { IconSettings } from '@tabler/icons-react'
import { Button, Switch } from '@mantine/core'
function MySettings() {
return (
<SettingsCardContainer>
<SettingsCardHeader
icon={<IconSettings />}
title="Настройки уведомлений"
description="Управление уведомлениями"
/>
<SettingsCardContent>
<Switch label="Email уведомления" />
<Switch label="Push уведомления" />
</SettingsCardContent>
<SettingsCardBottom>
<Button>Сохранить</Button>
</SettingsCardBottom>
</SettingsCardContainer>
)
}Компоненты:
SettingsCardContainer- Контейнер карточкиSettingsCardHeader- Заголовок с иконкой и описаниемSettingsCardContent- Основное содержимоеSettingsCardBottom- Нижняя секция с разделителем
Table
Компоненты для работы с таблицами.
import { TableContainer, TableCardTitle } from '@localzet/ui-kit'
import { IconTable } from '@tabler/icons-react'
import { Button } from '@mantine/core'
function MyTable() {
return (
<TableContainer>
<TableCardTitle
icon={<IconTable />}
title="Список пользователей"
description="Все пользователи системы"
actions={<Button>Добавить</Button>}
/>
{/* Ваша таблица */}
</TableContainer>
)
}Компоненты:
TableContainer- Контейнер для таблицыTableCardTitle- Заголовок таблицы с иконкой и действиями
UnderlineShape
Декоративный SVG-элемент для подчеркивания.
import { UnderlineShape } from '@localzet/ui-kit'
function MyComponent() {
return (
<div>
<h1>Заголовок</h1>
<UnderlineShape size={100} color="cyan" />
</div>
)
}Props:
size?: number | string- Размер SVG- Все остальные props передаются в
Boxиз Mantine
CheckboxCard
Карточка с чекбоксом для выбора опций.
import { CheckboxCard } from '@localzet/ui-kit'
function MyComponent() {
return (
<CheckboxCard
label="Опция 1"
description="Описание опции"
checked={isChecked}
onChange={(e) => setIsChecked(e.currentTarget.checked)}
/>
)
}Props:
label?: string- Метка карточкиdescription?: string- Описание- Все остальные props передаются в
Checkbox.Cardиз Mantine
CopyableArea
Текстовая область с возможностью копирования.
import { CopyableArea } from '@localzet/ui-kit'
function MyComponent() {
return (
<CopyableArea
label="Конфигурация"
value="some long text to copy..."
/>
)
}Props:
label?: string- Метка поляvalue: number | string- Значение для копирования
Logo
SVG логотип компонент.
import { Logo } from '@localzet/ui-kit'
function MyComponent() {
return <Logo size={32} color="cyan" />
}Props:
size?: number | string- Размер логотипа- Все остальные props передаются в
Boxиз Mantine
LoaderModal
Компонент загрузки для модальных окон.
import { LoaderModal } from '@localzet/ui-kit'
function MyModal() {
return (
<LoaderModal
text="Загрузка данных..."
h="80vh"
w="100%"
/>
)
}Props:
text?: string- Текст под индикатором загрузки- Все остальные props передаются в
Centerиз Mantine
PopoverWithInfo
Поповер с информационной иконкой.
import { PopoverWithInfo } from '@localzet/ui-kit'
function MyComponent() {
return (
<PopoverWithInfo
position="right"
text="Дополнительная информация о функции"
/>
)
}Props:
position?: 'bottom' | 'left' | 'right' | 'top'- Позиция поповераtext: ReactNode- Текст для отображения
CreateableTagInput
Поле ввода для создания и выбора тегов.
import { CreateableTagInput } from '@localzet/ui-kit'
function MyComponent() {
const [tags, setTags] = useState(['TAG1', 'TAG2'])
const [value, setValue] = useState<string | null>(null)
return (
<CreateableTagInput
tags={tags}
value={value}
onChange={setValue}
label="Tag"
placeholder="EXAMPLE_TAG_1"
/>
)
}Props:
tags: string[]- Список доступных теговvalue: string | null | undefined- Текущее значениеonChange?: (value: string | null) => void- Callback при измененииdefaultValue?: string | null- Значение по умолчаниюlabel?: string- Метка поляdescription?: string- Описаниеplaceholder?: string- Placeholdererror?: string- Ошибка валидацииvalidateTag?: (tag: string) => string | null- Кастомная валидация
MetricCard
Комплексный компонент для отображения метрик с различными вариантами.
import { MetricCard } from '@localzet/ui-kit'
import { IconUsers } from '@tabler/icons-react'
function MyComponent() {
return (
<MetricCard.Root>
<MetricCard.Icon c="cyan">
<IconUsers />
</MetricCard.Icon>
<MetricCard.TextMuted>Total Users</MetricCard.TextMuted>
<MetricCard.TextEmphasis>1,234</MetricCard.TextEmphasis>
<MetricCard.TextTrend value={12}>vs last month</MetricCard.TextTrend>
</MetricCard.Root>
)
}Компоненты:
MetricCard.Root- Корневой контейнерMetricCard.Icon- Иконка с градиентным фономMetricCard.TextMuted- Приглушенный текстMetricCard.TextEmphasis- Акцентный текстMetricCard.TextTrend- Тренд с иконкой и значениемMetricCard.RingProgress- Кольцевой прогрессMetricCard.BarChart- Столбчатая диаграмма
MetricWithTrend
Готовый компонент метрики с трендом.
import { MetricWithTrend } from '@localzet/ui-kit'
import { IconUsers } from '@tabler/icons-react'
function MyComponent() {
return (
<MetricWithTrend
title="Total Users"
value="1,234"
difference={12}
period="vs last month"
icon={<IconUsers />}
/>
)
}Props:
title: string- Заголовок метрикиvalue: number | string- Значениеdifference: number | string- Разница (для тренда)period?: string- Период сравненияicon: ReactNode- Иконка
SidebarLogo
Логотип для сайдбара с поддержкой кастомного изображения.
import { SidebarLogo } from '@localzet/ui-kit'
function MySidebar() {
return (
<SidebarLogo
logoUrl="https://example.com/logo.png"
fallbackLogo="/logo.svg"
onClick={() => navigate('/')}
size={30}
/>
)
}Props:
logoUrl?: string- URL кастомного логотипаfallbackLogo?: string- Fallback логотипonClick?: () => void- Обработчик кликаsize?: number | string- Размер логотипа
SidebarTitle
Заголовок для сайдбара с поддержкой цветных частей.
import { SidebarTitle } from '@localzet/ui-kit'
function MySidebar() {
return (
<SidebarTitle
title={[
{ text: 'My', color: 'cyan' },
{ text: 'App', color: 'white' }
]}
/>
)
}Props:
title?: string | Array<{ text: string; color?: string }>- ЗаголовокdefaultTitle?: Array<{ text: string; color?: string }>- Заголовок по умолчанию
MobileWarningOverlay
Модальное окно с предупреждением для мобильных устройств.
import { MobileWarningOverlay } from '@localzet/ui-kit'
function MyApp() {
const [opened, setOpened] = useState(true)
return (
<MobileWarningOverlay
opened={opened}
onClose={() => setOpened(false)}
title="Mobile device detected"
/>
)
}Props:
opened: boolean- Открыто ли модальное окноonClose: () => void- Обработчик закрытия- Все тексты настраиваются через props
LandscapeBanner
Баннер для принудительного поворота устройства.
import { LandscapeBanner } from '@localzet/ui-kit'
function MyComponent() {
return (
<LandscapeBanner
title="Please rotate your device"
description="This page works better in landscape orientation."
/>
)
}Props:
title?: string- Заголовокdescription?: string- Описание
LanguagePicker
Компонент выбора языка.
import { LanguagePicker } from '@localzet/ui-kit'
function MyHeader() {
return (
<LanguagePicker
currentLanguage="en"
onLanguageChange={(lang) => {
// Обработка смены языка
console.log(lang)
}}
/>
)
}Props:
languages?: Language[]- Список языковcurrentLanguage?: string- Текущий языкonLanguageChange?: (language: string) => void- Callback смены языкаdefaultLanguages?: Language[]- Языки по умолчанию
HeaderControl
Базовый компонент для кнопок в хедере.
import { HeaderControl } from '@localzet/ui-kit'
import { IconSettings } from '@tabler/icons-react'
function MyHeader() {
return (
<HeaderControl onClick={() => console.log('clicked')}>
<IconSettings />
</HeaderControl>
)
}Props:
- Все props передаются в
UnstyledButtonиз Mantine
HeaderControls
Группа контролов для хедера.
import { HeaderControls } from '@localzet/ui-kit'
function MyHeader() {
return (
<HeaderControls
githubLink="https://github.com/example"
stars={1234}
telegramLink="https://t.me/example"
supportLink="https://example.com/donate"
withGithub
withTelegram
withSupport
withLanguage
onRefresh={() => window.location.reload()}
onLogout={() => console.log('logout')}
/>
)
}Props:
githubLink?: string- Ссылка на GitHubstars?: number- Количество звездisGithubLoading?: boolean- Загрузка звездtelegramLink?: string- Ссылка на TelegramsupportLink?: string- Ссылка на поддержкуwithGithub?: boolean- Показывать GitHub контролwithTelegram?: boolean- Показывать Telegram контролwithSupport?: boolean- Показывать Support контролwithLanguage?: boolean- Показывать Language контролwithRefresh?: boolean- Показывать Refresh контролwithLogout?: boolean- Показывать Logout контролwithVersion?: boolean- Показывать Version контролonRefresh?: () => void- Обработчик обновленияonLogout?: () => void- Обработчик выходаversion?: string- Версия приложенияversionComponent?: ReactNode- Кастомный компонент версииrefreshIcon?: ReactNode- Иконка обновленияlogoutIcon?: ReactNode- Иконка выхода
HelpActionIcon
Иконка помощи с тултипом.
import { HelpActionIcon } from '@localzet/ui-kit'
function MyComponent() {
return (
<HelpActionIcon
onClick={() => openHelp()}
tooltip="Click for help"
/>
)
}Props:
hidden?: boolean- Скрыть иконкуonClick?: () => void- Обработчик кликаtooltip?: string- Текст тултипаsize?: string | number- Размерcolor?: string- Цвет
LoadingProgress
Компонент для старта индикатора прогресса навигации.
import { LoadingProgress } from '@localzet/ui-kit'
function MyComponent() {
return <LoadingProgress start={true} />
}Props:
start?: boolean- Начать прогресс (по умолчанию:true)
TableContent
Контент для таблицы в CardSection.
import { TableContent } from '@localzet/ui-kit'
function MyTable() {
return (
<TableContent>
{/* Ваша таблица */}
</TableContent>
)
}Props:
- Все props передаются в
CardSectionиз Mantine
Layouts
Page
Компонент-обертка для страниц приложения.
import { Page } from '@localzet/ui-kit'
function MyPage() {
return (
<Page
title="Моя страница"
appName="Мое приложение"
onMount={() => {
// Вызывается при монтировании страницы
console.log('Страница загружена')
}}
>
<div>Содержимое страницы</div>
</Page>
)
}Props:
title?: string- Заголовок страницы (устанавливается вdocument.title)appName?: string- Название приложения (используется в формате{title} | {appName})meta?: ReactNode- Мета-теги для страницыonMount?: () => void- Callback при монтировании компонента- Все остальные props передаются в
Boxиз Mantine
EmptyPage
Компонент для пустой страницы.
import { EmptyPage } from '@localzet/ui-kit'
import { IconEmpty } from '@tabler/icons-react'
import { Button } from '@mantine/core'
function MyEmptyPage() {
return (
<EmptyPage
icon={<IconEmpty size={48} />}
title="Nothing found"
description="There are no items to display"
action={<Button>Create new</Button>}
/>
)
}Props:
title?: string- Заголовокdescription?: string- Описаниеicon?: ReactNode- Иконкаaction?: ReactNode- Действие (кнопка и т.д.)
Тема
Тема UI-Kit включает:
- Цветовая палитра: Темная тема с акцентом на cyan
- Типографика: Montserrat, Vazirmatn, Noto Sans SC, Twemoji Country Flags
- Breakpoints: xs, sm, md, lg, xl, 2xl, 3xl, 4xl
- Компоненты с кастомизацией: Badge, Button, Card, Table, Input, Menu, Tooltip и другие
Использование темы
import { theme } from '@localzet/ui-kit'
import { MantineProvider } from '@mantine/core'
function App() {
return (
<MantineProvider theme={theme} defaultColorScheme="dark">
{/* Ваше приложение */}
</MantineProvider>
)
}Кастомизация темы
Вы можете расширить тему, используя createTheme из Mantine:
import { createTheme, mergeMantineTheme } from '@mantine/core'
import { theme as uiKitTheme } from '@localzet/ui-kit'
const customTheme = createTheme({
// Ваши кастомизации
})
const finalTheme = mergeMantineTheme(uiKitTheme, customTheme)Overrides компонентов
UI-Kit включает кастомизированные версии следующих компонентов Mantine:
- Badge - с радиусом
mdи вариантомoutline - Button - с радиусом
md, вариантомlightи плавными переходами - Card - с градиентным фоном и анимацией появления
- Table - с подсветкой при наведении
- Input - все инпуты с радиусом
md - Menu - с кастомными стилями для темной темы
- Tooltip - с анимацией и стрелкой
- Notification - с радиусом
md - И другие...
Все эти кастомизации применяются автоматически при использовании темы.
Стили
Глобальные стили включают:
- Поддержку safe-area для мобильных устройств
- Стили для таблиц (mantine-datatable)
- Стили для Monaco Editor
- Анимации
- Кастомные стили для компонентов Mantine
Структура проекта
ui-kit/
├── src/
│ ├── components/ # React компоненты
│ │ ├── LoadingScreen/
│ │ ├── Page/
│ │ └── PageHeader/
│ ├── theme/ # Тема Mantine
│ │ ├── overrides/ # Кастомизация компонентов
│ │ └── theme.ts
│ ├── styles/ # Глобальные стили
│ │ └── global.css
│ └── index.ts # Главный файл экспорта
├── dist/ # Собранная библиотека
├── package.json
├── tsconfig.json
└── vite.config.tsРазработка
Установка зависимостей
npm installСборка
npm run buildПроверка типов
npm run typecheckРежим разработки (watch)
npm run devПубликация в npm
npm run build
npm publishЛицензия
MIT
Автор
localzet ([email protected])
Примеры
Более подробные примеры использования смотрите в файле EXAMPLES.md.
Поддержка
Если у вас есть вопросы или предложения, создайте issue в репозитории проекта.
