diff --git a/packages/react-core/package.json b/packages/react-core/package.json index 18fe134ecce..dafd1a225a1 100644 --- a/packages/react-core/package.json +++ b/packages/react-core/package.json @@ -54,7 +54,7 @@ "tslib": "^2.8.1" }, "devDependencies": { - "@patternfly/patternfly": "6.5.0-prerelease.19", + "@patternfly/patternfly": "6.5.0-prerelease.21", "case-anything": "^3.1.2", "css": "^3.0.0", "fs-extra": "^11.3.0" diff --git a/packages/react-core/src/components/Compass/CompassContent.tsx b/packages/react-core/src/components/Compass/CompassContent.tsx index 09b3dc1cb19..cfd9a74219d 100644 --- a/packages/react-core/src/components/Compass/CompassContent.tsx +++ b/packages/react-core/src/components/Compass/CompassContent.tsx @@ -2,7 +2,7 @@ import { Drawer, DrawerContent, DrawerProps } from '../Drawer'; import styles from '@patternfly/react-styles/css/components/Compass/compass'; import { css } from '@patternfly/react-styles'; -interface CompassContentProps extends React.HTMLProps { +export interface CompassContentProps extends React.HTMLProps { /** Content of the main compass area. Typically one or more CompassPanel components. */ children: React.ReactNode; /** Additional classes added to the CompassContent */ diff --git a/packages/react-core/src/components/Compass/CompassHeader.tsx b/packages/react-core/src/components/Compass/CompassHeader.tsx index c249c1d8858..0d2896c2982 100644 --- a/packages/react-core/src/components/Compass/CompassHeader.tsx +++ b/packages/react-core/src/components/Compass/CompassHeader.tsx @@ -1,7 +1,7 @@ import styles from '@patternfly/react-styles/css/components/Compass/compass'; import { css } from '@patternfly/react-styles'; -interface CompassHeaderProps { +export interface CompassHeaderProps { /** Content of the logo area */ logo?: React.ReactNode; /** Content of the navigation area */ diff --git a/packages/react-core/src/components/Compass/CompassHero.tsx b/packages/react-core/src/components/Compass/CompassHero.tsx index 0987c25277e..6b28eb4af7f 100644 --- a/packages/react-core/src/components/Compass/CompassHero.tsx +++ b/packages/react-core/src/components/Compass/CompassHero.tsx @@ -1,87 +1,18 @@ import styles from '@patternfly/react-styles/css/components/Compass/compass'; import { css } from '@patternfly/react-styles'; -import compassHeroBackgroundImageLight from '@patternfly/react-tokens/dist/esm/c_compass__hero_BackgroundImage_light'; -import compassHeroBackgroundImageDark from '@patternfly/react-tokens/dist/esm/c_compass__hero_BackgroundImage_dark'; -import compassHeroGradientStop1Light from '@patternfly/react-tokens/dist/esm/c_compass__hero_gradient_stop_1_light'; -import compassHeroGradientStop2Light from '@patternfly/react-tokens/dist/esm/c_compass__hero_gradient_stop_2_light'; -import compassHeroGradientStop3Light from '@patternfly/react-tokens/dist/esm/c_compass__hero_gradient_stop_3_light'; -import compassHeroGradientStop1Dark from '@patternfly/react-tokens/dist/esm/c_compass__hero_gradient_stop_1_dark'; -import compassHeroGradientStop2Dark from '@patternfly/react-tokens/dist/esm/c_compass__hero_gradient_stop_2_dark'; -import compassHeroGradientStop3Dark from '@patternfly/react-tokens/dist/esm/c_compass__hero_gradient_stop_3_dark'; - -interface CompassHeroProps extends Omit, 'content'> { +/** A wrapper component to pass a PatternFly Hero component into. */ +export interface CompassHeroProps extends Omit, 'content'> { /** Content of the hero */ children?: React.ReactNode; /** Additional classes added to the hero */ className?: string; - /** Light theme background image path of the hero */ - backgroundSrcLight?: string; - /** Dark theme background image path of the hero */ - backgroundSrcDark?: string; - /** Light theme gradient of the hero */ - gradientLight?: { - stop1?: string; - stop2?: string; - stop3?: string; - }; - /** Dark theme gradient of the hero */ - gradientDark?: { - stop1?: string; - stop2?: string; - stop3?: string; - }; } -export const CompassHero: React.FunctionComponent = ({ - className, - children, - backgroundSrcLight, - backgroundSrcDark, - gradientLight, - gradientDark, - ...props -}) => { - const backgroundImageStyles: { [key: string]: string } = {}; - if (backgroundSrcLight) { - backgroundImageStyles[compassHeroBackgroundImageLight.name] = `url(${backgroundSrcLight})`; - } - if (backgroundSrcDark) { - backgroundImageStyles[compassHeroBackgroundImageDark.name] = `url(${backgroundSrcDark})`; - } - - if (gradientLight) { - if (gradientLight.stop1) { - backgroundImageStyles[compassHeroGradientStop1Light.name] = gradientLight.stop1; - } - if (gradientLight.stop2) { - backgroundImageStyles[compassHeroGradientStop2Light.name] = gradientLight.stop2; - } - if (gradientLight.stop3) { - backgroundImageStyles[compassHeroGradientStop3Light.name] = gradientLight.stop3; - } - } - if (gradientDark) { - if (gradientDark.stop1) { - backgroundImageStyles[compassHeroGradientStop1Dark.name] = gradientDark.stop1; - } - if (gradientDark.stop2) { - backgroundImageStyles[compassHeroGradientStop2Dark.name] = gradientDark.stop2; - } - if (gradientDark.stop3) { - backgroundImageStyles[compassHeroGradientStop3Dark.name] = gradientDark.stop3; - } - } - - return ( -
-
{children}
-
- ); -}; +export const CompassHero: React.FunctionComponent = ({ className, children, ...props }) => ( +
+ {children} +
+); CompassHero.displayName = 'CompassHero'; diff --git a/packages/react-core/src/components/Compass/CompassMainHeader.tsx b/packages/react-core/src/components/Compass/CompassMainHeader.tsx index 409f7b2e454..cb3b6528d1d 100644 --- a/packages/react-core/src/components/Compass/CompassMainHeader.tsx +++ b/packages/react-core/src/components/Compass/CompassMainHeader.tsx @@ -3,7 +3,7 @@ import { CompassPanel } from './CompassPanel'; import styles from '@patternfly/react-styles/css/components/Compass/compass'; import { css } from '@patternfly/react-styles'; -interface CompassMainHeaderProps extends Omit, 'title'> { +export interface CompassMainHeaderProps extends Omit, 'title'> { /** Additional classes added to the main header */ className?: string; /** Styled title. If title or toolbar is provided, the children will be ignored. */ diff --git a/packages/react-core/src/components/Compass/CompassMessageBar.tsx b/packages/react-core/src/components/Compass/CompassMessageBar.tsx index 4e9a737aa37..257a9b422dc 100644 --- a/packages/react-core/src/components/Compass/CompassMessageBar.tsx +++ b/packages/react-core/src/components/Compass/CompassMessageBar.tsx @@ -1,7 +1,7 @@ import styles from '@patternfly/react-styles/css/components/Compass/compass'; import { css } from '@patternfly/react-styles'; -interface CompassMessageBarProps extends React.HTMLProps { +export interface CompassMessageBarProps extends React.HTMLProps { /** Content of the message bar. Typically a @patternfly/chatbot MessageBar component. */ children?: React.ReactNode; /** Additional classes added to the message bar */ diff --git a/packages/react-core/src/components/Compass/CompassPanel.tsx b/packages/react-core/src/components/Compass/CompassPanel.tsx index 6b8096a51e6..bb62112f237 100644 --- a/packages/react-core/src/components/Compass/CompassPanel.tsx +++ b/packages/react-core/src/components/Compass/CompassPanel.tsx @@ -1,7 +1,7 @@ import styles from '@patternfly/react-styles/css/components/Compass/compass'; import { css } from '@patternfly/react-styles'; -interface CompassPanelProps extends React.HTMLProps { +export interface CompassPanelProps extends React.HTMLProps { /** Content of the panel. */ children: React.ReactNode; /** Additional classes added to the panel. */ diff --git a/packages/react-core/src/components/Compass/__tests__/CompassHero.test.tsx b/packages/react-core/src/components/Compass/__tests__/CompassHero.test.tsx index f68ed214b79..c46f8605e73 100644 --- a/packages/react-core/src/components/Compass/__tests__/CompassHero.test.tsx +++ b/packages/react-core/src/components/Compass/__tests__/CompassHero.test.tsx @@ -16,135 +16,23 @@ test('Renders with children', () => { expect(screen.getByText('Test content')).toBeVisible(); }); -test('Renders with custom class name when className prop is provided', () => { - render(Test); - expect(screen.getByText('Test').parentElement).toHaveClass('custom-class'); -}); - -test(`Renders with default ${styles.compassPanel} and ${styles.compassHero} classes on the hero and ${styles.compassHeroBody} class on the hero body`, () => { +test(`Renders with ${styles.compass}__hero class by defaulty`, () => { render(Test); - const heroBodyElement = screen.getByText('Test'); - expect(heroBodyElement).toHaveClass(styles.compassHeroBody); - - const heroElement = heroBodyElement.parentElement; - expect(heroElement).toHaveClass(styles.compassPanel); - expect(heroElement).toHaveClass(styles.compassHero); -}); - -test('Renders with light background image style when backgroundSrcLight is provided', () => { - const backgroundSrc = 'light-bg.jpg'; - render(Test); - expect(screen.getByText('Test').parentElement).toHaveStyle( - `--pf-v6-c-compass__hero--BackgroundImage--light: url(${backgroundSrc})` - ); -}); - -test('Renders with dark background image style when backgroundSrcDark is provided', () => { - const backgroundSrc = 'dark-bg.jpg'; - render(Test); - expect(screen.getByText('Test').parentElement).toHaveStyle( - `--pf-v6-c-compass__hero--BackgroundImage--dark: url(${backgroundSrc})` - ); -}); - -test('Renders with both light and dark background image styles when both are provided', () => { - const lightSrc = 'light-bg.jpg'; - const darkSrc = 'dark-bg.jpg'; - render( - - Test - - ); - const heroElement = screen.getByText('Test').parentElement; - expect(heroElement).toHaveStyle(`--pf-v6-c-compass__hero--BackgroundImage--light: url(${lightSrc})`); - expect(heroElement).toHaveStyle(`--pf-v6-c-compass__hero--BackgroundImage--dark: url(${darkSrc})`); -}); - -test('Renders with light gradient styles when gradientLight is provided', () => { - const gradient = { - stop1: '#ff0000', - stop2: '#00ff00', - stop3: '#0000ff' - }; - render(Test); - const heroElement = screen.getByText('Test').parentElement; - expect(heroElement).toHaveStyle(`--pf-v6-c-compass__hero--gradient--stop-1--light: ${gradient.stop1}`); - expect(heroElement).toHaveStyle(`--pf-v6-c-compass__hero--gradient--stop-2--light: ${gradient.stop2}`); - expect(heroElement).toHaveStyle(`--pf-v6-c-compass__hero--gradient--stop-3--light: ${gradient.stop3}`); -}); -test('Renders with dark gradient styles when gradientDark is provided', () => { - const gradient = { - stop1: '#ff0000', - stop2: '#00ff00', - stop3: '#0000ff' - }; - render(Test); - const heroElement = screen.getByText('Test').parentElement; - expect(heroElement).toHaveStyle(`--pf-v6-c-compass__hero--gradient--stop-1--dark: ${gradient.stop1}`); - expect(heroElement).toHaveStyle(`--pf-v6-c-compass__hero--gradient--stop-2--dark: ${gradient.stop2}`); - expect(heroElement).toHaveStyle(`--pf-v6-c-compass__hero--gradient--stop-3--dark: ${gradient.stop3}`); -}); - -test('Renders with both light and dark gradient styles when both are provided', () => { - const lightGradient = { - stop1: '#ff0000', - stop2: '#00ff00', - stop3: '#0000ff' - }; - const darkGradient = { - stop1: '#000000', - stop2: '#ffffff', - stop3: '#808080' - }; - render( - - Test - - ); - const heroElement = screen.getByText('Test').parentElement; - expect(heroElement).toHaveStyle(`--pf-v6-c-compass__hero--gradient--stop-1--light: ${lightGradient.stop1}`); - expect(heroElement).toHaveStyle(`--pf-v6-c-compass__hero--gradient--stop-1--dark: ${darkGradient.stop1}`); + expect(screen.getByText('Test')).toHaveClass(`${styles.compass}__hero`, { exact: true }); }); -test('Renders with both background images and gradient styles when both are provided', () => { - const lightSrc = 'light-bg.jpg'; - const darkSrc = 'dark-bg.jpg'; - const lightGradient = { stop1: '#ff0000' }; - const darkGradient = { stop1: '#000000' }; - - render( - - Test - - ); - const heroElement = screen.getByText('Test').parentElement; - expect(heroElement).toHaveStyle(`--pf-v6-c-compass__hero--BackgroundImage--light: url(${lightSrc})`); - expect(heroElement).toHaveStyle(`--pf-v6-c-compass__hero--BackgroundImage--dark: url(${darkSrc})`); - expect(heroElement).toHaveStyle(`--pf-v6-c-compass__hero--gradient--stop-1--light: ${lightGradient.stop1}`); - expect(heroElement).toHaveStyle(`--pf-v6-c-compass__hero--gradient--stop-1--dark: ${darkGradient.stop1}`); +test('Renders with custom class name when className prop is provided', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('custom-class'); }); test('Renders with additional props spread to the component', () => { render(Test); - expect(screen.getByText('Test').parentElement).toHaveAccessibleName('Test label'); + expect(screen.getByText('Test')).toHaveAccessibleName('Test label'); }); test('Matches the snapshot', () => { - const { asFragment } = render( - -
Hero content
-
- ); + const { asFragment } = render(Hero content); expect(asFragment()).toMatchSnapshot(); }); diff --git a/packages/react-core/src/components/Compass/__tests__/__snapshots__/CompassHero.test.tsx.snap b/packages/react-core/src/components/Compass/__tests__/__snapshots__/CompassHero.test.tsx.snap index f130da9f4dc..da16b2c6089 100644 --- a/packages/react-core/src/components/Compass/__tests__/__snapshots__/CompassHero.test.tsx.snap +++ b/packages/react-core/src/components/Compass/__tests__/__snapshots__/CompassHero.test.tsx.snap @@ -3,16 +3,9 @@ exports[`Matches the snapshot 1`] = `
-
-
- Hero content -
-
+ Hero content
`; diff --git a/packages/react-core/src/components/Compass/examples/CompassDemo.tsx b/packages/react-core/src/components/Compass/examples/CompassDemo.tsx index 735cbdf0e3f..f2c08e72180 100644 --- a/packages/react-core/src/components/Compass/examples/CompassDemo.tsx +++ b/packages/react-core/src/components/Compass/examples/CompassDemo.tsx @@ -7,6 +7,7 @@ import { CompassMainHeader, CompassPanel, CompassMessageBar, + Hero, Tabs, TabsComponent, Tab, @@ -119,8 +120,8 @@ export const CompassBasic: React.FunctionComponent = () => { const sidebarStartContent = sidebarContent; const mainContent = ( <> - -
Hero
+ + Hero Content title} /> diff --git a/packages/react-core/src/components/Hero/Hero.tsx b/packages/react-core/src/components/Hero/Hero.tsx new file mode 100644 index 00000000000..feec306183e --- /dev/null +++ b/packages/react-core/src/components/Hero/Hero.tsx @@ -0,0 +1,102 @@ +import styles from '@patternfly/react-styles/css/components/Hero/hero'; +import { css } from '@patternfly/react-styles'; +import heroBackgroundImageLight from '@patternfly/react-tokens/dist/esm/c_hero_BackgroundImage_light'; +import heroBackgroundImageDark from '@patternfly/react-tokens/dist/esm/c_hero_BackgroundImage_dark'; +import heroGradientStop1Light from '@patternfly/react-tokens/dist/esm/c_hero_gradient_stop_1_light'; +import heroGradientStop2Light from '@patternfly/react-tokens/dist/esm/c_hero_gradient_stop_2_light'; +import heroGradientStop3Light from '@patternfly/react-tokens/dist/esm/c_hero_gradient_stop_3_light'; +import heroGradientStop1Dark from '@patternfly/react-tokens/dist/esm/c_hero_gradient_stop_1_dark'; +import heroGradientStop2Dark from '@patternfly/react-tokens/dist/esm/c_hero_gradient_stop_2_dark'; +import heroGradientStop3Dark from '@patternfly/react-tokens/dist/esm/c_hero_gradient_stop_3_dark'; +import heroBodyWidth from '@patternfly/react-tokens/dist/esm/c_hero__body_Width'; +import heroBodyMaxWidth from '@patternfly/react-tokens/dist/esm/c_hero__body_MaxWidth'; + +/** The main Hero component that allows adjusting of its background images and gradients in different color modes (such as light and dark). */ + +export interface HeroProps extends Omit, 'content'> { + /** Content of the hero */ + children?: React.ReactNode; + /** Additional classes added to the hero */ + className?: string; + /** Light theme background image path of the hero */ + backgroundSrcLight?: string; + /** Dark theme background image path of the hero */ + backgroundSrcDark?: string; + /** Light theme gradient of the hero, taking any valid CSS color values for each stop property. */ + gradientLight?: { + stop1?: string; + stop2?: string; + stop3?: string; + }; + /** Dark theme gradient of the hero, taking any valid CSS color values for each stop property. */ + gradientDark?: { + stop1?: string; + stop2?: string; + stop3?: string; + }; + /** Flag indicating whether glass styles are removed from the hero when a glass theme is applied. */ + hasNoGlass?: boolean; + /** Modifies the width of the hero body. */ + bodyWidth?: string; + /** Modifies the max-width of the hero body. */ + bodyMaxWidth?: string; +} + +export const Hero: React.FunctionComponent = ({ + className, + children, + backgroundSrcLight, + backgroundSrcDark, + gradientLight, + gradientDark, + hasNoGlass = false, + bodyWidth, + bodyMaxWidth, + ...props +}) => { + const customStyles: { [key: string]: string } = {}; + if (backgroundSrcLight) { + customStyles[heroBackgroundImageLight.name] = `url(${backgroundSrcLight})`; + } + if (backgroundSrcDark) { + customStyles[heroBackgroundImageDark.name] = `url(${backgroundSrcDark})`; + } + + if (gradientLight?.stop1) { + customStyles[heroGradientStop1Light.name] = gradientLight.stop1; + } + if (gradientLight?.stop2) { + customStyles[heroGradientStop2Light.name] = gradientLight.stop2; + } + if (gradientLight?.stop3) { + customStyles[heroGradientStop3Light.name] = gradientLight.stop3; + } + if (gradientDark?.stop1) { + customStyles[heroGradientStop1Dark.name] = gradientDark.stop1; + } + if (gradientDark?.stop2) { + customStyles[heroGradientStop2Dark.name] = gradientDark.stop2; + } + if (gradientDark?.stop3) { + customStyles[heroGradientStop3Dark.name] = gradientDark.stop3; + } + + if (bodyWidth) { + customStyles[heroBodyWidth.name] = bodyWidth; + } + if (bodyMaxWidth) { + customStyles[heroBodyMaxWidth.name] = bodyMaxWidth; + } + + return ( +
+
{children}
+
+ ); +}; + +Hero.displayName = 'Hero'; diff --git a/packages/react-core/src/components/Hero/__tests__/Hero.test.tsx b/packages/react-core/src/components/Hero/__tests__/Hero.test.tsx new file mode 100644 index 00000000000..ee290be3aa8 --- /dev/null +++ b/packages/react-core/src/components/Hero/__tests__/Hero.test.tsx @@ -0,0 +1,175 @@ +import { render, screen } from '@testing-library/react'; +import { Hero } from '../Hero'; +import styles from '@patternfly/react-styles/css/components/Hero/hero'; + +test('Renders without children', () => { + render( +
+ +
+ ); + expect(screen.getByTestId('test-hero').firstChild).toBeVisible(); +}); + +test('Renders with children', () => { + render(Test content); + expect(screen.getByText('Test content')).toBeVisible(); +}); + +test(`Renders with ${styles.hero} class on wrapper by defaulty`, () => { + render(Test); + + expect(screen.getByText('Test').parentElement).toHaveClass(`${styles.hero}`, { exact: true }); +}); + +test('Renders with custom class name on wrapper when className prop is provided', () => { + render(Test); + expect(screen.getByText('Test').parentElement).toHaveClass('custom-class'); +}); + +test(`Renders with class ${styles.heroBody} on content element`, () => { + render(Test); + + expect(screen.getByText('Test')).toHaveClass(`${styles.heroBody}`, { exact: true }); +}); + +test('Renders with additional props spread to the wrapper component', () => { + render(Test); + expect(screen.getByText('Test').parentElement).toHaveAttribute('id', 'custom-id'); +}); + +test('Renders with light background image style when backgroundSrcLight is provided', () => { + const backgroundSrc = 'light-bg.jpg'; + render(Test); + expect(screen.getByText('Test').parentElement).toHaveStyle( + `--pf-v6-c-hero--BackgroundImage--light: url(${backgroundSrc})` + ); +}); + +test('Renders with dark background image style when backgroundSrcDark is provided', () => { + const backgroundSrc = 'dark-bg.jpg'; + render(Test); + expect(screen.getByText('Test').parentElement).toHaveStyle( + `--pf-v6-c-hero--BackgroundImage--dark: url(${backgroundSrc})` + ); +}); + +test('Renders with both light and dark background image styles when both are provided', () => { + const lightSrc = 'light-bg.jpg'; + const darkSrc = 'dark-bg.jpg'; + render( + + Test + + ); + const heroElement = screen.getByText('Test').parentElement; + expect(heroElement).toHaveStyle(`--pf-v6-c-hero--BackgroundImage--light: url(${lightSrc})`); + expect(heroElement).toHaveStyle(`--pf-v6-c-hero--BackgroundImage--dark: url(${darkSrc})`); +}); + +test('Renders with light gradient styles when gradientLight is provided', () => { + const gradient = { + stop1: '#ff0000', + stop2: '#00ff00', + stop3: '#0000ff' + }; + render(Test); + const heroElement = screen.getByText('Test').parentElement; + expect(heroElement).toHaveStyle(`--pf-v6-c-hero--gradient--stop-1--light: ${gradient.stop1}`); + expect(heroElement).toHaveStyle(`--pf-v6-c-hero--gradient--stop-2--light: ${gradient.stop2}`); + expect(heroElement).toHaveStyle(`--pf-v6-c-hero--gradient--stop-3--light: ${gradient.stop3}`); +}); + +test('Renders with dark gradient styles when gradientDark is provided', () => { + const gradient = { + stop1: '#ff0000', + stop2: '#00ff00', + stop3: '#0000ff' + }; + render(Test); + const heroElement = screen.getByText('Test').parentElement; + expect(heroElement).toHaveStyle(`--pf-v6-c-hero--gradient--stop-1--dark: ${gradient.stop1}`); + expect(heroElement).toHaveStyle(`--pf-v6-c-hero--gradient--stop-2--dark: ${gradient.stop2}`); + expect(heroElement).toHaveStyle(`--pf-v6-c-hero--gradient--stop-3--dark: ${gradient.stop3}`); +}); + +test('Renders with both light and dark gradient styles when both are provided', () => { + const lightGradient = { + stop1: '#ff0000', + stop2: '#00ff00', + stop3: '#0000ff' + }; + const darkGradient = { + stop1: '#000000', + stop2: '#ffffff', + stop3: '#808080' + }; + render( + + Test + + ); + const heroElement = screen.getByText('Test').parentElement; + expect(heroElement).toHaveStyle(`--pf-v6-c-hero--gradient--stop-1--light: ${lightGradient.stop1}`); + expect(heroElement).toHaveStyle(`--pf-v6-c-hero--gradient--stop-1--dark: ${darkGradient.stop1}`); +}); + +test('Renders with both background images and gradient styles when both are provided', () => { + const lightSrc = 'light-bg.jpg'; + const darkSrc = 'dark-bg.jpg'; + const lightGradient = { stop1: '#ff0000' }; + const darkGradient = { stop1: '#000000' }; + + render( + + Test + + ); + const heroElement = screen.getByText('Test').parentElement; + expect(heroElement).toHaveStyle(`--pf-v6-c-hero--BackgroundImage--light: url(${lightSrc})`); + expect(heroElement).toHaveStyle(`--pf-v6-c-hero--BackgroundImage--dark: url(${darkSrc})`); + expect(heroElement).toHaveStyle(`--pf-v6-c-hero--gradient--stop-1--light: ${lightGradient.stop1}`); + expect(heroElement).toHaveStyle(`--pf-v6-c-hero--gradient--stop-1--dark: ${darkGradient.stop1}`); +}); + +test('Renders with inline width style when bodyWidth is passed', () => { + const bodyWidth = '100px'; + + render(Test); + const heroElement = screen.getByText('Test').parentElement; + expect(heroElement).toHaveStyle(`--pf-v6-c-hero__body--Width: ${bodyWidth}`); +}); + +test('Renders with inline max-width style when bodyMaxWidth is passed', () => { + const bodyMaxWidth = '100px'; + + render(Test); + const heroElement = screen.getByText('Test').parentElement; + expect(heroElement).toHaveStyle(`--pf-v6-c-hero__body--MaxWidth: ${bodyMaxWidth}`); +}); + +test('Matches the snapshot without backgroundSrc and gradient props', () => { + const { asFragment } = render(Hero content); + + expect(asFragment()).toMatchSnapshot(); +}); + +test('Matches the snapshot with backgroundSrc and gradient props', () => { + const { asFragment } = render( + + Hero content + + ); + + expect(asFragment()).toMatchSnapshot(); +}); diff --git a/packages/react-core/src/components/Hero/__tests__/__snapshots__/Hero.test.tsx.snap b/packages/react-core/src/components/Hero/__tests__/__snapshots__/Hero.test.tsx.snap new file mode 100644 index 00000000000..ad439bf2870 --- /dev/null +++ b/packages/react-core/src/components/Hero/__tests__/__snapshots__/Hero.test.tsx.snap @@ -0,0 +1,30 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Matches the snapshot with backgroundSrc and gradient props 1`] = ` + +
+
+ Hero content +
+
+
+`; + +exports[`Matches the snapshot without backgroundSrc and gradient props 1`] = ` + +
+
+ Hero content +
+
+
+`; diff --git a/packages/react-core/src/components/Hero/examples/Hero.md b/packages/react-core/src/components/Hero/examples/Hero.md new file mode 100644 index 00000000000..5539d1e0057 --- /dev/null +++ b/packages/react-core/src/components/Hero/examples/Hero.md @@ -0,0 +1,19 @@ +--- +id: Hero +section: components +cssPrefix: pf-v6-c-hero +beta: true +propComponents: ['Hero'] +--- + +## Examples + +### Basic + +If you need finer control over the placement of text content within the ``, such as when you omit a background image, adjust the `bodyWidth` and `bodyMaxWidth` properties. Be mindful of using these properties when a background image is still present and ensure there is sufficient contrast between text and any part of the image that it overlaps. + +When using `gradientLight` or `gradientDark` to apply gradient backgrounds, check the color contrast to ensure proper accessibility. + +```ts file="HeroBasic.tsx" + +``` diff --git a/packages/react-core/src/components/Hero/examples/HeroBasic.tsx b/packages/react-core/src/components/Hero/examples/HeroBasic.tsx new file mode 100644 index 00000000000..0f428d4edd4 --- /dev/null +++ b/packages/react-core/src/components/Hero/examples/HeroBasic.tsx @@ -0,0 +1,3 @@ +import { Hero } from '@patternfly/react-core'; + +export const HeroBasic: React.FunctionComponent = () => Basic hero content; diff --git a/packages/react-core/src/components/Hero/index.ts b/packages/react-core/src/components/Hero/index.ts new file mode 100644 index 00000000000..729bca95fb2 --- /dev/null +++ b/packages/react-core/src/components/Hero/index.ts @@ -0,0 +1 @@ +export * from './Hero'; diff --git a/packages/react-core/src/components/index.ts b/packages/react-core/src/components/index.ts index 75ee15d8669..9ba1b78ec46 100644 --- a/packages/react-core/src/components/index.ts +++ b/packages/react-core/src/components/index.ts @@ -32,6 +32,7 @@ export * from './FileUpload'; export * from './Form'; export * from './FormSelect'; export * from './HelperText'; +export * from './Hero'; export * from './Hint'; export * from './Icon'; export * from './InputGroup'; diff --git a/packages/react-docs/package.json b/packages/react-docs/package.json index 42d38b92727..a29e982f87b 100644 --- a/packages/react-docs/package.json +++ b/packages/react-docs/package.json @@ -23,7 +23,7 @@ "test:a11y": "patternfly-a11y --config patternfly-a11y.config" }, "dependencies": { - "@patternfly/patternfly": "6.5.0-prerelease.19", + "@patternfly/patternfly": "6.5.0-prerelease.21", "@patternfly/react-charts": "workspace:^", "@patternfly/react-code-editor": "workspace:^", "@patternfly/react-core": "workspace:^", diff --git a/packages/react-icons/package.json b/packages/react-icons/package.json index 3a8262e1e9d..2728cadc260 100644 --- a/packages/react-icons/package.json +++ b/packages/react-icons/package.json @@ -33,7 +33,7 @@ "@fortawesome/free-brands-svg-icons": "^5.15.4", "@fortawesome/free-regular-svg-icons": "^5.15.4", "@fortawesome/free-solid-svg-icons": "^5.15.4", - "@patternfly/patternfly": "6.5.0-prerelease.19", + "@patternfly/patternfly": "6.5.0-prerelease.21", "fs-extra": "^11.3.0", "tslib": "^2.8.1" }, diff --git a/packages/react-styles/package.json b/packages/react-styles/package.json index dcf24bcdcc5..d2342094cd0 100644 --- a/packages/react-styles/package.json +++ b/packages/react-styles/package.json @@ -19,7 +19,7 @@ "clean": "rimraf dist css" }, "devDependencies": { - "@patternfly/patternfly": "6.5.0-prerelease.19", + "@patternfly/patternfly": "6.5.0-prerelease.21", "change-case": "^5.4.4", "fs-extra": "^11.3.0" }, diff --git a/packages/react-tokens/package.json b/packages/react-tokens/package.json index 504ab80fe60..40653027c9a 100644 --- a/packages/react-tokens/package.json +++ b/packages/react-tokens/package.json @@ -30,7 +30,7 @@ }, "devDependencies": { "@adobe/css-tools": "^4.4.4", - "@patternfly/patternfly": "6.5.0-prerelease.19", + "@patternfly/patternfly": "6.5.0-prerelease.21", "fs-extra": "^11.3.0" } } diff --git a/yarn.lock b/yarn.lock index 5be9657a36d..abeb14925ba 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4516,10 +4516,10 @@ __metadata: languageName: node linkType: hard -"@patternfly/patternfly@npm:6.5.0-prerelease.19": - version: 6.5.0-prerelease.19 - resolution: "@patternfly/patternfly@npm:6.5.0-prerelease.19" - checksum: 10c0/581e18b078e146ad72553f8fb1177ffe84e7bfbeb5920f8e7ce7da22dd9c9334fee850cf7e8fe274a8dee72a9b1608aad5cbcc5679b52275970e2801669f56ab +"@patternfly/patternfly@npm:6.5.0-prerelease.21": + version: 6.5.0-prerelease.21 + resolution: "@patternfly/patternfly@npm:6.5.0-prerelease.21" + checksum: 10c0/2de6f81ae974c005d9d38041f1bb93732567aa37fdb5e56e8547a117b126c3649e2c5133d64eb956964cb19ccb28f39f881de41b98232dc2ee83f8f5e125bfaf languageName: node linkType: hard @@ -4617,7 +4617,7 @@ __metadata: version: 0.0.0-use.local resolution: "@patternfly/react-core@workspace:packages/react-core" dependencies: - "@patternfly/patternfly": "npm:6.5.0-prerelease.19" + "@patternfly/patternfly": "npm:6.5.0-prerelease.21" "@patternfly/react-icons": "workspace:^" "@patternfly/react-styles": "workspace:^" "@patternfly/react-tokens": "workspace:^" @@ -4638,7 +4638,7 @@ __metadata: resolution: "@patternfly/react-docs@workspace:packages/react-docs" dependencies: "@patternfly/documentation-framework": "npm:^6.28.9" - "@patternfly/patternfly": "npm:6.5.0-prerelease.19" + "@patternfly/patternfly": "npm:6.5.0-prerelease.21" "@patternfly/patternfly-a11y": "npm:5.1.0" "@patternfly/react-charts": "workspace:^" "@patternfly/react-code-editor": "workspace:^" @@ -4678,7 +4678,7 @@ __metadata: "@fortawesome/free-brands-svg-icons": "npm:^5.15.4" "@fortawesome/free-regular-svg-icons": "npm:^5.15.4" "@fortawesome/free-solid-svg-icons": "npm:^5.15.4" - "@patternfly/patternfly": "npm:6.5.0-prerelease.19" + "@patternfly/patternfly": "npm:6.5.0-prerelease.21" fs-extra: "npm:^11.3.0" tslib: "npm:^2.8.1" peerDependencies: @@ -4763,7 +4763,7 @@ __metadata: version: 0.0.0-use.local resolution: "@patternfly/react-styles@workspace:packages/react-styles" dependencies: - "@patternfly/patternfly": "npm:6.5.0-prerelease.19" + "@patternfly/patternfly": "npm:6.5.0-prerelease.21" change-case: "npm:^5.4.4" fs-extra: "npm:^11.3.0" languageName: unknown @@ -4805,7 +4805,7 @@ __metadata: resolution: "@patternfly/react-tokens@workspace:packages/react-tokens" dependencies: "@adobe/css-tools": "npm:^4.4.4" - "@patternfly/patternfly": "npm:6.5.0-prerelease.19" + "@patternfly/patternfly": "npm:6.5.0-prerelease.21" fs-extra: "npm:^11.3.0" languageName: unknown linkType: soft