This commit is contained in:
Kulbhushan Kaushik 2022-11-04 08:30:22 -04:00
parent a4ef1ace14
commit 3df7c33845
6 changed files with 351 additions and 8 deletions

View file

@ -0,0 +1,51 @@
import { shallowMount } from "@vue/test-utils";
import menuModal from "./menu-modal";
describe("menu-modal.vue", () => {
it("Should return text Footer Navigation", async () => {
// Act
const wrapper = shallowMount(menuModal);
// Assert
const footerModalLabel = wrapper.find("h5");
// Expect
expect(footerModalLabel.text()).toContain("Footer Navigation");
});
it("Should return footer text as Safelite Group", async () => {
// Act
const wrapper = shallowMount(menuModal);
// Assert
const modalFooter = wrapper.find("div.modal-footer");
// Expect
expect(modalFooter.text()).toContain("Safelite Group");
});
it("Should return Terms of use text link text", async () => {
// Act
const wrapper = shallowMount(menuModal);
// Expect
expect(wrapper.html()).toContain("Terms of use");
});
it("Should return Privacy policy text link text", async () => {
// Act
const wrapper = shallowMount(menuModal);
// Expect
expect(wrapper.html()).toContain("Privacy policy");
});
it("Should returnDo not sell my information text link text", async () => {
// Act
const wrapper = shallowMount(menuModal);
// Expect
expect(wrapper.html()).toContain("Do not sell my information");
});
});

View file

@ -0,0 +1,170 @@
<template>
<div class="menu-modal-container">
<button class="menu-button" type="button" :class="[isActive ? 'active' : '']" data-bs-toggle="modal" data-bs-target="#footerModal" aria-label="Hamburger Menu (modal window)">
<div class="bar1"></div>
<div class="bar2"></div>
<div class="bar3"></div>
</button>
</div>
<!-- Modal -->
<div class="modal menu-modal fade" data-bs-backdrop="false" id="footerModal" tabindex="-1" aria-labelledby="footerModalLabel" aria-hidden="true" v-on="{ 'show.bs.modal' : show, 'hide.bs.modal' : hide }" :style="`height: calc(100% - ${currentFooterAndHeaderHeight}px);`">
<div class="menu-modal-container">
<button class="menu-button" type="button" :class="[isActive ? 'active' : '']" data-bs-toggle="modal" data-bs-target="#footerModal" aria-label="Hamburger Menu (modal window)">
<div class="bar1"></div>
<div class="bar2"></div>
<div class="bar3"></div>
</button>
</div>
<div class="modal-dialog modal-fullscreen">
<div class="modal-content">
<div class="modal-header visually-hidden">
<h5 class="modal-title" id="footerModalLabel">Footer Navigation</h5>
</div>
<div class="modal-body d-flex flex-column">
<textLink linkType="navigation" text="Terms of use" href="https://www.safelite.com/terms-of-use" target="_blank" />
<textLink linkType="navigation" text="Privacy policy" href="https://www.safelite.com/safelite-group-privacy-policy" target="_blank" />
<textLink linkType="navigation" text="Do not sell my information" href="https://privacyportal-cdn.onetrust.com/dsarwebform/d3b95a93-e22e-4d4d-a806-482052406557/9e371601-eae3-4338-9430-b90b9036022b.html" target="_blank" />
</div>
<div class="modal-footer d-flex justify-content-start">
&copy; {{new Date().getFullYear()}} Safelite Group
</div>
</div>
</div>
</div>
</template>
<script>
import textLink from "@/ux-components/text-link/text-link";
export default {
name: 'menuModal',
data() {
return {
isActive: false,
currentFooterAndHeaderHeight: 0,
};
},
methods: {
show() {
this.currentFooterAndHeaderHeight = this.getFooterInfoBoxHeight() + 72;
this.isActive = true;
document.querySelector('.page-container-grouped-styles').scrollTo({
top: 0, behavior: 'smooth'
});
},
hide() {
var self = this;
self.isActive = false;
},
},
components: {
textLink,
}
}
</script>
<style lang="scss" scoped>
.menu-modal-container {
position: absolute;
padding: 1.47rem 1rem 1.47rem 1.47rem;
right: 0;
button {
border: none;
&.menu-button {
width: 1.5rem;
height: 1.5rem;
border-radius: 50%;
box-shadow: 0 2px 8px 0 rgba(0,0,0,0.2);
background-color: $white;
position: relative;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 0;//Required to prevent 'squish' on iPhone
z-index: 1050;
.bar1,
.bar2,
.bar3 {
width: 14px;
height: 2px;
background-color: $blue;
margin: 1px 0;
transition: 0.25s;
}
&.active .bar1 {
transform: rotate(-45deg) translate(-3px, 3px);
}
&.active .bar2 {opacity: 0;}
&.active .bar3 {
transform: rotate(45deg) translate(-3px, -3px);
}
}
}
}
.modal {
&.menu-modal {
max-width: 576px;
left: auto;
height: calc(100% - 72px);
top: 72px;
border-top: 1px solid $gray-300;
overflow-x: visible;
overflow-y: visible;
.modal-body {
padding: 2rem;
}
.modal-fullscreen {
width: 100vw;
max-width: 576px;
}
.navigation-link {
margin-bottom: 1.5rem;
}
.modal-footer {
border-top: none;
padding: 2rem;
}
.menu-modal-container {
position: absolute;
padding: 1.47rem 1rem 1.47rem 1.47rem;
right: 0;
top: -4.5rem;
button {
border: none;
&.menu-button {
width: 1.5rem;
height: 1.5rem;
border-radius: 50%;
box-shadow: none;
background-color: $white;
position: relative;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 0;//Required to prevent 'squish' on iPhone
z-index: 1056;
.bar1,
.bar2,
.bar3 {
width: 14px;
height: 2px;
background-color: $blue;
margin: 1px 0;
transition: 0.25s;
}
&.active .bar1 {
transform: rotate(-45deg) translate(-3px, 3px);
}
&.active .bar2 {opacity: 0;}
&.active .bar3 {
transform: rotate(45deg) translate(-3px, -3px);
}
}
}
}
//.modal-backdrop styles are in common-styles.scss
}
}
</style>

View file

@ -1,10 +1,12 @@
<template>
<div class="headerContainer">
<img id="siteHeaderImage" :src="imageSrc" :alt="altText" />
<div class="site-header d-flex justify-content-center align-items-center flex-column">
<img id="siteHeaderImage" class="img-fluid" :src="imageSrc" :alt="altText" />
<menuModal/>
</div>
</template>
<script>
import menuModal from "@/common-components/site-header/menu-modal/menu-modal";
export default({
name: "siteHeader",
props: {
@ -19,16 +21,17 @@
{
return this.getCmsContent(this.cmsWidgetName, "AltText")
}
}
},
components: {
menuModal
},
})
</script>
<style lang="scss" scoped>
.headerContainer{
width: 100%;
margin: 16px auto;
text-align: center
}
.site-header {
padding: 0.97rem 0;
}
</style>

View file

@ -19,6 +19,10 @@ export default {
getCmsContent(widgetName, fieldName) {
return this.$root.cmsContentByWidget?.[widgetName]?.[fieldName] ? this.$root.cmsContentByWidget[widgetName][fieldName] : '';
},
getFooterInfoBoxHeight() {
const footerInfoBox = document.querySelector(".footer#infoBox");
return footerInfoBox ? footerInfoBox.offsetHeight : 0;
},
},
computed: {
// store will be accessible globally as its id + 'Store'

View file

@ -0,0 +1,49 @@
import { shallowMount } from "@vue/test-utils";
import textLink from "./text-link";
describe("text-link.vue", () => {
it("Should return class navigation-link", async () => {
// Act
const wrapper = shallowMount(textLink, {
propsData: {
linkType: "navigation",
},
});
// Assert
const paragraph = wrapper.find("a");
// Expect
expect(paragraph.attributes("class")).toContain("navigation-link");
});
it("Should return class footer", async () => {
// Act
const wrapper = shallowMount(textLink, {
propsData: {
linkType: "footer",
},
});
// Assert
const paragraph = wrapper.find("a");
// Expect
expect(paragraph.attributes("class")).toContain("footer");
});
it("Should return class text-small", async () => {
// Act
const wrapper = shallowMount(textLink, {
propsData: {
linkType: "textSmall",
},
});
// Assert
const paragraph = wrapper.find("a");
// Expect
expect(paragraph.attributes("class")).toContain("small");
});
});

View file

@ -0,0 +1,66 @@
<template>
<a v-if="linkType === 'navigation'" @click="handleClick" class="navigation-link" :href="href">{{text}}</a>
<a v-else-if="linkType === 'footer'" @click="handleClick" class="footer-link" :href="href" target="_blank">{{text}}</a>
<a v-else-if="linkType === 'textSmall'" @click="handleClick" class="small" :href="href">{{text}}</a>
<a v-else-if="linkType === 'dashedUnderline'" @click="handleClick" class="dashed-underline" :href="href">{{text}}</a>
<a v-else-if="linkType === 'text'" @click="handleClick" :href="href">{{text}}</a>
</template>
<script>
export default {
name: "textLink",
props: {
linkType: String,
text: String,
href: {
type: String,
},
},
methods: {
handleClick(event) {
this.$emit("click-event");
},
},
};
</script>
<style lang="scss">
a {
display: inline-flex !important;
color: $blue;
text-underline-offset: 0.5em;
line-height: 26px;
padding: 0 0 4px 0;
font-weight: 500;
&:hover {
color: $blue-700;
}
&.small {
line-height: 24px;
&:hover {
color: $blue-700;
}
}
&.navigation-link {
color: $black;
line-height: 26px;
white-space: nowrap;
}
&.footer-link {
color: $gray-600;
text-decoration: none;
line-height: 20px;
padding: 0 0 2px 0;
font-weight: 400;
font-size: 0.75rem;
&:hover {
padding: 0 0 2px 0;
text-decoration: underline;
}
}
&.dashed-underline {
text-decoration: underline dashed 1px;
}
}
</style>