import {AfterViewChecked, ChangeDetectorRef, Component, ElementRef, Input} from '@angular/core'; import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms'; import {AbstractComponent} from 'gp-admin-abstract'; @Component({ selector: 'gp-radio-button', template: `
`, styles: [ `@charset "UTF-8"; /** * Переменные */ :root { --color-white: white; --color-success: #00afec; --color-warning: #ffb827; --color-error: #f35252; --color-disabled: #dbdbdb; --color-black: black; --color-span: #b5b5b5; --color-span-second: #212121; --color-bg: #f8f8f8; --color-bg-second: #f8f8f8; --color-bg-success: rgba(0, 175, 236, 0.1); --color-bg-warning: var(--color-warning); --color-bg-error: var(--color-error); --color-placeholder: #b5b5b5; --color-border: #dbdbdb; --color-radio-border: #d3d3d3; --font-roboto: 'Roboto', sans-serif; --font-helvetica: 'Helvetica', sans-serif; } /** * */ /** * Стили для компонента "gp-radio-button" */ .gp-radio-button__radio { position: relative; display: block; width: 2rem; height: 2rem; -moz-transition: all 300ms ease; -o-transition: all 300ms ease; -webkit-transition: all 300ms ease; transition: all 300ms ease; border: 0.1rem solid #d3d3d3; border-radius: 50%; background-color: var(--color-white); } .gp-radio-button__input:checked + .gp-radio-button__radio { border-color: #00afec; background-color: #00afec; } .gp-radio-button__input:checked + span + .gp-radio-button__description { color: #212121; } .gp-radio-button__input--error + .gp-radio-button__radio { border-color: #f35252; background-color: var(--color-white); } .gp-radio-button__input--error + span + .gp-radio-button__description { color: #f35252; } .gp-radio-button__input--disabled + .gp-radio-button__radio { cursor: not-allowed; border-color: #b5b5b5; } .gp-radio-button__input--disabled + .gp-radio-button__radio:before { background-color: #b5b5b5; } .gp-radio-button__input--disabled + span + .gp-radio-button__description { cursor: not-allowed; color: #b5b5b5; } .gp-radio-button__radio:before { position: absolute; width: 0.6rem; height: 0.6rem; margin: 0.6rem; content: ''; -moz-transition: background-color 300ms ease; -o-transition: background-color 300ms ease; -webkit-transition: background-color 300ms ease; transition: background-color 300ms ease; border-radius: 50%; background-color: var(--color-white); } .gp-radio-button__description { font: 1.4rem/1.6rem "Roboto", sans-serif; -moz-transition: color 300ms ease; -o-transition: color 300ms ease; -webkit-transition: color 300ms ease; transition: color 300ms ease; color: #212121; } `], providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: RadioButtonComponent, multi: true } ] }) export class RadioButtonComponent extends AbstractComponent implements AfterViewChecked, ControlValueAccessor { /** * Уникальное имя * * @type {string} */ @Input() name: string; /** * Текст ошибки * * @type {string | boolean} */ @Input() error: string | boolean = false; /** * Дисаблед * * @type {boolean} */ @Input() disabled: boolean = false; /** * Значение по умолчанию */ @Input() value: string | number | any; public options: any[] = []; constructor(protected el: ElementRef, private changeDetector: ChangeDetectorRef) { super(el); } ngAfterViewChecked() { const opts = this.getElementRef().nativeElement.querySelectorAll('option'); if (opts.length > 0) { let needChanges = false; for (const option of opts) { const exists = this.options.find(f => f.value === option.value); if (!exists) { this.options.push({value: option.value, text: option.text, selected: this.value === option.value}); if (option.selected) { this.propagateChange(option.value); } needChanges = true; } } if (needChanges) { this.changeDetector.detectChanges(); } } } writeValue(obj: string | number | any): void { this.options.forEach((item, index) => { this.options[index].selected = obj === item.value; }); } registerOnChange(fn: any): void { this.propagateChange = fn; } registerOnTouched(fn: any): void { } propagateChange = (_: any) => { } setDisabledState(isDisabled: boolean): void { this.disabled = isDisabled; } onChange(e: any, event: any) { if (!event.currentTarget.checked) { event.currentTarget.checked = true; } else { this.options.forEach((item, index) => { this.options[index].selected = e === item.value; }); } this.propagateChange(e); } }