Message bar
View .mdA message bar communicates important information about the state of the entire product or the surface where it appears, such as a page, drawer, dialog, or card.
Default
Loading interactive example. Full source is available below.
View example source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { MessageBar } from "@coreai-ds/react-components";
import { MessageBarBody } from "@coreai-ds/react-components";
import { MessageBarTitle } from "@coreai-ds/react-components";
import { Link } from "@coreai-ds/react-components";
import { MessageBarActions } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { DismissRegular } from "@fluentui/react-icons";
export const Default = () => {
return (<MessageBar>
<MessageBarBody>
<MessageBarTitle>Descriptive title</MessageBarTitle>
Message providing information to the user with actionable insights. <Link>Link</Link>
</MessageBarBody>
<MessageBarActions containerAction={<Button aria-label="dismiss" appearance="transparent" icon={<DismissRegular />}/>}>
<Button>Action</Button>
<Button>Action</Button>
</MessageBarActions>
</MessageBar>);
};
export default Default;
Resources
Best practices
Do
- Match intent to the situation: informational, success, warning, or error.
- Include an action or link in warning and error messages.
- Stack messages from most critical to least critical.
Don't
- Use a message bar to prevent a destructive action; use a dialog.
- Use it for time-sensitive status originating elsewhere; use a toast.
- Overload the body with long explanations.
Behavior and states
- Message bar content never truncates.
- After the second line, reflow pushes actions below the body.
- Message bars are dismissible with a Close button.
- A dismissed warning or error reappears in the next session until the problem is resolved.
- If the message is intended to prevent a destructive action, try a dialog instead.
- If the message is time-sensitive, but relates to an activity or status from a different location, try a toast notification instead.
API referenceGenerated CoreAI prop and type summaries
API
Generated CoreAI prop summaries, not replacement type declarations. Most native DOM/event and ARIA props are omitted. ? means optional; JSDoc shows defaults, deprecations, and conditional requirements. Defaults assume the standard CoreAI provider.
MessageBar API
interface MessageBarProps {
as?: "div";
/**
* Rendered when the component is in multiline layout to guarantee correct spacing even
* if no actions are rendered. When actions are rendered, the default actions grid area will render
* over this element
*
* NOTE: If you are using this slot, this probably means that you are using the MessageBar without
* actions, this is not recommended from an accesibility point of view
*/
bottomReflowSpacer?: WithSlotShorthandValue<{ as?: "div"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & { ref?: ((instance: HTMLDivElement | null) => void) | RefObject<HTMLDivElement> | null; }, "children"> & { children?: any; }> | null | undefined;
children?: any;
className?: string;
icon?: WithSlotShorthandValue<{ as?: "div"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & { ref?: ((instance: HTMLDivElement | null) => void) | RefObject<HTMLDivElement> | null; }, "children"> & { children?: any; }> | null | undefined;
/**
* The intent of the message. In addition to Fluent's options, CoreAI adds
* `"brand"` for a branded informational callout.
*
* - `"info"`: Neutral informational surface.
* - `"warning"`: Warning status ramp.
* - `"error"`: Danger status ramp.
* - `"success"`: Success status ramp.
* - `"brand"`: Brand primary ramp.
* @default 'info'
*/
intent?: "brand" | "success" | "warning" | "error" | "info";
layout?: "auto" | "multiline" | "singleline";
politeness?: "assertive" | "polite";
ref?: Ref<HTMLDivElement>;
/**
* Use squal for page level messages and rounded for component level messages
* @default rounded
*/
shape?: "rounded" | "square";
style?: CSSProperties;
}
MessageBarActions API
MessageBarActions component
interface MessageBarActionsProps {
as?: "div";
children?: any;
className?: string;
/**
* Generally the 'Dismiss' button for the MessageBar
*/
containerAction?: WithSlotShorthandValue<{ as?: "div"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & { ref?: ((instance: HTMLDivElement | null) => void) | RefObject<HTMLDivElement> | null; }, "children"> & { children?: any; }> | null | undefined;
ref?: Ref<HTMLDivElement>;
style?: CSSProperties;
}
MessageBarBody API
MessageBarBody component
interface MessageBarBodyProps {
as?: "div";
children?: any;
className?: string;
ref?: Ref<HTMLDivElement>;
style?: CSSProperties;
}
MessageBarGroup API
MessageBarGroup component
interface MessageBarGroupProps {
animate?: "both" | "exit-only";
as?: "div";
children?: any;
className?: string;
ref?: Ref<HTMLDivElement>;
style?: CSSProperties;
}
MessageBarTitle API
MessageBarTitle component
interface MessageBarTitleProps {
as?: "span";
children?: any;
className?: string;
ref?: Ref<HTMLSpanElement>;
style?: CSSProperties;
}
Implementation
CoreAI 0.12.0; Fluent 9.74.9.
Import components from @coreai-ds/react-components. CoreAI guidance above takes precedence over API demonstration examples.
Actions
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import type { JSXElement } from "@coreai-ds/react-components";
import { MessageBar } from "@coreai-ds/react-components";
import { MessageBarBody } from "@coreai-ds/react-components";
import { MessageBarTitle } from "@coreai-ds/react-components";
import { Link } from "@coreai-ds/react-components";
import { MessageBarActions } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { DismissRegular } from "@fluentui/react-icons";
import * as React from 'react';
export const Actions = (): JSXElement => (<MessageBar>
<MessageBarBody>
<MessageBarTitle>Descriptive title</MessageBarTitle>
Message providing information to the user with actionable insights. <Link>Link</Link>
</MessageBarBody>
<MessageBarActions containerAction={<Button appearance="transparent" aria-label="Dismiss" icon={<DismissRegular />}/>}>
<Button>Action</Button>
<Button>Action</Button>
</MessageBarActions>
</MessageBar>);
export default Actions;
Animation
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { tokens } from "@coreai-ds/react-components";
import * as React from 'react';
import type { MessageBarGroupProps } from "@coreai-ds/react-components";
import type { MessageBarIntent } from "@coreai-ds/react-components";
import { Field } from "@coreai-ds/react-components";
import { RadioGroup } from "@coreai-ds/react-components";
import { Radio } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { MessageBarGroup } from "@coreai-ds/react-components";
import { MessageBar } from "@coreai-ds/react-components";
import { MessageBarBody } from "@coreai-ds/react-components";
import { MessageBarTitle } from "@coreai-ds/react-components";
import { Link } from "@coreai-ds/react-components";
import { MessageBarActions } from "@coreai-ds/react-components";
import { DismissRegular } from "@fluentui/react-icons";
const useStyles = makeStyles({
controlsContainer: {
display: 'flex',
flexDirection: 'row',
},
messageBarGroup: {
padding: tokens.spacingHorizontalMNudge,
display: 'flex',
flexDirection: 'column',
marginTop: '10px',
gap: '10px',
height: '300px',
overflow: 'auto',
border: `2px solid ${tokens.colorBrandForeground1}`,
},
field: {
flexGrow: 1,
alignItems: 'center',
gridTemplateColumns: 'max-content auto',
},
buttonGroup: {
display: 'flex',
gap: '5px',
},
});
interface ExampleMessage {
intent: MessageBarIntent;
id: number;
}
const intents: MessageBarIntent[] = ['info', 'warning', 'error', 'success'];
export const Animation = (): JSXElement => {
const styles = useStyles();
const counterRef = React.useRef(0);
const [animate, setAnimate] = React.useState<MessageBarGroupProps['animate']>('both');
const [messages, setMessages] = React.useState<ExampleMessage[]>([]);
const addMessage = () => {
const intent = intents[Math.floor(Math.random() * intents.length)];
const newMessage = { intent, id: counterRef.current++ };
setMessages(s => [newMessage, ...s]);
};
const clearMessages = () => setMessages([]);
const dismissMessage = (messageId: number) => setMessages(s => s.filter(entry => entry.id !== messageId));
return (<div>
<div className={styles.controlsContainer}>
<Field className={styles.field} label="Select animation type:" orientation="horizontal">
<RadioGroup layout="horizontal" onChange={(_, { value }) => setAnimate(value as MessageBarGroupProps['animate'])} value={animate}>
<Radio label="both" value="both"/>
<Radio label="exit-only" value="exit-only"/>
</RadioGroup>
</Field>
<div className={styles.buttonGroup}>
<Button appearance="primary" onClick={addMessage}>
Add message
</Button>
<Button onClick={clearMessages}>Clear</Button>
</div>
</div>
<MessageBarGroup animate={animate} className={styles.messageBarGroup}>
{messages.map(({ intent, id }) => (<MessageBar key={`${intent}-${id}`} intent={intent}>
<MessageBarBody>
<MessageBarTitle>Descriptive title</MessageBarTitle>
Message providing information to the user with actionable insights. <Link>Link</Link>
</MessageBarBody>
<MessageBarActions containerAction={<Button onClick={() => dismissMessage(id)} aria-label="dismiss" appearance="transparent" icon={<DismissRegular />}/>}/>
</MessageBar>))}
</MessageBarGroup>
</div>);
};
export default Animation;
Dismiss
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { tokens } from "@coreai-ds/react-components";
import * as React from 'react';
import type { MessageBarIntent } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { MessageBarGroup } from "@coreai-ds/react-components";
import { MessageBar } from "@coreai-ds/react-components";
import { MessageBarBody } from "@coreai-ds/react-components";
import { MessageBarTitle } from "@coreai-ds/react-components";
import { Link } from "@coreai-ds/react-components";
import { MessageBarActions } from "@coreai-ds/react-components";
import { DismissRegular } from "@fluentui/react-icons";
const useStyles = makeStyles({
messageBarGroup: {
padding: tokens.spacingHorizontalMNudge,
display: 'flex',
flexDirection: 'column',
marginTop: '10px',
gap: '10px',
height: '300px',
overflow: 'auto',
border: `2px solid ${tokens.colorBrandForeground1}`,
},
buttonGroup: {
display: 'flex',
justifyContent: 'end',
gap: '5px',
},
});
interface ExampleMessage {
intent: MessageBarIntent;
id: number;
}
const intents: MessageBarIntent[] = ['info', 'warning', 'error', 'success'];
export const Dismiss = (): JSXElement => {
const styles = useStyles();
const counterRef = React.useRef(0);
const [messages, setMessages] = React.useState<ExampleMessage[]>([]);
const addMessage = () => {
const intent = intents[Math.floor(Math.random() * intents.length)];
const newMessage = { intent, id: counterRef.current++ };
setMessages(s => [newMessage, ...s]);
};
const clearMessages = () => setMessages([]);
const dismissMessage = (messageId: number) => setMessages(s => s.filter(entry => entry.id !== messageId));
return (<>
<div className={styles.buttonGroup}>
<Button appearance="primary" onClick={addMessage}>
Add message
</Button>
<Button onClick={clearMessages}>Clear</Button>
</div>
<MessageBarGroup className={styles.messageBarGroup}>
{messages.map(({ intent, id }) => (<MessageBar key={`${intent}-${id}`} intent={intent}>
<MessageBarBody>
<MessageBarTitle>Descriptive title</MessageBarTitle>
Message providing information to the user with actionable insights. <Link>Link</Link>
</MessageBarBody>
<MessageBarActions containerAction={<Button onClick={() => dismissMessage(id)} aria-label="dismiss" appearance="transparent" icon={<DismissRegular />}/>}/>
</MessageBar>))}
</MessageBarGroup>
</>);
};
export default Dismiss;
Intent
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import type { MessageBarIntent } from "@coreai-ds/react-components";
import { MessageBar } from "@coreai-ds/react-components";
import { MessageBarBody } from "@coreai-ds/react-components";
import { MessageBarTitle } from "@coreai-ds/react-components";
import { Link } from "@coreai-ds/react-components";
export const Intent = () => {
// CoreAI adds `"brand"` on top of Fluent's four preset intents.
const intents: MessageBarIntent[] = ['info', 'warning', 'error', 'success', 'brand'];
const styles = /* css */ `
.message-bar-intent-example {
display: flex;
flex-direction: column;
gap: 10px;
}
`;
return (<>
<style>{styles}</style>
<div className="message-bar-intent-example">
{intents.map((intent) => (<MessageBar key={intent} intent={intent}>
<MessageBarBody>
<MessageBarTitle>Intent {intent}</MessageBarTitle>
Message providing information to the user with actionable insights.{' '}
<Link>Link</Link>
</MessageBarBody>
</MessageBar>))}
</div>
</>);
};
export default Intent;
Manual Layout
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import type { JSXElement } from "@coreai-ds/react-components";
import * as React from 'react';
import { Switch } from "@coreai-ds/react-components";
import { MessageBar } from "@coreai-ds/react-components";
import { MessageBarBody } from "@coreai-ds/react-components";
import { MessageBarTitle } from "@coreai-ds/react-components";
import { Link } from "@coreai-ds/react-components";
import { MessageBarActions } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { DismissRegular } from "@fluentui/react-icons";
const intents = ['info', 'warning', 'error', 'success'] as const;
export const ManualLayout = (): JSXElement => {
const [single, setSingle] = React.useState(true);
return (<>
<Switch label={single ? 'Single line layout' : 'Multi line layout'} checked={single} onChange={(_, { checked }) => setSingle(checked)}/>
<div style={{ display: 'flex', flexDirection: 'column', gap: '10px' }}>
{intents.map(intent => (<MessageBar key={intent} layout={single ? 'singleline' : 'multiline'} intent={intent}>
<MessageBarBody>
<MessageBarTitle>Descriptive title</MessageBarTitle>
Message providing information to the user with actionable insights. <Link>Link</Link>
</MessageBarBody>
<MessageBarActions containerAction={<Button aria-label="dismiss" appearance="transparent" icon={<DismissRegular />}/>}>
<Button>Action</Button>
<Button>Action</Button>
</MessageBarActions>
</MessageBar>))}
</div>
</>);
};
export default ManualLayout;
Reflow
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { tokens } from "@coreai-ds/react-components";
import * as React from 'react';
import { Switch } from "@coreai-ds/react-components";
import { mergeClasses } from "@coreai-ds/react-components";
import { MessageBar } from "@coreai-ds/react-components";
import { MessageBarBody } from "@coreai-ds/react-components";
import { MessageBarTitle } from "@coreai-ds/react-components";
import { Link } from "@coreai-ds/react-components";
import { MessageBarActions } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { DismissRegular } from "@fluentui/react-icons";
const useStyles = makeStyles({
compact: {
width: '600px',
},
resizableArea: {
display: 'flex',
flexDirection: 'column',
padding: '30px 10px',
gap: '10px',
border: `2px solid ${tokens.colorBrandBackground}`,
position: 'relative',
overflow: 'hidden',
'::after': {
content: `'Resizable Area'`,
position: 'absolute',
padding: '1px 4px 1px',
top: '-2px',
left: '-2px',
fontFamily: 'monospace',
fontSize: '15px',
fontWeight: 900,
lineHeight: 1,
letterSpacing: '1px',
color: tokens.colorNeutralForegroundOnBrand,
backgroundColor: tokens.colorBrandBackground,
},
},
});
export const Reflow = (): JSXElement => {
const styles = useStyles();
const [compact, setCompact] = React.useState(true);
return (<>
<Switch label={compact ? 'Compact width' : 'Full width'} checked={compact} onChange={(_, { checked }) => setCompact(checked)}/>
<div className={mergeClasses(styles.resizableArea, compact && styles.compact)}>
<MessageBar intent="success">
<MessageBarBody>
<MessageBarTitle>Descriptive title</MessageBarTitle>
Message providing information to the user with actionable insights. <Link>Link</Link>
</MessageBarBody>
<MessageBarActions containerAction={<Button aria-label="dismiss" appearance="transparent" icon={<DismissRegular />}/>}>
<Button>Action</Button>
<Button>Action</Button>
</MessageBarActions>
</MessageBar>
</div>
</>);
};
export default Reflow;
Shape
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { MessageBar } from "@coreai-ds/react-components";
import { MessageBarBody } from "@coreai-ds/react-components";
import { MessageBarTitle } from "@coreai-ds/react-components";
import * as React from 'react';
const useClasses = makeStyles({
container: {
display: 'flex',
flexDirection: 'column',
gap: '10px',
},
});
export const Shape = (): JSXElement => {
const classes = useClasses();
return (<div className={classes.container}>
<MessageBar shape="rounded">
<MessageBarBody>
<MessageBarTitle>Rounded shape</MessageBarTitle>
This message has rounded shape.
</MessageBarBody>
</MessageBar>
<MessageBar shape="square">
<MessageBarBody>
<MessageBarTitle>Square shape</MessageBarTitle>
This message has square shape.
</MessageBarBody>
</MessageBar>
</div>);
};
export default Shape;