
Security News
The Hidden Blast Radius of the Axios Compromise
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.
@localzet/ui-kit
Advanced tools
UI Kit библиотека компонентов на основе Mantine для проектов Localzet
UI Kit библиотека компонентов на основе Mantine для проектов Localzet. Единая система дизайна и компонентов, собранная из лучших практик проектов ЛК (frontend) и Агрегатор (kimai-aggregator).
npm install @localzet/ui-kit
# или
yarn add @localzet/ui-kit
# или
pnpm add @localzet/ui-kit
В вашем главном файле приложения (например, 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, которые вы используете
import '@localzet/ui-kit/styles'
import { MantineProvider } from '@mantine/core'
import { theme } from '@localzet/ui-kit'
function App() {
return (
<MantineProvider theme={theme} defaultColorScheme="dark">
{/* Ваше приложение */}
</MantineProvider>
)
}
UI-Kit разделен на несколько категорий:
@localzet/ui-kit) - Основные UI компоненты@localzet/ui-kit) - Компоненты для структуры страниц@localzet/ui-kit/theme) - Тема MantineКомпонент для отображения экрана загрузки с прогресс-баром.
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)Компонент заголовка страницы с иконкой, заголовком, описанием и действиями.
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 - Действия (кнопки и т.д.)Card из MantineПоле ввода с возможностью копирования значения в буфер обмена.
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' - Размер поляКомпонент для отображения пары "метка-значение".
import { InfoField } from '@localzet/ui-kit'
function MyComponent() {
return (
<InfoField
label="Статус"
value="Активен"
/>
)
}
Props:
label: string - Меткаvalue: ReactNode - Значение (может быть любым React-элементом)Футер для модальных окон с адаптивной версткой.
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 - Содержимое футера (обычно кнопки)Футер для 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 - Содержимое футераЛипкий заголовок, который остается видимым при прокрутке.
import { StickyHeader } from '@localzet/ui-kit'
function MyComponent() {
return (
<StickyHeader offset={10}>
<h1>Заголовок</h1>
</StickyHeader>
)
}
Props:
offset?: number - Отступ в пикселях для активации (по умолчанию: 2)Box из MantineНабор компонентов для создания карточек настроек.
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 - Нижняя секция с разделителемКомпоненты для работы с таблицами.
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 - Заголовок таблицы с иконкой и действиямиДекоративный SVG-элемент для подчеркивания.
import { UnderlineShape } from '@localzet/ui-kit'
function MyComponent() {
return (
<div>
<h1>Заголовок</h1>
<UnderlineShape size={100} color="cyan" />
</div>
)
}
Props:
size?: number | string - Размер SVGBox из MantineКарточка с чекбоксом для выбора опций.
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 - ОписаниеCheckbox.Card из MantineТекстовая область с возможностью копирования.
import { CopyableArea } from '@localzet/ui-kit'
function MyComponent() {
return (
<CopyableArea
label="Конфигурация"
value="some long text to copy..."
/>
)
}
Props:
label?: string - Метка поляvalue: number | string - Значение для копированияSVG логотип компонент.
import { Logo } from '@localzet/ui-kit'
function MyComponent() {
return <Logo size={32} color="cyan" />
}
Props:
size?: number | string - Размер логотипаBox из MantineКомпонент загрузки для модальных окон.
import { LoaderModal } from '@localzet/ui-kit'
function MyModal() {
return (
<LoaderModal
text="Загрузка данных..."
h="80vh"
w="100%"
/>
)
}
Props:
text?: string - Текст под индикатором загрузкиCenter из MantineПоповер с информационной иконкой.
import { PopoverWithInfo } from '@localzet/ui-kit'
function MyComponent() {
return (
<PopoverWithInfo
position="right"
text="Дополнительная информация о функции"
/>
)
}
Props:
position?: 'bottom' | 'left' | 'right' | 'top' - Позиция поповераtext: ReactNode - Текст для отображенияПоле ввода для создания и выбора тегов.
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 - Кастомная валидацияКомплексный компонент для отображения метрик с различными вариантами.
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 - Столбчатая диаграммаГотовый компонент метрики с трендом.
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 - ИконкаЛоготип для сайдбара с поддержкой кастомного изображения.
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 - Размер логотипаЗаголовок для сайдбара с поддержкой цветных частей.
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 }> - Заголовок по умолчаниюМодальное окно с предупреждением для мобильных устройств.
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 - Обработчик закрытияБаннер для принудительного поворота устройства.
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 - ОписаниеКомпонент выбора языка.
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[] - Языки по умолчаниюБазовый компонент для кнопок в хедере.
import { HeaderControl } from '@localzet/ui-kit'
import { IconSettings } from '@tabler/icons-react'
function MyHeader() {
return (
<HeaderControl onClick={() => console.log('clicked')}>
<IconSettings />
</HeaderControl>
)
}
Props:
UnstyledButton из MantineГруппа контролов для хедера.
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 - Иконка выходаИконка помощи с тултипом.
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 - ЦветКомпонент для старта индикатора прогресса навигации.
import { LoadingProgress } from '@localzet/ui-kit'
function MyComponent() {
return <LoadingProgress start={true} />
}
Props:
start?: boolean - Начать прогресс (по умолчанию: true)Контент для таблицы в CardSection.
import { TableContent } from '@localzet/ui-kit'
function MyTable() {
return (
<TableContent>
{/* Ваша таблица */}
</TableContent>
)
}
Props:
CardSection из MantineКомпонент-обертка для страниц приложения.
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 при монтировании компонентаBox из MantineКомпонент для пустой страницы.
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 включает:
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)
UI-Kit включает кастомизированные версии следующих компонентов Mantine:
md и вариантом outlinemd, вариантом light и плавными переходамиmdmdВсе эти кастомизации применяются автоматически при использовании темы.
Глобальные стили включают:
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
npm run dev
npm run build
npm publish
MIT
localzet (creator@localzet.com)
Более подробные примеры использования смотрите в файле EXAMPLES.md.
Если у вас есть вопросы или предложения, создайте issue в репозитории проекта.
FAQs
UI Kit библиотека компонентов на основе Mantine для проектов Localzet
We found that @localzet/ui-kit demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.