Skip to content

Commit 8317832

Browse files
committed
fix(ui-alerts): add variantScreenReaderLabel prop to Alert to improve screenreader usability
1 parent f75c699 commit 8317832

File tree

4 files changed

+30
-4
lines changed

4 files changed

+30
-4
lines changed

packages/ui-alerts/src/Alert/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,23 @@ type: example
2020
renderCloseButtonLabel="Close"
2121
margin="small"
2222
transition="none"
23+
variantScreenReaderLabel="Success: "
2324
>
2425
Sample success alert text. I will close w/o a transition out if you close me
2526
</Alert>
2627
<Alert
2728
variant="info"
2829
renderCloseButtonLabel="Close"
2930
margin="small"
31+
variantScreenReaderLabel="Information: "
3032
>
3133
Sample info text. I will fade out if you close me.
3234
</Alert>
3335
<Alert
3436
variant="error"
3537
renderCloseButtonLabel="Close"
3638
margin="small"
39+
variantScreenReaderLabel="Error: "
3740
>
3841
Sample error text that continues for a while
3942
to demonstrate what happens when the content stretches over
@@ -43,6 +46,7 @@ type: example
4346
<Alert
4447
variant="warning"
4548
margin="small"
49+
variantScreenReaderLabel="Warning: "
4650
>
4751
Sample warning text. This alert is not dismissible and cannot be closed.
4852
</Alert>

packages/ui-alerts/src/Alert/index.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,8 @@ class Alert extends Component<AlertProps, AlertState> {
258258
}
259259

260260
renderAlert() {
261-
const { margin, styles, children, ...props } = this.props
261+
const { margin, styles, children, variantScreenReaderLabel, ...props } =
262+
this.props
262263
return (
263264
<View
264265
{...passthroughProps({ ...props })}
@@ -269,7 +270,14 @@ class Alert extends Component<AlertProps, AlertState> {
269270
elementRef={this.handleRef}
270271
>
271272
{this.renderIcon()}
272-
<div css={styles?.content}>{children}</div>
273+
<div css={styles?.content}>
274+
{variantScreenReaderLabel && (
275+
<span css={styles?.variantScreenReaderLabel}>
276+
{variantScreenReaderLabel}
277+
</span>
278+
)}
279+
{children}
280+
</div>
273281
{this.renderCloseButton()}
274282
</View>
275283
)

packages/ui-alerts/src/Alert/props.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ type AlertOwnProps = {
4646
* Determines color and icon
4747
*/
4848
variant?: 'info' | 'success' | 'warning' | 'error'
49+
/**
50+
* How the screen reader should announce the alert variant. While the `variant` prop sets the color and icon for the alert component, this label should be a textual representation of that information. So e.g. if the variant is `info`, this label could be "Information:" or "Information alert:". Note the `:` at the end of the label which helps the screenreader to be more natural sounding.
51+
*/
52+
variantScreenReaderLabel?: string
4953
/**
5054
* Function that returns the DIV where screenreader alerts will be placed.
5155
*/
@@ -115,7 +119,9 @@ type AlertProps = AlertOwnProps &
115119
WithStyleProps<AlertTheme, AlertStyle> &
116120
WithDeterministicIdProps
117121

118-
type AlertStyle = ComponentStyle<'alert' | 'icon' | 'closeButton' | 'content'>
122+
type AlertStyle = ComponentStyle<
123+
'alert' | 'icon' | 'closeButton' | 'content' | 'variantScreenReaderLabel'
124+
>
119125

120126
const propTypes: PropValidators<PropKeys> = {
121127
children: PropTypes.node,
@@ -130,7 +136,8 @@ const propTypes: PropValidators<PropKeys> = {
130136
onDismiss: PropTypes.func,
131137
transition: PropTypes.oneOf(['none', 'fade']),
132138
open: PropTypes.bool,
133-
hasShadow: PropTypes.bool
139+
hasShadow: PropTypes.bool,
140+
variantScreenReaderLabel: PropTypes.string
134141
}
135142

136143
const allowedProps: AllowedPropKeys = [

packages/ui-alerts/src/Alert/styles.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,13 @@ const generateStyle = (
114114
fontWeight: componentTheme.contentFontWeight,
115115
lineHeight: componentTheme.contentLineHeight,
116116
padding: componentTheme.contentPadding
117+
},
118+
variantScreenReaderLabel: {
119+
position: 'absolute',
120+
height: '1px',
121+
width: '1px',
122+
overflow: 'hidden',
123+
margin: '-1px'
117124
}
118125
}
119126
}

0 commit comments

Comments
 (0)