diff --git a/src/constants/button-sizes.js b/src/constants/button-sizes.js new file mode 100644 index 00000000..d4f46ecc --- /dev/null +++ b/src/constants/button-sizes.js @@ -0,0 +1,8 @@ +const buttonSizes = Object.freeze({ + xs: 'xs', + sm: 'sm', + md: 'md', + lg: 'lg' +}); + +export default buttonSizes; diff --git a/src/constants/button-variants.js b/src/constants/button-variants.js new file mode 100644 index 00000000..cf73718a --- /dev/null +++ b/src/constants/button-variants.js @@ -0,0 +1,9 @@ +const buttonVariants = Object.freeze({ + primary: 'primary', + secondary: 'secondary', + success: 'success', + link: 'link', + navigation: 'navigation' +}); + +export default buttonVariants; diff --git a/src/digital-components/modal/modal.vue b/src/digital-components/modal/modal.vue index 8a4664e7..0ab74b24 100644 --- a/src/digital-components/modal/modal.vue +++ b/src/digital-components/modal/modal.vue @@ -34,30 +34,18 @@ @@ -65,7 +53,7 @@ diff --git a/src/iss-components/site-footer/site-footer.vue b/src/iss-components/site-footer/site-footer.vue index 81cb42f6..b73ab67a 100644 --- a/src/iss-components/site-footer/site-footer.vue +++ b/src/iss-components/site-footer/site-footer.vue @@ -16,7 +16,7 @@
- + variant="success" + :buttonText="modalBodyText2" + class="mt-4 w-100" + @clickEvent="returnToClaim"> +
@@ -29,10 +26,12 @@ diff --git a/src/layouts/tpa-submit/tpa-submit.spec.js b/src/layouts/tpa-submit/tpa-submit.spec.js index 9ce2cf6d..7dd6920b 100644 --- a/src/layouts/tpa-submit/tpa-submit.spec.js +++ b/src/layouts/tpa-submit/tpa-submit.spec.js @@ -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'); }); diff --git a/src/layouts/tpa-submit/tpa-submit.vue b/src/layouts/tpa-submit/tpa-submit.vue index 5b3b223a..181fa0aa 100644 --- a/src/layouts/tpa-submit/tpa-submit.vue +++ b/src/layouts/tpa-submit/tpa-submit.vue @@ -32,7 +32,7 @@ class="mb-4 small text-color--darker-gray" /> diff --git a/src/styles/client-customizations.scss b/src/styles/client-customizations.scss index 26beae9f..487a63ae 100644 --- a/src/styles/client-customizations.scss +++ b/src/styles/client-customizations.scss @@ -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 \ No newline at end of file diff --git a/src/styles/common-styles.scss b/src/styles/common-styles.scss index 01208d7f..fceed06e 100644 --- a/src/styles/common-styles.scss +++ b/src/styles/common-styles.scss @@ -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; + } } \ No newline at end of file diff --git a/src/styles/mixins/customMixins.scss b/src/styles/mixins/customMixins.scss index cd3555cc..fa1c1c15 100644 --- a/src/styles/mixins/customMixins.scss +++ b/src/styles/mixins/customMixins.scss @@ -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}; + } +} \ No newline at end of file diff --git a/src/ux-components/button-main/button-main.spec.js b/src/ux-components/button-main/button-main.spec.js index 95664421..bec1abf5 100644 --- a/src/ux-components/button-main/button-main.spec.js +++ b/src/ux-components/button-main/button-main.spec.js @@ -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(); + }); }); diff --git a/src/ux-components/button-main/button-main.vue b/src/ux-components/button-main/button-main.vue index 6000a9f2..1a69fd51 100644 --- a/src/ux-components/button-main/button-main.vue +++ b/src/ux-components/button-main/button-main.vue @@ -1,30 +1,49 @@ diff --git a/src/ux-components/modal-button-main/modal-button-main.spec.js b/src/ux-components/modal-button-main/modal-button-main.spec.js deleted file mode 100644 index d06fc1ca..00000000 --- a/src/ux-components/modal-button-main/modal-button-main.spec.js +++ /dev/null @@ -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(); - }); -}); diff --git a/src/ux-components/modal-button-main/modal-button-main.vue b/src/ux-components/modal-button-main/modal-button-main.vue deleted file mode 100644 index 7508667e..00000000 --- a/src/ux-components/modal-button-main/modal-button-main.vue +++ /dev/null @@ -1,121 +0,0 @@ - - - - -