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
35 changes: 35 additions & 0 deletions src/lib/components/progressspinner/progressspinner.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Component, Input } from '@angular/core';
import { ProgressSpinnerModule } from 'primeng/progressspinner'; // We use Module since PrimeNG 17/18 might export it this way. Wait, earlier we saw ProgressSpinner is standalone? Actually ProgressSpinner in v18 is standalone, but importing it as ProgressSpinner works.
// Let's import the component directly. Wait, index.d.ts exports { ProgressSpinner, ProgressSpinnerModule }. Either is fine. Let's use ProgressSpinner.
import { ProgressSpinner } from 'primeng/progressspinner';

export type ProgressSpinnerSize = 'small' | 'medium' | 'large' | 'xlarge';

@Component({
selector: 'progressspinner',
standalone: true,
imports: [ProgressSpinner],
template: `
<p-progressSpinner
[styleClass]="primeStyleClass"
[strokeWidth]="strokeWidth"
[fill]="fill"
[animationDuration]="animationDuration"
[ariaLabel]="ariaLabel"
></p-progressSpinner>
`
})
export class ProgressSpinnerComponent {
@Input() size: ProgressSpinnerSize = 'medium';
@Input() multicolor = true;
@Input() strokeWidth = '2';
@Input() fill = 'none';
@Input() animationDuration = '2s';
@Input() ariaLabel: string | undefined = undefined;

get primeStyleClass(): string {
const sizeClass = `p-progressspinner-${this.size}`;
const colorClass = this.multicolor ? '' : 'p-progressspinner-monochrome';
return `${sizeClass} ${colorClass}`.trim();
}
}
10 changes: 10 additions & 0 deletions src/prime-preset/map-tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import tokens from './tokens/tokens.json';
import { avatarCss } from './tokens/components/avatar';
import { buttonCss } from './tokens/components/button';
import { checkboxCss } from './tokens/components/checkbox';
import { progressspinnerCss } from './tokens/components/progressspinner';
import { tagCss } from './tokens/components/tag';
import { tooltipCss } from './tokens/components/tooltip';

const presetTokens: Preset<AuraBaseDesignTokens> = {
Expand All @@ -25,10 +27,18 @@ const presetTokens: Preset<AuraBaseDesignTokens> = {
...(tokens.components.button as unknown as ComponentsDesignTokens['button']),
css: buttonCss,
},
progressspinner: {
...(tokens.components.progressspinner as unknown as ComponentsDesignTokens['progressspinner']),
css: progressspinnerCss,
},
tag: {
...(tokens.components.tag as unknown as ComponentsDesignTokens['tag']),
css: tagCss,
},
tooltip: {
...(tokens.components.tooltip as unknown as ComponentsDesignTokens['tooltip']),
css: tooltipCss,
},
} as ComponentsDesignTokens,
};

Expand Down
35 changes: 35 additions & 0 deletions src/prime-preset/tokens/components/progressspinner.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
export const progressspinnerCss = ({ dt }: { dt: (token: string) => string }): string => `
.p-progressspinner-circle {
stroke-width: ${dt('progressspinner.root.borderWidth')};
}

/* multicolor false */
.p-progressspinner.p-progressspinner-monochrome .p-progressspinner-circle {
stroke: ${dt('primary.color')};
animation: p-progressspinner-dash 1.5s ease-in-out infinite;
}

.p-progressspinner.p-progressspinner-small,
.p-progressspinner.p-progressspinner-small .p-progressspinner-circle {
width: ${dt('progressspinner.extend.small')};
height: ${dt('progressspinner.extend.small')};
}

.p-progressspinner.p-progressspinner-medium,
.p-progressspinner.p-progressspinner-medium .p-progressspinner-circle {
width: ${dt('progressspinner.extend.medium')};
height: ${dt('progressspinner.extend.medium')};
}

.p-progressspinner.p-progressspinner-large,
.p-progressspinner.p-progressspinner-large .p-progressspinner-circle {
width: ${dt('progressspinner.extend.large')};
height: ${dt('progressspinner.extend.large')};
}

.p-progressspinner.p-progressspinner-xlarge,
.p-progressspinner.p-progressspinner-xlarge .p-progressspinner-circle {
width: ${dt('progressspinner.extend.xlarge')};
height: ${dt('progressspinner.extend.xlarge')};
}
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { Component, Input } from '@angular/core';
import { StoryObj } from '@storybook/angular';
import { ProgressSpinnerComponent } from '../../../../lib/components/progressspinner/progressspinner.component';

const template = `
<progressspinner [size]="size" [multicolor]="multicolor"></progressspinner>
`;

@Component({
selector: 'progressspinner-monochrome',
standalone: true,
imports: [ProgressSpinnerComponent],
template
})
export class ProgressSpinnerMonochromeComponent {
@Input() size: any = 'medium';
@Input() multicolor = false;
}

export const Monochrome: StoryObj = {
render: (args) => ({
props: args,
template: `<progressspinner-monochrome [size]="size" [multicolor]="multicolor"></progressspinner-monochrome>`
}),
args: {
size: 'medium',
multicolor: false
},
parameters: {
docs: {
description: {
story: 'Одноцветный вариант спиннера (monochrome).'
},
source: {
language: 'ts',
code: `
import { Component } from '@angular/core';
import { ProgressSpinnerComponent } from '@cdek-it/angular-ui-kit';

@Component({
selector: 'progressspinner-monochrome',
standalone: true,
imports: [ProgressSpinnerComponent],
template: \`<progressspinner [multicolor]="false"></progressspinner>\`
})
export class ProgressSpinnerMonochromeComponent {}
`
}
}
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { Component, Input } from '@angular/core';
import { StoryObj } from '@storybook/angular';
import { ProgressSpinnerComponent, ProgressSpinnerSize } from '../../../../lib/components/progressspinner/progressspinner.component';

const template = `
<progressspinner [size]="size" [multicolor]="multicolor"></progressspinner>
`;

@Component({
selector: 'progressspinner-sizes',
standalone: true,
imports: [ProgressSpinnerComponent],
template
})
export class ProgressSpinnerSizesComponent {
@Input() size: ProgressSpinnerSize = 'xlarge';
@Input() multicolor = true;
}

export const Sizes: StoryObj = {
render: (args) => ({
props: args,
template: `<progressspinner-sizes [size]="size" [multicolor]="multicolor"></progressspinner-sizes>`
}),
args: {
size: 'xlarge',
multicolor: true
},
parameters: {
docs: {
description: {
story: 'Изменение размера спиннера. Используйте Controls для выбора других вариантов.'
},
source: {
language: 'ts',
code: `
import { Component } from '@angular/core';
import { ProgressSpinnerComponent } from '@cdek-it/angular-ui-kit';

@Component({
selector: 'progressspinner-sizes',
standalone: true,
imports: [ProgressSpinnerComponent],
template: \`<progressspinner size="xlarge"></progressspinner>\`
})
export class ProgressSpinnerSizesComponent {}
`
}
}
}
};
118 changes: 118 additions & 0 deletions src/stories/components/progressspinner/progressspinner.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import { Meta, StoryObj, moduleMetadata } from '@storybook/angular';
import { ProgressSpinnerComponent } from '../../../lib/components/progressspinner/progressspinner.component';
import { Sizes, ProgressSpinnerSizesComponent } from './examples/progressspinner-sizes.component';
import { Monochrome, ProgressSpinnerMonochromeComponent } from './examples/progressspinner-monochrome.component';

type ProgressSpinnerArgs = ProgressSpinnerComponent;

const meta: Meta<ProgressSpinnerArgs> = {
title: 'Prime/Misc/ProgressSpinner',
component: ProgressSpinnerComponent,
tags: ['autodocs'],
decorators: [
moduleMetadata({ imports: [ProgressSpinnerComponent, ProgressSpinnerSizesComponent, ProgressSpinnerMonochromeComponent] })
],
parameters: {
docs: {
description: {
component: `Используется для отображения индикатора процесса/состояния загрузки неопределенного времени.

\`\`\`typescript
import { ProgressSpinnerComponent } from '@cdek-it/angular-ui-kit';
\`\`\``,
},
},
designTokens: { prefix: '--p-progressspinner' },
},
argTypes: {
size: {
control: 'select',
options: ['small', 'medium', 'large', 'xlarge'],
description: 'Размер спиннера (задает вычисленные CSS-классы).',
table: {
category: 'Props',
defaultValue: { summary: 'medium' },
type: { summary: "'small' | 'medium' | 'large' | 'xlarge'" },
},
},
multicolor: {
control: 'boolean',
description: 'Включить многоцветную анимацию.',
table: {
category: 'Props',
defaultValue: { summary: 'true' },
type: { summary: 'boolean' },
},
},
strokeWidth: {
table: { disable: true },
},
fill: {
table: { disable: true },
},
animationDuration: {
control: 'text',
description: 'Длительность одной итерации анимации вращения.',
table: {
category: 'Props',
defaultValue: { summary: '2s' },
type: { summary: 'string' },
},
},
ariaLabel: {
table: { disable: true },
},
},
args: {
size: 'medium',
multicolor: true,
strokeWidth: '2',
fill: 'none',
animationDuration: '2s',
},
};

export default meta;
type Story = StoryObj<ProgressSpinnerArgs>;

const commonTemplate = `
<progressspinner
[size]="size"
[multicolor]="multicolor"
[strokeWidth]="strokeWidth"
[fill]="fill"
[animationDuration]="animationDuration"
></progressspinner>
`;

// ── Default ──────────────────────────────────────────────────────────────────
export const Default: Story = {
name: 'Default',
render: (args) => {
const parts: string[] = [];

if (args.size && args.size !== 'medium') parts.push(`size="${args.size}"`);
if (!args.multicolor) parts.push(`[multicolor]="false"`);
if (args.strokeWidth && args.strokeWidth !== '2') parts.push(`strokeWidth="${args.strokeWidth}"`);
if (args.fill && args.fill !== 'none') parts.push(`fill="${args.fill}"`);
if (args.animationDuration && args.animationDuration !== '2s') parts.push(`animationDuration="${args.animationDuration}"`);

const properties = parts.length > 0 ? ' ' + parts.join('\n ') : '';

const template = `
<progressspinner${properties}></progressspinner>
`;
return { props: args, template };
},
parameters: {
docs: {
description: {
story: 'Базовый пример компонента. Используйте Controls для изменения размера, цвета и толщины линии.',
},
},
},
};

// ── Вариации ─────────────────────────────────────────────────────────────────

export { Sizes, Monochrome };
Loading