From 005534cef306a79e0958b33518ee82e08d840d0e Mon Sep 17 00:00:00 2001 From: Danil Khaliulin Date: Tue, 7 Apr 2026 12:50:27 +0700 Subject: [PATCH 1/4] =?UTF-8?q?avatar:=20=D1=81=D1=82=D0=B8=D0=BB=D0=B8?= =?UTF-8?q?=D0=B7=D0=B0=D1=86=D0=B8=D1=8F,=20=D1=81=D1=82=D0=BE=D1=80?= =?UTF-8?q?=D0=B8=D1=81=D1=8B,=20=D0=BE=D0=B1=D1=91=D1=80=D1=82=D0=BA?= =?UTF-8?q?=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/assets/images/avatar/avatar.png | Bin 0 -> 56869 bytes src/lib/components/avatar/avatar.component.ts | 44 +++ src/prime-preset/map-tokens.ts | 5 + src/prime-preset/tokens/components/avatar.ts | 20 ++ src/prime-preset/tokens/tokens.json | 6 +- .../components/avatar/avatar.stories.ts | 297 ++++++++++++++++++ .../avatar/examples/avatar-group.component.ts | 61 ++++ .../examples/avatar-icon-badge.component.ts | 65 ++++ .../avatar/examples/avatar-icon.component.ts | 57 ++++ .../examples/avatar-image-badge.component.ts | 65 ++++ .../avatar/examples/avatar-image.component.ts | 57 ++++ .../examples/avatar-label-badge.component.ts | 65 ++++ .../avatar/examples/avatar-label.component.ts | 57 ++++ .../examples/avatar-shapes.component.ts | 55 ++++ .../avatar/examples/avatar-sizes.component.ts | 57 ++++ 15 files changed, 908 insertions(+), 3 deletions(-) create mode 100644 public/assets/images/avatar/avatar.png create mode 100644 src/lib/components/avatar/avatar.component.ts create mode 100644 src/prime-preset/tokens/components/avatar.ts create mode 100644 src/stories/components/avatar/avatar.stories.ts create mode 100644 src/stories/components/avatar/examples/avatar-group.component.ts create mode 100644 src/stories/components/avatar/examples/avatar-icon-badge.component.ts create mode 100644 src/stories/components/avatar/examples/avatar-icon.component.ts create mode 100644 src/stories/components/avatar/examples/avatar-image-badge.component.ts create mode 100644 src/stories/components/avatar/examples/avatar-image.component.ts create mode 100644 src/stories/components/avatar/examples/avatar-label-badge.component.ts create mode 100644 src/stories/components/avatar/examples/avatar-label.component.ts create mode 100644 src/stories/components/avatar/examples/avatar-shapes.component.ts create mode 100644 src/stories/components/avatar/examples/avatar-sizes.component.ts diff --git a/public/assets/images/avatar/avatar.png b/public/assets/images/avatar/avatar.png new file mode 100644 index 0000000000000000000000000000000000000000..7c0bd535f39286a2d5d9733773c42ece6ffd0deb GIT binary patch literal 56869 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

%0Mx?B6^d`_+Lo=Jw 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 literal 0 HcmV?d00001 diff --git a/src/lib/components/avatar/avatar.component.ts b/src/lib/components/avatar/avatar.component.ts new file mode 100644 index 00000000..15f6db6c --- /dev/null +++ b/src/lib/components/avatar/avatar.component.ts @@ -0,0 +1,44 @@ +import { Component, Input } from '@angular/core'; +import { Avatar } from 'primeng/avatar'; +import { AvatarGroup } from 'primeng/avatargroup'; + +export type AvatarSize = 'normal' | 'large' | 'xlarge'; +export type AvatarShape = 'square' | 'circle'; + +@Component({ + selector: 'avatar', + standalone: true, + imports: [Avatar], + template: ` + + `, +}) +export class AvatarComponent { + @Input() label = ''; + @Input() icon = ''; + @Input() image = ''; + @Input() size: AvatarSize = 'normal'; + @Input() shape: AvatarShape = 'square'; + + get primeSize(): 'normal' | 'large' | 'xlarge' | undefined { + return this.size === 'normal' ? undefined : this.size; + } +} + +@Component({ + selector: 'avatar-group', + standalone: true, + imports: [AvatarGroup], + template: ` + + + + `, +}) +export class AvatarGroupComponent { } diff --git a/src/prime-preset/map-tokens.ts b/src/prime-preset/map-tokens.ts index 39627587..896d4d4e 100644 --- a/src/prime-preset/map-tokens.ts +++ b/src/prime-preset/map-tokens.ts @@ -3,6 +3,7 @@ import type { ComponentsDesignTokens } from '@primeuix/themes/types'; import type { AuraBaseDesignTokens } from '@primeuix/themes/aura/base'; import tokens from './tokens/tokens.json'; +import { avatarCss } from './tokens/components/avatar'; import { buttonCss } from './tokens/components/button'; const presetTokens: Preset = { @@ -10,6 +11,10 @@ const presetTokens: Preset = { semantic: tokens.semantic as unknown as AuraBaseDesignTokens['semantic'], components: { ...(tokens.components as unknown as ComponentsDesignTokens), + avatar: { + ...(tokens.components.avatar as unknown as ComponentsDesignTokens['avatar']), + css: avatarCss, + }, button: { ...(tokens.components.button as unknown as ComponentsDesignTokens['button']), css: buttonCss, diff --git a/src/prime-preset/tokens/components/avatar.ts b/src/prime-preset/tokens/components/avatar.ts new file mode 100644 index 00000000..562ebb5a --- /dev/null +++ b/src/prime-preset/tokens/components/avatar.ts @@ -0,0 +1,20 @@ +export const avatarCss = ({ dt }: { dt: (token: string) => string }): string => ` + :root { + --p-avatar-extend-border-color: ${dt('avatar.extend.borderColor')}; + --p-avatar-extend-circle-border-radius: ${dt('avatar.extend.circle.borderRadius')}; + --p-avatar-group-border-color: ${dt('avatar.group.borderColor')}; + --p-avatar-group-offset: ${dt('avatar.group.offset')}; + --p-avatar-lg-group-offset: ${dt('avatar.lg.group.offset')}; + --p-avatar-xl-group-offset: ${dt('avatar.xl.group.offset')}; + } + + /* ─── Круглая форма: clip изображения по максимальному border-radius ─── */ + .p-avatar.p-avatar-circle { + border-radius: var(--p-avatar-extend-circle-border-radius); + overflow: hidden; + } + + .p-overlaybadge.p-overlaybadge { + width: fit-content; + } +`; diff --git a/src/prime-preset/tokens/tokens.json b/src/prime-preset/tokens/tokens.json index f9ea56a8..8fb504b7 100644 --- a/src/prime-preset/tokens/tokens.json +++ b/src/prime-preset/tokens/tokens.json @@ -1509,7 +1509,7 @@ }, "group": { "borderColor": "{content.background}", - "offset": "{media.padding.300}" + "offset": "-{media.padding.300}" }, "lg": { "width": "{media.size.400}", @@ -1519,7 +1519,7 @@ "size": "{media.icon.size.100}" }, "group": { - "offset": "{media.padding.300}" + "offset": "-{media.padding.300}" } }, "xl": { @@ -1529,7 +1529,7 @@ "size": "{media.icon.size.200}" }, "group": { - "offset": "{media.padding.600}" + "offset": "-{media.padding.600}" }, "fontSize": "{fonts.fontSize.500}" } diff --git a/src/stories/components/avatar/avatar.stories.ts b/src/stories/components/avatar/avatar.stories.ts new file mode 100644 index 00000000..3dc24780 --- /dev/null +++ b/src/stories/components/avatar/avatar.stories.ts @@ -0,0 +1,297 @@ +import { Meta, StoryObj, moduleMetadata } from '@storybook/angular'; +import { OverlayBadge } from 'primeng/overlaybadge'; +import { AvatarComponent, AvatarGroupComponent } from '../../../lib/components/avatar/avatar.component'; + +const meta: Meta = { + title: 'Prime/Misc/Avatar', + component: AvatarComponent, + tags: ['autodocs'], + decorators: [ + moduleMetadata({ + imports: [AvatarComponent, AvatarGroupComponent, OverlayBadge], + }), + ], + parameters: { + docs: { + description: { + component: `Аватар представляет пользователя или сущность. Может содержать текст, иконку или изображение. [PrimeNG Avatar](https://primeng.org/avatar). + +\`\`\`typescript +import { AvatarComponent, AvatarGroupComponent } from '@cdek-it/angular-ui-kit'; +\`\`\``, + }, + }, + designTokens: { prefix: '--p-avatar' }, + }, + argTypes: { + // ── Props ──────────────────────────────────────────────── + label: { + control: 'text', + description: 'Текст внутри аватара', + table: { + category: 'Props', + defaultValue: { summary: "''" }, + type: { summary: 'string' }, + }, + }, + icon: { + control: 'text', + description: 'CSS-класс иконки (например: ti ti-user)', + table: { + category: 'Props', + defaultValue: { summary: "''" }, + type: { summary: 'string' }, + }, + }, + image: { + control: 'text', + description: 'URL изображения', + table: { + category: 'Props', + defaultValue: { summary: "''" }, + type: { summary: 'string' }, + }, + }, + size: { + control: 'select', + options: ['normal', 'large', 'xlarge'], + description: 'Размер аватара', + table: { + category: 'Props', + defaultValue: { summary: 'normal' }, + type: { summary: "'normal' | 'large' | 'xlarge'" }, + }, + }, + shape: { + control: 'select', + options: ['square', 'circle'], + description: 'Форма аватара', + table: { + category: 'Props', + defaultValue: { summary: 'square' }, + type: { summary: "'square' | 'circle'" }, + }, + }, + }, +}; + +const commonTemplate = ` + +`; + +export default meta; +type Story = StoryObj; + +// ── Default ────────────────────────────────────────────────────────────────── + +export const Default: Story = { + name: 'Default', + render: (args) => { + const parts: string[] = []; + + if (args.label) parts.push(`label="${args.label}"`); + if (args.icon) parts.push(`icon="${args.icon}"`); + if (args.image) parts.push(`image="${args.image}"`); + if (args.size && args.size !== 'normal') parts.push(`size="${args.size}"`); + if (args.shape && args.shape !== 'square') parts.push(`shape="${args.shape}"`); + + const template = parts.length + ? `` + : ``; + + return { props: args, template }; + }, + args: { + label: 'A', + size: 'normal', + shape: 'square', + }, + parameters: { + docs: { + description: { + story: 'Базовый пример компонента. Используйте Controls для интерактивного изменения пропсов.', + }, + }, + }, +}; + +// ── Label ──────────────────────────────────────────────────────────────────── + +export const Label: Story = { + render: (args) => ({ props: args, template: commonTemplate }), + args: { label: 'A', size: 'normal', shape: 'square' }, + parameters: { + docs: { + description: { story: 'Аватар с текстовой меткой.' }, + source: { + code: ``, + }, + }, + }, +}; + +// ── Icon ───────────────────────────────────────────────────────────────────── + +export const Icon: Story = { + render: (args) => ({ props: args, template: commonTemplate }), + args: { icon: 'ti ti-user', size: 'normal', shape: 'square' }, + parameters: { + docs: { + description: { story: 'Аватар с иконкой.' }, + source: { + code: ``, + }, + }, + }, +}; + +// ── Image ──────────────────────────────────────────────────────────────────── + +export const Image: Story = { + render: (args) => ({ props: args, template: commonTemplate }), + args: { image: '/assets/images/avatar/avatar.png', size: 'normal', shape: 'square' }, + parameters: { + docs: { + description: { story: 'Аватар с изображением. shape="square" — без обрезки, shape="circle" — с обрезкой по кругу.' }, + source: { + code: ``, + }, + }, + }, +}; + +// ── Sizes ──────────────────────────────────────────────────────────────────── + +export const Sizes: Story = { + render: (args) => ({ props: args, template: commonTemplate }), + args: { label: 'L', size: 'large', shape: 'square' }, + parameters: { + docs: { + description: { story: 'Размер аватара. Доступны: normal, large, xlarge.' }, + source: { + code: ``, + }, + }, + }, +}; + +// ── Shapes ─────────────────────────────────────────────────────────────────── + +export const Shapes: Story = { + render: (args) => ({ props: args, template: commonTemplate }), + args: { label: 'C', size: 'normal', shape: 'circle' }, + parameters: { + docs: { + description: { story: 'Форма аватара. circle — круглый, square — квадратный (по умолчанию).' }, + source: { + code: ``, + }, + }, + }, +}; + +// ── Group ──────────────────────────────────────────────────────────────────── +// Исключение: avatar-group — составной компонент, +// дочерние элементы — это его суть, не дублирование. + +export const Group: Story = { + render: () => ({ + template: ` + + + + + + + + + `, + }), + parameters: { + docs: { + description: { story: 'Группа аватаров с перекрытием.' }, + source: { + code: ` + + + +`, + }, + }, + }, +}; + +// ── LabelWithBadge ─────────────────────────────────────────────────────────── + +export const LabelWithBadge: Story = { + render: (args) => ({ + props: args, + template: ` + + + + `, + }), + parameters: { + docs: { + description: { story: 'Аватар с текстовой меткой и бейджем через OverlayBadge.' }, + source: { + code: ` + +`, + }, + }, + }, +}; + +// ── IconWithBadge ──────────────────────────────────────────────────────────── + +export const IconWithBadge: Story = { + render: (args) => ({ + props: args, + template: ` + + + + `, + }), + parameters: { + docs: { + description: { story: 'Аватар с иконкой и бейджем через OverlayBadge.' }, + source: { + code: ` + +`, + }, + }, + }, +}; + +// ── ImageWithBadge ─────────────────────────────────────────────────────────── + +export const ImageWithBadge: Story = { + render: (args) => ({ + props: args, + template: ` + + + + `, + }), + parameters: { + docs: { + description: { story: 'Аватар с изображением и бейджем через OverlayBadge.' }, + source: { + code: ` + +`, + }, + }, + }, +}; diff --git a/src/stories/components/avatar/examples/avatar-group.component.ts b/src/stories/components/avatar/examples/avatar-group.component.ts new file mode 100644 index 00000000..867d1b41 --- /dev/null +++ b/src/stories/components/avatar/examples/avatar-group.component.ts @@ -0,0 +1,61 @@ +import { Component } from '@angular/core'; +import { StoryObj } from '@storybook/angular'; +import { AvatarComponent, AvatarGroupComponent } from '../../../../lib/components/avatar/avatar.component'; + +const template = ` +

+ + + + + + + + +
+`; +const styles = ''; + +@Component({ + selector: 'app-avatar-group', + standalone: true, + imports: [AvatarComponent, AvatarGroupComponent], + template, + styles, +}) +export class AvatarGroupExampleComponent {} + +export const Group: StoryObj = { + render: () => ({ + template: ``, + }), + parameters: { + docs: { + description: { + story: 'Группа аватаров с перекрытием.', + }, + source: { + language: 'ts', + code: ` +import { Component } from '@angular/core'; +import { AvatarComponent, AvatarGroupComponent } from '@cdek-it/angular-ui-kit'; + +@Component({ + selector: 'app-avatar-group', + standalone: true, + imports: [AvatarComponent, AvatarGroupComponent], + template: \` + + + + + + + \`, +}) +export class AvatarGroupExampleComponent {} + `, + }, + }, + }, +}; diff --git a/src/stories/components/avatar/examples/avatar-icon-badge.component.ts b/src/stories/components/avatar/examples/avatar-icon-badge.component.ts new file mode 100644 index 00000000..d514bd12 --- /dev/null +++ b/src/stories/components/avatar/examples/avatar-icon-badge.component.ts @@ -0,0 +1,65 @@ +import { Component } from '@angular/core'; +import { StoryObj } from '@storybook/angular'; +import { OverlayBadge } from 'primeng/overlaybadge'; +import { AvatarComponent } from '../../../../lib/components/avatar/avatar.component'; + +const template = ` +
+
+ + + + + + +
+
+`; +const styles = ''; + +@Component({ + selector: 'app-avatar-icon-badge', + standalone: true, + imports: [AvatarComponent, OverlayBadge], + template, + styles, +}) +export class AvatarIconBadgeComponent {} + +export const IconWithBadge: StoryObj = { + render: () => ({ + template: ``, + }), + parameters: { + docs: { + description: { + story: 'Аватары с иконкой и бейджем через OverlayBadge.', + }, + source: { + language: 'ts', + code: ` +import { Component } from '@angular/core'; +import { OverlayBadge } from 'primeng/overlaybadge'; +import { AvatarComponent } from '@cdek-it/angular-ui-kit'; + +@Component({ + selector: 'app-avatar-icon-badge', + standalone: true, + imports: [AvatarComponent, OverlayBadge], + template: \` +
+ + + + + + +
+ \`, +}) +export class AvatarIconBadgeComponent {} + `, + }, + }, + }, +}; diff --git a/src/stories/components/avatar/examples/avatar-icon.component.ts b/src/stories/components/avatar/examples/avatar-icon.component.ts new file mode 100644 index 00000000..9dd91bdb --- /dev/null +++ b/src/stories/components/avatar/examples/avatar-icon.component.ts @@ -0,0 +1,57 @@ +import { Component } from '@angular/core'; +import { StoryObj } from '@storybook/angular'; +import { AvatarComponent } from '../../../../lib/components/avatar/avatar.component'; + +const template = ` +
+
+ + + +
+
+`; +const styles = ''; + +@Component({ + selector: 'app-avatar-icon', + standalone: true, + imports: [AvatarComponent], + template, + styles, +}) +export class AvatarIconComponent {} + +export const Icon: StoryObj = { + render: () => ({ + template: ``, + }), + parameters: { + docs: { + description: { + story: 'Аватары с иконкой разных размеров.', + }, + source: { + language: 'ts', + code: ` +import { Component } from '@angular/core'; +import { AvatarComponent } from '@cdek-it/angular-ui-kit'; + +@Component({ + selector: 'app-avatar-icon', + standalone: true, + imports: [AvatarComponent], + template: \` +
+ + + +
+ \`, +}) +export class AvatarIconComponent {} + `, + }, + }, + }, +}; diff --git a/src/stories/components/avatar/examples/avatar-image-badge.component.ts b/src/stories/components/avatar/examples/avatar-image-badge.component.ts new file mode 100644 index 00000000..f48dc980 --- /dev/null +++ b/src/stories/components/avatar/examples/avatar-image-badge.component.ts @@ -0,0 +1,65 @@ +import { Component } from '@angular/core'; +import { StoryObj } from '@storybook/angular'; +import { OverlayBadge } from 'primeng/overlaybadge'; +import { AvatarComponent } from '../../../../lib/components/avatar/avatar.component'; + +const template = ` +
+
+ + + + + + +
+
+`; +const styles = ''; + +@Component({ + selector: 'app-avatar-image-badge', + standalone: true, + imports: [AvatarComponent, OverlayBadge], + template, + styles, +}) +export class AvatarImageBadgeComponent {} + +export const ImageWithBadge: StoryObj = { + render: () => ({ + template: ``, + }), + parameters: { + docs: { + description: { + story: 'Аватары с изображением и бейджем через OverlayBadge.', + }, + source: { + language: 'ts', + code: ` +import { Component } from '@angular/core'; +import { OverlayBadge } from 'primeng/overlaybadge'; +import { AvatarComponent } from '@cdek-it/angular-ui-kit'; + +@Component({ + selector: 'app-avatar-image-badge', + standalone: true, + imports: [AvatarComponent, OverlayBadge], + template: \` +
+ + + + + + +
+ \`, +}) +export class AvatarImageBadgeComponent {} + `, + }, + }, + }, +}; diff --git a/src/stories/components/avatar/examples/avatar-image.component.ts b/src/stories/components/avatar/examples/avatar-image.component.ts new file mode 100644 index 00000000..c11580dc --- /dev/null +++ b/src/stories/components/avatar/examples/avatar-image.component.ts @@ -0,0 +1,57 @@ +import { Component } from '@angular/core'; +import { StoryObj } from '@storybook/angular'; +import { AvatarComponent } from '../../../../lib/components/avatar/avatar.component'; + +const template = ` +
+
+ + + +
+
+`; +const styles = ''; + +@Component({ + selector: 'app-avatar-image', + standalone: true, + imports: [AvatarComponent], + template, + styles, +}) +export class AvatarImageComponent {} + +export const Image: StoryObj = { + render: () => ({ + template: ``, + }), + parameters: { + docs: { + description: { + story: 'Аватары с изображением разных размеров.', + }, + source: { + language: 'ts', + code: ` +import { Component } from '@angular/core'; +import { AvatarComponent } from '@cdek-it/angular-ui-kit'; + +@Component({ + selector: 'app-avatar-image', + standalone: true, + imports: [AvatarComponent], + template: \` +
+ + + +
+ \`, +}) +export class AvatarImageComponent {} + `, + }, + }, + }, +}; diff --git a/src/stories/components/avatar/examples/avatar-label-badge.component.ts b/src/stories/components/avatar/examples/avatar-label-badge.component.ts new file mode 100644 index 00000000..bda2e9a0 --- /dev/null +++ b/src/stories/components/avatar/examples/avatar-label-badge.component.ts @@ -0,0 +1,65 @@ +import { Component } from '@angular/core'; +import { StoryObj } from '@storybook/angular'; +import { OverlayBadge } from 'primeng/overlaybadge'; +import { AvatarComponent } from '../../../../lib/components/avatar/avatar.component'; + +const template = ` +
+
+ + + + + + +
+
+`; +const styles = ''; + +@Component({ + selector: 'app-avatar-label-badge', + standalone: true, + imports: [AvatarComponent, OverlayBadge], + template, + styles, +}) +export class AvatarLabelBadgeComponent {} + +export const LabelWithBadge: StoryObj = { + render: () => ({ + template: ``, + }), + parameters: { + docs: { + description: { + story: 'Аватары с текстом и бейджем через OverlayBadge.', + }, + source: { + language: 'ts', + code: ` +import { Component } from '@angular/core'; +import { OverlayBadge } from 'primeng/overlaybadge'; +import { AvatarComponent } from '@cdek-it/angular-ui-kit'; + +@Component({ + selector: 'app-avatar-label-badge', + standalone: true, + imports: [AvatarComponent, OverlayBadge], + template: \` +
+ + + + + + +
+ \`, +}) +export class AvatarLabelBadgeComponent {} + `, + }, + }, + }, +}; diff --git a/src/stories/components/avatar/examples/avatar-label.component.ts b/src/stories/components/avatar/examples/avatar-label.component.ts new file mode 100644 index 00000000..a33588c3 --- /dev/null +++ b/src/stories/components/avatar/examples/avatar-label.component.ts @@ -0,0 +1,57 @@ +import { Component } from '@angular/core'; +import { StoryObj } from '@storybook/angular'; +import { AvatarComponent } from '../../../../lib/components/avatar/avatar.component'; + +const template = ` +
+
+ + + +
+
+`; +const styles = ''; + +@Component({ + selector: 'app-avatar-label', + standalone: true, + imports: [AvatarComponent], + template, + styles, +}) +export class AvatarLabelComponent {} + +export const Label: StoryObj = { + render: () => ({ + template: ``, + }), + parameters: { + docs: { + description: { + story: 'Аватары с текстовой меткой разных размеров.', + }, + source: { + language: 'ts', + code: ` +import { Component } from '@angular/core'; +import { AvatarComponent } from '@cdek-it/angular-ui-kit'; + +@Component({ + selector: 'app-avatar-label', + standalone: true, + imports: [AvatarComponent], + template: \` +
+ + + +
+ \`, +}) +export class AvatarLabelComponent {} + `, + }, + }, + }, +}; diff --git a/src/stories/components/avatar/examples/avatar-shapes.component.ts b/src/stories/components/avatar/examples/avatar-shapes.component.ts new file mode 100644 index 00000000..c4693b30 --- /dev/null +++ b/src/stories/components/avatar/examples/avatar-shapes.component.ts @@ -0,0 +1,55 @@ +import { Component } from '@angular/core'; +import { StoryObj } from '@storybook/angular'; +import { AvatarComponent } from '../../../../lib/components/avatar/avatar.component'; + +const template = ` +
+
+ + +
+
+`; +const styles = ''; + +@Component({ + selector: 'app-avatar-shapes', + standalone: true, + imports: [AvatarComponent], + template, + styles, +}) +export class AvatarShapesComponent {} + +export const Shapes: StoryObj = { + render: () => ({ + template: ``, + }), + parameters: { + docs: { + description: { + story: 'Формы аватара: square (по умолчанию) и circle.', + }, + source: { + language: 'ts', + code: ` +import { Component } from '@angular/core'; +import { AvatarComponent } from '@cdek-it/angular-ui-kit'; + +@Component({ + selector: 'app-avatar-shapes', + standalone: true, + imports: [AvatarComponent], + template: \` +
+ + +
+ \`, +}) +export class AvatarShapesComponent {} + `, + }, + }, + }, +}; diff --git a/src/stories/components/avatar/examples/avatar-sizes.component.ts b/src/stories/components/avatar/examples/avatar-sizes.component.ts new file mode 100644 index 00000000..99ff3370 --- /dev/null +++ b/src/stories/components/avatar/examples/avatar-sizes.component.ts @@ -0,0 +1,57 @@ +import { Component } from '@angular/core'; +import { StoryObj } from '@storybook/angular'; +import { AvatarComponent } from '../../../../lib/components/avatar/avatar.component'; + +const template = ` +
+
+ + + +
+
+`; +const styles = ''; + +@Component({ + selector: 'app-avatar-sizes', + standalone: true, + imports: [AvatarComponent], + template, + styles, +}) +export class AvatarSizesComponent {} + +export const Sizes: StoryObj = { + render: () => ({ + template: ``, + }), + parameters: { + docs: { + description: { + story: 'Все доступные размеры аватара: normal, large, xlarge.', + }, + source: { + language: 'ts', + code: ` +import { Component } from '@angular/core'; +import { AvatarComponent } from '@cdek-it/angular-ui-kit'; + +@Component({ + selector: 'app-avatar-sizes', + standalone: true, + imports: [AvatarComponent], + template: \` +
+ + + +
+ \`, +}) +export class AvatarSizesComponent {} + `, + }, + }, + }, +}; From 5301321f7c7325a7b6f8c7f8bcf95798e0491997 Mon Sep 17 00:00:00 2001 From: Danil Khaliulin Date: Tue, 7 Apr 2026 21:11:18 +0700 Subject: [PATCH 2/4] =?UTF-8?q?=D1=80=D0=B5=D0=B4=D0=B0=D0=BA=D1=82=D0=B8?= =?UTF-8?q?=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20=D0=B3=D1=80=D1=83?= =?UTF-8?q?=D0=BF=D0=BF=D1=8B=20=D0=BA=D0=BE=D0=BC=D0=BF=D0=BE=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/stories/components/avatar/avatar.stories.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stories/components/avatar/avatar.stories.ts b/src/stories/components/avatar/avatar.stories.ts index 3dc24780..036a9399 100644 --- a/src/stories/components/avatar/avatar.stories.ts +++ b/src/stories/components/avatar/avatar.stories.ts @@ -3,7 +3,7 @@ import { OverlayBadge } from 'primeng/overlaybadge'; import { AvatarComponent, AvatarGroupComponent } from '../../../lib/components/avatar/avatar.component'; const meta: Meta = { - title: 'Prime/Misc/Avatar', + title: 'Components/Misc/Avatar', component: AvatarComponent, tags: ['autodocs'], decorators: [ From b863bc97c72624855daaa316806a586eaa1f4427 Mon Sep 17 00:00:00 2001 From: Danil Khaliulin Date: Mon, 13 Apr 2026 15:15:39 +0700 Subject: [PATCH 3/4] =?UTF-8?q?=D1=84=D0=B8=D0=BA=D1=81=20=D1=81=D1=82?= =?UTF-8?q?=D0=B8=D0=BB=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D0=B8=20=D0=B2=D0=B0?= =?UTF-8?q?=D1=80=D0=B8=D0=B0=D0=BD=D1=82=D0=B0=20Group?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/lib/components/avatar/avatar.component.ts | 9 +++++++- src/prime-preset/tokens/components/avatar.ts | 21 +++++++++++++++---- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/lib/components/avatar/avatar.component.ts b/src/lib/components/avatar/avatar.component.ts index 15f6db6c..de933fd7 100644 --- a/src/lib/components/avatar/avatar.component.ts +++ b/src/lib/components/avatar/avatar.component.ts @@ -1,4 +1,4 @@ -import { Component, Input } from '@angular/core'; +import { Component, HostBinding, Input } from '@angular/core'; import { Avatar } from 'primeng/avatar'; import { AvatarGroup } from 'primeng/avatargroup'; @@ -26,6 +26,13 @@ export class AvatarComponent { @Input() size: AvatarSize = 'normal'; @Input() shape: AvatarShape = 'square'; + @HostBinding('class') get hostClass(): string { + const classes = ['ui-avatar']; + if (this.size === 'large') classes.push('ui-avatar-lg'); + if (this.size === 'xlarge') classes.push('ui-avatar-xl'); + return classes.join(' '); + } + get primeSize(): 'normal' | 'large' | 'xlarge' | undefined { return this.size === 'normal' ? undefined : this.size; } diff --git a/src/prime-preset/tokens/components/avatar.ts b/src/prime-preset/tokens/components/avatar.ts index 562ebb5a..2c80d571 100644 --- a/src/prime-preset/tokens/components/avatar.ts +++ b/src/prime-preset/tokens/components/avatar.ts @@ -2,10 +2,23 @@ export const avatarCss = ({ dt }: { dt: (token: string) => string }): string => :root { --p-avatar-extend-border-color: ${dt('avatar.extend.borderColor')}; --p-avatar-extend-circle-border-radius: ${dt('avatar.extend.circle.borderRadius')}; - --p-avatar-group-border-color: ${dt('avatar.group.borderColor')}; - --p-avatar-group-offset: ${dt('avatar.group.offset')}; - --p-avatar-lg-group-offset: ${dt('avatar.lg.group.offset')}; - --p-avatar-xl-group-offset: ${dt('avatar.xl.group.offset')}; + --p-avatar-group-border-color: ${dt('content.background')}; + --p-avatar-group-offset: calc(-1 * ${dt('media.padding.300')}); + --p-avatar-lg-group-offset: calc(-1 * ${dt('media.padding.300')}); + --p-avatar-xl-group-offset: calc(-1 * ${dt('media.padding.600')}); + } + + /* ─── Группировка: отступы для кастомных классов хост-элемента ─── */ + .p-avatar-group .ui-avatar + .ui-avatar { + margin-inline-start: var(--p-avatar-group-offset); + } + + .p-avatar-group .ui-avatar-lg + .ui-avatar-lg { + margin-inline-start: var(--p-avatar-lg-group-offset); + } + + .p-avatar-group .ui-avatar-xl + .ui-avatar-xl { + margin-inline-start: var(--p-avatar-xl-group-offset); } /* ─── Круглая форма: clip изображения по максимальному border-radius ─── */ From 57720ddfbe2a5942b8dea290b1379a7073fdef78 Mon Sep 17 00:00:00 2001 From: Danil Khaliulin Date: Mon, 13 Apr 2026 15:29:49 +0700 Subject: [PATCH 4/4] =?UTF-8?q?=D1=81=D1=82=D0=BE=D1=80=D0=B8=D1=81=D1=8B?= =?UTF-8?q?=20Icon-with-badge=20=D0=B8=20image-with-badge=20=D1=81=D0=BE?= =?UTF-8?q?=20=D0=B7=D0=BD=D0=B0=D1=87=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/stories/components/avatar/avatar.stories.ts | 8 ++++---- .../avatar/examples/avatar-icon-badge.component.ts | 8 ++++---- .../avatar/examples/avatar-image-badge.component.ts | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/stories/components/avatar/avatar.stories.ts b/src/stories/components/avatar/avatar.stories.ts index 036a9399..6f760953 100644 --- a/src/stories/components/avatar/avatar.stories.ts +++ b/src/stories/components/avatar/avatar.stories.ts @@ -256,7 +256,7 @@ export const IconWithBadge: Story = { render: (args) => ({ props: args, template: ` - + `, @@ -265,7 +265,7 @@ export const IconWithBadge: Story = { docs: { description: { story: 'Аватар с иконкой и бейджем через OverlayBadge.' }, source: { - code: ` + code: ` `, }, @@ -279,7 +279,7 @@ export const ImageWithBadge: Story = { render: (args) => ({ props: args, template: ` - + `, @@ -288,7 +288,7 @@ export const ImageWithBadge: Story = { docs: { description: { story: 'Аватар с изображением и бейджем через OverlayBadge.' }, source: { - code: ` + code: ` `, }, diff --git a/src/stories/components/avatar/examples/avatar-icon-badge.component.ts b/src/stories/components/avatar/examples/avatar-icon-badge.component.ts index d514bd12..e4b8fa96 100644 --- a/src/stories/components/avatar/examples/avatar-icon-badge.component.ts +++ b/src/stories/components/avatar/examples/avatar-icon-badge.component.ts @@ -6,10 +6,10 @@ import { AvatarComponent } from '../../../../lib/components/avatar/avatar.compon const template = `
- + - +
@@ -48,10 +48,10 @@ import { AvatarComponent } from '@cdek-it/angular-ui-kit'; imports: [AvatarComponent, OverlayBadge], template: \`
- + - +
diff --git a/src/stories/components/avatar/examples/avatar-image-badge.component.ts b/src/stories/components/avatar/examples/avatar-image-badge.component.ts index f48dc980..2117577b 100644 --- a/src/stories/components/avatar/examples/avatar-image-badge.component.ts +++ b/src/stories/components/avatar/examples/avatar-image-badge.component.ts @@ -6,10 +6,10 @@ import { AvatarComponent } from '../../../../lib/components/avatar/avatar.compon const template = `
- + - +
@@ -48,10 +48,10 @@ import { AvatarComponent } from '@cdek-it/angular-ui-kit'; imports: [AvatarComponent, OverlayBadge], template: \`
- + - +