@energycap/components 0.39.17-ECAP-25250-eclipse-formula-builder-proto.20240530-1020 → 0.39.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/energycap-components.min.css +1 -1
- package/esm2020/lib/controls/combobox/combobox.component.mjs +38 -40
- package/esm2020/lib/controls/form-control/form-control.component.mjs +2 -2
- package/esm2020/lib/controls/menu/menu.component.mjs +73 -40
- package/fesm2015/energycap-components.mjs +1034 -1003
- package/fesm2015/energycap-components.mjs.map +1 -1
- package/fesm2020/energycap-components.mjs +1023 -993
- package/fesm2020/energycap-components.mjs.map +1 -1
- package/lib/controls/combobox/combobox.component.d.ts +5 -0
- package/lib/controls/menu/menu.component.d.ts +26 -11
- package/package.json +1 -1
- package/src/styles/_global-variables.scss +1 -1
- package/src/styles/mixins/_menu-base.scss +0 -146
@@ -1488,218 +1488,245 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImpor
|
|
1488
1488
|
}] } });
|
1489
1489
|
|
1490
1490
|
/**
|
1491
|
-
*
|
1492
|
-
*
|
1493
|
-
* @export
|
1491
|
+
* Service to help with interfacing with the window object
|
1492
|
+
* and navigating around the application (going outside of the Angular 2+ router)
|
1494
1493
|
*/
|
1495
|
-
class
|
1494
|
+
class WindowService {
|
1496
1495
|
/**
|
1497
|
-
*
|
1498
|
-
*
|
1499
|
-
*
|
1500
|
-
*
|
1501
|
-
*
|
1496
|
+
* Tracks if there are any unsaved changes that the user could lose.
|
1497
|
+
*
|
1498
|
+
* It is set up as `get` only because it is set with `addNavigateAwayPrompt`.
|
1499
|
+
*
|
1500
|
+
* This also includes adding a prompt to the window itself (in addition to
|
1501
|
+
* working with the `CanDeactivateUnsavedChanges` guard) to cover page reloads
|
1502
|
+
* which do not trigger router events.
|
1502
1503
|
*/
|
1503
|
-
|
1504
|
-
this.
|
1505
|
-
this.viewContainer = viewContainer;
|
1506
|
-
this.document = document;
|
1507
|
-
this.renderer = renderer;
|
1508
|
-
/**
|
1509
|
-
* Emit the {@link PopupStatus} when it changes
|
1510
|
-
*/
|
1511
|
-
this.popperStatusChange = new EventEmitter();
|
1504
|
+
get hasUnsavedChanges() {
|
1505
|
+
return this._hasUnsavedChanges;
|
1512
1506
|
}
|
1513
1507
|
/**
|
1514
|
-
*
|
1515
|
-
*
|
1508
|
+
* Expose the innerWidth on the window global. Protects against errors when code
|
1509
|
+
* is running on a non-browser platform.
|
1516
1510
|
*/
|
1517
|
-
|
1518
|
-
|
1511
|
+
get innerWidth() {
|
1512
|
+
return window ? window.innerWidth : undefined;
|
1519
1513
|
}
|
1520
|
-
|
1521
|
-
|
1522
|
-
|
1523
|
-
|
1524
|
-
|
1525
|
-
|
1514
|
+
constructor(router, activatedRoute) {
|
1515
|
+
this.router = router;
|
1516
|
+
this.activatedRoute = activatedRoute;
|
1517
|
+
this._hasUnsavedChanges = false;
|
1518
|
+
/**
|
1519
|
+
* Function called when the window `beforeunload` event is fired.
|
1520
|
+
*
|
1521
|
+
* A reference to the function that was passed to `window.addEventListener`
|
1522
|
+
* must be retained for `window.removeEventListener` to function properly.
|
1523
|
+
*
|
1524
|
+
* Some browsers require the event's `returnValue` to be set to show the confirmation
|
1525
|
+
* dialog.
|
1526
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event
|
1527
|
+
*/
|
1528
|
+
this.beforeUnloadFunction = (event) => {
|
1529
|
+
// Cancel the event as stated by the standard.
|
1530
|
+
event.preventDefault();
|
1531
|
+
// Chrome requires returnValue to be set.
|
1532
|
+
event.returnValue = '';
|
1533
|
+
};
|
1534
|
+
if (window) {
|
1535
|
+
this.resized = fromEvent(window, 'resize');
|
1536
|
+
}
|
1526
1537
|
}
|
1527
1538
|
/**
|
1528
|
-
*
|
1529
|
-
*
|
1530
|
-
* @memberof PopupContainerDirective
|
1539
|
+
* Navigates to the previous page the user had visited
|
1531
1540
|
*/
|
1532
|
-
|
1533
|
-
|
1534
|
-
if (PopupContainerDirective.GlobalPopupRef != this) {
|
1535
|
-
PopupContainerDirective.GlobalPopupRef.hide();
|
1536
|
-
PopupContainerDirective.GlobalPopupRef = undefined;
|
1537
|
-
}
|
1538
|
-
}
|
1539
|
-
if (!this.globalCloseSubscription) {
|
1540
|
-
this.globalCloseSubscription = fromEvent(this.document.body, "click").subscribe((event) => {
|
1541
|
-
this.hide();
|
1542
|
-
});
|
1543
|
-
}
|
1544
|
-
if (!this.popperRef) {
|
1545
|
-
// Add the popper template as an embedded view since PopperJS
|
1546
|
-
// manipulates DOM elements.
|
1547
|
-
this.popupViewRef = this.viewContainer.createEmbeddedView(this.popup);
|
1548
|
-
// Since popper needs real DOM elements, grab the first non-comment
|
1549
|
-
// DOM element to use as our anchor.
|
1550
|
-
let anchorElement = this.popupViewRef.rootNodes.find(elem => { return elem.nodeName !== "#text"; });
|
1551
|
-
// Use the parents elements as our DOM elements to Popper
|
1552
|
-
this.popperRef = new Popper(this.templateViewRef.rootNodes[0], anchorElement, this.popperOptions);
|
1553
|
-
PopupContainerDirective.GlobalPopupRef = this;
|
1554
|
-
this.popperStatusChange.emit('visible');
|
1555
|
-
}
|
1541
|
+
goBack() {
|
1542
|
+
window.history.back();
|
1556
1543
|
}
|
1557
|
-
/**
|
1558
|
-
*
|
1559
|
-
*
|
1560
|
-
* @memberof PopupContainerDirective
|
1544
|
+
/**An abstraction around the browsers window history length.
|
1545
|
+
* Returns zero if unable to access or running outside a browser context
|
1561
1546
|
*/
|
1562
|
-
|
1563
|
-
|
1564
|
-
|
1565
|
-
this.globalCloseSubscription = undefined;
|
1566
|
-
}
|
1567
|
-
if (this.popperRef && this.popupViewRef) {
|
1568
|
-
this.popupViewRef.destroy();
|
1569
|
-
this.popperRef.destroy();
|
1570
|
-
this.popperRef = undefined;
|
1571
|
-
this.popperStatusChange.emit('hidden');
|
1572
|
-
}
|
1547
|
+
getHistoryLength() {
|
1548
|
+
var _a;
|
1549
|
+
return ((_a = window === null || window === void 0 ? void 0 : window.history) === null || _a === void 0 ? void 0 : _a.length) || 0;
|
1573
1550
|
}
|
1574
1551
|
/**
|
1575
|
-
*
|
1552
|
+
* Navigate to any url you know the path to
|
1553
|
+
* @param url The URL to navigate to
|
1554
|
+
*
|
1555
|
+
* @deprecated For legacy support only; use `router.navigateByUrl` instead
|
1576
1556
|
*/
|
1577
|
-
|
1578
|
-
|
1579
|
-
|
1580
|
-
|
1581
|
-
|
1582
|
-
fixPosition(minWidthNone, appendToBody = false) {
|
1583
|
-
if (this.popperRef && this.popperRef['reference'] && this.popperRef['popper']) {
|
1584
|
-
let popupEl = this.popperRef['popper'];
|
1585
|
-
// Reset width style previously assigned because the content may have
|
1586
|
-
// changed and the auto width would be different
|
1587
|
-
this.renderer.removeStyle(popupEl, 'width');
|
1588
|
-
this.renderer.setStyle(popupEl, 'position', 'fixed');
|
1589
|
-
if (appendToBody) {
|
1590
|
-
const bodyEl = this.document.querySelector('body');
|
1591
|
-
const popupParent = this.renderer.parentNode(popupEl);
|
1592
|
-
if (popupParent !== bodyEl) {
|
1593
|
-
this.renderer.appendChild(bodyEl, popupEl);
|
1594
|
-
}
|
1595
|
-
}
|
1596
|
-
let toggleEl = this.popperRef['reference'];
|
1597
|
-
let width = popupEl.offsetWidth;
|
1598
|
-
let boundaries = popupEl.getBoundingClientRect();
|
1599
|
-
let left = boundaries.left;
|
1600
|
-
let coords = toggleEl.getBoundingClientRect();
|
1601
|
-
// Set the top of our menu to the bottom of the toggle element
|
1602
|
-
let top = coords.bottom;
|
1603
|
-
if (this.popperOptions && this.popperOptions.placement) {
|
1604
|
-
if (this.popperOptions.placement === 'bottom-start' || this.popperOptions.placement === 'top-start') {
|
1605
|
-
left = coords.left;
|
1557
|
+
navigateToUrl(url) {
|
1558
|
+
return __awaiter(this, void 0, void 0, function* () {
|
1559
|
+
try {
|
1560
|
+
if (url.indexOf('/app/') === 0) {
|
1561
|
+
yield this.router.navigateByUrl(url.substring(5));
|
1606
1562
|
}
|
1607
1563
|
else {
|
1608
|
-
|
1564
|
+
yield this.router.navigateByUrl(url);
|
1609
1565
|
}
|
1610
1566
|
}
|
1611
|
-
|
1612
|
-
|
1613
|
-
|
1614
|
-
|
1615
|
-
|
1616
|
-
this.renderer.setStyle(popupEl, 'left', left + 'px');
|
1617
|
-
this.renderer.setStyle(popupEl, 'top', top + 'px');
|
1618
|
-
this.renderer.setStyle(popupEl, 'width', width + 'px');
|
1619
|
-
if (!minWidthNone) {
|
1620
|
-
this.renderer.setStyle(popupEl, 'min-width', coords.width + 'px');
|
1567
|
+
catch (e) {
|
1568
|
+
// If the router throws we will try to navigate to the fully qualified url as a last ditch effort.
|
1569
|
+
// This can happen if we missed a link that needs to be converted to ng5 or our ng1Href directive
|
1570
|
+
// didn't handle a link correctly
|
1571
|
+
window.location.href = url;
|
1621
1572
|
}
|
1622
|
-
}
|
1573
|
+
});
|
1623
1574
|
}
|
1624
|
-
}
|
1625
|
-
/**
|
1626
|
-
* Global reference to the currently displayed popup; only
|
1627
|
-
* one popup directive can be in `show` state at a given time.
|
1628
|
-
*
|
1629
|
-
* @memberof PopupContainerDirective
|
1630
|
-
*/
|
1631
|
-
PopupContainerDirective.GlobalPopupRef = undefined;
|
1632
|
-
PopupContainerDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: PopupContainerDirective, deps: [{ token: i0.TemplateRef }, { token: i0.ViewContainerRef }, { token: DOCUMENT }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive });
|
1633
|
-
PopupContainerDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.9", type: PopupContainerDirective, selector: "[ecPopup]", inputs: { popup: ["ecPopup", "popup"], popperOptions: ["options", "popperOptions"] }, ngImport: i0 });
|
1634
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: PopupContainerDirective, decorators: [{
|
1635
|
-
type: Directive,
|
1636
|
-
args: [{ selector: '[ecPopup]' }]
|
1637
|
-
}], ctorParameters: function () {
|
1638
|
-
return [{ type: i0.TemplateRef }, { type: i0.ViewContainerRef }, { type: undefined, decorators: [{
|
1639
|
-
type: Inject,
|
1640
|
-
args: [DOCUMENT]
|
1641
|
-
}] }, { type: i0.Renderer2 }];
|
1642
|
-
}, propDecorators: { popup: [{
|
1643
|
-
type: Input,
|
1644
|
-
args: ['ecPopup']
|
1645
|
-
}], popperOptions: [{
|
1646
|
-
type: Input,
|
1647
|
-
args: ['options']
|
1648
|
-
}] } });
|
1649
|
-
|
1650
|
-
class ScrollService {
|
1651
|
-
constructor() { }
|
1652
1575
|
/**
|
1653
|
-
*
|
1654
|
-
*
|
1655
|
-
*
|
1656
|
-
* @param scrollContainerSelector A valid CSS selector string for the scroll container.
|
1657
|
-
* @param targetElementSelector A valid CSS selector string for the target element.
|
1658
|
-
* @param topPadding The amount of space to leave above the target
|
1659
|
-
* to keep it from being pinned to the top of the scrollContainer. Defaults
|
1660
|
-
* to 32px, the default height of a menu item.
|
1576
|
+
* Adds a `beforeunload` function to the window to alert the user that there are about to leave
|
1577
|
+
* the current page and ask if they'd like to leave or stay
|
1661
1578
|
*/
|
1662
|
-
|
1663
|
-
|
1664
|
-
|
1665
|
-
return;
|
1666
|
-
}
|
1667
|
-
let targetElement = scrollContainer.querySelector(targetElementSelector);
|
1668
|
-
if (!targetElement) {
|
1669
|
-
return;
|
1670
|
-
}
|
1671
|
-
let targetRect = targetElement.getBoundingClientRect();
|
1672
|
-
let containerRect = scrollContainer.getBoundingClientRect();
|
1673
|
-
// Only scroll if the target is outside of the view bounds of the container
|
1674
|
-
if (targetRect.bottom > containerRect.bottom || targetRect.top < containerRect.top) {
|
1675
|
-
scrollContainer.scrollTop =
|
1676
|
-
(targetRect.top - containerRect.top) + scrollContainer.scrollTop - topPadding;
|
1677
|
-
}
|
1579
|
+
addNavigateAwayPrompt() {
|
1580
|
+
this._hasUnsavedChanges = true;
|
1581
|
+
window.addEventListener("beforeunload", this.beforeUnloadFunction);
|
1678
1582
|
}
|
1679
1583
|
/**
|
1680
|
-
*
|
1681
|
-
* @param scrollContainerSelector A valid CSS selector
|
1584
|
+
* Removes the `beforeunload` function added to the window
|
1682
1585
|
*/
|
1683
|
-
|
1684
|
-
|
1685
|
-
|
1686
|
-
return scrollContainer.scrollTop;
|
1687
|
-
}
|
1688
|
-
else {
|
1689
|
-
console.error(`Scroll container '${scrollContainerSelector}' does not exist.`);
|
1690
|
-
return 0;
|
1691
|
-
}
|
1586
|
+
removeNavigateAwayPrompt() {
|
1587
|
+
this._hasUnsavedChanges = false;
|
1588
|
+
window.removeEventListener("beforeunload", this.beforeUnloadFunction);
|
1692
1589
|
}
|
1693
1590
|
/**
|
1694
|
-
*
|
1695
|
-
*
|
1696
|
-
*
|
1697
|
-
|
1698
|
-
|
1699
|
-
|
1700
|
-
|
1701
|
-
|
1702
|
-
|
1591
|
+
* Send data to another window.
|
1592
|
+
*
|
1593
|
+
* __SECURITY RISK__ - Always use a specific target origin. Failing to provide a specific target origin can allow
|
1594
|
+
* malicious sites to receive the message.
|
1595
|
+
*
|
1596
|
+
* @param targetWindow - Window to send the message to
|
1597
|
+
* @param message - Data to send
|
1598
|
+
* @param targetOrigin - What the URI of the target window must be for the message to be sent.
|
1599
|
+
* If sending data to another EnergyCAP window, this should always be `window.location.origin` to ensure
|
1600
|
+
* that only instances of EnergyCAP app receive the message.
|
1601
|
+
*/
|
1602
|
+
postMessage(targetWindow, message, targetOrigin) {
|
1603
|
+
targetWindow.postMessage(message, targetOrigin);
|
1604
|
+
}
|
1605
|
+
/**
|
1606
|
+
* Open a new window
|
1607
|
+
* @param url - The URL of the resource to be loaded
|
1608
|
+
*/
|
1609
|
+
openNew(url) {
|
1610
|
+
window.open(url, '_blank');
|
1611
|
+
}
|
1612
|
+
/**
|
1613
|
+
* A wrapper around the router for changing the query params for the current url
|
1614
|
+
* without creating a new history entry or removing any existing query parameters.
|
1615
|
+
* The provided params are updated if they already exist or added to the url if they don't
|
1616
|
+
*
|
1617
|
+
* @returns a promise that resolves to true if the navigation succeeds, false if something (like a guard) blocks it.
|
1618
|
+
* In normal use, the navigation should succeed unless we use query params to block access to a route the user is already on
|
1619
|
+
*/
|
1620
|
+
modifyHistoryQueryParamsSubset(queryParams) {
|
1621
|
+
return __awaiter(this, void 0, void 0, function* () {
|
1622
|
+
return this.router.navigate([], {
|
1623
|
+
relativeTo: this.activatedRoute,
|
1624
|
+
replaceUrl: true,
|
1625
|
+
queryParams: queryParams,
|
1626
|
+
queryParamsHandling: 'merge',
|
1627
|
+
});
|
1628
|
+
});
|
1629
|
+
}
|
1630
|
+
/**A wrapper around the default javascript confirm dialog to allow us to unit test dependent code.
|
1631
|
+
* Of course eventually we'd like to have pretty confirmations for everything, but in some cases it wasn't worth the extra time
|
1632
|
+
* so we're using this instead.
|
1633
|
+
*/
|
1634
|
+
confirm(prompt) {
|
1635
|
+
return Promise.resolve(confirm(prompt));
|
1636
|
+
}
|
1637
|
+
/**
|
1638
|
+
* Close the current window or a window instance if one is provided
|
1639
|
+
* @param windowInstance - Window to close (optional)
|
1640
|
+
*/
|
1641
|
+
closeWindow(windowInstance) {
|
1642
|
+
if (windowInstance) {
|
1643
|
+
windowInstance.close();
|
1644
|
+
}
|
1645
|
+
else {
|
1646
|
+
window.close();
|
1647
|
+
}
|
1648
|
+
}
|
1649
|
+
getLocation() {
|
1650
|
+
return window.location.pathname + window.location.hash;
|
1651
|
+
}
|
1652
|
+
/** Get the current value of the full url, including protocol, host and path */
|
1653
|
+
getFullUrl() {
|
1654
|
+
return window.location.href;
|
1655
|
+
}
|
1656
|
+
/** Get the current value of the base url, including protocol, domain and port (if explicitly specified) */
|
1657
|
+
getBaseUrl() {
|
1658
|
+
return window.location.origin;
|
1659
|
+
}
|
1660
|
+
/**
|
1661
|
+
* Reloads the browser window.
|
1662
|
+
* NOT RECOMMENDED. Seek other options for reloading content within Angular before resorting to this.
|
1663
|
+
*/
|
1664
|
+
reloadWindow() {
|
1665
|
+
window.location.reload();
|
1666
|
+
}
|
1667
|
+
}
|
1668
|
+
WindowService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: WindowService, deps: [{ token: i1$2.Router }, { token: i1$2.ActivatedRoute }], target: i0.ɵɵFactoryTarget.Injectable });
|
1669
|
+
WindowService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: WindowService, providedIn: 'root' });
|
1670
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: WindowService, decorators: [{
|
1671
|
+
type: Injectable,
|
1672
|
+
args: [{
|
1673
|
+
providedIn: 'root'
|
1674
|
+
}]
|
1675
|
+
}], ctorParameters: function () { return [{ type: i1$2.Router }, { type: i1$2.ActivatedRoute }]; } });
|
1676
|
+
|
1677
|
+
class ScrollService {
|
1678
|
+
constructor() { }
|
1679
|
+
/**
|
1680
|
+
* Given a container and the target element to scroll to, we will set the scroll top on
|
1681
|
+
* the container to bring the target into view.
|
1682
|
+
*
|
1683
|
+
* @param scrollContainerSelector A valid CSS selector string for the scroll container.
|
1684
|
+
* @param targetElementSelector A valid CSS selector string for the target element.
|
1685
|
+
* @param topPadding The amount of space to leave above the target
|
1686
|
+
* to keep it from being pinned to the top of the scrollContainer. Defaults
|
1687
|
+
* to 32px, the default height of a menu item.
|
1688
|
+
*/
|
1689
|
+
scrollToItem(scrollContainerSelector, targetElementSelector, topPadding = 32) {
|
1690
|
+
let scrollContainer = document.querySelector(scrollContainerSelector);
|
1691
|
+
if (!scrollContainer) {
|
1692
|
+
return;
|
1693
|
+
}
|
1694
|
+
let targetElement = scrollContainer.querySelector(targetElementSelector);
|
1695
|
+
if (!targetElement) {
|
1696
|
+
return;
|
1697
|
+
}
|
1698
|
+
let targetRect = targetElement.getBoundingClientRect();
|
1699
|
+
let containerRect = scrollContainer.getBoundingClientRect();
|
1700
|
+
// Only scroll if the target is outside of the view bounds of the container
|
1701
|
+
if (targetRect.bottom > containerRect.bottom || targetRect.top < containerRect.top) {
|
1702
|
+
scrollContainer.scrollTop =
|
1703
|
+
(targetRect.top - containerRect.top) + scrollContainer.scrollTop - topPadding;
|
1704
|
+
}
|
1705
|
+
}
|
1706
|
+
/**
|
1707
|
+
* Return the value of the scrollTop property for an HTMLElement that matches the selector
|
1708
|
+
* @param scrollContainerSelector A valid CSS selector
|
1709
|
+
*/
|
1710
|
+
getCurrentScrollPosition(scrollContainerSelector) {
|
1711
|
+
let scrollContainer = document.querySelector(scrollContainerSelector);
|
1712
|
+
if (scrollContainer) {
|
1713
|
+
return scrollContainer.scrollTop;
|
1714
|
+
}
|
1715
|
+
else {
|
1716
|
+
console.error(`Scroll container '${scrollContainerSelector}' does not exist.`);
|
1717
|
+
return 0;
|
1718
|
+
}
|
1719
|
+
}
|
1720
|
+
/**
|
1721
|
+
* Set the scrollTop of an HTMLElement that matches the selector to a specific position
|
1722
|
+
* @param scrollContainerSelector A valid CSS selector
|
1723
|
+
* @param position
|
1724
|
+
*/
|
1725
|
+
scrollToPosition(scrollContainerSelector, position) {
|
1726
|
+
let scrollContainer = document.querySelector(scrollContainerSelector);
|
1727
|
+
if (scrollContainer) {
|
1728
|
+
scrollContainer.scrollTop = position;
|
1729
|
+
}
|
1703
1730
|
else {
|
1704
1731
|
console.error(`Scroll container '${scrollContainerSelector}' does not exist.`);
|
1705
1732
|
}
|
@@ -1734,929 +1761,935 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImpor
|
|
1734
1761
|
}]
|
1735
1762
|
}], ctorParameters: function () { return []; } });
|
1736
1763
|
|
1737
|
-
|
1738
|
-
const textboxValidation = (validatorParams) => {
|
1739
|
-
return (control) => {
|
1740
|
-
let validators = [];
|
1741
|
-
// Innocent until proven guilty
|
1742
|
-
validatorParams.valid = true;
|
1743
|
-
if (validatorParams.required) {
|
1744
|
-
validators.push(Validators.required);
|
1745
|
-
}
|
1746
|
-
if (validatorParams.minLength !== undefined) {
|
1747
|
-
validators.push(Validators.minLength(validatorParams.minLength));
|
1748
|
-
}
|
1749
|
-
if (validatorParams.maxLength !== undefined) {
|
1750
|
-
validators.push(Validators.maxLength(validatorParams.maxLength));
|
1751
|
-
}
|
1752
|
-
if (validatorParams.pattern !== undefined) {
|
1753
|
-
validators.push(Validators.pattern(validatorParams.pattern));
|
1754
|
-
}
|
1755
|
-
validators.forEach(validator => {
|
1756
|
-
let validationResult = validator(control);
|
1757
|
-
if (validationResult) {
|
1758
|
-
validatorParams.valid = false;
|
1759
|
-
}
|
1760
|
-
});
|
1761
|
-
if (validatorParams.valid) {
|
1762
|
-
return null;
|
1763
|
-
}
|
1764
|
-
else {
|
1765
|
-
return {
|
1766
|
-
textbox: validatorParams
|
1767
|
-
};
|
1768
|
-
}
|
1769
|
-
};
|
1770
|
-
};
|
1771
|
-
const phoneNumberValidationPattern = '^\\s*(?:\\+?(\\d{1,3}))?[-. (]*(\\d{3})[-. )]*(\\d{3})[-. ]*(\\d{4})(?: *x(\\d+))?\\s*$';
|
1772
|
-
const urlValidationPattern = '([A-Za-z])+(:\/\/)+[^\\s]*';
|
1773
|
-
class TextboxComponent extends FormControlBase {
|
1774
|
-
constructor(validationMessageService, formGroupHelper, translate) {
|
1775
|
-
super(validationMessageService, formGroupHelper);
|
1776
|
-
this.validationMessageService = validationMessageService;
|
1777
|
-
this.formGroupHelper = formGroupHelper;
|
1778
|
-
this.translate = translate;
|
1779
|
-
/**
|
1780
|
-
* Set the value of the input's autocomplete attribute
|
1781
|
-
*/
|
1782
|
-
this.autocomplete = 'off';
|
1783
|
-
/**
|
1784
|
-
* The textbox type
|
1785
|
-
*/
|
1786
|
-
this.type = "text";
|
1787
|
-
/**
|
1788
|
-
* The value of the rows attribute for a textarea. Only applies to multi-line type
|
1789
|
-
*/
|
1790
|
-
this.rows = 3;
|
1791
|
-
/**
|
1792
|
-
* If set to true, we will select all text within the input if
|
1793
|
-
* autofocus is also set to true
|
1794
|
-
*/
|
1795
|
-
this.selectOnAutofocus = false;
|
1796
|
-
/**
|
1797
|
-
* If set to true, we will upper case on focus out
|
1798
|
-
*/
|
1799
|
-
this.upperCase = false;
|
1800
|
-
/**
|
1801
|
-
* Validation pattern for the input. This is determined on the input type specified
|
1802
|
-
*/
|
1803
|
-
this.validationPattern = '';
|
1804
|
-
}
|
1805
|
-
ngOnChanges(changes) {
|
1806
|
-
super.ngOnChanges(changes);
|
1807
|
-
}
|
1764
|
+
class NavItemActiveDirective {
|
1808
1765
|
/**
|
1809
|
-
*
|
1766
|
+
* Determines whether the directive will try to make an exact match on the url or not
|
1767
|
+
* If false, the directive will add the active class if the first part of the url matches
|
1768
|
+
* the active route.
|
1769
|
+
* see: https://angular.io/api/router/Router#isactive
|
1810
1770
|
*/
|
1811
|
-
|
1812
|
-
|
1813
|
-
|
1814
|
-
if (this.type === 'tel') {
|
1815
|
-
this.validationPattern = phoneNumberValidationPattern;
|
1816
|
-
}
|
1817
|
-
else if (this.type === 'url') {
|
1818
|
-
this.validationPattern = urlValidationPattern;
|
1771
|
+
set exact(value) {
|
1772
|
+
if (value === undefined) {
|
1773
|
+
this._exact = true;
|
1819
1774
|
}
|
1820
|
-
|
1821
|
-
this.
|
1822
|
-
.subscribe((translated) => {
|
1823
|
-
this.placeholder = translated;
|
1824
|
-
});
|
1775
|
+
else {
|
1776
|
+
this._exact = value;
|
1825
1777
|
}
|
1778
|
+
this.update();
|
1826
1779
|
}
|
1827
1780
|
/**
|
1828
|
-
* The
|
1781
|
+
* The url of the NavItem to check for activeness. Convert the item url into a
|
1782
|
+
* UrlTree relative to the ActivatedRoute so router#isActive works even with relative urls.
|
1783
|
+
* See Angular's [routerLink](https://github.com/angular/angular/blob/8282e15c2becbe42a49befa07d6407247e8243d8/packages/router/src/directives/router_link.ts#L249)
|
1784
|
+
* and [routerLinkActive](https://github.com/angular/angular/blob/8282e15c2becbe42a49befa07d6407247e8243d8/packages/router/src/directives/router_link_active.ts#L139)
|
1785
|
+
* for a similiar implementation.
|
1829
1786
|
*/
|
1830
|
-
|
1831
|
-
if (
|
1832
|
-
this.
|
1787
|
+
set url(value) {
|
1788
|
+
if (value !== null && value !== undefined) {
|
1789
|
+
this._url = this.router.createUrlTree([value], { relativeTo: this.route, queryParams: this.queryParams });
|
1790
|
+
this.update();
|
1833
1791
|
}
|
1834
1792
|
}
|
1835
|
-
|
1836
|
-
|
1837
|
-
|
1838
|
-
|
1839
|
-
|
1840
|
-
|
1841
|
-
|
1842
|
-
|
1843
|
-
|
1844
|
-
|
1845
|
-
}
|
1846
|
-
/**
|
1847
|
-
* Focus out event handler
|
1848
|
-
* will upper case and trim value if upperCase is true (this is what we do on the apis)
|
1849
|
-
*/
|
1850
|
-
focusOutEvent() {
|
1851
|
-
if (this.upperCase && this.formModel.value) {
|
1852
|
-
this.formModel.setValue(this.formModel.value.toUpperCase().trim());
|
1853
|
-
}
|
1854
|
-
}
|
1855
|
-
}
|
1856
|
-
TextboxComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: TextboxComponent, deps: [{ token: ValidationMessageService }, { token: FormGroupHelper }, { token: i2.TranslateService }], target: i0.ɵɵFactoryTarget.Component });
|
1857
|
-
TextboxComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.9", type: TextboxComponent, selector: "ec-textbox", inputs: { autocomplete: "autocomplete", type: "type", placeholder: "placeholder", maxlength: "maxlength", minlength: "minlength", rows: "rows", selectOnAutofocus: "selectOnAutofocus", upperCase: "upperCase" }, viewQueries: [{ propertyName: "inputElement", first: true, predicate: ["textboxInput"], descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div class=\"control control-label-{{labelPosition}}\"\r\n [ngClass]=\"{'is-readonly': readonly}\">\r\n\r\n <label *ngIf=\"label\">\r\n <span>{{label | translate}}</span>\r\n <span *ngIf=\"validationErrors.length > 0 && formModel.touched && formModel.invalid\"> {{validationErrors |\r\n translate}}</span>\r\n <ec-help-popover id=\"{{id}}_helpPopover\"\r\n *ngIf=\"helpPopover\"\r\n class=\"d-inline-block my-n3 mx-n1\"\r\n text=\"{{helpPopover | translate}}\"\r\n contentPosition=\"{{helpPopoverPosition}}\">\r\n </ec-help-popover>\r\n </label>\r\n\r\n <div class=\"input-wrapper control-input\">\r\n <input *ngIf=\"type !== 'multi_line'\"\r\n #textboxInput\r\n email=\"{{type === 'email' ? true : false}}\"\r\n pattern=\"{{validationPattern}}\"\r\n type=\"{{type}}\"\r\n tabindex=\"{{tabindex}}\"\r\n title=\"{{tooltip}}\"\r\n [attr.id]=\"inputId\"\r\n [attr.autocomplete]=\"autocomplete\"\r\n [attr.placeholder]=\"placeholder\"\r\n [attr.maxlength]=\"maxlength\"\r\n [attr.minlength]=\"minlength\"\r\n [attr.required]=\"required ? required : null\"\r\n [formControl]=\"formModel\"\r\n [ngClass]=\"{'is-empty': !formModel?.value, 'is-pending': pending, 'is-uppercase': upperCase}\"\r\n (focusout)=\"focusOutEvent()\"\r\n [attr.cdkFocusInitial]=\"autofocus || null\">\r\n\r\n <textarea *ngIf=\"type === 'multi_line'\"\r\n [attr.rows]=\"rows\"\r\n #textboxInput\r\n tabindex=\"{{tabindex}}\"\r\n [attr.id]=\"inputId\"\r\n [attr.placeholder]=\"placeholder\"\r\n [attr.maxlength]=\"maxlength\"\r\n [attr.minlength]=\"minlength\"\r\n [attr.required]=\"required ? required : null\"\r\n [formControl]=\"formModel\"\r\n [ngClass]=\"{'is-empty': formModel?.value === '', 'is-pending': pending}\"\r\n [attr.cdkFocusInitial]=\"autofocus || null\">\r\n </textarea>\r\n\r\n <i class=\"ec-icon icon-required\"></i>\r\n <i class=\"ec-icon icon-invalid\"></i>\r\n <i class=\"ec-icon icon-loading\"></i>\r\n </div>\r\n</div>", styles: [":host{color:var(--ec-form-control-color);font-size:var(--ec-form-control-font-size);display:block;margin-bottom:1rem;width:100%}:host :host-context(.form-condensed){margin-bottom:.5rem}:host .control{width:100%;display:flex;flex-direction:column}:host .control.control-label-bottom{flex-direction:column-reverse}:host .control.control-label-left{flex-direction:row}:host .control.control-label-left label{margin-right:.25rem}:host .control.control-label-right{flex-direction:row-reverse}:host .control.control-label-right label{margin-left:.25rem}:host .control.control-label-left,:host .control.control-label-right{align-items:center}:host .control.control-label-left label,:host .control.control-label-right label{flex:1 1;margin-top:0;margin-bottom:0}:host .control.control-label-left .control-input,:host .control.control-label-right .control-input{flex:2 2}:host .control.is-readonly input,:host .control.is-readonly select,:host .control.is-readonly textarea{border-color:var(--ec-form-control-border-color-readonly);background-color:var(--ec-form-control-background-color-readonly);background-clip:border-box;background-image:none;color:var(--ec-form-control-color-readonly);opacity:1;-webkit-user-select:none;user-select:none;pointer-events:none;overflow:hidden;white-space:nowrap}:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-invalid,:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-valid{background-color:var(--ec-form-control-background-color-invalid);border-color:var(--ec-form-control-border-color-invalid);background-repeat:no-repeat;background-position:.5rem center;background-size:1rem,1rem;padding-left:1.75rem;background-image:none}:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-invalid:focus,:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-valid:focus{border-color:var(--ec-form-control-background-color-invalid)}:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-invalid~.icon-invalid,:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-valid~.icon-invalid{display:inline-flex;position:absolute;left:.5rem;top:.5rem;z-index:1}:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-invalid~.icon-required,:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-valid~.icon-required{display:none}:host .control.invalid:not(.open) .textbox-group-btn-right ::ng-deep button{background-color:var(--ec-form-control-background-color-invalid)}:host .control.invalid:not(.open) .textbox-group-btn-right ::ng-deep button:not(:focus){border-color:var(--ec-form-control-border-color-invalid)}:host .textbox-group{display:flex;position:relative}:host textarea:focus,:host input:focus,:host select:focus{outline:none}:host label{color:var(--ec-form-control-label-color, var(--ec-color-secondary-dark));display:block;font-size:var(--ec-font-size-label);line-height:1;margin:calc(var(--ec-font-size-label) / 2) 0}:host input{background-color:var(--ec-form-control-background-color);border:1px solid var(--ec-form-control-border-color);border-radius:var(--ec-border-radius);background-image:none;background-clip:padding-box;width:100%;line-height:1.25rem;padding:.3125rem .5rem;height:2rem}:host input::selection{background-color:var(--ec-form-control-background-color-selection);color:var(--ec-form-control-color-selection)}:host input::-webkit-input-placeholder{color:var(--ec-form-control-color-placeholder)}:host input::-moz-placeholder{color:var(--ec-form-control-color-placeholder);opacity:1}:host input:-ms-input-placeholder{color:var(--ec-form-control-color-placeholder)}:host input:-moz-placeholder{color:var(--ec-form-control-color-placeholder);opacity:1}:host input~.icon-required,:host input~.icon-invalid{color:var(--ec-form-control-border-color-invalid)}:host input:required.is-empty{background-repeat:no-repeat;background-position:.5rem center;background-size:1rem,1rem;padding-left:1.75rem;background-image:none}:host input:required.is-empty~.icon-required{display:inline-flex;position:absolute;left:.5rem;top:.5rem;z-index:1}:host input.ng-invalid.ng-touched{background-color:var(--ec-form-control-background-color-invalid);border-color:var(--ec-form-control-border-color-invalid);background-repeat:no-repeat;background-position:.5rem center;background-size:1rem,1rem;padding-left:1.75rem;background-image:none}:host input.ng-invalid.ng-touched:focus{border-color:var(--ec-form-control-background-color-invalid)}:host input.ng-invalid.ng-touched~.icon-invalid{display:inline-flex;position:absolute;left:.5rem;top:.5rem;z-index:1}:host input.ng-invalid.ng-touched~.icon-required{display:none}:host input.is-pending.ng-valid,:host input.is-pending.ng-invalid,:host input.is-pending.ng-pending{background-image:\"\";background-repeat:no-repeat;background-position:.5rem center;background-size:1rem,1rem;padding-left:1.75rem}:host input.is-pending.ng-valid~.icon-loading,:host input.is-pending.ng-invalid~.icon-loading,:host input.is-pending.ng-pending~.icon-loading{display:inline-flex;position:absolute;left:.5rem;top:.5rem;z-index:1}:host input.is-pending.ng-valid~.icon-required,:host input.is-pending.ng-valid~.icon-invalid,:host input.is-pending.ng-invalid~.icon-required,:host input.is-pending.ng-invalid~.icon-invalid,:host input.is-pending.ng-pending~.icon-required,:host input.is-pending.ng-pending~.icon-invalid{display:none}:host input:focus,:host input:focus.is-empty{border-color:var(--ec-form-control-border-color-focus);box-shadow:var(--ec-form-control-box-shadow-focus);position:relative;z-index:1}:host input:disabled{background-color:var(--ec-form-control-background-color-disabled);border-color:var(--ec-form-control-border-color-disabled);color:var(--ec-form-control-color-disabled);opacity:var(--ec-form-control-opacity-disabled)}:host input:disabled:required,:host input:disabled:required.is-empty{background-image:none;padding-left:.5rem;background-color:var(--ec-form-control-background-color-disabled);border-color:var(--ec-form-control-border-color-disabled)}:host input:disabled:required+.icon-required,:host input:disabled:required.is-empty+.icon-required{display:none}:host input.is-uppercase:not(.is-empty){text-transform:uppercase}:host textarea{background-color:var(--ec-form-control-background-color);border:1px solid var(--ec-form-control-border-color);border-radius:var(--ec-border-radius);background-image:none;background-clip:padding-box;width:100%;line-height:1.25rem;padding:.3125rem .5rem;height:auto;resize:none;display:block}:host textarea::selection{background-color:var(--ec-form-control-background-color-selection);color:var(--ec-form-control-color-selection)}:host textarea::-webkit-input-placeholder{color:var(--ec-form-control-color-placeholder)}:host textarea::-moz-placeholder{color:var(--ec-form-control-color-placeholder);opacity:1}:host textarea:-ms-input-placeholder{color:var(--ec-form-control-color-placeholder)}:host textarea:-moz-placeholder{color:var(--ec-form-control-color-placeholder);opacity:1}:host textarea~.icon-required,:host textarea~.icon-invalid{color:var(--ec-form-control-border-color-invalid)}:host textarea:required.is-empty{background-repeat:no-repeat;background-position:.5rem .5rem;background-size:1rem,1rem;padding-left:1.75rem;background-image:none}:host textarea:required.is-empty~.icon-required{display:inline-flex;position:absolute;left:.5rem;top:.5rem;z-index:1}:host textarea.ng-invalid.ng-touched{background-color:var(--ec-form-control-background-color-invalid);border-color:var(--ec-form-control-border-color-invalid);background-repeat:no-repeat;background-position:.5rem .5rem;background-size:1rem,1rem;padding-left:1.75rem;background-image:none}:host textarea.ng-invalid.ng-touched:focus{border-color:var(--ec-form-control-background-color-invalid)}:host textarea.ng-invalid.ng-touched~.icon-invalid{display:inline-flex;position:absolute;left:.5rem;top:.5rem;z-index:1}:host textarea.ng-invalid.ng-touched~.icon-required{display:none}:host textarea.is-pending.ng-valid,:host textarea.is-pending.ng-invalid,:host textarea.is-pending.ng-pending{background-image:\"\";background-repeat:no-repeat;background-position:.5rem .5rem;background-size:1rem,1rem;padding-left:1.75rem}:host textarea.is-pending.ng-valid~.icon-loading,:host textarea.is-pending.ng-invalid~.icon-loading,:host textarea.is-pending.ng-pending~.icon-loading{display:inline-flex;position:absolute;left:.5rem;top:.5rem;z-index:1}:host textarea.is-pending.ng-valid~.icon-required,:host textarea.is-pending.ng-valid~.icon-invalid,:host textarea.is-pending.ng-invalid~.icon-required,:host textarea.is-pending.ng-invalid~.icon-invalid,:host textarea.is-pending.ng-pending~.icon-required,:host textarea.is-pending.ng-pending~.icon-invalid{display:none}:host textarea:focus,:host textarea:focus.is-empty{border-color:var(--ec-form-control-border-color-focus);box-shadow:var(--ec-form-control-box-shadow-focus);position:relative;z-index:1}:host textarea:disabled{background-color:var(--ec-form-control-background-color-disabled);border-color:var(--ec-form-control-border-color-disabled);color:var(--ec-form-control-color-disabled);opacity:var(--ec-form-control-opacity-disabled)}:host textarea:disabled:required,:host textarea:disabled:required.is-empty{background-image:none;padding-left:.5rem;background-color:var(--ec-form-control-background-color-disabled);border-color:var(--ec-form-control-border-color-disabled)}:host textarea:disabled:required+.icon-required,:host textarea:disabled:required.is-empty+.icon-required{display:none}:host textarea.is-uppercase:not(.is-empty){text-transform:uppercase}.input-wrapper{position:relative}.input-wrapper>.ec-icon{display:none}:host(.textbox-group-input:not(:last-child)){flex:1 1 0%;width:1px}:host(.textbox-group-input:not(:last-child)) .control{margin-bottom:0}:host(.textbox-group-input:not(:last-child)) .control.is-readonly input{border-right-width:1px}:host(.textbox-group-input:not(:last-child)) input{border-top-right-radius:0;border-bottom-right-radius:0;border-right-width:0}:host(.textbox-group-input:not(:last-child)) input:focus{position:relative;z-index:1;border-right-width:1px}:host(.text-truncate) input{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host(.is-monospace) input,:host(.is-monospace) textarea,:host-context(.is-monospace) input,:host-context(.is-monospace) textarea{font-family:var(--ec-font-family-monospace)}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i4.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { kind: "directive", type: i4.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i4.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i4.EmailValidator, selector: "[email][formControlName],[email][formControl],[email][ngModel]", inputs: ["email"] }, { kind: "directive", type: i4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: HelpPopoverComponent, selector: "ec-help-popover", inputs: ["id", "text", "contentPosition", "maxWidth"] }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }] });
|
1858
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: TextboxComponent, decorators: [{
|
1859
|
-
type: Component,
|
1860
|
-
args: [{ selector: 'ec-textbox', template: "<div class=\"control control-label-{{labelPosition}}\"\r\n [ngClass]=\"{'is-readonly': readonly}\">\r\n\r\n <label *ngIf=\"label\">\r\n <span>{{label | translate}}</span>\r\n <span *ngIf=\"validationErrors.length > 0 && formModel.touched && formModel.invalid\"> {{validationErrors |\r\n translate}}</span>\r\n <ec-help-popover id=\"{{id}}_helpPopover\"\r\n *ngIf=\"helpPopover\"\r\n class=\"d-inline-block my-n3 mx-n1\"\r\n text=\"{{helpPopover | translate}}\"\r\n contentPosition=\"{{helpPopoverPosition}}\">\r\n </ec-help-popover>\r\n </label>\r\n\r\n <div class=\"input-wrapper control-input\">\r\n <input *ngIf=\"type !== 'multi_line'\"\r\n #textboxInput\r\n email=\"{{type === 'email' ? true : false}}\"\r\n pattern=\"{{validationPattern}}\"\r\n type=\"{{type}}\"\r\n tabindex=\"{{tabindex}}\"\r\n title=\"{{tooltip}}\"\r\n [attr.id]=\"inputId\"\r\n [attr.autocomplete]=\"autocomplete\"\r\n [attr.placeholder]=\"placeholder\"\r\n [attr.maxlength]=\"maxlength\"\r\n [attr.minlength]=\"minlength\"\r\n [attr.required]=\"required ? required : null\"\r\n [formControl]=\"formModel\"\r\n [ngClass]=\"{'is-empty': !formModel?.value, 'is-pending': pending, 'is-uppercase': upperCase}\"\r\n (focusout)=\"focusOutEvent()\"\r\n [attr.cdkFocusInitial]=\"autofocus || null\">\r\n\r\n <textarea *ngIf=\"type === 'multi_line'\"\r\n [attr.rows]=\"rows\"\r\n #textboxInput\r\n tabindex=\"{{tabindex}}\"\r\n [attr.id]=\"inputId\"\r\n [attr.placeholder]=\"placeholder\"\r\n [attr.maxlength]=\"maxlength\"\r\n [attr.minlength]=\"minlength\"\r\n [attr.required]=\"required ? required : null\"\r\n [formControl]=\"formModel\"\r\n [ngClass]=\"{'is-empty': formModel?.value === '', 'is-pending': pending}\"\r\n [attr.cdkFocusInitial]=\"autofocus || null\">\r\n </textarea>\r\n\r\n <i class=\"ec-icon icon-required\"></i>\r\n <i class=\"ec-icon icon-invalid\"></i>\r\n <i class=\"ec-icon icon-loading\"></i>\r\n </div>\r\n</div>", styles: [":host{color:var(--ec-form-control-color);font-size:var(--ec-form-control-font-size);display:block;margin-bottom:1rem;width:100%}:host :host-context(.form-condensed){margin-bottom:.5rem}:host .control{width:100%;display:flex;flex-direction:column}:host .control.control-label-bottom{flex-direction:column-reverse}:host .control.control-label-left{flex-direction:row}:host .control.control-label-left label{margin-right:.25rem}:host .control.control-label-right{flex-direction:row-reverse}:host .control.control-label-right label{margin-left:.25rem}:host .control.control-label-left,:host .control.control-label-right{align-items:center}:host .control.control-label-left label,:host .control.control-label-right label{flex:1 1;margin-top:0;margin-bottom:0}:host .control.control-label-left .control-input,:host .control.control-label-right .control-input{flex:2 2}:host .control.is-readonly input,:host .control.is-readonly select,:host .control.is-readonly textarea{border-color:var(--ec-form-control-border-color-readonly);background-color:var(--ec-form-control-background-color-readonly);background-clip:border-box;background-image:none;color:var(--ec-form-control-color-readonly);opacity:1;-webkit-user-select:none;user-select:none;pointer-events:none;overflow:hidden;white-space:nowrap}:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-invalid,:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-valid{background-color:var(--ec-form-control-background-color-invalid);border-color:var(--ec-form-control-border-color-invalid);background-repeat:no-repeat;background-position:.5rem center;background-size:1rem,1rem;padding-left:1.75rem;background-image:none}:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-invalid:focus,:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-valid:focus{border-color:var(--ec-form-control-background-color-invalid)}:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-invalid~.icon-invalid,:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-valid~.icon-invalid{display:inline-flex;position:absolute;left:.5rem;top:.5rem;z-index:1}:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-invalid~.icon-required,:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-valid~.icon-required{display:none}:host .control.invalid:not(.open) .textbox-group-btn-right ::ng-deep button{background-color:var(--ec-form-control-background-color-invalid)}:host .control.invalid:not(.open) .textbox-group-btn-right ::ng-deep button:not(:focus){border-color:var(--ec-form-control-border-color-invalid)}:host .textbox-group{display:flex;position:relative}:host textarea:focus,:host input:focus,:host select:focus{outline:none}:host label{color:var(--ec-form-control-label-color, var(--ec-color-secondary-dark));display:block;font-size:var(--ec-font-size-label);line-height:1;margin:calc(var(--ec-font-size-label) / 2) 0}:host input{background-color:var(--ec-form-control-background-color);border:1px solid var(--ec-form-control-border-color);border-radius:var(--ec-border-radius);background-image:none;background-clip:padding-box;width:100%;line-height:1.25rem;padding:.3125rem .5rem;height:2rem}:host input::selection{background-color:var(--ec-form-control-background-color-selection);color:var(--ec-form-control-color-selection)}:host input::-webkit-input-placeholder{color:var(--ec-form-control-color-placeholder)}:host input::-moz-placeholder{color:var(--ec-form-control-color-placeholder);opacity:1}:host input:-ms-input-placeholder{color:var(--ec-form-control-color-placeholder)}:host input:-moz-placeholder{color:var(--ec-form-control-color-placeholder);opacity:1}:host input~.icon-required,:host input~.icon-invalid{color:var(--ec-form-control-border-color-invalid)}:host input:required.is-empty{background-repeat:no-repeat;background-position:.5rem center;background-size:1rem,1rem;padding-left:1.75rem;background-image:none}:host input:required.is-empty~.icon-required{display:inline-flex;position:absolute;left:.5rem;top:.5rem;z-index:1}:host input.ng-invalid.ng-touched{background-color:var(--ec-form-control-background-color-invalid);border-color:var(--ec-form-control-border-color-invalid);background-repeat:no-repeat;background-position:.5rem center;background-size:1rem,1rem;padding-left:1.75rem;background-image:none}:host input.ng-invalid.ng-touched:focus{border-color:var(--ec-form-control-background-color-invalid)}:host input.ng-invalid.ng-touched~.icon-invalid{display:inline-flex;position:absolute;left:.5rem;top:.5rem;z-index:1}:host input.ng-invalid.ng-touched~.icon-required{display:none}:host input.is-pending.ng-valid,:host input.is-pending.ng-invalid,:host input.is-pending.ng-pending{background-image:\"\";background-repeat:no-repeat;background-position:.5rem center;background-size:1rem,1rem;padding-left:1.75rem}:host input.is-pending.ng-valid~.icon-loading,:host input.is-pending.ng-invalid~.icon-loading,:host input.is-pending.ng-pending~.icon-loading{display:inline-flex;position:absolute;left:.5rem;top:.5rem;z-index:1}:host input.is-pending.ng-valid~.icon-required,:host input.is-pending.ng-valid~.icon-invalid,:host input.is-pending.ng-invalid~.icon-required,:host input.is-pending.ng-invalid~.icon-invalid,:host input.is-pending.ng-pending~.icon-required,:host input.is-pending.ng-pending~.icon-invalid{display:none}:host input:focus,:host input:focus.is-empty{border-color:var(--ec-form-control-border-color-focus);box-shadow:var(--ec-form-control-box-shadow-focus);position:relative;z-index:1}:host input:disabled{background-color:var(--ec-form-control-background-color-disabled);border-color:var(--ec-form-control-border-color-disabled);color:var(--ec-form-control-color-disabled);opacity:var(--ec-form-control-opacity-disabled)}:host input:disabled:required,:host input:disabled:required.is-empty{background-image:none;padding-left:.5rem;background-color:var(--ec-form-control-background-color-disabled);border-color:var(--ec-form-control-border-color-disabled)}:host input:disabled:required+.icon-required,:host input:disabled:required.is-empty+.icon-required{display:none}:host input.is-uppercase:not(.is-empty){text-transform:uppercase}:host textarea{background-color:var(--ec-form-control-background-color);border:1px solid var(--ec-form-control-border-color);border-radius:var(--ec-border-radius);background-image:none;background-clip:padding-box;width:100%;line-height:1.25rem;padding:.3125rem .5rem;height:auto;resize:none;display:block}:host textarea::selection{background-color:var(--ec-form-control-background-color-selection);color:var(--ec-form-control-color-selection)}:host textarea::-webkit-input-placeholder{color:var(--ec-form-control-color-placeholder)}:host textarea::-moz-placeholder{color:var(--ec-form-control-color-placeholder);opacity:1}:host textarea:-ms-input-placeholder{color:var(--ec-form-control-color-placeholder)}:host textarea:-moz-placeholder{color:var(--ec-form-control-color-placeholder);opacity:1}:host textarea~.icon-required,:host textarea~.icon-invalid{color:var(--ec-form-control-border-color-invalid)}:host textarea:required.is-empty{background-repeat:no-repeat;background-position:.5rem .5rem;background-size:1rem,1rem;padding-left:1.75rem;background-image:none}:host textarea:required.is-empty~.icon-required{display:inline-flex;position:absolute;left:.5rem;top:.5rem;z-index:1}:host textarea.ng-invalid.ng-touched{background-color:var(--ec-form-control-background-color-invalid);border-color:var(--ec-form-control-border-color-invalid);background-repeat:no-repeat;background-position:.5rem .5rem;background-size:1rem,1rem;padding-left:1.75rem;background-image:none}:host textarea.ng-invalid.ng-touched:focus{border-color:var(--ec-form-control-background-color-invalid)}:host textarea.ng-invalid.ng-touched~.icon-invalid{display:inline-flex;position:absolute;left:.5rem;top:.5rem;z-index:1}:host textarea.ng-invalid.ng-touched~.icon-required{display:none}:host textarea.is-pending.ng-valid,:host textarea.is-pending.ng-invalid,:host textarea.is-pending.ng-pending{background-image:\"\";background-repeat:no-repeat;background-position:.5rem .5rem;background-size:1rem,1rem;padding-left:1.75rem}:host textarea.is-pending.ng-valid~.icon-loading,:host textarea.is-pending.ng-invalid~.icon-loading,:host textarea.is-pending.ng-pending~.icon-loading{display:inline-flex;position:absolute;left:.5rem;top:.5rem;z-index:1}:host textarea.is-pending.ng-valid~.icon-required,:host textarea.is-pending.ng-valid~.icon-invalid,:host textarea.is-pending.ng-invalid~.icon-required,:host textarea.is-pending.ng-invalid~.icon-invalid,:host textarea.is-pending.ng-pending~.icon-required,:host textarea.is-pending.ng-pending~.icon-invalid{display:none}:host textarea:focus,:host textarea:focus.is-empty{border-color:var(--ec-form-control-border-color-focus);box-shadow:var(--ec-form-control-box-shadow-focus);position:relative;z-index:1}:host textarea:disabled{background-color:var(--ec-form-control-background-color-disabled);border-color:var(--ec-form-control-border-color-disabled);color:var(--ec-form-control-color-disabled);opacity:var(--ec-form-control-opacity-disabled)}:host textarea:disabled:required,:host textarea:disabled:required.is-empty{background-image:none;padding-left:.5rem;background-color:var(--ec-form-control-background-color-disabled);border-color:var(--ec-form-control-border-color-disabled)}:host textarea:disabled:required+.icon-required,:host textarea:disabled:required.is-empty+.icon-required{display:none}:host textarea.is-uppercase:not(.is-empty){text-transform:uppercase}.input-wrapper{position:relative}.input-wrapper>.ec-icon{display:none}:host(.textbox-group-input:not(:last-child)){flex:1 1 0%;width:1px}:host(.textbox-group-input:not(:last-child)) .control{margin-bottom:0}:host(.textbox-group-input:not(:last-child)) .control.is-readonly input{border-right-width:1px}:host(.textbox-group-input:not(:last-child)) input{border-top-right-radius:0;border-bottom-right-radius:0;border-right-width:0}:host(.textbox-group-input:not(:last-child)) input:focus{position:relative;z-index:1;border-right-width:1px}:host(.text-truncate) input{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host(.is-monospace) input,:host(.is-monospace) textarea,:host-context(.is-monospace) input,:host-context(.is-monospace) textarea{font-family:var(--ec-font-family-monospace)}\n"] }]
|
1861
|
-
}], ctorParameters: function () { return [{ type: ValidationMessageService }, { type: FormGroupHelper }, { type: i2.TranslateService }]; }, propDecorators: { autocomplete: [{
|
1862
|
-
type: Input
|
1863
|
-
}], type: [{
|
1864
|
-
type: Input
|
1865
|
-
}], placeholder: [{
|
1866
|
-
type: Input
|
1867
|
-
}], maxlength: [{
|
1868
|
-
type: Input
|
1869
|
-
}], minlength: [{
|
1870
|
-
type: Input
|
1871
|
-
}], rows: [{
|
1872
|
-
type: Input
|
1873
|
-
}], selectOnAutofocus: [{
|
1874
|
-
type: Input
|
1875
|
-
}], upperCase: [{
|
1876
|
-
type: Input
|
1877
|
-
}], inputElement: [{
|
1878
|
-
type: ViewChild,
|
1879
|
-
args: ['textboxInput']
|
1880
|
-
}] } });
|
1881
|
-
|
1882
|
-
/** Exposes the markup and styles that represent the spinner. No inputs or outputs defined because it is just a visual component*/
|
1883
|
-
class SpinnerComponent {
|
1884
|
-
}
|
1885
|
-
SpinnerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SpinnerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
1886
|
-
SpinnerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.9", type: SpinnerComponent, selector: "ec-spinner", ngImport: i0, template: "<div class=\"spinner\">\r\n <span class=\"spinner-dot\"></span>\r\n <span class=\"spinner-dot\"></span>\r\n <span class=\"spinner-dot\"></span>\r\n <span class=\"spinner-dot\"></span>\r\n</div>", styles: ["@keyframes sk-bouncedelay{0%,80%,to{opacity:0}40%{opacity:1}}.spinner{display:flex}.spinner-dot{width:.75rem;height:.75rem;background-color:var(--ec-color-interactive);animation:sk-bouncedelay 1.7s infinite ease-in-out both;margin-right:.25rem}.spinner-dot:nth-child(1){animation-delay:-.6s}.spinner-dot:nth-child(2){animation-delay:-.4s}.spinner-dot:nth-child(3){animation-delay:-.2s}:host(.spinner-small) .spinner-dot{width:.5rem;height:.5rem;background-color:var(--ec-color-interactive);animation:sk-bouncedelay 1.7s infinite ease-in-out both;margin-right:.1666666667rem}:host(.spinner-small) .spinner-dot:nth-child(1){animation-delay:-.6s}:host(.spinner-small) .spinner-dot:nth-child(2){animation-delay:-.4s}:host(.spinner-small) .spinner-dot:nth-child(3){animation-delay:-.2s}\n"] });
|
1887
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SpinnerComponent, decorators: [{
|
1888
|
-
type: Component,
|
1889
|
-
args: [{ selector: 'ec-spinner', template: "<div class=\"spinner\">\r\n <span class=\"spinner-dot\"></span>\r\n <span class=\"spinner-dot\"></span>\r\n <span class=\"spinner-dot\"></span>\r\n <span class=\"spinner-dot\"></span>\r\n</div>", styles: ["@keyframes sk-bouncedelay{0%,80%,to{opacity:0}40%{opacity:1}}.spinner{display:flex}.spinner-dot{width:.75rem;height:.75rem;background-color:var(--ec-color-interactive);animation:sk-bouncedelay 1.7s infinite ease-in-out both;margin-right:.25rem}.spinner-dot:nth-child(1){animation-delay:-.6s}.spinner-dot:nth-child(2){animation-delay:-.4s}.spinner-dot:nth-child(3){animation-delay:-.2s}:host(.spinner-small) .spinner-dot{width:.5rem;height:.5rem;background-color:var(--ec-color-interactive);animation:sk-bouncedelay 1.7s infinite ease-in-out both;margin-right:.1666666667rem}:host(.spinner-small) .spinner-dot:nth-child(1){animation-delay:-.6s}:host(.spinner-small) .spinner-dot:nth-child(2){animation-delay:-.4s}:host(.spinner-small) .spinner-dot:nth-child(3){animation-delay:-.2s}\n"] }]
|
1890
|
-
}] });
|
1891
|
-
|
1892
|
-
class Overlay {
|
1893
|
-
constructor(status, message) {
|
1894
|
-
this.status = 'hasData';
|
1895
|
-
this.message = '';
|
1896
|
-
this.setStatus(status, message);
|
1897
|
-
}
|
1898
|
-
setStatus(status, message, action, noDataTemplate, overlayClassList) {
|
1899
|
-
this.status = status;
|
1900
|
-
this.message = message || '';
|
1901
|
-
this.action = action || undefined;
|
1902
|
-
this.noDataTemplate = noDataTemplate || undefined;
|
1903
|
-
this.overlayClassList = overlayClassList || '';
|
1793
|
+
constructor(router, el, renderer, route) {
|
1794
|
+
this.router = router;
|
1795
|
+
this.el = el;
|
1796
|
+
this.renderer = renderer;
|
1797
|
+
this.route = route;
|
1798
|
+
this._exact = true;
|
1799
|
+
/** Emits when the url becomes active */
|
1800
|
+
this.routerLinkActivated = new EventEmitter();
|
1801
|
+
/** Subject that emits when component is destroyed to unsubscribe from any subscriptions */
|
1802
|
+
this.destroyed = new Subject();
|
1904
1803
|
}
|
1905
|
-
|
1906
|
-
|
1907
|
-
|
1908
|
-
|
1909
|
-
|
1910
|
-
constructor() {
|
1911
|
-
this.status = 'hasData';
|
1804
|
+
/** Check if url is active on NavigationEnd events */
|
1805
|
+
ngOnInit() {
|
1806
|
+
this.router.events.pipe(takeUntil(this.destroyed), filter(e => e instanceof NavigationEnd)).subscribe(() => {
|
1807
|
+
this.update();
|
1808
|
+
});
|
1912
1809
|
}
|
1913
|
-
|
1914
|
-
this.
|
1915
|
-
this.
|
1916
|
-
this.action = action || undefined;
|
1917
|
-
this.noDataTemplate = noDataTemplate || undefined;
|
1810
|
+
ngOnDestroy() {
|
1811
|
+
this.destroyed.next();
|
1812
|
+
this.destroyed.unsubscribe();
|
1918
1813
|
}
|
1919
|
-
|
1920
|
-
|
1921
|
-
|
1814
|
+
/** If url is active apply the defined class to the element, otherwise remove it */
|
1815
|
+
update() {
|
1816
|
+
if (this._url && this.classValue) {
|
1817
|
+
if (this.router.isActive(this._url, { matrixParams: 'ignored', queryParams: this._exact ? 'exact' : 'subset', paths: this._exact ? 'exact' : 'subset', fragment: 'ignored' })) {
|
1818
|
+
this.renderer.addClass(this.el.nativeElement, this.classValue);
|
1819
|
+
this.routerLinkActivated.emit(new Event('routerLinkActivated'));
|
1820
|
+
}
|
1821
|
+
else {
|
1822
|
+
this.renderer.removeClass(this.el.nativeElement, this.classValue);
|
1823
|
+
}
|
1922
1824
|
}
|
1923
1825
|
}
|
1924
1826
|
}
|
1925
|
-
|
1926
|
-
|
1927
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type:
|
1928
|
-
type:
|
1929
|
-
args: [{
|
1930
|
-
|
1931
|
-
|
1932
|
-
|
1933
|
-
type: Input
|
1934
|
-
|
1935
|
-
|
1936
|
-
|
1937
|
-
|
1938
|
-
}],
|
1939
|
-
type: Input
|
1940
|
-
|
1941
|
-
|
1827
|
+
NavItemActiveDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: NavItemActiveDirective, deps: [{ token: i1$2.Router }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i1$2.ActivatedRoute }], target: i0.ɵɵFactoryTarget.Directive });
|
1828
|
+
NavItemActiveDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.9", type: NavItemActiveDirective, selector: "[ecNavItemActive]", inputs: { classValue: ["ecNavItemActive", "classValue"], exact: ["ecNavItemActiveExactMatch", "exact"], queryParams: ["ecNavItemActiveQueryParams", "queryParams"], url: ["ecNavItemActiveUrl", "url"] }, outputs: { routerLinkActivated: "routerLinkActivated" }, ngImport: i0 });
|
1829
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: NavItemActiveDirective, decorators: [{
|
1830
|
+
type: Directive,
|
1831
|
+
args: [{
|
1832
|
+
selector: '[ecNavItemActive]'
|
1833
|
+
}]
|
1834
|
+
}], ctorParameters: function () { return [{ type: i1$2.Router }, { type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i1$2.ActivatedRoute }]; }, propDecorators: { classValue: [{
|
1835
|
+
type: Input,
|
1836
|
+
args: ['ecNavItemActive']
|
1837
|
+
}], exact: [{
|
1838
|
+
type: Input,
|
1839
|
+
args: ['ecNavItemActiveExactMatch']
|
1840
|
+
}], queryParams: [{
|
1841
|
+
type: Input,
|
1842
|
+
args: ['ecNavItemActiveQueryParams']
|
1843
|
+
}], url: [{
|
1844
|
+
type: Input,
|
1845
|
+
args: ['ecNavItemActiveUrl']
|
1846
|
+
}], routerLinkActivated: [{
|
1847
|
+
type: Output
|
1942
1848
|
}] } });
|
1943
1849
|
|
1850
|
+
;
|
1851
|
+
const menuAnimationSpeed = 350;
|
1944
1852
|
/**
|
1945
|
-
*
|
1946
|
-
*
|
1853
|
+
* Primitive Menu component that encapsulates known templates
|
1854
|
+
*
|
1855
|
+
* @export
|
1947
1856
|
*/
|
1948
|
-
class
|
1857
|
+
class MenuComponent {
|
1949
1858
|
/**
|
1950
|
-
*
|
1951
|
-
*
|
1952
|
-
* It is set up as `get` only because it is set with `addNavigateAwayPrompt`.
|
1953
|
-
*
|
1954
|
-
* This also includes adding a prompt to the window itself (in addition to
|
1955
|
-
* working with the `CanDeactivateUnsavedChanges` guard) to cover page reloads
|
1956
|
-
* which do not trigger router events.
|
1859
|
+
* Helper function to return a flat list of all selectable items in the provided menu items. Filters out headings and divided-sections.
|
1860
|
+
* This makes it much easier to keep track of currently highlighted items for keyboard navigation.
|
1957
1861
|
*/
|
1958
|
-
|
1959
|
-
return
|
1862
|
+
static getSelectableItems(items) {
|
1863
|
+
return items.reduce((selectableItems, item) => {
|
1864
|
+
if (item.display !== 'heading' && item.display !== 'divided-section') {
|
1865
|
+
selectableItems.push(item);
|
1866
|
+
}
|
1867
|
+
else if (item.items) {
|
1868
|
+
selectableItems.push(...item.items.filter(childItem => childItem.display !== 'heading' && childItem.display !== 'divided-section'));
|
1869
|
+
}
|
1870
|
+
return selectableItems;
|
1871
|
+
}, []);
|
1960
1872
|
}
|
1961
1873
|
/**
|
1962
|
-
*
|
1963
|
-
* is
|
1874
|
+
* Returns an ID for the provided item based on its index in the provided items array. This mimics the behavior of the MenuComponent's
|
1875
|
+
* generated IDs for items that don't have provided IDs. This is used in MenuComponent and ComboboxComponent to scroll to specific items.
|
1876
|
+
* NOTE: If the items array does not match what is displayed in the menu, this function will not return the correct ID.
|
1877
|
+
*
|
1878
|
+
* Returns null if the not found
|
1879
|
+
* @param items The MenuItems array to search through.
|
1880
|
+
* @param item The item to generate the ID for.
|
1881
|
+
* @param menuComponentId Used to prefix the generated ID. This should be the ID of the menu component the item is present in.
|
1882
|
+
* @memberof MenuComponent
|
1964
1883
|
*/
|
1965
|
-
|
1966
|
-
|
1884
|
+
static getIndexedItemId(items, item, menuComponentId) {
|
1885
|
+
if (item) {
|
1886
|
+
for (let i = 0; i < items.length; i++) {
|
1887
|
+
const itemInList = items[i];
|
1888
|
+
if (itemInList.label === item.label) {
|
1889
|
+
return `${menuComponentId}_item${i}`;
|
1890
|
+
}
|
1891
|
+
// If the item is a heading or divided section, check its children
|
1892
|
+
if (itemInList.items && (itemInList.display === 'heading' || itemInList.display === 'divided-section')) {
|
1893
|
+
for (let j = 0; j < itemInList.items.length; j++) {
|
1894
|
+
const childItem = itemInList.items[j];
|
1895
|
+
// Fall back to checking only the label if the item doesn't have an id
|
1896
|
+
if (childItem.label === item.label) {
|
1897
|
+
return `${menuComponentId}_item${i}-${j}`;
|
1898
|
+
}
|
1899
|
+
}
|
1900
|
+
}
|
1901
|
+
}
|
1902
|
+
}
|
1903
|
+
return null;
|
1967
1904
|
}
|
1968
|
-
constructor(
|
1969
|
-
this.
|
1970
|
-
this.
|
1971
|
-
this.
|
1905
|
+
constructor(el, renderer, windowService, scrollService) {
|
1906
|
+
this.el = el;
|
1907
|
+
this.renderer = renderer;
|
1908
|
+
this.windowService = windowService;
|
1909
|
+
this.scrollService = scrollService;
|
1972
1910
|
/**
|
1973
|
-
*
|
1911
|
+
* Array of items to display
|
1974
1912
|
*
|
1975
|
-
*
|
1976
|
-
|
1913
|
+
* @memberof MenuComponent
|
1914
|
+
*/
|
1915
|
+
this.items = [];
|
1916
|
+
/**
|
1917
|
+
* Selected item; annotates the item
|
1918
|
+
* when displayed with 'selected' class
|
1977
1919
|
*
|
1978
|
-
*
|
1979
|
-
* dialog.
|
1980
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event
|
1920
|
+
* @memberof MenuComponent
|
1981
1921
|
*/
|
1982
|
-
this.
|
1983
|
-
|
1984
|
-
|
1985
|
-
|
1986
|
-
|
1987
|
-
|
1988
|
-
|
1989
|
-
|
1922
|
+
this.selected = null;
|
1923
|
+
/**
|
1924
|
+
* Display template
|
1925
|
+
*
|
1926
|
+
* @memberof MenuComponent
|
1927
|
+
*/
|
1928
|
+
this.templateType = 'label';
|
1929
|
+
/**
|
1930
|
+
* Show message when there are no items
|
1931
|
+
*/
|
1932
|
+
this.showNoItems = false;
|
1933
|
+
/**
|
1934
|
+
* Text to show when menu is empty and showNoItems is true
|
1935
|
+
*/
|
1936
|
+
this.noDataText = 'NoItems_TC';
|
1937
|
+
/**
|
1938
|
+
* Controls whether keyboard navigation is enabled
|
1939
|
+
*/
|
1940
|
+
this.enableKeyNav = false;
|
1941
|
+
/**
|
1942
|
+
* Item currently highlighted by keyboard navigation
|
1943
|
+
*/
|
1944
|
+
this.highlightedItem = null;
|
1945
|
+
/**
|
1946
|
+
* Tells the menu to maintain the selected/lastSelected item. Turning this off is useful for
|
1947
|
+
* action type menus that are displayed on the screen at all times and you do not
|
1948
|
+
* want the item to be selected when clicked.
|
1949
|
+
*/
|
1950
|
+
this.maintainSelectedItem = true;
|
1951
|
+
/**
|
1952
|
+
* Will prevent text-wrapping of menu items and truncate instead. Also turns on a tooltip for the menu item. Default: false;
|
1953
|
+
*/
|
1954
|
+
this.truncateItems = false;
|
1955
|
+
/**
|
1956
|
+
* When true, the space for the icon is preserved for menu items that do not have icons.
|
1957
|
+
* Only applicable for iconAndLabel menus.
|
1958
|
+
*/
|
1959
|
+
this.preserveIconSpace = false;
|
1960
|
+
/**
|
1961
|
+
* Emitted when `selected` is changed. Emits the referenced object.
|
1962
|
+
*
|
1963
|
+
* @memberof MenuComponent
|
1964
|
+
*/
|
1965
|
+
this.selectedChanged = new EventEmitter();
|
1966
|
+
/**
|
1967
|
+
* Emitted when the menu has a parent and back is clicked
|
1968
|
+
* @memberof MenuComponent
|
1969
|
+
*/
|
1970
|
+
this.menuClosed = new EventEmitter();
|
1971
|
+
/**
|
1972
|
+
* Index of the item currently highlighted using keyboard nav
|
1973
|
+
*/
|
1974
|
+
this.highlightedItemIndex = -1;
|
1975
|
+
/**
|
1976
|
+
* Last item this.selected was set to via selectItem().
|
1977
|
+
* This isn't necessarily the same as this.selected, because this.selected is an input property
|
1978
|
+
* and could have been changed by a consumer through some means other than selectItem().
|
1979
|
+
* This allows us to prevent double-calls to selectItem() with the same input.
|
1980
|
+
*/
|
1981
|
+
this.lastSelected = null;
|
1982
|
+
/**
|
1983
|
+
* Flattened array of all selectable items in the menu. Makes it easier to keep track of the currently highlighted item for keyboard navigation.
|
1984
|
+
*/
|
1985
|
+
this.selectableItems = [];
|
1986
|
+
}
|
1987
|
+
ngOnChanges(changes) {
|
1988
|
+
if (changes.items && this.items) {
|
1989
|
+
this.selectableItems = MenuComponent.getSelectableItems(this.items);
|
1990
1990
|
}
|
1991
1991
|
}
|
1992
1992
|
/**
|
1993
|
-
*
|
1993
|
+
* Sets & displays the interalized template based on
|
1994
|
+
* the set template.
|
1995
|
+
* @see { @link https://angular.io/guide/lifecycle-hooks|Angular Lifecycle Hooks}
|
1996
|
+
*
|
1997
|
+
* @memberof MenuComponent
|
1994
1998
|
*/
|
1995
|
-
|
1996
|
-
|
1999
|
+
ngAfterContentInit() {
|
2000
|
+
switch (this.templateType) {
|
2001
|
+
case ("label"):
|
2002
|
+
this.internalizedTemplate = this.iconAndLabelTemplate;
|
2003
|
+
break;
|
2004
|
+
case ("iconAndLabel"):
|
2005
|
+
this.internalizedTemplate = this.iconAndLabelTemplate;
|
2006
|
+
break;
|
2007
|
+
case ("checkAndLabel"):
|
2008
|
+
this.internalizedTemplate = this.checkAndLabelTemplate;
|
2009
|
+
break;
|
2010
|
+
case ("iconLabelCaption"):
|
2011
|
+
this.internalizedTemplate = this.iconLabelCaptionTemplate;
|
2012
|
+
break;
|
2013
|
+
default:
|
2014
|
+
throw new Error(`Invalid templateType for MenuComponent. Please use either: 'label', 'iconAndLabel' or 'checkAndLabel'`);
|
2015
|
+
}
|
2016
|
+
//if the consumer provided a menuItemTemplate, override the internalizedTemplate with that.
|
2017
|
+
if (this.customMenuTemplate) {
|
2018
|
+
this.internalizedTemplate = this.customMenuTemplate;
|
2019
|
+
}
|
2020
|
+
if (this.id) {
|
2021
|
+
this.attrId = this.id;
|
2022
|
+
}
|
2023
|
+
this.setItemIds();
|
2024
|
+
if (this.highlightedItem && this.selectableItems.length) {
|
2025
|
+
this.highlightedItemIndex = this.selectableItems.findIndex(item => { return this.highlightedItem === item; });
|
2026
|
+
}
|
2027
|
+
this.addKeydownListener();
|
1997
2028
|
}
|
1998
|
-
|
1999
|
-
|
2000
|
-
|
2001
|
-
|
2002
|
-
|
2003
|
-
return ((_a = window === null || window === void 0 ? void 0 : window.history) === null || _a === void 0 ? void 0 : _a.length) || 0;
|
2029
|
+
ngOnDestroy() {
|
2030
|
+
// Remove the listener when the component is destroyed
|
2031
|
+
if (this.removeKeydownListener) {
|
2032
|
+
this.removeKeydownListener();
|
2033
|
+
}
|
2004
2034
|
}
|
2005
2035
|
/**
|
2006
|
-
*
|
2007
|
-
*
|
2036
|
+
* When a menu item is selected, open a child menu if the item has items, call
|
2037
|
+
* the item's click method if defined, or emit the selected item.
|
2008
2038
|
*
|
2009
|
-
* @
|
2039
|
+
* @param item The selected item
|
2040
|
+
* @memberof MenuComponent
|
2010
2041
|
*/
|
2011
|
-
|
2012
|
-
|
2013
|
-
|
2014
|
-
|
2015
|
-
|
2042
|
+
selectItem(event, item, isKeyEvent) {
|
2043
|
+
var _a;
|
2044
|
+
event.stopPropagation();
|
2045
|
+
//In the case that the user clicks an item, selectItem() will be called from the click handler
|
2046
|
+
//and through onRouterLinkActivated. Only one of these will make it through this if statement
|
2047
|
+
//because the first one will set this.lastSelected = item.
|
2048
|
+
if (!item.disabled && !item.readonly && this.lastSelected !== item) {
|
2049
|
+
if (!item.url) {
|
2050
|
+
if (item.onClick) {
|
2051
|
+
item.onClick(item, false);
|
2052
|
+
}
|
2053
|
+
if (item.items && item.display !== 'heading' && item.display !== 'divided-section') {
|
2054
|
+
this.toggleChildMenu(true);
|
2016
2055
|
}
|
2017
2056
|
else {
|
2018
|
-
|
2057
|
+
this.onSelection(item);
|
2019
2058
|
}
|
2059
|
+
// We need to manually handle the url navigation if the keyboard was used
|
2020
2060
|
}
|
2021
|
-
|
2022
|
-
|
2023
|
-
|
2024
|
-
|
2025
|
-
|
2061
|
+
else if (isKeyEvent || ((_a = event.target) === null || _a === void 0 ? void 0 : _a.tagName) === 'LI') {
|
2062
|
+
if (item.target) {
|
2063
|
+
window.open(item.url, item.target);
|
2064
|
+
}
|
2065
|
+
else {
|
2066
|
+
this.windowService.navigateToUrl(item.url);
|
2067
|
+
}
|
2068
|
+
// Emit so upstream components know an item was selected
|
2069
|
+
this.onSelection(item);
|
2070
|
+
}
|
2071
|
+
else {
|
2072
|
+
this.onSelection(item);
|
2073
|
+
}
|
2074
|
+
if (this.maintainSelectedItem) {
|
2075
|
+
this.selected = item;
|
2076
|
+
this.lastSelected = item;
|
2026
2077
|
}
|
2027
|
-
|
2028
|
-
|
2029
|
-
|
2030
|
-
|
2031
|
-
|
2032
|
-
*/
|
2033
|
-
addNavigateAwayPrompt() {
|
2034
|
-
this._hasUnsavedChanges = true;
|
2035
|
-
window.addEventListener("beforeunload", this.beforeUnloadFunction);
|
2036
|
-
}
|
2037
|
-
/**
|
2038
|
-
* Removes the `beforeunload` function added to the window
|
2039
|
-
*/
|
2040
|
-
removeNavigateAwayPrompt() {
|
2041
|
-
this._hasUnsavedChanges = false;
|
2042
|
-
window.removeEventListener("beforeunload", this.beforeUnloadFunction);
|
2078
|
+
else {
|
2079
|
+
this.selected = null;
|
2080
|
+
this.lastSelected = null;
|
2081
|
+
}
|
2082
|
+
}
|
2043
2083
|
}
|
2044
2084
|
/**
|
2045
|
-
*
|
2046
|
-
*
|
2047
|
-
* __SECURITY RISK__ - Always use a specific target origin. Failing to provide a specific target origin can allow
|
2048
|
-
* malicious sites to receive the message.
|
2049
|
-
*
|
2050
|
-
* @param targetWindow - Window to send the message to
|
2051
|
-
* @param message - Data to send
|
2052
|
-
* @param targetOrigin - What the URI of the target window must be for the message to be sent.
|
2053
|
-
* If sending data to another EnergyCAP window, this should always be `window.location.origin` to ensure
|
2054
|
-
* that only instances of EnergyCAP app receive the message.
|
2085
|
+
* Close the current menu and open the parent menu
|
2086
|
+
* @memberof MenuComponent
|
2055
2087
|
*/
|
2056
|
-
|
2057
|
-
|
2088
|
+
back(event) {
|
2089
|
+
event.stopPropagation();
|
2090
|
+
if (this.parent && this.parent.onClick) {
|
2091
|
+
this.parent.onClick(null, true);
|
2092
|
+
}
|
2093
|
+
this.menuClosed.emit();
|
2058
2094
|
}
|
2059
2095
|
/**
|
2060
|
-
*
|
2061
|
-
* @param
|
2096
|
+
* Emit the selected item
|
2097
|
+
* @param item The selected item
|
2062
2098
|
*/
|
2063
|
-
|
2064
|
-
|
2099
|
+
onSelection(item) {
|
2100
|
+
if (item.display !== 'heading' && item.display !== 'divided-section') {
|
2101
|
+
this.selectedChanged.emit(item);
|
2102
|
+
}
|
2065
2103
|
}
|
2066
2104
|
/**
|
2067
|
-
*
|
2068
|
-
*
|
2069
|
-
*
|
2070
|
-
*
|
2071
|
-
* @returns a promise that resolves to true if the navigation succeeds, false if something (like a guard) blocks it.
|
2072
|
-
* In normal use, the navigation should succeed unless we use query params to block access to a route the user is already on
|
2105
|
+
* Open or close the child menu. When the child menu closes, the selected
|
2106
|
+
* item is reset.
|
2107
|
+
* @memberof MenuComponent
|
2073
2108
|
*/
|
2074
|
-
|
2075
|
-
|
2076
|
-
|
2077
|
-
|
2078
|
-
|
2079
|
-
|
2080
|
-
|
2109
|
+
toggleChildMenu(open) {
|
2110
|
+
let navEl = this.el.nativeElement.querySelector('nav');
|
2111
|
+
if (open) {
|
2112
|
+
// Remove the listener on the parent menu when a child menu is opened
|
2113
|
+
// This is to avoid interference between the parent and child menus
|
2114
|
+
if (this.removeKeydownListener) {
|
2115
|
+
this.removeKeydownListener();
|
2116
|
+
}
|
2117
|
+
let height = navEl.offsetHeight;
|
2118
|
+
let width = navEl.offsetWidth;
|
2119
|
+
// In order to animate the child menu, we need to set height on the nav element
|
2120
|
+
// so we can absolutely position the two menus and maintain the current menu's height
|
2121
|
+
this.renderer.setStyle(navEl, 'height', `${height}px`);
|
2122
|
+
this.renderer.setStyle(navEl, 'width', `${width}px`);
|
2123
|
+
this.renderer.addClass(this.el.nativeElement, 'open');
|
2124
|
+
setTimeout(() => {
|
2125
|
+
this.renderer.addClass(this.el.nativeElement, 'open-active');
|
2081
2126
|
});
|
2082
|
-
});
|
2083
|
-
}
|
2084
|
-
/**A wrapper around the default javascript confirm dialog to allow us to unit test dependent code.
|
2085
|
-
* Of course eventually we'd like to have pretty confirmations for everything, but in some cases it wasn't worth the extra time
|
2086
|
-
* so we're using this instead.
|
2087
|
-
*/
|
2088
|
-
confirm(prompt) {
|
2089
|
-
return Promise.resolve(confirm(prompt));
|
2090
|
-
}
|
2091
|
-
/**
|
2092
|
-
* Close the current window or a window instance if one is provided
|
2093
|
-
* @param windowInstance - Window to close (optional)
|
2094
|
-
*/
|
2095
|
-
closeWindow(windowInstance) {
|
2096
|
-
if (windowInstance) {
|
2097
|
-
windowInstance.close();
|
2098
2127
|
}
|
2099
2128
|
else {
|
2100
|
-
|
2129
|
+
// Re-add the listener once the child menu closes
|
2130
|
+
this.addKeydownListener();
|
2131
|
+
this.renderer.removeClass(this.el.nativeElement, 'open-active');
|
2132
|
+
setTimeout(() => {
|
2133
|
+
this.renderer.removeClass(this.el.nativeElement, 'open');
|
2134
|
+
// Reset the nav element's height to auto
|
2135
|
+
this.renderer.setStyle(navEl, 'height', '100%');
|
2136
|
+
this.selected = null;
|
2137
|
+
}, menuAnimationSpeed);
|
2101
2138
|
}
|
2102
2139
|
}
|
2103
|
-
getLocation() {
|
2104
|
-
return window.location.pathname + window.location.hash;
|
2105
|
-
}
|
2106
|
-
/** Get the current value of the full url, including protocol, host and path */
|
2107
|
-
getFullUrl() {
|
2108
|
-
return window.location.href;
|
2109
|
-
}
|
2110
|
-
/** Get the current value of the base url, including protocol, domain and port (if explicitly specified) */
|
2111
|
-
getBaseUrl() {
|
2112
|
-
return window.location.origin;
|
2113
|
-
}
|
2114
2140
|
/**
|
2115
|
-
*
|
2116
|
-
* NOT RECOMMENDED. Seek other options for reloading content within Angular before resorting to this.
|
2141
|
+
* Handle key presses to navigate the menu
|
2117
2142
|
*/
|
2118
|
-
|
2119
|
-
|
2143
|
+
keyNavigate(event) {
|
2144
|
+
var _a;
|
2145
|
+
if (this.enableKeyNav && event.target === ((_a = this.dropdownToggleButton) === null || _a === void 0 ? void 0 : _a.nativeElement)) {
|
2146
|
+
switch (event.key) {
|
2147
|
+
case 'ArrowUp':
|
2148
|
+
case 'Up':
|
2149
|
+
case 'ArrowDown':
|
2150
|
+
case 'Down':
|
2151
|
+
event.stopPropagation();
|
2152
|
+
event.preventDefault();
|
2153
|
+
this.moveHighlightedUpOrDown(event);
|
2154
|
+
break;
|
2155
|
+
case 'ArrowRight':
|
2156
|
+
case 'Right':
|
2157
|
+
event.stopPropagation();
|
2158
|
+
event.preventDefault();
|
2159
|
+
// Select the item if it has child items
|
2160
|
+
if (this.highlightedItem && this.highlightedItem.items) {
|
2161
|
+
this.selectItem(event, this.highlightedItem, true);
|
2162
|
+
}
|
2163
|
+
break;
|
2164
|
+
case 'ArrowLeft':
|
2165
|
+
case 'Left':
|
2166
|
+
event.stopPropagation();
|
2167
|
+
event.preventDefault();
|
2168
|
+
// Close the menu if it is a child menu
|
2169
|
+
if (this.parent) {
|
2170
|
+
this.back(event);
|
2171
|
+
}
|
2172
|
+
break;
|
2173
|
+
case ' ':
|
2174
|
+
case 'Spacebar':
|
2175
|
+
case 'Enter':
|
2176
|
+
// Prevent 'enter' from doing whatever it does on the currently focused element
|
2177
|
+
event.preventDefault();
|
2178
|
+
if (this.highlightedItemIndex > -1 && this.highlightedItem) {
|
2179
|
+
this.selectItem(event, this.highlightedItem, true);
|
2180
|
+
// If the header is highlighted
|
2181
|
+
}
|
2182
|
+
else if (this.highlightedItemIndex === -1) {
|
2183
|
+
// Close the menu if it's a child
|
2184
|
+
if (this.parent) {
|
2185
|
+
this.back(event);
|
2186
|
+
}
|
2187
|
+
}
|
2188
|
+
break;
|
2189
|
+
default:
|
2190
|
+
return;
|
2191
|
+
}
|
2192
|
+
}
|
2120
2193
|
}
|
2121
|
-
}
|
2122
|
-
WindowService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: WindowService, deps: [{ token: i1$2.Router }, { token: i1$2.ActivatedRoute }], target: i0.ɵɵFactoryTarget.Injectable });
|
2123
|
-
WindowService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: WindowService, providedIn: 'root' });
|
2124
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: WindowService, decorators: [{
|
2125
|
-
type: Injectable,
|
2126
|
-
args: [{
|
2127
|
-
providedIn: 'root'
|
2128
|
-
}]
|
2129
|
-
}], ctorParameters: function () { return [{ type: i1$2.Router }, { type: i1$2.ActivatedRoute }]; } });
|
2130
|
-
|
2131
|
-
class NavItemActiveDirective {
|
2132
2194
|
/**
|
2133
|
-
*
|
2134
|
-
*
|
2135
|
-
* the
|
2136
|
-
* see: https://angular.io/api/router/Router#isactive
|
2195
|
+
* Scroll to the item currently marked as 'is-selected'. Wait a tick for the
|
2196
|
+
* NgClassDirecitve or NavItemActiveDirective to respond to the model changes
|
2197
|
+
* and update the view.
|
2137
2198
|
*/
|
2138
|
-
|
2139
|
-
|
2140
|
-
|
2199
|
+
scrollToSelectedItem() {
|
2200
|
+
window.setTimeout(() => {
|
2201
|
+
const linkSelector = `li.is-selected`;
|
2202
|
+
this.scrollService.scrollToItem(`#${this.id}_list`, linkSelector);
|
2203
|
+
});
|
2204
|
+
}
|
2205
|
+
moveHighlightedUpOrDown(event) {
|
2206
|
+
switch (event.key) {
|
2207
|
+
case 'ArrowUp':
|
2208
|
+
case 'Up':
|
2209
|
+
if (this.highlightedItemIndex > -1) {
|
2210
|
+
this.highlightedItemIndex--;
|
2211
|
+
}
|
2212
|
+
break;
|
2213
|
+
case 'ArrowDown':
|
2214
|
+
case 'Down':
|
2215
|
+
if (this.highlightedItemIndex < this.selectableItems.length - 1) {
|
2216
|
+
this.highlightedItemIndex++;
|
2217
|
+
}
|
2218
|
+
break;
|
2219
|
+
default:
|
2220
|
+
return;
|
2221
|
+
}
|
2222
|
+
if (this.highlightedItemIndex > -1) {
|
2223
|
+
// Store the item at the current highlight index
|
2224
|
+
this.highlightedItem = this.selectableItems[this.highlightedItemIndex];
|
2141
2225
|
}
|
2142
2226
|
else {
|
2143
|
-
this.
|
2227
|
+
this.highlightedItem = null;
|
2144
2228
|
}
|
2145
|
-
this.
|
2229
|
+
this.scrollToHighlightedItem();
|
2146
2230
|
}
|
2147
2231
|
/**
|
2148
|
-
*
|
2149
|
-
|
2150
|
-
*
|
2151
|
-
|
2152
|
-
*
|
2232
|
+
* Scroll to the specified menu item.
|
2233
|
+
* If no item is provided, it will scroll to the first item.
|
2234
|
+
*
|
2235
|
+
* @param item The menu item to scroll to.
|
2236
|
+
* @memberof MenuComponent
|
2153
2237
|
*/
|
2154
|
-
|
2155
|
-
if (
|
2156
|
-
|
2157
|
-
this.
|
2158
|
-
|
2159
|
-
|
2160
|
-
constructor(router, el, renderer, route) {
|
2161
|
-
this.router = router;
|
2162
|
-
this.el = el;
|
2163
|
-
this.renderer = renderer;
|
2164
|
-
this.route = route;
|
2165
|
-
this._exact = true;
|
2166
|
-
/** Emits when the url becomes active */
|
2167
|
-
this.routerLinkActivated = new EventEmitter();
|
2168
|
-
/** Subject that emits when component is destroyed to unsubscribe from any subscriptions */
|
2169
|
-
this.destroyed = new Subject();
|
2170
|
-
}
|
2171
|
-
/** Check if url is active on NavigationEnd events */
|
2172
|
-
ngOnInit() {
|
2173
|
-
this.router.events.pipe(takeUntil(this.destroyed), filter(e => e instanceof NavigationEnd)).subscribe(() => {
|
2174
|
-
this.update();
|
2175
|
-
});
|
2238
|
+
scrollMenu(item) {
|
2239
|
+
if (this.items.length > 0 && this.id) {
|
2240
|
+
item = item ? item : this.items[0];
|
2241
|
+
let itemId = item.id ? item.id : MenuComponent.getIndexedItemId(this.items, item, this.id);
|
2242
|
+
this.scrollService.scrollItemCentered(`#${this.id}_list`, `#${itemId}`);
|
2243
|
+
}
|
2176
2244
|
}
|
2177
|
-
|
2178
|
-
this.
|
2179
|
-
this.destroyed.unsubscribe();
|
2245
|
+
scrollToHighlightedItem() {
|
2246
|
+
this.scrollMenu(this.highlightedItem);
|
2180
2247
|
}
|
2181
|
-
|
2182
|
-
|
2183
|
-
if (this.
|
2184
|
-
|
2185
|
-
|
2186
|
-
|
2187
|
-
|
2188
|
-
|
2189
|
-
|
2190
|
-
|
2248
|
+
addKeydownListener() {
|
2249
|
+
// Only attempt to add the listener if keyboard nav is enabled
|
2250
|
+
if (this.enableKeyNav) {
|
2251
|
+
// renderer.listen adds the listener and returns a function to remove it from the renderer.
|
2252
|
+
// The listener remains active until this function is called.
|
2253
|
+
this.removeKeydownListener = this.renderer.listen('document', 'keydown', (event) => this.keyNavigate(event));
|
2254
|
+
}
|
2255
|
+
}
|
2256
|
+
/**
|
2257
|
+
* Sets the menu item ids using its index if item doesn't already have one
|
2258
|
+
*/
|
2259
|
+
setItemIds() {
|
2260
|
+
if (this.items) {
|
2261
|
+
this.items.forEach((item, index) => {
|
2262
|
+
item.id = item.id ? item.id : this.id + '_item' + index;
|
2263
|
+
if (item.items) {
|
2264
|
+
item.items.forEach((childItem, childIndex) => {
|
2265
|
+
childItem.id = childItem.id ? childItem.id : this.id + '_item' + index + '-' + childIndex;
|
2266
|
+
});
|
2267
|
+
}
|
2268
|
+
});
|
2191
2269
|
}
|
2192
2270
|
}
|
2193
2271
|
}
|
2194
|
-
|
2195
|
-
NavItemActiveDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.9", type: NavItemActiveDirective, selector: "[ecNavItemActive]", inputs: { classValue: ["ecNavItemActive", "classValue"], exact: ["ecNavItemActiveExactMatch", "exact"], queryParams: ["ecNavItemActiveQueryParams", "queryParams"], url: ["ecNavItemActiveUrl", "url"] }, outputs: { routerLinkActivated: "routerLinkActivated" }, ngImport: i0 });
|
2196
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type:
|
2197
|
-
type:
|
2198
|
-
args: [{
|
2199
|
-
|
2200
|
-
|
2201
|
-
|
2202
|
-
type:
|
2203
|
-
args: ['
|
2204
|
-
}],
|
2205
|
-
type: Input
|
2206
|
-
|
2207
|
-
|
2208
|
-
|
2209
|
-
|
2210
|
-
}],
|
2211
|
-
type: Input
|
2212
|
-
|
2213
|
-
|
2272
|
+
MenuComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: MenuComponent, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: WindowService }, { token: ScrollService }], target: i0.ɵɵFactoryTarget.Component });
|
2273
|
+
MenuComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.9", type: MenuComponent, selector: "ec-menu", inputs: { id: "id", items: "items", selected: "selected", parent: "parent", templateType: "templateType", customMenuTemplate: "customMenuTemplate", title: "title", showNoItems: "showNoItems", noDataText: "noDataText", enableKeyNav: "enableKeyNav", highlightedItem: "highlightedItem", maintainSelectedItem: "maintainSelectedItem", truncateItems: "truncateItems", preserveIconSpace: "preserveIconSpace", dropdownToggleButton: "dropdownToggleButton" }, outputs: { selectedChanged: "selectedChanged", menuClosed: "menuClosed" }, host: { properties: { "attr.id": "this.attrId" } }, viewQueries: [{ propertyName: "labelTemplate", first: true, predicate: ["label"], descendants: true, static: true }, { propertyName: "iconAndLabelTemplate", first: true, predicate: ["iconAndLabel"], descendants: true, static: true }, { propertyName: "checkAndLabelTemplate", first: true, predicate: ["checkAndLabel"], descendants: true, static: true }, { propertyName: "iconLabelCaptionTemplate", first: true, predicate: ["iconLabelCaption"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<nav>\r\n <div class=\"parent\"\r\n [class.no-data]=\"showNoItems && (!items || items.length === 0)\">\r\n <header id=\"{{id}}_header\"\r\n class=\"text-heading-3 p-1\"\r\n [class.is-selected]=\"highlightedItemIndex === -1\"\r\n *ngIf=\"parent\"\r\n (click)=\"back($event)\">\r\n <div class=\"item-wrapper\">\r\n <i class=\"ec-icon icon-angle-down rotate-90 flex-shrink\"></i>\r\n <span class=\"label text-truncate flex-grow\">{{parent?.label}}</span>\r\n </div>\r\n </header>\r\n\r\n <ul id=\"{{id}}_list\"\r\n class=\"py-1\">\r\n <ng-container *ngFor=\"let item of items; index as i\">\r\n <ng-container *ngTemplateOutlet=\"itemTemplate; context: {$implicit: item, index: i}\"></ng-container>\r\n\r\n <!-- Show child items under parent item if the item is a heading or divided-section -->\r\n <ng-container *ngIf=\"item.items?.length && (item.display === 'heading' || item.display === 'divided-section')\">\r\n <ng-container *ngFor=\"let childItem of item.items; index as j; first as isFirst; last as isLast\"\r\n [ngTemplateOutlet]=\"itemTemplate\"\r\n [ngTemplateOutletContext]=\"{$implicit: childItem, index: i + '-' + j, isDividedSectionChild: item.display === 'divided-section', isFirst: isFirst, isLast: isLast}\">\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ul>\r\n\r\n <p class=\"no-data-message\">{{noDataText | translate}}</p>\r\n </div>\r\n\r\n <!-- Child menu (Rendered to the right) -->\r\n <ec-menu *ngIf=\"selected?.items && selected?.display !== 'heading' && selected?.display !== 'divided-section'\"\r\n id=\"{{id}}_child\"\r\n class=\"child\"\r\n [parent]=\"selected\"\r\n [items]=\"selected?.items\"\r\n [showNoItems]=\"true\"\r\n [templateType]=\"templateType\"\r\n [enableKeyNav]=\"true\"\r\n [truncateItems]=\"truncateItems\"\r\n (selectedChanged)=\"onSelection($event)\"\r\n (menuClosed)=\"toggleChildMenu(false)\">\r\n </ec-menu>\r\n</nav>\r\n\r\n<ng-template #itemTemplate\r\n let-item\r\n let-i=\"index\"\r\n let-isDividedSectionChild=\"isDividedSectionChild\"\r\n let-isFirst=\"isFirst\"\r\n let-isLast=\"isLast\">\r\n <li *ngIf=\"!(item.hideIfNoItems && !item.items?.length) && item.display !== 'divided-section'\"\r\n id=\"{{item.id || id + '_item' + i}}\"\r\n class=\"{{item.display || 'item'}} {{item.classList}}\"\r\n [class.divider-top]=\"item.display === 'divider-top' || (isDividedSectionChild && isFirst)\"\r\n [class.divider]=\"item.display === 'divider' || (isDividedSectionChild && isLast)\"\r\n [attr.disabled]=\"item.disabled\"\r\n [hidden]=\"item.hidden\"\r\n ecNavItemActive=\"is-selected\"\r\n [ecNavItemActiveQueryParams]=\"item.queryParams\"\r\n [ecNavItemActiveUrl]=\"item.url\"\r\n [ecNavItemActiveExactMatch]='item.isActiveExactMatch'\r\n (routerLinkActivated)=\"selectItem($event, item)\"\r\n [ngClass]=\"{'is-highlighted':(selected === item && item?.display !== 'heading') || highlightedItem === item, 'is-link': item.url, 'is-disabled': item.disabled, 'is-readonly': item.readonly, 'is-checked': item.checked, 'text-heading-3': item?.display === 'heading'}\"\r\n (click)=\"selectItem($event, item)\">\r\n\r\n <a *ngIf=\"item.url && !item.externalLink\"\r\n id=\"{{item.id}}_link\"\r\n title=\"{{truncateItems ? item.label : ''}}\"\r\n class=\"item-wrapper\"\r\n [routerLink]=\"item.url\"\r\n [queryParams]=\"item.queryParams || null\"\r\n target=\"{{item.target || '_self'}}\">\r\n <ng-container *ngTemplateOutlet=\"internalizedTemplate; context: {$implicit: item}\"></ng-container>\r\n </a>\r\n\r\n <a *ngIf=\"item.url && item.externalLink\"\r\n id=\"{{item.id}}_link\"\r\n title=\"{{truncateItems ? item.label : ''}}\"\r\n class=\"item-wrapper\"\r\n href=\"{{item.url}}\"\r\n target=\"{{item.target || '_self'}}\">\r\n <ng-container *ngTemplateOutlet=\"internalizedTemplate; context: {$implicit: item}\"></ng-container>\r\n </a>\r\n\r\n <div *ngIf=\"!item.url\"\r\n title=\"{{truncateItems ? item.label : ''}}\"\r\n class=\"item-wrapper\">\r\n <ng-container *ngTemplateOutlet=\"internalizedTemplate; context: {$implicit: item}\"></ng-container>\r\n </div>\r\n </li>\r\n</ng-template>\r\n\r\n<!-- 'label' Item Template -->\r\n<ng-template #label\r\n let-item>\r\n <span id=\"{{item.id}}_label\"\r\n class=\"label\"\r\n [class.text-truncate]=\"truncateItems\">{{item.label}}</span>\r\n\r\n <i class=\"ec-icon icon-angle-down rotate-270\"\r\n *ngIf=\"item?.items && item.display !== 'heading' && item.display !== 'divided-section'\"></i>\r\n</ng-template>\r\n\r\n<!-- 'checkAndLabel' Item Template -->\r\n<ng-template #checkAndLabel\r\n let-item>\r\n\r\n <i class=\"ec-icon icon-check ec-icon-sm\"\r\n *ngIf=\"item.display !== 'heading'\"></i>\r\n\r\n <i class=\"ec-icon {{item.icon}} ml-2\"\r\n *ngIf=\"item.icon\"></i>\r\n\r\n <span id=\"{{item.id}}_label\"\r\n class=\"label\"\r\n [class.text-truncate]=\"truncateItems\">{{item.label}}</span>\r\n\r\n <i class=\"ec-icon icon-angle-down rotate-270\"\r\n *ngIf=\"item?.items && item.display !== 'heading' && item.display !== 'divided-section'\"></i>\r\n</ng-template>\r\n\r\n<!-- 'iconAndLabel' Item Template -->\r\n<ng-template #iconAndLabel\r\n let-item>\r\n <!-- If menuItem.icon exists and is not blank, show the icon in the menu -->\r\n <i class=\"ec-icon {{item.icon}}\"\r\n *ngIf=\"(item.icon && item.icon !== '') || preserveIconSpace\"></i>\r\n\r\n <span id=\"{{item.id}}_label\"\r\n class=\"label\"\r\n [class.text-truncate]=\"truncateItems\">{{item.label}}</span>\r\n\r\n <i class=\"ec-icon icon-angle-down rotate-270\"\r\n *ngIf=\"item?.items && item.display !== 'heading' && item.display !== 'divided-section'\"></i>\r\n</ng-template>\r\n\r\n<ng-template #iconLabelCaption\r\n let-item>\r\n <i class=\"ec-icon {{item.icon}}\"\r\n *ngIf=\"(item.icon && item.icon !== '') || preserveIconSpace\"></i>\r\n <div *ngIf=\"item.display !== 'heading'\"\r\n class=\"label flex-grow\">\r\n <div id=\"{{item.id}}_label\"\r\n class=\"text-body-1\"\r\n [class.text-truncate]=\"truncateItems\">{{item.label}}</div>\r\n <div id=\"{{item.id}}_caption\"\r\n *ngIf=\"item.caption\"\r\n class=\"text-caption-1\"\r\n [class.text-truncate]=\"truncateItems\">{{item.caption}}</div>\r\n </div>\r\n <h3 *ngIf=\"item.display === 'heading'\"\r\n class=\"flex-grow text-heading-3 align-self-center\"\r\n [class.text-truncate]=\"truncateItems\">{{item.label}}</h3>\r\n <i class=\"ec-icon icon-angle-down rotate-270 align-self-center\"\r\n *ngIf=\"item?.items && item.display !== 'heading' && item.display !== 'divided-section'\"></i>\r\n</ng-template>", styles: ["@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(1turn)}}:host{display:block;font-size:var(--ec-menu-font-size, var(--ec-font-size-action));font-weight:400;background-color:var(--ec-menu-background-color, var(--ec-background-color))}:host.open>nav>.parent,:host.open>nav>.child{position:absolute;left:0;top:0;right:0;height:100%;transition:transform .25s ease}:host.open>nav>.parent{transform:translate(0)}:host.open>nav>.child{transform:translate(100%)}:host.open-active>nav>.parent{transform:translate(-100%)}:host.open-active>nav>.child{transform:translate(0)}:host(.bg-transparent){background-color:transparent}:host-context(.is-always-open){height:100%}:host-context(.is-always-open) .item-wrapper{padding-left:1rem;padding-right:1rem}nav{display:flex;position:relative;height:100%;overflow:hidden}.parent{display:flex;flex-direction:column;flex:auto;position:relative;max-width:100%}.parent>header{cursor:pointer}.parent>header.is-selected .item-wrapper,.parent>header.is-highlighted .item-wrapper{background-color:var(--ec-background-color-selected)}.parent>header:hover .item-wrapper{background-color:var(--ec-background-color-hover)}.parent.no-data ul{display:none}.parent.no-data .no-data-message{display:block}ul{padding:0;margin:0;list-style:none;flex:auto;height:100%;overflow-y:auto}ul li{cursor:pointer;padding:0 .25rem}ul li a{color:inherit;border-bottom:0;text-decoration:none}ul li.is-selected .item-wrapper,ul li.is-highlighted .item-wrapper{background-color:var(--ec-background-color-selected)}ul li:hover .item-wrapper{background-color:var(--ec-background-color-hover)}ul li:focus .item-wrapper{outline:none;background-color:var(--ec-color-disabled-dark);position:relative;z-index:1}ul li.is-disabled .item-wrapper{color:var(--ec-color-disabled-dark);opacity:var(--ec-form-control-opacity-disabled)}ul li.is-disabled,ul li.is-readonly{cursor:default}ul li.is-disabled .item-wrapper,ul li.is-readonly .item-wrapper{background-color:transparent;color:inherit}ul li.is-checked .icon-check{opacity:1}ul li.heading{cursor:default}ul li.heading .item-wrapper{background-color:transparent}ul li.heading:not(:first-child){margin-top:.5rem}ul li.divider:not(:last-child){border-bottom:1px solid var(--ec-border-color);padding-bottom:.25rem;margin-bottom:.25rem}ul li.divider-top:not(:first-child):not(.divider + .divider-top){border-top:1px solid var(--ec-border-color);padding-top:.25rem;margin-top:.25rem}ul li.indent-1 .item-wrapper{padding-left:1.5rem}ul li.indent-2 .item-wrapper{padding-left:2.5rem}ul li.indent-3 .item-wrapper{padding-left:3.5rem}.item-wrapper{cursor:inherit;line-height:1.25rem;min-height:1.75rem;padding:.25rem .5rem;border-radius:var(--ec-border-radius);display:flex;color:inherit}.item-wrapper .label{margin-right:auto}.item-wrapper .label+.ec-icon{margin-left:.5rem}.item-wrapper .ec-icon{margin-top:calc((1.25rem - var(--ec-font-size-icon)) / 2);flex:none}.item-wrapper .ec-icon+.label{margin-left:.5rem}.item-wrapper .ec-icon-sm{margin-top:calc((1.25rem - calc(var(--ec-font-size-icon) * .75)) / 2)}.item-wrapper .icon-check{opacity:0}.no-data-message{display:none;text-align:center;padding:1rem;color:var(--ec-color-hint-dark);margin-bottom:0;font-size:var(--ec-font-size-body)}:host-context(ec-tree) ul{overflow-x:hidden}:host-context(ec-tree) li.is-selected,:host-context(ec-tree) li.is-highlighted{font-weight:700;color:var(--ec-menu-color-highlighted, inherit)}:host-context(ec-tree) li.is-selected:not(:hover),:host-context(ec-tree) li.is-highlighted:not(:hover){background-color:transparent}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$2.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: NavItemActiveDirective, selector: "[ecNavItemActive]", inputs: ["ecNavItemActive", "ecNavItemActiveExactMatch", "ecNavItemActiveQueryParams", "ecNavItemActiveUrl"], outputs: ["routerLinkActivated"] }, { kind: "component", type: MenuComponent, selector: "ec-menu", inputs: ["id", "items", "selected", "parent", "templateType", "customMenuTemplate", "title", "showNoItems", "noDataText", "enableKeyNav", "highlightedItem", "maintainSelectedItem", "truncateItems", "preserveIconSpace", "dropdownToggleButton"], outputs: ["selectedChanged", "menuClosed"] }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }] });
|
2274
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: MenuComponent, decorators: [{
|
2275
|
+
type: Component,
|
2276
|
+
args: [{ selector: 'ec-menu', template: "<nav>\r\n <div class=\"parent\"\r\n [class.no-data]=\"showNoItems && (!items || items.length === 0)\">\r\n <header id=\"{{id}}_header\"\r\n class=\"text-heading-3 p-1\"\r\n [class.is-selected]=\"highlightedItemIndex === -1\"\r\n *ngIf=\"parent\"\r\n (click)=\"back($event)\">\r\n <div class=\"item-wrapper\">\r\n <i class=\"ec-icon icon-angle-down rotate-90 flex-shrink\"></i>\r\n <span class=\"label text-truncate flex-grow\">{{parent?.label}}</span>\r\n </div>\r\n </header>\r\n\r\n <ul id=\"{{id}}_list\"\r\n class=\"py-1\">\r\n <ng-container *ngFor=\"let item of items; index as i\">\r\n <ng-container *ngTemplateOutlet=\"itemTemplate; context: {$implicit: item, index: i}\"></ng-container>\r\n\r\n <!-- Show child items under parent item if the item is a heading or divided-section -->\r\n <ng-container *ngIf=\"item.items?.length && (item.display === 'heading' || item.display === 'divided-section')\">\r\n <ng-container *ngFor=\"let childItem of item.items; index as j; first as isFirst; last as isLast\"\r\n [ngTemplateOutlet]=\"itemTemplate\"\r\n [ngTemplateOutletContext]=\"{$implicit: childItem, index: i + '-' + j, isDividedSectionChild: item.display === 'divided-section', isFirst: isFirst, isLast: isLast}\">\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ul>\r\n\r\n <p class=\"no-data-message\">{{noDataText | translate}}</p>\r\n </div>\r\n\r\n <!-- Child menu (Rendered to the right) -->\r\n <ec-menu *ngIf=\"selected?.items && selected?.display !== 'heading' && selected?.display !== 'divided-section'\"\r\n id=\"{{id}}_child\"\r\n class=\"child\"\r\n [parent]=\"selected\"\r\n [items]=\"selected?.items\"\r\n [showNoItems]=\"true\"\r\n [templateType]=\"templateType\"\r\n [enableKeyNav]=\"true\"\r\n [truncateItems]=\"truncateItems\"\r\n (selectedChanged)=\"onSelection($event)\"\r\n (menuClosed)=\"toggleChildMenu(false)\">\r\n </ec-menu>\r\n</nav>\r\n\r\n<ng-template #itemTemplate\r\n let-item\r\n let-i=\"index\"\r\n let-isDividedSectionChild=\"isDividedSectionChild\"\r\n let-isFirst=\"isFirst\"\r\n let-isLast=\"isLast\">\r\n <li *ngIf=\"!(item.hideIfNoItems && !item.items?.length) && item.display !== 'divided-section'\"\r\n id=\"{{item.id || id + '_item' + i}}\"\r\n class=\"{{item.display || 'item'}} {{item.classList}}\"\r\n [class.divider-top]=\"item.display === 'divider-top' || (isDividedSectionChild && isFirst)\"\r\n [class.divider]=\"item.display === 'divider' || (isDividedSectionChild && isLast)\"\r\n [attr.disabled]=\"item.disabled\"\r\n [hidden]=\"item.hidden\"\r\n ecNavItemActive=\"is-selected\"\r\n [ecNavItemActiveQueryParams]=\"item.queryParams\"\r\n [ecNavItemActiveUrl]=\"item.url\"\r\n [ecNavItemActiveExactMatch]='item.isActiveExactMatch'\r\n (routerLinkActivated)=\"selectItem($event, item)\"\r\n [ngClass]=\"{'is-highlighted':(selected === item && item?.display !== 'heading') || highlightedItem === item, 'is-link': item.url, 'is-disabled': item.disabled, 'is-readonly': item.readonly, 'is-checked': item.checked, 'text-heading-3': item?.display === 'heading'}\"\r\n (click)=\"selectItem($event, item)\">\r\n\r\n <a *ngIf=\"item.url && !item.externalLink\"\r\n id=\"{{item.id}}_link\"\r\n title=\"{{truncateItems ? item.label : ''}}\"\r\n class=\"item-wrapper\"\r\n [routerLink]=\"item.url\"\r\n [queryParams]=\"item.queryParams || null\"\r\n target=\"{{item.target || '_self'}}\">\r\n <ng-container *ngTemplateOutlet=\"internalizedTemplate; context: {$implicit: item}\"></ng-container>\r\n </a>\r\n\r\n <a *ngIf=\"item.url && item.externalLink\"\r\n id=\"{{item.id}}_link\"\r\n title=\"{{truncateItems ? item.label : ''}}\"\r\n class=\"item-wrapper\"\r\n href=\"{{item.url}}\"\r\n target=\"{{item.target || '_self'}}\">\r\n <ng-container *ngTemplateOutlet=\"internalizedTemplate; context: {$implicit: item}\"></ng-container>\r\n </a>\r\n\r\n <div *ngIf=\"!item.url\"\r\n title=\"{{truncateItems ? item.label : ''}}\"\r\n class=\"item-wrapper\">\r\n <ng-container *ngTemplateOutlet=\"internalizedTemplate; context: {$implicit: item}\"></ng-container>\r\n </div>\r\n </li>\r\n</ng-template>\r\n\r\n<!-- 'label' Item Template -->\r\n<ng-template #label\r\n let-item>\r\n <span id=\"{{item.id}}_label\"\r\n class=\"label\"\r\n [class.text-truncate]=\"truncateItems\">{{item.label}}</span>\r\n\r\n <i class=\"ec-icon icon-angle-down rotate-270\"\r\n *ngIf=\"item?.items && item.display !== 'heading' && item.display !== 'divided-section'\"></i>\r\n</ng-template>\r\n\r\n<!-- 'checkAndLabel' Item Template -->\r\n<ng-template #checkAndLabel\r\n let-item>\r\n\r\n <i class=\"ec-icon icon-check ec-icon-sm\"\r\n *ngIf=\"item.display !== 'heading'\"></i>\r\n\r\n <i class=\"ec-icon {{item.icon}} ml-2\"\r\n *ngIf=\"item.icon\"></i>\r\n\r\n <span id=\"{{item.id}}_label\"\r\n class=\"label\"\r\n [class.text-truncate]=\"truncateItems\">{{item.label}}</span>\r\n\r\n <i class=\"ec-icon icon-angle-down rotate-270\"\r\n *ngIf=\"item?.items && item.display !== 'heading' && item.display !== 'divided-section'\"></i>\r\n</ng-template>\r\n\r\n<!-- 'iconAndLabel' Item Template -->\r\n<ng-template #iconAndLabel\r\n let-item>\r\n <!-- If menuItem.icon exists and is not blank, show the icon in the menu -->\r\n <i class=\"ec-icon {{item.icon}}\"\r\n *ngIf=\"(item.icon && item.icon !== '') || preserveIconSpace\"></i>\r\n\r\n <span id=\"{{item.id}}_label\"\r\n class=\"label\"\r\n [class.text-truncate]=\"truncateItems\">{{item.label}}</span>\r\n\r\n <i class=\"ec-icon icon-angle-down rotate-270\"\r\n *ngIf=\"item?.items && item.display !== 'heading' && item.display !== 'divided-section'\"></i>\r\n</ng-template>\r\n\r\n<ng-template #iconLabelCaption\r\n let-item>\r\n <i class=\"ec-icon {{item.icon}}\"\r\n *ngIf=\"(item.icon && item.icon !== '') || preserveIconSpace\"></i>\r\n <div *ngIf=\"item.display !== 'heading'\"\r\n class=\"label flex-grow\">\r\n <div id=\"{{item.id}}_label\"\r\n class=\"text-body-1\"\r\n [class.text-truncate]=\"truncateItems\">{{item.label}}</div>\r\n <div id=\"{{item.id}}_caption\"\r\n *ngIf=\"item.caption\"\r\n class=\"text-caption-1\"\r\n [class.text-truncate]=\"truncateItems\">{{item.caption}}</div>\r\n </div>\r\n <h3 *ngIf=\"item.display === 'heading'\"\r\n class=\"flex-grow text-heading-3 align-self-center\"\r\n [class.text-truncate]=\"truncateItems\">{{item.label}}</h3>\r\n <i class=\"ec-icon icon-angle-down rotate-270 align-self-center\"\r\n *ngIf=\"item?.items && item.display !== 'heading' && item.display !== 'divided-section'\"></i>\r\n</ng-template>", styles: ["@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(1turn)}}:host{display:block;font-size:var(--ec-menu-font-size, var(--ec-font-size-action));font-weight:400;background-color:var(--ec-menu-background-color, var(--ec-background-color))}:host.open>nav>.parent,:host.open>nav>.child{position:absolute;left:0;top:0;right:0;height:100%;transition:transform .25s ease}:host.open>nav>.parent{transform:translate(0)}:host.open>nav>.child{transform:translate(100%)}:host.open-active>nav>.parent{transform:translate(-100%)}:host.open-active>nav>.child{transform:translate(0)}:host(.bg-transparent){background-color:transparent}:host-context(.is-always-open){height:100%}:host-context(.is-always-open) .item-wrapper{padding-left:1rem;padding-right:1rem}nav{display:flex;position:relative;height:100%;overflow:hidden}.parent{display:flex;flex-direction:column;flex:auto;position:relative;max-width:100%}.parent>header{cursor:pointer}.parent>header.is-selected .item-wrapper,.parent>header.is-highlighted .item-wrapper{background-color:var(--ec-background-color-selected)}.parent>header:hover .item-wrapper{background-color:var(--ec-background-color-hover)}.parent.no-data ul{display:none}.parent.no-data .no-data-message{display:block}ul{padding:0;margin:0;list-style:none;flex:auto;height:100%;overflow-y:auto}ul li{cursor:pointer;padding:0 .25rem}ul li a{color:inherit;border-bottom:0;text-decoration:none}ul li.is-selected .item-wrapper,ul li.is-highlighted .item-wrapper{background-color:var(--ec-background-color-selected)}ul li:hover .item-wrapper{background-color:var(--ec-background-color-hover)}ul li:focus .item-wrapper{outline:none;background-color:var(--ec-color-disabled-dark);position:relative;z-index:1}ul li.is-disabled .item-wrapper{color:var(--ec-color-disabled-dark);opacity:var(--ec-form-control-opacity-disabled)}ul li.is-disabled,ul li.is-readonly{cursor:default}ul li.is-disabled .item-wrapper,ul li.is-readonly .item-wrapper{background-color:transparent;color:inherit}ul li.is-checked .icon-check{opacity:1}ul li.heading{cursor:default}ul li.heading .item-wrapper{background-color:transparent}ul li.heading:not(:first-child){margin-top:.5rem}ul li.divider:not(:last-child){border-bottom:1px solid var(--ec-border-color);padding-bottom:.25rem;margin-bottom:.25rem}ul li.divider-top:not(:first-child):not(.divider + .divider-top){border-top:1px solid var(--ec-border-color);padding-top:.25rem;margin-top:.25rem}ul li.indent-1 .item-wrapper{padding-left:1.5rem}ul li.indent-2 .item-wrapper{padding-left:2.5rem}ul li.indent-3 .item-wrapper{padding-left:3.5rem}.item-wrapper{cursor:inherit;line-height:1.25rem;min-height:1.75rem;padding:.25rem .5rem;border-radius:var(--ec-border-radius);display:flex;color:inherit}.item-wrapper .label{margin-right:auto}.item-wrapper .label+.ec-icon{margin-left:.5rem}.item-wrapper .ec-icon{margin-top:calc((1.25rem - var(--ec-font-size-icon)) / 2);flex:none}.item-wrapper .ec-icon+.label{margin-left:.5rem}.item-wrapper .ec-icon-sm{margin-top:calc((1.25rem - calc(var(--ec-font-size-icon) * .75)) / 2)}.item-wrapper .icon-check{opacity:0}.no-data-message{display:none;text-align:center;padding:1rem;color:var(--ec-color-hint-dark);margin-bottom:0;font-size:var(--ec-font-size-body)}:host-context(ec-tree) ul{overflow-x:hidden}:host-context(ec-tree) li.is-selected,:host-context(ec-tree) li.is-highlighted{font-weight:700;color:var(--ec-menu-color-highlighted, inherit)}:host-context(ec-tree) li.is-selected:not(:hover),:host-context(ec-tree) li.is-highlighted:not(:hover){background-color:transparent}\n"] }]
|
2277
|
+
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: WindowService }, { type: ScrollService }]; }, propDecorators: { id: [{
|
2278
|
+
type: Input
|
2279
|
+
}], attrId: [{
|
2280
|
+
type: HostBinding,
|
2281
|
+
args: ['attr.id']
|
2282
|
+
}], items: [{
|
2283
|
+
type: Input
|
2284
|
+
}], selected: [{
|
2285
|
+
type: Input
|
2286
|
+
}], parent: [{
|
2287
|
+
type: Input
|
2288
|
+
}], templateType: [{
|
2289
|
+
type: Input
|
2290
|
+
}], customMenuTemplate: [{
|
2291
|
+
type: Input
|
2292
|
+
}], title: [{
|
2293
|
+
type: Input
|
2294
|
+
}], showNoItems: [{
|
2295
|
+
type: Input
|
2296
|
+
}], noDataText: [{
|
2297
|
+
type: Input
|
2298
|
+
}], enableKeyNav: [{
|
2299
|
+
type: Input
|
2300
|
+
}], highlightedItem: [{
|
2301
|
+
type: Input
|
2302
|
+
}], maintainSelectedItem: [{
|
2303
|
+
type: Input
|
2304
|
+
}], truncateItems: [{
|
2305
|
+
type: Input
|
2306
|
+
}], preserveIconSpace: [{
|
2307
|
+
type: Input
|
2308
|
+
}], dropdownToggleButton: [{
|
2309
|
+
type: Input
|
2310
|
+
}], selectedChanged: [{
|
2311
|
+
type: Output
|
2312
|
+
}], menuClosed: [{
|
2214
2313
|
type: Output
|
2314
|
+
}], labelTemplate: [{
|
2315
|
+
type: ViewChild,
|
2316
|
+
args: ['label', { static: true }]
|
2317
|
+
}], iconAndLabelTemplate: [{
|
2318
|
+
type: ViewChild,
|
2319
|
+
args: ['iconAndLabel', { static: true }]
|
2320
|
+
}], checkAndLabelTemplate: [{
|
2321
|
+
type: ViewChild,
|
2322
|
+
args: ['checkAndLabel', { static: true }]
|
2323
|
+
}], iconLabelCaptionTemplate: [{
|
2324
|
+
type: ViewChild,
|
2325
|
+
args: ['iconLabelCaption', { static: true }]
|
2215
2326
|
}] } });
|
2216
2327
|
|
2217
|
-
;
|
2218
|
-
const menuAnimationSpeed = 350;
|
2219
2328
|
/**
|
2220
|
-
* Primitive
|
2329
|
+
* Primitive directive that popups a container using PopperJS
|
2221
2330
|
*
|
2222
2331
|
* @export
|
2223
2332
|
*/
|
2224
|
-
class
|
2225
|
-
|
2226
|
-
|
2333
|
+
class PopupContainerDirective {
|
2334
|
+
/**
|
2335
|
+
* Creates an instance of PopupContainerDirective.
|
2336
|
+
* @param templateRef Reference to the popup template
|
2337
|
+
* @param viewContainer Reference to the view container
|
2338
|
+
* @param document Reference to Document
|
2339
|
+
* @memberof PopupContainerDirective
|
2340
|
+
*/
|
2341
|
+
constructor(templateRef, viewContainer, document, renderer) {
|
2342
|
+
this.templateRef = templateRef;
|
2343
|
+
this.viewContainer = viewContainer;
|
2344
|
+
this.document = document;
|
2227
2345
|
this.renderer = renderer;
|
2228
|
-
this.windowService = windowService;
|
2229
|
-
this.scrollService = scrollService;
|
2230
|
-
/**
|
2231
|
-
* Array of items to display
|
2232
|
-
*
|
2233
|
-
* @memberof MenuComponent
|
2234
|
-
*/
|
2235
|
-
this.items = [];
|
2236
|
-
/**
|
2237
|
-
* Selected item; annotates the item
|
2238
|
-
* when displayed with 'selected' class
|
2239
|
-
*
|
2240
|
-
* @memberof MenuComponent
|
2241
|
-
*/
|
2242
|
-
this.selected = null;
|
2243
|
-
/**
|
2244
|
-
* Display template
|
2245
|
-
*
|
2246
|
-
* @memberof MenuComponent
|
2247
|
-
*/
|
2248
|
-
this.templateType = 'label';
|
2249
|
-
/**
|
2250
|
-
* Show message when there are no items
|
2251
|
-
*/
|
2252
|
-
this.showNoItems = false;
|
2253
|
-
/**
|
2254
|
-
* Text to show when menu is empty and showNoItems is true
|
2255
|
-
*/
|
2256
|
-
this.noDataText = 'NoItems_TC';
|
2257
|
-
/**
|
2258
|
-
* Controls whether keyboard navigation is enabled
|
2259
|
-
*/
|
2260
|
-
this.enableKeyNav = false;
|
2261
|
-
/**
|
2262
|
-
* Item currently highlighted by keyboard navigation
|
2263
|
-
*/
|
2264
|
-
this.highlightedItem = null;
|
2265
|
-
/**
|
2266
|
-
* Tells the menu to maintain the selected/lastSelected item. Turning this off is useful for
|
2267
|
-
* action type menus that are displayed on the screen at all times and you do not
|
2268
|
-
* want the item to be selected when clicked.
|
2269
|
-
*/
|
2270
|
-
this.maintainSelectedItem = true;
|
2271
|
-
/**
|
2272
|
-
* Will prevent text-wrapping of menu items and truncate instead. Also turns on a tooltip for the menu item. Default: false;
|
2273
|
-
*/
|
2274
|
-
this.truncateItems = false;
|
2275
|
-
/**
|
2276
|
-
* When true, the space for the icon is preserved for menu items that do not have icons.
|
2277
|
-
* Only applicable for iconAndLabel menus.
|
2278
|
-
*/
|
2279
|
-
this.preserveIconSpace = false;
|
2280
|
-
/**
|
2281
|
-
* Emitted when `selected` is changed. Emits the referenced object.
|
2282
|
-
*
|
2283
|
-
* @memberof MenuComponent
|
2284
|
-
*/
|
2285
|
-
this.selectedChanged = new EventEmitter();
|
2286
|
-
/**
|
2287
|
-
* Emitted when the menu has a parent and back is clicked
|
2288
|
-
* @memberof MenuComponent
|
2289
|
-
*/
|
2290
|
-
this.menuClosed = new EventEmitter();
|
2291
|
-
/**
|
2292
|
-
* Index of the item currently highlighted using keyboard nav
|
2293
|
-
*/
|
2294
|
-
this.highlightedItemIndex = -1;
|
2295
2346
|
/**
|
2296
|
-
*
|
2297
|
-
* This isn't necessarily the same as this.selected, because this.selected is an input property
|
2298
|
-
* and could have been changed by a consumer through some means other than selectItem().
|
2299
|
-
* This allows us to prevent double-calls to selectItem() with the same input.
|
2347
|
+
* Emit the {@link PopupStatus} when it changes
|
2300
2348
|
*/
|
2301
|
-
this.
|
2349
|
+
this.popperStatusChange = new EventEmitter();
|
2302
2350
|
}
|
2303
2351
|
/**
|
2304
|
-
*
|
2305
|
-
*
|
2306
|
-
|
2352
|
+
* Angular onInit lifecycle hook
|
2353
|
+
* @see https://angular.io/guide/lifecycle-hooks
|
2354
|
+
*/
|
2355
|
+
ngOnInit() {
|
2356
|
+
this.templateViewRef = this.viewContainer.createEmbeddedView(this.templateRef);
|
2357
|
+
}
|
2358
|
+
/**
|
2359
|
+
* Angular onDestroy lifecycle hook. Close and delete references. Unsubscribe observables
|
2360
|
+
* @see https://angular.io/guide/lifecycle-hooks
|
2361
|
+
*/
|
2362
|
+
ngOnDestroy() {
|
2363
|
+
this.hide();
|
2364
|
+
}
|
2365
|
+
/**
|
2366
|
+
* Displays the templateRef as a popup
|
2307
2367
|
*
|
2308
|
-
* @memberof
|
2368
|
+
* @memberof PopupContainerDirective
|
2309
2369
|
*/
|
2310
|
-
|
2311
|
-
|
2312
|
-
|
2313
|
-
|
2314
|
-
|
2315
|
-
|
2316
|
-
this.internalizedTemplate = this.iconAndLabelTemplate;
|
2317
|
-
break;
|
2318
|
-
case ("checkAndLabel"):
|
2319
|
-
this.internalizedTemplate = this.checkAndLabelTemplate;
|
2320
|
-
break;
|
2321
|
-
case ("iconLabelCaption"):
|
2322
|
-
this.internalizedTemplate = this.iconLabelCaptionTemplate;
|
2323
|
-
break;
|
2324
|
-
default:
|
2325
|
-
throw new Error(`Invalid templateType for MenuComponent. Please use either: 'label', 'iconAndLabel' or 'checkAndLabel'`);
|
2326
|
-
}
|
2327
|
-
//if the consumer provided a menuItemTemplate, override the internalizedTemplate with that.
|
2328
|
-
if (this.customMenuTemplate) {
|
2329
|
-
this.internalizedTemplate = this.customMenuTemplate;
|
2370
|
+
show() {
|
2371
|
+
if (PopupContainerDirective.GlobalPopupRef) {
|
2372
|
+
if (PopupContainerDirective.GlobalPopupRef != this) {
|
2373
|
+
PopupContainerDirective.GlobalPopupRef.hide();
|
2374
|
+
PopupContainerDirective.GlobalPopupRef = undefined;
|
2375
|
+
}
|
2330
2376
|
}
|
2331
|
-
if (this.
|
2332
|
-
this.
|
2377
|
+
if (!this.globalCloseSubscription) {
|
2378
|
+
this.globalCloseSubscription = fromEvent(this.document.body, "click").subscribe((event) => {
|
2379
|
+
this.hide();
|
2380
|
+
});
|
2333
2381
|
}
|
2334
|
-
this.
|
2335
|
-
|
2336
|
-
|
2382
|
+
if (!this.popperRef) {
|
2383
|
+
// Add the popper template as an embedded view since PopperJS
|
2384
|
+
// manipulates DOM elements.
|
2385
|
+
this.popupViewRef = this.viewContainer.createEmbeddedView(this.popup);
|
2386
|
+
// Since popper needs real DOM elements, grab the first non-comment
|
2387
|
+
// DOM element to use as our anchor.
|
2388
|
+
let anchorElement = this.popupViewRef.rootNodes.find(elem => { return elem.nodeName !== "#text"; });
|
2389
|
+
// Use the parents elements as our DOM elements to Popper
|
2390
|
+
this.popperRef = new Popper(this.templateViewRef.rootNodes[0], anchorElement, this.popperOptions);
|
2391
|
+
PopupContainerDirective.GlobalPopupRef = this;
|
2392
|
+
this.popperStatusChange.emit('visible');
|
2337
2393
|
}
|
2338
|
-
this.addKeydownListener();
|
2339
2394
|
}
|
2340
|
-
|
2341
|
-
|
2342
|
-
|
2343
|
-
|
2395
|
+
/**
|
2396
|
+
* Hides the templateRef
|
2397
|
+
*
|
2398
|
+
* @memberof PopupContainerDirective
|
2399
|
+
*/
|
2400
|
+
hide() {
|
2401
|
+
if (this.globalCloseSubscription) {
|
2402
|
+
this.globalCloseSubscription.unsubscribe();
|
2403
|
+
this.globalCloseSubscription = undefined;
|
2404
|
+
}
|
2405
|
+
if (this.popperRef && this.popupViewRef) {
|
2406
|
+
this.popupViewRef.destroy();
|
2407
|
+
this.popperRef.destroy();
|
2408
|
+
this.popperRef = undefined;
|
2409
|
+
this.popperStatusChange.emit('hidden');
|
2344
2410
|
}
|
2345
2411
|
}
|
2346
2412
|
/**
|
2347
|
-
*
|
2348
|
-
* the item's click method if defined, or emit the selected item.
|
2349
|
-
*
|
2350
|
-
* @param item The selected item
|
2351
|
-
* @memberof MenuComponent
|
2413
|
+
* Updates the popup container position
|
2352
2414
|
*/
|
2353
|
-
|
2354
|
-
|
2355
|
-
|
2356
|
-
|
2357
|
-
|
2358
|
-
|
2359
|
-
if (
|
2360
|
-
|
2361
|
-
|
2362
|
-
|
2363
|
-
|
2364
|
-
|
2365
|
-
|
2366
|
-
|
2367
|
-
|
2368
|
-
|
2415
|
+
update() {
|
2416
|
+
if (this.popperRef) {
|
2417
|
+
this.popperRef.update();
|
2418
|
+
}
|
2419
|
+
}
|
2420
|
+
fixPosition(minWidthNone, appendToBody = false) {
|
2421
|
+
if (this.popperRef && this.popperRef['reference'] && this.popperRef['popper']) {
|
2422
|
+
let popupEl = this.popperRef['popper'];
|
2423
|
+
// Reset width style previously assigned because the content may have
|
2424
|
+
// changed and the auto width would be different
|
2425
|
+
this.renderer.removeStyle(popupEl, 'width');
|
2426
|
+
this.renderer.setStyle(popupEl, 'position', 'fixed');
|
2427
|
+
if (appendToBody) {
|
2428
|
+
const bodyEl = this.document.querySelector('body');
|
2429
|
+
const popupParent = this.renderer.parentNode(popupEl);
|
2430
|
+
if (popupParent !== bodyEl) {
|
2431
|
+
this.renderer.appendChild(bodyEl, popupEl);
|
2369
2432
|
}
|
2370
|
-
// We need to manually handle the url navigation if the keyboard was used
|
2371
2433
|
}
|
2372
|
-
|
2373
|
-
|
2374
|
-
|
2434
|
+
let toggleEl = this.popperRef['reference'];
|
2435
|
+
let width = popupEl.offsetWidth;
|
2436
|
+
let boundaries = popupEl.getBoundingClientRect();
|
2437
|
+
let left = boundaries.left;
|
2438
|
+
let coords = toggleEl.getBoundingClientRect();
|
2439
|
+
// Set the top of our menu to the bottom of the toggle element
|
2440
|
+
let top = coords.bottom;
|
2441
|
+
if (this.popperOptions && this.popperOptions.placement) {
|
2442
|
+
if (this.popperOptions.placement === 'bottom-start' || this.popperOptions.placement === 'top-start') {
|
2443
|
+
left = coords.left;
|
2375
2444
|
}
|
2376
2445
|
else {
|
2377
|
-
|
2446
|
+
left = coords.right - ((minWidthNone || width > coords.width) ? width : coords.width);
|
2378
2447
|
}
|
2379
|
-
// Emit so upstream components know an item was selected
|
2380
|
-
this.onSelection(item);
|
2381
|
-
}
|
2382
|
-
else {
|
2383
|
-
this.onSelection(item);
|
2384
2448
|
}
|
2385
|
-
if (
|
2386
|
-
|
2387
|
-
|
2449
|
+
// if it won't fit (with 10px space before hitting the window edge), flip it
|
2450
|
+
if (boundaries.height + top + 10 > window.innerHeight) {
|
2451
|
+
top = coords.top - boundaries.height;
|
2388
2452
|
}
|
2389
|
-
|
2390
|
-
|
2391
|
-
|
2453
|
+
this.renderer.setStyle(popupEl, 'transform', 'none');
|
2454
|
+
this.renderer.setStyle(popupEl, 'left', left + 'px');
|
2455
|
+
this.renderer.setStyle(popupEl, 'top', top + 'px');
|
2456
|
+
this.renderer.setStyle(popupEl, 'width', width + 'px');
|
2457
|
+
if (!minWidthNone) {
|
2458
|
+
this.renderer.setStyle(popupEl, 'min-width', coords.width + 'px');
|
2392
2459
|
}
|
2393
2460
|
}
|
2394
2461
|
}
|
2395
|
-
|
2396
|
-
|
2397
|
-
|
2398
|
-
|
2399
|
-
|
2400
|
-
|
2401
|
-
|
2402
|
-
|
2462
|
+
}
|
2463
|
+
/**
|
2464
|
+
* Global reference to the currently displayed popup; only
|
2465
|
+
* one popup directive can be in `show` state at a given time.
|
2466
|
+
*
|
2467
|
+
* @memberof PopupContainerDirective
|
2468
|
+
*/
|
2469
|
+
PopupContainerDirective.GlobalPopupRef = undefined;
|
2470
|
+
PopupContainerDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: PopupContainerDirective, deps: [{ token: i0.TemplateRef }, { token: i0.ViewContainerRef }, { token: DOCUMENT }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive });
|
2471
|
+
PopupContainerDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.9", type: PopupContainerDirective, selector: "[ecPopup]", inputs: { popup: ["ecPopup", "popup"], popperOptions: ["options", "popperOptions"] }, ngImport: i0 });
|
2472
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: PopupContainerDirective, decorators: [{
|
2473
|
+
type: Directive,
|
2474
|
+
args: [{ selector: '[ecPopup]' }]
|
2475
|
+
}], ctorParameters: function () {
|
2476
|
+
return [{ type: i0.TemplateRef }, { type: i0.ViewContainerRef }, { type: undefined, decorators: [{
|
2477
|
+
type: Inject,
|
2478
|
+
args: [DOCUMENT]
|
2479
|
+
}] }, { type: i0.Renderer2 }];
|
2480
|
+
}, propDecorators: { popup: [{
|
2481
|
+
type: Input,
|
2482
|
+
args: ['ecPopup']
|
2483
|
+
}], popperOptions: [{
|
2484
|
+
type: Input,
|
2485
|
+
args: ['options']
|
2486
|
+
}] } });
|
2487
|
+
|
2488
|
+
/** Advanced validation for textbox form controls */
|
2489
|
+
const textboxValidation = (validatorParams) => {
|
2490
|
+
return (control) => {
|
2491
|
+
let validators = [];
|
2492
|
+
// Innocent until proven guilty
|
2493
|
+
validatorParams.valid = true;
|
2494
|
+
if (validatorParams.required) {
|
2495
|
+
validators.push(Validators.required);
|
2403
2496
|
}
|
2404
|
-
|
2405
|
-
|
2406
|
-
/**
|
2407
|
-
* Emit the selected item
|
2408
|
-
* @param item The selected item
|
2409
|
-
*/
|
2410
|
-
onSelection(item) {
|
2411
|
-
if (item.display !== 'heading') {
|
2412
|
-
this.selectedChanged.emit(item);
|
2497
|
+
if (validatorParams.minLength !== undefined) {
|
2498
|
+
validators.push(Validators.minLength(validatorParams.minLength));
|
2413
2499
|
}
|
2414
|
-
|
2415
|
-
|
2416
|
-
* Open or close the child menu. When the child menu closes, the selected
|
2417
|
-
* item is reset.
|
2418
|
-
* @memberof MenuComponent
|
2419
|
-
*/
|
2420
|
-
toggleChildMenu(open) {
|
2421
|
-
let navEl = this.el.nativeElement.querySelector('nav');
|
2422
|
-
if (open) {
|
2423
|
-
// Remove the listener on the parent menu when a child menu is opened
|
2424
|
-
// This is to avoid interference between the parent and child menus
|
2425
|
-
if (this.removeKeydownListener) {
|
2426
|
-
this.removeKeydownListener();
|
2427
|
-
}
|
2428
|
-
let height = navEl.offsetHeight;
|
2429
|
-
let width = navEl.offsetWidth;
|
2430
|
-
// In order to animate the child menu, we need to set height on the nav element
|
2431
|
-
// so we can absolutely position the two menus and maintain the current menu's height
|
2432
|
-
this.renderer.setStyle(navEl, 'height', `${height}px`);
|
2433
|
-
this.renderer.setStyle(navEl, 'width', `${width}px`);
|
2434
|
-
this.renderer.addClass(this.el.nativeElement, 'open');
|
2435
|
-
setTimeout(() => {
|
2436
|
-
this.renderer.addClass(this.el.nativeElement, 'open-active');
|
2437
|
-
});
|
2500
|
+
if (validatorParams.maxLength !== undefined) {
|
2501
|
+
validators.push(Validators.maxLength(validatorParams.maxLength));
|
2438
2502
|
}
|
2439
|
-
|
2440
|
-
|
2441
|
-
this.addKeydownListener();
|
2442
|
-
this.renderer.removeClass(this.el.nativeElement, 'open-active');
|
2443
|
-
setTimeout(() => {
|
2444
|
-
this.renderer.removeClass(this.el.nativeElement, 'open');
|
2445
|
-
// Reset the nav element's height to auto
|
2446
|
-
this.renderer.setStyle(navEl, 'height', '100%');
|
2447
|
-
this.selected = null;
|
2448
|
-
}, menuAnimationSpeed);
|
2503
|
+
if (validatorParams.pattern !== undefined) {
|
2504
|
+
validators.push(Validators.pattern(validatorParams.pattern));
|
2449
2505
|
}
|
2450
|
-
|
2451
|
-
|
2452
|
-
|
2453
|
-
|
2454
|
-
keyNavigate(event) {
|
2455
|
-
var _a;
|
2456
|
-
if (this.enableKeyNav && event.target === ((_a = this.dropdownToggleButton) === null || _a === void 0 ? void 0 : _a.nativeElement)) {
|
2457
|
-
switch (event.key) {
|
2458
|
-
case 'ArrowUp':
|
2459
|
-
case 'Up':
|
2460
|
-
case 'ArrowDown':
|
2461
|
-
case 'Down':
|
2462
|
-
event.stopPropagation();
|
2463
|
-
event.preventDefault();
|
2464
|
-
this.moveHighlightedUpOrDown(event);
|
2465
|
-
break;
|
2466
|
-
case 'ArrowRight':
|
2467
|
-
case 'Right':
|
2468
|
-
event.stopPropagation();
|
2469
|
-
event.preventDefault();
|
2470
|
-
// Select the item if it has child items
|
2471
|
-
if (this.highlightedItem && this.highlightedItem.items) {
|
2472
|
-
this.selectItem(event, this.highlightedItem, true);
|
2473
|
-
}
|
2474
|
-
break;
|
2475
|
-
case 'ArrowLeft':
|
2476
|
-
case 'Left':
|
2477
|
-
event.stopPropagation();
|
2478
|
-
event.preventDefault();
|
2479
|
-
// Close the menu if it is a child menu
|
2480
|
-
if (this.parent) {
|
2481
|
-
this.back(event);
|
2482
|
-
}
|
2483
|
-
break;
|
2484
|
-
case ' ':
|
2485
|
-
case 'Spacebar':
|
2486
|
-
case 'Enter':
|
2487
|
-
// Prevent 'enter' from doing whatever it does on the currently focused element
|
2488
|
-
event.preventDefault();
|
2489
|
-
if (this.highlightedItemIndex > -1 && this.highlightedItem) {
|
2490
|
-
this.selectItem(event, this.highlightedItem, true);
|
2491
|
-
// If the header is highlighted
|
2492
|
-
}
|
2493
|
-
else if (this.highlightedItemIndex === -1) {
|
2494
|
-
// Close the menu if it's a child
|
2495
|
-
if (this.parent) {
|
2496
|
-
this.back(event);
|
2497
|
-
}
|
2498
|
-
}
|
2499
|
-
break;
|
2500
|
-
default:
|
2501
|
-
return;
|
2506
|
+
validators.forEach(validator => {
|
2507
|
+
let validationResult = validator(control);
|
2508
|
+
if (validationResult) {
|
2509
|
+
validatorParams.valid = false;
|
2502
2510
|
}
|
2511
|
+
});
|
2512
|
+
if (validatorParams.valid) {
|
2513
|
+
return null;
|
2514
|
+
}
|
2515
|
+
else {
|
2516
|
+
return {
|
2517
|
+
textbox: validatorParams
|
2518
|
+
};
|
2503
2519
|
}
|
2520
|
+
};
|
2521
|
+
};
|
2522
|
+
const phoneNumberValidationPattern = '^\\s*(?:\\+?(\\d{1,3}))?[-. (]*(\\d{3})[-. )]*(\\d{3})[-. ]*(\\d{4})(?: *x(\\d+))?\\s*$';
|
2523
|
+
const urlValidationPattern = '([A-Za-z])+(:\/\/)+[^\\s]*';
|
2524
|
+
class TextboxComponent extends FormControlBase {
|
2525
|
+
constructor(validationMessageService, formGroupHelper, translate) {
|
2526
|
+
super(validationMessageService, formGroupHelper);
|
2527
|
+
this.validationMessageService = validationMessageService;
|
2528
|
+
this.formGroupHelper = formGroupHelper;
|
2529
|
+
this.translate = translate;
|
2530
|
+
/**
|
2531
|
+
* Set the value of the input's autocomplete attribute
|
2532
|
+
*/
|
2533
|
+
this.autocomplete = 'off';
|
2534
|
+
/**
|
2535
|
+
* The textbox type
|
2536
|
+
*/
|
2537
|
+
this.type = "text";
|
2538
|
+
/**
|
2539
|
+
* The value of the rows attribute for a textarea. Only applies to multi-line type
|
2540
|
+
*/
|
2541
|
+
this.rows = 3;
|
2542
|
+
/**
|
2543
|
+
* If set to true, we will select all text within the input if
|
2544
|
+
* autofocus is also set to true
|
2545
|
+
*/
|
2546
|
+
this.selectOnAutofocus = false;
|
2547
|
+
/**
|
2548
|
+
* If set to true, we will upper case on focus out
|
2549
|
+
*/
|
2550
|
+
this.upperCase = false;
|
2551
|
+
/**
|
2552
|
+
* Validation pattern for the input. This is determined on the input type specified
|
2553
|
+
*/
|
2554
|
+
this.validationPattern = '';
|
2555
|
+
}
|
2556
|
+
ngOnChanges(changes) {
|
2557
|
+
super.ngOnChanges(changes);
|
2504
2558
|
}
|
2505
2559
|
/**
|
2506
|
-
*
|
2507
|
-
* NgClassDirecitve or NavItemActiveDirective to respond to the model changes
|
2508
|
-
* and update the view.
|
2560
|
+
* The angular onInit lifecycle hook
|
2509
2561
|
*/
|
2510
|
-
|
2511
|
-
|
2512
|
-
|
2513
|
-
|
2514
|
-
|
2515
|
-
}
|
2516
|
-
moveHighlightedUpOrDown(event) {
|
2517
|
-
switch (event.key) {
|
2518
|
-
case 'ArrowUp':
|
2519
|
-
case 'Up':
|
2520
|
-
if (this.highlightedItemIndex > -1) {
|
2521
|
-
this.highlightedItemIndex--;
|
2522
|
-
// Skip any in-menu heading items
|
2523
|
-
if (this.highlightedItemIndex > -1 && this.items[this.highlightedItemIndex].display === 'heading') {
|
2524
|
-
this.highlightedItemIndex--;
|
2525
|
-
}
|
2526
|
-
}
|
2527
|
-
break;
|
2528
|
-
case 'ArrowDown':
|
2529
|
-
case 'Down':
|
2530
|
-
if (this.highlightedItemIndex < this.items.length - 1) {
|
2531
|
-
this.highlightedItemIndex++;
|
2532
|
-
// Skip any in-menu heading items
|
2533
|
-
if (this.highlightedItemIndex < this.items.length - 1 && this.items[this.highlightedItemIndex].display === 'heading') {
|
2534
|
-
this.highlightedItemIndex++;
|
2535
|
-
}
|
2536
|
-
}
|
2537
|
-
break;
|
2538
|
-
default:
|
2539
|
-
return;
|
2562
|
+
ngOnInit() {
|
2563
|
+
super.ngOnInit();
|
2564
|
+
this.validationPattern = '';
|
2565
|
+
if (this.type === 'tel') {
|
2566
|
+
this.validationPattern = phoneNumberValidationPattern;
|
2540
2567
|
}
|
2541
|
-
if (this.
|
2542
|
-
|
2543
|
-
this.highlightedItem = this.items[this.highlightedItemIndex];
|
2568
|
+
else if (this.type === 'url') {
|
2569
|
+
this.validationPattern = urlValidationPattern;
|
2544
2570
|
}
|
2545
|
-
|
2546
|
-
this.
|
2571
|
+
if (this.placeholder) {
|
2572
|
+
this.translate.get(this.placeholder)
|
2573
|
+
.subscribe((translated) => {
|
2574
|
+
this.placeholder = translated;
|
2575
|
+
});
|
2547
2576
|
}
|
2548
|
-
this.scrollToHighlightedItem();
|
2549
2577
|
}
|
2550
2578
|
/**
|
2551
|
-
*
|
2552
|
-
* If no item is provided, it will scroll to the first item.
|
2553
|
-
*
|
2554
|
-
* @param item The menu item to scroll to.
|
2555
|
-
* @memberof MenuComponent
|
2579
|
+
* The angular afterViewInit lifecycle hook
|
2556
2580
|
*/
|
2557
|
-
|
2558
|
-
if (this.
|
2559
|
-
|
2560
|
-
let itemIndex = this.findItemIndex(item);
|
2561
|
-
if (this.id) {
|
2562
|
-
let itemSelector = item.id ? `#${item.id}` : `#${this.id}_item${itemIndex}`;
|
2563
|
-
this.scrollService.scrollItemCentered(`#${this.id}_list`, itemSelector);
|
2564
|
-
}
|
2581
|
+
ngAfterViewInit() {
|
2582
|
+
if (this.autofocus) {
|
2583
|
+
this.setFocus(this.selectOnAutofocus);
|
2565
2584
|
}
|
2566
2585
|
}
|
2567
|
-
scrollToHighlightedItem() {
|
2568
|
-
this.scrollMenu(this.highlightedItem);
|
2569
|
-
}
|
2570
2586
|
/**
|
2571
|
-
*
|
2572
|
-
*
|
2573
|
-
*
|
2574
|
-
* @param itemToFind The matching item to find in the items array.
|
2575
|
-
* @memberof MenuComponent
|
2587
|
+
* Function to set focus on an input programmatically after the page
|
2588
|
+
* had been rendered. The highlight text flag will select the text
|
2589
|
+
* within the input if passed in and true
|
2576
2590
|
*/
|
2577
|
-
|
2578
|
-
|
2579
|
-
|
2580
|
-
|
2581
|
-
});
|
2582
|
-
}
|
2583
|
-
else {
|
2584
|
-
return -1;
|
2585
|
-
}
|
2586
|
-
}
|
2587
|
-
addKeydownListener() {
|
2588
|
-
// Only attempt to add the listener if keyboard nav is enabled
|
2589
|
-
if (this.enableKeyNav) {
|
2590
|
-
// renderer.listen adds the listener and returns a function to remove it from the renderer.
|
2591
|
-
// The listener remains active until this function is called.
|
2592
|
-
this.removeKeydownListener = this.renderer.listen('document', 'keydown', (event) => this.keyNavigate(event));
|
2591
|
+
setFocus(highlightText) {
|
2592
|
+
this.inputElement.nativeElement.focus();
|
2593
|
+
if (highlightText) {
|
2594
|
+
this.inputElement.nativeElement.select();
|
2593
2595
|
}
|
2594
2596
|
}
|
2595
2597
|
/**
|
2596
|
-
|
2597
|
-
|
2598
|
-
|
2599
|
-
|
2600
|
-
|
2601
|
-
|
2602
|
-
});
|
2598
|
+
* Focus out event handler
|
2599
|
+
* will upper case and trim value if upperCase is true (this is what we do on the apis)
|
2600
|
+
*/
|
2601
|
+
focusOutEvent() {
|
2602
|
+
if (this.upperCase && this.formModel.value) {
|
2603
|
+
this.formModel.setValue(this.formModel.value.toUpperCase().trim());
|
2603
2604
|
}
|
2604
2605
|
}
|
2605
2606
|
}
|
2606
|
-
|
2607
|
-
MenuComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.9", type: MenuComponent, selector: "ec-menu", inputs: { id: "id", items: "items", selected: "selected", parent: "parent", templateType: "templateType", customMenuTemplate: "customMenuTemplate", title: "title", showNoItems: "showNoItems", noDataText: "noDataText", enableKeyNav: "enableKeyNav", highlightedItem: "highlightedItem", maintainSelectedItem: "maintainSelectedItem", truncateItems: "truncateItems", preserveIconSpace: "preserveIconSpace", dropdownToggleButton: "dropdownToggleButton" }, outputs: { selectedChanged: "selectedChanged", menuClosed: "menuClosed" }, host: { properties: { "attr.id": "this.attrId" } }, viewQueries: [{ propertyName: "labelTemplate", first: true, predicate: ["label"], descendants: true, static: true }, { propertyName: "iconAndLabelTemplate", first: true, predicate: ["iconAndLabel"], descendants: true, static: true }, { propertyName: "checkAndLabelTemplate", first: true, predicate: ["checkAndLabel"], descendants: true, static: true }, { propertyName: "iconLabelCaptionTemplate", first: true, predicate: ["iconLabelCaption"], descendants: true, static: true }], ngImport: i0, template: "<nav>\r\n <div class=\"parent\"\r\n [class.no-data]=\"showNoItems && (!items || items.length === 0)\">\r\n <header id=\"{{id}}_header\"\r\n class=\"text-heading-3 p-1\"\r\n [class.is-selected]=\"highlightedItemIndex === -1\"\r\n *ngIf=\"parent\"\r\n (click)=\"back($event)\">\r\n <div class=\"item-wrapper\">\r\n <i class=\"ec-icon icon-angle-down rotate-90 flex-shrink\"></i>\r\n <span class=\"label text-truncate flex-grow\">{{parent?.label}}</span>\r\n </div>\r\n </header>\r\n\r\n <ul id=\"{{id}}_list\"\r\n class=\"py-1\">\r\n <li *ngFor=\"let item of items; index as i\"\r\n id=\"{{item.id || id + '_item' + i}}\"\r\n class=\"{{item.display || 'item'}} {{item.classList}}\"\r\n [attr.disabled]=\"item.disabled\"\r\n [hidden]=\"item.hidden\"\r\n ecNavItemActive=\"is-selected\"\r\n [ecNavItemActiveQueryParams]=\"item.queryParams\"\r\n [ecNavItemActiveUrl]=\"item.url\"\r\n [ecNavItemActiveExactMatch]='item.isActiveExactMatch'\r\n (routerLinkActivated)=\"selectItem($event, item)\"\r\n [ngClass]=\"{'is-highlighted':(selected === item && item?.display !== 'heading') || highlightedItem === item, 'is-link': item.url, 'is-disabled': item.disabled, 'is-readonly': item.readonly, 'is-checked': item.checked, 'text-heading-3': item?.display === 'heading'}\"\r\n (click)=\"selectItem($event, item)\">\r\n\r\n <a *ngIf=\"item.url && !item.externalLink\"\r\n id=\"{{item.id}}_link\"\r\n title=\"{{truncateItems ? item.label : ''}}\"\r\n class=\"item-wrapper\"\r\n [routerLink]=\"item.url\"\r\n [queryParams]=\"item.queryParams || null\"\r\n target=\"{{item.target || '_self'}}\">\r\n\r\n <ng-container *ngTemplateOutlet=\"internalizedTemplate; context: {$implicit: item}\"></ng-container>\r\n </a>\r\n\r\n <a *ngIf=\"item.url && item.externalLink\"\r\n id=\"{{item.id}}_link\"\r\n title=\"{{truncateItems ? item.label : ''}}\"\r\n class=\"item-wrapper\"\r\n href=\"{{item.url}}\"\r\n target=\"{{item.target || '_self'}}\">\r\n\r\n <ng-container *ngTemplateOutlet=\"internalizedTemplate; context: {$implicit: item}\"></ng-container>\r\n </a>\r\n\r\n <div *ngIf=\"!item.url\"\r\n title=\"{{truncateItems ? item.label : ''}}\"\r\n class=\"item-wrapper\">\r\n <ng-container *ngTemplateOutlet=\"internalizedTemplate; context: {$implicit: item}\"></ng-container>\r\n </div>\r\n </li>\r\n </ul>\r\n\r\n <p class=\"no-data-message\">{{noDataText | translate}}</p>\r\n </div>\r\n\r\n <!-- Child menu (Rendered to the right) -->\r\n <ec-menu *ngIf=\"selected?.items\"\r\n id=\"{{id}}_child\"\r\n class=\"child\"\r\n [parent]=\"selected\"\r\n [items]=\"selected?.items\"\r\n [showNoItems]=\"true\"\r\n [templateType]=\"templateType\"\r\n [enableKeyNav]=\"true\"\r\n [truncateItems]=\"truncateItems\"\r\n (selectedChanged)=\"onSelection($event)\"\r\n (menuClosed)=\"toggleChildMenu(false)\">\r\n </ec-menu>\r\n</nav>\r\n\r\n<!-- 'label' Item Template -->\r\n<ng-template #label\r\n let-item>\r\n <span id=\"{{item.id}}_label\"\r\n class=\"label\"\r\n [class.text-truncate]=\"truncateItems\">{{item.label}}</span>\r\n\r\n <i class=\"ec-icon icon-angle-down rotate-270\"\r\n *ngIf=\"item?.items\"></i>\r\n</ng-template>\r\n\r\n<!-- 'checkAndLabel' Item Template -->\r\n<ng-template #checkAndLabel\r\n let-item>\r\n\r\n <i class=\"ec-icon icon-check ec-icon-sm\"\r\n *ngIf=\"item.display !== 'heading'\"></i>\r\n\r\n <i class=\"ec-icon {{item.icon}} ml-2\"\r\n *ngIf=\"item.icon\"></i>\r\n\r\n <span id=\"{{item.id}}_label\"\r\n class=\"label\"\r\n [class.text-truncate]=\"truncateItems\">{{item.label}}</span>\r\n\r\n <i class=\"ec-icon icon-angle-down rotate-270\"\r\n *ngIf=\"item?.items\"></i>\r\n</ng-template>\r\n\r\n<!-- 'iconAndLabel' Item Template -->\r\n<ng-template #iconAndLabel\r\n let-item>\r\n <!-- If menuItem.icon exists and is not blank, show the icon in the menu -->\r\n <i class=\"ec-icon {{item.icon}}\"\r\n *ngIf=\"(item.icon && item.icon !== '') || preserveIconSpace\"></i>\r\n\r\n <span id=\"{{item.id}}_label\"\r\n class=\"label\"\r\n [class.text-truncate]=\"truncateItems\">{{item.label}}</span>\r\n\r\n <i class=\"ec-icon icon-angle-down rotate-270\"\r\n *ngIf=\"item?.items\"></i>\r\n</ng-template>\r\n\r\n<ng-template #iconLabelCaption\r\n let-item>\r\n <i class=\"ec-icon {{item.icon}}\"\r\n *ngIf=\"(item.icon && item.icon !== '') || preserveIconSpace\"></i>\r\n <div *ngIf=\"item.display !== 'heading'\"\r\n class=\"label flex-grow\">\r\n <div id=\"{{item.id}}_label\"\r\n class=\"text-body-1\"\r\n [class.text-truncate]=\"truncateItems\">{{item.label}}</div>\r\n <div id=\"{{item.id}}_caption\"\r\n *ngIf=\"item.caption\"\r\n class=\"text-caption-1\"\r\n [class.text-truncate]=\"truncateItems\">{{item.caption}}</div>\r\n </div>\r\n <h3 *ngIf=\"item.display === 'heading'\"\r\n class=\"flex-grow text-heading-3 align-self-center\"\r\n [class.text-truncate]=\"truncateItems\">{{item.label}}</h3>\r\n <i class=\"ec-icon icon-angle-down rotate-270 align-self-center\"\r\n *ngIf=\"item?.items\"></i>\r\n</ng-template>", styles: ["@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(1turn)}}:host{display:block;font-size:var(--ec-menu-font-size, var(--ec-font-size-action));font-weight:400;background-color:var(--ec-menu-background-color, var(--ec-background-color))}:host.open>nav>.parent,:host.open>nav>.child{position:absolute;left:0;top:0;right:0;height:100%;transition:transform .25s ease}:host.open>nav>.parent{transform:translate(0)}:host.open>nav>.child{transform:translate(100%)}:host.open-active>nav>.parent{transform:translate(-100%)}:host.open-active>nav>.child{transform:translate(0)}:host(.bg-transparent){background-color:transparent}:host-context(.is-always-open){height:100%}:host-context(.is-always-open) .item-wrapper{padding-left:1rem;padding-right:1rem}nav{display:flex;position:relative;height:100%;overflow:hidden}.parent{display:flex;flex-direction:column;flex:auto;position:relative;max-width:100%}.parent>header{cursor:pointer}.parent>header.is-selected .item-wrapper,.parent>header.is-highlighted .item-wrapper{background-color:var(--ec-background-color-selected)}.parent>header:hover .item-wrapper{background-color:var(--ec-background-color-hover)}.parent.no-data ul{display:none}.parent.no-data .no-data-message{display:block}ul{padding:0;margin:0;list-style:none;flex:auto;height:100%;overflow-y:auto}ul li{cursor:pointer;padding:0 .25rem}ul li a{color:inherit;border-bottom:0;text-decoration:none}ul li.is-selected .item-wrapper,ul li.is-highlighted .item-wrapper{background-color:var(--ec-background-color-selected)}ul li:hover .item-wrapper{background-color:var(--ec-background-color-hover)}ul li:focus .item-wrapper{outline:none;background-color:var(--ec-color-disabled-dark);position:relative;z-index:1}ul li.is-disabled .item-wrapper{color:var(--ec-color-disabled-dark);opacity:var(--ec-form-control-opacity-disabled)}ul li.is-disabled,ul li.is-readonly{cursor:default}ul li.is-disabled .item-wrapper,ul li.is-readonly .item-wrapper{background-color:transparent;color:inherit}ul li.is-checked .icon-check{opacity:1}ul li.heading{cursor:default}ul li.heading .item-wrapper{background-color:transparent}ul li.heading:not(:first-child){margin-top:.5rem}ul li.divider{border-bottom:1px solid var(--ec-border-color);padding-bottom:.25rem;margin-bottom:.25rem}ul li.indent-1 .item-wrapper{padding-left:1.5rem}ul li.indent-2 .item-wrapper{padding-left:2.5rem}ul li.indent-3 .item-wrapper{padding-left:3.5rem}.item-wrapper{cursor:inherit;line-height:1.25rem;min-height:1.75rem;padding:.25rem .5rem;border-radius:var(--ec-border-radius);display:flex;color:inherit}.item-wrapper .label{margin-right:auto}.item-wrapper .label+.ec-icon{margin-left:.5rem}.item-wrapper .ec-icon{margin-top:calc((1.25rem - var(--ec-font-size-icon)) / 2);flex:none}.item-wrapper .ec-icon+.label{margin-left:.5rem}.item-wrapper .ec-icon-sm{margin-top:calc((1.25rem - calc(var(--ec-font-size-icon) * .75)) / 2)}.item-wrapper .icon-check{opacity:0}.no-data-message{display:none;text-align:center;padding:1rem;color:var(--ec-color-hint-dark);margin-bottom:0;font-size:var(--ec-font-size-body)}:host-context(ec-tree) ul{overflow-x:hidden}:host-context(ec-tree) li.is-selected,:host-context(ec-tree) li.is-highlighted{font-weight:700;color:var(--ec-menu-color-highlighted, inherit)}:host-context(ec-tree) li.is-selected:not(:hover),:host-context(ec-tree) li.is-highlighted:not(:hover){background-color:transparent}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$2.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: NavItemActiveDirective, selector: "[ecNavItemActive]", inputs: ["ecNavItemActive", "ecNavItemActiveExactMatch", "ecNavItemActiveQueryParams", "ecNavItemActiveUrl"], outputs: ["routerLinkActivated"] }, { kind: "component", type: MenuComponent, selector: "ec-menu", inputs: ["id", "items", "selected", "parent", "templateType", "customMenuTemplate", "title", "showNoItems", "noDataText", "enableKeyNav", "highlightedItem", "maintainSelectedItem", "truncateItems", "preserveIconSpace", "dropdownToggleButton"], outputs: ["selectedChanged", "menuClosed"] }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }] });
|
2608
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type:
|
2607
|
+
TextboxComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: TextboxComponent, deps: [{ token: ValidationMessageService }, { token: FormGroupHelper }, { token: i2.TranslateService }], target: i0.ɵɵFactoryTarget.Component });
|
2608
|
+
TextboxComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.9", type: TextboxComponent, selector: "ec-textbox", inputs: { autocomplete: "autocomplete", type: "type", placeholder: "placeholder", maxlength: "maxlength", minlength: "minlength", rows: "rows", selectOnAutofocus: "selectOnAutofocus", upperCase: "upperCase" }, viewQueries: [{ propertyName: "inputElement", first: true, predicate: ["textboxInput"], descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div class=\"control control-label-{{labelPosition}}\"\r\n [ngClass]=\"{'is-readonly': readonly}\">\r\n\r\n <label *ngIf=\"label\">\r\n <span>{{label | translate}}</span>\r\n <span *ngIf=\"validationErrors.length > 0 && formModel.touched && formModel.invalid\"> {{validationErrors |\r\n translate}}</span>\r\n <ec-help-popover id=\"{{id}}_helpPopover\"\r\n *ngIf=\"helpPopover\"\r\n class=\"d-inline-block my-n3 mx-n1\"\r\n text=\"{{helpPopover | translate}}\"\r\n contentPosition=\"{{helpPopoverPosition}}\">\r\n </ec-help-popover>\r\n </label>\r\n\r\n <div class=\"input-wrapper control-input\">\r\n <input *ngIf=\"type !== 'multi_line'\"\r\n #textboxInput\r\n email=\"{{type === 'email' ? true : false}}\"\r\n pattern=\"{{validationPattern}}\"\r\n type=\"{{type}}\"\r\n tabindex=\"{{tabindex}}\"\r\n title=\"{{tooltip}}\"\r\n [attr.id]=\"inputId\"\r\n [attr.autocomplete]=\"autocomplete\"\r\n [attr.placeholder]=\"placeholder\"\r\n [attr.maxlength]=\"maxlength\"\r\n [attr.minlength]=\"minlength\"\r\n [attr.required]=\"required ? required : null\"\r\n [formControl]=\"formModel\"\r\n [ngClass]=\"{'is-empty': !formModel?.value, 'is-pending': pending, 'is-uppercase': upperCase}\"\r\n (focusout)=\"focusOutEvent()\"\r\n [attr.cdkFocusInitial]=\"autofocus || null\">\r\n\r\n <textarea *ngIf=\"type === 'multi_line'\"\r\n [attr.rows]=\"rows\"\r\n #textboxInput\r\n tabindex=\"{{tabindex}}\"\r\n [attr.id]=\"inputId\"\r\n [attr.placeholder]=\"placeholder\"\r\n [attr.maxlength]=\"maxlength\"\r\n [attr.minlength]=\"minlength\"\r\n [attr.required]=\"required ? required : null\"\r\n [formControl]=\"formModel\"\r\n [ngClass]=\"{'is-empty': formModel?.value === '', 'is-pending': pending}\"\r\n [attr.cdkFocusInitial]=\"autofocus || null\">\r\n </textarea>\r\n\r\n <i class=\"ec-icon icon-required\"></i>\r\n <i class=\"ec-icon icon-invalid\"></i>\r\n <i class=\"ec-icon icon-loading\"></i>\r\n </div>\r\n</div>", styles: [":host{color:var(--ec-form-control-color);font-size:var(--ec-form-control-font-size);display:block;margin-bottom:1rem;width:100%}:host :host-context(.form-condensed){margin-bottom:.5rem}:host .control{width:100%;display:flex;flex-direction:column}:host .control.control-label-bottom{flex-direction:column-reverse}:host .control.control-label-left{flex-direction:row}:host .control.control-label-left label{margin-right:.25rem}:host .control.control-label-right{flex-direction:row-reverse}:host .control.control-label-right label{margin-left:.25rem}:host .control.control-label-left,:host .control.control-label-right{align-items:center}:host .control.control-label-left label,:host .control.control-label-right label{flex:1 1;margin-top:0;margin-bottom:0}:host .control.control-label-left .control-input,:host .control.control-label-right .control-input{flex:2 2}:host .control.is-readonly input,:host .control.is-readonly select,:host .control.is-readonly textarea{border-color:var(--ec-form-control-border-color-readonly);background-color:var(--ec-form-control-background-color-readonly);background-clip:border-box;background-image:none;color:var(--ec-form-control-color-readonly);opacity:1;-webkit-user-select:none;user-select:none;pointer-events:none;overflow:hidden;white-space:nowrap}:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-invalid,:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-valid{background-color:var(--ec-form-control-background-color-invalid);border-color:var(--ec-form-control-border-color-invalid);background-repeat:no-repeat;background-position:.5rem center;background-size:1rem,1rem;padding-left:1.75rem;background-image:none}:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-invalid:focus,:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-valid:focus{border-color:var(--ec-form-control-background-color-invalid)}:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-invalid~.icon-invalid,:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-valid~.icon-invalid{display:inline-flex;position:absolute;left:.5rem;top:.5rem;z-index:1}:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-invalid~.icon-required,:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-valid~.icon-required{display:none}:host .control.invalid:not(.open) .textbox-group-btn-right ::ng-deep button{background-color:var(--ec-form-control-background-color-invalid)}:host .control.invalid:not(.open) .textbox-group-btn-right ::ng-deep button:not(:focus){border-color:var(--ec-form-control-border-color-invalid)}:host .textbox-group{display:flex;position:relative}:host textarea:focus,:host input:focus,:host select:focus{outline:none}:host label{color:var(--ec-form-control-label-color, var(--ec-color-secondary-dark));display:block;font-size:var(--ec-font-size-label);line-height:1;margin:calc(var(--ec-font-size-label) / 2) 0}:host input{background-color:var(--ec-form-control-background-color);border:1px solid var(--ec-form-control-border-color);border-radius:var(--ec-border-radius);background-image:none;background-clip:padding-box;width:100%;line-height:1.25rem;padding:.3125rem .5rem;height:2rem}:host input::selection{background-color:var(--ec-form-control-background-color-selection);color:var(--ec-form-control-color-selection)}:host input::-webkit-input-placeholder{color:var(--ec-form-control-color-placeholder)}:host input::-moz-placeholder{color:var(--ec-form-control-color-placeholder);opacity:1}:host input:-ms-input-placeholder{color:var(--ec-form-control-color-placeholder)}:host input:-moz-placeholder{color:var(--ec-form-control-color-placeholder);opacity:1}:host input~.icon-required,:host input~.icon-invalid{color:var(--ec-form-control-border-color-invalid)}:host input:required.is-empty{background-repeat:no-repeat;background-position:.5rem center;background-size:1rem,1rem;padding-left:1.75rem;background-image:none}:host input:required.is-empty~.icon-required{display:inline-flex;position:absolute;left:.5rem;top:.5rem;z-index:1}:host input.ng-invalid.ng-touched{background-color:var(--ec-form-control-background-color-invalid);border-color:var(--ec-form-control-border-color-invalid);background-repeat:no-repeat;background-position:.5rem center;background-size:1rem,1rem;padding-left:1.75rem;background-image:none}:host input.ng-invalid.ng-touched:focus{border-color:var(--ec-form-control-background-color-invalid)}:host input.ng-invalid.ng-touched~.icon-invalid{display:inline-flex;position:absolute;left:.5rem;top:.5rem;z-index:1}:host input.ng-invalid.ng-touched~.icon-required{display:none}:host input.is-pending.ng-valid,:host input.is-pending.ng-invalid,:host input.is-pending.ng-pending{background-image:\"\";background-repeat:no-repeat;background-position:.5rem center;background-size:1rem,1rem;padding-left:1.75rem}:host input.is-pending.ng-valid~.icon-loading,:host input.is-pending.ng-invalid~.icon-loading,:host input.is-pending.ng-pending~.icon-loading{display:inline-flex;position:absolute;left:.5rem;top:.5rem;z-index:1}:host input.is-pending.ng-valid~.icon-required,:host input.is-pending.ng-valid~.icon-invalid,:host input.is-pending.ng-invalid~.icon-required,:host input.is-pending.ng-invalid~.icon-invalid,:host input.is-pending.ng-pending~.icon-required,:host input.is-pending.ng-pending~.icon-invalid{display:none}:host input:focus,:host input:focus.is-empty{border-color:var(--ec-form-control-border-color-focus);box-shadow:var(--ec-form-control-box-shadow-focus);position:relative;z-index:1}:host input:disabled{background-color:var(--ec-form-control-background-color-disabled);border-color:var(--ec-form-control-border-color-disabled);color:var(--ec-form-control-color-disabled);opacity:var(--ec-form-control-opacity-disabled)}:host input:disabled:required,:host input:disabled:required.is-empty{background-image:none;padding-left:.5rem;background-color:var(--ec-form-control-background-color-disabled);border-color:var(--ec-form-control-border-color-disabled)}:host input:disabled:required+.icon-required,:host input:disabled:required.is-empty+.icon-required{display:none}:host input.is-uppercase:not(.is-empty){text-transform:uppercase}:host textarea{background-color:var(--ec-form-control-background-color);border:1px solid var(--ec-form-control-border-color);border-radius:var(--ec-border-radius);background-image:none;background-clip:padding-box;width:100%;line-height:1.25rem;padding:.3125rem .5rem;height:auto;resize:none;display:block}:host textarea::selection{background-color:var(--ec-form-control-background-color-selection);color:var(--ec-form-control-color-selection)}:host textarea::-webkit-input-placeholder{color:var(--ec-form-control-color-placeholder)}:host textarea::-moz-placeholder{color:var(--ec-form-control-color-placeholder);opacity:1}:host textarea:-ms-input-placeholder{color:var(--ec-form-control-color-placeholder)}:host textarea:-moz-placeholder{color:var(--ec-form-control-color-placeholder);opacity:1}:host textarea~.icon-required,:host textarea~.icon-invalid{color:var(--ec-form-control-border-color-invalid)}:host textarea:required.is-empty{background-repeat:no-repeat;background-position:.5rem .5rem;background-size:1rem,1rem;padding-left:1.75rem;background-image:none}:host textarea:required.is-empty~.icon-required{display:inline-flex;position:absolute;left:.5rem;top:.5rem;z-index:1}:host textarea.ng-invalid.ng-touched{background-color:var(--ec-form-control-background-color-invalid);border-color:var(--ec-form-control-border-color-invalid);background-repeat:no-repeat;background-position:.5rem .5rem;background-size:1rem,1rem;padding-left:1.75rem;background-image:none}:host textarea.ng-invalid.ng-touched:focus{border-color:var(--ec-form-control-background-color-invalid)}:host textarea.ng-invalid.ng-touched~.icon-invalid{display:inline-flex;position:absolute;left:.5rem;top:.5rem;z-index:1}:host textarea.ng-invalid.ng-touched~.icon-required{display:none}:host textarea.is-pending.ng-valid,:host textarea.is-pending.ng-invalid,:host textarea.is-pending.ng-pending{background-image:\"\";background-repeat:no-repeat;background-position:.5rem .5rem;background-size:1rem,1rem;padding-left:1.75rem}:host textarea.is-pending.ng-valid~.icon-loading,:host textarea.is-pending.ng-invalid~.icon-loading,:host textarea.is-pending.ng-pending~.icon-loading{display:inline-flex;position:absolute;left:.5rem;top:.5rem;z-index:1}:host textarea.is-pending.ng-valid~.icon-required,:host textarea.is-pending.ng-valid~.icon-invalid,:host textarea.is-pending.ng-invalid~.icon-required,:host textarea.is-pending.ng-invalid~.icon-invalid,:host textarea.is-pending.ng-pending~.icon-required,:host textarea.is-pending.ng-pending~.icon-invalid{display:none}:host textarea:focus,:host textarea:focus.is-empty{border-color:var(--ec-form-control-border-color-focus);box-shadow:var(--ec-form-control-box-shadow-focus);position:relative;z-index:1}:host textarea:disabled{background-color:var(--ec-form-control-background-color-disabled);border-color:var(--ec-form-control-border-color-disabled);color:var(--ec-form-control-color-disabled);opacity:var(--ec-form-control-opacity-disabled)}:host textarea:disabled:required,:host textarea:disabled:required.is-empty{background-image:none;padding-left:.5rem;background-color:var(--ec-form-control-background-color-disabled);border-color:var(--ec-form-control-border-color-disabled)}:host textarea:disabled:required+.icon-required,:host textarea:disabled:required.is-empty+.icon-required{display:none}:host textarea.is-uppercase:not(.is-empty){text-transform:uppercase}.input-wrapper{position:relative}.input-wrapper>.ec-icon{display:none}:host(.textbox-group-input:not(:last-child)){flex:1 1 0%;width:1px}:host(.textbox-group-input:not(:last-child)) .control{margin-bottom:0}:host(.textbox-group-input:not(:last-child)) .control.is-readonly input{border-right-width:1px}:host(.textbox-group-input:not(:last-child)) input{border-top-right-radius:0;border-bottom-right-radius:0;border-right-width:0}:host(.textbox-group-input:not(:last-child)) input:focus{position:relative;z-index:1;border-right-width:1px}:host(.text-truncate) input{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host(.is-monospace) input,:host(.is-monospace) textarea,:host-context(.is-monospace) input,:host-context(.is-monospace) textarea{font-family:var(--ec-font-family-monospace)}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i4.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { kind: "directive", type: i4.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i4.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i4.EmailValidator, selector: "[email][formControlName],[email][formControl],[email][ngModel]", inputs: ["email"] }, { kind: "directive", type: i4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: HelpPopoverComponent, selector: "ec-help-popover", inputs: ["id", "text", "contentPosition", "maxWidth"] }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }] });
|
2609
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: TextboxComponent, decorators: [{
|
2609
2610
|
type: Component,
|
2610
|
-
args: [{ selector: 'ec-menu', template: "<nav>\r\n <div class=\"parent\"\r\n [class.no-data]=\"showNoItems && (!items || items.length === 0)\">\r\n <header id=\"{{id}}_header\"\r\n class=\"text-heading-3 p-1\"\r\n [class.is-selected]=\"highlightedItemIndex === -1\"\r\n *ngIf=\"parent\"\r\n (click)=\"back($event)\">\r\n <div class=\"item-wrapper\">\r\n <i class=\"ec-icon icon-angle-down rotate-90 flex-shrink\"></i>\r\n <span class=\"label text-truncate flex-grow\">{{parent?.label}}</span>\r\n </div>\r\n </header>\r\n\r\n <ul id=\"{{id}}_list\"\r\n class=\"py-1\">\r\n <li *ngFor=\"let item of items; index as i\"\r\n id=\"{{item.id || id + '_item' + i}}\"\r\n class=\"{{item.display || 'item'}} {{item.classList}}\"\r\n [attr.disabled]=\"item.disabled\"\r\n [hidden]=\"item.hidden\"\r\n ecNavItemActive=\"is-selected\"\r\n [ecNavItemActiveQueryParams]=\"item.queryParams\"\r\n [ecNavItemActiveUrl]=\"item.url\"\r\n [ecNavItemActiveExactMatch]='item.isActiveExactMatch'\r\n (routerLinkActivated)=\"selectItem($event, item)\"\r\n [ngClass]=\"{'is-highlighted':(selected === item && item?.display !== 'heading') || highlightedItem === item, 'is-link': item.url, 'is-disabled': item.disabled, 'is-readonly': item.readonly, 'is-checked': item.checked, 'text-heading-3': item?.display === 'heading'}\"\r\n (click)=\"selectItem($event, item)\">\r\n\r\n <a *ngIf=\"item.url && !item.externalLink\"\r\n id=\"{{item.id}}_link\"\r\n title=\"{{truncateItems ? item.label : ''}}\"\r\n class=\"item-wrapper\"\r\n [routerLink]=\"item.url\"\r\n [queryParams]=\"item.queryParams || null\"\r\n target=\"{{item.target || '_self'}}\">\r\n\r\n <ng-container *ngTemplateOutlet=\"internalizedTemplate; context: {$implicit: item}\"></ng-container>\r\n </a>\r\n\r\n <a *ngIf=\"item.url && item.externalLink\"\r\n id=\"{{item.id}}_link\"\r\n title=\"{{truncateItems ? item.label : ''}}\"\r\n class=\"item-wrapper\"\r\n href=\"{{item.url}}\"\r\n target=\"{{item.target || '_self'}}\">\r\n\r\n <ng-container *ngTemplateOutlet=\"internalizedTemplate; context: {$implicit: item}\"></ng-container>\r\n </a>\r\n\r\n <div *ngIf=\"!item.url\"\r\n title=\"{{truncateItems ? item.label : ''}}\"\r\n class=\"item-wrapper\">\r\n <ng-container *ngTemplateOutlet=\"internalizedTemplate; context: {$implicit: item}\"></ng-container>\r\n </div>\r\n </li>\r\n </ul>\r\n\r\n <p class=\"no-data-message\">{{noDataText | translate}}</p>\r\n </div>\r\n\r\n <!-- Child menu (Rendered to the right) -->\r\n <ec-menu *ngIf=\"selected?.items\"\r\n id=\"{{id}}_child\"\r\n class=\"child\"\r\n [parent]=\"selected\"\r\n [items]=\"selected?.items\"\r\n [showNoItems]=\"true\"\r\n [templateType]=\"templateType\"\r\n [enableKeyNav]=\"true\"\r\n [truncateItems]=\"truncateItems\"\r\n (selectedChanged)=\"onSelection($event)\"\r\n (menuClosed)=\"toggleChildMenu(false)\">\r\n </ec-menu>\r\n</nav>\r\n\r\n<!-- 'label' Item Template -->\r\n<ng-template #label\r\n let-item>\r\n <span id=\"{{item.id}}_label\"\r\n class=\"label\"\r\n [class.text-truncate]=\"truncateItems\">{{item.label}}</span>\r\n\r\n <i class=\"ec-icon icon-angle-down rotate-270\"\r\n *ngIf=\"item?.items\"></i>\r\n</ng-template>\r\n\r\n<!-- 'checkAndLabel' Item Template -->\r\n<ng-template #checkAndLabel\r\n let-item>\r\n\r\n <i class=\"ec-icon icon-check ec-icon-sm\"\r\n *ngIf=\"item.display !== 'heading'\"></i>\r\n\r\n <i class=\"ec-icon {{item.icon}} ml-2\"\r\n *ngIf=\"item.icon\"></i>\r\n\r\n <span id=\"{{item.id}}_label\"\r\n class=\"label\"\r\n [class.text-truncate]=\"truncateItems\">{{item.label}}</span>\r\n\r\n <i class=\"ec-icon icon-angle-down rotate-270\"\r\n *ngIf=\"item?.items\"></i>\r\n</ng-template>\r\n\r\n<!-- 'iconAndLabel' Item Template -->\r\n<ng-template #iconAndLabel\r\n let-item>\r\n <!-- If menuItem.icon exists and is not blank, show the icon in the menu -->\r\n <i class=\"ec-icon {{item.icon}}\"\r\n *ngIf=\"(item.icon && item.icon !== '') || preserveIconSpace\"></i>\r\n\r\n <span id=\"{{item.id}}_label\"\r\n class=\"label\"\r\n [class.text-truncate]=\"truncateItems\">{{item.label}}</span>\r\n\r\n <i class=\"ec-icon icon-angle-down rotate-270\"\r\n *ngIf=\"item?.items\"></i>\r\n</ng-template>\r\n\r\n<ng-template #iconLabelCaption\r\n let-item>\r\n <i class=\"ec-icon {{item.icon}}\"\r\n *ngIf=\"(item.icon && item.icon !== '') || preserveIconSpace\"></i>\r\n <div *ngIf=\"item.display !== 'heading'\"\r\n class=\"label flex-grow\">\r\n <div id=\"{{item.id}}_label\"\r\n class=\"text-body-1\"\r\n [class.text-truncate]=\"truncateItems\">{{item.label}}</div>\r\n <div id=\"{{item.id}}_caption\"\r\n *ngIf=\"item.caption\"\r\n class=\"text-caption-1\"\r\n [class.text-truncate]=\"truncateItems\">{{item.caption}}</div>\r\n </div>\r\n <h3 *ngIf=\"item.display === 'heading'\"\r\n class=\"flex-grow text-heading-3 align-self-center\"\r\n [class.text-truncate]=\"truncateItems\">{{item.label}}</h3>\r\n <i class=\"ec-icon icon-angle-down rotate-270 align-self-center\"\r\n *ngIf=\"item?.items\"></i>\r\n</ng-template>", styles: ["@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(1turn)}}:host{display:block;font-size:var(--ec-menu-font-size, var(--ec-font-size-action));font-weight:400;background-color:var(--ec-menu-background-color, var(--ec-background-color))}:host.open>nav>.parent,:host.open>nav>.child{position:absolute;left:0;top:0;right:0;height:100%;transition:transform .25s ease}:host.open>nav>.parent{transform:translate(0)}:host.open>nav>.child{transform:translate(100%)}:host.open-active>nav>.parent{transform:translate(-100%)}:host.open-active>nav>.child{transform:translate(0)}:host(.bg-transparent){background-color:transparent}:host-context(.is-always-open){height:100%}:host-context(.is-always-open) .item-wrapper{padding-left:1rem;padding-right:1rem}nav{display:flex;position:relative;height:100%;overflow:hidden}.parent{display:flex;flex-direction:column;flex:auto;position:relative;max-width:100%}.parent>header{cursor:pointer}.parent>header.is-selected .item-wrapper,.parent>header.is-highlighted .item-wrapper{background-color:var(--ec-background-color-selected)}.parent>header:hover .item-wrapper{background-color:var(--ec-background-color-hover)}.parent.no-data ul{display:none}.parent.no-data .no-data-message{display:block}ul{padding:0;margin:0;list-style:none;flex:auto;height:100%;overflow-y:auto}ul li{cursor:pointer;padding:0 .25rem}ul li a{color:inherit;border-bottom:0;text-decoration:none}ul li.is-selected .item-wrapper,ul li.is-highlighted .item-wrapper{background-color:var(--ec-background-color-selected)}ul li:hover .item-wrapper{background-color:var(--ec-background-color-hover)}ul li:focus .item-wrapper{outline:none;background-color:var(--ec-color-disabled-dark);position:relative;z-index:1}ul li.is-disabled .item-wrapper{color:var(--ec-color-disabled-dark);opacity:var(--ec-form-control-opacity-disabled)}ul li.is-disabled,ul li.is-readonly{cursor:default}ul li.is-disabled .item-wrapper,ul li.is-readonly .item-wrapper{background-color:transparent;color:inherit}ul li.is-checked .icon-check{opacity:1}ul li.heading{cursor:default}ul li.heading .item-wrapper{background-color:transparent}ul li.heading:not(:first-child){margin-top:.5rem}ul li.divider{border-bottom:1px solid var(--ec-border-color);padding-bottom:.25rem;margin-bottom:.25rem}ul li.indent-1 .item-wrapper{padding-left:1.5rem}ul li.indent-2 .item-wrapper{padding-left:2.5rem}ul li.indent-3 .item-wrapper{padding-left:3.5rem}.item-wrapper{cursor:inherit;line-height:1.25rem;min-height:1.75rem;padding:.25rem .5rem;border-radius:var(--ec-border-radius);display:flex;color:inherit}.item-wrapper .label{margin-right:auto}.item-wrapper .label+.ec-icon{margin-left:.5rem}.item-wrapper .ec-icon{margin-top:calc((1.25rem - var(--ec-font-size-icon)) / 2);flex:none}.item-wrapper .ec-icon+.label{margin-left:.5rem}.item-wrapper .ec-icon-sm{margin-top:calc((1.25rem - calc(var(--ec-font-size-icon) * .75)) / 2)}.item-wrapper .icon-check{opacity:0}.no-data-message{display:none;text-align:center;padding:1rem;color:var(--ec-color-hint-dark);margin-bottom:0;font-size:var(--ec-font-size-body)}:host-context(ec-tree) ul{overflow-x:hidden}:host-context(ec-tree) li.is-selected,:host-context(ec-tree) li.is-highlighted{font-weight:700;color:var(--ec-menu-color-highlighted, inherit)}:host-context(ec-tree) li.is-selected:not(:hover),:host-context(ec-tree) li.is-highlighted:not(:hover){background-color:transparent}\n"] }]
|
2611
|
-
}], ctorParameters: function () { return [{ type:
|
2612
|
-
type: Input
|
2613
|
-
}], attrId: [{
|
2614
|
-
type: HostBinding,
|
2615
|
-
args: ['attr.id']
|
2616
|
-
}], items: [{
|
2611
|
+
args: [{ selector: 'ec-textbox', template: "<div class=\"control control-label-{{labelPosition}}\"\r\n [ngClass]=\"{'is-readonly': readonly}\">\r\n\r\n <label *ngIf=\"label\">\r\n <span>{{label | translate}}</span>\r\n <span *ngIf=\"validationErrors.length > 0 && formModel.touched && formModel.invalid\"> {{validationErrors |\r\n translate}}</span>\r\n <ec-help-popover id=\"{{id}}_helpPopover\"\r\n *ngIf=\"helpPopover\"\r\n class=\"d-inline-block my-n3 mx-n1\"\r\n text=\"{{helpPopover | translate}}\"\r\n contentPosition=\"{{helpPopoverPosition}}\">\r\n </ec-help-popover>\r\n </label>\r\n\r\n <div class=\"input-wrapper control-input\">\r\n <input *ngIf=\"type !== 'multi_line'\"\r\n #textboxInput\r\n email=\"{{type === 'email' ? true : false}}\"\r\n pattern=\"{{validationPattern}}\"\r\n type=\"{{type}}\"\r\n tabindex=\"{{tabindex}}\"\r\n title=\"{{tooltip}}\"\r\n [attr.id]=\"inputId\"\r\n [attr.autocomplete]=\"autocomplete\"\r\n [attr.placeholder]=\"placeholder\"\r\n [attr.maxlength]=\"maxlength\"\r\n [attr.minlength]=\"minlength\"\r\n [attr.required]=\"required ? required : null\"\r\n [formControl]=\"formModel\"\r\n [ngClass]=\"{'is-empty': !formModel?.value, 'is-pending': pending, 'is-uppercase': upperCase}\"\r\n (focusout)=\"focusOutEvent()\"\r\n [attr.cdkFocusInitial]=\"autofocus || null\">\r\n\r\n <textarea *ngIf=\"type === 'multi_line'\"\r\n [attr.rows]=\"rows\"\r\n #textboxInput\r\n tabindex=\"{{tabindex}}\"\r\n [attr.id]=\"inputId\"\r\n [attr.placeholder]=\"placeholder\"\r\n [attr.maxlength]=\"maxlength\"\r\n [attr.minlength]=\"minlength\"\r\n [attr.required]=\"required ? required : null\"\r\n [formControl]=\"formModel\"\r\n [ngClass]=\"{'is-empty': formModel?.value === '', 'is-pending': pending}\"\r\n [attr.cdkFocusInitial]=\"autofocus || null\">\r\n </textarea>\r\n\r\n <i class=\"ec-icon icon-required\"></i>\r\n <i class=\"ec-icon icon-invalid\"></i>\r\n <i class=\"ec-icon icon-loading\"></i>\r\n </div>\r\n</div>", styles: [":host{color:var(--ec-form-control-color);font-size:var(--ec-form-control-font-size);display:block;margin-bottom:1rem;width:100%}:host :host-context(.form-condensed){margin-bottom:.5rem}:host .control{width:100%;display:flex;flex-direction:column}:host .control.control-label-bottom{flex-direction:column-reverse}:host .control.control-label-left{flex-direction:row}:host .control.control-label-left label{margin-right:.25rem}:host .control.control-label-right{flex-direction:row-reverse}:host .control.control-label-right label{margin-left:.25rem}:host .control.control-label-left,:host .control.control-label-right{align-items:center}:host .control.control-label-left label,:host .control.control-label-right label{flex:1 1;margin-top:0;margin-bottom:0}:host .control.control-label-left .control-input,:host .control.control-label-right .control-input{flex:2 2}:host .control.is-readonly input,:host .control.is-readonly select,:host .control.is-readonly textarea{border-color:var(--ec-form-control-border-color-readonly);background-color:var(--ec-form-control-background-color-readonly);background-clip:border-box;background-image:none;color:var(--ec-form-control-color-readonly);opacity:1;-webkit-user-select:none;user-select:none;pointer-events:none;overflow:hidden;white-space:nowrap}:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-invalid,:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-valid{background-color:var(--ec-form-control-background-color-invalid);border-color:var(--ec-form-control-border-color-invalid);background-repeat:no-repeat;background-position:.5rem center;background-size:1rem,1rem;padding-left:1.75rem;background-image:none}:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-invalid:focus,:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-valid:focus{border-color:var(--ec-form-control-background-color-invalid)}:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-invalid~.icon-invalid,:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-valid~.icon-invalid{display:inline-flex;position:absolute;left:.5rem;top:.5rem;z-index:1}:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-invalid~.icon-required,:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-valid~.icon-required{display:none}:host .control.invalid:not(.open) .textbox-group-btn-right ::ng-deep button{background-color:var(--ec-form-control-background-color-invalid)}:host .control.invalid:not(.open) .textbox-group-btn-right ::ng-deep button:not(:focus){border-color:var(--ec-form-control-border-color-invalid)}:host .textbox-group{display:flex;position:relative}:host textarea:focus,:host input:focus,:host select:focus{outline:none}:host label{color:var(--ec-form-control-label-color, var(--ec-color-secondary-dark));display:block;font-size:var(--ec-font-size-label);line-height:1;margin:calc(var(--ec-font-size-label) / 2) 0}:host input{background-color:var(--ec-form-control-background-color);border:1px solid var(--ec-form-control-border-color);border-radius:var(--ec-border-radius);background-image:none;background-clip:padding-box;width:100%;line-height:1.25rem;padding:.3125rem .5rem;height:2rem}:host input::selection{background-color:var(--ec-form-control-background-color-selection);color:var(--ec-form-control-color-selection)}:host input::-webkit-input-placeholder{color:var(--ec-form-control-color-placeholder)}:host input::-moz-placeholder{color:var(--ec-form-control-color-placeholder);opacity:1}:host input:-ms-input-placeholder{color:var(--ec-form-control-color-placeholder)}:host input:-moz-placeholder{color:var(--ec-form-control-color-placeholder);opacity:1}:host input~.icon-required,:host input~.icon-invalid{color:var(--ec-form-control-border-color-invalid)}:host input:required.is-empty{background-repeat:no-repeat;background-position:.5rem center;background-size:1rem,1rem;padding-left:1.75rem;background-image:none}:host input:required.is-empty~.icon-required{display:inline-flex;position:absolute;left:.5rem;top:.5rem;z-index:1}:host input.ng-invalid.ng-touched{background-color:var(--ec-form-control-background-color-invalid);border-color:var(--ec-form-control-border-color-invalid);background-repeat:no-repeat;background-position:.5rem center;background-size:1rem,1rem;padding-left:1.75rem;background-image:none}:host input.ng-invalid.ng-touched:focus{border-color:var(--ec-form-control-background-color-invalid)}:host input.ng-invalid.ng-touched~.icon-invalid{display:inline-flex;position:absolute;left:.5rem;top:.5rem;z-index:1}:host input.ng-invalid.ng-touched~.icon-required{display:none}:host input.is-pending.ng-valid,:host input.is-pending.ng-invalid,:host input.is-pending.ng-pending{background-image:\"\";background-repeat:no-repeat;background-position:.5rem center;background-size:1rem,1rem;padding-left:1.75rem}:host input.is-pending.ng-valid~.icon-loading,:host input.is-pending.ng-invalid~.icon-loading,:host input.is-pending.ng-pending~.icon-loading{display:inline-flex;position:absolute;left:.5rem;top:.5rem;z-index:1}:host input.is-pending.ng-valid~.icon-required,:host input.is-pending.ng-valid~.icon-invalid,:host input.is-pending.ng-invalid~.icon-required,:host input.is-pending.ng-invalid~.icon-invalid,:host input.is-pending.ng-pending~.icon-required,:host input.is-pending.ng-pending~.icon-invalid{display:none}:host input:focus,:host input:focus.is-empty{border-color:var(--ec-form-control-border-color-focus);box-shadow:var(--ec-form-control-box-shadow-focus);position:relative;z-index:1}:host input:disabled{background-color:var(--ec-form-control-background-color-disabled);border-color:var(--ec-form-control-border-color-disabled);color:var(--ec-form-control-color-disabled);opacity:var(--ec-form-control-opacity-disabled)}:host input:disabled:required,:host input:disabled:required.is-empty{background-image:none;padding-left:.5rem;background-color:var(--ec-form-control-background-color-disabled);border-color:var(--ec-form-control-border-color-disabled)}:host input:disabled:required+.icon-required,:host input:disabled:required.is-empty+.icon-required{display:none}:host input.is-uppercase:not(.is-empty){text-transform:uppercase}:host textarea{background-color:var(--ec-form-control-background-color);border:1px solid var(--ec-form-control-border-color);border-radius:var(--ec-border-radius);background-image:none;background-clip:padding-box;width:100%;line-height:1.25rem;padding:.3125rem .5rem;height:auto;resize:none;display:block}:host textarea::selection{background-color:var(--ec-form-control-background-color-selection);color:var(--ec-form-control-color-selection)}:host textarea::-webkit-input-placeholder{color:var(--ec-form-control-color-placeholder)}:host textarea::-moz-placeholder{color:var(--ec-form-control-color-placeholder);opacity:1}:host textarea:-ms-input-placeholder{color:var(--ec-form-control-color-placeholder)}:host textarea:-moz-placeholder{color:var(--ec-form-control-color-placeholder);opacity:1}:host textarea~.icon-required,:host textarea~.icon-invalid{color:var(--ec-form-control-border-color-invalid)}:host textarea:required.is-empty{background-repeat:no-repeat;background-position:.5rem .5rem;background-size:1rem,1rem;padding-left:1.75rem;background-image:none}:host textarea:required.is-empty~.icon-required{display:inline-flex;position:absolute;left:.5rem;top:.5rem;z-index:1}:host textarea.ng-invalid.ng-touched{background-color:var(--ec-form-control-background-color-invalid);border-color:var(--ec-form-control-border-color-invalid);background-repeat:no-repeat;background-position:.5rem .5rem;background-size:1rem,1rem;padding-left:1.75rem;background-image:none}:host textarea.ng-invalid.ng-touched:focus{border-color:var(--ec-form-control-background-color-invalid)}:host textarea.ng-invalid.ng-touched~.icon-invalid{display:inline-flex;position:absolute;left:.5rem;top:.5rem;z-index:1}:host textarea.ng-invalid.ng-touched~.icon-required{display:none}:host textarea.is-pending.ng-valid,:host textarea.is-pending.ng-invalid,:host textarea.is-pending.ng-pending{background-image:\"\";background-repeat:no-repeat;background-position:.5rem .5rem;background-size:1rem,1rem;padding-left:1.75rem}:host textarea.is-pending.ng-valid~.icon-loading,:host textarea.is-pending.ng-invalid~.icon-loading,:host textarea.is-pending.ng-pending~.icon-loading{display:inline-flex;position:absolute;left:.5rem;top:.5rem;z-index:1}:host textarea.is-pending.ng-valid~.icon-required,:host textarea.is-pending.ng-valid~.icon-invalid,:host textarea.is-pending.ng-invalid~.icon-required,:host textarea.is-pending.ng-invalid~.icon-invalid,:host textarea.is-pending.ng-pending~.icon-required,:host textarea.is-pending.ng-pending~.icon-invalid{display:none}:host textarea:focus,:host textarea:focus.is-empty{border-color:var(--ec-form-control-border-color-focus);box-shadow:var(--ec-form-control-box-shadow-focus);position:relative;z-index:1}:host textarea:disabled{background-color:var(--ec-form-control-background-color-disabled);border-color:var(--ec-form-control-border-color-disabled);color:var(--ec-form-control-color-disabled);opacity:var(--ec-form-control-opacity-disabled)}:host textarea:disabled:required,:host textarea:disabled:required.is-empty{background-image:none;padding-left:.5rem;background-color:var(--ec-form-control-background-color-disabled);border-color:var(--ec-form-control-border-color-disabled)}:host textarea:disabled:required+.icon-required,:host textarea:disabled:required.is-empty+.icon-required{display:none}:host textarea.is-uppercase:not(.is-empty){text-transform:uppercase}.input-wrapper{position:relative}.input-wrapper>.ec-icon{display:none}:host(.textbox-group-input:not(:last-child)){flex:1 1 0%;width:1px}:host(.textbox-group-input:not(:last-child)) .control{margin-bottom:0}:host(.textbox-group-input:not(:last-child)) .control.is-readonly input{border-right-width:1px}:host(.textbox-group-input:not(:last-child)) input{border-top-right-radius:0;border-bottom-right-radius:0;border-right-width:0}:host(.textbox-group-input:not(:last-child)) input:focus{position:relative;z-index:1;border-right-width:1px}:host(.text-truncate) input{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host(.is-monospace) input,:host(.is-monospace) textarea,:host-context(.is-monospace) input,:host-context(.is-monospace) textarea{font-family:var(--ec-font-family-monospace)}\n"] }]
|
2612
|
+
}], ctorParameters: function () { return [{ type: ValidationMessageService }, { type: FormGroupHelper }, { type: i2.TranslateService }]; }, propDecorators: { autocomplete: [{
|
2617
2613
|
type: Input
|
2618
|
-
}],
|
2614
|
+
}], type: [{
|
2619
2615
|
type: Input
|
2620
|
-
}],
|
2616
|
+
}], placeholder: [{
|
2621
2617
|
type: Input
|
2622
|
-
}],
|
2618
|
+
}], maxlength: [{
|
2623
2619
|
type: Input
|
2624
|
-
}],
|
2620
|
+
}], minlength: [{
|
2625
2621
|
type: Input
|
2626
|
-
}],
|
2622
|
+
}], rows: [{
|
2627
2623
|
type: Input
|
2628
|
-
}],
|
2624
|
+
}], selectOnAutofocus: [{
|
2629
2625
|
type: Input
|
2630
|
-
}],
|
2626
|
+
}], upperCase: [{
|
2631
2627
|
type: Input
|
2632
|
-
}],
|
2628
|
+
}], inputElement: [{
|
2629
|
+
type: ViewChild,
|
2630
|
+
args: ['textboxInput']
|
2631
|
+
}] } });
|
2632
|
+
|
2633
|
+
/** Exposes the markup and styles that represent the spinner. No inputs or outputs defined because it is just a visual component*/
|
2634
|
+
class SpinnerComponent {
|
2635
|
+
}
|
2636
|
+
SpinnerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SpinnerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
2637
|
+
SpinnerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.9", type: SpinnerComponent, selector: "ec-spinner", ngImport: i0, template: "<div class=\"spinner\">\r\n <span class=\"spinner-dot\"></span>\r\n <span class=\"spinner-dot\"></span>\r\n <span class=\"spinner-dot\"></span>\r\n <span class=\"spinner-dot\"></span>\r\n</div>", styles: ["@keyframes sk-bouncedelay{0%,80%,to{opacity:0}40%{opacity:1}}.spinner{display:flex}.spinner-dot{width:.75rem;height:.75rem;background-color:var(--ec-color-interactive);animation:sk-bouncedelay 1.7s infinite ease-in-out both;margin-right:.25rem}.spinner-dot:nth-child(1){animation-delay:-.6s}.spinner-dot:nth-child(2){animation-delay:-.4s}.spinner-dot:nth-child(3){animation-delay:-.2s}:host(.spinner-small) .spinner-dot{width:.5rem;height:.5rem;background-color:var(--ec-color-interactive);animation:sk-bouncedelay 1.7s infinite ease-in-out both;margin-right:.1666666667rem}:host(.spinner-small) .spinner-dot:nth-child(1){animation-delay:-.6s}:host(.spinner-small) .spinner-dot:nth-child(2){animation-delay:-.4s}:host(.spinner-small) .spinner-dot:nth-child(3){animation-delay:-.2s}\n"] });
|
2638
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SpinnerComponent, decorators: [{
|
2639
|
+
type: Component,
|
2640
|
+
args: [{ selector: 'ec-spinner', template: "<div class=\"spinner\">\r\n <span class=\"spinner-dot\"></span>\r\n <span class=\"spinner-dot\"></span>\r\n <span class=\"spinner-dot\"></span>\r\n <span class=\"spinner-dot\"></span>\r\n</div>", styles: ["@keyframes sk-bouncedelay{0%,80%,to{opacity:0}40%{opacity:1}}.spinner{display:flex}.spinner-dot{width:.75rem;height:.75rem;background-color:var(--ec-color-interactive);animation:sk-bouncedelay 1.7s infinite ease-in-out both;margin-right:.25rem}.spinner-dot:nth-child(1){animation-delay:-.6s}.spinner-dot:nth-child(2){animation-delay:-.4s}.spinner-dot:nth-child(3){animation-delay:-.2s}:host(.spinner-small) .spinner-dot{width:.5rem;height:.5rem;background-color:var(--ec-color-interactive);animation:sk-bouncedelay 1.7s infinite ease-in-out both;margin-right:.1666666667rem}:host(.spinner-small) .spinner-dot:nth-child(1){animation-delay:-.6s}:host(.spinner-small) .spinner-dot:nth-child(2){animation-delay:-.4s}:host(.spinner-small) .spinner-dot:nth-child(3){animation-delay:-.2s}\n"] }]
|
2641
|
+
}] });
|
2642
|
+
|
2643
|
+
class Overlay {
|
2644
|
+
constructor(status, message) {
|
2645
|
+
this.status = 'hasData';
|
2646
|
+
this.message = '';
|
2647
|
+
this.setStatus(status, message);
|
2648
|
+
}
|
2649
|
+
setStatus(status, message, action, noDataTemplate, overlayClassList) {
|
2650
|
+
this.status = status;
|
2651
|
+
this.message = message || '';
|
2652
|
+
this.action = action || undefined;
|
2653
|
+
this.noDataTemplate = noDataTemplate || undefined;
|
2654
|
+
this.overlayClassList = overlayClassList || '';
|
2655
|
+
}
|
2656
|
+
}
|
2657
|
+
/**
|
2658
|
+
* Wraps content in order to show pending, error, and no data states with an optional message/noDataTemplate
|
2659
|
+
*/
|
2660
|
+
class ViewOverlayComponent {
|
2661
|
+
constructor() {
|
2662
|
+
this.status = 'hasData';
|
2663
|
+
}
|
2664
|
+
setStatus(status, message, action, noDataTemplate) {
|
2665
|
+
this.status = status;
|
2666
|
+
this.message = message || '';
|
2667
|
+
this.action = action || undefined;
|
2668
|
+
this.noDataTemplate = noDataTemplate || undefined;
|
2669
|
+
}
|
2670
|
+
actionClicked(event) {
|
2671
|
+
if (this.action && this.action.onClick) {
|
2672
|
+
this.action.onClick(event);
|
2673
|
+
}
|
2674
|
+
}
|
2675
|
+
}
|
2676
|
+
ViewOverlayComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ViewOverlayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
2677
|
+
ViewOverlayComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.9", type: ViewOverlayComponent, selector: "[ecOverlay]", inputs: { status: "status", message: "message", action: "action", noDataTemplate: "noDataTemplate", displayAsMask: "displayAsMask", overlayClassList: "overlayClassList" }, ngImport: i0, template: "<!-- Transcluded Content -->\r\n<ng-content *ngIf=\"displayAsMask || (!displayAsMask && status === 'hasData')\"></ng-content>\r\n<!--Used by GI tests to know the overlay status whether we use ngIf or mask version. No visual impact-->\r\n<span [hidden]=\"true\"\r\n\t class=\"overlay-status-{{status}}\"></span>\r\n<!-- Overlay goes last so it is rendered on top of preceding content due to source order -->\r\n<div *ngIf=\"status !== 'hasData'\"\r\n\t class=\"overlay flex-grow {{overlayClassList}}\"\r\n\t [ngClass]=\"{'not-mask': !displayAsMask,\r\n\t\t\t\t'overlay-error': status === 'error',\r\n\t\t\t\t'overlay-nodata': status === 'noData',\r\n\t\t\t\t'overlay-pending': status === 'pending'}\">\r\n\r\n\t<!--Pending Spinner-->\r\n\t<ec-spinner [hidden]=\"status !== 'pending'\"></ec-spinner>\r\n\r\n\t<ng-template [ngIf]=\"status === 'noData' && noDataTemplate\">\r\n\t\t<ng-container *ngTemplateOutlet=\"noDataTemplate\"></ng-container>\r\n\t</ng-template>\r\n\r\n\t<ng-container *ngIf=\"(status === 'noData' && !noDataTemplate) || status !== 'noData'\">\r\n\t\t<!--Status Message-->\r\n\t\t<div id=\"statusMessage\"\r\n\t\t\t class=\"message\"\r\n\t\t\t *ngIf=\"message\"\r\n\t\t\t [ngClass]=\"{'error': status === 'error', 'mt-1': status === 'pending'}\"\r\n\t\t\t [innerHtml]=\"message | translate\">\r\n\t\t</div>\r\n\r\n\t\t<!-- Action -->\r\n\t\t<ec-button type=\"common\"\r\n\t\t\t\t class=\"mt-3\"\r\n\t\t\t\t *ngIf=\"action?.onClick\"\r\n\t\t\t\t [icon]=\"action?.icon\"\r\n\t\t\t\t (clicked)=\"actionClicked($event)\"\r\n\t\t\t\t [label]=\"action?.label\"\r\n\t\t\t\t [hidden]=\"status === 'pending'\">\r\n\t\t</ec-button>\r\n\t</ng-container>\r\n\r\n</div>", styles: [":host{position:relative}:host(.bg-body)>.overlay{background-color:var(--ec-background-color-body)}:host(.bg-body).is-translucent>.overlay{background-color:var(--ec-background-color-overlay)}:host(.bg-content)>.overlay{background-color:var(--ec-background-color)}:host(.bg-content).is-translucent>.overlay{background-color:var(--ec-background-color-overlay)}.overlay{align-items:center;background-color:var(--ec-overlay-background-color, var(--ec-background-color));display:flex;flex-direction:column;justify-content:center;padding:3rem 4rem;z-index:var(--ec-z-index-overlay);position:absolute;inset:0}.overlay.not-mask{position:relative;min-height:100%}.message{color:var(--ec-color-secondary-dark);font-size:var(--ec-font-size-title)}.message.error{color:var(--ec-color-danger);font-size:var(--ec-font-size-title)}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ButtonComponent, selector: "ec-button", inputs: ["id", "disabled", "icon", "label", "badge", "tabindex", "type", "pending", "pendingIcon", "customTemplate", "isSubmit", "autofocus"], outputs: ["clicked"] }, { kind: "component", type: SpinnerComponent, selector: "ec-spinner" }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }] });
|
2678
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ViewOverlayComponent, decorators: [{
|
2679
|
+
type: Component,
|
2680
|
+
args: [{ selector: '[ecOverlay]', template: "<!-- Transcluded Content -->\r\n<ng-content *ngIf=\"displayAsMask || (!displayAsMask && status === 'hasData')\"></ng-content>\r\n<!--Used by GI tests to know the overlay status whether we use ngIf or mask version. No visual impact-->\r\n<span [hidden]=\"true\"\r\n\t class=\"overlay-status-{{status}}\"></span>\r\n<!-- Overlay goes last so it is rendered on top of preceding content due to source order -->\r\n<div *ngIf=\"status !== 'hasData'\"\r\n\t class=\"overlay flex-grow {{overlayClassList}}\"\r\n\t [ngClass]=\"{'not-mask': !displayAsMask,\r\n\t\t\t\t'overlay-error': status === 'error',\r\n\t\t\t\t'overlay-nodata': status === 'noData',\r\n\t\t\t\t'overlay-pending': status === 'pending'}\">\r\n\r\n\t<!--Pending Spinner-->\r\n\t<ec-spinner [hidden]=\"status !== 'pending'\"></ec-spinner>\r\n\r\n\t<ng-template [ngIf]=\"status === 'noData' && noDataTemplate\">\r\n\t\t<ng-container *ngTemplateOutlet=\"noDataTemplate\"></ng-container>\r\n\t</ng-template>\r\n\r\n\t<ng-container *ngIf=\"(status === 'noData' && !noDataTemplate) || status !== 'noData'\">\r\n\t\t<!--Status Message-->\r\n\t\t<div id=\"statusMessage\"\r\n\t\t\t class=\"message\"\r\n\t\t\t *ngIf=\"message\"\r\n\t\t\t [ngClass]=\"{'error': status === 'error', 'mt-1': status === 'pending'}\"\r\n\t\t\t [innerHtml]=\"message | translate\">\r\n\t\t</div>\r\n\r\n\t\t<!-- Action -->\r\n\t\t<ec-button type=\"common\"\r\n\t\t\t\t class=\"mt-3\"\r\n\t\t\t\t *ngIf=\"action?.onClick\"\r\n\t\t\t\t [icon]=\"action?.icon\"\r\n\t\t\t\t (clicked)=\"actionClicked($event)\"\r\n\t\t\t\t [label]=\"action?.label\"\r\n\t\t\t\t [hidden]=\"status === 'pending'\">\r\n\t\t</ec-button>\r\n\t</ng-container>\r\n\r\n</div>", styles: [":host{position:relative}:host(.bg-body)>.overlay{background-color:var(--ec-background-color-body)}:host(.bg-body).is-translucent>.overlay{background-color:var(--ec-background-color-overlay)}:host(.bg-content)>.overlay{background-color:var(--ec-background-color)}:host(.bg-content).is-translucent>.overlay{background-color:var(--ec-background-color-overlay)}.overlay{align-items:center;background-color:var(--ec-overlay-background-color, var(--ec-background-color));display:flex;flex-direction:column;justify-content:center;padding:3rem 4rem;z-index:var(--ec-z-index-overlay);position:absolute;inset:0}.overlay.not-mask{position:relative;min-height:100%}.message{color:var(--ec-color-secondary-dark);font-size:var(--ec-font-size-title)}.message.error{color:var(--ec-color-danger);font-size:var(--ec-font-size-title)}\n"] }]
|
2681
|
+
}], propDecorators: { status: [{
|
2633
2682
|
type: Input
|
2634
|
-
}],
|
2683
|
+
}], message: [{
|
2635
2684
|
type: Input
|
2636
|
-
}],
|
2685
|
+
}], action: [{
|
2637
2686
|
type: Input
|
2638
|
-
}],
|
2687
|
+
}], noDataTemplate: [{
|
2639
2688
|
type: Input
|
2640
|
-
}],
|
2689
|
+
}], displayAsMask: [{
|
2641
2690
|
type: Input
|
2642
|
-
}],
|
2691
|
+
}], overlayClassList: [{
|
2643
2692
|
type: Input
|
2644
|
-
}], selectedChanged: [{
|
2645
|
-
type: Output
|
2646
|
-
}], menuClosed: [{
|
2647
|
-
type: Output
|
2648
|
-
}], labelTemplate: [{
|
2649
|
-
type: ViewChild,
|
2650
|
-
args: ['label', { static: true }]
|
2651
|
-
}], iconAndLabelTemplate: [{
|
2652
|
-
type: ViewChild,
|
2653
|
-
args: ['iconAndLabel', { static: true }]
|
2654
|
-
}], checkAndLabelTemplate: [{
|
2655
|
-
type: ViewChild,
|
2656
|
-
args: ['checkAndLabel', { static: true }]
|
2657
|
-
}], iconLabelCaptionTemplate: [{
|
2658
|
-
type: ViewChild,
|
2659
|
-
args: ['iconLabelCaption', { static: true }]
|
2660
2693
|
}] } });
|
2661
2694
|
|
2662
2695
|
/**
|
@@ -2812,6 +2845,11 @@ class ComboboxComponent extends FormControlBase {
|
|
2812
2845
|
* Number of filtered options to display in the footer. Excludes headings.
|
2813
2846
|
*/
|
2814
2847
|
this.filteredOptionCount = 0;
|
2848
|
+
/**
|
2849
|
+
* Flat list of selectable items in the combobox.
|
2850
|
+
* Does not include headings or divider-section items.
|
2851
|
+
*/
|
2852
|
+
this.selectableItems = [];
|
2815
2853
|
/**
|
2816
2854
|
* Index of the currently-selected options
|
2817
2855
|
*/
|
@@ -2949,13 +2987,14 @@ class ComboboxComponent extends FormControlBase {
|
|
2949
2987
|
resetOptions(options) {
|
2950
2988
|
var _a;
|
2951
2989
|
this.filteredOptions = options || this.options;
|
2990
|
+
this.selectableItems = MenuComponent.getSelectableItems(this.filteredOptions);
|
2952
2991
|
// do not count headings
|
2953
|
-
this.filteredOptionCount = ((_a = this.filteredOptions) === null || _a === void 0 ? void 0 : _a.filter(o => o.display !== 'heading').length) || 0;
|
2992
|
+
this.filteredOptionCount = ((_a = this.filteredOptions) === null || _a === void 0 ? void 0 : _a.filter(o => o.display !== 'heading' && o.display !== 'divided-section').length) || 0;
|
2954
2993
|
//if they have no search term, don't try to select anything so they can clear the box out by hitting enter
|
2955
2994
|
//if they have a search term and the options changed, select an option from the menu so they will get it automatically if they hit enter
|
2956
2995
|
if (this.textboxFormModel.value !== '') {
|
2957
|
-
this.selectedItemIndex = this.findDefaultSelectionIndex(this.
|
2958
|
-
this.selectedItem = this.
|
2996
|
+
this.selectedItemIndex = this.findDefaultSelectionIndex(this.selectableItems, this.textboxFormModel.value);
|
2997
|
+
this.selectedItem = this.selectableItems[this.selectedItemIndex] || null;
|
2959
2998
|
this.scrollMenu(this.selectedItemIndex);
|
2960
2999
|
}
|
2961
3000
|
else {
|
@@ -3152,18 +3191,11 @@ class ComboboxComponent extends FormControlBase {
|
|
3152
3191
|
if (this.selectedItemIndex === -1 && this.addNewButton && !this.addNewButton.nativeElement.hidden && !this.addNewSelected) {
|
3153
3192
|
this.addNewSelected = true;
|
3154
3193
|
}
|
3155
|
-
else if (this.selectedItemIndex < this.
|
3194
|
+
else if (this.selectedItemIndex < this.selectableItems.length - 1) {
|
3195
|
+
this.selectedItemIndex++;
|
3156
3196
|
if (this.addNewSelected) {
|
3157
3197
|
this.addNewSelected = false;
|
3158
3198
|
}
|
3159
|
-
//if the last item is a heading and we are on the second last item, we shouldn't increment the selectedItemIndex because that would select the heading
|
3160
|
-
if (!(this.selectedItemIndex == this.filteredOptions.length - 2 && this.filteredOptions[this.selectedItemIndex + 1].display === 'heading')) {
|
3161
|
-
this.selectedItemIndex++;
|
3162
|
-
// Skip any in-menu heading items
|
3163
|
-
if (this.selectedItemIndex < this.filteredOptions.length - 1 && this.filteredOptions[this.selectedItemIndex].display === 'heading') {
|
3164
|
-
this.selectedItemIndex++;
|
3165
|
-
}
|
3166
|
-
}
|
3167
3199
|
}
|
3168
3200
|
break;
|
3169
3201
|
case "ArrowUp":
|
@@ -3172,30 +3204,16 @@ class ComboboxComponent extends FormControlBase {
|
|
3172
3204
|
this.addNewSelected = false;
|
3173
3205
|
}
|
3174
3206
|
else if (this.selectedItemIndex > -1) {
|
3175
|
-
if (this.selectedItemIndex === 0 && this.addNewButton && !this.addNewButton.nativeElement.hidden) {
|
3176
|
-
this.addNewSelected = true;
|
3177
|
-
}
|
3178
3207
|
this.selectedItemIndex--;
|
3179
|
-
|
3180
|
-
|
3181
|
-
this.selectedItemIndex--;
|
3182
|
-
//if the selectedItemIndex is -1, that means the very first item was a heading and we just skipped over it.
|
3183
|
-
if (this.selectedItemIndex == -1) {
|
3184
|
-
//if there is an add new button we should select it. otherwise we should lock them at index 1 (right before the heading)
|
3185
|
-
if (this.addNewButton && !this.addNewButton.nativeElement.hidden) {
|
3186
|
-
this.addNewSelected = true;
|
3187
|
-
}
|
3188
|
-
else {
|
3189
|
-
this.selectedItemIndex = 1;
|
3190
|
-
}
|
3191
|
-
}
|
3208
|
+
if (this.selectedItemIndex === -1 && this.addNewButton && !this.addNewButton.nativeElement.hidden) {
|
3209
|
+
this.addNewSelected = true;
|
3192
3210
|
}
|
3193
3211
|
}
|
3194
3212
|
break;
|
3195
3213
|
default:
|
3196
3214
|
return;
|
3197
3215
|
}
|
3198
|
-
this.selectedItem = this.
|
3216
|
+
this.selectedItem = this.selectableItems[this.selectedItemIndex];
|
3199
3217
|
if (this.menuStatus === 'hidden') {
|
3200
3218
|
this.setFormModelValue(this.selectedItem);
|
3201
3219
|
}
|
@@ -3214,10 +3232,23 @@ class ComboboxComponent extends FormControlBase {
|
|
3214
3232
|
filterOptionsArray(filterText) {
|
3215
3233
|
let searchText = filterText.toLowerCase();
|
3216
3234
|
if (filterText && filterText !== '') {
|
3217
|
-
|
3218
|
-
|
3219
|
-
|
3220
|
-
|
3235
|
+
const matchesSearch = (item) => item.label.toLowerCase().indexOf(searchText) >= 0 || (item.caption && item.caption.toLowerCase().indexOf(searchText) >= 0);
|
3236
|
+
return this.options.reduce((filteredItems, item) => {
|
3237
|
+
var _a, _b;
|
3238
|
+
// Match the item itself if it doesn't have any children
|
3239
|
+
if (!((_a = item.items) === null || _a === void 0 ? void 0 : _a.length) && matchesSearch(item)) {
|
3240
|
+
filteredItems.push(item);
|
3241
|
+
// If we have children, filter them and add the parent if it has any children that match
|
3242
|
+
}
|
3243
|
+
else if (((_b = item.items) === null || _b === void 0 ? void 0 : _b.length) && (item.display === 'heading' || item.display === 'divided-section')) {
|
3244
|
+
const filteredChildItems = item.items.filter(matchesSearch);
|
3245
|
+
if (filteredChildItems.length) {
|
3246
|
+
// Need to clone the parent item with the filtered children so we don't modify the original
|
3247
|
+
filteredItems.push(Object.assign(Object.assign({}, item), { items: filteredChildItems }));
|
3248
|
+
}
|
3249
|
+
}
|
3250
|
+
return filteredItems;
|
3251
|
+
}, []);
|
3221
3252
|
}
|
3222
3253
|
else {
|
3223
3254
|
return this.options;
|
@@ -3234,7 +3265,7 @@ class ComboboxComponent extends FormControlBase {
|
|
3234
3265
|
findSelectedItemIndex(item) {
|
3235
3266
|
let itemToFind = item ? item : this.selectedItem;
|
3236
3267
|
if (itemToFind) {
|
3237
|
-
return this.
|
3268
|
+
return this.selectableItems.findIndex(item => {
|
3238
3269
|
if (item.id && itemToFind.id) {
|
3239
3270
|
return item.label === itemToFind.label && item.id === itemToFind.id;
|
3240
3271
|
}
|
@@ -3260,7 +3291,7 @@ class ComboboxComponent extends FormControlBase {
|
|
3260
3291
|
this.textboxFormModel.setValue(data.selectedLabel || data.label);
|
3261
3292
|
this.selectedItemIndex = this.findSelectedItemIndex(data);
|
3262
3293
|
if (this.selectedItemIndex >= 0) {
|
3263
|
-
this.selectedItem = this.
|
3294
|
+
this.selectedItem = this.selectableItems[this.selectedItemIndex];
|
3264
3295
|
}
|
3265
3296
|
}
|
3266
3297
|
else {
|
@@ -3281,10 +3312,10 @@ class ComboboxComponent extends FormControlBase {
|
|
3281
3312
|
if (this.selectedItemIndex > -1 && this.selectedItem) {
|
3282
3313
|
// The menu component will automatically generate ids for the menu items if they dont have them,
|
3283
3314
|
// so they need to be accounted for here since the combobox doesn't know about those ids
|
3284
|
-
let
|
3315
|
+
let itemId = this.selectedItem.id ? this.selectedItem.id : MenuComponent.getIndexedItemId(this.filteredOptions, this.selectedItem, `${this.id}_menu`);
|
3285
3316
|
//trigger the scrolling after a tick to allow the menu to be up to date (and pending mask cleared) before measuring
|
3286
3317
|
setTimeout(() => {
|
3287
|
-
this.scrollService.scrollItemCentered(`#${this.id}_menu_list`,
|
3318
|
+
this.scrollService.scrollItemCentered(`#${this.id}_menu_list`, `#${itemId}`);
|
3288
3319
|
}, 0);
|
3289
3320
|
}
|
3290
3321
|
else {
|
@@ -3451,10 +3482,10 @@ class ComboboxComponent extends FormControlBase {
|
|
3451
3482
|
findDefaultSelectionIndex(options, searchText) {
|
3452
3483
|
let index = -1;
|
3453
3484
|
if (options && options.length) {
|
3454
|
-
index = options.findIndex(option => option != null
|
3485
|
+
index = options.findIndex(option => option != null);
|
3455
3486
|
if (searchText) {
|
3456
3487
|
searchText = searchText.toLowerCase().trim();
|
3457
|
-
let exactMatchIndex = options.findIndex(option => option.label.toLowerCase() == searchText
|
3488
|
+
let exactMatchIndex = options.findIndex(option => option.label.toLowerCase() == searchText);
|
3458
3489
|
if (exactMatchIndex >= 0) {
|
3459
3490
|
index = exactMatchIndex;
|
3460
3491
|
}
|
@@ -3794,10 +3825,10 @@ class FormControlComponent {
|
|
3794
3825
|
}
|
3795
3826
|
}
|
3796
3827
|
FormControlComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FormControlComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
|
3797
|
-
FormControlComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.9", type: FormControlComponent, selector: "ec-form-control", inputs: { id: "id", icon: "icon", actionIcon: "actionIcon", showClear: "showClear", pending: "pending", required: "required", readonly: "readonly" }, outputs: { actionClicked: "actionClicked" }, host: { listeners: { "click": "onClick()" }, properties: { "class.is-pending": "this.pending", "class.is-required": "this.required", "class.is-readonly": "this.readonly", "class.is-empty": "this.empty", "class.is-invalid": "this.invalid", "class.is-disabled": "this.disabled" } }, queries: [{ propertyName: "formModel", first: true, predicate: FormControlDirective, descendants: true }], ngImport: i0, template: "<ng-content></ng-content>\r\n<i id=\"{{id + '_icon'}}\" class=\"ec-form-control-icon ec-icon {{icon}}\"></i>\r\n<i id=\"{{id + '_loading'}}\" class=\"ec-form-control-icon ec-icon icon-loading\"></i>\r\n<i id=\"{{id + '_required'}}\" class=\"ec-form-control-icon ec-icon icon-required\"></i>\r\n<i id=\"{{id + '_invalid'}}\" class=\"ec-form-control-icon ec-icon icon-invalid\"></i>\r\n<i id=\"{{id + '_clear'}}\" *ngIf=\"showClear\" class=\"ec-form-control-clear ec-icon icon-cancel\" (click)=\"clear()\"></i>\r\n<i id=\"{{id + '_action'}}\" *ngIf=\"actionIcon\" class=\"ec-form-control-action ec-icon {{actionIcon}}\" (click)=\"actionClicked.emit()\"></i>\r\n<div class=\"ec-focus-ring\"></div>", styles: ["ec-form-control{background-color:var(--ec-form-control-background-color);background-clip:padding-box;border:1px solid var(--ec-form-control-border-color);border-radius:var(--ec-border-radius);padding:0 .5rem;position:relative;color:var(--ec-form-control-color);display:flex;font-size:var(--ec-form-control-font-size);min-height:2rem;width:100%}ec-form-control>input,ec-form-control>select,ec-form-control>textarea
|
3828
|
+
FormControlComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.9", type: FormControlComponent, selector: "ec-form-control", inputs: { id: "id", icon: "icon", actionIcon: "actionIcon", showClear: "showClear", pending: "pending", required: "required", readonly: "readonly" }, outputs: { actionClicked: "actionClicked" }, host: { listeners: { "click": "onClick()" }, properties: { "class.is-pending": "this.pending", "class.is-required": "this.required", "class.is-readonly": "this.readonly", "class.is-empty": "this.empty", "class.is-invalid": "this.invalid", "class.is-disabled": "this.disabled" } }, queries: [{ propertyName: "formModel", first: true, predicate: FormControlDirective, descendants: true }], ngImport: i0, template: "<ng-content></ng-content>\r\n<i id=\"{{id + '_icon'}}\" class=\"ec-form-control-icon ec-icon {{icon}}\"></i>\r\n<i id=\"{{id + '_loading'}}\" class=\"ec-form-control-icon ec-icon icon-loading\"></i>\r\n<i id=\"{{id + '_required'}}\" class=\"ec-form-control-icon ec-icon icon-required\"></i>\r\n<i id=\"{{id + '_invalid'}}\" class=\"ec-form-control-icon ec-icon icon-invalid\"></i>\r\n<i id=\"{{id + '_clear'}}\" *ngIf=\"showClear\" class=\"ec-form-control-clear ec-icon icon-cancel\" (click)=\"clear()\"></i>\r\n<i id=\"{{id + '_action'}}\" *ngIf=\"actionIcon\" class=\"ec-form-control-action ec-icon {{actionIcon}}\" (click)=\"actionClicked.emit()\"></i>\r\n<div class=\"ec-focus-ring\"></div>", styles: ["ec-form-control{background-color:var(--ec-form-control-background-color);background-clip:padding-box;border:1px solid var(--ec-form-control-border-color);border-radius:var(--ec-border-radius);padding:0 .5rem;position:relative;color:var(--ec-form-control-color);display:flex;font-size:var(--ec-form-control-font-size);min-height:2rem;width:100%}ec-form-control>input,ec-form-control>select,ec-form-control>textarea{color:inherit;flex:1 1;min-width:0;border:0;background-color:transparent;order:2}ec-form-control>input::selection,ec-form-control>select::selection,ec-form-control>textarea::selection{background-color:var(--ec-form-control-background-color-selection);color:var(--ec-form-control-color-selection)}ec-form-control>input::-webkit-input-placeholder,ec-form-control>select::-webkit-input-placeholder,ec-form-control>textarea::-webkit-input-placeholder{color:var(--ec-form-control-color-placeholder)}ec-form-control>input::-moz-placeholder,ec-form-control>select::-moz-placeholder,ec-form-control>textarea::-moz-placeholder{color:var(--ec-form-control-color-placeholder);opacity:1}ec-form-control>input:-ms-input-placeholder,ec-form-control>select:-ms-input-placeholder,ec-form-control>textarea:-ms-input-placeholder{color:var(--ec-form-control-color-placeholder)}ec-form-control>input:-moz-placeholder,ec-form-control>select:-moz-placeholder,ec-form-control>textarea:-moz-placeholder{color:var(--ec-form-control-color-placeholder);opacity:1}ec-form-control>input:focus,ec-form-control>select:focus,ec-form-control>textarea:focus{outline:none}ec-form-control>input:focus~.ec-focus-ring,ec-form-control>select:focus~.ec-focus-ring,ec-form-control>textarea:focus~.ec-focus-ring{display:block}ec-form-control>input,ec-form-control>textarea,ec-form-control>select,ec-form-control .ec-form-control-prefix,ec-form-control .ec-form-control-suffix{padding:calc((1.875rem - (var(--ec-font-size-body) * 1.25)) / 2) 0;line-height:1.25;font-size:inherit}ec-form-control>textarea{resize:none;padding:.3125rem 0}ec-form-control .ec-form-control-icon{margin-top:.4375rem;margin-right:.25rem;order:1}ec-form-control .ec-form-control-icon:not([class*=icon-]){display:none}ec-form-control .icon-required,ec-form-control .icon-invalid{color:var(--ec-form-control-border-color-invalid)}ec-form-control .ec-form-control-clear,ec-form-control .ec-form-control-action{cursor:pointer;flex:none;height:1.875rem;width:2rem;order:3}ec-form-control .ec-form-control-clear:last-of-type,ec-form-control .ec-form-control-action:last-of-type{margin-right:-.5rem}ec-form-control .ec-form-control-clear:hover,ec-form-control .ec-form-control-action:hover{background-color:var(--ec-background-color-hover)}ec-form-control .ec-form-control-clear{width:1.5rem}ec-form-control .ec-form-control-prefix,ec-form-control .ec-form-control-suffix{color:var(--ec-color-secondary-dark);flex:none;cursor:default}ec-form-control .ec-form-control-prefix{margin-right:.125rem;order:2}ec-form-control .ec-form-control-suffix{margin-left:.125rem;order:3}ec-form-control .ec-focus-ring{position:absolute;inset:-1px;border:.125rem solid var(--ec-form-control-border-color-focus);pointer-events:none;display:none;border-radius:var(--ec-form-control-border-radius);z-index:1}ec-form-control.is-pending .icon-invalid,ec-form-control.is-pending .icon-required{display:none}ec-form-control.is-invalid{border-color:var(--ec-form-control-border-color-invalid);background-color:var(--ec-form-control-background-color-invalid)}ec-form-control.is-invalid .icon-required{display:none}ec-form-control.is-empty .ec-form-control-clear{display:none}ec-form-control.is-required.is-empty .ec-form-control-icon:first-of-type{display:none}ec-form-control:not(.is-pending) .icon-loading{display:none}ec-form-control:not(.is-required) .icon-required,ec-form-control:not(.is-empty) .icon-required{display:none}ec-form-control:not(.is-invalid) .icon-invalid{display:none}ec-form-control.is-readonly,ec-form-control.is-disabled{background-color:var(--ec-form-control-background-color-disabled)}ec-form-control.is-readonly .icon-loading,ec-form-control.is-readonly .icon-invalid,ec-form-control.is-readonly .icon-required,ec-form-control.is-readonly .ec-form-control-clear,ec-form-control.is-disabled .icon-loading,ec-form-control.is-disabled .icon-invalid,ec-form-control.is-disabled .icon-required,ec-form-control.is-disabled .ec-form-control-clear{display:none}ec-form-control.is-readonly{border-color:var(--ec-form-control-border-color-readonly);color:var(--ec-form-control-color-readonly)}ec-form-control.is-readonly .ec-form-control-action{display:none}ec-form-control.is-disabled:not(.is-readonly){color:var(--ec-form-control-color-disabled);opacity:.6}ec-form-control.is-disabled:not(.is-readonly) .ec-form-control-prefix,ec-form-control.is-disabled:not(.is-readonly) .ec-form-control-suffix{color:inherit}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], encapsulation: i0.ViewEncapsulation.None });
|
3798
3829
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FormControlComponent, decorators: [{
|
3799
3830
|
type: Component,
|
3800
|
-
args: [{ selector: 'ec-form-control', encapsulation: ViewEncapsulation.None, template: "<ng-content></ng-content>\r\n<i id=\"{{id + '_icon'}}\" class=\"ec-form-control-icon ec-icon {{icon}}\"></i>\r\n<i id=\"{{id + '_loading'}}\" class=\"ec-form-control-icon ec-icon icon-loading\"></i>\r\n<i id=\"{{id + '_required'}}\" class=\"ec-form-control-icon ec-icon icon-required\"></i>\r\n<i id=\"{{id + '_invalid'}}\" class=\"ec-form-control-icon ec-icon icon-invalid\"></i>\r\n<i id=\"{{id + '_clear'}}\" *ngIf=\"showClear\" class=\"ec-form-control-clear ec-icon icon-cancel\" (click)=\"clear()\"></i>\r\n<i id=\"{{id + '_action'}}\" *ngIf=\"actionIcon\" class=\"ec-form-control-action ec-icon {{actionIcon}}\" (click)=\"actionClicked.emit()\"></i>\r\n<div class=\"ec-focus-ring\"></div>", styles: ["ec-form-control{background-color:var(--ec-form-control-background-color);background-clip:padding-box;border:1px solid var(--ec-form-control-border-color);border-radius:var(--ec-border-radius);padding:0 .5rem;position:relative;color:var(--ec-form-control-color);display:flex;font-size:var(--ec-form-control-font-size);min-height:2rem;width:100%}ec-form-control>input,ec-form-control>select,ec-form-control>textarea
|
3831
|
+
args: [{ selector: 'ec-form-control', encapsulation: ViewEncapsulation.None, template: "<ng-content></ng-content>\r\n<i id=\"{{id + '_icon'}}\" class=\"ec-form-control-icon ec-icon {{icon}}\"></i>\r\n<i id=\"{{id + '_loading'}}\" class=\"ec-form-control-icon ec-icon icon-loading\"></i>\r\n<i id=\"{{id + '_required'}}\" class=\"ec-form-control-icon ec-icon icon-required\"></i>\r\n<i id=\"{{id + '_invalid'}}\" class=\"ec-form-control-icon ec-icon icon-invalid\"></i>\r\n<i id=\"{{id + '_clear'}}\" *ngIf=\"showClear\" class=\"ec-form-control-clear ec-icon icon-cancel\" (click)=\"clear()\"></i>\r\n<i id=\"{{id + '_action'}}\" *ngIf=\"actionIcon\" class=\"ec-form-control-action ec-icon {{actionIcon}}\" (click)=\"actionClicked.emit()\"></i>\r\n<div class=\"ec-focus-ring\"></div>", styles: ["ec-form-control{background-color:var(--ec-form-control-background-color);background-clip:padding-box;border:1px solid var(--ec-form-control-border-color);border-radius:var(--ec-border-radius);padding:0 .5rem;position:relative;color:var(--ec-form-control-color);display:flex;font-size:var(--ec-form-control-font-size);min-height:2rem;width:100%}ec-form-control>input,ec-form-control>select,ec-form-control>textarea{color:inherit;flex:1 1;min-width:0;border:0;background-color:transparent;order:2}ec-form-control>input::selection,ec-form-control>select::selection,ec-form-control>textarea::selection{background-color:var(--ec-form-control-background-color-selection);color:var(--ec-form-control-color-selection)}ec-form-control>input::-webkit-input-placeholder,ec-form-control>select::-webkit-input-placeholder,ec-form-control>textarea::-webkit-input-placeholder{color:var(--ec-form-control-color-placeholder)}ec-form-control>input::-moz-placeholder,ec-form-control>select::-moz-placeholder,ec-form-control>textarea::-moz-placeholder{color:var(--ec-form-control-color-placeholder);opacity:1}ec-form-control>input:-ms-input-placeholder,ec-form-control>select:-ms-input-placeholder,ec-form-control>textarea:-ms-input-placeholder{color:var(--ec-form-control-color-placeholder)}ec-form-control>input:-moz-placeholder,ec-form-control>select:-moz-placeholder,ec-form-control>textarea:-moz-placeholder{color:var(--ec-form-control-color-placeholder);opacity:1}ec-form-control>input:focus,ec-form-control>select:focus,ec-form-control>textarea:focus{outline:none}ec-form-control>input:focus~.ec-focus-ring,ec-form-control>select:focus~.ec-focus-ring,ec-form-control>textarea:focus~.ec-focus-ring{display:block}ec-form-control>input,ec-form-control>textarea,ec-form-control>select,ec-form-control .ec-form-control-prefix,ec-form-control .ec-form-control-suffix{padding:calc((1.875rem - (var(--ec-font-size-body) * 1.25)) / 2) 0;line-height:1.25;font-size:inherit}ec-form-control>textarea{resize:none;padding:.3125rem 0}ec-form-control .ec-form-control-icon{margin-top:.4375rem;margin-right:.25rem;order:1}ec-form-control .ec-form-control-icon:not([class*=icon-]){display:none}ec-form-control .icon-required,ec-form-control .icon-invalid{color:var(--ec-form-control-border-color-invalid)}ec-form-control .ec-form-control-clear,ec-form-control .ec-form-control-action{cursor:pointer;flex:none;height:1.875rem;width:2rem;order:3}ec-form-control .ec-form-control-clear:last-of-type,ec-form-control .ec-form-control-action:last-of-type{margin-right:-.5rem}ec-form-control .ec-form-control-clear:hover,ec-form-control .ec-form-control-action:hover{background-color:var(--ec-background-color-hover)}ec-form-control .ec-form-control-clear{width:1.5rem}ec-form-control .ec-form-control-prefix,ec-form-control .ec-form-control-suffix{color:var(--ec-color-secondary-dark);flex:none;cursor:default}ec-form-control .ec-form-control-prefix{margin-right:.125rem;order:2}ec-form-control .ec-form-control-suffix{margin-left:.125rem;order:3}ec-form-control .ec-focus-ring{position:absolute;inset:-1px;border:.125rem solid var(--ec-form-control-border-color-focus);pointer-events:none;display:none;border-radius:var(--ec-form-control-border-radius);z-index:1}ec-form-control.is-pending .icon-invalid,ec-form-control.is-pending .icon-required{display:none}ec-form-control.is-invalid{border-color:var(--ec-form-control-border-color-invalid);background-color:var(--ec-form-control-background-color-invalid)}ec-form-control.is-invalid .icon-required{display:none}ec-form-control.is-empty .ec-form-control-clear{display:none}ec-form-control.is-required.is-empty .ec-form-control-icon:first-of-type{display:none}ec-form-control:not(.is-pending) .icon-loading{display:none}ec-form-control:not(.is-required) .icon-required,ec-form-control:not(.is-empty) .icon-required{display:none}ec-form-control:not(.is-invalid) .icon-invalid{display:none}ec-form-control.is-readonly,ec-form-control.is-disabled{background-color:var(--ec-form-control-background-color-disabled)}ec-form-control.is-readonly .icon-loading,ec-form-control.is-readonly .icon-invalid,ec-form-control.is-readonly .icon-required,ec-form-control.is-readonly .ec-form-control-clear,ec-form-control.is-disabled .icon-loading,ec-form-control.is-disabled .icon-invalid,ec-form-control.is-disabled .icon-required,ec-form-control.is-disabled .ec-form-control-clear{display:none}ec-form-control.is-readonly{border-color:var(--ec-form-control-border-color-readonly);color:var(--ec-form-control-color-readonly)}ec-form-control.is-readonly .ec-form-control-action{display:none}ec-form-control.is-disabled:not(.is-readonly){color:var(--ec-form-control-color-disabled);opacity:.6}ec-form-control.is-disabled:not(.is-readonly) .ec-form-control-prefix,ec-form-control.is-disabled:not(.is-readonly) .ec-form-control-suffix{color:inherit}\n"] }]
|
3801
3832
|
}], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { formModel: [{
|
3802
3833
|
type: ContentChild,
|
3803
3834
|
args: [FormControlDirective]
|