@thednp/color-picker 0.0.2-alpha5 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.md +21 -19
  2. package/dist/css/color-picker.css +82 -46
  3. package/dist/css/color-picker.min.css +2 -2
  4. package/dist/css/color-picker.rtl.css +82 -46
  5. package/dist/css/color-picker.rtl.min.css +2 -2
  6. package/dist/js/color-esm.js +2 -5
  7. package/dist/js/color-esm.min.js +1 -1
  8. package/dist/js/color-palette-esm.js +2 -5
  9. package/dist/js/color-palette-esm.min.js +1 -1
  10. package/dist/js/color-palette.js +2 -5
  11. package/dist/js/color-palette.min.js +1 -1
  12. package/dist/js/color-picker-element-esm.js +184 -189
  13. package/dist/js/color-picker-element-esm.min.js +2 -2
  14. package/dist/js/color-picker-element.js +184 -189
  15. package/dist/js/color-picker-element.min.js +2 -2
  16. package/dist/js/color-picker-esm.js +77 -134
  17. package/dist/js/color-picker-esm.min.js +2 -2
  18. package/dist/js/color-picker.js +77 -134
  19. package/dist/js/color-picker.min.js +2 -2
  20. package/dist/js/color.js +2 -5
  21. package/dist/js/color.min.js +1 -1
  22. package/package.json +20 -19
  23. package/src/js/color-picker-element.js +45 -37
  24. package/src/js/color-picker.js +46 -60
  25. package/src/js/color.js +1 -4
  26. package/src/js/index.js +5 -0
  27. package/src/js/util/getColorMenu.js +7 -8
  28. package/src/js/util/setMarkup.js +4 -7
  29. package/src/js/util/toggleCEAttr.js +70 -0
  30. package/src/js/util/version.js +0 -1
  31. package/src/js/version.js +0 -1
  32. package/src/scss/_variables.scss +7 -0
  33. package/src/scss/color-picker.scss +86 -45
  34. package/types/cp.d.ts +31 -17
  35. package/types/index.d.ts +0 -4
  36. package/types/source/source.ts +0 -1
  37. package/types/source/types.d.ts +8 -6
@@ -1,4 +1,4 @@
1
- import { addListener, removeListener } from 'event-listener.js';
1
+ import { addListener, removeListener } from '@thednp/event-listener/src/event-listener';
2
2
 
3
3
  import ariaDescription from 'shorter-js/src/strings/ariaDescription';
4
4
  import ariaSelected from 'shorter-js/src/strings/ariaSelected';
@@ -16,12 +16,12 @@ import focusinEvent from 'shorter-js/src/strings/focusinEvent';
16
16
  import mouseclickEvent from 'shorter-js/src/strings/mouseclickEvent';
17
17
  import keydownEvent from 'shorter-js/src/strings/keydownEvent';
18
18
  import changeEvent from 'shorter-js/src/strings/changeEvent';
19
- import touchstartEvent from 'shorter-js/src/strings/touchstartEvent';
19
+
20
20
  import touchmoveEvent from 'shorter-js/src/strings/touchmoveEvent';
21
- import touchendEvent from 'shorter-js/src/strings/touchendEvent';
22
- import mousedownEvent from 'shorter-js/src/strings/mousedownEvent';
23
- import mousemoveEvent from 'shorter-js/src/strings/mousemoveEvent';
24
- import mouseupEvent from 'shorter-js/src/strings/mouseupEvent';
21
+ import pointerdownEvent from 'shorter-js/src/strings/pointerdownEvent';
22
+ import pointermoveEvent from 'shorter-js/src/strings/pointermoveEvent';
23
+ import pointerupEvent from 'shorter-js/src/strings/pointerupEvent';
24
+
25
25
  import scrollEvent from 'shorter-js/src/strings/scrollEvent';
26
26
  import keyupEvent from 'shorter-js/src/strings/keyupEvent';
27
27
  import resizeEvent from 'shorter-js/src/strings/resizeEvent';
@@ -29,7 +29,6 @@ import focusoutEvent from 'shorter-js/src/strings/focusoutEvent';
29
29
 
30
30
  import getDocument from 'shorter-js/src/get/getDocument';
31
31
  import getDocumentElement from 'shorter-js/src/get/getDocumentElement';
32
- import getWindow from 'shorter-js/src/get/getWindow';
33
32
  import getElementStyle from 'shorter-js/src/get/getElementStyle';
34
33
  import getUID from 'shorter-js/src/get/getUID';
35
34
  import getBoundingClientRect from 'shorter-js/src/get/getBoundingClientRect';
@@ -80,7 +79,7 @@ const colorPickerDefaults = {
80
79
  // ColorPicker Static Methods
81
80
  // ==========================
82
81
 
83
- /** @type {CP.GetInstance<ColorPicker>} */
82
+ /** @type {CP.GetInstance<ColorPicker, HTMLInputElement>} */
84
83
  const getColorPickerInstance = (element) => getInstance(element, colorPickerString);
85
84
 
86
85
  /** @type {CP.InitCallback<ColorPicker>} */
@@ -115,17 +114,12 @@ function toggleEventsOnShown(self, action) {
115
114
  const fn = action ? addListener : removeListener;
116
115
  const { input, colorMenu, parent } = self;
117
116
  const doc = getDocument(input);
118
- const win = getWindow(input);
119
- const pointerEvents = `on${touchstartEvent}` in doc
120
- ? { down: touchstartEvent, move: touchmoveEvent, up: touchendEvent }
121
- : { down: mousedownEvent, move: mousemoveEvent, up: mouseupEvent };
117
+ const win = doc.defaultView;
122
118
 
123
- fn(self.controls, pointerEvents.down, self.pointerDown);
119
+ fn(self.controls, pointerdownEvent, self.pointerDown);
124
120
  self.controlKnobs.forEach((x) => fn(x, keydownEvent, self.handleKnobs));
125
121
 
126
- // @ts-ignore -- this is `Window`
127
122
  fn(win, scrollEvent, self.handleScroll);
128
- // @ts-ignore -- this is `Window`
129
123
  fn(win, resizeEvent, self.update);
130
124
 
131
125
  [input, ...self.inputs].forEach((x) => fn(x, changeEvent, self.changeHandler));
@@ -135,8 +129,8 @@ function toggleEventsOnShown(self, action) {
135
129
  fn(colorMenu, keydownEvent, self.menuKeyHandler);
136
130
  }
137
131
 
138
- fn(doc, pointerEvents.move, self.pointerMove);
139
- fn(doc, pointerEvents.up, self.pointerUp);
132
+ fn(doc, pointermoveEvent, self.pointerMove);
133
+ fn(doc, pointerupEvent, self.pointerUp);
140
134
  fn(parent, focusoutEvent, self.handleFocusOut);
141
135
  fn(doc, keyupEvent, self.handleDismiss);
142
136
  }
@@ -155,6 +149,7 @@ function firePickerChange(self) {
155
149
  * @returns {void}
156
150
  */
157
151
  function removePosition(element) {
152
+ /* istanbul ignore else */
158
153
  if (element) {
159
154
  ['bottom', 'top'].forEach((x) => removeClass(element, x));
160
155
  }
@@ -218,7 +213,6 @@ export default class ColorPicker {
218
213
  constructor(target, config) {
219
214
  const self = this;
220
215
  /** @type {HTMLInputElement} */
221
- // @ts-ignore
222
216
  const input = querySelector(target);
223
217
 
224
218
  // invalidate
@@ -229,7 +223,6 @@ export default class ColorPicker {
229
223
  if (!parent) throw new TypeError('ColorPicker requires a specific markup to work.');
230
224
 
231
225
  /** @type {HTMLElement} */
232
- // @ts-ignore
233
226
  self.parent = parent;
234
227
 
235
228
  /** @type {number} */
@@ -257,6 +250,7 @@ export default class ColorPicker {
257
250
  } = normalizeOptions(this.isCE ? parent : input, colorPickerDefaults, config || {});
258
251
 
259
252
  let translatedColorLabels = colorNames;
253
+ /* istanbul ignore else */
260
254
  if (colorLabels instanceof Array && colorLabels.length === 17) {
261
255
  translatedColorLabels = colorLabels;
262
256
  } else if (colorLabels && colorLabels.split(',').length === 17) {
@@ -273,7 +267,7 @@ export default class ColorPicker {
273
267
  ? JSON.parse(componentLabels) : componentLabels;
274
268
 
275
269
  /** @type {Record<string, string>} */
276
- self.componentLabels = ObjectAssign(colorPickerLabels, tempComponentLabels);
270
+ self.componentLabels = ObjectAssign({ ...colorPickerLabels }, tempComponentLabels);
277
271
 
278
272
  /** @type {Color} */
279
273
  self.color = new Color(input.value || '#fff', format);
@@ -282,14 +276,14 @@ export default class ColorPicker {
282
276
  self.format = format;
283
277
 
284
278
  // set colour defaults
285
- if (colorKeywords instanceof Array) {
279
+ if (colorKeywords instanceof Array && colorKeywords.length) {
286
280
  self.colorKeywords = colorKeywords;
287
281
  } else if (typeof colorKeywords === 'string' && colorKeywords.length) {
288
282
  self.colorKeywords = colorKeywords.split(',').map((x) => x.trim());
289
283
  }
290
284
 
291
285
  // set colour presets
292
- if (colorPresets instanceof Array) {
286
+ if (colorPresets instanceof Array && colorPresets.length) {
293
287
  self.colorPresets = colorPresets;
294
288
  } else if (typeof colorPresets === 'string' && colorPresets.length) {
295
289
  if (isValidJSON(colorPresets)) {
@@ -322,26 +316,20 @@ export default class ColorPicker {
322
316
  const [colorPicker, colorMenu] = getElementsByClassName('color-dropdown', parent);
323
317
  // set main elements
324
318
  /** @type {HTMLElement} */
325
- // @ts-ignore
326
319
  self.pickerToggle = querySelector('.picker-toggle', parent);
327
320
  /** @type {HTMLElement} */
328
- // @ts-ignore
329
321
  self.menuToggle = querySelector('.menu-toggle', parent);
330
322
  /** @type {HTMLElement} */
331
- // @ts-ignore
332
323
  self.colorPicker = colorPicker;
333
324
  /** @type {HTMLElement} */
334
- // @ts-ignore
335
325
  self.colorMenu = colorMenu;
336
326
  /** @type {HTMLInputElement[]} */
337
- // @ts-ignore
338
327
  self.inputs = [...getElementsByClassName('color-input', parent)];
339
328
  const [controls] = getElementsByClassName('color-controls', parent);
340
329
  self.controls = controls;
341
330
  /** @type {(HTMLElement | Element)[]} */
342
331
  self.controlKnobs = [...getElementsByClassName('knob', controls)];
343
332
  /** @type {(HTMLElement)[]} */
344
- // @ts-ignore
345
333
  self.visuals = [...getElementsByClassName('visual-control', controls)];
346
334
 
347
335
  // update colour picker controls, inputs and visuals
@@ -420,6 +408,7 @@ export default class ColorPicker {
420
408
  let colorName;
421
409
 
422
410
  // determine color appearance
411
+ /* istanbul ignore else */
423
412
  if (lightness === 100 && saturation === 0) {
424
413
  colorName = colorLabels.white;
425
414
  } else if (lightness === 0) {
@@ -493,7 +482,6 @@ export default class ColorPicker {
493
482
  * @this {ColorPicker}
494
483
  */
495
484
  handleFocusOut({ relatedTarget }) {
496
- // @ts-ignore
497
485
  if (relatedTarget && !this.parent.contains(relatedTarget)) {
498
486
  this.hide(true);
499
487
  }
@@ -520,13 +508,14 @@ export default class ColorPicker {
520
508
  const self = this;
521
509
  const { activeElement } = getDocument(self.input);
522
510
 
523
- if ((e.type === touchmoveEvent && self.dragElement)
511
+ self.updateDropdownPosition();
512
+
513
+ /* istanbul ignore next */
514
+ if (([pointermoveEvent, touchmoveEvent].includes(e.type) && self.dragElement)
524
515
  || (activeElement && self.controlKnobs.includes(activeElement))) {
525
516
  e.stopPropagation();
526
517
  e.preventDefault();
527
518
  }
528
-
529
- self.updateDropdownPosition();
530
519
  }
531
520
 
532
521
  /**
@@ -536,7 +525,6 @@ export default class ColorPicker {
536
525
  */
537
526
  menuKeyHandler(e) {
538
527
  const { target, code } = e;
539
- // @ts-ignore
540
528
  const { previousElementSibling, nextElementSibling, parentElement } = target;
541
529
  const isColorOptionsMenu = parentElement && hasClass(parentElement, 'color-options');
542
530
  const allSiblings = [...parentElement.children];
@@ -575,20 +563,20 @@ export default class ColorPicker {
575
563
 
576
564
  /**
577
565
  * The `ColorPicker` click event listener for the colour menu presets / defaults.
578
- * @param {Partial<Event>} e
566
+ * @param {Event} e
579
567
  * @this {ColorPicker}
580
568
  */
581
569
  menuClickHandler(e) {
582
570
  const self = this;
583
- /** @type {*} */
584
571
  const { target } = e;
585
572
  const { colorMenu } = self;
586
573
  const newOption = (getAttribute(target, 'data-value') || '').trim();
587
574
  // invalidate for targets other than color options
588
575
  if (!newOption.length) return;
589
576
  const currentActive = querySelector('li.active', colorMenu);
590
- let newColor = nonColors.includes(newOption) ? 'white' : newOption;
591
- newColor = newOption === 'transparent' ? 'rgba(0,0,0,0)' : newOption;
577
+ let newColor = newOption;
578
+ newColor = nonColors.includes(newColor) ? 'white' : newColor;
579
+ newColor = newColor === 'transparent' ? 'rgba(0,0,0,0)' : newColor;
592
580
 
593
581
  const {
594
582
  r, g, b, a,
@@ -600,7 +588,9 @@ export default class ColorPicker {
600
588
 
601
589
  self.update();
602
590
 
591
+ /* istanbul ignore else */
603
592
  if (currentActive !== target) {
593
+ /* istanbul ignore else */
604
594
  if (currentActive) {
605
595
  removeClass(currentActive, 'active');
606
596
  removeAttribute(currentActive, ariaSelected);
@@ -618,15 +608,13 @@ export default class ColorPicker {
618
608
 
619
609
  /**
620
610
  * The `ColorPicker` *touchstart* / *mousedown* events listener for control knobs.
621
- * @param {TouchEvent} e
611
+ * @param {PointerEvent} e
622
612
  * @this {ColorPicker}
623
613
  */
624
614
  pointerDown(e) {
625
615
  const self = this;
626
616
  /** @type {*} */
627
- const {
628
- type, target, touches, pageX, pageY,
629
- } = e;
617
+ const { target, pageX, pageY } = e;
630
618
  const { colorMenu, visuals, controlKnobs } = self;
631
619
  const [v1, v2, v3] = visuals;
632
620
  const [c1, c2, c3] = controlKnobs;
@@ -634,11 +622,10 @@ export default class ColorPicker {
634
622
  const visual = controlKnobs.includes(target) ? target.previousElementSibling : target;
635
623
  const visualRect = getBoundingClientRect(visual);
636
624
  const html = getDocumentElement(v1);
637
- const X = type === 'touchstart' ? touches[0].pageX : pageX;
638
- const Y = type === 'touchstart' ? touches[0].pageY : pageY;
639
- const offsetX = X - html.scrollLeft - visualRect.left;
640
- const offsetY = Y - html.scrollTop - visualRect.top;
625
+ const offsetX = pageX - html.scrollLeft - visualRect.left;
626
+ const offsetY = pageY - html.scrollTop - visualRect.top;
641
627
 
628
+ /* istanbul ignore else */
642
629
  if (target === v1 || target === c1) {
643
630
  self.dragElement = visual;
644
631
  self.changeControl1(offsetX, offsetY);
@@ -662,7 +649,7 @@ export default class ColorPicker {
662
649
 
663
650
  /**
664
651
  * The `ColorPicker` *touchend* / *mouseup* events listener for control knobs.
665
- * @param {TouchEvent} e
652
+ * @param {PointerEvent} e
666
653
  * @this {ColorPicker}
667
654
  */
668
655
  pointerUp({ target }) {
@@ -671,9 +658,8 @@ export default class ColorPicker {
671
658
  const doc = getDocument(parent);
672
659
  const currentOpen = querySelector(`${colorPickerParentSelector}.open`, doc) !== null;
673
660
  const selection = doc.getSelection();
674
- // @ts-ignore
661
+
675
662
  if (!self.dragElement && !selection.toString().length
676
- // @ts-ignore
677
663
  && !parent.contains(target)) {
678
664
  self.hide(currentOpen);
679
665
  }
@@ -683,25 +669,20 @@ export default class ColorPicker {
683
669
 
684
670
  /**
685
671
  * The `ColorPicker` *touchmove* / *mousemove* events listener for control knobs.
686
- * @param {TouchEvent} e
672
+ * @param {PointerEvent} e
687
673
  */
688
674
  pointerMove(e) {
689
675
  const self = this;
690
676
  const { dragElement, visuals } = self;
691
677
  const [v1, v2, v3] = visuals;
692
- const {
693
- // @ts-ignore
694
- type, touches, pageX, pageY,
695
- } = e;
678
+ const { pageX, pageY } = e;
696
679
 
697
680
  if (!dragElement) return;
698
681
 
699
682
  const controlRect = getBoundingClientRect(dragElement);
700
683
  const win = getDocumentElement(v1);
701
- const X = type === touchmoveEvent ? touches[0].pageX : pageX;
702
- const Y = type === touchmoveEvent ? touches[0].pageY : pageY;
703
- const offsetX = X - win.scrollLeft - controlRect.left;
704
- const offsetY = Y - win.scrollTop - controlRect.top;
684
+ const offsetX = pageX - win.scrollLeft - controlRect.left;
685
+ const offsetY = pageY - win.scrollTop - controlRect.top;
705
686
 
706
687
  if (dragElement === v1) {
707
688
  self.changeControl1(offsetX, offsetY);
@@ -735,13 +716,16 @@ export default class ColorPicker {
735
716
  const currentKnob = controlKnobs.find((x) => x === activeElement);
736
717
  const yRatio = offsetHeight / 360;
737
718
 
719
+ /* istanbul ignore else */
738
720
  if (currentKnob) {
739
721
  let offsetX = 0;
740
722
  let offsetY = 0;
741
723
 
724
+ /* istanbul ignore else */
742
725
  if (target === c1) {
743
726
  const xRatio = offsetWidth / 100;
744
727
 
728
+ /* istanbul ignore else */
745
729
  if ([keyArrowLeft, keyArrowRight].includes(code)) {
746
730
  self.controlPositions.c1x += code === keyArrowRight ? xRatio : -xRatio;
747
731
  } else if ([keyArrowUp, keyArrowDown].includes(code)) {
@@ -787,6 +771,7 @@ export default class ColorPicker {
787
771
  const isNonColorValue = self.hasNonColor && nonColors.includes(currentValue);
788
772
  const alpha = i4 ? v4 : (1 - controlPositions.c3y / offsetHeight);
789
773
 
774
+ /* istanbul ignore else */
790
775
  if (activeElement === input || (activeElement && inputs.includes(activeElement))) {
791
776
  if (activeElement === input) {
792
777
  if (isNonColorValue) {
@@ -1101,6 +1086,7 @@ export default class ColorPicker {
1101
1086
  const hue = roundPart(hsl.h * 360);
1102
1087
  let newColor;
1103
1088
 
1089
+ /* istanbul ignore else */
1104
1090
  if (format === 'hex') {
1105
1091
  newColor = self.color.toHexString(true);
1106
1092
  i1.value = self.hex;
@@ -1201,15 +1187,15 @@ export default class ColorPicker {
1201
1187
  const relatedBtn = openPicker ? pickerToggle : menuToggle;
1202
1188
  const animationDuration = openDropdown && getElementTransitionDuration(openDropdown);
1203
1189
 
1204
- // if (!self.isValid) {
1205
1190
  self.value = self.color.toString(true);
1206
- // }
1207
1191
 
1192
+ /* istanbul ignore else */
1208
1193
  if (openDropdown) {
1209
1194
  removeClass(openDropdown, 'show');
1210
1195
  setAttribute(relatedBtn, ariaExpanded, 'false');
1211
1196
  setTimeout(() => {
1212
1197
  removePosition(openDropdown);
1198
+ /* istanbul ignore else */
1213
1199
  if (!querySelector('.show', parent)) {
1214
1200
  removeClass(parent, 'open');
1215
1201
  toggleEventsOnShown(self);
@@ -1222,7 +1208,7 @@ export default class ColorPicker {
1222
1208
  focus(pickerToggle);
1223
1209
  }
1224
1210
  setAttribute(input, tabIndex, '-1');
1225
- if (menuToggle) {
1211
+ if (relatedBtn === menuToggle) {
1226
1212
  setAttribute(menuToggle, tabIndex, '-1');
1227
1213
  }
1228
1214
  }
package/src/js/color.js CHANGED
@@ -640,7 +640,7 @@ function inputToRGB(input) {
640
640
  format = 'hwb';
641
641
  }
642
642
  if (isValidCSSUnit(color.a)) {
643
- a = color.a; // @ts-ignore -- `parseFloat` works with numbers too
643
+ a = color.a;
644
644
  a = isPercentage(`${a}`) || parseFloat(a) > 1 ? bound01(a, 100) : a;
645
645
  }
646
646
  }
@@ -651,9 +651,6 @@ function inputToRGB(input) {
651
651
  return {
652
652
  ok,
653
653
  format,
654
- // r: Math.min(255, Math.max(rgb.r, 0)),
655
- // g: Math.min(255, Math.max(rgb.g, 0)),
656
- // b: Math.min(255, Math.max(rgb.b, 0)),
657
654
  r: rgb.r,
658
655
  g: rgb.g,
659
656
  b: rgb.b,
package/src/js/index.js CHANGED
@@ -1,3 +1,8 @@
1
+ /**
2
+ * A single import is required to add the `CP` namespace to `src` sources.
3
+ * @typedef {import("../../types/index")}
4
+ */
5
+
1
6
  import ColorPicker from './color-picker';
2
7
 
3
8
  export default ColorPicker;
@@ -23,17 +23,16 @@ export default function getColorMenu(self, colorsSource, menuClass) {
23
23
  const isOptionsMenu = menuClass === 'color-options';
24
24
  const isPalette = colorsSource instanceof ColorPalette;
25
25
  const menuLabel = isOptionsMenu ? presetsLabel : defaultsLabel;
26
- let colorsArray = isPalette ? colorsSource.colors : colorsSource;
27
- colorsArray = colorsArray instanceof Array ? colorsArray : [];
26
+ const colorsArray = isPalette ? colorsSource.colors : colorsSource;
28
27
  const colorsCount = colorsArray.length;
29
28
  const { lightSteps } = isPalette ? colorsSource : { lightSteps: null };
30
- const fit = lightSteps || [9, 10].find((x) => colorsCount > x * 2 && !(colorsCount % x)) || 5;
29
+ const fit = lightSteps || [9, 10].find((x) => colorsCount >= x * 2 && !(colorsCount % x)) || 5;
31
30
  const isMultiLine = isOptionsMenu && colorsCount > fit;
32
31
  let rowCountHover = 2;
33
- rowCountHover = isMultiLine && colorsCount >= fit * 2 ? 3 : rowCountHover;
34
- rowCountHover = colorsCount >= fit * 3 ? 4 : rowCountHover;
35
- rowCountHover = colorsCount >= fit * 4 ? 5 : rowCountHover;
36
- const rowCount = rowCountHover - (colorsCount < fit * 3 ? 1 : 2);
32
+ rowCountHover = isMultiLine && colorsCount > fit * 2 ? 3 : rowCountHover;
33
+ rowCountHover = isMultiLine && colorsCount > fit * 3 ? 4 : rowCountHover;
34
+ rowCountHover = isMultiLine && colorsCount > fit * 4 ? 5 : rowCountHover;
35
+ const rowCount = rowCountHover - (colorsCount <= fit * 3 ? 1 : 2);
37
36
  const isScrollable = isMultiLine && colorsCount > rowCount * fit;
38
37
  let finalClass = menuClass;
39
38
  finalClass += isScrollable ? ' scrollable' : '';
@@ -41,7 +40,7 @@ export default function getColorMenu(self, colorsSource, menuClass) {
41
40
  const gap = isMultiLine ? '1px' : '0.25rem';
42
41
  let optionSize = isMultiLine ? 1.75 : 2;
43
42
  optionSize = fit > 5 && isMultiLine ? 1.5 : optionSize;
44
- const menuHeight = `${(rowCount || 1) * optionSize}rem`;
43
+ const menuHeight = `${rowCount * optionSize}rem`;
45
44
  const menuHeightHover = `calc(${rowCountHover} * ${optionSize}rem + ${rowCountHover - 1} * ${gap})`;
46
45
  /** @type {HTMLUListElement} */
47
46
  // @ts-ignore -- <UL> is an `HTMLElement`
@@ -17,7 +17,6 @@ import vHidden from './vHidden';
17
17
  import tabIndex from './tabindex';
18
18
 
19
19
  import Color from '../color';
20
- import ColorPalette from '../color-palette';
21
20
 
22
21
  /**
23
22
  * Generate HTML markup and update instance properties.
@@ -75,16 +74,14 @@ export default function setMarkup(self) {
75
74
  });
76
75
 
77
76
  // color presets
78
- if ((colorPresets instanceof Array && colorPresets.length)
79
- || (colorPresets instanceof ColorPalette && colorPresets.colors)) {
80
- const presetsMenu = getColorMenu(self, colorPresets, 'color-options');
81
- presetsDropdown.append(presetsMenu);
77
+ if (colorPresets) {
78
+ presetsDropdown.append(getColorMenu(self, colorPresets, 'color-options'));
82
79
  }
83
80
 
84
81
  // explicit defaults [reset, initial, inherit, transparent, currentColor]
82
+ // also custom defaults [default: #069, complementary: #930]
85
83
  if (colorKeywords && colorKeywords.length) {
86
- const keywordsMenu = getColorMenu(self, colorKeywords, 'color-defaults');
87
- presetsDropdown.append(keywordsMenu);
84
+ presetsDropdown.append(getColorMenu(self, colorKeywords, 'color-defaults'));
88
85
  }
89
86
 
90
87
  const presetsBtn = createElement({
@@ -0,0 +1,70 @@
1
+ import setAttribute from 'shorter-js/src/attr/setAttribute';
2
+ import removeAttribute from 'shorter-js/src/attr/removeAttribute';
3
+ import ObjectKeys from 'shorter-js/src/misc/ObjectKeys';
4
+
5
+ import ColorPalette from '../color-palette';
6
+ import colorNames from './colorNames';
7
+ import colorPickerLabels from './colorPickerLabels';
8
+
9
+ /**
10
+ * A small utility to toggle `ColorPickerElement` attributes
11
+ * when `connectedCallback` or `disconnectedCallback` methods
12
+ * are called and helps the instance keep its value and settings instact.
13
+ *
14
+ * @param {CP.ColorPickerElement} self ColorPickerElement instance
15
+ * @param {Function=} callback when `true`, attributes are added
16
+ *
17
+ * @example
18
+ * const attributes = [
19
+ * // essentials
20
+ * 'value', 'format',
21
+ * // presets menus
22
+ * 'color-presets', 'color-keywords',
23
+ * // labels
24
+ * 'color-labels', 'component-labels',
25
+ * ];
26
+ */
27
+ export default function toggleCEAttr(self, callback) {
28
+ if (callback) {
29
+ const { input, colorPicker } = self;
30
+
31
+ const {
32
+ value, format, colorPresets, colorKeywords, componentLabels, colorLabels,
33
+ } = colorPicker;
34
+
35
+ const { id, placeholder } = input;
36
+
37
+ setAttribute(self, 'data-id', id);
38
+ setAttribute(self, 'data-value', value);
39
+ setAttribute(self, 'data-format', format);
40
+ setAttribute(self, 'data-placeholder', placeholder);
41
+
42
+ if (ObjectKeys(colorPickerLabels).some((l) => colorPickerLabels[l] !== componentLabels[l])) {
43
+ setAttribute(self, 'data-component-labels', JSON.stringify(componentLabels));
44
+ }
45
+ if (!colorNames.every((c) => c === colorLabels[c])) {
46
+ setAttribute(self, 'data-color-labels', colorNames.map((n) => colorLabels[n]).join(','));
47
+ }
48
+ if (colorPresets instanceof ColorPalette) {
49
+ const { hue, hueSteps, lightSteps } = colorPresets;
50
+ setAttribute(self, 'data-color-presets', JSON.stringify({ hue, hueSteps, lightSteps }));
51
+ }
52
+ if (Array.isArray(colorPresets) && colorPresets.length) {
53
+ setAttribute(self, 'data-color-presets', colorPresets.join(','));
54
+ }
55
+ if (colorKeywords) {
56
+ setAttribute(self, 'data-color-keywords', colorKeywords.join(','));
57
+ }
58
+ setTimeout(callback, 0);
59
+ } else {
60
+ // keep id
61
+ // removeAttribute(self, 'data-id');
62
+ removeAttribute(self, 'data-value');
63
+ removeAttribute(self, 'data-format');
64
+ removeAttribute(self, 'data-placeholder');
65
+ removeAttribute(self, 'data-component-labels');
66
+ removeAttribute(self, 'data-color-labels');
67
+ removeAttribute(self, 'data-color-presets');
68
+ removeAttribute(self, 'data-color-keywords');
69
+ }
70
+ }
@@ -1,4 +1,3 @@
1
- // @ts-ignore
2
1
  import { version } from '../../../package.json';
3
2
 
4
3
  const Version = version;
package/src/js/version.js CHANGED
@@ -1,4 +1,3 @@
1
- // @ts-ignore
2
1
  import { version } from '../../package.json';
3
2
 
4
3
  const Version = version;
@@ -0,0 +1,7 @@
1
+ $transparency-levels: (
2
+ 15, 25, 33, 50, 75, 90
3
+ );
4
+
5
+ $dropdown-transition: transform .33s ease, opacity .33s ease;
6
+ $btn-transition: box-shadow .33s ease, border .33s ease;
7
+ $options-transition: height .33s ease;