diff --git a/src/assets/styles/common-inputs.scss b/src/assets/styles/common-inputs.scss index 2fa3a42..7fff6a7 100644 --- a/src/assets/styles/common-inputs.scss +++ b/src/assets/styles/common-inputs.scss @@ -165,7 +165,7 @@ form .iqser-input-group:not(first-of-type) { } } - label:not(.mat-slide-toggle-label):not(.mat-radio-label) { + label:not(.mat-slide-toggle-label):not(.mat-radio-label):not(.details-radio-label) { opacity: 0.7; font-size: 11px; letter-spacing: 0; diff --git a/src/lib/inputs/details-radio/details-radio-option.ts b/src/lib/inputs/details-radio/details-radio-option.ts new file mode 100644 index 0000000..15162b3 --- /dev/null +++ b/src/lib/inputs/details-radio/details-radio-option.ts @@ -0,0 +1,5 @@ +export interface DetailsRadioOption { + label: string; + description: string; + value: I; +} diff --git a/src/lib/inputs/details-radio/details-radio.component.html b/src/lib/inputs/details-radio/details-radio.component.html new file mode 100644 index 0000000..4f69ffb --- /dev/null +++ b/src/lib/inputs/details-radio/details-radio.component.html @@ -0,0 +1,14 @@ +
+
+
+ + +
+ {{ option.description | translate }} +
+
diff --git a/src/lib/inputs/details-radio/details-radio.component.scss b/src/lib/inputs/details-radio/details-radio.component.scss new file mode 100644 index 0000000..181151c --- /dev/null +++ b/src/lib/inputs/details-radio/details-radio.component.scss @@ -0,0 +1,13 @@ +label { + font-weight: 600; +} + +.option { + padding: 16px; + border-radius: 8px; + background-color: var(--iqser-grey-2); + + &.active { + background-color: rgba(var(--iqser-primary-rgb), 0.1); + } +} diff --git a/src/lib/inputs/details-radio/details-radio.component.ts b/src/lib/inputs/details-radio/details-radio.component.ts new file mode 100644 index 0000000..f4c2a58 --- /dev/null +++ b/src/lib/inputs/details-radio/details-radio.component.ts @@ -0,0 +1,33 @@ +import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; +import { DetailsRadioOption } from './details-radio-option'; +import { NG_VALIDATORS, NG_VALUE_ACCESSOR } from '@angular/forms'; +import { FormFieldComponent } from '../form-field/form-field-component.directive'; + +@Component({ + selector: 'iqser-details-radio [options]', + templateUrl: './details-radio.component.html', + styleUrls: ['./details-radio.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, + providers: [ + { + provide: NG_VALUE_ACCESSOR, + multi: true, + useExisting: DetailsRadioComponent, + }, + { + provide: NG_VALIDATORS, + multi: true, + useExisting: DetailsRadioComponent, + }, + ], +}) +export class DetailsRadioComponent extends FormFieldComponent> { + @Input() options: DetailsRadioOption[] = []; + + toggleOption(option: DetailsRadioOption): void { + this.markAsTouched(); + const currentlyChecked = this.value?.value === option.value; + this._value = currentlyChecked ? undefined : option; + this.onChange(this._value); + } +} diff --git a/src/lib/inputs/form-field/form-field-component.directive.ts b/src/lib/inputs/form-field/form-field-component.directive.ts new file mode 100644 index 0000000..0574ac8 --- /dev/null +++ b/src/lib/inputs/form-field/form-field-component.directive.ts @@ -0,0 +1,45 @@ +import { Directive } from '@angular/core'; +import { ControlValueAccessor, ValidationErrors, Validator } from '@angular/forms'; + +@Directive() +export abstract class FormFieldComponent implements ControlValueAccessor, Validator { + touched = false; + disabled = false; + + protected _value: I | undefined; + + get value(): I | undefined { + return this._value; + } + + onChange = (value?: I) => {}; + + onTouched = () => {}; + + markAsTouched() { + if (!this.touched) { + this.onTouched(); + this.touched = true; + } + } + + setDisabledState(disabled: boolean) { + this.disabled = disabled; + } + + registerOnChange(onChange: (value?: I) => void): void { + this.onChange = onChange; + } + + registerOnTouched(onTouched: () => void): void { + this.onTouched = onTouched; + } + + writeValue(option: I): void { + this._value = option; + } + + validate(): ValidationErrors | null { + return null; + } +} diff --git a/src/lib/inputs/index.ts b/src/lib/inputs/index.ts index 490b7a1..4aca8bf 100644 --- a/src/lib/inputs/index.ts +++ b/src/lib/inputs/index.ts @@ -2,3 +2,5 @@ export * from './inputs.module'; export * from './round-checkbox/round-checkbox.component'; export * from './editable-input/editable-input.component'; export * from './input-with-action/input-with-action.component'; +export * from './details-radio/details-radio.component'; +export * from './details-radio/details-radio-option'; diff --git a/src/lib/inputs/inputs.module.ts b/src/lib/inputs/inputs.module.ts index fa1308c..9cd024d 100644 --- a/src/lib/inputs/inputs.module.ts +++ b/src/lib/inputs/inputs.module.ts @@ -6,13 +6,15 @@ import { RoundCheckboxComponent } from './round-checkbox/round-checkbox.componen import { EditableInputComponent } from './editable-input/editable-input.component'; import { InputWithActionComponent } from './input-with-action/input-with-action.component'; import { IqserIconsModule } from '../icons'; +import { DetailsRadioComponent } from './details-radio/details-radio.component'; +import { TranslateModule } from '@ngx-translate/core'; const modules = [IqserButtonsModule, FormsModule]; -const components = [RoundCheckboxComponent, EditableInputComponent, InputWithActionComponent]; +const components = [RoundCheckboxComponent, EditableInputComponent, InputWithActionComponent, DetailsRadioComponent]; @NgModule({ declarations: [...components], exports: [...components], - imports: [CommonModule, IqserIconsModule, ...modules], + imports: [CommonModule, IqserIconsModule, TranslateModule, ...modules], }) export class IqserInputsModule {}