@wix/design-system
Version:
@wix/design-system
482 lines (453 loc) • 16 kB
Markdown
## Feature Examples
### Structure
- description: Component consists of two main containers:<br/>
 - `<MediaOverlay>` - a parent container that accepts image or video content via `media` prop.<br/>
 - `<MediaOverlay.Content>` - child container that accepts items that should be displayed on top of a media as child elements.<br/>
- example:
```jsx
<Proportion aspectRatio={2}>
<MediaOverlay
hoverSkin="dark"
media={
<StorybookComponents.Stack
justifyContent="center"
alignItems="center"
height="100%"
>
Area for the media content
</StorybookComponents.Stack>
}
>
<MediaOverlay.Content visible="hover">
<StorybookComponents.Placeholder skin="light">
Area for overlay elements
</StorybookComponents.Placeholder>
</MediaOverlay.Content>
</MediaOverlay>
</Proportion>;
```
### Overlay content placement
- description: Control the position of overlay elements with placement prop. It supports 5 positions:<br/>
 - `top-start`<br/>
 - `top-end`<br/>
 - `middle`<br/>
 - `bottom-start`<br/>
 - `bottom-end`<br/>
- example:
```jsx
<Proportion aspectRatio={2}>
<MediaOverlay skin="gradient" media={<StorybookComponents.Placeholder />}>
<MediaOverlay.Content placement="top-start" visible="always">
<StorybookComponents.Placeholder>
Top Start
</StorybookComponents.Placeholder>
</MediaOverlay.Content>
<MediaOverlay.Content placement="top-end" visible="always">
<StorybookComponents.Placeholder>Top End</StorybookComponents.Placeholder>
</MediaOverlay.Content>
<MediaOverlay.Content placement="middle" visible="always">
<StorybookComponents.Placeholder>Middle</StorybookComponents.Placeholder>
</MediaOverlay.Content>
<MediaOverlay.Content placement="bottom-start" visible="always">
<StorybookComponents.Placeholder>
Bottom Start
</StorybookComponents.Placeholder>
</MediaOverlay.Content>
<MediaOverlay.Content placement="bottom-end" visible="always">
<StorybookComponents.Placeholder>
Bottom End
</StorybookComponents.Placeholder>
</MediaOverlay.Content>
</MediaOverlay>
</Proportion>;
```
### Initial overlay skin
- description: Control initial overlay type with `skin` prop. It supports 3 skins:<br/>
 - `none` (default) - use when no visual overlay is required.<br/>
 - `gradient` - use it when relevant data needs to be visible in a default state of the element.<br/>
 - `dark` - use it when media underneath is less important, e.g. as a last item in galleries with a total number or images on top.<br/>
- example:
```jsx
<StorybookComponents.Stack>
<Proportion>
<MediaOverlay skin="none" media="example.jpg">
<MediaOverlay.Content visible="always">None</MediaOverlay.Content>
</MediaOverlay>
</Proportion>
<Proportion>
<MediaOverlay skin="gradient" media="example.jpg">
<MediaOverlay.Content visible="always">Gradient</MediaOverlay.Content>
</MediaOverlay>
</Proportion>
<Proportion>
<MediaOverlay skin="dark" media="example.jpg">
<MediaOverlay.Content visible="always">
<Box color="D80">Dark</Box>
</MediaOverlay.Content>
</MediaOverlay>
</Proportion>
</StorybookComponents.Stack>;
```
### Hover overlay skin
- description: Control hover overlay type with `hoverSkin` prop. It supports 3 skins:<br/>
 - `none` (default) - use for static media items.<br/>
 - `gradient` - use it when hovered item must remain visible, but overlaid content needs a contrast.<br/>
 - `dark` - use it to bring the maximum contrast of relevant content on interactive element hover.<br/>
- example:
```jsx
<StorybookComponents.Stack>
<Proportion>
<MediaOverlay hoverSkin="none" media="example.jpg">
<MediaOverlay.Content visible="always">None</MediaOverlay.Content>
</MediaOverlay>
</Proportion>
<Proportion>
<MediaOverlay hoverSkin="gradient" media="example.jpg">
<MediaOverlay.Content visible="always">Gradient</MediaOverlay.Content>
</MediaOverlay>
</Proportion>
<Proportion>
<MediaOverlay hoverSkin="dark" media="example.jpg">
<MediaOverlay.Content visible="always">Dark</MediaOverlay.Content>
</MediaOverlay>
</Proportion>
</StorybookComponents.Stack>;
```
### Overlay content visibility
- description: Specify when overlay content should be revealed for the user with visible prop. It supports 3 values:<br/>
 - `default` (default) - use it to hide overlay content on element hover.<br/>
 - `hover` - use it to reveal overlay content on element hover.<br/>
 - `always` - use it to display overlay content all the time.<br/>
- example:
```jsx
<StorybookComponents.Stack>
<Proportion>
<MediaOverlay media="example.jpg">
<MediaOverlay.Content visible="default">
<StorybookComponents.Placeholder>
Visible in initial state
</StorybookComponents.Placeholder>
</MediaOverlay.Content>
</MediaOverlay>
</Proportion>
<Proportion>
<MediaOverlay media="example.jpg">
<MediaOverlay.Content visible="hover">
<StorybookComponents.Placeholder>
Visible on hover
</StorybookComponents.Placeholder>
</MediaOverlay.Content>
</MediaOverlay>
</Proportion>
<Proportion>
<MediaOverlay media="example.jpg">
<MediaOverlay.Content visible="always">
<StorybookComponents.Placeholder>
Always visible
</StorybookComponents.Placeholder>
</MediaOverlay.Content>
</MediaOverlay>
</Proportion>
</StorybookComponents.Stack>;
```
### Border radius
- description: Define border radius in pixels with `borderRadius` prop. Get rid of a default border radius with `removeRoundedBorders` prop.
- example:
```jsx
<StorybookComponents.Stack>
<Proportion>
<MediaOverlay media="example.jpg" removeRoundedBorders />
</Proportion>
<Proportion>
<MediaOverlay media="example.jpg" borderRadius="18px" />
</Proportion>
<Proportion>
<MediaOverlay media="example.jpg" borderRadius="42px" />
</Proportion>
</StorybookComponents.Stack>;
```
### Custom media element
- description: Pass a custom `media` element with media prop.
- example:
```jsx
<StorybookComponents.Stack width="25%">
<Proportion aspectRatio={1.4}>
<MediaOverlay
skin="gradient"
media={
<FillPreview fill="linear-gradient(to right top, #051937, #004d7a, #008793, #00bf72, #a8eb12)" />
}
>
<MediaOverlay.Content placement="bottom-start" visible="always">
<Text size="small" ellipsis light>
Item Title
</Text>
</MediaOverlay.Content>
</MediaOverlay>
</Proportion>
</StorybookComponents.Stack>;
```
### Drag handle
- description: Use a compound `<MediaOverlay.DragHandle />` component for reorderable components. Actions should be placed at the top right corner in this scenario.
- example:
```jsx
<StorybookComponents.Stack width="33%">
<Proportion aspectRatio={1.4}>
<MediaOverlay hoverSkin="dark" media="example.jpg">
<MediaOverlay.Content placement="top-end" visible="hover">
<IconButton priority="secondary" skin="inverted" size="tiny">
<Icons.Crop />
</IconButton>
<IconButton priority="secondary" skin="inverted" size="tiny">
<Icons.Star />
</IconButton>
<PopoverMenu
triggerElement={
<IconButton priority="secondary" skin="inverted" size="tiny">
<Icons.More />
</IconButton>
}
>
<PopoverMenu.MenuItem text="Edit" />
<PopoverMenu.MenuItem text="Preview" />
<PopoverMenu.MenuItem text="Remove" skin="destructive" />
</PopoverMenu>
</MediaOverlay.Content>
<MediaOverlay.Content visible="hover">
<MediaOverlay.DragHandle />
</MediaOverlay.Content>
</MediaOverlay>
</Proportion>
</StorybookComponents.Stack>;
```
## Common Use Case Examples
### Social media gallery
- description: Use media overlay to place identifying data, such as logo or video duration on top of a media item.
- example:
```jsx
<Box gap="30px">
<Proportion aspectRatio={1.5}>
<MediaOverlay skin="gradient" media="TravelExample7.jpg">
<MediaOverlay.Content placement="bottom-start" visible="always">
<Icons.Instagram style={{ color: 'white' }} />
</MediaOverlay.Content>
<MediaOverlay.Content placement="bottom-end" visible="always">
<Text size="small" light>
02:32
</Text>
</MediaOverlay.Content>
</MediaOverlay>
</Proportion>
<Proportion aspectRatio={1.5}>
<MediaOverlay skin="gradient" media="TravelExample8.jpg">
<MediaOverlay.Content placement="bottom-start" visible="always">
<Icons.Instagram style={{ color: 'white' }} />
</MediaOverlay.Content>
<MediaOverlay.Content placement="bottom-end" visible="always">
<Text size="small" light>
01:21
</Text>
</MediaOverlay.Content>
</MediaOverlay>
</Proportion>
<Proportion aspectRatio={1.5}>
<MediaOverlay skin="gradient" media="TravelExample9.jpg">
<MediaOverlay.Content placement="bottom-start" visible="always">
<Icons.Instagram style={{ color: 'white' }} />
</MediaOverlay.Content>
<MediaOverlay.Content placement="bottom-end" visible="always">
<Text size="small" light>
00:43
</Text>
</MediaOverlay.Content>
</MediaOverlay>
</Proportion>
</Box>;
```
### Item lists
- description: Use media overlay to list down visual items, such as dishes, that can be edited, marked as favourite or interacted with in any other way.
- example:
```jsx
() => {
const Controls = () => [
<IconButton priority="secondary" skin="inverted" size="tiny">
<Icons.Star />
</IconButton>,
<PopoverMenu
triggerElement={
<IconButton priority="secondary" skin="inverted" size="tiny">
<Icons.More />
</IconButton>
}
>
<PopoverMenu.MenuItem text="Edit" />
<PopoverMenu.MenuItem text="Preview" />
<PopoverMenu.MenuItem text="Remove" skin="destructive" />
</PopoverMenu>,
];
return (
<Box gap="30px">
<Proportion aspectRatio={1}>
<MediaOverlay skin="gradient" media="FoodExample1.jpg">
<MediaOverlay.Content placement="top-end" visible="hover">
<Controls />
</MediaOverlay.Content>
<MediaOverlay.Content placement="top-start" visible="always">
<Badge skin="success">New!</Badge>
</MediaOverlay.Content>
<MediaOverlay.Content placement="bottom-start" visible="always">
<Text size="small" weight="normal" light>
Breakfast toast
</Text>
</MediaOverlay.Content>
</MediaOverlay>
</Proportion>
<Proportion aspectRatio={1}>
<MediaOverlay skin="gradient" media="FoodExample2.jpg">
<MediaOverlay.Content placement="top-end" visible="hover">
<Controls />
</MediaOverlay.Content>
<MediaOverlay.Content placement="top-start" visible="always">
<Badge skin="neutralStandard">Popular</Badge>
</MediaOverlay.Content>
<MediaOverlay.Content placement="bottom-start" visible="always">
<Text size="small" weight="normal" light>
Lemon Ricotta Pasta
</Text>
</MediaOverlay.Content>
</MediaOverlay>
</Proportion>
<Proportion aspectRatio={1}>
<MediaOverlay skin="gradient" media="FoodExample3.jpg">
<MediaOverlay.Content placement="top-end" visible="hover">
<Controls />
</MediaOverlay.Content>
<MediaOverlay.Content placement="bottom-start" visible="always">
<Text size="small" weight="normal" light>
Spanish Paella
</Text>
</MediaOverlay.Content>
</MediaOverlay>
</Proportion>
</Box>
);
};
```
### Image gallery
- description: Use media overlay to place static data on top of an image, e.g. to place a counter indicating how many more images there are.
- example:
```jsx
<Layout gap="18px">
<Cell span={6} rows={2}>
<Image height="381px" src="TravelExample1.jpg" />
</Cell>
<Cell span={3}>
<Image height="180px" src="TravelExample2.jpg" />
</Cell>
<Cell span={3}>
<Image height="180px" src="TravelExample3.jpg" />
</Cell>
<Cell span={3}>
<Image height="180px" src="TravelExample4.jpg" />
</Cell>
<Cell span={3}>
<Box height="180px">
<MediaOverlay
skin="dark"
onClick={() => {}}
media="TravelExample5.jpg"
>
<MediaOverlay.Content visible="always">
<Heading light size="medium">
+128
</Heading>
</MediaOverlay.Content>
</MediaOverlay>
</Box>
</Cell>
</Layout>;
```
### Content edit
- description: Use media overlay to store actions related to that media element, such as edit, refresh or delete.
- example:
```jsx
<Proportion aspectRatio={1.6}>
<MediaOverlay hoverSkin="dark" media="TravelExample6.jpg">
<MediaOverlay.Content visible="hover">
<Box gap="12px" align="center">
<Button prefixIcon={<Icons.Refresh />}>Change Image</Button>
<Tooltip content="Delete">
<IconButton priority="secondary">
<Icons.Delete />
</IconButton>
</Tooltip>
</Box>
</MediaOverlay.Content>
</MediaOverlay>
</Proportion>;
```
### Reordable list
- description: Use middle placement at the center to position recordable element indication. This function should use a compound `<MediaOverlay.DragHandle/>` component.
- example:
```jsx
() => {
const Media = ({ img }) => (
<Proportion aspectRatio={1}>
<MediaOverlay hoverSkin="dark" media={img}>
<MediaOverlay.Content placement="top-end" visible="hover">
<IconButton priority="secondary" skin="inverted" size="tiny">
<Icons.Crop />
</IconButton>
<IconButton priority="secondary" skin="inverted" size="tiny">
<Icons.Star />
</IconButton>
<PopoverMenu
triggerElement={
<IconButton priority="secondary" skin="inverted" size="tiny">
<Icons.More />
</IconButton>
}
>
<PopoverMenu.MenuItem text="Edit" />
<PopoverMenu.MenuItem text="Preview" />
<PopoverMenu.MenuItem text="Remove" skin="destructive" />
</PopoverMenu>
</MediaOverlay.Content>
<MediaOverlay.Content visible="hover">
<MediaOverlay.DragHandle />
</MediaOverlay.Content>
</MediaOverlay>
</Proportion>
);
return (
<Box gap="30px">
<Media img="FoodExample4.jpg" />
<Media img="FoodExample5.jpg" />
<Media img="FoodExample6.jpg" />
</Box>
);
};
```
### Video Player
- description: Use MediaOverlay as a video player by setting `isVideo` prop to true and providing a video source via `videoSrc` prop. The component will automatically display play/pause controls and handle video playback.
- example:
```jsx
<Proportion aspectRatio={16/9}>
<MediaOverlay
isVideo
videoSrc="https://www.w3schools.com/html/mov_bbb.mp4"
hoverSkin="dark"
>
<MediaOverlay.Content placement="bottom-start" visible="always">
<Text size="small" light>
Big Buck Bunny
</Text>
</MediaOverlay.Content>
<MediaOverlay.Content placement="bottom-end" visible="always">
<Text size="small" light>
02:15
</Text>
</MediaOverlay.Content>
</MediaOverlay>
</Proportion>
```