Skip to content

Commit

Permalink
Kds 1953 port button fix from kaizen legacy (#4327)
Browse files Browse the repository at this point in the history
* Add tests

* Add 'polite' to aria-live conditionally

* Add changeset

* Use 'in' syntax instead of 'hasOwnProperty'

* Add ResolveWorking story

* Fix changeset

* Add ResolveWorking example to docs
  • Loading branch information
JakePitman authored Nov 21, 2023
1 parent 391c220 commit 41ff866
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .changeset/popular-gifts-sing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@kaizen/components": patch
---

Fix issue in Button, where screen readers would announce the Button's contents on page-load.
5 changes: 5 additions & 0 deletions packages/components/src/Button/Button/_docs/Button.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ Alternatively use the `workingLabelHidden` prop to hide the button label all tog

<Canvas of={ButtonStories.Working} />

### Controlling the working state
Here is an example of controlling whether the button is 'working' or not, using state.

<Canvas of={ButtonStories.ResolveWorking} />

### Loading

Use the <LinkTo pageId="components-loading-states-loadinginput">LoadingInput</LinkTo> component for button placeholders.
Expand Down
28 changes: 27 additions & 1 deletion packages/components/src/Button/Button/_docs/Button.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from "react"
import React, { useState } from "react"
import { StoryObj, Meta } from "@storybook/react"
import { AddIcon, ArrowRightIcon } from "~components/Icon"
import { LoadingInput } from "~components/Loading"
Expand Down Expand Up @@ -142,3 +142,29 @@ export const NativeFormButton: Story = {
),
parameters: { controls: { disable: true } },
}

export const ResolveWorking: Story = {
render: () => {
const [state, setState] = useState<"Ready" | "Working" | "Completed">(
"Ready"
)
const handleClick = (): void => {
if (state === "Ready") {
setState("Working")
setTimeout(() => setState("Completed"), 3000)
} else {
setState("Ready")
}
}

return (
<Button
label={state}
working={state === "Working"}
workingLabel="Button is doing some work"
workingLabelHidden
onClick={handleClick}
/>
)
},
}
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,72 @@ describe("<GenericButton /> with native HTML `form` attributes", () => {
).toHaveAttribute("form", buttonFormAttributes.form)
})
})

describe("<GenericButton /> `working` accessible states", () => {
it("renders a button without aria-live by default", () => {
const { getByTestId } = render(
<GenericButton
data-testid="id--generic-test"
id="id--button"
label="button label"
/>
)

const button = getByTestId("id--generic-test")
// The id is passed to the element not the container so we have to get its parent
const buttonContainer = button.parentElement

expect(buttonContainer).not.toHaveAttribute("aria-live", "")
})

it("renders a button with aria-live if working label if provided", () => {
const { getByTestId } = render(
<GenericButton
data-testid="id--generic-test"
id="id--button"
label="button label"
workingLabel="Loading"
/>
)
const button = getByTestId("id--generic-test")
const buttonContainer = button.parentElement

expect(buttonContainer).toHaveAttribute("aria-live", "polite")
})

it("renders a link button with aria-live if working label if provided", () => {
const { getByTestId } = render(
<GenericButton
data-testid="id--generic-test"
id="id--button"
label="button label"
workingLabel="Loading"
href="/"
/>
)
const button = getByTestId("id--generic-test")
const buttonContainer = button.parentElement

expect(buttonContainer).toHaveAttribute("aria-live", "polite")
})

it("renders a custom button with aria-live if working label if provided", () => {
const { getByTestId } = render(
<GenericButton
data-testid="id--generic-test"
id="id--button"
label="button label"
workingLabel="Loading"
component={props => (
<button type="button" {...props}>
Custom button
</button>
)}
/>
)
const button = getByTestId("id--generic-test")
const buttonContainer = button.parentElement

expect(buttonContainer).toHaveAttribute("aria-live", "polite")
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ export const GenericButton = forwardRef(
styles.container,
props.fullWidth && styles.fullWidth
)}
aria-live="polite"
aria-live={"workingLabel" in props ? "polite" : undefined}
>
{determineButtonRenderer()}
</span>
Expand Down

0 comments on commit 41ff866

Please sign in to comment.