From 7d7f3ef7312637843912ee81f4d1fd5324462b86 Mon Sep 17 00:00:00 2001 From: Titani Date: Tue, 31 Mar 2026 10:27:43 -0400 Subject: [PATCH 1/7] feat(Drawer): Added support for glass --- .../src/components/Drawer/Drawer.tsx | 3 ++ .../components/Drawer/DrawerPanelContent.tsx | 17 +++++++++- .../src/components/Drawer/DrawerSection.tsx | 9 +++++- .../__tests__/DrawerPanelContent.test.tsx | 32 ++++++++++++++++++- .../Drawer/__tests__/DrawerSection.test.tsx | 15 +++++++++ .../src/components/Drawer/examples/Drawer.md | 2 +- .../PrimaryDetailContentPadding.tsx | 4 +-- 7 files changed, 76 insertions(+), 6 deletions(-) create mode 100644 packages/react-core/src/components/Drawer/__tests__/DrawerSection.test.tsx diff --git a/packages/react-core/src/components/Drawer/Drawer.tsx b/packages/react-core/src/components/Drawer/Drawer.tsx index 3470426a6b8..eaa6c58dfcd 100644 --- a/packages/react-core/src/components/Drawer/Drawer.tsx +++ b/packages/react-core/src/components/Drawer/Drawer.tsx @@ -5,6 +5,9 @@ import { css } from '@patternfly/react-styles'; export enum DrawerColorVariant { default = 'default', secondary = 'secondary', + /** + * @deprecated `DrawerColorVariant.noBackground` is deprecated. Use the `isPlain` prop on `DrawerPanelContent` and the `DrawerSection`instead. + */ noBackground = 'no-background' } diff --git a/packages/react-core/src/components/Drawer/DrawerPanelContent.tsx b/packages/react-core/src/components/Drawer/DrawerPanelContent.tsx index 814390d3955..b1106f28c49 100644 --- a/packages/react-core/src/components/Drawer/DrawerPanelContent.tsx +++ b/packages/react-core/src/components/Drawer/DrawerPanelContent.tsx @@ -37,6 +37,12 @@ export interface DrawerPanelContentProps extends Omit void; /** The minimum size of a drawer. */ @@ -56,7 +62,10 @@ export interface DrawerPanelContentProps extends Omit { className?: string; /** Content to be rendered in the drawer section. */ children?: React.ReactNode; - /** Color variant of the background of the drawer Section */ + /** + * Color variant of the background of the drawer section. + * The `no-background` value is deprecated; use the `isPlain` prop instead. + */ colorVariant?: DrawerColorVariant | 'no-background' | 'default' | 'secondary'; + /** @beta Flag indicating that the drawer section should use plain styles. */ + isPlain?: boolean; } export const DrawerSection: React.FunctionComponent = ({ className = '', children, colorVariant = DrawerColorVariant.default, + isPlain = false, ...props }: DrawerSectionProps) => (
{ expect(screen.getByText('Drawer panel content')).toHaveClass(styles.drawerPanel, { exact: true }); }); -test(`Renders with class ${styles.modifiers.noBackground} when colorVariant="no-background"`, () => { +test(`Renders with class ${styles.modifiers.noBackground} when deprecated colorVariant="no-background" is used`, () => { render( Drawer panel content @@ -188,3 +188,33 @@ test(`Renders with class 'pf-m-no-glass' when hasNoGlass is true`, () => { expect(screen.getByText('Drawer panel content')).toHaveClass('pf-m-no-glass'); }); + +test(`Renders with class ${styles.modifiers.glass} when isGlass is true`, () => { + render( + + Drawer panel content + + ); + + expect(screen.getByText('Drawer panel content')).toHaveClass(styles.modifiers.glass); +}); + +test(`Renders with class ${styles.modifiers.plain} when isPlain is true`, () => { + render( + + Drawer panel content + + ); + + expect(screen.getByText('Drawer panel content')).toHaveClass(styles.modifiers.plain); +}); + +test(`Renders with class ${styles.modifiers.noPlain} when isNoPlainOnGlass is true`, () => { + render( + + Drawer panel content + + ); + + expect(screen.getByText('Drawer panel content')).toHaveClass(styles.modifiers.noPlain); +}); diff --git a/packages/react-core/src/components/Drawer/__tests__/DrawerSection.test.tsx b/packages/react-core/src/components/Drawer/__tests__/DrawerSection.test.tsx new file mode 100644 index 00000000000..849cf457ddf --- /dev/null +++ b/packages/react-core/src/components/Drawer/__tests__/DrawerSection.test.tsx @@ -0,0 +1,15 @@ +import { render, screen } from '@testing-library/react'; +import { DrawerSection } from '../DrawerSection'; +import styles from '@patternfly/react-styles/css/components/Drawer/drawer'; + +test(`Renders with only class ${styles.drawerSection} by default`, () => { + render(Section content); + + expect(screen.getByText('Section content')).toHaveClass(styles.drawerSection, { exact: true }); +}); + +test(`Renders with class ${styles.modifiers.plain} when isPlain is true`, () => { + render(Section content); + + expect(screen.getByText('Section content')).toHaveClass(styles.modifiers.plain); +}); diff --git a/packages/react-core/src/components/Drawer/examples/Drawer.md b/packages/react-core/src/components/Drawer/examples/Drawer.md index 544bc08a2ba..22d79215fe6 100644 --- a/packages/react-core/src/components/Drawer/examples/Drawer.md +++ b/packages/react-core/src/components/Drawer/examples/Drawer.md @@ -13,7 +13,7 @@ propComponents: DrawerCloseButton, DrawerPanelDescription, DrawerPanelBody, - DrawerPanelFocusTrapObject + DrawerPanelFocusTrapObject, ] section: components --- diff --git a/packages/react-core/src/demos/examples/PrimaryDetail/PrimaryDetailContentPadding.tsx b/packages/react-core/src/demos/examples/PrimaryDetail/PrimaryDetailContentPadding.tsx index c19ed8ca8ca..cd5f84f2bae 100644 --- a/packages/react-core/src/demos/examples/PrimaryDetail/PrimaryDetailContentPadding.tsx +++ b/packages/react-core/src/demos/examples/PrimaryDetail/PrimaryDetailContentPadding.tsx @@ -178,7 +178,7 @@ export const PrimaryDetailContentPadding: React.FunctionComponent = () => { ); const panelContent = ( - + node-{drawerPanelBodyContent} @@ -429,7 +429,7 @@ export const PrimaryDetailContentPadding: React.FunctionComponent = () => { <Divider component="div" /> <PageSection padding={{ default: 'noPadding' }} aria-label="Drawer content section"> <Drawer isExpanded={isDrawerExpanded}> - <DrawerContent panelContent={panelContent} colorVariant="no-background"> + <DrawerContent panelContent={panelContent}> <DrawerContentBody hasPadding>{drawerContent}</DrawerContentBody> </DrawerContent> </Drawer> From cce01d1ba2b0f04fcdea94919e2acd02b59238e3 Mon Sep 17 00:00:00 2001 From: Titani <tlabaj@redhat.com> Date: Mon, 6 Apr 2026 16:22:56 -0400 Subject: [PATCH 2/7] update test and logic --- .../components/Drawer/DrawerPanelContent.tsx | 2 +- .../__tests__/DrawerPanelContent.test.tsx | 4 +- .../cypress/integration/drawer.spec.ts | 55 +++++++++++++++++++ .../demos/DrawerDemo/DrawerDemo.tsx | 19 +++++++ 4 files changed, 77 insertions(+), 3 deletions(-) diff --git a/packages/react-core/src/components/Drawer/DrawerPanelContent.tsx b/packages/react-core/src/components/Drawer/DrawerPanelContent.tsx index b1106f28c49..83e03eddc54 100644 --- a/packages/react-core/src/components/Drawer/DrawerPanelContent.tsx +++ b/packages/react-core/src/components/Drawer/DrawerPanelContent.tsx @@ -382,7 +382,7 @@ export const DrawerPanelContent: React.FunctionComponent<DrawerPanelContentProps hasNoGlass && 'pf-m-no-glass', isGlass && styles.modifiers.glass, isPlain && styles.modifiers.plain, - isNoPlainOnGlass && styles.modifiers.noPlain, + isNoPlainOnGlass && styles.modifiers.noPlainOnGlass, hasNoBorder && styles.modifiers.noBorder, formatBreakpointMods(widths, styles), colorVariant === DrawerColorVariant.noBackground && styles.modifiers.noBackground, diff --git a/packages/react-core/src/components/Drawer/__tests__/DrawerPanelContent.test.tsx b/packages/react-core/src/components/Drawer/__tests__/DrawerPanelContent.test.tsx index b244cd7bb7e..ba0b0cec4c4 100644 --- a/packages/react-core/src/components/Drawer/__tests__/DrawerPanelContent.test.tsx +++ b/packages/react-core/src/components/Drawer/__tests__/DrawerPanelContent.test.tsx @@ -209,12 +209,12 @@ test(`Renders with class ${styles.modifiers.plain} when isPlain is true`, () => expect(screen.getByText('Drawer panel content')).toHaveClass(styles.modifiers.plain); }); -test(`Renders with class ${styles.modifiers.noPlain} when isNoPlainOnGlass is true`, () => { +test(`Renders with class ${styles.modifiers.noPlainOnGlass} when isNoPlainOnGlass is true`, () => { render( <Drawer isExpanded> <DrawerPanelContent isNoPlainOnGlass>Drawer panel content</DrawerPanelContent> </Drawer> ); - expect(screen.getByText('Drawer panel content')).toHaveClass(styles.modifiers.noPlain); + expect(screen.getByText('Drawer panel content')).toHaveClass(styles.modifiers.noPlainOnGlass); }); diff --git a/packages/react-integration/cypress/integration/drawer.spec.ts b/packages/react-integration/cypress/integration/drawer.spec.ts index 02a06d3fb9d..0a4bd2328ca 100644 --- a/packages/react-integration/cypress/integration/drawer.spec.ts +++ b/packages/react-integration/cypress/integration/drawer.spec.ts @@ -1,8 +1,63 @@ describe('Drawer Demo Test', () => { + afterEach(() => { + cy.document().then((doc) => { + doc.documentElement.classList.remove('pf-v6-theme-glass'); + }); + }); + it('Navigate to the drawer demo', () => { cy.visit('http://localhost:3000/drawer-demo-nav-link'); }); + // Known PatternFly CSS bug: when `pf-v6-theme-glass`, `pf-m-glass` (isGlass), and `pf-m-plain` are all active, + // `pf-m-no-plain-on-glass` does not take effect — plain-under-glass wins and no-plain-on-glass cannot restore + // the intended glass panel treatment. This test asserts the corrected outcome (semi-transparent background) + // and fails until Core CSS fixes selector/specificity for that combination. + it('glass theme + plain + glass: no-plain-on-glass should yield semi-transparent panel background (fails until CSS fix)', () => { + cy.document().then((doc) => { + doc.documentElement.classList.add('pf-v6-theme-glass'); + }); + cy.get('html').should('have.class', 'pf-v6-theme-glass'); + + cy.get('#drawer-panel-glass-plain-combo.pf-v6-c-drawer__panel') + .should('be.visible') + .should('have.class', 'pf-m-glass') + .and('have.class', 'pf-m-plain') + .and('have.class', 'pf-m-no-plain-on-glass'); + + cy.get('#drawer-panel-glass-plain-combo').within(() => { + cy.contains('Glass theme plain / no-plain-on-glass combo'); + }); + + // When the bug is fixed, no-plain-on-glass should override plain-under-glass and surface a non-opaque background. + cy.get('#drawer-panel-glass-plain-combo').should(($el) => { + const bg = window.getComputedStyle($el[0]).backgroundColor; + + const rgbaAlpha = (color: string): number | undefined => { + if (color === 'transparent') { + return 0; + } + if (!color.startsWith('rgba(') || !color.endsWith(')')) { + return undefined; + } + const inner = color.slice('rgba('.length, -1); + const parts = inner.split(',').map((p) => p.trim()); + if (parts.length !== 4) { + return undefined; + } + return parseFloat(parts[3]); + }; + + const alpha = rgbaAlpha(bg); + const hasSemiTransparentBackground = alpha !== undefined && alpha < 1; + if (!hasSemiTransparentBackground) { + throw new Error( + `expected no-plain-on-glass to win over plain+glass under theme (semi-transparent background, alpha < 1); got backgroundColor=${bg}` + ); + } + }); + }); + it('Verify focus is automatically handled with focus trap enabled', () => { cy.get('#toggleFocusTrapButton').click(); cy.get('#focusTrap-panelContent .pf-v6-c-button.pf-m-plain').should('have.focus'); diff --git a/packages/react-integration/demo-app-ts/src/components/demos/DrawerDemo/DrawerDemo.tsx b/packages/react-integration/demo-app-ts/src/components/demos/DrawerDemo/DrawerDemo.tsx index 6286a8a2330..5d85bc91118 100644 --- a/packages/react-integration/demo-app-ts/src/components/demos/DrawerDemo/DrawerDemo.tsx +++ b/packages/react-integration/demo-app-ts/src/components/demos/DrawerDemo/DrawerDemo.tsx @@ -118,6 +118,18 @@ export class DrawerDemo extends Component<DrawerProps, DrawerDemoState> { const drawerContent = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus pretium est a porttitor vehicula. Quisque vel commodo urna. Morbi mattis rutrum ante, id vehicula ex accumsan ut. Morbi viverra, eros vel porttitor facilisis, eros purus aliquet erat,nec lobortis felis elit pulvinar sem. Vivamus vulputate, risus eget commodo eleifend, eros nibh porta quam, vitae lacinia leo libero at magna. Maecenas aliquam sagittis orci, et posuere nisi ultrices sit amet. Aliquam ex odio, malesuada sed posuere quis, pellentesque at mauris. Phasellus venenatis massa ex, eget pulvinar libero auctor pretium. Aliquam erat volutpat. Duis euismod justo in quam ullamcorper, in commodo massa vulputate.'; + /** + * Repro for Core CSS: with glass theme (`pf-v6-theme-glass`, applied in Cypress on `html`), `isGlass` (pf-m-glass), + * and `isPlain` (pf-m-plain), `pf-m-no-plain-on-glass` may not apply — see drawer Cypress test. + */ + const glassThemePlainComboPanelContent = ( + <DrawerPanelContent id="drawer-panel-glass-plain-combo" isPlain isNoPlainOnGlass isGlass> + <DrawerHead> + <span>Glass theme plain / no-plain-on-glass combo</span> + </DrawerHead> + </DrawerPanelContent> + ); + return ( <> <Button id="toggleButton" onClick={this.onClick}> @@ -151,6 +163,13 @@ export class DrawerDemo extends Component<DrawerProps, DrawerDemoState> { <DrawerContentBody>{drawerContent}</DrawerContentBody> </DrawerContent> </Drawer> + <div id="drawer-glass-plain-combo-container"> + <Drawer id="drawer-glass-plain-combo" isExpanded style={{ minHeight: '120px', height: '120px' }}> + <DrawerContent colorVariant={DrawerColorVariant.default} panelContent={glassThemePlainComboPanelContent}> + <DrawerContentBody>Glass theme + isPlain + isNoPlainOnGlass + isGlass demo</DrawerContentBody> + </DrawerContent> + </Drawer> + </div> </> ); } From ac3baa8a9a71ec6465a22543e10124d0da18069b Mon Sep 17 00:00:00 2001 From: Titani <tlabaj@redhat.com> Date: Mon, 13 Apr 2026 17:36:16 -0400 Subject: [PATCH 3/7] fix test --- .../cypress/integration/drawer.spec.ts | 57 ++++++++++++------- .../demos/DrawerDemo/DrawerDemo.tsx | 23 ++++++-- 2 files changed, 55 insertions(+), 25 deletions(-) diff --git a/packages/react-integration/cypress/integration/drawer.spec.ts b/packages/react-integration/cypress/integration/drawer.spec.ts index 0a4bd2328ca..5ab5a595626 100644 --- a/packages/react-integration/cypress/integration/drawer.spec.ts +++ b/packages/react-integration/cypress/integration/drawer.spec.ts @@ -9,31 +9,34 @@ describe('Drawer Demo Test', () => { cy.visit('http://localhost:3000/drawer-demo-nav-link'); }); - // Known PatternFly CSS bug: when `pf-v6-theme-glass`, `pf-m-glass` (isGlass), and `pf-m-plain` are all active, - // `pf-m-no-plain-on-glass` does not take effect — plain-under-glass wins and no-plain-on-glass cannot restore - // the intended glass panel treatment. This test asserts the corrected outcome (semi-transparent background) - // and fails until Core CSS fixes selector/specificity for that combination. - it('glass theme + plain + glass: no-plain-on-glass should yield semi-transparent panel background (fails until CSS fix)', () => { + it('glass theme + plain + glass: panel shows glass treatment (transparent bg and/or backdrop-filter)', () => { + // Self-contained: do not rely on test order; other specs leave the page in various states. + cy.visit('http://localhost:3000/drawer-demo-nav-link'); + cy.viewport(1280, 800); + cy.document().then((doc) => { doc.documentElement.classList.add('pf-v6-theme-glass'); }); cy.get('html').should('have.class', 'pf-v6-theme-glass'); - cy.get('#drawer-panel-glass-plain-combo.pf-v6-c-drawer__panel') - .should('be.visible') - .should('have.class', 'pf-m-glass') - .and('have.class', 'pf-m-plain') - .and('have.class', 'pf-m-no-plain-on-glass'); + cy.get('#drawer-glass-plain-combo.pf-v6-c-drawer').should('have.class', 'pf-m-expanded'); - cy.get('#drawer-panel-glass-plain-combo').within(() => { - cy.contains('Glass theme plain / no-plain-on-glass combo'); + cy.get('[data-testid="drawer-glass-plain-panel"]').should(($el) => { + expect($el, 'glass plain combo panel').to.have.length(1); + expect($el).to.not.have.attr('hidden'); + expect($el).to.not.have.attr('inert'); + expect($el).to.have.class('pf-m-glass'); + expect($el).to.have.class('pf-m-plain'); + expect($el).to.have.class('pf-m-no-plain-on-glass'); + expect($el).to.contain.text('Glass theme plain / no-plain-on-glass combo'); }); - // When the bug is fixed, no-plain-on-glass should override plain-under-glass and surface a non-opaque background. - cy.get('#drawer-panel-glass-plain-combo').should(($el) => { - const bg = window.getComputedStyle($el[0]).backgroundColor; + cy.get('[data-testid="drawer-glass-plain-panel"]').should(($el) => { + const style = window.getComputedStyle($el[0]); + const bg = style.backgroundColor; + const backdrop = style.backdropFilter; - const rgbaAlpha = (color: string): number | undefined => { + const rgbaCommaAlpha = (color: string): number | undefined => { if (color === 'transparent') { return 0; } @@ -48,11 +51,27 @@ describe('Drawer Demo Test', () => { return parseFloat(parts[3]); }; - const alpha = rgbaAlpha(bg); + // e.g. rgb(255 255 255 / 0.08) from getComputedStyle in some engines + const rgbSlashAlpha = (color: string): number | undefined => { + if (!color.startsWith('rgb(')) { + return undefined; + } + const slash = color.indexOf('/'); + const close = color.lastIndexOf(')'); + if (slash === -1 || close === -1 || slash >= close) { + return undefined; + } + const a = parseFloat(color.slice(slash + 1, close).trim()); + return Number.isNaN(a) ? undefined : a; + }; + + const alpha = rgbaCommaAlpha(bg) ?? rgbSlashAlpha(bg); const hasSemiTransparentBackground = alpha !== undefined && alpha < 1; - if (!hasSemiTransparentBackground) { + const hasBackdropBlur = Boolean(backdrop && backdrop !== 'none'); + + if (!hasSemiTransparentBackground && !hasBackdropBlur) { throw new Error( - `expected no-plain-on-glass to win over plain+glass under theme (semi-transparent background, alpha < 1); got backgroundColor=${bg}` + `expected glass panel (semi-transparent background or backdrop-filter); got backgroundColor=${bg}, backdropFilter=${backdrop || ''}` ); } }); diff --git a/packages/react-integration/demo-app-ts/src/components/demos/DrawerDemo/DrawerDemo.tsx b/packages/react-integration/demo-app-ts/src/components/demos/DrawerDemo/DrawerDemo.tsx index 5d85bc91118..1af229d0ee6 100644 --- a/packages/react-integration/demo-app-ts/src/components/demos/DrawerDemo/DrawerDemo.tsx +++ b/packages/react-integration/demo-app-ts/src/components/demos/DrawerDemo/DrawerDemo.tsx @@ -118,12 +118,14 @@ export class DrawerDemo extends Component<DrawerProps, DrawerDemoState> { const drawerContent = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus pretium est a porttitor vehicula. Quisque vel commodo urna. Morbi mattis rutrum ante, id vehicula ex accumsan ut. Morbi viverra, eros vel porttitor facilisis, eros purus aliquet erat,nec lobortis felis elit pulvinar sem. Vivamus vulputate, risus eget commodo eleifend, eros nibh porta quam, vitae lacinia leo libero at magna. Maecenas aliquam sagittis orci, et posuere nisi ultrices sit amet. Aliquam ex odio, malesuada sed posuere quis, pellentesque at mauris. Phasellus venenatis massa ex, eget pulvinar libero auctor pretium. Aliquam erat volutpat. Duis euismod justo in quam ullamcorper, in commodo massa vulputate.'; - /** - * Repro for Core CSS: with glass theme (`pf-v6-theme-glass`, applied in Cypress on `html`), `isGlass` (pf-m-glass), - * and `isPlain` (pf-m-plain), `pf-m-no-plain-on-glass` may not apply — see drawer Cypress test. - */ const glassThemePlainComboPanelContent = ( - <DrawerPanelContent id="drawer-panel-glass-plain-combo" isPlain isNoPlainOnGlass isGlass> + <DrawerPanelContent + id="drawer-panel-glass-plain-combo" + data-testid="drawer-glass-plain-panel" + isPlain + isNoPlainOnGlass + isGlass + > <DrawerHead> <span>Glass theme plain / no-plain-on-glass combo</span> </DrawerHead> @@ -164,7 +166,16 @@ export class DrawerDemo extends Component<DrawerProps, DrawerDemoState> { </DrawerContent> </Drawer> <div id="drawer-glass-plain-combo-container"> - <Drawer id="drawer-glass-plain-combo" isExpanded style={{ minHeight: '120px', height: '120px' }}> + {/* + isStatic: panel must not use the collapsed `hidden` / inert path — Cypress be.visible fails on a hidden panel. + isExpanded: keeps pf-m-expanded on the drawer root for layout. + */} + <Drawer + id="drawer-glass-plain-combo" + isExpanded={true} + isStatic={true} + style={{ minHeight: '120px', height: '120px' }} + > <DrawerContent colorVariant={DrawerColorVariant.default} panelContent={glassThemePlainComboPanelContent}> <DrawerContentBody>Glass theme + isPlain + isNoPlainOnGlass + isGlass demo</DrawerContentBody> </DrawerContent> From 39435c23b6d85e44bd19587fab89ee051b29224f Mon Sep 17 00:00:00 2001 From: Titani <tlabaj@redhat.com> Date: Thu, 16 Apr 2026 11:42:33 -0400 Subject: [PATCH 4/7] update prop description --- .../react-core/src/components/Drawer/DrawerPanelContent.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-core/src/components/Drawer/DrawerPanelContent.tsx b/packages/react-core/src/components/Drawer/DrawerPanelContent.tsx index 83e03eddc54..d78658f9df5 100644 --- a/packages/react-core/src/components/Drawer/DrawerPanelContent.tsx +++ b/packages/react-core/src/components/Drawer/DrawerPanelContent.tsx @@ -39,7 +39,7 @@ export interface DrawerPanelContentProps extends Omit<React.HTMLProps<HTMLDivEle hasNoGlass?: boolean; /** @beta Flag indicating that the drawer panel should use glass styles. */ isGlass?: boolean; - /** @beta Flag indicating that the drawer panel should use plain styles. */ + /** @beta Flag indicating that the drawer panel should use plain styles. This only applies when the drawer is static or inline. */ isPlain?: boolean; /** @beta Flag indicating that plain styles should be disabled when glass styles are used. */ isNoPlainOnGlass?: boolean; From df7cf43835bb9d4ed81ac1bf8ee9ba37a629f090 Mon Sep 17 00:00:00 2001 From: Titani <tlabaj@redhat.com> Date: Thu, 16 Apr 2026 11:43:33 -0400 Subject: [PATCH 5/7] update prop description --- .../react-core/src/components/Drawer/DrawerPanelContent.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-core/src/components/Drawer/DrawerPanelContent.tsx b/packages/react-core/src/components/Drawer/DrawerPanelContent.tsx index d78658f9df5..b22dfa955e8 100644 --- a/packages/react-core/src/components/Drawer/DrawerPanelContent.tsx +++ b/packages/react-core/src/components/Drawer/DrawerPanelContent.tsx @@ -37,7 +37,7 @@ export interface DrawerPanelContentProps extends Omit<React.HTMLProps<HTMLDivEle isResizable?: boolean; /** @beta Flag indicating that the drawer panel should disable glass styles. This prop is intended to work with isPill drawers. */ hasNoGlass?: boolean; - /** @beta Flag indicating that the drawer panel should use glass styles. */ + /** @beta Flag indicating that the drawer panel should use glass styles when in glass theme */ isGlass?: boolean; /** @beta Flag indicating that the drawer panel should use plain styles. This only applies when the drawer is static or inline. */ isPlain?: boolean; From 94a8e16c43198eda334dee6bb5daf9a9ba649ac5 Mon Sep 17 00:00:00 2001 From: Titani <tlabaj@redhat.com> Date: Thu, 16 Apr 2026 12:01:51 -0400 Subject: [PATCH 6/7] update cypress tests --- .../cypress/integration/drawer.spec.ts | 147 ++++++++++-------- .../demos/DrawerDemo/DrawerDemo.tsx | 44 ++++-- 2 files changed, 119 insertions(+), 72 deletions(-) diff --git a/packages/react-integration/cypress/integration/drawer.spec.ts b/packages/react-integration/cypress/integration/drawer.spec.ts index 5ab5a595626..e77ccfd245b 100644 --- a/packages/react-integration/cypress/integration/drawer.spec.ts +++ b/packages/react-integration/cypress/integration/drawer.spec.ts @@ -1,3 +1,68 @@ +const visitDrawerDemoWithGlassTheme = () => { + cy.visit('http://localhost:3000/drawer-demo-nav-link'); + cy.viewport(1280, 800); + cy.document().then((doc) => { + doc.documentElement.classList.add('pf-v6-theme-glass'); + }); + cy.get('html').should('have.class', 'pf-v6-theme-glass'); +}; + +const assertGlassPlainPanel = (testId: string, headlineSnippet: string) => { + cy.get(`[data-testid="${testId}"]`).should(($el) => { + expect($el, testId).to.have.length(1); + expect($el).to.not.have.attr('hidden'); + expect($el).to.not.have.attr('inert'); + expect($el).to.have.class('pf-m-glass'); + expect($el).to.have.class('pf-m-plain'); + expect($el).to.have.class('pf-m-no-plain-on-glass'); + expect($el).to.contain.text(headlineSnippet); + }); + + cy.get(`[data-testid="${testId}"]`).should(($el) => { + const style = window.getComputedStyle($el[0]); + const bg = style.backgroundColor; + const backdrop = style.backdropFilter; + + const rgbaCommaAlpha = (color: string): number | undefined => { + if (color === 'transparent') { + return 0; + } + if (!color.startsWith('rgba(') || !color.endsWith(')')) { + return undefined; + } + const inner = color.slice('rgba('.length, -1); + const parts = inner.split(',').map((p) => p.trim()); + if (parts.length !== 4) { + return undefined; + } + return parseFloat(parts[3]); + }; + + const rgbSlashAlpha = (color: string): number | undefined => { + if (!color.startsWith('rgb(')) { + return undefined; + } + const slash = color.indexOf('/'); + const close = color.lastIndexOf(')'); + if (slash === -1 || close === -1 || slash >= close) { + return undefined; + } + const a = parseFloat(color.slice(slash + 1, close).trim()); + return Number.isNaN(a) ? undefined : a; + }; + + const alpha = rgbaCommaAlpha(bg) ?? rgbSlashAlpha(bg); + const hasSemiTransparentBackground = alpha !== undefined && alpha < 1; + const hasBackdropBlur = Boolean(backdrop && backdrop !== 'none'); + + if (!hasSemiTransparentBackground && !hasBackdropBlur) { + throw new Error( + `expected glass panel (semi-transparent background or backdrop-filter); got backgroundColor=${bg}, backdropFilter=${backdrop || ''}` + ); + } + }); +}; + describe('Drawer Demo Test', () => { afterEach(() => { cy.document().then((doc) => { @@ -9,72 +74,30 @@ describe('Drawer Demo Test', () => { cy.visit('http://localhost:3000/drawer-demo-nav-link'); }); - it('glass theme + plain + glass: panel shows glass treatment (transparent bg and/or backdrop-filter)', () => { - // Self-contained: do not rely on test order; other specs leave the page in various states. - cy.visit('http://localhost:3000/drawer-demo-nav-link'); - cy.viewport(1280, 800); + it('glass theme + isInline drawer + plain/glass: panel shows glass treatment (transparent bg and/or backdrop-filter)', () => { + visitDrawerDemoWithGlassTheme(); - cy.document().then((doc) => { - doc.documentElement.classList.add('pf-v6-theme-glass'); - }); - cy.get('html').should('have.class', 'pf-v6-theme-glass'); - - cy.get('#drawer-glass-plain-combo.pf-v6-c-drawer').should('have.class', 'pf-m-expanded'); - - cy.get('[data-testid="drawer-glass-plain-panel"]').should(($el) => { - expect($el, 'glass plain combo panel').to.have.length(1); - expect($el).to.not.have.attr('hidden'); - expect($el).to.not.have.attr('inert'); - expect($el).to.have.class('pf-m-glass'); - expect($el).to.have.class('pf-m-plain'); - expect($el).to.have.class('pf-m-no-plain-on-glass'); - expect($el).to.contain.text('Glass theme plain / no-plain-on-glass combo'); + cy.get('#drawer-glass-plain-inline.pf-v6-c-drawer').should(($drawer) => { + expect($drawer).to.have.length(1); + expect($drawer).to.have.class('pf-m-expanded'); + expect($drawer).to.have.class('pf-m-inline'); + expect($drawer).to.not.have.class('pf-m-static'); }); - cy.get('[data-testid="drawer-glass-plain-panel"]').should(($el) => { - const style = window.getComputedStyle($el[0]); - const bg = style.backgroundColor; - const backdrop = style.backdropFilter; - - const rgbaCommaAlpha = (color: string): number | undefined => { - if (color === 'transparent') { - return 0; - } - if (!color.startsWith('rgba(') || !color.endsWith(')')) { - return undefined; - } - const inner = color.slice('rgba('.length, -1); - const parts = inner.split(',').map((p) => p.trim()); - if (parts.length !== 4) { - return undefined; - } - return parseFloat(parts[3]); - }; - - // e.g. rgb(255 255 255 / 0.08) from getComputedStyle in some engines - const rgbSlashAlpha = (color: string): number | undefined => { - if (!color.startsWith('rgb(')) { - return undefined; - } - const slash = color.indexOf('/'); - const close = color.lastIndexOf(')'); - if (slash === -1 || close === -1 || slash >= close) { - return undefined; - } - const a = parseFloat(color.slice(slash + 1, close).trim()); - return Number.isNaN(a) ? undefined : a; - }; - - const alpha = rgbaCommaAlpha(bg) ?? rgbSlashAlpha(bg); - const hasSemiTransparentBackground = alpha !== undefined && alpha < 1; - const hasBackdropBlur = Boolean(backdrop && backdrop !== 'none'); - - if (!hasSemiTransparentBackground && !hasBackdropBlur) { - throw new Error( - `expected glass panel (semi-transparent background or backdrop-filter); got backgroundColor=${bg}, backdropFilter=${backdrop || ''}` - ); - } + assertGlassPlainPanel('drawer-glass-plain-panel-inline', 'Glass theme plain / no-plain-on-glass combo (inline)'); + }); + + it('glass theme + isStatic drawer + plain/glass: panel shows glass treatment (transparent bg and/or backdrop-filter)', () => { + visitDrawerDemoWithGlassTheme(); + + cy.get('#drawer-glass-plain-static.pf-v6-c-drawer').should(($drawer) => { + expect($drawer).to.have.length(1); + expect($drawer).to.have.class('pf-m-expanded'); + expect($drawer).to.have.class('pf-m-static'); + expect($drawer).to.not.have.class('pf-m-inline'); }); + + assertGlassPlainPanel('drawer-glass-plain-panel-static', 'Glass theme plain / no-plain-on-glass combo (static)'); }); it('Verify focus is automatically handled with focus trap enabled', () => { diff --git a/packages/react-integration/demo-app-ts/src/components/demos/DrawerDemo/DrawerDemo.tsx b/packages/react-integration/demo-app-ts/src/components/demos/DrawerDemo/DrawerDemo.tsx index 1af229d0ee6..2db1f6fb934 100644 --- a/packages/react-integration/demo-app-ts/src/components/demos/DrawerDemo/DrawerDemo.tsx +++ b/packages/react-integration/demo-app-ts/src/components/demos/DrawerDemo/DrawerDemo.tsx @@ -118,16 +118,30 @@ export class DrawerDemo extends Component<DrawerProps, DrawerDemoState> { const drawerContent = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus pretium est a porttitor vehicula. Quisque vel commodo urna. Morbi mattis rutrum ante, id vehicula ex accumsan ut. Morbi viverra, eros vel porttitor facilisis, eros purus aliquet erat,nec lobortis felis elit pulvinar sem. Vivamus vulputate, risus eget commodo eleifend, eros nibh porta quam, vitae lacinia leo libero at magna. Maecenas aliquam sagittis orci, et posuere nisi ultrices sit amet. Aliquam ex odio, malesuada sed posuere quis, pellentesque at mauris. Phasellus venenatis massa ex, eget pulvinar libero auctor pretium. Aliquam erat volutpat. Duis euismod justo in quam ullamcorper, in commodo massa vulputate.'; - const glassThemePlainComboPanelContent = ( + const glassThemePlainInlinePanelContent = ( <DrawerPanelContent - id="drawer-panel-glass-plain-combo" - data-testid="drawer-glass-plain-panel" + id="drawer-panel-glass-plain-inline" + data-testid="drawer-glass-plain-panel-inline" isPlain isNoPlainOnGlass isGlass > <DrawerHead> - <span>Glass theme plain / no-plain-on-glass combo</span> + <span>Glass theme plain / no-plain-on-glass combo (inline)</span> + </DrawerHead> + </DrawerPanelContent> + ); + + const glassThemePlainStaticPanelContent = ( + <DrawerPanelContent + id="drawer-panel-glass-plain-static" + data-testid="drawer-glass-plain-panel-static" + isPlain + isNoPlainOnGlass + isGlass + > + <DrawerHead> + <span>Glass theme plain / no-plain-on-glass combo (static)</span> </DrawerHead> </DrawerPanelContent> ); @@ -165,19 +179,29 @@ export class DrawerDemo extends Component<DrawerProps, DrawerDemoState> { <DrawerContentBody>{drawerContent}</DrawerContentBody> </DrawerContent> </Drawer> - <div id="drawer-glass-plain-combo-container"> + <div id="drawer-glass-plain-demos"> {/* - isStatic: panel must not use the collapsed `hidden` / inert path — Cypress be.visible fails on a hidden panel. - isExpanded: keeps pf-m-expanded on the drawer root for layout. + Split drawers so integration tests cover isInline and isStatic separately. + isExpanded keeps pf-m-expanded; inline uses pf-m-inline only; static uses pf-m-static only. */} <Drawer - id="drawer-glass-plain-combo" + id="drawer-glass-plain-inline" + isExpanded={true} + isInline={true} + style={{ minHeight: '120px', height: '120px' }} + > + <DrawerContent colorVariant={DrawerColorVariant.default} panelContent={glassThemePlainInlinePanelContent}> + <DrawerContentBody>Glass theme + isPlain + isGlass (inline)</DrawerContentBody> + </DrawerContent> + </Drawer> + <Drawer + id="drawer-glass-plain-static" isExpanded={true} isStatic={true} style={{ minHeight: '120px', height: '120px' }} > - <DrawerContent colorVariant={DrawerColorVariant.default} panelContent={glassThemePlainComboPanelContent}> - <DrawerContentBody>Glass theme + isPlain + isNoPlainOnGlass + isGlass demo</DrawerContentBody> + <DrawerContent colorVariant={DrawerColorVariant.default} panelContent={glassThemePlainStaticPanelContent}> + <DrawerContentBody>Glass theme + isPlain + isGlass (static)</DrawerContentBody> </DrawerContent> </Drawer> </div> From 5893e16bbc300d273859f20e852620de2448260d Mon Sep 17 00:00:00 2001 From: Titani <tlabaj@redhat.com> Date: Fri, 24 Apr 2026 14:03:37 -0400 Subject: [PATCH 7/7] Update tests and prop descriptions --- .../components/Drawer/DrawerPanelContent.tsx | 2 +- .../Drawer/__tests__/DrawerSection.test.tsx | 26 ++- .../cypress/integration/drawer.spec.ts | 169 ++++++++++++++---- .../demos/DrawerDemo/DrawerDemo.tsx | 52 +++++- 4 files changed, 205 insertions(+), 44 deletions(-) diff --git a/packages/react-core/src/components/Drawer/DrawerPanelContent.tsx b/packages/react-core/src/components/Drawer/DrawerPanelContent.tsx index b22dfa955e8..2933af16965 100644 --- a/packages/react-core/src/components/Drawer/DrawerPanelContent.tsx +++ b/packages/react-core/src/components/Drawer/DrawerPanelContent.tsx @@ -41,7 +41,7 @@ export interface DrawerPanelContentProps extends Omit<React.HTMLProps<HTMLDivEle isGlass?: boolean; /** @beta Flag indicating that the drawer panel should use plain styles. This only applies when the drawer is static or inline. */ isPlain?: boolean; - /** @beta Flag indicating that plain styles should be disabled when glass styles are used. */ + /** @beta Flag indicating that plain styles should be disabled when glass styles are used. This only applies when the drawer is static or inline. */ isNoPlainOnGlass?: boolean; /** Callback for resize end. */ onResize?: (event: MouseEvent | TouchEvent | React.KeyboardEvent, width: number, id: string) => void; diff --git a/packages/react-core/src/components/Drawer/__tests__/DrawerSection.test.tsx b/packages/react-core/src/components/Drawer/__tests__/DrawerSection.test.tsx index 849cf457ddf..e080cb25a8c 100644 --- a/packages/react-core/src/components/Drawer/__tests__/DrawerSection.test.tsx +++ b/packages/react-core/src/components/Drawer/__tests__/DrawerSection.test.tsx @@ -1,4 +1,5 @@ import { render, screen } from '@testing-library/react'; +import { DrawerColorVariant } from '../Drawer'; import { DrawerSection } from '../DrawerSection'; import styles from '@patternfly/react-styles/css/components/Drawer/drawer'; @@ -8,8 +9,29 @@ test(`Renders with only class ${styles.drawerSection} by default`, () => { expect(screen.getByText('Section content')).toHaveClass(styles.drawerSection, { exact: true }); }); -test(`Renders with class ${styles.modifiers.plain} when isPlain is true`, () => { +test(`Applies ${styles.drawerSection} and ${styles.modifiers.plain} when isPlain is true`, () => { render(<DrawerSection isPlain>Section content</DrawerSection>); - expect(screen.getByText('Section content')).toHaveClass(styles.modifiers.plain); + const section = screen.getByText('Section content'); + expect(section).toHaveClass(styles.drawerSection); + expect(section).toHaveClass(styles.modifiers.plain); +}); + +test(`Does not apply ${styles.modifiers.plain} when isPlain is false`, () => { + render(<DrawerSection isPlain={false}>Section content</DrawerSection>); + + expect(screen.getByText('Section content')).not.toHaveClass(styles.modifiers.plain); +}); + +test(`Applies plain and secondary modifiers together when isPlain and colorVariant are set`, () => { + render( + <DrawerSection isPlain colorVariant={DrawerColorVariant.secondary}> + Section content + </DrawerSection> + ); + + const section = screen.getByText('Section content'); + expect(section).toHaveClass(styles.drawerSection); + expect(section).toHaveClass(styles.modifiers.plain); + expect(section).toHaveClass(styles.modifiers.secondary); }); diff --git a/packages/react-integration/cypress/integration/drawer.spec.ts b/packages/react-integration/cypress/integration/drawer.spec.ts index e77ccfd245b..544ddb0cabe 100644 --- a/packages/react-integration/cypress/integration/drawer.spec.ts +++ b/packages/react-integration/cypress/integration/drawer.spec.ts @@ -7,6 +7,45 @@ const visitDrawerDemoWithGlassTheme = () => { cy.get('html').should('have.class', 'pf-v6-theme-glass'); }; +/** Matches integration checks for “glass” panel visuals (semi-transparent bg and/or backdrop-filter). */ +const rgbaCommaAlpha = (color: string): number | undefined => { + if (color === 'transparent') { + return 0; + } + if (!color.startsWith('rgba(') || !color.endsWith(')')) { + return undefined; + } + const inner = color.slice('rgba('.length, -1); + const parts = inner.split(',').map((p) => p.trim()); + if (parts.length !== 4) { + return undefined; + } + return parseFloat(parts[3]); +}; + +const rgbSlashAlpha = (color: string): number | undefined => { + if (!color.startsWith('rgb(')) { + return undefined; + } + const slash = color.indexOf('/'); + const close = color.lastIndexOf(')'); + if (slash === -1 || close === -1 || slash >= close) { + return undefined; + } + const a = parseFloat(color.slice(slash + 1, close).trim()); + return Number.isNaN(a) ? undefined : a; +}; + +const drawerPanelShowsGlassVisualTreatment = (el: HTMLElement): boolean => { + const style = window.getComputedStyle(el); + const bg = style.backgroundColor; + const backdrop = style.backdropFilter; + const alpha = rgbaCommaAlpha(bg) ?? rgbSlashAlpha(bg); + const hasSemiTransparentBackground = alpha !== undefined && alpha < 1; + const hasBackdropBlur = Boolean(backdrop && backdrop !== 'none'); + return hasSemiTransparentBackground || hasBackdropBlur; +}; + const assertGlassPlainPanel = (testId: string, headlineSnippet: string) => { cy.get(`[data-testid="${testId}"]`).should(($el) => { expect($el, testId).to.have.length(1); @@ -19,45 +58,10 @@ const assertGlassPlainPanel = (testId: string, headlineSnippet: string) => { }); cy.get(`[data-testid="${testId}"]`).should(($el) => { - const style = window.getComputedStyle($el[0]); - const bg = style.backgroundColor; - const backdrop = style.backdropFilter; - - const rgbaCommaAlpha = (color: string): number | undefined => { - if (color === 'transparent') { - return 0; - } - if (!color.startsWith('rgba(') || !color.endsWith(')')) { - return undefined; - } - const inner = color.slice('rgba('.length, -1); - const parts = inner.split(',').map((p) => p.trim()); - if (parts.length !== 4) { - return undefined; - } - return parseFloat(parts[3]); - }; - - const rgbSlashAlpha = (color: string): number | undefined => { - if (!color.startsWith('rgb(')) { - return undefined; - } - const slash = color.indexOf('/'); - const close = color.lastIndexOf(')'); - if (slash === -1 || close === -1 || slash >= close) { - return undefined; - } - const a = parseFloat(color.slice(slash + 1, close).trim()); - return Number.isNaN(a) ? undefined : a; - }; - - const alpha = rgbaCommaAlpha(bg) ?? rgbSlashAlpha(bg); - const hasSemiTransparentBackground = alpha !== undefined && alpha < 1; - const hasBackdropBlur = Boolean(backdrop && backdrop !== 'none'); - - if (!hasSemiTransparentBackground && !hasBackdropBlur) { + if (!drawerPanelShowsGlassVisualTreatment($el[0])) { + const style = window.getComputedStyle($el[0]); throw new Error( - `expected glass panel (semi-transparent background or backdrop-filter); got backgroundColor=${bg}, backdropFilter=${backdrop || ''}` + `expected glass panel (semi-transparent background or backdrop-filter); got backgroundColor=${style.backgroundColor}, backdropFilter=${style.backdropFilter || ''}` ); } }); @@ -100,6 +104,53 @@ describe('Drawer Demo Test', () => { assertGlassPlainPanel('drawer-glass-plain-panel-static', 'Glass theme plain / no-plain-on-glass combo (static)'); }); + it('glass theme + default overlay drawer: isPlain / isGlass / isNoPlainOnGlass modifiers do not get glass panel styles from Core', () => { + visitDrawerDemoWithGlassTheme(); + + cy.get('#drawer-glass-plain-overlay.pf-v6-c-drawer').should(($drawer) => { + expect($drawer).to.have.length(1); + expect($drawer).to.have.class('pf-m-expanded'); + expect($drawer).to.not.have.class('pf-m-inline'); + expect($drawer).to.not.have.class('pf-m-static'); + }); + + cy.get('[data-testid="drawer-glass-plain-panel-overlay"]').should(($el) => { + expect($el).to.have.length(1); + expect($el).to.not.have.attr('hidden'); + expect($el).to.not.have.attr('inert'); + expect($el).to.have.class('pf-m-glass'); + expect($el).to.have.class('pf-m-plain'); + expect($el).to.have.class('pf-m-no-plain-on-glass'); + expect($el).to.contain.text('Glass theme plain / no-plain-on-glass combo (overlay)'); + expect( + drawerPanelShowsGlassVisualTreatment($el[0]), + 'Core should not apply glass/plain-on-glass panel treatment without inline or static drawer' + ).to.equal(false); + }); + }); + + it('glass theme: drawer panel has no glass CSS when isGlass is false', () => { + visitDrawerDemoWithGlassTheme(); + + cy.get('#drawer-glass-theme-no-isglass.pf-v6-c-drawer').should(($drawer) => { + expect($drawer).to.have.length(1); + expect($drawer).to.have.class('pf-m-expanded'); + expect($drawer).to.have.class('pf-m-inline'); + }); + + cy.get('[data-testid="drawer-panel-content-glass-theme-no-isglass"]').should(($el) => { + expect($el).to.have.length(1); + expect($el).to.not.have.attr('hidden'); + expect($el).to.not.have.attr('inert'); + expect($el).to.have.class('pf-m-plain'); + expect($el).to.not.have.class('pf-m-glass'); + expect( + drawerPanelShowsGlassVisualTreatment($el[0]), + 'panel must not get glass treatment from theme alone; set isGlass for pf-m-glass and glass styles' + ).to.equal(false); + }); + }); + it('Verify focus is automatically handled with focus trap enabled', () => { cy.get('#toggleFocusTrapButton').click(); cy.get('#focusTrap-panelContent .pf-v6-c-button.pf-m-plain').should('have.focus'); @@ -115,6 +166,48 @@ describe('Drawer Demo Test', () => { cy.get('#toggleCustomFocusButton').click(); }); + it('DrawerSection isPlain: Core applies pf-m-plain and computed styles differ from default section', () => { + cy.visit('http://localhost:3000/drawer-demo-nav-link'); + cy.viewport(1280, 800); + cy.get('#toggleButton').click(); + cy.get('#basic-drawer.pf-v6-c-drawer').should('have.class', 'pf-m-expanded'); + + cy.get('[data-testid="drawer-section-is-plain"]').should(($el) => { + expect($el).to.have.length(1); + expect($el).to.have.class('pf-v6-c-drawer__section'); + expect($el).to.have.class('pf-m-plain'); + }); + + cy.get('[data-testid="drawer-section-default"]').should(($el) => { + expect($el).to.have.length(1); + expect($el).to.have.class('pf-v6-c-drawer__section'); + expect($el).to.not.have.class('pf-m-plain'); + }); + + cy.get('[data-testid="drawer-section-default"]').then(($default) => { + cy.get('[data-testid="drawer-section-is-plain"]').should(($plain) => { + const sDef = window.getComputedStyle($default[0]); + const sPlain = window.getComputedStyle($plain[0]); + const differs = + sPlain.backgroundColor !== sDef.backgroundColor || + sPlain.boxShadow !== sDef.boxShadow || + sPlain.borderTopWidth !== sDef.borderTopWidth; + if (!differs) { + throw new Error( + `expected isPlain section to differ from default in backgroundColor, boxShadow, or borderTopWidth; ` + + `bg default=${sDef.backgroundColor} plain=${sPlain.backgroundColor}; ` + + `boxShadow default=${sDef.boxShadow} plain=${sPlain.boxShadow}; ` + + `borderTopWidth default=${sDef.borderTopWidth} plain=${sPlain.borderTopWidth}` + ); + } + }); + }); + + // Leave basic drawer collapsed for later specs (e.g. "Verify drawer expands and collapses"). + cy.get('#toggleButton').click(); + cy.get('#basic-drawer.pf-v6-c-drawer').should('not.have.class', 'pf-m-expanded'); + }); + it('Verify text in content', () => { const drawerContent = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus pretium est a porttitor vehicula. Quisque vel commodo urna. Morbi mattis rutrum ante, id vehicula ex accumsan ut. Morbi viverra, eros vel porttitor facilisis, eros purus aliquet erat,nec lobortis felis elit pulvinar sem. Vivamus vulputate, risus eget commodo eleifend, eros nibh porta quam, vitae lacinia leo libero at magna. Maecenas aliquam sagittis orci, et posuere nisi ultrices sit amet. Aliquam ex odio, malesuada sed posuere quis, pellentesque at mauris. Phasellus venenatis massa ex, eget pulvinar libero auctor pretium. Aliquam erat volutpat. Duis euismod justo in quam ullamcorper, in commodo massa vulputate.'; diff --git a/packages/react-integration/demo-app-ts/src/components/demos/DrawerDemo/DrawerDemo.tsx b/packages/react-integration/demo-app-ts/src/components/demos/DrawerDemo/DrawerDemo.tsx index 2db1f6fb934..86727db2a9c 100644 --- a/packages/react-integration/demo-app-ts/src/components/demos/DrawerDemo/DrawerDemo.tsx +++ b/packages/react-integration/demo-app-ts/src/components/demos/DrawerDemo/DrawerDemo.tsx @@ -146,6 +146,32 @@ export class DrawerDemo extends Component<DrawerProps, DrawerDemoState> { </DrawerPanelContent> ); + const glassThemePlainOverlayPanelContent = ( + <DrawerPanelContent + id="drawer-panel-glass-plain-overlay" + data-testid="drawer-glass-plain-panel-overlay" + isPlain + isNoPlainOnGlass + isGlass + > + <DrawerHead> + <span>Glass theme plain / no-plain-on-glass combo (overlay)</span> + </DrawerHead> + </DrawerPanelContent> + ); + + const glassThemeInlinePanelNoIsGlass = ( + <DrawerPanelContent + id="drawer-panel-glass-theme-no-isglass" + data-testid="drawer-panel-content-glass-theme-no-isglass" + isPlain + > + <DrawerHead> + <span>Glass theme on html, isPlain, isGlass false</span> + </DrawerHead> + </DrawerPanelContent> + ); + return ( <> <Button id="toggleButton" onClick={this.onClick}> @@ -158,7 +184,12 @@ export class DrawerDemo extends Component<DrawerProps, DrawerDemoState> { position="bottom" style={{ minHeight: '300px', height: '300px' }} > - <DrawerSection colorVariant={DrawerColorVariant.default}>drawer-section</DrawerSection> + <DrawerSection colorVariant={DrawerColorVariant.default} data-testid="drawer-section-default"> + drawer-section + </DrawerSection> + <DrawerSection isPlain data-testid="drawer-section-is-plain"> + drawer-section plain + </DrawerSection> <DrawerContent colorVariant={DrawerColorVariant.default} panelContent={panelContent}> <DrawerContentBody>{drawerContent}</DrawerContentBody> </DrawerContent> @@ -181,8 +212,8 @@ export class DrawerDemo extends Component<DrawerProps, DrawerDemoState> { </Drawer> <div id="drawer-glass-plain-demos"> {/* - Split drawers so integration tests cover isInline and isStatic separately. - isExpanded keeps pf-m-expanded; inline uses pf-m-inline only; static uses pf-m-static only. + Split drawers so integration tests cover isInline, isStatic, and default overlay separately. + Plain / glass / no-plain-on-glass Core styles apply to inline & static; overlay keeps modifiers from React only. */} <Drawer id="drawer-glass-plain-inline" @@ -204,6 +235,21 @@ export class DrawerDemo extends Component<DrawerProps, DrawerDemoState> { <DrawerContentBody>Glass theme + isPlain + isGlass (static)</DrawerContentBody> </DrawerContent> </Drawer> + <Drawer id="drawer-glass-plain-overlay" isExpanded={true} style={{ minHeight: '120px', height: '120px' }}> + <DrawerContent colorVariant={DrawerColorVariant.default} panelContent={glassThemePlainOverlayPanelContent}> + <DrawerContentBody>Glass theme + isPlain + isGlass (default overlay)</DrawerContentBody> + </DrawerContent> + </Drawer> + <Drawer + id="drawer-glass-theme-no-isglass" + isExpanded={true} + isInline={true} + style={{ minHeight: '120px', height: '120px' }} + > + <DrawerContent colorVariant={DrawerColorVariant.default} panelContent={glassThemeInlinePanelNoIsGlass}> + <DrawerContentBody>pf-v6-theme-glass + isPlain only (no isGlass)</DrawerContentBody> + </DrawerContent> + </Drawer> </div> </> );