+ {{#each colorChannelInputs}}
+
+
+ {{label}}
+
+
+ {{#if showPercentSymbol}}
+ %
+ {{/if}}
+
+ {{/each}}
+
+
A
+
+
+
{{/if}}
diff --git a/packages/main/src/ColorPicker.ts b/packages/main/src/ColorPicker.ts
index c75f5391d308..38e14dda64db 100644
--- a/packages/main/src/ColorPicker.ts
+++ b/packages/main/src/ColorPicker.ts
@@ -10,19 +10,20 @@ import { getScopedVarName } from "@ui5/webcomponents-base/dist/CustomElementsSco
import type { IFormInputElement } from "@ui5/webcomponents-base/dist/features/InputElementsFormSupport.js";
import {
getRGBColor,
- HSLToRGB,
- HEXToRGB,
- RGBToHSL,
} from "@ui5/webcomponents-base/dist/util/ColorConversion.js";
import type {
ColorHSL,
ColorRGB,
} from "@ui5/webcomponents-base/dist/util/ColorConversion.js";
+import "@ui5/webcomponents-icons/dist/expand.js";
import ColorPickerTemplate from "./generated/templates/ColorPickerTemplate.lit.js";
import Input from "./Input.js";
import Slider from "./Slider.js";
import Label from "./Label.js";
+import Button from "./Button.js";
+import Icon from "./Icon.js";
import ColorPickerDisplayMode from "./types/ColorPickerDisplayMode.js";
+import ColorValue from "./ColorValue.js";
import {
COLORPICKER_ALPHA_SLIDER,
@@ -32,6 +33,10 @@ import {
COLORPICKER_GREEN,
COLORPICKER_BLUE,
COLORPICKER_ALPHA,
+ COLORPICKER_SATURATION,
+ COLORPICKER_LIGHT,
+ COLORPICKER_HUE,
+ COLORPICKER_TOGGLE_MODE_TOOLTIP,
} from "./generated/i18n/i18n-defaults.js";
// Styles
@@ -44,6 +49,14 @@ type ColorCoordinates = {
y: number,
}
+type ColorChannelInput = {
+ id: string,
+ value: number,
+ accessibleName: string
+ label: string,
+ showPercentSymbol?: boolean,
+}
+
/**
* @class
*
@@ -80,6 +93,8 @@ type ColorCoordinates = {
Input,
Slider,
Label,
+ Button,
+ Icon,
],
shadowRootOptions: { delegatesFocus: true },
})
@@ -121,15 +136,6 @@ class ColorPicker extends UI5Element implements IFormInputElement {
@property()
displayMode: `${ColorPickerDisplayMode}` = "Default";
- /**
- * Defines the HEX code of the currently selected color
- *
- * **Note**: If Alpha(transperancy) is set it is not included in this property. Use `color` property.
- * @private
- */
- @property({ noAttribute: true })
- hex = "ffffff";
-
/**
* Defines the current main color which is selected via the hue slider and is shown in the main color square.
* @private
@@ -138,11 +144,11 @@ class ColorPicker extends UI5Element implements IFormInputElement {
_mainValue: ColorRGB;
/**
- * Defines the currenty selected color from the main color section.
+ * Defines the currenty selected color.
* @private
*/
- @property({ type: Object })
- _value: ColorRGB = getRGBColor(this.value);
+ @property({ type: Boolean })
+ _colorValue: ColorValue;
/**
* @private
@@ -180,6 +186,12 @@ class ColorPicker extends UI5Element implements IFormInputElement {
@property({ type: Boolean })
_wrongHEX = false;
+ /**
+ * @private
+ */
+ @property({ type: Boolean })
+ _displayHSL = false;
+
selectedHue: number;
mouseDown: boolean;
@@ -199,6 +211,7 @@ class ColorPicker extends UI5Element implements IFormInputElement {
constructor() {
super();
+ this._colorValue = new ColorValue();
// Bottom Right corner
this._selectedCoordinates = {
@@ -220,10 +233,11 @@ class ColorPicker extends UI5Element implements IFormInputElement {
}
onBeforeRendering() {
- // we have the color & ._mainValue properties here
- this._value = getRGBColor(this.value);
- const tempColor = `rgba(${this._value.r},${this._value.g},${this._value.b},1)`;
- this._setHex();
+ const valueAsRGB = getRGBColor(this.value);
+ if (!this._isColorValueEqual(valueAsRGB)) {
+ this._colorValue.RGB = valueAsRGB;
+ }
+ const tempColor = this._colorValue.toString();
this._setValues();
this.style.setProperty(getScopedVarName("--ui5_Color_Picker_Progress_Container_Color"), tempColor);
}
@@ -291,8 +305,9 @@ class ColorPicker extends UI5Element implements IFormInputElement {
if (Number.isNaN(this._alpha)) {
this._alpha = 1;
}
+ this._colorValue.Alpha = this._alpha;
this._isHueValueChanged = true;
- this._setColor(this._value);
+ this._setColor();
}
_handleHueInput(e: CustomEvent) {
@@ -302,17 +317,14 @@ class ColorPicker extends UI5Element implements IFormInputElement {
// Idication that changes to the hue value triggered as a result of user pressing over the hue slider.
this._isHueValueChanged = true;
- const x: number = this._selectedCoordinates.x + PICKER_POINTER_WIDTH;
- const y: number = this._selectedCoordinates.y + PICKER_POINTER_WIDTH;
- const tempColor = this._calculateColorFromCoordinates(x, y);
+ const hue = Math.round(this._hue / 4.251);
+ const normalizedHue = ((hue % 360) + 360) % 360;
- if (tempColor) {
- this._setColor(HSLToRGB(tempColor));
- }
+ this._colorValue.H = normalizedHue;
+ this._setColor();
}
_handleHEXChange(e: CustomEvent | KeyboardEvent) {
- const hexRegex = new RegExp("^[<0-9 abcdef]+$");
const input: Input = (e.target as Input);
let inputValueLowerCase = input.value.toLowerCase();
@@ -321,48 +333,57 @@ class ColorPicker extends UI5Element implements IFormInputElement {
inputValueLowerCase = `${inputValueLowerCase[0]}${inputValueLowerCase[0]}${inputValueLowerCase[1]}${inputValueLowerCase[1]}${inputValueLowerCase[2]}${inputValueLowerCase[2]}`;
}
- const isNewValueValid = inputValueLowerCase.length === 6 && hexRegex.test(inputValueLowerCase);
+ this._colorValue.HEX = inputValueLowerCase;
+ const isValidColor = this._colorValue.isColorValueValid();
- if (isNewValueValid && input.value !== inputValueLowerCase) {
+ if (isValidColor && input.value !== inputValueLowerCase) {
this._wrongHEX = false;
input.value = inputValueLowerCase;
}
- if (inputValueLowerCase === this.hex) {
- return;
- }
-
- this.hex = inputValueLowerCase;
-
- if (!isNewValueValid) {
+ if (!isValidColor) {
this._wrongHEX = true;
} else {
this._wrongHEX = false;
- this._setColor(HEXToRGB(this.hex));
+ this._setColor();
}
}
- _handleRGBInputsChange(e: CustomEvent) {
+ _togglePickerMode() {
+ this._displayHSL = !this._displayHSL;
+ }
+
+ _handleColorInputChange(e: CustomEvent) {
const target = e.target as Input;
const targetValue = parseInt(target.value) || 0;
- let tempColor;
+
switch (target.id) {
case "red":
- tempColor = { ...this._value, r: targetValue };
+ this._colorValue.R = targetValue;
break;
case "green":
- tempColor = { ...this._value, g: targetValue };
+ this._colorValue.G = targetValue;
break;
case "blue":
- tempColor = { ...this._value, b: targetValue };
+ this._colorValue.B = targetValue;
+ break;
+
+ case "hue":
+ this._colorValue.H = targetValue;
+ break;
+
+ case "saturation":
+ this._colorValue.S = targetValue;
+ break;
+
+ case "light":
+ this._colorValue.L = targetValue;
break;
- default:
- tempColor = { ...this._value };
}
- this._setColor(tempColor);
+ this._setColor();
}
_setMainColor(hueValue: number) {
@@ -408,6 +429,7 @@ class ColorPicker extends UI5Element implements IFormInputElement {
_handleAlphaChange() {
this._alpha = this._alpha < 0 ? 0 : this._alpha;
this._alpha = this._alpha > 1 ? 1 : this._alpha;
+ this._colorValue.Alpha = this._alpha;
}
_changeSelectedColor(x: number, y: number) {
@@ -421,7 +443,8 @@ class ColorPicker extends UI5Element implements IFormInputElement {
const tempColor = this._calculateColorFromCoordinates(x, y);
if (tempColor) {
- this._setColor(HSLToRGB(tempColor));
+ this._colorValue.HSL = tempColor;
+ this._setColor();
}
}
@@ -444,51 +467,29 @@ class ColorPicker extends UI5Element implements IFormInputElement {
// 0 ≤ V ≤ 1
const l = +(Math.round(parseFloat((x / 256) + "e+2")) + "e-2"); // eslint-disable-line
- if (!s || !l) {
+ if (Number.isNaN(s) || Number.isNaN(l)) {
// The event is finished out of the main color section
return;
}
return {
- h,
- s,
- l,
+ h: Math.round(h),
+ s: Math.round(s * 100),
+ l: Math.round(l * 100),
};
}
- _setColor(color: ColorRGB = { r: 0, g: 0, b: 0 }) {
- this.value = `rgba(${color.r}, ${color.g}, ${color.b}, ${this._alpha})`;
- this._wrongHEX = !this.isValidRGBColor(color);
+ _setColor() {
+ this.value = this._colorValue.toString();
+ this._wrongHEX = !this._colorValue.isColorValueValid();
this.fireDecoratorEvent("change");
}
- isValidRGBColor(color: ColorRGB) {
- return color.r >= 0 && color.r <= 255 && color.g >= 0 && color.g <= 255 && color.b >= 0 && color.b <= 255;
- }
-
- _setHex() {
- let red = this._value.r.toString(16),
- green = this._value.g.toString(16),
- blue = this._value.b.toString(16);
-
- if (red.length === 1) {
- red = `0${red}`;
- }
- if (green.length === 1) {
- green = `0${green}`;
- }
- if (blue.length === 1) {
- blue = `0${blue}`;
- }
-
- this.hex = red + green + blue;
- }
-
_setValues() {
- const hslColours: ColorHSL = RGBToHSL(this._value);
+ const hslColours: ColorHSL = this._colorValue.HSL;
this._selectedCoordinates = {
- x: ((Math.round(hslColours.l * 100) * 2.56)) - PICKER_POINTER_WIDTH, // Center the coordinates, because of the width of the circle
- y: (256 - (Math.round(hslColours.s * 100) * 2.56)) - PICKER_POINTER_WIDTH, // Center the coordinates, because of the height of the circle
+ x: ((hslColours.l * 2.56)) - PICKER_POINTER_WIDTH, // Center the coordinates, because of the width of the circle
+ y: (256 - (hslColours.s * 2.56)) - PICKER_POINTER_WIDTH, // Center the coordinates, because of the height of the circle
};
if (this._isSelectedColorChanged) { // We shouldn't update the hue value when user presses over the main color section.
@@ -503,6 +504,12 @@ class ColorPicker extends UI5Element implements IFormInputElement {
this._setMainColor(this._hue);
}
+ _isColorValueEqual(value: ColorRGB): boolean {
+ return this._colorValue.R === value.r
+ && this._colorValue.G === value.g
+ && this._colorValue.B === value.b;
+ }
+
get hueSliderLabel() {
return ColorPicker.i18nBundle.getText(COLORPICKER_HUE_SLIDER);
}
@@ -527,10 +534,26 @@ class ColorPicker extends UI5Element implements IFormInputElement {
return ColorPicker.i18nBundle.getText(COLORPICKER_BLUE);
}
+ get hueInputLabel() {
+ return ColorPicker.i18nBundle.getText(COLORPICKER_HUE);
+ }
+
+ get saturationInputLabel() {
+ return ColorPicker.i18nBundle.getText(COLORPICKER_SATURATION);
+ }
+
+ get lightInputLabel() {
+ return ColorPicker.i18nBundle.getText(COLORPICKER_LIGHT);
+ }
+
get alphaInputLabel() {
return ColorPicker.i18nBundle.getText(COLORPICKER_ALPHA);
}
+ get toggleModeTooltip() {
+ return ColorPicker.i18nBundle.getText(COLORPICKER_TOGGLE_MODE_TOOLTIP);
+ }
+
get inputsDisabled() {
return this._wrongHEX ? true : undefined;
}
@@ -539,6 +562,75 @@ class ColorPicker extends UI5Element implements IFormInputElement {
return this._wrongHEX ? "Error" : undefined;
}
+ get rgbInputs(): Array