@thednp/color-picker 0.0.1-alpha2 → 0.0.1-alpha3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -15
- package/dist/css/color-picker.css +37 -15
- package/dist/css/color-picker.min.css +2 -2
- package/dist/css/color-picker.rtl.css +37 -15
- package/dist/css/color-picker.rtl.min.css +2 -2
- package/dist/js/color-picker-element-esm.js +164 -135
- package/dist/js/color-picker-element-esm.min.js +2 -2
- package/dist/js/color-picker-element.js +164 -135
- package/dist/js/color-picker-element.min.js +2 -2
- package/dist/js/color-picker-esm.js +159 -133
- package/dist/js/color-picker-esm.min.js +2 -2
- package/dist/js/color-picker.js +159 -133
- package/dist/js/color-picker.min.js +2 -2
- package/package.json +1 -1
- package/src/js/color-palette.js +18 -9
- package/src/js/color-picker-element.js +7 -3
- package/src/js/color-picker.js +59 -48
- package/src/js/color.js +33 -34
- package/src/js/util/getColorControls.js +3 -3
- package/src/js/util/getColorForm.js +0 -1
- package/src/js/util/getColorMenu.js +21 -28
- package/src/js/util/roundPart.js +9 -0
- package/src/js/util/setCSSProperties.js +12 -0
- package/src/js/util/tabindex.js +3 -0
- package/src/scss/color-picker.scss +35 -12
- package/types/cp.d.ts +1 -3
@@ -1,5 +1,5 @@
|
|
1
1
|
/*!
|
2
|
-
* ColorPickerElement v0.0.
|
2
|
+
* ColorPickerElement v0.0.1alpha3 (http://thednp.github.io/color-picker)
|
3
3
|
* Copyright 2022 © thednp
|
4
4
|
* Licensed under MIT (https://github.com/thednp/color-picker/blob/master/LICENSE)
|
5
5
|
*/
|
@@ -116,19 +116,36 @@
|
|
116
116
|
return property in computedStyle ? computedStyle[property] : '';
|
117
117
|
}
|
118
118
|
|
119
|
+
/**
|
120
|
+
* Shortcut for `Object.keys()` static method.
|
121
|
+
* @param {Record<string, any>} obj a target object
|
122
|
+
* @returns {string[]}
|
123
|
+
*/
|
124
|
+
const ObjectKeys = (obj) => Object.keys(obj);
|
125
|
+
|
119
126
|
/**
|
120
127
|
* Shortcut for multiple uses of `HTMLElement.style.propertyName` method.
|
121
128
|
* @param {HTMLElement | Element} element target element
|
122
129
|
* @param {Partial<CSSStyleDeclaration>} styles attribute value
|
123
130
|
*/
|
124
131
|
// @ts-ignore
|
125
|
-
const setElementStyle = (element, styles) =>
|
132
|
+
const setElementStyle = (element, styles) => ObjectAssign(element.style, styles);
|
126
133
|
|
127
134
|
/**
|
128
135
|
* A list of explicit default non-color values.
|
129
136
|
*/
|
130
137
|
const nonColors = ['transparent', 'currentColor', 'inherit', 'revert', 'initial'];
|
131
138
|
|
139
|
+
/**
|
140
|
+
* Round colour components, for all formats except HEX.
|
141
|
+
* @param {number} v one of the colour components
|
142
|
+
* @returns {number} the rounded number
|
143
|
+
*/
|
144
|
+
function roundPart(v) {
|
145
|
+
const floor = Math.floor(v);
|
146
|
+
return v - floor < 0.5 ? floor : Math.round(v);
|
147
|
+
}
|
148
|
+
|
132
149
|
// Color supported formats
|
133
150
|
const COLOR_FORMAT = ['rgb', 'hex', 'hsl', 'hsb', 'hwb'];
|
134
151
|
|
@@ -296,7 +313,7 @@
|
|
296
313
|
* @returns {string} - the hexadecimal value
|
297
314
|
*/
|
298
315
|
function convertDecimalToHex(d) {
|
299
|
-
return
|
316
|
+
return roundPart(d * 255).toString(16);
|
300
317
|
}
|
301
318
|
|
302
319
|
/**
|
@@ -548,9 +565,9 @@
|
|
548
565
|
*/
|
549
566
|
function rgbToHex(r, g, b, allow3Char) {
|
550
567
|
const hex = [
|
551
|
-
pad2(
|
552
|
-
pad2(
|
553
|
-
pad2(
|
568
|
+
pad2(roundPart(r).toString(16)),
|
569
|
+
pad2(roundPart(g).toString(16)),
|
570
|
+
pad2(roundPart(b).toString(16)),
|
554
571
|
];
|
555
572
|
|
556
573
|
// Return a 3 character hex if possible
|
@@ -575,9 +592,9 @@
|
|
575
592
|
*/
|
576
593
|
function rgbaToHex(r, g, b, a, allow4Char) {
|
577
594
|
const hex = [
|
578
|
-
pad2(
|
579
|
-
pad2(
|
580
|
-
pad2(
|
595
|
+
pad2(roundPart(r).toString(16)),
|
596
|
+
pad2(roundPart(g).toString(16)),
|
597
|
+
pad2(roundPart(b).toString(16)),
|
581
598
|
pad2(convertDecimalToHex(a)),
|
582
599
|
];
|
583
600
|
|
@@ -739,6 +756,8 @@
|
|
739
756
|
let w = null;
|
740
757
|
let b = null;
|
741
758
|
let h = null;
|
759
|
+
let r = null;
|
760
|
+
let g = null;
|
742
761
|
let ok = false;
|
743
762
|
let format = 'hex';
|
744
763
|
|
@@ -749,7 +768,10 @@
|
|
749
768
|
}
|
750
769
|
if (typeof color === 'object') {
|
751
770
|
if (isValidCSSUnit(color.r) && isValidCSSUnit(color.g) && isValidCSSUnit(color.b)) {
|
752
|
-
|
771
|
+
({ r, g, b } = color);
|
772
|
+
[r, g, b] = [...[r, g, b]]
|
773
|
+
.map((n) => bound01(n, isPercentage(n) ? 100 : 255) * 255).map(roundPart);
|
774
|
+
rgb = { r, g, b }; // RGB values now are all in [0, 255] range
|
753
775
|
ok = true;
|
754
776
|
format = 'rgb';
|
755
777
|
} else if (isValidCSSUnit(color.h) && isValidCSSUnit(color.s) && isValidCSSUnit(color.v)) {
|
@@ -837,14 +859,6 @@
|
|
837
859
|
self.ok = ok;
|
838
860
|
/** @type {CP.ColorFormats} */
|
839
861
|
self.format = configFormat || format;
|
840
|
-
|
841
|
-
// Don't let the range of [0,255] come back in [0,1].
|
842
|
-
// Potentially lose a little bit of precision here, but will fix issues where
|
843
|
-
// .5 gets interpreted as half of the total, instead of half of 1
|
844
|
-
// If it was supposed to be 128, this was already taken care of by `inputToRgb`
|
845
|
-
if (r < 1) self.r = Math.round(r);
|
846
|
-
if (g < 1) self.g = Math.round(g);
|
847
|
-
if (b < 1) self.b = Math.round(b);
|
848
862
|
}
|
849
863
|
|
850
864
|
/**
|
@@ -860,7 +874,7 @@
|
|
860
874
|
* @returns {boolean} the query result
|
861
875
|
*/
|
862
876
|
get isDark() {
|
863
|
-
return this.brightness <
|
877
|
+
return this.brightness < 120;
|
864
878
|
}
|
865
879
|
|
866
880
|
/**
|
@@ -912,13 +926,13 @@
|
|
912
926
|
const {
|
913
927
|
r, g, b, a,
|
914
928
|
} = this;
|
915
|
-
const [R, G, B] = [r, g, b].map((x) =>
|
929
|
+
const [R, G, B] = [r, g, b].map((x) => roundPart(x));
|
916
930
|
|
917
931
|
return {
|
918
932
|
r: R,
|
919
933
|
g: G,
|
920
934
|
b: B,
|
921
|
-
a:
|
935
|
+
a: roundPart(a * 100) / 100,
|
922
936
|
};
|
923
937
|
}
|
924
938
|
|
@@ -948,7 +962,7 @@
|
|
948
962
|
const {
|
949
963
|
r, g, b, a,
|
950
964
|
} = this.toRgb();
|
951
|
-
const A = a === 1 ? '' : ` / ${
|
965
|
+
const A = a === 1 ? '' : ` / ${roundPart(a * 100)}%`;
|
952
966
|
|
953
967
|
return `rgb(${r} ${g} ${b}${A})`;
|
954
968
|
}
|
@@ -1043,10 +1057,10 @@
|
|
1043
1057
|
let {
|
1044
1058
|
h, s, l, a,
|
1045
1059
|
} = this.toHsl();
|
1046
|
-
h =
|
1047
|
-
s =
|
1048
|
-
l =
|
1049
|
-
a =
|
1060
|
+
h = roundPart(h * 360);
|
1061
|
+
s = roundPart(s * 100);
|
1062
|
+
l = roundPart(l * 100);
|
1063
|
+
a = roundPart(a * 100) / 100;
|
1050
1064
|
|
1051
1065
|
return a === 1
|
1052
1066
|
? `hsl(${h}, ${s}%, ${l}%)`
|
@@ -1063,11 +1077,11 @@
|
|
1063
1077
|
let {
|
1064
1078
|
h, s, l, a,
|
1065
1079
|
} = this.toHsl();
|
1066
|
-
h =
|
1067
|
-
s =
|
1068
|
-
l =
|
1069
|
-
a =
|
1070
|
-
const A = a < 100 ? ` / ${
|
1080
|
+
h = roundPart(h * 360);
|
1081
|
+
s = roundPart(s * 100);
|
1082
|
+
l = roundPart(l * 100);
|
1083
|
+
a = roundPart(a * 100);
|
1084
|
+
const A = a < 100 ? ` / ${roundPart(a)}%` : '';
|
1071
1085
|
|
1072
1086
|
return `hsl(${h}deg ${s}% ${l}%${A})`;
|
1073
1087
|
}
|
@@ -1094,11 +1108,11 @@
|
|
1094
1108
|
let {
|
1095
1109
|
h, w, b, a,
|
1096
1110
|
} = this.toHwb();
|
1097
|
-
h =
|
1098
|
-
w =
|
1099
|
-
b =
|
1100
|
-
a =
|
1101
|
-
const A = a < 100 ? ` / ${
|
1111
|
+
h = roundPart(h * 360);
|
1112
|
+
w = roundPart(w * 100);
|
1113
|
+
b = roundPart(b * 100);
|
1114
|
+
a = roundPart(a * 100);
|
1115
|
+
const A = a < 100 ? ` / ${roundPart(a)}%` : '';
|
1102
1116
|
|
1103
1117
|
return `hwb(${h}deg ${w}% ${b}%${A})`;
|
1104
1118
|
}
|
@@ -1244,6 +1258,7 @@
|
|
1244
1258
|
numberInputToObject,
|
1245
1259
|
stringInputToObject,
|
1246
1260
|
inputToRGB,
|
1261
|
+
roundPart,
|
1247
1262
|
ObjectAssign,
|
1248
1263
|
});
|
1249
1264
|
|
@@ -1872,13 +1887,6 @@
|
|
1872
1887
|
return value;
|
1873
1888
|
}
|
1874
1889
|
|
1875
|
-
/**
|
1876
|
-
* Shortcut for `Object.keys()` static method.
|
1877
|
-
* @param {Record<string, any>} obj a target object
|
1878
|
-
* @returns {string[]}
|
1879
|
-
*/
|
1880
|
-
const ObjectKeys = (obj) => Object.keys(obj);
|
1881
|
-
|
1882
1890
|
/**
|
1883
1891
|
* Shortcut for `String.toLowerCase()`.
|
1884
1892
|
*
|
@@ -2081,7 +2089,6 @@
|
|
2081
2089
|
max,
|
2082
2090
|
step,
|
2083
2091
|
});
|
2084
|
-
// }
|
2085
2092
|
colorForm.append(cInputLabel, cInput);
|
2086
2093
|
});
|
2087
2094
|
return colorForm;
|
@@ -2105,6 +2112,8 @@
|
|
2105
2112
|
*/
|
2106
2113
|
const ariaValueMax = 'aria-valuemax';
|
2107
2114
|
|
2115
|
+
const tabIndex = 'tabindex';
|
2116
|
+
|
2108
2117
|
/**
|
2109
2118
|
* Returns all color controls for `ColorPicker`.
|
2110
2119
|
*
|
@@ -2170,10 +2179,8 @@
|
|
2170
2179
|
const {
|
2171
2180
|
i, c, l, min, max,
|
2172
2181
|
} = template;
|
2173
|
-
// const hidden = i === 2 && format === 'hwb' ? ' v-hidden' : '';
|
2174
2182
|
const control = createElement({
|
2175
2183
|
tagName: 'div',
|
2176
|
-
// className: `color-control${hidden}`,
|
2177
2184
|
className: 'color-control',
|
2178
2185
|
});
|
2179
2186
|
setAttribute(control, 'role', 'presentation');
|
@@ -2193,7 +2200,7 @@
|
|
2193
2200
|
|
2194
2201
|
setAttribute(knob, ariaLabel, l);
|
2195
2202
|
setAttribute(knob, 'role', 'slider');
|
2196
|
-
setAttribute(knob,
|
2203
|
+
setAttribute(knob, tabIndex, '0');
|
2197
2204
|
setAttribute(knob, ariaValueMin, `${min}`);
|
2198
2205
|
setAttribute(knob, ariaValueMax, `${max}`);
|
2199
2206
|
control.append(knob);
|
@@ -2203,6 +2210,17 @@
|
|
2203
2210
|
return colorControls;
|
2204
2211
|
}
|
2205
2212
|
|
2213
|
+
/**
|
2214
|
+
* Helps setting CSS variables to the color-menu.
|
2215
|
+
* @param {HTMLElement} element
|
2216
|
+
* @param {Record<string,any>} props
|
2217
|
+
*/
|
2218
|
+
function setCSSProperties(element, props) {
|
2219
|
+
ObjectKeys(props).forEach((prop) => {
|
2220
|
+
element.style.setProperty(prop, props[prop]);
|
2221
|
+
});
|
2222
|
+
}
|
2223
|
+
|
2206
2224
|
/**
|
2207
2225
|
* @class
|
2208
2226
|
* Returns a color palette with a given set of parameters.
|
@@ -2215,8 +2233,8 @@
|
|
2215
2233
|
* The `hue` parameter is optional, which would be set to 0.
|
2216
2234
|
* @param {number[]} args represeinting hue, hueSteps, lightSteps
|
2217
2235
|
* * `args.hue` the starting Hue [0, 360]
|
2218
|
-
* * `args.hueSteps` Hue Steps Count [5,
|
2219
|
-
* * `args.lightSteps` Lightness Steps Count [
|
2236
|
+
* * `args.hueSteps` Hue Steps Count [5, 24]
|
2237
|
+
* * `args.lightSteps` Lightness Steps Count [5, 12]
|
2220
2238
|
*/
|
2221
2239
|
constructor(...args) {
|
2222
2240
|
let hue = 0;
|
@@ -2229,24 +2247,32 @@
|
|
2229
2247
|
} else if (args.length === 2) {
|
2230
2248
|
[hueSteps, lightSteps] = args;
|
2231
2249
|
} else {
|
2232
|
-
throw TypeError('
|
2250
|
+
throw TypeError('ColorPalette requires minimum 2 arguments');
|
2233
2251
|
}
|
2234
2252
|
|
2235
2253
|
/** @type {string[]} */
|
2236
2254
|
const colors = [];
|
2237
2255
|
|
2238
2256
|
const hueStep = 360 / hueSteps;
|
2239
|
-
const
|
2240
|
-
const
|
2257
|
+
const half = roundPart((lightSteps - (lightSteps % 2 ? 1 : 0)) / 2);
|
2258
|
+
const estimatedStep = 100 / (lightSteps + (lightSteps % 2 ? 0 : 1)) / 100;
|
2259
|
+
|
2260
|
+
let lightStep = 0.25;
|
2261
|
+
lightStep = [4, 5].includes(lightSteps) ? 0.2 : lightStep;
|
2262
|
+
lightStep = [6, 7].includes(lightSteps) ? 0.15 : lightStep;
|
2263
|
+
lightStep = [8, 9].includes(lightSteps) ? 0.11 : lightStep;
|
2264
|
+
lightStep = [10, 11].includes(lightSteps) ? 0.09 : lightStep;
|
2265
|
+
lightStep = [12, 13].includes(lightSteps) ? 0.075 : lightStep;
|
2266
|
+
lightStep = lightSteps > 13 ? estimatedStep : lightStep;
|
2241
2267
|
|
2242
2268
|
// light tints
|
2243
|
-
for (let i =
|
2244
|
-
lightnessArray = [...lightnessArray, (0.5 + lightStep * (i
|
2269
|
+
for (let i = 1; i < half + 1; i += 1) {
|
2270
|
+
lightnessArray = [...lightnessArray, (0.5 + lightStep * (i))];
|
2245
2271
|
}
|
2246
2272
|
|
2247
2273
|
// dark tints
|
2248
|
-
for (let i =
|
2249
|
-
lightnessArray = [(0.5 - lightStep * (i
|
2274
|
+
for (let i = 1; i < lightSteps - half; i += 1) {
|
2275
|
+
lightnessArray = [(0.5 - lightStep * (i)), ...lightnessArray];
|
2250
2276
|
}
|
2251
2277
|
|
2252
2278
|
// feed `colors` Array
|
@@ -2281,45 +2307,38 @@
|
|
2281
2307
|
colorsArray = colorsArray instanceof Array ? colorsArray : [];
|
2282
2308
|
const colorsCount = colorsArray.length;
|
2283
2309
|
const { lightSteps } = isPalette ? colorsSource : { lightSteps: null };
|
2284
|
-
|
2285
|
-
|| Math.max(...[5, 6, 7, 8, 9, 10].filter((x) => colorsCount > (x * 2) && !(colorsCount % x)));
|
2286
|
-
fit = Number.isFinite(fit) ? fit : 5;
|
2310
|
+
const fit = lightSteps || [9, 10].find((x) => colorsCount > x * 2 && !(colorsCount % x)) || 5;
|
2287
2311
|
const isMultiLine = isOptionsMenu && colorsCount > fit;
|
2288
|
-
let rowCountHover =
|
2289
|
-
rowCountHover = isMultiLine && colorsCount
|
2290
|
-
rowCountHover = colorsCount >=
|
2291
|
-
rowCountHover = colorsCount >=
|
2292
|
-
|
2293
|
-
const
|
2294
|
-
const isScrollable = isMultiLine && colorsCount > rowCountHover * fit;
|
2312
|
+
let rowCountHover = 2;
|
2313
|
+
rowCountHover = isMultiLine && colorsCount >= fit * 2 ? 3 : rowCountHover;
|
2314
|
+
rowCountHover = colorsCount >= fit * 3 ? 4 : rowCountHover;
|
2315
|
+
rowCountHover = colorsCount >= fit * 4 ? 5 : rowCountHover;
|
2316
|
+
const rowCount = rowCountHover - (colorsCount < fit * 3 ? 1 : 2);
|
2317
|
+
const isScrollable = isMultiLine && colorsCount > rowCount * fit;
|
2295
2318
|
let finalClass = menuClass;
|
2296
2319
|
finalClass += isScrollable ? ' scrollable' : '';
|
2297
2320
|
finalClass += isMultiLine ? ' multiline' : '';
|
2298
2321
|
const gap = isMultiLine ? '1px' : '0.25rem';
|
2299
2322
|
let optionSize = isMultiLine ? 1.75 : 2;
|
2300
|
-
optionSize =
|
2323
|
+
optionSize = fit > 5 && isMultiLine ? 1.5 : optionSize;
|
2301
2324
|
const menuHeight = `${(rowCount || 1) * optionSize}rem`;
|
2302
2325
|
const menuHeightHover = `calc(${rowCountHover} * ${optionSize}rem + ${rowCountHover - 1} * ${gap})`;
|
2303
|
-
const gridTemplateColumns = `repeat(${fit}, ${optionSize}rem)`;
|
2304
|
-
const gridTemplateRows = `repeat(auto-fill, ${optionSize}rem)`;
|
2305
2326
|
|
2306
2327
|
const menu = createElement({
|
2307
2328
|
tagName: 'ul',
|
2308
2329
|
className: finalClass,
|
2309
2330
|
});
|
2310
2331
|
setAttribute(menu, 'role', 'listbox');
|
2311
|
-
setAttribute(menu, ariaLabel,
|
2312
|
-
|
2313
|
-
if (
|
2314
|
-
|
2315
|
-
|
2316
|
-
|
2317
|
-
|
2318
|
-
|
2319
|
-
|
2320
|
-
|
2321
|
-
};
|
2322
|
-
setElementStyle(menu, menuStyle);
|
2332
|
+
setAttribute(menu, ariaLabel, menuLabel);
|
2333
|
+
|
2334
|
+
if (isScrollable) { // @ts-ignore
|
2335
|
+
setCSSProperties(menu, {
|
2336
|
+
'--grid-item-size': `${optionSize}rem`,
|
2337
|
+
'--grid-fit': fit,
|
2338
|
+
'--grid-gap': gap,
|
2339
|
+
'--grid-height': menuHeight,
|
2340
|
+
'--grid-hover-height': menuHeightHover,
|
2341
|
+
});
|
2323
2342
|
}
|
2324
2343
|
|
2325
2344
|
colorsArray.forEach((x) => {
|
@@ -2334,15 +2353,13 @@
|
|
2334
2353
|
innerText: `${label || x}`,
|
2335
2354
|
});
|
2336
2355
|
|
2337
|
-
setAttribute(option,
|
2356
|
+
setAttribute(option, tabIndex, '0');
|
2338
2357
|
setAttribute(option, 'data-value', `${value}`);
|
2339
2358
|
setAttribute(option, 'role', 'option');
|
2340
2359
|
setAttribute(option, ariaSelected, isActive ? 'true' : 'false');
|
2341
2360
|
|
2342
2361
|
if (isOptionsMenu) {
|
2343
|
-
setElementStyle(option, {
|
2344
|
-
width: `${optionSize}rem`, height: `${optionSize}rem`, backgroundColor: x,
|
2345
|
-
});
|
2362
|
+
setElementStyle(option, { backgroundColor: x });
|
2346
2363
|
}
|
2347
2364
|
|
2348
2365
|
menu.append(option);
|
@@ -2364,7 +2381,7 @@
|
|
2364
2381
|
return true;
|
2365
2382
|
}
|
2366
2383
|
|
2367
|
-
var version = "0.0.
|
2384
|
+
var version = "0.0.1alpha3";
|
2368
2385
|
|
2369
2386
|
// @ts-ignore
|
2370
2387
|
|
@@ -2379,8 +2396,8 @@
|
|
2379
2396
|
componentLabels: colorPickerLabels,
|
2380
2397
|
colorLabels: colorNames,
|
2381
2398
|
format: 'rgb',
|
2382
|
-
colorPresets:
|
2383
|
-
colorKeywords:
|
2399
|
+
colorPresets: false,
|
2400
|
+
colorKeywords: false,
|
2384
2401
|
};
|
2385
2402
|
|
2386
2403
|
// ColorPicker Static Methods
|
@@ -2469,7 +2486,7 @@
|
|
2469
2486
|
tagName: 'button',
|
2470
2487
|
className: 'menu-toggle btn-appearance',
|
2471
2488
|
});
|
2472
|
-
setAttribute(presetsBtn,
|
2489
|
+
setAttribute(presetsBtn, tabIndex, '-1');
|
2473
2490
|
setAttribute(presetsBtn, ariaExpanded, 'false');
|
2474
2491
|
setAttribute(presetsBtn, ariaHasPopup, 'true');
|
2475
2492
|
|
@@ -2496,7 +2513,7 @@
|
|
2496
2513
|
if (colorKeywords && nonColors.includes(colorValue)) {
|
2497
2514
|
self.value = colorValue;
|
2498
2515
|
}
|
2499
|
-
setAttribute(input,
|
2516
|
+
setAttribute(input, tabIndex, '-1');
|
2500
2517
|
}
|
2501
2518
|
|
2502
2519
|
/**
|
@@ -2597,8 +2614,19 @@
|
|
2597
2614
|
addClass(dropdown, 'bottom');
|
2598
2615
|
reflow(dropdown);
|
2599
2616
|
addClass(dropdown, 'show');
|
2617
|
+
|
2600
2618
|
if (isPicker) self.update();
|
2601
|
-
|
2619
|
+
|
2620
|
+
if (!self.isOpen) {
|
2621
|
+
toggleEventsOnShown(self, true);
|
2622
|
+
self.updateDropdownPosition();
|
2623
|
+
self.isOpen = true;
|
2624
|
+
setAttribute(self.input, tabIndex, '0');
|
2625
|
+
if (menuToggle) {
|
2626
|
+
setAttribute(menuToggle, tabIndex, '0');
|
2627
|
+
}
|
2628
|
+
}
|
2629
|
+
|
2602
2630
|
setAttribute(nextBtn, ariaExpanded, 'true');
|
2603
2631
|
if (activeBtn) {
|
2604
2632
|
setAttribute(activeBtn, ariaExpanded, 'false');
|
@@ -2768,7 +2796,7 @@
|
|
2768
2796
|
set value(v) { this.input.value = v; }
|
2769
2797
|
|
2770
2798
|
/** Check if the colour presets include any non-colour. */
|
2771
|
-
get
|
2799
|
+
get hasNonColor() {
|
2772
2800
|
return this.colorKeywords instanceof Array
|
2773
2801
|
&& this.colorKeywords.some((x) => nonColors.includes(x));
|
2774
2802
|
}
|
@@ -2824,7 +2852,7 @@
|
|
2824
2852
|
const { r, g, b } = Color.hslToRgb(hue, 1, 0.5);
|
2825
2853
|
const whiteGrad = 'linear-gradient(rgb(255,255,255) 0%, rgb(255,255,255) 100%)';
|
2826
2854
|
const alpha = 1 - controlPositions.c3y / offsetHeight;
|
2827
|
-
const roundA =
|
2855
|
+
const roundA = roundPart((alpha * 100)) / 100;
|
2828
2856
|
|
2829
2857
|
if (format !== 'hsl') {
|
2830
2858
|
const fill = new Color({
|
@@ -2842,7 +2870,7 @@
|
|
2842
2870
|
});
|
2843
2871
|
setElementStyle(v2, { background: hueGradient });
|
2844
2872
|
} else {
|
2845
|
-
const saturation =
|
2873
|
+
const saturation = roundPart((controlPositions.c2y / offsetHeight) * 100);
|
2846
2874
|
const fill0 = new Color({
|
2847
2875
|
r: 255, g: 0, b: 0, a: alpha,
|
2848
2876
|
}).saturate(-saturation).toRgbString();
|
@@ -2997,12 +3025,12 @@
|
|
2997
3025
|
|
2998
3026
|
self.update();
|
2999
3027
|
|
3000
|
-
if (currentActive) {
|
3001
|
-
removeClass(currentActive, 'active');
|
3002
|
-
removeAttribute(currentActive, ariaSelected);
|
3003
|
-
}
|
3004
|
-
|
3005
3028
|
if (currentActive !== target) {
|
3029
|
+
if (currentActive) {
|
3030
|
+
removeClass(currentActive, 'active');
|
3031
|
+
removeAttribute(currentActive, ariaSelected);
|
3032
|
+
}
|
3033
|
+
|
3006
3034
|
addClass(target, 'active');
|
3007
3035
|
setAttribute(target, ariaSelected, 'true');
|
3008
3036
|
|
@@ -3169,7 +3197,7 @@
|
|
3169
3197
|
const [v1, v2, v3, v4] = format === 'rgb'
|
3170
3198
|
? inputs.map((i) => parseFloat(i.value) / (i === i4 ? 100 : 1))
|
3171
3199
|
: inputs.map((i) => parseFloat(i.value) / (i !== i1 ? 100 : 360));
|
3172
|
-
const isNonColorValue = self.
|
3200
|
+
const isNonColorValue = self.hasNonColor && nonColors.includes(currentValue);
|
3173
3201
|
const alpha = i4 ? v4 : (1 - controlPositions.c3y / offsetHeight);
|
3174
3202
|
|
3175
3203
|
if (activeElement === input || (activeElement && inputs.includes(activeElement))) {
|
@@ -3428,11 +3456,11 @@
|
|
3428
3456
|
} = componentLabels;
|
3429
3457
|
const { r, g, b } = color.toRgb();
|
3430
3458
|
const [knob1, knob2, knob3] = controlKnobs;
|
3431
|
-
const hue =
|
3459
|
+
const hue = roundPart(hsl.h * 360);
|
3432
3460
|
const alpha = color.a;
|
3433
3461
|
const saturationSource = format === 'hsl' ? hsl.s : hsv.s;
|
3434
|
-
const saturation =
|
3435
|
-
const lightness =
|
3462
|
+
const saturation = roundPart(saturationSource * 100);
|
3463
|
+
const lightness = roundPart(hsl.l * 100);
|
3436
3464
|
const hsvl = hsv.v * 100;
|
3437
3465
|
let colorName;
|
3438
3466
|
|
@@ -3479,8 +3507,8 @@
|
|
3479
3507
|
setAttribute(knob2, ariaValueNow, `${saturation}`);
|
3480
3508
|
} else if (format === 'hwb') {
|
3481
3509
|
const { hwb } = self;
|
3482
|
-
const whiteness =
|
3483
|
-
const blackness =
|
3510
|
+
const whiteness = roundPart(hwb.w * 100);
|
3511
|
+
const blackness = roundPart(hwb.b * 100);
|
3484
3512
|
colorLabel = `HWB: ${hue}°, ${whiteness}%, ${blackness}%`;
|
3485
3513
|
setAttribute(knob1, ariaDescription, `${valueLabel}: ${colorLabel}. ${appearanceLabel}: ${colorName}.`);
|
3486
3514
|
setAttribute(knob1, ariaValueText, `${whiteness}% & ${blackness}%`);
|
@@ -3496,7 +3524,7 @@
|
|
3496
3524
|
setAttribute(knob2, ariaValueNow, `${hue}`);
|
3497
3525
|
}
|
3498
3526
|
|
3499
|
-
const alphaValue =
|
3527
|
+
const alphaValue = roundPart(alpha * 100);
|
3500
3528
|
setAttribute(knob3, ariaValueText, `${alphaValue}%`);
|
3501
3529
|
setAttribute(knob3, ariaValueNow, `${alphaValue}`);
|
3502
3530
|
|
@@ -3519,10 +3547,14 @@
|
|
3519
3547
|
/** Updates the control knobs actual positions. */
|
3520
3548
|
updateControls() {
|
3521
3549
|
const { controlKnobs, controlPositions } = this;
|
3550
|
+
const {
|
3551
|
+
c1x, c1y, c2y, c3y,
|
3552
|
+
} = controlPositions;
|
3522
3553
|
const [control1, control2, control3] = controlKnobs;
|
3523
|
-
|
3524
|
-
setElementStyle(
|
3525
|
-
setElementStyle(
|
3554
|
+
|
3555
|
+
setElementStyle(control1, { transform: `translate3d(${c1x - 4}px,${c1y - 4}px,0)` });
|
3556
|
+
setElementStyle(control2, { transform: `translate3d(0,${c2y - 4}px,0)` });
|
3557
|
+
setElementStyle(control3, { transform: `translate3d(0,${c3y - 4}px,0)` });
|
3526
3558
|
}
|
3527
3559
|
|
3528
3560
|
/**
|
@@ -3535,16 +3567,16 @@
|
|
3535
3567
|
value: oldColor, format, inputs, color, hsl,
|
3536
3568
|
} = self;
|
3537
3569
|
const [i1, i2, i3, i4] = inputs;
|
3538
|
-
const alpha =
|
3539
|
-
const hue =
|
3570
|
+
const alpha = roundPart(color.a * 100);
|
3571
|
+
const hue = roundPart(hsl.h * 360);
|
3540
3572
|
let newColor;
|
3541
3573
|
|
3542
3574
|
if (format === 'hex') {
|
3543
3575
|
newColor = self.color.toHexString(true);
|
3544
3576
|
i1.value = self.hex;
|
3545
3577
|
} else if (format === 'hsl') {
|
3546
|
-
const lightness =
|
3547
|
-
const saturation =
|
3578
|
+
const lightness = roundPart(hsl.l * 100);
|
3579
|
+
const saturation = roundPart(hsl.s * 100);
|
3548
3580
|
newColor = self.color.toHslString();
|
3549
3581
|
i1.value = `${hue}`;
|
3550
3582
|
i2.value = `${saturation}`;
|
@@ -3552,8 +3584,8 @@
|
|
3552
3584
|
i4.value = `${alpha}`;
|
3553
3585
|
} else if (format === 'hwb') {
|
3554
3586
|
const { w, b } = self.hwb;
|
3555
|
-
const whiteness =
|
3556
|
-
const blackness =
|
3587
|
+
const whiteness = roundPart(w * 100);
|
3588
|
+
const blackness = roundPart(b * 100);
|
3557
3589
|
|
3558
3590
|
newColor = self.color.toHwbString();
|
3559
3591
|
i1.value = `${hue}`;
|
@@ -3625,7 +3657,7 @@
|
|
3625
3657
|
const self = this;
|
3626
3658
|
const { colorPicker } = self;
|
3627
3659
|
|
3628
|
-
if (!hasClass(colorPicker,
|
3660
|
+
if (!['top', 'bottom'].some((c) => hasClass(colorPicker, c))) {
|
3629
3661
|
showDropdown(self, colorPicker);
|
3630
3662
|
}
|
3631
3663
|
}
|
@@ -3642,21 +3674,6 @@
|
|
3642
3674
|
}
|
3643
3675
|
}
|
3644
3676
|
|
3645
|
-
/** Shows the `ColorPicker` dropdown or the presets menu. */
|
3646
|
-
show() {
|
3647
|
-
const self = this;
|
3648
|
-
const { menuToggle } = self;
|
3649
|
-
if (!self.isOpen) {
|
3650
|
-
toggleEventsOnShown(self, true);
|
3651
|
-
self.updateDropdownPosition();
|
3652
|
-
self.isOpen = true;
|
3653
|
-
setAttribute(self.input, 'tabindex', '0');
|
3654
|
-
if (menuToggle) {
|
3655
|
-
setAttribute(menuToggle, 'tabindex', '0');
|
3656
|
-
}
|
3657
|
-
}
|
3658
|
-
}
|
3659
|
-
|
3660
3677
|
/**
|
3661
3678
|
* Hides the currently open `ColorPicker` dropdown.
|
3662
3679
|
* @param {boolean=} focusPrevented
|
@@ -3691,9 +3708,9 @@
|
|
3691
3708
|
if (!focusPrevented) {
|
3692
3709
|
focus(pickerToggle);
|
3693
3710
|
}
|
3694
|
-
setAttribute(input,
|
3711
|
+
setAttribute(input, tabIndex, '-1');
|
3695
3712
|
if (menuToggle) {
|
3696
|
-
setAttribute(menuToggle,
|
3713
|
+
setAttribute(menuToggle, tabIndex, '-1');
|
3697
3714
|
}
|
3698
3715
|
}
|
3699
3716
|
}
|
@@ -3707,7 +3724,10 @@
|
|
3707
3724
|
[...parent.children].forEach((el) => {
|
3708
3725
|
if (el !== input) el.remove();
|
3709
3726
|
});
|
3727
|
+
|
3728
|
+
removeAttribute(input, tabIndex);
|
3710
3729
|
setElementStyle(input, { backgroundColor: '' });
|
3730
|
+
|
3711
3731
|
['txt-light', 'txt-dark'].forEach((c) => removeClass(parent, c));
|
3712
3732
|
Data.remove(input, colorPickerString);
|
3713
3733
|
}
|
@@ -3715,10 +3735,16 @@
|
|
3715
3735
|
|
3716
3736
|
ObjectAssign(ColorPicker, {
|
3717
3737
|
Color,
|
3738
|
+
ColorPalette,
|
3718
3739
|
Version,
|
3719
3740
|
getInstance: getColorPickerInstance,
|
3720
3741
|
init: initColorPicker,
|
3721
3742
|
selector: colorPickerSelector,
|
3743
|
+
// utils important for render
|
3744
|
+
roundPart,
|
3745
|
+
setElementStyle,
|
3746
|
+
setAttribute,
|
3747
|
+
getBoundingClientRect,
|
3722
3748
|
});
|
3723
3749
|
|
3724
3750
|
let CPID = 0;
|
@@ -3726,8 +3752,9 @@
|
|
3726
3752
|
/**
|
3727
3753
|
* `ColorPickerElement` Web Component.
|
3728
3754
|
* @example
|
3729
|
-
* <
|
3730
|
-
*
|
3755
|
+
* <label for="UNIQUE_ID">Label</label>
|
3756
|
+
* <color-picker data-format="hex" data-value="#075">
|
3757
|
+
* <input id="UNIQUE_ID" type="text" class="color-preview btn-appearance">
|
3731
3758
|
* </color-picker>
|
3732
3759
|
*/
|
3733
3760
|
class ColorPickerElement extends HTMLElement {
|
@@ -3808,6 +3835,8 @@
|
|
3808
3835
|
ObjectAssign(ColorPickerElement, {
|
3809
3836
|
Color,
|
3810
3837
|
ColorPicker,
|
3838
|
+
ColorPalette,
|
3839
|
+
getInstance: getColorPickerInstance,
|
3811
3840
|
Version,
|
3812
3841
|
});
|
3813
3842
|
|