Skip to content

Commit f71da53

Browse files
authored
feat(Data list): Add isNoPlainOnGlass prop to add pf-m-no-plain modfier to the data list (#12292)
* feat(Data list): Add isNoPlainOnGlass prop to add pf-m-no-plain modifier to the data list * fix docs * Removed warning. Added test case for broken feature * update cypress test * rebase and fix tests
1 parent 32dcebe commit f71da53

File tree

9 files changed

+172
-110
lines changed

9 files changed

+172
-110
lines changed

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

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,27 +19,29 @@ export enum DataListWrapModifier {
1919
}
2020

2121
export interface DataListProps extends React.HTMLProps<HTMLUListElement> {
22-
/** Content rendered inside the DataList list */
22+
/** Content rendered inside the data list list */
2323
children?: React.ReactNode;
24-
/** Additional classes added to the DataList list */
24+
/** Additional classes added to the data list list */
2525
className?: string;
26-
/** Adds accessible text to the DataList list */
26+
/** Adds accessible text to the data list list */
2727
'aria-label': string;
28-
/** Optional callback to make DataList selectable, fired when DataListItem selected */
28+
/** Optional callback to make data list selectable, fired when data list item selected */
2929
onSelectDataListItem?: (event: React.MouseEvent | React.KeyboardEvent, id: string) => void;
30-
/** Id of DataList item currently selected */
30+
/** Id of data list item currently selected */
3131
selectedDataListItemId?: string;
32-
/** Flag indicating if DataList should have compact styling */
32+
/** Flag indicating if data list should have compact styling */
3333
isCompact?: boolean;
34-
/** @beta Flag indicating if DataList should have plain styling with a transparent background */
34+
/** @beta Flag indicating if data list should have plain styling with a transparent background */
3535
isPlain?: boolean;
36+
/** @beta Flag to prevent the data list from automatically applying plain styling when glass theme is enabled. */
37+
isNoPlainOnGlass?: boolean;
3638
/** Specifies the grid breakpoints */
3739
gridBreakpoint?: 'none' | 'always' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';
38-
/** Determines which wrapping modifier to apply to the DataList */
40+
/** Determines which wrapping modifier to apply to the data list */
3941
wrapModifier?: DataListWrapModifier | 'nowrap' | 'truncate' | 'breakWord';
4042
/** Object that causes the data list to render hidden inputs which improve selectable item a11y */
4143
onSelectableRowChange?: (event: React.FormEvent<HTMLInputElement>, id: string) => void;
42-
/** @hide custom ref of the DataList */
44+
/** @hide custom ref of the data list */
4345
innerRef?: React.RefObject<HTMLUListElement | null>;
4446
}
4547

@@ -62,6 +64,7 @@ export const DataListBase: React.FunctionComponent<DataListProps> = ({
6264
selectedDataListItemId = '',
6365
isCompact = false,
6466
isPlain = false,
67+
isNoPlainOnGlass = false,
6568
gridBreakpoint = 'md',
6669
wrapModifier = null,
6770
onSelectableRowChange,
@@ -88,6 +91,7 @@ export const DataListBase: React.FunctionComponent<DataListProps> = ({
8891
styles.dataList,
8992
isCompact && styles.modifiers.compact,
9093
isPlain && styles.modifiers.plain,
94+
isNoPlainOnGlass && styles.modifiers.noPlainOnGlass,
9195
gridBreakpointClasses[gridBreakpoint],
9296
wrapModifier && styles.modifiers[wrapModifier],
9397
className

packages/react-core/src/components/DataList/DataListAction.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@ import styles from '@patternfly/react-styles/css/components/DataList/data-list';
33
import { formatBreakpointMods } from '../../helpers/util';
44

55
export interface DataListActionProps extends Omit<React.HTMLProps<HTMLDivElement>, 'children'> {
6-
/** Content rendered as DataList Action (e.g <Button> or <Dropdown>) */
6+
/** Content rendered as data list action (e.g <Button> or <Dropdown>) */
77
children: React.ReactNode;
8-
/** Additional classes added to the DataList Action */
8+
/** Additional classes added to the data list action */
99
className?: string;
10-
/** Identify the DataList toggle number */
10+
/** Identify the data list toggle number */
1111
id: string;
12-
/** Adds accessible text to the DataList Action */
12+
/** Adds accessible text to the data list action */
1313
'aria-labelledby': string;
14-
/** Adds accessible text to the DataList Action */
14+
/** Adds accessible text to the data list action */
1515
'aria-label': string;
1616
/** What breakpoints to hide/show the data list action */
1717
visibility?: {

packages/react-core/src/components/DataList/DataListCell.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,19 @@ import { DataListWrapModifier } from './DataList';
55
import { Tooltip } from '../Tooltip';
66

77
export interface DataListCellProps extends Omit<React.HTMLProps<HTMLDivElement>, 'width'> {
8-
/** Content rendered inside the DataList cell */
8+
/** Content rendered inside the data list cell */
99
children?: React.ReactNode;
10-
/** Additional classes added to the DataList cell */
10+
/** Additional classes added to the data list cell */
1111
className?: string;
12-
/** Width (from 1-5) to the DataList cell */
12+
/** Width (from 1-5) to the data list cell */
1313
width?: 1 | 2 | 3 | 4 | 5;
14-
/** Enables the body Content to fill the height of the card */
14+
/** Enables the body content to fill the height of the card */
1515
isFilled?: boolean;
1616
/** Aligns the cell content to the right of its parent. */
1717
alignRight?: boolean;
18-
/** Set to true if the cell content is an Icon */
18+
/** Set to true if the cell content is an icon */
1919
isIcon?: boolean;
20-
/** Determines which wrapping modifier to apply to the DataListCell */
20+
/** Determines which wrapping modifier to apply to the data list cell */
2121
wrapModifier?: DataListWrapModifier | 'nowrap' | 'truncate' | 'breakWord';
2222
}
2323

packages/react-core/src/components/DataList/DataListItemCells.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { css } from '@patternfly/react-styles';
22
import styles from '@patternfly/react-styles/css/components/DataList/data-list';
33

44
export interface DataListItemCellsProps extends React.HTMLProps<HTMLDivElement> {
5-
/** Additional classes added to the DataList item Content Wrapper. Children should be one ore more <DataListCell> nodes */
5+
/** Additional classes added to the data list item content wrapper. Children should be one or more <DataListCell> nodes */
66
className?: string;
77
/** Array of <DataListCell> nodes that are rendered one after the other. */
88
dataListCells?: React.ReactNode;

packages/react-core/src/components/DataList/DataListToggle.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@ import styles from '@patternfly/react-styles/css/components/DataList/data-list';
44
import { Button, ButtonProps, ButtonVariant } from '../Button';
55

66
export interface DataListToggleProps extends React.HTMLProps<HTMLDivElement> {
7-
/** Additional classes added to the DataList cell */
7+
/** Additional classes added to the data list cell */
88
className?: string;
9-
/** Flag to show if the expanded content of the DataList item is visible */
9+
/** Flag to show if the expanded content of the data list item is visible */
1010
isExpanded?: boolean;
11-
/** Identify the DataList toggle number */
11+
/** Identify the data list toggle number */
1212
id: string;
1313
/** Id for the row */
1414
rowid?: string;
15-
/** Adds accessible text to the DataList toggle */
15+
/** Adds accessible text to the data list toggle */
1616
'aria-labelledby'?: string;
17-
/** Adds accessible text to the DataList toggle */
17+
/** Adds accessible text to the data list toggle */
1818
'aria-label'?: string;
1919
/** Allows users of some screen readers to shift focus to the controlled element. Should be used when the controlled contents are not adjacent to the toggle that controls them. */
2020
'aria-controls'?: string;

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import '@testing-library/jest-dom';
12
import { render, screen } from '@testing-library/react';
23
import userEvent from '@testing-library/user-event';
34

@@ -77,6 +78,18 @@ test(`Renders with class ${styles.modifiers.plain} when isPlain is true`, () =>
7778
expect(screen.getByLabelText('list')).toHaveClass(styles.modifiers.plain);
7879
});
7980

81+
test(`Renders with ${styles.modifiers.noPlainOnGlass} when isNoPlainOnGlass is true`, () => {
82+
render(<DataList aria-label="list" isNoPlainOnGlass />);
83+
expect(screen.getByLabelText('list')).toHaveClass(styles.modifiers.noPlainOnGlass);
84+
});
85+
86+
test(`Renders with both ${styles.modifiers.plain} and ${styles.modifiers.noPlainOnGlass} when isPlain and isNoPlainOnGlass are true`, () => {
87+
render(<DataList aria-label="list" isPlain isNoPlainOnGlass />);
88+
const list = screen.getByLabelText('list');
89+
expect(list).toHaveClass(styles.modifiers.plain);
90+
expect(list).toHaveClass(styles.modifiers.noPlainOnGlass);
91+
});
92+
8093
test('Renders with a hidden input to improve a11y when onSelectableRowChange is passed', () => {
8194
render(
8295
<DataList aria-label="this is a simple list" onSelectableRowChange={() => {}}>

packages/react-integration/cypress/integration/accordion.spec.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,6 @@ describe('Accordion Demo Test', () => {
3939
.should('have.class', 'pf-m-no-plain-on-glass')
4040
.and('have.class', 'pf-m-plain');
4141

42-
/**
43-
* This test fails due to a css bug.
44-
*/
4542
cy.get('[data-testid="accordion-glass-plain-both"]').then(($el) => {
4643
const el = $el[0];
4744
const win = el.ownerDocument.defaultView;

packages/react-integration/cypress/integration/datalist.spec.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,34 @@ describe('Data List Demo Test', () => {
33
cy.visit('http://localhost:3000/data-list-demo-nav-link');
44
});
55

6+
it('in glass theme, does not apply glass plain transparent background when pf-m-no-plain-on-glass is present (even with pf-m-plain)', () => {
7+
cy.visit('http://localhost:3000/data-list-demo-nav-link');
8+
cy.document().then((doc) => {
9+
doc.documentElement.classList.add('pf-v6-theme-glass');
10+
});
11+
12+
cy.get('[data-testid="data-list-glass-plain-both"]')
13+
.should('have.class', 'pf-m-no-plain-on-glass')
14+
.and('have.class', 'pf-m-plain');
15+
16+
// Glass/plain tokens set --pf-v6-c-data-list__item--BackgroundColor on the list; items paint it.
17+
// The `<ul>` has no background-color rule, so its computed background stays transparent.
18+
cy.get('[data-testid="data-list-glass-plain-both"] .pf-v6-c-data-list__item')
19+
.first()
20+
.then(($item) => {
21+
const el = $item[0];
22+
const win = el.ownerDocument.defaultView;
23+
if (!win) {
24+
throw new Error('expected window');
25+
}
26+
const bg = win.getComputedStyle(el).backgroundColor;
27+
const fullyTransparent = bg === 'transparent' || bg === 'rgba(0, 0, 0, 0)' || bg === 'rgba(0,0,0,0)';
28+
expect(fullyTransparent, `expected non-transparent item background, got ${bg}`).to.eq(false);
29+
});
30+
});
31+
632
it('Verify rows selectable', () => {
33+
cy.visit('http://localhost:3000/data-list-demo-nav-link');
734
cy.get('#row1.pf-m-clickable').should('exist');
835
cy.get('#row2.pf-m-clickable').should('exist');
936

packages/react-integration/demo-app-ts/src/components/demos/DataListDemo/DataListDemo.tsx

Lines changed: 102 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -48,89 +48,110 @@ class DataListDemo extends Component<DataListProps, DataListState> {
4848

4949
render() {
5050
return (
51-
<DataList
52-
aria-label="Simple data list example"
53-
selectedDataListItemId={this.state.selectedDataListItemId}
54-
onSelectDataListItem={this.onSelectDataListItem}
55-
>
56-
<DataListItem aria-labelledby="simple-item1" id="row1">
57-
<DataListItemRow>
58-
<DataListItemCells
59-
dataListCells={[
60-
<DataListCell key="primary content">
61-
<span id="simple-item1">Primary content</span>
62-
</DataListCell>,
63-
<DataListCell key="secondary content">
64-
<span id="simple-item2">Secondary content</span>
65-
</DataListCell>
66-
]}
67-
/>
68-
<DataListAction
69-
aria-labelledby="selectable-action-item1 selectable-action-action1"
70-
id="selectable-action-action1"
71-
aria-label="Actions"
72-
>
73-
<Dropdown
74-
id="dropdown"
75-
isOpen={this.state.isOpen}
76-
onSelect={this.onSelect}
77-
onOpenChange={(isOpen) => this.setState({ isOpen })}
78-
toggle={(toggleRef) => (
79-
<MenuToggle
80-
variant="plain"
81-
ref={toggleRef}
82-
isExpanded={this.state.isOpen}
83-
onClick={this.onToggle}
84-
icon={<EllipsisVIcon />}
85-
/>
86-
)}
51+
<>
52+
<DataList
53+
aria-label="Simple data list example"
54+
selectedDataListItemId={this.state.selectedDataListItemId}
55+
onSelectDataListItem={this.onSelectDataListItem}
56+
>
57+
<DataListItem aria-labelledby="simple-item1" id="row1">
58+
<DataListItemRow>
59+
<DataListItemCells
60+
dataListCells={[
61+
<DataListCell key="primary content">
62+
<span id="simple-item1">Primary content</span>
63+
</DataListCell>,
64+
<DataListCell key="secondary content">
65+
<span id="simple-item2">Secondary content</span>
66+
</DataListCell>
67+
]}
68+
/>
69+
<DataListAction
70+
aria-labelledby="selectable-action-item1 selectable-action-action1"
71+
id="selectable-action-action1"
72+
aria-label="Actions"
8773
>
88-
<DropdownList>
89-
<DropdownItem key="link">Link</DropdownItem>
90-
<DropdownItem key="action">Action</DropdownItem>
91-
<DropdownItem key="disabled link" isDisabled>
92-
Disabled Link
93-
</DropdownItem>
94-
</DropdownList>
95-
</Dropdown>
96-
</DataListAction>
97-
</DataListItemRow>
98-
</DataListItem>
99-
<DataListItem aria-labelledby="simple-item2" id="row2">
100-
<DataListItemRow>
101-
<DataListItemCells
102-
dataListCells={[
103-
<DataListCell isFilled={false} key="secondary content fill">
104-
<span id="simple-item3">Secondary content (pf-m-no-fill)</span>
105-
</DataListCell>,
106-
<DataListCell isFilled={false} alignRight key="secondary content align">
107-
<span id="simple-item4">Secondary content (pf-m-align-right pf-m-no-fill)</span>
108-
</DataListCell>
109-
]}
110-
/>
111-
</DataListItemRow>
112-
</DataListItem>
113-
<DataListItem aria-labelledby="simple-item3">
114-
<DataListItemRow>
115-
<DataListItemCells
116-
dataListCells={[
117-
<DataListCell key="primary content" wrapModifier={DataListWrapModifier.breakWord}>
118-
<span id="simple-item1">Primary content</span>
119-
</DataListCell>,
120-
<DataListCell
121-
id="truncate-content"
122-
key="secondary content"
123-
wrapModifier={DataListWrapModifier.truncate}
74+
<Dropdown
75+
id="dropdown"
76+
isOpen={this.state.isOpen}
77+
onSelect={this.onSelect}
78+
onOpenChange={(isOpen) => this.setState({ isOpen })}
79+
toggle={(toggleRef) => (
80+
<MenuToggle
81+
variant="plain"
82+
ref={toggleRef}
83+
isExpanded={this.state.isOpen}
84+
onClick={this.onToggle}
85+
icon={<EllipsisVIcon />}
86+
/>
87+
)}
12488
>
125-
Really really really really really really really really really really really really really really
126-
really really really really really really really really really really really really really really long
127-
description that should be truncated before it ends
128-
</DataListCell>
129-
]}
130-
/>
131-
</DataListItemRow>
132-
</DataListItem>
133-
</DataList>
89+
<DropdownList>
90+
<DropdownItem key="link">Link</DropdownItem>
91+
<DropdownItem key="action">Action</DropdownItem>
92+
<DropdownItem key="disabled link" isDisabled>
93+
Disabled Link
94+
</DropdownItem>
95+
</DropdownList>
96+
</Dropdown>
97+
</DataListAction>
98+
</DataListItemRow>
99+
</DataListItem>
100+
<DataListItem aria-labelledby="simple-item2" id="row2">
101+
<DataListItemRow>
102+
<DataListItemCells
103+
dataListCells={[
104+
<DataListCell isFilled={false} key="secondary content fill">
105+
<span id="simple-item3">Secondary content (pf-m-no-fill)</span>
106+
</DataListCell>,
107+
<DataListCell isFilled={false} alignRight key="secondary content align">
108+
<span id="simple-item4">Secondary content (pf-m-align-right pf-m-no-fill)</span>
109+
</DataListCell>
110+
]}
111+
/>
112+
</DataListItemRow>
113+
</DataListItem>
114+
<DataListItem aria-labelledby="simple-item3">
115+
<DataListItemRow>
116+
<DataListItemCells
117+
dataListCells={[
118+
<DataListCell key="primary content" wrapModifier={DataListWrapModifier.breakWord}>
119+
<span id="simple-item1">Primary content</span>
120+
</DataListCell>,
121+
<DataListCell
122+
id="truncate-content"
123+
key="secondary content"
124+
wrapModifier={DataListWrapModifier.truncate}
125+
>
126+
Really really really really really really really really really really really really really really
127+
really really really really really really really really really really really really really really
128+
long description that should be truncated before it ends
129+
</DataListCell>
130+
]}
131+
/>
132+
</DataListItemRow>
133+
</DataListItem>
134+
</DataList>
135+
<br />
136+
<DataList
137+
data-testid="data-list-glass-plain-both"
138+
aria-label="Data list for glass theme integration test"
139+
isPlain
140+
isNoPlainOnGlass
141+
>
142+
<DataListItem aria-labelledby="glass-plain-item1">
143+
<DataListItemRow>
144+
<DataListItemCells
145+
dataListCells={[
146+
<DataListCell key="primary">
147+
<span id="glass-plain-item1">Glass theme: isPlain and isNoPlainOnGlass</span>
148+
</DataListCell>
149+
]}
150+
/>
151+
</DataListItemRow>
152+
</DataListItem>
153+
</DataList>
154+
</>
134155
);
135156
}
136157
}

0 commit comments

Comments
 (0)