Merge pull request #168 from Safelite/CSR-266-update-button-component

CSR 266 update button component
This commit is contained in:
bmauger 2022-01-26 09:54:59 -05:00 committed by GitHub
commit d504f9950f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 210 additions and 8 deletions

View file

@ -22,16 +22,18 @@
</div>
<div class="row">
<div class="col my-3 d-flex align-items-center">
<buttonPrimary
<buttonMain
isPrimary
buttonText="Primary"
loaderColor="white"
sizeInRem="1" />
sizeInRem="1"
/>
</div>
</div>
<div class="row">
<div class="col my-3 d-flex align-items-center">
<buttonSecondary
buttonText="Secondary"
<buttonMain
buttonText="secondary"
loaderColor="white"
sizeInRem="1"
/>
@ -887,8 +889,7 @@
</template>
<script>
import buttonPrimary from "@/ux-components/button-primary/button-primary";
import buttonSecondary from "@/ux-components/button-secondary/button-secondary";
import buttonMain from "@/ux-components/button-main/button-main";
import buttonBack from "@/common-components/button-back/button-back";
import listCard from "@/ux-components/list-card/list-card";
import listButton from "@/ux-components/list-button/list-button";
@ -902,8 +903,7 @@ import textLink from "@/ux-components/text-link/text-link";
export default {
name: "App",
components: {
buttonPrimary,
buttonSecondary,
buttonMain,
buttonBack,
listCard,
listButton,

View file

@ -0,0 +1,108 @@
import { shallowMount } from "@vue/test-utils";
import buttonMain from "./button-main";
import { nextTick } from "vue";
describe("buttonMain.vue", () => {
it("Should return btn-primary class", async () => {
// Act
const wrapper = shallowMount(buttonMain, {
propsData: {
isPrimary: true
},
});
// Assert
const button = wrapper.find("button");
// Expect
expect(button.attributes('class')).toContain("btn-primary");
});
it("Should return aria-disabled state", async () => {
// Act
const wrapper = shallowMount(buttonMain, {
propsData: {
isDisabled: true
},
});
// Assert
const button = wrapper.find("button");
// Expect
expect(button.attributes()["aria-disabled"]).toEqual("true");
});
it("Should return loader color", async () => {
// Act
const wrapper = shallowMount(buttonMain, {
propsData: {
loaderColor: "blue",
loaderEnabled: true
},
});
// Assert
const label = wrapper.find("label");
wrapper.vm.clicked();
await nextTick();
const loader = wrapper.find("loader-stub");
expect(loader.attributes('class')).toContain("blue");
});
it("Should return loader position", async () => {
// Act
const wrapper = shallowMount(buttonMain, {
propsData: {
loaderPosition: "right",
loaderEnabled: true
},
});
// Assert
const label = wrapper.find("label");
wrapper.vm.clicked();
await nextTick();
const loader = wrapper.find("loader-stub");
expect(loader.attributes('class')).toContain("right");
});
it("Should return loader size in rem", async () => {
// Act
const wrapper = shallowMount(buttonMain, {
propsData: {
sizeInRem: 1,
loaderEnabled: true
},
});
// Assert
const label = wrapper.find("label");
wrapper.vm.clicked();
await nextTick();
const loader = wrapper.find("loader-stub");
expect(loader.attributes('style')).toContain("1rem");
});
});

View file

@ -0,0 +1,94 @@
<template>
<button :disabled="isDisabled" :aria-disabled="isDisabled" class="btn d-flex align-items-center py-3 px-4" :class="isPrimary ? 'btn-primary' : 'btn-secondary'" @click="clicked()">
<span class="m-0">{{ this.buttonText }}</span>
<loader class="ms-2" v-if="isLoaderDisplayed" v-bind:style="{ width: `${sizeInRem}rem`, height: `${sizeInRem}rem` }" v-bind:class="[this.loaderColor, this.loaderPosition]" />
</button>
</template>
<script>
import loader from "@/ux-components/loader/loader";
export default {
name: "buttonMain",
props: {
isPrimary: Boolean,
buttonText: String,
isDisabled: Boolean,
loaderColor: String,
loaderPosition: String,
sizeInRem: [Number, String],
},
data() {
return {
isLoaderDisplayed: false,
};
},
methods: {
clicked() {
this.isLoaderDisplayed = true;
this.$emit('click-event');
}
},
components: {
loader,
},
};
</script>
<style lang="scss">
.btn {
&.btn-primary {
position: relative;
background: $blue-700;
@include blue-gradient;
border: none;
border-radius: $border-radius-lg;
color: $white;
transition: all 150ms linear;
&:hover {
background: linear-gradient(270deg, rgba(6,87,124,1) 0%, rgba(6,87,124,1) 100%);
}
&:focus, // Mouse, touch, stylus focus
&:focus-visible { // Keyboard focus for accessibility
outline: none;
box-shadow: 0 0 0 3px, 0 0 0 5.5px $blue-700;
color: $white;
@include blue-gradient;
}
&:disabled {
background: $gray-100 !important;
background: linear-gradient(270deg, $gray-100 0%, $gray-100 100%) !important;
color: $gray !important;
height: 48px;
border: none;
border-radius: $border-radius-lg;
}
}
&.btn-secondary {
position: relative;
background: transparent;
border: 1px solid $blue;
border-radius: $border-radius-lg;
color: $blue;
transition: all 150ms linear;
&:hover {
color: $white;
@include blue-gradient;
}
&:focus, // Mouse, touch, stylus focus
&:focus-visible { // Keyboard focus for accessibility
outline: none;
box-shadow: 0 0 0 3px $white, 0 0 0 5.5px $blue-700;
color: $white;
@include blue-gradient;
}
&:disabled {
background: transparent;
color: $gray !important;
height: 48px;
border: 1px solid $gray-300;
border-radius: $border-radius-lg;
}
}
}
</style>