diff --git a/packages/ibm-products/src/components/Datagrid/Datagrid.test.js b/packages/ibm-products/src/components/Datagrid/Datagrid.test.js index aa18a8c878..831daca93d 100644 --- a/packages/ibm-products/src/components/Datagrid/Datagrid.test.js +++ b/packages/ibm-products/src/components/Datagrid/Datagrid.test.js @@ -1184,19 +1184,38 @@ describe(componentName, () => { const { rerender } = render(); screen.getAllByText('Empty State Title'); screen.getByText('Description test explaining why this card is empty.'); - expect(screen.getByRole('img')).toHaveClass( - `${pkg.prefix}--empty-state__illustration-noData` - ); + + expect( + screen + .getAllByRole('img', { hidden: true }) + .find((img) => + img.classList.contains( + `${pkg.prefix}--empty-state__illustration-noData` + ) + ) + ).toBeInTheDocument(); rerender(); - expect(screen.getByRole('img')).toHaveClass( - `${pkg.prefix}--empty-state__illustration-error` - ); + expect( + screen + .getAllByRole('img', { hidden: true }) + .find((img) => + img.classList.contains( + `${pkg.prefix}--empty-state__illustration-error` + ) + ) + ).toBeInTheDocument(); rerender(); - expect(screen.getByRole('img')).toHaveClass( - `${pkg.prefix}--empty-state__illustration-notFound` - ); + expect( + screen + .getAllByRole('img', { hidden: true }) + .find((img) => + img.classList.contains( + `${pkg.prefix}--empty-state__illustration-notFound` + ) + ) + ).toBeInTheDocument(); rerender(); expect(screen.queryByRole('img')).not.toBeInTheDocument(); diff --git a/packages/ibm-products/src/components/EmptyStates/EmptyState.tsx b/packages/ibm-products/src/components/EmptyStates/EmptyState.tsx index fbde2f7712..c3e5818377 100644 --- a/packages/ibm-products/src/components/EmptyStates/EmptyState.tsx +++ b/packages/ibm-products/src/components/EmptyStates/EmptyState.tsx @@ -6,7 +6,7 @@ */ // Import portions of React that are needed. -import React, { ReactNode } from 'react'; +import React, { ElementType, ReactNode } from 'react'; import { EmptyStateV2 } from '.'; // Other standard imports. @@ -32,9 +32,10 @@ enum sizes { } // Default values for props -export const defaults: { position: string; size: sizes } = { +export const defaults: { position: string; size: sizes; headingAs: string } = { position: 'top', size: sizes.lg, + headingAs: 'h3', }; export interface EmptyStateProps { @@ -77,6 +78,11 @@ export interface EmptyStateProps { href?: string; }; + /** + * Empty state headingAs allows you to customize the type of heading element + */ + headingAs?: (() => ReactNode) | string | ElementType; + /** * Empty state size */ @@ -116,6 +122,7 @@ export let EmptyState = React.forwardRef( illustrationPosition = defaults.position, link, size = defaults.size, + headingAs = defaults.headingAs, subtitle, title, ...rest @@ -140,12 +147,14 @@ export let EmptyState = React.forwardRef( `${blockClass}__illustration`, `${blockClass}__illustration--${size}`, ])} + aria-hidden="true" /> )} @@ -176,6 +185,11 @@ EmptyState.propTypes = { */ className: PropTypes.string, + /** + * Empty state headingAs allows you to customize the type of heading element + */ + headingAs: PropTypes.elementType, + /** * Empty state illustration, specify the `src` for a provided illustration to be displayed. In the case of requiring a light and dark illustration of your own, simply pass the corresponding illustration based on the current theme of your application. * For example: `illustration={appTheme === 'dark' ? darkIllustration : lightIllustration}` @@ -194,7 +208,6 @@ EmptyState.propTypes = { * Designates the position of the illustration relative to the content */ illustrationPosition: PropTypes.oneOf(['top', 'right', 'bottom', 'left']), - /** * Empty state link object */ @@ -204,7 +217,6 @@ EmptyState.propTypes = { text: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), href: PropTypes.string, }), - /** * Empty state size */ diff --git a/packages/ibm-products/src/components/EmptyStates/EmptyStateContent.js b/packages/ibm-products/src/components/EmptyStates/EmptyStateContent.js index 176b4a2ecb..a7c46ac7df 100644 --- a/packages/ibm-products/src/components/EmptyStates/EmptyStateContent.js +++ b/packages/ibm-products/src/components/EmptyStates/EmptyStateContent.js @@ -14,22 +14,30 @@ import { pkg } from '../../settings'; import cx from 'classnames'; // Carbon and package components we use. -import { Button, Link } from '@carbon/react'; +import { Button, Link, Section } from '@carbon/react'; // The block part of our conventional BEM class names (blockClass__E--M). const blockClass = `${pkg.prefix}--empty-state`; const componentName = 'EmptyStateContent'; -export const EmptyStateContent = ({ action, link, size, subtitle, title }) => { +export const EmptyStateContent = ({ + action, + link, + headingAs, + size, + subtitle, + title, +}) => { return (
-

{title} -

+ {subtitle && (

{ const Illustration = getIllustration(kind); return ( - + ); }; diff --git a/packages/ibm-products/src/components/EmptyStates/EmptyStates.stories.jsx b/packages/ibm-products/src/components/EmptyStates/EmptyStates.stories.jsx index 814b434ddb..2483644622 100644 --- a/packages/ibm-products/src/components/EmptyStates/EmptyStates.stories.jsx +++ b/packages/ibm-products/src/components/EmptyStates/EmptyStates.stories.jsx @@ -42,6 +42,7 @@ export default { }; const emptyStateCommonProps = { + headingAs: 'h3', title: 'Start by adding data assets', subtitle: ( <> diff --git a/packages/ibm-products/src/components/EmptyStates/ErrorEmptyState/ErrorEmptyState.stories.jsx b/packages/ibm-products/src/components/EmptyStates/ErrorEmptyState/ErrorEmptyState.stories.jsx index 7317cbf0f4..592d442338 100644 --- a/packages/ibm-products/src/components/EmptyStates/ErrorEmptyState/ErrorEmptyState.stories.jsx +++ b/packages/ibm-products/src/components/EmptyStates/ErrorEmptyState/ErrorEmptyState.stories.jsx @@ -41,6 +41,7 @@ export default { }; const defaultStoryProps = { + headingAs: 'h3', title: 'Empty state title', subtitle: 'Description text explaining why this section is empty.', illustrationDescription: 'Test alt text', diff --git a/packages/ibm-products/src/components/EmptyStates/ErrorEmptyState/ErrorEmptyState.tsx b/packages/ibm-products/src/components/EmptyStates/ErrorEmptyState/ErrorEmptyState.tsx index 0b70b344ec..3724ee6890 100644 --- a/packages/ibm-products/src/components/EmptyStates/ErrorEmptyState/ErrorEmptyState.tsx +++ b/packages/ibm-products/src/components/EmptyStates/ErrorEmptyState/ErrorEmptyState.tsx @@ -6,7 +6,7 @@ */ // Import portions of React that are needed. -import React, { ReactNode } from 'react'; +import React, { ElementType, ReactNode } from 'react'; // Other standard imports. import PropTypes from 'prop-types'; @@ -68,6 +68,10 @@ export interface ErrorEmptyStateProps { href?: string; }; + /** + * Empty state headingAs allows you to customize the type of heading element + */ + headingAs?: (() => ReactNode) | string | ElementType; /** * Empty state size */ @@ -102,6 +106,7 @@ export let ErrorEmptyState = React.forwardRef< illustrationTheme, link, size = defaults.size, + headingAs = defaults.headingAs, subtitle, title, @@ -134,6 +139,7 @@ export let ErrorEmptyState = React.forwardRef< action={action} link={link} size={size} + headingAs={headingAs} subtitle={subtitle} title={title || ''} /> @@ -171,6 +177,11 @@ ErrorEmptyState.propTypes = { */ className: PropTypes.string, + /** + * Empty state headingAs allows you to customize the type of heading element + */ + headingAs: PropTypes.elementType, + /** * The alt text for empty state svg images. If not provided , title will be used. */ diff --git a/packages/ibm-products/src/components/EmptyStates/NoDataEmptyState/NoDataEmptyState.stories.jsx b/packages/ibm-products/src/components/EmptyStates/NoDataEmptyState/NoDataEmptyState.stories.jsx index 805b133e6e..3b4cd4ea60 100644 --- a/packages/ibm-products/src/components/EmptyStates/NoDataEmptyState/NoDataEmptyState.stories.jsx +++ b/packages/ibm-products/src/components/EmptyStates/NoDataEmptyState/NoDataEmptyState.stories.jsx @@ -41,6 +41,7 @@ export default { }; const defaultStoryProps = { + headingAs: 'h3', title: 'Empty state title', subtitle: 'Description text explaining why this section is empty.', illustrationDescription: 'Test alt text', diff --git a/packages/ibm-products/src/components/EmptyStates/NoDataEmptyState/NoDataEmptyState.tsx b/packages/ibm-products/src/components/EmptyStates/NoDataEmptyState/NoDataEmptyState.tsx index a8e61a941e..1c61549b4a 100644 --- a/packages/ibm-products/src/components/EmptyStates/NoDataEmptyState/NoDataEmptyState.tsx +++ b/packages/ibm-products/src/components/EmptyStates/NoDataEmptyState/NoDataEmptyState.tsx @@ -6,7 +6,7 @@ */ // Import portions of React that are needed. -import React, { ReactNode } from 'react'; +import React, { ElementType, ReactNode } from 'react'; // Other standard imports. import PropTypes from 'prop-types'; @@ -67,6 +67,11 @@ export interface NoDataEmptyStateProps { href?: string; }; + /** + * Empty state headingAs allows you to customize the type of heading element + */ + headingAs?: (() => ReactNode) | string | ElementType; + /** * Empty state size */ @@ -101,6 +106,7 @@ export let NoDataEmptyState = React.forwardRef< illustrationDescription, link, size = defaults.size, + headingAs = defaults.headingAs, subtitle, title, @@ -133,6 +139,7 @@ export let NoDataEmptyState = React.forwardRef< action={action} link={link} size={size} + headingAs={headingAs} subtitle={subtitle} title={title || ''} /> @@ -170,6 +177,11 @@ NoDataEmptyState.propTypes = { */ className: PropTypes.string, + /** + * Empty state headingAs allows you to customize the type of heading element + */ + headingAs: PropTypes.elementType, + /** * The alt text for empty state svg images. If not provided , title will be used. */ diff --git a/packages/ibm-products/src/components/EmptyStates/NoTagsEmptyState/NoTagsEmptyState.stories.jsx b/packages/ibm-products/src/components/EmptyStates/NoTagsEmptyState/NoTagsEmptyState.stories.jsx index 982d7df14e..0b3ffbdcc2 100644 --- a/packages/ibm-products/src/components/EmptyStates/NoTagsEmptyState/NoTagsEmptyState.stories.jsx +++ b/packages/ibm-products/src/components/EmptyStates/NoTagsEmptyState/NoTagsEmptyState.stories.jsx @@ -41,6 +41,7 @@ export default { }; const defaultStoryProps = { + headingAs: 'h3', title: 'Empty state title', subtitle: 'Description text explaining why this section is empty.', illustrationDescription: 'Test alt text', diff --git a/packages/ibm-products/src/components/EmptyStates/NoTagsEmptyState/NoTagsEmptyState.tsx b/packages/ibm-products/src/components/EmptyStates/NoTagsEmptyState/NoTagsEmptyState.tsx index 9acf8297b9..d34ff4e8c1 100644 --- a/packages/ibm-products/src/components/EmptyStates/NoTagsEmptyState/NoTagsEmptyState.tsx +++ b/packages/ibm-products/src/components/EmptyStates/NoTagsEmptyState/NoTagsEmptyState.tsx @@ -6,7 +6,7 @@ */ // Import portions of React that are needed. -import React, { ReactNode } from 'react'; +import React, { ElementType, ReactNode } from 'react'; // Other standard imports. import PropTypes from 'prop-types'; @@ -68,6 +68,11 @@ export interface NoTagsEmptyStateProps { href?: string; }; + /** + * Empty state headingAs allows you to customize the type of heading element + */ + headingAs?: (() => ReactNode) | string | ElementType; + /** * Empty state size */ @@ -102,6 +107,7 @@ export let NoTagsEmptyState = React.forwardRef< illustrationDescription, link, size = defaults.size, + headingAs = defaults.headingAs, subtitle, title, @@ -134,6 +140,7 @@ export let NoTagsEmptyState = React.forwardRef< action={action} link={link} size={size} + headingAs={headingAs} subtitle={subtitle} title={(title = '')} /> @@ -171,6 +178,11 @@ NoTagsEmptyState.propTypes = { */ className: PropTypes.string, + /** + * Empty state headingAs allows you to customize the type of heading element + */ + headingAs: PropTypes.elementType, + /** * The alt text for empty state svg images. If not provided , title will be used. */ diff --git a/packages/ibm-products/src/components/EmptyStates/NotFoundEmptyState/NotFoundEmptyState.stories.jsx b/packages/ibm-products/src/components/EmptyStates/NotFoundEmptyState/NotFoundEmptyState.stories.jsx index 2e496e9581..2c3eab81df 100644 --- a/packages/ibm-products/src/components/EmptyStates/NotFoundEmptyState/NotFoundEmptyState.stories.jsx +++ b/packages/ibm-products/src/components/EmptyStates/NotFoundEmptyState/NotFoundEmptyState.stories.jsx @@ -40,6 +40,7 @@ export default { }; const defaultStoryProps = { + headingAs: 'h3', title: 'Empty state title', subtitle: 'Description text explaining why this section is empty.', illustrationDescription: 'Test alt text', diff --git a/packages/ibm-products/src/components/EmptyStates/NotFoundEmptyState/NotFoundEmptyState.tsx b/packages/ibm-products/src/components/EmptyStates/NotFoundEmptyState/NotFoundEmptyState.tsx index bc4b82417c..c32c08bd7d 100644 --- a/packages/ibm-products/src/components/EmptyStates/NotFoundEmptyState/NotFoundEmptyState.tsx +++ b/packages/ibm-products/src/components/EmptyStates/NotFoundEmptyState/NotFoundEmptyState.tsx @@ -6,7 +6,7 @@ */ // Import portions of React that are needed. -import React, { ReactNode } from 'react'; +import React, { ElementType, ReactNode } from 'react'; // Other standard imports. import PropTypes from 'prop-types'; @@ -67,6 +67,11 @@ export interface NotFoundEmptyStateProps { href?: string; }; + /** + * Empty state headingAs allows you to customize the type of heading element + */ + headingAs?: (() => ReactNode) | string | ElementType; + /** * Empty state size */ @@ -101,6 +106,7 @@ export let NotFoundEmptyState = React.forwardRef< illustrationDescription, link, size = defaults.size, + headingAs = defaults.headingAs, subtitle, title, @@ -133,6 +139,7 @@ export let NotFoundEmptyState = React.forwardRef< action={action} link={link} size={size} + headingAs={headingAs} subtitle={subtitle} title={title || ''} /> @@ -173,6 +180,11 @@ NotFoundEmptyState.propTypes = { */ className: PropTypes.string, + /** + * Empty state headingAs allows you to customize the type of heading element + */ + headingAs: PropTypes.elementType, + /** * The alt text for empty state svg images. If not provided , title will be used. */ diff --git a/packages/ibm-products/src/components/EmptyStates/NotificationsEmptyState/NotificationsEmptyState.stories.jsx b/packages/ibm-products/src/components/EmptyStates/NotificationsEmptyState/NotificationsEmptyState.stories.jsx index d838c2ed13..d14b9258a9 100644 --- a/packages/ibm-products/src/components/EmptyStates/NotificationsEmptyState/NotificationsEmptyState.stories.jsx +++ b/packages/ibm-products/src/components/EmptyStates/NotificationsEmptyState/NotificationsEmptyState.stories.jsx @@ -40,6 +40,7 @@ export default { }; const defaultStoryProps = { + headingAs: 'h3', title: 'Empty state title', subtitle: 'Description text explaining why this section is empty.', illustrationDescription: 'Test alt text', diff --git a/packages/ibm-products/src/components/EmptyStates/NotificationsEmptyState/NotificationsEmptyState.tsx b/packages/ibm-products/src/components/EmptyStates/NotificationsEmptyState/NotificationsEmptyState.tsx index 51a3afc4a1..e2a4a98a3b 100644 --- a/packages/ibm-products/src/components/EmptyStates/NotificationsEmptyState/NotificationsEmptyState.tsx +++ b/packages/ibm-products/src/components/EmptyStates/NotificationsEmptyState/NotificationsEmptyState.tsx @@ -6,7 +6,7 @@ */ // Import portions of React that are needed. -import React, { ReactNode } from 'react'; +import React, { ElementType, ReactNode } from 'react'; // Other standard imports. import PropTypes from 'prop-types'; @@ -69,6 +69,11 @@ export interface NotificationsEmptyStateProps { href?: string; }; + /** + * Empty state headingAs allows you to customize the type of heading element + */ + headingAs?: (() => ReactNode) | string | ElementType; + /** * Empty state size */ @@ -103,6 +108,7 @@ export let NotificationsEmptyState = React.forwardRef< illustrationDescription, link, size = defaults.size, + headingAs = defaults.headingAs, subtitle, title, @@ -135,6 +141,7 @@ export let NotificationsEmptyState = React.forwardRef< action={action} link={link} size={size} + headingAs={headingAs} subtitle={subtitle} title={title || ''} /> @@ -175,6 +182,11 @@ NotificationsEmptyState.propTypes = { */ className: PropTypes.string, + /** + * Empty state headingAs allows you to customize the type of heading element + */ + headingAs: PropTypes.elementType, + /** * The alt text for empty state svg images. If not provided , title will be used. */ diff --git a/packages/ibm-products/src/components/EmptyStates/UnauthorizedEmptyState/UnauthorizedEmptyState.stories.jsx b/packages/ibm-products/src/components/EmptyStates/UnauthorizedEmptyState/UnauthorizedEmptyState.stories.jsx index 685625a6e9..c259d147ca 100644 --- a/packages/ibm-products/src/components/EmptyStates/UnauthorizedEmptyState/UnauthorizedEmptyState.stories.jsx +++ b/packages/ibm-products/src/components/EmptyStates/UnauthorizedEmptyState/UnauthorizedEmptyState.stories.jsx @@ -40,6 +40,7 @@ export default { }; const defaultStoryProps = { + headingAs: 'h3', title: 'Empty state title', subtitle: 'Description text explaining why this section is empty.', illustrationDescription: 'Test alt text', diff --git a/packages/ibm-products/src/components/EmptyStates/UnauthorizedEmptyState/UnauthorizedEmptyState.tsx b/packages/ibm-products/src/components/EmptyStates/UnauthorizedEmptyState/UnauthorizedEmptyState.tsx index 138de84a24..f1008b03ca 100644 --- a/packages/ibm-products/src/components/EmptyStates/UnauthorizedEmptyState/UnauthorizedEmptyState.tsx +++ b/packages/ibm-products/src/components/EmptyStates/UnauthorizedEmptyState/UnauthorizedEmptyState.tsx @@ -6,7 +6,7 @@ */ // Import portions of React that are needed. -import React, { ReactNode } from 'react'; +import React, { ElementType, ReactNode } from 'react'; // Other standard imports. import PropTypes from 'prop-types'; @@ -66,6 +66,10 @@ export interface UnauthorizedEmptyStateProps { text?: string | ReactNode; href?: string; }; + /** + * Empty state headingAs allows you to customize the type of heading element + */ + headingAs?: (() => ReactNode) | string | ElementType; /** * Empty state size @@ -101,6 +105,7 @@ export let UnauthorizedEmptyState = React.forwardRef< illustrationDescription, link, size = defaults.size, + headingAs = defaults.headingAs, subtitle, title, @@ -133,6 +138,7 @@ export let UnauthorizedEmptyState = React.forwardRef< action={action} link={link} size={size} + headingAs={headingAs} subtitle={subtitle} title={title || ''} /> @@ -173,6 +179,11 @@ UnauthorizedEmptyState.propTypes = { */ className: PropTypes.string, + /** + * Empty state headingAs allows you to customize the type of heading element + */ + headingAs: PropTypes.elementType, + /** * The alt text for empty state svg images. If not provided , title will be used. */ @@ -190,7 +201,6 @@ UnauthorizedEmptyState.propTypes = { * `illustrationTheme={appTheme === ('carbon--g100' || 'carbon--g90') ? 'dark' : 'light'}` */ illustrationTheme: PropTypes.oneOf(['light', 'dark']), - /** * Empty state link object */ @@ -200,7 +210,6 @@ UnauthorizedEmptyState.propTypes = { text: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), href: PropTypes.string, }), - /** * Empty state size */ diff --git a/packages/ibm-products/src/components/EmptyStates/assets/ErrorIllustration.js b/packages/ibm-products/src/components/EmptyStates/assets/ErrorIllustration.js index 099556deec..996829c636 100644 --- a/packages/ibm-products/src/components/EmptyStates/assets/ErrorIllustration.js +++ b/packages/ibm-products/src/components/EmptyStates/assets/ErrorIllustration.js @@ -32,6 +32,7 @@ export const ErrorIllustration = ({ theme, size, alt, ...rest }) => { `${blockClass}__illustration--${size}`, ])} role="img" + aria-hidden="true" > {alt} {theme === 'dark' ? ( diff --git a/packages/ibm-products/src/components/EmptyStates/assets/NoDataIllustration.js b/packages/ibm-products/src/components/EmptyStates/assets/NoDataIllustration.js index af6da233ab..530a64f450 100644 --- a/packages/ibm-products/src/components/EmptyStates/assets/NoDataIllustration.js +++ b/packages/ibm-products/src/components/EmptyStates/assets/NoDataIllustration.js @@ -32,6 +32,7 @@ export const NoDataIllustration = ({ theme, size, alt, ...rest }) => { `${blockClass}__illustration--${size}`, ])} role="img" + aria-hidden="true" > {alt} {theme === 'dark' ? ( diff --git a/packages/ibm-products/src/components/EmptyStates/assets/NoTagsIllustration.js b/packages/ibm-products/src/components/EmptyStates/assets/NoTagsIllustration.js index f88b77e2c2..2818fe7b54 100644 --- a/packages/ibm-products/src/components/EmptyStates/assets/NoTagsIllustration.js +++ b/packages/ibm-products/src/components/EmptyStates/assets/NoTagsIllustration.js @@ -33,6 +33,7 @@ export const NoTagsIllustration = ({ theme, size, alt, ...rest }) => { `${blockClass}__illustration--${size}`, ])} role="img" + aria-hidden="true" > {alt} {theme === 'dark' ? ( diff --git a/packages/ibm-products/src/components/EmptyStates/assets/NotFoundIllustration.js b/packages/ibm-products/src/components/EmptyStates/assets/NotFoundIllustration.js index 00b7106e56..870e100120 100644 --- a/packages/ibm-products/src/components/EmptyStates/assets/NotFoundIllustration.js +++ b/packages/ibm-products/src/components/EmptyStates/assets/NotFoundIllustration.js @@ -32,6 +32,7 @@ export const NotFoundIllustration = ({ theme, size, alt, ...rest }) => { `${blockClass}__illustration--${size}`, ])} role="img" + aria-hidden="true" > {alt} {theme === 'dark' ? ( diff --git a/packages/ibm-products/src/components/EmptyStates/assets/NotificationsIllustration.js b/packages/ibm-products/src/components/EmptyStates/assets/NotificationsIllustration.js index a8f2c0b44a..005206edc2 100644 --- a/packages/ibm-products/src/components/EmptyStates/assets/NotificationsIllustration.js +++ b/packages/ibm-products/src/components/EmptyStates/assets/NotificationsIllustration.js @@ -31,6 +31,7 @@ export const NotificationsIllustration = ({ theme, size, alt, ...rest }) => { `${blockClass}__illustration-notification`, `${blockClass}__illustration--${size}`, ])} + aria-hidden="true" > {alt} {theme === 'dark' ? ( diff --git a/packages/ibm-products/src/components/EmptyStates/assets/UnauthorizedIllustration.js b/packages/ibm-products/src/components/EmptyStates/assets/UnauthorizedIllustration.js index ea8945180a..7759ff89a5 100644 --- a/packages/ibm-products/src/components/EmptyStates/assets/UnauthorizedIllustration.js +++ b/packages/ibm-products/src/components/EmptyStates/assets/UnauthorizedIllustration.js @@ -33,6 +33,7 @@ export const UnauthorizedIllustration = ({ theme, size, alt, ...rest }) => { `${blockClass}__illustration--${size}`, ])} role="img" + aria-hidden="true" > {alt} {theme === 'dark' ? (