@patternfly/react-core 4.232.0 → 4.232.3

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patternfly/react-core",
3
- "version": "4.232.0",
3
+ "version": "4.232.3",
4
4
  "description": "This library provides a set of common React components for use with the PatternFly reference implementation.",
5
5
  "main": "dist/js/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -50,9 +50,9 @@
50
50
  "generate": "node scripts/copyStyles.js"
51
51
  },
52
52
  "dependencies": {
53
- "@patternfly/react-icons": "^4.83.0",
54
- "@patternfly/react-styles": "^4.82.0",
55
- "@patternfly/react-tokens": "^4.84.0",
53
+ "@patternfly/react-icons": "^4.83.3",
54
+ "@patternfly/react-styles": "^4.82.3",
55
+ "@patternfly/react-tokens": "^4.84.3",
56
56
  "focus-trap": "6.9.2",
57
57
  "react-dropzone": "9.0.0",
58
58
  "tippy.js": "5.1.2",
@@ -76,5 +76,5 @@
76
76
  "react": "^16.8.0 || ^17.0.0",
77
77
  "react-dom": "^16.8.0 || ^17.0.0"
78
78
  },
79
- "gitHead": "6faf7d797507f4ac5e1453f4755695a33c33a9ab"
79
+ "gitHead": "b795fb56a4d187599e9dd7f9715f11138715caa9"
80
80
  }
@@ -558,7 +558,7 @@ export class Select extends React.Component<SelectProps & OUIAProps, SelectState
558
558
  };
559
559
 
560
560
  extendTypeaheadChildren(typeaheadCurrIndex: number, favoritesGroup?: React.ReactNode[]) {
561
- const { isGrouped, onFavorite } = this.props;
561
+ const { isGrouped, onFavorite, createText } = this.props;
562
562
  const typeaheadChildren = favoritesGroup
563
563
  ? favoritesGroup.concat(this.state.typeaheadFilteredChildren)
564
564
  : this.state.typeaheadFilteredChildren;
@@ -586,8 +586,8 @@ export class Select extends React.Component<SelectProps & OUIAProps, SelectState
586
586
  activeElement &&
587
587
  (activeElement.id === (child as React.ReactElement).props.id ||
588
588
  (this.props.isCreatable &&
589
- typeaheadActiveChild.innerText ===
590
- `{createText} "${(group as React.ReactElement).props.value}"`))
589
+ typeaheadActiveChild.textContent ===
590
+ `${createText} "${(group as React.ReactElement).props.value}"`))
591
591
  })
592
592
  )
593
593
  });
@@ -600,10 +600,10 @@ export class Select extends React.Component<SelectProps & OUIAProps, SelectState
600
600
  : React.cloneElement(child as React.ReactElement, {
601
601
  isFocused:
602
602
  typeaheadActiveChild &&
603
- (typeaheadActiveChild.innerText === (child as React.ReactElement).props.value.toString() ||
603
+ (typeaheadActiveChild.textContent === (child as React.ReactElement).props.value.toString() ||
604
604
  (this.props.isCreatable &&
605
- typeaheadActiveChild.innerText ===
606
- `{createText} "${(child as React.ReactElement).props.value}"`))
605
+ typeaheadActiveChild.textContent ===
606
+ `${createText} "${(child as React.ReactElement).props.value}"`))
607
607
  })
608
608
  )
609
609
  });
@@ -612,8 +612,8 @@ export class Select extends React.Component<SelectProps & OUIAProps, SelectState
612
612
  return React.cloneElement(group as React.ReactElement, {
613
613
  isFocused:
614
614
  typeaheadActiveChild &&
615
- (typeaheadActiveChild.innerText === group.props.value.toString() ||
616
- (this.props.isCreatable && typeaheadActiveChild.innerText === `{createText} "${group.props.value}"`))
615
+ (typeaheadActiveChild.textContent === group.props.value.toString() ||
616
+ (this.props.isCreatable && typeaheadActiveChild.textContent === `${createText} "${group.props.value}"`))
617
617
  });
618
618
  }
619
619
  });
@@ -624,9 +624,9 @@ export class Select extends React.Component<SelectProps & OUIAProps, SelectState
624
624
  ? child
625
625
  : React.cloneElement(child as React.ReactElement, {
626
626
  isFocused: typeaheadActiveChild
627
- ? typeaheadActiveChild.innerText === (child as React.ReactElement).props.value.toString() ||
627
+ ? typeaheadActiveChild.textContent === (child as React.ReactElement).props.value.toString() ||
628
628
  (this.props.isCreatable &&
629
- typeaheadActiveChild.innerText === `{createText} "${(child as React.ReactElement).props.value}"`)
629
+ typeaheadActiveChild.textContent === `${createText} "${(child as React.ReactElement).props.value}"`)
630
630
  : index === typeaheadCurrIndex // fallback for view more + typeahead use cases, when the new expanded list is loaded and refCollection hasn't be updated yet
631
631
  });
632
632
  });
@@ -665,11 +665,11 @@ export class Select extends React.Component<SelectProps & OUIAProps, SelectState
665
665
  : this.refCollection[nextIndex][0];
666
666
 
667
667
  let typeaheadInputValue = '';
668
- if (isCreatable && optionTextElm.innerText.includes(createText)) {
668
+ if (isCreatable && optionTextElm.textContent.includes(createText)) {
669
669
  typeaheadInputValue = this.state.creatableValue;
670
670
  } else if (optionTextElm && !isLoad) {
671
671
  // !isLoad prevents the view more button text from appearing the typeahead input
672
- typeaheadInputValue = optionTextElm.innerText;
672
+ typeaheadInputValue = optionTextElm.textContent;
673
673
  }
674
674
  this.setState(prevState => ({
675
675
  typeaheadCurrIndex: updateCurrentIndex ? nextIndex : prevState.typeaheadCurrIndex,
@@ -725,15 +725,15 @@ export class Select extends React.Component<SelectProps & OUIAProps, SelectState
725
725
  if (!typeaheadActiveChild.classList.contains('pf-m-load')) {
726
726
  const hasDescriptionElm = typeaheadActiveChild.childElementCount > 1;
727
727
  const typeaheadActiveChildText = hasDescriptionElm
728
- ? (typeaheadActiveChild.firstChild as HTMLElement).innerText
729
- : typeaheadActiveChild.innerText;
728
+ ? (typeaheadActiveChild.firstChild as HTMLElement).textContent
729
+ : typeaheadActiveChild.textContent;
730
730
  this.setState({
731
731
  typeaheadInputValue: typeaheadActiveChildText
732
732
  });
733
733
  }
734
734
  } else if (this.refCollection[0] && this.refCollection[0][0]) {
735
735
  this.setState({
736
- typeaheadInputValue: this.refCollection[0][0].innerText
736
+ typeaheadInputValue: this.refCollection[0][0].textContent
737
737
  });
738
738
  }
739
739
  if (typeaheadActiveChild) {
@@ -1267,7 +1267,6 @@ export class Select extends React.Component<SelectProps & OUIAProps, SelectState
1267
1267
  className
1268
1268
  )}
1269
1269
  {...(width && { style: { width } })}
1270
- {...(ariaDescribedby && { 'aria-describedby': ariaDescribedby })}
1271
1270
  {...(validated !== ValidatedOptions.default && { 'aria-invalid': ariaInvalid })}
1272
1271
  >
1273
1272
  {isOpen && menuContainer}
@@ -1288,7 +1287,6 @@ export class Select extends React.Component<SelectProps & OUIAProps, SelectState
1288
1287
  ref={this.parentRef}
1289
1288
  {...getOUIAProps(Select.displayName, ouiaId !== undefined ? ouiaId : this.state.ouiaStateId, ouiaSafe)}
1290
1289
  {...(width && { style: { width } })}
1291
- {...(ariaDescribedby && { 'aria-describedby': ariaDescribedby })}
1292
1290
  {...(validated !== ValidatedOptions.default && { 'aria-invalid': ariaInvalid })}
1293
1291
  >
1294
1292
  <SelectToggle
@@ -1308,6 +1306,7 @@ export class Select extends React.Component<SelectProps & OUIAProps, SelectState
1308
1306
  variant={variant}
1309
1307
  aria-labelledby={`${ariaLabelledBy || ''} ${selectToggleId}`}
1310
1308
  aria-label={toggleAriaLabel}
1309
+ {...(ariaDescribedby && { 'aria-describedby': ariaDescribedby })}
1311
1310
  handleTypeaheadKeys={this.handleTypeaheadKeys}
1312
1311
  moveFocusToLastMenuItem={this.moveFocusToLastMenuItem}
1313
1312
  isDisabled={isDisabled}
@@ -516,3 +516,23 @@ describe('select with placeholder', () => {
516
516
  expect(screen.getByRole('button', { name: 'Options menu' })).not.toHaveClass('pf-m-placeholder');
517
517
  });
518
518
  });
519
+
520
+ test('applies focus styling to the create option when reached via keyboard navigation', () => {
521
+ render(
522
+ <Select
523
+ variant={SelectVariant.typeahead}
524
+ onToggle={() => {}}
525
+ isOpen
526
+ isCreatable
527
+ >
528
+ {selectOptions}
529
+ </Select>
530
+ );
531
+
532
+ const input = screen.getByRole('textbox');
533
+ userEvent.type(input, 'a{arrowdown}');
534
+
535
+ const createOption = screen.getByRole('option', { name: 'Create "a"' });
536
+
537
+ expect(createOption.parentElement).toHaveClass('pf-m-focus');
538
+ });
@@ -0,0 +1,403 @@
1
+ import React from 'react';
2
+ import { render, screen } from '@testing-library/react';
3
+ import '@testing-library/jest-dom';
4
+ import userEvent from '@testing-library/user-event';
5
+ import { OverflowTab } from '../OverflowTab';
6
+ import { TabsContext } from '../TabsContext';
7
+
8
+ jest.mock('../../../helpers', () => ({
9
+ Popper: ({ trigger, popper, isVisible, popperMatchesTriggerWidth, appendTo }) => (
10
+ <div data-testid="popper-mock">
11
+ <div data-testid="trigger">{trigger}</div>
12
+ <div data-testid="popper">{isVisible && popper}</div>
13
+ <p>Popper matches trigger width: {`${popperMatchesTriggerWidth}`}</p>
14
+ <p>Append to class name: {appendTo && `${appendTo.className}`}</p>
15
+ </div>
16
+ )
17
+ }));
18
+
19
+ jest.mock('../../Menu', () => {
20
+ const { forwardRef } = jest.requireActual('react');
21
+ return {
22
+ Menu: forwardRef((props: { children; onSelect }, ref) => (
23
+ <div data-testid="menu-mock" ref={ref}>
24
+ {props.children}
25
+ <button onClick={() => props.onSelect('mouseEvent', 1, 'fakeRef')}>Select</button>
26
+ </div>
27
+ )),
28
+ MenuContent: ({ children }) => <div data-testid="menu-content-mock">{children}</div>,
29
+ MenuList: ({ children }) => <ul data-testid="menu-list-mock">{children}</ul>,
30
+ MenuItem: ({ children, itemId, isSelected }) => (
31
+ <>
32
+ <li id={`${itemId}-menu-item-mock`}>
33
+ {children}
34
+ <p>Selected: {`${isSelected}`}</p>
35
+ </li>
36
+ </>
37
+ )
38
+ };
39
+ });
40
+
41
+ const tabsContextDefaultProps = {
42
+ variant: 'default' as 'default',
43
+ mountOnEnter: false,
44
+ unmountOnExit: false,
45
+ localActiveKey: '',
46
+ uniqueId: '',
47
+ handleTabClick: () => null,
48
+ handleTabClose: undefined
49
+ };
50
+
51
+ test('Renders', () => {
52
+ render(
53
+ <div data-testid="overflow-tab-container">
54
+ <OverflowTab />
55
+ </div>
56
+ );
57
+
58
+ expect(screen.getByTestId('overflow-tab-container').firstChild).toBeVisible();
59
+ });
60
+
61
+ test('Renders with the passed aria label', () => {
62
+ render(<OverflowTab aria-label="Overflow tab label test" />);
63
+
64
+ expect(screen.getByRole('presentation')).toHaveAccessibleName('Overflow tab label test');
65
+ });
66
+
67
+ test('Renders with inherited element props spread to the component', () => {
68
+ render(
69
+ <>
70
+ <OverflowTab aria-labelledby="labelling-id" />
71
+ <p id="labelling-id">Label</p>
72
+ </>
73
+ );
74
+
75
+ expect(screen.getByRole('presentation')).toHaveAccessibleName('Label');
76
+ });
77
+
78
+ test('Renders with class names pf-m-overflow and pf-c-tabs__item on the presentation element', () => {
79
+ render(<OverflowTab />);
80
+
81
+ expect(screen.getByRole('presentation')).toHaveClass('pf-m-overflow');
82
+ expect(screen.getByRole('presentation')).toHaveClass('pf-c-tabs__item');
83
+ });
84
+
85
+ test('Renders with class pf-c-tabs__link on the tab element', () => {
86
+ render(<OverflowTab />);
87
+
88
+ expect(screen.getByRole('tab')).toHaveClass('pf-c-tabs__link');
89
+ });
90
+
91
+ test("Renders with class pf-c-tabs__link-toggle-icon on the img element's container", () => {
92
+ render(<OverflowTab />);
93
+
94
+ expect(screen.getByRole('img', { hidden: true }).parentElement).toHaveClass('pf-c-tabs__link-toggle-icon');
95
+ });
96
+
97
+ test('Renders with custom class names provided via prop', () => {
98
+ render(<OverflowTab className="test-class" />);
99
+
100
+ expect(screen.getByRole('presentation')).toHaveClass('test-class');
101
+ });
102
+
103
+ test('Renders without pf-m-expanded on the tab element by default', () => {
104
+ render(<OverflowTab />);
105
+
106
+ expect(screen.getByRole('tab')).not.toHaveClass('pf-m-expanded');
107
+ });
108
+
109
+ test('Renders with pf-m-expanded on the tab element once clicked', () => {
110
+ render(<OverflowTab />);
111
+
112
+ const overflowTab = screen.getByRole('tab');
113
+
114
+ userEvent.click(overflowTab);
115
+
116
+ expect(overflowTab).toHaveClass('pf-m-expanded');
117
+ });
118
+
119
+ test('Renders without pf-m-current on the presentation element by default', () => {
120
+ render(<OverflowTab />);
121
+
122
+ expect(screen.getByRole('presentation')).not.toHaveClass('pf-m-current');
123
+ });
124
+
125
+ test('Renders without pf-m-current when the overflowingTabs does not include the tab indicated by localActiveKey via a context', () => {
126
+ render(
127
+ <TabsContext.Provider value={{ ...tabsContextDefaultProps, localActiveKey: 0 }}>
128
+ <OverflowTab overflowingTabs={[{ title: 'tabTitle', eventKey: 1 }]} />
129
+ </TabsContext.Provider>
130
+ );
131
+
132
+ expect(screen.getByRole('presentation')).not.toHaveClass('pf-m-current');
133
+ });
134
+
135
+ test("Renders with pf-m-current when TabContext's localActiveKey matches an overflowingTabs' eventKey", () => {
136
+ render(
137
+ <TabsContext.Provider value={{ ...tabsContextDefaultProps, localActiveKey: 1 }}>
138
+ <OverflowTab overflowingTabs={[{ title: 'Tab one', eventKey: 1 }]} />
139
+ </TabsContext.Provider>
140
+ );
141
+
142
+ expect(screen.getByRole('presentation')).toHaveClass('pf-m-current');
143
+ });
144
+
145
+ test('Does not render tabs passed via overflowingTabs when not expanded', () => {
146
+ render(
147
+ <OverflowTab
148
+ overflowingTabs={[
149
+ { title: 'Tab one', eventKey: 1 },
150
+ { title: 'Tab two', eventKey: 2 }
151
+ ]}
152
+ />
153
+ );
154
+
155
+ expect(screen.queryByText('Tab one')).not.toBeInTheDocument();
156
+ expect(screen.queryByText('Tab two')).not.toBeInTheDocument();
157
+ });
158
+
159
+ test('Renders tabs passed via overflowingTabs when expanded', () => {
160
+ render(
161
+ <OverflowTab
162
+ overflowingTabs={[
163
+ { title: 'Tab one', eventKey: 1 },
164
+ { title: 'Tab two', eventKey: 2 }
165
+ ]}
166
+ />
167
+ );
168
+
169
+ userEvent.click(screen.getByRole('tab', { name: 'More' }));
170
+
171
+ expect(screen.getByText('Tab one')).toBeVisible();
172
+ expect(screen.getByText('Tab two')).toBeVisible();
173
+ });
174
+
175
+ test('Closes the overflowing tabs menu when a tab is selected', () => {
176
+ render(
177
+ <TabsContext.Provider value={{ ...tabsContextDefaultProps, localActiveKey: 0 }}>
178
+ <OverflowTab
179
+ overflowingTabs={[
180
+ { title: 'Tab one', eventKey: 1, tabContentRef: ('fakeRef' as unknown) as React.RefObject<any> },
181
+ { title: 'Tab two', eventKey: 2, tabContentRef: ('fakeRef' as unknown) as React.RefObject<any> }
182
+ ]}
183
+ />
184
+ </TabsContext.Provider>
185
+ );
186
+
187
+ userEvent.click(screen.getByRole('tab', { name: 'More' }));
188
+
189
+ // rather than actually clicking a menu item here we click the Select button provided via our Menu mock to keep the mocks simpler
190
+ userEvent.click(screen.getByRole('button', { name: 'Select' }));
191
+
192
+ expect(screen.queryByText('Tab two')).not.toBeInTheDocument();
193
+ });
194
+
195
+ test('Closes the overflowing tabs menu when the user clicks outside of the menu', () => {
196
+ render(
197
+ <TabsContext.Provider value={{ ...tabsContextDefaultProps, localActiveKey: 0 }}>
198
+ <OverflowTab
199
+ overflowingTabs={[
200
+ { title: 'Tab one', eventKey: 1, tabContentRef: ('fakeRef' as unknown) as React.RefObject<any> },
201
+ { title: 'Tab two', eventKey: 2, tabContentRef: ('fakeRef' as unknown) as React.RefObject<any> }
202
+ ]}
203
+ />
204
+ </TabsContext.Provider>
205
+ );
206
+
207
+ userEvent.click(screen.getByRole('tab', { name: 'More' }));
208
+
209
+ userEvent.click(document.body);
210
+
211
+ expect(screen.queryByText('Tab two')).not.toBeInTheDocument();
212
+ });
213
+
214
+ test('Calls the onTabClick callback provided via context when a tab is clicked', () => {
215
+ const mockHandleTabClick = jest.fn();
216
+
217
+ render(
218
+ <TabsContext.Provider value={{ ...tabsContextDefaultProps, handleTabClick: mockHandleTabClick }}>
219
+ <OverflowTab
220
+ overflowingTabs={[
221
+ { title: 'Tab one', eventKey: 1, tabContentRef: ('fakeRef' as unknown) as React.RefObject<any> }
222
+ ]}
223
+ />
224
+ </TabsContext.Provider>
225
+ );
226
+
227
+ userEvent.click(screen.getByRole('tab', { name: 'More' }));
228
+
229
+ // rather than actually clicking a menu item here we click the Select button provided via our Menu mock to keep the mocks simpler
230
+ userEvent.click(screen.getByRole('button', { name: 'Select' }));
231
+
232
+ expect(mockHandleTabClick).toHaveBeenCalledTimes(1);
233
+ expect(mockHandleTabClick).toHaveBeenCalledWith('mouseEvent', 1, 'fakeRef');
234
+ });
235
+
236
+ test('Does not show the overflowing tab count by default', () => {
237
+ render(
238
+ <OverflowTab
239
+ overflowingTabs={[
240
+ { title: 'Tab one', eventKey: 1 },
241
+ { title: 'Tab two', eventKey: 2 }
242
+ ]}
243
+ />
244
+ );
245
+
246
+ expect(screen.queryByRole('tab', { name: 'More (2)' })).not.toBeInTheDocument();
247
+ });
248
+
249
+ test('Shows the overflowing tab count when showTabCount is true', () => {
250
+ render(
251
+ <OverflowTab
252
+ overflowingTabs={[
253
+ { title: 'Tab one', eventKey: 1 },
254
+ { title: 'Tab two', eventKey: 2 }
255
+ ]}
256
+ showTabCount
257
+ />
258
+ );
259
+
260
+ expect(screen.getByRole('tab', { name: 'More (2)' })).toBeVisible();
261
+ });
262
+
263
+ test('Uses "More" as the default overflow tab title', () => {
264
+ render(<OverflowTab />);
265
+
266
+ expect(screen.getByRole('tab')).toHaveTextContent('More');
267
+ });
268
+
269
+ test('Uses the selected tab title as the overflow tab title rather than the default title when a tab is selected', () => {
270
+ render(
271
+ <TabsContext.Provider value={{ ...tabsContextDefaultProps, localActiveKey: 1 }}>
272
+ <OverflowTab
273
+ overflowingTabs={[
274
+ { title: 'Tab one', eventKey: 1, tabContentRef: ('fakeRef' as unknown) as React.RefObject<any> }
275
+ ]}
276
+ />
277
+ </TabsContext.Provider>
278
+ );
279
+
280
+ expect(screen.getByRole('tab')).toHaveTextContent('Tab one');
281
+ });
282
+
283
+ test('Uses custom overflow tab title text provided via defaultTitleText', () => {
284
+ render(<OverflowTab defaultTitleText="Test" />);
285
+
286
+ expect(screen.getByRole('tab')).toHaveTextContent('Test');
287
+ });
288
+
289
+ test('Uses the selected tab title as the overflow tab title rather than the defaultTitleText when a tab is selected', () => {
290
+ render(
291
+ <TabsContext.Provider value={{ ...tabsContextDefaultProps, localActiveKey: 1 }}>
292
+ <OverflowTab
293
+ overflowingTabs={[
294
+ { title: 'Tab one', eventKey: 1, tabContentRef: ('fakeRef' as unknown) as React.RefObject<any> }
295
+ ]}
296
+ defaultTitleText="Test"
297
+ />
298
+ </TabsContext.Provider>
299
+ );
300
+
301
+ expect(screen.getByRole('tab')).toHaveTextContent('Tab one');
302
+ });
303
+
304
+ test('Does not have an aria label on the tab by default', () => {
305
+ render(<OverflowTab />);
306
+
307
+ expect(screen.getByRole('tab')).not.toHaveAttribute('aria-label');
308
+ });
309
+
310
+ test('Renders with the toggleAriaLabel as an aria label on the tab', () => {
311
+ render(<OverflowTab toggleAriaLabel="Test aria label" />);
312
+
313
+ expect(screen.getByRole('tab')).toHaveAttribute('aria-label', 'Test aria label');
314
+ });
315
+
316
+ test('Renders the tab with aria-haspopup=menu', () => {
317
+ render(<OverflowTab />);
318
+
319
+ expect(screen.getByRole('tab')).toHaveAttribute('aria-haspopup', 'menu');
320
+ });
321
+
322
+ test('Renders the tab with aria-expanded set to false by default', () => {
323
+ render(<OverflowTab />);
324
+
325
+ expect(screen.getByRole('tab')).toHaveAttribute('aria-expanded', 'false');
326
+ });
327
+
328
+ test('Renders the tab with aria-expanded set to true when the menu is opened', () => {
329
+ render(<OverflowTab />);
330
+
331
+ const overflowTab = screen.getByRole('tab');
332
+
333
+ userEvent.click(overflowTab);
334
+
335
+ expect(overflowTab).toHaveAttribute('aria-expanded', 'true');
336
+ });
337
+
338
+ test('Passes Popper popperMatchesTriggerWidth set to false', () => {
339
+ render(<OverflowTab />);
340
+
341
+ // This assertion relies on the structure of the Popper mock to verify the correct props are being sent to Popper
342
+ expect(screen.getByText('Popper matches trigger width: false')).toBeVisible();
343
+ });
344
+
345
+ test('Passes Popper an appendTo value of the presentation element', () => {
346
+ render(<OverflowTab />);
347
+
348
+ userEvent.click(screen.getByRole('tab'));
349
+
350
+ // This assertion relies on the structure of the Popper mock to verify the correct props are being sent to Popper
351
+ expect(screen.getByText('Append to class name: pf-c-tabs__item pf-m-overflow')).toBeVisible();
352
+ });
353
+
354
+ test('Does not render an overflowing tab as a selected menu item by default', () => {
355
+ render(
356
+ <TabsContext.Provider value={{ ...tabsContextDefaultProps, localActiveKey: 0 }}>
357
+ <OverflowTab
358
+ overflowingTabs={[
359
+ { title: 'Tab one', eventKey: 1, tabContentRef: ('fakeRef' as unknown) as React.RefObject<any> }
360
+ ]}
361
+ />
362
+ </TabsContext.Provider>
363
+ );
364
+
365
+ userEvent.click(screen.getByRole('tab'));
366
+
367
+ // This assertion relies on the structure of the Popper mock to verify the correct props are being sent to Popper
368
+ expect(screen.queryByText('Selected: true')).not.toBeInTheDocument();
369
+ });
370
+
371
+ test('Renders an overflowing tab as a selected menu item when its key matches the localActiveKey provided via context', () => {
372
+ render(
373
+ <TabsContext.Provider value={{ ...tabsContextDefaultProps, localActiveKey: 1 }}>
374
+ <OverflowTab
375
+ overflowingTabs={[
376
+ { title: 'Tab one', eventKey: 1, tabContentRef: ('fakeRef' as unknown) as React.RefObject<any> }
377
+ ]}
378
+ />
379
+ </TabsContext.Provider>
380
+ );
381
+
382
+ userEvent.click(screen.getByRole('tab'));
383
+
384
+ // This assertion relies on the structure of the Popper mock to verify the correct props are being sent to Popper
385
+ expect(screen.getByText('Selected: true')).toBeVisible();
386
+ });
387
+
388
+ test('Matches snapshot when expanded', () => {
389
+ const { asFragment } = render(
390
+ <TabsContext.Provider value={{ ...tabsContextDefaultProps, localActiveKey: 1 }}>
391
+ <OverflowTab
392
+ overflowingTabs={[
393
+ { title: 'Tab one', eventKey: 1, tabContentRef: ('fakeRef' as unknown) as React.RefObject<any> },
394
+ { title: 'Tab two', eventKey: 2, tabContentRef: ('fakeRef' as unknown) as React.RefObject<any> }
395
+ ]}
396
+ />
397
+ </TabsContext.Provider>
398
+ );
399
+
400
+ userEvent.click(screen.getByRole('tab'));
401
+
402
+ expect(asFragment()).toMatchSnapshot();
403
+ });
@@ -0,0 +1,89 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`Matches snapshot when expanded 1`] = `
4
+ <DocumentFragment>
5
+ <div
6
+ data-testid="popper-mock"
7
+ >
8
+ <div
9
+ data-testid="trigger"
10
+ >
11
+ <li
12
+ class="pf-c-tabs__item pf-m-overflow pf-m-current"
13
+ role="presentation"
14
+ >
15
+ <button
16
+ aria-expanded="true"
17
+ aria-haspopup="menu"
18
+ class="pf-c-tabs__link pf-m-expanded"
19
+ role="tab"
20
+ >
21
+ <span
22
+ class="pf-c-tabs__item-text"
23
+ >
24
+ Tab one
25
+ </span>
26
+ <span
27
+ class="pf-c-tabs__link-toggle-icon"
28
+ >
29
+ <svg
30
+ aria-hidden="true"
31
+ fill="currentColor"
32
+ height="1em"
33
+ role="img"
34
+ style="vertical-align: -0.125em;"
35
+ viewBox="0 0 256 512"
36
+ width="1em"
37
+ >
38
+ <path
39
+ d="M224.3 273l-136 136c-9.4 9.4-24.6 9.4-33.9 0l-22.6-22.6c-9.4-9.4-9.4-24.6 0-33.9l96.4-96.4-96.4-96.4c-9.4-9.4-9.4-24.6 0-33.9L54.3 103c9.4-9.4 24.6-9.4 33.9 0l136 136c9.5 9.4 9.5 24.6.1 34z"
40
+ />
41
+ </svg>
42
+ </span>
43
+ </button>
44
+ </li>
45
+ </div>
46
+ <div
47
+ data-testid="popper"
48
+ >
49
+ <div
50
+ data-testid="menu-mock"
51
+ >
52
+ <div
53
+ data-testid="menu-content-mock"
54
+ >
55
+ <ul
56
+ data-testid="menu-list-mock"
57
+ >
58
+ <li
59
+ id="1-menu-item-mock"
60
+ >
61
+ Tab one
62
+ <p>
63
+ Selected: true
64
+ </p>
65
+ </li>
66
+ <li
67
+ id="2-menu-item-mock"
68
+ >
69
+ Tab two
70
+ <p>
71
+ Selected: false
72
+ </p>
73
+ </li>
74
+ </ul>
75
+ </div>
76
+ <button>
77
+ Select
78
+ </button>
79
+ </div>
80
+ </div>
81
+ <p>
82
+ Popper matches trigger width: false
83
+ </p>
84
+ <p>
85
+ Append to class name: pf-c-tabs__item pf-m-overflow pf-m-current
86
+ </p>
87
+ </div>
88
+ </DocumentFragment>
89
+ `;