@wix/design-system
Version:
@wix/design-system
475 lines (435 loc) • 13.4 kB
Markdown
## Feature Examples
### Background
- description: Define a gallery item's background using one of the following:<br/>
 - `backgroundImageUrl` - use it to pass a link to the background image source file.<br/>
 - `backgroundImageNode` - use it to pass a custom component as a background.
- example:
```jsx
<StorybookComponents.Stack>
<CardGalleryItem
backgroundImageUrl="example.jpg"
primaryActionProps={{
label: 'Button',
}}
/>
<CardGalleryItem
backgroundImageNode=<Image height="100%" />
primaryActionProps={{
label: 'Button',
}}
/>
<CardGalleryItem
backgroundImageNode=<FillPreview fill="linear-gradient(45deg, rgba(14,0,255,1) 0%, rgba(0,212,255,1) 80%)" />
primaryActionProps={{
label: 'Button',
}}
/>
</StorybookComponents.Stack>;
```
### Image placement
- description: <p>Specify the placement of the background image using one of the following:</p><p>- <code>top</code> (default) - Places the background image on top of the footer, as a <code><MediaOverlay/></code>.</p><p>- <code>side</code> - Places the image in the footer, to the left of the title/subtitle.</p><p></p>
- example:
```jsx
<StorybookComponents.Stack>
<CardGalleryItem
backgroundImageUrl="example.jpg"
primaryActionProps={{
label: 'Button',
}}
title="Title"
imagePlacement="top"
/>
<CardGalleryItem
backgroundImageUrl="example.jpg"
primaryActionProps={{}}
title="Title"
imagePlacement="side"
/>
</StorybookComponents.Stack>;
```
### Title
- description: Give more context to a card with following props:<br/>
 - `title` - use it for a short and descriptive card title.<br/>
 - `subtitle` - use it for a short caption to provide more narrative.
- example:
```jsx
<StorybookComponents.Stack width="200px">
<CardGalleryItem
backgroundImageUrl="example.jpg"
primaryActionProps={{
label: 'Button',
}}
title="Title"
subtitle="Subtitle"
/>
</StorybookComponents.Stack>;
```
### Badge
- description: Emphasise item status with a `badge`. Use it to promote new items or highlight ones that require attention.
- example:
```jsx
<StorybookComponents.Stack width="200px">
<CardGalleryItem
backgroundImageUrl="example.jpg"
primaryActionProps={{
label: 'Button',
}}
badge={<Badge skin="standard">Badge</Badge>}
/>
</StorybookComponents.Stack>;
```
### Actions
- description: Define primary and secondary actions for an item with `primaryActionProps` and `secondaryActionProps`.
This component is an interactive element so primary action is mandatory, while the secondary button is optional.
- example:
```jsx
<StorybookComponents.Stack width="400px">
<CardGalleryItem
backgroundImageUrl="example.jpg"
primaryActionProps={{
label: 'Button',
}}
secondaryActionProps={{
label: 'Text Button',
}}
/>
<CardGalleryItem
backgroundImageUrl="example.jpg"
primaryActionProps={{
label: 'Button',
disabled: true,
disabledMessage: 'Message explaining the status',
}}
secondaryActionProps={{
label: 'Text Button',
}}
/>
</StorybookComponents.Stack>;
```
### Draggable
- description: <p>Control if the component is draggable with these properties:</p><li><code>draggable</code>: Enables drag behavior and shows an interactive drag handle on the card.</li><li><code>dragDisabled</code>: Disables dragging when draggable is enabled, keeping the drag handle visible but non-interactive.</li>
- example:
```jsx
() => (
<Box gap="20px" direction="vertical">
<Box direction="horizontal" width="600px" gap="20px">
<CardGalleryItem
backgroundImageUrl="example.jpg"
size="small"
draggable
primaryActionProps={{ label: 'Edit' }}
title="Draggable"
subtitle="Drag handle enabled"
/>
<CardGalleryItem
backgroundImageUrl="example.jpg"
size="medium"
draggable
dragDisabled
primaryActionProps={{ label: 'Edit' }}
title="Drag disabled"
subtitle="Drag handle disabled"
/>
</Box>
<Box direction="horizontal" width="600px" gap="20px">
<CardGalleryItem
backgroundImageUrl="example.jpg"
size="small"
imagePlacement="side"
draggable
primaryActionProps={{ label: 'Edit' }}
title="Draggable"
subtitle="Side layout"
/>
<CardGalleryItem
backgroundImageUrl="example.jpg"
size="medium"
imagePlacement="side"
draggable
dragDisabled
primaryActionProps={{ label: 'Edit' }}
title="Drag disabled"
subtitle="Side layout"
/>
</Box>
<Box direction="horizontal" width="600px" gap="20px">
<CardGalleryItem
backgroundImageUrl="example.jpg"
draggable
primaryActionProps={{ label: 'Edit' }}
/>
<CardGalleryItem
backgroundImageUrl="example.jpg"
draggable
dragDisabled
primaryActionProps={{ label: 'Edit' }}
/>
</Box>
</Box>
);
```
### Settings menu
- description: <p>Allow users to act on a specific item by providing a <code>settingsMenu</code>.
Popover menu can contain any required number of actions inside of it.</p>
- example:
```jsx
() => (
<Box gap="20px" direction="vertical">
<Box width="300px">
<CardGalleryItem
backgroundImageUrl="example.jpg"
size="medium"
title="Seasonal Special"
subtitle="$18.00"
primaryActionProps={{ label: 'Edit' }}
settingsMenu={
<PopoverMenu
triggerElement={({ toggle }) => (
<IconButton
size="small"
skin="light"
priority="secondary"
onClick={toggle}
dataHook="card-gallery-item-settings-button"
>
<Icons.More />
</IconButton>
)}
>
<PopoverMenu.MenuItem
text="Duplicate"
prefixIcon={<Icons.Duplicate />}
/>
<PopoverMenu.MenuItem text="Move to" prefixIcon={<Icons.MoveTo />} />
<PopoverMenu.MenuItem text="Hide" prefixIcon={<Icons.Hidden />} />
<PopoverMenu.MenuItem
text="Archive"
skin="destructive"
prefixIcon={<Icons.Delete />}
/>
</PopoverMenu>
}
/>
</Box>
</Box>
);
```
### Size
- description: <p>Control the size of the card. It supports 2 sizes:</p><p></p><p>- <code>small</code>. Use this size if the card is stretched to less than 200px.</p><p></p><p>- <code>medium</code> (default). This size is supposed to be used if the card is stretched to more than or equal 200px in the container.</p><p></p><p>Note that if <code>imagePlacement="side"</code> is enabled, the size prop will change the size of the image.</p>
- example:
```jsx
<StorybookComponents.Stack flexDirection="column">
<Box width="198px">
<CardGalleryItem
backgroundImageUrl="example.jpg"
size="small"
primaryActionProps={{
label: 'Edit',
}}
title="Title"
subtitle="Subtitle"
/>
</Box>
<Box width="300px">
<CardGalleryItem
backgroundImageUrl="example.jpg"
size="medium"
primaryActionProps={{
label: 'Edit',
}}
title="Title"
subtitle="Subtitle"
/>
</Box>
<Box width="300px">
<CardGalleryItem
backgroundImageUrl="example.jpg"
primaryActionProps={{}}
title="Title"
size="small"
imagePlacement="side"
/>
</Box>
<Box width="300px">
<CardGalleryItem
backgroundImageUrl="example.jpg"
primaryActionProps={{}}
title="Title"
size="medium"
imagePlacement="side"
/>
</Box>
</StorybookComponents.Stack>;
```
### Suffix
- description: <p>Define a component (commonly icon) to be added to the footer. Use <code>showSuffixOnHover</code> to make it appear only when hovering over the card.</p>
- example:
```jsx
<StorybookComponents.Stack>
<CardGalleryItem
backgroundImageUrl="example.jpg"
size="medium"
primaryActionProps={{
label: 'Edit',
}}
title="Title"
subtitle="Subtitle"
suffix={<Icons.Home />}
/>
<CardGalleryItem
backgroundImageUrl="example.jpg"
size="medium"
primaryActionProps={{
label: 'Edit',
}}
title="Title"
subtitle="Subtitle"
suffix={<Icons.Home />}
showSuffixOnHover
/>
</StorybookComponents.Stack>;
```
### Skin
- description: <p>Control the look of the card border with <code>skin</code> prop.</p><p>- <code>standard</code> (default) shows a shadow around the card</p><p>- <code>outlined</code> gives a one pixel border around the card</p>
- example:
```jsx
<StorybookComponents.Stack width="400px" flexDirection="column">
<CardGalleryItem
backgroundImageUrl="example.jpg"
primaryActionProps={{
label: 'Button',
}}
title="Title"
skin="standard"
imagePlacement="top"
/>
<CardGalleryItem
backgroundImageUrl="example.jpg"
primaryActionProps={{}}
title="Title"
skin="standard"
imagePlacement="side"
/>
<CardGalleryItem
backgroundImageUrl="example.jpg"
primaryActionProps={{
label: 'Button',
}}
title="Title"
skin="outlined"
imagePlacement="top"
/>
<CardGalleryItem
backgroundImageUrl="example.jpg"
primaryActionProps={{}}
title="Title"
skin="outlined"
imagePlacement="side"
/>
</StorybookComponents.Stack>;
```
### Skin visibility
- description: <p>Control if the <code>skin</code> should be visible at all times or only on hover with <code>skinVisibility</code> prop.</p>
- example:
```jsx
<StorybookComponents.Stack width="400px" flexDirection="column">
<CardGalleryItem
backgroundImageUrl="example.jpg"
primaryActionProps={{
label: 'Button',
}}
title="Title"
skinVisibility
skin="standard"
imagePlacement="top"
/>
<CardGalleryItem
backgroundImageUrl="example.jpg"
primaryActionProps={{}}
title="Title"
skinVisibility
skin="standard"
imagePlacement="side"
/>
</StorybookComponents.Stack>;
```
## Common Use Case Examples
### Product list
- description: <p>Use <code><CardGalleryItem/></code> to list down visual items, such as dishes, blog posts, products or their collections. These lists are commonly accompanied by an <code><AddItem/></code> component at the end of the list which allows users to add a new item to the grid.</p>
- example:
```jsx
() => {
const dishes = [
{
id: 'breakfast-soup',
imageSrc: 'https://images.unsplash.com/photo-1547592166-23ac45744acd?auto=format&fit=crop&w=1200&q=80',
title: 'Breakfast Soup',
subtitle: '$7.89',
badgeText: 'New',
badgeSkin: 'success',
},
{
id: 'lemon-ricotta-pasta',
imageSrc: 'https://images.unsplash.com/photo-1555949258-eb67b1ef0ceb?auto=format&fit=crop&w=1200&q=80',
title: 'Lemon Ricotta Pasta',
subtitle: '$15.99',
badgeText: 'Popular',
badgeSkin: 'standard',
},
];
return (
<Box padding="20px" gap="20px" direction="vertical">
<Card showShadow>
<Card.Header
title="Dishes"
suffix={
<Button size="small" prefixIcon={<Icons.Add />} dataHook="new-dish-button">
New Dish
</Button>
}
/>
<Card.Divider />
<Card.Content>
<Layout>
{dishes.map((dish) => (
<Cell key={dish.id} span={4}>
<CardGalleryItem
backgroundImageUrl={dish.imageSrc}
title={<Text weight="bold">{dish.title}</Text>}
subtitle={dish.subtitle}
badge={<Badge skin={dish.badgeSkin}>{dish.badgeText}</Badge>}
primaryActionProps={{ label: 'Edit' }}
settingsMenu={
<PopoverMenu
triggerElement={({ toggle }) => (
<IconButton
onClick={toggle}
skin="light"
size="small"
priority="secondary"
dataHook={`${dish.id}-menu-button`}
>
<Icons.More />
</IconButton>
)}
>
<PopoverMenu.MenuItem text="Duplicate" prefixIcon={<Icons.Duplicate />} />
<PopoverMenu.MenuItem text="Move to" prefixIcon={<Icons.MoveTo />} />
<PopoverMenu.MenuItem text="Sold out" prefixIcon={<Icons.FoodOutOfStock />} />
<PopoverMenu.MenuItem text="Hide" prefixIcon={<Icons.Hidden />} />
<PopoverMenu.MenuItem text="Archive" skin="destructive" prefixIcon={<Icons.Delete />} />
</PopoverMenu>
}
/>
</Cell>
))}
<Cell span={4}>
<AddItem size="medium" tooltipContent="Add new dish" dataHook="add-dish-item" />
</Cell>
</Layout>
</Card.Content>
</Card>
</Box>
);
};
```