@inaccess-fang/ui-components
Version:
The Inaccess UI Components Library for the Front-end projects
1,061 lines (1,009 loc) • 45.3 kB
JavaScript
import { Component, ViewEncapsulation, ChangeDetectionStrategy, Input, EventEmitter, ChangeDetectorRef, ContentChildren, Output, NgModule, Directive, HostBinding, ElementRef, HostListener, ComponentFactoryResolver, ViewContainerRef } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HttpClientModule } from '@angular/common/http';
import { filter } from 'rxjs/operators';
import { ScrollDispatcher } from '@angular/cdk/overlay';
import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
import { FormsModule, NgModel } from '@angular/forms';
import tippy from 'tippy.js';
import { ReplaySubject, fromEvent, combineLatest } from 'rxjs';
import Popper from 'popper.js';
// @angular/core
class FangTabComponent {
constructor() {
this.active = false;
}
// Ovveride
ngOnInit() {
console.log('FangTabComponent [ngOnInit]');
}
}
FangTabComponent.decorators = [
{ type: Component, args: [{
selector: 'fang-tab',
template: "<div [hidden]=\"!active\">\n\t<ng-content></ng-content>\n</div>\n",
encapsulation: ViewEncapsulation.ShadowDom,
changeDetection: ChangeDetectionStrategy.Default,
styles: [":host{display:block;height:inherit}"]
},] }
];
FangTabComponent.ctorParameters = () => [];
FangTabComponent.propDecorators = {
title: [{ type: Input, args: ['tabTitle',] }]
};
// @angular/core
class FangMultiTabsComponent {
constructor(_changeDetectorRef) {
this._changeDetectorRef = _changeDetectorRef;
this.selectedTabChanged = new EventEmitter();
}
// @Override
ngOnInit() {
console.log('FangMultiTabsComponent [ngOnInit]');
}
// @Override
ngAfterViewInit() {
// Set initial active tab
if (this.tabs.length && !this.tabs.first.active) {
this.selectTab(this.tabs.first);
}
// Set selected Tab after each time child view changes on a single lifecycle
this._changesSubscription$ = this.tabs.changes
.pipe(filter((change) => change.first))
.subscribe(() => this.selectTab(this.tabs.first));
}
// @Override
ngOnDestroy() {
this._changesSubscription$.unsubscribe();
}
selectTab(tab) {
console.log('FangMultiTabsComponent [selectTab]');
this.tabs.toArray().map(tab => tab.active = false);
tab.active = true;
this.selectedTabChanged.emit();
this._changeDetectorRef.detectChanges();
}
}
FangMultiTabsComponent.decorators = [
{ type: Component, args: [{
selector: 'fang-multi-tabs',
template: "<ul class=\"fang-multi-tabs\">\n\t<li *ngFor=\"let tab of tabs.toArray()\"\n\t\t[class.fang-tab-active]=\"tab.active\"\n\t\t(click)=\"selectTab(tab)\"\n\t\tclass=\"fang-tab\">\n\t\t<a class=\"fang-tab-header\">{{tab.title}}</a>\n\t</li>\n</ul>\n<ng-content></ng-content>\n",
changeDetection: ChangeDetectionStrategy.Default,
styles: [".fang-multi-tabs{display:flex;margin:0 8px;padding:0}.fang-tab{border-bottom:2px solid #ceeaf2;display:inline-flex;flex-grow:1;justify-content:space-around;padding:6px}.fang-tab-active,.fang-tab:focus{outline-color:transparent}.fang-tab-active{border-bottom:2px solid #519eae}.fang-tab-header{color:#6a6a6a;cursor:pointer;font-size:.85em;font-weight:600;text-transform:uppercase}"]
},] }
];
FangMultiTabsComponent.ctorParameters = () => [
{ type: ChangeDetectorRef }
];
FangMultiTabsComponent.propDecorators = {
tabs: [{ type: ContentChildren, args: [FangTabComponent,] }],
selectedTabChanged: [{ type: Output }]
};
// @angular/core
class FangMultiTabsModule {
}
FangMultiTabsModule.decorators = [
{ type: NgModule, args: [{
declarations: [
FangMultiTabsComponent,
FangTabComponent
],
imports: [
CommonModule,
HttpClientModule
],
exports: [
FangMultiTabsComponent,
FangTabComponent
],
providers: []
},] }
];
// @angular/core
class FangViewportAutoResizeDirective {
constructor(cdkVirtualScrollViewport) {
this.cdkVirtualScrollViewport = cdkVirtualScrollViewport;
const ResizeObserver = window.ResizeObserver;
if (ResizeObserver) {
this.resizeObserver = new ResizeObserver(() => this.cdkVirtualScrollViewport.checkViewportSize());
this.resizeObserver.observe(this.cdkVirtualScrollViewport.elementRef.nativeElement);
}
}
ngOnDestroy() {
this.resizeObserver && this.resizeObserver.disconnect();
this.resizeObserver = null;
}
}
FangViewportAutoResizeDirective.decorators = [
{ type: Directive, args: [{
selector: 'cdk-virtual-scroll-viewport[viewport-auto-resize], fang-table-virtual-scroll-viewport[viewport-auto-resize]'
},] }
];
FangViewportAutoResizeDirective.ctorParameters = () => [
{ type: CdkVirtualScrollViewport }
];
// @angular/core
const EXPORTED_DECLARATIONS = [
FangViewportAutoResizeDirective
];
class FangVirtualScrollingModule {
}
FangVirtualScrollingModule.decorators = [
{ type: NgModule, args: [{
declarations: EXPORTED_DECLARATIONS,
imports: [],
exports: EXPORTED_DECLARATIONS,
providers: [ScrollDispatcher]
},] }
];
// Current version.
var VERSION = '1.11.0';
// Establish the root object, `window` (`self`) in the browser, `global`
// on the server, or `this` in some virtual machines. We use `self`
// instead of `window` for `WebWorker` support.
var root = typeof self == 'object' && self.self === self && self ||
typeof global == 'object' && global.global === global && global ||
Function('return this')() ||
{};
// Save bytes in the minified (but not gzipped) version:
var ArrayProto = Array.prototype, ObjProto = Object.prototype;
var SymbolProto = typeof Symbol !== 'undefined' ? Symbol.prototype : null;
// Create quick reference variables for speed access to core prototypes.
var push = ArrayProto.push, slice = ArrayProto.slice, toString = ObjProto.toString, hasOwnProperty = ObjProto.hasOwnProperty;
// Modern feature detection.
var supportsArrayBuffer = typeof ArrayBuffer !== 'undefined';
// All **ECMAScript 5+** native function implementations that we hope to use
// are declared here.
var nativeIsArray = Array.isArray, nativeKeys = Object.keys, nativeCreate = Object.create, nativeIsView = supportsArrayBuffer && ArrayBuffer.isView;
// Create references to these builtin functions because we override them.
var _isNaN = isNaN, _isFinite = isFinite;
// Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.
var hasEnumBug = !{ toString: null }.propertyIsEnumerable('toString');
var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',
'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];
// The largest integer that can be represented exactly.
var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;
function _(obj) {
if (obj instanceof _)
return obj;
if (!(this instanceof _))
return new _(obj);
this._wrapped = obj;
}
_.VERSION = VERSION;
// Extracts the result from a wrapped and chained object.
_.prototype.value = function () {
return this._wrapped;
};
// Provide unwrapping proxies for some methods used in engine operations
// such as arithmetic and JSON stringification.
_.prototype.valueOf = _.prototype.toJSON = _.prototype.value;
_.prototype.toString = function () {
return String(this._wrapped);
};
// Keep the identity function around for default iteratees.
function identity(value) {
return value;
}
// Internal function for creating a `toString`-based type tester.
function tagTester(name) {
return function (obj) {
return toString.call(obj) === '[object ' + name + ']';
};
}
var isFunction = tagTester('Function');
// Optimize `isFunction` if appropriate. Work around some `typeof` bugs in old
// v8, IE 11 (#1621), Safari 8 (#1929), and PhantomJS (#2236).
var nodelist = root.document && root.document.childNodes;
if (typeof /./ != 'function' && typeof Int8Array != 'object' && typeof nodelist != 'function') {
isFunction = function (obj) {
return typeof obj == 'function' || false;
};
}
var isFunction$1 = isFunction;
// Is a given variable an object?
function isObject(obj) {
var type = typeof obj;
return type === 'function' || type === 'object' && !!obj;
}
// Is a given value an array?
// Delegates to ECMA5's native `Array.isArray`.
var isArray = nativeIsArray || tagTester('Array');
// An internal function for creating assigner functions.
function createAssigner(keysFunc, defaults) {
return function (obj) {
var length = arguments.length;
if (defaults)
obj = Object(obj);
if (length < 2 || obj == null)
return obj;
for (var index = 1; index < length; index++) {
var source = arguments[index], keys = keysFunc(source), l = keys.length;
for (var i = 0; i < l; i++) {
var key = keys[i];
if (!defaults || obj[key] === void 0)
obj[key] = source[key];
}
}
return obj;
};
}
// Internal function to check whether `key` is an own property name of `obj`.
function has(obj, key) {
return obj != null && hasOwnProperty.call(obj, key);
}
// Internal helper to create a simple lookup structure.
// `collectNonEnumProps` used to depend on `_.contains`, but this led to
// circular imports. `emulatedSet` is a one-off solution that only works for
// arrays of strings.
function emulatedSet(keys) {
var hash = {};
for (var l = keys.length, i = 0; i < l; ++i)
hash[keys[i]] = true;
return {
contains: function (key) { return hash[key]; },
push: function (key) {
hash[key] = true;
return keys.push(key);
}
};
}
// Internal helper. Checks `keys` for the presence of keys in IE < 9 that won't
// be iterated by `for key in ...` and thus missed. Extends `keys` in place if
// needed.
function collectNonEnumProps(obj, keys) {
keys = emulatedSet(keys);
var nonEnumIdx = nonEnumerableProps.length;
var constructor = obj.constructor;
var proto = isFunction$1(constructor) && constructor.prototype || ObjProto;
// Constructor is a special case.
var prop = 'constructor';
if (has(obj, prop) && !keys.contains(prop))
keys.push(prop);
while (nonEnumIdx--) {
prop = nonEnumerableProps[nonEnumIdx];
if (prop in obj && obj[prop] !== proto[prop] && !keys.contains(prop)) {
keys.push(prop);
}
}
}
// Retrieve the names of an object's own properties.
// Delegates to **ECMAScript 5**'s native `Object.keys`.
function keys(obj) {
if (!isObject(obj))
return [];
if (nativeKeys)
return nativeKeys(obj);
var keys = [];
for (var key in obj)
if (has(obj, key))
keys.push(key);
// Ahem, IE < 9.
if (hasEnumBug)
collectNonEnumProps(obj, keys);
return keys;
}
// Assigns a given object with all the own properties in the passed-in
// object(s).
// (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)
var extendOwn = createAssigner(keys);
// Returns whether an object has a given set of `key:value` pairs.
function isMatch(object, attrs) {
var _keys = keys(attrs), length = _keys.length;
if (object == null)
return !length;
var obj = Object(object);
for (var i = 0; i < length; i++) {
var key = _keys[i];
if (attrs[key] !== obj[key] || !(key in obj))
return false;
}
return true;
}
// Returns a predicate for checking whether an object has a given set of
// `key:value` pairs.
function matcher(attrs) {
attrs = extendOwn({}, attrs);
return function (obj) {
return isMatch(obj, attrs);
};
}
// Internal function to obtain a nested property in `obj` along `path`.
function deepGet(obj, path) {
var length = path.length;
for (var i = 0; i < length; i++) {
if (obj == null)
return void 0;
obj = obj[path[i]];
}
return length ? obj : void 0;
}
// Normalize a (deep) property `path` to array.
// Like `_.iteratee`, this function can be customized.
function toPath(path) {
return isArray(path) ? path : [path];
}
_.toPath = toPath;
// Internal wrapper for `_.toPath` to enable minification.
// Similar to `cb` for `_.iteratee`.
function toPath$1(path) {
return _.toPath(path);
}
// Creates a function that, when passed an object, will traverse that object’s
// properties down the given `path`, specified as an array of keys or indices.
function property(path) {
path = toPath$1(path);
return function (obj) {
return deepGet(obj, path);
};
}
function optimizeCb(func, context, argCount) {
if (context === void 0)
return func;
switch (argCount == null ? 3 : argCount) {
case 1: return function (value) {
return func.call(context, value);
};
// The 2-argument case is omitted because we’re not using it.
case 3: return function (value, index, collection) {
return func.call(context, value, index, collection);
};
case 4: return function (accumulator, value, index, collection) {
return func.call(context, accumulator, value, index, collection);
};
}
return function () {
return func.apply(context, arguments);
};
}
// An internal function to generate callbacks that can be applied to each
// element in a collection, returning the desired result — either `_.identity`,
// an arbitrary callback, a property matcher, or a property accessor.
function baseIteratee(value, context, argCount) {
if (value == null)
return identity;
if (isFunction$1(value))
return optimizeCb(value, context, argCount);
if (isObject(value) && !isArray(value))
return matcher(value);
return property(value);
}
// External wrapper for our callback generator. Users may customize
// `_.iteratee` if they want additional predicate/iteratee shorthand styles.
// This abstraction hides the internal-only `argCount` argument.
function iteratee(value, context) {
return baseIteratee(value, context, Infinity);
}
_.iteratee = iteratee;
// The function we call internally to generate a callback. It invokes
// `_.iteratee` if overridden, otherwise `baseIteratee`.
function cb(value, context, argCount) {
if (_.iteratee !== iteratee)
return _.iteratee(value, context);
return baseIteratee(value, context, argCount);
}
// Common internal logic for `isArrayLike` and `isBufferLike`.
function createSizePropertyCheck(getSizeProperty) {
return function (collection) {
var sizeProperty = getSizeProperty(collection);
return typeof sizeProperty == 'number' && sizeProperty >= 0 && sizeProperty <= MAX_ARRAY_INDEX;
};
}
// Internal helper to generate a function to obtain property `key` from `obj`.
function shallowProperty(key) {
return function (obj) {
return obj == null ? void 0 : obj[key];
};
}
// Internal helper to obtain the `length` property of an object.
var getLength = shallowProperty('length');
// Internal helper for collection methods to determine whether a collection
// should be iterated as an array or as an object.
// Related: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength
// Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094
var isArrayLike = createSizePropertyCheck(getLength);
// Return the results of applying the iteratee to each element.
function map(obj, iteratee, context) {
iteratee = cb(iteratee, context);
var _keys = !isArrayLike(obj) && keys(obj), length = (_keys || obj).length, results = Array(length);
for (var index = 0; index < length; index++) {
var currentKey = _keys ? _keys[index] : index;
results[index] = iteratee(obj[currentKey], currentKey, obj);
}
return results;
}
// Convenience version of a common use case of `_.map`: fetching a property.
function pluck(obj, key) {
return map(obj, property(key));
}
// Sort the object's values by a criterion produced by an iteratee.
function sortBy(obj, iteratee, context) {
var index = 0;
iteratee = cb(iteratee, context);
return pluck(map(obj, function (value, key, list) {
return {
value: value,
index: index++,
criteria: iteratee(value, key, list)
};
}).sort(function (left, right) {
var a = left.criteria;
var b = right.criteria;
if (a !== b) {
if (a > b || a === void 0)
return 1;
if (a < b || b === void 0)
return -1;
}
return left.index - right.index;
}), 'value');
}
class FangChipGroupComponent {
constructor() {
this.dataChange = new EventEmitter();
this.chipGroupDataChange = new EventEmitter();
}
ngOnChanges(changes) {
if (changes['data']) {
this.cursor = this.config.interaction === 'select' ? 'pointer' : 'default';
this.chipGroupData = this.data.reduce((acc, data, index) => {
let selected;
if (this.config.interaction !== 'select') {
selected = true;
}
else {
selected = this.chipGroupData && this.chipGroupData[index] && this.chipGroupData[index].selected;
}
acc.push({
displayValue: this.config.propertyAccessKey ? data[this.config.propertyAccessKey] : data,
selected
});
return acc;
}, []);
this.chipGroupData = this.sortData(this.chipGroupData);
this.chipGroupDataChange.emit(this.chipGroupData);
}
}
removeChip(event, chip) {
event.stopPropagation();
this.chipGroupData = this.chipGroupData.filter(chipData => chipData.displayValue !== chip.displayValue);
this.chipGroupData = this.sortData(this.chipGroupData);
const chipToRemove = this.data.filter(data => this.config.propertyAccessKey
? data[this.config.propertyAccessKey] === chip.displayValue
: data === chip.displayValue)[0];
this.dataChange.emit(chipToRemove);
this.chipGroupDataChange.emit(this.chipGroupData);
}
toggleChipSelection(chipIndex) {
this.chipGroupData[chipIndex].selected = !this.chipGroupData[chipIndex].selected;
}
sortData(data) {
return sortBy(data, ['displayValue']);
}
}
FangChipGroupComponent.decorators = [
{ type: Component, args: [{
selector: 'fang-chip-group',
template: "<div *ngIf=\"chipGroupData && chipGroupData.length\"\n\t [ngClass]=\"{'no-wrap': config.hasWrap !== undefined && !config.hasWrap}\"\n\t class=\"{{config.alignment ? config.alignment: 'group-inline'}}\n\t {{config.chipGroupBackground}}\"\n>\n\t<div *ngFor=\"let chip of chipGroupData; let chipIndex = index\"\n\t\t [ngClass]=\"{'selected': chip.selected}\"\n\t\t class=\"{{config.chipBackground ? config.chipBackground : 'chip-light'}}\"\n\t\t (click)=\"config.interaction === 'select' && toggleChipSelection(chipIndex)\">\n\n\t\t<p [ngClass]=\"{'text-truncate-100': config.hasTextTruncate}\"\n\t\t title=\"{{chip.displayValue}}\" style=\"pointer-events: auto;\">\n\t\t\t{{chip.displayValue}}\n\t\t</p>\n\n\t\t<i *ngIf=\"config.interaction && config.interaction === 'close'\"\n\t\t class=\"ic-close\"\n\t\t style=\"pointer-events: auto !important\"\n\t\t (click)=\"removeChip($event,chip)\">\n\t\t</i>\n\t</div>\n</div>\n",
changeDetection: ChangeDetectionStrategy.OnPush,
styles: [":host{max-height:650px}::-webkit-scrollbar{background-color:#fff;border:none;border-left:1px solid hsla(0,0%,88.6%,.4);width:12px}"]
},] }
];
FangChipGroupComponent.propDecorators = {
cursor: [{ type: HostBinding, args: ['style.cursor',] }],
data: [{ type: Input }],
config: [{ type: Input }],
dataChange: [{ type: Output }],
chipGroupDataChange: [{ type: Output }]
};
class FangChipGroupModule {
}
FangChipGroupModule.decorators = [
{ type: NgModule, args: [{
imports: [
CommonModule
],
exports: [
FangChipGroupComponent
],
declarations: [
FangChipGroupComponent
],
providers: [],
entryComponents: [FangChipGroupComponent]
},] }
];
class FangSearchComponent {
constructor() {
this.config = {};
this.filteredDataChange = new EventEmitter();
this.inputTextChange = new EventEmitter();
this.inputText = '';
}
filterInputElements() {
if (this.data) {
this.filteredData = this.data
.filter(e => {
return this.inputText.toLowerCase().split(' ').every(keyword => {
return (this.config.searchBy ? e[this.config.searchBy] : e).toString().toLowerCase().includes(keyword);
});
});
this.filteredDataChange.emit(this.filteredData);
}
this.inputTextChange.emit(this.inputText);
}
clearInputText(event) {
event && event.stopPropagation();
this.inputText = '';
this.filterInputElements();
}
}
FangSearchComponent.decorators = [
{ type: Component, args: [{
selector: 'fang-search',
template: "<div class=\"input\">\n\t<input type=\"text\"\n\t\t [(ngModel)]=\"inputText\"\n\t\t (ngModelChange)=\"filterInputElements()\"\n\t\t placeholder=\"{{config?.placeholder ? config.placeholder : 'Search...'}}\"/>\n\t<i class=\"ic-close \" *ngIf=\"inputText.length\"\n\t (click)=\"clearInputText($event)\"\n\t></i>\n</div>\n\n",
changeDetection: ChangeDetectionStrategy.OnPush,
styles: [""]
},] }
];
FangSearchComponent.propDecorators = {
data: [{ type: Input }],
config: [{ type: Input }],
filteredDataChange: [{ type: Output }],
inputTextChange: [{ type: Output }]
};
class FangSearchModule {
}
FangSearchModule.decorators = [
{ type: NgModule, args: [{
imports: [
CommonModule,
FormsModule
],
exports: [
FangSearchComponent
],
declarations: [
FangSearchComponent
],
providers: [],
entryComponents: [FangSearchComponent]
},] }
];
const dropdownTypeMap = {
'default': 'dropdown-wrapper',
'compact': 'dropdown-wrapper-sm',
'large': 'dropdown-wrapper-lg'
};
class FangDropdownComponent {
constructor() {
this.config = {};
this.selectedItemsChanged = new EventEmitter();
this.isDropdownOpen = false;
this.selectedItems = [];
this.searchInputText = '';
}
ngOnChanges(changes) {
if (changes['data']) {
if (this.config.hasChipGroup && this.config.chipGroupConfig) {
this.config.chipGroupConfig.propertyAccessKey = this.config.propertyAccessKey;
this.config.chipGroupConfig.interaction = 'close';
}
// Transform dropdownData to string[]
this.dropdownData = [...this.data].map((el) => {
return this.getPropertyValue(el);
});
this.filteredDropdownData = [...this.dropdownData];
this.filteredDropdownData = this.sortData(this.filteredDropdownData);
}
if (changes['config'].isFirstChange()) {
if (!this.config.type) {
this.config.type = 'default';
}
if (this.config.isGrowable === undefined) {
this.config.isGrowable = true;
}
if (this.config.isPortfolio) {
this.config.hasContainer = false;
this.config.chipGroupConfig.alignment = 'group-inline';
this.config.chipGroupConfig.chipBackground = undefined;
}
}
}
selectItem(item) {
if (this.config.hasMultiSelect) {
const isElementSelected = this.selectedItems.find((el) => this.getPropertyValue(el) === item);
if (!isElementSelected) {
this.selectedItems = [...this.selectedItems, this.data.find((el) => this.getPropertyValue(el) === item)];
}
else {
this.selectedItems = this.selectedItems.filter((el) => this.getPropertyValue(el) !== item);
}
// Chip Group & portfolio
if (this.config.hasChipGroup && this.config.chipGroupConfig) {
this.dropdownData = this.dropdownData.filter((el) => el !== item);
this.filteredDropdownData = this.filteredDropdownData.filter((el) => el !== item);
this.filteredDropdownData = this.sortData(this.filteredDropdownData);
}
this.selectedItemsChanged.emit(this.selectedItems);
// TODO Tree implementation
}
else { // single select
this.selectedItems = [this.data.find((el) => this.getPropertyValue(el) === item)];
this.isDropdownOpen = false;
this.selectedItemsChanged.emit(this.selectedItems);
}
}
toggleDropdown(arrowPressed = false, event = undefined) {
event && event.stopPropagation();
if (arrowPressed || !this.config.hasChipGroup || (this.config.hasChipGroup && !this.selectedItems.length && !arrowPressed)) {
this.isDropdownOpen = !this.isDropdownOpen;
}
}
getPropertyValue(element) {
return this.config.propertyAccessKey
? element[this.config.propertyAccessKey]
: element;
}
isItemSelected(item) {
return this.selectedItems.find((el) => this.getPropertyValue(el) === item);
}
removeChip(item) {
this.selectedItems = this.selectedItems.filter((el) => el !== item);
// re-add chip to list only if its not portfolio
if (this.config.hasChipGroup && this.config.chipGroupConfig) {
this.dropdownData = [...this.dropdownData, this.getPropertyValue(item)];
this.filteredDropdownData = [...this.filteredDropdownData, this.getPropertyValue(item)];
this.filteredDropdownData = this.sortData(this.filteredDropdownData);
}
}
getConcatSelectedItems(items) {
return items.map(item => this.getPropertyValue(item)).join(', ');
}
selectAll() {
this.selectedItems = [...this.data];
if (this.config.hasChipGroup) {
this.dropdownData = [];
this.filteredDropdownData = [];
}
else {
this.dropdownData = this.selectedItems.map((selectedItem) => {
return this.getPropertyValue(selectedItem);
});
}
}
clearAll() {
this.selectedItems = [];
if (this.config.hasChipGroup) {
this.dropdownData = [...this.data].map((dataEl) => {
return this.getPropertyValue(dataEl);
});
this.filteredDropdownData = [...this.dropdownData];
this.filteredDropdownData = this.sortData(this.filteredDropdownData);
}
}
proceedToSelection(item, event = undefined) {
event && event.stopPropagation();
if (!!this.selectedItems.find((el) => this.getPropertyValue(el) === item)
|| (this.config.multiActions && this.config.multiActions.selectLimit && this.config.multiActions.selectLimit > this.selectedItems.length)
|| (this.config.multiActions && !this.config.multiActions.selectLimit)
|| !this.config.multiActions) {
this.selectItem(item);
}
}
sortData(data) {
return sortBy(data);
}
getDropdownSize() {
return dropdownTypeMap[this.config.type];
}
totalSelectedItems() {
if (this.config.titleConfig && this.config.titleConfig.isTitleConcatenated) {
if (this.config.multiActions && this.config.multiActions.selectLimit) {
return `${this.getConcatSelectedItems(this.selectedItems)} (${this.selectedItems.length}/${this.config.multiActions.selectLimit})`;
}
return `${this.getConcatSelectedItems(this.selectedItems)} (${this.selectedItems.length})`;
}
else {
if (this.config.multiActions && this.config.multiActions.selectLimit) {
return `Total Selected (${this.selectedItems.length}/${this.config.multiActions.selectLimit})`;
}
return `Total Selected (${this.selectedItems.length})`;
}
}
}
FangDropdownComponent.decorators = [
{ type: Component, args: [{
selector: 'fang-dropdown',
template: "<div uds-ui class=\"light-theme\" (clickOutsideElement)=\"isDropdownOpen=false\">\n\t<div class=\" {{getDropdownSize()}}\"\n\t\t [ngClass]=\"{'no-container ': config.hasContainer !== undefined && !config.hasContainer,\n\t\t\t\t\t 'reverse': config.isPortfolio,\n\t\t\t\t\t 'grow': config.isGrowable && !config.isPortfolio}\"\n\t\t style=\"margin: 0 12px\">\n\t\t<div class=\"input\" (click)=\"toggleDropdown(false)\">\n\n\t\t\t<!-- Single Item Select -->\n\t\t\t<ng-container *ngIf=\"!config.hasMultiSelect\">\n\t\t\t\t<p *ngIf=\"!selectedItems.length\" class=\"text-placeholder\">\n\t\t\t\t\t{{config.titleConfig && config.titleConfig.placeholder ? config.titleConfig.placeholder : 'Select item...'}}\n\t\t\t\t</p>\n\t\t\t\t<p *ngIf=\"selectedItems.length\">{{getPropertyValue(selectedItems[0])}}</p>\n\t\t\t</ng-container>\n\n\t\t\t<!-- Multi Item Select -->\n\t\t\t<ng-container *ngIf=\"config.hasMultiSelect\">\n\t\t\t\t<!-- CheckList -->\n\t\t\t\t<p *ngIf=\"!selectedItems.length && !config.isPortfolio\" class=\"text-placeholder\">\n\t\t\t\t\t{{config.titleConfig && config.titleConfig.placeholder ? config.titleConfig.placeholder : 'Select items...'}}\n\t\t\t\t</p>\n\n\t\t\t\t<!-- Multi Select title -->\n\t\t\t\t<ng-container *ngIf=\"selectedItems.length && !config.hasChipGroup\">\n\t\t\t\t\t<p>{{totalSelectedItems()}}</p>\n\t\t\t\t</ng-container>\n\n\t\t\t\t<!-- Portfolio title -->\n\t\t\t\t<ng-container *ngIf=\"!selectedItems.length && config.isPortfolio\">\n\t\t\t\t\t<p>PORTFOLIOS</p>\n\t\t\t\t</ng-container>\n\n\t\t\t\t<!-- Chip Group & Portfolio -->\n\t\t\t\t<fang-chip-group *ngIf=\"config.hasChipGroup && this.selectedItems.length\"\n\t\t\t\t\t\t\t\t [data]=\"this.selectedItems\"\n\t\t\t\t\t\t\t\t [config]=\"config.chipGroupConfig\"\n\t\t\t\t\t\t\t\t (dataChange)=\"removeChip($event)\">\n\t\t\t\t</fang-chip-group>\n\t\t\t</ng-container>\n\n\t\t\t<!-- Arrow\t-->\n\t\t\t<button class=\"btn-icon grow\" (click)=\"toggleDropdown(true,$event)\">\n\t\t\t\t<i [ngClass]=\"{'ic-caret-down-sm': !isDropdownOpen, 'ic-caret-up-sm': isDropdownOpen}\"></i>\n\t\t\t</button>\n\t\t</div>\n\n\t\t<div class=\"dropdown-container\">\n\t\t\t<!-- Multi Actions -->\n\t\t\t<div class=\"dropdown-header\">\n\t\t\t\t<div class=\"dropdown-header-select\" *ngIf=\"isDropdownOpen && config.hasMultiActions && config.multiActions\">\n\t\t\t\t\t<button *ngIf=\"config.multiActions.hasClearAll\"\n\t\t\t\t\t\t\t[disabled]=\"!selectedItems.length\"\n\t\t\t\t\t\t\tclass=\"btn-secondary-sm\"\n\t\t\t\t\t\t\t(click)=\"clearAll()\">\n\t\t\t\t\t\tclearAll\n\t\t\t\t\t</button>\n\t\t\t\t\t<button [disabled]=\"!(dropdownData && dropdownData.length && ((dropdownData.length <= config.multiActions.selectLimit) || config.multiActions.selectLimit === undefined))\n\t\t\t\t\t\t\t\t\t\t|| (selectedItems.length === dropdownData.length)\"\n\t\t\t\t\t\t\tclass=\"btn-primary-sm\"\n\t\t\t\t\t\t\t(click)=\"(selectedItems.length !== dropdownData.length) && selectAll()\">\n\t\t\t\t\t\tselectAll\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\n\t\t\t\t<!-- Search field -->\n\t\t\t\t<div *ngIf=\"config.hasSearchField\"\n\t\t\t\t\t [hidden]=\"!isDropdownOpen || !dropdownData.length\"\n\t\t\t\t\t class=\"dropdown-header-search\">\n\t\t\t\t\t<fang-search [data]=\"dropdownData\"\n\t\t\t\t\t\t\t\t [config]=\"config.searchFieldConfig\"\n\t\t\t\t\t\t\t\t (filteredDataChange)=\"filteredDropdownData = $event\"\n\t\t\t\t\t\t\t\t (inputTextChange)=\"searchInputText = $event\">\n\t\t\t\t\t</fang-search>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<!-- Dropdown List\t-->\n\t\t\t<div class=\"dropdown-body\" *ngIf=\"isDropdownOpen\">\n\t\t\t\t<div *ngFor=\"let item of filteredDropdownData\"\n\t\t\t\t\t class=\"dropdown-option\"\n\t\t\t\t\t [ngClass]=\"{'select': config.hasMultiSelect && isItemSelected(item)}\"\n\t\t\t\t\t (click)=\"proceedToSelection(item,$event)\">\n\t\t\t\t\t<p>{{item}}</p>\n\t\t\t\t\t<i *ngIf=\"config.hasMultiSelect && isItemSelected(item)\" class=\"ic-check\"> </i>\n\t\t\t\t</div>\n\t\t\t\t<p *ngIf=\"!filteredDropdownData.length && searchInputText.length\" class=\"no-options\">No results found</p>\n\t\t\t</div>\n\t\t</div>\n\t</div>\n</div>\n",
changeDetection: ChangeDetectionStrategy.OnPush,
styles: [""]
},] }
];
FangDropdownComponent.propDecorators = {
data: [{ type: Input }],
config: [{ type: Input }],
selectedItemsChanged: [{ type: Output }]
};
tippy.setDefaultProps({
ignoreAttributes: true,
arrow: false,
maxWidth: '300px',
trigger: 'mouseenter',
zIndex: 99999,
});
class FangPopoverDirective {
constructor(el) {
this.el = el;
}
ngOnChanges(changes) {
if (changes['options']) {
if (this.options && !this.instance) {
this.instance = tippy(this.el.nativeElement, this.options);
}
else if (this.options && this.instance) {
this.instance.setProps(this.options);
}
else if ((!this.options || !this.options.content) && this.instance) {
this.instance.destroy();
this.instance = undefined;
}
}
if (changes['content'] && this.instance) {
this.instance.setContent(this.content);
}
}
ngOnDestroy() {
this.instance && this.instance.destroy();
}
}
FangPopoverDirective.decorators = [
{ type: Directive, args: [{ selector: '[fang-popover]' },] }
];
FangPopoverDirective.ctorParameters = () => [
{ type: ElementRef }
];
FangPopoverDirective.propDecorators = {
options: [{ type: Input, args: ['fang-popover',] }],
content: [{ type: Input, args: ['content',] }]
};
class FangPopoverModule {
}
FangPopoverModule.decorators = [
{ type: NgModule, args: [{
imports: [
CommonModule
],
exports: [
FangPopoverDirective
],
declarations: [
FangPopoverDirective
],
providers: [],
entryComponents: []
},] }
];
// @angular/core
class ClickOutsideElementDirective {
constructor(_elementRef) {
this._elementRef = _elementRef;
this.clickOutsideElement = new EventEmitter();
}
onClick(event, targetElement) {
if (!targetElement) {
return;
}
const clickedInsideElement = this._elementRef.nativeElement.contains(targetElement);
if (!clickedInsideElement) {
this.clickOutsideElement.emit(event);
}
}
}
ClickOutsideElementDirective.decorators = [
{ type: Directive, args: [{
selector: '[clickOutsideElement]'
},] }
];
ClickOutsideElementDirective.ctorParameters = () => [
{ type: ElementRef }
];
ClickOutsideElementDirective.propDecorators = {
clickOutsideElement: [{ type: Output }],
onClick: [{ type: HostListener, args: ['document:click', ['$event', '$event.target'],] }]
};
class ClickOutsideElementModule {
}
ClickOutsideElementModule.decorators = [
{ type: NgModule, args: [{
imports: [
CommonModule
],
exports: [
ClickOutsideElementDirective
],
declarations: [
ClickOutsideElementDirective
],
providers: [],
entryComponents: []
},] }
];
class FangDirectivesModule {
}
FangDirectivesModule.decorators = [
{ type: NgModule, args: [{
imports: [
CommonModule,
FangPopoverModule,
ClickOutsideElementModule
],
exports: [
FangPopoverModule,
ClickOutsideElementModule
],
declarations: [],
providers: [],
entryComponents: []
},] }
];
class FangDropdownModule {
}
FangDropdownModule.decorators = [
{ type: NgModule, args: [{
imports: [
CommonModule,
FangChipGroupModule,
FangSearchModule,
FangDirectivesModule
],
exports: [
FangDropdownComponent
],
declarations: [
FangDropdownComponent
],
providers: [],
entryComponents: [FangDropdownComponent]
},] }
];
class FangAutocompleteDropdownComponent {
constructor() {
this.onSelect = new EventEmitter();
}
selectElement(element) {
this.onSelect.emit(element);
}
}
FangAutocompleteDropdownComponent.decorators = [
{ type: Component, args: [{
selector: 'autocomplete-dropdown',
template: "<div class=\"dropdown-list\">\n\t<div *ngFor=\"let el of dropdownElements; let i=index\"\n\t\t class=\"dropdown-item\"\n\t\t (click)=\"selectElement(el)\">\n\t\t{{el}}\n\t</div>\n</div>\n",
styles: [":host{background-clip:padding-box;border:1px solid #bdbdc3;border-radius:4px;border-top:0;box-shadow:4px 4px 4px rgba(0,0,0,.12),0 1px 4px rgba(0,0,0,.24);display:block;flex-direction:column;margin:2px 0 2px 1px;overflow:hidden;z-index:9999999999}.dropdown-list,:host{background-color:#fff}.dropdown-list{flex-grow:1;height:100%;max-height:20vh;overflow-x:hidden;overflow-y:auto;position:relative;width:100%;will-change:transform,scroll-position}.dropdown-item{align-items:center;color:#333;cursor:pointer;display:flex;flex-direction:row;justify-content:space-between;padding:8px}.dropdown-item:hover{background-color:#f5f5f5}"]
},] }
];
FangAutocompleteDropdownComponent.propDecorators = {
dropdownElements: [{ type: Input }],
onSelect: [{ type: Output }]
};
class FangAutocompleteInputDirective {
constructor(element, factoryResolver, viewContainerRef, _changeDetectorRef, ngModel) {
this.element = element;
this.factoryResolver = factoryResolver;
this.viewContainerRef = viewContainerRef;
this._changeDetectorRef = _changeDetectorRef;
this.ngModel = ngModel;
this.dropdownElements$ = new ReplaySubject(1);
this.popperConfig = {
placement: 'bottom',
positionFixed: true,
modifiers: {
preventOverflow: {
enabled: true,
boundariesElement: 'window'
},
setWidth: {
enabled: true,
order: 840,
fn(data) {
data.offsets.popper.left = data.offsets.reference.left;
data.offsets.popper.right = data.offsets.reference.right;
data.offsets.popper.width = data.styles.width = Math.round(data.offsets.reference.width);
return data;
}
}
}
};
}
set dropdownElements(dropdownElements) {
this.dropdownElements$.next(dropdownElements || []);
}
;
ngOnInit() {
fromEvent(document, "click", { passive: true }).pipe(filter(() => !!this.componentRef && this.componentRef.location.nativeElement.style.display !== 'none'))
.subscribe((e) => {
if (!this.element.nativeElement.contains(e.target)) {
this.componentRef.location.nativeElement.style.display = 'none';
}
});
this._changeDetectorRef.detectChanges();
}
ngAfterContentInit() {
if (this.ngModel) {
this.input = this.ngModel.control;
this.autocompleteSubscription =
combineLatest(this.dropdownElements$.asObservable(), fromEvent(this.element.nativeElement, "focus", { passive: true }), fromEvent(this.element.nativeElement, "keyup", { passive: true }))
.subscribe(([arr, input, input2]) => {
console.log(arr, input, input2);
if (!this.componentRef) {
const factory = this.factoryResolver.resolveComponentFactory(FangAutocompleteDropdownComponent);
this.componentRef = this.viewContainerRef.createComponent(factory);
this.componentRef.location.nativeElement.style.display = 'none';
this.dropdownPopper = new Popper(this.element.nativeElement, this.componentRef.location.nativeElement, this.popperConfig);
this.inputChangesSubscription = this.componentRef.instance.onSelect.subscribe(v => {
this.input.setValue(v);
});
}
const inputValue = input.target.value;
const lowerCaseInput = inputValue && inputValue.toLocaleLowerCase();
const array = arr.slice().filter(e => e.toLowerCase().startsWith(lowerCaseInput));
const lowerCaseArray = arr.slice().map(a => a.toLowerCase()).filter(e => e.startsWith(lowerCaseInput));
if (inputValue && inputValue.length > 0 && (lowerCaseArray.length > 1 || !lowerCaseArray.includes(lowerCaseInput))) {
this.componentRef.location.nativeElement.style.display = 'block';
this.componentRef.instance.dropdownElements = array;
this.componentRef.changeDetectorRef.detectChanges();
this.dropdownPopper.scheduleUpdate();
}
else {
this.componentRef.location.nativeElement.style.display = 'none';
}
});
}
this._changeDetectorRef.detectChanges();
}
ngOnDestroy() {
this.dropdownPopper && this.dropdownPopper.destroy();
this.autocompleteSubscription && this.autocompleteSubscription.unsubscribe();
this.inputChangesSubscription && this.inputChangesSubscription.unsubscribe();
}
}
FangAutocompleteInputDirective.decorators = [
{ type: Directive, args: [{ selector: '[autoComplete][ngModel]' },] }
];
FangAutocompleteInputDirective.ctorParameters = () => [
{ type: ElementRef },
{ type: ComponentFactoryResolver },
{ type: ViewContainerRef },
{ type: ChangeDetectorRef },
{ type: NgModel }
];
FangAutocompleteInputDirective.propDecorators = {
dropdownElements: [{ type: Input, args: ['autoComplete',] }]
};
class FangAutocompleteModule {
}
FangAutocompleteModule.decorators = [
{ type: NgModule, args: [{
imports: [
CommonModule,
FormsModule
],
exports: [
FangAutocompleteInputDirective
],
declarations: [
FangAutocompleteDropdownComponent,
FangAutocompleteInputDirective
],
providers: [],
entryComponents: [FangAutocompleteDropdownComponent]
},] }
];
/*
* Public API Surface of fang-ui-components
*/
/**
* Generated bundle index. Do not edit.
*/
export { FangAutocompleteModule, FangChipGroupComponent, FangChipGroupModule, FangDropdownComponent, FangDropdownModule, FangMultiTabsComponent, FangMultiTabsModule, FangSearchComponent, FangSearchModule, FangTabComponent, FangViewportAutoResizeDirective, FangVirtualScrollingModule, FangDirectivesModule as ɵa, FangPopoverModule as ɵb, FangPopoverDirective as ɵc, ClickOutsideElementModule as ɵd, ClickOutsideElementDirective as ɵe, FangAutocompleteInputDirective as ɵf, FangAutocompleteDropdownComponent as ɵg };
//# sourceMappingURL=inaccess-fang-ui-components.js.map