diff --git a/docs/components-api/metergroup.md b/docs/components-api/metergroup.md index af6384cb..9359a59c 100644 --- a/docs/components-api/metergroup.md +++ b/docs/components-api/metergroup.md @@ -2,6 +2,8 @@ # ExtraMeterGroup +> ✅ **Реализован**: `ExtraMeterGroupComponent` (`@cdek-it/angular-ui-kit`) соответствует спецификации. + Отображение массива данных в виде группы измерителей (сегментов). | Свойство | Описание | Типизация | diff --git a/src/lib/components/metergroup/metergroup.component.ts b/src/lib/components/metergroup/metergroup.component.ts index b68c71cd..23382635 100644 --- a/src/lib/components/metergroup/metergroup.component.ts +++ b/src/lib/components/metergroup/metergroup.component.ts @@ -1,25 +1,31 @@ import { ChangeDetectionStrategy, Component, HostBinding, Input } from '@angular/core'; -import { MeterGroup, MeterItem } from 'primeng/metergroup'; -import { MultiSelect } from 'primeng/multiselect'; +import { MeterGroup } from 'primeng/metergroup'; export type ExtraMeterGroupOrientation = 'horizontal' | 'vertical'; export type ExtraMeterGroupLabelPosition = 'start' | 'end'; export type ExtraMeterGroupLabelOrientation = 'horizontal' | 'vertical'; -export type ExtraMeterItem = MeterItem; + +export interface ExtraMeterItem { + label?: string; + value?: number; + color?: string; + icon?: string; +} @Component({ selector: 'extra-metergroup', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, - imports: [MeterGroup, MultiSelect], + imports: [MeterGroup], template: ` - ` }) export class ExtraMeterGroupComponent { @@ -27,6 +33,9 @@ export class ExtraMeterGroupComponent { @Input() orientation: ExtraMeterGroupOrientation = 'horizontal'; @Input() labelPosition: ExtraMeterGroupLabelPosition = 'end'; @Input() labelOrientation: ExtraMeterGroupLabelOrientation = 'horizontal'; + /** Доступное имя: у корня role="meter", без имени его не прочитает скринридер. */ + @Input() ariaLabel: string | undefined = undefined; + @Input() ariaLabelledBy: string | undefined = undefined; @HostBinding('style.display') get hostDisplay() { return this.orientation === 'vertical' ? 'flex' : null; diff --git a/src/lib/components/metergroup/metergroup.figma.md b/src/lib/components/metergroup/metergroup.figma.md index a0ee4c4d..41251aa5 100644 --- a/src/lib/components/metergroup/metergroup.figma.md +++ b/src/lib/components/metergroup/metergroup.figma.md @@ -28,7 +28,11 @@ updated: '2026-06-22' | `labelPosition` | `'start' \| 'end'` | `'end'` | Позиция блока подписей относительно шкалы — соответствует Figma-свойству `label-position` | | `labelOrientation` | `'horizontal' \| 'vertical'` | `'horizontal'` | Раскладка списка подписей — соответствует Figma-свойству `label-orientation` | -Тип `ExtraMeterItem` реэкспортирует PrimeNG `MeterItem`: поле `value` (число) обязательно, поля `label`, `color` и `icon` опциональны. CSS-классы иконок берутся из справочника [icons.md](../../figma-code-connect/icons.md), цвета сегментов — из токенов [tokens.md](../../figma-code-connect/tokens.md). +Тип `ExtraMeterItem` — собственный интерфейс (поля `label`, `value`, `color`, `icon`, структурно +совпадает с PrimeNG `MeterItem`, но не реэкспортирует его напрямую — публичное API не должно течь +из PrimeNG, см. раздел «Общее направление проекта» в корневом `CLAUDE.md`). CSS-классы иконок +берутся из справочника [icons.md](../../figma-code-connect/icons.md), цвета сегментов — из токенов +[tokens.md](../../figma-code-connect/tokens.md). ## Variants diff --git a/src/lib/components/metergroup/public_api.ts b/src/lib/components/metergroup/public_api.ts index 810d4058..ed5d5b5b 100644 --- a/src/lib/components/metergroup/public_api.ts +++ b/src/lib/components/metergroup/public_api.ts @@ -1,4 +1 @@ export * from './metergroup.component'; - - - diff --git a/src/stories/components/metergroup/examples/metergroup-basic.component.ts b/src/stories/components/metergroup/examples/metergroup-basic.component.ts deleted file mode 100644 index 698f7639..00000000 --- a/src/stories/components/metergroup/examples/metergroup-basic.component.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { ChangeDetectionStrategy, Component } from '@angular/core'; -import { ExtraMeterGroupComponent } from '../../../../lib/components/metergroup/metergroup.component'; -import { MeterItem } from 'primeng/metergroup'; -import { defaultValue } from '../metergroup.data'; - -@Component({ - selector: 'app-metergroup-basic', - standalone: true, - imports: [ExtraMeterGroupComponent], - changeDetection: ChangeDetectionStrategy.OnPush, - template: ` -
- -
- ` -}) -export class MeterGroupBasicComponent { - value: MeterItem[] = defaultValue; -} diff --git a/src/stories/components/metergroup/examples/metergroup-horizontal.component.ts b/src/stories/components/metergroup/examples/metergroup-horizontal.component.ts index 014be3c3..09878056 100644 --- a/src/stories/components/metergroup/examples/metergroup-horizontal.component.ts +++ b/src/stories/components/metergroup/examples/metergroup-horizontal.component.ts @@ -1,7 +1,6 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; import { StoryObj } from '@storybook/angular'; -import { ExtraMeterGroupComponent } from '../../../../lib/components/metergroup/metergroup.component'; -import { MeterItem } from 'primeng/metergroup'; +import { ExtraMeterGroupComponent, ExtraMeterItem } from '../../../../lib/components/metergroup/metergroup.component'; import { defaultValue } from '../metergroup.data'; @Component({ @@ -11,17 +10,17 @@ import { defaultValue } from '../metergroup.data'; imports: [ExtraMeterGroupComponent], template: `
- +
` }) export class MeterGroupHorizontalComponent { - value: MeterItem[] = defaultValue; + value: ExtraMeterItem[] = defaultValue; } export const Horizontal: StoryObj = { render: () => ({ - template: ``, + template: `` }), parameters: { docs: { @@ -30,7 +29,7 @@ export const Horizontal: StoryObj = { language: 'ts', code: ` import { Component } from '@angular/core'; -import { ExtraMeterGroupComponent } from '@cdek-it/angular-ui-kit'; +import { ExtraMeterGroupComponent, ExtraMeterItem } from '@cdek-it/angular-ui-kit'; @Component({ selector: 'app-metergroup-horizontal', @@ -38,18 +37,18 @@ import { ExtraMeterGroupComponent } from '@cdek-it/angular-ui-kit'; changeDetection: ChangeDetectionStrategy.OnPush, imports: [ExtraMeterGroupComponent], template: \` - + \`, }) export class MeterGroupHorizontalComponent { - value: MeterItem[] = [ + value: ExtraMeterItem[] = [ { label: 'Space used', color: '#34d399', value: 16 }, { label: 'Unused', color: '#fbbf24', value: 8 }, { label: 'System', color: '#60a5fa', value: 24 }, ]; } - `, - }, - }, - }, + ` + } + } + } }; diff --git a/src/stories/components/metergroup/examples/metergroup-icon.component.ts b/src/stories/components/metergroup/examples/metergroup-icon.component.ts index 1f7e1779..fcc4f9bb 100644 --- a/src/stories/components/metergroup/examples/metergroup-icon.component.ts +++ b/src/stories/components/metergroup/examples/metergroup-icon.component.ts @@ -1,7 +1,6 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; import { StoryObj } from '@storybook/angular'; -import { ExtraMeterGroupComponent } from '../../../../lib/components/metergroup/metergroup.component'; -import { MeterItem } from 'primeng/metergroup'; +import { ExtraMeterGroupComponent, ExtraMeterItem } from '../../../../lib/components/metergroup/metergroup.component'; import { iconValue } from '../metergroup.data'; @Component({ @@ -11,17 +10,17 @@ import { iconValue } from '../metergroup.data'; imports: [ExtraMeterGroupComponent], template: `
- +
` }) export class MeterGroupIconComponent { - value: MeterItem[] = iconValue; + value: ExtraMeterItem[] = iconValue; } export const Icon: StoryObj = { render: () => ({ - template: ``, + template: `` }), parameters: { docs: { @@ -30,7 +29,7 @@ export const Icon: StoryObj = { language: 'ts', code: ` import { Component } from '@angular/core'; -import { ExtraMeterGroupComponent } from '@cdek-it/angular-ui-kit'; +import { ExtraMeterGroupComponent, ExtraMeterItem } from '@cdek-it/angular-ui-kit'; @Component({ selector: 'app-metergroup-icon', @@ -38,18 +37,18 @@ import { ExtraMeterGroupComponent } from '@cdek-it/angular-ui-kit'; changeDetection: ChangeDetectionStrategy.OnPush, imports: [ExtraMeterGroupComponent], template: \` - + \`, }) export class MeterGroupIconComponent { - value: MeterItem[] = [ + value: ExtraMeterItem[] = [ { label: 'Apps', color: '#34d399', value: 16, icon: 'ti ti-apps' }, { label: 'Messages', color: '#fbbf24', value: 8, icon: 'ti ti-message' }, { label: 'System', color: '#60a5fa', value: 24, icon: 'ti ti-cpu' }, ]; } - `, - }, - }, - }, + ` + } + } + } }; diff --git a/src/stories/components/metergroup/examples/metergroup-label-start.component.ts b/src/stories/components/metergroup/examples/metergroup-label-start.component.ts index 7997b9d6..6702aec4 100644 --- a/src/stories/components/metergroup/examples/metergroup-label-start.component.ts +++ b/src/stories/components/metergroup/examples/metergroup-label-start.component.ts @@ -1,9 +1,8 @@ -import { Component, ChangeDetectionStrategy} from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { StoryObj } from '@storybook/angular'; -import { ExtraMeterGroupComponent } from '../../../../lib/components/metergroup/metergroup.component'; -import { MeterItem } from 'primeng/metergroup'; +import { ExtraMeterGroupComponent, ExtraMeterItem } from '../../../../lib/components/metergroup/metergroup.component'; import { defaultValue } from '../metergroup.data'; -// todo написать extrameteritem + @Component({ selector: 'app-metergroup-label-start', standalone: true, @@ -11,17 +10,17 @@ import { defaultValue } from '../metergroup.data'; imports: [ExtraMeterGroupComponent], template: `
- +
` }) export class MeterGroupLabelStartComponent { - value: MeterItem[] = defaultValue; + value: ExtraMeterItem[] = defaultValue; } export const LabelStart: StoryObj = { render: () => ({ - template: ``, + template: `` }), parameters: { docs: { @@ -30,26 +29,26 @@ export const LabelStart: StoryObj = { language: 'ts', code: ` import { Component } from '@angular/core'; -import { ExtraMeterGroupComponent } from '@cdek-it/angular-ui-kit'; -// todo проверить meter item +import { ExtraMeterGroupComponent, ExtraMeterItem } from '@cdek-it/angular-ui-kit'; + @Component({ selector: 'app-metergroup-label-start', standalone: true, imports: [ExtraMeterGroupComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: \` - + \`, }) export class MeterGroupLabelStartComponent { - value: MeterItem[] = [ + value: ExtraMeterItem[] = [ { label: 'Space used', color: '#34d399', value: 16 }, { label: 'Unused', color: '#fbbf24', value: 8 }, { label: 'System', color: '#60a5fa', value: 24 }, ]; } - `, - }, - }, - }, + ` + } + } + } }; diff --git a/src/stories/components/metergroup/examples/metergroup-label-vertical.component.ts b/src/stories/components/metergroup/examples/metergroup-label-vertical.component.ts index 0886639b..92b71cec 100644 --- a/src/stories/components/metergroup/examples/metergroup-label-vertical.component.ts +++ b/src/stories/components/metergroup/examples/metergroup-label-vertical.component.ts @@ -1,7 +1,6 @@ -import { Component, ChangeDetectionStrategy} from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { StoryObj } from '@storybook/angular'; -import { ExtraMeterGroupComponent } from '../../../../lib/components/metergroup/metergroup.component'; -import { MeterItem } from 'primeng/metergroup'; +import { ExtraMeterGroupComponent, ExtraMeterItem } from '../../../../lib/components/metergroup/metergroup.component'; import { defaultValue } from '../metergroup.data'; @Component({ @@ -11,17 +10,17 @@ import { defaultValue } from '../metergroup.data'; imports: [ExtraMeterGroupComponent], template: `
- +
- `, + ` }) export class MeterGroupLabelVerticalComponent { - value: MeterItem[] = defaultValue; + value: ExtraMeterItem[] = defaultValue; } export const LabelVertical: StoryObj = { render: () => ({ - template: ``, + template: `` }), parameters: { docs: { @@ -30,7 +29,7 @@ export const LabelVertical: StoryObj = { language: 'ts', code: ` import { Component } from '@angular/core'; -import { ExtraMeterGroupComponent } from '@cdek-it/angular-ui-kit'; +import { ExtraMeterGroupComponent, ExtraMeterItem } from '@cdek-it/angular-ui-kit'; @Component({ selector: 'app-metergroup-label-vertical', @@ -38,18 +37,18 @@ import { ExtraMeterGroupComponent } from '@cdek-it/angular-ui-kit'; imports: [ExtraMeterGroupComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: \` - + \`, }) export class MeterGroupLabelVerticalComponent { - value: MeterItem[] = [ + value: ExtraMeterItem[] = [ { label: 'Space used', color: '#34d399', value: 16 }, { label: 'Unused', color: '#fbbf24', value: 8 }, { label: 'System', color: '#60a5fa', value: 24 }, ]; } - `, - }, - }, - }, + ` + } + } + } }; diff --git a/src/stories/components/metergroup/examples/metergroup-vertical.component.ts b/src/stories/components/metergroup/examples/metergroup-vertical.component.ts index 5ba664d6..884e295c 100644 --- a/src/stories/components/metergroup/examples/metergroup-vertical.component.ts +++ b/src/stories/components/metergroup/examples/metergroup-vertical.component.ts @@ -1,7 +1,6 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; import { StoryObj } from '@storybook/angular'; -import { ExtraMeterGroupComponent } from '../../../../lib/components/metergroup/metergroup.component'; -import { MeterItem } from 'primeng/metergroup'; +import { ExtraMeterGroupComponent, ExtraMeterItem } from '../../../../lib/components/metergroup/metergroup.component'; import { defaultValue } from '../metergroup.data'; @Component({ @@ -12,18 +11,18 @@ import { defaultValue } from '../metergroup.data'; template: `
- +
` }) export class MeterGroupVerticalComponent { - value: MeterItem[] = defaultValue; + value: ExtraMeterItem[] = defaultValue; } export const Vertical: StoryObj = { render: () => ({ - template: ``, + template: `` }), parameters: { docs: { @@ -32,7 +31,7 @@ export const Vertical: StoryObj = { language: 'ts', code: ` import { Component } from '@angular/core'; -import { ExtraMeterGroupComponent } from '@cdek-it/angular-ui-kit'; +import { ExtraMeterGroupComponent, ExtraMeterItem } from '@cdek-it/angular-ui-kit'; @Component({ selector: 'app-metergroup-vertical', @@ -41,19 +40,19 @@ import { ExtraMeterGroupComponent } from '@cdek-it/angular-ui-kit'; imports: [ExtraMeterGroupComponent], template: \`
- +
\`, }) export class MeterGroupVerticalComponent { - value: MeterItem[] = [ + value: ExtraMeterItem[] = [ { label: 'Space used', color: '#34d399', value: 16 }, { label: 'Unused', color: '#fbbf24', value: 8 }, { label: 'System', color: '#60a5fa', value: 24 }, ]; } - `, - }, - }, - }, + ` + } + } + } }; diff --git a/src/stories/components/metergroup/metergroup.data.ts b/src/stories/components/metergroup/metergroup.data.ts index 3c13fd5b..f59a7aae 100644 --- a/src/stories/components/metergroup/metergroup.data.ts +++ b/src/stories/components/metergroup/metergroup.data.ts @@ -1,13 +1,13 @@ -import { MeterItem } from 'primeng/metergroup'; +import { ExtraMeterItem } from '../../../lib/components/metergroup/metergroup.component'; -export const defaultValue: MeterItem[] = [ +export const defaultValue: ExtraMeterItem[] = [ { label: 'Space used', color: '#34d399', value: 16 }, { label: 'Unused', color: '#fbbf24', value: 8 }, - { label: 'System', color: '#60a5fa', value: 24 }, + { label: 'System', color: '#60a5fa', value: 24 } ]; -export const iconValue: MeterItem[] = [ +export const iconValue: ExtraMeterItem[] = [ { label: 'Apps', color: '#34d399', value: 16, icon: 'ti ti-apps' }, { label: 'Messages', color: '#fbbf24', value: 8, icon: 'ti ti-message' }, - { label: 'System', color: '#60a5fa', value: 24, icon: 'ti ti-cpu' }, + { label: 'System', color: '#60a5fa', value: 24, icon: 'ti ti-cpu' } ]; diff --git a/src/stories/components/metergroup/metergroup.stories.ts b/src/stories/components/metergroup/metergroup.stories.ts index f4eb03d2..afc6e110 100644 --- a/src/stories/components/metergroup/metergroup.stories.ts +++ b/src/stories/components/metergroup/metergroup.stories.ts @@ -21,9 +21,9 @@ const meta: Meta = { MeterGroupVerticalComponent, MeterGroupIconComponent, MeterGroupLabelStartComponent, - MeterGroupLabelVerticalComponent, - ], - }), + MeterGroupLabelVerticalComponent + ] + }) ], parameters: { docs: { @@ -31,54 +31,54 @@ const meta: Meta = { component: `Визуализирует несколько числовых значений в виде единой полосы прогресса с подписями. \`\`\`typescript -import { ExtraMeterGroupComponent as MeterGroupComponent } from '@cdek-it/angular-ui-kit'; -\`\`\``, - }, +import { ExtraMeterGroupComponent } from '@cdek-it/angular-ui-kit/components/metergroup'; +\`\`\`` + } }, designTokens: { - prefix: '--p-metergroup', - }, + prefix: '--p-metergroup' + } }, argTypes: { value: { control: false, description: 'Массив элементов с полями label, color, value и опционально icon', table: { - category: 'Props', - type: { summary: 'MeterItem[]' }, - }, + category: 'Свойства', + type: { summary: 'ExtraMeterItem[]' } + } }, orientation: { control: 'select', options: ['horizontal', 'vertical'], description: 'Ориентация полосы', table: { - category: 'Props', + category: 'Свойства', defaultValue: { summary: 'horizontal' }, - type: { summary: "'horizontal' | 'vertical'" }, - }, + type: { summary: "'horizontal' | 'vertical'" } + } }, labelPosition: { control: 'select', options: ['start', 'end'], description: 'Позиция списка меток относительно полосы', table: { - category: 'Props', + category: 'Свойства', defaultValue: { summary: 'end' }, - type: { summary: "'start' | 'end'" }, - }, + type: { summary: "'start' | 'end'" } + } }, labelOrientation: { control: 'select', options: ['horizontal', 'vertical'], description: 'Ориентация списка меток', table: { - category: 'Props', + category: 'Свойства', defaultValue: { summary: 'horizontal' }, - type: { summary: "'horizontal' | 'vertical'" }, - }, - }, - }, + type: { summary: "'horizontal' | 'vertical'" } + } + } + } }; const commonTemplate = ``; export default meta; @@ -97,22 +98,24 @@ export const Default: Story = { name: 'Default', render: (args) => ({ props: { ...args, value: defaultValue }, - template: args.orientation === 'vertical' - ? `
${commonTemplate}
` - : commonTemplate, + template: + args.orientation === 'vertical' + ? `
${commonTemplate}
` + : commonTemplate }), args: { + ariaLabel: 'Использование диска', orientation: 'horizontal', labelPosition: 'end', - labelOrientation: 'horizontal', + labelOrientation: 'horizontal' }, parameters: { docs: { description: { - story: 'Базовый пример компонента. Используйте Controls для интерактивного изменения пропсов.', - }, - }, - }, + story: 'Базовый пример компонента. Используйте Controls для интерактивного изменения пропсов.' + } + } + } }; // ── Re-exports from example components ────────────────────────────────────