@thednp/color-picker 0.0.1-alpha1 → 0.0.1-alpha2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +40 -19
  3. package/dist/css/color-picker.css +481 -337
  4. package/dist/css/color-picker.min.css +2 -0
  5. package/dist/css/color-picker.rtl.css +506 -0
  6. package/dist/css/color-picker.rtl.min.css +2 -0
  7. package/dist/js/color-picker-element-esm.js +3810 -2
  8. package/dist/js/color-picker-element-esm.min.js +2 -0
  9. package/dist/js/color-picker-element.js +2009 -1242
  10. package/dist/js/color-picker-element.min.js +2 -2
  11. package/dist/js/color-picker-esm.js +3704 -0
  12. package/dist/js/color-picker-esm.min.js +2 -0
  13. package/dist/js/color-picker.js +1962 -1256
  14. package/dist/js/color-picker.min.js +2 -2
  15. package/package.json +18 -9
  16. package/src/js/color-palette.js +62 -0
  17. package/src/js/color-picker-element.js +55 -13
  18. package/src/js/color-picker.js +686 -595
  19. package/src/js/color.js +615 -349
  20. package/src/js/index.js +0 -9
  21. package/src/js/util/colorNames.js +2 -152
  22. package/src/js/util/colorPickerLabels.js +22 -0
  23. package/src/js/util/getColorControls.js +103 -0
  24. package/src/js/util/getColorForm.js +27 -19
  25. package/src/js/util/getColorMenu.js +95 -0
  26. package/src/js/util/isValidJSON.js +13 -0
  27. package/src/js/util/nonColors.js +5 -0
  28. package/src/js/util/templates.js +1 -0
  29. package/src/scss/color-picker.rtl.scss +23 -0
  30. package/src/scss/color-picker.scss +430 -0
  31. package/types/cp.d.ts +263 -160
  32. package/types/index.d.ts +9 -2
  33. package/types/source/source.ts +2 -1
  34. package/types/source/types.d.ts +28 -5
  35. package/dist/js/color-picker.esm.js +0 -2998
  36. package/dist/js/color-picker.esm.min.js +0 -2
  37. package/src/js/util/getColorControl.js +0 -49
  38. package/src/js/util/init.js +0 -14
package/src/js/index.js CHANGED
@@ -1,12 +1,3 @@
1
- import querySelectorAll from 'shorter-js/src/selectors/querySelectorAll';
2
1
  import ColorPicker from './color-picker';
3
2
 
4
- function initCallBack() {
5
- const { init, selector } = ColorPicker;
6
- [...querySelectorAll(selector)].forEach(init);
7
- }
8
-
9
- if (document.body) initCallBack();
10
- else document.addEventListener('DOMContentLoaded', initCallBack, { once: true });
11
-
12
3
  export default ColorPicker;
@@ -1,156 +1,6 @@
1
1
  /**
2
- * A complete list of web safe colors.
3
- * @see https://github.com/bahamas10/css-color-names/blob/master/css-color-names.json
2
+ * A list of 17 color names used for WAI-ARIA compliance.
4
3
  * @type {string[]}
5
4
  */
6
- const colorNames = [
7
- 'aliceblue',
8
- 'antiquewhite',
9
- 'aqua',
10
- 'aquamarine',
11
- 'azure',
12
- 'beige',
13
- 'bisque',
14
- 'black',
15
- 'blanchedalmond',
16
- 'blue',
17
- 'blueviolet',
18
- 'brown',
19
- 'burlywood',
20
- 'cadetblue',
21
- 'chartreuse',
22
- 'chocolate',
23
- 'coral',
24
- 'cornflowerblue',
25
- 'cornsilk',
26
- 'crimson',
27
- 'cyan',
28
- 'darkblue',
29
- 'darkcyan',
30
- 'darkgoldenrod',
31
- 'darkgray',
32
- 'darkgreen',
33
- 'darkgrey',
34
- 'darkkhaki',
35
- 'darkmagenta',
36
- 'darkolivegreen',
37
- 'darkorange',
38
- 'darkorchid',
39
- 'darkred',
40
- 'darksalmon',
41
- 'darkseagreen',
42
- 'darkslateblue',
43
- 'darkslategray',
44
- 'darkslategrey',
45
- 'darkturquoise',
46
- 'darkviolet',
47
- 'deeppink',
48
- 'deepskyblue',
49
- 'dimgray',
50
- 'dimgrey',
51
- 'dodgerblue',
52
- 'firebrick',
53
- 'floralwhite',
54
- 'forestgreen',
55
- 'fuchsia',
56
- 'gainsboro',
57
- 'ghostwhite',
58
- 'goldenrod',
59
- 'gold',
60
- 'gray',
61
- 'green',
62
- 'greenyellow',
63
- 'grey',
64
- 'honeydew',
65
- 'hotpink',
66
- 'indianred',
67
- 'indigo',
68
- 'ivory',
69
- 'khaki',
70
- 'lavenderblush',
71
- 'lavender',
72
- 'lawngreen',
73
- 'lemonchiffon',
74
- 'lightblue',
75
- 'lightcoral',
76
- 'lightcyan',
77
- 'lightgoldenrodyellow',
78
- 'lightgray',
79
- 'lightgreen',
80
- 'lightgrey',
81
- 'lightpink',
82
- 'lightsalmon',
83
- 'lightseagreen',
84
- 'lightskyblue',
85
- 'lightslategray',
86
- 'lightslategrey',
87
- 'lightsteelblue',
88
- 'lightyellow',
89
- 'lime',
90
- 'limegreen',
91
- 'linen',
92
- 'magenta',
93
- 'maroon',
94
- 'mediumaquamarine',
95
- 'mediumblue',
96
- 'mediumorchid',
97
- 'mediumpurple',
98
- 'mediumseagreen',
99
- 'mediumslateblue',
100
- 'mediumspringgreen',
101
- 'mediumturquoise',
102
- 'mediumvioletred',
103
- 'midnightblue',
104
- 'mintcream',
105
- 'mistyrose',
106
- 'moccasin',
107
- 'navajowhite',
108
- 'navy',
109
- 'oldlace',
110
- 'olive',
111
- 'olivedrab',
112
- 'orange',
113
- 'orangered',
114
- 'orchid',
115
- 'palegoldenrod',
116
- 'palegreen',
117
- 'paleturquoise',
118
- 'palevioletred',
119
- 'papayawhip',
120
- 'peachpuff',
121
- 'peru',
122
- 'pink',
123
- 'plum',
124
- 'powderblue',
125
- 'purple',
126
- 'rebeccapurple',
127
- 'red',
128
- 'rosybrown',
129
- 'royalblue',
130
- 'saddlebrown',
131
- 'salmon',
132
- 'sandybrown',
133
- 'seagreen',
134
- 'seashell',
135
- 'sienna',
136
- 'silver',
137
- 'skyblue',
138
- 'slateblue',
139
- 'slategray',
140
- 'slategrey',
141
- 'snow',
142
- 'springgreen',
143
- 'steelblue',
144
- 'tan',
145
- 'teal',
146
- 'thistle',
147
- 'tomato',
148
- 'turquoise',
149
- 'violet',
150
- 'wheat',
151
- 'white',
152
- 'whitesmoke',
153
- 'yellow',
154
- 'yellowgreen',
155
- ];
5
+ const colorNames = ['white', 'black', 'grey', 'red', 'orange', 'brown', 'gold', 'olive', 'yellow', 'lime', 'green', 'teal', 'cyan', 'blue', 'violet', 'magenta', 'pink'];
156
6
  export default colorNames;
@@ -0,0 +1,22 @@
1
+ /** @type {Record<string, string>} */
2
+ const colorPickerLabels = {
3
+ pickerLabel: 'Colour Picker',
4
+ appearanceLabel: 'Colour Appearance',
5
+ valueLabel: 'Colour Value',
6
+ toggleLabel: 'Select Colour',
7
+ presetsLabel: 'Colour Presets',
8
+ defaultsLabel: 'Colour Defaults',
9
+ formatLabel: 'Format',
10
+ alphaLabel: 'Alpha',
11
+ hexLabel: 'Hexadecimal',
12
+ hueLabel: 'Hue',
13
+ whitenessLabel: 'Whiteness',
14
+ blacknessLabel: 'Blackness',
15
+ saturationLabel: 'Saturation',
16
+ lightnessLabel: 'Lightness',
17
+ redLabel: 'Red',
18
+ greenLabel: 'Green',
19
+ blueLabel: 'Blue',
20
+ };
21
+
22
+ export default colorPickerLabels;
@@ -0,0 +1,103 @@
1
+ import ariaLabel from 'shorter-js/src/strings/ariaLabel';
2
+ import ariaValueMin from 'shorter-js/src/strings/ariaValueMin';
3
+ import ariaValueMax from 'shorter-js/src/strings/ariaValueMax';
4
+ import createElement from 'shorter-js/src/misc/createElement';
5
+ import setAttribute from 'shorter-js/src/attr/setAttribute';
6
+
7
+ /**
8
+ * Returns all color controls for `ColorPicker`.
9
+ *
10
+ * @param {CP.ColorPicker} self the `ColorPicker` instance
11
+ * @returns {HTMLElement | Element} color controls
12
+ */
13
+ export default function getColorControls(self) {
14
+ const { format, componentLabels } = self;
15
+ const {
16
+ hueLabel, alphaLabel, lightnessLabel, saturationLabel,
17
+ whitenessLabel, blacknessLabel,
18
+ } = componentLabels;
19
+
20
+ const max1 = format === 'hsl' ? 360 : 100;
21
+ const max2 = format === 'hsl' ? 100 : 360;
22
+ const max3 = 100;
23
+
24
+ let ctrl1Label = format === 'hsl'
25
+ ? `${hueLabel} & ${lightnessLabel}`
26
+ : `${lightnessLabel} & ${saturationLabel}`;
27
+
28
+ ctrl1Label = format === 'hwb'
29
+ ? `${whitenessLabel} & ${blacknessLabel}`
30
+ : ctrl1Label;
31
+
32
+ const ctrl2Label = format === 'hsl'
33
+ ? `${saturationLabel}`
34
+ : `${hueLabel}`;
35
+
36
+ const colorControls = createElement({
37
+ tagName: 'div',
38
+ className: `color-controls ${format}`,
39
+ });
40
+
41
+ const colorPointer = 'color-pointer';
42
+ const colorSlider = 'color-slider';
43
+
44
+ const controls = [
45
+ {
46
+ i: 1,
47
+ c: colorPointer,
48
+ l: ctrl1Label,
49
+ min: 0,
50
+ max: max1,
51
+ },
52
+ {
53
+ i: 2,
54
+ c: colorSlider,
55
+ l: ctrl2Label,
56
+ min: 0,
57
+ max: max2,
58
+ },
59
+ {
60
+ i: 3,
61
+ c: colorSlider,
62
+ l: alphaLabel,
63
+ min: 0,
64
+ max: max3,
65
+ },
66
+ ];
67
+
68
+ controls.forEach((template) => {
69
+ const {
70
+ i, c, l, min, max,
71
+ } = template;
72
+ // const hidden = i === 2 && format === 'hwb' ? ' v-hidden' : '';
73
+ const control = createElement({
74
+ tagName: 'div',
75
+ // className: `color-control${hidden}`,
76
+ className: 'color-control',
77
+ });
78
+ setAttribute(control, 'role', 'presentation');
79
+
80
+ control.append(
81
+ createElement({
82
+ tagName: 'div',
83
+ className: `visual-control visual-control${i}`,
84
+ }),
85
+ );
86
+
87
+ const knob = createElement({
88
+ tagName: 'div',
89
+ className: `${c} knob`,
90
+ ariaLive: 'polite',
91
+ });
92
+
93
+ setAttribute(knob, ariaLabel, l);
94
+ setAttribute(knob, 'role', 'slider');
95
+ setAttribute(knob, 'tabindex', '0');
96
+ setAttribute(knob, ariaValueMin, `${min}`);
97
+ setAttribute(knob, ariaValueMax, `${max}`);
98
+ control.append(knob);
99
+ colorControls.append(control);
100
+ });
101
+
102
+ return colorControls;
103
+ }
@@ -6,12 +6,13 @@ import toUpperCase from 'shorter-js/src/misc/toUpperCase';
6
6
  import vHidden from './vHidden';
7
7
 
8
8
  /**
9
- * Returns the color form.
9
+ * Returns the color form for `ColorPicker`.
10
+ *
10
11
  * @param {CP.ColorPicker} self the `ColorPicker` instance
11
- * @returns {HTMLElement | Element}
12
+ * @returns {HTMLElement | Element} a new `<div>` element with color component `<input>`
12
13
  */
13
14
  export default function getColorForm(self) {
14
- const { format, id } = self;
15
+ const { format, id, componentLabels } = self;
15
16
  const colorForm = createElement({
16
17
  tagName: 'div',
17
18
  className: `color-form ${format}`,
@@ -20,38 +21,45 @@ export default function getColorForm(self) {
20
21
  let components = ['hex'];
21
22
  if (format === 'rgb') components = ['red', 'green', 'blue', 'alpha'];
22
23
  else if (format === 'hsl') components = ['hue', 'saturation', 'lightness', 'alpha'];
24
+ else if (format === 'hwb') components = ['hue', 'whiteness', 'blackness', 'alpha'];
23
25
 
24
26
  components.forEach((c) => {
25
27
  const [C] = format === 'hex' ? ['#'] : toUpperCase(c).split('');
26
28
  const cID = `color_${format}_${c}_${id}`;
29
+ const formatLabel = componentLabels[`${c}Label`];
27
30
  const cInputLabel = createElement({ tagName: 'label' });
28
31
  setAttribute(cInputLabel, 'for', cID);
29
32
  cInputLabel.append(
30
33
  createElement({ tagName: 'span', ariaHidden: 'true', innerText: `${C}:` }),
31
- createElement({ tagName: 'span', className: vHidden, innerText: `${c}` }),
34
+ createElement({ tagName: 'span', className: vHidden, innerText: formatLabel }),
32
35
  );
33
36
  const cInput = createElement({
34
37
  tagName: 'input',
35
- id: cID, // name: cID,
38
+ id: cID,
39
+ // name: cID, - prevent saving the value to a form
36
40
  type: format === 'hex' ? 'text' : 'number',
37
- value: c === 'alpha' ? '1' : '0',
41
+ value: c === 'alpha' ? '100' : '0',
38
42
  className: `color-input ${c}`,
39
- autocomplete: 'off',
40
- spellcheck: 'false',
41
43
  });
42
- if (format !== 'hex') {
43
- // alpha
44
- let max = '1';
45
- let step = '0.01';
46
- if (c !== 'alpha') {
47
- if (format === 'rgb') { max = '255'; step = '1'; } else if (c === 'hue') { max = '360'; step = '1'; } else { max = '100'; step = '1'; }
44
+ setAttribute(cInput, 'autocomplete', 'off');
45
+ setAttribute(cInput, 'spellcheck', 'false');
46
+
47
+ // alpha
48
+ let max = '100';
49
+ let step = '1';
50
+ if (c !== 'alpha') {
51
+ if (format === 'rgb') {
52
+ max = '255'; step = '1';
53
+ } else if (c === 'hue') {
54
+ max = '360'; step = '1';
48
55
  }
49
- ObjectAssign(cInput, {
50
- min: '0',
51
- max,
52
- step,
53
- });
54
56
  }
57
+ ObjectAssign(cInput, {
58
+ min: '0',
59
+ max,
60
+ step,
61
+ });
62
+ // }
55
63
  colorForm.append(cInputLabel, cInput);
56
64
  });
57
65
  return colorForm;
@@ -0,0 +1,95 @@
1
+ import ariaLabel from 'shorter-js/src/strings/ariaLabel';
2
+ import ariaSelected from 'shorter-js/src/strings/ariaSelected';
3
+ import setAttribute from 'shorter-js/src/attr/setAttribute';
4
+ import getAttribute from 'shorter-js/src/attr/getAttribute';
5
+ import createElement from 'shorter-js/src/misc/createElement';
6
+ import setElementStyle from 'shorter-js/src/misc/setElementStyle';
7
+
8
+ import Color from '../color';
9
+ import ColorPalette from '../color-palette';
10
+
11
+ /**
12
+ * Returns a color-defaults with given values and class.
13
+ * @param {CP.ColorPicker} self
14
+ * @param {CP.ColorPalette | string[]} colorsSource
15
+ * @param {string} menuClass
16
+ * @returns {HTMLElement | Element}
17
+ */
18
+ export default function getColorMenu(self, colorsSource, menuClass) {
19
+ const { input, format, componentLabels } = self;
20
+ const { defaultsLabel, presetsLabel } = componentLabels;
21
+ const isOptionsMenu = menuClass === 'color-options';
22
+ const isPalette = colorsSource instanceof ColorPalette;
23
+ const menuLabel = isOptionsMenu ? presetsLabel : defaultsLabel;
24
+ let colorsArray = isPalette ? colorsSource.colors : colorsSource;
25
+ colorsArray = colorsArray instanceof Array ? colorsArray : [];
26
+ const colorsCount = colorsArray.length;
27
+ const { lightSteps } = isPalette ? colorsSource : { lightSteps: null };
28
+ let fit = lightSteps
29
+ || Math.max(...[5, 6, 7, 8, 9, 10].filter((x) => colorsCount > (x * 2) && !(colorsCount % x)));
30
+ fit = Number.isFinite(fit) ? fit : 5;
31
+ const isMultiLine = isOptionsMenu && colorsCount > fit;
32
+ let rowCountHover = 1;
33
+ rowCountHover = isMultiLine && colorsCount < 27 ? 2 : rowCountHover;
34
+ rowCountHover = colorsCount >= 27 ? 3 : rowCountHover;
35
+ rowCountHover = colorsCount >= 36 ? 4 : rowCountHover;
36
+ rowCountHover = colorsCount >= 45 ? 5 : rowCountHover;
37
+ const rowCount = rowCountHover - (colorsCount < 27 ? 1 : 2);
38
+ const isScrollable = isMultiLine && colorsCount > rowCountHover * fit;
39
+ let finalClass = menuClass;
40
+ finalClass += isScrollable ? ' scrollable' : '';
41
+ finalClass += isMultiLine ? ' multiline' : '';
42
+ const gap = isMultiLine ? '1px' : '0.25rem';
43
+ let optionSize = isMultiLine ? 1.75 : 2;
44
+ optionSize = !(colorsCount % 10) && isMultiLine ? 1.5 : optionSize;
45
+ const menuHeight = `${(rowCount || 1) * optionSize}rem`;
46
+ const menuHeightHover = `calc(${rowCountHover} * ${optionSize}rem + ${rowCountHover - 1} * ${gap})`;
47
+ const gridTemplateColumns = `repeat(${fit}, ${optionSize}rem)`;
48
+ const gridTemplateRows = `repeat(auto-fill, ${optionSize}rem)`;
49
+
50
+ const menu = createElement({
51
+ tagName: 'ul',
52
+ className: finalClass,
53
+ });
54
+ setAttribute(menu, 'role', 'listbox');
55
+ setAttribute(menu, ariaLabel, `${menuLabel}`);
56
+
57
+ if (isOptionsMenu) {
58
+ if (isScrollable) {
59
+ const styleText = 'this.style.height=';
60
+ setAttribute(menu, 'onmouseout', `${styleText}'${menuHeight}'`);
61
+ setAttribute(menu, 'onmouseover', `${styleText}'${menuHeightHover}'`);
62
+ }
63
+ const menuStyle = {
64
+ height: isScrollable ? menuHeight : '', gridTemplateColumns, gridTemplateRows, gap,
65
+ };
66
+ setElementStyle(menu, menuStyle);
67
+ }
68
+
69
+ colorsArray.forEach((x) => {
70
+ const [value, label] = x.trim().split(':');
71
+ const xRealColor = new Color(value, format).toString();
72
+ const isActive = xRealColor === getAttribute(input, 'value');
73
+ const active = isActive ? ' active' : '';
74
+
75
+ const option = createElement({
76
+ tagName: 'li',
77
+ className: `color-option${active}`,
78
+ innerText: `${label || x}`,
79
+ });
80
+
81
+ setAttribute(option, 'tabindex', '0');
82
+ setAttribute(option, 'data-value', `${value}`);
83
+ setAttribute(option, 'role', 'option');
84
+ setAttribute(option, ariaSelected, isActive ? 'true' : 'false');
85
+
86
+ if (isOptionsMenu) {
87
+ setElementStyle(option, {
88
+ width: `${optionSize}rem`, height: `${optionSize}rem`, backgroundColor: x,
89
+ });
90
+ }
91
+
92
+ menu.append(option);
93
+ });
94
+ return menu;
95
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Check if a string is valid JSON string.
3
+ * @param {string} str the string input
4
+ * @returns {boolean} the query result
5
+ */
6
+ export default function isValidJSON(str) {
7
+ try {
8
+ JSON.parse(str);
9
+ } catch (e) {
10
+ return false;
11
+ }
12
+ return true;
13
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * A list of explicit default non-color values.
3
+ */
4
+ const nonColors = ['transparent', 'currentColor', 'inherit', 'revert', 'initial'];
5
+ export default nonColors;
@@ -1,3 +1,4 @@
1
+ /** A future project to allow using custom `ColorPicker` templates */
1
2
  const templates = {
2
3
  control: {
3
4
  tagName: 'div',
@@ -0,0 +1,23 @@
1
+ @import "color-picker";
2
+
3
+ [dir="rtl"] {
4
+ .color-preview { text-align: right; }
5
+
6
+ .menu-toggle {
7
+ right: auto; left: 0;
8
+ border-radius: .25rem 0 0 .25rem;
9
+ }
10
+ .color-dropdown.picker {
11
+ right: 0; left: auto;
12
+ }
13
+ .color-dropdown.menu {
14
+ right: auto; left: 0;
15
+ }
16
+ .color-control + .color-control {
17
+ margin-right: .5rem;
18
+ margin-left: 0;
19
+ }
20
+ .color-options.scrollable {
21
+ margin: 0 0 0 -.5rem;
22
+ }
23
+ }