feat:generic Badge(0.3.0)

This commit is contained in:
Тимур Городецкий
2026-08-14 12:06:07 +05:00
parent c72f93e359
commit d16e4a2216
6 changed files with 114 additions and 1 deletions
+29
View File
@@ -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; }
+35
View File
@@ -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>
)
};
+30
View File
@@ -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>;
};
+2
View File
@@ -10,6 +10,8 @@ export { PrintButton } from './PrintButton/PrintButton';
// --- Сообщения / плашки ---
export { Alert } from './Alert/Alert';
export { RequestNumber } from './RequestNumber/RequestNumber';
export { Badge } from './Badge/Badge';
export type { IBadgeProps, BadgeVariant } from './Badge/Badge';
// --- Оболочка и раскладка формы ---
export { FormCard } from './FormCard/FormCard';