@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
|
-
* ColorPicker v0.0.
|
2
|
+
* ColorPicker 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
|
*/
|
@@ -661,13 +661,20 @@ const Data = {
|
|
661
661
|
*/
|
662
662
|
const getInstance = (target, component) => Data.get(target, component);
|
663
663
|
|
664
|
+
/**
|
665
|
+
* Shortcut for `Object.keys()` static method.
|
666
|
+
* @param {Record<string, any>} obj a target object
|
667
|
+
* @returns {string[]}
|
668
|
+
*/
|
669
|
+
const ObjectKeys = (obj) => Object.keys(obj);
|
670
|
+
|
664
671
|
/**
|
665
672
|
* Shortcut for multiple uses of `HTMLElement.style.propertyName` method.
|
666
673
|
* @param {HTMLElement | Element} element target element
|
667
674
|
* @param {Partial<CSSStyleDeclaration>} styles attribute value
|
668
675
|
*/
|
669
676
|
// @ts-ignore
|
670
|
-
const setElementStyle = (element, styles) =>
|
677
|
+
const setElementStyle = (element, styles) => ObjectAssign(element.style, styles);
|
671
678
|
|
672
679
|
/**
|
673
680
|
* Shortcut for `HTMLElement.getAttribute()` method.
|
@@ -710,13 +717,6 @@ function normalizeValue(value) {
|
|
710
717
|
return value;
|
711
718
|
}
|
712
719
|
|
713
|
-
/**
|
714
|
-
* Shortcut for `Object.keys()` static method.
|
715
|
-
* @param {Record<string, any>} obj a target object
|
716
|
-
* @returns {string[]}
|
717
|
-
*/
|
718
|
-
const ObjectKeys = (obj) => Object.keys(obj);
|
719
|
-
|
720
720
|
/**
|
721
721
|
* Shortcut for `String.toLowerCase()`.
|
722
722
|
*
|
@@ -933,7 +933,6 @@ function getColorForm(self) {
|
|
933
933
|
max,
|
934
934
|
step,
|
935
935
|
});
|
936
|
-
// }
|
937
936
|
colorForm.append(cInputLabel, cInput);
|
938
937
|
});
|
939
938
|
return colorForm;
|
@@ -957,6 +956,8 @@ const ariaValueMin = 'aria-valuemin';
|
|
957
956
|
*/
|
958
957
|
const ariaValueMax = 'aria-valuemax';
|
959
958
|
|
959
|
+
const tabIndex = 'tabindex';
|
960
|
+
|
960
961
|
/**
|
961
962
|
* Returns all color controls for `ColorPicker`.
|
962
963
|
*
|
@@ -1022,10 +1023,8 @@ function getColorControls(self) {
|
|
1022
1023
|
const {
|
1023
1024
|
i, c, l, min, max,
|
1024
1025
|
} = template;
|
1025
|
-
// const hidden = i === 2 && format === 'hwb' ? ' v-hidden' : '';
|
1026
1026
|
const control = createElement({
|
1027
1027
|
tagName: 'div',
|
1028
|
-
// className: `color-control${hidden}`,
|
1029
1028
|
className: 'color-control',
|
1030
1029
|
});
|
1031
1030
|
setAttribute(control, 'role', 'presentation');
|
@@ -1045,7 +1044,7 @@ function getColorControls(self) {
|
|
1045
1044
|
|
1046
1045
|
setAttribute(knob, ariaLabel, l);
|
1047
1046
|
setAttribute(knob, 'role', 'slider');
|
1048
|
-
setAttribute(knob,
|
1047
|
+
setAttribute(knob, tabIndex, '0');
|
1049
1048
|
setAttribute(knob, ariaValueMin, `${min}`);
|
1050
1049
|
setAttribute(knob, ariaValueMax, `${max}`);
|
1051
1050
|
control.append(knob);
|
@@ -1055,6 +1054,17 @@ function getColorControls(self) {
|
|
1055
1054
|
return colorControls;
|
1056
1055
|
}
|
1057
1056
|
|
1057
|
+
/**
|
1058
|
+
* Helps setting CSS variables to the color-menu.
|
1059
|
+
* @param {HTMLElement} element
|
1060
|
+
* @param {Record<string,any>} props
|
1061
|
+
*/
|
1062
|
+
function setCSSProperties(element, props) {
|
1063
|
+
ObjectKeys(props).forEach((prop) => {
|
1064
|
+
element.style.setProperty(prop, props[prop]);
|
1065
|
+
});
|
1066
|
+
}
|
1067
|
+
|
1058
1068
|
/**
|
1059
1069
|
* Returns the `document.head` or the `<head>` element.
|
1060
1070
|
*
|
@@ -1065,6 +1075,16 @@ function getDocumentHead(node) {
|
|
1065
1075
|
return getDocument(node).head;
|
1066
1076
|
}
|
1067
1077
|
|
1078
|
+
/**
|
1079
|
+
* Round colour components, for all formats except HEX.
|
1080
|
+
* @param {number} v one of the colour components
|
1081
|
+
* @returns {number} the rounded number
|
1082
|
+
*/
|
1083
|
+
function roundPart(v) {
|
1084
|
+
const floor = Math.floor(v);
|
1085
|
+
return v - floor < 0.5 ? floor : Math.round(v);
|
1086
|
+
}
|
1087
|
+
|
1068
1088
|
// Color supported formats
|
1069
1089
|
const COLOR_FORMAT = ['rgb', 'hex', 'hsl', 'hsb', 'hwb'];
|
1070
1090
|
|
@@ -1232,7 +1252,7 @@ function getRGBFromName(name) {
|
|
1232
1252
|
* @returns {string} - the hexadecimal value
|
1233
1253
|
*/
|
1234
1254
|
function convertDecimalToHex(d) {
|
1235
|
-
return
|
1255
|
+
return roundPart(d * 255).toString(16);
|
1236
1256
|
}
|
1237
1257
|
|
1238
1258
|
/**
|
@@ -1484,9 +1504,9 @@ function hsvToRgb(H, S, V) {
|
|
1484
1504
|
*/
|
1485
1505
|
function rgbToHex(r, g, b, allow3Char) {
|
1486
1506
|
const hex = [
|
1487
|
-
pad2(
|
1488
|
-
pad2(
|
1489
|
-
pad2(
|
1507
|
+
pad2(roundPart(r).toString(16)),
|
1508
|
+
pad2(roundPart(g).toString(16)),
|
1509
|
+
pad2(roundPart(b).toString(16)),
|
1490
1510
|
];
|
1491
1511
|
|
1492
1512
|
// Return a 3 character hex if possible
|
@@ -1511,9 +1531,9 @@ function rgbToHex(r, g, b, allow3Char) {
|
|
1511
1531
|
*/
|
1512
1532
|
function rgbaToHex(r, g, b, a, allow4Char) {
|
1513
1533
|
const hex = [
|
1514
|
-
pad2(
|
1515
|
-
pad2(
|
1516
|
-
pad2(
|
1534
|
+
pad2(roundPart(r).toString(16)),
|
1535
|
+
pad2(roundPart(g).toString(16)),
|
1536
|
+
pad2(roundPart(b).toString(16)),
|
1517
1537
|
pad2(convertDecimalToHex(a)),
|
1518
1538
|
];
|
1519
1539
|
|
@@ -1675,6 +1695,8 @@ function inputToRGB(input) {
|
|
1675
1695
|
let w = null;
|
1676
1696
|
let b = null;
|
1677
1697
|
let h = null;
|
1698
|
+
let r = null;
|
1699
|
+
let g = null;
|
1678
1700
|
let ok = false;
|
1679
1701
|
let format = 'hex';
|
1680
1702
|
|
@@ -1685,7 +1707,10 @@ function inputToRGB(input) {
|
|
1685
1707
|
}
|
1686
1708
|
if (typeof color === 'object') {
|
1687
1709
|
if (isValidCSSUnit(color.r) && isValidCSSUnit(color.g) && isValidCSSUnit(color.b)) {
|
1688
|
-
|
1710
|
+
({ r, g, b } = color);
|
1711
|
+
[r, g, b] = [...[r, g, b]]
|
1712
|
+
.map((n) => bound01(n, isPercentage(n) ? 100 : 255) * 255).map(roundPart);
|
1713
|
+
rgb = { r, g, b }; // RGB values now are all in [0, 255] range
|
1689
1714
|
ok = true;
|
1690
1715
|
format = 'rgb';
|
1691
1716
|
} else if (isValidCSSUnit(color.h) && isValidCSSUnit(color.s) && isValidCSSUnit(color.v)) {
|
@@ -1773,14 +1798,6 @@ class Color {
|
|
1773
1798
|
self.ok = ok;
|
1774
1799
|
/** @type {CP.ColorFormats} */
|
1775
1800
|
self.format = configFormat || format;
|
1776
|
-
|
1777
|
-
// Don't let the range of [0,255] come back in [0,1].
|
1778
|
-
// Potentially lose a little bit of precision here, but will fix issues where
|
1779
|
-
// .5 gets interpreted as half of the total, instead of half of 1
|
1780
|
-
// If it was supposed to be 128, this was already taken care of by `inputToRgb`
|
1781
|
-
if (r < 1) self.r = Math.round(r);
|
1782
|
-
if (g < 1) self.g = Math.round(g);
|
1783
|
-
if (b < 1) self.b = Math.round(b);
|
1784
1801
|
}
|
1785
1802
|
|
1786
1803
|
/**
|
@@ -1796,7 +1813,7 @@ class Color {
|
|
1796
1813
|
* @returns {boolean} the query result
|
1797
1814
|
*/
|
1798
1815
|
get isDark() {
|
1799
|
-
return this.brightness <
|
1816
|
+
return this.brightness < 120;
|
1800
1817
|
}
|
1801
1818
|
|
1802
1819
|
/**
|
@@ -1848,13 +1865,13 @@ class Color {
|
|
1848
1865
|
const {
|
1849
1866
|
r, g, b, a,
|
1850
1867
|
} = this;
|
1851
|
-
const [R, G, B] = [r, g, b].map((x) =>
|
1868
|
+
const [R, G, B] = [r, g, b].map((x) => roundPart(x));
|
1852
1869
|
|
1853
1870
|
return {
|
1854
1871
|
r: R,
|
1855
1872
|
g: G,
|
1856
1873
|
b: B,
|
1857
|
-
a:
|
1874
|
+
a: roundPart(a * 100) / 100,
|
1858
1875
|
};
|
1859
1876
|
}
|
1860
1877
|
|
@@ -1884,7 +1901,7 @@ class Color {
|
|
1884
1901
|
const {
|
1885
1902
|
r, g, b, a,
|
1886
1903
|
} = this.toRgb();
|
1887
|
-
const A = a === 1 ? '' : ` / ${
|
1904
|
+
const A = a === 1 ? '' : ` / ${roundPart(a * 100)}%`;
|
1888
1905
|
|
1889
1906
|
return `rgb(${r} ${g} ${b}${A})`;
|
1890
1907
|
}
|
@@ -1979,10 +1996,10 @@ class Color {
|
|
1979
1996
|
let {
|
1980
1997
|
h, s, l, a,
|
1981
1998
|
} = this.toHsl();
|
1982
|
-
h =
|
1983
|
-
s =
|
1984
|
-
l =
|
1985
|
-
a =
|
1999
|
+
h = roundPart(h * 360);
|
2000
|
+
s = roundPart(s * 100);
|
2001
|
+
l = roundPart(l * 100);
|
2002
|
+
a = roundPart(a * 100) / 100;
|
1986
2003
|
|
1987
2004
|
return a === 1
|
1988
2005
|
? `hsl(${h}, ${s}%, ${l}%)`
|
@@ -1999,11 +2016,11 @@ class Color {
|
|
1999
2016
|
let {
|
2000
2017
|
h, s, l, a,
|
2001
2018
|
} = this.toHsl();
|
2002
|
-
h =
|
2003
|
-
s =
|
2004
|
-
l =
|
2005
|
-
a =
|
2006
|
-
const A = a < 100 ? ` / ${
|
2019
|
+
h = roundPart(h * 360);
|
2020
|
+
s = roundPart(s * 100);
|
2021
|
+
l = roundPart(l * 100);
|
2022
|
+
a = roundPart(a * 100);
|
2023
|
+
const A = a < 100 ? ` / ${roundPart(a)}%` : '';
|
2007
2024
|
|
2008
2025
|
return `hsl(${h}deg ${s}% ${l}%${A})`;
|
2009
2026
|
}
|
@@ -2030,11 +2047,11 @@ class Color {
|
|
2030
2047
|
let {
|
2031
2048
|
h, w, b, a,
|
2032
2049
|
} = this.toHwb();
|
2033
|
-
h =
|
2034
|
-
w =
|
2035
|
-
b =
|
2036
|
-
a =
|
2037
|
-
const A = a < 100 ? ` / ${
|
2050
|
+
h = roundPart(h * 360);
|
2051
|
+
w = roundPart(w * 100);
|
2052
|
+
b = roundPart(b * 100);
|
2053
|
+
a = roundPart(a * 100);
|
2054
|
+
const A = a < 100 ? ` / ${roundPart(a)}%` : '';
|
2038
2055
|
|
2039
2056
|
return `hwb(${h}deg ${w}% ${b}%${A})`;
|
2040
2057
|
}
|
@@ -2180,6 +2197,7 @@ ObjectAssign(Color, {
|
|
2180
2197
|
numberInputToObject,
|
2181
2198
|
stringInputToObject,
|
2182
2199
|
inputToRGB,
|
2200
|
+
roundPart,
|
2183
2201
|
ObjectAssign,
|
2184
2202
|
});
|
2185
2203
|
|
@@ -2195,8 +2213,8 @@ class ColorPalette {
|
|
2195
2213
|
* The `hue` parameter is optional, which would be set to 0.
|
2196
2214
|
* @param {number[]} args represeinting hue, hueSteps, lightSteps
|
2197
2215
|
* * `args.hue` the starting Hue [0, 360]
|
2198
|
-
* * `args.hueSteps` Hue Steps Count [5,
|
2199
|
-
* * `args.lightSteps` Lightness Steps Count [
|
2216
|
+
* * `args.hueSteps` Hue Steps Count [5, 24]
|
2217
|
+
* * `args.lightSteps` Lightness Steps Count [5, 12]
|
2200
2218
|
*/
|
2201
2219
|
constructor(...args) {
|
2202
2220
|
let hue = 0;
|
@@ -2209,24 +2227,32 @@ class ColorPalette {
|
|
2209
2227
|
} else if (args.length === 2) {
|
2210
2228
|
[hueSteps, lightSteps] = args;
|
2211
2229
|
} else {
|
2212
|
-
throw TypeError('
|
2230
|
+
throw TypeError('ColorPalette requires minimum 2 arguments');
|
2213
2231
|
}
|
2214
2232
|
|
2215
2233
|
/** @type {string[]} */
|
2216
2234
|
const colors = [];
|
2217
2235
|
|
2218
2236
|
const hueStep = 360 / hueSteps;
|
2219
|
-
const
|
2220
|
-
const
|
2237
|
+
const half = roundPart((lightSteps - (lightSteps % 2 ? 1 : 0)) / 2);
|
2238
|
+
const estimatedStep = 100 / (lightSteps + (lightSteps % 2 ? 0 : 1)) / 100;
|
2239
|
+
|
2240
|
+
let lightStep = 0.25;
|
2241
|
+
lightStep = [4, 5].includes(lightSteps) ? 0.2 : lightStep;
|
2242
|
+
lightStep = [6, 7].includes(lightSteps) ? 0.15 : lightStep;
|
2243
|
+
lightStep = [8, 9].includes(lightSteps) ? 0.11 : lightStep;
|
2244
|
+
lightStep = [10, 11].includes(lightSteps) ? 0.09 : lightStep;
|
2245
|
+
lightStep = [12, 13].includes(lightSteps) ? 0.075 : lightStep;
|
2246
|
+
lightStep = lightSteps > 13 ? estimatedStep : lightStep;
|
2221
2247
|
|
2222
2248
|
// light tints
|
2223
|
-
for (let i =
|
2224
|
-
lightnessArray = [...lightnessArray, (0.5 + lightStep * (i
|
2249
|
+
for (let i = 1; i < half + 1; i += 1) {
|
2250
|
+
lightnessArray = [...lightnessArray, (0.5 + lightStep * (i))];
|
2225
2251
|
}
|
2226
2252
|
|
2227
2253
|
// dark tints
|
2228
|
-
for (let i =
|
2229
|
-
lightnessArray = [(0.5 - lightStep * (i
|
2254
|
+
for (let i = 1; i < lightSteps - half; i += 1) {
|
2255
|
+
lightnessArray = [(0.5 - lightStep * (i)), ...lightnessArray];
|
2230
2256
|
}
|
2231
2257
|
|
2232
2258
|
// feed `colors` Array
|
@@ -2261,45 +2287,38 @@ function getColorMenu(self, colorsSource, menuClass) {
|
|
2261
2287
|
colorsArray = colorsArray instanceof Array ? colorsArray : [];
|
2262
2288
|
const colorsCount = colorsArray.length;
|
2263
2289
|
const { lightSteps } = isPalette ? colorsSource : { lightSteps: null };
|
2264
|
-
|
2265
|
-
|| Math.max(...[5, 6, 7, 8, 9, 10].filter((x) => colorsCount > (x * 2) && !(colorsCount % x)));
|
2266
|
-
fit = Number.isFinite(fit) ? fit : 5;
|
2290
|
+
const fit = lightSteps || [9, 10].find((x) => colorsCount > x * 2 && !(colorsCount % x)) || 5;
|
2267
2291
|
const isMultiLine = isOptionsMenu && colorsCount > fit;
|
2268
|
-
let rowCountHover =
|
2269
|
-
rowCountHover = isMultiLine && colorsCount
|
2270
|
-
rowCountHover = colorsCount >=
|
2271
|
-
rowCountHover = colorsCount >=
|
2272
|
-
|
2273
|
-
const
|
2274
|
-
const isScrollable = isMultiLine && colorsCount > rowCountHover * fit;
|
2292
|
+
let rowCountHover = 2;
|
2293
|
+
rowCountHover = isMultiLine && colorsCount >= fit * 2 ? 3 : rowCountHover;
|
2294
|
+
rowCountHover = colorsCount >= fit * 3 ? 4 : rowCountHover;
|
2295
|
+
rowCountHover = colorsCount >= fit * 4 ? 5 : rowCountHover;
|
2296
|
+
const rowCount = rowCountHover - (colorsCount < fit * 3 ? 1 : 2);
|
2297
|
+
const isScrollable = isMultiLine && colorsCount > rowCount * fit;
|
2275
2298
|
let finalClass = menuClass;
|
2276
2299
|
finalClass += isScrollable ? ' scrollable' : '';
|
2277
2300
|
finalClass += isMultiLine ? ' multiline' : '';
|
2278
2301
|
const gap = isMultiLine ? '1px' : '0.25rem';
|
2279
2302
|
let optionSize = isMultiLine ? 1.75 : 2;
|
2280
|
-
optionSize =
|
2303
|
+
optionSize = fit > 5 && isMultiLine ? 1.5 : optionSize;
|
2281
2304
|
const menuHeight = `${(rowCount || 1) * optionSize}rem`;
|
2282
2305
|
const menuHeightHover = `calc(${rowCountHover} * ${optionSize}rem + ${rowCountHover - 1} * ${gap})`;
|
2283
|
-
const gridTemplateColumns = `repeat(${fit}, ${optionSize}rem)`;
|
2284
|
-
const gridTemplateRows = `repeat(auto-fill, ${optionSize}rem)`;
|
2285
2306
|
|
2286
2307
|
const menu = createElement({
|
2287
2308
|
tagName: 'ul',
|
2288
2309
|
className: finalClass,
|
2289
2310
|
});
|
2290
2311
|
setAttribute(menu, 'role', 'listbox');
|
2291
|
-
setAttribute(menu, ariaLabel,
|
2292
|
-
|
2293
|
-
if (
|
2294
|
-
|
2295
|
-
|
2296
|
-
|
2297
|
-
|
2298
|
-
|
2299
|
-
|
2300
|
-
|
2301
|
-
};
|
2302
|
-
setElementStyle(menu, menuStyle);
|
2312
|
+
setAttribute(menu, ariaLabel, menuLabel);
|
2313
|
+
|
2314
|
+
if (isScrollable) { // @ts-ignore
|
2315
|
+
setCSSProperties(menu, {
|
2316
|
+
'--grid-item-size': `${optionSize}rem`,
|
2317
|
+
'--grid-fit': fit,
|
2318
|
+
'--grid-gap': gap,
|
2319
|
+
'--grid-height': menuHeight,
|
2320
|
+
'--grid-hover-height': menuHeightHover,
|
2321
|
+
});
|
2303
2322
|
}
|
2304
2323
|
|
2305
2324
|
colorsArray.forEach((x) => {
|
@@ -2314,15 +2333,13 @@ function getColorMenu(self, colorsSource, menuClass) {
|
|
2314
2333
|
innerText: `${label || x}`,
|
2315
2334
|
});
|
2316
2335
|
|
2317
|
-
setAttribute(option,
|
2336
|
+
setAttribute(option, tabIndex, '0');
|
2318
2337
|
setAttribute(option, 'data-value', `${value}`);
|
2319
2338
|
setAttribute(option, 'role', 'option');
|
2320
2339
|
setAttribute(option, ariaSelected, isActive ? 'true' : 'false');
|
2321
2340
|
|
2322
2341
|
if (isOptionsMenu) {
|
2323
|
-
setElementStyle(option, {
|
2324
|
-
width: `${optionSize}rem`, height: `${optionSize}rem`, backgroundColor: x,
|
2325
|
-
});
|
2342
|
+
setElementStyle(option, { backgroundColor: x });
|
2326
2343
|
}
|
2327
2344
|
|
2328
2345
|
menu.append(option);
|
@@ -2344,7 +2361,7 @@ function isValidJSON(str) {
|
|
2344
2361
|
return true;
|
2345
2362
|
}
|
2346
2363
|
|
2347
|
-
var version = "0.0.
|
2364
|
+
var version = "0.0.1alpha3";
|
2348
2365
|
|
2349
2366
|
// @ts-ignore
|
2350
2367
|
|
@@ -2359,8 +2376,8 @@ const colorPickerDefaults = {
|
|
2359
2376
|
componentLabels: colorPickerLabels,
|
2360
2377
|
colorLabels: colorNames,
|
2361
2378
|
format: 'rgb',
|
2362
|
-
colorPresets:
|
2363
|
-
colorKeywords:
|
2379
|
+
colorPresets: false,
|
2380
|
+
colorKeywords: false,
|
2364
2381
|
};
|
2365
2382
|
|
2366
2383
|
// ColorPicker Static Methods
|
@@ -2449,7 +2466,7 @@ function initCallback(self) {
|
|
2449
2466
|
tagName: 'button',
|
2450
2467
|
className: 'menu-toggle btn-appearance',
|
2451
2468
|
});
|
2452
|
-
setAttribute(presetsBtn,
|
2469
|
+
setAttribute(presetsBtn, tabIndex, '-1');
|
2453
2470
|
setAttribute(presetsBtn, ariaExpanded, 'false');
|
2454
2471
|
setAttribute(presetsBtn, ariaHasPopup, 'true');
|
2455
2472
|
|
@@ -2476,7 +2493,7 @@ function initCallback(self) {
|
|
2476
2493
|
if (colorKeywords && nonColors.includes(colorValue)) {
|
2477
2494
|
self.value = colorValue;
|
2478
2495
|
}
|
2479
|
-
setAttribute(input,
|
2496
|
+
setAttribute(input, tabIndex, '-1');
|
2480
2497
|
}
|
2481
2498
|
|
2482
2499
|
/**
|
@@ -2577,8 +2594,19 @@ function showDropdown(self, dropdown) {
|
|
2577
2594
|
addClass(dropdown, 'bottom');
|
2578
2595
|
reflow(dropdown);
|
2579
2596
|
addClass(dropdown, 'show');
|
2597
|
+
|
2580
2598
|
if (isPicker) self.update();
|
2581
|
-
|
2599
|
+
|
2600
|
+
if (!self.isOpen) {
|
2601
|
+
toggleEventsOnShown(self, true);
|
2602
|
+
self.updateDropdownPosition();
|
2603
|
+
self.isOpen = true;
|
2604
|
+
setAttribute(self.input, tabIndex, '0');
|
2605
|
+
if (menuToggle) {
|
2606
|
+
setAttribute(menuToggle, tabIndex, '0');
|
2607
|
+
}
|
2608
|
+
}
|
2609
|
+
|
2582
2610
|
setAttribute(nextBtn, ariaExpanded, 'true');
|
2583
2611
|
if (activeBtn) {
|
2584
2612
|
setAttribute(activeBtn, ariaExpanded, 'false');
|
@@ -2748,7 +2776,7 @@ class ColorPicker {
|
|
2748
2776
|
set value(v) { this.input.value = v; }
|
2749
2777
|
|
2750
2778
|
/** Check if the colour presets include any non-colour. */
|
2751
|
-
get
|
2779
|
+
get hasNonColor() {
|
2752
2780
|
return this.colorKeywords instanceof Array
|
2753
2781
|
&& this.colorKeywords.some((x) => nonColors.includes(x));
|
2754
2782
|
}
|
@@ -2804,7 +2832,7 @@ class ColorPicker {
|
|
2804
2832
|
const { r, g, b } = Color.hslToRgb(hue, 1, 0.5);
|
2805
2833
|
const whiteGrad = 'linear-gradient(rgb(255,255,255) 0%, rgb(255,255,255) 100%)';
|
2806
2834
|
const alpha = 1 - controlPositions.c3y / offsetHeight;
|
2807
|
-
const roundA =
|
2835
|
+
const roundA = roundPart((alpha * 100)) / 100;
|
2808
2836
|
|
2809
2837
|
if (format !== 'hsl') {
|
2810
2838
|
const fill = new Color({
|
@@ -2822,7 +2850,7 @@ class ColorPicker {
|
|
2822
2850
|
});
|
2823
2851
|
setElementStyle(v2, { background: hueGradient });
|
2824
2852
|
} else {
|
2825
|
-
const saturation =
|
2853
|
+
const saturation = roundPart((controlPositions.c2y / offsetHeight) * 100);
|
2826
2854
|
const fill0 = new Color({
|
2827
2855
|
r: 255, g: 0, b: 0, a: alpha,
|
2828
2856
|
}).saturate(-saturation).toRgbString();
|
@@ -2977,12 +3005,12 @@ class ColorPicker {
|
|
2977
3005
|
|
2978
3006
|
self.update();
|
2979
3007
|
|
2980
|
-
if (currentActive) {
|
2981
|
-
removeClass(currentActive, 'active');
|
2982
|
-
removeAttribute(currentActive, ariaSelected);
|
2983
|
-
}
|
2984
|
-
|
2985
3008
|
if (currentActive !== target) {
|
3009
|
+
if (currentActive) {
|
3010
|
+
removeClass(currentActive, 'active');
|
3011
|
+
removeAttribute(currentActive, ariaSelected);
|
3012
|
+
}
|
3013
|
+
|
2986
3014
|
addClass(target, 'active');
|
2987
3015
|
setAttribute(target, ariaSelected, 'true');
|
2988
3016
|
|
@@ -3149,7 +3177,7 @@ class ColorPicker {
|
|
3149
3177
|
const [v1, v2, v3, v4] = format === 'rgb'
|
3150
3178
|
? inputs.map((i) => parseFloat(i.value) / (i === i4 ? 100 : 1))
|
3151
3179
|
: inputs.map((i) => parseFloat(i.value) / (i !== i1 ? 100 : 360));
|
3152
|
-
const isNonColorValue = self.
|
3180
|
+
const isNonColorValue = self.hasNonColor && nonColors.includes(currentValue);
|
3153
3181
|
const alpha = i4 ? v4 : (1 - controlPositions.c3y / offsetHeight);
|
3154
3182
|
|
3155
3183
|
if (activeElement === input || (activeElement && inputs.includes(activeElement))) {
|
@@ -3408,11 +3436,11 @@ class ColorPicker {
|
|
3408
3436
|
} = componentLabels;
|
3409
3437
|
const { r, g, b } = color.toRgb();
|
3410
3438
|
const [knob1, knob2, knob3] = controlKnobs;
|
3411
|
-
const hue =
|
3439
|
+
const hue = roundPart(hsl.h * 360);
|
3412
3440
|
const alpha = color.a;
|
3413
3441
|
const saturationSource = format === 'hsl' ? hsl.s : hsv.s;
|
3414
|
-
const saturation =
|
3415
|
-
const lightness =
|
3442
|
+
const saturation = roundPart(saturationSource * 100);
|
3443
|
+
const lightness = roundPart(hsl.l * 100);
|
3416
3444
|
const hsvl = hsv.v * 100;
|
3417
3445
|
let colorName;
|
3418
3446
|
|
@@ -3459,8 +3487,8 @@ class ColorPicker {
|
|
3459
3487
|
setAttribute(knob2, ariaValueNow, `${saturation}`);
|
3460
3488
|
} else if (format === 'hwb') {
|
3461
3489
|
const { hwb } = self;
|
3462
|
-
const whiteness =
|
3463
|
-
const blackness =
|
3490
|
+
const whiteness = roundPart(hwb.w * 100);
|
3491
|
+
const blackness = roundPart(hwb.b * 100);
|
3464
3492
|
colorLabel = `HWB: ${hue}°, ${whiteness}%, ${blackness}%`;
|
3465
3493
|
setAttribute(knob1, ariaDescription, `${valueLabel}: ${colorLabel}. ${appearanceLabel}: ${colorName}.`);
|
3466
3494
|
setAttribute(knob1, ariaValueText, `${whiteness}% & ${blackness}%`);
|
@@ -3476,7 +3504,7 @@ class ColorPicker {
|
|
3476
3504
|
setAttribute(knob2, ariaValueNow, `${hue}`);
|
3477
3505
|
}
|
3478
3506
|
|
3479
|
-
const alphaValue =
|
3507
|
+
const alphaValue = roundPart(alpha * 100);
|
3480
3508
|
setAttribute(knob3, ariaValueText, `${alphaValue}%`);
|
3481
3509
|
setAttribute(knob3, ariaValueNow, `${alphaValue}`);
|
3482
3510
|
|
@@ -3499,10 +3527,14 @@ class ColorPicker {
|
|
3499
3527
|
/** Updates the control knobs actual positions. */
|
3500
3528
|
updateControls() {
|
3501
3529
|
const { controlKnobs, controlPositions } = this;
|
3530
|
+
const {
|
3531
|
+
c1x, c1y, c2y, c3y,
|
3532
|
+
} = controlPositions;
|
3502
3533
|
const [control1, control2, control3] = controlKnobs;
|
3503
|
-
|
3504
|
-
setElementStyle(
|
3505
|
-
setElementStyle(
|
3534
|
+
|
3535
|
+
setElementStyle(control1, { transform: `translate3d(${c1x - 4}px,${c1y - 4}px,0)` });
|
3536
|
+
setElementStyle(control2, { transform: `translate3d(0,${c2y - 4}px,0)` });
|
3537
|
+
setElementStyle(control3, { transform: `translate3d(0,${c3y - 4}px,0)` });
|
3506
3538
|
}
|
3507
3539
|
|
3508
3540
|
/**
|
@@ -3515,16 +3547,16 @@ class ColorPicker {
|
|
3515
3547
|
value: oldColor, format, inputs, color, hsl,
|
3516
3548
|
} = self;
|
3517
3549
|
const [i1, i2, i3, i4] = inputs;
|
3518
|
-
const alpha =
|
3519
|
-
const hue =
|
3550
|
+
const alpha = roundPart(color.a * 100);
|
3551
|
+
const hue = roundPart(hsl.h * 360);
|
3520
3552
|
let newColor;
|
3521
3553
|
|
3522
3554
|
if (format === 'hex') {
|
3523
3555
|
newColor = self.color.toHexString(true);
|
3524
3556
|
i1.value = self.hex;
|
3525
3557
|
} else if (format === 'hsl') {
|
3526
|
-
const lightness =
|
3527
|
-
const saturation =
|
3558
|
+
const lightness = roundPart(hsl.l * 100);
|
3559
|
+
const saturation = roundPart(hsl.s * 100);
|
3528
3560
|
newColor = self.color.toHslString();
|
3529
3561
|
i1.value = `${hue}`;
|
3530
3562
|
i2.value = `${saturation}`;
|
@@ -3532,8 +3564,8 @@ class ColorPicker {
|
|
3532
3564
|
i4.value = `${alpha}`;
|
3533
3565
|
} else if (format === 'hwb') {
|
3534
3566
|
const { w, b } = self.hwb;
|
3535
|
-
const whiteness =
|
3536
|
-
const blackness =
|
3567
|
+
const whiteness = roundPart(w * 100);
|
3568
|
+
const blackness = roundPart(b * 100);
|
3537
3569
|
|
3538
3570
|
newColor = self.color.toHwbString();
|
3539
3571
|
i1.value = `${hue}`;
|
@@ -3605,7 +3637,7 @@ class ColorPicker {
|
|
3605
3637
|
const self = this;
|
3606
3638
|
const { colorPicker } = self;
|
3607
3639
|
|
3608
|
-
if (!hasClass(colorPicker,
|
3640
|
+
if (!['top', 'bottom'].some((c) => hasClass(colorPicker, c))) {
|
3609
3641
|
showDropdown(self, colorPicker);
|
3610
3642
|
}
|
3611
3643
|
}
|
@@ -3622,21 +3654,6 @@ class ColorPicker {
|
|
3622
3654
|
}
|
3623
3655
|
}
|
3624
3656
|
|
3625
|
-
/** Shows the `ColorPicker` dropdown or the presets menu. */
|
3626
|
-
show() {
|
3627
|
-
const self = this;
|
3628
|
-
const { menuToggle } = self;
|
3629
|
-
if (!self.isOpen) {
|
3630
|
-
toggleEventsOnShown(self, true);
|
3631
|
-
self.updateDropdownPosition();
|
3632
|
-
self.isOpen = true;
|
3633
|
-
setAttribute(self.input, 'tabindex', '0');
|
3634
|
-
if (menuToggle) {
|
3635
|
-
setAttribute(menuToggle, 'tabindex', '0');
|
3636
|
-
}
|
3637
|
-
}
|
3638
|
-
}
|
3639
|
-
|
3640
3657
|
/**
|
3641
3658
|
* Hides the currently open `ColorPicker` dropdown.
|
3642
3659
|
* @param {boolean=} focusPrevented
|
@@ -3671,9 +3688,9 @@ class ColorPicker {
|
|
3671
3688
|
if (!focusPrevented) {
|
3672
3689
|
focus(pickerToggle);
|
3673
3690
|
}
|
3674
|
-
setAttribute(input,
|
3691
|
+
setAttribute(input, tabIndex, '-1');
|
3675
3692
|
if (menuToggle) {
|
3676
|
-
setAttribute(menuToggle,
|
3693
|
+
setAttribute(menuToggle, tabIndex, '-1');
|
3677
3694
|
}
|
3678
3695
|
}
|
3679
3696
|
}
|
@@ -3687,7 +3704,10 @@ class ColorPicker {
|
|
3687
3704
|
[...parent.children].forEach((el) => {
|
3688
3705
|
if (el !== input) el.remove();
|
3689
3706
|
});
|
3707
|
+
|
3708
|
+
removeAttribute(input, tabIndex);
|
3690
3709
|
setElementStyle(input, { backgroundColor: '' });
|
3710
|
+
|
3691
3711
|
['txt-light', 'txt-dark'].forEach((c) => removeClass(parent, c));
|
3692
3712
|
Data.remove(input, colorPickerString);
|
3693
3713
|
}
|
@@ -3695,10 +3715,16 @@ class ColorPicker {
|
|
3695
3715
|
|
3696
3716
|
ObjectAssign(ColorPicker, {
|
3697
3717
|
Color,
|
3718
|
+
ColorPalette,
|
3698
3719
|
Version,
|
3699
3720
|
getInstance: getColorPickerInstance,
|
3700
3721
|
init: initColorPicker,
|
3701
3722
|
selector: colorPickerSelector,
|
3723
|
+
// utils important for render
|
3724
|
+
roundPart,
|
3725
|
+
setElementStyle,
|
3726
|
+
setAttribute,
|
3727
|
+
getBoundingClientRect,
|
3702
3728
|
});
|
3703
3729
|
|
3704
3730
|
export default ColorPicker;
|