Skip to content

Commit

Permalink
Merge pull request #7121 from Sage/FE-7013_step-flow-aria-attributes
Browse files Browse the repository at this point in the history
feat(step-flow): add aria props to component - FE-7013
  • Loading branch information
DipperTheDan authored Dec 19, 2024
2 parents 4ec5bd9 + 037aac1 commit 04e4a47
Show file tree
Hide file tree
Showing 3 changed files with 152 additions and 4 deletions.
64 changes: 62 additions & 2 deletions src/components/step-flow/step-flow-test.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,31 @@
import React from "react";
import Typography from "../typography";
import { StepFlow, StepFlowProps } from ".";

export default {
title: "Step Flow/Test",
includeStories: ["Default"],
parameters: {
info: { disable: true },
chromatic: {
disableSnapshot: true,
},
},
argTypes: {
ariaLabel: {
control: {
type: "text",
},
},
ariaLabelledby: {
control: {
type: "text",
},
},
ariaDescribedBy: {
control: {
type: "text",
},
},
category: {
control: {
type: "text",
Expand Down Expand Up @@ -54,4 +69,49 @@ export const Default = (props: Partial<StepFlowProps>) => (
<StepFlow title="default" currentStep={1} totalSteps={8} {...props} />
);

Default.storyName = "default";
Default.storyName = "Default";

export const DefaultWithAriaLabel = () => (
<StepFlow
title="default"
currentStep={1}
totalSteps={8}
aria-label="This is step flow"
/>
);

DefaultWithAriaLabel.storyName = "Default with aria-label";

export const DefaultWithAriaLabelledBy = () => (
<>
<StepFlow
title="default"
currentStep={1}
totalSteps={8}
aria-labelledby="ariaLabelledBy-text"
/>
<Typography as="span" id="ariaLabelledBy-text">
This is step flow
</Typography>
</>
);

DefaultWithAriaLabelledBy.storyName = "Default with aria-labelledby";

export const DefaultWithAriaDescribedBy = () => (
<>
<StepFlow
title="default"
currentStep={1}
totalSteps={8}
aria-describedby="ariaDescribedBy-text"
/>
<Typography mt={3} id="ariaDescribedBy-text">
This is step flow. A step flow represents an end-to-end journey that a
user can complete in one go. It has a specific start and end point. It
shows the current step and the total number of steps in the journey
</Typography>
</>
);

DefaultWithAriaDescribedBy.storyName = "Default with aria-describedby";
26 changes: 24 additions & 2 deletions src/components/step-flow/step-flow.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,19 @@ import StepFlowTitle from "./step-flow-title/step-flow-title.component";

export type Steps = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;

export interface StepFlowProps extends MarginProps, TagProps {
interface StepFlowAriaProps {
/** Prop to specify the aria-label of the component */
"aria-label"?: string;
/** Prop to specify the aria-labelledby of the component */
"aria-labelledby"?: string;
/** Prop to specify the aria-describedby of the component */
"aria-describedby"?: string;
}

export interface StepFlowProps
extends StepFlowAriaProps,
MarginProps,
TagProps {
/** A category for the user journey. */
category?: string;
/** The title of the current step, this can be a string or a valid React node
Expand Down Expand Up @@ -66,6 +78,9 @@ export const StepFlow = forwardRef<StepFlowHandle, StepFlowProps>(
showProgressIndicator = false,
showCloseIcon = false,
onDismiss,
"aria-label": ariaLabel,
"aria-labelledby": ariaLabelledBy,
"aria-describedby": ariaDescribedBy,
...rest
},
ref,
Expand Down Expand Up @@ -180,7 +195,14 @@ export const StepFlow = forwardRef<StepFlowHandle, StepFlowProps>(
);

return (
<StyledStepFlow {...rest} {...tagComponent("step-flow", rest)}>
<StyledStepFlow
role="group"
aria-label={ariaLabel}
aria-describedby={ariaDescribedBy}
aria-labelledby={ariaLabelledBy}
{...rest}
{...tagComponent("step-flow", rest)}
>
<StyledStepContent>
{category ? (
<StyledStepContentText>
Expand Down
66 changes: 66 additions & 0 deletions src/components/step-flow/step-flow.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,72 @@ function calculateStepStateIndexes(
return [stepsBefore, stepsAfter];
}

test("when aria-label is specified, the attribute is applied to the expected element", () => {
render(
<StepFlow
data-role="step-flow"
aria-label="foo"
title="foo"
currentStep={5}
totalSteps={6}
category="bar"
ref={() => {}}
/>,
);

const stepFlowComponent = screen.getByTestId("step-flow");

expect(stepFlowComponent).toHaveAccessibleName("foo");
});

test("when aria-labelledby is specified, the attribute is applied to the expected element", () => {
render(
<>
<StepFlow
data-role="step-flow"
aria-labelledby="foo"
title="foo"
currentStep={5}
totalSteps={6}
category="bar"
ref={() => {}}
/>
<span id="foo" role="presentation">
This is step flow
</span>
</>,
);

const stepFlowComponent = screen.getByTestId("step-flow");

expect(stepFlowComponent).toHaveAccessibleName("This is step flow");
});

test("when aria-describedby is specified, the attribute is applied to the expected element", () => {
render(
<>
<StepFlow
data-role="step-flow"
aria-describedby="foo"
title="foo"
currentStep={5}
totalSteps={6}
category="bar"
ref={() => {}}
/>
<span id="foo" role="presentation">
Description of step flow
</span>
</>,
);

const stepFlowComponent = screen.getByTestId("step-flow");

expect(stepFlowComponent).toHaveAccessibleDescription(
"Description of step flow",
);
});

test("should render the correct element and text when the category prop is passed", () => {
render(
<StepFlow
Expand Down

0 comments on commit 04e4a47

Please sign in to comment.