From 51808ee8762aa3675ca4112106d24ec05f254a9b Mon Sep 17 00:00:00 2001 From: Trevor Burch Date: Tue, 19 Nov 2024 16:55:44 -0500 Subject: [PATCH] feat(components/lookup): tokenize country field styles (#2914) --- .../src/e2e/country-field.component.cy.ts | 2 +- .../country-field.component.html | 23 +-- .../country-field.component.scss | 164 +++++++++++++---- .../country-field.component.spec.ts | 170 +++++++++++++----- 4 files changed, 264 insertions(+), 95 deletions(-) diff --git a/apps/e2e/lookup-storybook-e2e/src/e2e/country-field.component.cy.ts b/apps/e2e/lookup-storybook-e2e/src/e2e/country-field.component.cy.ts index a644979cab..015206e03a 100644 --- a/apps/e2e/lookup-storybook-e2e/src/e2e/country-field.component.cy.ts +++ b/apps/e2e/lookup-storybook-e2e/src/e2e/country-field.component.cy.ts @@ -127,5 +127,5 @@ describe('lookup-storybook', () => { ); }); }); - }); + }, true); }); diff --git a/libs/components/lookup/src/lib/modules/country-field/country-field.component.html b/libs/components/lookup/src/lib/modules/country-field/country-field.component.html index 53957863bd..c7915ee6d8 100644 --- a/libs/components/lookup/src/lib/modules/country-field/country-field.component.html +++ b/libs/components/lookup/src/lib/modules/country-field/country-field.component.html @@ -56,16 +56,19 @@ -
- {{ item.name }} - @if (includePhoneInfo) { - - {{ item.dialCode }} - - } +
+
+
+
+ {{ item.name }} + @if (includePhoneInfo) { + + {{ item.dialCode }} + + } +
diff --git a/libs/components/lookup/src/lib/modules/country-field/country-field.component.scss b/libs/components/lookup/src/lib/modules/country-field/country-field.component.scss index 690cbd2206..b1f4d82fdf 100644 --- a/libs/components/lookup/src/lib/modules/country-field/country-field.component.scss +++ b/libs/components/lookup/src/lib/modules/country-field/country-field.component.scss @@ -1,11 +1,55 @@ @use 'libs/components/theme/src/lib/styles/mixins' as mixins; @use 'libs/components/theme/src/lib/styles/variables' as *; +@use 'libs/components/theme/src/lib/styles/compat-tokens-mixins' as compatMixins; @import 'node_modules/intl-tel-input/build/css/intlTelInput.css'; -@mixin sky-country-field-textarea { - overflow: hidden; - resize: none; - white-space: nowrap; +@include compatMixins.sky-default-overrides('.sky-country-field-container') { + --sky-override-country-field-disabled-flag-filter: none; + --sky-override-country-field-disabled-flag-opacity: 0.65; + --sky-override-country-field-disabled-input-background-color: #{$sky-background-color-disabled}; + --sky-override-country-field-flag-bottom: 0; + --sky-override-country-field-input-box-flag-height: 35px; + --sky-override-country-field-input-box-flag-left: 13px; + --sky-override-country-field-input-box-form-control-padding-left: 40px; + --sky-override-country-field-max-height: 13px; + --sky-override-country-field-max-width: 25px; + --sky-override-country-field-transform: scaleX(1.25) translateX(2px); +} + +@include compatMixins.sky-default-overrides( + '.sky-autocomplete-result:has(.sky-country-field-search-result-flag)' +) { + --sky-override-country-field-max-height: 13px; + --sky-override-country-field-max-width: 25px; + --sky-override-country-field-phone-info-font-size: 15px; + --sky-override-country-field-search-result-dial-code-padding-left: 0; + --sky-override-country-field-search-result-info-padding-left: 29px; + --sky-override-country-field-transform: scaleX(1.25) translateX(2px); +} + +@include compatMixins.sky-modern-overrides( + '.sky-country-field-container', + false +) { + --sky-override-country-field-flag-bottom: 0; + --sky-override-country-field-input-box-flag-height: 40px; + --sky-override-country-field-input-box-flag-left: 15px; + --sky-override-country-field-input-box-form-control-padding-left: 45px; + --sky-override-country-field-max-height: 13px; + --sky-override-country-field-max-width: 25px; + --sky-override-country-field-transform: scaleX(1.25) translateX(2px); +} + +@include compatMixins.sky-modern-overrides( + '.sky-autocomplete-result:has(.sky-country-field-search-result-flag)', + false +) { + --sky-override-country-field-max-height: 13px; + --sky-override-country-field-max-width: 25px; + --sky-override-country-field-phone-info-font-size: 15px; + --sky-override-country-field-search-result-dial-code-padding-left: 0; + --sky-override-country-field-search-result-info-padding-left: 29px; + --sky-override-country-field-transform: scaleX(1.25) translateX(2px); } .sky-country-field-country-btn + .sky-form-control { @@ -16,9 +60,31 @@ width: 100%; } +.sky-autocomplete-result:has(.sky-country-field-search-result-flag) { + position: relative; +} + .sky-country-field-search-result-flag { - display: inline-block; - margin-right: 9px; + display: flex; + align-items: center; + position: absolute; + bottom: 0; + height: 100%; +} + +.sky-country-field-search-result-info { + padding-left: var( + --sky-override-country-field-search-result-info-padding-left, + calc(var(--sky-size-icon-s) + var(--sky-space-gap-icon-m)) + ); +} + +.sky-country-field-search-result-dial-code.sky-font-deemphasized { + font-size: var(--sky-override-country-field-phone-info-font-size, inherit); + padding-left: var( + --sky-override-country-field-search-result-dial-code-padding-left, + var(--sky-space-gap-label-s) + ); } .sky-country-field-flag { @@ -28,9 +94,13 @@ .sky-country-field-disabled { .sky-country-field-input { cursor: default; - background-color: $sky-background-color-disabled; + background-color: var( + --sky-override-country-field-disabled-input-background-color, + transparent + ); } + // NOTE: This rule is set for non-input box country fields. Remove when support for this is fully removed. .sky-country-field-flag { opacity: 0.65; } @@ -46,13 +116,17 @@ margin-bottom: auto; margin-top: auto; position: absolute; + + // NOTE: These styles are set for non-input box country fields. Remove when support for this is fully removed. + bottom: 0; left: 13px; height: 35px; - bottom: 0; } textarea { - @include sky-country-field-textarea; + overflow: hidden; + resize: none !important; + white-space: nowrap; } } @@ -61,55 +135,71 @@ display: flex; } + // NOTE: This rule is set for non-input box country fields. Remove when support for this is fully removed. .sky-form-control { padding-left: 40px; } } -.sky-country-field-country-selected, -.sky-country-field-country-default { - @include mixins.sky-border(light, bottom); +// NOTE: These rules are set for non-input box country fields. Remove when support for this is fully removed. +:host(.ng-invalid.ng-touched) .sky-country-field-input textarea { + box-shadow: 0 0 8px rgba($sky-highlight-color-danger, 0.6); + border: 1px solid var(--sky-highlight-color-danger); + outline: none; } -:host(.ng-invalid.ng-touched) .sky-country-field-input textarea { - @include mixins.sky-field-status(invalid); +.sky-country-field-disabled { + .sky-country-field-flag { + filter: var( + --sky-override-country-field-disabled-flag-filter, + grayscale(100%) + ); + } } -.sky-theme-modern { - .sky-country-field-disabled { +.sky-input-box .sky-form-group { + .sky-country-field-input-with-flag { .sky-country-field-flag { - filter: grayscale(100%); + height: var( + --sky-override-country-field-input-box-flag-height, + calc( + var(--sky-font-line_height-input-val) * var(--sky-font-size-input-val) + ) + ); + left: var( + --sky-override-country-field-input-box-flag-left, + var(--sky-space-inset-input-left-m) + ); + bottom: var( + --sky-override-country-field-flag-bottom, + var(--sky-space-inset-input-bottom-m) + ); } - } - - .sky-input-box .sky-form-group { - .sky-country-field-input { - background-color: transparent; - border-radius: $sky-theme-modern-box-border-radius-default; - textarea.sky-form-control { - @include sky-country-field-textarea; - } + .sky-form-control { + padding-left: var( + --sky-override-country-field-input-box-form-control-padding-left, + calc( + var(--sky-space-inset-input-left-m) + var(--sky-size-icon-s) + + var(--sky-space-gap-icon-m) + ) + ); } + } + .sky-country-field-disabled { .sky-country-field-input-with-flag { .sky-country-field-flag { - height: 40px; - left: 15px; - opacity: 1; - } - - .sky-form-control { - padding-left: 45px; + opacity: var(--sky-override-country-field-disabled-flag-opacity, 1); } } } } -.sky-country-field-search-result-flag, +.sky-country-field-search-result-flag .iti__flag, .sky-country-field-flag .iti__flag { - max-width: 25px; - max-height: 13px; background-image: url(https://sky.blackbaudcdn.net/static/skyux-public-assets/1.0.0-beta.4/assets/images/intl-tel-input/flags@2x.webp) !important; - transform: scaleX(1.25) translateX(2px); + max-width: var(--sky-override-country-field-max-width, inherit); + max-height: var(--sky-override-country-field-max-height, inherit); + transform: var(--sky-override-country-field-transform, inherit); } diff --git a/libs/components/lookup/src/lib/modules/country-field/country-field.component.spec.ts b/libs/components/lookup/src/lib/modules/country-field/country-field.component.spec.ts index eb698c6946..0c429885c7 100644 --- a/libs/components/lookup/src/lib/modules/country-field/country-field.component.spec.ts +++ b/libs/components/lookup/src/lib/modules/country-field/country-field.component.spec.ts @@ -306,8 +306,12 @@ describe('Country Field Component', () => { const results = searchAndGetResults('us', fixture); expect(results[0]).toHaveText('Cyprus'); - expect(results[0].querySelector('div')).toHaveCssClass('iti__flag'); - expect(results[0].querySelector('div')).toHaveCssClass('iti__cy'); + expect( + results[0].querySelector('.sky-country-field-search-result-flag div'), + ).toHaveCssClass('iti__flag'); + expect( + results[0].querySelector('.sky-country-field-search-result-flag div'), + ).toHaveCssClass('iti__cy'); })); it('should only display supported countries', fakeAsync(() => { @@ -320,12 +324,20 @@ describe('Country Field Component', () => { const results = searchAndGetResults('us', fixture); expect(results[0]).toHaveText('United States'); - expect(results[0].querySelector('div')).toHaveCssClass('iti__flag'); - expect(results[0].querySelector('div')).toHaveCssClass('iti__us'); + expect( + results[0].querySelector('.sky-country-field-search-result-flag div'), + ).toHaveCssClass('iti__flag'); + expect( + results[0].querySelector('.sky-country-field-search-result-flag div'), + ).toHaveCssClass('iti__us'); expect(results[1]).toHaveText('Australia'); - expect(results[1].querySelector('div')).toHaveCssClass('iti__flag'); - expect(results[1].querySelector('div')).toHaveCssClass('iti__au'); + expect( + results[1].querySelector('.sky-country-field-search-result-flag div'), + ).toHaveCssClass('iti__flag'); + expect( + results[1].querySelector('.sky-country-field-search-result-flag div'), + ).toHaveCssClass('iti__au'); expect(results.length).toBe(2); })); @@ -343,11 +355,19 @@ describe('Country Field Component', () => { const results = searchAndGetResults('us', fixture); expect(results[0]).toHaveText('United States'); - expect(results[0].querySelector('div')).toHaveCssClass('iti__flag'); - expect(results[0].querySelector('div')).toHaveCssClass('iti__us'); + expect( + results[0].querySelector('.sky-country-field-search-result-flag div'), + ).toHaveCssClass('iti__flag'); + expect( + results[0].querySelector('.sky-country-field-search-result-flag div'), + ).toHaveCssClass('iti__us'); expect(results[1]).toHaveText('Cyprus'); - expect(results[1].querySelector('div')).toHaveCssClass('iti__flag'); - expect(results[1].querySelector('div')).toHaveCssClass('iti__cy'); + expect( + results[1].querySelector('.sky-country-field-search-result-flag div'), + ).toHaveCssClass('iti__flag'); + expect( + results[1].querySelector('.sky-country-field-search-result-flag div'), + ).toHaveCssClass('iti__cy'); })); it('should clear the selection when all search text is cleared', fakeAsync(() => { @@ -495,7 +515,9 @@ describe('Country Field Component', () => { }); let searchResults = searchAndGetResults('Austr', fixture); - expect(searchResults[0].querySelector('.sky-deemphasized')).toBeNull(); + expect( + searchResults[0].querySelector('.sky-font-deemphasized'), + ).toBeNull(); component.countryFieldComponent.includePhoneInfo = undefined; searchAndSelect('Austr', 0, fixture); @@ -507,7 +529,9 @@ describe('Country Field Component', () => { }); searchResults = searchAndGetResults('Austr', fixture); - expect(searchResults[0].querySelector('.sky-deemphasized')).toBeNull(); + expect( + searchResults[0].querySelector('.sky-font-deemphasized'), + ).toBeNull(); })); it('should include dial code information when the `includePhoneInfo` input is set', fakeAsync(() => { @@ -537,9 +561,9 @@ describe('Country Field Component', () => { }); const searchResults = searchAndGetResults('Austr', fixture); - expect(searchResults[0].querySelector('.sky-deemphasized')).toHaveText( - '61', - ); + expect( + searchResults[0].querySelector('.sky-font-deemphasized'), + ).toHaveText('61'); })); it('should not hide the flag in the input box if the `hideSelectedCountryFlag` is not set', fakeAsync(() => { @@ -876,8 +900,12 @@ describe('Country Field Component', () => { const results = searchAndGetResults('us', fixture); expect(results[0]).toHaveText('Cyprus'); - expect(results[0].querySelector('div')).toHaveCssClass('iti__flag'); - expect(results[0].querySelector('div')).toHaveCssClass('iti__cy'); + expect( + results[0].querySelector('.sky-country-field-search-result-flag div'), + ).toHaveCssClass('iti__flag'); + expect( + results[0].querySelector('.sky-country-field-search-result-flag div'), + ).toHaveCssClass('iti__cy'); })); it('should only display supported countries', fakeAsync(() => { @@ -890,12 +918,20 @@ describe('Country Field Component', () => { const results = searchAndGetResults('us', fixture); expect(results[0]).toHaveText('United States'); - expect(results[0].querySelector('div')).toHaveCssClass('iti__flag'); - expect(results[0].querySelector('div')).toHaveCssClass('iti__us'); + expect( + results[0].querySelector('.sky-country-field-search-result-flag div'), + ).toHaveCssClass('iti__flag'); + expect( + results[0].querySelector('.sky-country-field-search-result-flag div'), + ).toHaveCssClass('iti__us'); expect(results[1]).toHaveText('Australia'); - expect(results[1].querySelector('div')).toHaveCssClass('iti__flag'); - expect(results[1].querySelector('div')).toHaveCssClass('iti__au'); + expect( + results[1].querySelector('.sky-country-field-search-result-flag div'), + ).toHaveCssClass('iti__flag'); + expect( + results[1].querySelector('.sky-country-field-search-result-flag div'), + ).toHaveCssClass('iti__au'); expect(results.length).toBe(2); })); @@ -910,12 +946,20 @@ describe('Country Field Component', () => { const results = searchAndGetResults('us', fixture); expect(results[0]).toHaveText('United States'); - expect(results[0].querySelector('div')).toHaveCssClass('iti__flag'); - expect(results[0].querySelector('div')).toHaveCssClass('iti__us'); + expect( + results[0].querySelector('.sky-country-field-search-result-flag div'), + ).toHaveCssClass('iti__flag'); + expect( + results[0].querySelector('.sky-country-field-search-result-flag div'), + ).toHaveCssClass('iti__us'); expect(results[1]).toHaveText('Australia'); - expect(results[1].querySelector('div')).toHaveCssClass('iti__flag'); - expect(results[1].querySelector('div')).toHaveCssClass('iti__au'); + expect( + results[1].querySelector('.sky-country-field-search-result-flag div'), + ).toHaveCssClass('iti__flag'); + expect( + results[1].querySelector('.sky-country-field-search-result-flag div'), + ).toHaveCssClass('iti__au'); expect(results.length).toBe(2); })); @@ -958,11 +1002,19 @@ describe('Country Field Component', () => { const results = searchAndGetResults('us', fixture); expect(results[0]).toHaveText('United States'); - expect(results[0].querySelector('div')).toHaveCssClass('iti__flag'); - expect(results[0].querySelector('div')).toHaveCssClass('iti__us'); + expect( + results[0].querySelector('.sky-country-field-search-result-flag div'), + ).toHaveCssClass('iti__flag'); + expect( + results[0].querySelector('.sky-country-field-search-result-flag div'), + ).toHaveCssClass('iti__us'); expect(results[1]).toHaveText('Cyprus'); - expect(results[1].querySelector('div')).toHaveCssClass('iti__flag'); - expect(results[1].querySelector('div')).toHaveCssClass('iti__cy'); + expect( + results[1].querySelector('.sky-country-field-search-result-flag div'), + ).toHaveCssClass('iti__flag'); + expect( + results[1].querySelector('.sky-country-field-search-result-flag div'), + ).toHaveCssClass('iti__cy'); })); it('should clear the selection when all search text is cleared', fakeAsync(() => { @@ -1118,7 +1170,9 @@ describe('Country Field Component', () => { }); const searchResults = searchAndGetResults('Austr', fixture); - expect(searchResults[0].querySelector('.sky-deemphasized')).toBeNull(); + expect( + searchResults[0].querySelector('.sky-font-deemphasized'), + ).toBeNull(); })); it('should include dial code information when the `includePhoneInfo` input is set', fakeAsync(() => { @@ -1147,9 +1201,9 @@ describe('Country Field Component', () => { }); const searchResults = searchAndGetResults('Austr', fixture); - expect(searchResults[0].querySelector('.sky-deemphasized')).toHaveText( - '61', - ); + expect( + searchResults[0].querySelector('.sky-font-deemphasized'), + ).toHaveText('61'); })); it('should not hide the flag in the input box if the `hideSelectedCountryFlag` is not set', fakeAsync(() => { @@ -1345,8 +1399,12 @@ describe('Country Field Component', () => { const results = searchAndGetResults('us', fixture); expect(results[0]).toHaveText('Cyprus'); - expect(results[0].querySelector('div')).toHaveCssClass('iti__flag'); - expect(results[0].querySelector('div')).toHaveCssClass('iti__cy'); + expect( + results[0].querySelector('.sky-country-field-search-result-flag div'), + ).toHaveCssClass('iti__flag'); + expect( + results[0].querySelector('.sky-country-field-search-result-flag div'), + ).toHaveCssClass('iti__cy'); })); it('should only display supported countries', fakeAsync(() => { @@ -1359,12 +1417,20 @@ describe('Country Field Component', () => { const results = searchAndGetResults('us', fixture); expect(results[0]).toHaveText('United States'); - expect(results[0].querySelector('div')).toHaveCssClass('iti__flag'); - expect(results[0].querySelector('div')).toHaveCssClass('iti__us'); + expect( + results[0].querySelector('.sky-country-field-search-result-flag div'), + ).toHaveCssClass('iti__flag'); + expect( + results[0].querySelector('.sky-country-field-search-result-flag div'), + ).toHaveCssClass('iti__us'); expect(results[1]).toHaveText('Australia'); - expect(results[1].querySelector('div')).toHaveCssClass('iti__flag'); - expect(results[1].querySelector('div')).toHaveCssClass('iti__au'); + expect( + results[1].querySelector('.sky-country-field-search-result-flag div'), + ).toHaveCssClass('iti__flag'); + expect( + results[1].querySelector('.sky-country-field-search-result-flag div'), + ).toHaveCssClass('iti__au'); expect(results.length).toBe(2); })); @@ -1384,11 +1450,19 @@ describe('Country Field Component', () => { const results = searchAndGetResults('us', fixture); expect(results[0]).toHaveText('Australia'); - expect(results[0].querySelector('div')).toHaveCssClass('iti__flag'); - expect(results[0].querySelector('div')).toHaveCssClass('iti__au'); + expect( + results[0].querySelector('.sky-country-field-search-result-flag div'), + ).toHaveCssClass('iti__flag'); + expect( + results[0].querySelector('.sky-country-field-search-result-flag div'), + ).toHaveCssClass('iti__au'); expect(results[1]).toHaveText('Cyprus'); - expect(results[1].querySelector('div')).toHaveCssClass('iti__flag'); - expect(results[1].querySelector('div')).toHaveCssClass('iti__cy'); + expect( + results[1].querySelector('.sky-country-field-search-result-flag div'), + ).toHaveCssClass('iti__flag'); + expect( + results[1].querySelector('.sky-country-field-search-result-flag div'), + ).toHaveCssClass('iti__cy'); })); it('should clear the selection when all search text is cleared', fakeAsync(() => { @@ -1452,7 +1526,9 @@ describe('Country Field Component', () => { }); const searchResults = searchAndGetResults('Austr', fixture); - expect(searchResults[0].querySelector('.sky-deemphasized')).toBeNull(); + expect( + searchResults[0].querySelector('.sky-font-deemphasized'), + ).toBeNull(); })); it('should include dial code information when the `includePhoneInfo` input is set', fakeAsync(() => { @@ -1477,9 +1553,9 @@ describe('Country Field Component', () => { }); const searchResults = searchAndGetResults('Austr', fixture); - expect(searchResults[0].querySelector('.sky-deemphasized')).toHaveText( - '61', - ); + expect( + searchResults[0].querySelector('.sky-font-deemphasized'), + ).toHaveText('61'); })); it('should not hide the flag in the input box if the `hideSelectedCountryFlag` is not set', fakeAsync(() => {