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
67 changes: 67 additions & 0 deletions src/lib/components/toggleswitch/toggleswitch.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { Component, EventEmitter, Optional, Output, Self } from '@angular/core';
import { ControlValueAccessor, FormsModule, NgControl } from '@angular/forms';
import { ToggleSwitch } from 'primeng/toggleswitch';

@Component({
selector: 'toggleswitch',
standalone: true,
imports: [ToggleSwitch, FormsModule],
template: `
<p-toggleswitch
[ngModel]="modelValue"
(ngModelChange)="handleChange($event)"
[invalid]="isInvalid"
[disabled]="isDisabled"
(onChange)="onChange.emit($event)"
(onFocus)="onFocus.emit($event)"
(onBlur)="onBlur.emit($event)"
></p-toggleswitch>
`,
})
export class ToggleSwitchComponent implements ControlValueAccessor {
@Output() onChange = new EventEmitter<any>();
@Output() onFocus = new EventEmitter<FocusEvent>();
@Output() onBlur = new EventEmitter<FocusEvent>();

modelValue = false;
private _disabled = false;

private _onChange: (value: boolean) => void = () => {};
private _onTouched: () => void = () => {};

constructor(@Optional() @Self() private ngControl: NgControl) {
if (ngControl) {
ngControl.valueAccessor = this;
}
}

get isDisabled(): boolean {
return this._disabled;
}

get isInvalid(): boolean {
return !!this.ngControl?.invalid;
}

handleChange(value: boolean): void {
this.modelValue = value;
this._onChange(value);
this._onTouched();
}

writeValue(value: boolean): void {
this.modelValue = value ?? false;
}

registerOnChange(fn: (value: boolean) => void): void {
this._onChange = fn;
}

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

setDisabledState(isDisabled: boolean): void {
this._disabled = isDisabled;
}
}
11 changes: 11 additions & 0 deletions src/prime-preset/tokens/components/toggleswitch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export const toggleswitchCss = ({ dt }: { dt: (token: string) => string }): string => `
/* Focus ring для валидных состояний */
.p-toggleswitch:not(.p-disabled):not(.p-invalid):has(.p-toggleswitch-input:focus-visible) .p-toggleswitch-slider {
box-shadow: 0 0 0 ${dt('toggleswitch.root.focusRing.width')} ${dt('focusRing.extend.success')};
}
/* Focus ring для состояния ошибки */
.p-toggleswitch.p-invalid:not(.p-disabled):has(.p-toggleswitch-input:focus-visible) .p-toggleswitch-slider {
box-shadow: 0 0 0 ${dt('focusRing.width')} ${dt('focusRing.extend.invalid')};
}
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { Component } from '@angular/core';
import { FormControl, ReactiveFormsModule } from '@angular/forms';
import { StoryObj } from '@storybook/angular';
import { ToggleSwitchComponent } from '../../../../lib/components/toggleswitch/toggleswitch.component';

@Component({
selector: 'app-toggleswitch-checked',
standalone: true,
imports: [ToggleSwitchComponent, ReactiveFormsModule],
template: `
<toggleswitch [formControl]="control"></toggleswitch>
`,
})
export class ToggleSwitchCheckedComponent {
control = new FormControl(true);
}

export const Checked: StoryObj = {
render: () => ({
template: `<app-toggleswitch-checked></app-toggleswitch-checked>`,
}),
parameters: {
docs: {
description: { story: 'Переключатель во включённом состоянии.' },
source: {
language: 'ts',
code: `
import { Component } from '@angular/core';
import { FormControl, ReactiveFormsModule } from '@angular/forms';
import { ToggleSwitchComponent } from '@cdek-it/angular-ui-kit';

@Component({
selector: 'app-toggleswitch-checked',
standalone: true,
imports: [ToggleSwitchComponent, ReactiveFormsModule],
template: \`
<toggleswitch [formControl]="control"></toggleswitch>
\`,
})
export class ToggleSwitchCheckedComponent {
control = new FormControl(true);
}
`,
},
},
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { Component } from '@angular/core';
import { FormControl, ReactiveFormsModule } from '@angular/forms';
import { StoryObj } from '@storybook/angular';
import { ToggleSwitchComponent } from '../../../../lib/components/toggleswitch/toggleswitch.component';

@Component({
selector: 'app-toggleswitch-disabled',
standalone: true,
imports: [ToggleSwitchComponent, ReactiveFormsModule],
template: `
<toggleswitch [formControl]="control"></toggleswitch>
`,
})
export class ToggleSwitchDisabledComponent {
control = new FormControl({ value: false, disabled: true });
}

export const Disabled: StoryObj = {
render: () => ({
template: `<app-toggleswitch-disabled></app-toggleswitch-disabled>`,
}),
parameters: {
docs: {
description: { story: 'Заблокированное состояние переключателя через FormControl.' },
source: {
language: 'ts',
code: `
import { Component } from '@angular/core';
import { FormControl, ReactiveFormsModule } from '@angular/forms';
import { ToggleSwitchComponent } from '@cdek-it/angular-ui-kit';

@Component({
selector: 'app-toggleswitch-disabled',
standalone: true,
imports: [ToggleSwitchComponent, ReactiveFormsModule],
template: \`
<toggleswitch [formControl]="control"></toggleswitch>
\`,
})
export class ToggleSwitchDisabledComponent {
control = new FormControl({ value: false, disabled: true });
}
`,
},
},
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { Component } from '@angular/core';
import { FormControl, ReactiveFormsModule, Validators } from '@angular/forms';
import { StoryObj } from '@storybook/angular';
import { ToggleSwitchComponent } from '../../../../lib/components/toggleswitch/toggleswitch.component';

@Component({
selector: 'app-toggleswitch-invalid',
standalone: true,
imports: [ToggleSwitchComponent, ReactiveFormsModule],
template: `
<toggleswitch [formControl]="control"></toggleswitch>
`,
})
export class ToggleSwitchInvalidComponent {
// Validators.requiredTrue требует значение true, поэтому false делает контрол невалидным
control = new FormControl(false, [Validators.requiredTrue]);
}

export const Invalid: StoryObj = {
render: () => ({
template: `<app-toggleswitch-invalid></app-toggleswitch-invalid>`,
}),
parameters: {
docs: {
description: { story: 'Невалидное состояние переключателя через FormControl и Validators.' },
source: {
language: 'ts',
code: `
import { Component } from '@angular/core';
import { FormControl, ReactiveFormsModule, Validators } from '@angular/forms';
import { ToggleSwitchComponent } from '@cdek-it/angular-ui-kit';

@Component({
selector: 'app-toggleswitch-invalid',
standalone: true,
imports: [ToggleSwitchComponent, ReactiveFormsModule],
template: \`
<toggleswitch [formControl]="control"></toggleswitch>
\`,
})
export class ToggleSwitchInvalidComponent {
control = new FormControl(false, [Validators.requiredTrue]);
}
`,
},
},
},
};
Loading
Loading