diff --git a/src/lib/components/select-button/select-button.component.ts b/src/lib/components/select-button/select-button.component.ts index b23a66b1..052d366d 100644 --- a/src/lib/components/select-button/select-button.component.ts +++ b/src/lib/components/select-button/select-button.component.ts @@ -1,16 +1,23 @@ import { Component, EventEmitter, Input, Optional, Output, Self } from '@angular/core'; import { NgClass } from '@angular/common'; import { ControlValueAccessor, FormsModule, NgControl } from '@angular/forms'; -import { SelectButton } from 'primeng/selectbutton'; +import { SelectButton, SelectButtonChangeEvent } from 'primeng/selectbutton'; import { SharedModule } from 'primeng/api'; -export interface ExtraSelectButtonItem { - label: string; - value: string; +export interface ExtraSelectButtonOption { + name: string; + code: string | number; 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, @@ -20,13 +27,15 @@ export interface ExtraSelectButtonItem { [options]="options" [ngModel]="value" (ngModelChange)="onValueChange($event)" + (onChange)="onChangeHandler($event)" [optionLabel]="optionLabel" [optionValue]="optionValue" [optionDisabled]="optionDisabled" [multiple]="multiple" [allowEmpty]="allowEmpty" [disabled]="isDisabled" - [ngClass]="sizeClass" + [size]="primeSize" + [styleClass]="primeStyleClass" > @if ($any(item)['icon']) { @@ -38,21 +47,21 @@ export interface ExtraSelectButtonItem { `, }) export class ExtraSelectButtonComponent implements ControlValueAccessor { - @Input() options: unknown[] = []; - @Input() optionLabel = 'label'; - @Input() optionValue = 'value'; + @Input() options: ExtraSelectButtonOption[] | any[] = []; + @Input() optionLabel = 'name'; + @Input() optionValue = 'code'; @Input() optionDisabled = 'disabled'; - @Input() size: 'base' | 'small' | 'large' | 'xlarge' = 'base'; + @Input() size: ExtraSelectButtonSize = 'base'; @Input() multiple = false; @Input() allowEmpty = true; - @Output() valueChange = new EventEmitter(); + @Output() onChange = new EventEmitter(); - value: string | string[] = ''; + value: any = null; private _disabled = false; - private onChange = (_: string | string[]) => {}; - private onTouched = () => {}; + private _onChange = (_: any) => {}; + private _onTouched = () => {}; constructor(@Optional() @Self() private ngControl: NgControl) { if (ngControl) ngControl.valueAccessor = this; @@ -62,35 +71,39 @@ export class ExtraSelectButtonComponent implements ControlValueAccessor { return this._disabled; } - get sizeClass(): string { - const sizeMap: Record = { - small: 'p-selectbutton-small', - large: 'p-selectbutton-large', - xlarge: 'p-selectbutton-xlarge', - }; - return sizeMap[this.size] ?? ''; + get primeSize(): 'small' | 'large' | undefined { + if (this.size === 'small') return 'small'; + if (this.size === 'large') return 'large'; + return undefined; } - writeValue(value: string | string[]): void { - this.value = value ?? ''; + get primeStyleClass(): string { + return this.size === 'xlarge' ? 'p-selectbutton-xlarge' : ''; } - registerOnChange(fn: (value: string | string[]) => void): void { - this.onChange = fn; + writeValue(value: any): void { + this.value = value ?? null; + } + + registerOnChange(fn: (value: any) => void): void { + this._onChange = fn; } registerOnTouched(fn: () => void): void { - this.onTouched = fn; + this._onTouched = fn; } setDisabledState(isDisabled: boolean): void { this._disabled = isDisabled; } - onValueChange(newValue: string | string[]): void { + onValueChange(newValue: any): void { this.value = newValue; - this.onChange(newValue); - this.onTouched(); - this.valueChange.emit(newValue); + this._onChange(newValue); + this._onTouched(); + } + + onChangeHandler(event: SelectButtonChangeEvent): void { + this.onChange.emit({ value: event.value, originalEvent: event.originalEvent }); } } diff --git a/src/lib/components/select-button/select-button.figma.md b/src/lib/components/select-button/select-button.figma.md index a08e8cc7..eeabe652 100644 --- a/src/lib/components/select-button/select-button.figma.md +++ b/src/lib/components/select-button/select-button.figma.md @@ -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` формы | diff --git a/src/stories/components/select-button/examples/select-button-disabled.component.ts b/src/stories/components/select-button/examples/select-button-disabled.component.ts index d50cc6b2..5f8375f9 100644 --- a/src/stories/components/select-button/examples/select-button-disabled.component.ts +++ b/src/stories/components/select-button/examples/select-button-disabled.component.ts @@ -1,7 +1,7 @@ import { Component } from '@angular/core'; import { ReactiveFormsModule, FormControl } from '@angular/forms'; import { StoryObj } from '@storybook/angular'; -import { ExtraSelectButtonComponent, ExtraSelectButtonItem } from '../../../../lib/components/select-button/select-button.component'; +import { ExtraSelectButtonComponent, ExtraSelectButtonOption } from '../../../../lib/components/select-button/select-button.component'; const template = `
@@ -19,10 +19,10 @@ const styles = ''; }) export class SelectButtonDisabledComponent { control = new FormControl({ value: '1', disabled: true }); - options: ExtraSelectButtonItem[] = [ - { label: 'Option 1', value: '1' }, - { label: 'Option 2', value: '2' }, - { label: 'Option 3', value: '3' }, + options: ExtraSelectButtonOption[] = [ + { name: 'Option 1', code: '1' }, + { name: 'Option 2', code: '2' }, + { name: 'Option 3', code: '3' }, ]; } @@ -40,7 +40,7 @@ export const Disabled: StoryObj = { code: ` import { Component } from '@angular/core'; import { ReactiveFormsModule, FormControl } from '@angular/forms'; -import { ExtraSelectButtonComponent, ExtraSelectButtonItem } from '@cdek-it/angular-ui-kit'; +import { ExtraSelectButtonComponent, ExtraSelectButtonOption } from '@cdek-it/angular-ui-kit'; @Component({ selector: 'app-select-button-disabled', @@ -52,10 +52,10 @@ import { ExtraSelectButtonComponent, ExtraSelectButtonItem } from '@cdek-it/angu }) export class SelectButtonDisabledComponent { control = new FormControl({ value: '1', disabled: true }); - options: ExtraSelectButtonItem[] = [ - { label: 'Option 1', value: '1' }, - { label: 'Option 2', value: '2' }, - { label: 'Option 3', value: '3' }, + options: ExtraSelectButtonOption[] = [ + { name: 'Option 1', code: '1' }, + { name: 'Option 2', code: '2' }, + { name: 'Option 3', code: '3' }, ]; } `, diff --git a/src/stories/components/select-button/examples/select-button-icons.component.ts b/src/stories/components/select-button/examples/select-button-icons.component.ts index 1d045f87..bcf4c0de 100644 --- a/src/stories/components/select-button/examples/select-button-icons.component.ts +++ b/src/stories/components/select-button/examples/select-button-icons.component.ts @@ -1,7 +1,7 @@ import { Component } from '@angular/core'; import { ReactiveFormsModule, FormControl } from '@angular/forms'; import { StoryObj } from '@storybook/angular'; -import { ExtraSelectButtonComponent, ExtraSelectButtonItem } from '../../../../lib/components/select-button/select-button.component'; +import { ExtraSelectButtonComponent, ExtraSelectButtonOption } from '../../../../lib/components/select-button/select-button.component'; const template = `
@@ -19,10 +19,10 @@ const styles = ''; }) export class SelectButtonIconsComponent { control = new FormControl('left'); - 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' }, + 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' }, ]; } @@ -40,7 +40,7 @@ export const WithIcons: StoryObj = { code: ` import { Component } from '@angular/core'; import { ReactiveFormsModule, FormControl } from '@angular/forms'; -import { ExtraSelectButtonComponent, ExtraSelectButtonItem } from '@cdek-it/angular-ui-kit'; +import { ExtraSelectButtonComponent, ExtraSelectButtonOption } from '@cdek-it/angular-ui-kit'; @Component({ selector: 'app-select-button-icons', @@ -52,10 +52,10 @@ import { ExtraSelectButtonComponent, ExtraSelectButtonItem } from '@cdek-it/angu }) export class SelectButtonIconsComponent { control = new FormControl('left'); - 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' }, + 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' }, ]; } `, diff --git a/src/stories/components/select-button/examples/select-button-selected.component.ts b/src/stories/components/select-button/examples/select-button-selected.component.ts index 7a9f329f..5f463398 100644 --- a/src/stories/components/select-button/examples/select-button-selected.component.ts +++ b/src/stories/components/select-button/examples/select-button-selected.component.ts @@ -1,7 +1,7 @@ import { Component } from '@angular/core'; import { ReactiveFormsModule, FormControl } from '@angular/forms'; import { StoryObj } from '@storybook/angular'; -import { ExtraSelectButtonComponent, ExtraSelectButtonItem } from '../../../../lib/components/select-button/select-button.component'; +import { ExtraSelectButtonComponent, ExtraSelectButtonOption } from '../../../../lib/components/select-button/select-button.component'; const template = `
@@ -19,10 +19,10 @@ const styles = ''; }) export class SelectButtonSelectedComponent { control = new FormControl('2'); - options: ExtraSelectButtonItem[] = [ - { label: 'Option 1', value: '1' }, - { label: 'Option 2', value: '2' }, - { label: 'Option 3', value: '3' }, + options: ExtraSelectButtonOption[] = [ + { name: 'Option 1', code: '1' }, + { name: 'Option 2', code: '2' }, + { name: 'Option 3', code: '3' }, ]; } @@ -40,7 +40,7 @@ export const Selected: StoryObj = { code: ` import { Component } from '@angular/core'; import { ReactiveFormsModule, FormControl } from '@angular/forms'; -import { ExtraSelectButtonComponent, ExtraSelectButtonItem } from '@cdek-it/angular-ui-kit'; +import { ExtraSelectButtonComponent, ExtraSelectButtonOption } from '@cdek-it/angular-ui-kit'; @Component({ selector: 'app-select-button-selected', @@ -52,10 +52,10 @@ import { ExtraSelectButtonComponent, ExtraSelectButtonItem } from '@cdek-it/angu }) export class SelectButtonSelectedComponent { control = new FormControl('2'); - options: ExtraSelectButtonItem[] = [ - { label: 'Option 1', value: '1' }, - { label: 'Option 2', value: '2' }, - { label: 'Option 3', value: '3' }, + options: ExtraSelectButtonOption[] = [ + { name: 'Option 1', code: '1' }, + { name: 'Option 2', code: '2' }, + { name: 'Option 3', code: '3' }, ]; } `, diff --git a/src/stories/components/select-button/examples/select-button-semi-disabled.component.ts b/src/stories/components/select-button/examples/select-button-semi-disabled.component.ts index d26f6865..37aba1e7 100644 --- a/src/stories/components/select-button/examples/select-button-semi-disabled.component.ts +++ b/src/stories/components/select-button/examples/select-button-semi-disabled.component.ts @@ -1,7 +1,7 @@ import { Component } from '@angular/core'; import { ReactiveFormsModule, FormControl } from '@angular/forms'; import { StoryObj } from '@storybook/angular'; -import { ExtraSelectButtonComponent, ExtraSelectButtonItem } from '../../../../lib/components/select-button/select-button.component'; +import { ExtraSelectButtonComponent, ExtraSelectButtonOption } from '../../../../lib/components/select-button/select-button.component'; const template = `
@@ -19,10 +19,10 @@ const styles = ''; }) export class SelectButtonSemiDisabledComponent { control = new FormControl('1'); - options: ExtraSelectButtonItem[] = [ - { label: 'Option 1', value: '1' }, - { label: 'Option 2', value: '2', disabled: true }, - { label: 'Option 3', value: '3' }, + options: ExtraSelectButtonOption[] = [ + { name: 'Option 1', code: '1' }, + { name: 'Option 2', code: '2', disabled: true }, + { name: 'Option 3', code: '3' }, ]; } @@ -40,7 +40,7 @@ export const SemiDisabled: StoryObj = { code: ` import { Component } from '@angular/core'; import { ReactiveFormsModule, FormControl } from '@angular/forms'; -import { ExtraSelectButtonComponent, ExtraSelectButtonItem } from '@cdek-it/angular-ui-kit'; +import { ExtraSelectButtonComponent, ExtraSelectButtonOption } from '@cdek-it/angular-ui-kit'; @Component({ selector: 'app-select-button-semi-disabled', @@ -52,10 +52,10 @@ import { ExtraSelectButtonComponent, ExtraSelectButtonItem } from '@cdek-it/angu }) export class SelectButtonSemiDisabledComponent { control = new FormControl('1'); - options: ExtraSelectButtonItem[] = [ - { label: 'Option 1', value: '1' }, - { label: 'Option 2', value: '2', disabled: true }, - { label: 'Option 3', value: '3' }, + options: ExtraSelectButtonOption[] = [ + { name: 'Option 1', code: '1' }, + { name: 'Option 2', code: '2', disabled: true }, + { name: 'Option 3', code: '3' }, ]; } `, diff --git a/src/stories/components/select-button/select-button.stories.ts b/src/stories/components/select-button/select-button.stories.ts index a16bf479..4a933d81 100644 --- a/src/stories/components/select-button/select-button.stories.ts +++ b/src/stories/components/select-button/select-button.stories.ts @@ -28,7 +28,7 @@ const meta: Meta = { component: `Группа кнопок-переключателей с поддержкой одиночного и множественного выбора. \`\`\`typescript -import { ExtraSelectButtonComponent, ExtraSelectButtonItem } from '@cdek-it/angular-ui-kit'; +import { ExtraSelectButtonComponent, ExtraSelectButtonOption } from '@cdek-it/angular-ui-kit'; \`\`\``, }, }, @@ -45,12 +45,12 @@ import { ExtraSelectButtonComponent, ExtraSelectButtonItem } from '@cdek-it/angu }, size: { control: 'radio', - options: ['base', 'small', 'large', 'xlarge'], + options: ['small', 'base', 'large', 'xlarge'], description: 'Размер компонента', table: { category: 'Props', defaultValue: { summary: 'base' }, - type: { summary: "'base' | 'small' | 'large' | 'xlarge'" }, + type: { summary: "'small' | 'base' | 'large' | 'xlarge'" }, }, }, multiple: { @@ -76,7 +76,7 @@ import { ExtraSelectButtonComponent, ExtraSelectButtonItem } from '@cdek-it/angu description: 'Массив опций', table: { category: 'Props', - type: { summary: 'ExtraSelectButtonItem[]' }, + type: { summary: 'ExtraSelectButtonOption[]' }, }, }, }, @@ -105,9 +105,9 @@ export const Default: Story = { args: { value: '1', options: [ - { label: 'Option 1', value: '1' }, - { label: 'Option 2', value: '2' }, - { label: 'Option 3', value: '3' }, + { name: 'Option 1', code: '1' }, + { name: 'Option 2', code: '2' }, + { name: 'Option 3', code: '3' }, ], size: 'base', multiple: false,