@patternfly/react-core 4.226.0 → 4.226.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patternfly/react-core",
3
- "version": "4.226.0",
3
+ "version": "4.226.1",
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",
@@ -34,9 +34,9 @@
34
34
  "generate": "node scripts/copyStyles.js"
35
35
  },
36
36
  "dependencies": {
37
- "@patternfly/react-icons": "^4.77.0",
38
- "@patternfly/react-styles": "^4.76.0",
39
- "@patternfly/react-tokens": "^4.78.0",
37
+ "@patternfly/react-icons": "^4.77.1",
38
+ "@patternfly/react-styles": "^4.76.1",
39
+ "@patternfly/react-tokens": "^4.78.1",
40
40
  "focus-trap": "6.9.2",
41
41
  "react-dropzone": "9.0.0",
42
42
  "tippy.js": "5.1.2",
@@ -60,5 +60,5 @@
60
60
  "react": "^16.8.0 || ^17.0.0",
61
61
  "react-dom": "^16.8.0 || ^17.0.0"
62
62
  },
63
- "gitHead": "a7097958c8ccb70a8faaf2fa401413cfa4372809"
63
+ "gitHead": "a8c0fc47245d670f26681e0c58769f91302d85a7"
64
64
  }
@@ -1,7 +1,83 @@
1
1
  import React from 'react';
2
- import { render } from '@testing-library/react';
2
+ import { render, screen } from '@testing-library/react';
3
3
  import { Truncate } from '../Truncate';
4
4
 
5
+ jest.mock('../../Tooltip', () => ({
6
+ Tooltip: ({ content, position, children, ...props }) => (
7
+ <div data-testid="Tooltip-mock" {...props}>
8
+ <div data-testid="Tooltip-mock-content-container">Test {content}</div>
9
+ <p>{`position: ${position}`}</p>
10
+ {children}
11
+ </div>
12
+ )
13
+ }));
14
+
15
+ test('renders with class pf-c-truncate', () => {
16
+ render(
17
+ <Truncate
18
+ content={''}
19
+ aria-label='test-id'
20
+ />
21
+ );
22
+
23
+ const test = screen.getByLabelText('test-id');
24
+
25
+ expect(test).toHaveClass('pf-c-truncate');
26
+ });
27
+
28
+ test('renders with custom class name passed via prop', () => {
29
+ render(
30
+ <Truncate
31
+ content={''}
32
+ aria-label='test-id'
33
+ className='custom-classname'
34
+ />
35
+ );
36
+
37
+ const test = screen.getByLabelText('test-id');
38
+
39
+ expect(test).toHaveClass('custom-classname');
40
+ });
41
+
42
+ test('renders truncate with empty content', () => {
43
+ render(
44
+ <Truncate
45
+ content={''}
46
+ aria-label='test-id'
47
+ />
48
+ );
49
+
50
+ const test = screen.getByLabelText('test-id');
51
+
52
+ expect(test).toHaveTextContent('');
53
+ });
54
+
55
+ test('renders truncate with content', () => {
56
+ render(
57
+ <Truncate
58
+ content={'Test'}
59
+ aria-label='test-id'
60
+ />
61
+ );
62
+
63
+ const test = screen.getByLabelText('test-id');
64
+
65
+ expect(test).toHaveTextContent('Test');
66
+ });
67
+
68
+ test('only renders pf-c-truncate__start with default position', () => {
69
+ render(
70
+ <Truncate
71
+ content={'Testing truncate content'}
72
+ />
73
+ );
74
+
75
+ const start = screen.getByText('Testing truncate content');
76
+
77
+ expect(start).toHaveClass('pf-c-truncate__start');
78
+ expect(start).not.toHaveClass('pf-c-truncate__end');
79
+ });
80
+
5
81
  test('renders default truncation', () => {
6
82
  const { asFragment } = render(
7
83
  <Truncate content={'Vestibulum interdum risus et enim faucibus, sit amet molestie est accumsan.'} />
@@ -9,7 +85,7 @@ test('renders default truncation', () => {
9
85
  expect(asFragment()).toMatchSnapshot();
10
86
  });
11
87
 
12
- test('renders start truncation', () => {
88
+ test('renders start truncation with &lrm; at end', () => {
13
89
  const { asFragment } = render(
14
90
  <Truncate
15
91
  content={'Vestibulum interdum risus et enim faucibus, sit amet molestie est accumsan.'}
@@ -20,11 +96,74 @@ test('renders start truncation', () => {
20
96
  });
21
97
 
22
98
  test('renders middle truncation', () => {
23
- const { asFragment } = render(
99
+ render(
24
100
  <Truncate
25
101
  content={'Vestibulum interdum risus et enim faucibus, sit amet molestie est accumsan.'}
26
102
  position={'middle'}
27
103
  />
28
104
  );
29
- expect(asFragment()).toMatchSnapshot();
105
+
106
+ const start = screen.getByText('Vestibulum interdum risus et enim faucibus, sit amet molestie est ac');
107
+
108
+ expect(start).toHaveClass('pf-c-truncate__start');
109
+
110
+ const end = screen.getByText('cumsan.');
111
+
112
+ expect(end).toHaveClass('pf-c-truncate__end');
113
+ });
114
+
115
+ test('renders different content when trailingNumChars is passed with middle truncate', () => {
116
+ render(
117
+ <Truncate
118
+ content={'Vestibulum interdum risus et enim faucibus, sit amet molestie est accumsan.'}
119
+ trailingNumChars={3}
120
+ position='middle'
121
+ />
122
+ );
123
+
124
+ const start = screen.getByText('Vestibulum interdum risus et enim faucibus, sit amet molestie est accums');
125
+
126
+ expect(start).toHaveClass('pf-c-truncate__start');
127
+
128
+ const end = screen.getByText('an.');
129
+
130
+ expect(end).toHaveClass('pf-c-truncate__end');
131
+ });
132
+
133
+ test('renders tooltip position', () => {
134
+ render(
135
+ <Truncate
136
+ content={''}
137
+ tooltipPosition='top'
138
+ />
139
+ );
140
+
141
+ const input = screen.getByText('position: top');
142
+
143
+ expect(input).toBeVisible();
144
+ });
145
+
146
+ test('renders tooltip content', () => {
147
+ render(
148
+ <Truncate
149
+ content={'Another Tooltip'}
150
+ tooltipPosition='top'
151
+ />
152
+ );
153
+
154
+ const input = screen.getByText('Test Another Tooltip');
155
+
156
+ expect(input).toBeVisible();
157
+ });
158
+
159
+ test('renders with inherited element props spread to the component', () => {
160
+ render(
161
+ <Truncate
162
+ content={'Test'}
163
+ data-testid="test-id"
164
+ aria-label="labelling-id"
165
+ />
166
+ );
167
+
168
+ expect(screen.getByTestId('test-id')).toHaveAccessibleName('labelling-id');
30
169
  });
@@ -2,47 +2,52 @@
2
2
 
3
3
  exports[`renders default truncation 1`] = `
4
4
  <DocumentFragment>
5
- <span
6
- class="pf-c-truncate"
5
+ <div
6
+ data-testid="Tooltip-mock"
7
7
  >
8
- <span
9
- class="pf-c-truncate__start"
8
+ <div
9
+ data-testid="Tooltip-mock-content-container"
10
10
  >
11
- Vestibulum interdum risus et enim faucibus, sit amet molestie est accumsan.
12
- </span>
13
- </span>
14
- </DocumentFragment>
15
- `;
16
-
17
- exports[`renders middle truncation 1`] = `
18
- <DocumentFragment>
19
- <span
20
- class="pf-c-truncate"
21
- >
11
+ Test Vestibulum interdum risus et enim faucibus, sit amet molestie est accumsan.
12
+ </div>
13
+ <p>
14
+ position: top
15
+ </p>
22
16
  <span
23
- class="pf-c-truncate__start"
17
+ class="pf-c-truncate"
24
18
  >
25
- Vestibulum interdum risus et enim faucibus, sit amet molestie est ac
19
+ <span
20
+ class="pf-c-truncate__start"
21
+ >
22
+ Vestibulum interdum risus et enim faucibus, sit amet molestie est accumsan.
23
+ </span>
26
24
  </span>
27
- <span
28
- class="pf-c-truncate__end"
29
- >
30
- cumsan.
31
- </span>
32
- </span>
25
+ </div>
33
26
  </DocumentFragment>
34
27
  `;
35
28
 
36
- exports[`renders start truncation 1`] = `
29
+ exports[`renders start truncation with &lrm; at end 1`] = `
37
30
  <DocumentFragment>
38
- <span
39
- class="pf-c-truncate"
31
+ <div
32
+ data-testid="Tooltip-mock"
40
33
  >
34
+ <div
35
+ data-testid="Tooltip-mock-content-container"
36
+ >
37
+ Test Vestibulum interdum risus et enim faucibus, sit amet molestie est accumsan.
38
+ </div>
39
+ <p>
40
+ position: top
41
+ </p>
41
42
  <span
42
- class="pf-c-truncate__end"
43
+ class="pf-c-truncate"
43
44
  >
44
- Vestibulum interdum risus et enim faucibus, sit amet molestie est accumsan.‎
45
+ <span
46
+ class="pf-c-truncate__end"
47
+ >
48
+ Vestibulum interdum risus et enim faucibus, sit amet molestie est accumsan.‎
49
+ </span>
45
50
  </span>
46
- </span>
51
+ </div>
47
52
  </DocumentFragment>
48
53
  `;
@@ -106,6 +106,8 @@ export interface WizardProps extends React.HTMLProps<HTMLDivElement> {
106
106
  isOpen?: boolean;
107
107
  /** Flag indicating nav items with sub steps are expandable */
108
108
  isNavExpandable?: boolean;
109
+ /** Callback function to signal the current step in the wizard */
110
+ onCurrentStepChanged?: (step: WizardStep) => void;
109
111
  /** @beta Flag indicating the wizard has a drawer for at least one of the wizard steps */
110
112
  hasDrawer?: boolean;
111
113
  /** @beta Flag indicating the wizard drawer is expanded */
@@ -164,6 +166,14 @@ export class Wizard extends React.Component<WizardProps, WizardState> {
164
166
  isNavOpen: false
165
167
  };
166
168
 
169
+ if (props.onCurrentStepChanged) {
170
+ const flattenedSteps = this.getFlattenedSteps();
171
+ if (flattenedSteps.length >= this.state.currentStep) {
172
+ const currentStep = flattenedSteps[this.state.currentStep - 1];
173
+ props.onCurrentStepChanged(currentStep);
174
+ }
175
+ }
176
+
167
177
  this.drawerRef = React.createRef();
168
178
  }
169
179
 
@@ -202,9 +212,7 @@ export class Wizard extends React.Component<WizardProps, WizardState> {
202
212
  }
203
213
  }
204
214
 
205
- this.setState({
206
- currentStep: newStep
207
- });
215
+ this.setCurrentStep(newStep, flattenedSteps[newStep - 1]);
208
216
  const { id: prevId, name: prevName } = flattenedSteps[currentStep - 1];
209
217
  const { id, name } = flattenedSteps[newStep - 1];
210
218
  return onNext && onNext({ id, name }, { prevId, prevName });
@@ -218,9 +226,7 @@ export class Wizard extends React.Component<WizardProps, WizardState> {
218
226
  if (flattenedSteps.length < currentStep) {
219
227
  // Previous step was removed, just update the currentStep state
220
228
  const adjustedStep = flattenedSteps.length;
221
- this.setState({
222
- currentStep: adjustedStep
223
- });
229
+ this.setCurrentStep(adjustedStep, flattenedSteps[adjustedStep - 1]);
224
230
  } else {
225
231
  let newStep = currentStep;
226
232
 
@@ -235,9 +241,7 @@ export class Wizard extends React.Component<WizardProps, WizardState> {
235
241
  }
236
242
  }
237
243
 
238
- this.setState({
239
- currentStep: newStep
240
- });
244
+ this.setCurrentStep(newStep, flattenedSteps[newStep - 1]);
241
245
  const { id: prevId, name: prevName } = flattenedSteps[newStep];
242
246
  const { id, name } = flattenedSteps[newStep - 1];
243
247
  return onBack && onBack({ id, name }, { prevId, prevName });
@@ -259,7 +263,8 @@ export class Wizard extends React.Component<WizardProps, WizardState> {
259
263
  } else if (step > maxSteps) {
260
264
  step = maxSteps;
261
265
  }
262
- this.setState({ currentStep: step, isNavOpen: false });
266
+ this.setCurrentStep(step, flattenedSteps[step - 1]);
267
+ this.setState({ isNavOpen: false });
263
268
  const { id: prevId, name: prevName } = flattenedSteps[currentStep - 1];
264
269
  const { id, name } = flattenedSteps[step - 1];
265
270
  return onGoToStep && onGoToStep({ id, name }, { prevId, prevName });
@@ -275,7 +280,7 @@ export class Wizard extends React.Component<WizardProps, WizardState> {
275
280
  }
276
281
  }
277
282
  if (step) {
278
- this.setState({ currentStep: step });
283
+ this.setCurrentStep(step, flattenedSteps[step - 1]);
279
284
  }
280
285
  };
281
286
 
@@ -289,7 +294,7 @@ export class Wizard extends React.Component<WizardProps, WizardState> {
289
294
  }
290
295
  }
291
296
  if (step) {
292
- this.setState({ currentStep: step });
297
+ this.setCurrentStep(step, flattenedSteps[step - 1]);
293
298
  }
294
299
  };
295
300
 
@@ -338,6 +343,16 @@ export class Wizard extends React.Component<WizardProps, WizardState> {
338
343
  return appendTo || document.body;
339
344
  };
340
345
 
346
+ private setCurrentStep(currentStep: number, currentStepObject: WizardStep) {
347
+ this.setState({
348
+ currentStep
349
+ });
350
+
351
+ if (this.props.onCurrentStepChanged) {
352
+ this.props.onCurrentStepChanged(currentStepObject);
353
+ }
354
+ }
355
+
341
356
  componentDidMount() {
342
357
  const target = typeof document !== 'undefined' ? document.body : null;
343
358
  if (target) {
@@ -384,6 +399,7 @@ export class Wizard extends React.Component<WizardProps, WizardState> {
384
399
  titleId,
385
400
  descriptionId,
386
401
  isNavExpandable,
402
+ onCurrentStepChanged,
387
403
  hasDrawer,
388
404
  isDrawerExpanded,
389
405
  ...rest
@@ -222,6 +222,34 @@ describe('Wizard', () => {
222
222
  expect(main).toBeInTheDocument();
223
223
  expect(main).toHaveAttribute('aria-labelledby', 'main-aria-labelledby');
224
224
  });
225
+
226
+ test('wiz with onCurrentStepChanged setter', () => {
227
+ const stepA = { name: 'A', component: <p>Step 1</p> };
228
+ const stepB = { name: 'B', component: <p>Step 2</p> };
229
+ const stepC = { name: 'C', component: <p>Step 3</p> };
230
+
231
+ const steps: WizardStep[] = [ stepA, stepB, stepC ];
232
+ const setter = jest.fn();
233
+
234
+ render(
235
+ <Wizard
236
+ title="Wiz title"
237
+ onCurrentStepChanged={ setter }
238
+ steps={steps}
239
+ />
240
+ );
241
+ expect(setter).toHaveBeenLastCalledWith(expect.objectContaining(stepA));
242
+ userEvent.click(screen.getByText(/next/i));
243
+ expect(setter).toHaveBeenLastCalledWith(expect.objectContaining(stepB));
244
+ userEvent.click(screen.getByText(/next/i));
245
+ expect(setter).toHaveBeenLastCalledWith(expect.objectContaining(stepC));
246
+ userEvent.click(screen.getByText('A'));
247
+ expect(setter).toHaveBeenLastCalledWith(expect.objectContaining(stepA));
248
+ userEvent.click(screen.getByText(/next/i));
249
+ expect(setter).toHaveBeenLastCalledWith(expect.objectContaining(stepB));
250
+ userEvent.click(screen.getByText(/back/i));
251
+ expect(setter).toHaveBeenLastCalledWith(expect.objectContaining(stepA));
252
+ });
225
253
  });
226
254
 
227
255
  test('wiz with disabled steps', () => {
@@ -782,36 +782,29 @@ class ProgressiveWizard extends React.Component {
782
782
  }
783
783
  ```
784
784
 
785
- ### Remember last step
785
+ ### Get current step
786
786
 
787
787
  ```js
788
788
  import React from 'react';
789
789
  import { Button, Wizard } from '@patternfly/react-core';
790
790
 
791
- class RememberLastStepWizard extends React.Component {
791
+ class GetCurrentStepWizard extends React.Component {
792
792
  constructor(props) {
793
793
  super(props);
794
794
  this.state = {
795
795
  step: 1
796
796
  };
797
+ this.onCurrentStepChanged = ({ id }) => {
798
+ this.setState({
799
+ step: id
800
+ });
801
+ }
797
802
  this.closeWizard = () => {
798
803
  console.log('close wizard');
799
804
  };
800
- this.onMove = (curr, prev) => {
801
- this.setState({
802
- step: curr.id
803
- });
804
- };
805
- this.onSave = () => {
806
- this.setState({
807
- step: 1
808
- });
809
- };
810
805
  }
811
806
 
812
807
  render() {
813
- const { step } = this.state;
814
-
815
808
  const steps = [
816
809
  { id: 1, name: 'First step', component: <p>Step 1 content</p> },
817
810
  { id: 2, name: 'Second step', component: <p>Step 2 content</p> },
@@ -819,19 +812,16 @@ class RememberLastStepWizard extends React.Component {
819
812
  { id: 4, name: 'Fourth step', component: <p>Step 4 content</p> },
820
813
  { id: 5, name: 'Review', component: <p>Review step content</p>, nextButtonText: 'Finish' }
821
814
  ];
822
- const title = 'Remember last step wizard';
815
+ const title = 'Get current step wizard';
823
816
  return (
824
817
  <Wizard
825
818
  navAriaLabel={`${title} steps`}
826
819
  mainAriaLabel={`${title} content`}
827
- startAtStep={step}
828
- onNext={this.onMove}
829
- onBack={this.onMove}
830
- onSave={this.onSave}
831
820
  onClose={this.closeWizard}
832
821
  description="Simple Wizard Description"
833
822
  steps={steps}
834
823
  height={400}
824
+ onCurrentStepChanged={this.onCurrentStepChanged}
835
825
  />
836
826
  );
837
827
  }