Browse Source

UI: Refactoring color picker

pull/8364/head
Artem Dzhereleiko 4 years ago
parent
commit
64264a7834
  1. 30
      ui-ngx/src/app/shared/components/color-picker/color-picker.component.html
  2. 52
      ui-ngx/src/app/shared/components/color-picker/color-picker.component.scss
  3. 109
      ui-ngx/src/app/shared/components/color-picker/color-picker.component.ts
  4. 6
      ui-ngx/src/app/shared/components/dialog/color-picker-dialog.component.html
  5. 8
      ui-ngx/src/app/shared/components/dialog/color-picker-dialog.component.ts

30
ui-ngx/src/app/shared/components/color-picker/color-picker.component.html

@ -17,29 +17,21 @@
--> -->
<saturation-component class="saturation-component" [hue]="control.hue" [(color)]="control.value"></saturation-component> <saturation-component class="saturation-component" [hue]="control.hue" [(color)]="control.value"></saturation-component>
<div class="controls"> <div fxFlex fxLayout="row" class="control-component" fxLayoutGap="16px">
<div class="controls-row hue-alpha"> <indicator-component [colorType]="presentations[selectedPresentation]" [color]="control.value"></indicator-component>
<div class="column"> <div fxFlex fxLayout="column" fxLayoutAlign="space-between" class="hue-alpha-range">
<indicator-component [colorType]="presentations[selectedPresentation]" [color]="control.value"></indicator-component>
</div>
<div class="column" class="hue-alpha-range">
<hue-component [(hue)]="control.hue" [(color)]="control.value"></hue-component> <hue-component [(hue)]="control.hue" [(color)]="control.value"></hue-component>
<alpha-component *ngIf="control.alphaChannelVisibilityChanges | async" [(color)]="control.value"></alpha-component> <alpha-component *ngIf="control.alphaChannelVisibilityChanges | async" [(color)]="control.value"></alpha-component>
</div> </div>
</div> </div>
<div fxLayoutAlign="row"> <div fxFlex fxLayout="row">
<div class="controls-row presentation"> <div fxFlex [ngSwitch]="presentations[selectedPresentation]">
<div class="column" [ngSwitch]="presentations[selectedPresentation]"> <rgba-input-component *ngSwitchCase="'rgba'" [alpha]="control.alphaChannelVisibilityChanges | async" label [(color)]="control.value" [(hue)]="control.hue"></rgba-input-component>
<rgba-input-component *ngSwitchCase="'rgba'" [alpha]="control.alphaChannelVisibilityChanges | async" label [(color)]="control.value" [(hue)]="control.hue"></rgba-input-component> <hsla-input-component *ngSwitchCase="'hsla'" [alpha]="control.alphaChannelVisibilityChanges | async" label [(color)]="control.value" [(hue)]="control.hue"></hsla-input-component>
<rgba-input-component *ngSwitchCase="'rgb'" [alpha]="false" label [(color)]="control.value" [(hue)]="control.hue"></rgba-input-component> <hex-input-component *ngSwitchCase="'hex'" label prefix="#" [(color)]="control.value" [(hue)]="control.hue"></hex-input-component>
<hsla-input-component *ngSwitchCase="'hsla'" [alpha]="control.alphaChannelVisibilityChanges | async" label [(color)]="control.value" [(hue)]="control.hue"></hsla-input-component> </div>
<hsla-input-component *ngSwitchCase="'hsl'" [alpha]="false" label [(color)]="control.value" [(hue)]="control.hue"></hsla-input-component> <div>
<hex-input-component *ngSwitchCase="'hex'" label prefix="#" [(color)]="control.value" [(hue)]="control.hue"></hex-input-component> <span class="type-btn" (click)="changePresentation()"></span>
</div>
<div class="column type-column">
<span class="type-btn" (click)="changePresentation()"></span>
</div>
</div> </div>
</div> </div>
</div>

52
ui-ngx/src/app/shared/components/color-picker/color-picker.component.scss

@ -14,17 +14,17 @@
* limitations under the License. * limitations under the License.
*/ */
:host { :host {
display: block;
width: 100%; width: 100%;
max-width: 320px; display: flex;
min-width: 100%; flex-direction: column;
border-radius: 2px;
background: #fff;
::ng-deep { ::ng-deep {
.saturation-component { .saturation-component {
height: 200px; height: 100%;
min-height: 200px;
max-height: 300px;
border-radius: 8px; border-radius: 8px;
margin-bottom: 16px;
div.pointer { div.pointer {
border-width: 2px; border-width: 2px;
width: 16px; width: 16px;
@ -56,25 +56,9 @@
} }
} }
.control-component {
max-height: 48px;
.controls { margin-bottom: 16px;
padding: 15px 0;
}
.controls-row {
display: table;
width: 100%;
}
.column {
display: table-cell;
vertical-align: middle;
}
.hue-alpha .column:first-child {
width: 42px;
padding: 0 10px 0 0;
} }
indicator-component { indicator-component {
@ -90,17 +74,8 @@ indicator-component {
} }
} }
hue-component {
margin-bottom: 16px;
}
color-presets-component { color-presets-component {
border-top: 1px solid #d0d0d0; border-top: 1px solid #d0d0d0;
padding: 12px;
::ng-deep .presets-row {
padding: 12px 0 0;
}
} }
.type-btn { .type-btn {
@ -114,12 +89,3 @@ color-presets-component {
background-color: #eee; background-color: #eee;
} }
} }
.type-column {
width: 25px;
text-align: right;
}
.presentation {
padding: 12px 0 0;
}

109
ui-ngx/src/app/shared/components/color-picker/color-picker.component.ts

@ -14,20 +14,10 @@
/// limitations under the License. /// limitations under the License.
/// ///
import { import { Component, forwardRef, OnDestroy, OnInit } from '@angular/core';
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
EventEmitter,
Input,
OnChanges,
OnDestroy,
OnInit,
Output,
SimpleChanges
} from '@angular/core';
import { Color, ColorPickerControl } from '@iplab/ngx-color-picker'; import { Color, ColorPickerControl } from '@iplab/ngx-color-picker';
import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
export enum ColorType { export enum ColorType {
hex = 'hex', hex = 'hex',
@ -43,89 +33,90 @@ export enum ColorType {
selector: `tb-color-picker`, selector: `tb-color-picker`,
templateUrl: `./color-picker.component.html`, templateUrl: `./color-picker.component.html`,
styleUrls: [`./color-picker.component.scss`], styleUrls: [`./color-picker.component.scss`],
changeDetection: ChangeDetectionStrategy.OnPush providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => ColorPickerComponent),
multi: true
}
]
}) })
export class ColorPickerComponent implements OnInit, OnChanges, OnDestroy { export class ColorPickerComponent implements OnInit, ControlValueAccessor, OnDestroy {
public selectedPresentation = 0;
public presentations = [ColorType.hex, ColorType.rgb, ColorType.rgba, ColorType.hsla, ColorType.hsl];
@Input() selectedPresentation = 0;
public color: string; presentations = [ColorType.hex, ColorType.rgba, ColorType.hsla];
control = new ColorPickerControl();
@Input() private modelValue: string;
public control: ColorPickerControl;
@Output()
public colorChange: EventEmitter<string> = new EventEmitter(false);
private subscriptions: Array<Subscription> = []; private subscriptions: Array<Subscription> = [];
constructor(private readonly cdr: ChangeDetectorRef) { private propagateChange = null;
constructor() {
} }
public ngOnInit(): void { public ngOnInit(): void {
if (!this.control) { this.subscriptions.push(
this.control = new ColorPickerControl(); this.control.valueChanges.subscribe(value => {
} if (this.modelValue) {
this.updateModel();
}
})
);
}
registerOnChange(fn: any): void {
this.propagateChange = fn;
}
registerOnTouched(fn: any): void {
}
writeValue(value: string): void {
this.control. setValueFrom(value || '#fff');
this.modelValue = value;
if (this.control.initType === ColorType.hexa) { if (this.control.initType === ColorType.hexa) {
this.control.initType = ColorType.hex; this.control.initType = ColorType.hex;
} else if (this.control.initType === ColorType.rgb) {
this.control.initType = ColorType.rgba;
} else if (this.control.initType === ColorType.hsl) {
this.control.initType = ColorType.hsla;
} }
this.selectedPresentation = this.presentations.indexOf(this.control.initType); this.selectedPresentation = this.presentations.indexOf(this.control.initType);
if (this.color) {
this.control.setValueFrom(this.color);
}
this.subscriptions.push(
this.control.valueChanges.subscribe((value) => {
this.cdr.markForCheck();
this.colorChange.emit(this.getValueByType(value, this.presentations[this.selectedPresentation]));
})
);
} }
changeColorFormat(event: Event) { private updateModel() {
this.colorChange.emit(this.getValueByType(this.control.value, this.presentations[this.selectedPresentation])); const color: string = this.getValueByType(this.control.value, this.presentations[this.selectedPresentation]);
if (this.modelValue !== color) {
this.modelValue = color;
this.propagateChange(color);
}
} }
public ngOnDestroy(): void { public ngOnDestroy(): void {
this.cdr.detach();
this.subscriptions.forEach((subscription) => subscription.unsubscribe()); this.subscriptions.forEach((subscription) => subscription.unsubscribe());
this.subscriptions.length = 0; this.subscriptions.length = 0;
} }
public ngOnChanges(changes: SimpleChanges): void {
if (this.color && this.control &&
this.getValueByType(this.control.value, this.presentations[this.selectedPresentation]) !== this.color) {
this.control.setValueFrom(this.color);
}
}
public changePresentation(): void { public changePresentation(): void {
this.selectedPresentation = this.selectedPresentation =
this.selectedPresentation === this.presentations.length - 1 ? 0 : this.selectedPresentation + 1; this.selectedPresentation === this.presentations.length - 1 ? 0 : this.selectedPresentation + 1;
this.colorChange.emit(this.getValueByType(this.control.value, this.presentations[this.selectedPresentation])); this.updateModel();
this.cdr.markForCheck();
} }
getValueByType(color: Color, type: ColorType): string { getValueByType(color: Color, type: ColorType): string {
switch (type) { switch (type) {
case ColorType.hex || ColorType.hexa: case ColorType.hex:
return color.toHexString(this.control.value.getRgba().getAlpha() !== 1); return color.toHexString(this.control.value.getRgba().getAlpha() !== 1);
case ColorType.rgb:
return color.toRgbString();
case ColorType.rgba: case ColorType.rgba:
return color.toRgbaString(); return this.control.value.getRgba().getAlpha() !== 1 ? color.toRgbaString() : color.toRgbString();
case ColorType.hsl:
return color.toHslString();
case ColorType.hsla: case ColorType.hsla:
return color.toHslaString(); return this.control.value.getRgba().getAlpha() !== 1 ? color.toHslaString() : color.toHslString();
default: default:
return color.toRgbaString(); return color.toRgbaString();
} }
} }
} }

6
ui-ngx/src/app/shared/components/dialog/color-picker-dialog.component.html

@ -15,9 +15,9 @@
limitations under the License. limitations under the License.
--> -->
<form [formGroup]="colorPickerFormGroup" (ngSubmit)="select()" style="width: 320px;"> <form [formGroup]="colorPickerFormGroup" (ngSubmit)="select()">
<div mat-dialog-content style="padding: 16px" fxLayout="row" fxLayoutAlign="center"> <div mat-dialog-content style="padding: 16px; width: 320px; min-width: 100%; max-width: 100%;" fxLayout="row" fxLayoutAlign="center">
<tb-color-picker [control]="sketchControl" (colorChange)="onColorChange($event)"></tb-color-picker> <tb-color-picker formControlName="color"></tb-color-picker>
</div> </div>
<div mat-dialog-actions fxLayout="row"> <div mat-dialog-actions fxLayout="row">
<span fxFlex></span> <span fxFlex></span>

8
ui-ngx/src/app/shared/components/dialog/color-picker-dialog.component.ts

@ -29,7 +29,6 @@ import {
} from '@angular/forms'; } from '@angular/forms';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { DialogComponent } from '@shared/components/dialog.component'; import { DialogComponent } from '@shared/components/dialog.component';
import { ColorPickerControl } from '@iplab/ngx-color-picker';
export interface ColorPickerDialogData { export interface ColorPickerDialogData {
color: string; color: string;
@ -48,8 +47,6 @@ export class ColorPickerDialogComponent extends DialogComponent<ColorPickerDialo
submitted = false; submitted = false;
sketchControl = new ColorPickerControl().setValueFrom(this.data.color);
constructor(protected store: Store<AppState>, constructor(protected store: Store<AppState>,
protected router: Router, protected router: Router,
@Inject(MAT_DIALOG_DATA) public data: ColorPickerDialogData, @Inject(MAT_DIALOG_DATA) public data: ColorPickerDialogData,
@ -71,11 +68,6 @@ export class ColorPickerDialogComponent extends DialogComponent<ColorPickerDialo
return originalErrorState || customErrorState; return originalErrorState || customErrorState;
} }
onColorChange(color: string) {
this.colorPickerFormGroup.get('color').setValue(color);
this.colorPickerFormGroup.markAsDirty();
}
cancel(): void { cancel(): void {
this.dialogRef.close(null); this.dialogRef.close(null);
} }

Loading…
Cancel
Save