Skip to content

Commit

Permalink
feat(Tile): deprecate (#10821)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
kmcfaul authored Sep 26, 2024
1 parent ba620ef commit 548cd34
Show file tree
Hide file tree
Showing 19 changed files with 264 additions and 59 deletions.
11 changes: 9 additions & 2 deletions packages/react-core/src/components/Card/CardHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ export interface CardHeaderSelectableActionsObject {
* the isSelected prop on the card component instead.
*/
isChecked?: boolean;
/** Flag indicating the action is hidden */
isHidden?: boolean;
}

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

const SelectableCardInput = selectableActions?.variant === 'single' ? Radio : Checkbox;
const getSelectableProps = () => ({
className: 'pf-m-standalone',
className: css('pf-m-standalone'),
inputClassName: css(selectableActions?.isHidden && 'pf-v6-screen-reader'),
label: <></>,
'aria-label': selectableActions.selectableActionAriaLabel,
'aria-labelledby': selectableActions.selectableActionAriaLabelledby,
Expand All @@ -150,7 +153,11 @@ export const CardHeader: React.FunctionComponent<CardHeaderProps> = ({
const getClickableProps = () => {
const isDisabledLinkCard = isCardDisabled && isClickableLinkCard;
const baseProps = {
className: css('pf-v6-c-card__clickable-action', isDisabledLinkCard && styles.modifiers.disabled),
className: css(
'pf-v6-c-card__clickable-action',
isDisabledLinkCard && styles.modifiers.disabled,
selectableActions?.isHidden && 'pf-v6-screen-reader'
),
id: selectableActions.selectableActionId,
'aria-label': selectableActions.selectableActionAriaLabel,
'aria-labelledby': selectableActions.selectableActionAriaLabelledby,
Expand Down
23 changes: 23 additions & 0 deletions packages/react-core/src/components/Card/examples/Card.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ ouia: true
import pfLogo from '../../assets/PF-HorizontalLogo-Color.svg';
import pfLogoSmall from '../../assets/PF-IconLogo.svg';
import EllipsisVIcon from '@patternfly/react-icons/dist/esm/icons/ellipsis-v-icon';
import PlusIcon from '@patternfly/react-icons/dist/esm/icons/plus-icon';

## Examples

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

```

## Cards as tiles

Sets of selectable cards can be used as tiles, which are static options that users can select.

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.

### Single selectable tiles

To prevent users from selecting more than 1 tile in a set, set `variant` to "single" within the `selectableActions` object of `<CardHeader>`.

```ts file='./CardTile.tsx'

```

### Multi selectable tiles

To allow users to select more than 1 tile in a set, do not set `variant` within the `selectableActions` object of `<CardHeader>`.

```ts file='./CardTileMulti.tsx'

```
73 changes: 73 additions & 0 deletions packages/react-core/src/components/Card/examples/CardTile.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import React from 'react';
import { Card, CardHeader, CardBody, Gallery, Flex } from '@patternfly/react-core';
import PlusIcon from '@patternfly/react-icons/dist/esm/icons/plus-icon';

export const CardTile: React.FunctionComponent = () => {
const [isChecked, setIsChecked] = React.useState('');
const id1 = 'tile-1';
const id2 = 'tile-2';
const id3 = 'tile-3';

const onChange = (event: React.FormEvent<HTMLInputElement>) => {
setIsChecked(event.currentTarget.id);
};

return (
<Gallery hasGutter>
<Card id="tile-example-1" isSelectable isSelected={isChecked === id1}>
<CardHeader
selectableActions={{
selectableActionId: id1,
selectableActionAriaLabelledby: 'tile-example-1',
name: id1,
variant: 'single',
onChange,
isHidden: true
}}
>
<Flex gap={{ default: 'gapSm' }} alignItems={{ default: 'alignItemsCenter' }}>
<PlusIcon />
<b>Tile header</b>
</Flex>
</CardHeader>
<CardBody>Tile content and description</CardBody>
</Card>
<Card id="tile-example-2" isSelectable isSelected={isChecked === id2}>
<CardHeader
selectableActions={{
selectableActionId: id2,
selectableActionAriaLabelledby: 'tile-example-2',
name: id2,
variant: 'single',
onChange,
isHidden: true
}}
>
<Flex gap={{ default: 'gapSm' }} alignItems={{ default: 'alignItemsCenter' }}>
<PlusIcon />
<b>Tile header</b>
</Flex>
</CardHeader>
<CardBody>Tile content and description</CardBody>
</Card>
<Card id="tile-example-3" isSelectable isDisabled isSelected={isChecked === id3}>
<CardHeader
selectableActions={{
selectableActionId: id3,
selectableActionAriaLabelledby: 'tile-example-3',
name: id3,
variant: 'single',
onChange,
isHidden: true
}}
>
<Flex gap={{ default: 'gapSm' }} alignItems={{ default: 'alignItemsCenter' }}>
<PlusIcon />
<b>Tile header (disabled)</b>
</Flex>
</CardHeader>
<CardBody>Tile content and description</CardBody>
</Card>
</Gallery>
);
};
84 changes: 84 additions & 0 deletions packages/react-core/src/components/Card/examples/CardTileMulti.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import React from 'react';
import { Card, CardHeader, CardBody, Gallery, Flex } from '@patternfly/react-core';
import PlusIcon from '@patternfly/react-icons/dist/esm/icons/plus-icon';

export const CardTileMulti: React.FunctionComponent = () => {
const [isChecked1, setIsChecked1] = React.useState(false);
const [isChecked2, setIsChecked2] = React.useState(false);
const [isChecked3, setIsChecked3] = React.useState(false);
const id1 = 'multi-tile-1';
const id2 = 'multi-tile-2';
const id3 = 'multi-tile-3';

const onChange = (event: React.FormEvent<HTMLInputElement>, checked: boolean) => {
const name = event.currentTarget.name;

switch (name) {
case id1:
setIsChecked1(checked);
break;
case id2:
setIsChecked2(checked);
break;
case id3:
setIsChecked3(checked);
break;
}
};

return (
<Gallery hasGutter>
<Card id="multi-tile-example-1" isSelectable isSelected={isChecked1}>
<CardHeader
selectableActions={{
selectableActionId: id1,
selectableActionAriaLabelledby: 'multi-tile-example-1',
name: id1,
onChange,
isHidden: true
}}
>
<Flex gap={{ default: 'gapSm' }} alignItems={{ default: 'alignItemsCenter' }}>
<PlusIcon />
<b>Tile header</b>
</Flex>
</CardHeader>
<CardBody>Tile content and description</CardBody>
</Card>
<Card id="multi-tile-example-2" isSelectable isSelected={isChecked2}>
<CardHeader
selectableActions={{
selectableActionId: id2,
selectableActionAriaLabelledby: 'multi-tile-example-2',
name: id2,
onChange,
isHidden: true
}}
>
<Flex gap={{ default: 'gapSm' }} alignItems={{ default: 'alignItemsCenter' }}>
<PlusIcon />
<b>Tile header</b>
</Flex>
</CardHeader>
<CardBody>Tile content and description</CardBody>
</Card>
<Card id="multi-tile-example-3" isSelectable isDisabled isSelected={isChecked3}>
<CardHeader
selectableActions={{
selectableActionId: id3,
selectableActionAriaLabelledby: 'multi-tile-example-3',
name: id3,
onChange,
isHidden: true
}}
>
<Flex gap={{ default: 'gapSm' }} alignItems={{ default: 'alignItemsCenter' }}>
<PlusIcon />
<b>Tile header (disabled)</b>
</Flex>
</CardHeader>
<CardBody>Tile content and description</CardBody>
</Card>
</Gallery>
);
};
48 changes: 0 additions & 48 deletions packages/react-core/src/components/Tile/examples/Tile.md

This file was deleted.

1 change: 0 additions & 1 deletion packages/react-core/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ export * from './Switch';
export * from './Tabs';
export * from './TextArea';
export * from './TextInput';
export * from './Tile';
export * from './TimePicker';
export * from './Timestamp';
export * from './Title';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,80 @@
---
id: Tile
section: components
cssPrefix: pf-v6-c-tile
propComponents: ['Tile']
deprecated: true
---

import PlusIcon from '@patternfly/react-icons/dist/esm/icons/plus-icon';
import BellIcon from '@patternfly/react-icons/dist/esm/icons/bell-icon';
import './Tile.css';

**Note:** Tile has been deprecated. Use the [card](/components/card#cards-as-tiles) component instead.

## Examples

Keyboard interaction patterns and a11y is implemented in the Tile demos, located in the [Demo section](/components/tile/react-demos).

### Basic tile

Basic tiles can appear in one of three states: a default state, selected state, and a disabled state. To change the state of a tile, use the properties `isSelected` and `isDisabled`.

```ts file="./TileBasic.tsx"

```

### With subtext

Tile subtext can provide users with additional context. To add subtext, pass a short description to the `<Tile>` component.

```ts file="./TileWithSubtext.tsx"

```

### With icon

Icons can provide a visual cue that helps users understand what the tile is being used for. To add an icon, use the `icon` property.

```ts file="./TileWithIcon.tsx"

```

### With stacked icon

You can further customize a tile’s appearance by placing an icon above the title. To stack your icon on top of a tile’s title, use the `isStacked` property.

```ts file="./TileStacked.tsx"

```

### With large icons

You can make your icons larger to help catch a user’s attention. To increase the size of an icon, use the `isDisplayLarge` property.

Be aware that `isDisplayLarge` can only be used when `isStacked` is also applied.

```ts file="./TileStackedWithLargeIcons.tsx"

```

### With long subtext

To provide users with a large amount of context, subtext can be elongated to wrap around to the next line. To format a long subtext, you can pass the component `Flex` into `<Tile>`.

You can also change the type of `Flex` you can use so that the line breaks in the subtext fits your needs. You can do this by changing the default flex. The standard is `default: “flex_1”`, and changing the number in the default will also change where the sentence breaks.

```ts file="./TileWithExtraContent.tsx"

```

## Demos

### Tiles with single selection

```ts
import React from 'react';
import { Tile } from '@patternfly/react-core';
import { Tile } from '@patternfly/react-core/deprecated';

const TileSingleSelect: React.FunctionComponent = () => {
const [selectedId, setSelectedId] = React.useState<string>('');
Expand Down Expand Up @@ -40,7 +105,7 @@ const TileSingleSelect: React.FunctionComponent = () => {

```ts
import React from 'react';
import { Tile } from '@patternfly/react-core';
import { Tile } from '@patternfly/react-core/deprecated';

const TileMultiSelect: React.FunctionComponent = () => {
const [selectedIds, setSelectedIds] = React.useState<string[]>([]);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { Tile } from '@patternfly/react-core';
import { Tile } from '@patternfly/react-core/deprecated';

export const TileBasic: React.FunctionComponent = () => (
<div role="listbox" aria-label="Basic tiles">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { Tile } from '@patternfly/react-core';
import { Tile } from '@patternfly/react-core/deprecated';
import BellIcon from '@patternfly/react-icons/dist/esm/icons/bell-icon';

export const TileStacked: React.FunctionComponent = () => (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { Tile } from '@patternfly/react-core';
import { Tile } from '@patternfly/react-core/deprecated';
import BellIcon from '@patternfly/react-icons/dist/esm/icons/bell-icon';

export const TileStackedWithLargeIcons: React.FunctionComponent = () => (
Expand Down
Loading

0 comments on commit 548cd34

Please sign in to comment.