Skip to content
Open
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
71 changes: 29 additions & 42 deletions src/lib/components/select-button/select-button.component.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,16 @@
import { Component, EventEmitter, Input, Optional, Output, Self } from '@angular/core';
import { NgClass } from '@angular/common';
import { ControlValueAccessor, FormsModule, NgControl } from '@angular/forms';
import { SelectButton, SelectButtonChangeEvent } from 'primeng/selectbutton';
import { SelectButton } from 'primeng/selectbutton';
import { SharedModule } from 'primeng/api';

export interface ExtraSelectButtonOption {
name: string;
code: string | number;
export interface ExtraSelectButtonItem {
label: string;
value: string;
icon?: string;
disabled?: boolean;
}

export interface ExtraSelectButtonChangeEvent {
value: any;
originalEvent?: Event;
}

export type ExtraSelectButtonSize = 'small' | 'base' | 'large' | 'xlarge';

@Component({
selector: 'extra-select-button',
standalone: true,
Expand All @@ -27,15 +20,13 @@ export type ExtraSelectButtonSize = 'small' | 'base' | 'large' | 'xlarge';
[options]="options"
[ngModel]="value"
(ngModelChange)="onValueChange($event)"
(onChange)="onChangeHandler($event)"
[optionLabel]="optionLabel"
[optionValue]="optionValue"
[optionDisabled]="optionDisabled"
[multiple]="multiple"
[allowEmpty]="allowEmpty"
[disabled]="isDisabled"
[size]="primeSize"
[styleClass]="primeStyleClass"
[ngClass]="sizeClass"
>
<ng-template pTemplate="item" let-item>
@if ($any(item)['icon']) {
Expand All @@ -47,21 +38,21 @@ export type ExtraSelectButtonSize = 'small' | 'base' | 'large' | 'xlarge';
`,
})
export class ExtraSelectButtonComponent implements ControlValueAccessor {
@Input() options: ExtraSelectButtonOption[] | any[] = [];
@Input() optionLabel = 'name';
@Input() optionValue = 'code';
@Input() options: unknown[] = [];
@Input() optionLabel = 'label';
@Input() optionValue = 'value';
@Input() optionDisabled = 'disabled';
@Input() size: ExtraSelectButtonSize = 'base';
@Input() size: 'base' | 'small' | 'large' | 'xlarge' = 'base';
@Input() multiple = false;
@Input() allowEmpty = true;

@Output() onChange = new EventEmitter<ExtraSelectButtonChangeEvent>();
@Output() valueChange = new EventEmitter<string | string[]>();

value: any = null;
value: string | string[] = '';

private _disabled = false;
private _onChange = (_: any) => {};
private _onTouched = () => {};
private onChange = (_: string | string[]) => {};
private onTouched = () => {};

constructor(@Optional() @Self() private ngControl: NgControl) {
if (ngControl) ngControl.valueAccessor = this;
Expand All @@ -71,39 +62,35 @@ export class ExtraSelectButtonComponent implements ControlValueAccessor {
return this._disabled;
}

get primeSize(): 'small' | 'large' | undefined {
if (this.size === 'small') return 'small';
if (this.size === 'large') return 'large';
return undefined;
get sizeClass(): string {
const sizeMap: Record<string, string> = {
small: 'p-selectbutton-small',
large: 'p-selectbutton-large',
xlarge: 'p-selectbutton-xlarge',
};
return sizeMap[this.size] ?? '';
}

get primeStyleClass(): string {
return this.size === 'xlarge' ? 'p-selectbutton-xlarge' : '';
writeValue(value: string | string[]): void {
this.value = value ?? '';
}

writeValue(value: any): void {
this.value = value ?? null;
}

registerOnChange(fn: (value: any) => void): void {
this._onChange = fn;
registerOnChange(fn: (value: string | string[]) => void): void {
this.onChange = fn;
}

registerOnTouched(fn: () => void): void {
this._onTouched = fn;
this.onTouched = fn;
}

setDisabledState(isDisabled: boolean): void {
this._disabled = isDisabled;
}

onValueChange(newValue: any): void {
onValueChange(newValue: string | string[]): void {
this.value = newValue;
this._onChange(newValue);
this._onTouched();
}

onChangeHandler(event: SelectButtonChangeEvent): void {
this.onChange.emit({ value: event.value, originalEvent: event.originalEvent });
this.onChange(newValue);
this.onTouched();
this.valueChange.emit(newValue);
}
}
2 changes: 1 addition & 1 deletion src/lib/components/select-button/select-button.figma.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ updated: '2026-06-22'
| `optionLabel` | `string` | `'label'` | Имя поля объекта опции, из которого берётся подпись сегмента |
| `optionValue` | `string` | `'value'` | Имя поля объекта опции, из которого берётся значение модели |
| `optionDisabled` | `string` | `'disabled'` | Имя поля объекта опции, отключающего отдельный сегмент |
| `size` | `'small' \| 'base' \| 'large' \| 'xlarge'` | `'base'` | Размер контрола |
| `size` | `'small' \| 'base' \| 'large' \| 'xLarge'` | `'base'` | Размер контрола |
| `multiple` | `boolean` | `false` | Множественный выбор: модель — массив значений вместо одиночного значения |
| `allowEmpty` | `boolean` | `true` | Разрешает снять выбор (пустое значение) повторным нажатием на активный сегмент |
| `disabled` | `boolean` | `false` | Отключённое состояние всего контрола — соответствует Figma-свойству `state=disabled`; задаётся через `[disabled]` или `setDisabledState` формы |
Expand Down
53 changes: 48 additions & 5 deletions src/lib/providers/prime-preset/tokens/components/dialog.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
/**
* Кастомная CSS-стилизация для компонента p-dialog.
* Подключается в map-tokens.ts: `import { dialogCss } from './tokens/components/dialog'`
*
* Радиусы, отступы, фон и тень приходят токенами пресета (dialog.root.*, dialog.header.* и т.д.).
* Здесь — типографика и то, что Aura зашила сырыми значениями: рамка окна и фон подложки.
*/
export const dialogCss = ({ dt }: { dt: (token: string) => string }): string => `
.p-dialog .p-dialog-title {
font-family: ${dt('fonts.fontFamily.heading')};
Expand All @@ -14,7 +21,7 @@ export const dialogCss = ({ dt }: { dt: (token: string) => string }): string =>
}

.p-dialog .p-dialog-header {
border-bottom: ${dt('dimension.borderWidth.100')} solid ${dt('dialog.root.borderColor')};
border-bottom: ${dt('dialog.extend.borderWidth')} solid ${dt('dialog.root.borderColor')};
display: flex;
align-items: center;
justify-content: space-between;
Expand All @@ -35,19 +42,55 @@ export const dialogCss = ({ dt }: { dt: (token: string) => string }): string =>
box-shadow: none;
}

/* Рамка окна: Aura зашивает её сырым 1px, дизайн задаёт токеном.
Ширина по умолчанию — base; в экспорте нет ветки overlayWidth, поэтому значения
берём с той же ступени примитивов, что рисует Figma (overlay/width: 280 / 350 / 420 / 630) */
.p-dialog {
width: ${dt('dialog.extend.dimension_overlayWidth_base')};
border: ${dt('dialog.extend.borderWidth')} solid ${dt('dialog.root.borderColor')};
width: ${dt('sizing.175x')};
}

/* Подложка: Aura держит свой цвет анимацией появления (fill-mode: forwards),
поэтому одного правила background мало — переопределяем саму анимацию маски диалога */
.p-dialog-mask.p-overlay-mask {
background: ${dt('dialog.extend.backdrop')};
}

.p-dialog-mask.p-overlay-mask-enter {
animation-name: p-dialog-mask-enter;
}

.p-dialog-mask.p-overlay-mask-leave {
animation-name: p-dialog-mask-leave;
}

@keyframes p-dialog-mask-enter {
from {
background: transparent;
}
to {
background: ${dt('dialog.extend.backdrop')};
}
}

@keyframes p-dialog-mask-leave {
from {
background: ${dt('dialog.extend.backdrop')};
}
to {
background: transparent;
}
}

.p-dialog.p-component.p-dialog-sm {
width: ${dt('dialog.extend.dimension_overlayWidth_sm')};
width: ${dt('sizing.140x')};
}

.p-dialog.p-component.p-dialog-lg {
width: ${dt('dialog.extend.dimension_overlayWidth_lg')};
width: ${dt('sizing.210x')};
}

.p-dialog.p-component.p-dialog-xlg {
width: ${dt('dialog.extend.dimension_overlayWidth_xlg')};
width: ${dt('sizing.315x')};
}
`;
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ const template = `
<ng-template extraDialogTemplate="header">
<div class="flex items-center gap-2">
<i class="ti ti-package text-primary text-xl"></i>
<span class="font-semibold">Инвойс №CDEK-7842</span>
<extra-tag severity="warning" value="ожидает оплаты"></extra-tag>
<span class="font-semibold">Инвойс №7842</span>
<extra-tag severity="warning" value="ожидает"></extra-tag>
</div>
</ng-template>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Component } from '@angular/core';
import { ReactiveFormsModule, FormControl } from '@angular/forms';
import { StoryObj } from '@storybook/angular';
import { ExtraSelectButtonComponent, ExtraSelectButtonOption } from '../../../../lib/components/select-button/select-button.component';
import { ExtraSelectButtonComponent, ExtraSelectButtonItem } from '../../../../lib/components/select-button/select-button.component';

const template = `
<div class="bg-surface-ground p-4">
Expand All @@ -19,10 +19,10 @@ const styles = '';
})
export class SelectButtonDisabledComponent {
control = new FormControl({ value: '1', disabled: true });
options: ExtraSelectButtonOption[] = [
{ name: 'Option 1', code: '1' },
{ name: 'Option 2', code: '2' },
{ name: 'Option 3', code: '3' },
options: ExtraSelectButtonItem[] = [
{ label: 'Option 1', value: '1' },
{ label: 'Option 2', value: '2' },
{ label: 'Option 3', value: '3' },
];
}

Expand All @@ -40,7 +40,7 @@ export const Disabled: StoryObj = {
code: `
import { Component } from '@angular/core';
import { ReactiveFormsModule, FormControl } from '@angular/forms';
import { ExtraSelectButtonComponent, ExtraSelectButtonOption } from '@cdek-it/angular-ui-kit';
import { ExtraSelectButtonComponent, ExtraSelectButtonItem } from '@cdek-it/angular-ui-kit';

@Component({
selector: 'app-select-button-disabled',
Expand All @@ -52,10 +52,10 @@ import { ExtraSelectButtonComponent, ExtraSelectButtonOption } from '@cdek-it/an
})
export class SelectButtonDisabledComponent {
control = new FormControl({ value: '1', disabled: true });
options: ExtraSelectButtonOption[] = [
{ name: 'Option 1', code: '1' },
{ name: 'Option 2', code: '2' },
{ name: 'Option 3', code: '3' },
options: ExtraSelectButtonItem[] = [
{ label: 'Option 1', value: '1' },
{ label: 'Option 2', value: '2' },
{ label: 'Option 3', value: '3' },
];
}
`,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Component } from '@angular/core';
import { ReactiveFormsModule, FormControl } from '@angular/forms';
import { StoryObj } from '@storybook/angular';
import { ExtraSelectButtonComponent, ExtraSelectButtonOption } from '../../../../lib/components/select-button/select-button.component';
import { ExtraSelectButtonComponent, ExtraSelectButtonItem } from '../../../../lib/components/select-button/select-button.component';

const template = `
<div class="bg-surface-ground p-4">
Expand All @@ -19,10 +19,10 @@ const styles = '';
})
export class SelectButtonIconsComponent {
control = new FormControl('left');
options: ExtraSelectButtonOption[] = [
{ name: 'Left', code: 'left', icon: 'ti ti-align-left' },
{ name: 'Center', code: 'center', icon: 'ti ti-align-center' },
{ name: 'Right', code: 'right', icon: 'ti ti-align-right' },
options: ExtraSelectButtonItem[] = [
{ label: 'Left', value: 'left', icon: 'ti ti-align-left' },
{ label: 'Center', value: 'center', icon: 'ti ti-align-center' },
{ label: 'Right', value: 'right', icon: 'ti ti-align-right' },
];
}

Expand All @@ -40,7 +40,7 @@ export const WithIcons: StoryObj = {
code: `
import { Component } from '@angular/core';
import { ReactiveFormsModule, FormControl } from '@angular/forms';
import { ExtraSelectButtonComponent, ExtraSelectButtonOption } from '@cdek-it/angular-ui-kit';
import { ExtraSelectButtonComponent, ExtraSelectButtonItem } from '@cdek-it/angular-ui-kit';

@Component({
selector: 'app-select-button-icons',
Expand All @@ -52,10 +52,10 @@ import { ExtraSelectButtonComponent, ExtraSelectButtonOption } from '@cdek-it/an
})
export class SelectButtonIconsComponent {
control = new FormControl('left');
options: ExtraSelectButtonOption[] = [
{ name: 'Left', code: 'left', icon: 'ti ti-align-left' },
{ name: 'Center', code: 'center', icon: 'ti ti-align-center' },
{ name: 'Right', code: 'right', icon: 'ti ti-align-right' },
options: ExtraSelectButtonItem[] = [
{ label: 'Left', value: 'left', icon: 'ti ti-align-left' },
{ label: 'Center', value: 'center', icon: 'ti ti-align-center' },
{ label: 'Right', value: 'right', icon: 'ti ti-align-right' },
];
}
`,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Component } from '@angular/core';
import { ReactiveFormsModule, FormControl } from '@angular/forms';
import { StoryObj } from '@storybook/angular';
import { ExtraSelectButtonComponent, ExtraSelectButtonOption } from '../../../../lib/components/select-button/select-button.component';
import { ExtraSelectButtonComponent, ExtraSelectButtonItem } from '../../../../lib/components/select-button/select-button.component';

const template = `
<div class="bg-surface-ground p-4">
Expand All @@ -19,10 +19,10 @@ const styles = '';
})
export class SelectButtonSelectedComponent {
control = new FormControl('2');
options: ExtraSelectButtonOption[] = [
{ name: 'Option 1', code: '1' },
{ name: 'Option 2', code: '2' },
{ name: 'Option 3', code: '3' },
options: ExtraSelectButtonItem[] = [
{ label: 'Option 1', value: '1' },
{ label: 'Option 2', value: '2' },
{ label: 'Option 3', value: '3' },
];
}

Expand All @@ -40,7 +40,7 @@ export const Selected: StoryObj = {
code: `
import { Component } from '@angular/core';
import { ReactiveFormsModule, FormControl } from '@angular/forms';
import { ExtraSelectButtonComponent, ExtraSelectButtonOption } from '@cdek-it/angular-ui-kit';
import { ExtraSelectButtonComponent, ExtraSelectButtonItem } from '@cdek-it/angular-ui-kit';

@Component({
selector: 'app-select-button-selected',
Expand All @@ -52,10 +52,10 @@ import { ExtraSelectButtonComponent, ExtraSelectButtonOption } from '@cdek-it/an
})
export class SelectButtonSelectedComponent {
control = new FormControl('2');
options: ExtraSelectButtonOption[] = [
{ name: 'Option 1', code: '1' },
{ name: 'Option 2', code: '2' },
{ name: 'Option 3', code: '3' },
options: ExtraSelectButtonItem[] = [
{ label: 'Option 1', value: '1' },
{ label: 'Option 2', value: '2' },
{ label: 'Option 3', value: '3' },
];
}
`,
Expand Down
Loading
Loading