Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions docs/components-api/badge.md
Original file line number Diff line number Diff line change
Expand Up @@ -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` |
11 changes: 8 additions & 3 deletions src/lib/components/badge/badge.component.ts
Original file line number Diff line number Diff line change
@@ -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<Badge['severity']>;
Expand All @@ -12,13 +12,18 @@ type PrimeBadgeSize = ReturnType<Badge['size']>;
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [Badge],
template: ` <p-badge [value]="value" [severity]="primeSeverity" [size]="primeSize"></p-badge> `
template: ` <p-badge [value]="badgeValue" [severity]="primeSeverity" [size]="primeSize"></p-badge> `
})
export class ExtraBadgeComponent {
@Input() value: string | number = '';
@Input() severity: ExtraBadgeSeverity = 'primary';
@Input() value: string | number = '';
@Input() dot = false;
@Input() size: ExtraBadgeSize = 'base';

get badgeValue(): string | number | undefined {
return this.dot || this.value === '' ? undefined : this.value;
}

get primeSeverity(): PrimeBadgeSeverity {
if (this.severity === 'primary') return null;
if (this.severity === 'warning') return 'warn';
Expand Down
22 changes: 13 additions & 9 deletions src/lib/components/badge/badge.figma.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ figma:
componentKey: 'b8e76ebb1556bc428673719f4f3a5dccd0cf20a9'
name: '<Badge>'
status: stable
updated: '2026-06-22'
updated: '2026-09-29'
---

## Overview
Expand All @@ -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' \| '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

Expand Down Expand Up @@ -71,10 +72,10 @@ Figma: `<Badge>`, severity=danger, dot=false

### Dot (точка-индикатор без числа)

Figma: `<Badge>`, dot=true — пустое `value` даёт точку
Figma: `<Badge>`, dot=true

```html
<extra-badge severity="danger"></extra-badge>
<extra-badge [dot]="true" severity="danger"></extra-badge>
```

### Large (большой размер)
Expand Down Expand Up @@ -107,12 +108,15 @@ Figma: `<Badge>`, 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` приоритетнее и скроет значение
59 changes: 42 additions & 17 deletions src/stories/components/badge/badge.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<ExtraBadgeComponent> = {
title: 'Components/Misc/Badge',
component: ExtraBadgeComponent,
Expand All @@ -31,23 +27,32 @@ 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' }
}
},
severity: {
control: 'select',
options: ['primary', 'success', 'info', 'warning', 'danger'],
description: 'Цветовая схема бейджа',
dot: {
control: 'boolean',
description: 'Режим точки-индикатора без значения; приоритетнее value',
table: {
category: 'Props',
defaultValue: { summary: "'primary'" },
type: { summary: "'primary' | 'success' | 'info' | 'warning' | 'danger'" }
defaultValue: { summary: 'false' },
type: { summary: 'boolean' }
}
},
size: {
Expand All @@ -62,8 +67,9 @@ import { BadgeModule } from 'primeng/badge';
}
},
args: {
value: '8',
severity: 'primary',
value: '8',
dot: false,
size: 'base'
}
};
Expand All @@ -75,12 +81,25 @@ type Story = StoryObj<ExtraBadgeComponent>;

export const Default: Story = {
name: 'Default',
render: (args) => ({
props: args,
template: `<app-badge-severity [value]="value" [severity]="severity" [size]="size"></app-badge-severity>`
}),
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
? `<extra-badge\n ${parts.join('\n ')}\n></extra-badge>`
: `<extra-badge value="8"></extra-badge>`;

return { props: args, template };
},
args: {
value: '8'
severity: 'primary',
value: '8',
dot: false,
size: 'base'
},
parameters: {
docs: {
Expand All @@ -90,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';
58 changes: 37 additions & 21 deletions src/stories/components/badge/examples/badge-dot.component.ts
Original file line number Diff line number Diff line change
@@ -1,10 +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 = `
<div class="p-4">
<extra-badge [severity]="severity" [size]="size"></extra-badge>
<div class="flex flex-col gap-4">
<div class="flex gap-4 items-center">
@for (severity of severities; track severity) {
<extra-badge [dot]="true" [severity]="severity"></extra-badge>
}
</div>
<div class="flex gap-4 items-center">
<extra-badge [dot]="true" severity="danger"></extra-badge>
<extra-badge [dot]="true" severity="danger" size="large"></extra-badge>
<extra-badge [dot]="true" severity="danger" size="xlarge"></extra-badge>
</div>
</div>
</div>
`;

Expand All @@ -19,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: `<app-badge-dot [severity]="severity" [size]="size"></app-badge-dot>`
render: () => ({
template: `<app-badge-dot></app-badge-dot>`
}),
args: {
severity: 'primary'
},
argTypes: {
severity: {
control: 'select',
options: ['primary', 'success', 'info', 'warning', 'danger'],
description: 'Цветовая схема бейджа'
}
},
parameters: {
controls: { disable: true },
docs: {
description: {
story: 'Без значения — отображается как точка-индикатор.'
story:
'`[dot]="true"` — точка-индикатор без значения, приоритетнее `value`. Первый ряд — все severity, второй — размеры base, large, xlarge.'
},
source: {
language: 'ts',
Expand All @@ -53,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: \`
<div class="flex gap-4 items-center">
<extra-badge [dot]="true" severity="primary"></extra-badge>
<extra-badge [dot]="true" severity="info"></extra-badge>
<extra-badge [dot]="true" severity="success"></extra-badge>
<extra-badge [dot]="true" severity="warning"></extra-badge>
<extra-badge [dot]="true" severity="danger"></extra-badge>
</div>

<!-- размеры точки -->
<div class="flex gap-4 items-center">
<extra-badge [dot]="true" severity="danger"></extra-badge>
<extra-badge [dot]="true" severity="danger" size="large"></extra-badge>
<extra-badge [dot]="true" severity="danger" size="xlarge"></extra-badge>
</div>
\`
})
export class BadgeDotComponent {}
`
Expand Down
49 changes: 22 additions & 27 deletions src/stories/components/badge/examples/badge-severity.component.ts
Original file line number Diff line number Diff line change
@@ -1,10 +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 = `
<div class="p-4">
<extra-badge [value]="value" [severity]="severity" [size]="size"></extra-badge>
<div class="flex gap-4 items-center">
@for (severity of severities; track severity) {
<extra-badge [severity]="severity" value="8"></extra-badge>
}
</div>
</div>
`;

Expand All @@ -19,35 +23,18 @@ const styles = '';
styles
})
export class BadgeSeverityComponent {
@Input() value: string | number = '8';
@Input() severity: ExtraBadgeSeverity = 'success';
@Input() size: ExtraBadgeSize = 'base';
severities: ExtraBadgeSeverity[] = ['primary', 'info', 'success', 'warning', 'danger'];
}

export const Severity: StoryObj = {
render: (args) => ({
props: args,
template: `<app-badge-severity [value]="value" [severity]="severity" [size]="size"></app-badge-severity>`
render: () => ({
template: `<app-badge-severity></app-badge-severity>`
}),
args: {
value: '8',
severity: 'success'
},
argTypes: {
severity: {
control: 'select',
options: ['primary', 'success', 'info', 'warning', 'danger'],
description: 'Цветовая схема бейджа'
},
value: {
control: 'text',
description: 'Отображаемое значение бейджа'
}
},
parameters: {
controls: { disable: true },
docs: {
description: {
story: 'Цветовые схемы: primary, success, info, warning, danger.'
story: 'Все варианты стиля (severity): primary, info, success, warning, danger.'
},
source: {
language: 'ts',
Expand All @@ -59,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: \`
<div class="flex gap-4 items-center">
<extra-badge severity="primary" value="8"></extra-badge>
<extra-badge severity="info" value="8"></extra-badge>
<extra-badge severity="success" value="8"></extra-badge>
<extra-badge severity="warning" value="8"></extra-badge>
<extra-badge severity="danger" value="8"></extra-badge>
</div>
\`
})
export class BadgeSeverityComponent {}
`
Expand Down
Loading
Loading