Skip to content

Commit 19b6dae

Browse files
committed
add logic to check if glass theme is on
1 parent 641c888 commit 19b6dae

File tree

3 files changed

+56
-6
lines changed

3 files changed

+56
-6
lines changed

packages/react-core/src/components/Accordion/Accordion.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { css } from '@patternfly/react-styles';
22
import styles from '@patternfly/react-styles/css/components/Accordion/accordion';
3+
import { hasGlassTheme } from '../../helpers/util';
34
import { AccordionContext } from './AccordionContext';
45

56
export interface AccordionProps extends React.HTMLProps<HTMLDListElement> {
@@ -15,6 +16,8 @@ export interface AccordionProps extends React.HTMLProps<HTMLDListElement> {
1516
asDefinitionList?: boolean;
1617
/** Flag to indicate the accordion had a border */
1718
isBordered?: boolean;
19+
/** Flag to indicate if the accordion is plain */
20+
isPlain?: boolean;
1821
/** Display size variant. */
1922
displaySize?: 'default' | 'lg';
2023
/** Sets the toggle icon position for all accordion toggles. */
@@ -28,6 +31,7 @@ export const Accordion: React.FunctionComponent<AccordionProps> = ({
2831
headingLevel = 'h3',
2932
asDefinitionList = true,
3033
isBordered = false,
34+
isPlain = false,
3135
displaySize = 'default',
3236
togglePosition = 'end',
3337
...props
@@ -38,6 +42,7 @@ export const Accordion: React.FunctionComponent<AccordionProps> = ({
3842
className={css(
3943
styles.accordion,
4044
isBordered && styles.modifiers.bordered,
45+
!isPlain && hasGlassTheme() && styles.modifiers.noPlain,
4146
togglePosition === 'start' && styles.modifiers.toggleStart,
4247
displaySize === 'lg' && styles.modifiers.displayLg,
4348
className

packages/react-core/src/components/Accordion/__tests__/Accordion.test.tsx

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
import '@testing-library/jest-dom';
2+
// eslint-disable-next-line no-restricted-imports -- React in scope required for TS (test file)
3+
import React from 'react';
14
import { render, screen } from '@testing-library/react';
25

36
import { Accordion } from '../Accordion';
47
import { AccordionContext } from '../AccordionContext';
8+
// @ts-ignore - react-styles subpath module resolution
59
import styles from '@patternfly/react-styles/css/components/Accordion/accordion';
610

711
test('Renders without children', () => {
@@ -33,7 +37,7 @@ test('Renders with inherited element props spread to the component', () => {
3337
expect(screen.getByText('Test')).toHaveAccessibleName('Label');
3438
});
3539

36-
test(`Renders with class name ${styles.accordion}`, () => {
40+
test(`Renders with class ${styles.accordion}`, () => {
3741
render(<Accordion>Test</Accordion>);
3842

3943
expect(screen.getByText('Test')).toHaveClass(styles.accordion);
@@ -62,7 +66,7 @@ test('Renders Accordion as a "div" when asDefinitionList is false', () => {
6266
test('Provides a ContentContainer of "dd" in a context by default', () => {
6367
render(
6468
<Accordion>
65-
<AccordionContext.Consumer>{({ ContentContainer }) => ContentContainer}</AccordionContext.Consumer>
69+
<AccordionContext.Consumer>{({ ContentContainer }) => String(ContentContainer)}</AccordionContext.Consumer>
6670
</Accordion>
6771
);
6872

@@ -72,7 +76,7 @@ test('Provides a ContentContainer of "dd" in a context by default', () => {
7276
test('Provides a ContentContainer of "div" in a context when asDefinitionList is false', () => {
7377
render(
7478
<Accordion asDefinitionList={false}>
75-
<AccordionContext.Consumer>{({ ContentContainer }) => ContentContainer}</AccordionContext.Consumer>
79+
<AccordionContext.Consumer>{({ ContentContainer }) => String(ContentContainer)}</AccordionContext.Consumer>
7680
</Accordion>
7781
);
7882

@@ -82,7 +86,7 @@ test('Provides a ContentContainer of "div" in a context when asDefinitionList is
8286
test('Provides a ToggleContainer of "dt" in a context by default', () => {
8387
render(
8488
<Accordion>
85-
<AccordionContext.Consumer>{({ ToggleContainer }) => ToggleContainer}</AccordionContext.Consumer>
89+
<AccordionContext.Consumer>{({ ToggleContainer }) => String(ToggleContainer)}</AccordionContext.Consumer>
8690
</Accordion>
8791
);
8892

@@ -92,7 +96,7 @@ test('Provides a ToggleContainer of "dt" in a context by default', () => {
9296
test('Provides a ToggleContainer of "h3" in a context when asDefinitionList is false', () => {
9397
render(
9498
<Accordion asDefinitionList={false}>
95-
<AccordionContext.Consumer>{({ ToggleContainer }) => ToggleContainer}</AccordionContext.Consumer>
99+
<AccordionContext.Consumer>{({ ToggleContainer }) => String(ToggleContainer)}</AccordionContext.Consumer>
96100
</Accordion>
97101
);
98102

@@ -102,7 +106,7 @@ test('Provides a ToggleContainer of "h3" in a context when asDefinitionList is f
102106
test('Provides a ToggleContainer of "h2" in a context when asDefinitionList is false and headingLevel is "h2"', () => {
103107
render(
104108
<Accordion asDefinitionList={false} headingLevel="h2">
105-
<AccordionContext.Consumer>{({ ToggleContainer }) => ToggleContainer}</AccordionContext.Consumer>
109+
<AccordionContext.Consumer>{({ ToggleContainer }) => String(ToggleContainer)}</AccordionContext.Consumer>
106110
</Accordion>
107111
);
108112

@@ -121,6 +125,38 @@ test('Renders with pf-m-bordered when isBordered=true', () => {
121125
expect(screen.getByText('Test')).toHaveClass('pf-m-bordered');
122126
});
123127

128+
test(`Renders without class ${styles.modifiers.noPlain} by default`, () => {
129+
render(<Accordion>Test</Accordion>);
130+
131+
expect(screen.getByText('Test')).not.toHaveClass(styles.modifiers.noPlain);
132+
});
133+
134+
test(`Renders without class ${styles.modifiers.noPlain} when isPlain is undefined`, () => {
135+
render(<Accordion isPlain={undefined}>Test</Accordion>);
136+
137+
expect(screen.getByText('Test')).not.toHaveClass(styles.modifiers.noPlain);
138+
});
139+
140+
test(`Renders without class ${styles.modifiers.noPlain} when isPlain=false and glass theme is not applied`, () => {
141+
render(<Accordion isPlain={false}>Test</Accordion>);
142+
143+
expect(screen.getByText('Test')).not.toHaveClass(styles.modifiers.noPlain);
144+
});
145+
146+
test(`Renders with class ${styles.modifiers.noPlain} when isPlain=false and glass theme is applied`, () => {
147+
document.documentElement.classList.add('pf-v6-theme-glass');
148+
render(<Accordion isPlain={false}>Test</Accordion>);
149+
150+
expect(screen.getByText('Test')).toHaveClass(styles.modifiers.noPlain);
151+
document.documentElement.classList.remove('pf-v6-theme-glass');
152+
});
153+
154+
test(`Renders without class ${styles.modifiers.noPlain} when isPlain=true`, () => {
155+
render(<Accordion isPlain>Test</Accordion>);
156+
157+
expect(screen.getByText('Test')).not.toHaveClass(styles.modifiers.noPlain);
158+
});
159+
124160
test('Renders without pf-m-display-lg by default', () => {
125161
render(<Accordion>Test</Accordion>);
126162

packages/react-core/src/helpers/util.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,15 @@ export const toCamel = (s: string) => s.replace(/([-_][a-z])/gi, camelize);
395395
*/
396396
export const canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement);
397397

398+
/**
399+
* Checks if the PatternFly glass theme is applied at the document root.
400+
* Used by components that adapt styling for glass theme (e.g. Accordion).
401+
*
402+
* @returns {boolean} - True if the glass theme class is present on the html element
403+
*/
404+
export const hasGlassTheme = (): boolean =>
405+
typeof document !== 'undefined' && document.documentElement.classList.contains('pf-v6-theme-glass');
406+
398407
/**
399408
* Calculate the width of the text
400409
* Example:

0 commit comments

Comments
 (0)