@thednp/color-picker 2.0.2 → 2.0.4

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 (55) hide show
  1. package/README.md +25 -14
  2. package/dist/css/color-picker.css +3 -6
  3. package/dist/css/color-picker.css.map +1 -0
  4. package/dist/css/color-picker.min.css +1 -2
  5. package/dist/css/color-picker.min.css.map +1 -0
  6. package/dist/css/color-picker.rtl.css +3 -6
  7. package/dist/css/color-picker.rtl.css.map +1 -0
  8. package/dist/css/color-picker.rtl.min.css +1 -2
  9. package/dist/css/color-picker.rtl.min.css.map +1 -0
  10. package/dist/js/color-picker.cjs +2 -2
  11. package/dist/js/color-picker.cjs.map +1 -1
  12. package/dist/js/color-picker.d.ts +307 -300
  13. package/dist/js/color-picker.js +2 -2
  14. package/dist/js/color-picker.js.map +1 -1
  15. package/dist/js/color-picker.mjs +390 -491
  16. package/dist/js/color-picker.mjs.map +1 -1
  17. package/package.json +40 -47
  18. package/.eslintrc.cjs +0 -199
  19. package/.lgtm.yml +0 -9
  20. package/.prettierrc.json +0 -15
  21. package/.stylelintrc.json +0 -236
  22. package/compile.cjs +0 -51
  23. package/dts.config.ts +0 -15
  24. package/src/scss/_variables.scss +0 -6
  25. package/src/scss/color-picker.rtl.scss +0 -27
  26. package/src/scss/color-picker.scss +0 -536
  27. package/src/ts/colorPalette.ts +0 -89
  28. package/src/ts/index.ts +0 -1237
  29. package/src/ts/interface/ColorNames.ts +0 -20
  30. package/src/ts/interface/colorPickerLabels.ts +0 -20
  31. package/src/ts/interface/colorPickerOptions.ts +0 -11
  32. package/src/ts/interface/paletteOptions.ts +0 -6
  33. package/src/ts/util/colorNames.ts +0 -21
  34. package/src/ts/util/colorPickerLabels.ts +0 -24
  35. package/src/ts/util/getColorControls.ts +0 -90
  36. package/src/ts/util/getColorForm.ts +0 -75
  37. package/src/ts/util/getColorMenu.ts +0 -83
  38. package/src/ts/util/isValidJSON.ts +0 -19
  39. package/src/ts/util/setMarkup.ts +0 -130
  40. package/src/ts/util/vHidden.ts +0 -2
  41. package/test/color-palette.test.ts +0 -137
  42. package/test/color-picker.test.ts +0 -705
  43. package/test/fixtures/colorNamesFrench.js +0 -3
  44. package/test/fixtures/componentLabelsFrench.js +0 -21
  45. package/test/fixtures/format.js +0 -3
  46. package/test/fixtures/getMarkup.js +0 -36
  47. package/test/fixtures/getRandomInt.js +0 -6
  48. package/test/fixtures/sampleWebcolors.js +0 -18
  49. package/test/fixtures/swipe.ts +0 -33
  50. package/test/fixtures/testSample.js +0 -8
  51. package/test/fixtures/write.ts +0 -37
  52. package/tsconfig.json +0 -47
  53. package/vite.config.mts +0 -27
  54. package/vitest.config-ui.ts +0 -26
  55. package/vitest.config.ts +0 -26
@@ -1,705 +0,0 @@
1
- import { expect, it, describe, beforeEach, vi } from 'vitest';
2
- import Color from '@thednp/color';
3
- import ColorPalette from '~/ts/colorPalette';
4
- import ColorPicker from '~/ts/index';
5
- import getRandomInt from './fixtures/getRandomInt';
6
- import FORMAT from './fixtures/format';
7
- import getMarkup from './fixtures/getMarkup';
8
- import componentLabelsFrench from './fixtures/componentLabelsFrench';
9
- import colorNamesFrench from './fixtures/colorNamesFrench';
10
- import write from './fixtures/write';
11
- import swipe from './fixtures/swipe';
12
- import "~/scss/color-picker.scss";
13
-
14
- const colorNames = ['white', 'black', 'grey', 'red', 'orange', 'brown', 'gold', 'olive', 'yellow', 'lime', 'green', 'teal', 'cyan', 'blue', 'violet', 'magenta', 'pink'];
15
- const colorNameValues = ['#fff', '#000', '#808080', '#f00', '#ffa500', '#653c24', '#c8af00', '#808000', '#ff0', '#0f0', '#080', '#075', '#0ff', '#05f', '#a7f', '#b0f', '#f0d'];
16
- const colorPresets = '#470000,#750000,#a30000,#d10000,#ff0000,#ff2e2e,#ff5c5c,#ff8a8a,#ffb8b8,#ffe6e6,#004700,#007500,#00a300,#00d100,#00ff00,#2eff2e,#5cff5c,#8aff8a,#b8ffb8,#e6ffe6,#000047,#000075,#0000a3,#0000d1,#0000ff,#2e2eff,#5c5cff,#8a8aff,#b8b8ff,#e6e6ff';
17
-
18
- describe('ColorPicker Class Test', () => {
19
- const wrapper = document.createElement('div');
20
- document.body.append(wrapper);
21
-
22
- beforeEach(async () => {
23
- wrapper.innerHTML = '';
24
- });
25
-
26
- it('initialize with no parameter throws error', () => {
27
- try {
28
- // @ts-expect-error
29
- new ColorPicker();
30
- } catch (error) {
31
- expect(error).to.be.instanceOf(TypeError);
32
- expect(error).to.have.property('message', `ColorPicker target not specified.`);
33
- }
34
- });
35
- it('inject incomplete markup and initialize, throws error', () => {
36
- const cp = document.createElement('div');
37
- const input = document.createElement('input');
38
- cp.append(input)
39
- document.body.append(cp);
40
-
41
- try {
42
- new ColorPicker(input);
43
- } catch (error) {
44
- expect(error).to.be.instanceOf(TypeError);
45
- expect(error).to.have.property('message', 'ColorPicker requires a specific markup to work.');
46
- }
47
- });
48
- it('inject markup and initialize with all DATA API', async () => {
49
- const id = getRandomInt(0, 999);
50
- const format = FORMAT[getRandomInt(0, 3)];
51
- const { init, selector } = ColorPicker;
52
- const { container, value } = await vi.waitFor(() => getMarkup(id, format), { timeout: 150 });
53
- wrapper.append(container);
54
- const input = await vi.waitFor(() => document.querySelector(selector) as HTMLInputElement, { timeout: 200 });
55
-
56
- if (!input) return;
57
- input.setAttribute('value', value);
58
- input.setAttribute('data-function', "color-picker");
59
- input.setAttribute('data-color-presets', '{"hue": 120, "hueSteps": 6, "lightSteps": 10}');
60
- input.setAttribute('data-color-keywords', 'magenta, olive, yellow, red:default, currentColor:textColor');
61
- input.setAttribute('data-color-labels', colorNamesFrench);
62
- input.setAttribute('data-component-labels', '{"pickerLabel": "Couleur Sélection", "appearanceLabel": "Apparence de la couleur", "valueLabel": "Valeur de couleur", "toggleLabel": "Sélectionner la couleur", "presetsLabel": "Préréglages de couleur", "defaultsLabel": "Couleur par défaut", "formatLabel": "Format", "alphaLabel": "Alpha", "hexLabel": "Hexadécimal", "hueLabel": "Nuance", "whitenessLabel": "Blancheur", "blacknessLabel": "Noirceur", "saturationLabel": "Saturation", "lightnessLabel": "Légèreté", "redLabel": "Rouge", "greenLabel": "Vert", "blueLabel": "Bleu"}');
63
-
64
- init(input);
65
-
66
- const cp = ColorPicker.getInstance(input as HTMLInputElement);
67
- expect(Object.values(cp?.colorLabels!)).to.deep.equal(colorNamesFrench.split(','));
68
- expect(cp?.format).to.equal(format);
69
- expect(cp?.value).to.equal(value);
70
- expect(cp?.value).to.equal(new Color(value, format).toString(true));
71
- expect(cp?.colorKeywords).to.deep.equal(['magenta', 'olive', 'yellow', 'red:default', 'currentColor:textColor']);
72
- expect(cp?.colorPresets).to.be.instanceOf(ColorPalette);
73
- (cp?.colorPresets as ColorPalette).colors.forEach(c => expect(c).to.be.instanceOf(Color));
74
- expect(cp?.colorPicker).to.be.instanceOf(HTMLDivElement);
75
- expect(cp?.colorMenu).to.be.instanceOf(HTMLDivElement);
76
- });
77
- it('inject markup and initialize via JavaScript API', async () => {
78
- const id = getRandomInt(0, 999);
79
- const format = FORMAT[getRandomInt(0, 3)];
80
- const { container, value } = await vi.waitFor(() => getMarkup(id, format), { timeout: 150 });
81
- wrapper.append(container); const input = await vi.waitFor(() => document.querySelector('input') as HTMLInputElement, { timeout: 200 });
82
- if (!input) return;
83
-
84
- const cp = new ColorPicker(input, {
85
- colorKeywords: ['orange', 'lime', 'darkred'],
86
- colorPresets: '#330033, #990099, #ff00ff, #ff66ff, #ffccff',
87
- colorLabels: colorNamesFrench,
88
- componentLabels: componentLabelsFrench,
89
- });
90
- expect(cp.input).to.be.eq(input);
91
- expect(cp.format).to.be.eq(format);
92
- expect(cp?.value).to.equal(value);
93
- expect(cp?.colorPresets).to.be.instanceOf(Array);
94
- expect(cp?.colorPresets as string[]).to.deep.equal('#330033,#990099,#ff00ff,#ff66ff,#ffccff'.split(','));
95
- expect(cp?.colorPicker).to.be.instanceOf(HTMLDivElement);
96
- expect(Object.values(cp?.colorLabels)).to.deep.equal(colorNamesFrench.split(','));
97
- expect(cp?.colorKeywords).to.deep.equal(['orange', 'lime', 'darkred']);
98
- });
99
- it('inject markup and initialize with `colorKeywords`', async () => {
100
- const id = getRandomInt(0, 999);
101
- const format = FORMAT[getRandomInt(0, 3)];
102
-
103
- const { container } = await vi.waitFor(() => getMarkup(id, format), { timeout: 150 });
104
- wrapper.append(container); const input = await vi.waitFor(() => document.querySelector('input') as HTMLInputElement, { timeout: 200 });
105
- if (!input) return;
106
-
107
- const cp = new ColorPicker(input, {
108
- colorKeywords: 'orange, lime, darkred',
109
- });
110
- expect(cp.colorKeywords).to.deep.equal('orange,lime,darkred'.split(','))
111
- });
112
- it('inject markup and initialize with `colorPresets`', async () => {
113
- const id = getRandomInt(0, 999);
114
- const format = FORMAT[getRandomInt(0, 3)];
115
- const { container } = await vi.waitFor(() => getMarkup(id, format), { timeout: 150 });
116
- wrapper.append(container);
117
- const input = await vi.waitFor(() => document.querySelector('input') as HTMLInputElement, { timeout: 200 });
118
- if (!input) return;
119
-
120
- const cp = new ColorPicker(input, {
121
- colorPresets: '#330033, #990099, #ff00ff, #ff66ff, #ffccff'.split(',').map(x => x.trim()),
122
- });
123
- expect(cp.colorPresets).to.deep.equal('#330033,#990099,#ff00ff,#ff66ff,#ffccff'.split(',').map(x => x.trim()));
124
- });
125
- it('Test showing & hiding `colorPicker` / `presetsMenu`', async function () {
126
- vi.useFakeTimers();
127
- const id = getRandomInt(0, 999);
128
- const format = FORMAT[getRandomInt(0, 3)];
129
-
130
- const { container } = await vi.waitUntil(() => getMarkup(id, format), { timeout: 150 });
131
- wrapper.append(container);
132
- const mylink = await vi.waitUntil(() => container.getElementsByClassName('my-link')[0] as HTMLAnchorElement, { timeout: 17 });
133
- const input = await vi.waitUntil(() => container.querySelector('input') as HTMLInputElement, { timeout: 200 });
134
- if (!input) return;
135
-
136
- const cp = new ColorPicker(input, {
137
- colorKeywords: 'olive,green,red,:empty,transparent',
138
- colorPresets: colorPresets,
139
- colorLabels: colorNamesFrench,
140
- });
141
-
142
- cp.pickerToggle.click();
143
- vi.advanceTimersByTime(350);
144
- expect(cp.colorPicker.className).to.contain('show');
145
-
146
- cp.hide();
147
- vi.advanceTimersByTime(350);
148
- expect(cp.colorPicker.className).to.not.contain('show');
149
-
150
- cp.menuToggle.click();
151
- vi.advanceTimersByTime(350);
152
- expect(cp.colorPicker.className).to.not.contain('show');
153
- expect(cp.colorMenu.className).to.contain('show');
154
-
155
- cp.hide();
156
- vi.advanceTimersByTime(350);
157
-
158
- write(cp.pickerToggle, "Space");
159
- vi.advanceTimersByTime(50);
160
- expect(cp.colorPicker.className).to.contain('show');
161
- expect(cp.colorMenu.className).to.not.contain('show');
162
-
163
- write(cp.menuToggle, 'Enter');
164
- vi.advanceTimersByTime(350);
165
- expect(cp.colorMenu.className).to.contain('show');
166
-
167
- write(cp.menuToggle, 'Space');
168
- vi.advanceTimersByTime(350);
169
- expect(cp.colorMenu.className).to.not.contain('show');
170
-
171
- cp.togglePicker();
172
- vi.advanceTimersByTime(350);
173
- expect(cp.colorPicker.className).to.contain('show');
174
-
175
- if (!mylink) return;
176
- // mylink.click();
177
- mylink.dispatchEvent(new PointerEvent('pointerup', { bubbles: true }))
178
-
179
- vi.advanceTimersByTime(350);
180
- expect(cp.colorPicker.className).to.not.contain('show');
181
-
182
- vi.advanceTimersByTime(350);
183
- cp.togglePicker();
184
- vi.advanceTimersByTime(350);
185
- expect(cp.colorPicker.className).to.contain('show');
186
- document.body.dispatchEvent(new PointerEvent('pointerup', { bubbles: true, clientX: 200, clientY: 550 }))
187
- vi.advanceTimersByTime(350);
188
- expect(cp.colorPicker.className).to.not.contain('show');
189
-
190
- cp.showPicker();
191
- vi.advanceTimersByTime(350);
192
- expect(cp.colorPicker.className).to.contain('show');
193
- vi.advanceTimersByTime(350);
194
-
195
- write(cp.input, 'transparentEnter');
196
- vi.advanceTimersByTime(350);
197
- expect(cp.rgb).to.deep.equal({ r: 0, g: 0, b: 0, a: 0 });
198
-
199
- write(cp.input, 'currentColorEnter');
200
- vi.advanceTimersByTime(350);
201
- expect(cp.rgb).to.deep.equal({ r: 0, g: 0, b: 0, a: 1 });
202
-
203
- write(cp.input, 'wombatEnter');
204
- vi.advanceTimersByTime(350);
205
- expect(cp.value).to.not.equal('wombat');
206
-
207
- write(cp.input, 'hsl 0 0 100');
208
- vi.advanceTimersByTime(350);
209
- cp.hide();
210
- vi.advanceTimersByTime(350);
211
- expect(cp.rgb).to.not.deep.equal({ r: 255, g: 255, b: 255, a: 1 });
212
- expect(cp.value).to.not.equal('hsl 0 0 100');
213
- });
214
- it('Test `pointer` event listeners', async () => {
215
- vi.useFakeTimers();
216
- const id = getRandomInt(0, 999);
217
- const format = FORMAT[getRandomInt(0, 3)];
218
-
219
- const { container } = await vi.waitFor(() => getMarkup(id, format), { timeout: 150 });
220
- wrapper.append(container)
221
- const input = await vi.waitFor(() => container.querySelector('input') as HTMLInputElement, { timeout: 200 });
222
- if (!input) return;
223
-
224
- const cp = new ColorPicker(input);
225
- let lastRgb = cp.rgb;
226
-
227
- cp.showPicker();
228
- vi.advanceTimersByTime(350);
229
- write(input, 'hsl 0 100 50 Enter');
230
- vi.advanceTimersByTime(350);
231
- expect(cp.colorPicker.className, 'dropdown is open').to.include('show');
232
- expect(input.value, 'write check').to.equal(cp.value);
233
- lastRgb = cp.rgb;
234
-
235
- vi.advanceTimersByTime(350);
236
- swipe(cp.visuals[0], [[5, 5], [-5, -5], [500, 500], [100, 100], [100, 100]]);
237
- vi.advanceTimersByTime(350);
238
- expect(cp.rgb, 'swipe check').to.not.deep.equal(lastRgb);
239
- vi.advanceTimersByTime(350);
240
- lastRgb = cp.rgb;
241
-
242
- vi.advanceTimersByTime(550);
243
- swipe(cp.visuals[1], [[5, 5], [5, 0], [5, -5], [5, 500], [5, 100], [5, 100]]);
244
- vi.advanceTimersByTime(350);
245
- expect(cp.rgb, 'swipe check').to.not.deep.equal(lastRgb);
246
- vi.advanceTimersByTime(350);
247
- lastRgb = cp.rgb;
248
-
249
- vi.advanceTimersByTime(550);
250
- swipe(cp.visuals[2], [[5, 5], [5, -5], [5, 200], [5, 500], [5, 100], [5, 100]]);
251
- vi.advanceTimersByTime(350);
252
- expect(cp.rgb, 'swipe check').to.not.deep.equal(lastRgb);
253
- vi.advanceTimersByTime(350);
254
- lastRgb = cp.rgb;
255
- vi.advanceTimersByTime(350);
256
- });
257
- it('Test `keyboard` event listeners', async () => {
258
- vi.useFakeTimers();
259
- const id = getRandomInt(0, 999);
260
- const format = FORMAT[getRandomInt(0, 3)];
261
- const { container } = getMarkup(id, format);
262
- wrapper.append(container);
263
- const input = container.querySelector('input');
264
- if (!input) return;
265
-
266
- const cp = new ColorPicker(input, {
267
- colorKeywords: 'olive,green,red,:empty,transparent',
268
- colorPresets: colorPresets,
269
- colorLabels: colorNamesFrench,
270
- });
271
-
272
- cp.togglePicker();
273
- vi.advanceTimersByTime(350);
274
-
275
- input.focus();
276
- input.select();
277
- write(input, "hsl 0 0 100");
278
- vi.advanceTimersByTime(350);
279
- // input.addEventListener('keyup', (e) => console.log(e));
280
- input.dispatchEvent(new KeyboardEvent('keyup', { code: "Escape", key: "Escape", bubbles: true }));
281
- vi.advanceTimersByTime(350);
282
- expect(cp.rgb).to.not.deep.equal({ r: 255, g: 255, b: 255 });
283
- expect(cp.value).to.not.equal("hsl 0 0 100");
284
-
285
- cp.toggleMenu();
286
- vi.advanceTimersByTime(350);
287
- const defaults = cp.colorMenu.children[1].getElementsByTagName('LI') as HTMLCollectionOf<HTMLLIElement>;
288
- defaults[0].focus();
289
- defaults[0].dispatchEvent(new KeyboardEvent('keydown', { bubbles: true, key: 'ArrowRight', code: 'ArrowRight' }));
290
- vi.advanceTimersByTime(350);
291
- // console.log(document.activeElement);
292
- expect(defaults[1]).to.equal(document.activeElement);
293
-
294
- vi.advanceTimersByTime(350);
295
- defaults[1].dispatchEvent(new KeyboardEvent('keydown', { bubbles: true, key: 'ArrowLeft', code: 'ArrowLeft' }));
296
- vi.advanceTimersByTime(350);
297
- expect(defaults[0]).to.equal(document.activeElement);
298
-
299
- vi.advanceTimersByTime(350);
300
- defaults[0].dispatchEvent(new KeyboardEvent('keydown', { bubbles: true, key: 'ArrowDown', code: 'ArrowDown' }));
301
- vi.advanceTimersByTime(350);
302
- expect(defaults[1]).to.equal(document.activeElement);
303
-
304
- vi.advanceTimersByTime(350);
305
- defaults[1].dispatchEvent(new KeyboardEvent('keydown', { bubbles: true, key: 'ArrowUp', code: 'ArrowUp' }));
306
- vi.advanceTimersByTime(350);
307
- expect(defaults[0]).to.equal(document.activeElement);
308
-
309
- let prevValue = cp.value;
310
- vi.advanceTimersByTime(350);
311
- defaults[0].dispatchEvent(new KeyboardEvent('keydown', { bubbles: true, key: 'Enter', code: 'Enter' }));
312
- vi.advanceTimersByTime(350);
313
- expect(defaults[0].className).to.contain('active');
314
- expect(cp.value).to.not.equal(prevValue);
315
-
316
- vi.advanceTimersByTime(350);
317
- const transparent = cp.colorMenu.querySelector<HTMLLIElement>('[data-value="transparent"]');
318
- if (transparent) {
319
- transparent.click();
320
- vi.advanceTimersByTime(350);
321
- prevValue = cp.value;
322
-
323
- expect(transparent.className).to.contain('active');
324
- expect(cp.value).to.equal('transparent');
325
- }
326
-
327
- vi.advanceTimersByTime(350);
328
- const empty = cp.colorMenu.querySelector<HTMLLIElement>('[data-value="empty"]');
329
- if (empty) {
330
- empty.click();
331
- vi.advanceTimersByTime(350);
332
- prevValue = cp.value;
333
-
334
- expect(empty.className).to.contain('active');
335
- expect(cp.value).to.not.equal('empty');
336
- }
337
-
338
- vi.advanceTimersByTime(350);
339
- const options = cp.colorMenu.children[0].getElementsByTagName('LI') as HTMLCollectionOf<HTMLLIElement>;
340
- options[0].focus();
341
- // options[0].addEventListener('keydown', e => console.log(e))
342
- options[0].dispatchEvent(new KeyboardEvent('keydown', { bubbles: true, key: 'ArrowRight', code: 'ArrowRight' }));
343
- vi.advanceTimersByTime(350);
344
- expect(options[1]).to.equal(document.activeElement);
345
-
346
- vi.advanceTimersByTime(350);
347
- options[1].dispatchEvent(new KeyboardEvent('keydown', { bubbles: true, key: 'ArrowLeft', code: 'ArrowLeft' }));
348
- vi.advanceTimersByTime(350);
349
- expect(options[0]).to.equal(document.activeElement);
350
-
351
- vi.advanceTimersByTime(350);
352
- options[0].dispatchEvent(new KeyboardEvent('keydown', { bubbles: true, key: 'ArrowDown', code: 'ArrowDown' }));
353
- vi.advanceTimersByTime(350);
354
- // console.log(document.activeElement);
355
- expect(options[10]).to.equal(document.activeElement);
356
-
357
- vi.advanceTimersByTime(350);
358
- options[10].dispatchEvent(new KeyboardEvent('keydown', { bubbles: true, key: 'ArrowUp', code: 'ArrowUp' }));
359
- vi.advanceTimersByTime(350);
360
- expect(options[0]).to.equal(document.activeElement);
361
-
362
- prevValue = cp.value;
363
- options[0].dispatchEvent(new KeyboardEvent('keydown', { bubbles: true, key: 'Enter', code: 'Enter' }));
364
- vi.advanceTimersByTime(350);
365
- expect(options[0].className).to.contain('active');
366
- expect(cp.value).to.not.equal(prevValue);
367
-
368
- prevValue = cp.value;
369
- options[1].click();
370
- vi.advanceTimersByTime(350);
371
- expect(options[1].className).to.contain('active');
372
- expect(cp.value).to.not.equal(prevValue);
373
-
374
- document.dispatchEvent(new KeyboardEvent('keyup', { bubbles: true, code: 'Escape' }))
375
- vi.advanceTimersByTime(350);
376
- expect(cp.colorMenu.className).to.not.contain('show');
377
- });
378
- it('Test `scroll` event listeners', async () => {
379
- vi.useFakeTimers();
380
- const id = getRandomInt(0, 999);
381
- const format = FORMAT[getRandomInt(0, 3)];
382
- const { container } = getMarkup(id, format);
383
- Object.assign(container.style, { margin: '750px 0' });
384
- wrapper.append(container);
385
- const input = container.querySelector('input');
386
- if (!input) return;
387
-
388
- const win = input.ownerDocument.defaultView!;
389
- const cp = new ColorPicker(input, {
390
- colorKeywords: 'olive,green,red,:empty,transparent',
391
- colorPresets: colorPresets,
392
- colorLabels: colorNamesFrench,
393
- });
394
-
395
- cp.showPicker();
396
- vi.advanceTimersByTime(350);
397
- expect(cp.colorPicker.className).to.contain('show');
398
-
399
- vi.advanceTimersByTime(350);
400
- win.scrollTo({ left: 0, top: 10, behavior: "smooth" });
401
- win.dispatchEvent(new Event('scroll'));
402
- await Promise.resolve(() =>
403
- new Promise((resolve) => {
404
- setTimeout(() => {
405
- expect(cp.colorPicker.className).to.contain('top');
406
- resolve('done')
407
- }, 550)
408
- vi.advanceTimersByTime(550);
409
- })
410
- );
411
-
412
- win.scrollTo({ left: 0, top: document.body.scrollHeight, behavior: "smooth" });
413
- win.dispatchEvent(new Event('scroll'));
414
- await Promise.resolve(() =>
415
- new Promise((resolve) => {
416
- setTimeout(() => {
417
- expect(cp.colorPicker.className).to.not.contain('top');
418
- resolve('done')
419
- }, 550)
420
- vi.advanceTimersByTime(550);
421
- })
422
- );
423
- });
424
- it('Test controls mouse & keyboard events', async () => {
425
- vi.useFakeTimers();
426
- const id = getRandomInt(0, 999);
427
- const format = FORMAT[getRandomInt(0, 3)];
428
- const { container } = getMarkup(id, format);
429
- wrapper.append(container);
430
- const input = container.querySelector('input');
431
- if (!input) return;
432
-
433
- const cp = new ColorPicker(input, {
434
- colorKeywords: 'green,green,red,transparent',
435
- colorPresets: colorPresets,
436
- });
437
-
438
- cp.togglePicker();
439
- vi.advanceTimersByTime(350);
440
- write(input, "hsl 0 100 50 Enter");
441
- vi.advanceTimersByTime(350);
442
-
443
- // test visuals click, but we're using pointerdown more reliably
444
- const v0rect = cp.visuals[0].getBoundingClientRect();
445
- cp.visuals[0].dispatchEvent(new PointerEvent('pointerdown', {
446
- bubbles: true, cancelable: true,
447
- clientX: v0rect.left + v0rect.width / 2,
448
- clientY: v0rect.top + v0rect.height / 2,
449
- }));
450
- vi.advanceTimersByTime(350);
451
- expect(cp.rgb).to.not.deep.equal({ r: 255, g: 0, b: 0, a: 1 });
452
-
453
- write(input, "hsl 300 100 50 Enter");
454
- vi.advanceTimersByTime(350);
455
- const v1rect = cp.visuals[1].getBoundingClientRect();
456
- cp.visuals[1].dispatchEvent(new PointerEvent('pointerdown', {
457
- bubbles: true, cancelable: true,
458
- clientX: v1rect.left + v1rect.width / 2,
459
- clientY: v1rect.top + v1rect.height / 2,
460
- }));
461
- vi.advanceTimersByTime(350);
462
- expect(cp.rgb).to.not.deep.equal({ r: 255, g: 0, b: 255, a: 1 });
463
-
464
- write(input, "hsl 120 100 50 Enter");
465
- vi.advanceTimersByTime(350);
466
- const v2rect = cp.visuals[2].getBoundingClientRect();
467
- cp.visuals[2].dispatchEvent(new PointerEvent('pointerdown', {
468
- bubbles: true, cancelable: true,
469
- clientX: v2rect.left + v2rect.width / 2,
470
- clientY: v2rect.top + v2rect.height / 2,
471
- }));
472
- vi.advanceTimersByTime(350);
473
- expect(cp.rgb).to.deep.equal({ r: 0, g: 255, b: 0, a: 0.5 });
474
-
475
- // test control knobs pointer events
476
- write(input, "hsl 0 100 100 Enter");
477
- vi.advanceTimersByTime(350);
478
- swipe(cp.controlKnobs[0], [[2, 2], [-v0rect.left, -v0rect.top], [300, 300], [v0rect.width / 2, v0rect.height / 2]], { x: v0rect.left, y: v0rect.top });
479
- vi.advanceTimersByTime(350);
480
- expect(cp.rgb).to.not.deep.equal({ r: 255, g: 0, b: 0, a: 1 });
481
-
482
- write(input, "hsl 0 100 100 Enter");
483
- vi.advanceTimersByTime(350);
484
- swipe(cp.controlKnobs[1], [[2, 2], [-v1rect.left, -v1rect.top], [2, 300], [v1rect.width / 2, v1rect.height / 2]], { x: v1rect.left, y: v1rect.top });
485
- vi.advanceTimersByTime(350);
486
- expect(cp.rgb).to.not.deep.equal({ r: 255, g: 0, b: 0, a: 1 });
487
-
488
- write(input, "hsl 0 100 100 Enter");
489
- vi.advanceTimersByTime(350);
490
- swipe(cp.controlKnobs[2], [[2, 2], [-v2rect.left, -v2rect.top], [2, 300], [v2rect.width / 2, v2rect.height / 2]], { x: v2rect.left, y: v2rect.top });
491
- vi.advanceTimersByTime(350);
492
- expect(cp.rgb).to.not.deep.equal({ r: 255, g: 0, b: 0, a: 1 });
493
-
494
- // test control knobs keyboard events
495
- write(input, 'hsl 300 100 50 Enter');
496
- vi.advanceTimersByTime(350);
497
- let currentRgb = cp.rgb;
498
- cp.controlKnobs[0].focus();
499
- cp.controlKnobs[0].dispatchEvent(new KeyboardEvent('keydown', { bubbles: true, key: "ArrowDown", code: 'ArrowDown' }));
500
- cp.controlKnobs[0].dispatchEvent(new KeyboardEvent('keydown', { bubbles: true, key: "ArrowDown", code: 'ArrowDown' }));
501
- cp.controlKnobs[0].dispatchEvent(new KeyboardEvent('keydown', { bubbles: true, key: "a", code: 'a' })); // adge case, produces no effect
502
- cp.controlKnobs[0].dispatchEvent(new KeyboardEvent('keydown', { bubbles: true, key: "ArrowRight", code: 'ArrowRight' }));
503
- cp.controlKnobs[0].dispatchEvent(new KeyboardEvent('keydown', { bubbles: true, key: "ArrowRight", code: 'ArrowRight' }));
504
- cp.controlKnobs[0].dispatchEvent(new KeyboardEvent('keydown', { bubbles: true, key: "ArrowLeft", code: 'ArrowLeft' }));
505
- vi.advanceTimersByTime(350);
506
- expect(cp.rgb).to.not.deep.equal(currentRgb);
507
-
508
- write(input, 'hsl 180 100 50 Enter');
509
- vi.advanceTimersByTime(350);
510
- currentRgb = cp.rgb;
511
- cp.controlKnobs[1].focus();
512
- cp.controlKnobs[1].dispatchEvent(new KeyboardEvent('keydown', { bubbles: true, key: "ArrowDown", code: 'ArrowDown' }));
513
- cp.controlKnobs[1].dispatchEvent(new KeyboardEvent('keydown', { bubbles: true, key: "ArrowDown", code: 'ArrowDown' }));
514
- cp.controlKnobs[1].dispatchEvent(new KeyboardEvent('keydown', { bubbles: true, key: "b", code: 'b' }));
515
- cp.controlKnobs[1].dispatchEvent(new KeyboardEvent('keydown', { bubbles: true, key: "ArrowRight", code: 'ArrowRight' }));
516
- cp.controlKnobs[1].dispatchEvent(new KeyboardEvent('keydown', { bubbles: true, key: "ArrowRight", code: 'ArrowRight' }));
517
- cp.controlKnobs[1].dispatchEvent(new KeyboardEvent('keydown', { bubbles: true, key: "ArrowLeft", code: 'ArrowLeft' }));
518
- vi.advanceTimersByTime(350);
519
- expect(cp.rgb).to.not.deep.equal(currentRgb);
520
-
521
- write(input, 'hsl 0 100 50');
522
- vi.advanceTimersByTime(350);
523
- currentRgb = cp.rgb;
524
- cp.controlKnobs[2].focus();
525
- cp.controlKnobs[2].dispatchEvent(new KeyboardEvent('keydown', { bubbles: true, key: "ArrowDown", code: 'ArrowDown' }));
526
- cp.controlKnobs[2].dispatchEvent(new KeyboardEvent('keydown', { bubbles: true, key: "ArrowDown", code: 'ArrowDown' }));
527
- cp.controlKnobs[2].dispatchEvent(new KeyboardEvent('keydown', { bubbles: true, key: "b", code: 'c' }));
528
- cp.controlKnobs[2].dispatchEvent(new KeyboardEvent('keydown', { bubbles: true, key: "ArrowRight", code: 'ArrowRight' }));
529
- cp.controlKnobs[2].dispatchEvent(new KeyboardEvent('keydown', { bubbles: true, key: "ArrowRight", code: 'ArrowRight' }));
530
- cp.controlKnobs[2].dispatchEvent(new KeyboardEvent('keydown', { bubbles: true, key: "ArrowLeft", code: 'ArrowLeft' }));
531
- vi.advanceTimersByTime(350);
532
- expect(cp.rgb).to.not.deep.equal(currentRgb);
533
- });
534
- it('Test private methods', function () {
535
- vi.useFakeTimers();
536
- const id = getRandomInt(0, 999);
537
- const format = FORMAT[getRandomInt(0, 3)];
538
- const { container } = getMarkup(id, format);
539
- wrapper.append(container);
540
- const input = container.querySelector('input');
541
- if (!input) return;
542
-
543
- const cp = new ColorPicker(input, {
544
- colorKeywords: 'green,green,red,transparent',
545
- colorPresets: colorPresets,
546
- });
547
-
548
- cp.togglePicker();
549
- vi.advanceTimersByTime(350);
550
- expect(cp.colorPicker.className).to.contain('show');
551
-
552
- cp.togglePicker();
553
- vi.advanceTimersByTime(350);
554
- expect(cp.colorPicker.className).to.not.contain('show');
555
-
556
- cp.toggleMenu();
557
- vi.advanceTimersByTime(350);
558
- expect(cp.colorMenu.className).to.contain('show');
559
-
560
- cp.toggleMenu();
561
- vi.advanceTimersByTime(350);
562
- expect(cp.colorMenu.className).to.not.contain('show');
563
-
564
- cp.showPicker();
565
- vi.advanceTimersByTime(350);
566
- expect(cp.colorPicker.className).to.contain('show');
567
-
568
- cp.hide();
569
- vi.advanceTimersByTime(350);
570
- expect(cp.colorPicker.className).to.not.contain('show');
571
-
572
- cp.dispose();
573
- vi.advanceTimersByTime(350);
574
- expect(cp.colorPicker).to.not.undefined;
575
- });
576
-
577
- const frenchColors = colorNamesFrench.split(',');
578
- frenchColors.forEach((color) => {
579
- it(`Test color appearance and color luminance ${color}`, () => {
580
- vi.useFakeTimers();
581
- const id = getRandomInt(0, 999);
582
- const format = FORMAT[getRandomInt(0, 3)];
583
- const { container } = getMarkup(id, format);
584
- wrapper.append(container);
585
- const input = container.querySelector('input');
586
- if (!input) return;
587
-
588
- const cp = new ColorPicker(input, {
589
- colorKeywords: 'olive,green,red,transparent',
590
- colorPresets: colorPresets,
591
- colorLabels: colorNamesFrench,
592
- });
593
-
594
- const webcolor = colorNameValues[frenchColors.indexOf(color)];
595
-
596
- vi.advanceTimersByTime(350);
597
- write(input, webcolor + "Enter");
598
- vi.advanceTimersByTime(50);
599
- expect(cp.isValid).to.be.true;
600
- expect(cp.appearance).to.equal(color);
601
-
602
- if (colorNames[frenchColors.indexOf(color)] === 'white') {
603
- expect(cp.luminance).to.be.greaterThan(0.99);
604
- } else {
605
- expect(cp.luminance).to.be.lessThan(0.99);
606
- }
607
- vi.advanceTimersByTime(350);
608
-
609
- });
610
- });
611
-
612
- FORMAT.forEach((format) => {
613
- it(`Test format specific event listeners - ${format.toUpperCase()}`, async () => {
614
- vi.useFakeTimers();
615
- const id = getRandomInt(0, 999);
616
- const { container } = getMarkup(id, format);
617
- wrapper.append(container);
618
- const input = container.querySelector('input');
619
- if (!input) return;
620
-
621
- const cp = new ColorPicker(input, {
622
- colorKeywords: ['green', 'green', 'red', 'transparent', 'currentColor'],
623
- colorPresets: colorPresets.split(','),
624
- colorLabels: colorNamesFrench.split(','),
625
- });
626
- cp.showPicker();
627
- vi.advanceTimersByTime(350);
628
-
629
- // Test typing a valid value and press `Enter`
630
- write(input, 'hsl 0 100 50 Enter');
631
- vi.advanceTimersByTime(350);
632
- if (format === 'hsl') {
633
- expect(cp.value).to.be.equal('hsl(0, 100%, 50%)');
634
- } else if (format === 'rgb') {
635
- expect(cp.value).to.be.equal('rgb(255, 0, 0)');
636
- } else if (format === 'hex') {
637
- expect(cp.value).to.be.equal('#f00');
638
- } else if (format === 'hwb') {
639
- expect(cp.value).to.be.equal('hwb(0deg 0% 0%)');
640
- }
641
-
642
- // Test keyboard event listeners on `inputs`
643
- if (format === 'hex') {
644
- write(input, "hsl 300 100 50 Enter");
645
- vi.advanceTimersByTime(350);
646
- const rgb = cp.rgb;
647
- write(cp.inputs[0], 'hsl 100 100 50 Enter');
648
- vi.advanceTimersByTime(350);
649
- expect(cp.rgb).to.not.deep.equal(rgb);
650
- } else if (format === 'rgb') {
651
- write(input, "hsl 300 100 50 Enter");
652
- vi.advanceTimersByTime(350);
653
- let rgb = cp.rgb;
654
- write(cp.inputs[0], '150Enter');
655
- vi.advanceTimersByTime(350);
656
- expect(cp.rgb).to.not.deep.equal(rgb);
657
-
658
- write(input, "hsl 100 100 50 Enter");
659
- vi.advanceTimersByTime(350);
660
- rgb = cp.rgb;
661
- write(cp.inputs[1], '150Enter');
662
- vi.advanceTimersByTime(350);
663
- expect(cp.rgb).to.not.deep.equal(rgb);
664
-
665
- write(input, "hsl 300 100 50 Enter");
666
- vi.advanceTimersByTime(350);
667
- rgb = cp.rgb;
668
- write(cp.inputs[2], '150Enter');
669
- vi.advanceTimersByTime(350);
670
- expect(cp.rgb).to.not.deep.equal(rgb);
671
-
672
- } else if (format === 'hsl' || format === 'hwb') {
673
- write(input, "hsl 270 100 50 Enter");
674
- vi.advanceTimersByTime(350);
675
- let rgb = cp.rgb;
676
- write(cp.inputs[0], '0Enter');
677
- vi.advanceTimersByTime(350);
678
- expect(cp.rgb).to.not.deep.equal(rgb);
679
-
680
- write(input, "hsl 330 100 50 Enter");
681
- vi.advanceTimersByTime(350);
682
- rgb = cp.rgb;
683
- write(cp.inputs[1], '50Enter');
684
- vi.advanceTimersByTime(350);
685
- expect(cp.rgb).to.not.deep.equal(rgb);
686
-
687
- write(input, "hsl 300 100 50 Enter");
688
- vi.advanceTimersByTime(350);
689
- rgb = cp.rgb;
690
- write(cp.inputs[2], '25Enter');
691
- vi.advanceTimersByTime(350);
692
- expect(cp.rgb).to.not.deep.equal(rgb);
693
- }
694
-
695
- if (format !== 'hex') {
696
- write(input, "hsl 240 100 50 Enter");
697
- vi.advanceTimersByTime(350);
698
- const rgb = cp.rgb;
699
- write(cp.inputs[3], '25Enter');
700
- vi.advanceTimersByTime(350);
701
- expect(cp.rgb).to.not.deep.equal(rgb);
702
- }
703
- });
704
- });
705
- });