Skip to content

Commit

Permalink
Merge pull request #1058 from EnergySage/CED-643-create-EsVideo
Browse files Browse the repository at this point in the history
feat: add EsVideo component
  • Loading branch information
suleiy authored Jul 27, 2023
2 parents 8732291 + c111774 commit e71b5bd
Show file tree
Hide file tree
Showing 11 changed files with 355 additions and 7 deletions.
2 changes: 1 addition & 1 deletion es-bs-base/scss/utilities/_text.scss
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@

@mixin text-colors($color, $value, $relative: true) {
.text-#{$color} {
color: $value;
color: $value !important;
}
}

Expand Down
5 changes: 5 additions & 0 deletions es-design-system/components/ds-molecules-list.vue
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,11 @@
EsVerificationCode
</b-link>
</li>
<li>
<b-link to="/molecules/es-video">
EsVideo
</b-link>
</li>
<li>
<b-link to="/molecules/es-view-more">
EsViewMore
Expand Down
19 changes: 15 additions & 4 deletions es-design-system/pages/atoms/icons.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
<div class="mb-300">
<p>
These icons are designed to work with design system components. Their size can be adjusted by passing
in <code>height</code> and <code>width</code> parameters. By default, icons will take the font color
of the container in which they're placed. To change their color, simply place the appropriate
in <code>height</code> and <code>width</code> parameters. By default, icons will take the font color of
the container in which they're placed. To change their color, simply place the appropriate
<code>text-{xxx}</code> utility class on their containing element.
</p>
<b-form-group label="Select an option to see how the icons look with that color applied.">
Expand Down Expand Up @@ -477,6 +477,17 @@
<code>IconFilePdf</code>
</li>
</ul>
<h2>
Miscellaneous Icons
</h2>
<ul
class="ds-icon-list m-0 mb-300 p-0"
:class="{ [textColorClass]: true }">
<li>
<icon-video-play />
<code>IconVideoPlay</code>
</li>
</ul>

<ds-doc-source
:doc-code="docCode"
Expand Down Expand Up @@ -521,7 +532,7 @@ export default {
},
async created() {
if (this.$prism) {
/* eslint-disable import/no-webpack-loader-syntax, import/no-self-import */
/* eslint-disable import/no-webpack-loader-syntax, import/no-self-import */
const docSource = await import('!raw-loader!./icons.vue');
/* eslint-enable import/no-webpack-loader-syntax, import/no-self-import */
Expand All @@ -534,7 +545,7 @@ export default {

<style lang="scss" scoped>
@import '~@energysage/es-bs-base/scss/bootstrap';
@import "~@energysage/es-bs-base/scss/variables";
@import '~@energysage/es-bs-base/scss/variables';
.ds-icon-list {
list-style: none;
Expand Down
48 changes: 48 additions & 0 deletions es-design-system/pages/molecules/es-video.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<template>
<div>
<h1>
Video
</h1>
<p>
Shows a YouTube video when the provided cover image is clicked.
</p>
<div>
<b-row class="justify-content-center my-200 my-lg-450">
<b-col md="8">
<es-video
alt-text="Community solar: Everything you want to know before you join"
cover-image-url="https://a-us.storyblok.com/f/1006156/1920x1080/d391440b19/energysage_thumbnail.png"
embed-url="https://www.youtube.com/embed/hgmZG3GLLNg" />
</b-col>
</b-row>
</div>
<ds-doc-source
:comp-code="compCode"
comp-source="es-vue-base/src/lib-components/EsVideo.vue"
:doc-code="docCode"
doc-source="es-design-system/pages/molecules/es-video.vue" />
</div>
</template>
<script>
export default {
name: 'EsVideoDocs',
data() {
return {
compCode: '',
docCode: '',
};
},
async created() {
if (this.$prism) {
/* eslint-disable import/no-webpack-loader-syntax, import/no-self-import */
const docSource = await import('!raw-loader!./es-video.vue');
const compSource = await import('!raw-loader!@energysage/es-vue-base/src/lib-components/EsVideo.vue');
/* eslint-enable import/no-webpack-loader-syntax, import/no-self-import */
this.docCode = this.$prism.normalizeCode(docSource.default);
this.compCode = this.$prism.normalizeCode(compSource.default);
this.$prism.highlight(this);
}
},
};
</script>
93 changes: 93 additions & 0 deletions es-vue-base/src/lib-components/EsVideo.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<template>
<div>
<b-embed
v-if="showVideo"
allowfullscreen
aspect="16by9"
:src="autoplayUrl"
:title="altText"
type="iframe" />
<es-button
v-else
class="EsVideo-button text-gray-900 border-0 p-0 position-relative text-gray w-100"
@click="showVideo = true">
<slot
v-if="hasImage"
name="image" />
<b-img
v-else-if="altText && coverImageUrl"
:alt="altText"
sizes="md:530px sm:275px"
class="EsVideo-image d-block rounded-lg w-100"
:src="coverImageUrl" />
<icon-video-play
class="EsVideo-icon position-absolute"
width="74px"
height="54px" />
</es-button>
</div>
</template>

<script lang="js">
import { BImg, BEmbed } from 'bootstrap-vue';
import IconVideoPlay from '../lib-icons/icon-video-play.vue';
export default ({
name: 'EsVideo',
components: {
BImg,
BEmbed,
IconVideoPlay,
},
props: {
altText: {
type: String,
required: true,
},
coverImageUrl: {
type: String,
required: true,
},
embedUrl: {
type: String,
required: true,
},
},
data() {
return {
showVideo: false,
};
},
computed: {
hasImage() {
return !!this.$slots.image;
},
autoplayUrl() {
const pieces = this.embedUrl.split('?');
// "&cc_load_policy=1&cc_lang_pref=en" turns closed captions on by default
// https://support.google.com/youtube/answer/171780?hl=en#zippy=%2Cadd-captions-to-an-embedded-video
// but requires that the video owner upload non-auto-generated captions
return `${pieces[0]}?rel=0&autoplay=1&cc_load_policy=1&cc_lang_pref=en`;
},
},
});
</script>

<style lang="scss" scoped>
@import '~@energysage/es-bs-base/scss/includes';
.EsVideo {
&-button,
&-image {
height: auto;
}
&-icon {
left: 50%;
top: 50%;
transform: translateX(-50%) translateY(-50%);
z-index: 2;
}
}
</style>
1 change: 1 addition & 0 deletions es-vue-base/src/lib-components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export { default as EsSupport } from './EsSupport.vue';
export { default as EsSupportCard } from './EsSupportCard.vue';
export { default as EsTab } from './EsTab.vue';
export { default as EsTabs } from './EsTabs.vue';
export { default as EsVideo } from './EsVideo.vue';
export { default as EsViewMore } from './EsViewMore.vue';
export { default as EsVerificationCode } from './EsVerificationCode.vue';
export { default as EsZipCodeForm } from './EsZipCodeForm.vue';
41 changes: 41 additions & 0 deletions es-vue-base/src/lib-icons/icon-video-play.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<template>
<svg
:style="{
height: height,
width: width,
}"
viewBox="0 0 74 54"
xmlns="http://www.w3.org/2000/svg">
<path
d="M73.987 24.269v-1.94c-.029-2.373-.2-4.701-.401-7.073-.172-2.056-.473-4.485-1.36-6.915-1.36-3.694-3.951-5.965-7.702-6.741-1.49-.317-2.992-.403-4.524-.475a866.577 866.577 0 0 0-8.633-.388L49.635.665h-3.479c-1.832 0-3.665 0-5.483-.086C39.37.536 38.068.536 36.765.536c-.916 0-1.847 0-2.763-.015h-.058c-.071 0-.157 0-.243.015l-2.92.086c-1.618 0-3.236.029-4.868.058-3.335.071-6.657.186-9.992.316a77.343 77.343 0 0 0-4.625.316c-4.91.431-8.332 3.076-9.634 7.418-.53 1.753-.902 3.593-1.131 5.649-.544 4.686-.53 9.43-.53 14.015v2.703c0 2.645.2 5.232.415 7.633.158 1.797.444 4.183 1.246 6.57 1.245 3.765 3.793 6.08 7.573 6.913 1.875.403 3.78.561 5.426.676 2.061.144 4.151.187 6.184.244 1.804.043 3.622.087 5.426.202.372.014.744.014 1.117 0h.63c1.088.014 2.19.043 3.278.057 2.148.043 4.28.086 6.428.086h.673c1.875 0 3.736-.043 5.612-.086 1.532-.029 3.063-.057 4.595-.072 3.02-.029 6.07-.172 8.934-.302l.5-.028c1.876-.087 3.823-.187 5.727-.475 4.18-.618 7.015-2.89 8.39-6.742.787-2.199 1.116-4.384 1.316-6.253.573-5.103.544-10.278.516-15.28v.029Z"
fill="currentColor"
fill-opacity=".75" />
<path
d="m47.56 26.023-17.152-9.948a1.114 1.114 0 0 0-1.675.963v19.88c0 .863.93 1.395 1.675.964l17.151-9.948a1.122 1.122 0 0 0 0-1.94v.029Z"
fill="#fff" />
</svg>
</template>

<script lang="ts">
export default {
name: 'IconVideoPlay',
props: {
/**
* Width
*/
width: {
type: String,
default: '74px',
required: false,
},
/**
* Height
*/
height: {
type: String,
default: '54px',
required: false,
},
},
};
</script>
1 change: 1 addition & 0 deletions es-vue-base/src/lib-icons/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ export { default as IconSearch } from './icon-search.vue';
export { default as IconSolar } from './icon-solar.vue';
export { default as IconTree } from './icon-tree.vue';
export { default as IconUpload } from './icon-upload.vue';
export { default as IconVideoPlay } from './icon-video-play.vue';

// marketing icons
export { default as IconBattery } from './icon-battery.vue';
Expand Down
98 changes: 98 additions & 0 deletions es-vue-base/tests/EsVideo.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import { mount } from '@vue/test-utils';
import EsVideo from '@/src/lib-components/EsVideo.vue';
import jestVue from '@/tests/jest.vue.config';
import { BImg, BEmbed } from 'bootstrap-vue';

describe('EsVideo', () => {
const slots = {
default: 'Test EsVideo Slot',
};
// Basic test; should exist for most components
test('<EsVideo />', async () => {
const wrapper = mount(EsVideo, {
...jestVue,
propsData: {
altText: 'Community solar: Everything you want to know before you join',
coverImageUrl: 'https://a-us.storyblok.com/f/1006156/1920x1080/d391440b19/energysage_thumbnail.png',
embedUrl: 'https://www.youtube.com/embed/hgmZG3GLLNg',
},
});
const a11y = await axe(wrapper.element);

expect(wrapper.vm).toBeTruthy();
expect(wrapper.html()).toMatchSnapshot();
expect(a11y).toHaveNoViolations();
});
// Image component exists when slot is empty
test('Image exists', async () => {
const wrapper = mount(EsVideo, {
...jestVue,
propsData: {
altText: 'Community solar: Everything you want to know before you join',
coverImageUrl: 'https://a-us.storyblok.com/f/1006156/1920x1080/d391440b19/energysage_thumbnail.png',
embedUrl: 'https://www.youtube.com/embed/hgmZG3GLLNg',
},
});

expect(wrapper.findComponent(BImg).exists()).toBe(true);
expect(wrapper.vm).toBeTruthy();
expect(wrapper.html()).toMatchSnapshot();
});
// Embed component exists when show video is true
test('Embed exists', async () => {
const wrapper = mount(EsVideo, {
...jestVue,
propsData: {
altText: 'Community solar: Everything you want to know before you join',
coverImageUrl: 'https://a-us.storyblok.com/f/1006156/1920x1080/d391440b19/energysage_thumbnail.png',
embedUrl: 'https://www.youtube.com/embed/hgmZG3GLLNg',
},
data() {
return {
showVideo: true,
};
},
});

expect(wrapper.findComponent(BEmbed).exists()).toBe(true);
expect(wrapper.vm).toBeTruthy();
expect(wrapper.html()).toMatchSnapshot();
});
// Test props
test('<EsVideo props />', async () => {
const wrapper = mount(EsVideo, {
...jestVue,
propsData: {
altText: 'Community solar: Everything you want to know before you join',
coverImageUrl: 'https://a-us.storyblok.com/f/1006156/1920x1080/d391440b19/energysage_thumbnail.png',
embedUrl: 'https://www.youtube.com/embed/hgmZG3GLLNg',
},
});

expect(wrapper.vm).toBeTruthy();
expect(wrapper.html()).toMatchSnapshot();

expect(wrapper.props('altText')).toBe('Community solar: Everything you want to know before you join');
expect(wrapper.props('coverImageUrl')).toBe(
'https://a-us.storyblok.com/f/1006156/1920x1080/d391440b19/energysage_thumbnail.png',
);
expect(wrapper.props('embedUrl')).toBe('https://www.youtube.com/embed/hgmZG3GLLNg');
});
// Test slot exists
test('<EsVideo slots />', async () => {
const wrapper = mount(EsVideo, {
...jestVue,
slots,
propsData: {
altText: 'Community solar: Everything you want to know before you join',
coverImageUrl: 'https://a-us.storyblok.com/f/1006156/1920x1080/d391440b19/energysage_thumbnail.png',
embedUrl: 'https://www.youtube.com/embed/hgmZG3GLLNg',
},
});

const imageSlot = wrapper.vm.$slots.default;
expect(imageSlot[0].text).toBe('Test EsVideo Slot');
expect(wrapper.vm).toBeTruthy();
expect(wrapper.html()).toMatchSnapshot();
});
});
Loading

0 comments on commit e71b5bd

Please sign in to comment.