Merge pull request #168 from Safelite/CSR-266-update-button-component
CSR 266 update button component
This commit is contained in:
commit
d504f9950f
3 changed files with 210 additions and 8 deletions
|
|
@ -22,16 +22,18 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col my-3 d-flex align-items-center">
|
<div class="col my-3 d-flex align-items-center">
|
||||||
<buttonPrimary
|
<buttonMain
|
||||||
|
isPrimary
|
||||||
buttonText="Primary"
|
buttonText="Primary"
|
||||||
loaderColor="white"
|
loaderColor="white"
|
||||||
sizeInRem="1" />
|
sizeInRem="1"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col my-3 d-flex align-items-center">
|
<div class="col my-3 d-flex align-items-center">
|
||||||
<buttonSecondary
|
<buttonMain
|
||||||
buttonText="Secondary"
|
buttonText="secondary"
|
||||||
loaderColor="white"
|
loaderColor="white"
|
||||||
sizeInRem="1"
|
sizeInRem="1"
|
||||||
/>
|
/>
|
||||||
|
|
@ -887,8 +889,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import buttonPrimary from "@/ux-components/button-primary/button-primary";
|
import buttonMain from "@/ux-components/button-main/button-main";
|
||||||
import buttonSecondary from "@/ux-components/button-secondary/button-secondary";
|
|
||||||
import buttonBack from "@/common-components/button-back/button-back";
|
import buttonBack from "@/common-components/button-back/button-back";
|
||||||
import listCard from "@/ux-components/list-card/list-card";
|
import listCard from "@/ux-components/list-card/list-card";
|
||||||
import listButton from "@/ux-components/list-button/list-button";
|
import listButton from "@/ux-components/list-button/list-button";
|
||||||
|
|
@ -902,8 +903,7 @@ import textLink from "@/ux-components/text-link/text-link";
|
||||||
export default {
|
export default {
|
||||||
name: "App",
|
name: "App",
|
||||||
components: {
|
components: {
|
||||||
buttonPrimary,
|
buttonMain,
|
||||||
buttonSecondary,
|
|
||||||
buttonBack,
|
buttonBack,
|
||||||
listCard,
|
listCard,
|
||||||
listButton,
|
listButton,
|
||||||
|
|
|
||||||
108
src/ux-components/button-main/button-main.spec.js
Normal file
108
src/ux-components/button-main/button-main.spec.js
Normal 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");
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
94
src/ux-components/button-main/button-main.vue
Normal file
94
src/ux-components/button-main/button-main.vue
Normal 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>
|
||||||
Loading…
Reference in a new issue