@rhds/elements
Version:
Red Hat Design System Elements
263 lines • 15.8 kB
JavaScript
var _RhVideoEmbed_instances, _RhVideoEmbed_slots, _RhVideoEmbed_iframe, _RhVideoEmbed_showConsent_get, _RhVideoEmbed_getIframe, _RhVideoEmbed_copyIframe, _RhVideoEmbed_handleConsentClick, _RhVideoEmbed_handleConsentKeyup, _RhVideoEmbed_handlePlayClick, _RhVideoEmbed_handlePlayKeyup, _RhVideoEmbed_playVideo;
import { __classPrivateFieldGet, __classPrivateFieldSet, __decorate } from "tslib";
import { LitElement, html, isServer } from 'lit';
import { property } from 'lit/decorators/property.js';
import { customElement } from 'lit/decorators/custom-element.js';
import { state } from 'lit/decorators/state.js';
import { classMap } from 'lit/directives/class-map.js';
import { SlotController } from '@patternfly/pfe-core/controllers/slot-controller.js';
import '@rhds/elements/rh-button/rh-button.js';
import '@rhds/elements/rh-surface/rh-surface.js';
import { themable } from '@rhds/elements/lib/themable.js';
import { css } from "lit";
const styles = css `:host{display:flex}:host([hidden]),[hidden]{display:none!important}#consent,#video{display:inline-flex;align-items:center;flex-direction:column}#video{justify-content:stretch;position:relative}::slotted([slot=thumbnail]),::slotted(iframe),figure{max-width:100%}::slotted([slot=thumbnail]){display:block}::slotted(iframe){width:100%;height:100%;position:absolute;inset-block-start:0;inset-inline-start:0;border:0}figure{--_video-focus-border-color:var(--rh-color-border-interactive);--_video-play-btn-bkg-color:light-dark(rgb(31 31 31/var(--rh-opacity-50,50%)),rgb(255 255 255/var(--rh-opacity-20,20%)));--_video-play-btn-interactive-bkg-color:light-dark(rgb(21 21 21/var(--rh-opacity-80,80%)),rgb(255 255 255/var(--rh-opacity-50,50%)));display:flex;flex-direction:column;margin:0}figcaption{margin-block-start:var(--rh-space-lg,16px)}figcaption ::slotted(p){margin-block-start:0!important}::slotted([slot=caption]){color:var(--rh-color-text-secondary);font-size:var(--rh-font-size-body-text-sm,.875rem)!important;line-height:var(--rh-line-height-body-text,1.5)}#consent,#watermark{position:absolute;inset:0}#consent{justify-content:center;container:consent/inline-size}#consent-body{display:flex;flex-direction:column;align-items:center;position:relative;text-align:center;z-index:5}#consent-message,::slotted([slot=consent-message]){font-family:var(--rh-font-family-heading,RedHatDisplay,"Red Hat Display",Helvetica,Arial,sans-serif);font-size:var(--rh-font-size-heading-xs,1.25rem);line-height:var(--rh-line-height-heading,1.3)}#consent-message,::slotted([slot=consent-message]:last-of-type){margin-block-end:var(--rh-space-lg,16px)} consent (min-width: 576px){#consent-message,::slotted([slot=consent-message]:last-of-type){margin-block-end:var(--rh-space-xl,24px)}#consent-body{padding:var(--rh-space-xl,24px)}#consent-message{font-size:var(--rh-font-size-heading-sm,1.5rem)}}#play{cursor:pointer;display:block;height:100%;inset:0;position:absolute;width:100%}#play:focus-within{border-radius:var(--rh-border-radius-default,3px);outline:var(--rh-border-width-lg,3px) solid var(--_video-focus-border-color);outline-offset:var(--rh-border-width-md,2px)}#play::part(button){background-color:var(--_video-play-btn-bkg-color,var(--rh-color-surface-darkest,#151515));inset-block:calc(50% - var(--rh-length-2xl, 32px)) 0;inset-inline:50% 0;position:absolute;outline:none;transform:translate(-50%);width:var(--rh-length-4xl,64px)}#play:active::part(button),#play:focus::part(button),#play:hover::part(button){background-color:var(--_video-play-btn-interactive-bkg-color)}#play::part(icon){color:var(--rh-color-surface)}#play[hidden],:is(.video,.consent) ::slotted([slot=thumbnail]){opacity:0;pointer-events:none}.visually-hidden{position:fixed;inset-block-start:0;inset-inline-start:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}#autoplay{position:absolute;inset:0;opacity:0;transition:opacity .2s ease-in}.video #autoplay{opacity:1}`;
export class ConsentClickEvent extends Event {
constructor() {
super('consent-click', { bubbles: true, cancelable: true });
}
}
export class VideoClickEvent extends Event {
constructor() {
super('request-play', { bubbles: true, cancelable: true });
}
}
export class VideoPlayEvent extends Event {
constructor() {
super('play', { bubbles: true, cancelable: true });
}
}
/**
* A Video embed is a graphical preview of a video overlayed with a play button. When clicked, the embedded YouTube video will begin playing.
*
* @summary Reveals a small area of information on hover
*
* @alias video-embed
*
* @fires consent-click - "Update preferences" consent button is clicked
* @fires request-play - Play button is clicked
* @fires play - Video is about to be played
*/
let RhVideoEmbed = class RhVideoEmbed extends LitElement {
constructor() {
super(...arguments);
_RhVideoEmbed_instances.add(this);
/**
* Add to `rh-video-embed` when a video requires consent for cookies
*/
this.requireConsent = false;
/**
* Boolean flag to flip with JavaScript when cookie consent has been granted or revoked.
* See the Require Consent demo for reference.
*/
this.consented = false;
// TODO(bennyp): https://lit.dev/docs/data/context/#content
this._consentClicked = false;
this._playClicked = false;
this._playStarted = false;
_RhVideoEmbed_slots.set(this, new SlotController(this, 'caption', 'thumbnail', null));
_RhVideoEmbed_iframe.set(this, void 0);
}
get consentButton() {
return this.shadowRoot?.querySelector('#consent-button');
}
get consentClicked() {
return this._consentClicked;
}
get focusableElement() {
let el;
if (__classPrivateFieldGet(this, _RhVideoEmbed_instances, "a", _RhVideoEmbed_showConsent_get)) {
el = this.consentButton;
}
else if (this.playClicked) {
el = this.iframeElement;
}
else {
el = this.playButton;
}
return el;
}
get iframeElement() {
return __classPrivateFieldGet(this, _RhVideoEmbed_iframe, "f");
}
get playButton() {
return this.shadowRoot?.querySelector('#play');
}
get playClicked() {
return this._playClicked;
}
get playStarted() {
return this._playStarted;
}
firstUpdated() {
if (!isServer) {
__classPrivateFieldSet(this, _RhVideoEmbed_iframe, __classPrivateFieldGet(this, _RhVideoEmbed_instances, "m", _RhVideoEmbed_getIframe).call(this), "f");
}
}
render() {
const { playClicked } = this;
const hasCaption = __classPrivateFieldGet(this, _RhVideoEmbed_slots, "f").hasSlotted('caption');
const hasThumbnail = __classPrivateFieldGet(this, _RhVideoEmbed_slots, "f").hasSlotted('thumbnail');
const playLabel = __classPrivateFieldGet(this, _RhVideoEmbed_iframe, "f") && __classPrivateFieldGet(this, _RhVideoEmbed_iframe, "f").title ? `${__classPrivateFieldGet(this, _RhVideoEmbed_iframe, "f").title} (play video)` : 'Play video';
const consent = __classPrivateFieldGet(this, _RhVideoEmbed_instances, "a", _RhVideoEmbed_showConsent_get);
const video = !!playClicked || !hasThumbnail;
const show = consent ? 'consent' : video ? 'video' : 'thumbnail';
return html `
<!-- The outer container for rh-video-embed -->
<figure part="figure" class="${classMap({ video, consent })}">
<!-- The container for the video, thumbnail, and play button -->
<div part="video" id="video">
<div aria-hidden="${show !== 'thumbnail'}">
<!-- Optional thumbnail image on top of video embed; should include \`alt\` text -->
<slot id="thumbnail" name="thumbnail"></slot>
</div>
<!-- Place video embed code here; iframe should include a \`title\` attribute with the video title -->
<slot></slot>
<div id="autoplay"><!--
DO NOT USE! (Used by \`rh-video-embed\`.)
--><slot name="autoplay"></slot></div>
${__classPrivateFieldGet(this, _RhVideoEmbed_instances, "a", _RhVideoEmbed_showConsent_get) ? html `
<rh-surface id="consent" color-palette="darker">
<svg id="watermark" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1136 639">
<defs>
<clipPath id="clip-path">
<rect id="Rectangle" width="1136" height="639" transform="translate(150 212)" fill="#212427"/>
</clipPath>
<clipPath id="clip-path-2">
<rect id="Rectangle_1" data-name="Rectangle 1" width="1000.925" height="756.901" fill="none"/>
</clipPath>
</defs>
<g id="Mask_Group_1" data-name="Mask Group 1" transform="translate(-150 -212)" clip-path="url(#clip-path)">
<g id="Group_2000" data-name="Group 2000" transform="translate(50.847 23.483)" opacity="0.2">
<g id="Group_1999" data-name="Group 1999" clip-path="url(#clip-path-2)">
<path id="Path_3" data-name="Path 3" d="M667.591,436.2c65.743-.063,160.93-13.755,160.857-91.955-.005-6.1-.173-12.042-1.645-17.992L787.482,156.147c-9.114-37.392-17.046-54.39-82.815-87.2C653.636,42.937,542.528-.032,509.656,0c-30.6.026-39.626,39.7-75.9,39.731-35.126.032-61.218-29.408-94.094-29.376-31.72.032-52.114,21.576-67.935,65.8,0,0-44.093,124.706-49.749,142.834a33.047,33.047,0,0,0-1.156,10.213c.047,48.45,191.011,207.231,446.766,207m171.085-60.229c9.114,43.058,9.114,47.589,9.119,53.255.074,73.68-82.641,114.546-191.432,114.645-245.953.226-461.415-143.507-461.5-238.71a97,97,0,0,1,7.889-38.543C114.352,271.234-.1,287.2,0,388.072.148,553.538,392.488,757.185,703.022,756.9c238.021-.216,297.977-107.934,297.9-192.935-.068-66.884-57.932-142.75-162.245-187.994" transform="translate(0.004 0)"/>
</g>
</g>
</g>
</svg>
<!-- The container for the consent message and consent button -->
<div part="consent-body" id="consent-body">
<!-- Text explaining opt-in to cookies is required, e.g. \`<p>View this video by opting in to “Advertising Cookies.”</p>\` -->
<slot name="consent-message">
<p id="consent-message">View this video by opting in to “Advertising Cookies.”</p>
</slot>
<rh-button
id="consent-button"
variant="tertiary"
="${__classPrivateFieldGet(this, _RhVideoEmbed_instances, "m", _RhVideoEmbed_handleConsentClick)}"
="${__classPrivateFieldGet(this, _RhVideoEmbed_instances, "m", _RhVideoEmbed_handleConsentKeyup)}"><!--
Text for CTA button to update preferences, e.g. "Update preferences"
--><slot name="consent-button-text">Update preferences</slot></rh-button>
</div>
</rh-surface>
` : ''}
<!-- The play button on top of the thumbnail -->
<rh-button part="play"
id="play"
variant="play"
?hidden="${show !== 'thumbnail'}"
="${__classPrivateFieldGet(this, _RhVideoEmbed_instances, "m", _RhVideoEmbed_handlePlayClick)}"
="${__classPrivateFieldGet(this, _RhVideoEmbed_instances, "m", _RhVideoEmbed_handlePlayKeyup)}">
<span class="visually-hidden"><!--
Text for play button; recommended value "Video title (video)"
--><slot name="play-button-text">${playLabel}</slot></span>
</rh-button>
</div>
<!-- The container for the caption -->
<figcaption part="caption" ?hidden="${!hasCaption}"><!--
Optional caption below video embed
--><slot name="caption"></slot></figcaption>
</figure>
`;
}
};
_RhVideoEmbed_slots = new WeakMap();
_RhVideoEmbed_iframe = new WeakMap();
_RhVideoEmbed_instances = new WeakSet();
_RhVideoEmbed_showConsent_get = function _RhVideoEmbed_showConsent_get() {
return this.requireConsent && !this.consented;
};
_RhVideoEmbed_getIframe = function _RhVideoEmbed_getIframe() {
const template = this.querySelector('template');
const node = template ? document.importNode(template.content, true) : undefined;
const iframe = node ?
node.querySelector('iframe')?.cloneNode(true) : undefined;
return iframe;
};
_RhVideoEmbed_copyIframe = function _RhVideoEmbed_copyIframe() {
if (__classPrivateFieldGet(this, _RhVideoEmbed_iframe, "f")) {
const url = new URL(__classPrivateFieldGet(this, _RhVideoEmbed_iframe, "f").getAttribute('src') || '');
url.searchParams.append('autoplay', '1');
url.searchParams.append('rel', '0');
__classPrivateFieldGet(this, _RhVideoEmbed_iframe, "f").src = url.href;
__classPrivateFieldGet(this, _RhVideoEmbed_iframe, "f").classList.add('rh-yt-iframe');
__classPrivateFieldGet(this, _RhVideoEmbed_iframe, "f").allow = 'autoplay';
__classPrivateFieldGet(this, _RhVideoEmbed_iframe, "f").slot = 'autoplay';
}
__classPrivateFieldGet(this, _RhVideoEmbed_instances, "m", _RhVideoEmbed_playVideo).call(this);
};
_RhVideoEmbed_handleConsentClick = function _RhVideoEmbed_handleConsentClick() {
this._consentClicked = true;
this.dispatchEvent(new ConsentClickEvent());
};
_RhVideoEmbed_handleConsentKeyup = function _RhVideoEmbed_handleConsentKeyup(event) {
switch (event.key) {
case ' ':
case 'Enter':
this._consentClicked = true;
this.dispatchEvent(new ConsentClickEvent());
break;
}
};
_RhVideoEmbed_handlePlayClick = function _RhVideoEmbed_handlePlayClick() {
if (!this.playClicked) {
this._playClicked = true;
this.dispatchEvent(new VideoClickEvent());
__classPrivateFieldGet(this, _RhVideoEmbed_instances, "m", _RhVideoEmbed_copyIframe).call(this);
}
};
_RhVideoEmbed_handlePlayKeyup = function _RhVideoEmbed_handlePlayKeyup(event) {
switch (event.key) {
case ' ':
case 'Enter':
if (!this.playClicked) {
this._playClicked = true;
this.dispatchEvent(new VideoClickEvent());
__classPrivateFieldGet(this, _RhVideoEmbed_instances, "m", _RhVideoEmbed_copyIframe).call(this);
}
break;
}
};
_RhVideoEmbed_playVideo = function _RhVideoEmbed_playVideo() {
if (!__classPrivateFieldGet(this, _RhVideoEmbed_instances, "a", _RhVideoEmbed_showConsent_get) && this.playClicked && this.iframeElement) {
this.appendChild(this.iframeElement);
this.iframeElement?.focus();
this._playStarted = true;
this.dispatchEvent(new VideoPlayEvent());
}
};
RhVideoEmbed.styles = [styles];
RhVideoEmbed.shadowRootOptions = {
...LitElement.shadowRootOptions,
delegatesFocus: true,
};
__decorate([
property({ type: Boolean, attribute: 'require-consent' })
], RhVideoEmbed.prototype, "requireConsent", void 0);
__decorate([
property({ type: Boolean })
], RhVideoEmbed.prototype, "consented", void 0);
__decorate([
state()
], RhVideoEmbed.prototype, "_consentClicked", void 0);
__decorate([
state()
], RhVideoEmbed.prototype, "_playClicked", void 0);
__decorate([
state()
], RhVideoEmbed.prototype, "_playStarted", void 0);
RhVideoEmbed = __decorate([
customElement('rh-video-embed'),
themable
], RhVideoEmbed);
export { RhVideoEmbed };
//# sourceMappingURL=rh-video-embed.js.map