@lumx/react 3.6.7 → 3.6.8

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 (41) hide show
  1. package/_internal/types.d.ts +29 -29
  2. package/index.d.ts +45 -45
  3. package/index.js +28 -16
  4. package/index.js.map +1 -1
  5. package/package.json +4 -4
  6. package/src/components/alert-dialog/AlertDialog.tsx +2 -12
  7. package/src/components/autocomplete/Autocomplete.test.tsx +1 -1
  8. package/src/components/autocomplete/AutocompleteMultiple.test.tsx +1 -1
  9. package/src/components/badge/Badge.test.tsx +1 -1
  10. package/src/components/button/Button.test.tsx +2 -2
  11. package/src/components/button/IconButton.test.tsx +1 -1
  12. package/src/components/chip/Chip.test.tsx +22 -5
  13. package/src/components/chip/Chip.tsx +9 -5
  14. package/src/components/date-picker/DatePickerControlled.tsx +5 -4
  15. package/src/components/generic-block/GenericBlock.test.tsx +9 -9
  16. package/src/components/grid-column/GridColumn.tsx +32 -34
  17. package/src/components/icon/Icon.test.tsx +1 -1
  18. package/src/components/input-helper/InputHelper.test.tsx +1 -1
  19. package/src/components/link/Link.test.tsx +3 -3
  20. package/src/components/link-preview/LinkPreview.test.tsx +1 -2
  21. package/src/components/message/Message.test.tsx +1 -1
  22. package/src/components/mosaic/Mosaic.tsx +5 -4
  23. package/src/components/popover/Popover.tsx +13 -20
  24. package/src/components/select/Select.test.tsx +3 -3
  25. package/src/components/select/SelectMultiple.stories.tsx +56 -58
  26. package/src/components/select/SelectMultiple.test.tsx +4 -4
  27. package/src/components/side-navigation/SideNavigation.test.tsx +2 -2
  28. package/src/components/slideshow/SlideshowControls.stories.tsx +4 -9
  29. package/src/components/slideshow/useSlideFocusManagement.tsx +1 -1
  30. package/src/components/tabs/TabProvider.test.tsx +1 -1
  31. package/src/components/thumbnail/Thumbnail.stories.tsx +5 -5
  32. package/src/constants.ts +2 -2
  33. package/src/stories/decorators/withCombinations.tsx +76 -74
  34. package/src/utils/date/getFirstDayOfWeek.ts +2 -1
  35. package/src/utils/date/getMonthCalendar.test.ts +4 -0
  36. package/src/utils/date/getMonthCalendar.ts +10 -2
  37. package/src/utils/focus/constants.ts +4 -2
  38. package/src/utils/focus/getFirstAndLastFocusable.test.ts +19 -19
  39. package/src/utils/focus/getFocusableElements.test.ts +13 -13
  40. package/src/utils/type.ts +17 -13
  41. package/src/utils/utils.test.ts +5 -5
@@ -265,66 +265,64 @@ export const SelectWithinADialog = ({ theme }: any) => {
265
265
  searchText && searchText.length > 0 ? CHOICES.filter((choice) => choice.includes(searchText)) : CHOICES;
266
266
 
267
267
  return (
268
- <>
269
- <Dialog isOpen>
270
- <header>
271
- <Toolbar label={<span className="lumx-typography-title">Dialog header</span>} />
272
- </header>
273
- <div className="lumx-spacing-padding-horizontal-huge lumx-spacing-padding-bottom-huge">
274
- {/* Testing hidden input do not count in th focus trap*/}
275
- <input hidden type="file" />
276
- <input type="hidden" />
268
+ <Dialog isOpen>
269
+ <header>
270
+ <Toolbar label={<span className="lumx-typography-title">Dialog header</span>} />
271
+ </header>
272
+ <div className="lumx-spacing-padding-horizontal-huge lumx-spacing-padding-bottom-huge">
273
+ {/* Testing hidden input do not count in th focus trap*/}
274
+ <input hidden type="file" />
275
+ <input type="hidden" />
277
276
 
278
- <div className="lumx-spacing-margin-bottom-huge">The select should capture the focus on open.</div>
277
+ <div className="lumx-spacing-margin-bottom-huge">The select should capture the focus on open.</div>
279
278
 
280
- <SelectMultiple
281
- isOpen={isOpen}
282
- value={values}
283
- onClear={clearSelected}
284
- clearButtonProps={{ label: 'Clear' }}
285
- label={LABEL}
286
- placeholder={PLACEHOLDER}
287
- theme={theme}
288
- onInputClick={toggleSelect}
289
- onDropdownClose={closeSelect}
290
- icon={mdiTram}
291
- focusElement={searchFieldRef}
292
- >
293
- <List isClickable>
294
- <>
295
- <ListSubheader>
296
- <TextField
297
- clearButtonProps={{ label: 'Clear' }}
298
- placeholder="Search"
299
- role="searchbox"
300
- inputRef={searchFieldRef}
301
- onChange={setSearchText}
302
- value={searchText}
303
- />
304
- </ListSubheader>
305
- <ListDivider role="presentation" />
306
- </>
279
+ <SelectMultiple
280
+ isOpen={isOpen}
281
+ value={values}
282
+ onClear={clearSelected}
283
+ clearButtonProps={{ label: 'Clear' }}
284
+ label={LABEL}
285
+ placeholder={PLACEHOLDER}
286
+ theme={theme}
287
+ onInputClick={toggleSelect}
288
+ onDropdownClose={closeSelect}
289
+ icon={mdiTram}
290
+ focusElement={searchFieldRef}
291
+ >
292
+ <List isClickable>
293
+ <>
294
+ <ListSubheader>
295
+ <TextField
296
+ clearButtonProps={{ label: 'Clear' }}
297
+ placeholder="Search"
298
+ role="searchbox"
299
+ inputRef={searchFieldRef}
300
+ onChange={setSearchText}
301
+ value={searchText}
302
+ />
303
+ </ListSubheader>
304
+ <ListDivider role="presentation" />
305
+ </>
307
306
 
308
- {filteredChoices.length > 0
309
- ? filteredChoices.map((choice) => (
310
- <ListItem
311
- isSelected={values.includes(choice)}
312
- key={choice}
313
- onItemSelected={selectItem(choice)}
314
- size={Size.tiny}
315
- >
316
- {choice}
317
- </ListItem>
318
- ))
319
- : [
320
- <ListItem key={0} size={Size.tiny}>
321
- No data
322
- </ListItem>,
323
- ]}
324
- </List>
325
- </SelectMultiple>
326
- </div>
327
- </Dialog>
328
- </>
307
+ {filteredChoices.length > 0
308
+ ? filteredChoices.map((choice) => (
309
+ <ListItem
310
+ isSelected={values.includes(choice)}
311
+ key={choice}
312
+ onItemSelected={selectItem(choice)}
313
+ size={Size.tiny}
314
+ >
315
+ {choice}
316
+ </ListItem>
317
+ ))
318
+ : [
319
+ <ListItem key={0} size={Size.tiny}>
320
+ No data
321
+ </ListItem>,
322
+ ]}
323
+ </List>
324
+ </SelectMultiple>
325
+ </div>
326
+ </Dialog>
329
327
  );
330
328
  };
@@ -39,7 +39,7 @@ const setup = (props: Partial<SelectMultipleProps> = {}) => {
39
39
  return { props, select, getDropdown, helpers, inputWrapper, chip, valueChips };
40
40
  };
41
41
 
42
- describe(`<SelectMultiple>`, () => {
42
+ describe('<SelectMultiple>', () => {
43
43
  describe('Props', () => {
44
44
  it('should have default classNames', () => {
45
45
  const { select, inputWrapper, valueChips, chip } = setup();
@@ -48,7 +48,7 @@ describe(`<SelectMultiple>`, () => {
48
48
  expect(valueChips).toBeEmptyDOMElement();
49
49
  expect(chip).not.toBeInTheDocument();
50
50
  expect(select.className).toMatchInlineSnapshot(
51
- `"lumx-select lumx-select--has-multiple lumx-select lumx-select--is-empty lumx-select--theme-light"`,
51
+ '"lumx-select lumx-select--has-multiple lumx-select lumx-select--is-empty lumx-select--theme-light"',
52
52
  );
53
53
  });
54
54
 
@@ -119,7 +119,7 @@ describe(`<SelectMultiple>`, () => {
119
119
  expect(inputWrapper).not.toBeInTheDocument();
120
120
  expect(chip).toBeInTheDocument();
121
121
  expect(select.className).toMatchInlineSnapshot(
122
- `"lumx-select lumx-select--has-multiple lumx-select lumx-select--is-empty lumx-select--theme-light"`,
122
+ '"lumx-select lumx-select--has-multiple lumx-select lumx-select--is-empty lumx-select--theme-light"',
123
123
  );
124
124
  });
125
125
 
@@ -127,7 +127,7 @@ describe(`<SelectMultiple>`, () => {
127
127
  const { select, chip } = setup({ variant: SelectVariant.chip, value: ['val1', 'val2'] });
128
128
  expect(chip).toHaveTextContent('val1 +1');
129
129
  expect(select.className).toMatchInlineSnapshot(
130
- `"lumx-select lumx-select--has-multiple lumx-select lumx-select--has-value lumx-select--theme-light"`,
130
+ '"lumx-select lumx-select--has-multiple lumx-select lumx-select--has-value lumx-select--theme-light"',
131
131
  );
132
132
  });
133
133
 
@@ -21,12 +21,12 @@ const setup = (props: Partial<SideNavigationProps> = {}) => {
21
21
  describe(`<${SideNavigation.displayName}>`, () => {
22
22
  it('should render default', () => {
23
23
  const { sideNavigation } = setup();
24
- expect(sideNavigation.className).toMatchInlineSnapshot(`"lumx-side-navigation"`);
24
+ expect(sideNavigation.className).toMatchInlineSnapshot('"lumx-side-navigation"');
25
25
  });
26
26
 
27
27
  it('should render dark theme', () => {
28
28
  const { sideNavigation } = setup({ theme: Theme.dark });
29
- expect(sideNavigation.className).toMatchInlineSnapshot(`"lumx-color-font-light-N lumx-side-navigation"`);
29
+ expect(sideNavigation.className).toMatchInlineSnapshot('"lumx-color-font-light-N lumx-side-navigation"');
30
30
  });
31
31
 
32
32
  // Common tests suite.
@@ -7,15 +7,10 @@ import { LANDSCAPE_IMAGES } from '@lumx/react/stories/controls/image';
7
7
  export default { title: 'LumX components/slideshow/Slideshow controls' };
8
8
 
9
9
  export const Simple = () => {
10
- const {
11
- activeIndex,
12
- slidesCount,
13
- onNextClick,
14
- onPreviousClick,
15
- onPaginationClick,
16
- } = SlideshowControls.useSlideshowControls({
17
- itemsCount: 9,
18
- });
10
+ const { activeIndex, slidesCount, onNextClick, onPreviousClick, onPaginationClick } =
11
+ SlideshowControls.useSlideshowControls({
12
+ itemsCount: 9,
13
+ });
19
14
 
20
15
  return (
21
16
  <SlideshowControls
@@ -11,7 +11,7 @@ export interface UseSlideFocusManagementProps {
11
11
  * This is to easily find elements that have been tempered with,
12
12
  * and not elements whose focus was already initially blocked.
13
13
  * */
14
- const BLOCKED_FOCUS_CLASSNAME = `focus-blocked`;
14
+ const BLOCKED_FOCUS_CLASSNAME = 'focus-blocked';
15
15
 
16
16
  /**
17
17
  * Manage how slides must behave when visible or not.
@@ -21,7 +21,7 @@ const setup = (props: Partial<TabProviderProps> = {}) => {
21
21
  );
22
22
  };
23
23
 
24
- describe(`TabProvider`, () => {
24
+ describe('TabProvider', () => {
25
25
  describe('default config', () => {
26
26
  it('should render with accessible DOM', () => {
27
27
  setup();
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
 
3
- import { mdiAbTesting, mdiImageBroken } from '@lumx/icons';
3
+ import { mdiAbTesting } from '@lumx/icons';
4
4
  import { Alignment, AspectRatio, Badge, FlexBox, Icon, Size, Thumbnail, ThumbnailVariant } from '@lumx/react';
5
5
  import { CustomLink } from '@lumx/react/stories/utils/CustomLink';
6
6
  import { IMAGE_SIZES, imageArgType, IMAGES } from '@lumx/react/stories/controls/image';
@@ -159,16 +159,16 @@ export const Original = () => (
159
159
  </tr>
160
160
  <tr>
161
161
  <td>
162
- <Thumbnail alt="" image={IMAGES.landscape1} />
162
+ <Thumbnail alt="landscape image" image={IMAGES.landscape1} />
163
163
  </td>
164
164
  <td>
165
- <Thumbnail alt="" image={IMAGES.landscape1} imgProps={IMAGE_SIZES.landscape1} />
165
+ <Thumbnail alt="landscape image" image={IMAGES.landscape1} imgProps={IMAGE_SIZES.landscape1} />
166
166
  </td>
167
167
  <td>
168
- <Thumbnail alt="" image={IMAGES.portrait1} />
168
+ <Thumbnail alt="portrait image" image={IMAGES.portrait1} />
169
169
  </td>
170
170
  <td>
171
- <Thumbnail alt="" image={IMAGES.portrait1} imgProps={IMAGE_SIZES.portrait1} />
171
+ <Thumbnail alt="portrait image" image={IMAGES.portrait1} imgProps={IMAGE_SIZES.portrait1} />
172
172
  </td>
173
173
  </tr>
174
174
  </table>
package/src/constants.ts CHANGED
@@ -9,9 +9,9 @@ export {
9
9
  /**
10
10
  * Optional global `window` instance (not defined when running SSR).
11
11
  */
12
- export const WINDOW = typeof window !== `undefined` ? window : undefined;
12
+ export const WINDOW = typeof window !== 'undefined' ? window : undefined;
13
13
 
14
14
  /**
15
15
  * Optional global `document` instance (not defined when running SSR).
16
16
  */
17
- export const DOCUMENT = typeof document !== `undefined` ? document : undefined;
17
+ export const DOCUMENT = typeof document !== 'undefined' ? document : undefined;
@@ -20,80 +20,82 @@ function formatProps(config?: Combination): PropCombination {
20
20
  /**
21
21
  * SB decorator generating a tables of combination of props (max 3 levels of props)
22
22
  */
23
- export const withCombinations = ({
24
- combinations,
25
- tableStyle,
26
- firstColStyle,
27
- cellStyle,
28
- combinator = Object.assign,
29
- }: {
30
- /** Props combinations */
31
- combinations: {
32
- rows?: Combination;
33
- cols?: Combination;
34
- sections?: Combination;
35
- };
36
- /** Inject style on table */
37
- tableStyle?: React.CSSProperties;
38
- /** Inject style on first col */
39
- firstColStyle?: React.CSSProperties;
40
- /** Inject style on cells */
41
- cellStyle?: React.CSSProperties;
42
- /** Combinator function */
43
- combinator?: (a: any, b: any) => any;
44
- }) => (Story: any, ctx: any) => {
45
- const rows = formatProps(combinations.rows);
46
- const cols = formatProps(combinations.cols);
47
- const sections = formatProps(combinations.sections);
23
+ export const withCombinations =
24
+ ({
25
+ combinations,
26
+ tableStyle,
27
+ firstColStyle,
28
+ cellStyle,
29
+ combinator = Object.assign,
30
+ }: {
31
+ /** Props combinations */
32
+ combinations: {
33
+ rows?: Combination;
34
+ cols?: Combination;
35
+ sections?: Combination;
36
+ };
37
+ /** Inject style on table */
38
+ tableStyle?: React.CSSProperties;
39
+ /** Inject style on first col */
40
+ firstColStyle?: React.CSSProperties;
41
+ /** Inject style on cells */
42
+ cellStyle?: React.CSSProperties;
43
+ /** Combinator function */
44
+ combinator?: (a: any, b: any) => any;
45
+ }) =>
46
+ (Story: any, ctx: any) => {
47
+ const rows = formatProps(combinations.rows);
48
+ const cols = formatProps(combinations.cols);
49
+ const sections = formatProps(combinations.sections);
48
50
 
49
- return (
50
- <>
51
- {Object.entries(sections).map(([level2Key, level2Value]) => (
52
- <div key={level2Key}>
53
- {level2Key && <h2>{level2Key}</h2>}
51
+ return (
52
+ <>
53
+ {Object.entries(sections).map(([level2Key, level2Value]) => (
54
+ <div key={level2Key}>
55
+ {level2Key && <h2>{level2Key}</h2>}
54
56
 
55
- <table style={{ ...tableStyle, borderCollapse: 'separate', borderSpacing: 8 }}>
56
- {combinations.cols && (
57
- <thead>
58
- <tr>
59
- <th />
60
- {Object.keys(cols).map((key) => (
61
- <th key={key}>
62
- <small>{key}</small>
57
+ <table style={{ ...tableStyle, borderCollapse: 'separate', borderSpacing: 8 }}>
58
+ {combinations.cols && (
59
+ <thead>
60
+ <tr>
61
+ <th />
62
+ {Object.keys(cols).map((key) => (
63
+ <th key={key}>
64
+ <small>{key}</small>
65
+ </th>
66
+ ))}
67
+ </tr>
68
+ </thead>
69
+ )}
70
+ <tbody>
71
+ {Object.entries(rows).map(([level0Key, level0Value], i1) => (
72
+ <tr key={i1}>
73
+ <th style={{ ...firstColStyle, textAlign: 'left' }}>
74
+ <small>{level0Key}</small>
63
75
  </th>
64
- ))}
65
- </tr>
66
- </thead>
67
- )}
68
- <tbody>
69
- {Object.entries(rows).map(([level0Key, level0Value], i1) => (
70
- <tr key={i1}>
71
- <th style={{ ...firstColStyle, textAlign: 'left' }}>
72
- <small>{level0Key}</small>
73
- </th>
74
- {Object.entries(cols).map(([level1Key, level1Value]) => {
75
- const args = [level0Value, level1Value, level2Value].reduce(
76
- (acc, value) => combinator(acc, value),
77
- { ...ctx.args },
78
- );
79
- return (
80
- <td
81
- key={level1Key}
82
- style={{
83
- textAlign: combinations.cols ? 'center' : undefined,
84
- ...cellStyle,
85
- }}
86
- >
87
- <Story args={args} />
88
- </td>
89
- );
90
- })}
91
- </tr>
92
- ))}
93
- </tbody>
94
- </table>
95
- </div>
96
- ))}
97
- </>
98
- );
99
- };
76
+ {Object.entries(cols).map(([level1Key, level1Value]) => {
77
+ const args = [level0Value, level1Value, level2Value].reduce(
78
+ (acc, value) => combinator(acc, value),
79
+ { ...ctx.args },
80
+ );
81
+ return (
82
+ <td
83
+ key={level1Key}
84
+ style={{
85
+ textAlign: combinations.cols ? 'center' : undefined,
86
+ ...cellStyle,
87
+ }}
88
+ >
89
+ <Story args={args} />
90
+ </td>
91
+ );
92
+ })}
93
+ </tr>
94
+ ))}
95
+ </tbody>
96
+ </table>
97
+ </div>
98
+ ))}
99
+ </>
100
+ );
101
+ };
@@ -22,7 +22,8 @@ const FIRST_DAY_FOR_LOCALES = [
22
22
  },
23
23
  {
24
24
  // Locales with Monday as the first day of the week
25
- localeRX: /^(ar-(ma|tn)|az|be|bg|bs|ca|cs|da|de|el|en-(au|gb|ie|in|nz)|eo|es|et|eu|fi|fr|fy|gl|gu|hr|ht|hu|hy|id|is|it|ka|kk|kn|lb|lt|lv|mk|mn|ms|mt|nb|nl|nn|oc|pl|pt|ro|ru|sk|sl|sq|sr|sv|ta|tr|uk|uz|vi|zh-(cn|tw))$/i,
25
+ localeRX:
26
+ /^(ar-(ma|tn)|az|be|bg|bs|ca|cs|da|de|el|en-(au|gb|ie|in|nz)|eo|es|et|eu|fi|fr|fy|gl|gu|hr|ht|hu|hy|id|is|it|ka|kk|kn|lb|lt|lv|mk|mn|ms|mt|nb|nl|nn|oc|pl|pt|ro|ru|sk|sl|sq|sr|sv|ta|tr|uk|uz|vi|zh-(cn|tw))$/i,
26
27
  firstDay: 1,
27
28
  },
28
29
  {
@@ -57,6 +57,8 @@ describe(getMonthCalendar.name, () => {
57
57
  '1': { date: new Date('2017-02-27') },
58
58
  '2': { date: new Date('2017-02-28') },
59
59
  },
60
+ // Empty row (used for padding to avoid layout shift)
61
+ {},
60
62
  ],
61
63
  });
62
64
  });
@@ -117,6 +119,8 @@ describe(getMonthCalendar.name, () => {
117
119
  '1': { date: new Date('2017-02-27'), isOutOfRange: true },
118
120
  '2': { date: new Date('2017-02-28'), isOutOfRange: true },
119
121
  },
122
+ // Empty row (used for padding to avoid layout shift)
123
+ {},
120
124
  ],
121
125
  });
122
126
  });
@@ -11,6 +11,9 @@ interface MonthCalendar {
11
11
  weeks: Array<AnnotatedWeek>;
12
12
  }
13
13
 
14
+ /** Up to 6 rows can appear in a month calendar => 4 weeks + 1 start of month partial week + 1 send of month partial week */
15
+ const MONTH_ROW_COUNT = 6;
16
+
14
17
  /**
15
18
  * Get month calendar.
16
19
  * A list of weeks with days indexed by week day number
@@ -30,7 +33,8 @@ export const getMonthCalendar = (
30
33
 
31
34
  const weeks: Array<AnnotatedWeek> = [];
32
35
  let week: AnnotatedWeek = {};
33
- while (iterDate.getMonth() === month) {
36
+ let rowCount = 0;
37
+ while (rowCount < MONTH_ROW_COUNT) {
34
38
  const weekDayNumber = iterDate.getDay();
35
39
  const day: AnnotatedDay = { date: new Date(iterDate.getTime()) };
36
40
 
@@ -39,9 +43,13 @@ export const getMonthCalendar = (
39
43
  day.isOutOfRange = true;
40
44
  }
41
45
 
42
- week[weekDayNumber] = day;
46
+ if (iterDate.getMonth() === month) {
47
+ week[weekDayNumber] = day;
48
+ }
49
+
43
50
  if (weekDayNumber === lastDayOfWeek.number) {
44
51
  weeks.push(week);
52
+ rowCount += 1;
45
53
  week = {};
46
54
  }
47
55
  iterDate.setDate(iterDate.getDate() + 1);
@@ -1,5 +1,7 @@
1
1
  /** CSS selector listing all tabbable elements. */
2
- export const TABBABLE_ELEMENTS_SELECTOR = `a[href], button, textarea, input:not([type="hidden"]):not([hidden]), [tabindex]`;
2
+ export const TABBABLE_ELEMENTS_SELECTOR =
3
+ 'a[href], button, textarea, input:not([type="hidden"]):not([hidden]), [tabindex]';
3
4
 
4
5
  /** CSS selector matching element that are disabled (should not receive focus). */
5
- export const DISABLED_SELECTOR = `[hidden], [tabindex="-1"], [disabled]:not([disabled="false"]), [aria-disabled]:not([aria-disabled="false"])`;
6
+ export const DISABLED_SELECTOR =
7
+ '[hidden], [tabindex="-1"], [disabled]:not([disabled="false"]), [aria-disabled]:not([aria-disabled="false"])';
@@ -8,13 +8,13 @@ function htmlToElement(html: string): any {
8
8
 
9
9
  describe(getFirstAndLastFocusable.name, () => {
10
10
  it('should get empty', () => {
11
- const element = htmlToElement(`<div></div>`);
11
+ const element = htmlToElement('<div></div>');
12
12
  const focusable = getFirstAndLastFocusable(element);
13
13
  expect(focusable).toEqual({});
14
14
  });
15
15
 
16
16
  it('should get single item', () => {
17
- const element = htmlToElement(`<div><button /></div>`);
17
+ const element = htmlToElement('<div><button /></div>');
18
18
  const focusable = getFirstAndLastFocusable(element);
19
19
  expect(focusable.last).toBe(focusable.first);
20
20
  });
@@ -44,13 +44,13 @@ describe(getFirstAndLastFocusable.name, () => {
44
44
 
45
45
  describe('match focusable elements', () => {
46
46
  it('should match input element', () => {
47
- const element = htmlToElement(`<div><input /></div>`);
47
+ const element = htmlToElement('<div><input /></div>');
48
48
  const focusable = getFirstAndLastFocusable(element);
49
- expect(focusable.first).toMatchInlineSnapshot(`<input />`);
49
+ expect(focusable.first).toMatchInlineSnapshot('<input />');
50
50
  });
51
51
 
52
52
  it('should match link element', () => {
53
- const element = htmlToElement(`<div><a href="#" /></div>`);
53
+ const element = htmlToElement('<div><a href="#" /></div>');
54
54
  const focusable = getFirstAndLastFocusable(element);
55
55
  expect(focusable.first).toMatchInlineSnapshot(`
56
56
  <a
@@ -60,7 +60,7 @@ describe(getFirstAndLastFocusable.name, () => {
60
60
  });
61
61
 
62
62
  it('should match textarea element', () => {
63
- const element = htmlToElement(`<div><textarea /></div>`);
63
+ const element = htmlToElement('<div><textarea /></div>');
64
64
  const focusable = getFirstAndLastFocusable(element);
65
65
  expect(focusable.first).toMatchInlineSnapshot(`
66
66
  <textarea>
@@ -70,7 +70,7 @@ describe(getFirstAndLastFocusable.name, () => {
70
70
  });
71
71
 
72
72
  it('should match element with tabindex', () => {
73
- const element = htmlToElement(`<div><span tabindex="0" /></div>`);
73
+ const element = htmlToElement('<div><span tabindex="0" /></div>');
74
74
  const focusable = getFirstAndLastFocusable(element);
75
75
  expect(focusable.first).toMatchInlineSnapshot(`
76
76
  <span
@@ -80,7 +80,7 @@ describe(getFirstAndLastFocusable.name, () => {
80
80
  });
81
81
 
82
82
  it('should keep disabled=false', () => {
83
- const element = htmlToElement(`<div><button disabled="false" /><button /></div>`);
83
+ const element = htmlToElement('<div><button disabled="false" /><button /></div>');
84
84
  const focusable = getFirstAndLastFocusable(element);
85
85
  expect(focusable.first).toMatchInlineSnapshot(`
86
86
  <button
@@ -90,7 +90,7 @@ describe(getFirstAndLastFocusable.name, () => {
90
90
  });
91
91
 
92
92
  it('should keep aria-disabled=false', () => {
93
- const element = htmlToElement(`<div><button aria-disabled="false" /><button /></div>`);
93
+ const element = htmlToElement('<div><button aria-disabled="false" /><button /></div>');
94
94
  const focusable = getFirstAndLastFocusable(element);
95
95
  expect(focusable.first).toMatchInlineSnapshot(`
96
96
  <button
@@ -102,33 +102,33 @@ describe(getFirstAndLastFocusable.name, () => {
102
102
 
103
103
  describe('skip disabled elements', () => {
104
104
  it('should skip disabled', () => {
105
- const element = htmlToElement(`<div><button disabled /><button /></div>`);
105
+ const element = htmlToElement('<div><button disabled /><button /></div>');
106
106
  const focusable = getFirstAndLastFocusable(element);
107
- expect(focusable.first).toMatchInlineSnapshot(`<button />`);
107
+ expect(focusable.first).toMatchInlineSnapshot('<button />');
108
108
  });
109
109
 
110
110
  it('should skip aria-disabled', () => {
111
- const element = htmlToElement(`<div><button aria-disabled /><button /></div>`);
111
+ const element = htmlToElement('<div><button aria-disabled /><button /></div>');
112
112
  const focusable = getFirstAndLastFocusable(element);
113
- expect(focusable.first).toMatchInlineSnapshot(`<button />`);
113
+ expect(focusable.first).toMatchInlineSnapshot('<button />');
114
114
  });
115
115
 
116
116
  it('should skip tabindex=-1', () => {
117
- const element = htmlToElement(`<div><button tabindex="-1" /><button /></div>`);
117
+ const element = htmlToElement('<div><button tabindex="-1" /><button /></div>');
118
118
  const focusable = getFirstAndLastFocusable(element);
119
- expect(focusable.first).toMatchInlineSnapshot(`<button />`);
119
+ expect(focusable.first).toMatchInlineSnapshot('<button />');
120
120
  });
121
121
 
122
122
  it('should skip input type hidden', () => {
123
- const element = htmlToElement(`<div><input type="hidden" /><button /></div>`);
123
+ const element = htmlToElement('<div><input type="hidden" /><button /></div>');
124
124
  const focusable = getFirstAndLastFocusable(element);
125
- expect(focusable.first).toMatchInlineSnapshot(`<button />`);
125
+ expect(focusable.first).toMatchInlineSnapshot('<button />');
126
126
  });
127
127
 
128
128
  it('should skip hidden input', () => {
129
- const element = htmlToElement(`<div><input hidden /><button /></div>`);
129
+ const element = htmlToElement('<div><input hidden /><button /></div>');
130
130
  const focusable = getFirstAndLastFocusable(element);
131
- expect(focusable.first).toMatchInlineSnapshot(`<button />`);
131
+ expect(focusable.first).toMatchInlineSnapshot('<button />');
132
132
  });
133
133
  });
134
134
  });