Skip to content

Commit 548cd34

Browse files
authored
feat(Tile): deprecate (#10821)
* feat(Tile): deprecate in docs * moved Tile to deprecated dir * add isHidden, add example & desc * update to screenreader css, add link * rebase, use styles obj, fix screenreader application * add more spacing to icon * revert stylesheet import, adjust flex
1 parent ba620ef commit 548cd34

File tree

19 files changed

+264
-59
lines changed

19 files changed

+264
-59
lines changed

packages/react-core/src/components/Card/CardHeader.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ export interface CardHeaderSelectableActionsObject {
5454
* the isSelected prop on the card component instead.
5555
*/
5656
isChecked?: boolean;
57+
/** Flag indicating the action is hidden */
58+
isHidden?: boolean;
5759
}
5860

5961
export interface CardHeaderProps extends React.HTMLProps<HTMLDivElement> {
@@ -133,7 +135,8 @@ export const CardHeader: React.FunctionComponent<CardHeaderProps> = ({
133135

134136
const SelectableCardInput = selectableActions?.variant === 'single' ? Radio : Checkbox;
135137
const getSelectableProps = () => ({
136-
className: 'pf-m-standalone',
138+
className: css('pf-m-standalone'),
139+
inputClassName: css(selectableActions?.isHidden && 'pf-v6-screen-reader'),
137140
label: <></>,
138141
'aria-label': selectableActions.selectableActionAriaLabel,
139142
'aria-labelledby': selectableActions.selectableActionAriaLabelledby,
@@ -150,7 +153,11 @@ export const CardHeader: React.FunctionComponent<CardHeaderProps> = ({
150153
const getClickableProps = () => {
151154
const isDisabledLinkCard = isCardDisabled && isClickableLinkCard;
152155
const baseProps = {
153-
className: css('pf-v6-c-card__clickable-action', isDisabledLinkCard && styles.modifiers.disabled),
156+
className: css(
157+
'pf-v6-c-card__clickable-action',
158+
isDisabledLinkCard && styles.modifiers.disabled,
159+
selectableActions?.isHidden && 'pf-v6-screen-reader'
160+
),
154161
id: selectableActions.selectableActionId,
155162
'aria-label': selectableActions.selectableActionAriaLabel,
156163
'aria-labelledby': selectableActions.selectableActionAriaLabelledby,

packages/react-core/src/components/Card/examples/Card.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ ouia: true
1919
import pfLogo from '../../assets/PF-HorizontalLogo-Color.svg';
2020
import pfLogoSmall from '../../assets/PF-IconLogo.svg';
2121
import EllipsisVIcon from '@patternfly/react-icons/dist/esm/icons/ellipsis-v-icon';
22+
import PlusIcon from '@patternfly/react-icons/dist/esm/icons/plus-icon';
2223

2324
## Examples
2425

@@ -178,3 +179,25 @@ Dividers can be placed between sections of the card.
178179
```ts file='./CardWithDividers.tsx'
179180

180181
```
182+
183+
## Cards as tiles
184+
185+
Sets of selectable cards can be used as tiles, which are static options that users can select.
186+
187+
They can be either single selectable or multi selectable, by passing the `variant` property to the `selectableActions` object. You can also toggle the visibility of the radio or checkbox by passing the `isHidden` property to the `selectableActions` object.
188+
189+
### Single selectable tiles
190+
191+
To prevent users from selecting more than 1 tile in a set, set `variant` to "single" within the `selectableActions` object of `<CardHeader>`.
192+
193+
```ts file='./CardTile.tsx'
194+
195+
```
196+
197+
### Multi selectable tiles
198+
199+
To allow users to select more than 1 tile in a set, do not set `variant` within the `selectableActions` object of `<CardHeader>`.
200+
201+
```ts file='./CardTileMulti.tsx'
202+
203+
```
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import React from 'react';
2+
import { Card, CardHeader, CardBody, Gallery, Flex } from '@patternfly/react-core';
3+
import PlusIcon from '@patternfly/react-icons/dist/esm/icons/plus-icon';
4+
5+
export const CardTile: React.FunctionComponent = () => {
6+
const [isChecked, setIsChecked] = React.useState('');
7+
const id1 = 'tile-1';
8+
const id2 = 'tile-2';
9+
const id3 = 'tile-3';
10+
11+
const onChange = (event: React.FormEvent<HTMLInputElement>) => {
12+
setIsChecked(event.currentTarget.id);
13+
};
14+
15+
return (
16+
<Gallery hasGutter>
17+
<Card id="tile-example-1" isSelectable isSelected={isChecked === id1}>
18+
<CardHeader
19+
selectableActions={{
20+
selectableActionId: id1,
21+
selectableActionAriaLabelledby: 'tile-example-1',
22+
name: id1,
23+
variant: 'single',
24+
onChange,
25+
isHidden: true
26+
}}
27+
>
28+
<Flex gap={{ default: 'gapSm' }} alignItems={{ default: 'alignItemsCenter' }}>
29+
<PlusIcon />
30+
<b>Tile header</b>
31+
</Flex>
32+
</CardHeader>
33+
<CardBody>Tile content and description</CardBody>
34+
</Card>
35+
<Card id="tile-example-2" isSelectable isSelected={isChecked === id2}>
36+
<CardHeader
37+
selectableActions={{
38+
selectableActionId: id2,
39+
selectableActionAriaLabelledby: 'tile-example-2',
40+
name: id2,
41+
variant: 'single',
42+
onChange,
43+
isHidden: true
44+
}}
45+
>
46+
<Flex gap={{ default: 'gapSm' }} alignItems={{ default: 'alignItemsCenter' }}>
47+
<PlusIcon />
48+
<b>Tile header</b>
49+
</Flex>
50+
</CardHeader>
51+
<CardBody>Tile content and description</CardBody>
52+
</Card>
53+
<Card id="tile-example-3" isSelectable isDisabled isSelected={isChecked === id3}>
54+
<CardHeader
55+
selectableActions={{
56+
selectableActionId: id3,
57+
selectableActionAriaLabelledby: 'tile-example-3',
58+
name: id3,
59+
variant: 'single',
60+
onChange,
61+
isHidden: true
62+
}}
63+
>
64+
<Flex gap={{ default: 'gapSm' }} alignItems={{ default: 'alignItemsCenter' }}>
65+
<PlusIcon />
66+
<b>Tile header (disabled)</b>
67+
</Flex>
68+
</CardHeader>
69+
<CardBody>Tile content and description</CardBody>
70+
</Card>
71+
</Gallery>
72+
);
73+
};
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import React from 'react';
2+
import { Card, CardHeader, CardBody, Gallery, Flex } from '@patternfly/react-core';
3+
import PlusIcon from '@patternfly/react-icons/dist/esm/icons/plus-icon';
4+
5+
export const CardTileMulti: React.FunctionComponent = () => {
6+
const [isChecked1, setIsChecked1] = React.useState(false);
7+
const [isChecked2, setIsChecked2] = React.useState(false);
8+
const [isChecked3, setIsChecked3] = React.useState(false);
9+
const id1 = 'multi-tile-1';
10+
const id2 = 'multi-tile-2';
11+
const id3 = 'multi-tile-3';
12+
13+
const onChange = (event: React.FormEvent<HTMLInputElement>, checked: boolean) => {
14+
const name = event.currentTarget.name;
15+
16+
switch (name) {
17+
case id1:
18+
setIsChecked1(checked);
19+
break;
20+
case id2:
21+
setIsChecked2(checked);
22+
break;
23+
case id3:
24+
setIsChecked3(checked);
25+
break;
26+
}
27+
};
28+
29+
return (
30+
<Gallery hasGutter>
31+
<Card id="multi-tile-example-1" isSelectable isSelected={isChecked1}>
32+
<CardHeader
33+
selectableActions={{
34+
selectableActionId: id1,
35+
selectableActionAriaLabelledby: 'multi-tile-example-1',
36+
name: id1,
37+
onChange,
38+
isHidden: true
39+
}}
40+
>
41+
<Flex gap={{ default: 'gapSm' }} alignItems={{ default: 'alignItemsCenter' }}>
42+
<PlusIcon />
43+
<b>Tile header</b>
44+
</Flex>
45+
</CardHeader>
46+
<CardBody>Tile content and description</CardBody>
47+
</Card>
48+
<Card id="multi-tile-example-2" isSelectable isSelected={isChecked2}>
49+
<CardHeader
50+
selectableActions={{
51+
selectableActionId: id2,
52+
selectableActionAriaLabelledby: 'multi-tile-example-2',
53+
name: id2,
54+
onChange,
55+
isHidden: true
56+
}}
57+
>
58+
<Flex gap={{ default: 'gapSm' }} alignItems={{ default: 'alignItemsCenter' }}>
59+
<PlusIcon />
60+
<b>Tile header</b>
61+
</Flex>
62+
</CardHeader>
63+
<CardBody>Tile content and description</CardBody>
64+
</Card>
65+
<Card id="multi-tile-example-3" isSelectable isDisabled isSelected={isChecked3}>
66+
<CardHeader
67+
selectableActions={{
68+
selectableActionId: id3,
69+
selectableActionAriaLabelledby: 'multi-tile-example-3',
70+
name: id3,
71+
onChange,
72+
isHidden: true
73+
}}
74+
>
75+
<Flex gap={{ default: 'gapSm' }} alignItems={{ default: 'alignItemsCenter' }}>
76+
<PlusIcon />
77+
<b>Tile header (disabled)</b>
78+
</Flex>
79+
</CardHeader>
80+
<CardBody>Tile content and description</CardBody>
81+
</Card>
82+
</Gallery>
83+
);
84+
};

packages/react-core/src/components/Tile/examples/Tile.md

Lines changed: 0 additions & 48 deletions
This file was deleted.

packages/react-core/src/components/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ export * from './Switch';
6565
export * from './Tabs';
6666
export * from './TextArea';
6767
export * from './TextInput';
68-
export * from './Tile';
6968
export * from './TimePicker';
7069
export * from './Timestamp';
7170
export * from './Title';

0 commit comments

Comments
 (0)