Skip to content
This repository has been archived by the owner on May 24, 2024. It is now read-only.

[terra-alert] Update notification banner documentation #3933

Merged
merged 4 commits into from
Oct 11, 2023
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
3 changes: 3 additions & 0 deletions packages/terra-alert/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## Unreleased

* Updated
* Updated prop documentation for optional custom titles.

## 4.82.0 - (October 3, 2023)

* Changed
Expand Down
5 changes: 4 additions & 1 deletion packages/terra-alert/src/Alert.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,15 @@ const propTypes = {
*/
role: PropTypes.string,
/**
* The title for the notification banner which will be bolded.
* The optional custom title for the notification banner which will be bolded.
* Overrides the provided default title for all notification types (excludes `custom`).
* Title should be provided for `custom` notification banners.
*/
title: PropTypes.string,
/**
* The type of notification banner to be rendered. One of `alert`, `error`, `warning`, `unsatisfied`, `unverified`, `advisory`,
* `info`, `success`, or `custom`.
* A default title is provided for all notification types except `custom`.
*/
type: PropTypes.oneOf([
AlertTypes.ALERT,
Expand Down
3 changes: 3 additions & 0 deletions packages/terra-core-docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## Unreleased

* Updated
* Updated `terra-alert` documentation for custom titles.

## 1.44.1 - (October 11, 2023)

* Fixed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import CustomExample from './example/CustomExample?dev-site-example';
import LongTextExample from './example/LongTextExample?dev-site-example';
import ActionExample from './example/ActionExample?dev-site-example';
import DismissibleExample from './example/DismissibleExample?dev-site-example';
import ActionAndDismissibleExample from './example/ActionAndDismissibleExample?dev-site-example';
import LiveRegionsExampleCode from './example/LiveRegionsExampleCode';

import AlertPropsTable from 'terra-alert/lib/Alert?dev-site-props-table';

Expand Down Expand Up @@ -73,40 +73,18 @@ For further guidance, please view the full [Accessibility Guide](./accessibility
<Notice variant="important" ariaLevel="3">

- The `alert` notification type will seize keyboard focus by default when an action element is present. This behavior should only be used when absolutely necessary to interrupt the user's workflow.
- Custom notification banners should always have a title provided to the `title` prop.

</Notice>

#### Accessibility Guidance: Titles
- Notification banners of type `custom` should always have a title provided to the `title` prop.
- All other notification types will provide a default title. The `title` prop will override the default title and should be avoided.

#### Accessibility Guidance: Live regions
- For less critical notifications (non-alerts), the notification banner should be in an `aria-live="polite"` region. See example code below.
- Avoid mixing critical alert notifications and less critical notifications in the same region.

<div aria-label="Example code">

import Alert from 'terra-alert';

<>
// This less critical notification should be in polite aria-live region so screen reader users are notified.
<div aria-live="polite">
{isOpen && (
<Alert type="success">
This notification is a less critical and should be polite.
</Alert>
)}
</div>

// Alert notifications are implicitly assertive, no aria-live needed
// It is recommended to keep these separate from polite aria-live regions.
<div>
{isOpen && (
<Alert type="alert">
This notification is a critical alert that is interruptive.
</Alert>
)}
</div>
</>

</div>
<LiveRegionsExampleCode />
Copy link
Contributor Author

@trandrew1023 trandrew1023 Oct 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to toggle button to show example code rather than leaving code on page by default


## Component Features
* [Cross-Browser Support](https://engineering.cerner.com/terra-ui/about/terra-ui/component-standards#cross-browser-support)
Expand All @@ -125,10 +103,9 @@ For further guidance, please view the full [Accessibility Guide](./accessibility
<InfoExample title="Information Notification Banner" />
<SuccessExample title="Success Notification Banner" />
<CustomExample title="Custom Notification Banner" />
<LongTextExample title="Long Text Notification Banner" />
<ActionExample title="Notification Banner with Action" />
<DismissibleExample title="Dismissible Notification Banner" />
<ActionAndDismissibleExample title="Dismissible Notification Banner with Actions" />
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed this since it was a bad example of a custom notification without title and there are already examples of notification with action and dismiss

<LongTextExample title="Long Text Notification Banner" />

## Alert Props
<AlertPropsTable />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,11 @@ In combination with the notification criticality, screen reader users should und

</div>

#### Custom Titles
#### Titles

- Custom notification banners should have a title provided to the `title` prop in order to be accessible.
- Notification banners of type `custom` should have a title provided to the `title` prop in order to be accessible.
- All other notification types will provide a default title. The `title` prop will override the default title and should be avoided.
- Screen readers will always announce the notification type by default and then the custom title if one is provided.

<CustomExampleNoTitle title="Bad: Avoid notifications with no titles" />
<CustomExample title="Good: Titles help users understand notifications" />
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,26 +1,31 @@
import React, { useState } from 'react';
import Button from 'terra-button';

import Alert from 'terra-alert';
import Button from 'terra-button';
import { IconHazardLow } from 'terra-icon';

const AlertActionButton = () => {
const [actionButtonClickCount, setActionButtonClickCount] = useState(0);

const action = () => {
setActionButtonClickCount(prevCount => prevCount + 1);
};

return (
<Alert
id="actionAlert"
type="warning"
title="Action Required."
type="custom"
customIcon={<IconHazardLow />}
action={(
<Button
text="Action"
variant="emphasis"
onClick={() => {
const updatedCount = actionButtonClickCount + 1;
setActionButtonClickCount(updatedCount);
}}
onClick={action}
/>
)}
>
{`This is a warning. It is configured with a custom Action button. Action button has been clicked ${actionButtonClickCount} times.`}
{`This is a notification configured with a custom action. Action button has been clicked ${actionButtonClickCount} times.`}
</Alert>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import React from 'react';

import Alert from 'terra-alert';

const AdvisoryExample = () => (
<Alert type="advisory">This is an advisory notification banner</Alert>
<Alert type="advisory">This item is typically not used.</Alert>
);

export default AdvisoryExample;
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useState } from 'react';
import Button from 'terra-button';

import Alert from 'terra-alert';
import Button from 'terra-button';

const AlertActionFocusDemo = () => {
const [isOpen, setIsOpen] = useState(false);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import React from 'react';

import Alert from 'terra-alert';

const AlertExample = () => (
<Alert type="alert">This is an alert notification banner</Alert>
<Alert type="alert">Site is down for maintenance.</Alert>
);

export default AlertExample;
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import React from 'react';
import { IconHelp } from 'terra-icon';
import classNames from 'classnames/bind';

import Alert from 'terra-alert';
import { IconHelp } from 'terra-icon';
import styles from './colors.module.scss';

const cx = classNames.bind(styles);

const CustomExample = () => (
<Alert type="custom" title="Help!" customColorClass={cx(['my-app-alert-help-example'])} customIcon={<IconHelp />}>
<span>
This is a
<b> custom</b>
{' '}
notification banner
</span>
<Alert
type="custom"
title="Help!"
customColorClass={cx(['my-app-alert-help-example'])}
customIcon={<IconHelp />}
>
Welcome to Terra!
</Alert>
);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import React from 'react';
import { IconHelp } from 'terra-icon';
import classNames from 'classnames/bind';

import Alert from 'terra-alert';
import { IconHelp } from 'terra-icon';
import styles from './colors.module.scss';

const cx = classNames.bind(styles);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useState } from 'react';
import Button from 'terra-button';

import Alert from 'terra-alert';
import Button from 'terra-button';

const AlertDismissible = () => {
const [isOpen, setIsOpen] = useState(true);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import React from 'react';

import Alert from 'terra-alert';

const ErrorExample = () => (
<Alert type="error">This is an error notification banner</Alert>
<Alert type="error">Unable to save at this time. Please try again later.</Alert>
);

export default ErrorExample;
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import React from 'react';

import Alert from 'terra-alert';

const InfoExample = () => (
<Alert type="info">This is an information notification banner</Alert>
<Alert type="info">This receipt is for a bill-only purchase order.</Alert>
);

export default InfoExample;
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React from 'react';

import ToggleButton from 'terra-toggle-button';

const LiveRegionsExampleCode = () => {
const temp = `
import Alert from 'terra-alert';

<>
// This less critical notification should be in polite aria-live region so screen reader users are notified.
<div aria-live="polite">
{isOpen && (
<Alert type="success">
This notification is a less critical and should be polite.
</Alert>
)}
</div>

// Alert notifications are implicitly assertive, no aria-live needed
// It is recommended to keep these separate from polite aria-live regions.
<div>
{isOpen && (
<Alert type="alert">
This notification is a critical alert that is interruptive.
</Alert>
)}
</div>
</>
`;

return (
<ToggleButton
closedButtonText="Show live region example code"
openedButtonText="Hide live region example code"
>
<pre>{temp}</pre>
</ToggleButton>
);
};

export default LiveRegionsExampleCode;
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React, { useState, useRef } from 'react';
import ShowHide, { ShowHideFocuser } from 'terra-show-hide';
import Alert from 'terra-alert';
import classNames from 'classnames/bind';

import Alert from 'terra-alert';
import ShowHide, { ShowHideFocuser } from 'terra-show-hide';
import styles from './LongTextExample.module.scss';

const cx = classNames.bind(styles);
Expand All @@ -14,7 +14,7 @@ const LongTextExample = () => {
const paragraph = 'Now we are engaged in a great civil war, testing whether that nation, or any nation so conceived and so dedicated, can long endure. We are met on a great battle-field of that war. We have come to dedicate a portion of that field, as a final resting place for those who here gave their lives that that nation might live. It is altogether fitting and proper that we should do this.';

return (
<Alert type="info" title="Gettysburg Address:">
<Alert type="custom" title="Gettysburg Address:">
<ShowHide
focusRef={focusRef}
preview={previewText}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import React from 'react';

import Alert from 'terra-alert';

const SuccessExample = () => (
<Alert type="success">This is a success notification banner</Alert>
<Alert type="success">Changes successfully committed.</Alert>
);

export default SuccessExample;
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import React from 'react';

import Alert from 'terra-alert';

const Example = () => (
<Alert type="unsatisfied">This is an unsatisfied notification banner</Alert>
<Alert type="unsatisfied">Only one package must be selected.</Alert>
);

export default Example;
Loading