feat:generic Badge(0.3.0)
This commit is contained in:
+17
@@ -118,6 +118,23 @@ Tabs (из CategoryTabs), Breadcrumbs (новый), Sidebar (из SideNav), AppL
|
|||||||
Drawer(?). Сначала «расцепить» от роутинга портала → сделать controlled
|
Drawer(?). Сначала «расцепить» от роутинга портала → сделать controlled
|
||||||
(items + activeId + onSelect), потом переносить. Даёт новым приложениям готовую оболочку.
|
(items + activeId + onSelect), потом переносить. Даёт новым приложениям готовую оболочку.
|
||||||
|
|
||||||
|
### Миграция request-portal (в процессе)
|
||||||
|
- [СДЕЛАНО] Формы переведены на пакет через переключение barrel shared/ui/index.ts
|
||||||
|
(перенесённые компоненты реэкспортятся из @tnsu/ui-kit). FormMode объединён на пакетный.
|
||||||
|
- [СДЕЛАНО] Чистка: 12 прямых импортеров (SideNav, табы, Drawer, RequestGrid, пикеры,
|
||||||
|
unsavedChanges, RequestPortal→IconSprite, ItemsTable, SubmitActions) → @tnsu/ui-kit;
|
||||||
|
удалены 20 локальных папок-дублей. В shared/ui осталось: ItemsTable, PeopleField,
|
||||||
|
SubmitActions, ErrorOverlay, InitiatorLine (+useRequestSubmit, index). Heft собирается.
|
||||||
|
- [СДЕЛАНО] B: локальный components/SideNav заменён на пакетный Sidebar + SidebarToggle.
|
||||||
|
В RequestPortal: navItems (с counts), состояние mobileNavOpen, бургер в шапке main
|
||||||
|
(.mobileNav, виден < 768px). Shell CSS: убран старый перелом 900px; на < 768 .side
|
||||||
|
схлопывается (drawer position:fixed), main на всю ширину. SideNav удалён. Heft ок.
|
||||||
|
|
||||||
|
### Badge (0.3.0) — паттерн «презентация в kit, смысл в проекте»
|
||||||
|
Generic Badge в kit (variant: neutral/muted/info/success/warning/danger/primary). Портальный
|
||||||
|
StatusBadge переписан в тонкий маппер REQUEST_STATUS→variant поверх Badge; StatusBadge.module.scss
|
||||||
|
удалён. Это шаблон для будущего разделения пикеров (group 3): вид в kit, привязка к данным в проекте.
|
||||||
|
|
||||||
### Порядок работ
|
### Порядок работ
|
||||||
1. [СДЕЛАНО в 0.1.0] Быстрая пачка (20 компонентов): вся Группа 1 (кроме ErrorOverlay/
|
1. [СДЕЛАНО в 0.1.0] Быстрая пачка (20 компонентов): вся Группа 1 (кроме ErrorOverlay/
|
||||||
StatusBadge — оказались связаны с diagnostics/statuses, отложены) + ConfirmDialog/
|
StatusBadge — оказались связаны с diagnostics/statuses, отложены) + ConfirmDialog/
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@tnsu/ui-kit",
|
"name": "@tnsu/ui-kit",
|
||||||
"version": "0.2.0",
|
"version": "0.3.0",
|
||||||
"description": "TNSU shared UI components for SPFx web parts",
|
"description": "TNSU shared UI components for SPFx web parts",
|
||||||
"author": "Timur Gorodetskiy",
|
"author": "Timur Gorodetskiy",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
@import '../tokens/tokens';
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 5px 12px;
|
||||||
|
border-radius: $r-sm;
|
||||||
|
font-family: $font-sans;
|
||||||
|
font-size: 12.5px;
|
||||||
|
font-weight: 600;
|
||||||
|
letter-spacing: .2px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Компактный вариант — для ячейки таблицы.
|
||||||
|
.sm {
|
||||||
|
padding: 3px 10px;
|
||||||
|
border-radius: $r-md;
|
||||||
|
font-size: $fs-caption;
|
||||||
|
letter-spacing: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.neutral { background: $gray-100; color: $gray-700; }
|
||||||
|
.muted { background: $gray-100; color: $gray-500; }
|
||||||
|
.info { background: $blue-50; color: $blue-600; }
|
||||||
|
.success { background: $green-50; color: $green-600; }
|
||||||
|
.warning { background: $gold-50; color: $amber-700; }
|
||||||
|
.danger { background: $red-50; color: $red-500; }
|
||||||
|
.primary { background: $navy-50; color: $navy-800; }
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import type { Meta, StoryObj } from '@storybook/react-vite';
|
||||||
|
import { Badge } from './Badge';
|
||||||
|
|
||||||
|
const meta: Meta<typeof Badge> = {
|
||||||
|
title: 'Сообщения/Badge',
|
||||||
|
component: Badge,
|
||||||
|
tags: ['autodocs'],
|
||||||
|
argTypes: {
|
||||||
|
variant: {
|
||||||
|
control: 'select',
|
||||||
|
options: ['neutral', 'muted', 'info', 'success', 'warning', 'danger', 'primary']
|
||||||
|
},
|
||||||
|
size: { control: 'radio', options: ['sm', 'md'] }
|
||||||
|
},
|
||||||
|
args: { variant: 'info', size: 'md', children: 'На согласовании' }
|
||||||
|
};
|
||||||
|
|
||||||
|
export default meta;
|
||||||
|
type Story = StoryObj<typeof Badge>;
|
||||||
|
|
||||||
|
export const Info: Story = {};
|
||||||
|
|
||||||
|
export const AllVariants: Story = {
|
||||||
|
render: () => (
|
||||||
|
<div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
|
||||||
|
<Badge variant="neutral">Черновик</Badge>
|
||||||
|
<Badge variant="muted">В очереди</Badge>
|
||||||
|
<Badge variant="info">На согласовании</Badge>
|
||||||
|
<Badge variant="success">Согласовано</Badge>
|
||||||
|
<Badge variant="warning">Возвращена</Badge>
|
||||||
|
<Badge variant="danger">Отклонена</Badge>
|
||||||
|
<Badge variant="primary">На исполнении</Badge>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
};
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import styles from './Badge.module.scss';
|
||||||
|
|
||||||
|
export type BadgeVariant = 'neutral' | 'muted' | 'info' | 'success' | 'warning' | 'danger' | 'primary';
|
||||||
|
|
||||||
|
export interface IBadgeProps {
|
||||||
|
/** Цвет плашки. Смысл (статус заявки и т.п.) назначает проект. */
|
||||||
|
variant?: BadgeVariant;
|
||||||
|
/** 'md' (по умолчанию) — обычный; 'sm' — компактный (для ячейки таблицы). */
|
||||||
|
size?: 'sm' | 'md';
|
||||||
|
children: React.ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
const variantClass: Record<BadgeVariant, string> = {
|
||||||
|
neutral: styles.neutral,
|
||||||
|
muted: styles.muted,
|
||||||
|
info: styles.info,
|
||||||
|
success: styles.success,
|
||||||
|
warning: styles.warning,
|
||||||
|
danger: styles.danger,
|
||||||
|
primary: styles.primary
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Цветная плашка-бейдж. Цвет — через variant; что он означает, решает проект. */
|
||||||
|
export const Badge: React.FC<IBadgeProps> = ({ variant = 'neutral', size = 'md', children }) => {
|
||||||
|
const classes = [styles.badge, size === 'sm' ? styles.sm : '', variantClass[variant]]
|
||||||
|
.filter(Boolean)
|
||||||
|
.join(' ');
|
||||||
|
return <span className={classes}>{children}</span>;
|
||||||
|
};
|
||||||
@@ -10,6 +10,8 @@ export { PrintButton } from './PrintButton/PrintButton';
|
|||||||
// --- Сообщения / плашки ---
|
// --- Сообщения / плашки ---
|
||||||
export { Alert } from './Alert/Alert';
|
export { Alert } from './Alert/Alert';
|
||||||
export { RequestNumber } from './RequestNumber/RequestNumber';
|
export { RequestNumber } from './RequestNumber/RequestNumber';
|
||||||
|
export { Badge } from './Badge/Badge';
|
||||||
|
export type { IBadgeProps, BadgeVariant } from './Badge/Badge';
|
||||||
|
|
||||||
// --- Оболочка и раскладка формы ---
|
// --- Оболочка и раскладка формы ---
|
||||||
export { FormCard } from './FormCard/FormCard';
|
export { FormCard } from './FormCard/FormCard';
|
||||||
|
|||||||
Reference in New Issue
Block a user