From d1d453edec8824fc6a25ce5bda7545c8ff42746b Mon Sep 17 00:00:00 2001 From: Alexander Nickel Date: Wed, 4 Sep 2019 14:24:11 +0200 Subject: [PATCH] Add first working-draft for a better demo-app This references #15 --- .stylintrc | 45 +++ package.json | 5 +- .../intersection-directives.module.ts | 90 +++--- .../angular-intersection/src/public-api.ts | 8 +- src/_color-helpers.styl | 129 +++++++++ src/_variables.styl | 26 ++ src/app/app.component.html | 12 - src/app/app.component.styl | 7 - src/app/app.component.ts | 34 --- src/app/app.module.ts | 30 +- src/app/components/app.component.html | 100 +++++++ .../{ => components}/app.component.spec.ts | 0 src/app/components/app.component.styl | 68 +++++ src/app/components/app.component.ts | 55 ++++ .../scroll-motivation.component.spec.ts | 25 ++ .../scroll-motivation.component.styl | 49 ++++ .../scroll-motivation.component.ts | 31 ++ .../services/scroll-information.service.ts | 223 +++++++++++++++ src/index.html | 18 +- src/styles.styl | 29 +- yarn.lock | 270 +++++++++++++++++- 21 files changed, 1124 insertions(+), 130 deletions(-) create mode 100644 .stylintrc create mode 100644 src/_color-helpers.styl create mode 100644 src/_variables.styl delete mode 100644 src/app/app.component.html delete mode 100644 src/app/app.component.styl delete mode 100644 src/app/app.component.ts create mode 100644 src/app/components/app.component.html rename src/app/{ => components}/app.component.spec.ts (100%) create mode 100644 src/app/components/app.component.styl create mode 100644 src/app/components/app.component.ts create mode 100644 src/app/components/scroll-motivation/scroll-motivation.component.spec.ts create mode 100644 src/app/components/scroll-motivation/scroll-motivation.component.styl create mode 100644 src/app/components/scroll-motivation/scroll-motivation.component.ts create mode 100644 src/app/services/scroll-information.service.ts diff --git a/.stylintrc b/.stylintrc new file mode 100644 index 0000000..41c1aff --- /dev/null +++ b/.stylintrc @@ -0,0 +1,45 @@ +{ + "blocks": false, + "brackets": "never", + "colons": "always", + "colors": "always", + "commaSpace": "always", + "commentSpace": "always", + "cssLiteral": "never", + "customProperties": [], + "depthLimit": false, + "duplicates": true, + "efficient": "always", + "exclude": [], + "extendPref": false, + "globalDupe": false, + "groupOutputByFile": true, + "indentPref": 2, + "leadingZero": "never", + "maxErrors": false, + "maxWarnings": false, + "mixed": false, + "mixins": [], + "namingConvention": false, + "namingConventionStrict": false, + "none": "never", + "noImportant": true, + "parenSpace": false, + "placeholders": "always", + "prefixVarsWithDollar": "always", + "quotePref": false, + "reporterOptions": { + "columns": ["lineData", "severity", "description", "rule"], + "columnSplitter": " ", + "showHeaders": false, + "truncate": true + }, + "semicolons": "never", + "sortOrder": "alphabetical", + "stackedProperties": "never", + "trailingWhitespace": "never", + "universal": false, + "valid": false, + "zeroUnits": "never", + "zIndexNormalize": false +} diff --git a/package.json b/package.json index fb898c3..8965e04 100644 --- a/package.json +++ b/package.json @@ -11,11 +11,13 @@ }, "private": true, "dependencies": { - "@angular/animations": "~7.1.0", + "@angular/animations": "7", + "@angular/cdk": "7", "@angular/common": "~7.1.0", "@angular/compiler": "~7.1.0", "@angular/core": "~7.1.0", "@angular/forms": "~7.1.0", + "@angular/material": "7", "@angular/platform-browser": "~7.1.0", "@angular/platform-browser-dynamic": "~7.1.0", "@angular/router": "~7.1.0", @@ -45,6 +47,7 @@ "karma-jasmine-html-reporter": "^0.2.2", "ng-packagr": "^4.2.0", "protractor": "~5.4.0", + "stylint": "^2.0.0", "ts-node": "~7.0.0", "tsickle": ">=0.29.0", "tslib": "^1.9.0", diff --git a/projects/angular-intersection/src/lib/directives/intersection-directives.module.ts b/projects/angular-intersection/src/lib/directives/intersection-directives.module.ts index 28eb2ea..48ded8f 100644 --- a/projects/angular-intersection/src/lib/directives/intersection-directives.module.ts +++ b/projects/angular-intersection/src/lib/directives/intersection-directives.module.ts @@ -30,64 +30,38 @@ import { IntersectionPresentStartOnceExitDirective } from './present/public-api'; +export const intersectionDirectives = [ + // future + IntersectionFutureEndDirective, + IntersectionFutureEndExitDirective, + IntersectionFutureEndOnceDirective, + IntersectionFutureEndOnceExitDirective, + IntersectionFutureStartDirective, + IntersectionFutureStartExitDirective, + IntersectionFutureStartOnceDirective, + IntersectionFutureStartOnceExitDirective, + // past + IntersectionPastEndDirective, + IntersectionPastEndExitDirective, + IntersectionPastEndOnceDirective, + IntersectionPastEndOnceExitDirective, + IntersectionPastStartDirective, + IntersectionPastStartExitDirective, + IntersectionPastStartOnceDirective, + IntersectionPastStartOnceExitDirective, + // present + IntersectionPresentEndDirective, + IntersectionPresentEndExitDirective, + IntersectionPresentEndOnceDirective, + IntersectionPresentEndOnceExitDirective, + IntersectionPresentStartDirective, + IntersectionPresentStartExitDirective, + IntersectionPresentStartOnceDirective, + IntersectionPresentStartOnceExitDirective +]; + @NgModule({ - declarations: [ - // future - IntersectionFutureEndDirective, - IntersectionFutureEndExitDirective, - IntersectionFutureEndOnceDirective, - IntersectionFutureEndOnceExitDirective, - IntersectionFutureStartDirective, - IntersectionFutureStartExitDirective, - IntersectionFutureStartOnceDirective, - IntersectionFutureStartOnceExitDirective, - // past - IntersectionPastEndDirective, - IntersectionPastEndExitDirective, - IntersectionPastEndOnceDirective, - IntersectionPastEndOnceExitDirective, - IntersectionPastStartDirective, - IntersectionPastStartExitDirective, - IntersectionPastStartOnceDirective, - IntersectionPastStartOnceExitDirective, - // present - IntersectionPresentEndDirective, - IntersectionPresentEndExitDirective, - IntersectionPresentEndOnceDirective, - IntersectionPresentEndOnceExitDirective, - IntersectionPresentStartDirective, - IntersectionPresentStartExitDirective, - IntersectionPresentStartOnceDirective, - IntersectionPresentStartOnceExitDirective - ], - exports: [ - // future - IntersectionFutureEndDirective, - IntersectionFutureEndExitDirective, - IntersectionFutureEndOnceDirective, - IntersectionFutureEndOnceExitDirective, - IntersectionFutureStartDirective, - IntersectionFutureStartExitDirective, - IntersectionFutureStartOnceDirective, - IntersectionFutureStartOnceExitDirective, - // past - IntersectionPastEndDirective, - IntersectionPastEndExitDirective, - IntersectionPastEndOnceDirective, - IntersectionPastEndOnceExitDirective, - IntersectionPastStartDirective, - IntersectionPastStartExitDirective, - IntersectionPastStartOnceDirective, - IntersectionPastStartOnceExitDirective, - // present - IntersectionPresentEndDirective, - IntersectionPresentEndExitDirective, - IntersectionPresentEndOnceDirective, - IntersectionPresentEndOnceExitDirective, - IntersectionPresentStartDirective, - IntersectionPresentStartExitDirective, - IntersectionPresentStartOnceDirective, - IntersectionPresentStartOnceExitDirective - ] + declarations: intersectionDirectives, + exports: intersectionDirectives }) export class IntersectionDirectivesModule {} diff --git a/projects/angular-intersection/src/public-api.ts b/projects/angular-intersection/src/public-api.ts index 293aaa4..042a2b8 100644 --- a/projects/angular-intersection/src/public-api.ts +++ b/projects/angular-intersection/src/public-api.ts @@ -10,5 +10,11 @@ export * from './lib/legacy-directives/public-api'; // SERVICES // ============================================================================= export * from './lib/services/public-api'; - +// +// DIRECTIVES +// ============================================================================= export * from './lib/directives/public-api'; +// +// INJECTION TOKENS +// ============================================================================= +export * from './lib/config/injection-tokens'; diff --git a/src/_color-helpers.styl b/src/_color-helpers.styl new file mode 100644 index 0000000..4e14837 --- /dev/null +++ b/src/_color-helpers.styl @@ -0,0 +1,129 @@ +@require _variables + +// +// COLOR CLASSES +// ============================================================================= +.color-white + color: $color--white !important + +.color-black + color: $color--black !important + +.color-primary + color: $color--primary !important + +.color-secondary + color: $color--secondary !important + +.color-functional-1 + color: $color--functional-1 !important + +.color-functional-2 + color: $color--functional-2 !important + +.color-functional-3 + color: $color--functional-3 !important + +.color-dark-grey + color: $color--dark-grey !important + +.color-middle-grey + color: $color--middle-grey !important + +.color-light-grey + color: $color--light-grey !important + +.color-error, .color-red + color: $color--error !important + +.color-success, .color-green + color: $color--success !important + +.color-warning, .color-yellow + color: $color--warning !important + +// +// BORDER CLASSES +// ============================================================================= +.border-primary + border-color: $color--primary !important + color: $color--primary !important + +.border-secondary + border-color: $color--secondary !important + color: $color--secondary !important + +.border-functional-1 + border-color: $color--functional-1 !important + color: $color--functional-1 !important + +.border-functional-2 + border-color: $color--functional-2 !important + color: $color--functional-2 !important + +.border-functional-3 + border-color: $color--functional-3 !important + color: $color--functional-3 !important + +.border-dark-grey + border-color: $color--dark-grey !important + color: $color--dark-grey !important + +.border-middle-grey + border-color: $color--middle-grey !important + color: $color--middle-grey !important + +.border-light-grey + border-color: $color--light-grey !important + color: $color--light-grey !important + +.border-error + border-color: $color--error !important + color: $color--error !important + +.border-success + border-color: $color--success !important + color: $color--success !important + +.border-warning + border-color: $color--warning !important + color: $color--warning !important + +// +// BACKGROUND CLASSES +// ============================================================================= +.background-primary + background-color: $color--primary + +.background-secondary + background-color: $color--secondary + +.background-functional-1 + background-color: $color--functional-1 + +.background-functional-2 + background-color: $color--functional-2 + +.background-functional-3 + background-color: $color--functional-3 + +.background-dark-grey + background-color: $color--dark-grey + +.background-middle-grey + background-color: $color--middle-grey + +.background-light-grey + background-color: $color--light-grey + +.background-error + background-color: $color--error + +.background-success + background-color: $color--success + +.background-warning + background-color: $color--warning + +.background-black + background-color: $color--black \ No newline at end of file diff --git a/src/_variables.styl b/src/_variables.styl new file mode 100644 index 0000000..26b3398 --- /dev/null +++ b/src/_variables.styl @@ -0,0 +1,26 @@ +// colors palette +$color--primary = rgb(73, 10, 61) +$color--secondary = rgb(189, 21, 80) +$color--functional-1 = rgb(233, 127, 2) +$color--functional-2 = rgb(248, 202, 0) +$color--functional-3 = rgb(138, 155, 15) +// colors bw +$color--black = #000000 +$color--white = #FFFFFF +$color--dark-grey = #6F6F6E +$color--middle-grey = #9C9B9B +$color--light-grey = #DCDCDC +// colors state +$color--error = $color--secondary +$color--success = $color--functional-3 +$color--warning = $color--functional-2 +// +// ============================================================================= +// +// spaces +$space--default = 20px +// font +$font-family--default = 'Open Sans', sans-serif +$font-size--default = 16px +$line-height--default = 1.618 +$letter-spacing--default = .02em \ No newline at end of file diff --git a/src/app/app.component.html b/src/app/app.component.html deleted file mode 100644 index 22a8d8b..0000000 --- a/src/app/app.component.html +++ /dev/null @@ -1,12 +0,0 @@ -
- -
diff --git a/src/app/app.component.styl b/src/app/app.component.styl deleted file mode 100644 index bddba3b..0000000 --- a/src/app/app.component.styl +++ /dev/null @@ -1,7 +0,0 @@ -.dummies { - list-style: none; - - li { - height: 200px; - } -} \ No newline at end of file diff --git a/src/app/app.component.ts b/src/app/app.component.ts deleted file mode 100644 index a848604..0000000 --- a/src/app/app.component.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Component, ChangeDetectorRef } from '@angular/core'; - -@Component({ - selector: 'app-root', - templateUrl: './app.component.html', - styleUrls: ['./app.component.styl'] -}) -export class AppComponent { - title = 'angular-intersection'; - - public dummies = []; - - public someConfig = { - bla: 123 - }; - - constructor(public cr: ChangeDetectorRef) { - this.createDummies(10); - } - - public createDummies(num: number): void { - let i = 0; - while (i < num) { - this.dummies.push({ - value: i + 1 - }); - i++; - } - } - - public emitHandler(dummy: any, event: any): void { - console.log('emit', dummy.value, event); - } -} diff --git a/src/app/app.module.ts b/src/app/app.module.ts index f4e1f09..ca944c1 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,13 +1,31 @@ import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; - -import { AppComponent } from './app.component'; -import { AngularIntersectionModule } from '@mralexandernickel/angular-intersection'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { MatSnackBarModule } from '@angular/material/snack-bar'; +import { AppComponent } from './components/app.component'; +import { + AngularIntersectionModule, + IntersectionDirectivesModule, + ROOT_MARGIN_FUTURE, + ROOT_MARGIN_PAST, + ROOT_MARGIN_PRESENT +} from '@mralexandernickel/angular-intersection'; +import { ScrollMotivationComponent } from './components/scroll-motivation/scroll-motivation.component'; @NgModule({ - declarations: [AppComponent], - imports: [BrowserModule, AngularIntersectionModule], - providers: [], + declarations: [AppComponent, ScrollMotivationComponent], + imports: [ + BrowserModule, + AngularIntersectionModule, + IntersectionDirectivesModule, + BrowserAnimationsModule, + MatSnackBarModule + ], + providers: [ + { provide: ROOT_MARGIN_FUTURE, useValue: '0px' }, + { provide: ROOT_MARGIN_PAST, useValue: '-200px' }, + { provide: ROOT_MARGIN_PRESENT, useValue: '-100px' } + ], bootstrap: [AppComponent] }) export class AppModule {} diff --git a/src/app/components/app.component.html b/src/app/components/app.component.html new file mode 100644 index 0000000..ae7983d --- /dev/null +++ b/src/app/components/app.component.html @@ -0,0 +1,100 @@ +
+

ngx-intersection

+
ROOT_MAGIN_FUTURE: {{ rootMarginFuture }}
+
ROOT_MAGIN_PAST: {{ rootMarginPast }}
+
ROOT_MAGIN_PRESENT: {{ rootMarginPresent }}
+
+ +
+ +
+ +
+
+
+
+
+ + diff --git a/src/app/app.component.spec.ts b/src/app/components/app.component.spec.ts similarity index 100% rename from src/app/app.component.spec.ts rename to src/app/components/app.component.spec.ts diff --git a/src/app/components/app.component.styl b/src/app/components/app.component.styl new file mode 100644 index 0000000..c71e800 --- /dev/null +++ b/src/app/components/app.component.styl @@ -0,0 +1,68 @@ +@require '../../_variables' + +header + text-align: center + + h1 + font-size: 128px + +.dummies + list-style: none + margin: 0 auto + width: 960px + + li + background: $color--functional-1 + height: 80vh + margin-top: 200vh + overflow: hidden + position: relative + + h2 + font-size: 24px + margin-top: 24px + text-align: center + + .index + bottom: 0 + color: $color--functional-2 + font-size: 128px + line-height: 1 + position: absolute + right: 0 + +.overlay + bottom: 0 + height: 100vh + left: 0 + position: fixed + right: 0 + top: 0 + width: 100vw + z-index: 9999 + + &.hidden + opacity: 0 + + div + border: 1px solid $color--black + display: block + position: absolute + + &::before + background: $color--black + color: $color--white + display: block + padding: 0 10px + position: absolute + right: 0 + top: 0 + + &.future::before + content: 'future' + + &.past::before + content: 'past' + + &.present::before + content: 'present' \ No newline at end of file diff --git a/src/app/components/app.component.ts b/src/app/components/app.component.ts new file mode 100644 index 0000000..a89a25a --- /dev/null +++ b/src/app/components/app.component.ts @@ -0,0 +1,55 @@ +import { Component, ChangeDetectorRef, Inject } from '@angular/core'; +import { Subject } from 'rxjs'; +import { MatSnackBar } from '@angular/material/snack-bar'; +import { + intersectionDirectives, + ROOT_MARGIN_FUTURE, + ROOT_MARGIN_PAST, + ROOT_MARGIN_PRESENT +} from '@mralexandernickel/angular-intersection'; + +@Component({ + selector: 'app-root', + templateUrl: './app.component.html', + styleUrls: ['./app.component.styl'] +}) +export class AppComponent { + title = 'angular-intersection'; + + public flash$ = new Subject(); + + public dummies = intersectionDirectives.map((item: any) => { + const data = { + name: item.name, + selector: item.decorators[0].args[0].selector.slice(1, -1) + }; + return data; + }); + + constructor( + public cr: ChangeDetectorRef, + private _snackBar: MatSnackBar, + @Inject(ROOT_MARGIN_FUTURE) public rootMarginFuture: string, + @Inject(ROOT_MARGIN_PAST) public rootMarginPast: string, + @Inject(ROOT_MARGIN_PRESENT) public rootMarginPresent: string + ) { + // this.generateHtml(); + } + + public generateHtml(): void { + let html = ''; + for (const dummy of this.dummies) { + html += `
  • ${dummy.selector}

  • \r\n`; + } + console.log(html); + } + + public emitHandler(selector: string, event: IntersectionObserverEntry): void { + console.log('emit', selector, event); + this._snackBar.open(`${selector} emitted`, 'OK', { + duration: 2000, + horizontalPosition: 'right', + verticalPosition: 'top' + }); + } +} diff --git a/src/app/components/scroll-motivation/scroll-motivation.component.spec.ts b/src/app/components/scroll-motivation/scroll-motivation.component.spec.ts new file mode 100644 index 0000000..b752958 --- /dev/null +++ b/src/app/components/scroll-motivation/scroll-motivation.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ScrollMotivationComponent } from './scroll-motivation.component'; + +describe('ScrollMotivationComponent', () => { + let component: ScrollMotivationComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ ScrollMotivationComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ScrollMotivationComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/scroll-motivation/scroll-motivation.component.styl b/src/app/components/scroll-motivation/scroll-motivation.component.styl new file mode 100644 index 0000000..dcd2c7c --- /dev/null +++ b/src/app/components/scroll-motivation/scroll-motivation.component.styl @@ -0,0 +1,49 @@ +@require '../../../_variables' + +$scroll-motivation--color = $color--secondary +$scroll-motivation--height = 70px +$scroll-motivation--width = 40px +$scroll-motivation--border-radius = 25px +$scroll-motivation--border-width = 2px +$scroll-motivation--dot--size = 8px +$scroll-motivation--dot--position-start = ($space--default / 2) +$scroll-motivation--dot--animation-rail = $scroll-motivation--height - ($scroll-motivation--dot--position-start * 2) - ($scroll-motivation--border-width * 2) + +:host .scroll-motivation + border-radius: $scroll-motivation--border-radius + box-shadow: inset 0 0 0 $scroll-motivation--border-width $scroll-motivation--color + height: $scroll-motivation--height + left: 50% + margin-left: -($scroll-motivation--width / 2) + margin-top: -($scroll-motivation--height / 2) + opacity: 0 + position: fixed + top: 80% + transition: opacity .35s ease-in-out + width: $scroll-motivation--width + + &.visible + opacity: 1 + + &:before + animation-duration: 1.5s + animation-iteration-count: infinite + animation-name: scroll + background: $scroll-motivation--color + border-radius: ($scroll-motivation--dot--size / 2) + content: '' + display: block + height: $scroll-motivation--dot--size + left: 50% + margin-left: -($scroll-motivation--dot--size / 2) + position: relative + top: $scroll-motivation--dot--position-start + width: $scroll-motivation--dot--size + +@keyframes scroll + 0% + opacity: 1 + + 100% + opacity: 0 + transform: translateY($scroll-motivation--dot--animation-rail) \ No newline at end of file diff --git a/src/app/components/scroll-motivation/scroll-motivation.component.ts b/src/app/components/scroll-motivation/scroll-motivation.component.ts new file mode 100644 index 0000000..4cd9838 --- /dev/null +++ b/src/app/components/scroll-motivation/scroll-motivation.component.ts @@ -0,0 +1,31 @@ +import { + Component, + OnInit, + ChangeDetectionStrategy, + OnDestroy +} from '@angular/core'; +import { ScrollInformationService } from '../../services/scroll-information.service'; +import { pluck, map, distinctUntilChanged, tap } from 'rxjs/operators'; +import { Observable } from 'rxjs'; + +export const SCROLLED_OFFSET = 50; + +@Component({ + selector: 'app-scroll-motivation', + template: '
    ', + styleUrls: ['./scroll-motivation.component.styl'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class ScrollMotivationComponent implements OnInit { + public scrolledDown$: Observable; + + constructor(public scrollInformationService: ScrollInformationService) {} + + public ngOnInit(): void { + this.scrolledDown$ = this.scrollInformationService.get().pipe( + pluck('position'), + map((position: number) => !(position > SCROLLED_OFFSET)), + distinctUntilChanged() + ); + } +} diff --git a/src/app/services/scroll-information.service.ts b/src/app/services/scroll-information.service.ts new file mode 100644 index 0000000..cbb896a --- /dev/null +++ b/src/app/services/scroll-information.service.ts @@ -0,0 +1,223 @@ +import { Inject, PLATFORM_ID, Injectable } from '@angular/core'; +import { isPlatformBrowser, DOCUMENT } from '@angular/common'; +import { fromEvent, BehaviorSubject, Observable } from 'rxjs'; +import { filter } from 'rxjs/operators'; + +const DEBOUNCE_TIME = 500; +const FAST_SCROLL_DISTANCE = 35; +const MINIMUM_SCROLL_DISTANCE = 50; + +export const enum ScrollDirections { + none = 0, + up = 1, + down = 2 +} + +export const enum ScrollSpeeds { + slow = 1, + regular = 2, + fast = 3 +} + +export type ScrollDirection = + | ScrollDirections.up + | ScrollDirections.down + | ScrollDirections.none; +export type ScrollSpeed = ScrollSpeeds.regular | ScrollSpeeds.fast; + +export interface IScrollInformation { + direction: ScrollDirection; + speed: ScrollSpeed; + position: number; +} + +/** + * ScrollDirectionService + * ====================== + * + * ## Usage + * ```typescript + * export class SomeComponent { + * constructor( + * public scrollInformationService: ScrollInformationService + * ) { + * this.scrollInformationService + * .get() + * .pipe( + * tap((scrollInformation: IScrollInformation) => { + * console.log('Scrollinformation is', scrollInformation) + * }) + * ).subscribe(); + * } + * } + * ``` + */ +@Injectable({ + providedIn: 'root' +}) +export class ScrollInformationService { + /** */ + constructor( + @Inject(PLATFORM_ID) public platformId: Object, + @Inject(DOCUMENT) public document: any + ) { + this.isBrowser = isPlatformBrowser(platformId); + + if (this.isBrowser) { + fromEvent(window, 'scroll').subscribe(this.scrollHandler.bind(this)); + } + } + /** */ + public isBrowser = false; + + /** */ + public subject = new BehaviorSubject(null); + + /** + * SetTimeout handle + */ + private timer: any; + + /** + * Initial scroll information + */ + private scrollInformation: IScrollInformation = { + direction: ScrollDirections.none, + speed: ScrollSpeeds.regular, + position: 0 + }; + + /** + * Last saved offset of window + */ + private lastScrollTop: number = + window.pageYOffset || this.document.documentElement.scrollTop; + + /** + * Find out if the body been scrolled to top + * @param scrollTop current scrollTop position + */ + public scrolledToTop(scrollTop: number): boolean { + return scrollTop < MINIMUM_SCROLL_DISTANCE; + } + + /** + * Find out if the body been scrolled to bottom + * @param scrollTop current scrollTop position + */ + public scrolledToBottom(scrollTop: number): boolean { + const windowHeight = window.innerHeight; + const bodyHeight = this.document.body.clientHeight; + + return scrollTop + windowHeight >= bodyHeight - MINIMUM_SCROLL_DISTANCE; + } + + /** + * Check if one boundary is reached + * @param scrollTop current scrollTop position + */ + public boundaryReached(scrollTop: number): boolean { + return this.scrolledToTop(scrollTop) || this.scrolledToBottom(scrollTop); + } + + /** */ + public get(): Observable { + const scrollTop = this.getScrollTop(); + this.reset(scrollTop); + + return this.subject.pipe(filter(data => !!data)); + } + + /** + * Detect if the user has stopped scrolling + */ + private detectStop(): void { + clearTimeout(this.timer); + this.timer = setTimeout(() => { + this.scrollInformation.direction = ScrollDirections.none; + this.scrollInformation.speed = ScrollSpeeds.regular; + this.subject.next(this.scrollInformation); + }, DEBOUNCE_TIME); + } + + /** + * Detect in which direction the user is scrolling + * @param scrollTop current scrollTop + */ + private detectDirection(scrollTop: number): void { + let scrollDirection: ScrollDirection; + if (scrollTop > this.lastScrollTop) { + scrollDirection = ScrollDirections.down; + } else if (scrollTop < this.lastScrollTop) { + scrollDirection = ScrollDirections.up; + } else { + scrollDirection = ScrollDirections.none; + } + if (this.scrollInformation.direction !== scrollDirection) { + this.scrollInformation.speed = ScrollSpeeds.regular; + // this.scrollInformation.direction = ScrollDirections.none; + this.scrollInformation.direction = scrollDirection; + this.subject.next(this.scrollInformation); + } + } + + /** + * Detect how fast the user is scrolling + * @param scrollTop current scrollTop + */ + private detectSpeed(scrollTop: number): void { + const scrollTopDifference = Math.abs(scrollTop - this.lastScrollTop); + let scrollSpeed: ScrollSpeed = ScrollSpeeds.regular; + if (scrollTopDifference >= FAST_SCROLL_DISTANCE) { + scrollSpeed = ScrollSpeeds.fast; + } + if ( + this.scrollInformation.speed !== ScrollSpeeds.fast && + this.scrollInformation.speed !== scrollSpeed + ) { + this.scrollInformation.speed = scrollSpeed; + this.subject.next(this.scrollInformation); + } + } + + /** + * Reset scroll information + */ + private reset(scrollTop: number): void { + this.scrollInformation = { + direction: ScrollDirections.none, + speed: ScrollSpeeds.regular, + position: scrollTop + }; + this.subject.next(this.scrollInformation); + } + + /** */ + public getScrollTop(): number { + const scrollTop = + window.scrollY || + window.pageYOffset || + document.body.scrollTop + + ((document.documentElement && document.documentElement.scrollTop) || 0); + + return scrollTop; + } + + /** + * Callback function for the onscroll event-listener + */ + private scrollHandler(): void { + const scrollTop = this.getScrollTop(); + this.scrollInformation.position = scrollTop; + + if (this.boundaryReached(scrollTop)) { + this.reset(scrollTop); + } else { + this.detectStop(); + this.detectDirection(scrollTop); + this.detectSpeed(scrollTop); + } + + this.lastScrollTop = scrollTop; + } +} diff --git a/src/index.html b/src/index.html index e1948da..8534b63 100644 --- a/src/index.html +++ b/src/index.html @@ -1,14 +1,28 @@ + AngularIntersection - - + + + + + diff --git a/src/styles.styl b/src/styles.styl index 90d4ee0..05cbc04 100644 --- a/src/styles.styl +++ b/src/styles.styl @@ -1 +1,28 @@ -/* You can add global styles to this file, and also import other style files */ +@import '~@angular/material/prebuilt-themes/indigo-pink.css' +@require _variables +@require _color-helpers + +* + margin: 0 + outline: 0 + padding: 0 + +html + height: 100% + + body + background: $color--primary + color: $color--secondary + font-family: $font-family--default + font-size: $font-size--default + letter-spacing: $letter-spacing--default + line-height: $line-height--default + min-height: 100% + +.mat-snack-bar-container + background: $color--black + border-radius: 0 !important + color: $color--white + + .mat-simple-snackbar-action + color: $color--error \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index d38d9e2..51da5a2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -112,13 +112,22 @@ "@angular-devkit/core" "7.1.4" rxjs "6.3.3" -"@angular/animations@~7.1.0": - version "7.1.4" - resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-7.1.4.tgz#6c1ca6b8449bb0fa874343371961fccbe19791bc" - integrity sha512-877LZ83scksJtflVz97CUWlSsZnxduBxPD+ls5OTrTT/bq3muzHCm8rgTO7S8fBwwrEVXLorvMAlhDPpMg5Swg== +"@angular/animations@7": + version "7.2.15" + resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-7.2.15.tgz#980c1f523a79d4b7cb44508f57fba06f2e0872fa" + integrity sha512-8oBt3HLgd2+kyJHUgsd7OzKCCss67t2sch15XNoIWlOLfxclqU+EfFE6t/vCzpT8/+lpZS6LU9ZrTnb+UBj5jg== dependencies: tslib "^1.9.0" +"@angular/cdk@7": + version "7.3.7" + resolved "https://registry.yarnpkg.com/@angular/cdk/-/cdk-7.3.7.tgz#ce1ad53ba04beb9c8e950acc5691ea0143753764" + integrity sha512-xbXxhHHKGkVuW6K7pzPmvpJXIwpl0ykBnvA2g+/7Sgy5Pd35wCC+UtHD9RYczDM/mkygNxMQtagyCErwFnDtQA== + dependencies: + tslib "^1.7.1" + optionalDependencies: + parse5 "^5.0.0" + "@angular/cli@~7.1.3": version "7.1.4" resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-7.1.4.tgz#f07ee4e979ec202bf2fd91a665e3d2d6c065bbe1" @@ -184,6 +193,13 @@ resolved "https://registry.yarnpkg.com/@angular/language-service/-/language-service-7.1.4.tgz#59303e719937f774d9266a5e5f498ba254e0fe7b" integrity sha512-Pvrk3W3+6XfrmpCRcTumfyplv6AQJXKfDdPFSbhdpHJlpdcQRo6TckA85Yln5/CXZSAiPaZeiejQt2OogrIRLg== +"@angular/material@7": + version "7.3.7" + resolved "https://registry.yarnpkg.com/@angular/material/-/material-7.3.7.tgz#dcd95e6618ba6254c5880efee1aad349cf5b9140" + integrity sha512-Eq+7frkeNGkLOfEtmkmJgR+AgoWajOipXZWWfCSamNfpCcPof82DwvGOpAmgGni9FuN2XFQdqP5MoaffQzIvUA== + dependencies: + tslib "^1.7.1" + "@angular/platform-browser-dynamic@~7.1.0": version "7.1.4" resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-7.1.4.tgz#e76a5a267caf27d17bf46d16f009cd9c68a8dfd3" @@ -704,6 +720,14 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" +anymatch@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.0.tgz#e609350e50a9313b472789b2f14ef35808ee14d6" + integrity sha512-Ozz7l4ixzI7Oxj2+cw+p0tVUt27BpaJ+1+q1TCeANWxHpvyn2+Un+YamBdfKu0uh8xLodGhoa1v7595NhKDAuA== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + app-root-path@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-2.1.0.tgz#98bf6599327ecea199309866e8140368fd2e646a" @@ -863,7 +887,7 @@ async-limiter@~1.0.0: resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" integrity sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg== -async@1.x, async@^1.5.2: +async@1.5.2, async@1.x, async@^1.5.2: version "1.5.2" resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= @@ -1079,6 +1103,11 @@ binary-extensions@^1.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.12.0.tgz#c2d780f53d45bba8317a8902d4ceeaf3a6385b14" integrity sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg== +binary-extensions@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.0.0.tgz#23c0df14f6a88077f5f986c0d167ec03c3d5537c" + integrity sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow== + blob@0.0.5: version "0.0.5" resolved "https://registry.yarnpkg.com/blob/-/blob-0.0.5.tgz#d680eeef25f8cd91ad533f5b01eed48e64caf683" @@ -1189,6 +1218,13 @@ braces@^2.3.0, braces@^2.3.1: split-string "^3.0.2" to-regex "^3.0.1" +braces@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + brorand@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" @@ -1488,6 +1524,21 @@ chokidar@2.0.4, chokidar@^2.0.0, chokidar@^2.0.2, chokidar@^2.0.3: optionalDependencies: fsevents "^1.2.2" +chokidar@3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.0.2.tgz#0d1cd6d04eb2df0327446188cd13736a3367d681" + integrity sha512-c4PR2egjNjI1um6bamCQ6bUNPDiyofNQruHvKgHQ4gDUP/ITSVSzNsiI5OWtHOsX323i5ha/kk4YmOZ1Ktg7KA== + dependencies: + anymatch "^3.0.1" + braces "^3.0.2" + glob-parent "^5.0.0" + is-binary-path "^2.1.0" + is-glob "^4.0.1" + normalize-path "^3.0.0" + readdirp "^3.1.1" + optionalDependencies: + fsevents "^2.0.6" + chokidar@^1.4.2: version "1.7.0" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" @@ -1601,6 +1652,11 @@ clone-deep@^2.0.1: kind-of "^6.0.0" shallow-clone "^1.0.0" +clone@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" + integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= + clone@^2.1.1, clone@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" @@ -1658,6 +1714,14 @@ colors@^1.1.0: resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.3.tgz#39e005d546afe01e01f9c4ca8fa50f686a01205d" integrity sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg== +columnify@1.5.4: + version "1.5.4" + resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.5.4.tgz#4737ddf1c7b69a8a7c340570782e947eec8e78bb" + integrity sha1-Rzfd8ce2mop8NAVweC6UfuyOeLs= + dependencies: + strip-ansi "^3.0.0" + wcwidth "^1.0.0" + combine-lists@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/combine-lists/-/combine-lists-1.0.1.tgz#458c07e09e0d900fc28b70a3fec2dacd1d2cb7f6" @@ -2114,6 +2178,13 @@ default-require-extensions@^2.0.0: dependencies: strip-bom "^3.0.0" +defaults@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" + integrity sha1-xlYFHpgX2f8I7YgUd/P+QBnz730= + dependencies: + clone "^1.0.2" + define-property@^0.2.5: version "0.2.5" resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" @@ -2823,6 +2894,13 @@ fill-range@^4.0.0: repeat-string "^1.6.1" to-regex-range "^2.1.0" +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + finalhandler@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.0.tgz#ce0b6855b45853e791b2fcc680046d88253dd7f5" @@ -3023,6 +3101,11 @@ fsevents@^1.0.0, fsevents@^1.2.2: nan "^2.9.2" node-pre-gyp "^0.10.0" +fsevents@^2.0.6: + version "2.0.7" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.0.7.tgz#382c9b443c6cbac4c57187cdda23aa3bf1ccfc2a" + integrity sha512-a7YT0SV3RB+DjYcppwVDLtn13UQnmg0SWZS7ezZD0UjnLwXmy8Zm21GMVGLaFGimIqcvyMQaOJBrop8MyOp1kQ== + fstream@^1.0.0, fstream@^1.0.2: version "1.0.11" resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" @@ -3116,6 +3199,25 @@ glob-parent@^3.1.0: is-glob "^3.1.0" path-dirname "^1.0.0" +glob-parent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.0.0.tgz#1dc99f0f39b006d3e92c2c284068382f0c20e954" + integrity sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg== + dependencies: + is-glob "^4.0.1" + +glob@7.0.4: + version "7.0.4" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.4.tgz#3b44afa0943bdc31b2037b934791e2e084bcb7f6" + integrity sha1-O0SvoJQ73DGyA3uTR5Hi4IS8t/Y= + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "2 || 3" + once "^1.3.0" + path-is-absolute "^1.0.0" + glob@7.0.x: version "7.0.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.6.tgz#211bafaf49e525b8cd93260d14ab136152b3f57a" @@ -3701,6 +3803,13 @@ is-binary-path@^1.0.0: dependencies: binary-extensions "^1.0.0" +is-binary-path@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + is-buffer@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" @@ -3831,6 +3940,13 @@ is-glob@^4.0.0: dependencies: is-extglob "^2.1.1" +is-glob@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + is-installed-globally@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80" @@ -3873,6 +3989,11 @@ is-number@^4.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ== +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + is-obj@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" @@ -4455,7 +4576,7 @@ lie@~3.1.0: dependencies: immediate "~3.0.5" -load-json-file@^1.0.0: +load-json-file@^1.0.0, load-json-file@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= @@ -4525,7 +4646,7 @@ locate-path@^3.0.0: p-locate "^3.0.0" path-exists "^3.0.0" -lodash.assign@^4.2.0: +lodash.assign@^4.0.3, lodash.assign@^4.0.6, lodash.assign@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" integrity sha1-DZnzzNem0mHRm9rrkkUAXShYCOc= @@ -4540,6 +4661,11 @@ lodash.debounce@^4.0.8: resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= +lodash.defaults@4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" + integrity sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw= + lodash.mergewith@^4.6.0: version "4.6.1" resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz#639057e726c3afbdb3e7d42741caa8d6e4335927" @@ -4929,6 +5055,11 @@ mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0: dependencies: minimist "0.0.8" +mout@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/mout/-/mout-0.5.0.tgz#ff967566a90f29595e9cb8b6e7800a5b56635583" + integrity sha1-/5Z1ZqkPKVlenLi254AKW1ZjVYM= + move-concurrently@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" @@ -5230,6 +5361,11 @@ normalize-path@^2.0.0, normalize-path@^2.0.1, normalize-path@^2.1.1: dependencies: remove-trailing-separator "^1.0.1" +normalize-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + normalize-range@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" @@ -5653,6 +5789,11 @@ parse5@4.0.0: resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608" integrity sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA== +parse5@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.0.tgz#c59341c9723f414c452975564c7c00a68d58acd2" + integrity sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ== + parseqs@0.0.5: version "0.0.5" resolved "https://registry.yarnpkg.com/parseqs/-/parseqs-0.0.5.tgz#d5208a3738e46766e291ba2ea173684921a8b89d" @@ -5763,6 +5904,11 @@ performance-now@^2.1.0: resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= +picomatch@^2.0.4: + version "2.0.7" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.0.7.tgz#514169d8c7cd0bdbeecc8a2609e34a7163de69f6" + integrity sha512-oLHIdio3tZ0qH76NybpeneBhYVj0QFTfXEFTc/B3zKQspYfYYkWYgFsmzo+4kvId/bQRcNkVeguI3y+CD22BtA== + pify@^2.0.0, pify@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" @@ -5785,6 +5931,16 @@ pinkie@^2.0.0: resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= +pkg-conf@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/pkg-conf/-/pkg-conf-1.1.3.tgz#378e56d6fd13e88bfb6f4a25df7a83faabddba5b" + integrity sha1-N45W1v0T6Iv7b0ol33qD+qvduls= + dependencies: + find-up "^1.0.0" + load-json-file "^1.1.0" + object-assign "^4.0.1" + symbol "^0.2.1" + pkg-dir@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" @@ -6225,6 +6381,13 @@ readdirp@^2.0.0: micromatch "^3.1.10" readable-stream "^2.0.2" +readdirp@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.1.2.tgz#fa85d2d14d4289920e4671dead96431add2ee78a" + integrity sha512-8rhl0xs2cxfVsqzreYCvs8EwBfn/DhVdqtoLmw19uI3SC5avYX9teCurlErfpPXGmYtMHReGaP2RsLnFvz/lnw== + dependencies: + picomatch "^2.0.4" + rechoir@^0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" @@ -6720,6 +6883,11 @@ serve-static@1.13.2: parseurl "~1.3.2" send "0.16.2" +set-blocking@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-1.0.0.tgz#cd5e5d938048df1ac92dfe92e1f16add656f5ec5" + integrity sha1-zV5dk4BI3xrJLf6S4fFq3WVvXsU= + set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" @@ -7119,6 +7287,13 @@ ssri@^6.0.0, ssri@^6.0.1: dependencies: figgy-pudding "^3.5.1" +stampit@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/stampit/-/stampit-1.2.0.tgz#51f9c6a08c146473fcd021af551c9f32ed5c7b9d" + integrity sha1-UfnGoIwUZHP80CGvVRyfMu1ce50= + dependencies: + mout "~0.5.0" + static-extend@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" @@ -7272,7 +7447,7 @@ strip-indent@^1.0.1: dependencies: get-stdin "^4.0.1" -strip-json-comments@~2.0.1: +strip-json-comments@2.0.1, strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= @@ -7285,6 +7460,22 @@ style-loader@0.23.1: loader-utils "^1.1.0" schema-utils "^1.0.0" +stylint@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/stylint/-/stylint-2.0.0.tgz#7e5ec8158a38604dd68caa4f872058497696412c" + integrity sha512-luHn2OAMGJouOnadm6Fim6WXodQ2AWDkWjYq0rMdyEwzO5PdE4LzoXAEn9LL2snmBAlwUp1URVOTF7lZR3KU+Q== + dependencies: + async "1.5.2" + chalk "1.1.3" + chokidar "3.0.2" + columnify "1.5.4" + glob "7.0.4" + lodash.defaults "4.2.0" + stampit "1.2.0" + strip-json-comments "2.0.1" + user-home "2.0.0" + yargs "4.7.1" + stylus-loader@3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/stylus-loader/-/stylus-loader-3.0.2.tgz#27a706420b05a38e038e7cacb153578d450513c6" @@ -7330,6 +7521,11 @@ symbol-observable@1.2.0: resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== +symbol@^0.2.1: + version "0.2.3" + resolved "https://registry.yarnpkg.com/symbol/-/symbol-0.2.3.tgz#3b9873b8a901e47c6efe21526a3ac372ef28bbc7" + integrity sha1-O5hzuKkB5Hxu/iFSajrDcu8ou8c= + tapable@^1.0.0, tapable@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.1.tgz#4d297923c5a72a42360de2ab52dadfaaec00018e" @@ -7466,6 +7662,13 @@ to-regex-range@^2.1.0: is-number "^3.0.0" repeat-string "^1.6.1" +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + to-regex@^3.0.1, to-regex@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" @@ -7529,6 +7732,11 @@ tsickle@>=0.29.0: mkdirp "^0.5.1" source-map "^0.7.3" +tslib@^1.7.1: + version "1.10.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" + integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== + tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" @@ -7751,6 +7959,13 @@ use@^3.1.0: resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== +user-home@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f" + integrity sha1-nHC/2Babwdy/SGBODwS4tJzenp8= + dependencies: + os-homedir "^1.0.0" + useragent@2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/useragent/-/useragent-2.3.0.tgz#217f943ad540cb2128658ab23fc960f6a88c9972" @@ -7845,6 +8060,13 @@ wbuf@^1.1.0, wbuf@^1.7.2: dependencies: minimalistic-assert "^1.0.0" +wcwidth@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" + integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g= + dependencies: + defaults "^1.0.3" + webdriver-js-extender@2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/webdriver-js-extender/-/webdriver-js-extender-2.1.0.tgz#57d7a93c00db4cc8d556e4d3db4b5db0a80c3bb7" @@ -8039,6 +8261,11 @@ widest-line@^2.0.0: dependencies: string-width "^2.1.1" +window-size@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075" + integrity sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU= + wordwrap@^1.0.0, wordwrap@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" @@ -8154,6 +8381,14 @@ yargs-parser@^10.1.0: dependencies: camelcase "^4.1.0" +yargs-parser@^2.4.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-2.4.1.tgz#85568de3cf150ff49fa51825f03a8c880ddcc5c4" + integrity sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ= + dependencies: + camelcase "^3.0.0" + lodash.assign "^4.0.6" + yargs-parser@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.0.tgz#275ecf0d7ffe05c77e64e7c86e4cd94bf0e1228a" @@ -8186,6 +8421,25 @@ yargs@12.0.2: y18n "^3.2.1 || ^4.0.0" yargs-parser "^10.1.0" +yargs@4.7.1: + version "4.7.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-4.7.1.tgz#e60432658a3387ff269c028eacde4a512e438dff" + integrity sha1-5gQyZYozh/8mnAKOrN5KUS5Djf8= + dependencies: + camelcase "^3.0.0" + cliui "^3.2.0" + decamelize "^1.1.1" + lodash.assign "^4.0.3" + os-locale "^1.4.0" + pkg-conf "^1.1.2" + read-pkg-up "^1.0.1" + require-main-filename "^1.0.1" + set-blocking "^1.0.0" + string-width "^1.0.1" + window-size "^0.2.0" + y18n "^3.2.1" + yargs-parser "^2.4.0" + yargs@9.0.1: version "9.0.1" resolved "https://registry.yarnpkg.com/yargs/-/yargs-9.0.1.tgz#52acc23feecac34042078ee78c0c007f5085db4c"