Skip to content

Commit 3d202a8

Browse files
authored
feat(Wizard): warning step status (#12041)
Signed-off-by: gitdallas <[email protected]>
1 parent 46edc2b commit 3d202a8

File tree

6 files changed

+45
-12
lines changed

6 files changed

+45
-12
lines changed

packages/react-core/src/components/Wizard/WizardNavItem.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import styles from '@patternfly/react-styles/css/components/Wizard/wizard';
44
import AngleRightIcon from '@patternfly/react-icons/dist/esm/icons/angle-right-icon';
55
import ExclamationCircleIcon from '@patternfly/react-icons/dist/esm/icons/exclamation-circle-icon';
66
import CheckCircleIcon from '@patternfly/react-icons/dist/esm/icons/check-circle-icon';
7+
import ExclamationTriangleIcon from '@patternfly/react-icons/dist/esm/icons/exclamation-triangle-icon';
78

89
import { OUIAProps, useOUIAProps } from '../../helpers';
910
import { WizardNavItemStatus } from './types';
@@ -38,7 +39,7 @@ export interface WizardNavItemProps
3839
/** The id for the navigation item */
3940
id?: string | number;
4041
/** Used to determine the icon displayed next to content. Default has no icon. */
41-
status?: 'default' | 'error' | 'success';
42+
status?: 'default' | 'error' | 'success' | 'warning';
4243
}
4344

4445
export const WizardNavItem = ({
@@ -97,7 +98,8 @@ export const WizardNavItem = ({
9798
isCurrent && styles.modifiers.current,
9899
isDisabled && styles.modifiers.disabled,
99100
status === WizardNavItemStatus.Error && styles.modifiers.danger,
100-
status === WizardNavItemStatus.Success && styles.modifiers.success
101+
status === WizardNavItemStatus.Success && styles.modifiers.success,
102+
status === WizardNavItemStatus.Warning && styles.modifiers.warning
101103
)}
102104
aria-disabled={isDisabled ? true : null}
103105
aria-current={isCurrent && !children ? 'step' : false}
@@ -110,6 +112,7 @@ export const WizardNavItem = ({
110112
<span className={css(styles.wizardNavLinkStatusIcon)}>
111113
{status === WizardNavItemStatus.Error && <ExclamationCircleIcon />}
112114
{status === WizardNavItemStatus.Success && <CheckCircleIcon />}
115+
{status === WizardNavItemStatus.Warning && <ExclamationTriangleIcon />}
113116
</span>
114117
</>
115118
)}

packages/react-core/src/components/Wizard/WizardStep.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export interface WizardStepProps {
2828
/** Replaces the step's footer. The step's footer takes precedence over the wizard's footer. */
2929
footer?: React.ReactElement<any> | Partial<WizardFooterProps>;
3030
/** Used to determine icon next to the step's navigation item */
31-
status?: 'default' | 'error' | 'success';
31+
status?: 'default' | 'error' | 'success' | 'warning';
3232
/** Flag to determine whether parent steps can expand or not. Defaults to false. */
3333
isExpandable?: boolean;
3434
}

packages/react-core/src/components/Wizard/__tests__/WizardNavItem.test.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,9 @@ test(`Renders screen reader text and success icon when status is success`, () =>
6363
expect(screen.getByRole('button')).toHaveClass(styles.modifiers.success);
6464
expect(screen.getByText(', success')).toBeInTheDocument();
6565
});
66+
67+
test(`Renders screen reader text and warning icon when status is warning`, () => {
68+
render(<WizardNavItem status="warning" />);
69+
expect(screen.getByRole('button')).toHaveClass(styles.modifiers.warning);
70+
expect(screen.getByText(', warning')).toBeInTheDocument();
71+
});

packages/react-core/src/components/Wizard/__tests__/WizardStep.test.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,6 @@ test('updates "status" in context when the value changes', () => {
7070
expect(setStep).toHaveBeenCalledWith({ ...testStepProps, status: 'error', isVisited: true });
7171
render(<WizardStep {...testStep} status="success" />);
7272
expect(setStep).toHaveBeenCalledWith({ ...testStepProps, status: 'success', isVisited: true });
73+
render(<WizardStep {...testStep} status="warning" />);
74+
expect(setStep).toHaveBeenCalledWith({ ...testStepProps, status: 'warning', isVisited: true });
7375
});

packages/react-core/src/components/Wizard/examples/WizardStepStatus.tsx

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ interface SomeContextProps {
66
setErrorMessage(error: string | undefined): void;
77
successMessage: string | undefined;
88
setSuccessMessage(error: string | undefined): void;
9+
warningMessage: string | undefined;
10+
setWarningMessage(error: string | undefined): void;
911
}
10-
type SomeContextRenderProps = Pick<SomeContextProps, 'successMessage', 'errorMessage'>;
12+
type SomeContextRenderProps = Pick<SomeContextProps, 'successMessage', 'errorMessage', 'warningMessage'>;
1113
interface SomeContextProviderProps {
1214
children: (context: SomeContextRenderProps) => React.ReactElement<any>;
1315
}
@@ -17,16 +19,20 @@ const SomeContext: React.Context<SomeContextProps> = createContext({} as SomeCon
1719
const SomeContextProvider = ({ children }: SomeContextProviderProps) => {
1820
const [errorMessage, setErrorMessage] = useState<string>();
1921
const [successMessage, setSuccessMessage] = useState<string>();
22+
const [warningMessage, setWarningMessage] = useState<string>();
2023

2124
return (
22-
<SomeContext.Provider value={{ errorMessage, setErrorMessage, successMessage, setSuccessMessage }}>
23-
{children({ errorMessage, successMessage })}
25+
<SomeContext.Provider
26+
value={{ errorMessage, setErrorMessage, successMessage, setSuccessMessage, warningMessage, setWarningMessage }}
27+
>
28+
{children({ errorMessage, successMessage, warningMessage })}
2429
</SomeContext.Provider>
2530
);
2631
};
2732

2833
const StepContentWithAction = () => {
29-
const { errorMessage, setErrorMessage, successMessage, setSuccessMessage } = useContext(SomeContext);
34+
const { errorMessage, setErrorMessage, successMessage, setSuccessMessage, warningMessage, setWarningMessage } =
35+
useContext(SomeContext);
3036

3137
return (
3238
<>
@@ -35,7 +41,8 @@ const StepContentWithAction = () => {
3541
isChecked={!!errorMessage}
3642
onChange={(_event, checked) => {
3743
setErrorMessage(checked ? 'Some error message' : undefined);
38-
setSuccessMessage(!checked ? 'Some error message' : undefined);
44+
setSuccessMessage(checked ? undefined : successMessage);
45+
setWarningMessage(checked ? undefined : warningMessage);
3946
}}
4047
id="toggle-error-checkbox"
4148
name="Toggle Status"
@@ -45,23 +52,37 @@ const StepContentWithAction = () => {
4552
isChecked={!!successMessage}
4653
onChange={(_event, checked) => {
4754
setSuccessMessage(checked ? 'Some success message' : undefined);
48-
setErrorMessage(!checked ? 'Some success message' : undefined);
55+
setErrorMessage(checked ? undefined : errorMessage);
56+
setWarningMessage(checked ? undefined : warningMessage);
4957
}}
5058
id="toggle-success-checkbox"
5159
name="Toggle Status"
5260
/>
61+
<Radio
62+
label="Give step 1 a warning status"
63+
isChecked={!!warningMessage}
64+
onChange={(_event, checked) => {
65+
setWarningMessage(checked ? 'Some warning message' : undefined);
66+
setErrorMessage(checked ? undefined : errorMessage);
67+
setSuccessMessage(checked ? undefined : successMessage);
68+
}}
69+
id="toggle-warning-checkbox"
70+
name="Toggle Status"
71+
/>
5372
</>
5473
);
5574
};
5675

5776
export const WizardStepStatus: React.FunctionComponent = () => (
5877
<SomeContextProvider>
59-
{({ errorMessage, successMessage }) => {
78+
{({ errorMessage, successMessage, warningMessage }) => {
6079
let status = 'default';
6180
if (errorMessage) {
6281
status = 'error';
6382
} else if (successMessage) {
6483
status = 'success';
84+
} else if (warningMessage) {
85+
status = 'warning';
6586
}
6687
return (
6788
<Wizard height={400} title="Step status wizard">

packages/react-core/src/components/Wizard/types.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,14 @@ export interface WizardBasicStep {
2323
/** Replaces the step's footer. The step's footer takes precedence over the wizard's footer. */
2424
footer?: React.ReactElement<any> | Partial<WizardFooterProps>;
2525
/** Used to determine icon next to the step's navItem */
26-
status?: 'default' | 'error' | 'success';
26+
status?: 'default' | 'error' | 'success' | 'warning';
2727
}
2828

2929
export enum WizardNavItemStatus {
3030
Default = 'default',
3131
Error = 'error',
32-
Success = 'success'
32+
Success = 'success',
33+
Warning = 'warning'
3334
}
3435

3536
/** Type for customizing a button (next, back or cancel) in a Wizard footer. It omits some props which either have a default value or are passed directly via WizardFooterProps. */

0 commit comments

Comments
 (0)