diff --git a/packages/react-core/src/components/Banner/Banner.tsx b/packages/react-core/src/components/Banner/Banner.tsx index df01c6b0a7e..9c48a564c91 100644 --- a/packages/react-core/src/components/Banner/Banner.tsx +++ b/packages/react-core/src/components/Banner/Banner.tsx @@ -2,6 +2,10 @@ import * as React from 'react'; import styles from '@patternfly/react-styles/css/components/Banner/banner'; import { css } from '@patternfly/react-styles'; +export type BannerColor = 'red' | 'orangered' | 'orange' | 'gold' | 'green' | 'cyan' | 'blue' | 'purple'; + +export type BannerStatus = 'success' | 'warning' | 'danger' | 'info' | 'custom'; + export interface BannerProps extends React.HTMLProps { /** Content rendered inside the banner. */ children?: React.ReactNode; @@ -13,29 +17,48 @@ export interface BannerProps extends React.HTMLProps { * be passed in when the banner conveys status/severity. */ screenReaderText?: string; - /** Variant styles for the banner. */ - variant?: 'default' | 'blue' | 'red' | 'green' | 'gold'; + /** Color options for the banner, will be overwritten by any applied using the status prop. */ + color?: BannerColor; + /** Status style options for the banner, will overwrite any color applied using the color prop. */ + status?: BannerStatus; +} +interface StatusBanner extends BannerProps { + color?: never; + status?: BannerStatus; } -export const Banner: React.FunctionComponent = ({ +interface NonStatusBanner extends BannerProps { + color?: BannerColor; + status?: never; +} + +export const Banner: React.FunctionComponent = ({ children, className, - variant = 'default', screenReaderText, isSticky = false, + color, + status, ...props -}: BannerProps) => ( -
- {screenReaderText && {screenReaderText}} - {children} -
-); +}: BannerProps) => { + const getStatusOrColorModifier = () => { + if (status) { + return styles.modifiers[status]; + } + + if (color) { + return styles.modifiers[color]; + } + }; + + return ( +
+ {screenReaderText && {screenReaderText}} + {children} +
+ ); +}; Banner.displayName = 'Banner'; diff --git a/packages/react-core/src/components/Banner/__tests__/Banner.test.tsx b/packages/react-core/src/components/Banner/__tests__/Banner.test.tsx index e13ab61b4b3..214f9cf7c71 100644 --- a/packages/react-core/src/components/Banner/__tests__/Banner.test.tsx +++ b/packages/react-core/src/components/Banner/__tests__/Banner.test.tsx @@ -27,31 +27,76 @@ test('Renders with custom class name when className prop is provided', () => { expect(screen.getByText('Test')).toHaveClass('custom-class'); }); -test('Renders without any modifier class when variant prop is not passed', () => { +test('Renders without any modifier class when color and status props are not passed', () => { render(Test); expect(screen.getByText('Test')).toHaveClass(styles.banner, { exact: true }); }); -test('Renders with class name pf-m-green when "green" is passed to variant prop', () => { - render(Test); - expect(screen.getByText('Test')).toHaveClass('pf-m-green'); +test('Renders with class name pf-m-red when "red" is passed to color prop', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('pf-m-red'); }); -test('Renders with class name pf-m-red when "red" is passed to variant prop', () => { - render(Test); - expect(screen.getByText('Test')).toHaveClass('pf-m-red'); +test('Renders with class name pf-m-orangered when "orangered" is passed to color prop', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('pf-m-orangered'); }); -test('Renders with class name pf-m-gold when "gold" is passed to variant prop', () => { - render(Test); +test('Renders with class name pf-m-orange when "orange" is passed to color prop', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('pf-m-orange'); +}); + +test('Renders with class name pf-m-gold when "gold" is passed to color prop', () => { + render(Test); expect(screen.getByText('Test')).toHaveClass('pf-m-gold'); }); -test('Renders with class name pf-m-blue when "blue" is passed to variant prop', () => { - render(Test); +test('Renders with class name pf-m-green when "green" is passed to color prop', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('pf-m-green'); +}); + +test('Renders with class name pf-m-cyan when "cyan" is passed to color prop', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('pf-m-cyan'); +}); + +test('Renders with class name pf-m-blue when "blue" is passed to color prop', () => { + render(Test); expect(screen.getByText('Test')).toHaveClass('pf-m-blue'); }); +test('Renders with class name pf-m-purple when "purple" is passed to color prop', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('pf-m-purple'); +}); + +test('Renders with class name pf-m-success when "success" is passed to status prop', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('pf-m-success'); +}); + +test('Renders with class name pf-m-warning when "warning" is passed to status prop', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('pf-m-warning'); +}); + +test('Renders with class name pf-m-danger when "danger" is passed to status prop', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('pf-m-danger'); +}); + +test('Renders with class name pf-m-info when "info" is passed to status prop', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('pf-m-info'); +}); + +test('Renders with class name pf-m-custom when "custom" is passed to status prop', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('pf-m-custom'); +}); + test('Does not render pf-v5-screen-reader class by default', () => { render(Test); expect(screen.getByText('Test')).not.toContainHTML(''); diff --git a/packages/react-core/src/components/Banner/examples/Banner.md b/packages/react-core/src/components/Banner/examples/Banner.md index 369fe7afdbf..e075c612aae 100644 --- a/packages/react-core/src/components/Banner/examples/Banner.md +++ b/packages/react-core/src/components/Banner/examples/Banner.md @@ -15,7 +15,7 @@ import BellIcon from '@patternfly/react-icons/dist/esm/icons/bell-icon'; ### Basic -Banners can be styled with one of 5 different colors. A basic banner should only be used when the banner color does not represent status or severity. +Banners can be styled with one of 9 different colors using the `color` prop. A basic banner should only be used when the banner color does not represent status or severity. ```ts file="./BannerBasic.tsx" @@ -23,7 +23,9 @@ Banners can be styled with one of 5 different colors. A basic banner should only ### Status -When a banner is used to convey status, it is advised to pass in an icon inside the banner to convey the status in a way besides just color. The `screenReaderText` prop should also be passed in to convey the status/severity of the banner to users of certain assistive technologies such as screen readers. +When a banner is used to convey status it should be styled using the `status` prop. Additionally, it is advised to pass an icon inside the banner to convey the status in a way besides just color. + +The `screenReaderText` prop should also be passed in to convey the status/severity of the banner to users of certain assistive technologies such as screen readers. In the following example, a flex layout is used inside the banner content to show one possible way to create spacing between the icons and banner text. diff --git a/packages/react-core/src/components/Banner/examples/BannerBasic.tsx b/packages/react-core/src/components/Banner/examples/BannerBasic.tsx index acedc38a541..a53e1efdeba 100644 --- a/packages/react-core/src/components/Banner/examples/BannerBasic.tsx +++ b/packages/react-core/src/components/Banner/examples/BannerBasic.tsx @@ -5,12 +5,20 @@ export const BannerBasic: React.FunctionComponent = () => ( <> Default banner
- Blue banner + Red banner
- Red banner + Orangered banner
- Green banner + Orange banner
- Gold banner + Gold banner +
+ Green banner +
+ Cyan banner +
+ Blue banner +
+ Purple banner ); diff --git a/packages/react-core/src/components/Banner/examples/BannerStatus.tsx b/packages/react-core/src/components/Banner/examples/BannerStatus.tsx index 80d130ea03f..56f60c8de7c 100644 --- a/packages/react-core/src/components/Banner/examples/BannerStatus.tsx +++ b/packages/react-core/src/components/Banner/examples/BannerStatus.tsx @@ -8,25 +8,25 @@ import BellIcon from '@patternfly/react-icons/dist/esm/icons/bell-icon'; export const BannerStatus: React.FunctionComponent = () => ( <> - + - + - Default banner + Success banner
- + - + - Info banner + Warning banner
- + @@ -35,21 +35,21 @@ export const BannerStatus: React.FunctionComponent = () => (
- + - + - Success banner + Info banner
- + - + - Warning banner + Custom banner