@ifsworld/granite-components 4.4.0 → 5.0.1
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/README.md +117 -4
- package/esm2020/ifsworld-granite-components.mjs +5 -0
- package/esm2020/index.mjs +48 -0
- package/esm2020/lib/arrange-grid/arrange-grid-item.component.mjs +44 -0
- package/esm2020/lib/arrange-grid/arrange-grid.component.mjs +125 -0
- package/esm2020/lib/arrange-grid/arrange-grid.module.mjs +19 -0
- package/esm2020/lib/badge/badge.component.mjs +39 -0
- package/esm2020/lib/badge/badge.module.mjs +18 -0
- package/esm2020/lib/badge/testing/badge.harness.mjs +25 -0
- package/esm2020/lib/button/button.component.mjs +89 -0
- package/esm2020/lib/button/button.module.mjs +16 -0
- package/esm2020/lib/checkbox/checkbox-group.component.mjs +17 -0
- package/esm2020/lib/checkbox/checkbox.component.mjs +96 -0
- package/esm2020/lib/checkbox/checkbox.module.mjs +17 -0
- package/esm2020/lib/core/animation.mjs +34 -0
- package/esm2020/lib/core/client-environment.mjs +20 -0
- package/esm2020/lib/core/common-behaviors/disabled.mjs +27 -0
- package/esm2020/lib/core/core.module.mjs +36 -0
- package/esm2020/lib/core/devices/client-input-desktop.directive.mjs +29 -0
- package/esm2020/lib/core/devices/client-input-touch.directive.mjs +29 -0
- package/esm2020/lib/core/devices/client-output-desktop.directive.mjs +29 -0
- package/esm2020/lib/core/devices/client-output-touch.directive.mjs +29 -0
- package/esm2020/lib/core/pipes/pure-pipes.module.mjs +16 -0
- package/esm2020/lib/core/pipes/title.pipe.mjs +21 -0
- package/esm2020/lib/core/radio-checkbox-base.mjs +19 -0
- package/esm2020/lib/core/theme.library.mjs +59 -0
- package/esm2020/lib/core/types.mjs +2 -0
- package/esm2020/lib/grid/grid.component.mjs +128 -0
- package/esm2020/lib/grid/grid.module.mjs +18 -0
- package/esm2020/lib/icon/icon.component.mjs +43 -0
- package/esm2020/lib/icon/icon.module.mjs +16 -0
- package/esm2020/lib/input-field/input-field.component.mjs +160 -0
- package/esm2020/lib/input-field/input-field.module.mjs +20 -0
- package/esm2020/lib/menu/divider.directive.mjs +23 -0
- package/esm2020/lib/menu/menu-base.mjs +347 -0
- package/esm2020/lib/menu/menu-desktop-animations.mjs +23 -0
- package/esm2020/lib/menu/menu-errors.mjs +37 -0
- package/esm2020/lib/menu/menu-item.component.mjs +91 -0
- package/esm2020/lib/menu/menu-panel.mjs +7 -0
- package/esm2020/lib/menu/menu-positions.mjs +9 -0
- package/esm2020/lib/menu/menu-touch-animations.mjs +137 -0
- package/esm2020/lib/menu/menu-touch-close.component.mjs +13 -0
- package/esm2020/lib/menu/menu-touch-title.component.mjs +59 -0
- package/esm2020/lib/menu/menu-trigger-for.directive.mjs +702 -0
- package/esm2020/lib/menu/menu.component.mjs +30 -0
- package/esm2020/lib/menu/menu.module.mjs +55 -0
- package/esm2020/lib/menu/testing/menu.harness.mjs +109 -0
- package/esm2020/lib/menu/title.directive.mjs +17 -0
- package/esm2020/lib/radio-button/radio-button.component.mjs +118 -0
- package/esm2020/lib/radio-button/radio-button.module.mjs +17 -0
- package/esm2020/lib/radio-button/radio-group.component.mjs +17 -0
- package/esm2020/lib/table/cell/cell.mjs +15 -0
- package/esm2020/lib/table/cell/table-data-cell.component.mjs +26 -0
- package/esm2020/lib/table/cell/table-header-cell.component.mjs +12 -0
- package/esm2020/lib/table/column/table-column.directive.mjs +23 -0
- package/esm2020/lib/table/table-constants.library.mjs +4 -0
- package/esm2020/lib/table/table.component.mjs +36 -0
- package/esm2020/lib/table/table.module.mjs +32 -0
- package/esm2020/lib/toggle-switch/toggle-switch.component.mjs +96 -0
- package/esm2020/lib/toggle-switch/toggle-switch.module.mjs +16 -0
- package/fesm2015/ifsworld-granite-components.mjs +3145 -0
- package/fesm2015/ifsworld-granite-components.mjs.map +1 -0
- package/fesm2020/ifsworld-granite-components.mjs +3103 -0
- package/fesm2020/ifsworld-granite-components.mjs.map +1 -0
- package/ifsworld-granite-components.d.ts +1 -8
- package/lib/arrange-grid/arrange-grid-item.component.d.ts +3 -0
- package/lib/arrange-grid/arrange-grid.component.d.ts +3 -0
- package/lib/arrange-grid/arrange-grid.module.d.ts +7 -0
- package/lib/badge/badge.component.d.ts +3 -0
- package/lib/badge/badge.module.d.ts +6 -0
- package/lib/button/button.component.d.ts +5 -0
- package/lib/button/button.module.d.ts +5 -0
- package/lib/checkbox/checkbox-group.component.d.ts +3 -0
- package/lib/checkbox/checkbox.component.d.ts +3 -0
- package/lib/checkbox/checkbox.module.d.ts +6 -0
- package/lib/core/core.module.d.ts +8 -0
- package/lib/core/devices/client-input-desktop.directive.d.ts +3 -0
- package/lib/core/devices/client-input-touch.directive.d.ts +3 -0
- package/lib/core/devices/client-output-desktop.directive.d.ts +3 -0
- package/lib/core/devices/client-output-touch.directive.d.ts +3 -0
- package/lib/core/pipes/pure-pipes.module.d.ts +5 -0
- package/lib/core/pipes/title.pipe.d.ts +3 -0
- package/lib/core/radio-checkbox-base.d.ts +3 -0
- package/lib/grid/grid.component.d.ts +5 -0
- package/lib/grid/grid.module.d.ts +6 -0
- package/lib/icon/icon.component.d.ts +3 -0
- package/lib/icon/icon.module.d.ts +5 -0
- package/lib/input-field/input-field.component.d.ts +3 -0
- package/lib/input-field/input-field.module.d.ts +8 -0
- package/lib/menu/divider.directive.d.ts +3 -0
- package/lib/menu/menu-base.d.ts +190 -0
- package/lib/menu/menu-item.component.d.ts +3 -0
- package/lib/menu/menu-touch-close.component.d.ts +3 -0
- package/lib/menu/menu-touch-title.component.d.ts +4 -1
- package/lib/menu/menu-trigger-for.directive.d.ts +4 -1
- package/lib/menu/menu.component.d.ts +4 -187
- package/lib/menu/menu.module.d.ts +15 -0
- package/lib/menu/title.directive.d.ts +3 -0
- package/lib/radio-button/radio-button.component.d.ts +4 -1
- package/lib/radio-button/radio-button.module.d.ts +6 -0
- package/lib/radio-button/radio-group.component.d.ts +3 -0
- package/lib/table/cell/cell.d.ts +3 -0
- package/lib/table/cell/table-data-cell.component.d.ts +3 -0
- package/lib/table/cell/table-header-cell.component.d.ts +3 -0
- package/lib/table/column/table-column.directive.d.ts +3 -0
- package/lib/table/table.component.d.ts +3 -0
- package/lib/table/table.module.d.ts +12 -0
- package/lib/toggle-switch/toggle-switch.component.d.ts +3 -0
- package/lib/toggle-switch/toggle-switch.module.d.ts +5 -0
- package/package.json +26 -13
- package/bundles/ifsworld-granite-components.umd.js +0 -3649
- package/bundles/ifsworld-granite-components.umd.js.map +0 -1
- package/bundles/ifsworld-granite-components.umd.min.js +0 -10
- package/bundles/ifsworld-granite-components.umd.min.js.map +0 -1
- package/esm2015/ifsworld-granite-components.js +0 -13
- package/esm2015/ifsworld-granite-components.js.map +0 -1
- package/esm2015/ifsworld-granite-components.metadata.json +0 -1
- package/esm2015/index.js +0 -48
- package/esm2015/index.js.map +0 -1
- package/esm2015/index.metadata.json +0 -1
- package/esm2015/lib/arrange-grid/arrange-grid-item.component.js +0 -48
- package/esm2015/lib/arrange-grid/arrange-grid-item.component.js.map +0 -1
- package/esm2015/lib/arrange-grid/arrange-grid-item.component.metadata.json +0 -1
- package/esm2015/lib/arrange-grid/arrange-grid.component.js +0 -123
- package/esm2015/lib/arrange-grid/arrange-grid.component.js.map +0 -1
- package/esm2015/lib/arrange-grid/arrange-grid.component.metadata.json +0 -1
- package/esm2015/lib/arrange-grid/arrange-grid.module.js +0 -14
- package/esm2015/lib/arrange-grid/arrange-grid.module.js.map +0 -1
- package/esm2015/lib/arrange-grid/arrange-grid.module.metadata.json +0 -1
- package/esm2015/lib/badge/badge.component.js +0 -44
- package/esm2015/lib/badge/badge.component.js.map +0 -1
- package/esm2015/lib/badge/badge.component.metadata.json +0 -1
- package/esm2015/lib/badge/badge.module.js +0 -13
- package/esm2015/lib/badge/badge.module.js.map +0 -1
- package/esm2015/lib/badge/badge.module.metadata.json +0 -1
- package/esm2015/lib/badge/testing/badge.harness.js +0 -30
- package/esm2015/lib/badge/testing/badge.harness.js.map +0 -1
- package/esm2015/lib/badge/testing/badge.harness.metadata.json +0 -1
- package/esm2015/lib/button/button.component.js +0 -108
- package/esm2015/lib/button/button.component.js.map +0 -1
- package/esm2015/lib/button/button.component.metadata.json +0 -1
- package/esm2015/lib/button/button.module.js +0 -11
- package/esm2015/lib/button/button.module.js.map +0 -1
- package/esm2015/lib/button/button.module.metadata.json +0 -1
- package/esm2015/lib/checkbox/checkbox-group.component.js +0 -19
- package/esm2015/lib/checkbox/checkbox-group.component.js.map +0 -1
- package/esm2015/lib/checkbox/checkbox-group.component.metadata.json +0 -1
- package/esm2015/lib/checkbox/checkbox.component.js +0 -89
- package/esm2015/lib/checkbox/checkbox.component.js.map +0 -1
- package/esm2015/lib/checkbox/checkbox.component.metadata.json +0 -1
- package/esm2015/lib/checkbox/checkbox.module.js +0 -12
- package/esm2015/lib/checkbox/checkbox.module.js.map +0 -1
- package/esm2015/lib/checkbox/checkbox.module.metadata.json +0 -1
- package/esm2015/lib/core/animation.js +0 -34
- package/esm2015/lib/core/animation.js.map +0 -1
- package/esm2015/lib/core/animation.metadata.json +0 -1
- package/esm2015/lib/core/client-environment.js +0 -20
- package/esm2015/lib/core/client-environment.js.map +0 -1
- package/esm2015/lib/core/client-environment.metadata.json +0 -1
- package/esm2015/lib/core/common-behaviors/disabled.js +0 -25
- package/esm2015/lib/core/common-behaviors/disabled.js.map +0 -1
- package/esm2015/lib/core/common-behaviors/disabled.metadata.json +0 -1
- package/esm2015/lib/core/core.module.js +0 -25
- package/esm2015/lib/core/core.module.js.map +0 -1
- package/esm2015/lib/core/core.module.metadata.json +0 -1
- package/esm2015/lib/core/devices/client-input-desktop.directive.js +0 -22
- package/esm2015/lib/core/devices/client-input-desktop.directive.js.map +0 -1
- package/esm2015/lib/core/devices/client-input-desktop.directive.metadata.json +0 -1
- package/esm2015/lib/core/devices/client-input-touch.directive.js +0 -22
- package/esm2015/lib/core/devices/client-input-touch.directive.js.map +0 -1
- package/esm2015/lib/core/devices/client-input-touch.directive.metadata.json +0 -1
- package/esm2015/lib/core/devices/client-output-desktop.directive.js +0 -22
- package/esm2015/lib/core/devices/client-output-desktop.directive.js.map +0 -1
- package/esm2015/lib/core/devices/client-output-desktop.directive.metadata.json +0 -1
- package/esm2015/lib/core/devices/client-output-touch.directive.js +0 -22
- package/esm2015/lib/core/devices/client-output-touch.directive.js.map +0 -1
- package/esm2015/lib/core/devices/client-output-touch.directive.metadata.json +0 -1
- package/esm2015/lib/core/pipes/pure-pipes.module.js +0 -11
- package/esm2015/lib/core/pipes/pure-pipes.module.js.map +0 -1
- package/esm2015/lib/core/pipes/pure-pipes.module.metadata.json +0 -1
- package/esm2015/lib/core/pipes/title.pipe.js +0 -17
- package/esm2015/lib/core/pipes/title.pipe.js.map +0 -1
- package/esm2015/lib/core/pipes/title.pipe.metadata.json +0 -1
- package/esm2015/lib/core/radio-checkbox-base.js +0 -15
- package/esm2015/lib/core/radio-checkbox-base.js.map +0 -1
- package/esm2015/lib/core/radio-checkbox-base.metadata.json +0 -1
- package/esm2015/lib/core/theme.library.js +0 -59
- package/esm2015/lib/core/theme.library.js.map +0 -1
- package/esm2015/lib/core/theme.library.metadata.json +0 -1
- package/esm2015/lib/core/types.js +0 -2
- package/esm2015/lib/core/types.js.map +0 -1
- package/esm2015/lib/core/types.metadata.json +0 -1
- package/esm2015/lib/grid/grid.component.js +0 -131
- package/esm2015/lib/grid/grid.component.js.map +0 -1
- package/esm2015/lib/grid/grid.component.metadata.json +0 -1
- package/esm2015/lib/grid/grid.module.js +0 -13
- package/esm2015/lib/grid/grid.module.js.map +0 -1
- package/esm2015/lib/grid/grid.module.metadata.json +0 -1
- package/esm2015/lib/icon/icon.component.js +0 -48
- package/esm2015/lib/icon/icon.component.js.map +0 -1
- package/esm2015/lib/icon/icon.component.metadata.json +0 -1
- package/esm2015/lib/icon/icon.module.js +0 -11
- package/esm2015/lib/icon/icon.module.js.map +0 -1
- package/esm2015/lib/icon/icon.module.metadata.json +0 -1
- package/esm2015/lib/input-field/input-field.component.js +0 -144
- package/esm2015/lib/input-field/input-field.component.js.map +0 -1
- package/esm2015/lib/input-field/input-field.component.metadata.json +0 -1
- package/esm2015/lib/input-field/input-field.module.js +0 -15
- package/esm2015/lib/input-field/input-field.module.js.map +0 -1
- package/esm2015/lib/input-field/input-field.module.metadata.json +0 -1
- package/esm2015/lib/menu/divider.directive.js +0 -20
- package/esm2015/lib/menu/divider.directive.js.map +0 -1
- package/esm2015/lib/menu/divider.directive.metadata.json +0 -1
- package/esm2015/lib/menu/menu-desktop-animations.js +0 -23
- package/esm2015/lib/menu/menu-desktop-animations.js.map +0 -1
- package/esm2015/lib/menu/menu-desktop-animations.metadata.json +0 -1
- package/esm2015/lib/menu/menu-errors.js +0 -37
- package/esm2015/lib/menu/menu-errors.js.map +0 -1
- package/esm2015/lib/menu/menu-errors.metadata.json +0 -1
- package/esm2015/lib/menu/menu-item.component.js +0 -82
- package/esm2015/lib/menu/menu-item.component.js.map +0 -1
- package/esm2015/lib/menu/menu-item.component.metadata.json +0 -1
- package/esm2015/lib/menu/menu-panel.js +0 -7
- package/esm2015/lib/menu/menu-panel.js.map +0 -1
- package/esm2015/lib/menu/menu-panel.metadata.json +0 -1
- package/esm2015/lib/menu/menu-positions.js +0 -9
- package/esm2015/lib/menu/menu-positions.js.map +0 -1
- package/esm2015/lib/menu/menu-positions.metadata.json +0 -1
- package/esm2015/lib/menu/menu-touch-animations.js +0 -137
- package/esm2015/lib/menu/menu-touch-animations.js.map +0 -1
- package/esm2015/lib/menu/menu-touch-animations.metadata.json +0 -1
- package/esm2015/lib/menu/menu-touch-close.component.js +0 -16
- package/esm2015/lib/menu/menu-touch-close.component.js.map +0 -1
- package/esm2015/lib/menu/menu-touch-close.component.metadata.json +0 -1
- package/esm2015/lib/menu/menu-touch-title.component.js +0 -45
- package/esm2015/lib/menu/menu-touch-title.component.js.map +0 -1
- package/esm2015/lib/menu/menu-touch-title.component.metadata.json +0 -1
- package/esm2015/lib/menu/menu-trigger-for.directive.js +0 -684
- package/esm2015/lib/menu/menu-trigger-for.directive.js.map +0 -1
- package/esm2015/lib/menu/menu-trigger-for.directive.metadata.json +0 -1
- package/esm2015/lib/menu/menu.component.js +0 -362
- package/esm2015/lib/menu/menu.component.js.map +0 -1
- package/esm2015/lib/menu/menu.component.metadata.json +0 -1
- package/esm2015/lib/menu/menu.module.js +0 -38
- package/esm2015/lib/menu/menu.module.js.map +0 -1
- package/esm2015/lib/menu/menu.module.metadata.json +0 -1
- package/esm2015/lib/menu/testing/menu.harness.js +0 -133
- package/esm2015/lib/menu/testing/menu.harness.js.map +0 -1
- package/esm2015/lib/menu/testing/menu.harness.metadata.json +0 -1
- package/esm2015/lib/menu/title.directive.js +0 -13
- package/esm2015/lib/menu/title.directive.js.map +0 -1
- package/esm2015/lib/menu/title.directive.metadata.json +0 -1
- package/esm2015/lib/radio-button/radio-button.component.js +0 -110
- package/esm2015/lib/radio-button/radio-button.component.js.map +0 -1
- package/esm2015/lib/radio-button/radio-button.component.metadata.json +0 -1
- package/esm2015/lib/radio-button/radio-button.module.js +0 -12
- package/esm2015/lib/radio-button/radio-button.module.js.map +0 -1
- package/esm2015/lib/radio-button/radio-button.module.metadata.json +0 -1
- package/esm2015/lib/radio-button/radio-group.component.js +0 -19
- package/esm2015/lib/radio-button/radio-group.component.js.map +0 -1
- package/esm2015/lib/radio-button/radio-group.component.metadata.json +0 -1
- package/esm2015/lib/table/cell/cell.js +0 -12
- package/esm2015/lib/table/cell/cell.js.map +0 -1
- package/esm2015/lib/table/cell/cell.metadata.json +0 -1
- package/esm2015/lib/table/cell/table-data-cell.component.js +0 -21
- package/esm2015/lib/table/cell/table-data-cell.component.js.map +0 -1
- package/esm2015/lib/table/cell/table-data-cell.component.metadata.json +0 -1
- package/esm2015/lib/table/cell/table-header-cell.component.js +0 -13
- package/esm2015/lib/table/cell/table-header-cell.component.js.map +0 -1
- package/esm2015/lib/table/cell/table-header-cell.component.metadata.json +0 -1
- package/esm2015/lib/table/column/table-column.directive.js +0 -16
- package/esm2015/lib/table/column/table-column.directive.js.map +0 -1
- package/esm2015/lib/table/column/table-column.directive.metadata.json +0 -1
- package/esm2015/lib/table/table-constants.library.js +0 -4
- package/esm2015/lib/table/table-constants.library.js.map +0 -1
- package/esm2015/lib/table/table-constants.library.metadata.json +0 -1
- package/esm2015/lib/table/table.component.js +0 -28
- package/esm2015/lib/table/table.component.js.map +0 -1
- package/esm2015/lib/table/table.component.metadata.json +0 -1
- package/esm2015/lib/table/table.module.js +0 -24
- package/esm2015/lib/table/table.module.js.map +0 -1
- package/esm2015/lib/table/table.module.metadata.json +0 -1
- package/esm2015/lib/toggle-switch/toggle-switch.component.js +0 -89
- package/esm2015/lib/toggle-switch/toggle-switch.component.js.map +0 -1
- package/esm2015/lib/toggle-switch/toggle-switch.component.metadata.json +0 -1
- package/esm2015/lib/toggle-switch/toggle-switch.module.js +0 -11
- package/esm2015/lib/toggle-switch/toggle-switch.module.js.map +0 -1
- package/esm2015/lib/toggle-switch/toggle-switch.module.metadata.json +0 -1
- package/fesm2015/ifsworld-granite-components.js +0 -2992
- package/fesm2015/ifsworld-granite-components.js.map +0 -1
- package/ifsworld-granite-components.metadata.json +0 -1
|
@@ -1,684 +0,0 @@
|
|
|
1
|
-
import { Directive, ElementRef, Inject, Input, Optional, Self, ViewContainerRef, } from '@angular/core';
|
|
2
|
-
import { DOCUMENT } from '@angular/common';
|
|
3
|
-
import { FocusMonitor, isFakeMousedownFromScreenReader, } from '@angular/cdk/a11y';
|
|
4
|
-
import { Directionality } from '@angular/cdk/bidi';
|
|
5
|
-
import { normalizePassiveListenerOptions } from '@angular/cdk/platform';
|
|
6
|
-
import { Overlay, OverlayConfig, } from '@angular/cdk/overlay';
|
|
7
|
-
import { TemplatePortal } from '@angular/cdk/portal';
|
|
8
|
-
import { asapScheduler, fromEvent, merge, of as observableOf, Subscription, } from 'rxjs';
|
|
9
|
-
import { delay, filter, take, takeUntil } from 'rxjs/operators';
|
|
10
|
-
import { _MenuBaseComponent } from './menu.component';
|
|
11
|
-
import { GraniteMenuItemComponent } from './menu-item.component';
|
|
12
|
-
import { GRANITE_MENU_PANEL } from './menu-panel';
|
|
13
|
-
//#region --- Touch device customizations ---
|
|
14
|
-
import { GRANITE_CLIENT_INPUT, GRANITE_CLIENT_OUTPUT, } from '../core/client-environment';
|
|
15
|
-
import { throwGraniteMenuMissingError } from './menu-errors';
|
|
16
|
-
/** Options for binding a passive event listener. */
|
|
17
|
-
const passiveEventListenerOptions = normalizePassiveListenerOptions({
|
|
18
|
-
passive: true,
|
|
19
|
-
});
|
|
20
|
-
//#endregion --- Touch device customizations ---
|
|
21
|
-
/**
|
|
22
|
-
* Directive used to turn a button element into a (popup) menu trigger
|
|
23
|
-
*
|
|
24
|
-
* Stripped-down version of Angular Material's menu trigger directive (.../menu/menu-trigger.ts)
|
|
25
|
-
*/
|
|
26
|
-
export class GraniteMenuTriggerForDirective {
|
|
27
|
-
constructor(_overlay, _element, _viewContainerRef,
|
|
28
|
-
/** If this is a _submenu_ trigger, it will have a parent menu */
|
|
29
|
-
_parentMenu,
|
|
30
|
-
//#region --- Touch device customizations ---
|
|
31
|
-
/** Client input device information */
|
|
32
|
-
_clientInput,
|
|
33
|
-
/** Client output device information */
|
|
34
|
-
_clientOutput,
|
|
35
|
-
//#endregion --- Touch device customizations ---
|
|
36
|
-
/**
|
|
37
|
-
* If this is a _submenu_ trigger, there should be a corresponding menu
|
|
38
|
-
* item directive present as well:
|
|
39
|
-
*
|
|
40
|
-
* <button graniteMenuItem [graniteMenuTriggerFor]="...">
|
|
41
|
-
* ^-- This one
|
|
42
|
-
*/
|
|
43
|
-
_menuItemInstance, _dir, _focusMonitor,
|
|
44
|
-
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
45
|
-
document) {
|
|
46
|
-
this._overlay = _overlay;
|
|
47
|
-
this._element = _element;
|
|
48
|
-
this._viewContainerRef = _viewContainerRef;
|
|
49
|
-
this._parentMenu = _parentMenu;
|
|
50
|
-
this._clientInput = _clientInput;
|
|
51
|
-
this._clientOutput = _clientOutput;
|
|
52
|
-
this._menuItemInstance = _menuItemInstance;
|
|
53
|
-
this._dir = _dir;
|
|
54
|
-
this._focusMonitor = _focusMonitor;
|
|
55
|
-
/** Whether the associated menu is open */
|
|
56
|
-
this._isMenuOpen = false;
|
|
57
|
-
// Tracking input type is necessary so it's possible to only auto-focus
|
|
58
|
-
// the first item of the list when the menu is opened via the keyboard
|
|
59
|
-
this._openedBy = null;
|
|
60
|
-
this._hoverSubscription = Subscription.EMPTY;
|
|
61
|
-
this._menuCloseSubscription = Subscription.EMPTY;
|
|
62
|
-
this._closingActionsSubscription = Subscription.EMPTY;
|
|
63
|
-
this._portal = null;
|
|
64
|
-
this._overlayRef = null;
|
|
65
|
-
this._touchTouchingElement = false;
|
|
66
|
-
/**
|
|
67
|
-
* Handles touch start events on the trigger.
|
|
68
|
-
* Needs to be an arrow function so we can easily use addEventListener and removeEventListener.
|
|
69
|
-
*/
|
|
70
|
-
this._handleTouchStart = () => {
|
|
71
|
-
this._openedBy = 'touch';
|
|
72
|
-
};
|
|
73
|
-
// ----------------------------------------- //
|
|
74
|
-
// --- Here be poor man's touch gestures --- //
|
|
75
|
-
// ----------------------------------------- //
|
|
76
|
-
// TODO: Replace with Hammer or other gesture library
|
|
77
|
-
/**
|
|
78
|
-
* Handles touch start events on the overlay host element (wrapper).
|
|
79
|
-
* Needs to be an arrow function so we can easily use addEventListener and removeEventListener.
|
|
80
|
-
*/
|
|
81
|
-
this._handleOverlayTouchStart = (event) => {
|
|
82
|
-
if (this.menu._isAnimating) {
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
this._touchStartTime = new Date().getTime();
|
|
86
|
-
this._touchStartX = event.changedTouches[0].clientX;
|
|
87
|
-
this._touchStartY = event.changedTouches[0].clientY;
|
|
88
|
-
this._touchCurrentX = this._touchStartX;
|
|
89
|
-
this._touchCurrentY = this._touchStartY;
|
|
90
|
-
this._touchTranslateX = 0;
|
|
91
|
-
this._touchMaxX = this._overlayRef.hostElement.getBoundingClientRect().width;
|
|
92
|
-
this._touchLockedX = null;
|
|
93
|
-
this._touchTouchingElement = true;
|
|
94
|
-
};
|
|
95
|
-
this._handleOverlayTouchMove = (event) => {
|
|
96
|
-
if (!this._touchTouchingElement || this.menu._isAnimating) {
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
|
-
if (this._touchLockedX) {
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
this._touchCurrentX = event.changedTouches[0].clientX;
|
|
103
|
-
this._touchCurrentY = event.changedTouches[0].clientY;
|
|
104
|
-
// Lock X-axis pan if initiating pan on Y-axis
|
|
105
|
-
if (this._touchLockedX === null) {
|
|
106
|
-
const dy = Math.abs(this._touchCurrentY - this._touchStartY);
|
|
107
|
-
const dx = Math.abs(this._touchCurrentX - this._touchStartX);
|
|
108
|
-
if (dx > 10 || dy > 10) {
|
|
109
|
-
this._touchLockedX = dy > dx;
|
|
110
|
-
return;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
// Restrict to right pan/swipe and make menu movement extremely slow when
|
|
114
|
-
// moved past allowed limits.
|
|
115
|
-
const menuMargin = 16;
|
|
116
|
-
this._touchTranslateX = this._touchCurrentX - this._touchStartX;
|
|
117
|
-
if (this._touchTranslateX < 0) {
|
|
118
|
-
this._touchTranslateX = this.easeOutExpo(this._touchTranslateX, 0, -menuMargin / 2, this._touchMaxX * -4);
|
|
119
|
-
}
|
|
120
|
-
else if (!this._parentMenu) {
|
|
121
|
-
this._touchTranslateX = this.easeOutExpo(this._touchTranslateX, 0, menuMargin / 2, this._touchMaxX * 4);
|
|
122
|
-
}
|
|
123
|
-
else if (this._touchTranslateX > this._touchMaxX) {
|
|
124
|
-
this._touchTranslateX = this.easeOutExpo(this._touchTranslateX - this._touchMaxX, this._touchMaxX, menuMargin / 2, this._touchMaxX * 4);
|
|
125
|
-
}
|
|
126
|
-
// Set new sub menu position and tell any parent to follow;
|
|
127
|
-
this.animateSetMenuPosition(this._touchTranslateX);
|
|
128
|
-
};
|
|
129
|
-
this._handleOverlayTouchEnd = () => {
|
|
130
|
-
if (!this._touchTouchingElement || this.menu._isAnimating) {
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
this._touchTranslateX = this._touchCurrentX - this._touchStartX;
|
|
134
|
-
if (this._touchTranslateX === 0) {
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
this._touchTouchingElement = false;
|
|
138
|
-
this._touchTimeTaken = new Date().getTime() - this._touchStartTime;
|
|
139
|
-
const swipeMinDistance = 10;
|
|
140
|
-
const swipeMinTime = 50;
|
|
141
|
-
const swipeMaxTime = 300;
|
|
142
|
-
const pannedHalfwayRight = this._touchTranslateX > this._touchMaxX / 2;
|
|
143
|
-
const swipedRight = this._touchTranslateX > this._touchMaxX / swipeMinDistance &&
|
|
144
|
-
this._touchTimeTaken > swipeMinTime &&
|
|
145
|
-
this._touchTimeTaken < swipeMaxTime;
|
|
146
|
-
if (!!this._parentMenu && (swipedRight || pannedHalfwayRight)) {
|
|
147
|
-
// Close submenu keydown-style: close only this menu and leave parents open
|
|
148
|
-
this.menu.closed.emit('keydown');
|
|
149
|
-
}
|
|
150
|
-
else {
|
|
151
|
-
// Pan ended but the menu was not moved far enough. Reset menus to
|
|
152
|
-
// where they were before panning stared.
|
|
153
|
-
this.animateOpenMenu();
|
|
154
|
-
}
|
|
155
|
-
};
|
|
156
|
-
_element.nativeElement.addEventListener('touchstart', this._handleTouchStart, passiveEventListenerOptions);
|
|
157
|
-
if (_menuItemInstance) {
|
|
158
|
-
_menuItemInstance._triggersSubmenu = this.triggersSubmenu();
|
|
159
|
-
}
|
|
160
|
-
this._document = document;
|
|
161
|
-
}
|
|
162
|
-
ngOnChanges(changes) {
|
|
163
|
-
if (changes.menu) {
|
|
164
|
-
this._handleMenuChange();
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
ngAfterContentInit() {
|
|
168
|
-
// removed checkMenu here to avoid errors in dynamically genarated menus
|
|
169
|
-
// menu is checked when opening the menu
|
|
170
|
-
// this._checkMenu();
|
|
171
|
-
this._handleHover();
|
|
172
|
-
}
|
|
173
|
-
ngOnDestroy() {
|
|
174
|
-
if (this._overlayRef) {
|
|
175
|
-
//#region --- Touch device customizations ---
|
|
176
|
-
this.removeOverlayListeners();
|
|
177
|
-
//#endregion --- Touch device customizations ---
|
|
178
|
-
this._overlayRef.dispose();
|
|
179
|
-
this._overlayRef = null;
|
|
180
|
-
}
|
|
181
|
-
this._element.nativeElement.removeEventListener('touchstart', this._handleTouchStart, passiveEventListenerOptions);
|
|
182
|
-
this._hoverSubscription.unsubscribe();
|
|
183
|
-
this._menuCloseSubscription.unsubscribe();
|
|
184
|
-
this._closingActionsSubscription.unsubscribe();
|
|
185
|
-
}
|
|
186
|
-
/** Handles change of associated menu */
|
|
187
|
-
_handleMenuChange() {
|
|
188
|
-
this._menuCloseSubscription.unsubscribe();
|
|
189
|
-
// Close the menu overlay when the menu itself says it wants to be closed
|
|
190
|
-
if (this.menu) {
|
|
191
|
-
const closed = this.menu.closed;
|
|
192
|
-
this._menuCloseSubscription = closed.subscribe((reason) => {
|
|
193
|
-
//#region --- Touch device customizations ---
|
|
194
|
-
if (this.menu._isClosing) {
|
|
195
|
-
return;
|
|
196
|
-
}
|
|
197
|
-
this.menu._isClosing = true;
|
|
198
|
-
// Get rid of the menu and tell any parent to restore its position
|
|
199
|
-
if (this._clientOutput.device === 'touch') {
|
|
200
|
-
// First we wait for any running animation to complete
|
|
201
|
-
const runningAnimationDone = this.menu._isAnimating
|
|
202
|
-
? this.menu._animationDone
|
|
203
|
-
: observableOf([null]);
|
|
204
|
-
runningAnimationDone
|
|
205
|
-
.pipe(take(1), delay(0, asapScheduler))
|
|
206
|
-
// eslint-disable-next-line rxjs/no-nested-subscribe
|
|
207
|
-
.subscribe(() => {
|
|
208
|
-
this.animateCloseMenu(reason !== 'keydown', reason === 'click');
|
|
209
|
-
this.menu._animationDone
|
|
210
|
-
.pipe(take(1), delay(0, asapScheduler))
|
|
211
|
-
// eslint-disable-next-line rxjs/no-nested-subscribe
|
|
212
|
-
.subscribe(() => this._destroyMenu());
|
|
213
|
-
});
|
|
214
|
-
}
|
|
215
|
-
else {
|
|
216
|
-
//#endregion --- Touch device customizations ---
|
|
217
|
-
this._destroyMenu();
|
|
218
|
-
}
|
|
219
|
-
// If a click closed the menu, we should close the entire chain of nested menus.
|
|
220
|
-
if ((reason === 'click' || reason === 'tab') && this._parentMenu) {
|
|
221
|
-
this._parentMenu.closed.emit(reason);
|
|
222
|
-
}
|
|
223
|
-
});
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
isOpen() {
|
|
227
|
-
return this._isMenuOpen;
|
|
228
|
-
}
|
|
229
|
-
/** Open the associated menu */
|
|
230
|
-
openMenu() {
|
|
231
|
-
var _a;
|
|
232
|
-
if (this._isMenuOpen) {
|
|
233
|
-
return;
|
|
234
|
-
}
|
|
235
|
-
this._checkMenu();
|
|
236
|
-
this.menu.parentMenu = this.triggersSubmenu()
|
|
237
|
-
? this._parentMenu
|
|
238
|
-
: undefined;
|
|
239
|
-
this.menu.direction = this._dir.value === 'rtl' ? 'rtl' : 'ltr';
|
|
240
|
-
if (this._parentMenu) {
|
|
241
|
-
// Menu triggers inherit target device types from their parent.
|
|
242
|
-
// Ultimately it is the root trigger that determines device types for
|
|
243
|
-
// the whole menu hierarchy.
|
|
244
|
-
this._clientInput = this._parentMenu._clientInput;
|
|
245
|
-
this._clientOutput = this._parentMenu._clientOutput;
|
|
246
|
-
}
|
|
247
|
-
//#region --- Touch device customizations ---
|
|
248
|
-
// Make the menu we're about to open use the same devices as the trigger
|
|
249
|
-
this.menu._setDevice(this._clientInput, this._clientOutput);
|
|
250
|
-
if (this._clientOutput.device === 'touch') {
|
|
251
|
-
this.menu.showBackButton = !!this._parentMenu;
|
|
252
|
-
this.menu._updateShowTitle();
|
|
253
|
-
if (!this.menu.closeLabel) {
|
|
254
|
-
this.menu.closeLabel = (_a = this._parentMenu) === null || _a === void 0 ? void 0 : _a.closeLabel;
|
|
255
|
-
}
|
|
256
|
-
this.menu.showCloseButton = !!this.menu.closeLabel;
|
|
257
|
-
}
|
|
258
|
-
this.menu._isClosing = false;
|
|
259
|
-
const panelClass = [];
|
|
260
|
-
if (this._clientOutput.device === 'touch') {
|
|
261
|
-
panelClass.push('granite-overlay-pane-fill-width-bottom');
|
|
262
|
-
}
|
|
263
|
-
const scrollStrategy = this._clientOutput.device !== 'touch'
|
|
264
|
-
? this._overlay.scrollStrategies.reposition()
|
|
265
|
-
: undefined;
|
|
266
|
-
const hasBackdrop = this._clientOutput.device === 'touch' && !this.triggersSubmenu();
|
|
267
|
-
//#endregion --- Touch device customizations ---
|
|
268
|
-
// Create an overlay to stuff the menu (portal) into below
|
|
269
|
-
if (!this._overlayRef) {
|
|
270
|
-
const config = new OverlayConfig({
|
|
271
|
-
positionStrategy: this._positionStrategy(),
|
|
272
|
-
backdropClass: 'granite-overlay-dark-glass-backdrop',
|
|
273
|
-
scrollStrategy,
|
|
274
|
-
direction: this._dir,
|
|
275
|
-
panelClass,
|
|
276
|
-
hasBackdrop,
|
|
277
|
-
});
|
|
278
|
-
this._overlayRef = this._overlay.create(config);
|
|
279
|
-
//#region --- Touch device customizations ---
|
|
280
|
-
// Add touch listener for submenu back pan/swipe
|
|
281
|
-
if (this._clientOutput.device === 'touch') {
|
|
282
|
-
this.addOverlayListeners();
|
|
283
|
-
}
|
|
284
|
-
//#endregion --- Touch device customizations ---
|
|
285
|
-
}
|
|
286
|
-
else {
|
|
287
|
-
// Reset animation state for reused overlays
|
|
288
|
-
if (this._clientOutput.device === 'touch') {
|
|
289
|
-
this.menu._panelAnimationState = 'void';
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
// Create portal from associated menu's template
|
|
293
|
-
if (!this._portal || this._portal.templateRef !== this.menu.templateRef) {
|
|
294
|
-
this._portal = new TemplatePortal(this.menu.templateRef, this._viewContainerRef);
|
|
295
|
-
}
|
|
296
|
-
// Attach menu portal to overlay ref (which is a portal outlet)
|
|
297
|
-
this._overlayRef.attach(this._portal);
|
|
298
|
-
// Subscribe to stream that emits whenever an action that should close the menu occurs
|
|
299
|
-
this._closingActionsSubscription = this._menuClosingActions().subscribe(() => this.closeMenu());
|
|
300
|
-
this.animateOpenMenu();
|
|
301
|
-
this._setIsMenuOpen(true);
|
|
302
|
-
this.menu.focusFirstItem(this._openedBy || 'program');
|
|
303
|
-
}
|
|
304
|
-
/** Whether the menu triggers a sub-menu or a top-level one. */
|
|
305
|
-
triggersSubmenu() {
|
|
306
|
-
return !!(this._menuItemInstance && this._parentMenu);
|
|
307
|
-
}
|
|
308
|
-
/** Toggles the menu between the open and closed states. */
|
|
309
|
-
toggleMenu() {
|
|
310
|
-
if (this._isMenuOpen) {
|
|
311
|
-
this.closeMenu();
|
|
312
|
-
}
|
|
313
|
-
else {
|
|
314
|
-
this.openMenu();
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
/** Close the associated menu */
|
|
318
|
-
closeMenu() {
|
|
319
|
-
this.menu.closed.emit();
|
|
320
|
-
}
|
|
321
|
-
/**
|
|
322
|
-
* Focuses the menu trigger.
|
|
323
|
-
* @param origin Source of the menu trigger's focus.
|
|
324
|
-
*/
|
|
325
|
-
focus(origin = 'program', options) {
|
|
326
|
-
if (this._focusMonitor) {
|
|
327
|
-
this._focusMonitor.focusVia(this._element, origin, options);
|
|
328
|
-
}
|
|
329
|
-
else {
|
|
330
|
-
this._element.nativeElement.focus(options);
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
/** Detach menu portal from overlay and update open state */
|
|
334
|
-
_destroyMenu() {
|
|
335
|
-
if (!this._overlayRef || !this._isMenuOpen) {
|
|
336
|
-
return;
|
|
337
|
-
}
|
|
338
|
-
this._closingActionsSubscription.unsubscribe();
|
|
339
|
-
this._overlayRef.detach();
|
|
340
|
-
this._restoreFocus();
|
|
341
|
-
this.menu._resetAnimation();
|
|
342
|
-
this._setIsMenuOpen(false);
|
|
343
|
-
}
|
|
344
|
-
/** Handles mouse presses on the trigger. */
|
|
345
|
-
_handleMousedown(event) {
|
|
346
|
-
if (!isFakeMousedownFromScreenReader(event)) {
|
|
347
|
-
if (this._openedBy !== 'touch') {
|
|
348
|
-
// Since right or middle button clicks won't trigger the `click` event,
|
|
349
|
-
// we shouldn't consider the menu as opened by mouse in those cases.
|
|
350
|
-
this._openedBy = event.button === 0 ? 'mouse' : null;
|
|
351
|
-
}
|
|
352
|
-
// Since clicking on the trigger won't close the menu if it opens a sub-menu,
|
|
353
|
-
// we should prevent focus from moving onto it via click to avoid the
|
|
354
|
-
// highlight from lingering on the menu item.
|
|
355
|
-
if (this.triggersSubmenu() && !this._toggleOnSubmenuClick()) {
|
|
356
|
-
event.preventDefault();
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
/** Handles key presses on the trigger. */
|
|
361
|
-
_handleKeydown(event) {
|
|
362
|
-
const key = event.key;
|
|
363
|
-
if (this.triggersSubmenu() &&
|
|
364
|
-
((key === 'ArrowRight' && this._dir.value === 'ltr') ||
|
|
365
|
-
(key === 'ArrowLeft' && this._dir.value === 'rtl'))) {
|
|
366
|
-
this.openMenu();
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
/** Handles click events on the trigger. */
|
|
370
|
-
_handleClick(event) {
|
|
371
|
-
if (this.triggersSubmenu()) {
|
|
372
|
-
// Stop event propagation to avoid closing the parent menu.
|
|
373
|
-
event.stopPropagation();
|
|
374
|
-
this._toggleOnSubmenuClick() ? this.toggleMenu() : this.openMenu();
|
|
375
|
-
}
|
|
376
|
-
else {
|
|
377
|
-
this.toggleMenu();
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
/** Handles the cases where the user hovers over the trigger. */
|
|
381
|
-
_handleHover() {
|
|
382
|
-
// Subscribe to changes in the hovered item in order to toggle the panel.
|
|
383
|
-
if (!this.triggersSubmenu() || !this._parentMenu) {
|
|
384
|
-
return;
|
|
385
|
-
}
|
|
386
|
-
this._hoverSubscription = this._parentMenu
|
|
387
|
-
._hovered()
|
|
388
|
-
.pipe(filter(() => this._openOnHover()),
|
|
389
|
-
// Since we might have multiple competing triggers for the same menu (e.g. a sub-menu
|
|
390
|
-
// with different data and triggers), we have to delay it by a tick to ensure that
|
|
391
|
-
// it won't be closed immediately after it is opened.
|
|
392
|
-
filter((active) => active === this._menuItemInstance /*&& !active.disabled*/), delay(0, asapScheduler))
|
|
393
|
-
.subscribe(() => {
|
|
394
|
-
this._openedBy = 'mouse';
|
|
395
|
-
// If the same menu is used between multiple triggers, it might still be animating
|
|
396
|
-
// while the new trigger tries to re-open it. Wait for the animation to finish
|
|
397
|
-
// before doing so. Also interrupt if the user moves to another item.
|
|
398
|
-
if (this.menu instanceof _MenuBaseComponent && this.menu._isAnimating) {
|
|
399
|
-
// We need the `delay(0)` here in order to avoid
|
|
400
|
-
// 'changed after checked' errors in some cases. See Angular Material #12194.
|
|
401
|
-
this.menu._animationDone
|
|
402
|
-
.pipe(take(1), delay(0, asapScheduler), takeUntil(this._parentMenu._hovered()))
|
|
403
|
-
// eslint-disable-next-line rxjs/no-nested-subscribe
|
|
404
|
-
.subscribe(() => this.openMenu());
|
|
405
|
-
}
|
|
406
|
-
else {
|
|
407
|
-
this.openMenu();
|
|
408
|
-
}
|
|
409
|
-
});
|
|
410
|
-
}
|
|
411
|
-
/**
|
|
412
|
-
* Restores focus to the element that was focused before the menu was open.
|
|
413
|
-
* Could be the root trigger button or a submenu trigger item
|
|
414
|
-
*/
|
|
415
|
-
_restoreFocus() {
|
|
416
|
-
// We should reset focus if the user is navigating using a keyboard or
|
|
417
|
-
// if we have a top-level trigger which might cause focus to be lost
|
|
418
|
-
// when clicking outside of the menu.
|
|
419
|
-
if (!this._openedBy) {
|
|
420
|
-
// Note that the focus style will show up both for `program` and
|
|
421
|
-
// `keyboard` so we don't have to specify which one it is.
|
|
422
|
-
this.focus();
|
|
423
|
-
}
|
|
424
|
-
else if (!this.triggersSubmenu()) {
|
|
425
|
-
this.focus(this._openedBy);
|
|
426
|
-
}
|
|
427
|
-
this._openedBy = null;
|
|
428
|
-
}
|
|
429
|
-
// Set state rather than toggle to support triggers sharing a menu
|
|
430
|
-
_setIsMenuOpen(isOpen) {
|
|
431
|
-
this._isMenuOpen = isOpen;
|
|
432
|
-
if (this.triggersSubmenu()) {
|
|
433
|
-
this._menuItemInstance._highlighted =
|
|
434
|
-
isOpen && this._clientOutput.device !== 'touch';
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
/**
|
|
438
|
-
* This method checks that a valid instance of MenuComponent has been passed into
|
|
439
|
-
* graniteMenuTriggerFor. If not, an exception is thrown.
|
|
440
|
-
*/
|
|
441
|
-
_checkMenu() {
|
|
442
|
-
if (!this.menu) {
|
|
443
|
-
throwGraniteMenuMissingError();
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
/**
|
|
447
|
-
* Returns strategy for positioning the overlay for desktop devices:
|
|
448
|
-
* Place adjacent to the trigger button (preferably immediately below)
|
|
449
|
-
* in order to show as much of the menu as possible.
|
|
450
|
-
*/
|
|
451
|
-
_desktopPositionStrategy() {
|
|
452
|
-
const positionStrategy = this._overlay
|
|
453
|
-
.position()
|
|
454
|
-
.flexibleConnectedTo(this._element)
|
|
455
|
-
.withLockedPosition()
|
|
456
|
-
.withTransformOriginOn('.granite-menu')
|
|
457
|
-
.withPush(false);
|
|
458
|
-
this._setPosition(positionStrategy);
|
|
459
|
-
return positionStrategy;
|
|
460
|
-
}
|
|
461
|
-
/**
|
|
462
|
-
* Sets the appropriate positions on a position strategy
|
|
463
|
-
* so the overlay connects with the trigger correctly.
|
|
464
|
-
* @param positionStrategy Strategy whose position to update.
|
|
465
|
-
*/
|
|
466
|
-
_setPosition(positionStrategy) {
|
|
467
|
-
const MENU_PANEL_TOP_PADDING = 0;
|
|
468
|
-
let [originX, originFallbackX] = this.menu.xPosition === 'before' ? ['end', 'start'] : ['start', 'end'];
|
|
469
|
-
const [overlayY, overlayFallbackY] = this.menu.yPosition === 'above' ? ['bottom', 'top'] : ['top', 'bottom'];
|
|
470
|
-
let [originY, originFallbackY] = [overlayY, overlayFallbackY];
|
|
471
|
-
let [overlayX, overlayFallbackX] = [originX, originFallbackX];
|
|
472
|
-
let offsetY = 0;
|
|
473
|
-
if (this.triggersSubmenu()) {
|
|
474
|
-
// When the menu is a sub-menu, it should always align itself
|
|
475
|
-
// to the edges of the trigger, instead of overlapping it.
|
|
476
|
-
overlayFallbackX = originX =
|
|
477
|
-
this.menu.xPosition === 'before' ? 'start' : 'end';
|
|
478
|
-
originFallbackX = overlayX = originX === 'end' ? 'start' : 'end';
|
|
479
|
-
offsetY =
|
|
480
|
-
overlayY === 'bottom'
|
|
481
|
-
? MENU_PANEL_TOP_PADDING
|
|
482
|
-
: -MENU_PANEL_TOP_PADDING;
|
|
483
|
-
}
|
|
484
|
-
else {
|
|
485
|
-
originY = overlayY === 'top' ? 'bottom' : 'top';
|
|
486
|
-
originFallbackY = overlayFallbackY === 'top' ? 'bottom' : 'top';
|
|
487
|
-
}
|
|
488
|
-
positionStrategy.withPositions([
|
|
489
|
-
{ originX, originY, overlayX, overlayY, offsetY },
|
|
490
|
-
{
|
|
491
|
-
originX: originFallbackX,
|
|
492
|
-
originY,
|
|
493
|
-
overlayX: overlayFallbackX,
|
|
494
|
-
overlayY,
|
|
495
|
-
offsetY,
|
|
496
|
-
},
|
|
497
|
-
{
|
|
498
|
-
originX,
|
|
499
|
-
originY: originFallbackY,
|
|
500
|
-
overlayX,
|
|
501
|
-
overlayY: overlayFallbackY,
|
|
502
|
-
offsetY: -offsetY,
|
|
503
|
-
},
|
|
504
|
-
{
|
|
505
|
-
originX: originFallbackX,
|
|
506
|
-
originY: originFallbackY,
|
|
507
|
-
overlayX: overlayFallbackX,
|
|
508
|
-
overlayY: overlayFallbackY,
|
|
509
|
-
offsetY: -offsetY,
|
|
510
|
-
},
|
|
511
|
-
]);
|
|
512
|
-
}
|
|
513
|
-
/** Returns a stream that emits whenever an action that should close the menu occurs. */
|
|
514
|
-
_menuClosingActions() {
|
|
515
|
-
var _a;
|
|
516
|
-
const detachments = (_a = this._overlayRef) === null || _a === void 0 ? void 0 : _a.detachments();
|
|
517
|
-
const parentClose = this._parentMenu
|
|
518
|
-
? this._parentMenu.closed
|
|
519
|
-
: observableOf();
|
|
520
|
-
const hover = this._clientOutput.device === 'desktop' && this._parentMenu
|
|
521
|
-
? this._parentMenu._hovered().pipe(filter((item) => item !== this._menuItemInstance), filter(() => this._isMenuOpen))
|
|
522
|
-
: observableOf();
|
|
523
|
-
// Note: Quick fix. Feature reportedly exists in CDK for Angular 10
|
|
524
|
-
// Filter to prevent closing when animating added though. Applied to
|
|
525
|
-
// root menu only.
|
|
526
|
-
const outsideClick = !this._parentMenu
|
|
527
|
-
? fromEvent(this._document, 'click').pipe(filter((e) => e.target !== this._element.nativeElement &&
|
|
528
|
-
e.target.closest('.granite-menu') === null), filter(() => !this.menu._isAnimating))
|
|
529
|
-
: observableOf();
|
|
530
|
-
return merge(detachments, hover, parentClose, outsideClick);
|
|
531
|
-
}
|
|
532
|
-
/**
|
|
533
|
-
* Whether to automatically open submenus on hover. This is true when showing
|
|
534
|
-
* desktop menus and having mouse support.
|
|
535
|
-
*/
|
|
536
|
-
_openOnHover() {
|
|
537
|
-
var _a, _b;
|
|
538
|
-
return ((this.triggersSubmenu()
|
|
539
|
-
? this._parentMenu.openOnHover
|
|
540
|
-
: this.menu.openOnHover) &&
|
|
541
|
-
((_a = this._parentMenu._clientOutput) === null || _a === void 0 ? void 0 : _a.device) === 'desktop' && ((_b = this._parentMenu._clientInput) === null || _b === void 0 ? void 0 : _b.devices.includes('mouse')));
|
|
542
|
-
}
|
|
543
|
-
/**
|
|
544
|
-
* Whether to toggle submenus on click. This is true when showing desktop menus
|
|
545
|
-
* without mouse support. Which, by the way, is not a great idea to begin with.
|
|
546
|
-
*/
|
|
547
|
-
_toggleOnSubmenuClick() {
|
|
548
|
-
var _a, _b;
|
|
549
|
-
return (!(this.triggersSubmenu()
|
|
550
|
-
? this._parentMenu.openOnHover
|
|
551
|
-
: this.menu.openOnHover) ||
|
|
552
|
-
(((_a = this._parentMenu._clientOutput) === null || _a === void 0 ? void 0 : _a.device) === 'desktop' &&
|
|
553
|
-
!((_b = this._parentMenu._clientInput) === null || _b === void 0 ? void 0 : _b.devices.includes('mouse'))));
|
|
554
|
-
}
|
|
555
|
-
// ------------------------------------------- //
|
|
556
|
-
// --- Here be touch device customizations --- //
|
|
557
|
-
// ------------------------------------------- //
|
|
558
|
-
/** Set animation state to bring a newly opened menu into view */
|
|
559
|
-
animateOpenMenu() {
|
|
560
|
-
this._clientOutput.device === 'touch'
|
|
561
|
-
? this.animateTouchOpenMenu()
|
|
562
|
-
: this.menu._startAnimation();
|
|
563
|
-
}
|
|
564
|
-
animateTouchOpenMenu() {
|
|
565
|
-
if (this.triggersSubmenu()) {
|
|
566
|
-
// Slide newly opened sub menu into view from the side,
|
|
567
|
-
// pushing any parent menu out of view on the other side
|
|
568
|
-
this.menu._startTouchSubmenuEnterAnimation();
|
|
569
|
-
this._parentMenu._startTouchHideAnimation();
|
|
570
|
-
}
|
|
571
|
-
else {
|
|
572
|
-
// Slide root menu into view from below
|
|
573
|
-
this.menu._startTouchRootEnterAnimation();
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
/** Set animation state to close the active menu */
|
|
577
|
-
animateCloseMenu(toBelow, withDelay) {
|
|
578
|
-
this._clientOutput.device === 'touch'
|
|
579
|
-
? this._animateTouchCloseMenu(toBelow, withDelay)
|
|
580
|
-
: this._parentMenu._resetAnimation();
|
|
581
|
-
}
|
|
582
|
-
_animateTouchCloseMenu(toBelow, withDelay) {
|
|
583
|
-
var _a;
|
|
584
|
-
if (toBelow) {
|
|
585
|
-
// Slide menu out of view below the viewport
|
|
586
|
-
withDelay
|
|
587
|
-
? this.menu._startTouchCloseDownAnimationWithDelay()
|
|
588
|
-
: this.menu._startTouchCloseDownAnimation();
|
|
589
|
-
}
|
|
590
|
-
else {
|
|
591
|
-
// Slide the closed menu out of view to the side
|
|
592
|
-
// and slide any parent menu back into view
|
|
593
|
-
this.menu._startTouchCloseSideAnimation();
|
|
594
|
-
(_a = this._parentMenu) === null || _a === void 0 ? void 0 : _a._startTouchSubmenuEnterAnimation();
|
|
595
|
-
}
|
|
596
|
-
}
|
|
597
|
-
/**
|
|
598
|
-
* Set animation state to place the menu and any parent at the given
|
|
599
|
-
* horizontal position, i.e. following touch pan movement.
|
|
600
|
-
*
|
|
601
|
-
* @param xOffset Horizontal offset
|
|
602
|
-
*/
|
|
603
|
-
animateSetMenuPosition(xOffset) {
|
|
604
|
-
this.menu._startTouchPanAnimation(xOffset);
|
|
605
|
-
if (this._parentMenu) {
|
|
606
|
-
this._parentMenu._startTouchHidePanAnimation(xOffset);
|
|
607
|
-
}
|
|
608
|
-
}
|
|
609
|
-
/**
|
|
610
|
-
* Returns strategy for positioning the overlay depending on what type of
|
|
611
|
-
* device the menu is being shown on
|
|
612
|
-
*/
|
|
613
|
-
_positionStrategy() {
|
|
614
|
-
return this._clientOutput.device === 'touch'
|
|
615
|
-
? this._touchPositionStrategy()
|
|
616
|
-
: this._desktopPositionStrategy();
|
|
617
|
-
}
|
|
618
|
-
/**
|
|
619
|
-
* Returns strategy for positioning the overlay for touch devices:
|
|
620
|
-
* Place centered at the bottom of the screen.
|
|
621
|
-
*/
|
|
622
|
-
_touchPositionStrategy() {
|
|
623
|
-
return this._overlay.position().global();
|
|
624
|
-
}
|
|
625
|
-
/**
|
|
626
|
-
* Remove touch device pan/swipe listeners from overlay host element
|
|
627
|
-
*/
|
|
628
|
-
addOverlayListeners() {
|
|
629
|
-
this._overlayRef.hostElement.addEventListener('touchstart', this._handleOverlayTouchStart, passiveEventListenerOptions);
|
|
630
|
-
this._overlayRef.hostElement.addEventListener('touchmove', this._handleOverlayTouchMove, passiveEventListenerOptions);
|
|
631
|
-
this._overlayRef.hostElement.addEventListener('touchend', this._handleOverlayTouchEnd, passiveEventListenerOptions);
|
|
632
|
-
}
|
|
633
|
-
/**
|
|
634
|
-
* Remove touch device pan/swipe listeners from overlay host element
|
|
635
|
-
*/
|
|
636
|
-
removeOverlayListeners() {
|
|
637
|
-
this._overlayRef.hostElement.removeEventListener('touchstart', this._handleOverlayTouchStart, passiveEventListenerOptions);
|
|
638
|
-
this._overlayRef.hostElement.removeEventListener('touchmove', this._handleOverlayTouchMove, passiveEventListenerOptions);
|
|
639
|
-
this._overlayRef.hostElement.removeEventListener('touchend', this._handleOverlayTouchEnd, passiveEventListenerOptions);
|
|
640
|
-
}
|
|
641
|
-
/**
|
|
642
|
-
* Standard exponential ease out function
|
|
643
|
-
*
|
|
644
|
-
* @param current Current value
|
|
645
|
-
* @param offset Offset value, to which calculated value will be added
|
|
646
|
-
* @param target The target value
|
|
647
|
-
* @param end Value to which current value is compared
|
|
648
|
-
*/
|
|
649
|
-
easeOutExpo(current, offset, target, end) {
|
|
650
|
-
return current === end
|
|
651
|
-
? offset + target
|
|
652
|
-
: target * (-Math.pow(2, (-10 * current) / end) + 1) + offset;
|
|
653
|
-
}
|
|
654
|
-
}
|
|
655
|
-
GraniteMenuTriggerForDirective.decorators = [
|
|
656
|
-
{ type: Directive, args: [{
|
|
657
|
-
selector: `[graniteMenuTriggerFor]`,
|
|
658
|
-
host: {
|
|
659
|
-
class: 'granite-menu-trigger',
|
|
660
|
-
'aria-haspopup': 'true',
|
|
661
|
-
'[attr.aria-expanded]': '_isMenuOpen || null',
|
|
662
|
-
'[attr.aria-controls]': '_isMenuOpen ? menu.panelId : null',
|
|
663
|
-
'(mousedown)': '_handleMousedown($event)',
|
|
664
|
-
'(keydown)': '_handleKeydown($event)',
|
|
665
|
-
'(click)': '_handleClick($event)',
|
|
666
|
-
},
|
|
667
|
-
},] }
|
|
668
|
-
];
|
|
669
|
-
GraniteMenuTriggerForDirective.ctorParameters = () => [
|
|
670
|
-
{ type: Overlay },
|
|
671
|
-
{ type: ElementRef },
|
|
672
|
-
{ type: ViewContainerRef },
|
|
673
|
-
{ type: _MenuBaseComponent, decorators: [{ type: Inject, args: [GRANITE_MENU_PANEL,] }, { type: Optional }] },
|
|
674
|
-
{ type: undefined, decorators: [{ type: Inject, args: [GRANITE_CLIENT_INPUT,] }, { type: Optional }] },
|
|
675
|
-
{ type: undefined, decorators: [{ type: Inject, args: [GRANITE_CLIENT_OUTPUT,] }, { type: Optional }] },
|
|
676
|
-
{ type: GraniteMenuItemComponent, decorators: [{ type: Optional }, { type: Self }] },
|
|
677
|
-
{ type: Directionality, decorators: [{ type: Optional }] },
|
|
678
|
-
{ type: FocusMonitor },
|
|
679
|
-
{ type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] }
|
|
680
|
-
];
|
|
681
|
-
GraniteMenuTriggerForDirective.propDecorators = {
|
|
682
|
-
menu: [{ type: Input, args: ['graniteMenuTriggerFor',] }]
|
|
683
|
-
};
|
|
684
|
-
//# sourceMappingURL=menu-trigger-for.directive.js.map
|