feat: FormHeader (0.6.0)
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@tnsu/ui-kit",
|
||||
"version": "0.5.0",
|
||||
"version": "0.6.0",
|
||||
"description": "TNSU shared UI components for SPFx web parts",
|
||||
"author": "Timur Gorodetskiy",
|
||||
"license": "ISC",
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
@import '../tokens/tokens';
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: $sp-3;
|
||||
padding: 14px 20px;
|
||||
background: $navy-50;
|
||||
border: 1px solid $navy-100;
|
||||
border-left: 3px solid $gold-500; // фирменный золотой акцент
|
||||
border-radius: $r-md;
|
||||
}
|
||||
|
||||
.icon {
|
||||
flex-shrink: 0;
|
||||
color: $navy-700;
|
||||
}
|
||||
|
||||
.title {
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
font-family: $font-serif;
|
||||
font-size: $fs-section-title;
|
||||
font-weight: 600;
|
||||
color: $navy-900;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.right {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: $sp-2;
|
||||
}
|
||||
|
||||
// Мобилка: разрешаем перенос и заголовку, и правому слоту — ничего не обрезается.
|
||||
@include below($bp-sm) {
|
||||
.header {
|
||||
flex-wrap: wrap;
|
||||
padding: 12px 14px;
|
||||
}
|
||||
|
||||
.title {
|
||||
white-space: normal;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react-vite';
|
||||
import { FormHeader } from './FormHeader';
|
||||
import { Badge } from '../Badge/Badge';
|
||||
|
||||
const meta: Meta<typeof FormHeader> = {
|
||||
title: 'Формы/FormHeader',
|
||||
component: FormHeader,
|
||||
tags: ['autodocs'],
|
||||
args: { title: 'Сравнительная таблица №1' }
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof FormHeader>;
|
||||
|
||||
export const Basic: Story = {};
|
||||
|
||||
export const WithStatus: Story = {
|
||||
args: { right: <Badge variant="info">На согласовании</Badge> }
|
||||
};
|
||||
|
||||
export const LongTitle: Story = {
|
||||
args: {
|
||||
title: 'Сравнительная таблица по закупке материалов для строительства жилого дома в п. Топар',
|
||||
right: <Badge variant="success">Согласована</Badge>
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
import * as React from 'react';
|
||||
import styles from './FormHeader.module.scss';
|
||||
import { Icon } from '../Icon/Icon';
|
||||
import { IconName } from '../Icon/iconNames';
|
||||
|
||||
export interface IFormHeaderProps {
|
||||
title: React.ReactNode;
|
||||
/** Иконка слева. По умолчанию 'document'. */
|
||||
icon?: IconName;
|
||||
/**
|
||||
* Правый слот — обычно статус-бейдж (Badge), но может быть что угодно
|
||||
* (номер, кнопки). Смысл статуса задаёт проект, FormHeader про него не знает.
|
||||
*/
|
||||
right?: React.ReactNode;
|
||||
}
|
||||
|
||||
/** Шапка формы: золотой акцент слева, иконка, заголовок и правый слот (статус). */
|
||||
export const FormHeader: React.FC<IFormHeaderProps> = ({ title, icon = 'document', right }) => (
|
||||
<div className={styles.header}>
|
||||
<Icon name={icon} className={styles.icon} />
|
||||
<span className={styles.title}>{title}</span>
|
||||
{right && <span className={styles.right}>{right}</span>}
|
||||
</div>
|
||||
);
|
||||
@@ -14,6 +14,8 @@ export { Badge } from './Badge/Badge';
|
||||
export type { IBadgeProps, BadgeVariant } from './Badge/Badge';
|
||||
|
||||
// --- Оболочка и раскладка формы ---
|
||||
export { FormHeader } from './FormHeader/FormHeader';
|
||||
export type { IFormHeaderProps } from './FormHeader/FormHeader';
|
||||
export { FormCard } from './FormCard/FormCard';
|
||||
export { FormGrid } from './FormGrid/FormGrid';
|
||||
export { FormField } from './FormField/FormField';
|
||||
|
||||
Reference in New Issue
Block a user