diff --git a/Dockerfile b/Dockerfile
index 9f48afc71..ced8e4e65 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -20,4 +20,13 @@ RUN chmod +x /usr/local/bin/docker-entrypoint
ENTRYPOINT ["docker-entrypoint"]
+RUN apk update;
+RUN apk upgrade;
+
+RUN echo "" >> /usr/local/apache2/conf/httpd.conf
+RUN echo "###SPECIFIC CUSTOMIZATIONS###" >> /usr/local/apache2/conf/httpd.conf
+RUN echo "" >> /usr/local/apache2/conf/httpd.conf
+
+RUN printf ' \nOrder Allow,Deny \nAllow from all \nAllowOverride all \nHeader set Access-Control-Allow-Origin "*" \n' >> /usr/local/apache2/conf/httpd.conf
+
CMD ["httpd", "-D", "FOREGROUND"]
diff --git a/defaults-ci-overrides.env b/defaults-ci-overrides.env
new file mode 100644
index 000000000..187b67e6e
--- /dev/null
+++ b/defaults-ci-overrides.env
@@ -0,0 +1,7 @@
+#
+# This overrides file should contain only those value which need to be overriden
+# in ./defaults.env when running a build for continuous integration.
+#
+
+BASE_URL=https://tamulib.github.io/weaver-components/docs
+ASSETS_URL=https://tamulib.github.io/weaver-components/docs/assets
diff --git a/package.json b/package.json
index a1e0e59c4..4cd847248 100644
--- a/package.json
+++ b/package.json
@@ -4,7 +4,7 @@
"type": "git",
"url": "git+https://github.com/TAMULib/weaver-components.git"
},
- "version": "1.3.0-rc3",
+ "version": "1.4.0",
"private": false,
"license": "MIT",
"bin": {
@@ -31,7 +31,7 @@
"build:static-setup": "node scripts/build-wvr-components-static.js",
"build:static-docs": "npm run test:audit && npm run build:static-setup && npm run build:docs-usage && npm run build:docs-development",
"build:static-reports": "npm run build:static-setup && npm run test:coverage",
- "build:static-production": "npm run build:static && ls -A | grep -v static | xargs rimraf && mv static/weaver-components/* . && rimraf static",
+ "build:static-production": "npm run build:static && node scripts/build-wvr-components-configuration.js defaults-ci-overrides.env && ls -A | grep -v static | xargs rimraf && mv static/weaver-components/* . && rimraf static",
"clean": "rimraf dist",
"clean:static": "rimraf static",
"lint": "ng lint",
@@ -50,16 +50,16 @@
"test:ci": "npm run test:coverage && npm run test:audit"
},
"dependencies": {
- "@angular/animations": "^10.0.9",
- "@angular/common": "^10.0.9",
- "@angular/compiler": "^10.0.9",
- "@angular/core": "^10.0.9",
- "@angular/elements": "^10.0.9",
- "@angular/forms": "^10.0.9",
- "@angular/localize": "^10.0.9",
- "@angular/platform-browser": "^10.0.9",
- "@angular/platform-browser-dynamic": "^10.0.9",
- "@angular/router": "^10.0.9",
+ "@angular/animations": "^10.0.12",
+ "@angular/common": "^10.0.12",
+ "@angular/compiler": "^10.0.12",
+ "@angular/core": "^10.0.12",
+ "@angular/elements": "^10.0.12",
+ "@angular/forms": "^10.0.12",
+ "@angular/localize": "^10.0.12",
+ "@angular/platform-browser": "^10.0.12",
+ "@angular/platform-browser-dynamic": "^10.0.12",
+ "@angular/router": "^10.0.12",
"@ng-bootstrap/ng-bootstrap": "^7.0.0",
"@types/json5": "0.0.30",
"dotenv-override": "^5.0.1",
@@ -76,18 +76,18 @@
"zone.js": "~0.10.3"
},
"devDependencies": {
- "@angular-devkit/build-angular": "~0.1000.5",
- "@angular-devkit/build-ng-packagr": "~0.1000.5",
- "@angular-devkit/schematics": "^10.0.5",
- "@angular/cli": "^10.0.5",
- "@angular/compiler-cli": "^10.0.9",
- "@angular/language-service": "^10.0.9",
+ "@angular-devkit/build-angular": "~0.1000.7",
+ "@angular-devkit/build-ng-packagr": "~0.1000.7",
+ "@angular-devkit/schematics": "^10.0.7",
+ "@angular/cli": "^10.0.7",
+ "@angular/compiler-cli": "^10.0.12",
+ "@angular/language-service": "^10.0.12",
"@compodoc/compodoc": "^1.1.11",
- "@lhci/cli": "^0.4.4",
+ "@lhci/cli": "^0.5.0",
"@pickra/copy-code-block": "^1.2.0",
- "@types/jasmine": "~3.5.12",
+ "@types/jasmine": "~3.5.13",
"@types/jasminewd2": "~2.0.8",
- "@types/node": "^14.0.27",
+ "@types/node": "^14.6.0",
"angular-tslint-rules": "^1.20.4",
"chalk": "^4.1.0",
"chrome-launcher": "^0.13.4",
@@ -106,13 +106,13 @@
"karma-jasmine-html-reporter": "^1.5.4",
"lighthouse": "^6.2.0",
"lighthouse-badges": "^1.0.33",
- "ng-packagr": "^10.0.3",
+ "ng-packagr": "^10.0.4",
"protractor": "~7.0.0",
"rimraf": "^3.0.2",
"static-server": "^2.2.1",
- "ts-loader": "^8.0.2",
- "ts-node": "~8.10.2",
+ "ts-loader": "^8.0.3",
+ "ts-node": "~9.0.0",
"tslint": "~6.1.3",
- "typescript": "~3.9.7"
+ "typescript": "~3.9.4"
}
}
diff --git a/projects/wvr-elements/package.json b/projects/wvr-elements/package.json
index 4879d875d..f42c4a6da 100644
--- a/projects/wvr-elements/package.json
+++ b/projects/wvr-elements/package.json
@@ -1,6 +1,6 @@
{
"name": "@wvr/elements",
- "version": "1.3.0",
+ "version": "1.4.0",
"description": "Collection of angular components for Weaver's Custom Web Component UI",
"author": "Texas A&M University Libraries",
"private": false,
diff --git a/projects/wvr-elements/src/lib/core/icon.service.ts b/projects/wvr-elements/src/lib/core/icon.service.ts
index d89fad207..749f8d49b 100644
--- a/projects/wvr-elements/src/lib/core/icon.service.ts
+++ b/projects/wvr-elements/src/lib/core/icon.service.ts
@@ -17,7 +17,6 @@ export class IconService {
private readonly http: HttpClient,
@Inject(APP_CONFIG) private readonly appConfig: AppConfig
) {
-
}
registerIcons(icons: IconSet): void {
diff --git a/projects/wvr-elements/src/lib/core/mobile.service.spec.ts b/projects/wvr-elements/src/lib/core/mobile.service.spec.ts
new file mode 100644
index 000000000..a315b8161
--- /dev/null
+++ b/projects/wvr-elements/src/lib/core/mobile.service.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { MobileService } from './mobile.service';
+
+describe('MobileService', () => {
+ let service: MobileService;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({});
+ service = TestBed.inject(MobileService);
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+});
diff --git a/projects/wvr-elements/src/lib/core/mobile.service.ts b/projects/wvr-elements/src/lib/core/mobile.service.ts
new file mode 100644
index 000000000..2eabb2825
--- /dev/null
+++ b/projects/wvr-elements/src/lib/core/mobile.service.ts
@@ -0,0 +1,28 @@
+import { Injectable } from '@angular/core';
+import { fromEvent, Observable } from 'rxjs';
+import { delay, map, throttleTime } from 'rxjs/operators';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class MobileService {
+
+ isMobileLayout: boolean;
+
+ private readonly screenSizeChanged$: Observable;
+
+ constructor() {
+ this.screenSizeChanged$ = fromEvent(window, 'resize')
+ .pipe(throttleTime(100))
+ .pipe(map(this.checkScreenSize));
+
+ this.screenSizeChanged$.subscribe(iml => {
+ this.isMobileLayout = iml;
+ });
+
+ this.isMobileLayout = this.checkScreenSize();
+ }
+
+ private readonly checkScreenSize = () => window.innerWidth < 767;
+
+}
diff --git a/projects/wvr-elements/src/lib/shared/utility/decorators.utilty.ts b/projects/wvr-elements/src/lib/shared/utility/decorators.utilty.ts
new file mode 100644
index 000000000..34c446a27
--- /dev/null
+++ b/projects/wvr-elements/src/lib/shared/utility/decorators.utilty.ts
@@ -0,0 +1,20 @@
+// tslint:disable-next-line:only-arrow-functions
+function debounce(delay = 300): MethodDecorator {
+ return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
+ const timeoutKey = Symbol();
+ const original = descriptor.value;
+ // tslint:disable-next-line:typedef
+ descriptor.value = function(...args) {
+ // tslint:disable-next-line:no-invalid-this
+ clearTimeout(this[timeoutKey]);
+ // tslint:disable-next-line:no-invalid-this
+ this[timeoutKey] = setTimeout(() => original.apply(this, args), delay);
+ };
+
+ return descriptor;
+ };
+}
+
+export {
+ debounce
+};
diff --git a/projects/wvr-elements/src/lib/shared/utility/index.ts b/projects/wvr-elements/src/lib/shared/utility/index.ts
index c3b760301..693c2d7da 100644
--- a/projects/wvr-elements/src/lib/shared/utility/index.ts
+++ b/projects/wvr-elements/src/lib/shared/utility/index.ts
@@ -1,2 +1,2 @@
export { obtainConfigPath, weaverBootstrap } from './bootstrap.utility';
-
+export { debounce } from './decorators.utilty';
diff --git a/projects/wvr-elements/src/lib/shared/wvr-base.component.ts b/projects/wvr-elements/src/lib/shared/wvr-base.component.ts
index eb09e7456..c21c14f07 100644
--- a/projects/wvr-elements/src/lib/shared/wvr-base.component.ts
+++ b/projects/wvr-elements/src/lib/shared/wvr-base.component.ts
@@ -1,14 +1,18 @@
-import { AfterContentInit, Directive, ElementRef, EventEmitter, Injector, Input, OnInit, Output, ViewChild } from '@angular/core';
+import { AfterContentInit, Directive, ElementRef, EventEmitter, HostBinding, Injector, Input, OnInit, Output, ViewChild } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
import * as JSON5 from 'json5';
import { fromEvent, Observable } from 'rxjs';
import { debounceTime, map } from 'rxjs/operators';
import { WvrAnimationService } from '../core/wvr-animation.service';
+import { IconService } from '../core/icon.service';
+import { MobileService } from '../core/mobile.service';
@Directive()
// tslint:disable-next-line:directive-class-suffix
export abstract class WvrBaseComponent implements AfterContentInit, OnInit {
+ @HostBinding('class.wvr-bootstrap') wvrBootstrap = true;
+
private _animationSettings: any = {};
@Input() set animate(value: string) {
this._animationSettings = JSON5.parse(value);
@@ -27,6 +31,10 @@ export abstract class WvrBaseComponent implements AfterContentInit, OnInit {
@ViewChild('animationRoot') animationRootElem: ElementRef;
+ get isMobileLayout(): boolean {
+ return this.mobileService.isMobileLayout;
+ }
+
get isMobileAgent(): boolean {
const agent = navigator.userAgent || navigator.vendor || (window as any).opera;
@@ -34,27 +42,27 @@ export abstract class WvrBaseComponent implements AfterContentInit, OnInit {
return (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(agent) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(agent.substr(0, 4)));
}
- screenSizeChanged$: Observable;
-
- isMobileLayout = this.isMobileAgent;
-
protected readonly _animationService: WvrAnimationService;
protected readonly _domSanitizer: DomSanitizer;
protected readonly _eRef: ElementRef;
+ private readonly mobileService: MobileService;
+
+ @HostBinding('class.wvr-hidden') private get _hiddenInMobile(): boolean {
+ return this.mobileService.isMobileLayout && this.hiddenInMobile;
+ }
+
+ @Input() hiddenInMobile = false;
+
@Output() protected readonly animationEventTrigger = new EventEmitter();
constructor(injector: Injector) {
-
this._animationService = injector.get(WvrAnimationService);
this._domSanitizer = injector.get(DomSanitizer);
this._eRef = injector.get(ElementRef);
-
- this.screenSizeChanged$ = fromEvent(window, 'resize')
- .pipe(debounceTime(50))
- .pipe(map(this.checkScreenSize));
+ this.mobileService = injector.get(MobileService);
}
ngOnInit(): void {
@@ -70,10 +78,6 @@ export abstract class WvrBaseComponent implements AfterContentInit, OnInit {
}
});
}
- this.screenSizeChanged$.subscribe(iml => {
- this.isMobileLayout = iml;
- });
- this.isMobileLayout = this.checkScreenSize();
}
ngAfterContentInit(): void {
@@ -101,6 +105,4 @@ export abstract class WvrBaseComponent implements AfterContentInit, OnInit {
this.triggerAnimations($event.type);
}
- private readonly checkScreenSize = () => document.body.offsetWidth < 767;
-
}
diff --git a/projects/wvr-elements/src/lib/wvr-dropdown/wvr-dropdown.component.html b/projects/wvr-elements/src/lib/wvr-dropdown/wvr-dropdown.component.html
index 02b50d0ef..943b7cbdb 100644
--- a/projects/wvr-elements/src/lib/wvr-dropdown/wvr-dropdown.component.html
+++ b/projects/wvr-elements/src/lib/wvr-dropdown/wvr-dropdown.component.html
@@ -1,5 +1,5 @@