;
+
+// ── Default ───────────────────────────────────────────────────────────────────
+
+export const ConfirmDialog: Story = DefaultStory;
+
+// ── Severities ────────────────────────────────────────────────────────────────
+
+export const SeveritiesStory: Story = Severities;
+
+// ── Sizes ─────────────────────────────────────────────────────────────────────
+
+export const Sizes: Story = SizesStory;
diff --git a/src/stories/components/confirm-dialog/examples/confirm-dialog-default.component.ts b/src/stories/components/confirm-dialog/examples/confirm-dialog-default.component.ts
new file mode 100644
index 0000000..44db24e
--- /dev/null
+++ b/src/stories/components/confirm-dialog/examples/confirm-dialog-default.component.ts
@@ -0,0 +1,81 @@
+import { Component } from '@angular/core';
+import { ExtraButtonComponent } from '../../../../lib/components/button/button.component';
+import { ExtraConfirmDialogComponent } from '../../../../lib/components/confirm-dialog/confirm-dialog.component';
+import { ConfirmDialogService } from '../../../../lib/components/confirm-dialog/confirm-dialog.service';
+
+const template = `
+
+
+
+
+
+`;
+
+@Component({
+ selector: 'app-confirm-dialog-default',
+ standalone: true,
+ imports: [ExtraConfirmDialogComponent, ExtraButtonComponent],
+ template,
+})
+export class ConfirmDialogDefaultComponent {
+ constructor(private confirmDialogService: ConfirmDialogService) {}
+
+ showConfirm(): void {
+ this.confirmDialogService.confirm({
+ key: 'cd-default',
+ message: 'Вы уверены, что хотите продолжить?',
+ header: 'Подтверждение',
+ icon: 'ti ti-alert-triangle',
+ acceptLabel: 'Да',
+ rejectLabel: 'Нет',
+ accept: () => {},
+ reject: () => {},
+ });
+ }
+}
+
+export const Default = {
+ name: 'ConfirmDialog',
+ render: () => ({
+ template: ``,
+ }),
+ parameters: {
+ docs: {
+ description: { story: 'Базовый пример диалога подтверждения.' },
+ source: {
+ language: 'ts',
+ code: `
+import { Component } from '@angular/core';
+import { ExtraConfirmDialogComponent, ConfirmDialogService, ExtraButtonComponent, provideConfirmDialog } from '@cdek-it/angular-ui-kit';
+
+@Component({
+ selector: 'app-confirm-dialog-default',
+ standalone: true,
+ imports: [ExtraConfirmDialogComponent, ExtraButtonComponent],
+ providers: [provideConfirmDialog()],
+ template: \`
+
+
+ \`,
+})
+export class ConfirmDialogDefaultComponent {
+ constructor(private confirmDialogService: ConfirmDialogService) {}
+
+ showConfirm(): void {
+ this.confirmDialogService.confirm({
+ key: 'cd-default',
+ message: 'Вы уверены, что хотите продолжить?',
+ header: 'Подтверждение',
+ icon: 'ti ti-alert-triangle',
+ acceptLabel: 'Да',
+ rejectLabel: 'Нет',
+ accept: () => {},
+ reject: () => {},
+ });
+ }
+}
+ `,
+ },
+ },
+ },
+};
diff --git a/src/stories/components/confirm-dialog/examples/confirm-dialog-severities.component.ts b/src/stories/components/confirm-dialog/examples/confirm-dialog-severities.component.ts
new file mode 100644
index 0000000..00a0920
--- /dev/null
+++ b/src/stories/components/confirm-dialog/examples/confirm-dialog-severities.component.ts
@@ -0,0 +1,189 @@
+import { Component } from '@angular/core';
+import { ExtraButtonComponent } from '../../../../lib/components/button/button.component';
+import { ExtraConfirmDialogComponent } from '../../../../lib/components/confirm-dialog/confirm-dialog.component';
+import { ConfirmDialogService } from '../../../../lib/components/confirm-dialog/confirm-dialog.service';
+
+interface SeverityItem {
+ type: 'success' | 'info' | 'warn' | 'help' | 'danger';
+ buttonSeverity: 'success' | 'info' | 'warn' | 'help' | 'danger';
+ icon: string;
+ label: string;
+ header: string;
+ message: string;
+ acceptLabel: string;
+}
+
+const SEVERITIES: SeverityItem[] = [
+ {
+ type: 'success',
+ buttonSeverity: 'success',
+ icon: 'ti ti-circle-check',
+ label: 'Успех',
+ header: 'Успех',
+ message: 'Операция выполнена успешно.',
+ acceptLabel: 'OK',
+ },
+ {
+ type: 'info',
+ buttonSeverity: 'info',
+ icon: 'ti ti-info-circle',
+ label: 'Информация',
+ header: 'Информация',
+ message: 'Это информационное сообщение.',
+ acceptLabel: 'Понятно',
+ },
+ {
+ type: 'warn',
+ buttonSeverity: 'warn',
+ icon: 'ti ti-alert-triangle',
+ label: 'Предупреждение',
+ header: 'Предупреждение',
+ message: 'Внимание! Это действие может иметь последствия.',
+ acceptLabel: 'Продолжить',
+ },
+ {
+ type: 'help',
+ buttonSeverity: 'help',
+ icon: 'ti ti-help-circle',
+ label: 'Справка',
+ header: 'Справка',
+ message: 'Нужна помощь с этим действием?',
+ acceptLabel: 'Да',
+ },
+ {
+ type: 'danger',
+ buttonSeverity: 'danger',
+ icon: 'ti ti-circle-x',
+ label: 'Удаление',
+ header: 'Подтверждение',
+ message: 'Это действие нельзя отменить. Продолжить?',
+ acceptLabel: 'Удалить',
+ },
+];
+
+const template = `
+
+
+
+
+
+
+
+
+ @for (severity of severities; track severity.type) {
+
+ }
+
+
+`;
+
+@Component({
+ selector: 'app-confirm-dialog-severities',
+ standalone: true,
+ imports: [ExtraConfirmDialogComponent, ExtraButtonComponent],
+ template,
+})
+export class ConfirmDialogSeveritiesComponent {
+ severities = SEVERITIES;
+
+ constructor(private confirmDialogService: ConfirmDialogService) {}
+
+ showConfirm(severity: SeverityItem): void {
+ this.confirmDialogService.confirm({
+ key: 'cd-severity-' + severity.type,
+ message: severity.message,
+ header: severity.header,
+ icon: severity.icon,
+ acceptLabel: severity.acceptLabel,
+ rejectLabel: 'Нет',
+ acceptButtonProps: { severity: severity.buttonSeverity },
+ accept: () => {},
+ reject: () => {},
+ });
+ }
+}
+
+export const Severities = {
+ name: 'Severities',
+ render: () => ({
+ template: ``,
+ }),
+ parameters: {
+ docs: {
+ description: { story: 'Варианты диалога с различными уровнями важности: success, info, warn, help, danger.' },
+ source: {
+ language: 'ts',
+ code: `
+import { Component } from '@angular/core';
+import { ExtraConfirmDialogComponent, ConfirmDialogService, ExtraButtonComponent, provideConfirmDialog } from '@cdek-it/angular-ui-kit';
+
+interface SeverityItem {
+ type: 'success' | 'info' | 'warn' | 'help' | 'danger';
+ buttonSeverity: 'success' | 'info' | 'warn' | 'help' | 'danger';
+ icon: string;
+ label: string;
+ header: string;
+ message: string;
+ acceptLabel: string;
+}
+
+const SEVERITIES: SeverityItem[] = [
+ { type: 'success', buttonSeverity: 'success', icon: 'ti ti-circle-check', label: 'Успех', header: 'Успех', message: 'Операция выполнена успешно.', acceptLabel: 'OK' },
+ { type: 'info', buttonSeverity: 'info', icon: 'ti ti-info-circle', label: 'Информация', header: 'Информация', message: 'Это информационное сообщение.', acceptLabel: 'Понятно' },
+ { type: 'warn', buttonSeverity: 'warn', icon: 'ti ti-alert-triangle', label: 'Предупреждение', header: 'Предупреждение', message: 'Внимание! Это действие может иметь последствия.', acceptLabel: 'Продолжить' },
+ { type: 'help', buttonSeverity: 'help', icon: 'ti ti-help-circle', label: 'Справка', header: 'Справка', message: 'Нужна помощь с этим действием?', acceptLabel: 'Да' },
+ { type: 'danger', buttonSeverity: 'danger', icon: 'ti ti-circle-x', label: 'Удаление', header: 'Подтверждение', message: 'Это действие нельзя отменить. Продолжить?', acceptLabel: 'Удалить' },
+];
+
+@Component({
+ selector: 'app-confirm-dialog-severities',
+ standalone: true,
+ imports: [ExtraConfirmDialogComponent, ExtraButtonComponent],
+ providers: [provideConfirmDialog()],
+ template: \`
+
+
+
+
+
+
+
+ @for (severity of severities; track severity.type) {
+
+ }
+
+ \`,
+})
+export class ConfirmDialogSeveritiesComponent {
+ severities = SEVERITIES;
+ constructor(private confirmDialogService: ConfirmDialogService) {}
+
+ showConfirm(severity: SeverityItem): void {
+ this.confirmDialogService.confirm({
+ key: 'cd-severity-' + severity.type,
+ message: severity.message,
+ header: severity.header,
+ icon: severity.icon,
+ acceptLabel: severity.acceptLabel,
+ rejectLabel: 'Нет',
+ acceptButtonProps: { severity: severity.buttonSeverity },
+ accept: () => {},
+ reject: () => {},
+ });
+ }
+}
+ `,
+ },
+ },
+ },
+};
diff --git a/src/stories/components/confirm-dialog/examples/confirm-dialog-sizes.component.ts b/src/stories/components/confirm-dialog/examples/confirm-dialog-sizes.component.ts
new file mode 100644
index 0000000..5fc3945
--- /dev/null
+++ b/src/stories/components/confirm-dialog/examples/confirm-dialog-sizes.component.ts
@@ -0,0 +1,130 @@
+import { Component } from '@angular/core';
+import { ExtraButtonComponent } from '../../../../lib/components/button/button.component';
+import {
+ ExtraConfirmDialogComponent,
+ ExtraConfirmDialogSize,
+} from '../../../../lib/components/confirm-dialog/confirm-dialog.component';
+import { ConfirmDialogService } from '../../../../lib/components/confirm-dialog/confirm-dialog.service';
+
+interface SizeItem {
+ key: ExtraConfirmDialogSize;
+ label: string;
+}
+
+const SIZES: SizeItem[] = [
+ { key: 'sm', label: 'Small' },
+ { key: 'default', label: 'Base' },
+ { key: 'lg', label: 'Large' },
+ { key: 'xlg', label: 'Extra Large' },
+];
+
+const template = `
+
+
+
+
+
+
+
+ @for (size of sizes; track size.key) {
+
+ }
+
+
+`;
+
+@Component({
+ selector: 'app-confirm-dialog-sizes',
+ standalone: true,
+ imports: [ExtraConfirmDialogComponent, ExtraButtonComponent],
+ template,
+})
+export class ConfirmDialogSizesComponent {
+ sizes = SIZES;
+
+ constructor(private confirmDialogService: ConfirmDialogService) {}
+
+ showConfirm(size: SizeItem): void {
+ this.confirmDialogService.confirm({
+ key: 'cd-size-' + size.key,
+ message: 'Это диалог размера ' + size.label,
+ header: 'Подтверждение',
+ icon: 'ti ti-alert-triangle',
+ acceptLabel: 'Да',
+ rejectLabel: 'Нет',
+ accept: () => {},
+ reject: () => {},
+ });
+ }
+}
+
+export const Sizes = {
+ name: 'Sizes',
+ render: () => ({
+ template: ``,
+ }),
+ parameters: {
+ docs: {
+ description: { story: 'Доступные размеры диалога: sm, base, lg, xlg.' },
+ source: {
+ language: 'ts',
+ code: `
+import { Component } from '@angular/core';
+import { ExtraConfirmDialogComponent, ExtraConfirmDialogSize, ConfirmDialogService, ExtraButtonComponent, provideConfirmDialog } from '@cdek-it/angular-ui-kit';
+
+interface SizeItem {
+ key: ExtraConfirmDialogSize;
+ label: string;
+}
+
+const SIZES: SizeItem[] = [
+ { key: 'sm', label: 'Small' },
+ { key: 'default', label: 'Base' },
+ { key: 'lg', label: 'Large' },
+ { key: 'xlg', label: 'Extra Large' },
+];
+
+@Component({
+ selector: 'app-confirm-dialog-sizes',
+ standalone: true,
+ imports: [ExtraConfirmDialogComponent, ExtraButtonComponent],
+ providers: [provideConfirmDialog()],
+ template: \`
+
+
+
+
+
+
+ @for (size of sizes; track size.key) {
+
+ }
+
+ \`,
+})
+export class ConfirmDialogSizesComponent {
+ sizes = SIZES;
+ constructor(private confirmDialogService: ConfirmDialogService) {}
+
+ showConfirm(size: SizeItem): void {
+ this.confirmDialogService.confirm({
+ key: 'cd-size-' + size.key,
+ message: 'Это диалог размера ' + size.label,
+ header: 'Подтверждение',
+ icon: 'ti ti-alert-triangle',
+ acceptLabel: 'Да',
+ rejectLabel: 'Нет',
+ accept: () => {},
+ reject: () => {},
+ });
+ }
+}
+ `,
+ },
+ },
+ },
+};
diff --git a/src/stories/components/p-data-table/examples/primeng-table-custom-body.component.ts b/src/stories/components/p-data-table/examples/primeng-table-custom-body.component.ts
new file mode 100644
index 0000000..f3920a9
--- /dev/null
+++ b/src/stories/components/p-data-table/examples/primeng-table-custom-body.component.ts
@@ -0,0 +1,134 @@
+import { Component } from '@angular/core';
+import { StoryObj, moduleMetadata } from '@storybook/angular';
+import { CommonModule } from '@angular/common';
+import { TableModule } from 'primeng/table';
+import { TagModule } from 'primeng/tag';
+
+const SHIPMENTS = [
+ { id: 1, trackNumber: 'ЦД-00123456', destination: 'Москва', status: 'В пути', weight: 2.5, cost: 1200 },
+ { id: 2, trackNumber: 'ЦД-00123457', destination: 'Новосибирск', status: 'Доставлен', weight: 0.8, cost: 450 },
+ { id: 3, trackNumber: 'ЦД-00123458', destination: 'Екатеринбург', status: 'Задержан', weight: 5.2, cost: 2100 },
+ { id: 4, trackNumber: 'ЦД-00123459', destination: 'Казань', status: 'В пути', weight: 1.3, cost: 750 },
+ { id: 5, trackNumber: 'ЦД-00123460', destination: 'Краснодар', status: 'Доставлен', weight: 3.7, cost: 1800 },
+];
+
+@Component({
+ selector: 'app-primeng-table-custom-body',
+ standalone: true,
+ imports: [CommonModule, TableModule, TagModule],
+ template: `
+
+
+
+ | Трек-номер |
+ Назначение |
+ Статус |
+ Вес, кг |
+ Стоимость, ₽ |
+
+
+
+
+ | {{ shipment.trackNumber }} |
+ {{ shipment.destination }} |
+
+
+ |
+ {{ shipment.weight }} кг |
+ {{ shipment.cost | currency:'RUB':'symbol':'1.0-0':'ru' }} |
+
+
+
+ | Нет данных для отображения |
+
+
+ `,
+})
+export class PDataTableCustomBodyComponent {
+ shipments = SHIPMENTS;
+
+ getSeverity(status: string): 'success' | 'warn' | 'danger' | 'info' | 'secondary' | undefined {
+ switch (status) {
+ case 'Доставлен': return 'success';
+ case 'В пути': return 'info';
+ case 'Задержан': return 'danger';
+ case 'Ожидание': return 'warn';
+ default: return 'secondary';
+ }
+ }
+}
+
+export const CustomBody: StoryObj = {
+ name: 'Custom Templates',
+ decorators: [moduleMetadata({ imports: [PDataTableCustomBodyComponent] })],
+ render: () => ({ template: `` }),
+ parameters: {
+ controls: { disable: true },
+ docs: {
+ description: {
+ story: 'Кастомные шаблоны для заголовка и тела таблицы на базе PrimeNG pTable.',
+ },
+ source: {
+ language: 'ts',
+ code: `import { Component } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { TableModule } from 'primeng/table';
+import { TagModule } from 'primeng/tag';
+
+const SHIPMENTS = [
+ { id: 1, trackNumber: 'ЦД-00123456', destination: 'Москва', status: 'В пути', weight: 2.5, cost: 1200 },
+ { id: 2, trackNumber: 'ЦД-00123457', destination: 'Новосибирск', status: 'Доставлен', weight: 0.8, cost: 450 },
+ { id: 3, trackNumber: 'ЦД-00123458', destination: 'Екатеринбург', status: 'Задержан', weight: 5.2, cost: 2100 },
+ { id: 4, trackNumber: 'ЦД-00123459', destination: 'Казань', status: 'В пути', weight: 1.3, cost: 750 },
+ { id: 5, trackNumber: 'ЦД-00123460', destination: 'Краснодар', status: 'Доставлен', weight: 3.7, cost: 1800 },
+];
+
+@Component({
+ selector: 'app-example',
+ standalone: true,
+ imports: [CommonModule, TableModule, TagModule],
+ template: \`
+
+
+
+ | Трек-номер |
+ Назначение |
+ Статус |
+ Вес, кг |
+ Стоимость, ₽ |
+
+
+
+
+ | {{ shipment.trackNumber }} |
+ {{ shipment.destination }} |
+
+
+ |
+ {{ shipment.weight }} кг |
+ {{ shipment.cost | currency:'RUB':'symbol':'1.0-0':'ru' }} |
+
+
+
+ | Нет данных для отображения |
+
+
+ \`,
+})
+export class ExampleComponent {
+ shipments = SHIPMENTS;
+
+ getSeverity(status: string): 'success' | 'warn' | 'danger' | 'info' | 'secondary' | undefined {
+ switch (status) {
+ case 'Доставлен': return 'success';
+ case 'В пути': return 'info';
+ case 'Задержан': return 'danger';
+ case 'Ожидание': return 'warn';
+ default: return 'secondary';
+ }
+ }
+}`,
+ },
+ },
+ },
+};
diff --git a/src/stories/components/p-data-table/examples/primeng-table-default.component.ts b/src/stories/components/p-data-table/examples/primeng-table-default.component.ts
new file mode 100644
index 0000000..f50fd9a
--- /dev/null
+++ b/src/stories/components/p-data-table/examples/primeng-table-default.component.ts
@@ -0,0 +1,106 @@
+import { Component } from '@angular/core';
+import { StoryObj, moduleMetadata } from '@storybook/angular';
+import { TableModule } from 'primeng/table';
+
+const SHIPMENTS = [
+ { id: 1, trackNumber: 'ЦД-00123456', destination: 'Москва', status: 'В пути', weight: 2.5, cost: 1200 },
+ { id: 2, trackNumber: 'ЦД-00123457', destination: 'Новосибирск', status: 'Доставлен', weight: 0.8, cost: 450 },
+ { id: 3, trackNumber: 'ЦД-00123458', destination: 'Екатеринбург', status: 'Задержан', weight: 5.2, cost: 2100 },
+ { id: 4, trackNumber: 'ЦД-00123459', destination: 'Казань', status: 'В пути', weight: 1.3, cost: 750 },
+ { id: 5, trackNumber: 'ЦД-00123460', destination: 'Краснодар', status: 'Доставлен', weight: 3.7, cost: 1800 },
+ { id: 6, trackNumber: 'ЦД-00123461', destination: 'Воронеж', status: 'Ожидание', weight: 0.5, cost: 350 },
+ { id: 7, trackNumber: 'ЦД-00123462', destination: 'Самара', status: 'В пути', weight: 8.0, cost: 3200 },
+ { id: 8, trackNumber: 'ЦД-00123463', destination: 'Ростов-на-Дону', status: 'Доставлен', weight: 2.1, cost: 980 },
+];
+
+@Component({
+ selector: 'app-primeng-table-default',
+ standalone: true,
+ imports: [TableModule],
+ template: `
+
+
+
+ | Трек-номер |
+ Назначение |
+ Статус |
+ Вес, кг |
+ Стоимость, ₽ |
+
+
+
+
+ | {{ shipment.trackNumber }} |
+ {{ shipment.destination }} |
+ {{ shipment.status }} |
+ {{ shipment.weight }} |
+ {{ shipment.cost }} |
+
+
+
+ `,
+})
+export class PDataTableDefaultComponent {
+ shipments = SHIPMENTS;
+}
+
+export const Default: StoryObj = {
+ name: 'DataTable',
+ decorators: [moduleMetadata({ imports: [PDataTableDefaultComponent] })],
+ render: () => ({ template: `` }),
+ parameters: {
+ controls: { disable: true },
+ docs: {
+ description: {
+ story: 'Базовая таблица отправлений с сортировкой по всем столбцам на базе PrimeNG pTable.',
+ },
+ source: {
+ language: 'ts',
+ code: `import { Component } from '@angular/core';
+import { TableModule } from 'primeng/table';
+
+const SHIPMENTS = [
+ { id: 1, trackNumber: 'ЦД-00123456', destination: 'Москва', status: 'В пути', weight: 2.5, cost: 1200 },
+ { id: 2, trackNumber: 'ЦД-00123457', destination: 'Новосибирск', status: 'Доставлен', weight: 0.8, cost: 450 },
+ { id: 3, trackNumber: 'ЦД-00123458', destination: 'Екатеринбург', status: 'Задержан', weight: 5.2, cost: 2100 },
+ { id: 4, trackNumber: 'ЦД-00123459', destination: 'Казань', status: 'В пути', weight: 1.3, cost: 750 },
+ { id: 5, trackNumber: 'ЦД-00123460', destination: 'Краснодар', status: 'Доставлен', weight: 3.7, cost: 1800 },
+ { id: 6, trackNumber: 'ЦД-00123461', destination: 'Воронеж', status: 'Ожидание', weight: 0.5, cost: 350 },
+ { id: 7, trackNumber: 'ЦД-00123462', destination: 'Самара', status: 'В пути', weight: 8.0, cost: 3200 },
+ { id: 8, trackNumber: 'ЦД-00123463', destination: 'Ростов-на-Дону', status: 'Доставлен', weight: 2.1, cost: 980 },
+];
+
+@Component({
+ selector: 'app-example',
+ standalone: true,
+ imports: [TableModule],
+ template: \`
+
+
+
+ | Трек-номер |
+ Назначение |
+ Статус |
+ Вес, кг |
+ Стоимость, ₽ |
+
+
+
+
+ | {{ shipment.trackNumber }} |
+ {{ shipment.destination }} |
+ {{ shipment.status }} |
+ {{ shipment.weight }} |
+ {{ shipment.cost }} |
+
+
+
+ \`,
+})
+export class ExampleComponent {
+ shipments = SHIPMENTS;
+}`,
+ },
+ },
+ },
+};
diff --git a/src/stories/components/p-data-table/examples/primeng-table-grid-lines.component.ts b/src/stories/components/p-data-table/examples/primeng-table-grid-lines.component.ts
new file mode 100644
index 0000000..4eb8316
--- /dev/null
+++ b/src/stories/components/p-data-table/examples/primeng-table-grid-lines.component.ts
@@ -0,0 +1,100 @@
+import { Component } from '@angular/core';
+import { StoryObj, moduleMetadata } from '@storybook/angular';
+import { TableModule } from 'primeng/table';
+
+const SHIPMENTS = [
+ { id: 1, trackNumber: 'ЦД-00123456', destination: 'Москва', status: 'В пути', weight: 2.5, cost: 1200 },
+ { id: 2, trackNumber: 'ЦД-00123457', destination: 'Новосибирск', status: 'Доставлен', weight: 0.8, cost: 450 },
+ { id: 3, trackNumber: 'ЦД-00123458', destination: 'Екатеринбург', status: 'Задержан', weight: 5.2, cost: 2100 },
+ { id: 4, trackNumber: 'ЦД-00123459', destination: 'Казань', status: 'В пути', weight: 1.3, cost: 750 },
+ { id: 5, trackNumber: 'ЦД-00123460', destination: 'Краснодар', status: 'Доставлен', weight: 3.7, cost: 1800 },
+];
+
+@Component({
+ selector: 'app-primeng-table-grid-lines',
+ standalone: true,
+ imports: [TableModule],
+ template: `
+
+
+
+ | Трек-номер |
+ Назначение |
+ Статус |
+ Вес, кг |
+ Стоимость, ₽ |
+
+
+
+
+ | {{ shipment.trackNumber }} |
+ {{ shipment.destination }} |
+ {{ shipment.status }} |
+ {{ shipment.weight }} |
+ {{ shipment.cost }} |
+
+
+
+ `,
+})
+export class PDataTableGridLinesComponent {
+ shipments = SHIPMENTS;
+}
+
+export const GridLines: StoryObj = {
+ name: 'GridLines',
+ decorators: [moduleMetadata({ imports: [PDataTableGridLinesComponent] })],
+ render: () => ({ template: `` }),
+ parameters: {
+ controls: { disable: true },
+ docs: {
+ description: {
+ story: 'Сетка между ячейками для наглядного разграничения данных на базе PrimeNG pTable.',
+ },
+ source: {
+ language: 'ts',
+ code: `import { Component } from '@angular/core';
+import { TableModule } from 'primeng/table';
+
+const SHIPMENTS = [
+ { id: 1, trackNumber: 'ЦД-00123456', destination: 'Москва', status: 'В пути', weight: 2.5, cost: 1200 },
+ { id: 2, trackNumber: 'ЦД-00123457', destination: 'Новосибирск', status: 'Доставлен', weight: 0.8, cost: 450 },
+ { id: 3, trackNumber: 'ЦД-00123458', destination: 'Екатеринбург', status: 'Задержан', weight: 5.2, cost: 2100 },
+ { id: 4, trackNumber: 'ЦД-00123459', destination: 'Казань', status: 'В пути', weight: 1.3, cost: 750 },
+ { id: 5, trackNumber: 'ЦД-00123460', destination: 'Краснодар', status: 'Доставлен', weight: 3.7, cost: 1800 },
+];
+
+@Component({
+ selector: 'app-example',
+ standalone: true,
+ imports: [TableModule],
+ template: \`
+
+
+
+ | Трек-номер |
+ Назначение |
+ Статус |
+ Вес, кг |
+ Стоимость, ₽ |
+
+
+
+
+ | {{ shipment.trackNumber }} |
+ {{ shipment.destination }} |
+ {{ shipment.status }} |
+ {{ shipment.weight }} |
+ {{ shipment.cost }} |
+
+
+
+ \`,
+})
+export class ExampleComponent {
+ shipments = SHIPMENTS;
+}`,
+ },
+ },
+ },
+};
diff --git a/src/stories/components/p-data-table/examples/primeng-table-lazy.component.ts b/src/stories/components/p-data-table/examples/primeng-table-lazy.component.ts
new file mode 100644
index 0000000..62c6905
--- /dev/null
+++ b/src/stories/components/p-data-table/examples/primeng-table-lazy.component.ts
@@ -0,0 +1,182 @@
+import { Component, OnInit } from '@angular/core';
+import { StoryObj, moduleMetadata } from '@storybook/angular';
+import { TableModule } from 'primeng/table';
+
+const ALL_SHIPMENTS = Array.from({ length: 500 }, (_, i) => ({
+ id: i + 1,
+ trackNumber: `ЦД-${String(i + 100000).padStart(8, '0')}`,
+ destination: ['Москва', 'Новосибирск', 'Екатеринбург', 'Казань', 'Краснодар', 'Санкт-Петербург', 'Воронеж', 'Самара', 'Ростов-на-Дону', 'Уфа'][i % 10],
+ status: ['В пути', 'Доставлен', 'Задержан', 'Ожидание'][i % 4],
+ weight: Number(((i * 0.37 + 0.5) % 10).toFixed(1)),
+ cost: ((i * 137 + 200) % 5000) + 200,
+}));
+
+const PAGE_SIZE = 50;
+
+@Component({
+ selector: 'app-primeng-table-lazy',
+ standalone: true,
+ imports: [TableModule],
+ template: `
+
+
+
+ | Трек-номер |
+ Назначение |
+ Статус |
+ Вес, кг |
+ Стоимость, ₽ |
+
+
+
+
+ | {{ shipment?.trackNumber }} |
+ {{ shipment?.destination }} |
+ {{ shipment?.status }} |
+ {{ shipment?.weight }} |
+ {{ shipment?.cost }} |
+
+
+
+
+ | Загрузка… |
+
+
+
+ `,
+})
+export class PDataTableLazyComponent implements OnInit {
+ readonly PAGE_SIZE = PAGE_SIZE;
+
+ shipments: any[] = Array.from({ length: ALL_SHIPMENTS.length });
+ totalRecords = ALL_SHIPMENTS.length;
+ loading = false;
+
+ ngOnInit(): void {}
+
+ onLazyLoad(event: any): void {
+ this.loading = true;
+ const start = event.first ?? 0;
+ const end = start + (event.rows ?? PAGE_SIZE);
+
+ setTimeout(() => {
+ const page = ALL_SHIPMENTS.slice(start, end);
+ const updated = [...this.shipments];
+ for (let i = 0; i < page.length; i++) {
+ updated[start + i] = page[i];
+ }
+ this.shipments = updated;
+ this.loading = false;
+ }, 300);
+ }
+}
+
+export const LazyLoading: StoryObj = {
+ name: 'Lazy Loading',
+ decorators: [moduleMetadata({ imports: [PDataTableLazyComponent] })],
+ render: () => ({ template: `` }),
+ parameters: {
+ controls: { disable: true },
+ docs: {
+ description: {
+ story: 'Lazy Loading + Virtual Scroll для работы с большими наборами данных. Данные подгружаются порциями при прокрутке таблицы. Используйте `[lazy]="true"`, `[virtualScroll]="true"`, `[virtualScrollItemSize]`, `[totalRecords]` и `(onLazyLoad)` для управления загрузкой данных с сервера.',
+ },
+ source: {
+ language: 'ts',
+ code: `import { Component, OnInit } from '@angular/core';
+import { TableModule } from 'primeng/table';
+
+const ALL_SHIPMENTS = Array.from({ length: 500 }, (_, i) => ({
+ id: i + 1,
+ trackNumber: \`ЦД-\${String(i + 100000).padStart(8, '0')}\`,
+ destination: ['Москва', 'Новосибирск', 'Екатеринбург', 'Казань', 'Краснодар', 'Санкт-Петербург', 'Воронеж', 'Самара', 'Ростов-на-Дону', 'Уфа'][i % 10],
+ status: ['В пути', 'Доставлен', 'Задержан', 'Ожидание'][i % 4],
+ weight: Number(((i * 0.37 + 0.5) % 10).toFixed(1)),
+ cost: ((i * 137 + 200) % 5000) + 200,
+}));
+
+const PAGE_SIZE = 50;
+
+@Component({
+ selector: 'app-example',
+ standalone: true,
+ imports: [TableModule],
+ template: \`
+
+
+
+ | Трек-номер |
+ Назначение |
+ Статус |
+ Вес, кг |
+ Стоимость, ₽ |
+
+
+
+
+ | {{ shipment?.trackNumber }} |
+ {{ shipment?.destination }} |
+ {{ shipment?.status }} |
+ {{ shipment?.weight }} |
+ {{ shipment?.cost }} |
+
+
+
+
+ | Загрузка… |
+
+
+
+ \`,
+})
+export class ExampleComponent implements OnInit {
+ readonly PAGE_SIZE = PAGE_SIZE;
+
+ shipments: any[] = Array.from({ length: ALL_SHIPMENTS.length });
+ totalRecords = ALL_SHIPMENTS.length;
+ loading = false;
+
+ ngOnInit(): void {}
+
+ onLazyLoad(event: any): void {
+ this.loading = true;
+ const start = event.first ?? 0;
+ const end = start + (event.rows ?? PAGE_SIZE);
+
+ setTimeout(() => {
+ const page = ALL_SHIPMENTS.slice(start, end);
+ const updated = [...this.shipments];
+ for (let i = 0; i < page.length; i++) {
+ updated[start + i] = page[i];
+ }
+ this.shipments = updated;
+ this.loading = false;
+ }, 300);
+ }
+}`,
+ },
+ },
+ },
+};
diff --git a/src/stories/components/p-data-table/examples/primeng-table-pagination.component.ts b/src/stories/components/p-data-table/examples/primeng-table-pagination.component.ts
new file mode 100644
index 0000000..3c4446c
--- /dev/null
+++ b/src/stories/components/p-data-table/examples/primeng-table-pagination.component.ts
@@ -0,0 +1,106 @@
+import { Component } from '@angular/core';
+import { StoryObj, moduleMetadata } from '@storybook/angular';
+import { TableModule } from 'primeng/table';
+
+const SHIPMENTS = [
+ { id: 1, trackNumber: 'ЦД-00123456', destination: 'Москва', status: 'В пути', weight: 2.5, cost: 1200 },
+ { id: 2, trackNumber: 'ЦД-00123457', destination: 'Новосибирск', status: 'Доставлен', weight: 0.8, cost: 450 },
+ { id: 3, trackNumber: 'ЦД-00123458', destination: 'Екатеринбург', status: 'Задержан', weight: 5.2, cost: 2100 },
+ { id: 4, trackNumber: 'ЦД-00123459', destination: 'Казань', status: 'В пути', weight: 1.3, cost: 750 },
+ { id: 5, trackNumber: 'ЦД-00123460', destination: 'Краснодар', status: 'Доставлен', weight: 3.7, cost: 1800 },
+ { id: 6, trackNumber: 'ЦД-00123461', destination: 'Воронеж', status: 'Ожидание', weight: 0.5, cost: 350 },
+ { id: 7, trackNumber: 'ЦД-00123462', destination: 'Самара', status: 'В пути', weight: 8.0, cost: 3200 },
+ { id: 8, trackNumber: 'ЦД-00123463', destination: 'Ростов-на-Дону', status: 'Доставлен', weight: 2.1, cost: 980 },
+];
+
+@Component({
+ selector: 'app-primeng-table-pagination',
+ standalone: true,
+ imports: [TableModule],
+ template: `
+
+
+
+ | Трек-номер |
+ Назначение |
+ Статус |
+ Вес, кг |
+ Стоимость, ₽ |
+
+
+
+
+ | {{ shipment.trackNumber }} |
+ {{ shipment.destination }} |
+ {{ shipment.status }} |
+ {{ shipment.weight }} |
+ {{ shipment.cost }} |
+
+
+
+ `,
+})
+export class PDataTablePaginationComponent {
+ shipments = SHIPMENTS;
+}
+
+export const Pagination: StoryObj = {
+ name: 'Pagination',
+ decorators: [moduleMetadata({ imports: [PDataTablePaginationComponent] })],
+ render: () => ({ template: `` }),
+ parameters: {
+ controls: { disable: true },
+ docs: {
+ description: {
+ story: 'Пагинация для больших наборов данных на базе PrimeNG pTable.',
+ },
+ source: {
+ language: 'ts',
+ code: `import { Component } from '@angular/core';
+import { TableModule } from 'primeng/table';
+
+const SHIPMENTS = [
+ { id: 1, trackNumber: 'ЦД-00123456', destination: 'Москва', status: 'В пути', weight: 2.5, cost: 1200 },
+ { id: 2, trackNumber: 'ЦД-00123457', destination: 'Новосибирск', status: 'Доставлен', weight: 0.8, cost: 450 },
+ { id: 3, trackNumber: 'ЦД-00123458', destination: 'Екатеринбург', status: 'Задержан', weight: 5.2, cost: 2100 },
+ { id: 4, trackNumber: 'ЦД-00123459', destination: 'Казань', status: 'В пути', weight: 1.3, cost: 750 },
+ { id: 5, trackNumber: 'ЦД-00123460', destination: 'Краснодар', status: 'Доставлен', weight: 3.7, cost: 1800 },
+ { id: 6, trackNumber: 'ЦД-00123461', destination: 'Воронеж', status: 'Ожидание', weight: 0.5, cost: 350 },
+ { id: 7, trackNumber: 'ЦД-00123462', destination: 'Самара', status: 'В пути', weight: 8.0, cost: 3200 },
+ { id: 8, trackNumber: 'ЦД-00123463', destination: 'Ростов-на-Дону', status: 'Доставлен', weight: 2.1, cost: 980 },
+];
+
+@Component({
+ selector: 'app-example',
+ standalone: true,
+ imports: [TableModule],
+ template: \`
+
+
+
+ | Трек-номер |
+ Назначение |
+ Статус |
+ Вес, кг |
+ Стоимость, ₽ |
+
+
+
+
+ | {{ shipment.trackNumber }} |
+ {{ shipment.destination }} |
+ {{ shipment.status }} |
+ {{ shipment.weight }} |
+ {{ shipment.cost }} |
+
+
+
+ \`,
+})
+export class ExampleComponent {
+ shipments = SHIPMENTS;
+}`,
+ },
+ },
+ },
+};
diff --git a/src/stories/components/p-data-table/examples/primeng-table-scroll-horizontal.component.ts b/src/stories/components/p-data-table/examples/primeng-table-scroll-horizontal.component.ts
new file mode 100644
index 0000000..9e3cb8c
--- /dev/null
+++ b/src/stories/components/p-data-table/examples/primeng-table-scroll-horizontal.component.ts
@@ -0,0 +1,132 @@
+import { Component } from '@angular/core';
+import { StoryObj, moduleMetadata } from '@storybook/angular';
+import { TableModule } from 'primeng/table';
+
+const SHIPMENTS = [
+ { id: 1, trackNumber: 'ЦД-00123456', sender: 'Иванов И.И.', destination: 'Москва', status: 'В пути', weight: 2.5, cost: 1200, dimensions: '30×20×15 см' },
+ { id: 2, trackNumber: 'ЦД-00123457', sender: 'Петров П.П.', destination: 'Новосибирск', status: 'Доставлен', weight: 0.8, cost: 450, dimensions: '10×10×10 см' },
+ { id: 3, trackNumber: 'ЦД-00123458', sender: 'Сидоров С.С.', destination: 'Екатеринбург', status: 'Задержан', weight: 5.2, cost: 2100, dimensions: '50×40×30 см' },
+ { id: 4, trackNumber: 'ЦД-00123459', sender: 'Козлов К.К.', destination: 'Казань', status: 'В пути', weight: 1.3, cost: 750, dimensions: '20×15×10 см' },
+ { id: 5, trackNumber: 'ЦД-00123460', sender: 'Новиков Н.Н.', destination: 'Краснодар', status: 'Доставлен', weight: 3.7, cost: 1800, dimensions: '40×30×20 см' },
+];
+
+@Component({
+ selector: 'app-primeng-table-scroll-horizontal',
+ standalone: true,
+ imports: [TableModule],
+ template: `
+
+
+
+ |
+ Трек-номер
+ |
+
+ Отправитель
+ |
+
+ Назначение
+ |
+
+ Статус
+ |
+
+ Вес, кг
+ |
+
+ Стоимость, ₽
+ |
+ Габариты |
+
+
+
+
+ | {{ shipment.trackNumber }} |
+ {{ shipment.sender }} |
+ {{ shipment.destination }} |
+ {{ shipment.status }} |
+ {{ shipment.weight }} |
+ {{ shipment.cost }} |
+ {{ shipment.dimensions }} |
+
+
+
+ `,
+})
+export class PDataTableScrollHorizontalComponent {
+ shipments = SHIPMENTS;
+}
+
+export const ScrollHorizontal: StoryObj = {
+ name: 'Scroll: Horizontal',
+ decorators: [moduleMetadata({ imports: [PDataTableScrollHorizontalComponent] })],
+ render: () => ({ template: `` }),
+ parameters: {
+ controls: { disable: true },
+ docs: {
+ description: {
+ story: 'Горизонтальная прокрутка при большом количестве столбцов на базе PrimeNG pTable.',
+ },
+ source: {
+ language: 'ts',
+ code: `import { Component } from '@angular/core';
+import { TableModule } from 'primeng/table';
+
+const SHIPMENTS = [
+ { id: 1, trackNumber: 'ЦД-00123456', sender: 'Иванов И.И.', destination: 'Москва', status: 'В пути', weight: 2.5, cost: 1200, dimensions: '30×20×15 см' },
+ { id: 2, trackNumber: 'ЦД-00123457', sender: 'Петров П.П.', destination: 'Новосибирск', status: 'Доставлен', weight: 0.8, cost: 450, dimensions: '10×10×10 см' },
+ { id: 3, trackNumber: 'ЦД-00123458', sender: 'Сидоров С.С.', destination: 'Екатеринбург', status: 'Задержан', weight: 5.2, cost: 2100, dimensions: '50×40×30 см' },
+ { id: 4, trackNumber: 'ЦД-00123459', sender: 'Козлов К.К.', destination: 'Казань', status: 'В пути', weight: 1.3, cost: 750, dimensions: '20×15×10 см' },
+ { id: 5, trackNumber: 'ЦД-00123460', sender: 'Новиков Н.Н.', destination: 'Краснодар', status: 'Доставлен', weight: 3.7, cost: 1800, dimensions: '40×30×20 см' },
+];
+
+@Component({
+ selector: 'app-example',
+ standalone: true,
+ imports: [TableModule],
+ template: \`
+
+
+
+ |
+ Трек-номер
+ |
+
+ Отправитель
+ |
+
+ Назначение
+ |
+
+ Статус
+ |
+
+ Вес, кг
+ |
+
+ Стоимость, ₽
+ |
+ Габариты |
+
+
+
+
+ | {{ shipment.trackNumber }} |
+ {{ shipment.sender }} |
+ {{ shipment.destination }} |
+ {{ shipment.status }} |
+ {{ shipment.weight }} |
+ {{ shipment.cost }} |
+ {{ shipment.dimensions }} |
+
+
+
+ \`,
+})
+export class ExampleComponent {
+ shipments = SHIPMENTS;
+}`,
+ },
+ },
+ },
+};
diff --git a/src/stories/components/p-data-table/examples/primeng-table-scroll-vertical.component.ts b/src/stories/components/p-data-table/examples/primeng-table-scroll-vertical.component.ts
new file mode 100644
index 0000000..ea9a6cc
--- /dev/null
+++ b/src/stories/components/p-data-table/examples/primeng-table-scroll-vertical.component.ts
@@ -0,0 +1,102 @@
+import { Component } from '@angular/core';
+import { StoryObj, moduleMetadata } from '@storybook/angular';
+import { TableModule } from 'primeng/table';
+
+const BASE_SHIPMENTS = [
+ { id: 1, trackNumber: 'ЦД-00123456', destination: 'Москва', status: 'В пути', weight: 2.5 },
+ { id: 2, trackNumber: 'ЦД-00123457', destination: 'Новосибирск', status: 'Доставлен', weight: 0.8 },
+ { id: 3, trackNumber: 'ЦД-00123458', destination: 'Екатеринбург', status: 'Задержан', weight: 5.2 },
+ { id: 4, trackNumber: 'ЦД-00123459', destination: 'Казань', status: 'В пути', weight: 1.3 },
+ { id: 5, trackNumber: 'ЦД-00123460', destination: 'Краснодар', status: 'Доставлен', weight: 3.7 },
+ { id: 6, trackNumber: 'ЦД-00123461', destination: 'Воронеж', status: 'Ожидание', weight: 0.5 },
+ { id: 7, trackNumber: 'ЦД-00123462', destination: 'Самара', status: 'В пути', weight: 8.0 },
+ { id: 8, trackNumber: 'ЦД-00123463', destination: 'Ростов-на-Дону', status: 'Доставлен', weight: 2.1 },
+];
+
+@Component({
+ selector: 'app-primeng-table-scroll-vertical',
+ standalone: true,
+ imports: [TableModule],
+ template: `
+
+
+
+ | Трек-номер |
+ Назначение |
+ Статус |
+ Вес, кг |
+
+
+
+
+ | {{ shipment.trackNumber }} |
+ {{ shipment.destination }} |
+ {{ shipment.status }} |
+ {{ shipment.weight }} |
+
+
+
+ `,
+})
+export class PDataTableScrollVerticalComponent {
+ shipments = [...BASE_SHIPMENTS, ...BASE_SHIPMENTS, ...BASE_SHIPMENTS];
+}
+
+export const ScrollVertical: StoryObj = {
+ name: 'Scroll: Vertical',
+ decorators: [moduleMetadata({ imports: [PDataTableScrollVerticalComponent] })],
+ render: () => ({ template: `` }),
+ parameters: {
+ controls: { disable: true },
+ docs: {
+ description: {
+ story: 'Вертикальная прокрутка с фиксированной высотой контейнера на базе PrimeNG pTable.',
+ },
+ source: {
+ language: 'ts',
+ code: `import { Component } from '@angular/core';
+import { TableModule } from 'primeng/table';
+
+const BASE_SHIPMENTS = [
+ { id: 1, trackNumber: 'ЦД-00123456', destination: 'Москва', status: 'В пути', weight: 2.5 },
+ { id: 2, trackNumber: 'ЦД-00123457', destination: 'Новосибирск', status: 'Доставлен', weight: 0.8 },
+ { id: 3, trackNumber: 'ЦД-00123458', destination: 'Екатеринбург', status: 'Задержан', weight: 5.2 },
+ { id: 4, trackNumber: 'ЦД-00123459', destination: 'Казань', status: 'В пути', weight: 1.3 },
+ { id: 5, trackNumber: 'ЦД-00123460', destination: 'Краснодар', status: 'Доставлен', weight: 3.7 },
+ { id: 6, trackNumber: 'ЦД-00123461', destination: 'Воронеж', status: 'Ожидание', weight: 0.5 },
+ { id: 7, trackNumber: 'ЦД-00123462', destination: 'Самара', status: 'В пути', weight: 8.0 },
+ { id: 8, trackNumber: 'ЦД-00123463', destination: 'Ростов-на-Дону', status: 'Доставлен', weight: 2.1 },
+];
+
+@Component({
+ selector: 'app-example',
+ standalone: true,
+ imports: [TableModule],
+ template: \`
+
+
+
+ | Трек-номер |
+ Назначение |
+ Статус |
+ Вес, кг |
+
+
+
+
+ | {{ shipment.trackNumber }} |
+ {{ shipment.destination }} |
+ {{ shipment.status }} |
+ {{ shipment.weight }} |
+
+
+
+ \`,
+})
+export class ExampleComponent {
+ shipments = [...BASE_SHIPMENTS, ...BASE_SHIPMENTS, ...BASE_SHIPMENTS];
+}`,
+ },
+ },
+ },
+};
diff --git a/src/stories/components/p-data-table/examples/primeng-table-selectable.component.ts b/src/stories/components/p-data-table/examples/primeng-table-selectable.component.ts
new file mode 100644
index 0000000..58b0f54
--- /dev/null
+++ b/src/stories/components/p-data-table/examples/primeng-table-selectable.component.ts
@@ -0,0 +1,102 @@
+import { Component } from '@angular/core';
+import { StoryObj, moduleMetadata } from '@storybook/angular';
+import { TableModule } from 'primeng/table';
+
+const SHIPMENTS = [
+ { id: 1, trackNumber: 'ЦД-00123456', destination: 'Москва', status: 'В пути', weight: 2.5, cost: 1200 },
+ { id: 2, trackNumber: 'ЦД-00123457', destination: 'Новосибирск', status: 'Доставлен', weight: 0.8, cost: 450 },
+ { id: 3, trackNumber: 'ЦД-00123458', destination: 'Екатеринбург', status: 'Задержан', weight: 5.2, cost: 2100 },
+ { id: 4, trackNumber: 'ЦД-00123459', destination: 'Казань', status: 'В пути', weight: 1.3, cost: 750 },
+ { id: 5, trackNumber: 'ЦД-00123460', destination: 'Краснодар', status: 'Доставлен', weight: 3.7, cost: 1800 },
+];
+
+@Component({
+ selector: 'app-primeng-table-selectable',
+ standalone: true,
+ imports: [TableModule],
+ template: `
+
+
+
+ | Трек-номер |
+ Назначение |
+ Статус |
+ Вес, кг |
+ Стоимость, ₽ |
+
+
+
+
+ | {{ shipment.trackNumber }} |
+ {{ shipment.destination }} |
+ {{ shipment.status }} |
+ {{ shipment.weight }} |
+ {{ shipment.cost }} |
+
+
+
+ `,
+})
+export class PDataTableSelectableComponent {
+ shipments = SHIPMENTS;
+ selected: any = null;
+}
+
+export const Selectable: StoryObj = {
+ name: 'Selectable',
+ decorators: [moduleMetadata({ imports: [PDataTableSelectableComponent] })],
+ render: () => ({ template: `` }),
+ parameters: {
+ controls: { disable: true },
+ docs: {
+ description: {
+ story: 'Выбор строки кликом. Режим single — выбирается одна строка на базе PrimeNG pTable.',
+ },
+ source: {
+ language: 'ts',
+ code: `import { Component } from '@angular/core';
+import { TableModule } from 'primeng/table';
+
+const SHIPMENTS = [
+ { id: 1, trackNumber: 'ЦД-00123456', destination: 'Москва', status: 'В пути', weight: 2.5, cost: 1200 },
+ { id: 2, trackNumber: 'ЦД-00123457', destination: 'Новосибирск', status: 'Доставлен', weight: 0.8, cost: 450 },
+ { id: 3, trackNumber: 'ЦД-00123458', destination: 'Екатеринбург', status: 'Задержан', weight: 5.2, cost: 2100 },
+ { id: 4, trackNumber: 'ЦД-00123459', destination: 'Казань', status: 'В пути', weight: 1.3, cost: 750 },
+ { id: 5, trackNumber: 'ЦД-00123460', destination: 'Краснодар', status: 'Доставлен', weight: 3.7, cost: 1800 },
+];
+
+@Component({
+ selector: 'app-example',
+ standalone: true,
+ imports: [TableModule],
+ template: \`
+
+
+
+ | Трек-номер |
+ Назначение |
+ Статус |
+ Вес, кг |
+ Стоимость, ₽ |
+
+
+
+
+ | {{ shipment.trackNumber }} |
+ {{ shipment.destination }} |
+ {{ shipment.status }} |
+ {{ shipment.weight }} |
+ {{ shipment.cost }} |
+
+
+
+ \`,
+})
+export class ExampleComponent {
+ shipments = SHIPMENTS;
+ selected: any = null;
+}`,
+ },
+ },
+ },
+};
diff --git a/src/stories/components/p-data-table/examples/primeng-table-selection-checkbox.component.ts b/src/stories/components/p-data-table/examples/primeng-table-selection-checkbox.component.ts
new file mode 100644
index 0000000..76ad388
--- /dev/null
+++ b/src/stories/components/p-data-table/examples/primeng-table-selection-checkbox.component.ts
@@ -0,0 +1,110 @@
+import { Component } from '@angular/core';
+import { StoryObj, moduleMetadata } from '@storybook/angular';
+import { TableModule } from 'primeng/table';
+
+const SHIPMENTS = [
+ { id: 1, trackNumber: 'ЦД-00123456', destination: 'Москва', status: 'В пути', weight: 2.5 },
+ { id: 2, trackNumber: 'ЦД-00123457', destination: 'Новосибирск', status: 'Доставлен', weight: 0.8 },
+ { id: 3, trackNumber: 'ЦД-00123458', destination: 'Екатеринбург', status: 'Задержан', weight: 5.2 },
+ { id: 4, trackNumber: 'ЦД-00123459', destination: 'Казань', status: 'В пути', weight: 1.3 },
+ { id: 5, trackNumber: 'ЦД-00123460', destination: 'Краснодар', status: 'Доставлен', weight: 3.7 },
+];
+
+@Component({
+ selector: 'app-primeng-table-selection-checkbox',
+ standalone: true,
+ imports: [TableModule],
+ template: `
+
+
+
+ |
+
+ |
+ Трек-номер |
+ Назначение |
+ Статус |
+ Вес, кг |
+
+
+
+
+ |
+
+ |
+ {{ shipment.trackNumber }} |
+ {{ shipment.destination }} |
+ {{ shipment.status }} |
+ {{ shipment.weight }} |
+
+
+
+ `,
+})
+export class PDataTableSelectionCheckboxComponent {
+ shipments = SHIPMENTS;
+ selected: any[] = [];
+}
+
+export const SelectionCheckbox: StoryObj = {
+ name: 'Row Selection: Checkbox',
+ decorators: [moduleMetadata({ imports: [PDataTableSelectionCheckboxComponent] })],
+ render: () => ({ template: `` }),
+ parameters: {
+ controls: { disable: true },
+ docs: {
+ description: {
+ story: 'Множественный выбор строк через чекбоксы на базе PrimeNG pTable.',
+ },
+ source: {
+ language: 'ts',
+ code: `import { Component } from '@angular/core';
+import { TableModule } from 'primeng/table';
+
+const SHIPMENTS = [
+ { id: 1, trackNumber: 'ЦД-00123456', destination: 'Москва', status: 'В пути', weight: 2.5 },
+ { id: 2, trackNumber: 'ЦД-00123457', destination: 'Новосибирск', status: 'Доставлен', weight: 0.8 },
+ { id: 3, trackNumber: 'ЦД-00123458', destination: 'Екатеринбург', status: 'Задержан', weight: 5.2 },
+ { id: 4, trackNumber: 'ЦД-00123459', destination: 'Казань', status: 'В пути', weight: 1.3 },
+ { id: 5, trackNumber: 'ЦД-00123460', destination: 'Краснодар', status: 'Доставлен', weight: 3.7 },
+];
+
+@Component({
+ selector: 'app-example',
+ standalone: true,
+ imports: [TableModule],
+ template: \`
+
+
+
+ |
+
+ |
+ Трек-номер |
+ Назначение |
+ Статус |
+ Вес, кг |
+
+
+
+
+ |
+
+ |
+ {{ shipment.trackNumber }} |
+ {{ shipment.destination }} |
+ {{ shipment.status }} |
+ {{ shipment.weight }} |
+
+
+
+ \`,
+})
+export class ExampleComponent {
+ shipments = SHIPMENTS;
+ selected: any[] = [];
+}`,
+ },
+ },
+ },
+};
diff --git a/src/stories/components/p-data-table/examples/primeng-table-selection-radio.component.ts b/src/stories/components/p-data-table/examples/primeng-table-selection-radio.component.ts
new file mode 100644
index 0000000..f955a99
--- /dev/null
+++ b/src/stories/components/p-data-table/examples/primeng-table-selection-radio.component.ts
@@ -0,0 +1,106 @@
+import { Component } from '@angular/core';
+import { StoryObj, moduleMetadata } from '@storybook/angular';
+import { TableModule } from 'primeng/table';
+
+const SHIPMENTS = [
+ { id: 1, trackNumber: 'ЦД-00123456', destination: 'Москва', status: 'В пути', weight: 2.5 },
+ { id: 2, trackNumber: 'ЦД-00123457', destination: 'Новосибирск', status: 'Доставлен', weight: 0.8 },
+ { id: 3, trackNumber: 'ЦД-00123458', destination: 'Екатеринбург', status: 'Задержан', weight: 5.2 },
+ { id: 4, trackNumber: 'ЦД-00123459', destination: 'Казань', status: 'В пути', weight: 1.3 },
+ { id: 5, trackNumber: 'ЦД-00123460', destination: 'Краснодар', status: 'Доставлен', weight: 3.7 },
+];
+
+@Component({
+ selector: 'app-primeng-table-selection-radio',
+ standalone: true,
+ imports: [TableModule],
+ template: `
+
+
+
+ |
+ Трек-номер |
+ Назначение |
+ Статус |
+ Вес, кг |
+
+
+
+
+ |
+
+ |
+ {{ shipment.trackNumber }} |
+ {{ shipment.destination }} |
+ {{ shipment.status }} |
+ {{ shipment.weight }} |
+
+
+
+ `,
+})
+export class PDataTableSelectionRadioComponent {
+ shipments = SHIPMENTS;
+ selected: any = null;
+}
+
+export const SelectionRadio: StoryObj = {
+ name: 'Row Selection: RadioButton',
+ decorators: [moduleMetadata({ imports: [PDataTableSelectionRadioComponent] })],
+ render: () => ({ template: `` }),
+ parameters: {
+ controls: { disable: true },
+ docs: {
+ description: {
+ story: 'Выбор одной строки через радио-кнопку на базе PrimeNG pTable.',
+ },
+ source: {
+ language: 'ts',
+ code: `import { Component } from '@angular/core';
+import { TableModule } from 'primeng/table';
+
+const SHIPMENTS = [
+ { id: 1, trackNumber: 'ЦД-00123456', destination: 'Москва', status: 'В пути', weight: 2.5 },
+ { id: 2, trackNumber: 'ЦД-00123457', destination: 'Новосибирск', status: 'Доставлен', weight: 0.8 },
+ { id: 3, trackNumber: 'ЦД-00123458', destination: 'Екатеринбург', status: 'Задержан', weight: 5.2 },
+ { id: 4, trackNumber: 'ЦД-00123459', destination: 'Казань', status: 'В пути', weight: 1.3 },
+ { id: 5, trackNumber: 'ЦД-00123460', destination: 'Краснодар', status: 'Доставлен', weight: 3.7 },
+];
+
+@Component({
+ selector: 'app-example',
+ standalone: true,
+ imports: [TableModule],
+ template: \`
+
+
+
+ |
+ Трек-номер |
+ Назначение |
+ Статус |
+ Вес, кг |
+
+
+
+
+ |
+
+ |
+ {{ shipment.trackNumber }} |
+ {{ shipment.destination }} |
+ {{ shipment.status }} |
+ {{ shipment.weight }} |
+
+
+
+ \`,
+})
+export class ExampleComponent {
+ shipments = SHIPMENTS;
+ selected: any = null;
+}`,
+ },
+ },
+ },
+};
diff --git a/src/stories/components/p-data-table/examples/primeng-table-striped-rows.component.ts b/src/stories/components/p-data-table/examples/primeng-table-striped-rows.component.ts
new file mode 100644
index 0000000..52ef46c
--- /dev/null
+++ b/src/stories/components/p-data-table/examples/primeng-table-striped-rows.component.ts
@@ -0,0 +1,106 @@
+import { Component } from '@angular/core';
+import { StoryObj, moduleMetadata } from '@storybook/angular';
+import { TableModule } from 'primeng/table';
+
+const SHIPMENTS = [
+ { id: 1, trackNumber: 'ЦД-00123456', destination: 'Москва', status: 'В пути', weight: 2.5, cost: 1200 },
+ { id: 2, trackNumber: 'ЦД-00123457', destination: 'Новосибирск', status: 'Доставлен', weight: 0.8, cost: 450 },
+ { id: 3, trackNumber: 'ЦД-00123458', destination: 'Екатеринбург', status: 'Задержан', weight: 5.2, cost: 2100 },
+ { id: 4, trackNumber: 'ЦД-00123459', destination: 'Казань', status: 'В пути', weight: 1.3, cost: 750 },
+ { id: 5, trackNumber: 'ЦД-00123460', destination: 'Краснодар', status: 'Доставлен', weight: 3.7, cost: 1800 },
+ { id: 6, trackNumber: 'ЦД-00123461', destination: 'Воронеж', status: 'Ожидание', weight: 0.5, cost: 350 },
+ { id: 7, trackNumber: 'ЦД-00123462', destination: 'Самара', status: 'В пути', weight: 8.0, cost: 3200 },
+ { id: 8, trackNumber: 'ЦД-00123463', destination: 'Ростов-на-Дону', status: 'Доставлен', weight: 2.1, cost: 980 },
+];
+
+@Component({
+ selector: 'app-primeng-table-striped-rows',
+ standalone: true,
+ imports: [TableModule],
+ template: `
+
+
+
+ | Трек-номер |
+ Назначение |
+ Статус |
+ Вес, кг |
+ Стоимость, ₽ |
+
+
+
+
+ | {{ shipment.trackNumber }} |
+ {{ shipment.destination }} |
+ {{ shipment.status }} |
+ {{ shipment.weight }} |
+ {{ shipment.cost }} |
+
+
+
+ `,
+})
+export class PDataTableStripedRowsComponent {
+ shipments = SHIPMENTS;
+}
+
+export const StripedRows: StoryObj = {
+ name: 'StripedRows',
+ decorators: [moduleMetadata({ imports: [PDataTableStripedRowsComponent] })],
+ render: () => ({ template: `` }),
+ parameters: {
+ controls: { disable: true },
+ docs: {
+ description: {
+ story: 'Чередование цвета строк для улучшения читаемости на базе PrimeNG pTable.',
+ },
+ source: {
+ language: 'ts',
+ code: `import { Component } from '@angular/core';
+import { TableModule } from 'primeng/table';
+
+const SHIPMENTS = [
+ { id: 1, trackNumber: 'ЦД-00123456', destination: 'Москва', status: 'В пути', weight: 2.5, cost: 1200 },
+ { id: 2, trackNumber: 'ЦД-00123457', destination: 'Новосибирск', status: 'Доставлен', weight: 0.8, cost: 450 },
+ { id: 3, trackNumber: 'ЦД-00123458', destination: 'Екатеринбург', status: 'Задержан', weight: 5.2, cost: 2100 },
+ { id: 4, trackNumber: 'ЦД-00123459', destination: 'Казань', status: 'В пути', weight: 1.3, cost: 750 },
+ { id: 5, trackNumber: 'ЦД-00123460', destination: 'Краснодар', status: 'Доставлен', weight: 3.7, cost: 1800 },
+ { id: 6, trackNumber: 'ЦД-00123461', destination: 'Воронеж', status: 'Ожидание', weight: 0.5, cost: 350 },
+ { id: 7, trackNumber: 'ЦД-00123462', destination: 'Самара', status: 'В пути', weight: 8.0, cost: 3200 },
+ { id: 8, trackNumber: 'ЦД-00123463', destination: 'Ростов-на-Дону', status: 'Доставлен', weight: 2.1, cost: 980 },
+];
+
+@Component({
+ selector: 'app-example',
+ standalone: true,
+ imports: [TableModule],
+ template: \`
+
+
+
+ | Трек-номер |
+ Назначение |
+ Статус |
+ Вес, кг |
+ Стоимость, ₽ |
+
+
+
+
+ | {{ shipment.trackNumber }} |
+ {{ shipment.destination }} |
+ {{ shipment.status }} |
+ {{ shipment.weight }} |
+ {{ shipment.cost }} |
+
+
+
+ \`,
+})
+export class ExampleComponent {
+ shipments = SHIPMENTS;
+}`,
+ },
+ },
+ },
+};
diff --git a/src/stories/components/p-data-table/primeng-data-table.stories.ts b/src/stories/components/p-data-table/primeng-data-table.stories.ts
new file mode 100644
index 0000000..a711e0d
--- /dev/null
+++ b/src/stories/components/p-data-table/primeng-data-table.stories.ts
@@ -0,0 +1,63 @@
+import { Meta, StoryObj, moduleMetadata } from '@storybook/angular';
+import { PDataTableDefaultComponent, Default } from './examples/primeng-table-default.component';
+import { PDataTableStripedRowsComponent, StripedRows } from './examples/primeng-table-striped-rows.component';
+import { PDataTableSelectableComponent, Selectable } from './examples/primeng-table-selectable.component';
+import { PDataTableGridLinesComponent, GridLines } from './examples/primeng-table-grid-lines.component';
+import { PDataTablePaginationComponent, Pagination } from './examples/primeng-table-pagination.component';
+import { PDataTableSelectionRadioComponent, SelectionRadio } from './examples/primeng-table-selection-radio.component';
+import { PDataTableSelectionCheckboxComponent, SelectionCheckbox } from './examples/primeng-table-selection-checkbox.component';
+import { PDataTableScrollVerticalComponent, ScrollVertical } from './examples/primeng-table-scroll-vertical.component';
+import { PDataTableScrollHorizontalComponent, ScrollHorizontal } from './examples/primeng-table-scroll-horizontal.component';
+import { PDataTableCustomBodyComponent, CustomBody } from './examples/primeng-table-custom-body.component';
+import { PDataTableLazyComponent, LazyLoading } from './examples/primeng-table-lazy.component';
+
+const meta: Meta = {
+ title: 'Components/Data/DataTable (PrimeNG)',
+ tags: ['autodocs'],
+ decorators: [
+ moduleMetadata({
+ imports: [
+ PDataTableDefaultComponent,
+ PDataTableStripedRowsComponent,
+ PDataTableSelectableComponent,
+ PDataTableGridLinesComponent,
+ PDataTablePaginationComponent,
+ PDataTableSelectionRadioComponent,
+ PDataTableSelectionCheckboxComponent,
+ PDataTableScrollVerticalComponent,
+ PDataTableScrollHorizontalComponent,
+ PDataTableCustomBodyComponent,
+ PDataTableLazyComponent,
+ ],
+ }),
+ ],
+ parameters: {
+ docs: {
+ description: {
+ component: `Таблица данных на базе PrimeNG pTable с поддержкой сортировки, пагинации, выбора строк и прокрутки.
+
+\`\`\`typescript
+import { TableModule } from 'primeng/table';
+\`\`\``,
+ },
+ },
+ designTokens: { prefix: '--p-datatable' },
+ },
+};
+
+export default meta;
+type Story = StoryObj;
+
+export {
+ Default,
+ StripedRows,
+ Selectable,
+ GridLines,
+ Pagination,
+ SelectionRadio,
+ SelectionCheckbox,
+ ScrollVertical,
+ ScrollHorizontal,
+ CustomBody,
+ LazyLoading,
+};
diff --git a/src/stories/components/stepper/examples/stepper-error.component.ts b/src/stories/components/stepper/examples/stepper-error.component.ts
new file mode 100644
index 0000000..d2080d4
--- /dev/null
+++ b/src/stories/components/stepper/examples/stepper-error.component.ts
@@ -0,0 +1,61 @@
+import { Component } from '@angular/core';
+import { StoryObj } from '@storybook/angular';
+import { ExtraStepperComponent, ExtraStepperItem } from '../../../../lib/components/stepper/stepper.component';
+
+const template = `
+
+
+
+`;
+const styles = '';
+
+@Component({
+ selector: 'app-stepper-error',
+ standalone: true,
+ imports: [ExtraStepperComponent],
+ template,
+ styles,
+})
+export class StepperErrorComponent {
+ steps: ExtraStepperItem[] = [
+ { value: 1, label: 'Stepper', caption: 'caption', content: 'Step 1 Content' },
+ { value: 2, label: 'Stepper', caption: 'caption', content: 'Step 2 Content (Invalid)', invalid: true },
+ { value: 3, label: 'Stepper', caption: 'caption', content: 'Step 3 Content', disabled: true },
+ ];
+}
+
+export const Error: StoryObj = {
+ name: 'Error (Invalid step)',
+ render: () => ({
+ template: ``,
+ }),
+ parameters: {
+ controls: { disable: true },
+ docs: {
+ description: { story: 'Шаг с ошибкой — визуально выделяется красным при активном состоянии.' },
+ source: {
+ language: 'ts',
+ code: `
+import { Component } from '@angular/core';
+import { ExtraStepperComponent, StepperItem } from '@cdek-it/angular-ui-kit';
+
+@Component({
+ selector: 'app-stepper-error',
+ standalone: true,
+ imports: [ExtraStepperComponent],
+ template: \`
+
+ \`,
+})
+export class StepperErrorComponent {
+ steps: StepperItem[] = [
+ { value: 1, label: 'Stepper', caption: 'caption', content: 'Step 1 Content' },
+ { value: 2, label: 'Stepper', caption: 'caption', content: 'Step 2 Content (Invalid)', invalid: true },
+ { value: 3, label: 'Stepper', caption: 'caption', content: 'Step 3 Content', disabled: true },
+ ];
+}
+ `,
+ },
+ },
+ },
+};
diff --git a/src/stories/components/stepper/examples/stepper-linear.component.ts b/src/stories/components/stepper/examples/stepper-linear.component.ts
new file mode 100644
index 0000000..245d6d9
--- /dev/null
+++ b/src/stories/components/stepper/examples/stepper-linear.component.ts
@@ -0,0 +1,60 @@
+import { Component } from '@angular/core';
+import { StoryObj } from '@storybook/angular';
+import { ExtraStepperComponent, ExtraStepperItem } from '../../../../lib/components/stepper/stepper.component';
+
+const template = `
+
+
+
+`;
+const styles = '';
+
+@Component({
+ selector: 'app-stepper-linear',
+ standalone: true,
+ imports: [ExtraStepperComponent],
+ template,
+ styles,
+})
+export class StepperLinearComponent {
+ steps: ExtraStepperItem[] = [
+ { value: 1, label: 'Stepper', caption: 'caption', content: 'Step 1 Content' },
+ { value: 2, label: 'Stepper', caption: 'caption', content: 'Step 2 Content' },
+ { value: 3, label: 'Stepper', caption: 'caption', content: 'Step 3 Content' },
+ ];
+}
+
+export const Linear: StoryObj = {
+ render: () => ({
+ template: ``,
+ }),
+ parameters: {
+ controls: { disable: true },
+ docs: {
+ description: { story: 'Линейный режим — переход к следующему шагу только после завершения текущего.' },
+ source: {
+ language: 'ts',
+ code: `
+import { Component } from '@angular/core';
+import { ExtraStepperComponent, StepperItem } from '@cdek-it/angular-ui-kit';
+
+@Component({
+ selector: 'app-stepper-linear',
+ standalone: true,
+ imports: [ExtraStepperComponent],
+ template: \`
+
+ \`,
+})
+export class StepperLinearComponent {
+ steps: StepperItem[] = [
+ { value: 1, label: 'Stepper', caption: 'caption', content: 'Step 1 Content' },
+ { value: 2, label: 'Stepper', caption: 'caption', content: 'Step 2 Content' },
+ { value: 3, label: 'Stepper', caption: 'caption', content: 'Step 3 Content' },
+ ];
+}
+ `,
+ },
+ },
+ },
+};
diff --git a/src/stories/components/stepper/examples/stepper-steps-only.component.ts b/src/stories/components/stepper/examples/stepper-steps-only.component.ts
new file mode 100644
index 0000000..2a7288d
--- /dev/null
+++ b/src/stories/components/stepper/examples/stepper-steps-only.component.ts
@@ -0,0 +1,60 @@
+import { Component } from '@angular/core';
+import { StoryObj } from '@storybook/angular';
+import { ExtraStepperComponent, ExtraStepperItem } from '../../../../lib/components/stepper/stepper.component';
+
+const template = `
+
+
+
+`;
+const styles = '';
+
+@Component({
+ selector: 'app-stepper-steps-only',
+ standalone: true,
+ imports: [ExtraStepperComponent],
+ template,
+ styles,
+})
+export class StepperStepsOnlyComponent {
+ steps: ExtraStepperItem[] = [
+ { value: 1, label: 'Stepper', caption: 'caption' },
+ { value: 2, label: 'Stepper', caption: 'caption' },
+ { value: 3, label: 'Stepper', caption: 'caption' },
+ ];
+}
+
+export const StepsOnly: StoryObj = {
+ render: () => ({
+ template: ``,
+ }),
+ parameters: {
+ controls: { disable: true },
+ docs: {
+ description: { story: 'Только шаги без панелей контента.' },
+ source: {
+ language: 'ts',
+ code: `
+import { Component } from '@angular/core';
+import { ExtraStepperComponent, StepperItem } from '@cdek-it/angular-ui-kit';
+
+@Component({
+ selector: 'app-stepper-steps-only',
+ standalone: true,
+ imports: [ExtraStepperComponent],
+ template: \`
+
+ \`,
+})
+export class StepperStepsOnlyComponent {
+ steps: StepperItem[] = [
+ { value: 1, label: 'Stepper', caption: 'caption' },
+ { value: 2, label: 'Stepper', caption: 'caption' },
+ { value: 3, label: 'Stepper', caption: 'caption' },
+ ];
+}
+ `,
+ },
+ },
+ },
+};
diff --git a/src/stories/components/stepper/examples/stepper-vertical.component.ts b/src/stories/components/stepper/examples/stepper-vertical.component.ts
new file mode 100644
index 0000000..695bd9f
--- /dev/null
+++ b/src/stories/components/stepper/examples/stepper-vertical.component.ts
@@ -0,0 +1,60 @@
+import { Component } from '@angular/core';
+import { StoryObj } from '@storybook/angular';
+import { ExtraStepperComponent, ExtraStepperItem } from '../../../../lib/components/stepper/stepper.component';
+
+const template = `
+
+
+
+`;
+const styles = '';
+
+@Component({
+ selector: 'app-stepper-vertical',
+ standalone: true,
+ imports: [ExtraStepperComponent],
+ template,
+ styles,
+})
+export class StepperVerticalComponent {
+ steps: ExtraStepperItem[] = [
+ { value: 1, label: 'Stepper', caption: 'caption', content: 'Step 1 Content' },
+ { value: 2, label: 'Stepper', caption: 'caption', content: 'Step 2 Content' },
+ { value: 3, label: 'Stepper', caption: 'caption', content: 'Step 3 Content' },
+ ];
+}
+
+export const Vertical: StoryObj = {
+ render: () => ({
+ template: ``,
+ }),
+ parameters: {
+ controls: { disable: true },
+ docs: {
+ description: { story: 'Вертикальная ориентация степпера.' },
+ source: {
+ language: 'ts',
+ code: `
+import { Component } from '@angular/core';
+import { ExtraStepperComponent, StepperItem } from '@cdek-it/angular-ui-kit';
+
+@Component({
+ selector: 'app-stepper-vertical',
+ standalone: true,
+ imports: [ExtraStepperComponent],
+ template: \`
+
+ \`,
+})
+export class StepperVerticalComponent {
+ steps: StepperItem[] = [
+ { value: 1, label: 'Stepper', caption: 'caption', content: 'Step 1 Content' },
+ { value: 2, label: 'Stepper', caption: 'caption', content: 'Step 2 Content' },
+ { value: 3, label: 'Stepper', caption: 'caption', content: 'Step 3 Content' },
+ ];
+}
+ `,
+ },
+ },
+ },
+};
diff --git a/src/stories/components/stepper/stepper.stories.ts b/src/stories/components/stepper/stepper.stories.ts
new file mode 100644
index 0000000..41e8d72
--- /dev/null
+++ b/src/stories/components/stepper/stepper.stories.ts
@@ -0,0 +1,140 @@
+import { Meta, StoryObj, moduleMetadata } from '@storybook/angular';
+import { ExtraStepperComponent } from '../../../lib/components/stepper/stepper.component';
+import { StepperVerticalComponent, Vertical as VerticalStory } from './examples/stepper-vertical.component';
+import { StepperLinearComponent, Linear as LinearStory } from './examples/stepper-linear.component';
+import { StepperStepsOnlyComponent, StepsOnly as StepsOnlyStory } from './examples/stepper-steps-only.component';
+import { StepperErrorComponent, Error as ErrorStory } from './examples/stepper-error.component';
+
+type StepperArgs = ExtraStepperComponent;
+
+const meta: Meta = {
+ title: 'Components/Stepper',
+ component: ExtraStepperComponent,
+ tags: ['autodocs'],
+ decorators: [
+ moduleMetadata({
+ imports: [
+ ExtraStepperComponent,
+ StepperVerticalComponent,
+ StepperLinearComponent,
+ StepperStepsOnlyComponent,
+ StepperErrorComponent,
+ ],
+ }),
+ ],
+ parameters: {
+ docs: {
+ description: {
+ component: `Пошаговый навигационный компонент для отображения прогресса через последовательность шагов.
+
+\`\`\`typescript
+import { ExtraStepperComponent, StepperItem } from '@cdek-it/angular-ui-kit';
+\`\`\``,
+ },
+ },
+ designTokens: { prefix: '--p-stepper' },
+ },
+ argTypes: {
+ value: {
+ control: 'number',
+ description: 'Значение активного шага',
+ table: {
+ category: 'Props',
+ defaultValue: { summary: '1' },
+ type: { summary: 'number | undefined' },
+ },
+ },
+ linear: {
+ control: 'boolean',
+ description: 'Запрещает переход к следующему шагу без завершения текущего',
+ table: {
+ category: 'Props',
+ defaultValue: { summary: 'false' },
+ type: { summary: 'boolean' },
+ },
+ },
+ orientation: {
+ control: 'radio',
+ options: ['horizontal', 'vertical'],
+ description: 'Ориентация степпера',
+ table: {
+ category: 'Props',
+ defaultValue: { summary: 'horizontal' },
+ type: { summary: "'horizontal' | 'vertical'" },
+ },
+ },
+ showPanels: {
+ control: 'boolean',
+ description: 'Показывать панели контента',
+ table: {
+ category: 'Props',
+ defaultValue: { summary: 'true' },
+ type: { summary: 'boolean' },
+ },
+ },
+ steps: {
+ control: 'object',
+ description: 'Массив шагов',
+ table: {
+ category: 'Props',
+ type: { summary: 'StepperItem[]' },
+ },
+ },
+ },
+};
+
+export default meta;
+type Story = StoryObj;
+
+// ── Default (Horizontal) ─────────────────────────────────────────────────────
+
+export const Default: Story = {
+ name: 'Horizontal',
+ render: (args) => {
+ const parts: string[] = [];
+
+ parts.push(`[value]="value"`);
+ parts.push(`[steps]="steps"`);
+ if (args.linear) parts.push(`[linear]="true"`);
+ if (args.orientation === 'vertical') parts.push(`orientation="vertical"`);
+ if (!args.showPanels) parts.push(`[showPanels]="false"`);
+
+ const template = ``;
+
+ return { props: args, template };
+ },
+ args: {
+ value: 1,
+ steps: [
+ { value: 1, label: 'Stepper', caption: 'caption', content: 'Step 1 Content' },
+ { value: 2, label: 'Stepper', caption: 'caption', content: 'Step 2 Content' },
+ { value: 3, label: 'Stepper', caption: 'caption', content: 'Step 3 Content' },
+ ],
+ linear: false,
+ orientation: 'horizontal',
+ showPanels: true,
+ },
+ parameters: {
+ docs: {
+ description: {
+ story: 'Горизонтальный степпер. Используйте Controls для интерактивного изменения пропсов.',
+ },
+ },
+ },
+};
+
+// ── Vertical ──────────────────────────────────────────────────────────────────
+
+export const Vertical: Story = VerticalStory;
+
+// ── Linear ────────────────────────────────────────────────────────────────────
+
+export const Linear: Story = LinearStory;
+
+// ── StepsOnly ─────────────────────────────────────────────────────────────────
+
+export const StepsOnly: Story = StepsOnlyStory;
+
+// ── Error ─────────────────────────────────────────────────────────────────────
+
+export const Error: Story = ErrorStory;