diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000..36d521172 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,46 @@ +## PR Checklist +Please check if your PR fulfills the following requirements: + + + +- [ ] The commit message follows our guidelines: https://github.com/mobi/goponents/blob/master/CONTRIBUTING.md +- [ ] Tests for the changes have been added (for bug fixes / features) +- [ ] Docs have been added / updated (for bug fixes / features) + + +## PR Type +What kind of change does this PR introduce? + + + +- [ ] Bugfix +- [ ] Feature +- [ ] Code style update (formatting, local variables) +- [ ] Refactoring (no functional changes, no api changes) +- [ ] Build related changes +- [ ] CI related changes +- [ ] Documentation content changes +- [ ] Other... Please describe: + + +## What is the current behavior? + + +Issue Number: N/A + + +## What is the new behavior? + + +## Does this PR introduce a breaking change? + + + +- [ ] Yes +- [ ] No + + + + + +## Other information diff --git a/.sass-lint.yml b/.sass-lint.yml index d422f7de7..3ef28d6d4 100644 --- a/.sass-lint.yml +++ b/.sass-lint.yml @@ -54,22 +54,22 @@ rules: # Name Formats class-name-format: - 1 - - convention: hyphenatedbem + - convention: hyphenated_BEM function-name-format: - 1 - - convention: hyphenatedbem + - convention: hyphenated_BEM id-name-format: - 1 - - convention: hyphenatedbem + - convention: hyphenated_BEM mixin-name-format: - 1 - - convention: hyphenatedbem + - convention: hyphenated_BEM placeholder-name-format: - 1 - - convention: hyphenatedbem + - convention: hyphenated_BEM variable-name-format: - 1 - - convention: hyphenatedbem + - convention: hyphenated_BEM # Style Guide attribute-quotes: 1 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f39176378..bb9af5a7f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,13 +4,6 @@ _**Note:** The guide for contributing to this repo is based on the [contribution ## Code of Conduct Please read and follow our [Code of conduct](https://github.com/mobi/goponents/blob/master/CODE_OF_CONDUCT.md). -## Got a question, problem, or feedback? -Feel free to open up [an issue](https://github.com/mobi/goponents/issues/new/choose) using the appropriate template. - -When any sort of issue is created, depending on the impact or urgency of the issue, one of our [contributors](https://github.com/mobi/goponents/graphs/contributors) will respond as quickly as appropriate on the issue itself. We will try to give a timeline and release schedule for any request that is made. - -We would also welcome anyone to open up a [pull request]() for a bug or issue experienced in order to expedite the process. - ## Feature requests You can request a new feature by submitting an issue to our [GitHub Repository](https://github.com/mobi/goponents/issues). If you would like to _implement_ a new feature, please submit an issue with a proposal for your work first. @@ -19,11 +12,15 @@ Our team will first make sure of the following: 2. Where it fits into our current road map. 3. What design resources and support will be needed before the feature work can begin. -Please consider what kind of change it is: +## Working Issues +Before working on an issue, you must claim it. To do so, simply comment on the issue stating that you're looking into it. +Once claimed, a contributor will modify the issue and apply the appropriate labels and milestones. -For a **Major Feature**, first open an issue and outline your proposal so that it can be discussed. This will also allow us to better coordinate our efforts, prevent duplication of work, and help you to craft the change so that it is successfully accepted into the project. +### What issues can be worked? -**Small Features** can be crafted and directly submitted as a Pull Request so long as they have the appropriate design support. +Any issue that does not have the `Needs Triaged` milestone can be worked. + +Issues labeled as `bugs` take priority over general a `chore` or `feature`. ## Submitting a pull request (PR) Before you submit your pull request (PR) consider the following guidelines: @@ -48,13 +45,20 @@ Before you submit your pull request (PR) consider the following guidelines: ```bash git push origin my-branch-name ``` -9. In GitHub, send a pull request to `goponents:master`. - - If we suggest changes then: - 1. Make the required updates. - 2. Re-run the test suite to ensure tests are still passing. - 3. Rebase your branch and force push to your GitHub repository (this will update your Pull Request): +9. In GitHub, send a pull request to `goponents:dev`. + - Please format the description of your PR with our [pull request template](https://github.com/mobi/goponents/blob/master/.github/PULL_REQUEST_TEMPLATE.md) + - If we suggest changes then: + 1. Make the required updates. + 2. Re-run the test suite to ensure tests are still passing. + 3. Rebase your branch and force push to your GitHub repository (this will update your Pull Request): ``` - git rebase master -i + git rebase dev -i git push -f ``` +## Got a question, problem, or feedback? +Feel free to open up [an issue](https://github.com/mobi/goponents/issues/new/choose) using the appropriate template. + +When any sort of issue is created, depending on the impact or urgency of the issue, one of our [contributors](https://github.com/mobi/goponents/graphs/contributors) will respond as quickly as appropriate on the issue itself. We will try to give a timeline and release schedule for any request that is made. + +We would also welcome anyone to open up a [pull request]() for a bug or issue experienced in order to expedite the process. diff --git a/angular.json b/angular.json index e24502714..612078cbc 100644 --- a/angular.json +++ b/angular.json @@ -168,7 +168,117 @@ } } } + }, + "go-style-guide": { + "root": "projects/go-style-guide/", + "sourceRoot": "projects/go-style-guide/src", + "projectType": "application", + "prefix": "app", + "schematics": { + "@schematics/angular:component": { + "styleext": "scss" + } + }, + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:browser", + "options": { + "outputPath": "dist/go-style-guide", + "index": "projects/go-style-guide/src/index.html", + "main": "projects/go-style-guide/src/main.ts", + "polyfills": "projects/go-style-guide/src/polyfills.ts", + "tsConfig": "projects/go-style-guide/tsconfig.app.json", + "assets": [ + "projects/go-style-guide/src/favicon.ico", + "projects/go-style-guide/src/assets", + "projects/go-style-guide/src/_redirects" + ], + "styles": [ + "projects/go-style-guide/src/styles/styles.scss" + ], + "scripts": [], + "stylePreprocessorOptions": { + "includePaths": [ + "projects/go-style-guide/src/styles" + ] + }, + "es5BrowserSupport": true + }, + "configurations": { + "production": { + "fileReplacements": [ + { + "replace": "projects/go-style-guide/src/environments/environment.ts", + "with": "projects/go-style-guide/src/environments/environment.prod.ts" + } + ], + "optimization": true, + "outputHashing": "all", + "sourceMap": false, + "extractCss": true, + "namedChunks": false, + "aot": true, + "extractLicenses": true, + "vendorChunk": false, + "buildOptimizer": true, + "budgets": [ + { + "type": "initial", + "maximumWarning": "2mb", + "maximumError": "5mb" + } + ] + } + } + }, + "serve": { + "builder": "@angular-devkit/build-angular:dev-server", + "options": { + "browserTarget": "go-style-guide:build" + }, + "configurations": { + "production": { + "browserTarget": "go-style-guide:build:production" + } + } + }, + "extract-i18n": { + "builder": "@angular-devkit/build-angular:extract-i18n", + "options": { + "browserTarget": "go-style-guide:build" + } + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "main": "projects/go-style-guide/src/test.ts", + "polyfills": "projects/go-style-guide/src/polyfills.ts", + "tsConfig": "projects/go-style-guide/tsconfig.spec.json", + "karmaConfig": "projects/go-style-guide/karma.conf.js", + "styles": [ + "projects/go-style-guide/src/styles.css" + ], + "scripts": [], + "assets": [ + "projects/go-style-guide/src/favicon.ico", + "projects/go-style-guide/src/assets" + ] + } + }, + "lint": { + "builder": "@angular-devkit/build-angular:tslint", + "options": { + "tsConfig": [ + "projects/go-style-guide/tsconfig.app.json", + "projects/go-style-guide/tsconfig.spec.json" + ], + "exclude": [ + "**/node_modules/**" + ] + } + } + } } }, "defaultProject": "go-lib" -} +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 7f2087c28..1e63985bc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4286,6 +4286,11 @@ "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", "dev": true }, + "faker": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/faker/-/faker-4.1.0.tgz", + "integrity": "sha1-HkW7vsxndLPBlfrSg1EJxtdIzD8=" + }, "fast-deep-equal": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", @@ -5486,6 +5491,11 @@ "minimalistic-assert": "^1.0.1" } }, + "highlight.js": { + "version": "9.15.10", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.15.10.tgz", + "integrity": "sha512-RoV7OkQm0T3os3Dd2VHLNMoaoDVx77Wygln3n9l5YV172XonWG6rgQD3XnF/BuFFZw9A0TJgmMSO8FEWQgvcXw==" + }, "hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", @@ -7679,6 +7689,14 @@ } } }, + "ngx-highlightjs": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/ngx-highlightjs/-/ngx-highlightjs-3.0.3.tgz", + "integrity": "sha512-/Eh+uJL9CiePWXzyT7VpLaQoWQyyNEUQaHhJ4faUBQZLBpachCBY55iDX0mi50zG9dapTiiapH5Vz/sL2GDxlg==", + "requires": { + "tslib": "^1.9.0" + } + }, "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", diff --git a/package.json b/package.json index f28f42dbb..47a6fae16 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,9 @@ "package": "npm run build_lib && npm run npm_pack", "publish": "npm run package && cd dist/go-lib && npm publish", "publish_local": "npm run package && node ./local_install.js", - "sass-lint": "node_modules/.bin/sass-lint -c .sass-lint.yml" + "sass-lint": "node_modules/.bin/sass-lint -c .sass-lint.yml", + "style_guide": "ng serve --project=go-style-guide", + "style_guide_publish": "ng build --prod --project=go-style-guide" }, "private": true, "engines": { @@ -43,6 +45,9 @@ "@ng-select/ng-select": "^2.20.5", "classlist.js": "^1.1.20150312", "core-js": "^2.5.4", + "faker": "4.1.0", + "highlight.js": "^9.13.1", + "ngx-highlightjs": "^3.0.1", "npm": "^6.10.1", "rxjs": "~6.5.2", "web-animations-js": "^2.3.2", diff --git a/projects/go-lib/src/lib/animations/accordion.animation.ts b/projects/go-lib/src/lib/animations/accordion.animation.ts index 234b39251..64f3f1489 100644 --- a/projects/go-lib/src/lib/animations/accordion.animation.ts +++ b/projects/go-lib/src/lib/animations/accordion.animation.ts @@ -12,10 +12,12 @@ import { easing, timing } from './_configs'; export const accordionAnimation: AnimationTriggerMetadata = trigger('accordionAnimation', [ state('open', style({ height: '*', + overflow: 'visible', visibility: 'visible' })), state('close', style({ height: 0, + overflow: 'hidden', visibility: 'hidden' })), transition('open <=> close', [ diff --git a/projects/go-lib/src/lib/components/go-accordion/go-accordion-panel.component.html b/projects/go-lib/src/lib/components/go-accordion/go-accordion-panel.component.html index 7a45cbd8c..dd0ae7494 100644 --- a/projects/go-lib/src/lib/components/go-accordion/go-accordion-panel.component.html +++ b/projects/go-lib/src/lib/components/go-accordion/go-accordion-panel.component.html @@ -2,6 +2,10 @@ class="go-accordion-panel" [ngClass]="containerClasses" > +
{ let component: GoAccordionPanelComponent; @@ -14,6 +15,9 @@ describe('GoAccordionPanelComponent', () => { imports: [ BrowserAnimationsModule, GoIconModule + ], + providers: [ + GoConfigService ] }) .compileComponents(); diff --git a/projects/go-lib/src/lib/components/go-accordion/go-accordion-panel.component.ts b/projects/go-lib/src/lib/components/go-accordion/go-accordion-panel.component.ts index 22ca99f91..a9e26f087 100644 --- a/projects/go-lib/src/lib/components/go-accordion/go-accordion-panel.component.ts +++ b/projects/go-lib/src/lib/components/go-accordion/go-accordion-panel.component.ts @@ -2,13 +2,15 @@ import { Component, EventEmitter, Input, + OnChanges, OnInit, Output, - ViewEncapsulation, - OnChanges } from '@angular/core'; import { accordionAnimation } from '../../animations/accordion.animation'; +import { GoConfigService } from '../../go-config.service'; +import { distinctUntilKeyChanged } from 'rxjs/operators'; +import { GoConfigInterface } from '../../go-config.model'; @Component({ selector: 'go-accordion-panel', @@ -22,6 +24,7 @@ export class GoAccordionPanelComponent implements OnInit, OnChanges { _expanded: boolean = false; // Note: Use _expanded in the template containerClasses: object = {}; headerClasses: object = {}; + brandColor: string; @Input() borderless: boolean; @Input() heading: string; @@ -44,11 +47,19 @@ export class GoAccordionPanelComponent implements OnInit, OnChanges { @Output() toggle: EventEmitter = new EventEmitter(); - constructor() { } + constructor( + private configService: GoConfigService + ) { } ngOnInit(): void { // NOTE: `title` is deprecated and will be removed in later version this.heading = this.heading || this.title; + + this.configService.config + .pipe(distinctUntilKeyChanged('brandColor')) + .subscribe((value: GoConfigInterface) => { + this.brandColor = value.brandColor; + }); } ngOnChanges(): void { diff --git a/projects/go-lib/src/lib/components/go-accordion/go-accordion.component.spec.ts b/projects/go-lib/src/lib/components/go-accordion/go-accordion.component.spec.ts index 3ec72d82a..34a3b19fc 100644 --- a/projects/go-lib/src/lib/components/go-accordion/go-accordion.component.spec.ts +++ b/projects/go-lib/src/lib/components/go-accordion/go-accordion.component.spec.ts @@ -5,6 +5,7 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { GoAccordionComponent } from './go-accordion.component'; import { GoIconModule } from '../go-icon/go-icon.module'; import { GoAccordionPanelComponent } from './go-accordion-panel.component'; +import { GoConfigService } from '../../go-config.service'; @Component({ selector: 'go-test', @@ -37,6 +38,9 @@ describe('AccordionComponent', () => { imports: [ BrowserAnimationsModule, GoIconModule + ], + providers: [ + GoConfigService ] }) .compileComponents(); diff --git a/projects/go-lib/src/lib/components/go-accordion/go-accordion.module.ts b/projects/go-lib/src/lib/components/go-accordion/go-accordion.module.ts index d370d302a..3d09a26a6 100644 --- a/projects/go-lib/src/lib/components/go-accordion/go-accordion.module.ts +++ b/projects/go-lib/src/lib/components/go-accordion/go-accordion.module.ts @@ -4,6 +4,7 @@ import { CommonModule } from '@angular/common'; import { GoAccordionComponent } from './go-accordion.component'; import { GoAccordionPanelComponent } from './go-accordion-panel.component'; import { GoIconModule } from '../go-icon/go-icon.module'; +import { GoConfigService } from '../../go-config.service'; @NgModule({ declarations: [ @@ -17,6 +18,9 @@ import { GoIconModule } from '../go-icon/go-icon.module'; exports: [ GoAccordionComponent, GoAccordionPanelComponent + ], + providers: [ + GoConfigService ] }) diff --git a/projects/go-lib/src/lib/components/go-action-sheet/go-action-sheet.component.scss b/projects/go-lib/src/lib/components/go-action-sheet/go-action-sheet.component.scss index 1681ff33b..01d3f83d5 100644 --- a/projects/go-lib/src/lib/components/go-action-sheet/go-action-sheet.component.scss +++ b/projects/go-lib/src/lib/components/go-action-sheet/go-action-sheet.component.scss @@ -2,6 +2,7 @@ @import '../../../styles/mixins'; .go-action-sheet { + display: inline-block; position: relative; } @@ -25,7 +26,7 @@ go-action-sheet-button { background: $theme-light-bg; border: 1px solid $theme-light-border; border-radius: $global-radius; - box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.2); + box-shadow: $global-box-shadow--small; left: 50%; opacity: 0; position: absolute; @@ -39,7 +40,7 @@ go-action-sheet-button { background: $theme-light-bg; border: 1px solid $theme-light-border; - box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.2); + box-shadow: $global-box-shadow--small; content: " "; height: 15px; left: calc(50% - 7.5px); diff --git a/projects/go-lib/src/lib/components/go-button/go-button.component.html b/projects/go-lib/src/lib/components/go-button/go-button.component.html index 815bb69bd..24ca19fe5 100644 --- a/projects/go-lib/src/lib/components/go-button/go-button.component.html +++ b/projects/go-lib/src/lib/components/go-button/go-button.component.html @@ -5,9 +5,16 @@ [ngClass]="classObject" [type]="buttonType" > + + + { let component: GoButtonComponent; @@ -10,7 +13,12 @@ describe('GoButtonComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [ GoButtonComponent ], - imports: [ GoIconModule ] + imports: [ + BrowserModule, + BrowserAnimationsModule, + GoIconModule, + GoLoaderModule + ] }) .compileComponents(); })); @@ -43,16 +51,12 @@ describe('GoButtonComponent', () => { describe('classObject()', () => { beforeEach(() => { - expect(component.classObject).toEqual({}); + component.classObject = {}; }); it('returns an object that sets go-button--negative to true based on buttonVariant', () => { expect(component.classObject['go-button--negative']).toBeFalsy(); - component.buttonVariant = 'alert'; - component.ngOnChanges(); - expect(component.classObject['go-button--negative']).toBe(true); - component.buttonVariant = 'negative'; component.ngOnChanges(); expect(component.classObject['go-button--negative']).toBe(true); @@ -66,12 +70,28 @@ describe('GoButtonComponent', () => { expect(component.classObject['go-button--neutral']).toBe(true); }); - it('returns an object that set go-button--positive to true based on buttonVariant', () => { - expect(component.classObject['go-button--positive']).toBeFalsy(); + it('returns an object that set go-button--primary to true based on buttonVariant', () => { + expect(component.classObject['go-button--primary']).toBeFalsy(); + + component.buttonVariant = 'primary'; + component.ngOnChanges(); + expect(component.classObject['go-button--primary']).toBe(true); + }); + + it('returns an object that set go-button--secondary to true based on buttonVariant', () => { + expect(component.classObject['go-button--secondary']).toBeFalsy(); + + component.buttonVariant = 'secondary'; + component.ngOnChanges(); + expect(component.classObject['go-button--secondary']).toBe(true); + }); + + it('returns an object that set go-button--tertiary to true based on buttonVariant', () => { + expect(component.classObject['go-button--tertiary']).toBeFalsy(); - component.buttonVariant = 'positive'; + component.buttonVariant = 'tertiary'; component.ngOnChanges(); - expect(component.classObject['go-button--positive']).toBe(true); + expect(component.classObject['go-button--tertiary']).toBe(true); }); it('returns an object that set other modifiers to true', () => { @@ -142,4 +162,44 @@ describe('GoButtonComponent', () => { expect(buttonElement.type).toBe(component.buttonType); }); }); + + describe('isAlternativeDark', () => { + it('returns true if useDarkTheme is true and buttonVariant is "secondary"', () => { + component.buttonVariant = 'secondary'; + component.useDarkTheme = true; + + const result: boolean = component['isAlternativeDark'](); + + expect(result).toBe(true); + }); + + it('returns true if useDarkTheme is true and buttonVariant is "tertiary"', () => { + component.buttonVariant = 'tertiary'; + component.useDarkTheme = true; + + const result: boolean = component['isAlternativeDark'](); + + expect(result).toBe(true); + }); + }); + + describe('isAlternativeLight', () => { + it('returns true if useDarkTheme is false and buttonVariant is "secondary"', () => { + component.buttonVariant = 'secondary'; + component.useDarkTheme = false; + + const result: boolean = component['isAlternativeLight'](); + + expect(result).toBe(true); + }); + + it('returns true if useDarkTheme is false and buttonVariant is "tertiary"', () => { + component.buttonVariant = 'tertiary'; + component.useDarkTheme = false; + + const result: boolean = component['isAlternativeLight'](); + + expect(result).toBe(true); + }); + }); }); diff --git a/projects/go-lib/src/lib/components/go-button/go-button.component.ts b/projects/go-lib/src/lib/components/go-button/go-button.component.ts index 7d1c6bb06..13849ebaa 100644 --- a/projects/go-lib/src/lib/components/go-button/go-button.component.ts +++ b/projects/go-lib/src/lib/components/go-button/go-button.component.ts @@ -1,20 +1,30 @@ -import { Component, EventEmitter, Input, Output, OnChanges } from '@angular/core'; +import { + Component, + EventEmitter, + Input, + OnChanges, + OnInit, + Output +} from '@angular/core'; +import { fadeTemplateAnimation } from '../../animations/fade.animation'; @Component({ + animations: [fadeTemplateAnimation], selector: 'go-button', templateUrl: './go-button.component.html', styleUrls: ['./go-button.component.scss'] }) -export class GoButtonComponent implements OnChanges { +export class GoButtonComponent implements OnChanges, OnInit { classObject: object = {}; + loaderClassObject: object = {}; + loaderType: 'light' | 'dark' = 'light'; @Input() buttonDisabled: boolean; @Input() buttonIcon: string; @Input() buttonType: string = 'button'; - @Input() buttonVariant: string; + @Input() buttonVariant: string = 'primary'; @Input() isProcessing: boolean = false; @Input() useDarkTheme: boolean = false; - @Input() useLoader: boolean = false; @Output() handleClick: EventEmitter = new EventEmitter(); @@ -25,20 +35,44 @@ export class GoButtonComponent implements OnChanges { reset(): void { } + ngOnInit(): void { + this.setupButton(); + } + ngOnChanges(): void { - // 'alert' as a variant is depreciated and - // will be removed in a later version - const isNegative: boolean = [ - 'alert', - 'negative' - ].includes(this.buttonVariant); + this.setupButton(); + this.buttonLoader(); + } + + private setupButton(): void { + this.buttonVariant = this.buttonVariant === 'positive' ? 'primary' : this.buttonVariant; this.classObject = { 'go-button--dark': this.useDarkTheme, - 'go-button--loading': this.isProcessing, - 'go-button--negative': isNegative, - 'go-button--neutral': (this.buttonVariant === 'neutral'), - 'go-button--positive': (this.buttonVariant === 'positive') + 'go-button--loading': this.isProcessing }; + + this.classObject['go-button--' + this.buttonVariant] = true; + } + + private buttonLoader(): void { + if (this.isAlternativeDark()) { + this.loaderType = 'light'; + this.loaderClassObject['go-button__loader--dark'] = true; + } else if (this.isAlternativeLight()) { + this.loaderType = 'dark'; + this.loaderClassObject['go-button__loader--light'] = true; + } else { + this.loaderType = 'light'; + this.loaderClassObject[`go-button__loader--${this.buttonVariant}`] = true; + } + } + + private isAlternativeDark(): boolean { + return (this.buttonVariant === 'secondary' || this.buttonVariant === 'tertiary') && this.useDarkTheme; + } + + private isAlternativeLight(): boolean { + return (this.buttonVariant === 'secondary' || this.buttonVariant === 'tertiary') && !this.useDarkTheme; } } diff --git a/projects/go-lib/src/lib/components/go-button/go-button.module.ts b/projects/go-lib/src/lib/components/go-button/go-button.module.ts index d08dd9988..aef150e37 100644 --- a/projects/go-lib/src/lib/components/go-button/go-button.module.ts +++ b/projects/go-lib/src/lib/components/go-button/go-button.module.ts @@ -3,12 +3,14 @@ import { CommonModule } from '@angular/common'; import { GoButtonComponent } from './go-button.component'; import { GoIconModule } from '../go-icon/go-icon.module'; +import { GoLoaderModule } from '../go-loader/go-loader.module'; @NgModule({ declarations: [GoButtonComponent], imports: [ CommonModule, - GoIconModule + GoIconModule, + GoLoaderModule ], exports: [GoButtonComponent] }) diff --git a/projects/go-lib/src/lib/components/go-card/go-card.component.scss b/projects/go-lib/src/lib/components/go-card/go-card.component.scss index 272053318..d7eff8284 100644 --- a/projects/go-lib/src/lib/components/go-card/go-card.component.scss +++ b/projects/go-lib/src/lib/components/go-card/go-card.component.scss @@ -4,7 +4,7 @@ .card { background: $theme-light-bg; border-radius: $global-radius; - box-shadow: $global-box-shadow; + box-shadow: $global-box-shadow--regular; display: flex; flex-direction: column; padding: 1rem; diff --git a/projects/go-lib/src/lib/components/go-checkbox/go-checkbox.component.html b/projects/go-lib/src/lib/components/go-checkbox/go-checkbox.component.html index d84f2ed10..77b46c8a3 100644 --- a/projects/go-lib/src/lib/components/go-checkbox/go-checkbox.component.html +++ b/projects/go-lib/src/lib/components/go-checkbox/go-checkbox.component.html @@ -10,4 +10,16 @@ [ngClass]="{'go-form__label--dark': theme === 'dark'}"> {{ label }} + + + +
+ +
diff --git a/projects/go-lib/src/lib/components/go-checkbox/go-checkbox.component.spec.ts b/projects/go-lib/src/lib/components/go-checkbox/go-checkbox.component.spec.ts index 47d94a00d..d58089721 100644 --- a/projects/go-lib/src/lib/components/go-checkbox/go-checkbox.component.spec.ts +++ b/projects/go-lib/src/lib/components/go-checkbox/go-checkbox.component.spec.ts @@ -2,6 +2,7 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms'; import { GoCheckboxComponent } from './go-checkbox.component'; +import { GoHintModule } from '../go-hint/go-hint.module'; describe('GoCheckboxComponent', () => { let component: GoCheckboxComponent; @@ -10,7 +11,11 @@ describe('GoCheckboxComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [GoCheckboxComponent], - imports: [FormsModule, ReactiveFormsModule] + imports: [ + FormsModule, + ReactiveFormsModule, + GoHintModule + ] }) .compileComponents(); })); diff --git a/projects/go-lib/src/lib/components/go-copy/go-copy.component.html b/projects/go-lib/src/lib/components/go-copy/go-copy.component.html index 4ab1db152..18c07f732 100644 --- a/projects/go-lib/src/lib/components/go-copy/go-copy.component.html +++ b/projects/go-lib/src/lib/components/go-copy/go-copy.component.html @@ -1,4 +1,4 @@ -
+
diff --git a/projects/go-lib/src/lib/components/go-copy/go-copy.component.scss b/projects/go-lib/src/lib/components/go-copy/go-copy.component.scss index b8574be71..992b398dc 100644 --- a/projects/go-lib/src/lib/components/go-copy/go-copy.component.scss +++ b/projects/go-lib/src/lib/components/go-copy/go-copy.component.scss @@ -2,3 +2,8 @@ position: absolute; left: 99999px; } + +.go-copy { + overflow: hidden; + position: relative; +} diff --git a/projects/go-lib/src/lib/components/go-datepicker/date-adapter.ts b/projects/go-lib/src/lib/components/go-datepicker/date-adapter.ts index dfb2ce35f..c3bf152e5 100644 --- a/projects/go-lib/src/lib/components/go-datepicker/date-adapter.ts +++ b/projects/go-lib/src/lib/components/go-datepicker/date-adapter.ts @@ -16,7 +16,7 @@ export class DateAdapter { } public getYearName(year: number): string { - const format: Intl.DateTimeFormat = new Intl.DateTimeFormat(this._locale, {year: 'numeric', timeZone: 'utc'}); + const format: Intl.DateTimeFormat = new Intl.DateTimeFormat(this._locale, {year: 'numeric'}); return this.format(format, new Date(year, 0, 1)); } @@ -63,7 +63,7 @@ export class DateAdapter { } private getMonthNames(style: 'long' | 'short' | 'narrow'): Array { - const format: Intl.DateTimeFormat = new Intl.DateTimeFormat(this._locale, {month: style, timeZone: 'utc'}); + const format: Intl.DateTimeFormat = new Intl.DateTimeFormat(this._locale, {month: style}); const months: Array = []; for (let i: number = 0; i < 12; i++) { months.push(this.format(format, new Date(2017, i, 1))); @@ -72,7 +72,7 @@ export class DateAdapter { } private getDateNames(): Array { - const format: Intl.DateTimeFormat = new Intl.DateTimeFormat(this._locale, {day: 'numeric', timeZone: 'utc'}); + const format: Intl.DateTimeFormat = new Intl.DateTimeFormat(this._locale, {day: 'numeric'}); const dates: Array = []; for (let i: number = 0; i < 31; i++) { @@ -83,7 +83,7 @@ export class DateAdapter { } private getDayOfWeekNames(style: 'long' | 'short' | 'narrow'): Array { - const format: Intl.DateTimeFormat = new Intl.DateTimeFormat(this._locale, {weekday: style, timeZone: 'utc'}); + const format: Intl.DateTimeFormat = new Intl.DateTimeFormat(this._locale, {weekday: style}); const dayNames: Array = []; for (let i: number = 0; i < 7; i++) { diff --git a/projects/go-lib/src/lib/components/go-file-upload/go-dragon-drop.directive.ts b/projects/go-lib/src/lib/components/go-file-upload/go-dragon-drop.directive.ts new file mode 100644 index 000000000..8f5ec478d --- /dev/null +++ b/projects/go-lib/src/lib/components/go-file-upload/go-dragon-drop.directive.ts @@ -0,0 +1,41 @@ +import { Directive, EventEmitter, HostBinding, HostListener, Input, Output } from '@angular/core'; + +@Directive({ + selector: '[goDragonDrop]' +}) +export class DragonDropDirective { + active: boolean = false; + @Input() class: string = ''; // override the standard class attr with a new one. + @Input() activeClass: string = ''; + @Output() dropped: EventEmitter = new EventEmitter(); + + @HostBinding('class') + get hostClasses(): string { + return [ + this.class, + this.active ? this.activeClass : '', + ].join(' '); + } + + // Dragover listener + @HostListener('dragover', ['$event']) onDragOver(evt: Event): void { + evt.preventDefault(); + evt.stopPropagation(); + this.active = true; + } + + // Dragleave listener + @HostListener('dragleave', ['$event']) public onDragLeave(evt: Event): void { + evt.preventDefault(); + evt.stopPropagation(); + this.active = false; + } + + // Drop listener + @HostListener('drop', ['$event']) public ondrop(evt: any): void { + evt.preventDefault(); + evt.stopPropagation(); + this.active = false; + this.dropped.emit(evt); + } +} diff --git a/projects/go-lib/src/lib/components/go-file-upload/go-file-upload.component.html b/projects/go-lib/src/lib/components/go-file-upload/go-file-upload.component.html new file mode 100644 index 000000000..8bacb9894 --- /dev/null +++ b/projects/go-lib/src/lib/components/go-file-upload/go-file-upload.component.html @@ -0,0 +1,56 @@ + +
+
+
+ + Drag and Drop File or Click to Browse +
+
+ + Uploading File... +
+
+ + File Selected +
+ +
+
+ +
+ + +

+ {{ file }} + +

+
+ + + + +
+ +
diff --git a/projects/go-lib/src/lib/components/go-file-upload/go-file-upload.component.scss b/projects/go-lib/src/lib/components/go-file-upload/go-file-upload.component.scss new file mode 100644 index 000000000..f8f034dac --- /dev/null +++ b/projects/go-lib/src/lib/components/go-file-upload/go-file-upload.component.scss @@ -0,0 +1,87 @@ +@import '../../../styles/variables'; + +@mixin upload-active { + cursor: pointer; + background-color: $theme-light-bg-hover; + opacity: 0.8; +} + +.go-file-upload__input { + visibility: hidden; +} + +.go-file-upload { + height: 10rem; + border: 1px dashed $theme-light-border; + border-radius: $global-radius; +} + +.go-file-upload--disabled { + color: lighten($theme-light-color, 40); + cursor: not-allowed; + pointer-events: none; + border-style: solid; +} + +.go-file-upload--dark { + border: 1px dashed $theme-dark-border; + background-color: $theme-dark-bg; + border-radius: $global-radius; + color: $theme-dark-color; + + .go-file-upload:hover { + background-color: $theme-dark-bg-hover; + color: $theme-dark-color-hover + } + + .go-file-upload--active { + color: $theme-dark-color-hover; + background-color: $theme-dark-bg-hover; + } +} + +.go-file-upload:hover { + @include upload-active; +} + +.go-file-upload--active { + @include upload-active; + border-style: solid; +} + +.go-file-upload__container { + justify-content: center; + display: flex; + flex-direction: column; + text-align: center; +} + +.go-file-upload__file-list { + display: flex; + justify-content: space-between; +} + +.go-file-upload__file-name { + margin-top: .5rem; + padding-right: .5rem; +} + +.go-file-upload__container--loading-text { + padding-top: .5rem; +} + +.go-file-upload__container--loading { + padding-top: 1rem; +} + +.file-name__label { + padding-bottom: .25rem; +} + +.go-file-upload__file-name--dark { + color: $theme-dark-color; +} + +.go-file-upload__selected-checkmark { + color: $ui-color-positive; +} diff --git a/projects/go-lib/src/lib/components/go-file-upload/go-file-upload.component.spec.ts b/projects/go-lib/src/lib/components/go-file-upload/go-file-upload.component.spec.ts new file mode 100644 index 000000000..bf8a26d57 --- /dev/null +++ b/projects/go-lib/src/lib/components/go-file-upload/go-file-upload.component.spec.ts @@ -0,0 +1,113 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { GoFileUploadComponent } from './go-file-upload.component'; +import { CommonModule } from '@angular/common'; +import { FormsModule, ReactiveFormsModule, FormArray, FormGroup, FormControl } from '@angular/forms'; +import { GoButtonModule } from '../go-button/go-button.module'; +import { GoHintModule } from '../go-hint/go-hint.module'; +import { GoIconButtonModule } from '../go-icon-button/go-icon-button.module'; +import { GoIconModule } from '../go-icon/go-icon.module'; +import { GoLoaderModule } from '../go-loader/go-loader.module'; +import { createHostListener } from '@angular/compiler/src/core'; + +describe('GoFileUploadComponent', () => { + let component: GoFileUploadComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [GoFileUploadComponent], + imports: [ + CommonModule, + FormsModule, + GoButtonModule, + GoHintModule, + GoIconModule, + GoIconButtonModule, + GoLoaderModule, + ReactiveFormsModule + ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(GoFileUploadComponent); + component = fixture.componentInstance; + component.control = new FormControl(''); + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + describe('removeFile', () => { + beforeEach(() => { + const file: FormGroup = new FormGroup({ + file: new FormControl('whatever') + }); + component.files = new FormArray([file]); + component.filePreview = ['whatever']; + }); + + it('should set state to selecting if it was previously selected', () => { + component.state = 'selected'; + component.removeFile(0); + expect(component.state).toBe('selecting'); + }); + + it('should not change the state if the state was selecting', () => { + component.state = 'selecting'; + component.removeFile(0); + expect(component.state).toBe('selecting'); + }); + + it('should remove the file at the given index from the form control', () => { + component.removeFile(0); + expect(component.control.value.length).toBe(0); + }); + + it('should remove the file at the given index from our file Preview Array', () => { + component.removeFile(0); + expect(component.filePreview.length).toBe(0); + }); + }); + + describe('ngOnInit()', () => { + beforeEach(() => { + component.id = undefined; + }); + + it('sets the id of the input to `key` if one is passed in', () => { + expect(component.id).toBeUndefined(); + + component.key = 'a-specific-id'; + component.ngOnInit(); + + expect(component.id).toBe(component.key); + }); + + it('generates a semi-random id based on the label if key is undefined', () => { + expect(component.key).toBeUndefined(); + expect(component.id).toBeUndefined(); + + component.label = 'test label'; + component.ngOnInit(); + + expect(component.id).toBeDefined(); + expect(component.id).toContain('test-label-'); + }); + + it('generates a semi-random id if a label and key are undefined', () => { + expect(component.key).toBeUndefined(); + expect(component.label).toBeUndefined(); + expect(component.id).toBeUndefined(); + + component.ngOnInit(); + + expect(component.id).toBeDefined(); + expect(component.id).toContain('file-upload-'); + }); + }); +}); diff --git a/projects/go-lib/src/lib/components/go-file-upload/go-file-upload.component.ts b/projects/go-lib/src/lib/components/go-file-upload/go-file-upload.component.ts new file mode 100644 index 000000000..222d67f0a --- /dev/null +++ b/projects/go-lib/src/lib/components/go-file-upload/go-file-upload.component.ts @@ -0,0 +1,75 @@ +import { Component, ElementRef, Input, OnInit, ViewChild } from '@angular/core'; +import { AbstractControl, FormArray, FormBuilder, FormControl, FormGroup } from '@angular/forms'; + +@Component({ + selector: 'go-file-upload', + templateUrl: './go-file-upload.component.html', + styleUrls: ['./go-file-upload.component.scss'] +}) +export class GoFileUploadComponent implements OnInit { + form: FormGroup; + files: FormArray; + fb: FormBuilder; + filePreview: Array = []; + id: string; + + @Input() control: FormControl; + @Input() hints: Array = []; + @Input() isLoading: boolean = false; + @Input() key: string; + @Input() label: string; + @Input() multiple: boolean = false; + @Input() state: 'selecting' | 'selected' = 'selecting'; + @Input() theme: 'light' | 'dark' = 'light'; + + constructor() { } + + ngOnInit(): void { + this.id = this.key || this.generateId(this.label); + this.fb = new FormBuilder(); + this.form = this.fb.group({ + filesArray: this.fb.array([]) + }); + this.files = this.form.controls['filesArray']; + this.files.valueChanges.subscribe( (fileChanges: any) => { + this.control.setValue(fileChanges); + }); + } + + onFilePicked(evt: any): void { + const files: File[] = evt.dataTransfer.files; + if (files.length > 0) { + Array.from(files).forEach((file: any) => { + this.files.push(this.patchValues(file)); + this.filePreview.push(file.name); + }); + if (!this.multiple) { + this.state = 'selected'; + } + } + } + + removeFile(index: number): void { + this.files.removeAt(index); + this.filePreview.splice(index, 1); + if (this.state === 'selected') { + this.state = 'selecting'; + } + } + + private patchValues(file: any): AbstractControl { + return this.fb.group({ + file: [file] + }); + } + + private generateId(label: string): string { + const labelText: string = label || 'file-upload'; + const idArray: Array = labelText.split(' '); + + // NOTE: There is only a one in a million chance that this number is not unique. + idArray.push(String(Math.round(Math.random() * 1000000))); + + return idArray.join('-'); + } +} diff --git a/projects/go-lib/src/lib/components/go-file-upload/go-file-upload.module.ts b/projects/go-lib/src/lib/components/go-file-upload/go-file-upload.module.ts new file mode 100644 index 000000000..e38f3590d --- /dev/null +++ b/projects/go-lib/src/lib/components/go-file-upload/go-file-upload.module.ts @@ -0,0 +1,31 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; + +import { GoHintModule } from '../go-hint/go-hint.module'; +import { GoFileUploadComponent } from './go-file-upload.component'; +import { GoButtonModule } from '../go-button/go-button.module'; +import { GoIconButtonModule } from '../go-icon-button/go-icon-button.module'; +import { DragonDropDirective } from './go-dragon-drop.directive'; +import { GoIconModule } from '../go-icon/go-icon.module'; +import { GoLoaderModule } from '../go-loader/go-loader.module'; + +@NgModule({ + declarations: [ + DragonDropDirective, + GoFileUploadComponent + ], + imports: [ + CommonModule, + FormsModule, + GoButtonModule, + GoHintModule, + GoIconModule, + GoIconButtonModule, + GoLoaderModule, + ReactiveFormsModule + ], + exports: [GoFileUploadComponent] +}) + +export class GoFileUploadModule { } diff --git a/projects/go-lib/src/lib/components/go-footer/go-footer.component.html b/projects/go-lib/src/lib/components/go-footer/go-footer.component.html new file mode 100644 index 000000000..f6cf67da9 --- /dev/null +++ b/projects/go-lib/src/lib/components/go-footer/go-footer.component.html @@ -0,0 +1,3 @@ + diff --git a/projects/go-lib/src/lib/components/go-footer/go-footer.component.scss b/projects/go-lib/src/lib/components/go-footer/go-footer.component.scss new file mode 100644 index 000000000..0e3b89a0a --- /dev/null +++ b/projects/go-lib/src/lib/components/go-footer/go-footer.component.scss @@ -0,0 +1,4 @@ +.go-footer { + justify-content: center; + display: flex; +} diff --git a/projects/go-lib/src/lib/components/go-footer/go-footer.component.spec.ts b/projects/go-lib/src/lib/components/go-footer/go-footer.component.spec.ts new file mode 100644 index 000000000..066895a2c --- /dev/null +++ b/projects/go-lib/src/lib/components/go-footer/go-footer.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { GoFooterComponent } from './go-footer.component'; + +describe('GoFooterComponent', () => { + let component: GoFooterComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ GoFooterComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(GoFooterComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/projects/go-lib/src/lib/components/go-footer/go-footer.component.ts b/projects/go-lib/src/lib/components/go-footer/go-footer.component.ts new file mode 100644 index 000000000..2686c618e --- /dev/null +++ b/projects/go-lib/src/lib/components/go-footer/go-footer.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'go-footer', + styleUrls: ['./go-footer.component.scss'], + templateUrl: './go-footer.component.html' +}) +export class GoFooterComponent { + +} diff --git a/projects/go-lib/src/lib/components/go-footer/go-footer.module.ts b/projects/go-lib/src/lib/components/go-footer/go-footer.module.ts new file mode 100644 index 000000000..0ce67f2fa --- /dev/null +++ b/projects/go-lib/src/lib/components/go-footer/go-footer.module.ts @@ -0,0 +1,18 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +import { GoFooterComponent } from './go-footer.component'; + +@NgModule({ + declarations: [ + GoFooterComponent + ], + imports: [ + CommonModule + ], + exports: [ + GoFooterComponent + ] +}) + +export class GoFooterModule { } diff --git a/projects/go-lib/src/lib/components/go-header/go-header.component.html b/projects/go-lib/src/lib/components/go-header/go-header.component.html index fe6a5e051..0e6a681a1 100644 --- a/projects/go-lib/src/lib/components/go-header/go-header.component.html +++ b/projects/go-lib/src/lib/components/go-header/go-header.component.html @@ -1,21 +1,22 @@
- - + [ngClass]="{ 'go-header__left--dark': brandColorIsDark }"> +
+ + +
+ [ngClass]="{ 'go-header__logo-container--collapsed': isNavCollapsed() }" + [ngStyle]="{ 'background': getLogoBackground() }">
diff --git a/projects/go-lib/src/lib/components/go-header/go-header.component.scss b/projects/go-lib/src/lib/components/go-header/go-header.component.scss index 119fae2ef..4c5e95263 100644 --- a/projects/go-lib/src/lib/components/go-header/go-header.component.scss +++ b/projects/go-lib/src/lib/components/go-header/go-header.component.scss @@ -5,7 +5,7 @@ $breakpoint-header-mobile-small: 500px; .go-header { background: $theme-light-bg; - box-shadow: $global-box-shadow; + box-shadow: $global-box-shadow--large; display: flex; height: $header-height; justify-content: space-between; @@ -18,13 +18,26 @@ $breakpoint-header-mobile-small: 500px; } } +.go-header__menu-container { + align-items: center; + cursor: pointer; + display: flex; + justify-content: center; + width: $side-nav-width--collapsed; + + &:hover { + .go-header__menu { + opacity: .5; + } + } +} + .go-header__menu { - @include transition(background); + @include transition(all); align-items: center; align-self: center; border-radius: 50%; - cursor: pointer; display: flex; flex-shrink: 0; font-size: 1.5rem; @@ -39,7 +52,7 @@ $breakpoint-header-mobile-small: 500px; display: flex; flex: 1; justify-content: flex-start; - padding: 0.5rem 1rem; + padding: 1rem; @media (max-width: $breakpoint-header-mobile-small) { padding: 0.5rem; @@ -61,7 +74,6 @@ $breakpoint-header-mobile-small: 500px; @include transition(width); display: flex; - padding: 0.5rem; width: 15.5rem; @media (max-width: $breakpoint-mobile) { @@ -69,8 +81,8 @@ $breakpoint-header-mobile-small: 500px; } } -.go-header__left--collapsed { - width: auto; +.go-header__left--dark { + color: $theme-dark-color } .go-header__middle { @@ -90,10 +102,6 @@ $breakpoint-header-mobile-small: 500px; } } -.go-header__middle--collapsed { - padding: 0 1rem; -} - .go-header__middle--hide { display: none; } diff --git a/projects/go-lib/src/lib/components/go-header/go-header.component.spec.ts b/projects/go-lib/src/lib/components/go-header/go-header.component.spec.ts index 6bfbcfc0e..82003500b 100644 --- a/projects/go-lib/src/lib/components/go-header/go-header.component.spec.ts +++ b/projects/go-lib/src/lib/components/go-header/go-header.component.spec.ts @@ -1,7 +1,11 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { GoHeaderComponent } from './go-header.component'; -import { GoIconButtonModule } from '../go-icon-button/go-icon-button.module'; +import { GoIconModule } from '../go-icon/go-icon.module'; +import { CommonModule } from '@angular/common'; +import { RouterModule } from '@angular/router'; +import { RouterTestingModule } from '@angular/router/testing'; +import { GoConfigService } from '../../go-config.service'; describe('GoHeaderComponent', () => { let component: GoHeaderComponent; @@ -11,7 +15,13 @@ describe('GoHeaderComponent', () => { TestBed.configureTestingModule({ declarations: [ GoHeaderComponent ], imports: [ - GoIconButtonModule + CommonModule, + GoIconModule, + RouterModule, + RouterTestingModule + ], + providers: [ + GoConfigService ] }) .compileComponents(); diff --git a/projects/go-lib/src/lib/components/go-header/go-header.component.ts b/projects/go-lib/src/lib/components/go-header/go-header.component.ts index 20a46931b..7c2dc4682 100644 --- a/projects/go-lib/src/lib/components/go-header/go-header.component.ts +++ b/projects/go-lib/src/lib/components/go-header/go-header.component.ts @@ -1,33 +1,67 @@ -import { Component, ElementRef, Input, ViewChild } from '@angular/core'; -import { GoSideNavService } from '../go-side-nav/go-side-nav/go-side-nav.service'; +import { Component, ElementRef, Input, OnChanges, ViewChild } from '@angular/core'; import { fromEvent, Observable, Subscription } from 'rxjs'; -import { debounceTime } from 'rxjs/operators'; +import { debounceTime, distinctUntilChanged } from 'rxjs/operators'; +import { GoConfigInterface } from '../../go-config.model'; +import { GoConfigService } from '../../go-config.service'; +import { GoSideNavService } from '../go-side-nav/go-side-nav/go-side-nav.service'; @Component({ selector: 'go-header', templateUrl: './go-header.component.html', styleUrls: ['./go-header.component.scss'] }) -export class GoHeaderComponent { +export class GoHeaderComponent implements OnChanges { @Input() altText: string = ''; @Input() logo: string = ''; @ViewChild('middleSection') middleSection: ElementRef; + public brandColor: string; + public brandColorIsDark: boolean; + private minWidthBreakpoint: number = 768; private resizeObservable: Observable = fromEvent(window, 'resize'); - private resizeSubsciption: Subscription; + private resizeSubscription: Subscription; - constructor(public sideNavService: GoSideNavService) { + constructor ( + public sideNavService: GoSideNavService, + private configService: GoConfigService + ) { this.setMobileNav(); this.setupResizeSubscription(); } + ngOnChanges(): void { + this.configService.config + .pipe(distinctUntilChanged()) + .subscribe((value: GoConfigInterface) => { + if (value.headerBrandingEnabled) { + if (value.brandFontColor) { + this.brandColor = value.brandColor; + this.brandColorIsDark = value.brandFontColor === 'light'; + } else { + this.handleBrandColorChange(value); + } + } else { + this.brandColor = ''; + this.brandColorIsDark = false; + } + }); + } + isNavCollapsed(): boolean { return window.innerWidth <= this.minWidthBreakpoint ? true : !this.sideNavService.navOpen; } + getLogoBackground(): string | null { + if (this.brandColor && !this.isNavCollapsed()) { + return this.brandColor; + } else { + return null; + } + } + toggleSideMenu(): void { this.sideNavService.toggleNav(); } @@ -37,7 +71,7 @@ export class GoHeaderComponent { } private setupResizeSubscription(): void { - this.resizeSubsciption = this.resizeObservable + this.resizeSubscription = this.resizeObservable .pipe(debounceTime(250)) .subscribe(event => { this.setMobileNav(); @@ -49,4 +83,11 @@ export class GoHeaderComponent { this.sideNavService.navOpen = false; } } + + private handleBrandColorChange(value: GoConfigInterface): void { + const baseDarkHex: string = '#313536'; + this.brandColor = value.brandColor; + + this.brandColorIsDark = !this.configService.contrastIsAccessible(this.brandColor, baseDarkHex); + } } diff --git a/projects/go-lib/src/lib/components/go-header/go-header.module.ts b/projects/go-lib/src/lib/components/go-header/go-header.module.ts index 0fb57a052..f18580700 100644 --- a/projects/go-lib/src/lib/components/go-header/go-header.module.ts +++ b/projects/go-lib/src/lib/components/go-header/go-header.module.ts @@ -1,7 +1,7 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; -import { GoIconButtonModule} from '../go-icon-button/go-icon-button.module'; +import { GoIconModule} from '../go-icon/go-icon.module'; import { GoSideNavModule } from '../go-side-nav/go-side-nav.module'; import { GoSideNavService } from '../go-side-nav/go-side-nav/go-side-nav.service'; @@ -14,7 +14,7 @@ import { GoHeaderComponent } from './go-header.component'; ], imports: [ CommonModule, - GoIconButtonModule, + GoIconModule, GoSideNavModule ], exports: [ diff --git a/projects/go-lib/src/lib/components/go-icon-button/go-icon-button.component.scss b/projects/go-lib/src/lib/components/go-icon-button/go-icon-button.component.scss index 6f5cc5a18..a184bcf5a 100644 --- a/projects/go-lib/src/lib/components/go-icon-button/go-icon-button.component.scss +++ b/projects/go-lib/src/lib/components/go-icon-button/go-icon-button.component.scss @@ -4,10 +4,10 @@ .go-icon-button { @include transition(background-color); - background: $theme-light-bg; + background: transparent; border: 0; border-radius: $global-radius--round; - color: $base-dark; + color: inherit; cursor: pointer; display: inline-flex; outline: none; @@ -18,7 +18,7 @@ } &:hover, &:focus { - background: $theme-light-bg-hover; + background: $base-light-secondary; } &:active { diff --git a/projects/go-lib/src/lib/components/go-icon/go-icon.component.scss b/projects/go-lib/src/lib/components/go-icon/go-icon.component.scss index d3642e339..75d7d322d 100644 --- a/projects/go-lib/src/lib/components/go-icon/go-icon.component.scss +++ b/projects/go-lib/src/lib/components/go-icon/go-icon.component.scss @@ -7,10 +7,10 @@ $icon-sizes: (small: 1rem, medium: 1.5rem, large: 2rem); // icons documentation and applied to our own bem style block class. .go-icon { // sass-lint:disable-block no-vendor-prefixes property-sort-order + display: inline-block; font-family: 'Material Icons'; - font-weight: normal; font-style: normal; - display: inline-block; + font-weight: normal; line-height: 1; text-transform: none; letter-spacing: normal; @@ -31,24 +31,23 @@ $icon-sizes: (small: 1rem, medium: 1.5rem, large: 2rem); font-feature-settings: 'liga'; } -.go-icon--light { - @include fill-text-background($color: $theme-light-border); -} +.go-icon--dark { + color: $theme-light-color; -.go-icon--negative { - @include fill-text-background($ui-color-negative-gradient, $ui-color-negative); + &.go-icon--disabled { + color: rgba($theme-light-color, .7); + } } +.go-icon--light, +.go-icon--primary, +.go-icon--negative, .go-icon--neutral { - @include fill-text-background($ui-color-neutral-gradient, $ui-color-neutral); -} + color: $theme-dark-color; -.go-icon--positive { - @include fill-text-background($ui-color-positive-gradient, $ui-color-positive); -} - -.go-icon--disabled { - @include fill-text-background($color: $theme-light-border); + &.go-icon--disabled { + color: rgba($theme-dark-color, .7); + } } @each $name, $size in $icon-sizes { @@ -58,11 +57,11 @@ $icon-sizes: (small: 1rem, medium: 1.5rem, large: 2rem); } .go-button__icon { - font-size: 1.25rem; + font-size: 1rem; line-height: 1rem; margin-bottom: -.2rem; - margin-left: -$column-gutter--half; - margin-right: $column-gutter--quarter; + margin-left: -$column-gutter--quarter; + margin-right: $column-gutter--half; margin-top: -.2rem; padding: .2rem 0; vertical-align: top; diff --git a/projects/go-lib/src/lib/components/go-layout/go-layout.component.html b/projects/go-lib/src/lib/components/go-layout/go-layout.component.html index b26490764..807e5245c 100644 --- a/projects/go-lib/src/lib/components/go-layout/go-layout.component.html +++ b/projects/go-lib/src/lib/components/go-layout/go-layout.component.html @@ -1,20 +1,27 @@
-
+
+ +
diff --git a/projects/go-lib/src/lib/components/go-layout/go-layout.component.scss b/projects/go-lib/src/lib/components/go-layout/go-layout.component.scss index 32fa929ae..b8386df5f 100644 --- a/projects/go-lib/src/lib/components/go-layout/go-layout.component.scss +++ b/projects/go-lib/src/lib/components/go-layout/go-layout.component.scss @@ -9,14 +9,10 @@ body { display: flex; flex-direction: column; height: 100vh; + width: 100vw; overflow: hidden; } -.go-layout__nav { - max-height: 100%; - overflow-y: auto; -} - .go-layout__content { display: flex; flex-grow: 1; @@ -26,16 +22,22 @@ body { .go-layout__route-container { display: flex; flex-grow: 1; - position: relative; + flex-direction: column; + width: 100%; + overflow-x: hidden; + overflow-y: scroll; + height: calc(100vh - 4rem); } -.go-layout__route-container-outlet ~ * { - height: 100%; - overflow-x: hidden; - overflow-y: auto; +.go-layout__route-container-outlet ~ :not(go-footer) { + width: 100%; padding: 2rem; - position: absolute; + flex-grow: 1; +} + +.go-footer { width: 100%; + padding: 0 2rem 2rem 2rem; } .go-route-loader { @@ -47,4 +49,5 @@ body { overflow: hidden; position: absolute; width: 100%; + z-index: z-index(loading-screen); } diff --git a/projects/go-lib/src/lib/components/go-loader/go-loader.component.scss b/projects/go-lib/src/lib/components/go-loader/go-loader.component.scss index f5811ef54..f53f9700d 100644 --- a/projects/go-lib/src/lib/components/go-loader/go-loader.component.scss +++ b/projects/go-lib/src/lib/components/go-loader/go-loader.component.scss @@ -2,6 +2,7 @@ @import '../../../styles/mixins'; $loader-sizes: ( + xsmall: 1.5rem, small: 50px, medium: 100px, large: 150px diff --git a/projects/go-lib/src/lib/components/go-loader/go-loader.component.spec.ts b/projects/go-lib/src/lib/components/go-loader/go-loader.component.spec.ts index 72b3309d9..ddc455ebe 100644 --- a/projects/go-lib/src/lib/components/go-loader/go-loader.component.spec.ts +++ b/projects/go-lib/src/lib/components/go-loader/go-loader.component.spec.ts @@ -26,10 +26,21 @@ describe('GoLoaderComponent', () => { }); describe('loaderClasses()', () => { + it('adds an xsmall modifier class based on loaderSize', () => { + component.loaderSize = 'xsmall'; + + const containerClasses: object = component.loaderClasses(); + expect(containerClasses['go-loader--xsmall']).toBe(true); + expect(containerClasses['go-loader--small']).toBe(false); + expect(containerClasses['go-loader--medium']).toBe(false); + expect(containerClasses['go-loader--large']).toBe(false); + }); + it('adds a small modifier class based on loaderSize', () => { component.loaderSize = 'small'; - const containerClasses = component.loaderClasses(); + const containerClasses: object = component.loaderClasses(); + expect(containerClasses['go-loader--xsmall']).toBe(false); expect(containerClasses['go-loader--small']).toBe(true); expect(containerClasses['go-loader--medium']).toBe(false); expect(containerClasses['go-loader--large']).toBe(false); @@ -38,7 +49,8 @@ describe('GoLoaderComponent', () => { it('adds a medium modifier class based on loaderSize', () => { component.loaderSize = 'medium'; - const containerClasses = component.loaderClasses(); + const containerClasses: object = component.loaderClasses(); + expect(containerClasses['go-loader--xsmall']).toBe(false); expect(containerClasses['go-loader--small']).toBe(false); expect(containerClasses['go-loader--medium']).toBe(true); expect(containerClasses['go-loader--large']).toBe(false); @@ -47,7 +59,8 @@ describe('GoLoaderComponent', () => { it('adds a large modifier class based on loaderSize', () => { component.loaderSize = 'large'; - const containerClasses = component.loaderClasses(); + const containerClasses: object = component.loaderClasses(); + expect(containerClasses['go-loader--xsmall']).toBe(false); expect(containerClasses['go-loader--small']).toBe(false); expect(containerClasses['go-loader--medium']).toBe(false); expect(containerClasses['go-loader--large']).toBe(true); @@ -56,7 +69,7 @@ describe('GoLoaderComponent', () => { it('adds a neutral modifier class based on loaderType', () => { component.loaderType = 'neutral'; - const containerClasses = component.loaderClasses(); + const containerClasses: object = component.loaderClasses(); expect(containerClasses['go-loader--neutral']).toBe(true); expect(containerClasses['go-loader--negative']).toBe(false); expect(containerClasses['go-loader--positive']).toBe(false); @@ -65,7 +78,7 @@ describe('GoLoaderComponent', () => { it('adds a negative modifier class based on loaderType', () => { component.loaderType = 'negative'; - const containerClasses = component.loaderClasses(); + const containerClasses: object = component.loaderClasses(); expect(containerClasses['go-loader--neutral']).toBe(false); expect(containerClasses['go-loader--negative']).toBe(true); expect(containerClasses['go-loader--positive']).toBe(false); @@ -74,7 +87,7 @@ describe('GoLoaderComponent', () => { it('adds a positive modifier class based on loaderType', () => { component.loaderType = 'positive'; - const containerClasses = component.loaderClasses(); + const containerClasses: object = component.loaderClasses(); expect(containerClasses['go-loader--neutral']).toBe(false); expect(containerClasses['go-loader--negative']).toBe(false); expect(containerClasses['go-loader--positive']).toBe(true); diff --git a/projects/go-lib/src/lib/components/go-loader/go-loader.component.ts b/projects/go-lib/src/lib/components/go-loader/go-loader.component.ts index 9828c188b..6687a2c40 100644 --- a/projects/go-lib/src/lib/components/go-loader/go-loader.component.ts +++ b/projects/go-lib/src/lib/components/go-loader/go-loader.component.ts @@ -19,6 +19,7 @@ export class GoLoaderComponent { loaderClasses(): object { return { + 'go-loader--xsmall': this.loaderSize === 'xsmall', 'go-loader--small': this.loaderSize === 'small', 'go-loader--medium': this.loaderSize === 'medium', 'go-loader--large': this.loaderSize === 'large', diff --git a/projects/go-lib/src/lib/components/go-modal/go-modal.component.scss b/projects/go-lib/src/lib/components/go-modal/go-modal.component.scss index 22e8ad8b4..9f46a8029 100644 --- a/projects/go-lib/src/lib/components/go-modal/go-modal.component.scss +++ b/projects/go-lib/src/lib/components/go-modal/go-modal.component.scss @@ -20,7 +20,7 @@ .go-modal__container { background: $theme-light-bg; border-radius: $global-radius; - box-shadow: $global-box-shadow; + box-shadow: $global-box-shadow--regular; color: $theme-light-color; max-height: 80%; max-width: 32.5rem; diff --git a/projects/go-lib/src/lib/components/go-off-canvas/go-off-canvas.component.html b/projects/go-lib/src/lib/components/go-off-canvas/go-off-canvas.component.html index 752ca9ec4..c1f19fc3a 100644 --- a/projects/go-lib/src/lib/components/go-off-canvas/go-off-canvas.component.html +++ b/projects/go-lib/src/lib/components/go-off-canvas/go-off-canvas.component.html @@ -11,13 +11,12 @@ role="dialog" >
- +

+ {{ header }} +

+ +
diff --git a/projects/go-lib/src/lib/components/go-off-canvas/go-off-canvas.component.scss b/projects/go-lib/src/lib/components/go-off-canvas/go-off-canvas.component.scss index 7ac3dee9b..ccc239408 100644 --- a/projects/go-lib/src/lib/components/go-off-canvas/go-off-canvas.component.scss +++ b/projects/go-lib/src/lib/components/go-off-canvas/go-off-canvas.component.scss @@ -30,6 +30,15 @@ align-self: flex-start; flex: 0 0 auto; width: 100%; + display: flex; + padding: $column-gutter; + align-items: center; + justify-content: flex-end; +} + +.go-off-canvas__title { + flex-grow: 1; + padding-right: .5rem; } .go-off-canvas__button { @@ -38,7 +47,7 @@ color: $base-light; cursor: pointer; display: block; - font-family: $heading-font-stack; + font-family: $primary-font-stack; font-size: .8rem; line-height: 1rem; outline-offset: -2px; diff --git a/projects/go-lib/src/lib/components/go-off-canvas/go-off-canvas.component.ts b/projects/go-lib/src/lib/components/go-off-canvas/go-off-canvas.component.ts index 0ca4cf0cc..811c257ec 100644 --- a/projects/go-lib/src/lib/components/go-off-canvas/go-off-canvas.component.ts +++ b/projects/go-lib/src/lib/components/go-off-canvas/go-off-canvas.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild, ComponentFactoryResolver } from '@angular/core'; +import { Component, ComponentFactoryResolver, OnInit, ViewChild } from '@angular/core'; import { GoOffCanvasDirective } from './go-off-canvas.directive'; import { GoOffCanvasService } from './go-off-canvas.service'; import { GoOffCanvasItem } from './go-off-canvas.interface'; @@ -20,6 +20,7 @@ import { offCanvasAnimation } from '../../animations/off-canvas.animation'; export class GoOffCanvasComponent implements OnInit { currentOffCanvasItem: GoOffCanvasItem; opened: boolean = false; + header: string; @ViewChild(GoOffCanvasDirective) goOffCanvasHost: GoOffCanvasDirective; @@ -39,7 +40,7 @@ export class GoOffCanvasComponent implements OnInit { }); } - public closeOffCanvas(): void { + closeOffCanvas(): void { this.goOffCanvasService.closeOffCanvas(); } @@ -56,5 +57,7 @@ export class GoOffCanvasComponent implements OnInit { Object.keys(this.currentOffCanvasItem.bindings).forEach(key => { componentRef.instance[key] = this.currentOffCanvasItem.bindings[key]; }); + + this.header = this.currentOffCanvasItem.header; } } diff --git a/projects/go-lib/src/lib/components/go-off-canvas/go-off-canvas.interface.ts b/projects/go-lib/src/lib/components/go-off-canvas/go-off-canvas.interface.ts index 237deda5f..803f419b0 100644 --- a/projects/go-lib/src/lib/components/go-off-canvas/go-off-canvas.interface.ts +++ b/projects/go-lib/src/lib/components/go-off-canvas/go-off-canvas.interface.ts @@ -1,6 +1,7 @@ -import { Type } from "@angular/core"; +import { Type } from '@angular/core'; export interface GoOffCanvasItem { component: Type<{}>; bindings: {}; + header?: string; } diff --git a/projects/go-lib/src/lib/components/go-off-canvas/go-off-canvas.module.ts b/projects/go-lib/src/lib/components/go-off-canvas/go-off-canvas.module.ts index 1f18cf8a2..a2f03c32d 100644 --- a/projects/go-lib/src/lib/components/go-off-canvas/go-off-canvas.module.ts +++ b/projects/go-lib/src/lib/components/go-off-canvas/go-off-canvas.module.ts @@ -3,6 +3,7 @@ import { CommonModule } from '@angular/common'; import { GoOffCanvasComponent } from './go-off-canvas.component'; import { GoOffCanvasDirective } from './go-off-canvas.directive'; +import { GoIconButtonModule } from '../go-icon-button/go-icon-button.module'; @NgModule({ declarations: [ @@ -10,7 +11,8 @@ import { GoOffCanvasDirective } from './go-off-canvas.directive'; GoOffCanvasDirective ], imports: [ - CommonModule + CommonModule, + GoIconButtonModule ], exports: [ GoOffCanvasComponent diff --git a/projects/go-lib/src/lib/components/go-search/go-search.component.scss b/projects/go-lib/src/lib/components/go-search/go-search.component.scss index ac83110e6..c705a1605 100644 --- a/projects/go-lib/src/lib/components/go-search/go-search.component.scss +++ b/projects/go-lib/src/lib/components/go-search/go-search.component.scss @@ -41,11 +41,7 @@ } .go-search__container--active { - border: 0; - box-shadow: $global-box-shadow; - padding: 0.5rem; - top: calc(50% - (2.875rem / 2)); - // height of input with padding, halfed + box-shadow: $global-box-shadow--search; &:hover { background: $theme-light-bg; @@ -89,7 +85,7 @@ background: transparent; border: 0; flex: 1; - font-family: $base-font-stack; + font-family: $primary-font-stack; font-size: 0.875rem; font-weight: 300; letter-spacing: 0.02rem; diff --git a/projects/go-lib/src/lib/components/go-select/go-select.component.html b/projects/go-lib/src/lib/components/go-select/go-select.component.html index 9c9226709..dc8e99c4e 100644 --- a/projects/go-lib/src/lib/components/go-select/go-select.component.html +++ b/projects/go-lib/src/lib/components/go-select/go-select.component.html @@ -6,12 +6,16 @@ + [formControl]="control" + [typeahead]="typeahead" + [placeholder]="placeholder"> diff --git a/projects/go-lib/src/lib/components/go-select/go-select.component.ts b/projects/go-lib/src/lib/components/go-select/go-select.component.ts index 9c2bc3240..8df3dace3 100644 --- a/projects/go-lib/src/lib/components/go-select/go-select.component.ts +++ b/projects/go-lib/src/lib/components/go-select/go-select.component.ts @@ -1,5 +1,6 @@ import { Component, Input, OnInit, ViewEncapsulation } from '@angular/core'; import { FormControl } from '@angular/forms'; +import { Subject } from 'rxjs'; @Component({ encapsulation: ViewEncapsulation.None, @@ -10,6 +11,7 @@ import { FormControl } from '@angular/forms'; export class GoSelectComponent implements OnInit { id: string; + @Input() appendTo: string; @Input() bindLabel: string; @Input() bindValue: string; @Input() control: FormControl; @@ -17,7 +19,10 @@ export class GoSelectComponent implements OnInit { @Input() items: any[]; @Input() key: string; @Input() label: string; + @Input() loading: boolean = false; @Input() multiple: boolean = false; + @Input() placeholder: string; + @Input() typeahead?: Subject; @Input() theme: 'light' | 'dark' = 'light'; ngOnInit(): void { diff --git a/projects/go-lib/src/lib/components/go-side-nav/_variables.scss b/projects/go-lib/src/lib/components/go-side-nav/_variables.scss index 68df03c55..1cc332dfd 100644 --- a/projects/go-lib/src/lib/components/go-side-nav/_variables.scss +++ b/projects/go-lib/src/lib/components/go-side-nav/_variables.scss @@ -1,6 +1,7 @@ @import "../../../styles/variables"; -$inner-side-nav-font-size: 0.875rem; +$inner-side-nav-font-size: .875rem; $inner-side-nav-padding: $column-gutter--half $column-gutter--three-quarters $column-gutter--half 3.2rem; $outer-side-nav-padding: 1rem 1rem 1rem 0; -$side-nav-letter-spacing: .02rem; +$side-nav-base-color: rgba($theme-dark-color, .7); +$side-nav-root-item-height: 3.2rem; diff --git a/projects/go-lib/src/lib/components/go-side-nav/go-nav-group/go-nav-group.component.html b/projects/go-lib/src/lib/components/go-side-nav/go-nav-group/go-nav-group.component.html index dd24126c7..b3b83a666 100644 --- a/projects/go-lib/src/lib/components/go-side-nav/go-nav-group/go-nav-group.component.html +++ b/projects/go-lib/src/lib/components/go-side-nav/go-nav-group/go-nav-group.component.html @@ -3,10 +3,14 @@ *ngIf="group.subRoutes && group.subRoutes.length > 0; else noSubRoutes">
+ [attr.title]="group.description" + [ngClass]="{ 'go-nav-group__dropdown--expanded': group.expanded }">
- + diff --git a/projects/go-lib/src/lib/components/go-side-nav/go-nav-group/go-nav-group.component.scss b/projects/go-lib/src/lib/components/go-side-nav/go-nav-group/go-nav-group.component.scss index e2076c564..cbe509d19 100644 --- a/projects/go-lib/src/lib/components/go-side-nav/go-nav-group/go-nav-group.component.scss +++ b/projects/go-lib/src/lib/components/go-side-nav/go-nav-group/go-nav-group.component.scss @@ -2,43 +2,68 @@ @import '../variables'; .go-nav-group__dropdown { + @include transition(background, color); + align-items: center; + color: $side-nav-base-color; + cursor: pointer; display: flex; + font-weight: $weight-light; padding-right: .5rem; user-select: none; - @include transition(all); &:hover { background: $theme-dark-bg-hover; + color: $theme-dark-color; + + .go-nav-group__expand-icon { + color: $theme-dark-color; + } + } +} + +.go-nav-group__dropdown--expanded { + background: $theme-dark-bg-active; + color: $theme-dark-color; + font-weight: $weight-regular; + + .go-nav-group__expand-icon { + color: $theme-dark-color; } } .go-nav-group__link { display: flex; flex-grow: 1; + position: relative; } .go-nav-group__title { align-items: center; display: flex; - font-weight: $weight-light; - letter-spacing: $side-nav-letter-spacing; padding: $outer-side-nav-padding; } .go-nav-group__icon { + align-self: flex-start; font-size: 1.2rem; + height: $side-nav-root-item-height; padding: 1rem; } +.go-nav-group__icon--external { + padding-left: .5rem; + padding-right: .75rem; +} + .go-nav-group__expand-icon { border-radius: 50%; - color: $theme-dark-color; + color: $side-nav-base-color; cursor: pointer; font-size: 1.5rem; - height: 2.5rem; - padding: 0.5rem; - width: 2.5rem; + height: 2rem; + padding: .25rem; + width: 2rem; &:hover { background: $theme-dark-bg; @@ -58,4 +83,17 @@ .go-nav-group--expanded { background: $theme-dark-bg-active; + color: $theme-dark-color; } + +.go-nav-item--selected { + @include transition(all); + + border-radius: 0 $global-radius $global-radius 0; + content: ' '; + height: 1.5rem; + position: absolute; + top: 50%; + transform: translateY(-50%); + width: 4px; +} \ No newline at end of file diff --git a/projects/go-lib/src/lib/components/go-side-nav/go-nav-group/go-nav-group.component.ts b/projects/go-lib/src/lib/components/go-side-nav/go-nav-group/go-nav-group.component.ts index 4ff759941..222e2b608 100644 --- a/projects/go-lib/src/lib/components/go-side-nav/go-nav-group/go-nav-group.component.ts +++ b/projects/go-lib/src/lib/components/go-side-nav/go-nav-group/go-nav-group.component.ts @@ -1,26 +1,47 @@ -import { Component, EventEmitter, Input, OnInit, Output, ViewEncapsulation } from '@angular/core'; +import { + Component, + EventEmitter, + Input, + OnInit, + Output, + ViewEncapsulation +} from '@angular/core'; import { NavGroup } from '../nav-group.model'; import { NavItem } from '../nav-item.model'; import { GoSideNavService } from '../go-side-nav/go-side-nav.service'; +import { GoConfigService } from '../../../go-config.service'; +import { distinctUntilKeyChanged } from 'rxjs/operators'; +import { GoConfigInterface } from '../../../go-config.model'; @Component({ selector: 'go-nav-group', templateUrl: './go-nav-group.component.html', styleUrls: ['./go-nav-group.component.scss'], + // tslint:disable-next-line: use-component-view-encapsulation encapsulation: ViewEncapsulation.None }) -export class GoNavGroupComponent implements OnInit { +export class GoNavGroupComponent implements OnInit { @Input() navItem: NavGroup | NavItem; @Input() class: string; - @Output() closeNavs = new EventEmitter(); + @Input() level: number; + @Output() closeNavs: EventEmitter = new EventEmitter(); + brandColor: string; group: NavGroup; - constructor (public navService: GoSideNavService) { } + constructor ( + public navService: GoSideNavService, + private configService: GoConfigService + ) { } ngOnInit(): void { // Using this to do type checking between NavGroup and NavItem in the html this.group = this.navItem as NavGroup; + this.configService.config + .pipe(distinctUntilKeyChanged('brandColor')) + .subscribe((value: GoConfigInterface) => { + this.brandColor = value.brandColor; + }); } expand(navGroup: NavGroup): void { diff --git a/projects/go-lib/src/lib/components/go-side-nav/go-nav-item/go-nav-item.component.html b/projects/go-lib/src/lib/components/go-side-nav/go-nav-item/go-nav-item.component.html index 542f6f567..db3f6fe51 100644 --- a/projects/go-lib/src/lib/components/go-side-nav/go-nav-item/go-nav-item.component.html +++ b/projects/go-lib/src/lib/components/go-side-nav/go-nav-item/go-nav-item.component.html @@ -1,9 +1,13 @@
+ [attr.title]="navItem.description" + [ngClass]="{ 'go-nav-item--collapsed': !navService.navOpen }"> + @@ -13,22 +17,21 @@ [target]="navItem.externalLinkTarget ? navItem.externalLinkTarget : '_blank'" rel="noreferrer"> - + class="go-nav-group__icon go-nav-group__icon--external">
- {{navItem.routeTitle}} - diff --git a/projects/go-lib/src/lib/components/go-side-nav/go-nav-item/go-nav-item.component.scss b/projects/go-lib/src/lib/components/go-side-nav/go-nav-item/go-nav-item.component.scss index f76fa401a..f1daefdb9 100644 --- a/projects/go-lib/src/lib/components/go-side-nav/go-nav-item/go-nav-item.component.scss +++ b/projects/go-lib/src/lib/components/go-side-nav/go-nav-item/go-nav-item.component.scss @@ -3,64 +3,83 @@ @import '../variables'; .go-nav-item { + @include transition(all); + align-items: center; display: flex; - @include transition(all); + min-height: 2rem; + position: relative; &:hover { - background: $theme-dark-bg-hover; + .go-nav-item__link { + background: $theme-dark-bg-hover; + color: $theme-dark-color; + } } } -.go-nav-item__link::before { - background: $base-primary; - border-radius: 0 $global-radius $global-radius 0; - content: " "; - height: 1.5rem; - left: 0; - opacity: 0; - position: absolute; - top: 50%; - transform: translateY(-50%); - width: 4px; - @include transition(all); +.go-nav-item--collapsed { + min-height: 0; } .go-nav-item__link--active { .go-nav-item__title { font-weight: $weight-regular; + color: $theme-dark-color; } -} -.go-nav-item__link--active::before { - opacity: 1; + .go-nav-group__icon { + color: $theme-dark-color; + } + + .go-nav-item--selected { + @include transition(all); + + border-radius: 0 $global-radius $global-radius 0; + content: ' '; + height: 1.5rem; + position: absolute; + top: 50%; + transform: translateY(-50%); + width: 4px; + } } .go-nav-item__link, .go-nav-item__link:visited, .go-nav-item__link:focus, .go-nav-item__link:active { - color: $theme-dark-color; + color: $side-nav-base-color; } .go-nav-item__link { + @include transition(all); + align-items: center; - border: none; + border: 0; display: flex; flex-grow: 1; + max-width: 100%; position: relative; text-decoration: none; } .go-nav-item__title { + flex-grow: 1; font-size: $inner-side-nav-font-size; font-weight: $weight-light; - letter-spacing: $side-nav-letter-spacing; + max-height: $side-nav-root-item-height; padding: $inner-side-nav-padding; - flex-grow: 1; +} + +.go-nav-item__title--level-2 { + padding-left: calc(#{$side-nav-root-item-height} + .5rem); } .go-nav-item__title--with-icon { + align-items: center; + display: inline-flex; font-size: 1rem; - padding: $outer-side-nav-padding; + height: $side-nav-root-item-height; + padding: 0 1rem 0 0; } diff --git a/projects/go-lib/src/lib/components/go-side-nav/go-nav-item/go-nav-item.component.ts b/projects/go-lib/src/lib/components/go-side-nav/go-nav-item/go-nav-item.component.ts index 3102c194f..d5bcc7d56 100644 --- a/projects/go-lib/src/lib/components/go-side-nav/go-nav-item/go-nav-item.component.ts +++ b/projects/go-lib/src/lib/components/go-side-nav/go-nav-item/go-nav-item.component.ts @@ -1,14 +1,31 @@ -import { Component, Input } from '@angular/core'; +import { Component, Input, OnInit } from '@angular/core'; import { NavItem } from '../nav-item.model'; import { GoSideNavService } from '../go-side-nav/go-side-nav.service'; +import { GoConfigService } from '../../../go-config.service'; +import { GoConfigInterface } from '../../../go-config.model'; +import { distinctUntilKeyChanged } from 'rxjs/operators'; @Component({ selector: 'go-nav-item', templateUrl: './go-nav-item.component.html', styleUrls: ['./go-nav-item.component.scss'] }) -export class GoNavItemComponent { +export class GoNavItemComponent implements OnInit { + brandColor: string; + @Input() navItem: NavItem; + @Input() level: number; + + constructor ( + public navService: GoSideNavService, + private configService: GoConfigService + ) { } - constructor (public navService: GoSideNavService) { } + ngOnInit(): void { + this.configService.config + .pipe(distinctUntilKeyChanged('brandColor')) + .subscribe((value: GoConfigInterface) => { + this.brandColor = value.brandColor; + }); + } } diff --git a/projects/go-lib/src/lib/components/go-side-nav/go-side-nav.module.ts b/projects/go-lib/src/lib/components/go-side-nav/go-side-nav.module.ts index 3c4ca99d6..6f8520b7f 100644 --- a/projects/go-lib/src/lib/components/go-side-nav/go-side-nav.module.ts +++ b/projects/go-lib/src/lib/components/go-side-nav/go-side-nav.module.ts @@ -7,6 +7,7 @@ import { GoIconModule } from '../go-icon/go-icon.module'; import { GoSideNavComponent } from './go-side-nav/go-side-nav.component'; import { GoNavGroupComponent } from './go-nav-group/go-nav-group.component'; import { GoNavItemComponent } from './go-nav-item/go-nav-item.component'; +import { GoConfigService } from '../../go-config.service'; @NgModule({ declarations: [ @@ -23,6 +24,9 @@ import { GoNavItemComponent } from './go-nav-item/go-nav-item.component'; GoSideNavComponent, GoNavGroupComponent, GoNavItemComponent + ], + providers: [ + GoConfigService ] }) diff --git a/projects/go-lib/src/lib/components/go-side-nav/go-side-nav/go-side-nav.component.html b/projects/go-lib/src/lib/components/go-side-nav/go-side-nav/go-side-nav.component.html index 3ab0ca377..39248234f 100644 --- a/projects/go-lib/src/lib/components/go-side-nav/go-side-nav/go-side-nav.component.html +++ b/projects/go-lib/src/lib/components/go-side-nav/go-side-nav/go-side-nav.component.html @@ -2,6 +2,7 @@ [ngClass]="{ 'go-side-nav--show-mobile' : navService.navOpen, 'go-side-nav--collapsed' : !navService.navOpen }"> + (closeNavs)="closeNavs($event)" + [level]="0">
diff --git a/projects/go-lib/src/lib/components/go-side-nav/go-side-nav/go-side-nav.component.scss b/projects/go-lib/src/lib/components/go-side-nav/go-side-nav/go-side-nav.component.scss index 00f81562a..7ef291ec4 100644 --- a/projects/go-lib/src/lib/components/go-side-nav/go-side-nav/go-side-nav.component.scss +++ b/projects/go-lib/src/lib/components/go-side-nav/go-side-nav/go-side-nav.component.scss @@ -8,6 +8,7 @@ display: flex; flex-direction: column; flex-grow: 1; + font-family: $secondary-font-stack; height: 100%; overflow-y: auto; padding: 2rem 0; diff --git a/projects/go-lib/src/lib/components/go-side-nav/go-side-nav/go-side-nav.component.ts b/projects/go-lib/src/lib/components/go-side-nav/go-side-nav/go-side-nav.component.ts index 856909e68..9a5887461 100644 --- a/projects/go-lib/src/lib/components/go-side-nav/go-side-nav/go-side-nav.component.ts +++ b/projects/go-lib/src/lib/components/go-side-nav/go-side-nav/go-side-nav.component.ts @@ -1,5 +1,5 @@ -import { Component, OnInit, Input } from '@angular/core'; -import { Router, NavigationEnd } from '@angular/router'; +import { Component, Input, OnInit } from '@angular/core'; +import { NavigationEnd, Router } from '@angular/router'; import { filter } from 'rxjs/operators'; import { NavGroup } from '../nav-group.model'; import { NavItem } from '../nav-item.model'; @@ -13,22 +13,26 @@ import { GoSideNavService } from './go-side-nav.service'; export class GoSideNavComponent implements OnInit { @Input() menuItems: Array; - constructor (private router: Router, public navService: GoSideNavService) { } + constructor ( + private router: Router, + public navService: GoSideNavService + ) { } ngOnInit(): void { + this.navService.setMenuItems(this.menuItems); this.router.events .pipe( - filter(event => event instanceof NavigationEnd) + filter((event: any) => event instanceof NavigationEnd) ).subscribe((event: NavigationEnd) => { - this.menuItems.forEach(item => { + this.menuItems.forEach((item: (NavGroup | NavItem)) => { (item as NavGroup).expanded = this.setExpanded(item, event.url); }); }); } closeNavs(navGroup: NavGroup): void { - this.menuItems.forEach(group => { - const g = group as NavGroup; + this.menuItems.forEach((group: (NavGroup | NavItem)) => { + const g: NavGroup = group as NavGroup; g.expanded = this.openAccordion(g, navGroup); }); } @@ -44,7 +48,7 @@ export class GoSideNavComponent implements OnInit { } private navGroupExpansion(group: NavGroup, url: string): boolean { - group.expanded = group.subRoutes.some(subRoute => { + group.expanded = group.subRoutes.some((subRoute: (NavGroup | NavItem)) => { return this.setExpanded(subRoute, url); }); return group.expanded; @@ -58,11 +62,10 @@ export class GoSideNavComponent implements OnInit { * @param group this is the group we are trying to decide if it should be open. * @param item this is the group that we are searching for that was clicked on and needs opened. */ - private openAccordion(group: NavGroup, item: NavGroup): boolean { if (group.subRoutes) { if (group.routeTitle !== item.routeTitle) { - group.expanded = group.subRoutes.some(subRoute => { + group.expanded = group.subRoutes.some((subRoute: (NavGroup | NavItem)) => { return this.openAccordion((subRoute as NavGroup), item); }); } else { diff --git a/projects/go-lib/src/lib/components/go-side-nav/go-side-nav/go-side-nav.service.ts b/projects/go-lib/src/lib/components/go-side-nav/go-side-nav/go-side-nav.service.ts index d2f2dda34..87a9da7f5 100644 --- a/projects/go-lib/src/lib/components/go-side-nav/go-side-nav/go-side-nav.service.ts +++ b/projects/go-lib/src/lib/components/go-side-nav/go-side-nav/go-side-nav.service.ts @@ -1,16 +1,66 @@ import { Injectable } from '@angular/core'; -import { Observable, of as observableOf, BehaviorSubject } from 'rxjs'; +import { NavGroup } from '../nav-group.model'; +import { NavItem } from '../nav-item.model'; +import { NavigationEnd, Router } from '@angular/router'; @Injectable({ providedIn: 'root' }) export class GoSideNavService { - public navOpen = true; + public navOpen: boolean = true; + public menuItems: (NavGroup | NavItem)[]; + private _menuItems: Map = new Map(); + private currentItem: NavItem | NavGroup; - constructor() { } + constructor(private router: Router) { + this.router.events.subscribe((event: any) => { + if (event instanceof NavigationEnd) { + const obj: NavGroup | NavItem = this._menuItems.get(event.urlAfterRedirects); + if (obj) { + if (this.currentItem) { + this.currentItem.routeActive = false; + } - toggleNav() { + obj.routeActive = true; + this.currentItem = obj; + } + } + }); + } + + setMenuItems(val: (NavGroup | NavItem)[]): void { + this.menuItems = val; + this.createNavMap(); + } + + toggleNav(): void { this.navOpen = !this.navOpen; } + + private isNavGroup(item: NavGroup | NavItem): item is NavGroup { + return (item as NavGroup).subRoutes !== undefined; + } + + private extractNested(group: NavGroup, base: NavGroup): void { + for (const route of group.subRoutes) { + if (this.isNavGroup(route)) { + this.extractNested(route, base); + } else { + this._menuItems.set('/' + route.route, base); + } + } + } + + private createNavMap(): void { + let baseItem: NavGroup | NavItem; + for (let i: number = 0; i < this.menuItems.length; i++) { + baseItem = this.menuItems[i]; + if (!this.isNavGroup(baseItem)) { + this._menuItems.set('/' + baseItem.route, baseItem); + } else { + this.extractNested(baseItem, baseItem); + } + } + } } diff --git a/projects/go-lib/src/lib/components/go-side-nav/nav-group.model.ts b/projects/go-lib/src/lib/components/go-side-nav/nav-group.model.ts index dd13bde46..4014d2c2b 100644 --- a/projects/go-lib/src/lib/components/go-side-nav/nav-group.model.ts +++ b/projects/go-lib/src/lib/components/go-side-nav/nav-group.model.ts @@ -3,6 +3,7 @@ import { NavItem } from './nav-item.model'; export interface NavGroup { description?: string; expanded?: boolean; + routeActive?: boolean; routeIcon?: string; routeTitle: string; subRoutes: Array; diff --git a/projects/go-lib/src/lib/components/go-side-nav/nav-item.model.ts b/projects/go-lib/src/lib/components/go-side-nav/nav-item.model.ts index eeaa0b8cf..a3fdb7a46 100644 --- a/projects/go-lib/src/lib/components/go-side-nav/nav-item.model.ts +++ b/projects/go-lib/src/lib/components/go-side-nav/nav-item.model.ts @@ -3,6 +3,7 @@ export interface NavItem { route: string; routeIcon?: string; routeTitle: string; + routeActive?: boolean; /** * When `isExternalLink` is true, the value passed to `route` will be used for redirection. By default, all external links will open in a diff --git a/projects/go-lib/src/lib/components/go-switch-toggle/go-switch-toggle.component.html b/projects/go-lib/src/lib/components/go-switch-toggle/go-switch-toggle.component.html index 79e4cadcb..2ac033100 100644 --- a/projects/go-lib/src/lib/components/go-switch-toggle/go-switch-toggle.component.html +++ b/projects/go-lib/src/lib/components/go-switch-toggle/go-switch-toggle.component.html @@ -1,32 +1,36 @@ -
-
- - -
+ +
+ + +
+ + + + + +
+ +
+ + - - - -
- -
-
+ diff --git a/projects/go-lib/src/lib/components/go-switch-toggle/go-switch-toggle.component.scss b/projects/go-lib/src/lib/components/go-switch-toggle/go-switch-toggle.component.scss index 49064aa79..6e31917d4 100644 --- a/projects/go-lib/src/lib/components/go-switch-toggle/go-switch-toggle.component.scss +++ b/projects/go-lib/src/lib/components/go-switch-toggle/go-switch-toggle.component.scss @@ -61,14 +61,14 @@ transform: translateX(1.125rem); } -.go-form__switch-toggle__wrapper { - position: relative; -} - .go-form__switch-toggle__label { line-height: 1.125rem; padding-bottom: 0; padding-left: 0.75rem; - position: absolute; user-select: none; } + +.go-form__switch-toggle__label--before { + padding-left: 0; + padding-right: 0.75rem; +} diff --git a/projects/go-lib/src/lib/components/go-switch-toggle/go-switch-toggle.component.ts b/projects/go-lib/src/lib/components/go-switch-toggle/go-switch-toggle.component.ts index 3c9223f55..009f74f17 100644 --- a/projects/go-lib/src/lib/components/go-switch-toggle/go-switch-toggle.component.ts +++ b/projects/go-lib/src/lib/components/go-switch-toggle/go-switch-toggle.component.ts @@ -13,6 +13,7 @@ export class GoSwitchToggleComponent implements OnInit { @Input() key: string; @Input() hints: string[]; @Input() label: string; + @Input() labelPosition: 'before' | 'after' = 'after'; @Input() theme: 'light' | 'dark' = 'light'; constructor() { } diff --git a/projects/go-lib/src/lib/components/go-table/go-table-column.component.ts b/projects/go-lib/src/lib/components/go-table/go-table-column.component.ts index 3faad70ad..07e5815a4 100644 --- a/projects/go-lib/src/lib/components/go-table/go-table-column.component.ts +++ b/projects/go-lib/src/lib/components/go-table/go-table-column.component.ts @@ -9,6 +9,7 @@ export class GoTableColumnComponent { @Input() field: string; @Input() title: string; @Input() width: number; + @Input() sortable?: boolean; @ContentChild('goTableCell') goTableCell: TemplateRef; @ContentChild('goTableHead') goTableHead: TemplateRef; diff --git a/projects/go-lib/src/lib/components/go-table/go-table.component.html b/projects/go-lib/src/lib/components/go-table/go-table.component.html index c8c0e3c49..f78471d12 100644 --- a/projects/go-lib/src/lib/components/go-table/go-table.component.html +++ b/projects/go-lib/src/lib/components/go-table/go-table.component.html @@ -10,7 +10,7 @@
{{ tableTitle *ngIf="hasData(); else noDataTable"> - @@ -18,7 +18,8 @@
{{ tableTitle + (click)="toggleSort(col.sortable, col.field)" + [ngClass]="{ 'go-table__head--sortable': col.sortable !== undefined ? col.sortable : localTableConfig.sortable }">
{{ col.title || col.field }} @@ -58,7 +59,7 @@
{{ tableTitle
- diff --git a/projects/go-lib/src/lib/components/go-table/go-table.component.scss b/projects/go-lib/src/lib/components/go-table/go-table.component.scss index 38de2f8d4..d2f566343 100644 --- a/projects/go-lib/src/lib/components/go-table/go-table.component.scss +++ b/projects/go-lib/src/lib/components/go-table/go-table.component.scss @@ -4,7 +4,7 @@ .go-table-container { background: $theme-light-bg; border-radius: $global-radius; - box-shadow: $global-box-shadow; + box-shadow: $global-box-shadow--regular; position: relative; } @@ -60,7 +60,6 @@ @include transition(background); color: $theme-light-color; - cursor: pointer; font-size: .75rem; font-weight: bold; letter-spacing: 1pt; @@ -70,10 +69,6 @@ text-transform: uppercase; white-space: nowrap; - &:hover { - background: $theme-light-app-bg; - } - &:first-of-type { border-top-left-radius: $global-radius; } @@ -83,6 +78,14 @@ } } +.go-table__head--sortable { + cursor: pointer; + + &:hover { + background: $theme-light-app-bg; + } +} + .go-table__head-content { display: flex; line-height: 1; diff --git a/projects/go-lib/src/lib/components/go-table/go-table.component.spec.ts b/projects/go-lib/src/lib/components/go-table/go-table.component.spec.ts index 1b7fd7e71..034509f15 100644 --- a/projects/go-lib/src/lib/components/go-table/go-table.component.spec.ts +++ b/projects/go-lib/src/lib/components/go-table/go-table.component.spec.ts @@ -9,6 +9,10 @@ import { GoTablePageConfig } from './go-table-paging.model'; describe('GoTableComponent', () => { let component: GoTableComponent; let fixture: ComponentFixture; + const tableConfig: GoTableConfig = new GoTableConfig({ + pageable: true, + tableData: [] + }); beforeEach(async(() => { TestBed.configureTestingModule({ @@ -24,10 +28,8 @@ describe('GoTableComponent', () => { beforeEach(() => { fixture = TestBed.createComponent(GoTableComponent); component = fixture.componentInstance; - component.tableConfig = new GoTableConfig({ - pageable: true, - tableData: [] - }); + component.tableConfig = tableConfig; + fixture.detectChanges(); }); @@ -73,4 +75,30 @@ describe('GoTableComponent', () => { expect(resultSet).toBe(firstNumber + ' - ' + secondNumber); }); }); + + describe('toggleSort', () => { + beforeEach(() => { + spyOn(component.tableChange, 'emit'); + }); + + afterEach(() => { + component.tableConfig = tableConfig; + }); + + it('should update columns if column is sortable', () => { + component.toggleSort(true, 'value'); + expect(component.tableChange.emit).toHaveBeenCalled(); + }); + + it('should not update columns if column is not sortable', () => { + component.toggleSort(false, 'value'); + expect(component.tableChange.emit).not.toHaveBeenCalled(); + }); + + it('should update columns if column sortable is undefined, but table is sortable', () => { + component.tableConfig.sortable = true; + component.toggleSort(undefined, 'value'); + expect(component.tableChange.emit).toHaveBeenCalled(); + }); + }); }); diff --git a/projects/go-lib/src/lib/components/go-table/go-table.component.ts b/projects/go-lib/src/lib/components/go-table/go-table.component.ts index e126ddee0..a654e3c96 100644 --- a/projects/go-lib/src/lib/components/go-table/go-table.component.ts +++ b/projects/go-lib/src/lib/components/go-table/go-table.component.ts @@ -102,7 +102,7 @@ export class GoTableComponent implements OnInit, OnChanges { return this.hasData() && this.localTableConfig.pageable; } - toggleSort(columnField: string): void { + toggleSort(columnSortable: boolean, columnField: string): void { const { sortable, sortConfig, tableData }: { sortable: boolean, @@ -110,7 +110,9 @@ export class GoTableComponent implements OnInit, OnChanges { tableData: any[] } = this.localTableConfig; - if (tableData && sortable) { + columnSortable = columnSortable !== undefined ? columnSortable : sortable; + + if (tableData && columnSortable) { if (sortConfig && sortConfig.column === columnField) { this.localTableConfig.sortConfig.direction = this.toggleSortDir(sortConfig.direction); } else { diff --git a/projects/go-lib/src/lib/components/go-toast/go-toast.component.html b/projects/go-lib/src/lib/components/go-toast/go-toast.component.html index 51c15c43f..090f927e6 100644 --- a/projects/go-lib/src/lib/components/go-toast/go-toast.component.html +++ b/projects/go-lib/src/lib/components/go-toast/go-toast.component.html @@ -5,7 +5,7 @@
{{ header }}
-

{{ message }}

+

diff --git a/projects/go-tester/src/app/components/off-canvas-test/off-canvas-test.component.ts b/projects/go-tester/src/app/components/off-canvas-test/off-canvas-test.component.ts index 538cdf12f..0544fc3b7 100644 --- a/projects/go-tester/src/app/components/off-canvas-test/off-canvas-test.component.ts +++ b/projects/go-tester/src/app/components/off-canvas-test/off-canvas-test.component.ts @@ -1,9 +1,26 @@ import { Component } from '@angular/core'; +import { FormControl } from '@angular/forms'; @Component({ selector: 'off-canvas-test', templateUrl: './off-canvas-test.component.html' }) export class OffCanvasTestComponent { - + selectControl: FormControl = new FormControl(); + selectData: any = [{ + value: 1, + name: 'Harry' + }, { + value: 2, + name: 'Hermione' + }, { + value: 3, + name: 'Ron' + }, { + value: 4, + name: 'Voldermort' + }, { + value: 5, + name: 'Snake' + }]; } diff --git a/projects/go-tester/src/app/components/test-page-1/test-page-1.component.html b/projects/go-tester/src/app/components/test-page-1/test-page-1.component.html index 42e802989..ff2a75b7b 100644 --- a/projects/go-tester/src/app/components/test-page-1/test-page-1.component.html +++ b/projects/go-tester/src/app/components/test-page-1/test-page-1.component.html @@ -49,10 +49,10 @@ Selection State - - - + + + -
\ No newline at end of file +
diff --git a/projects/go-tester/src/app/components/test-page-1/test-page-1.component.ts b/projects/go-tester/src/app/components/test-page-1/test-page-1.component.ts index 6c700dc16..31fe6aaa1 100644 --- a/projects/go-tester/src/app/components/test-page-1/test-page-1.component.ts +++ b/projects/go-tester/src/app/components/test-page-1/test-page-1.component.ts @@ -33,7 +33,8 @@ export class TestPage1Component implements OnInit { selectable: true, selectBy: 'id', tableData: data.results, - totalCount: data.totalCount + totalCount: data.totalCount, + sortable: false }); this.tableLoading = false; }); diff --git a/projects/go-tester/src/app/components/test-page-2/test-page-2.component.html b/projects/go-tester/src/app/components/test-page-2/test-page-2.component.html index 084d96693..76e3bce22 100644 --- a/projects/go-tester/src/app/components/test-page-2/test-page-2.component.html +++ b/projects/go-tester/src/app/components/test-page-2/test-page-2.component.html @@ -83,11 +83,46 @@

Buttons

+
+

Button Group

+
    +
  • + Button 1 +
  • +
  • + Button 2 +
  • +
+
+

Toasts

+ + +
+ +
+

Branding

+
+ + +
+ +
+ + Update Branding Color + +
diff --git a/projects/go-tester/src/app/components/test-page-2/test-page-2.component.ts b/projects/go-tester/src/app/components/test-page-2/test-page-2.component.ts index 8fb533002..be9f632ae 100644 --- a/projects/go-tester/src/app/components/test-page-2/test-page-2.component.ts +++ b/projects/go-tester/src/app/components/test-page-2/test-page-2.component.ts @@ -1,9 +1,11 @@ import { Component, OnInit, ViewChild } from '@angular/core'; import { GoButtonComponent, + GoConfigService, GoLoaderComponent, - GoToasterService + GoToasterService, } from '../../../../../go-lib/src/public_api'; +import { FormControl } from '@angular/forms'; @Component({ selector: 'app-test-page-2', @@ -13,14 +15,20 @@ export class TestPage2Component implements OnInit { @ViewChild('loader') loader: GoLoaderComponent; + brandingControl: FormControl; title: string = 'Test 2'; shopping: boolean = false; loaderType: string = 'neutral'; loading: boolean = true; - constructor(private goToasterService: GoToasterService) { } + constructor( + private goToasterService: GoToasterService, + private goConfigService: GoConfigService + ) { } ngOnInit(): void { + this.brandingControl = new FormControl(this.goConfigService.config.getValue().brandColor); + setTimeout(() => { this.goToasterService.toastInfo({ message: 'Check this out'}); this.goToasterService.toastSuccess({message: 'Check this out' }); @@ -49,4 +57,8 @@ export class TestPage2Component implements OnInit { openToast(): void { this.goToasterService.toastInfo({ message: 'From the action sheet'}); } + + updateColor(): void { + this.goConfigService.setBrandColor(this.brandingControl.value); + } } diff --git a/projects/go-tester/src/app/components/test-page-3/test-page-3.component.html b/projects/go-tester/src/app/components/test-page-3/test-page-3.component.html index 2fe385d79..2e2ac085d 100644 --- a/projects/go-tester/src/app/components/test-page-3/test-page-3.component.html +++ b/projects/go-tester/src/app/components/test-page-3/test-page-3.component.html @@ -45,6 +45,16 @@

> +
+ +
+
bindValue="value" bindLabel="name" [hints]="['Select an option here, whatever you want']" + [loading]="loadingSelectOptions" + placeholder="Select Box Placeholder" label="Select Box Here">
@@ -147,11 +159,20 @@

+
+ +
+
{ + this.loadingSelectOptions = false; + }, 3000); + } + onSubmit(): void { this.loading = true; diff --git a/projects/go-tester/src/styles.scss b/projects/go-tester/src/styles.scss index 928959a5d..a6c18bd67 100644 --- a/projects/go-tester/src/styles.scss +++ b/projects/go-tester/src/styles.scss @@ -1,5 +1,6 @@ /* You can add global styles to this file, and also import other style files */ @import url('https://fonts.googleapis.com/css?family=Roboto:300,400,700'); +@import url('https://fonts.googleapis.com/css?family=Nunito:300,400,700'); @import url('https://fonts.googleapis.com/icon?family=Material+Icons'); /* http://meyerweb.com/eric/tools/css/reset/