React Components

# Message

_**Message** component helps to communicate with users providing feedback or information._

Message

## Overview

---

**Message** component communicates information to the user.

It grabs the user's attention in a prominent way.

<table class="_table_e3iru_2 _table--md_e3iru_59 _table--striped_e3iru_167 _identity-card__table_75e8e_7" data-ods="table" data-storybook="table"><tbody><tr><th scope="row">Name</th><td>Message</td></tr><tr><th scope="row">Also known as</th><td>Notifier, Notification, Banner, Alert, Feedback</td></tr><tr><th scope="row">Links</th><td><a class="_link_1qra4_2 _identity-card__app-link_75e8e_12" data-ods="link" href="https://www.figma.com/design/9jDDTcR4a9jPRFcdjawAlf/ODS---UI-Kit?node-id=44-8300" target="_blank">Design <span class="_icon_g76et_2 _icon--external-link_g76et_256" data-ods="icon" role="presentation"></span></a><a class="_link_1qra4_2 _identity-card__app-link_75e8e_12" data-ods="link" href="https://github.com/ovh/design-system/tree/master/packages/ods-react/src/components/message" target="_blank">Github <span class="_icon_g76et_2 _icon--external-link_g76et_256" data-ods="icon" role="presentation"></span></a><a class="_link_1qra4_2 _identity-card__app-link_75e8e_12" data-ods="link" href="https://ovh.github.io/design-system/v18.6.4/?path=/docs/ods-components-message--documentation" target="_blank">Previous major version<span class="_icon_g76et_2 _icon--external-link_g76et_256" data-ods="icon" role="presentation"></span></a></td></tr></tbody></table>

## Usage

---

**Messages** are used as notification status.

There are four different subtypes of standard **Messages**, in order of priority:

-   **Information**: Provides info to users in context. Shouldn't be overused to replace regular content.
-   **Success**: Reserved to provide to a success message. They are displayed as a snackbar.
-   **Warning**: Reserved for **Messages** that need the user attention and acknowledgment but might not cause errors.
-   **Critical**: Reserved for errors, malfunctions, as well as critical issues. Inform the user that a problem requires immediate intervention or correction before the process continues.

### Message vs Toast

**Message**

-   Persistent or semi-persistent information banner.
-   Usually appears inline or at the top of a page as part of the content flow.
-   Designed for status communication (success, warning, critical error, info) that’s tied to a specific screen or context.
-   Remains visible until dismissed or until the state changes.

**Toast**

-   Ephemeral notification that appears for a short time (usually overlay in a corner of the viewport)
-   Designed for lightweight, transient feedback ("Action succeeded", "File uploaded"), except for toast with actions.
-   Auto-dismisses after a few seconds.

### Dos & Don'ts

| ✅ Do |
| --- |
| - Write Message in a clear, concise, and affirmative tone that aligns with the user's task |
| - Place Message in a visible and relevant area of the page, ideally close to the triggering element if any or top of the section |
| - Use the correct variant (e.g., information, success, warning, error) to match the context and urgency |
| - Use non-dismissible Message for critical warnings or errors that require immediate resolution |
| - Allow content selection (e.g., to copy error messages) |

| ❌ Don't |
| --- |
| - Don't use Message to highlight static or decorative content, prefer components like Card for that |
| - Don't write overly long or complex Message that could overwhelm or confuse users |
| - Don't rely solely on color to convey meaning, always keep the Icon for clarity |
| - Don't use vague or generic text, always provide helpful context or guidance |
| - Don't overload the interface with multiple simultaneous Messages unless absolutely necessary |

### Best Practices in Context

1.  **Message**
2.  **Icon**
3.  **Close button** - optional
4.  **Content**

## Placement

---

**Messages** show up during a task to notify users of the status of an action. In every page, it is possible to display one or more **Messages** to inform the user.

They are positioned near their related items or right after the header and before the page title and page content.

## Behavior

---

Based on its informational manner, the component default behavior is being read-only. You can only select its content if needed.

When a **Message** is dismissible, a click on the `xmark` icon button will dismiss the **Message**.

## Variation

---

### Color

-   **Information** _(default)_: informing users of specific content, providing global feedback to the user.
-   **Success**: confirming that an action has been completed successfully, providing positive feedback to the user.
-   **Warning**: alerting users to potential issues or cautionary information, prompting them to take preventive actions.
-   **Critical**: highlighting severe and potentially catastrophic issues that demand urgent and decisive action to prevent significant negative consequences.

### Variant

-   **Default**: conveying mild to important information, ensuring the message is seen by the user.
-   **Light**: conveying non-urgent, informational content in a subtle and less prominent manner, ensuring the message is seen without drawing too much attention.

## Navigation

---

### Focus Management

The **Message** component itself is non-interactive and does not receive keyboard focus.

If the **Message** is dismissible, the close icon button is focusable.

### General Keyboard Shortcuts

Pressing Tab moves focus to the close icon button (if available).

Pressing Enter or Space while the close icon button is focused should trigger the action to dismiss the **Message**.

Pressing Shift + Tab moves focus to the previous interactive element.

## Accessibility

---

### Structuring multiple Messages

When displaying multiple **Messages** together, they should be wrapped within an unordered list of items (`<ul>` and `<li>`) to ensure a proper announcement by screen readers.

-   Your changes have been saved.
    
-   Some fields need your attention.
    

```jsx
{
  globals: {
    imports: `import { ICON_NAME, MESSAGE_COLOR, Message, MessageBody, MessageIcon } from '@ovhcloud/ods-react';`
  },
  tags: ['!dev'],
  render: ({}) => <ul style={{
    display: 'flex',
    flexFlow: 'column',
    rowGap: '8px',
    margin: 0,
    padding: 0,
    listStyle: 'none'
  }}>
      <li>
        <Message>
          <MessageIcon name={ICON_NAME.circleCheck} />
          <MessageBody>
            Your changes have been saved.          </MessageBody>
        </Message>
      </li>
      <li>
        <Message color={MESSAGE_COLOR.warning}>
          <MessageIcon name={ICON_NAME.triangleExclamation} />
          <MessageBody>
            Some fields need your attention.          </MessageBody>
        </Message>
      </li>
    </ul>
}
```

This structure ensures that assistive technologies announce **Messages** as a list, rather than reading them as separate, unrelated announcements.

Screen readers will announce the list, the number of items and the **Messages** content.

### Alternative approach with ARIA roles

When modifying the HTML structure is not possible, use [role="list"](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Roles/list_role) and [role="listitem"](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Roles/listitem_role) to mimic list semantics.

Your changes have been saved.

Some fields need your attention.

```jsx
{
  globals: {
    imports: `import { ICON_NAME, MESSAGE_COLOR, Message, MessageBody, MessageIcon } from '@ovhcloud/ods-react';`
  },
  tags: ['!dev'],
  render: ({}) => <div role="list" style={{
    display: 'flex',
    flexFlow: 'column',
    rowGap: '8px'
  }}>
      <Message role="listitem">
        <MessageIcon name={ICON_NAME.circleCheck} />
        <MessageBody>
          Your changes have been saved.        </MessageBody>
      </Message>
      <Message color={MESSAGE_COLOR.warning} role="listitem">
        <MessageIcon name={ICON_NAME.triangleExclamation} />
        <MessageBody>
          Some fields need your attention.        </MessageBody>
      </Message>
    </div>
}
```

### Setting the container ARIA role

When adding a new **Message** element, its container should have a `role` attribute set, so that assistive technologies can announce the content correctly.

If you're adding a critical **Message**, use `role="alert"`. For non-critical **Messages** (e.g., info, success, warning), use `role="status"`.

```jsx
const [alerts, setAlerts] = useState<string[]>([]);
  const [statuses, setStatuses] = useState<string[]>([]);
  return <>
      <div>
        <Button onClick={() => setStatuses(s => s.concat([new Date().toString()]))}>
          Add status        </Button>
        <Button color={BUTTON_COLOR.critical} onClick={() => setAlerts(a => a.concat([new Date().toString()]))}>
          Add alert        </Button>
      </div>
      <div role="alert">
        {alerts.map(alert => <Message color={MESSAGE_COLOR.critical} key={alert}>
              <MessageIcon name={ICON_NAME.hexagonExclamation} />
              <MessageBody>
                Alert: {alert}
              </MessageBody>
            </Message>)}
      </div>
      <div role="status">
        {statuses.map(status => <Message key={status}>
              <MessageIcon name={ICON_NAME.circleInfo} />
              <MessageBody>
                Status: {status}
              </MessageBody>
            </Message>)}
      </div>
    </>;
}
```

This ensures that screen readers announce the **Message** at the appropriate time without interrupting.