@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
package/dist/js/color-picker.js
CHANGED
@@ -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
|
*/
|
@@ -667,13 +667,20 @@
|
|
667
667
|
*/
|
668
668
|
const getInstance = (target, component) => Data.get(target, component);
|
669
669
|
|
670
|
+
/**
|
671
|
+
* Shortcut for `Object.keys()` static method.
|
672
|
+
* @param {Record<string, any>} obj a target object
|
673
|
+
* @returns {string[]}
|
674
|
+
*/
|
675
|
+
const ObjectKeys = (obj) => Object.keys(obj);
|
676
|
+
|
670
677
|
/**
|
671
678
|
* Shortcut for multiple uses of `HTMLElement.style.propertyName` method.
|
672
679
|
* @param {HTMLElement | Element} element target element
|
673
680
|
* @param {Partial<CSSStyleDeclaration>} styles attribute value
|
674
681
|
*/
|
675
682
|
// @ts-ignore
|
676
|
-
const setElementStyle = (element, styles) =>
|
683
|
+
const setElementStyle = (element, styles) => ObjectAssign(element.style, styles);
|
677
684
|
|
678
685
|
/**
|
679
686
|
* Shortcut for `HTMLElement.getAttribute()` method.
|
@@ -716,13 +723,6 @@
|
|
716
723
|
return value;
|
717
724
|
}
|
718
725
|
|
719
|
-
/**
|
720
|
-
* Shortcut for `Object.keys()` static method.
|
721
|
-
* @param {Record<string, any>} obj a target object
|
722
|
-
* @returns {string[]}
|
723
|
-
*/
|
724
|
-
const ObjectKeys = (obj) => Object.keys(obj);
|
725
|
-
|
726
726
|
/**
|
727
727
|
* Shortcut for `String.toLowerCase()`.
|
728
728
|
*
|
@@ -939,7 +939,6 @@
|
|
939
939
|
max,
|
940
940
|
step,
|
941
941
|
});
|
942
|
-
// }
|
943
942
|
colorForm.append(cInputLabel, cInput);
|
944
943
|
});
|
945
944
|
return colorForm;
|
@@ -963,6 +962,8 @@
|
|
963
962
|
*/
|
964
963
|
const ariaValueMax = 'aria-valuemax';
|
965
964
|
|
965
|
+
const tabIndex = 'tabindex';
|
966
|
+
|
966
967
|
/**
|
967
968
|
* Returns all color controls for `ColorPicker`.
|
968
969
|
*
|
@@ -1028,10 +1029,8 @@
|
|
1028
1029
|
const {
|
1029
1030
|
i, c, l, min, max,
|
1030
1031
|
} = template;
|
1031
|
-
// const hidden = i === 2 && format === 'hwb' ? ' v-hidden' : '';
|
1032
1032
|
const control = createElement({
|
1033
1033
|
tagName: 'div',
|
1034
|
-
// className: `color-control${hidden}`,
|
1035
1034
|
className: 'color-control',
|
1036
1035
|
});
|
1037
1036
|
setAttribute(control, 'role', 'presentation');
|
@@ -1051,7 +1050,7 @@
|
|
1051
1050
|
|
1052
1051
|
setAttribute(knob, ariaLabel, l);
|
1053
1052
|
setAttribute(knob, 'role', 'slider');
|
1054
|
-
setAttribute(knob,
|
1053
|
+
setAttribute(knob, tabIndex, '0');
|
1055
1054
|
setAttribute(knob, ariaValueMin, `${min}`);
|
1056
1055
|
setAttribute(knob, ariaValueMax, `${max}`);
|
1057
1056
|
control.append(knob);
|
@@ -1061,6 +1060,17 @@
|
|
1061
1060
|
return colorControls;
|
1062
1061
|
}
|
1063
1062
|
|
1063
|
+
/**
|
1064
|
+
* Helps setting CSS variables to the color-menu.
|
1065
|
+
* @param {HTMLElement} element
|
1066
|
+
* @param {Record<string,any>} props
|
1067
|
+
*/
|
1068
|
+
function setCSSProperties(element, props) {
|
1069
|
+
ObjectKeys(props).forEach((prop) => {
|
1070
|
+
element.style.setProperty(prop, props[prop]);
|
1071
|
+
});
|
1072
|
+
}
|
1073
|
+
|
1064
1074
|
/**
|
1065
1075
|
* Returns the `document.head` or the `<head>` element.
|
1066
1076
|
*
|
@@ -1071,6 +1081,16 @@
|
|
1071
1081
|
return getDocument(node).head;
|
1072
1082
|
}
|
1073
1083
|
|
1084
|
+
/**
|
1085
|
+
* Round colour components, for all formats except HEX.
|
1086
|
+
* @param {number} v one of the colour components
|
1087
|
+
* @returns {number} the rounded number
|
1088
|
+
*/
|
1089
|
+
function roundPart(v) {
|
1090
|
+
const floor = Math.floor(v);
|
1091
|
+
return v - floor < 0.5 ? floor : Math.round(v);
|
1092
|
+
}
|
1093
|
+
|
1074
1094
|
// Color supported formats
|
1075
1095
|
const COLOR_FORMAT = ['rgb', 'hex', 'hsl', 'hsb', 'hwb'];
|
1076
1096
|
|
@@ -1238,7 +1258,7 @@
|
|
1238
1258
|
* @returns {string} - the hexadecimal value
|
1239
1259
|
*/
|
1240
1260
|
function convertDecimalToHex(d) {
|
1241
|
-
return
|
1261
|
+
return roundPart(d * 255).toString(16);
|
1242
1262
|
}
|
1243
1263
|
|
1244
1264
|
/**
|
@@ -1490,9 +1510,9 @@
|
|
1490
1510
|
*/
|
1491
1511
|
function rgbToHex(r, g, b, allow3Char) {
|
1492
1512
|
const hex = [
|
1493
|
-
pad2(
|
1494
|
-
pad2(
|
1495
|
-
pad2(
|
1513
|
+
pad2(roundPart(r).toString(16)),
|
1514
|
+
pad2(roundPart(g).toString(16)),
|
1515
|
+
pad2(roundPart(b).toString(16)),
|
1496
1516
|
];
|
1497
1517
|
|
1498
1518
|
// Return a 3 character hex if possible
|
@@ -1517,9 +1537,9 @@
|
|
1517
1537
|
*/
|
1518
1538
|
function rgbaToHex(r, g, b, a, allow4Char) {
|
1519
1539
|
const hex = [
|
1520
|
-
pad2(
|
1521
|
-
pad2(
|
1522
|
-
pad2(
|
1540
|
+
pad2(roundPart(r).toString(16)),
|
1541
|
+
pad2(roundPart(g).toString(16)),
|
1542
|
+
pad2(roundPart(b).toString(16)),
|
1523
1543
|
pad2(convertDecimalToHex(a)),
|
1524
1544
|
];
|
1525
1545
|
|
@@ -1681,6 +1701,8 @@
|
|
1681
1701
|
let w = null;
|
1682
1702
|
let b = null;
|
1683
1703
|
let h = null;
|
1704
|
+
let r = null;
|
1705
|
+
let g = null;
|
1684
1706
|
let ok = false;
|
1685
1707
|
let format = 'hex';
|
1686
1708
|
|
@@ -1691,7 +1713,10 @@
|
|
1691
1713
|
}
|
1692
1714
|
if (typeof color === 'object') {
|
1693
1715
|
if (isValidCSSUnit(color.r) && isValidCSSUnit(color.g) && isValidCSSUnit(color.b)) {
|
1694
|
-
|
1716
|
+
({ r, g, b } = color);
|
1717
|
+
[r, g, b] = [...[r, g, b]]
|
1718
|
+
.map((n) => bound01(n, isPercentage(n) ? 100 : 255) * 255).map(roundPart);
|
1719
|
+
rgb = { r, g, b }; // RGB values now are all in [0, 255] range
|
1695
1720
|
ok = true;
|
1696
1721
|
format = 'rgb';
|
1697
1722
|
} else if (isValidCSSUnit(color.h) && isValidCSSUnit(color.s) && isValidCSSUnit(color.v)) {
|
@@ -1779,14 +1804,6 @@
|
|
1779
1804
|
self.ok = ok;
|
1780
1805
|
/** @type {CP.ColorFormats} */
|
1781
1806
|
self.format = configFormat || format;
|
1782
|
-
|
1783
|
-
// Don't let the range of [0,255] come back in [0,1].
|
1784
|
-
// Potentially lose a little bit of precision here, but will fix issues where
|
1785
|
-
// .5 gets interpreted as half of the total, instead of half of 1
|
1786
|
-
// If it was supposed to be 128, this was already taken care of by `inputToRgb`
|
1787
|
-
if (r < 1) self.r = Math.round(r);
|
1788
|
-
if (g < 1) self.g = Math.round(g);
|
1789
|
-
if (b < 1) self.b = Math.round(b);
|
1790
1807
|
}
|
1791
1808
|
|
1792
1809
|
/**
|
@@ -1802,7 +1819,7 @@
|
|
1802
1819
|
* @returns {boolean} the query result
|
1803
1820
|
*/
|
1804
1821
|
get isDark() {
|
1805
|
-
return this.brightness <
|
1822
|
+
return this.brightness < 120;
|
1806
1823
|
}
|
1807
1824
|
|
1808
1825
|
/**
|
@@ -1854,13 +1871,13 @@
|
|
1854
1871
|
const {
|
1855
1872
|
r, g, b, a,
|
1856
1873
|
} = this;
|
1857
|
-
const [R, G, B] = [r, g, b].map((x) =>
|
1874
|
+
const [R, G, B] = [r, g, b].map((x) => roundPart(x));
|
1858
1875
|
|
1859
1876
|
return {
|
1860
1877
|
r: R,
|
1861
1878
|
g: G,
|
1862
1879
|
b: B,
|
1863
|
-
a:
|
1880
|
+
a: roundPart(a * 100) / 100,
|
1864
1881
|
};
|
1865
1882
|
}
|
1866
1883
|
|
@@ -1890,7 +1907,7 @@
|
|
1890
1907
|
const {
|
1891
1908
|
r, g, b, a,
|
1892
1909
|
} = this.toRgb();
|
1893
|
-
const A = a === 1 ? '' : ` / ${
|
1910
|
+
const A = a === 1 ? '' : ` / ${roundPart(a * 100)}%`;
|
1894
1911
|
|
1895
1912
|
return `rgb(${r} ${g} ${b}${A})`;
|
1896
1913
|
}
|
@@ -1985,10 +2002,10 @@
|
|
1985
2002
|
let {
|
1986
2003
|
h, s, l, a,
|
1987
2004
|
} = this.toHsl();
|
1988
|
-
h =
|
1989
|
-
s =
|
1990
|
-
l =
|
1991
|
-
a =
|
2005
|
+
h = roundPart(h * 360);
|
2006
|
+
s = roundPart(s * 100);
|
2007
|
+
l = roundPart(l * 100);
|
2008
|
+
a = roundPart(a * 100) / 100;
|
1992
2009
|
|
1993
2010
|
return a === 1
|
1994
2011
|
? `hsl(${h}, ${s}%, ${l}%)`
|
@@ -2005,11 +2022,11 @@
|
|
2005
2022
|
let {
|
2006
2023
|
h, s, l, a,
|
2007
2024
|
} = this.toHsl();
|
2008
|
-
h =
|
2009
|
-
s =
|
2010
|
-
l =
|
2011
|
-
a =
|
2012
|
-
const A = a < 100 ? ` / ${
|
2025
|
+
h = roundPart(h * 360);
|
2026
|
+
s = roundPart(s * 100);
|
2027
|
+
l = roundPart(l * 100);
|
2028
|
+
a = roundPart(a * 100);
|
2029
|
+
const A = a < 100 ? ` / ${roundPart(a)}%` : '';
|
2013
2030
|
|
2014
2031
|
return `hsl(${h}deg ${s}% ${l}%${A})`;
|
2015
2032
|
}
|
@@ -2036,11 +2053,11 @@
|
|
2036
2053
|
let {
|
2037
2054
|
h, w, b, a,
|
2038
2055
|
} = this.toHwb();
|
2039
|
-
h =
|
2040
|
-
w =
|
2041
|
-
b =
|
2042
|
-
a =
|
2043
|
-
const A = a < 100 ? ` / ${
|
2056
|
+
h = roundPart(h * 360);
|
2057
|
+
w = roundPart(w * 100);
|
2058
|
+
b = roundPart(b * 100);
|
2059
|
+
a = roundPart(a * 100);
|
2060
|
+
const A = a < 100 ? ` / ${roundPart(a)}%` : '';
|
2044
2061
|
|
2045
2062
|
return `hwb(${h}deg ${w}% ${b}%${A})`;
|
2046
2063
|
}
|
@@ -2186,6 +2203,7 @@
|
|
2186
2203
|
numberInputToObject,
|
2187
2204
|
stringInputToObject,
|
2188
2205
|
inputToRGB,
|
2206
|
+
roundPart,
|
2189
2207
|
ObjectAssign,
|
2190
2208
|
});
|
2191
2209
|
|
@@ -2201,8 +2219,8 @@
|
|
2201
2219
|
* The `hue` parameter is optional, which would be set to 0.
|
2202
2220
|
* @param {number[]} args represeinting hue, hueSteps, lightSteps
|
2203
2221
|
* * `args.hue` the starting Hue [0, 360]
|
2204
|
-
* * `args.hueSteps` Hue Steps Count [5,
|
2205
|
-
* * `args.lightSteps` Lightness Steps Count [
|
2222
|
+
* * `args.hueSteps` Hue Steps Count [5, 24]
|
2223
|
+
* * `args.lightSteps` Lightness Steps Count [5, 12]
|
2206
2224
|
*/
|
2207
2225
|
constructor(...args) {
|
2208
2226
|
let hue = 0;
|
@@ -2215,24 +2233,32 @@
|
|
2215
2233
|
} else if (args.length === 2) {
|
2216
2234
|
[hueSteps, lightSteps] = args;
|
2217
2235
|
} else {
|
2218
|
-
throw TypeError('
|
2236
|
+
throw TypeError('ColorPalette requires minimum 2 arguments');
|
2219
2237
|
}
|
2220
2238
|
|
2221
2239
|
/** @type {string[]} */
|
2222
2240
|
const colors = [];
|
2223
2241
|
|
2224
2242
|
const hueStep = 360 / hueSteps;
|
2225
|
-
const
|
2226
|
-
const
|
2243
|
+
const half = roundPart((lightSteps - (lightSteps % 2 ? 1 : 0)) / 2);
|
2244
|
+
const estimatedStep = 100 / (lightSteps + (lightSteps % 2 ? 0 : 1)) / 100;
|
2245
|
+
|
2246
|
+
let lightStep = 0.25;
|
2247
|
+
lightStep = [4, 5].includes(lightSteps) ? 0.2 : lightStep;
|
2248
|
+
lightStep = [6, 7].includes(lightSteps) ? 0.15 : lightStep;
|
2249
|
+
lightStep = [8, 9].includes(lightSteps) ? 0.11 : lightStep;
|
2250
|
+
lightStep = [10, 11].includes(lightSteps) ? 0.09 : lightStep;
|
2251
|
+
lightStep = [12, 13].includes(lightSteps) ? 0.075 : lightStep;
|
2252
|
+
lightStep = lightSteps > 13 ? estimatedStep : lightStep;
|
2227
2253
|
|
2228
2254
|
// light tints
|
2229
|
-
for (let i =
|
2230
|
-
lightnessArray = [...lightnessArray, (0.5 + lightStep * (i
|
2255
|
+
for (let i = 1; i < half + 1; i += 1) {
|
2256
|
+
lightnessArray = [...lightnessArray, (0.5 + lightStep * (i))];
|
2231
2257
|
}
|
2232
2258
|
|
2233
2259
|
// dark tints
|
2234
|
-
for (let i =
|
2235
|
-
lightnessArray = [(0.5 - lightStep * (i
|
2260
|
+
for (let i = 1; i < lightSteps - half; i += 1) {
|
2261
|
+
lightnessArray = [(0.5 - lightStep * (i)), ...lightnessArray];
|
2236
2262
|
}
|
2237
2263
|
|
2238
2264
|
// feed `colors` Array
|
@@ -2267,45 +2293,38 @@
|
|
2267
2293
|
colorsArray = colorsArray instanceof Array ? colorsArray : [];
|
2268
2294
|
const colorsCount = colorsArray.length;
|
2269
2295
|
const { lightSteps } = isPalette ? colorsSource : { lightSteps: null };
|
2270
|
-
|
2271
|
-
|| Math.max(...[5, 6, 7, 8, 9, 10].filter((x) => colorsCount > (x * 2) && !(colorsCount % x)));
|
2272
|
-
fit = Number.isFinite(fit) ? fit : 5;
|
2296
|
+
const fit = lightSteps || [9, 10].find((x) => colorsCount > x * 2 && !(colorsCount % x)) || 5;
|
2273
2297
|
const isMultiLine = isOptionsMenu && colorsCount > fit;
|
2274
|
-
let rowCountHover =
|
2275
|
-
rowCountHover = isMultiLine && colorsCount
|
2276
|
-
rowCountHover = colorsCount >=
|
2277
|
-
rowCountHover = colorsCount >=
|
2278
|
-
|
2279
|
-
const
|
2280
|
-
const isScrollable = isMultiLine && colorsCount > rowCountHover * fit;
|
2298
|
+
let rowCountHover = 2;
|
2299
|
+
rowCountHover = isMultiLine && colorsCount >= fit * 2 ? 3 : rowCountHover;
|
2300
|
+
rowCountHover = colorsCount >= fit * 3 ? 4 : rowCountHover;
|
2301
|
+
rowCountHover = colorsCount >= fit * 4 ? 5 : rowCountHover;
|
2302
|
+
const rowCount = rowCountHover - (colorsCount < fit * 3 ? 1 : 2);
|
2303
|
+
const isScrollable = isMultiLine && colorsCount > rowCount * fit;
|
2281
2304
|
let finalClass = menuClass;
|
2282
2305
|
finalClass += isScrollable ? ' scrollable' : '';
|
2283
2306
|
finalClass += isMultiLine ? ' multiline' : '';
|
2284
2307
|
const gap = isMultiLine ? '1px' : '0.25rem';
|
2285
2308
|
let optionSize = isMultiLine ? 1.75 : 2;
|
2286
|
-
optionSize =
|
2309
|
+
optionSize = fit > 5 && isMultiLine ? 1.5 : optionSize;
|
2287
2310
|
const menuHeight = `${(rowCount || 1) * optionSize}rem`;
|
2288
2311
|
const menuHeightHover = `calc(${rowCountHover} * ${optionSize}rem + ${rowCountHover - 1} * ${gap})`;
|
2289
|
-
const gridTemplateColumns = `repeat(${fit}, ${optionSize}rem)`;
|
2290
|
-
const gridTemplateRows = `repeat(auto-fill, ${optionSize}rem)`;
|
2291
2312
|
|
2292
2313
|
const menu = createElement({
|
2293
2314
|
tagName: 'ul',
|
2294
2315
|
className: finalClass,
|
2295
2316
|
});
|
2296
2317
|
setAttribute(menu, 'role', 'listbox');
|
2297
|
-
setAttribute(menu, ariaLabel,
|
2298
|
-
|
2299
|
-
if (
|
2300
|
-
|
2301
|
-
|
2302
|
-
|
2303
|
-
|
2304
|
-
|
2305
|
-
|
2306
|
-
|
2307
|
-
};
|
2308
|
-
setElementStyle(menu, menuStyle);
|
2318
|
+
setAttribute(menu, ariaLabel, menuLabel);
|
2319
|
+
|
2320
|
+
if (isScrollable) { // @ts-ignore
|
2321
|
+
setCSSProperties(menu, {
|
2322
|
+
'--grid-item-size': `${optionSize}rem`,
|
2323
|
+
'--grid-fit': fit,
|
2324
|
+
'--grid-gap': gap,
|
2325
|
+
'--grid-height': menuHeight,
|
2326
|
+
'--grid-hover-height': menuHeightHover,
|
2327
|
+
});
|
2309
2328
|
}
|
2310
2329
|
|
2311
2330
|
colorsArray.forEach((x) => {
|
@@ -2320,15 +2339,13 @@
|
|
2320
2339
|
innerText: `${label || x}`,
|
2321
2340
|
});
|
2322
2341
|
|
2323
|
-
setAttribute(option,
|
2342
|
+
setAttribute(option, tabIndex, '0');
|
2324
2343
|
setAttribute(option, 'data-value', `${value}`);
|
2325
2344
|
setAttribute(option, 'role', 'option');
|
2326
2345
|
setAttribute(option, ariaSelected, isActive ? 'true' : 'false');
|
2327
2346
|
|
2328
2347
|
if (isOptionsMenu) {
|
2329
|
-
setElementStyle(option, {
|
2330
|
-
width: `${optionSize}rem`, height: `${optionSize}rem`, backgroundColor: x,
|
2331
|
-
});
|
2348
|
+
setElementStyle(option, { backgroundColor: x });
|
2332
2349
|
}
|
2333
2350
|
|
2334
2351
|
menu.append(option);
|
@@ -2350,7 +2367,7 @@
|
|
2350
2367
|
return true;
|
2351
2368
|
}
|
2352
2369
|
|
2353
|
-
var version = "0.0.
|
2370
|
+
var version = "0.0.1alpha3";
|
2354
2371
|
|
2355
2372
|
// @ts-ignore
|
2356
2373
|
|
@@ -2365,8 +2382,8 @@
|
|
2365
2382
|
componentLabels: colorPickerLabels,
|
2366
2383
|
colorLabels: colorNames,
|
2367
2384
|
format: 'rgb',
|
2368
|
-
colorPresets:
|
2369
|
-
colorKeywords:
|
2385
|
+
colorPresets: false,
|
2386
|
+
colorKeywords: false,
|
2370
2387
|
};
|
2371
2388
|
|
2372
2389
|
// ColorPicker Static Methods
|
@@ -2455,7 +2472,7 @@
|
|
2455
2472
|
tagName: 'button',
|
2456
2473
|
className: 'menu-toggle btn-appearance',
|
2457
2474
|
});
|
2458
|
-
setAttribute(presetsBtn,
|
2475
|
+
setAttribute(presetsBtn, tabIndex, '-1');
|
2459
2476
|
setAttribute(presetsBtn, ariaExpanded, 'false');
|
2460
2477
|
setAttribute(presetsBtn, ariaHasPopup, 'true');
|
2461
2478
|
|
@@ -2482,7 +2499,7 @@
|
|
2482
2499
|
if (colorKeywords && nonColors.includes(colorValue)) {
|
2483
2500
|
self.value = colorValue;
|
2484
2501
|
}
|
2485
|
-
setAttribute(input,
|
2502
|
+
setAttribute(input, tabIndex, '-1');
|
2486
2503
|
}
|
2487
2504
|
|
2488
2505
|
/**
|
@@ -2583,8 +2600,19 @@
|
|
2583
2600
|
addClass(dropdown, 'bottom');
|
2584
2601
|
reflow(dropdown);
|
2585
2602
|
addClass(dropdown, 'show');
|
2603
|
+
|
2586
2604
|
if (isPicker) self.update();
|
2587
|
-
|
2605
|
+
|
2606
|
+
if (!self.isOpen) {
|
2607
|
+
toggleEventsOnShown(self, true);
|
2608
|
+
self.updateDropdownPosition();
|
2609
|
+
self.isOpen = true;
|
2610
|
+
setAttribute(self.input, tabIndex, '0');
|
2611
|
+
if (menuToggle) {
|
2612
|
+
setAttribute(menuToggle, tabIndex, '0');
|
2613
|
+
}
|
2614
|
+
}
|
2615
|
+
|
2588
2616
|
setAttribute(nextBtn, ariaExpanded, 'true');
|
2589
2617
|
if (activeBtn) {
|
2590
2618
|
setAttribute(activeBtn, ariaExpanded, 'false');
|
@@ -2754,7 +2782,7 @@
|
|
2754
2782
|
set value(v) { this.input.value = v; }
|
2755
2783
|
|
2756
2784
|
/** Check if the colour presets include any non-colour. */
|
2757
|
-
get
|
2785
|
+
get hasNonColor() {
|
2758
2786
|
return this.colorKeywords instanceof Array
|
2759
2787
|
&& this.colorKeywords.some((x) => nonColors.includes(x));
|
2760
2788
|
}
|
@@ -2810,7 +2838,7 @@
|
|
2810
2838
|
const { r, g, b } = Color.hslToRgb(hue, 1, 0.5);
|
2811
2839
|
const whiteGrad = 'linear-gradient(rgb(255,255,255) 0%, rgb(255,255,255) 100%)';
|
2812
2840
|
const alpha = 1 - controlPositions.c3y / offsetHeight;
|
2813
|
-
const roundA =
|
2841
|
+
const roundA = roundPart((alpha * 100)) / 100;
|
2814
2842
|
|
2815
2843
|
if (format !== 'hsl') {
|
2816
2844
|
const fill = new Color({
|
@@ -2828,7 +2856,7 @@
|
|
2828
2856
|
});
|
2829
2857
|
setElementStyle(v2, { background: hueGradient });
|
2830
2858
|
} else {
|
2831
|
-
const saturation =
|
2859
|
+
const saturation = roundPart((controlPositions.c2y / offsetHeight) * 100);
|
2832
2860
|
const fill0 = new Color({
|
2833
2861
|
r: 255, g: 0, b: 0, a: alpha,
|
2834
2862
|
}).saturate(-saturation).toRgbString();
|
@@ -2983,12 +3011,12 @@
|
|
2983
3011
|
|
2984
3012
|
self.update();
|
2985
3013
|
|
2986
|
-
if (currentActive) {
|
2987
|
-
removeClass(currentActive, 'active');
|
2988
|
-
removeAttribute(currentActive, ariaSelected);
|
2989
|
-
}
|
2990
|
-
|
2991
3014
|
if (currentActive !== target) {
|
3015
|
+
if (currentActive) {
|
3016
|
+
removeClass(currentActive, 'active');
|
3017
|
+
removeAttribute(currentActive, ariaSelected);
|
3018
|
+
}
|
3019
|
+
|
2992
3020
|
addClass(target, 'active');
|
2993
3021
|
setAttribute(target, ariaSelected, 'true');
|
2994
3022
|
|
@@ -3155,7 +3183,7 @@
|
|
3155
3183
|
const [v1, v2, v3, v4] = format === 'rgb'
|
3156
3184
|
? inputs.map((i) => parseFloat(i.value) / (i === i4 ? 100 : 1))
|
3157
3185
|
: inputs.map((i) => parseFloat(i.value) / (i !== i1 ? 100 : 360));
|
3158
|
-
const isNonColorValue = self.
|
3186
|
+
const isNonColorValue = self.hasNonColor && nonColors.includes(currentValue);
|
3159
3187
|
const alpha = i4 ? v4 : (1 - controlPositions.c3y / offsetHeight);
|
3160
3188
|
|
3161
3189
|
if (activeElement === input || (activeElement && inputs.includes(activeElement))) {
|
@@ -3414,11 +3442,11 @@
|
|
3414
3442
|
} = componentLabels;
|
3415
3443
|
const { r, g, b } = color.toRgb();
|
3416
3444
|
const [knob1, knob2, knob3] = controlKnobs;
|
3417
|
-
const hue =
|
3445
|
+
const hue = roundPart(hsl.h * 360);
|
3418
3446
|
const alpha = color.a;
|
3419
3447
|
const saturationSource = format === 'hsl' ? hsl.s : hsv.s;
|
3420
|
-
const saturation =
|
3421
|
-
const lightness =
|
3448
|
+
const saturation = roundPart(saturationSource * 100);
|
3449
|
+
const lightness = roundPart(hsl.l * 100);
|
3422
3450
|
const hsvl = hsv.v * 100;
|
3423
3451
|
let colorName;
|
3424
3452
|
|
@@ -3465,8 +3493,8 @@
|
|
3465
3493
|
setAttribute(knob2, ariaValueNow, `${saturation}`);
|
3466
3494
|
} else if (format === 'hwb') {
|
3467
3495
|
const { hwb } = self;
|
3468
|
-
const whiteness =
|
3469
|
-
const blackness =
|
3496
|
+
const whiteness = roundPart(hwb.w * 100);
|
3497
|
+
const blackness = roundPart(hwb.b * 100);
|
3470
3498
|
colorLabel = `HWB: ${hue}°, ${whiteness}%, ${blackness}%`;
|
3471
3499
|
setAttribute(knob1, ariaDescription, `${valueLabel}: ${colorLabel}. ${appearanceLabel}: ${colorName}.`);
|
3472
3500
|
setAttribute(knob1, ariaValueText, `${whiteness}% & ${blackness}%`);
|
@@ -3482,7 +3510,7 @@
|
|
3482
3510
|
setAttribute(knob2, ariaValueNow, `${hue}`);
|
3483
3511
|
}
|
3484
3512
|
|
3485
|
-
const alphaValue =
|
3513
|
+
const alphaValue = roundPart(alpha * 100);
|
3486
3514
|
setAttribute(knob3, ariaValueText, `${alphaValue}%`);
|
3487
3515
|
setAttribute(knob3, ariaValueNow, `${alphaValue}`);
|
3488
3516
|
|
@@ -3505,10 +3533,14 @@
|
|
3505
3533
|
/** Updates the control knobs actual positions. */
|
3506
3534
|
updateControls() {
|
3507
3535
|
const { controlKnobs, controlPositions } = this;
|
3536
|
+
const {
|
3537
|
+
c1x, c1y, c2y, c3y,
|
3538
|
+
} = controlPositions;
|
3508
3539
|
const [control1, control2, control3] = controlKnobs;
|
3509
|
-
|
3510
|
-
setElementStyle(
|
3511
|
-
setElementStyle(
|
3540
|
+
|
3541
|
+
setElementStyle(control1, { transform: `translate3d(${c1x - 4}px,${c1y - 4}px,0)` });
|
3542
|
+
setElementStyle(control2, { transform: `translate3d(0,${c2y - 4}px,0)` });
|
3543
|
+
setElementStyle(control3, { transform: `translate3d(0,${c3y - 4}px,0)` });
|
3512
3544
|
}
|
3513
3545
|
|
3514
3546
|
/**
|
@@ -3521,16 +3553,16 @@
|
|
3521
3553
|
value: oldColor, format, inputs, color, hsl,
|
3522
3554
|
} = self;
|
3523
3555
|
const [i1, i2, i3, i4] = inputs;
|
3524
|
-
const alpha =
|
3525
|
-
const hue =
|
3556
|
+
const alpha = roundPart(color.a * 100);
|
3557
|
+
const hue = roundPart(hsl.h * 360);
|
3526
3558
|
let newColor;
|
3527
3559
|
|
3528
3560
|
if (format === 'hex') {
|
3529
3561
|
newColor = self.color.toHexString(true);
|
3530
3562
|
i1.value = self.hex;
|
3531
3563
|
} else if (format === 'hsl') {
|
3532
|
-
const lightness =
|
3533
|
-
const saturation =
|
3564
|
+
const lightness = roundPart(hsl.l * 100);
|
3565
|
+
const saturation = roundPart(hsl.s * 100);
|
3534
3566
|
newColor = self.color.toHslString();
|
3535
3567
|
i1.value = `${hue}`;
|
3536
3568
|
i2.value = `${saturation}`;
|
@@ -3538,8 +3570,8 @@
|
|
3538
3570
|
i4.value = `${alpha}`;
|
3539
3571
|
} else if (format === 'hwb') {
|
3540
3572
|
const { w, b } = self.hwb;
|
3541
|
-
const whiteness =
|
3542
|
-
const blackness =
|
3573
|
+
const whiteness = roundPart(w * 100);
|
3574
|
+
const blackness = roundPart(b * 100);
|
3543
3575
|
|
3544
3576
|
newColor = self.color.toHwbString();
|
3545
3577
|
i1.value = `${hue}`;
|
@@ -3611,7 +3643,7 @@
|
|
3611
3643
|
const self = this;
|
3612
3644
|
const { colorPicker } = self;
|
3613
3645
|
|
3614
|
-
if (!hasClass(colorPicker,
|
3646
|
+
if (!['top', 'bottom'].some((c) => hasClass(colorPicker, c))) {
|
3615
3647
|
showDropdown(self, colorPicker);
|
3616
3648
|
}
|
3617
3649
|
}
|
@@ -3628,21 +3660,6 @@
|
|
3628
3660
|
}
|
3629
3661
|
}
|
3630
3662
|
|
3631
|
-
/** Shows the `ColorPicker` dropdown or the presets menu. */
|
3632
|
-
show() {
|
3633
|
-
const self = this;
|
3634
|
-
const { menuToggle } = self;
|
3635
|
-
if (!self.isOpen) {
|
3636
|
-
toggleEventsOnShown(self, true);
|
3637
|
-
self.updateDropdownPosition();
|
3638
|
-
self.isOpen = true;
|
3639
|
-
setAttribute(self.input, 'tabindex', '0');
|
3640
|
-
if (menuToggle) {
|
3641
|
-
setAttribute(menuToggle, 'tabindex', '0');
|
3642
|
-
}
|
3643
|
-
}
|
3644
|
-
}
|
3645
|
-
|
3646
3663
|
/**
|
3647
3664
|
* Hides the currently open `ColorPicker` dropdown.
|
3648
3665
|
* @param {boolean=} focusPrevented
|
@@ -3677,9 +3694,9 @@
|
|
3677
3694
|
if (!focusPrevented) {
|
3678
3695
|
focus(pickerToggle);
|
3679
3696
|
}
|
3680
|
-
setAttribute(input,
|
3697
|
+
setAttribute(input, tabIndex, '-1');
|
3681
3698
|
if (menuToggle) {
|
3682
|
-
setAttribute(menuToggle,
|
3699
|
+
setAttribute(menuToggle, tabIndex, '-1');
|
3683
3700
|
}
|
3684
3701
|
}
|
3685
3702
|
}
|
@@ -3693,7 +3710,10 @@
|
|
3693
3710
|
[...parent.children].forEach((el) => {
|
3694
3711
|
if (el !== input) el.remove();
|
3695
3712
|
});
|
3713
|
+
|
3714
|
+
removeAttribute(input, tabIndex);
|
3696
3715
|
setElementStyle(input, { backgroundColor: '' });
|
3716
|
+
|
3697
3717
|
['txt-light', 'txt-dark'].forEach((c) => removeClass(parent, c));
|
3698
3718
|
Data.remove(input, colorPickerString);
|
3699
3719
|
}
|
@@ -3701,10 +3721,16 @@
|
|
3701
3721
|
|
3702
3722
|
ObjectAssign(ColorPicker, {
|
3703
3723
|
Color,
|
3724
|
+
ColorPalette,
|
3704
3725
|
Version,
|
3705
3726
|
getInstance: getColorPickerInstance,
|
3706
3727
|
init: initColorPicker,
|
3707
3728
|
selector: colorPickerSelector,
|
3729
|
+
// utils important for render
|
3730
|
+
roundPart,
|
3731
|
+
setElementStyle,
|
3732
|
+
setAttribute,
|
3733
|
+
getBoundingClientRect,
|
3708
3734
|
});
|
3709
3735
|
|
3710
3736
|
return ColorPicker;
|