kopia lustrzana https://github.com/shoelace-style/shoelace
Add responsive embed utility component
rodzic
e361a5cad7
commit
215ea51a26
docs
components
src
components/responsive-embed
|
@ -1,5 +1,4 @@
|
|||
- Getting Started
|
||||
|
||||
- [Overview](/)
|
||||
- [Installation](/getting-started/installation.md)
|
||||
- [Usage](/getting-started/usage.md)
|
||||
|
@ -9,9 +8,7 @@
|
|||
- [Community](/getting-started/community.md)
|
||||
|
||||
- Components
|
||||
|
||||
- [Alert](/components/alert.md)
|
||||
- [Animation](/components/animation.md)
|
||||
- [Avatar](/components/avatar.md)
|
||||
- [Badge](/components/badge.md)
|
||||
- [Button](/components/button.md)
|
||||
|
@ -49,7 +46,9 @@
|
|||
- [Tooltip](/components/tooltip.md)
|
||||
|
||||
- Utility Components
|
||||
- [Animation](/components/animation.md)
|
||||
- [Format Bytes](/components/format-bytes.md)
|
||||
- [Responsive Embed](/components/responsive-embed.md)
|
||||
|
||||
- Design Tokens
|
||||
- [Typography](/tokens/typography.md)
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
# Responsive Embed
|
||||
|
||||
[component-header:sl-responsive-embed]
|
||||
|
||||
Displays embedded media in a responsive manner based on its aspect ratio.
|
||||
|
||||
You can embed any element of the `<iframe>`, `<embed>`, or `<object>` type. The default aspect ratio is `16:9`.
|
||||
|
||||
```html preview
|
||||
<sl-responsive-embed>
|
||||
<iframe src="https://player.vimeo.com/video/1053647?title=0&byline=0&portrait=0" frameborder="0" allow="autoplay; fullscreen" allowfullscreen></iframe>
|
||||
</sl-responsive-embed>
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Aspect Ratio
|
||||
|
||||
To set the aspect ratio, use the `aspect-ratio` attribute.
|
||||
|
||||
```html preview
|
||||
<sl-responsive-embed aspect-ratio="4:3">
|
||||
<iframe src="https://www.youtube.com/embed/mM5_T-F1Yn4" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||
</sl-responsive-embed>
|
||||
```
|
||||
|
||||
[component-metadata:sl-responsive-embed]
|
|
@ -785,6 +785,12 @@ export namespace Components {
|
|||
*/
|
||||
"value": number;
|
||||
}
|
||||
interface SlResponsiveEmbed {
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
"aspectRatio": string;
|
||||
}
|
||||
interface SlSelect {
|
||||
/**
|
||||
* Set to true to add a clear button when the select is populated.
|
||||
|
@ -1282,6 +1288,12 @@ declare global {
|
|||
prototype: HTMLSlRatingElement;
|
||||
new (): HTMLSlRatingElement;
|
||||
};
|
||||
interface HTMLSlResponsiveEmbedElement extends Components.SlResponsiveEmbed, HTMLStencilElement {
|
||||
}
|
||||
var HTMLSlResponsiveEmbedElement: {
|
||||
prototype: HTMLSlResponsiveEmbedElement;
|
||||
new (): HTMLSlResponsiveEmbedElement;
|
||||
};
|
||||
interface HTMLSlSelectElement extends Components.SlSelect, HTMLStencilElement {
|
||||
}
|
||||
var HTMLSlSelectElement: {
|
||||
|
@ -1371,6 +1383,7 @@ declare global {
|
|||
"sl-radio": HTMLSlRadioElement;
|
||||
"sl-range": HTMLSlRangeElement;
|
||||
"sl-rating": HTMLSlRatingElement;
|
||||
"sl-responsive-embed": HTMLSlResponsiveEmbedElement;
|
||||
"sl-select": HTMLSlSelectElement;
|
||||
"sl-skeleton": HTMLSlSkeletonElement;
|
||||
"sl-spinner": HTMLSlSpinnerElement;
|
||||
|
@ -2211,6 +2224,12 @@ declare namespace LocalJSX {
|
|||
*/
|
||||
"value"?: number;
|
||||
}
|
||||
interface SlResponsiveEmbed {
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
"aspectRatio"?: string;
|
||||
}
|
||||
interface SlSelect {
|
||||
/**
|
||||
* Set to true to add a clear button when the select is populated.
|
||||
|
@ -2563,6 +2582,7 @@ declare namespace LocalJSX {
|
|||
"sl-radio": SlRadio;
|
||||
"sl-range": SlRange;
|
||||
"sl-rating": SlRating;
|
||||
"sl-responsive-embed": SlResponsiveEmbed;
|
||||
"sl-select": SlSelect;
|
||||
"sl-skeleton": SlSkeleton;
|
||||
"sl-spinner": SlSpinner;
|
||||
|
@ -2607,6 +2627,7 @@ declare module "@stencil/core" {
|
|||
"sl-radio": LocalJSX.SlRadio & JSXBase.HTMLAttributes<HTMLSlRadioElement>;
|
||||
"sl-range": LocalJSX.SlRange & JSXBase.HTMLAttributes<HTMLSlRangeElement>;
|
||||
"sl-rating": LocalJSX.SlRating & JSXBase.HTMLAttributes<HTMLSlRatingElement>;
|
||||
"sl-responsive-embed": LocalJSX.SlResponsiveEmbed & JSXBase.HTMLAttributes<HTMLSlResponsiveEmbedElement>;
|
||||
"sl-select": LocalJSX.SlSelect & JSXBase.HTMLAttributes<HTMLSlSelectElement>;
|
||||
"sl-skeleton": LocalJSX.SlSkeleton & JSXBase.HTMLAttributes<HTMLSlSkeletonElement>;
|
||||
"sl-spinner": LocalJSX.SlSpinner & JSXBase.HTMLAttributes<HTMLSlSpinnerElement>;
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
@import 'component';
|
||||
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.responsive-embed {
|
||||
position: relative;
|
||||
|
||||
::slotted(embed),
|
||||
::slotted(iframe),
|
||||
::slotted(object) {
|
||||
position: absolute !important;
|
||||
top: 0 !important;
|
||||
left: 0 !important;
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
import { Component, Prop, Watch, h } from '@stencil/core';
|
||||
|
||||
/**
|
||||
* @since 2.0
|
||||
* @status stable
|
||||
*
|
||||
* @part base - The component's base wrapper.
|
||||
*/
|
||||
|
||||
@Component({
|
||||
tag: 'sl-responsive-embed',
|
||||
styleUrl: 'responsive-embed.scss',
|
||||
shadow: true
|
||||
})
|
||||
export class ResponsiveEmbed {
|
||||
base: HTMLElement;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
@Prop() aspectRatio = '16:9';
|
||||
|
||||
@Watch('aspectRatio')
|
||||
handleAspectRatioChange() {
|
||||
this.setAspectRatio();
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.handleSlotChange = this.handleSlotChange.bind(this);
|
||||
}
|
||||
|
||||
handleSlotChange() {
|
||||
this.setAspectRatio();
|
||||
}
|
||||
|
||||
setAspectRatio() {
|
||||
const split = this.aspectRatio.split(':');
|
||||
const x = parseInt(split[0]);
|
||||
const y = parseInt(split[1]);
|
||||
|
||||
this.base.style.paddingBottom = x && y ? `${(y / x) * 100}%` : null;
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div ref={el => (this.base = el)} part="base" class="responsive-embed">
|
||||
<slot onSlotchange={this.handleSlotChange} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
Ładowanie…
Reference in New Issue