diff --git a/packages/fuselage/.loki/reference/chrome_iphone7_Containers_Banner_Banner.png b/packages/fuselage/.loki/reference/chrome_iphone7_Containers_Banner_Banner.png
new file mode 100644
index 0000000000000000000000000000000000000000..1ddd560b2d3a1c43de37c8e0e5a6cdc921f7ef33
Binary files /dev/null and b/packages/fuselage/.loki/reference/chrome_iphone7_Containers_Banner_Banner.png differ
diff --git a/packages/fuselage/.loki/reference/chrome_iphone7_Containers_Banner_Inline.png b/packages/fuselage/.loki/reference/chrome_iphone7_Containers_Banner_Inline.png
new file mode 100644
index 0000000000000000000000000000000000000000..20becab25e5694f404ab139817bbc33e2453a6c2
Binary files /dev/null and b/packages/fuselage/.loki/reference/chrome_iphone7_Containers_Banner_Inline.png differ
diff --git a/packages/fuselage/.loki/reference/chrome_iphone7_Containers_Banner_Normal.png b/packages/fuselage/.loki/reference/chrome_iphone7_Containers_Banner_Normal.png
new file mode 100644
index 0000000000000000000000000000000000000000..8258e8c780938a7be66dcc243a9f584d223c7f2e
Binary files /dev/null and b/packages/fuselage/.loki/reference/chrome_iphone7_Containers_Banner_Normal.png differ
diff --git a/packages/fuselage/.loki/reference/chrome_laptop_Containers_Banner_Banner.png b/packages/fuselage/.loki/reference/chrome_laptop_Containers_Banner_Banner.png
new file mode 100644
index 0000000000000000000000000000000000000000..6831838c0903707e8dee584baccdf57c43af3fd7
Binary files /dev/null and b/packages/fuselage/.loki/reference/chrome_laptop_Containers_Banner_Banner.png differ
diff --git a/packages/fuselage/.loki/reference/chrome_laptop_Containers_Banner_Inline.png b/packages/fuselage/.loki/reference/chrome_laptop_Containers_Banner_Inline.png
new file mode 100644
index 0000000000000000000000000000000000000000..4f3370dd6988c234b9fcaa5c1a3e75a9225b7e03
Binary files /dev/null and b/packages/fuselage/.loki/reference/chrome_laptop_Containers_Banner_Inline.png differ
diff --git a/packages/fuselage/.loki/reference/chrome_laptop_Containers_Banner_Normal.png b/packages/fuselage/.loki/reference/chrome_laptop_Containers_Banner_Normal.png
new file mode 100644
index 0000000000000000000000000000000000000000..72d80ec9553a02984efc132443ae36c666a25b16
Binary files /dev/null and b/packages/fuselage/.loki/reference/chrome_laptop_Containers_Banner_Normal.png differ
diff --git a/packages/fuselage/src/components/Banner/Banner.js b/packages/fuselage/src/components/Banner/Banner.js
new file mode 100644
index 0000000000000000000000000000000000000000..7d02a7d5f5bf59f2b08d9f27c187dab9f44b5057
--- /dev/null
+++ b/packages/fuselage/src/components/Banner/Banner.js
@@ -0,0 +1,52 @@
+import React, { useMemo } from 'react';
+
+import { composeClassNames as cx } from '../../helpers/composeClassNames';
+import { useStyleSheet } from '../../hooks/useStyleSheet';
+import Button from '../Button';
+import { Icon } from '../Icon';
+
+const variants = ['neutral', 'info', 'success', 'warning', 'danger'];
+
+const Banner = ({
+ inline = false,
+ children,
+ className,
+ closeable,
+ icon,
+ title,
+ variant = 'neutral',
+ onClose,
+ ...props
+}) => {
+ useStyleSheet();
+
+ variant = variants.includes(variant) ? variant : variants[0];
+
+ const closeButtonProps = useMemo(() => {
+ return variant !== variants[0] ? { [variant]: true } : {};
+ }, [variant]);
+
+ return (
+
+ {icon &&
{icon}
}
+
+ {title && (
+
{title}
+ )}
+ {children}
+
+ {closeable && (
+
+
+
+ )}
+
+ );
+};
+
+export default Banner;
diff --git a/packages/fuselage/src/components/Banner/Banner.stories.js b/packages/fuselage/src/components/Banner/Banner.stories.js
new file mode 100644
index 0000000000000000000000000000000000000000..d537ac8c159d15e20205b11d860f02b9666bc704
--- /dev/null
+++ b/packages/fuselage/src/components/Banner/Banner.stories.js
@@ -0,0 +1,148 @@
+import { action } from '@storybook/addon-actions';
+import React from 'react';
+
+import { Icon } from '../Icon';
+import Banner from './Banner';
+
+export default {
+ title: 'Containers/Banner',
+ component: Banner,
+};
+
+export const _Banner = () => (
+ }
+ title='Sed ut perspiciatis unde'
+ onClose={action('close')}
+ >
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
+ tempor
+
+);
+_Banner.storyName = 'Banner';
+
+export const Normal = () => (
+ <>
+ }
+ title='Sed ut perspiciatis unde'
+ variant='neutral'
+ onClose={action('close')}
+ >
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
+ tempor
+
+
+ }
+ title='Sed ut perspiciatis unde'
+ variant='info'
+ onClose={action('close')}
+ >
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
+ tempor
+
+
+ }
+ title='Sed ut perspiciatis unde'
+ variant='success'
+ onClose={action('close')}
+ >
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
+ tempor
+
+
+ }
+ title='Sed ut perspiciatis unde'
+ variant='warning'
+ onClose={action('close')}
+ >
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
+ tempor
+
+
+ }
+ title='Sed ut perspiciatis unde'
+ variant='danger'
+ onClose={action('close')}
+ >
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
+ tempor
+
+
+ >
+);
+
+export const Inline = () => (
+ <>
+ }
+ title='Sed ut perspiciatis unde'
+ variant='neutral'
+ onClose={action('close')}
+ >
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
+ tempor
+
+
+ }
+ title='Sed ut perspiciatis unde'
+ variant='info'
+ onClose={action('close')}
+ >
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
+ tempor
+
+
+ }
+ title='Sed ut perspiciatis unde'
+ variant='success'
+ onClose={action('close')}
+ >
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
+ tempor
+
+
+ }
+ title='Sed ut perspiciatis unde'
+ variant='warning'
+ onClose={action('close')}
+ >
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
+ tempor
+
+
+ }
+ title='Sed ut perspiciatis unde'
+ variant='danger'
+ onClose={action('close')}
+ >
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
+ tempor
+
+
+ >
+);
diff --git a/packages/fuselage/src/components/Banner/Banner.styles.scss b/packages/fuselage/src/components/Banner/Banner.styles.scss
new file mode 100644
index 0000000000000000000000000000000000000000..307977c92dcf543b99b7295722c2f3a43a319f78
--- /dev/null
+++ b/packages/fuselage/src/components/Banner/Banner.styles.scss
@@ -0,0 +1,117 @@
+@use 'sass:map';
+@use '../../styles/colors.scss';
+@use '../../styles/typography.scss';
+
+@mixin -variant($colors) {
+ color: map.get($colors, color);
+ background-color: map.get($colors, background-color);
+}
+
+.rcx-banner {
+ display: flex;
+ flex-flow: row nowrap;
+ justify-content: space-between;
+ align-items: flex-start;
+ flex: 0 1 auto;
+
+ box-sizing: border-box;
+
+ font-family: typography.font-family('sans');
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+
+ &--neutral {
+ @include -variant(
+ (
+ background-color: colors.neutral(100),
+ color: colors.neutral(800),
+ )
+ );
+ }
+
+ &--info {
+ @include -variant(
+ (
+ background-color: colors.info(200),
+ color: colors.info(600),
+ )
+ );
+ }
+
+ &--success {
+ @include -variant(
+ (
+ background-color: colors.success(200),
+ color: colors.success(800),
+ )
+ );
+ }
+
+ &--warning {
+ @include -variant(
+ (
+ background-color: colors.warning(200),
+ color: colors.warning(900),
+ )
+ );
+ }
+
+ &--danger {
+ @include -variant(
+ (
+ background-color: colors.danger(200),
+ color: colors.danger(600),
+ )
+ );
+ }
+
+ &__icon {
+ display: none;
+
+ padding-block: 22px;
+ padding-inline-start: 16px;
+
+ @include on-breakpoint(sm) {
+ display: unset;
+ }
+
+ &--inline {
+ padding-block: 10px;
+ }
+ }
+
+ &__content {
+ flex-grow: 1;
+ align-self: center;
+
+ padding-block: 14px;
+ padding-inline: 12px;
+ @include typography.use-font-scale(p1);
+
+ &--inline {
+ padding-block: 12px;
+ @include typography.use-with-truncated-text;
+ }
+ }
+
+ &__title {
+ margin: 0;
+ padding: 0;
+ @include typography.use-font-scale(p2);
+
+ &--inline {
+ float: inline-start;
+
+ padding-inline-end: 8px;
+ }
+ }
+
+ &__close-button {
+ padding-block: 20px;
+ padding-inline-end: 24px;
+
+ &--inline {
+ padding-block: 8px;
+ }
+ }
+}
diff --git a/packages/fuselage/src/components/Banner/index.js b/packages/fuselage/src/components/Banner/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..b927b80912cf8f52346d55b5a94617d3dff663f1
--- /dev/null
+++ b/packages/fuselage/src/components/Banner/index.js
@@ -0,0 +1 @@
+export { default } from './Banner';
diff --git a/packages/fuselage/src/components/index.js b/packages/fuselage/src/components/index.js
index 4e44423ceed9ca5203adaa9a173ccf23689d28aa..27f659367f69c181846b2684f29be23629bea4fa 100644
--- a/packages/fuselage/src/components/index.js
+++ b/packages/fuselage/src/components/index.js
@@ -2,6 +2,7 @@ export * from './Accordion';
export * from './AutoComplete';
export * from './Avatar';
export * from './Badge';
+export { default } from './Banner';
export * from './Box';
export { default as Button, ActionButton } from './Button';
export * from './ButtonGroup';
diff --git a/packages/fuselage/src/components/index.scss b/packages/fuselage/src/components/index.scss
index 601bf82b5e46f15dcddce83b1df2a73ab854c7ad..0b777a67930e8efb75b80323b93bfc97b2de7b87 100644
--- a/packages/fuselage/src/components/index.scss
+++ b/packages/fuselage/src/components/index.scss
@@ -2,6 +2,7 @@
@import './AutoComplete/styles.scss';
@import './Avatar/styles.scss';
@import './Badge/styles.scss';
+@import './Banner/Banner.styles.scss';
@import './Box/styles.scss';
@import './Button/Button.styles.scss';
@import './ButtonGroup/styles.scss';
diff --git a/packages/fuselage/src/helpers/composeClassNames.js b/packages/fuselage/src/helpers/composeClassNames.js
new file mode 100644
index 0000000000000000000000000000000000000000..45842118fc057f3493e2801e50647a7d379a0753
--- /dev/null
+++ b/packages/fuselage/src/helpers/composeClassNames.js
@@ -0,0 +1,49 @@
+const withPrefix = (prefix) => (modifier) =>
+ prefix ? `${prefix}--${modifier}` : modifier;
+
+export const composeClassNames = (prefix) => (...args) => {
+ const addPrefix = withPrefix(prefix);
+
+ const classNames = args
+ .map((arg) => {
+ if (typeof arg === 'string') {
+ return arg;
+ }
+
+ if (typeof arg === 'object' && Array.isArray(arg)) {
+ return arg.filter(Boolean).map(addPrefix).join(' ');
+ }
+
+ if (typeof arg === 'object' && arg !== null) {
+ return Object.entries(arg)
+ .map(([key, value]) => {
+ if (typeof value === 'boolean') {
+ if (value) {
+ return addPrefix(key);
+ }
+
+ return null;
+ }
+
+ if (typeof value === 'string' || typeof value === 'number') {
+ return addPrefix(`${key}-${value}`);
+ }
+
+ return null;
+ })
+ .filter(Boolean)
+ .join(' ');
+ }
+
+ return null;
+ })
+ .concat()
+ .filter(Boolean)
+ .join(' ');
+
+ if (!prefix) {
+ return classNames;
+ }
+
+ return `${prefix} ${classNames}`;
+};