Detailed radio options form field
This commit is contained in:
parent
463e329163
commit
4aad2e33ad
@ -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;
|
opacity: 0.7;
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
letter-spacing: 0;
|
letter-spacing: 0;
|
||||||
|
|||||||
5
src/lib/inputs/details-radio/details-radio-option.ts
Normal file
5
src/lib/inputs/details-radio/details-radio-option.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export interface DetailsRadioOption<I> {
|
||||||
|
label: string;
|
||||||
|
description: string;
|
||||||
|
value: I;
|
||||||
|
}
|
||||||
14
src/lib/inputs/details-radio/details-radio.component.html
Normal file
14
src/lib/inputs/details-radio/details-radio.component.html
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<div class="iqser-input-group">
|
||||||
|
<div
|
||||||
|
(click)="toggleOption(option)"
|
||||||
|
*ngFor="let option of options"
|
||||||
|
[class.active]="option.value === value?.value"
|
||||||
|
class="option mb-8 pointer"
|
||||||
|
>
|
||||||
|
<div class="flex-align-items-center mb-8">
|
||||||
|
<iqser-round-checkbox [active]="option.value === value?.value" class="mr-6"></iqser-round-checkbox>
|
||||||
|
<label class="details-radio-label pointer">{{ option.label | translate }}</label>
|
||||||
|
</div>
|
||||||
|
<span class="hint">{{ option.description | translate }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
13
src/lib/inputs/details-radio/details-radio.component.scss
Normal file
13
src/lib/inputs/details-radio/details-radio.component.scss
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
33
src/lib/inputs/details-radio/details-radio.component.ts
Normal file
33
src/lib/inputs/details-radio/details-radio.component.ts
Normal file
@ -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<I> extends FormFieldComponent<DetailsRadioOption<I>> {
|
||||||
|
@Input() options: DetailsRadioOption<I>[] = [];
|
||||||
|
|
||||||
|
toggleOption(option: DetailsRadioOption<I>): void {
|
||||||
|
this.markAsTouched();
|
||||||
|
const currentlyChecked = this.value?.value === option.value;
|
||||||
|
this._value = currentlyChecked ? undefined : option;
|
||||||
|
this.onChange(this._value);
|
||||||
|
}
|
||||||
|
}
|
||||||
45
src/lib/inputs/form-field/form-field-component.directive.ts
Normal file
45
src/lib/inputs/form-field/form-field-component.directive.ts
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import { Directive } from '@angular/core';
|
||||||
|
import { ControlValueAccessor, ValidationErrors, Validator } from '@angular/forms';
|
||||||
|
|
||||||
|
@Directive()
|
||||||
|
export abstract class FormFieldComponent<I> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,3 +2,5 @@ export * from './inputs.module';
|
|||||||
export * from './round-checkbox/round-checkbox.component';
|
export * from './round-checkbox/round-checkbox.component';
|
||||||
export * from './editable-input/editable-input.component';
|
export * from './editable-input/editable-input.component';
|
||||||
export * from './input-with-action/input-with-action.component';
|
export * from './input-with-action/input-with-action.component';
|
||||||
|
export * from './details-radio/details-radio.component';
|
||||||
|
export * from './details-radio/details-radio-option';
|
||||||
|
|||||||
@ -6,13 +6,15 @@ import { RoundCheckboxComponent } from './round-checkbox/round-checkbox.componen
|
|||||||
import { EditableInputComponent } from './editable-input/editable-input.component';
|
import { EditableInputComponent } from './editable-input/editable-input.component';
|
||||||
import { InputWithActionComponent } from './input-with-action/input-with-action.component';
|
import { InputWithActionComponent } from './input-with-action/input-with-action.component';
|
||||||
import { IqserIconsModule } from '../icons';
|
import { IqserIconsModule } from '../icons';
|
||||||
|
import { DetailsRadioComponent } from './details-radio/details-radio.component';
|
||||||
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
|
||||||
const modules = [IqserButtonsModule, FormsModule];
|
const modules = [IqserButtonsModule, FormsModule];
|
||||||
const components = [RoundCheckboxComponent, EditableInputComponent, InputWithActionComponent];
|
const components = [RoundCheckboxComponent, EditableInputComponent, InputWithActionComponent, DetailsRadioComponent];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [...components],
|
declarations: [...components],
|
||||||
exports: [...components],
|
exports: [...components],
|
||||||
imports: [CommonModule, IqserIconsModule, ...modules],
|
imports: [CommonModule, IqserIconsModule, TranslateModule, ...modules],
|
||||||
})
|
})
|
||||||
export class IqserInputsModule {}
|
export class IqserInputsModule {}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user