@thednp/color-picker 0.0.1-alpha2 → 0.0.1-alpha3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|