Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/visual-regression.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
start: npm run dev
working-directory: regression-test
- name: Upload cypress artifact for chromatic
- uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v4
with:
name: test-results
path: regression-test/cypress/downloads
Expand Down
19 changes: 19 additions & 0 deletions packages/ui-alerts/src/Alert/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,23 @@ type: example
renderCloseButtonLabel="Close"
margin="small"
transition="none"
variantScreenReaderLabel="Success, "
>
Sample success alert text. I will close w/o a transition out if you close me
</Alert>
<Alert
variant="info"
renderCloseButtonLabel="Close"
margin="small"
variantScreenReaderLabel="Information, "
>
Sample info text. I will fade out if you close me.
</Alert>
<Alert
variant="error"
renderCloseButtonLabel="Close"
margin="small"
variantScreenReaderLabel="Error, "
>
Sample error text that continues for a while
to demonstrate what happens when the content stretches over
Expand All @@ -43,6 +46,7 @@ type: example
<Alert
variant="warning"
margin="small"
variantScreenReaderLabel="Warning, "
>
Sample warning text. This alert is not dismissible and cannot be closed.
</Alert>
Expand All @@ -59,6 +63,7 @@ type: example
variant="info"
margin="small"
timeout={5000}
variantScreenReaderLabel="Information, "
>
Sample info text. I will fade out after 5 seconds
</Alert>
Expand Down Expand Up @@ -111,6 +116,16 @@ For more information about live regions, see
this.setState({ alerts })
}

getScreenReaderLabel(variant) {
const labels = {
info: 'Information, ',
success: 'Success, ',
warning: 'Warning, ',
error: 'Error, '
}
return labels[variant] || ''
}

render() {
return (
<div>
Expand All @@ -125,6 +140,9 @@ For more information about live regions, see
liveRegion={() => document.getElementById('flash-messages')}
liveRegionPoliteness={alert.politeness}
margin="small 0"
variantScreenReaderLabel={this.getScreenReaderLabel(
alert.variant
)}
>
This is {alert.politeness === 'polite' ? 'a' : 'an'}{' '}
{alert.politeness} {alert.variant} alert
Expand Down Expand Up @@ -325,6 +343,7 @@ type: embed
<Figure.Item>Use the Error alert to notify user of an error</Figure.Item>
<Figure.Item>Use the Warning alert to notify user of a warning</Figure.Item>
<Figure.Item>Use the Success alert to notify user of a success event or action</Figure.Item>
<Figure.Item>Use the `variantScreenReaderLabel` prop to indicate the alert variant to screen reader users</Figure.Item>
</Figure>
<Figure recommendation="no" title="Don't">
<Figure.Item>Have alert messaging that is more than two lines long</Figure.Item>
Expand Down
24 changes: 21 additions & 3 deletions packages/ui-alerts/src/Alert/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,11 @@ class Alert extends Component<AlertProps, AlertState> {
}

createScreenreaderContentNode() {
return <ScreenReaderContent>{this.props.children}</ScreenReaderContent>
return (
<ScreenReaderContent>
{this.props.variantScreenReaderLabel || ''} {this.props.children}
</ScreenReaderContent>
)
}

createScreenreaderAlert() {
Expand Down Expand Up @@ -260,7 +264,14 @@ class Alert extends Component<AlertProps, AlertState> {
renderAlert() {
// prevent onDismiss from being passed to the View component
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { margin, styles, children, onDismiss, ...props } = this.props
const {
margin,
styles,
children,
onDismiss,
variantScreenReaderLabel,
...props
} = this.props
return (
<View
{...passthroughProps({ ...props })}
Expand All @@ -271,7 +282,14 @@ class Alert extends Component<AlertProps, AlertState> {
elementRef={this.handleRef}
>
{this.renderIcon()}
<div css={styles?.content}>{children}</div>
<div css={styles?.content}>
{variantScreenReaderLabel && (
<span css={styles?.variantScreenReaderLabel}>
{variantScreenReaderLabel}
</span>
)}
{children}
</div>
{this.renderCloseButton()}
</View>
)
Expand Down
11 changes: 9 additions & 2 deletions packages/ui-alerts/src/Alert/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ type AlertOwnProps = {
* Determines color and icon
*/
variant?: 'info' | 'success' | 'warning' | 'error'
/**
* 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.
*/
variantScreenReaderLabel?: string
/**
* Function that returns the DIV where screenreader alerts will be placed.
*/
Expand Down Expand Up @@ -115,7 +119,9 @@ type AlertProps = AlertOwnProps &
WithStyleProps<AlertTheme, AlertStyle> &
WithDeterministicIdProps

type AlertStyle = ComponentStyle<'alert' | 'icon' | 'closeButton' | 'content'>
type AlertStyle = ComponentStyle<
'alert' | 'icon' | 'closeButton' | 'content' | 'variantScreenReaderLabel'
>

const propTypes: PropValidators<PropKeys> = {
children: PropTypes.node,
Expand All @@ -130,7 +136,8 @@ const propTypes: PropValidators<PropKeys> = {
onDismiss: PropTypes.func,
transition: PropTypes.oneOf(['none', 'fade']),
open: PropTypes.bool,
hasShadow: PropTypes.bool
hasShadow: PropTypes.bool,
variantScreenReaderLabel: PropTypes.string
}

const allowedProps: AllowedPropKeys = [
Expand Down
7 changes: 7 additions & 0 deletions packages/ui-alerts/src/Alert/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,13 @@ const generateStyle = (
fontWeight: componentTheme.contentFontWeight,
lineHeight: componentTheme.contentLineHeight,
padding: componentTheme.contentPadding
},
variantScreenReaderLabel: {
position: 'absolute',
height: '1px',
width: '1px',
overflow: 'hidden',
margin: '-1px'
}
}
}
Expand Down
Loading