2023-05-11 14:26:12 +02:00
import { Meta, Preview, ArgTypes } from '@storybook/blocks';
2021-09-29 14:34:40 +02:00
import { Card } from './Card';
2020-10-28 09:23:22 +02:00
import { Button } from '../Button';
import { IconButton } from '../IconButton/IconButton';
2021-09-29 14:34:40 +02:00
import { TagList } from '../Tags/TagList';
2020-10-28 09:23:22 +02:00
2021-09-29 14:34:40 +02:00
export const logo = 'https://grafana.com/static/assets/img/apple-touch-icon.png';
2020-10-28 09:23:22 +02:00
2021-09-29 14:34:40 +02:00
<Meta title="MDX/Card" component={Card} />
2020-10-28 09:23:22 +02:00
# Card
## Usage
### Basic
2021-09-29 14:34:40 +02:00
2020-11-19 09:48:56 +02:00
A basic `Card` component expects at least a heading, used as a title.
2021-09-29 14:34:40 +02:00
2020-10-28 09:23:22 +02:00
```jsx
2022-01-06 15:48:12 +00:00
<Card>
<Card.Heading>Filter by name</Card.Heading>
<Card.Description>Filter data by query.</Card.Description>
</Card>
2020-10-28 09:23:22 +02:00
```
2021-09-29 14:34:40 +02:00
2020-10-28 09:23:22 +02:00
<Preview>
2022-01-06 15:48:12 +00:00
<Card>
<Card.Heading>Filter by name</Card.Heading>
<Card.Description>Filter data by query.</Card.Description>
</Card>
2020-10-28 09:23:22 +02:00
</Preview>
### Multiple metadata elements
2021-09-29 14:34:40 +02:00
2020-11-19 09:48:56 +02:00
For providing metadata elements, which can be any extra information for the card, `Card.Meta` component should be used. If metadata consists of multiple strings, each of them has to be escaped (wrapped in brackets `{}`) or better passed in as an array.
2020-10-28 09:23:22 +02:00
```jsx
2022-01-06 15:48:12 +00:00
<Card>
<Card.Heading>Test dashboard</Card.Heading>
2021-09-29 14:34:40 +02:00
<Card.Meta>{['Folder: Test', 'Views: 100']}</Card.Meta>
2020-11-19 09:48:56 +02:00
</Card>
2020-10-28 09:23:22 +02:00
```
<Preview>
2022-01-06 15:48:12 +00:00
<Card>
<Card.Heading>Test dashboard</Card.Heading>
2021-09-29 14:34:40 +02:00
<Card.Meta>{['Folder: Test', 'Views: 100']}</Card.Meta>
2020-11-19 09:48:56 +02:00
</Card>
</Preview>
Metadata also accepts HTML elements, which could be links, for example. For elements, that are not strings, a `key` prop has to be manually specified.
```jsx
2022-01-06 15:48:12 +00:00
<Card>
<Card.Heading>Test dashboard</Card.Heading>
2021-09-29 14:34:40 +02:00
<Card.Meta>
2020-11-19 09:48:56 +02:00
Grafana
2021-09-29 14:34:40 +02:00
<a key="prom-link" href="https://ops-us-east4.grafana.net/api/prom">
https://ops-us-east4.grafana.net/api/prom
</a>
</Card.Meta>
2020-11-19 09:48:56 +02:00
</Card>
```
<Preview>
2022-01-06 15:48:12 +00:00
<Card>
<Card.Heading>Test dashboard</Card.Heading>
2020-11-19 09:48:56 +02:00
<Card.Meta>
Grafana
2021-09-29 14:34:40 +02:00
<a key="prom-link" href="https://ops-us-east4.grafana.net/api/prom">
https://ops-us-east4.grafana.net/api/prom
</a>
2020-11-19 09:48:56 +02:00
</Card.Meta>
</Card>
2020-10-28 09:23:22 +02:00
</Preview>
2021-01-19 14:23:11 +02:00
The separator for multiple metadata elements defaults to a vertical line `|`, but can be customised.
```jsx
2022-01-06 15:48:12 +00:00
<Card>
<Card.Heading>Test dashboard</Card.Heading>
2021-09-29 14:34:40 +02:00
<Card.Meta separator={'-'}>
2021-01-19 14:23:11 +02:00
Grafana
2021-09-29 14:34:40 +02:00
<a key="prom-link" href="https://ops-us-east4.grafana.net/api/prom">
https://ops-us-east4.grafana.net/api/prom
</a>
</Card.Meta>
2021-01-19 14:23:11 +02:00
</Card>
```
<Preview>
2022-01-06 15:48:12 +00:00
<Card>
<Card.Heading>Test dashboard</Card.Heading>
2021-01-19 14:23:11 +02:00
<Card.Meta separator={'-'}>
Grafana
2021-09-29 14:34:40 +02:00
<a key="prom-link" href="https://ops-us-east4.grafana.net/api/prom">
https://ops-us-east4.grafana.net/api/prom
</a>
2021-01-19 14:23:11 +02:00
</Card.Meta>
</Card>
</Preview>
2020-11-19 09:48:56 +02:00
### Tags
2021-09-29 14:34:40 +02:00
2020-11-19 09:48:56 +02:00
Tags can be rendered inside the Card, by being wrapped in `Card.Tags` component. Note that this component does not provide any tag styling and that should be handled by the children. It is recommended to use it with Grafana-UI's `TagList` component.
2020-10-28 09:23:22 +02:00
```jsx
2022-01-06 15:48:12 +00:00
<Card>
<Card.Heading>Test dashboard</Card.Heading>
<Card.Description>Card with a list of tags</Card.Description>
2020-11-19 09:48:56 +02:00
<Card.Tags>
2021-09-29 14:34:40 +02:00
<TagList tags={['tag1', 'tag2', 'tag3']} onClick={(tag) => console.log(tag)} />
2020-11-19 09:48:56 +02:00
</Card.Tags>
</Card>
2020-10-28 09:23:22 +02:00
```
<Preview>
2022-01-06 15:48:12 +00:00
<Card>
<Card.Heading>Test dashboard</Card.Heading>
<Card.Description>Card with a list of tags</Card.Description>
2020-11-19 09:48:56 +02:00
<Card.Tags>
2021-09-29 14:34:40 +02:00
<TagList tags={['tag1', 'tag2', 'tag3']} onClick={(tag) => console.log(tag)} />
2020-11-19 09:48:56 +02:00
</Card.Tags>
</Card>
2020-10-28 09:23:22 +02:00
</Preview>
### As a link
2020-11-19 09:48:56 +02:00
2022-03-10 13:52:34 +00:00
Card can be used as a clickable link item by specifying `href` prop.
2020-10-28 09:23:22 +02:00
```jsx
2022-01-06 15:48:12 +00:00
<Card href="https://grafana.com">
<Card.Heading>Redirect to Grafana</Card.Heading>
<Card.Description>Clicking this card will redirect to grafana website</Card.Description>
</Card>
2020-10-28 09:23:22 +02:00
```
2021-09-29 14:34:40 +02:00
2020-10-28 09:23:22 +02:00
<Preview>
2022-01-06 15:48:12 +00:00
<Card href="https://grafana.com">
<Card.Heading>Redirect to Grafana</Card.Heading>
<Card.Description>Clicking this card will redirect to grafana website</Card.Description>
</Card>
2020-10-28 09:23:22 +02:00
</Preview>
2022-03-10 13:52:34 +00:00
### As a button
Card can be used as a clickable buttons item by specifying `onClick` prop.
```jsx
<Card onClick={() => alert('Hello, Grafana!')}>
<Card.Heading>Hello, Grafana</Card.Heading>
<Card.Description>Clicking this card will create an alert</Card.Description>
</Card>
```
<Preview>
<Card onClick={() => alert('Hello, Grafana!')}>
<Card.Heading>Hello, Grafana</Card.Heading>
<Card.Description>Clicking this card will create an alert</Card.Description>
</Card>
</Preview>
> **Note**: When used in conjunction with [Metadata elements](#multiple-metadata-elements), clicking on any element
> inside `<Card.Meta>` will prevent the card action to be executed (either `href` to be followed or `onClick` to be called).
>
> Example:
```jsx
<Card onClick={() => alert('Hello, Grafana!')}>
<Card.Heading>Hello, Grafana</Card.Heading>
<Card.Meta>Clicking on this text (Meta) WILL NOT trigger the alert!</Card.Meta>
<Card.Description>Clicking on this text (Description) WILL trigger the alert!</Card.Description>
</Card>
```
<Preview>
<Card onClick={() => alert('Hello, Grafana!')}>
<Card.Heading>Hello, Grafana</Card.Heading>
<Card.Meta>Clicking on this text (Meta) WILL NOT trigger the alert!</Card.Meta>
<Card.Description>Clicking on this text (Description) WILL trigger the alert!</Card.Description>
</Card>
</Preview>
2020-10-28 09:23:22 +02:00
### Inside a list item
To render cards in a list, it is possible to nest them inside `li` items.
2021-09-29 14:34:40 +02:00
2020-10-28 09:23:22 +02:00
```jsx
<ul>
<li>
2022-01-06 15:48:12 +00:00
<Card>
<Card.Heading>List card item</Card.Heading>
<Card.Description>Card that is rendered inside li element.</Card.Description>
</Card>
2020-10-28 09:23:22 +02:00
</li>
<li>
2022-01-06 15:48:12 +00:00
<Card>
<Card.Heading>List card item</Card.Heading>
<Card.Description>Card that is rendered inside li element.</Card.Description>
</Card>
2020-10-28 09:23:22 +02:00
</li>
<li>
2022-01-06 15:48:12 +00:00
<Card>
<Card.Heading>List card item</Card.Heading>
<Card.Description>Card that is rendered inside li element.</Card.Description>
</Card>
2020-10-28 09:23:22 +02:00
</li>
<li>
2022-01-06 15:48:12 +00:00
<Card>
<Card.Heading>List card item</Card.Heading>
<Card.Description>Card that is rendered inside li element.</Card.Description>
</Card>
2020-10-28 09:23:22 +02:00
</li>
</ul>
```
2021-09-29 14:34:40 +02:00
2020-10-28 09:23:22 +02:00
<Preview>
2022-01-06 15:48:12 +00:00
<ul style={{ padding: '20px', maxWidth: '800px', listStyle: 'none', display: 'grid' }}>
2020-10-28 09:23:22 +02:00
<li>
2022-01-06 15:48:12 +00:00
<Card>
<Card.Heading>List card item</Card.Heading>
<Card.Description>Card that is rendered inside li element.</Card.Description>
</Card>
2020-10-28 09:23:22 +02:00
</li>
<li>
2022-01-06 15:48:12 +00:00
<Card>
<Card.Heading>List card item</Card.Heading>
<Card.Description>Card that is rendered inside li element.</Card.Description>
</Card>
2020-10-28 09:23:22 +02:00
</li>
<li>
2022-01-06 15:48:12 +00:00
<Card>
<Card.Heading>List card item</Card.Heading>
<Card.Description>Card that is rendered inside li element.</Card.Description>
</Card>
2020-10-28 09:23:22 +02:00
</li>
<li>
2022-01-06 15:48:12 +00:00
<Card>
<Card.Heading>List card item</Card.Heading>
<Card.Description>Card that is rendered inside li element.</Card.Description>
</Card>
2020-10-28 09:23:22 +02:00
</li>
</ul>
</Preview>
### With media elements
2020-11-19 09:48:56 +02:00
Cards can also be rendered with media content such icons or images. Such elements need to be wrapped in `Card.Figure` component.
2020-10-28 09:23:22 +02:00
```jsx
2022-01-06 15:48:12 +00:00
<Card>
<Card.Heading>1-ops-tools1-fallback</Card.Heading>
2020-11-19 09:48:56 +02:00
<Card.Figure>
2022-01-06 15:48:12 +00:00
<img src={logo} alt="Grafana Logo" width="40" height="40" />
2020-11-19 09:48:56 +02:00
</Card.Figure>
<Card.Meta>
Grafana
2021-09-29 14:34:40 +02:00
<a key="prom-link" href="https://ops-us-east4.grafana.net/api/prom">
https://ops-us-east4.grafana.net/api/prom
</a>
2020-11-19 09:48:56 +02:00
</Card.Meta>
</Card>
2020-10-28 09:23:22 +02:00
```
<Preview>
2022-01-06 15:48:12 +00:00
<Card>
<Card.Heading>1-ops-tools1-fallback</Card.Heading>
2020-11-19 09:48:56 +02:00
<Card.Figure>
2022-01-06 15:48:12 +00:00
<img src={logo} alt="Grafana Logo" width="40" height="40" />
2020-11-19 09:48:56 +02:00
</Card.Figure>
<Card.Meta>
Grafana
2021-09-29 14:34:40 +02:00
<a key="prom-link" href="https://ops-us-east4.grafana.net/api/prom">
https://ops-us-east4.grafana.net/api/prom
</a>
2020-11-19 09:48:56 +02:00
</Card.Meta>
</Card>
2020-10-28 09:23:22 +02:00
</Preview>
### Action Cards
2020-11-19 09:48:56 +02:00
Cards also accept primary and secondary actions. Usually the primary actions are displayed as buttons while secondary actions are displayed as icon buttons. The actions need to be wrappd in `Card.Actions` and `Card.SecondaryActions` components respectively.
2020-10-28 09:23:22 +02:00
```jsx
2022-01-06 15:48:12 +00:00
<Card>
<Card.Heading>1-ops-tools1-fallback</Card.Heading>
2020-11-19 09:48:56 +02:00
<Card.Meta>
Grafana
2021-09-29 14:34:40 +02:00
<a key="prom-link" href="https://ops-us-east4.grafana.net/api/prom">
https://ops-us-east4.grafana.net/api/prom
</a>
2020-11-19 09:48:56 +02:00
</Card.Meta>
<Card.Figure>
2022-01-06 15:48:12 +00:00
<img src={logo} alt="Grafana Logo" width="40" height="40" />
2020-11-19 09:48:56 +02:00
</Card.Figure>
<Card.Actions>
2021-09-29 14:34:40 +02:00
<Button key="settings" variant="secondary">
Settings
</Button>
<Button key="explore" variant="secondary">
Explore
</Button>
2020-11-19 09:48:56 +02:00
</Card.Actions>
<Card.SecondaryActions>
<IconButton key="showAll" name="apps" tooltip="Show all dashboards for this data source" />
<IconButton key="delete" name="trash-alt" tooltip="Delete this data source" />
</Card.SecondaryActions>
</Card>
2020-10-28 09:23:22 +02:00
```
<Preview>
2022-01-06 15:48:12 +00:00
<Card>
<Card.Heading>1-ops-tools1-fallback</Card.Heading>
2020-11-19 09:48:56 +02:00
<Card.Meta>
Grafana
2021-09-29 14:34:40 +02:00
<a key="prom-link" href="https://ops-us-east4.grafana.net/api/prom">
https://ops-us-east4.grafana.net/api/prom
</a>
2020-11-19 09:48:56 +02:00
</Card.Meta>
<Card.Figure>
2022-01-06 15:48:12 +00:00
<img src={logo} alt="Grafana Logo" width="40" height="40" />
2020-11-19 09:48:56 +02:00
</Card.Figure>
<Card.Actions>
2021-09-29 14:34:40 +02:00
<Button key="settings" variant="secondary">
Settings
</Button>
<Button key="explore" variant="secondary">
Explore
</Button>
2020-11-19 09:48:56 +02:00
</Card.Actions>
<Card.SecondaryActions>
<IconButton key="showAll" name="apps" tooltip="Show all dashboards for this data source" />
<IconButton key="delete" name="trash-alt" tooltip="Delete this data source" />
</Card.SecondaryActions>
</Card>
2020-10-28 09:23:22 +02:00
</Preview>
### Disabled state
2020-11-19 09:48:56 +02:00
Card can have a disabled state, effectively making it and its actions non-clickable. If there are any actions, they will be disabled instead of the whole card.
2020-10-28 09:23:22 +02:00
```jsx
2022-01-06 15:48:12 +00:00
<Card disabled>
<Card.Heading>1-ops-tools1-fallback</Card.Heading>
2020-11-19 09:48:56 +02:00
<Card.Meta>
Grafana
2021-09-29 14:34:40 +02:00
<a key="prom-link" href="https://ops-us-east4.grafana.net/api/prom">
https://ops-us-east4.grafana.net/api/prom
</a>
2020-11-19 09:48:56 +02:00
</Card.Meta>
<Card.Figure>
2022-01-06 15:48:12 +00:00
<img src={logo} alt="Grafana Logo" width="40" height="40" />
2020-11-19 09:48:56 +02:00
</Card.Figure>
</Card>
2020-10-28 09:23:22 +02:00
```
<Preview>
2022-01-06 15:48:12 +00:00
<Card disabled>
<Card.Heading>1-ops-tools1-fallback</Card.Heading>
2020-11-19 09:48:56 +02:00
<Card.Meta>
Grafana
2021-09-29 14:34:40 +02:00
<a key="prom-link" href="https://ops-us-east4.grafana.net/api/prom">
https://ops-us-east4.grafana.net/api/prom
</a>
2020-11-19 09:48:56 +02:00
</Card.Meta>
<Card.Figure>
2022-01-06 15:48:12 +00:00
<img src={logo} alt="Grafana Logo" width="40" height="40" />
2020-11-19 09:48:56 +02:00
</Card.Figure>
</Card>
2020-10-28 09:23:22 +02:00
</Preview>
```jsx
2022-01-06 15:48:12 +00:00
<Card disabled>
<Card.Heading>1-ops-tools1-fallback</Card.Heading>
2020-11-19 09:48:56 +02:00
<Card.Meta>
Grafana
2021-09-29 14:34:40 +02:00
<a key="prom-link" href="https://ops-us-east4.grafana.net/api/prom">
https://ops-us-east4.grafana.net/api/prom
</a>
2020-11-19 09:48:56 +02:00
</Card.Meta>
<Card.Figure>
2022-01-06 15:48:12 +00:00
<img src={logo} alt="Grafana Logo" width="40" height="40" />
2020-11-19 09:48:56 +02:00
</Card.Figure>
<Card.Actions>
2021-09-29 14:34:40 +02:00
<Button key="settings" variant="secondary">
Settings
</Button>
<Button key="explore" variant="secondary">
Explore
</Button>
2020-11-19 09:48:56 +02:00
</Card.Actions>
<Card.SecondaryActions>
<IconButton key="showAll" name="apps" tooltip="Show all dashboards for this data source" />
<IconButton key="delete" name="trash-alt" tooltip="Delete this data source" />
</Card.SecondaryActions>
</Card>
2020-10-28 09:23:22 +02:00
```
<Preview>
2022-01-06 15:48:12 +00:00
<Card disabled>
<Card.Heading>1-ops-tools1-fallback</Card.Heading>
2020-11-19 09:48:56 +02:00
<Card.Meta>
Grafana
2021-09-29 14:34:40 +02:00
<a key="prom-link" href="https://ops-us-east4.grafana.net/api/prom">
https://ops-us-east4.grafana.net/api/prom
</a>
2020-11-19 09:48:56 +02:00
</Card.Meta>
<Card.Figure>
2022-01-06 15:48:12 +00:00
<img src={logo} alt="Grafana Logo" width="40" height="40" />
2020-11-19 09:48:56 +02:00
</Card.Figure>
<Card.Actions>
2021-09-29 14:34:40 +02:00
<Button key="settings" variant="secondary">
Settings
</Button>
<Button key="explore" variant="secondary">
Explore
</Button>
2020-11-19 09:48:56 +02:00
</Card.Actions>
<Card.SecondaryActions>
<IconButton key="showAll" name="apps" tooltip="Show all dashboards for this data source" />
<IconButton key="delete" name="trash-alt" tooltip="Delete this data source" />
</Card.SecondaryActions>
</Card>
2020-10-28 09:23:22 +02:00
</Preview>
2022-02-28 11:23:23 +01:00
### Selectable
```jsx
<Card isSelected disabled>
<Card.Heading>Option #1</Card.Heading>
<Card.Meta>This is a really great option, you won't regret it.</Card.Meta>
<Card.Figure>
<img src={logo} alt="Grafana Logo" width="40" height="40" />
</Card.Figure>
</Card>
```
<Preview>
<Card isSelected disabled>
<Card.Heading>Option #1</Card.Heading>
<Card.Description>This is a really great option, you won't regret it.</Card.Description>
<Card.Figure>
<img src={logo} alt="Grafana Logo" width="40" height="40" />
</Card.Figure>
</Card>
</Preview>
2020-10-28 09:23:22 +02:00
### Props
2023-05-11 14:26:12 +02:00
<ArgTypes of={Card} />