Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(Tile): deprecate #10821

Merged
merged 7 commits into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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'
kmcfaul marked this conversation as resolved.
Show resolved Hide resolved
),
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

kmcfaul marked this conversation as resolved.
Show resolved Hide resolved
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

kmcfaul marked this conversation as resolved.
Show resolved Hide resolved
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
Loading