@onewelcome/react-lib-components 0.1.7-alpha → 0.1.8-alpha

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 (69) hide show
  1. package/dist/DataGrid/DataGrid.d.ts +30 -0
  2. package/dist/DataGrid/DataGridActions/DataGridActions.d.ts +14 -0
  3. package/dist/DataGrid/DataGridActions/DataGridColumnsToggle.d.ts +13 -0
  4. package/dist/DataGrid/DataGridBody/DataGridBody.d.ts +16 -0
  5. package/dist/DataGrid/DataGridBody/DataGridCell.d.ts +6 -0
  6. package/dist/DataGrid/DataGridBody/DataGridRow.d.ts +7 -0
  7. package/dist/DataGrid/DataGridHeader/DataGridHeader.d.ts +10 -0
  8. package/dist/DataGrid/DataGridHeader/DataGridHeaderCell.d.ts +10 -0
  9. package/dist/DataGrid/datagrid.interfaces.d.ts +13 -0
  10. package/dist/Form/Select/Option.d.ts +9 -4
  11. package/dist/Form/Select/Select.d.ts +8 -2
  12. package/dist/Form/Wrapper/SelectWrapper/SelectWrapper.d.ts +1 -1
  13. package/dist/Icon/Icon.d.ts +1 -0
  14. package/dist/_BaseStyling_/BaseStyling.d.ts +4 -0
  15. package/dist/hooks/useSpacing.d.ts +1 -1
  16. package/dist/hooks/useWrapper.d.ts +1 -1
  17. package/dist/index.d.ts +5 -0
  18. package/dist/react-lib-components.cjs.development.js +949 -272
  19. package/dist/react-lib-components.cjs.development.js.map +1 -1
  20. package/dist/react-lib-components.cjs.production.min.js +1 -1
  21. package/dist/react-lib-components.cjs.production.min.js.map +1 -1
  22. package/dist/react-lib-components.esm.js +947 -273
  23. package/dist/react-lib-components.esm.js.map +1 -1
  24. package/dist/util/helper.d.ts +1 -1
  25. package/package.json +11 -11
  26. package/src/ContextMenu/ContextMenu.tsx +16 -1
  27. package/src/DataGrid/DataGrid.module.scss +21 -0
  28. package/src/DataGrid/DataGrid.test.tsx +276 -0
  29. package/src/DataGrid/DataGrid.tsx +101 -0
  30. package/src/DataGrid/DataGridActions/DataGridActions.module.scss +35 -0
  31. package/src/DataGrid/DataGridActions/DataGridActions.test.tsx +184 -0
  32. package/src/DataGrid/DataGridActions/DataGridActions.tsx +109 -0
  33. package/src/DataGrid/DataGridActions/DataGridColumnsToggle.module.scss +41 -0
  34. package/src/DataGrid/DataGridActions/DataGridColumnsToggle.test.tsx +83 -0
  35. package/src/DataGrid/DataGridActions/DataGridColumnsToggle.tsx +88 -0
  36. package/src/DataGrid/DataGridBody/DataGridBody.module.scss +10 -0
  37. package/src/DataGrid/DataGridBody/DataGridBody.test.tsx +123 -0
  38. package/src/DataGrid/DataGridBody/DataGridBody.tsx +64 -0
  39. package/src/DataGrid/DataGridBody/DataGridCell.module.scss +33 -0
  40. package/src/DataGrid/DataGridBody/DataGridCell.test.tsx +74 -0
  41. package/src/DataGrid/DataGridBody/DataGridCell.tsx +25 -0
  42. package/src/DataGrid/DataGridBody/DataGridRow.module.scss +7 -0
  43. package/src/DataGrid/DataGridBody/DataGridRow.test.tsx +101 -0
  44. package/src/DataGrid/DataGridBody/DataGridRow.tsx +27 -0
  45. package/src/DataGrid/DataGridBody/__snapshots__/DataGridBody.test.tsx.snap +258 -0
  46. package/src/DataGrid/DataGridHeader/DataGridHeader.module.scss +26 -0
  47. package/src/DataGrid/DataGridHeader/DataGridHeader.test.tsx +255 -0
  48. package/src/DataGrid/DataGridHeader/DataGridHeader.tsx +80 -0
  49. package/src/DataGrid/DataGridHeader/DataGridHeaderCell.module.scss +68 -0
  50. package/src/DataGrid/DataGridHeader/DataGridHeaderCell.test.tsx +128 -0
  51. package/src/DataGrid/DataGridHeader/DataGridHeaderCell.tsx +72 -0
  52. package/src/DataGrid/datagrid.interfaces.ts +14 -0
  53. package/src/Form/Select/Option.tsx +39 -21
  54. package/src/Form/Select/Select.module.scss +1 -1
  55. package/src/Form/Select/Select.test.tsx +235 -56
  56. package/src/Form/Select/Select.tsx +194 -34
  57. package/src/Form/Toggle/Toggle.module.scss +1 -0
  58. package/src/Form/Wrapper/SelectWrapper/SelectWrapper.test.tsx +44 -0
  59. package/src/Form/Wrapper/SelectWrapper/SelectWrapper.tsx +4 -2
  60. package/src/Icon/Icon.module.scss +4 -0
  61. package/src/Icon/Icon.tsx +1 -0
  62. package/src/Notifications/BaseModal/BaseModal.module.scss +1 -1
  63. package/src/Notifications/BaseModal/BaseModal.test.tsx +2 -1
  64. package/src/Notifications/Dialog/Dialog.module.scss +1 -1
  65. package/src/Notifications/Snackbar/SnackbarContainer/SnackbarContainer.module.scss +1 -1
  66. package/src/Notifications/Snackbar/SnackbarItem/SnackbarItem.module.scss +1 -1
  67. package/src/Pagination/Pagination.module.scss +74 -74
  68. package/src/_BaseStyling_/BaseStyling.tsx +14 -6
  69. package/src/index.ts +6 -0
@@ -1,6 +1,6 @@
1
1
  import React, { useEffect, useRef } from 'react';
2
2
  import { Select as SelectComponent, Props } from './Select';
3
- import { render } from '@testing-library/react';
3
+ import { render, waitFor } from '@testing-library/react';
4
4
  import { Option } from './Option';
5
5
  import userEvent from '@testing-library/user-event';
6
6
 
@@ -25,7 +25,10 @@ const defaultParams: Props = {
25
25
  <Option value="option16">Test16</Option>,
26
26
  <Option value="option17">Test17</Option>,
27
27
  ],
28
- value: '',
28
+ value: 'option1',
29
+ searchInputProps: { 'data-testid': 'search-input' },
30
+ // @ts-ignore it does exist Typescript, pls.
31
+ selectButtonProps: { 'data-testid': 'select-button' },
29
32
  };
30
33
 
31
34
  const createSelect = (params?: (defaultParams: Props) => Props) => {
@@ -35,7 +38,7 @@ const createSelect = (params?: (defaultParams: Props) => Props) => {
35
38
  }
36
39
  const queries = render(<SelectComponent {...parameters} data-testid="select" />);
37
40
  const select = queries.getByTestId('select');
38
- const button = select.querySelector('button');
41
+ const button = queries.getByTestId('select-button');
39
42
  const list = select.querySelector('ul[role="listbox"]');
40
43
  const dropdownWrapper = select.querySelector('.list-wrapper');
41
44
 
@@ -60,6 +63,7 @@ describe('Select should render', () => {
60
63
  <Option value="option5">Test5</Option>,
61
64
  ],
62
65
  placeholder: 'Placeholder',
66
+ value: '',
63
67
  }));
64
68
 
65
69
  if (button) {
@@ -126,20 +130,20 @@ describe('ref should work', () => {
126
130
 
127
131
  describe('Select should render with search', () => {
128
132
  it('shows the search and filtering works', () => {
129
- const { select, list, button, dropdownWrapper } = createSelect();
133
+ const { select, list, button, getByTestId } = createSelect();
134
+
135
+ const searchInput = getByTestId('search-input');
130
136
 
131
137
  if (button) {
132
138
  userEvent.click(button);
133
139
  }
134
140
 
135
- const search = dropdownWrapper?.querySelector('input');
136
-
137
141
  expect(select).toBeTruthy();
138
- expect(search).toBeTruthy();
142
+ expect(searchInput).toBeTruthy();
139
143
  expect(list?.querySelectorAll("li[role='option']").length).toBe(17);
140
144
 
141
- if (search) {
142
- userEvent.type(search, '17');
145
+ if (searchInput) {
146
+ userEvent.type(searchInput, '17');
143
147
  }
144
148
 
145
149
  expect(list?.querySelectorAll("li[role='option']").length).toBe(1);
@@ -148,32 +152,51 @@ describe('Select should render with search', () => {
148
152
  });
149
153
 
150
154
  describe('Selecting options using keyboard', () => {
151
- it('should focus through list items and select on enterpress', () => {
152
- const { select, button, list } = createSelect();
155
+ it('should focus through list items and select on enterpress', async () => {
156
+ const onChangeHandler = jest.fn();
157
+ const { select, button } = createSelect((defaultParams) => ({
158
+ ...defaultParams,
159
+ onChange: onChangeHandler,
160
+ }));
153
161
 
154
- if (button) {
155
- userEvent.click(button);
156
- }
162
+ userEvent.click(button);
157
163
 
158
- userEvent.tab();
159
- userEvent.tab();
160
- expect(list?.querySelectorAll('li')[0]).toHaveFocus();
161
- userEvent.tab();
162
- expect(list?.querySelectorAll('li')[1]).toHaveFocus();
163
- userEvent.tab();
164
- expect(list?.querySelectorAll('li')[2]).toHaveFocus();
165
- userEvent.tab();
166
- expect(list?.querySelectorAll('li')[3]).toHaveFocus();
167
- userEvent.tab();
168
- expect(list?.querySelectorAll('li')[4]).toHaveFocus();
169
- userEvent.tab();
170
- expect(list?.querySelectorAll('li')[5]).toHaveFocus();
164
+ expect(button).toHaveAttribute('aria-expanded', 'true');
171
165
 
166
+ userEvent.keyboard('{arrowdown}');
167
+ userEvent.keyboard('{arrowdown}');
172
168
  userEvent.keyboard('{enter}');
173
169
 
174
- setTimeout(() => {
175
- expect(select.querySelector('button > span > span')?.innerHTML).toBe('Test5');
176
- }, 50);
170
+ expect(button).toHaveAttribute('aria-expanded', 'false');
171
+
172
+ expect(onChangeHandler).toHaveBeenCalled();
173
+
174
+ userEvent.keyboard('{enter}');
175
+
176
+ expect(button).toHaveAttribute('aria-expanded', 'true');
177
+
178
+ userEvent.keyboard('{arrowdown}');
179
+
180
+ expect(select.querySelector('li[data-value="option3"]')).toHaveFocus();
181
+
182
+ userEvent.keyboard('{arrowup}');
183
+ userEvent.keyboard('{arrowup}');
184
+ userEvent.keyboard('{arrowup}');
185
+ userEvent.keyboard('{arrowup}');
186
+
187
+ expect(select.querySelector('li[data-value="option16"]')).toHaveFocus();
188
+ userEvent.keyboard('{arrowup}');
189
+ expect(select.querySelector('li[data-value="option15"]')).toHaveFocus();
190
+
191
+ userEvent.keyboard('{arrowdown}');
192
+ userEvent.keyboard('{arrowdown}');
193
+ userEvent.keyboard('{arrowdown}');
194
+
195
+ expect(select.querySelector('li[data-value="option1"]')).toHaveFocus();
196
+
197
+ userEvent.keyboard('{escape}');
198
+
199
+ expect(button).toHaveAttribute('aria-expanded', 'false');
177
200
  });
178
201
  });
179
202
 
@@ -193,7 +216,7 @@ describe('Expanded should be false whenever we click the body', () => {
193
216
 
194
217
  describe('List expansion', () => {
195
218
  it('should expand upwards', () => {
196
- const { select, button } = createSelect();
219
+ const { select, button, dropdownWrapper } = createSelect();
197
220
 
198
221
  Object.defineProperty(window, 'innerHeight', { value: 500, writable: true });
199
222
 
@@ -213,16 +236,13 @@ describe('List expansion', () => {
213
236
  userEvent.click(button);
214
237
  }
215
238
 
216
- const listWrapper = select.querySelector('.list-wrapper');
217
-
218
- expect(listWrapper).toHaveStyle({ bottom: '0px' });
239
+ expect(dropdownWrapper).toHaveStyle({ bottom: '0px' });
219
240
  });
220
241
 
221
242
  it('should expand downwards with a max height set', () => {
222
- const { select, getByRole } = createSelect();
223
- const listWrapper = select.querySelector('.list-wrapper');
243
+ const { select, getByRole, dropdownWrapper } = createSelect();
224
244
 
225
- listWrapper!.getBoundingClientRect = () => ({
245
+ dropdownWrapper!.getBoundingClientRect = () => ({
226
246
  x: 50,
227
247
  y: 50,
228
248
  width: 500,
@@ -252,39 +272,198 @@ describe('List expansion', () => {
252
272
  const button = getByRole('button');
253
273
  userEvent.click(button);
254
274
 
255
- expect(listWrapper).toHaveStyle({ maxHeight: '474px' });
256
- expect(listWrapper).toHaveStyle({ top: '0px' });
275
+ expect(dropdownWrapper).toHaveStyle({ maxHeight: '474px' });
276
+ expect(dropdownWrapper).toHaveStyle({ top: '0px' });
257
277
  });
258
278
  });
259
279
 
260
280
  describe('onClear method', () => {
261
- it('should show a cross and fire the passed onClear function', async () => {
281
+ it('should show a cross and fire the passed onClear function with enter', async () => {
262
282
  const onClearHandler = jest.fn();
263
- const onChangeHandler = jest.fn();
264
283
 
265
- const { button, container } = createSelect((defaultParams) => ({
284
+ const { select, button } = createSelect((defaultParams) => ({
285
+ ...defaultParams,
286
+ onClear: onClearHandler,
287
+ value: 'option4',
288
+ }));
289
+
290
+ button.focus();
291
+ const clearButton = select.querySelector('[data-clear]');
292
+
293
+ userEvent.tab();
294
+
295
+ expect(clearButton).toHaveFocus();
296
+
297
+ userEvent.keyboard('{enter}');
298
+
299
+ expect(onClearHandler).toHaveBeenCalled();
300
+ expect(button?.getAttribute('aria-expanded')).toBe('false');
301
+ });
302
+
303
+ it('should show a cross and fire the passed onClear function with enter', async () => {
304
+ const onClearHandler = jest.fn();
305
+
306
+ const { select, button } = createSelect((defaultParams) => ({
266
307
  ...defaultParams,
267
308
  onClear: onClearHandler,
268
- onChange: onChangeHandler,
269
309
  value: 'option4',
270
310
  }));
271
311
 
272
- if (button) {
273
- userEvent.click(button);
274
- }
312
+ button.focus();
313
+ const clearButton = select.querySelector('[data-clear]');
314
+ expect(document.querySelector('[data-display-inner]')).toBeInTheDocument();
275
315
 
276
- const optionToClick = container.querySelector('li[data-value="option5"]')!;
277
- const onClearButton = container.querySelector('[data-clear]')!;
316
+ userEvent.tab();
278
317
 
279
- userEvent.click(optionToClick);
280
- userEvent.click(onClearButton);
318
+ expect(clearButton).toHaveFocus();
319
+
320
+ userEvent.keyboard('{space}');
281
321
 
282
322
  expect(onClearHandler).toHaveBeenCalled();
283
- expect(onClearButton).toBeInTheDocument();
284
- expect(container.querySelector('li[aria-selected="true"]')).toHaveTextContent('Test4');
285
- expect(container.querySelector('.selected-option')).toHaveTextContent('Test4');
286
- expect(onChangeHandler).toBeCalledWith(
287
- expect.objectContaining({ target: expect.objectContaining({ value: 'option5' }) })
288
- );
323
+ expect(button?.getAttribute('aria-expanded')).toBe('false');
324
+ });
325
+
326
+ it('should not show cross', () => {
327
+ createSelect((defaultParams) => ({
328
+ ...defaultParams,
329
+ value: '',
330
+ }));
331
+
332
+ expect(document.querySelector('[data-clear]')).not.toBeInTheDocument();
333
+ expect(document.querySelector('[data-display-inner]')).not.toBeInTheDocument();
334
+ });
335
+ });
336
+
337
+ describe('previously selected item', () => {
338
+ it('should have focus', () => {
339
+ const { select, button } = createSelect((defaultParams) => ({
340
+ ...defaultParams,
341
+ value: 'option4',
342
+ }));
343
+
344
+ button.focus();
345
+
346
+ const option2 = select.querySelector('li[data-value="option2"]')!;
347
+
348
+ userEvent.keyboard('{enter}');
349
+ expect(button).toHaveAttribute('aria-expanded', 'true');
350
+ userEvent.keyboard('{arrowdown}');
351
+ userEvent.keyboard('{arrowdown}');
352
+ userEvent.keyboard('{space}');
353
+
354
+ userEvent.click(button);
355
+
356
+ expect(document.activeElement).toBe(option2);
357
+ });
358
+ });
359
+
360
+ describe('search input', () => {
361
+ it('listens to different keyboard inputs', async () => {
362
+ const { button, select } = createSelect();
363
+
364
+ const searchInput = document.querySelector('.select-search')!;
365
+
366
+ userEvent.click(button);
367
+ (searchInput as HTMLElement).focus();
368
+
369
+ userEvent.keyboard('{arrowup}');
370
+ expect(select.querySelector('li[data-value="option17"]')).toHaveFocus();
371
+ });
372
+
373
+ it('move focus with arrowdown', async () => {
374
+ const { button, select } = createSelect();
375
+
376
+ const searchInput = document.querySelector('.select-search')!;
377
+
378
+ userEvent.click(button);
379
+ (searchInput as HTMLElement).focus();
380
+
381
+ userEvent.keyboard('{arrowdown}');
382
+ expect(select.querySelector('li[data-value="option1"]')).toHaveFocus();
383
+ });
384
+
385
+ it('select with enter', async () => {
386
+ const { button, select } = createSelect();
387
+
388
+ const searchInput = document.querySelector('.select-search')!;
389
+
390
+ userEvent.click(button);
391
+ (searchInput as HTMLElement).focus();
392
+
393
+ userEvent.keyboard('{enter}');
394
+ expect(select.querySelector('li[data-value="option1"]')).toHaveFocus();
395
+ });
396
+
397
+ it('expand list with arrowdown', async () => {
398
+ const { button } = createSelect();
399
+
400
+ button.focus();
401
+ userEvent.keyboard('{arrowdown}');
402
+
403
+ expect(button).toHaveAttribute('aria-expanded', 'true');
404
+ });
405
+
406
+ it('expand list with space', async () => {
407
+ const { button } = createSelect();
408
+
409
+ button.focus();
410
+ userEvent.keyboard('{space}');
411
+
412
+ expect(button).toHaveAttribute('aria-expanded', 'true');
413
+ });
414
+
415
+ it('closes on escape', async () => {
416
+ const { button } = createSelect();
417
+
418
+ const searchInput = document.querySelector('.select-search')!;
419
+
420
+ userEvent.click(button);
421
+ userEvent.tab();
422
+
423
+ await waitFor(() => expect(searchInput).toHaveFocus());
424
+
425
+ userEvent.keyboard('{escape}');
426
+
427
+ expect(button).toHaveAttribute('aria-expanded', 'false');
428
+ });
429
+
430
+ it('closes on tab', async () => {
431
+ const { button } = createSelect();
432
+
433
+ const searchInput = document.querySelector('.select-search')!;
434
+
435
+ userEvent.click(button);
436
+ userEvent.tab();
437
+ expect(searchInput).toHaveFocus();
438
+ userEvent.tab();
439
+ });
440
+ });
441
+
442
+ describe('home and end keys work', () => {
443
+ it('goes to home and end', () => {
444
+ const { button } = createSelect();
445
+
446
+ userEvent.click(button);
447
+
448
+ const firstOption = document.querySelector('li[data-value="option1"]');
449
+ const lastOption = document.querySelector('li[data-value="option17"]');
450
+
451
+ userEvent.keyboard('{end}');
452
+
453
+ expect(lastOption).toHaveFocus();
454
+ userEvent.keyboard('{home}');
455
+
456
+ expect(firstOption).toHaveFocus();
457
+ });
458
+ });
459
+
460
+ describe('search input props work', () => {
461
+ it('adds a classname', () => {
462
+ createSelect((defaultParams) => ({
463
+ ...defaultParams,
464
+ searchInputProps: { wrapperProps: { className: 'test-wrapper-classname' } },
465
+ }));
466
+
467
+ expect(document.querySelector('.test-wrapper-classname')).toBeInTheDocument();
289
468
  });
290
469
  });