From 6acf7a149d3efc775268b8938fd5b1ba13e4a6f7 Mon Sep 17 00:00:00 2001 From: "ak.dmitriev" Date: Tue, 29 Sep 2026 00:31:35 +0700 Subject: [PATCH 1/2] API.badge --- docs/components-api/badge.md | 14 +++++++----- src/lib/components/badge/badge.component.ts | 7 +++++- src/lib/components/badge/badge.figma.md | 22 +++++++++++-------- src/stories/components/badge/badge.stories.ts | 15 +++++++++++-- .../badge/examples/badge-dot.component.ts | 10 ++++++--- .../examples/badge-severity.component.ts | 16 +++++++++++--- 6 files changed, 60 insertions(+), 24 deletions(-) diff --git a/docs/components-api/badge.md b/docs/components-api/badge.md index 1081281a..9e790c38 100644 --- a/docs/components-api/badge.md +++ b/docs/components-api/badge.md @@ -2,11 +2,13 @@ # ExtraBadge +> ✅ **Реализован**: `ExtraBadgeComponent` (`@cdek-it/angular-ui-kit`) соответствует спецификации. + Счётчик или статус для элемента. -| Свойство | Описание | Типизация | -| ----------- | ------------------------------------------ | -------------------------------------- | -| `severity` | вариант стиля | `primary \| info \| success \| warning \| danger` | -| `value` | значение (счётчик/текст) | `string` | -| `dot` | режим точки (без значения) | `boolean` | -| `size` | размер | `base \| large \| xlarge` | +| Свойство | Описание | Типизация | +| ---------- | -------------------------- | ------------------------------------------------- | +| `severity` | вариант стиля | `primary \| info \| success \| warning \| danger` | +| `value` | значение (счётчик/текст) | `string` | +| `dot` | режим точки (без значения) | `boolean` | +| `size` | размер | `base \| large \| xlarge` | diff --git a/src/lib/components/badge/badge.component.ts b/src/lib/components/badge/badge.component.ts index 7066097d..8978a0cd 100644 --- a/src/lib/components/badge/badge.component.ts +++ b/src/lib/components/badge/badge.component.ts @@ -12,13 +12,18 @@ type PrimeBadgeSize = ReturnType; standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [Badge], - template: ` ` + template: ` ` }) export class ExtraBadgeComponent { @Input() value: string | number = ''; + @Input() dot = false; @Input() severity: ExtraBadgeSeverity = 'primary'; @Input() size: ExtraBadgeSize = 'base'; + get badgeValue(): string | number | undefined { + return this.dot ? undefined : this.value || undefined; + } + get primeSeverity(): PrimeBadgeSeverity { if (this.severity === 'primary') return null; if (this.severity === 'warning') return 'warn'; diff --git a/src/lib/components/badge/badge.figma.md b/src/lib/components/badge/badge.figma.md index df09d875..76725313 100644 --- a/src/lib/components/badge/badge.figma.md +++ b/src/lib/components/badge/badge.figma.md @@ -10,7 +10,7 @@ figma: componentKey: 'b8e76ebb1556bc428673719f4f3a5dccd0cf20a9' name: '' status: stable -updated: '2026-06-22' +updated: '2026-09-29' --- ## Overview @@ -21,11 +21,12 @@ updated: '2026-06-22' ## Props mapping -| Свойство | Тип | По умолчанию | Описание | -|----------|-----|--------------|---------| -| `value` | `string \| number` | `''` | Отображаемое значение бейджа; пустое значение даёт точку-индикатор — соответствует Figma-свойству `dot=true` | -| `severity` | `'primary' \| 'success' \| 'info' \| 'warning' \| 'danger'` | `'primary'` | Цветовая схема — соответствует Figma-свойству `severity` (значение `primary` соответствует Figma `severity=basic`); цвета описаны в [tokens.md](../../figma-code-connect/tokens.md) | -| `size` | `'base' \| 'large' \| 'xlarge'` | `'base'` | Размер бейджа; отдельного свойства размера в Figma нет — управляется на уровне макета | +| Свойство | Тип | По умолчанию | Описание | +| ---------- | ----------------------------------------------------------- | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `value` | `string \| number` | `''` | Отображаемое значение бейджа; игнорируется при `dot=true` | +| `dot` | `boolean` | `false` | Режим точки-индикатора без значения — соответствует Figma-свойству `dot=true`; приоритетнее `value` | +| `severity` | `'primary' \| 'success' \| 'info' \| 'warning' \| 'danger'` | `'primary'` | Цветовая схема — соответствует Figma-свойству `severity` (значение `primary` соответствует Figma `severity=basic`); цвета описаны в [tokens.md](../../figma-code-connect/tokens.md) | +| `size` | `'base' \| 'large' \| 'xlarge'` | `'base'` | Размер бейджа; отдельного свойства размера в Figma нет — управляется на уровне макета | ## Variants @@ -71,10 +72,10 @@ Figma: ``, severity=danger, dot=false ### Dot (точка-индикатор без числа) -Figma: ``, dot=true — пустое `value` даёт точку +Figma: ``, dot=true ```html - + ``` ### Large (большой размер) @@ -107,12 +108,15 @@ Figma: ``, dot=false — счётчик с числом более 99 ## Do / Don't **Do:** + - Используйте `value` для счётчика непрочитанных/новых элементов -- Оставляйте `value` пустым для точки-индикатора (Figma `dot=true`) +- Задавайте `[dot]="true"` для точки-индикатора без числа (Figma `dot=true`) - Задавайте `severity="danger"` для критичных уведомлений, требующих внимания - Используйте формат `99+` для переполнения вместо больших чисел **Don't:** + - Не используйте бейдж как кликабельный элемент — он неинтерактивен (для действий используйте [ExtraButton](../button/button.figma.md)) - Не применяйте бейдж как текстовую метку категории — для этого есть [ExtraTag](../tag/tag.figma.md) - Не инлайньте цвета вручную — используйте `severity` и токены [tokens.md](../../figma-code-connect/tokens.md) +- Не задавайте одновременно `value` и `[dot]="true"`, ожидая увидеть value — `dot` приоритетнее и скроет значение diff --git a/src/stories/components/badge/badge.stories.ts b/src/stories/components/badge/badge.stories.ts index 7316e8b9..4f1305f0 100644 --- a/src/stories/components/badge/badge.stories.ts +++ b/src/stories/components/badge/badge.stories.ts @@ -40,6 +40,15 @@ import { BadgeModule } from 'primeng/badge'; type: { summary: 'string | number' } } }, + dot: { + control: 'boolean', + description: 'Режим точки-индикатора без значения; приоритетнее value', + table: { + category: 'Props', + defaultValue: { summary: 'false' }, + type: { summary: 'boolean' } + } + }, severity: { control: 'select', options: ['primary', 'success', 'info', 'warning', 'danger'], @@ -63,6 +72,7 @@ import { BadgeModule } from 'primeng/badge'; }, args: { value: '8', + dot: false, severity: 'primary', size: 'base' } @@ -77,10 +87,11 @@ export const Default: Story = { name: 'Default', render: (args) => ({ props: args, - template: `` + template: `` }), args: { - value: '8' + value: '8', + dot: false }, parameters: { docs: { diff --git a/src/stories/components/badge/examples/badge-dot.component.ts b/src/stories/components/badge/examples/badge-dot.component.ts index f5c03604..89c5074f 100644 --- a/src/stories/components/badge/examples/badge-dot.component.ts +++ b/src/stories/components/badge/examples/badge-dot.component.ts @@ -1,10 +1,14 @@ import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; import { StoryObj } from '@storybook/angular'; -import { ExtraBadgeSeverity, ExtraBadgeSize, ExtraBadgeComponent } from '../../../../lib/components/badge/badge.component'; +import { + ExtraBadgeSeverity, + ExtraBadgeSize, + ExtraBadgeComponent +} from '../../../../lib/components/badge/badge.component'; const template = `
- +
`; @@ -41,7 +45,7 @@ export const Dot: StoryObj = { parameters: { docs: { description: { - story: 'Без значения — отображается как точка-индикатор.' + story: '`[dot]="true"` — точка-индикатор без значения; приоритетнее `value`.' }, source: { language: 'ts', diff --git a/src/stories/components/badge/examples/badge-severity.component.ts b/src/stories/components/badge/examples/badge-severity.component.ts index 309a2e8c..f5c42345 100644 --- a/src/stories/components/badge/examples/badge-severity.component.ts +++ b/src/stories/components/badge/examples/badge-severity.component.ts @@ -1,10 +1,14 @@ import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; import { StoryObj } from '@storybook/angular'; -import { ExtraBadgeSeverity, ExtraBadgeSize, ExtraBadgeComponent } from '../../../../lib/components/badge/badge.component'; +import { + ExtraBadgeSeverity, + ExtraBadgeSize, + ExtraBadgeComponent +} from '../../../../lib/components/badge/badge.component'; const template = `
- +
`; @@ -20,6 +24,7 @@ const styles = ''; }) export class BadgeSeverityComponent { @Input() value: string | number = '8'; + @Input() dot = false; @Input() severity: ExtraBadgeSeverity = 'success'; @Input() size: ExtraBadgeSize = 'base'; } @@ -27,10 +32,11 @@ export class BadgeSeverityComponent { export const Severity: StoryObj = { render: (args) => ({ props: args, - template: `` + template: `` }), args: { value: '8', + dot: false, severity: 'success' }, argTypes: { @@ -42,6 +48,10 @@ export const Severity: StoryObj = { value: { control: 'text', description: 'Отображаемое значение бейджа' + }, + dot: { + control: 'boolean', + description: 'Режим точки-индикатора без значения' } }, parameters: { From 660c615b9d8b8ed6bb9d9917ffd068c673333ff6 Mon Sep 17 00:00:00 2001 From: ichiesov Date: Tue, 13 Oct 2026 14:13:02 +0700 Subject: [PATCH 2/2] ~fix stories --- src/lib/components/badge/badge.component.ts | 6 +- src/lib/components/badge/badge.figma.md | 2 +- src/stories/components/badge/badge.stories.ts | 56 ++++++++++------- .../badge/examples/badge-dot.component.ts | 62 +++++++++++-------- .../examples/badge-severity.component.ts | 59 +++++++----------- .../badge/examples/badge-sizes.component.ts | 47 ++++++-------- 6 files changed, 118 insertions(+), 114 deletions(-) diff --git a/src/lib/components/badge/badge.component.ts b/src/lib/components/badge/badge.component.ts index 8978a0cd..a9e6cf5b 100644 --- a/src/lib/components/badge/badge.component.ts +++ b/src/lib/components/badge/badge.component.ts @@ -1,7 +1,7 @@ import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; import { Badge } from 'primeng/badge'; -export type ExtraBadgeSeverity = 'primary' | 'success' | 'info' | 'warning' | 'danger'; +export type ExtraBadgeSeverity = 'primary' | 'info' | 'success' | 'warning' | 'danger'; export type ExtraBadgeSize = 'base' | 'large' | 'xlarge'; type PrimeBadgeSeverity = ReturnType; @@ -15,13 +15,13 @@ type PrimeBadgeSize = ReturnType; template: ` ` }) export class ExtraBadgeComponent { + @Input() severity: ExtraBadgeSeverity = 'primary'; @Input() value: string | number = ''; @Input() dot = false; - @Input() severity: ExtraBadgeSeverity = 'primary'; @Input() size: ExtraBadgeSize = 'base'; get badgeValue(): string | number | undefined { - return this.dot ? undefined : this.value || undefined; + return this.dot || this.value === '' ? undefined : this.value; } get primeSeverity(): PrimeBadgeSeverity { diff --git a/src/lib/components/badge/badge.figma.md b/src/lib/components/badge/badge.figma.md index 76725313..ebb5d646 100644 --- a/src/lib/components/badge/badge.figma.md +++ b/src/lib/components/badge/badge.figma.md @@ -25,7 +25,7 @@ updated: '2026-09-29' | ---------- | ----------------------------------------------------------- | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `value` | `string \| number` | `''` | Отображаемое значение бейджа; игнорируется при `dot=true` | | `dot` | `boolean` | `false` | Режим точки-индикатора без значения — соответствует Figma-свойству `dot=true`; приоритетнее `value` | -| `severity` | `'primary' \| 'success' \| 'info' \| 'warning' \| 'danger'` | `'primary'` | Цветовая схема — соответствует Figma-свойству `severity` (значение `primary` соответствует Figma `severity=basic`); цвета описаны в [tokens.md](../../figma-code-connect/tokens.md) | +| `severity` | `'primary' \| 'info' \| 'success' \| 'warning' \| 'danger'` | `'primary'` | Цветовая схема — соответствует Figma-свойству `severity` (значение `primary` соответствует Figma `severity=basic`); цвета описаны в [tokens.md](../../figma-code-connect/tokens.md) | | `size` | `'base' \| 'large' \| 'xlarge'` | `'base'` | Размер бейджа; отдельного свойства размера в Figma нет — управляется на уровне макета | ## Variants diff --git a/src/stories/components/badge/badge.stories.ts b/src/stories/components/badge/badge.stories.ts index 4f1305f0..9c377a1f 100644 --- a/src/stories/components/badge/badge.stories.ts +++ b/src/stories/components/badge/badge.stories.ts @@ -4,10 +4,6 @@ import { BadgeSeverityComponent } from './examples/badge-severity.component'; import { BadgeSizesComponent } from './examples/badge-sizes.component'; import { BadgeDotComponent } from './examples/badge-dot.component'; -export { Severity } from './examples/badge-severity.component'; -export { Sizes } from './examples/badge-sizes.component'; -export { Dot } from './examples/badge-dot.component'; - const meta: Meta = { title: 'Components/Misc/Badge', component: ExtraBadgeComponent, @@ -31,13 +27,23 @@ import { BadgeModule } from 'primeng/badge'; }, argTypes: { // ── Props ──────────────────────────────────────────────── + severity: { + control: 'select', + options: ['primary', 'info', 'success', 'warning', 'danger'], + description: 'Цветовая схема бейджа', + table: { + category: 'Props', + defaultValue: { summary: "'primary'" }, + type: { summary: "'primary' | 'info' | 'success' | 'warning' | 'danger'" } + } + }, value: { control: 'text', description: 'Отображаемое значение бейджа', table: { category: 'Props', defaultValue: { summary: "''" }, - type: { summary: 'string | number' } + type: { summary: 'string' } } }, dot: { @@ -49,16 +55,6 @@ import { BadgeModule } from 'primeng/badge'; type: { summary: 'boolean' } } }, - severity: { - control: 'select', - options: ['primary', 'success', 'info', 'warning', 'danger'], - description: 'Цветовая схема бейджа', - table: { - category: 'Props', - defaultValue: { summary: "'primary'" }, - type: { summary: "'primary' | 'success' | 'info' | 'warning' | 'danger'" } - } - }, size: { control: 'select', options: ['base', 'large', 'xlarge'], @@ -71,9 +67,9 @@ import { BadgeModule } from 'primeng/badge'; } }, args: { + severity: 'primary', value: '8', dot: false, - severity: 'primary', size: 'base' } }; @@ -85,13 +81,25 @@ type Story = StoryObj; export const Default: Story = { name: 'Default', - render: (args) => ({ - props: args, - template: `` - }), + render: (args) => { + const parts: string[] = []; + + if (args.severity && args.severity !== 'primary') parts.push(`severity="${args.severity}"`); + if (args.dot) parts.push(`[dot]="true"`); + else if (args.value) parts.push(`value="${args.value}"`); + if (args.size && args.size !== 'base') parts.push(`size="${args.size}"`); + + const template = parts.length + ? `` + : ``; + + return { props: args, template }; + }, args: { + severity: 'primary', value: '8', - dot: false + dot: false, + size: 'base' }, parameters: { docs: { @@ -101,3 +109,9 @@ export const Default: Story = { } } }; + +// ── Витрины вариантов ──────────────────────────────────────────────────────── + +export { Severity } from './examples/badge-severity.component'; +export { Sizes } from './examples/badge-sizes.component'; +export { Dot } from './examples/badge-dot.component'; diff --git a/src/stories/components/badge/examples/badge-dot.component.ts b/src/stories/components/badge/examples/badge-dot.component.ts index 89c5074f..b49335e0 100644 --- a/src/stories/components/badge/examples/badge-dot.component.ts +++ b/src/stories/components/badge/examples/badge-dot.component.ts @@ -1,14 +1,21 @@ -import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; import { StoryObj } from '@storybook/angular'; -import { - ExtraBadgeSeverity, - ExtraBadgeSize, - ExtraBadgeComponent -} from '../../../../lib/components/badge/badge.component'; +import { ExtraBadgeSeverity, ExtraBadgeComponent } from '../../../../lib/components/badge/badge.component'; const template = `
- +
+
+ @for (severity of severities; track severity) { + + } +
+
+ + + +
+
`; @@ -23,29 +30,19 @@ const styles = ''; styles }) export class BadgeDotComponent { - @Input() severity: ExtraBadgeSeverity = 'primary'; - @Input() size: ExtraBadgeSize = 'base'; + severities: ExtraBadgeSeverity[] = ['primary', 'info', 'success', 'warning', 'danger']; } export const Dot: StoryObj = { - render: (args) => ({ - props: args, - template: `` + render: () => ({ + template: `` }), - args: { - severity: 'primary' - }, - argTypes: { - severity: { - control: 'select', - options: ['primary', 'success', 'info', 'warning', 'danger'], - description: 'Цветовая схема бейджа' - } - }, parameters: { + controls: { disable: true }, docs: { description: { - story: '`[dot]="true"` — точка-индикатор без значения; приоритетнее `value`.' + story: + '`[dot]="true"` — точка-индикатор без значения, приоритетнее `value`. Первый ряд — все severity, второй — размеры base, large, xlarge.' }, source: { language: 'ts', @@ -57,8 +54,23 @@ import { ExtraBadgeComponent } from '@cdek-it/angular-ui-kit'; selector: 'app-badge-dot', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, - imports: [BadgeComponent], - template: \`${template}\` + imports: [ExtraBadgeComponent], + template: \` +
+ + + + + +
+ + +
+ + + +
+ \` }) export class BadgeDotComponent {} ` diff --git a/src/stories/components/badge/examples/badge-severity.component.ts b/src/stories/components/badge/examples/badge-severity.component.ts index f5c42345..f0dc5327 100644 --- a/src/stories/components/badge/examples/badge-severity.component.ts +++ b/src/stories/components/badge/examples/badge-severity.component.ts @@ -1,14 +1,14 @@ -import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; import { StoryObj } from '@storybook/angular'; -import { - ExtraBadgeSeverity, - ExtraBadgeSize, - ExtraBadgeComponent -} from '../../../../lib/components/badge/badge.component'; +import { ExtraBadgeSeverity, ExtraBadgeComponent } from '../../../../lib/components/badge/badge.component'; const template = `
- +
+ @for (severity of severities; track severity) { + + } +
`; @@ -23,41 +23,18 @@ const styles = ''; styles }) export class BadgeSeverityComponent { - @Input() value: string | number = '8'; - @Input() dot = false; - @Input() severity: ExtraBadgeSeverity = 'success'; - @Input() size: ExtraBadgeSize = 'base'; + severities: ExtraBadgeSeverity[] = ['primary', 'info', 'success', 'warning', 'danger']; } export const Severity: StoryObj = { - render: (args) => ({ - props: args, - template: `` + render: () => ({ + template: `` }), - args: { - value: '8', - dot: false, - severity: 'success' - }, - argTypes: { - severity: { - control: 'select', - options: ['primary', 'success', 'info', 'warning', 'danger'], - description: 'Цветовая схема бейджа' - }, - value: { - control: 'text', - description: 'Отображаемое значение бейджа' - }, - dot: { - control: 'boolean', - description: 'Режим точки-индикатора без значения' - } - }, parameters: { + controls: { disable: true }, docs: { description: { - story: 'Цветовые схемы: primary, success, info, warning, danger.' + story: 'Все варианты стиля (severity): primary, info, success, warning, danger.' }, source: { language: 'ts', @@ -69,8 +46,16 @@ import { ExtraBadgeComponent } from '@cdek-it/angular-ui-kit'; selector: 'app-badge-severity', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, - imports: [BadgeComponent], - template: \`${template}\` + imports: [ExtraBadgeComponent], + template: \` +
+ + + + + +
+ \` }) export class BadgeSeverityComponent {} ` diff --git a/src/stories/components/badge/examples/badge-sizes.component.ts b/src/stories/components/badge/examples/badge-sizes.component.ts index 34195d2e..60bf6920 100644 --- a/src/stories/components/badge/examples/badge-sizes.component.ts +++ b/src/stories/components/badge/examples/badge-sizes.component.ts @@ -1,10 +1,21 @@ -import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; import { StoryObj } from '@storybook/angular'; -import { ExtraBadgeSize, ExtraBadgeComponent } from '../../../../lib/components/badge/badge.component'; +import { ExtraBadgeComponent } from '../../../../lib/components/badge/badge.component'; const template = `
- +
+
+ + + +
+
+ + + +
+
`; @@ -18,35 +29,17 @@ const styles = ''; template, styles }) -export class BadgeSizesComponent { - @Input() value: string | number = '8'; - @Input() size: ExtraBadgeSize = 'large'; -} +export class BadgeSizesComponent {} export const Sizes: StoryObj = { - render: (args) => ({ - props: args, - template: `` + render: () => ({ + template: `` }), - args: { - value: '8', - size: 'large' - }, - argTypes: { - size: { - control: 'select', - options: ['base', 'large', 'xlarge'], - description: 'Размер бейджа' - }, - value: { - control: 'text', - description: 'Отображаемое значение бейджа' - } - }, parameters: { + controls: { disable: true }, docs: { description: { - story: 'Все доступные размеры: base, large, xlarge.' + story: 'Все доступные размеры: base, large, xlarge — с одним символом (круг) и с переполнением `99+` (пилюля).' }, source: { language: 'ts', @@ -58,7 +51,7 @@ import { ExtraBadgeComponent } from '@cdek-it/angular-ui-kit'; selector: 'app-badge-sizes', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, - imports: [BadgeComponent], + imports: [ExtraBadgeComponent], template: \`${template}\` }) export class BadgeSizesComponent {}