From 003a10884989dba37c59f20688fe8d353119e771 Mon Sep 17 00:00:00 2001 From: Danil Khaliulin Date: Wed, 22 Apr 2026 13:46:28 +0700 Subject: [PATCH 1/2] =?UTF-8?q?multiselect:=20=D1=81=D1=82=D0=B8=D0=BB?= =?UTF-8?q?=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../multiselect/multiselect.component.ts | 170 ++++++++++++++++ src/prime-preset/map-tokens.ts | 5 + .../tokens/components/multiselect.ts | 66 +++++++ .../examples/multiselect-chips.component.ts | 89 +++++++++ .../multiselect-disabled.component.ts | 69 +++++++ .../multiselect-float-label.component.ts | 99 ++++++++++ .../multiselect/multiselect.stories.ts | 187 ++++++++++++++++++ 7 files changed, 685 insertions(+) create mode 100644 src/lib/components/multiselect/multiselect.component.ts create mode 100644 src/prime-preset/tokens/components/multiselect.ts create mode 100644 src/stories/components/multiselect/examples/multiselect-chips.component.ts create mode 100644 src/stories/components/multiselect/examples/multiselect-disabled.component.ts create mode 100644 src/stories/components/multiselect/examples/multiselect-float-label.component.ts create mode 100644 src/stories/components/multiselect/multiselect.stories.ts diff --git a/src/lib/components/multiselect/multiselect.component.ts b/src/lib/components/multiselect/multiselect.component.ts new file mode 100644 index 00000000..9df2ef29 --- /dev/null +++ b/src/lib/components/multiselect/multiselect.component.ts @@ -0,0 +1,170 @@ +import { Component, EventEmitter, forwardRef, inject, Injector, Input, OnInit, Output, TemplateRef } from '@angular/core'; +import { NgClass, NgTemplateOutlet } from '@angular/common'; +import { ControlValueAccessor, NgControl, NG_VALUE_ACCESSOR } from '@angular/forms'; +import { FormsModule } from '@angular/forms'; +import { MultiSelect } from 'primeng/multiselect'; +import { PrimeTemplate } from 'primeng/api'; + +export type MultiSelectSize = 'small' | 'base' | 'large' | 'xlarge'; +export type MultiSelectDisplay = 'comma' | 'chip'; + +@Component({ + selector: 'multiselect-field', + standalone: true, + imports: [MultiSelect, NgClass, NgTemplateOutlet, PrimeTemplate, FormsModule], + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => MultiSelectComponent), + multi: true, + }, + ], + template: ` + + @if (optionTemplate) { + + + + } + @if (selectedItemsTemplate) { + + + + } + @if (optionGroupTemplate) { + + + + } + @if (headerTemplate) { + + + + } + @if (footerTemplate) { + + + + } + + `, +}) +export class MultiSelectComponent implements ControlValueAccessor, OnInit { + private readonly _injector = inject(Injector); + private _ngControl: NgControl | null = null; + + ngOnInit(): void { + this._ngControl = this._injector.get(NgControl, null, { self: true, optional: true }); + } + + @Input() options: any[] | null | undefined; + @Input() optionLabel: string | undefined; + @Input() optionValue: string | undefined; + @Input() optionGroupLabel: string | undefined; + @Input() optionGroupChildren = 'items'; + @Input() group = false; + @Input() placeholder = ''; + @Input() size: MultiSelectSize = 'base'; + @Input() display: MultiSelectDisplay = 'comma'; + @Input() filter = false; + @Input() showClear = false; + @Input() readonly = false; + @Input() loading = false; + @Input() inputId: string | undefined; + @Input() appendTo: any = 'body'; + @Input() maxSelectedLabels = 3; + @Input() selectedItemsLabel = 'Выбрано {0}'; + @Input() emptyMessage = 'Нет данных'; + @Input() emptyFilterMessage = 'Результаты не найдены'; + @Input() optionTemplate: TemplateRef | null = null; + @Input() selectedItemsTemplate: TemplateRef | null = null; + @Input() optionGroupTemplate: TemplateRef | null = null; + @Input() headerTemplate: TemplateRef | null = null; + @Input() footerTemplate: TemplateRef | null = null; + + disabled = false; + modelValue: any[] = []; + + @Output() onClear = new EventEmitter(); + @Output() onFilter = new EventEmitter(); + @Output() onShow = new EventEmitter(); + @Output() onHide = new EventEmitter(); + @Output() onFocus = new EventEmitter(); + @Output() onBlur = new EventEmitter(); + + get invalid(): boolean { + return !!(this._ngControl?.invalid && this._ngControl?.touched); + } + + get primeSize(): 'small' | 'large' | undefined { + if (this.size === 'small') return 'small'; + if (this.size === 'large') return 'large'; + return undefined; + } + + get multiSelectClasses(): Record { + return { + 'p-multiselect-xlg': this.size === 'xlarge', + 'p-invalid': this.invalid, + }; + } + + private _onChange: (value: any[]) => void = () => {}; + private _onTouched: () => void = () => {}; + + onMultiSelectChange(event: { value: any[] }): void { + this.modelValue = event.value; + this._onChange(event.value); + } + + handleBlur(event: Event): void { + this._onTouched(); + this.onBlur.emit(event); + } + + writeValue(value: any[]): void { + this.modelValue = value ?? []; + } + + registerOnChange(fn: (value: any[]) => void): void { + this._onChange = fn; + } + + registerOnTouched(fn: () => void): void { + this._onTouched = fn; + } + + setDisabledState(isDisabled: boolean): void { + this.disabled = isDisabled; + } +} diff --git a/src/prime-preset/map-tokens.ts b/src/prime-preset/map-tokens.ts index 51acda5a..a144a215 100644 --- a/src/prime-preset/map-tokens.ts +++ b/src/prime-preset/map-tokens.ts @@ -12,6 +12,7 @@ import { tagCss } from './tokens/components/tag'; import { tooltipCss } from './tokens/components/tooltip'; import { megamenuCss } from './tokens/components/megamenu'; import { selectCss } from './tokens/components/select'; +import { multiselectCss } from './tokens/components/multiselect'; const presetTokens: Preset = { primitive: tokens.primitive as unknown as AuraBaseDesignTokens['primitive'], @@ -54,6 +55,10 @@ const presetTokens: Preset = { ...(tokens.components.select as unknown as ComponentsDesignTokens['select']), css: selectCss, }, + multiselect: { + ...(tokens.components.multiselect as unknown as ComponentsDesignTokens['multiselect']), + css: multiselectCss, + }, } as ComponentsDesignTokens, }; diff --git a/src/prime-preset/tokens/components/multiselect.ts b/src/prime-preset/tokens/components/multiselect.ts new file mode 100644 index 00000000..a06e7230 --- /dev/null +++ b/src/prime-preset/tokens/components/multiselect.ts @@ -0,0 +1,66 @@ +export const multiselectCss = ({ dt }: { dt: (token: string) => string }): string => ` + /* ─── Базовые стили ─── */ + .p-multiselect.p-component { + width: 100%; + border-width: ${dt('multiselect.extend.borderWidth')}; + line-height: ${dt('fonts.lineHeight.250')}; + } + + /* ─── Focus ─── */ + .p-multiselect.p-component:not(.p-disabled).p-focus { + box-shadow: 0 0 0 ${dt('multiselect.root.focusRing.width')} ${dt('form.focusRing.color')}; + } + + /* ─── Invalid + Focus ─── */ + .p-multiselect.p-component.p-invalid.p-focus { + border-color: ${dt('form.invalidBorderColor')}; + box-shadow: 0 0 0 ${dt('multiselect.root.focusRing.width')} ${dt('focusRing.extend.invalid')}; + } + + /* ─── Readonly ─── */ + .p-multiselect.p-component[readonly] { + background: ${dt('multiselect.extend.readonlyBackground')}; + border-color: ${dt('form.borderColor')}; + cursor: default; + pointer-events: none; + } + + /* ─── XLarge ─── */ + .p-multiselect.p-component.p-multiselect-xlg .p-multiselect-label { + font-size: ${dt('inputtext.extend.extXlg.fontSize')}; + padding-block: ${dt('inputtext.extend.extXlg.paddingY')}; + padding-inline: ${dt('inputtext.extend.extXlg.paddingX')}; + } + + /* ─── Chips: базовые отступы ─── */ + .p-multiselect.p-component.p-multiselect-display-chip .p-multiselect-label:has(.p-chip) { + padding-block: calc(${dt('multiselect.root.paddingY')} - 7px); + padding-inline: calc(${dt('multiselect.root.paddingX')} - 7px); + } + + .p-multiselect.p-component.p-multiselect-sm.p-multiselect-display-chip .p-multiselect-label:has(.p-chip) { + padding-block: calc(${dt('multiselect.root.sm.paddingY')} - 7px); + padding-inline: calc(${dt('multiselect.root.sm.paddingX')} - 7px); + } + + .p-multiselect.p-component.p-multiselect-lg.p-multiselect-display-chip .p-multiselect-label:has(.p-chip) { + padding-block: calc(${dt('multiselect.root.lg.paddingY')} - 7px); + padding-inline: calc(${dt('multiselect.root.lg.paddingX')} - 7px); + } + + .p-multiselect.p-component.p-multiselect-xlg.p-multiselect-display-chip .p-multiselect-label:has(.p-chip) { + padding-block: calc(${dt('inputtext.extend.extXlg.paddingY')} - 7px); + padding-inline: calc(${dt('inputtext.extend.extXlg.paddingX')} - 7px); + } + + /* ─── Chip: отступ при наличии иконки удаления ─── */ + .p-multiselect .p-chip:has(.p-chip-remove-icon) { + padding-inline-end: ${dt('chip.root.paddingX')}; + } + + /* ─── FloatLabel variant="in" ─── */ + .p-floatlabel-in .p-multiselect.p-component .p-multiselect-label { + padding-block-start: ${dt('floatlabel.in.input.paddingTop')}; + padding-block-end: ${dt('floatlabel.in.input.paddingBottom')}; + } +`; diff --git a/src/stories/components/multiselect/examples/multiselect-chips.component.ts b/src/stories/components/multiselect/examples/multiselect-chips.component.ts new file mode 100644 index 00000000..6afec90e --- /dev/null +++ b/src/stories/components/multiselect/examples/multiselect-chips.component.ts @@ -0,0 +1,89 @@ +import { Component, Input } from '@angular/core'; +import { FormControl, ReactiveFormsModule } from '@angular/forms'; +import { MultiSelectComponent, MultiSelectSize } from '../../../../lib/components/multiselect/multiselect.component'; + +const OPTIONS = [ + { name: 'Новосибирск', code: 'NSK' }, + { name: 'Москва', code: 'MSK' }, + { name: 'Санкт-Петербург', code: 'SPB' }, + { name: 'Екатеринбург', code: 'EKB' }, + { name: 'Казань', code: 'KZN' }, +]; + +const template = ` + +`; +const styles = ''; + +@Component({ + selector: 'app-multiselect-chips', + standalone: true, + imports: [MultiSelectComponent, ReactiveFormsModule], + template, + styles, +}) +export class MultiSelectChipsComponent { + @Input() size: MultiSelectSize = 'base'; + @Input() showClear = false; + control = new FormControl(null); + options = OPTIONS; +} + +export const Chips = { + name: 'Chips', + render: (args: any) => ({ + props: { size: args['size'], showClear: args['showClear'] }, + template: ``, + }), + argTypes: { + display: { table: { disable: true } }, + filter: { table: { disable: true } }, + readonly: { table: { disable: true } }, + disabled: { table: { disable: true } }, + invalid: { table: { disable: true } }, + }, + parameters: { + docs: { + description: { story: 'Выбранные значения отображаются в виде чипов (`display="chip"`).' }, + source: { + language: 'ts', + code: ` +import { Component } from '@angular/core'; +import { FormControl, ReactiveFormsModule } from '@angular/forms'; +import { MultiSelectComponent } from '@cdek-it/angular-ui-kit'; + +@Component({ + standalone: true, + imports: [MultiSelectComponent, ReactiveFormsModule], + template: \` + + \`, +}) +export class MultiSelectChipsExample { + control = new FormControl(null); + options = [ + { name: 'Новосибирск', code: 'NSK' }, + { name: 'Москва', code: 'MSK' }, + { name: 'Санкт-Петербург', code: 'SPB' }, + ]; +} + `, + }, + }, + }, +}; diff --git a/src/stories/components/multiselect/examples/multiselect-disabled.component.ts b/src/stories/components/multiselect/examples/multiselect-disabled.component.ts new file mode 100644 index 00000000..0a47d46a --- /dev/null +++ b/src/stories/components/multiselect/examples/multiselect-disabled.component.ts @@ -0,0 +1,69 @@ +import { FormControl, ReactiveFormsModule } from '@angular/forms'; +import { StoryObj } from '@storybook/angular'; +import { MultiSelectComponent } from '../../../../lib/components/multiselect/multiselect.component'; + +const OPTIONS = [ + { name: 'Новосибирск', code: 'NSK' }, + { name: 'Москва', code: 'MSK' }, + { name: 'Санкт-Петербург', code: 'SPB' }, +]; + +export const Disabled: StoryObj = { + name: 'Disabled', + render: () => { + const control = new FormControl({ value: null, disabled: true }); + return { + props: { control, options: OPTIONS }, + template: ` + + `, + }; + }, + decorators: [ + (story: any) => ({ + ...story(), + moduleMetadata: { + imports: [MultiSelectComponent, ReactiveFormsModule], + }, + }), + ], + parameters: { + controls: { disable: true }, + docs: { + description: { story: 'Отключённое состояние — управляется через FormControl.' }, + source: { + language: 'ts', + code: ` +import { Component } from '@angular/core'; +import { FormControl, ReactiveFormsModule } from '@angular/forms'; +import { MultiSelectComponent } from '@cdek-it/angular-ui-kit'; + +@Component({ + standalone: true, + imports: [MultiSelectComponent, ReactiveFormsModule], + template: \` + + \`, +}) +export class MultiSelectDisabledExample { + control = new FormControl({ value: null, disabled: true }); + options = [ + { name: 'Новосибирск', code: 'NSK' }, + { name: 'Москва', code: 'MSK' }, + ]; +} + `, + }, + }, + }, +}; diff --git a/src/stories/components/multiselect/examples/multiselect-float-label.component.ts b/src/stories/components/multiselect/examples/multiselect-float-label.component.ts new file mode 100644 index 00000000..74c0ea3f --- /dev/null +++ b/src/stories/components/multiselect/examples/multiselect-float-label.component.ts @@ -0,0 +1,99 @@ +import { Component, Input } from '@angular/core'; +import { FormControl, ReactiveFormsModule } from '@angular/forms'; +import { FloatLabel } from 'primeng/floatlabel'; +import { MultiSelectComponent } from '../../../../lib/components/multiselect/multiselect.component'; + +const OPTIONS = [ + { name: 'Новосибирск', code: 'NSK' }, + { name: 'Москва', code: 'MSK' }, + { name: 'Санкт-Петербург', code: 'SPB' }, + { name: 'Екатеринбург', code: 'EKB' }, +]; + +const template = ` +
+ + + + +
+`; +const styles = ''; + +@Component({ + selector: 'app-multiselect-float-label', + standalone: true, + imports: [MultiSelectComponent, FloatLabel, ReactiveFormsModule], + template, + styles, +}) +export class MultiSelectFloatLabelComponent { + @Input() showClear = false; + control = new FormControl(null); + options = OPTIONS; +} + +export const FloatLabelStory = { + name: 'FloatLabel', + render: (args: any) => ({ + props: { showClear: args['showClear'] }, + template: ``, + }), + argTypes: { + size: { table: { disable: true } }, + display: { table: { disable: true } }, + filter: { table: { disable: true } }, + readonly: { table: { disable: true } }, + disabled: { table: { disable: true } }, + invalid: { table: { disable: true } }, + }, + parameters: { + docs: { + description: { + story: 'Интеграция с `p-floatlabel` — плавающая метка внутри поля.', + }, + source: { + language: 'ts', + code: ` +import { Component } from '@angular/core'; +import { FormControl, ReactiveFormsModule } from '@angular/forms'; +import { FloatLabel } from 'primeng/floatlabel'; +import { MultiSelectComponent } from '@cdek-it/angular-ui-kit'; + +@Component({ + standalone: true, + imports: [MultiSelectComponent, FloatLabel, ReactiveFormsModule], + template: \` +
+ + + + +
+ \`, +}) +export class MultiSelectFloatLabelExample { + control = new FormControl(null); + options = [ + { name: 'Новосибирск', code: 'NSK' }, + { name: 'Москва', code: 'MSK' }, + { name: 'Санкт-Петербург', code: 'SPB' }, + ]; +} + `, + }, + }, + }, +}; diff --git a/src/stories/components/multiselect/multiselect.stories.ts b/src/stories/components/multiselect/multiselect.stories.ts new file mode 100644 index 00000000..3e4ee7a9 --- /dev/null +++ b/src/stories/components/multiselect/multiselect.stories.ts @@ -0,0 +1,187 @@ +import { Meta, StoryObj, moduleMetadata } from '@storybook/angular'; +import { FormControl, ReactiveFormsModule, Validators } from '@angular/forms'; +import { FloatLabel as PrimeFloatLabel } from 'primeng/floatlabel'; +import { MultiSelectComponent } from '../../../lib/components/multiselect/multiselect.component'; +import { MultiSelectChipsComponent, Chips as ChipsStory } from './examples/multiselect-chips.component'; +import { Disabled as DisabledStory } from './examples/multiselect-disabled.component'; +import { MultiSelectFloatLabelComponent, FloatLabelStory } from './examples/multiselect-float-label.component'; + +const BASIC_OPTIONS = [ + { name: 'Новосибирск', code: 'NSK' }, + { name: 'Москва', code: 'MSK' }, + { name: 'Санкт-Петербург', code: 'SPB' }, + { name: 'Екатеринбург', code: 'EKB' }, + { name: 'Казань', code: 'KZN' }, +]; + +type MultiSelectArgs = Pick & { + disabled: boolean; + invalid: boolean; +}; + +const meta: Meta = { + title: 'Components/Form/MultiSelect', + component: MultiSelectComponent, + tags: ['autodocs'], + decorators: [ + moduleMetadata({ + imports: [ + MultiSelectComponent, + ReactiveFormsModule, + PrimeFloatLabel, + MultiSelectChipsComponent, + MultiSelectFloatLabelComponent, + ], + }), + ], + parameters: { + docs: { + description: { + component: `Выпадающий список для выбора нескольких значений из набора опций. Поддерживает отображение выбранных значений через запятую или в виде чипов. + +\`\`\`typescript +import { MultiSelectComponent } from '@cdek-it/angular-ui-kit'; +\`\`\``, + }, + }, + designTokens: { prefix: '--p-multiselect' }, + }, + argTypes: { + size: { + control: 'select', + options: ['small', 'base', 'large', 'xlarge'], + description: 'Размер поля', + table: { + category: 'Props', + defaultValue: { summary: "'base'" }, + type: { summary: "'small' | 'base' | 'large' | 'xlarge'" }, + }, + }, + display: { + control: 'select', + options: ['comma', 'chip'], + description: 'Способ отображения выбранных значений', + table: { + category: 'Props', + defaultValue: { summary: "'comma'" }, + type: { summary: "'comma' | 'chip'" }, + }, + }, + placeholder: { + control: 'text', + description: 'Текст подсказки при пустом поле', + table: { + category: 'Props', + defaultValue: { summary: "''" }, + type: { summary: 'string' }, + }, + }, + showClear: { + control: 'boolean', + description: 'Отображает иконку очистки выбранных значений', + table: { + category: 'Props', + defaultValue: { summary: 'false' }, + type: { summary: 'boolean' }, + }, + }, + filter: { + control: 'boolean', + description: 'Включает строку поиска в выпадающем списке', + table: { + category: 'Props', + defaultValue: { summary: 'false' }, + type: { summary: 'boolean' }, + }, + }, + readonly: { + control: 'boolean', + description: 'Режим только для чтения', + table: { + category: 'Props', + defaultValue: { summary: 'false' }, + type: { summary: 'boolean' }, + }, + }, + disabled: { + control: 'boolean', + description: 'Отключает взаимодействие — управляется через FormControl', + table: { + category: 'Props', + defaultValue: { summary: 'false' }, + type: { summary: 'boolean' }, + }, + }, + invalid: { + control: 'boolean', + description: 'Невалидное состояние — управляется через FormControl', + table: { + category: 'Props', + defaultValue: { summary: 'false' }, + type: { summary: 'boolean' }, + }, + }, + }, + args: { + size: 'base', + display: 'comma', + placeholder: 'Выберите города...', + showClear: true, + filter: false, + readonly: false, + disabled: false, + invalid: false, + }, +}; + +export default meta; +type Story = StoryObj; + +// ── Default ─────────────────────────────────────────────────────────────────── + +export const Default: Story = { + name: 'Default', + render: (args) => { + const control = new FormControl( + { value: null, disabled: !!args['disabled'] }, + args['invalid'] ? [Validators.required] : [] + ); + if (args['invalid']) control.markAsTouched(); + + return { + props: { ...args, control, options: BASIC_OPTIONS }, + template: ` + + `, + }; + }, + parameters: { + docs: { + description: { + story: 'Базовый пример компонента. Используйте Controls для интерактивного изменения пропсов.', + }, + }, + }, +}; + +// ── Chips ───────────────────────────────────────────────────────────────────── + +export const Chips: Story = ChipsStory; + +// ── Disabled ────────────────────────────────────────────────────────────────── + +export const Disabled: Story = DisabledStory; + +// ── FloatLabel ──────────────────────────────────────────────────────────────── + +export const FloatLabel: Story = FloatLabelStory; From 4db58b2ef095eb7970851ee608c5727122f89b98 Mon Sep 17 00:00:00 2001 From: Danil Khaliulin Date: Wed, 22 Apr 2026 14:25:33 +0700 Subject: [PATCH 2/2] =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BF=D1=80=D0=BE=D0=BF=D1=81=D0=BE=D0=B2?= =?UTF-8?q?=20=D0=B4=D0=BB=D1=8F=20=D0=BE=D1=82=D0=BE=D0=B1=D1=80=D0=B0?= =?UTF-8?q?=D0=B6=D0=B5=D0=BD=D0=B8=D1=8F=20filters?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/multiselect/multiselect.component.ts | 7 +++++++ src/prime-preset/tokens/tokens.json | 10 ++++------ .../examples/multiselect-chips.component.ts | 7 ++++--- .../examples/multiselect-float-label.component.ts | 7 ++++--- .../components/multiselect/multiselect.stories.ts | 2 +- 5 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/lib/components/multiselect/multiselect.component.ts b/src/lib/components/multiselect/multiselect.component.ts index 9df2ef29..73153604 100644 --- a/src/lib/components/multiselect/multiselect.component.ts +++ b/src/lib/components/multiselect/multiselect.component.ts @@ -43,6 +43,7 @@ export type MultiSelectDisplay = 'comma' | 'chip'; [emptyMessage]="emptyMessage" [emptyFilterMessage]="emptyFilterMessage" [size]="primeSize" + [pt]="filterPt" (onChange)="onMultiSelectChange($event)" (onClear)="onClear.emit($event)" (onFilter)="onFilter.emit($event)" @@ -122,6 +123,12 @@ export class MultiSelectComponent implements ControlValueAccessor, OnInit { @Output() onFocus = new EventEmitter(); @Output() onBlur = new EventEmitter(); + readonly filterPt = { + pcFilterContainer: { root: { class: 'p-iconfield p-multiselect-filter-container' } }, + pcFilter: { root: { class: 'p-inputtext-sm' } }, + pcFilterIconContainer: { root: { class: 'p-inputicon' } }, + }; + get invalid(): boolean { return !!(this._ngControl?.invalid && this._ngControl?.touched); } diff --git a/src/prime-preset/tokens/tokens.json b/src/prime-preset/tokens/tokens.json index 14eeb718..eb827836 100644 --- a/src/prime-preset/tokens/tokens.json +++ b/src/prime-preset/tokens/tokens.json @@ -570,8 +570,6 @@ "paddingY": "{spacing.3x}" }, "fontSize": "{fonts.fontSize.300}", - "paddingX": "{spacing.4x}", - "paddingY": "{spacing.4x}", "lg": { "width": "{sizing.76x}", "fontSize": "{fonts.fontSize.300}", @@ -3811,8 +3809,8 @@ }, "root": { "shadow": "0", - "paddingX": "{form.paddingX}", - "paddingY": "{form.paddingY}", + "paddingX": "{form.padding.300}", + "paddingY": "{form.padding.300}", "borderRadius": "{form.borderRadius.200}", "transitionDuration": "{form.transitionDuration}", "sm": { @@ -4729,8 +4727,8 @@ "placeholderColor": "{form.placeholderColor}", "invalidPlaceholderColor": "{form.invalidPlaceholderColor}", "shadow": "0", - "paddingX": "{form.paddingX}", - "paddingY": "{form.paddingY}", + "paddingX": "{form.padding.300}", + "paddingY": "{form.padding.300}", "borderRadius": "{form.borderRadius.200}", "transitionDuration": "{form.transitionDuration}", "focusRing": { diff --git a/src/stories/components/multiselect/examples/multiselect-chips.component.ts b/src/stories/components/multiselect/examples/multiselect-chips.component.ts index 6afec90e..02b69204 100644 --- a/src/stories/components/multiselect/examples/multiselect-chips.component.ts +++ b/src/stories/components/multiselect/examples/multiselect-chips.component.ts @@ -19,6 +19,7 @@ const template = ` display="chip" [showClear]="showClear" [size]="size" + [filter]="filter" > `; const styles = ''; @@ -33,6 +34,7 @@ const styles = ''; export class MultiSelectChipsComponent { @Input() size: MultiSelectSize = 'base'; @Input() showClear = false; + @Input() filter = true; control = new FormControl(null); options = OPTIONS; } @@ -40,12 +42,11 @@ export class MultiSelectChipsComponent { export const Chips = { name: 'Chips', render: (args: any) => ({ - props: { size: args['size'], showClear: args['showClear'] }, - template: ``, + props: { size: args['size'], showClear: args['showClear'], filter: args['filter'] }, + template: ``, }), argTypes: { display: { table: { disable: true } }, - filter: { table: { disable: true } }, readonly: { table: { disable: true } }, disabled: { table: { disable: true } }, invalid: { table: { disable: true } }, diff --git a/src/stories/components/multiselect/examples/multiselect-float-label.component.ts b/src/stories/components/multiselect/examples/multiselect-float-label.component.ts index 74c0ea3f..c5781794 100644 --- a/src/stories/components/multiselect/examples/multiselect-float-label.component.ts +++ b/src/stories/components/multiselect/examples/multiselect-float-label.component.ts @@ -19,6 +19,7 @@ const template = ` [options]="options" optionLabel="name" [showClear]="showClear" + [filter]="filter" > @@ -35,6 +36,7 @@ const styles = ''; }) export class MultiSelectFloatLabelComponent { @Input() showClear = false; + @Input() filter = true; control = new FormControl(null); options = OPTIONS; } @@ -42,13 +44,12 @@ export class MultiSelectFloatLabelComponent { export const FloatLabelStory = { name: 'FloatLabel', render: (args: any) => ({ - props: { showClear: args['showClear'] }, - template: ``, + props: { showClear: args['showClear'], filter: args['filter'] }, + template: ``, }), argTypes: { size: { table: { disable: true } }, display: { table: { disable: true } }, - filter: { table: { disable: true } }, readonly: { table: { disable: true } }, disabled: { table: { disable: true } }, invalid: { table: { disable: true } }, diff --git a/src/stories/components/multiselect/multiselect.stories.ts b/src/stories/components/multiselect/multiselect.stories.ts index 3e4ee7a9..349afae7 100644 --- a/src/stories/components/multiselect/multiselect.stories.ts +++ b/src/stories/components/multiselect/multiselect.stories.ts @@ -127,7 +127,7 @@ import { MultiSelectComponent } from '@cdek-it/angular-ui-kit'; display: 'comma', placeholder: 'Выберите города...', showClear: true, - filter: false, + filter: true, readonly: false, disabled: false, invalid: false,