Initial work on moving heritage button styles to NextGen button component

Added button variant support
Added button size support
Merged button features from modal button to button component
Removed modal button component
Created button mixins for creating buttons
Created initial button variants using mixins
Moved client button customizations to mixins
This commit is contained in:
Josh Dassinger 2026-01-05 10:42:15 -06:00
parent e679c02582
commit fa965468b4
16 changed files with 342 additions and 555 deletions

View file

@ -0,0 +1,8 @@
const buttonSizes = Object.freeze({
xs: 'xs',
sm: 'sm',
md: 'md',
lg: 'lg'
});
export default buttonSizes;

View file

@ -0,0 +1,9 @@
const buttonVariants = Object.freeze({
primary: 'primary',
secondary: 'secondary',
success: 'success',
link: 'link',
navigation: 'navigation'
});
export default buttonVariants;

View file

@ -34,30 +34,18 @@
<slot></slot>
</div>
<div class="modal-footer px-5 py-4">
<modalButtonMain
v-if="useDefaultButton"
<buttonMain
id="modalbtn"
ref="modalButtonMain"
isPrimary
:variant="buttonVariant"
class="w-100"
:buttonText="footerButtonText"
pushToGA
:class="[
(isButtonDisabled || isFooterButtonDisabled) &&
'form-test-invalid',
additionalClassesString
'form-test-invalid'
]"
@clickEvent="validateAndEmit" />
<button
v-if="!useDefaultButton"
class="w-100 btn d-flex align-items-center justify-content-center delay"
:class="[
(isButtonDisabled || isFooterButtonDisabled) &&
'form-test-invalid',
additionalClassesString
]"
@click="validateAndEmit">
<span class="m-0">{{ footerButtonText }}</span>
</button>
</div>
</div>
</div>
@ -65,7 +53,7 @@
</template>
<script>
import modalButtonMain from '@/ux-components/modal-button-main/modal-button-main.vue';
import ButtonMain from '@/ux-components/button-main/button-main.vue';
import { Modal } from 'bootstrap';
import { useForm } from 'vee-validate';
@ -73,7 +61,7 @@ export default {
// eslint-disable-next-line vue/multi-word-component-names
name: 'modal',
components: {
modalButtonMain
ButtonMain
},
props: {
modalId: String,
@ -86,13 +74,9 @@ export default {
type: Function
},
isButtonDisabled: Boolean,
useDefaultButton: {
type: Boolean,
default: true
},
additionalClassesString: {
buttonVariant: {
type: String,
default: null
default: 'success'
}
},
emits: ['footer-button-event', 'isModalOpened'],

View file

@ -34,8 +34,7 @@
<buttonMain
ref="buttonMain"
class="w-100"
isPrimary
suppressLoader
variant="success"
:buttonText="ModalSelectButtonText"
data-bs-dismiss="modal"
@clickEvent="buttonClick" />

View file

@ -7,19 +7,19 @@
ref="continueModal"
:headerText="modalHeaderText"
:footerButtonText="modalFooterText"
buttonVariant="primary"
@isModalOpened="setModalStatus"
@footerButtonEvent="startNewReferral">
<p class="mb-2 subheader-text text-center">
{{ modalSubHeaderText }}
</p>
<button
<buttonMain
id="btnContinueReferral"
type="button"
class="btn btn-white-blue continue-referral
align-items-center justify-content-center d-inline-flex mt-2 py-3 px-4 delay w-100"
variant="success"
class="mt-2 w-100"
:buttonText="modalBodyText"
@click="continueReferral">
{{ modalBodyText }}
</button>
</buttonMain>
</modal>
</div>
</transition>
@ -28,10 +28,12 @@
<script>
import modal from '@/digital-components/modal/modal.vue';
import { getISSCookie } from '@/helpers/cookie-helper.js';
import ButtonMain from '@/ux-components/button-main/button-main.vue';
export default {
name: 'continue-modal',
components: {
ButtonMain,
modal
},
emits: ['continue-previous-referral', 'start-new-referral'],
@ -80,16 +82,5 @@ export default {
</script>
<style lang="scss" scoped>
.btn-white-blue {
border-radius: 0.5rem;
border-color: $blue;
color: $blue;
font-size: 1rem;
font-weight: $font-weight-bold;
line-height: 1.5rem;
background-color: #ffffff;
--bs-btn-focus-shadow-rgb: 218, 72, 62;
--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
}
</style>

View file

@ -16,7 +16,7 @@
<buttonMain
v-if="!isForwardButtonHidden"
ref="buttonMain"
isPrimary
variant="navigation"
:buttonText="buttonText"
:class="
(disableForwardAction || isForwardActionDisabled) &&
@ -136,7 +136,7 @@ export default {
width: auto;
justify-content: flex-end;
}
.btn-primary {
.btn-navigation {
width: auto;
}
a {
@ -149,7 +149,7 @@ export default {
overflow-x: visible; // needed to fix hidden footer on some iphones
}
div.flex-column {
.btn-primary {
.btn-navigation {
width: 100%;
justify-content: center;
}

View file

@ -8,20 +8,17 @@
ref="cancelClaimModal"
:headerText="modalHeaderText"
:footerButtonText="modalFooterText"
additionalClassesString="navigation-link"
:useDefaultButton="false"
buttonVariant="link"
@isModalOpened="setModalStatus"
@footerButtonEvent="cancelClaimConfirmation">
<div v-html="modalBodyText"></div>
<button
<buttonMain
id="btnContinueReferral"
type="button"
:aria-disabled="false"
class="btn btn-primary btn-override
align-items-center justify-content-center d-inline-flex mt-4 py-3 px-4 delay w-100"
@click="returnToClaim">
{{ modalBodyText2 }}
</button>
variant="success"
:buttonText="modalBodyText2"
class="mt-4 w-100"
@clickEvent="returnToClaim">
</buttonMain>
</modal>
</div>
</transition>
@ -29,10 +26,12 @@
<script>
import modal from '@/digital-components/modal/modal.vue';
import ButtonMain from '@/ux-components/button-main/button-main.vue';
export default {
name: 'cancel-claim-modal',
components: {
ButtonMain,
modal
},
emits: ['cancel-claim-confirmation', 'return-to-claim'],
@ -76,19 +75,5 @@ export default {
</script>
<style lang="scss" scoped>
.btn {
&.btn-primary {
position: relative;
background: linear-gradient(270deg, $blue 0%, $blue-800 100%);
border: none;
border-radius: $border-radius-lg;
color: $white;
justify-content: center;
font-weight: $font-weight-bold;
letter-spacing: inherit;
@media (hover: hover) {
background: linear-gradient(270deg, $blue 0%, $blue-800 100%);
}
}
}
</style>

View file

@ -169,7 +169,7 @@ describe('tpa-submit', () => {
// Assert
expect(mainButton.exists()).toBeTruthy();
expect(mainButton.props().isPrimary).toBe(true);
expect(mainButton.props().variant).toBe('success');
expect(mainButton.classes()).toContain('w-100');
expect(mainButton.classes()).toContain('mb-5');
});

View file

@ -32,7 +32,7 @@
class="mb-4 small text-color--darker-gray" />
<buttonMain
ref="buttonMainOne"
isPrimary
variant="success"
:buttonText="forwardButtonText"
class="w-100 mb-5"
@clickEvent="forwardButtonAction" />

View file

@ -86,52 +86,14 @@
.btn-link {
color: $link;
}
.btn {
&.btn-override[aria-disabled="false"]:not(.form-test-invalid) {
&.btn-primary {
background: $button-color;
color: $button-text-color;
}
&:focus-visible {
background: $button-color;
color: $button-text-color;
box-shadow: 0 0 0 3px $white, 0 0 0 5.5px $button-color;
}
}
}
}
&.modal-open {
.modal {
.modal-body {
.btn {
&.btn-override[aria-disabled="false"]:not(.form-test-invalid) {
&.btn-primary {
background: $button-color;
color: $button-text-color;
}
&:focus-visible {
background: $button-color;
color: $button-text-color;
box-shadow: 0 0 0 3px $white, 0 0 0 5.5px $button-color;
}
}
}
}
.modal-footer {
.btn:not(.navigation-link) {
background: $button-color;
color: $button-text-color;
}
}
}
.btn {
&.btn-override {
@include heritage-btn-variant('success', $button-text-color, $button-color, transparent, true);
@include heritage-btn-variant('navigation', $button-text-color, $button-color, transparent, true);
}
}
}
// End Amica
@ -171,52 +133,14 @@
a.new-window-link {
color: $link;
}
.btn {
&.btn-override[aria-disabled="false"]:not(.form-test-invalid) {
&.btn-primary {
background: $button-color;
color: $button-text-color;
}
&:focus-visible {
background: $button-color;
color: $button-text-color;
box-shadow: 0 0 0 3px $white, 0 0 0 5.5px $button-color;
}
}
}
}
&.modal-open {
.modal {
.modal-body {
.btn {
&.btn-override[aria-disabled="false"]:not(.form-test-invalid) {
&.btn-primary {
background: $button-color;
color: $button-text-color;
}
&:focus-visible {
background: $button-color;
color: $button-text-color;
box-shadow: 0 0 0 3px $white, 0 0 0 5.5px $button-color;
}
}
}
}
.modal-footer {
.btn:not(.navigation-link) {
background: $button-color;
color: $button-text-color;
}
}
}
.btn {
&.btn-override {
@include heritage-btn-variant('success', $button-text-color, $button-color, transparent, true);
@include heritage-btn-variant('navigation', $button-text-color, $button-color, transparent, true);
}
}
}
// End Nationwide
@ -256,52 +180,14 @@
a.new-window-link {
color: $link;
}
.btn {
&.btn-override[aria-disabled="false"]:not(.form-test-invalid) {
&.btn-primary {
background: $button-color;
color: $button-text-color;
}
&:focus-visible {
background: $button-color;
color: $button-text-color;
box-shadow: 0 0 0 3px $white, 0 0 0 5.5px $button-color;
}
}
}
}
&.modal-open {
.modal {
.modal-body {
.btn {
&.btn-override[aria-disabled="false"]:not(.form-test-invalid) {
&.btn-primary {
background: $button-color;
color: $button-text-color;
}
&:focus-visible {
background: $button-color;
color: $button-text-color;
box-shadow: 0 0 0 3px $white, 0 0 0 5.5px $button-color;
}
}
}
}
.modal-footer {
.btn:not(.navigation-link) {
background: $button-color;
color: $button-text-color;
}
}
}
.btn {
&.btn-override {
@include heritage-btn-variant('success', $button-text-color, $button-color, transparent, true);
@include heritage-btn-variant('navigation', $button-text-color, $button-color, transparent, true);
}
}
}
// End Country Financial
@ -341,52 +227,14 @@
a.new-window-link {
color: $link;
}
.btn {
&.btn-override[aria-disabled="false"]:not(.form-test-invalid) {
&.btn-primary {
background: $button-color;
color: $button-text-color;
}
&:focus-visible {
background: $button-color;
color: $button-text-color;
box-shadow: 0 0 0 3px $white, 0 0 0 5.5px $button-color;
}
}
}
}
&.modal-open {
.modal {
.modal-body {
.btn {
&.btn-override[aria-disabled="false"]:not(.form-test-invalid) {
&.btn-primary {
background: $button-color;
color: $button-text-color;
}
&:focus-visible {
background: $button-color;
color: $button-text-color;
box-shadow: 0 0 0 3px $white, 0 0 0 5.5px $button-color;
}
}
}
}
.modal-footer {
.btn:not(.navigation-link) {
background: $button-color;
color: $button-text-color;
}
}
}
.btn {
&.btn-override {
@include heritage-btn-variant('success', $button-text-color, $button-color, transparent, true);
@include heritage-btn-variant('navigation', $button-text-color, $button-color, transparent, true);
}
}
}
// End Travelers

View file

@ -182,4 +182,50 @@ body {
:root {
--iss-loader-color: white;
}
//Button Styles
$heritage-btn-border-radius: 1.40625rem; // 22.5px
$heritage-btn-height: 2.8125rem; // 45px
$heritage-btn-width: 9.0625rem; // 145px
.btn {
position: relative;
--bs-btn-font-weight: #{$font-weight-bolder};
min-height: $heritage-btn-height;
min-width: $heritage-btn-width;
letter-spacing: inherit;
line-height: .94;
@include heritage-btn-variant('primary', $white, $heritage-blue-primary, transparent, true);
@include heritage-btn-variant('success', $white, $green, transparent, true);
@include heritage-btn-variant('navigation', $white, $green, transparent, true);
@include heritage-btn-variant('secondary', $white, $heritage-blue-secondary, transparent, true);
@include heritage-btn-link('link', $blue, transparent, $heritage-blue-secondary);
@include heritage-btn-size('lg', 0.625rem, 1.25rem, 20px, $heritage-btn-border-radius);
@include heritage-btn-size('md', 7px, 15px, 15px, $heritage-btn-border-radius);
@include heritage-btn-size('sm', 3px, 6px, 12px, $heritage-btn-border-radius);
@include heritage-btn-size('xs', 1px, 5px, 12px, $heritage-btn-border-radius);
&.btn-link {
--bs-btn-padding-x: 0px;
text-decoration: none;
&:hover,
&:focus {
text-decoration: underline;
}
&.disabled,
&[disabled],
fieldset[disabled] {
text-decoration: none;
}
}
&.delay {
// fixes flicker while transitioning between states
transition: background 0s 0s ease-in-out;
}
}

View file

@ -8,3 +8,54 @@
@mixin box-shadow-hover($color) {
box-shadow: 0 0 0 4px $color;
}
@mixin heritage-btn-box-shadow($color) {
box-shadow:0 0 0 3px $white,0 0 0 5.5px $color
}
@mixin heritage-btn-variant($name, $color, $background, $border-color, $box-shadow) {
&.btn-#{$name} {
@include button-variant($background,
$border-color,
$color,
#{darken($background, 10%)},
$border-color,
$color,
$background,
$border-color,
$color,
$background,
$border-color,
$color
);
@if($box-shadow) {
&:focus, &:active, &:active:focus {
@include heritage-btn-box-shadow($background);
}
}
}
&.btn-outline-#{$name} {
@include button-outline-variant($background,
$color,
$background,
$color,
$background
$color,
);
}
}
@mixin heritage-btn-size($size, $y-padding, $x-padding, $font-size, $border-radius) {
&.btn-#{$size} {
@include button-size($y-padding, $x-padding, $font-size, $border-radius);
}
}
@mixin heritage-btn-link($name, $color, $background, $hover-color) {
&.btn-#{$name} {
--bs-btn-color: #{$color};
--bs-btn-bg: #{$background};
--bs-btn-hover-color: #{$hover-color};
--bs-btn-active-color: #{$hover-color};
}
}

View file

@ -1,6 +1,7 @@
import { shallowMount } from '@vue/test-utils';
import { getMountOptions } from '@/helpers/unit-test-helper.js';
import buttonMain from '@/ux-components/button-main/button-main.vue';
import buttonVariants from '@/constants/button-variants';
/** @ignore */
function setupMocks(mountOptionsMockData = {}) {
@ -12,13 +13,75 @@ function setupMocks(mountOptionsMockData = {}) {
}
describe('buttonMain.vue', () => {
it('Should return btn-primary class', async () => {
describe.each([...Object.keys(buttonVariants)])('Button Variants', (variant) => {
test(`Should return btn-${variant} class`, () => {
// Act
const wrapper = shallowMount(
buttonMain,
setupMocks({
propsData: {
variant
}
})
);
// Assert
const button = wrapper.find('button');
// Expect
expect(button.attributes('class')).toContain(`btn-${variant}`);
});
});
describe.each([...Object.keys(buttonVariants)])('Button Outline Variants', (variant) => {
test(`Should return btn-outline-${variant} class`, () => {
// Act
const wrapper = shallowMount(
buttonMain,
setupMocks({
propsData: {
variant,
isOutline: true
}
})
);
// Assert
const button = wrapper.find('button');
// Expect
expect(button.attributes('class')).toContain(`btn-outline-${variant}`);
});
});
describe.each(['', 'sm', 'lg'])('Button Sizes', (size) => {
test(`Should return btn-${size} class`, () => {
// Act
const wrapper = shallowMount(
buttonMain,
setupMocks({
propsData: {
size
}
})
);
// Assert
const button = wrapper.find('button');
// Expect
expect(button.attributes('class')).toContain(`btn-${size}`);
});
});
it('Should return button text', async () => {
// Act
const buttonText = 'Test Text';
const wrapper = shallowMount(
buttonMain,
setupMocks({
propsData: {
isPrimary: true
buttonText
}
})
);
@ -27,10 +90,10 @@ describe('buttonMain.vue', () => {
const button = wrapper.find('button');
// Expect
expect(button.attributes('class')).toContain('btn-primary');
expect(button.text()).toContain(buttonText);
});
it('Should return aria-disabled state', async () => {
it('Should return disabled state', async () => {
// Act
const wrapper = shallowMount(
buttonMain,
@ -47,4 +110,85 @@ describe('buttonMain.vue', () => {
// Expect
expect(button.attributes()['aria-disabled']).toEqual('true');
});
it('Should emit click-event', async () => {
// Act
const wrapper = shallowMount(
buttonMain,
setupMocks({
propsData: {
isDisabled: false
}
})
);
// Assert
const button = wrapper.find('button');
await button.trigger('click');
// Expect
expect(wrapper.emitted('click').length).toBe(1);
});
it('Should not emit click-event when disabled', async () => {
// Act
const wrapper = shallowMount(
buttonMain,
setupMocks({
propsData: {
isDisabled: true
}
})
);
// Assert
const button = wrapper.find('button');
await button.trigger('click');
// Expect
expect(wrapper.emitted('click').length).toBe(1);
});
it('Should emit GA event when clicked', async () => {
// Act
const wrapper = shallowMount(
buttonMain,
setupMocks({
propsData: {
pushToGA: true
}
})
);
const spy = jest.spyOn(wrapper.vm, 'pushEventToGA');
// Assert
const button = wrapper.find('button');
await button.trigger('click');
// Expect
expect(spy).toHaveBeenCalled();
});
it('Should not emit GA event when clicked', async () => {
// Act
const wrapper = shallowMount(
buttonMain,
setupMocks({
propsData: {
pushToGA: false
}
})
);
const spy = jest.spyOn(wrapper.vm, 'pushEventToGA');
// Assert
const button = wrapper.find('button');
await button.trigger('click');
// Expect
expect(spy).not.toHaveBeenCalled();
});
});

View file

@ -1,30 +1,49 @@
<template>
<button
:aria-disabled="isDisabled"
class="btn d-flex btn-override align-items-center justify-content-center py-3 px-4 delay"
:class="[
isPrimary ? 'btn-primary' : 'btn-secondary',
isFloat ? 'float-end' : '',
]"
class="btn d-flex align-items-center justify-content-center delay"
:class="[getVariant, `btn-${size}`, canOverride ? 'btn-override' : '']"
@click="clicked">
<span class="m-0">{{ buttonText }}</span>
</button>
</template>
<script>
import buttonVariants from '@/constants/button-variants';
import buttonSizes from '@/constants/button-sizes';
export default {
name: 'button-main',
props: {
isPrimary: Boolean,
variant: { type: String, default: 'primary', validator: (val) => Object.keys(buttonVariants).includes(val) },
size: { type: String, default: 'md', validator: (val) => Object.keys(buttonSizes).includes(val) },
buttonText: String,
isDisabled: Boolean,
loaderPosition: String,
isFloat: Boolean,
suppressLoader: Boolean
isOutline: Boolean,
pushToGA: Boolean,
canOverride: { type: Boolean, required: false, default: true }
},
emits: ['click-event'],
computed: {
getVariant() {
if (this.isOutline) {
return `btn-outline-${this.variant}`;
}
return `btn-${this.variant}`;
}
},
methods: {
clicked() {
if (this.pushToGA) {
this.pushEventToGA(
this.$route.query[this.queryStrings.ISS_PAGE],
this.GaActions.CLICKED,
this.buttonText,
true
);
}
if (!this.isDisabled) {
this.$emit('click-event');
}
@ -34,86 +53,5 @@ export default {
</script>
<style lang="scss" scoped>
$border-radius-heritage: 1.40625rem; // 22.5px
$button-height-heritage: 2.8125rem; // 45px
$button-width-heritage: 9.0625rem; // 145px
.btn {
&.btn-primary {
position: relative;
background: #0c7e47;
padding-left: 2rem;
padding-right: 2rem;
min-height: $button-height-heritage;
min-width: $button-width-heritage;
border: none;
border-radius: $border-radius-heritage;
color: $white;
justify-content: center;
font-weight: 600;
letter-spacing: inherit;
&:focus {
// Keyboard focus for accessibility
outline: none;
box-shadow: 0 0 0 3px #fff, 0 0 0 5.5px #0c7e47;
}
&:hover {
// Keyboard focus for accessibility
color: #fff;
background-color: #084f2d;
border-color: #042f1a;
}
&:active {
outline: none;
background-color: #0c7e47;
box-shadow: 0 0 0 3px #fff, 0 0 0 5.5px #0c7e47;
}
&:disabled {
background: red;
color: $gray-600 !important;
border: none;
border-radius: $border-radius-heritage;
cursor: pointer;
pointer-events: all;
}
&.delay {
// fixes flicker while transitioning between states
transition: background 0s 0s ease-in-out;
}
}
&.btn-secondary {
position: relative;
background: transparent;
border: 1px solid $blue;
border-radius: $border-radius-heritage;
color: $blue;
font-weight: 500;
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-550 !important;
font-weight: 400;
border: 1px solid $gray-550;
border-radius: $border-radius-heritage;
cursor: pointer;
pointer-events: all;
}
&.delay {
// fixes flicker while transitioning between states
transition: background 0s 0s ease-in-out;
}
}
}
</style>

View file

@ -1,95 +0,0 @@
import { shallowMount } from '@vue/test-utils';
import { getMountOptions } from '@/helpers/unit-test-helper.js';
import { nextTick } from 'vue';
import modalButtonMain from '@/ux-components/modal-button-main/modal-button-main.vue';
/** @ignore */
function setupMocks(mountOptionsMockData = {}) {
const defaultMountOptions = { route: { query: { issPage: 'page-name' } } };
const baseMountOptions = getMountOptions(Object.assign(defaultMountOptions, mountOptionsMockData));
const allMountOptions = Object.assign(defaultMountOptions, baseMountOptions);
return allMountOptions;
}
describe('modal-button-main.vue', () => {
it('Should return btn-primary class', () => {
// Arrange/Act
const wrapper = shallowMount(
modalButtonMain,
setupMocks({
propsData: {
isPrimary: true
}
})
);
const button = wrapper.find('button');
// Assert
expect(button.attributes('class')).toContain('btn-primary');
});
it('Should return aria-disabled state', () => {
// Arrange/Act
const wrapper = shallowMount(
modalButtonMain,
setupMocks({
propsData: {
isDisabled: true
}
})
);
const button = wrapper.find('button');
// Assert
expect(button.attributes()['aria-disabled']).toEqual('true');
});
it("Should emit 'click-event' event when clicking if the button is enabled", async () => {
// Arrange
const wrapper = shallowMount(
modalButtonMain,
setupMocks({
propsData: {
loaderPosition: 'right',
loaderEnabled: true,
isDisabled: false
}
})
);
const buttonElement = wrapper.find('button');
// Act
buttonElement.trigger('click');
await nextTick();
// Assert
expect(wrapper.emitted('click-event')).toBeTruthy();
});
it("Should not emit 'click-event' event when clicking if the button is disabled", async () => {
// Arrange
const wrapper = shallowMount(
modalButtonMain,
setupMocks({
propsData: {
loaderPosition: 'right',
loaderEnabled: true,
isDisabled: true
}
})
);
const buttonElement = wrapper.find('button');
// Act
buttonElement.trigger('click');
await nextTick();
// Assert
expect(wrapper.emitted('click-event')).toBeFalsy();
});
});

View file

@ -1,121 +0,0 @@
<template>
<button
type="button"
:aria-disabled="isDisabled"
class="btn d-flex btn-override align-items-center justify-content-center py-3 px-4 delay"
:class="[
isPrimary ? 'btn-primary' : 'btn-secondary',
isFloat ? 'float-end' : '',
]"
@click="clicked">
<span class="m-0">{{ buttonText }}</span>
</button>
</template>
<script>
export default {
name: 'modal-button-main',
props: {
isPrimary: Boolean,
buttonText: String,
isDisabled: Boolean,
loaderColor: String,
loaderPosition: String,
isFloat: Boolean,
suppressLoader: Boolean
},
emits: ['click-event'],
methods: {
clicked() {
this.pushEventToGA(
this.$route.query[this.queryStrings.ISS_PAGE],
this.GaActions.CLICKED,
this.buttonText,
true
);
if (!this.isDisabled) {
this.$emit('click-event');
}
}
}
};
</script>
<style lang="scss" scoped>
.btn {
&.btn-primary {
position: relative;
background: linear-gradient(270deg, $blue 0%, $blue-800 100%);
border: none;
border-radius: $border-radius-lg;
color: $white;
justify-content: center;
font-weight: 500;
letter-spacing: inherit;
@media (hover: hover) {
background: linear-gradient(270deg, $blue 0%, $blue-800 100%);
}
// 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;
background: linear-gradient(270deg, rgba(6, 87, 124, 1) 0%, rgba(6, 87, 124, 1) 100%);
}
&:disabled {
background: $gray-200 !important;
background: linear-gradient(270deg, $gray-200 0%, $gray-200 100%) !important;
color: $gray-600 !important;
font-weight: 400;
height: 48px;
border: none;
border-radius: $border-radius-lg;
cursor: pointer;
pointer-events: all;
}
&.delay {
// fixes flicker while transitioning between states
transition: background 0s 0s ease-in-out;
}
}
&.btn-secondary {
position: relative;
background: transparent;
border: 1px solid $blue;
border-radius: $border-radius-lg;
color: $blue;
font-weight: 500;
transition: all 150ms linear;
height: 3rem;
&: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-550 !important;
font-weight: 400;
height: 48px;
border: 1px solid $gray-550;
border-radius: $border-radius-lg;
cursor: pointer;
pointer-events: all;
}
&.delay {
// fixes flicker while transitioning between states
transition: background 0s 0s ease-in-out;
}
}
}
</style>