Skip to content

Commit

Permalink
feat: add aria attributes to loaders (#1449)
Browse files Browse the repository at this point in the history
* feat: add aria attributes to loaders

- Add aria-valuenow attribute to linear loader
- Add aria-label attribute to both linear and circular loaders
- Add unit tests for loaders

* refactor: change aria-label to use hyphen after code review

Co-authored-by: Diana Nanyanzi <d-rita@users.noreply.github.com>

---------

Co-authored-by: Mozafar Haider <mozafar@dhis2.org>
Co-authored-by: Diana Nanyanzi <d-rita@users.noreply.github.com>
  • Loading branch information
3 people committed Jun 3, 2024
1 parent 1dc5439 commit aaa60fb
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { mount } from 'enzyme'
import React from 'react'
import { CircularLoader } from '../circular-loader.js'

describe('Circular Loader', () => {
it('renders the circular loader with aria label', () => {
const wrapper = mount(
<CircularLoader
dataTest={'circular-loader-test'}
aria-label="Circular Loader"
/>
)
const actual = wrapper.find({ 'data-test': 'circular-loader-test' })
expect(actual.prop('role')).toBe('progressbar')
expect(actual.prop('aria-label')).toBe('Circular Loader')
})

it('renders the circular loader without aria label', () => {
const wrapper = mount(
<CircularLoader dataTest={'circular-loader-test'} />
)
const actual = wrapper.find({ 'data-test': 'circular-loader-test' })
expect(actual.prop('aria-label')).toBe(undefined)
expect(actual.prop('role')).toBe('progressbar')
})
})
3 changes: 3 additions & 0 deletions components/loader/src/circular-loader/circular-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const CircularLoader = ({
invert,
className,
dataTest,
'aria-label': ariaLabel,
}) => (
<div
role="progressbar"
Expand All @@ -20,6 +21,7 @@ const CircularLoader = ({
invert,
})}
data-test={dataTest}
aria-label={ariaLabel}
>
<style jsx>{`
div {
Expand Down Expand Up @@ -67,6 +69,7 @@ CircularLoader.defaultProps = {
}

CircularLoader.propTypes = {
'aria-label': PropTypes.string,
className: PropTypes.string,
dataTest: PropTypes.string,
extrasmall: sharedPropTypes.sizePropType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,13 @@ export default {
const Template = (args) => <CircularLoader {...args} />

export const Default = Template.bind({})
Default.args = { 'aria-label': 'Default Loader' }

export const Small = Template.bind({})
Small.args = { small: true }
Small.args = { small: true, 'aria-label': 'Small Loader' }

export const Large = Template.bind({})
Large.args = { large: true }
Large.args = { large: true, 'aria-label': 'Large Loader' }

export const ExtraSmall = Template.bind({})
ExtraSmall.args = { extrasmall: true }
ExtraSmall.args = { extrasmall: true, 'aria-label': 'ExtraSmall Loader' }
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { mount } from 'enzyme'
import React from 'react'
import { LinearLoader } from '../linear-loader.js'

describe('Linear Loader', () => {
it('renders the linear loader with provided aria attributes', () => {
const wrapper = mount(
<LinearLoader
dataTest={'linear-loader-test'}
aria-label="Linear Loader"
amount={15}
/>
)
const actual = wrapper.find({ 'data-test': 'linear-loader-test' })
expect(actual.prop('role')).toBe('progressbar')
expect(actual.prop('aria-label')).toBe('Linear Loader')
expect(actual.prop('aria-valuenow')).toBe(15)
})

it('renders the linear loader without aria label', () => {
const wrapper = mount(
<LinearLoader dataTest={'linear-loader-test'} amount={45} />
)
const actual = wrapper.find({ 'data-test': 'linear-loader-test' })
expect(actual.prop('role')).toBe('progressbar')
expect(actual.prop('aria-label')).toBe(undefined)
expect(actual.prop('aria-valuenow')).toBe(45)
})
})
4 changes: 4 additions & 0 deletions components/loader/src/linear-loader/linear-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,13 @@ const LinearLoader = ({
invert,
className,
dataTest,
'aria-label': ariaLabel,
}) => {
return (
<div
role="progressbar"
aria-valuenow={amount}
aria-label={ariaLabel}
className={cx(className, { invert })}
data-test={dataTest}
>
Expand Down Expand Up @@ -78,6 +81,7 @@ LinearLoader.defaultProps = {
LinearLoader.propTypes = {
/** The progression in percent without the '%' sign */
amount: PropTypes.number.isRequired,
'aria-label': PropTypes.string,
className: PropTypes.string,
dataTest: PropTypes.string,
/** Use inverted color scheme */
Expand Down
13 changes: 9 additions & 4 deletions components/loader/src/linear-loader/linear-loader.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,16 @@ export default {
componentSubtitle: subtitle,
docs: { description: { component: description } },
},
argTypes: { margin: { table: { defaultValue: { summary: '12px' } } } },
argTypes: {
margin: { table: { defaultValue: { summary: '12px' } } },
},
}

export const Determinate = (args) => <LinearLoader {...args} />
Determinate.args = { amount: 60 }
Determinate.args = {
amount: 60,
'aria-label': 'Determinate Loader',
}

export const OverlayPage = (args) => (
<Layer level={layers.blocking} translucent>
Expand All @@ -37,7 +42,7 @@ export const OverlayPage = (args) => (
</Center>
</Layer>
)
OverlayPage.args = { amount: 30 }
OverlayPage.args = { amount: 30, 'aria-label': 'Loader with Overlay Page' }
OverlayPage.parameters = { docs: { inlineStories: false } }

export const OverlayComponent = (args) => (
Expand All @@ -49,7 +54,7 @@ export const OverlayComponent = (args) => (
</Cover>
</div>
)
OverlayComponent.args = { amount: 80 }
OverlayComponent.args = { amount: 80, 'aria-label': 'Loader with Overlay Component', }

export const RTL = (args) => (
<div dir="rtl">
Expand Down
2 changes: 2 additions & 0 deletions components/loader/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export interface CircularLoaderProps {
invert?: boolean
large?: boolean
small?: boolean
'aria-label'?: string
}

export const CircularLoader: React.FC<CircularLoaderProps>
Expand All @@ -30,6 +31,7 @@ export interface LinearLoaderProps {
* The width of the entire indicator
*/
width?: string
'aria-label'?: string
}

export const LinearLoader: React.FC<LinearLoaderProps>

0 comments on commit aaa60fb

Please sign in to comment.