Skip to content

Commit

Permalink
add responsive media component; fixes #436
Browse files Browse the repository at this point in the history
  • Loading branch information
claviska committed May 4, 2021
1 parent 86fc6b8 commit 5c619b8
Show file tree
Hide file tree
Showing 9 changed files with 125 additions and 94 deletions.
2 changes: 1 addition & 1 deletion docs/_sidebar.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
- [Radio Group](/components/radio-group.md)
- [Range](/components/range.md)
- [Rating](/components/rating.md)
- [Responsive Embed](/components/responsive-embed.md)
- [Select](/components/select.md)
- [Skeleton](/components/skeleton.md)
- [Spinner](/components/spinner.md)
Expand All @@ -59,6 +58,7 @@
- [QR Code](/components/qr-code.md)
- [Relative Time](/components/relative-time.md)
- [Resize Observer](/components/resize-observer.md)
- [Responsive Media](/components/responsive-media.md)

- Design Tokens
- [Typography](/tokens/typography.md)
Expand Down
27 changes: 0 additions & 27 deletions docs/components/responsive-embed.md

This file was deleted.

37 changes: 37 additions & 0 deletions docs/components/responsive-media.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Responsive Media

[component-header:sl-responsive-media]

Displays media in the desired aspect ratio.

You can slot in any [replaced element](https://developer.mozilla.org/en-US/docs/Web/CSS/Replaced_element), including `<iframe>`, `<img>`, and `<video>`. As the element's width changes, its height will resize proportionally. Only one element should be slotted into the container. The default aspect ratio is `16:9`.

```html preview
<sl-responsive-media>
<img src="https://images.unsplash.com/photo-1541427468627-a89a96e5ca1d?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1800&q=80" alt="A train riding through autumn foliage with mountains in the distance.">
</sl-responsive-media>
```

## Examples

### Responsive Images

The following image maintains a `4:3` aspect ratio as its container is resized.

```html preview
<sl-responsive-media aspect-ratio="4:3">
<img src="https://images.unsplash.com/photo-1473186578172-c141e6798cf4?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1800&q=80" alt="Two blue chairs on a sandy beach.">
</sl-responsive-media>
```

### Responsive Videos

The following video is embedded using an `iframe` and maintains a `16:9` aspect ratio as its container is resized.

```html preview
<sl-responsive-media aspect-ratio="16:9">
<iframe src="https://player.vimeo.com/video/1053647?title=0&byline=0&portrait=0" frameborder="0" allow="autoplay; fullscreen" allowfullscreen></iframe>
</sl-responsive-media>
```

[component-metadata:sl-responsive-media]
1 change: 1 addition & 0 deletions docs/resources/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ _During the beta period, these restrictions may be relaxed in the event of a mis

## Next

- 🚨 BREAKING: renamed `sl-responsive-embed` to `sl-responsive-media` and added support for images and videos [#436](https://github.com/shoelace-style/shoelace/issues/436)
- Fixed a bug where setting properties before an element was defined would render incorrectly [#425](https://github.com/shoelace-style/shoelace/issues/425)
- Fixed a bug that caused all modules to be imported when cherry picking certain components [#439](https://github.com/shoelace-style/shoelace/issues/439)
- Improved a11y in `sl-progress-ring`
Expand Down
19 changes: 0 additions & 19 deletions src/components/responsive-embed/responsive-embed.scss

This file was deleted.

46 changes: 0 additions & 46 deletions src/components/responsive-embed/responsive-embed.ts

This file was deleted.

35 changes: 35 additions & 0 deletions src/components/responsive-media/responsive-media.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
@use '../../styles/component';

:host {
display: block;
}

.responsive-media {
position: relative;

::slotted(*) {
position: absolute !important;
top: 0 !important;
left: 0 !important;
width: 100% !important;
height: 100% !important;
}
}

.responsive-media--cover {
::slotted(embed),
::slotted(iframe),
::slotted(img),
::slotted(video) {
object-fit: cover !important;
}
}

.responsive-media--contain {
::slotted(embed),
::slotted(iframe),
::slotted(img),
::slotted(video) {
object-fit: contain !important;
}
}
50 changes: 50 additions & 0 deletions src/components/responsive-media/responsive-media.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { LitElement, html, unsafeCSS } from 'lit';
import { customElement, property } from 'lit/decorators';
import { classMap } from 'lit-html/directives/class-map';
import styles from 'sass:./responsive-media.scss';

/**
* @since 2.0
* @status stable
*
* @slot - The element to receive the aspect ratio. Should be a replaced element, such as `<img>`, `<iframe>`, or `<video>`.
*/
@customElement('sl-responsive-media')
export default class SlResponsiveMedia extends LitElement {
static styles = unsafeCSS(styles);

/**
* The aspect ratio of the embedded media in the format of `width:height`, e.g. `16:9`, `4:3`, or `1:1`. Ratios not in
* this format will be ignored.
*/
@property({ attribute: 'aspect-ratio' }) aspectRatio = '16:9';

/** Determines how content will be resized to fit its container. */
@property() fit: 'cover' | 'contain' = 'cover';

render() {
const split = this.aspectRatio.split(':');
const x = parseInt(split[0]);
const y = parseInt(split[1]);
const paddingBottom = x && y ? `${(y / x) * 100}%` : '0';

return html`
<div
class=${classMap({
'responsive-media': true,
'responsive-media--cover': this.fit === 'cover',
'responsive-media--contain': this.fit === 'contain'
})}
style="padding-bottom: ${paddingBottom}"
>
<slot></slot>
</div>
`;
}
}

declare global {
interface HTMLElementTagNameMap {
'sl-responsive-media': SlResponsiveMedia;
}
}
2 changes: 1 addition & 1 deletion src/shoelace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export { default as SlRange } from './components/range/range';
export { default as SlRating } from './components/rating/rating';
export { default as SlRelativeTime } from './components/relative-time/relative-time';
export { default as SlResizeObserver } from './components/resize-observer/resize-observer';
export { default as SlResponsiveEmbed } from './components/responsive-embed/responsive-embed';
export { default as SlResponsiveMedia } from './components/responsive-media/responsive-media';
export { default as SlSelect } from './components/select/select';
export { default as SlSkeleton } from './components/skeleton/skeleton';
export { default as SlSpinner } from './components/spinner/spinner';
Expand Down

0 comments on commit 5c619b8

Please sign in to comment.