@skyux/popovers 5.0.2 → 5.5.0

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.
Files changed (152) hide show
  1. package/README.md +6 -4
  2. package/bundles/skyux-popovers-testing.umd.js +8 -8
  3. package/bundles/skyux-popovers.umd.js +43 -39
  4. package/documentation.json +241 -44
  5. package/esm2015/index.js +23 -0
  6. package/esm2015/index.js.map +1 -0
  7. package/esm2015/lib/modules/dropdown/dropdown-button.component.js +14 -0
  8. package/esm2015/lib/modules/dropdown/dropdown-button.component.js.map +1 -0
  9. package/esm2015/lib/modules/dropdown/dropdown-extensions.js +14 -0
  10. package/esm2015/lib/modules/dropdown/dropdown-extensions.js.map +1 -0
  11. package/esm2015/lib/modules/dropdown/dropdown-item.component.js +72 -0
  12. package/esm2015/lib/modules/dropdown/dropdown-item.component.js.map +1 -0
  13. package/esm2015/lib/modules/dropdown/dropdown-menu.component.js +307 -0
  14. package/esm2015/lib/modules/dropdown/dropdown-menu.component.js.map +1 -0
  15. package/esm2015/lib/modules/dropdown/dropdown.component.js +360 -0
  16. package/esm2015/lib/modules/dropdown/dropdown.component.js.map +1 -0
  17. package/esm2015/lib/modules/dropdown/dropdown.module.js +60 -0
  18. package/esm2015/lib/modules/dropdown/dropdown.module.js.map +1 -0
  19. package/esm2015/lib/modules/dropdown/types/dropdown-horizontal-alignment.js +2 -0
  20. package/esm2015/lib/modules/dropdown/types/dropdown-horizontal-alignment.js.map +1 -0
  21. package/esm2015/lib/modules/dropdown/types/dropdown-menu-change.js +2 -0
  22. package/esm2015/lib/modules/dropdown/types/dropdown-menu-change.js.map +1 -0
  23. package/esm2015/lib/modules/dropdown/types/dropdown-message-type.js +37 -0
  24. package/esm2015/lib/modules/dropdown/types/dropdown-message-type.js.map +1 -0
  25. package/esm2015/lib/modules/dropdown/types/dropdown-message.js +2 -0
  26. package/esm2015/lib/modules/dropdown/types/dropdown-message.js.map +1 -0
  27. package/esm2015/lib/modules/dropdown/types/dropdown-trigger-type.js +2 -0
  28. package/esm2015/lib/modules/dropdown/types/dropdown-trigger-type.js.map +1 -0
  29. package/esm2015/lib/modules/popover/popover-adapter.service.js +74 -0
  30. package/esm2015/lib/modules/popover/popover-adapter.service.js.map +1 -0
  31. package/esm2015/lib/modules/popover/popover-animation-state.js +2 -0
  32. package/esm2015/lib/modules/popover/popover-animation-state.js.map +1 -0
  33. package/esm2015/lib/modules/popover/popover-animation.js +19 -0
  34. package/esm2015/lib/modules/popover/popover-animation.js.map +1 -0
  35. package/esm2015/lib/modules/popover/popover-content.component.js +268 -0
  36. package/esm2015/lib/modules/popover/popover-content.component.js.map +1 -0
  37. package/esm2015/lib/modules/popover/popover-context.js +10 -0
  38. package/esm2015/lib/modules/popover/popover-context.js.map +1 -0
  39. package/esm2015/lib/modules/popover/popover-extensions.js +29 -0
  40. package/esm2015/lib/modules/popover/popover-extensions.js.map +1 -0
  41. package/esm2015/lib/modules/popover/popover.component.js +203 -0
  42. package/esm2015/lib/modules/popover/popover.component.js.map +1 -0
  43. package/esm2015/lib/modules/popover/popover.directive.js +176 -0
  44. package/esm2015/lib/modules/popover/popover.directive.js.map +1 -0
  45. package/esm2015/lib/modules/popover/popover.module.js +56 -0
  46. package/esm2015/lib/modules/popover/popover.module.js.map +1 -0
  47. package/esm2015/lib/modules/popover/types/popover-adapter-arrow-coordinates.js +2 -0
  48. package/esm2015/lib/modules/popover/types/popover-adapter-arrow-coordinates.js.map +1 -0
  49. package/esm2015/lib/modules/popover/types/popover-adapter-elements.js +2 -0
  50. package/esm2015/lib/modules/popover/types/popover-adapter-elements.js.map +1 -0
  51. package/esm2015/lib/modules/popover/types/popover-alignment.js +2 -0
  52. package/esm2015/lib/modules/popover/types/popover-alignment.js.map +1 -0
  53. package/esm2015/lib/modules/popover/types/popover-message-type.js +24 -0
  54. package/esm2015/lib/modules/popover/types/popover-message-type.js.map +1 -0
  55. package/esm2015/lib/modules/popover/types/popover-message.js +2 -0
  56. package/esm2015/lib/modules/popover/types/popover-message.js.map +1 -0
  57. package/esm2015/lib/modules/popover/types/popover-placement.js +2 -0
  58. package/esm2015/lib/modules/popover/types/popover-placement.js.map +1 -0
  59. package/esm2015/lib/modules/popover/types/popover-position.js +2 -0
  60. package/esm2015/lib/modules/popover/types/popover-position.js.map +1 -0
  61. package/esm2015/lib/modules/popover/types/popover-trigger.js +2 -0
  62. package/esm2015/lib/modules/popover/types/popover-trigger.js.map +1 -0
  63. package/esm2015/lib/modules/shared/sky-popovers-resources.module.js +47 -0
  64. package/esm2015/lib/modules/shared/sky-popovers-resources.module.js.map +1 -0
  65. package/esm2015/skyux-popovers.js +2 -2
  66. package/esm2015/skyux-popovers.js.map +1 -0
  67. package/esm2015/testing/dropdown/dropdown-fixture.js +1 -1
  68. package/esm2015/testing/dropdown/dropdown-fixture.js.map +1 -0
  69. package/esm2015/testing/dropdown/dropdown-testing.module.js +5 -5
  70. package/esm2015/testing/dropdown/dropdown-testing.module.js.map +1 -0
  71. package/esm2015/testing/dropdown/popovers-fixture-dropdown-item.js +1 -1
  72. package/esm2015/testing/dropdown/popovers-fixture-dropdown-item.js.map +1 -0
  73. package/esm2015/testing/dropdown/popovers-fixture-dropdown-menu.js +1 -1
  74. package/esm2015/testing/dropdown/popovers-fixture-dropdown-menu.js.map +1 -0
  75. package/esm2015/testing/dropdown/popovers-fixture-dropdown.js +1 -1
  76. package/esm2015/testing/dropdown/popovers-fixture-dropdown.js.map +1 -0
  77. package/esm2015/testing/popover/popover-fixture.js +1 -1
  78. package/esm2015/testing/popover/popover-fixture.js.map +1 -0
  79. package/esm2015/testing/popover/popover-testing.module.js +5 -5
  80. package/esm2015/testing/popover/popover-testing.module.js.map +1 -0
  81. package/esm2015/testing/public-api.js +1 -1
  82. package/esm2015/testing/public-api.js.map +1 -0
  83. package/esm2015/testing/skyux-popovers-testing.js +1 -1
  84. package/esm2015/testing/skyux-popovers-testing.js.map +1 -0
  85. package/fesm2015/skyux-popovers-testing.js +8 -8
  86. package/fesm2015/skyux-popovers-testing.js.map +1 -1
  87. package/fesm2015/skyux-popovers.js +53 -49
  88. package/fesm2015/skyux-popovers.js.map +1 -1
  89. package/index.d.ts +20 -0
  90. package/{modules → lib/modules}/dropdown/dropdown-button.component.d.ts +0 -0
  91. package/{modules → lib/modules}/dropdown/dropdown-extensions.d.ts +0 -0
  92. package/{modules → lib/modules}/dropdown/dropdown-item.component.d.ts +0 -0
  93. package/{modules → lib/modules}/dropdown/dropdown-menu.component.d.ts +0 -0
  94. package/{modules → lib/modules}/dropdown/dropdown.component.d.ts +0 -0
  95. package/{modules → lib/modules}/dropdown/dropdown.module.d.ts +0 -0
  96. package/{modules → lib/modules}/dropdown/types/dropdown-horizontal-alignment.d.ts +0 -0
  97. package/{modules → lib/modules}/dropdown/types/dropdown-menu-change.d.ts +0 -0
  98. package/{modules → lib/modules}/dropdown/types/dropdown-message-type.d.ts +0 -0
  99. package/{modules → lib/modules}/dropdown/types/dropdown-message.d.ts +0 -0
  100. package/{modules → lib/modules}/dropdown/types/dropdown-trigger-type.d.ts +0 -0
  101. package/{modules → lib/modules}/popover/popover-adapter.service.d.ts +0 -0
  102. package/{modules → lib/modules}/popover/popover-animation-state.d.ts +0 -0
  103. package/{modules → lib/modules}/popover/popover-animation.d.ts +0 -0
  104. package/{modules → lib/modules}/popover/popover-content.component.d.ts +0 -0
  105. package/{modules → lib/modules}/popover/popover-context.d.ts +0 -0
  106. package/{modules → lib/modules}/popover/popover-extensions.d.ts +0 -0
  107. package/{modules → lib/modules}/popover/popover.component.d.ts +4 -1
  108. package/{modules → lib/modules}/popover/popover.directive.d.ts +2 -0
  109. package/{modules → lib/modules}/popover/popover.module.d.ts +0 -0
  110. package/{modules → lib/modules}/popover/types/popover-adapter-arrow-coordinates.d.ts +0 -0
  111. package/{modules → lib/modules}/popover/types/popover-adapter-elements.d.ts +0 -0
  112. package/{modules → lib/modules}/popover/types/popover-alignment.d.ts +0 -0
  113. package/{modules → lib/modules}/popover/types/popover-message-type.d.ts +0 -0
  114. package/{modules → lib/modules}/popover/types/popover-message.d.ts +0 -0
  115. package/{modules → lib/modules}/popover/types/popover-placement.d.ts +0 -0
  116. package/{modules → lib/modules}/popover/types/popover-position.d.ts +0 -0
  117. package/{modules → lib/modules}/popover/types/popover-trigger.d.ts +0 -0
  118. package/{modules → lib/modules}/shared/sky-popovers-resources.module.d.ts +0 -0
  119. package/package.json +23 -9
  120. package/skyux-popovers.d.ts +1 -1
  121. package/LICENSE +0 -21
  122. package/esm2015/modules/dropdown/dropdown-button.component.js +0 -14
  123. package/esm2015/modules/dropdown/dropdown-extensions.js +0 -14
  124. package/esm2015/modules/dropdown/dropdown-item.component.js +0 -72
  125. package/esm2015/modules/dropdown/dropdown-menu.component.js +0 -306
  126. package/esm2015/modules/dropdown/dropdown.component.js +0 -357
  127. package/esm2015/modules/dropdown/dropdown.module.js +0 -60
  128. package/esm2015/modules/dropdown/types/dropdown-horizontal-alignment.js +0 -2
  129. package/esm2015/modules/dropdown/types/dropdown-menu-change.js +0 -2
  130. package/esm2015/modules/dropdown/types/dropdown-message-type.js +0 -37
  131. package/esm2015/modules/dropdown/types/dropdown-message.js +0 -2
  132. package/esm2015/modules/dropdown/types/dropdown-trigger-type.js +0 -2
  133. package/esm2015/modules/popover/popover-adapter.service.js +0 -74
  134. package/esm2015/modules/popover/popover-animation-state.js +0 -2
  135. package/esm2015/modules/popover/popover-animation.js +0 -19
  136. package/esm2015/modules/popover/popover-content.component.js +0 -266
  137. package/esm2015/modules/popover/popover-context.js +0 -10
  138. package/esm2015/modules/popover/popover-extensions.js +0 -29
  139. package/esm2015/modules/popover/popover.component.js +0 -200
  140. package/esm2015/modules/popover/popover.directive.js +0 -175
  141. package/esm2015/modules/popover/popover.module.js +0 -56
  142. package/esm2015/modules/popover/types/popover-adapter-arrow-coordinates.js +0 -2
  143. package/esm2015/modules/popover/types/popover-adapter-elements.js +0 -2
  144. package/esm2015/modules/popover/types/popover-alignment.js +0 -2
  145. package/esm2015/modules/popover/types/popover-message-type.js +0 -24
  146. package/esm2015/modules/popover/types/popover-message.js +0 -2
  147. package/esm2015/modules/popover/types/popover-placement.js +0 -2
  148. package/esm2015/modules/popover/types/popover-position.js +0 -2
  149. package/esm2015/modules/popover/types/popover-trigger.js +0 -2
  150. package/esm2015/modules/shared/sky-popovers-resources.module.js +0 -47
  151. package/esm2015/public-api.js +0 -23
  152. package/public-api.d.ts +0 -20
@@ -0,0 +1,23 @@
1
+ export * from './lib/modules/dropdown/types/dropdown-horizontal-alignment';
2
+ export * from './lib/modules/dropdown/types/dropdown-menu-change';
3
+ export * from './lib/modules/dropdown/types/dropdown-message';
4
+ export * from './lib/modules/dropdown/types/dropdown-message-type';
5
+ export * from './lib/modules/dropdown/types/dropdown-trigger-type';
6
+ export * from './lib/modules/dropdown/dropdown.module';
7
+ export * from './lib/modules/popover/popover.module';
8
+ export * from './lib/modules/popover/types/popover-alignment';
9
+ export * from './lib/modules/popover/types/popover-message';
10
+ export * from './lib/modules/popover/types/popover-message-type';
11
+ export * from './lib/modules/popover/types/popover-placement';
12
+ export * from './lib/modules/popover/types/popover-position';
13
+ export * from './lib/modules/popover/types/popover-trigger';
14
+ // Components and directives must be exported to support Angular's "partial" Ivy compiler.
15
+ // Obscure names are used to indicate types are not part of the public API.
16
+ export { SkyDropdownItemComponent as λ1 } from './lib/modules/dropdown/dropdown-item.component';
17
+ export { SkyDropdownButtonComponent as λ2 } from './lib/modules/dropdown/dropdown-button.component';
18
+ export { SkyDropdownComponent as λ3 } from './lib/modules/dropdown/dropdown.component';
19
+ export { SkyDropdownMenuComponent as λ4 } from './lib/modules/dropdown/dropdown-menu.component';
20
+ export { SkyPopoverContentComponent as λ5 } from './lib/modules/popover/popover-content.component';
21
+ export { SkyPopoverComponent as λ6 } from './lib/modules/popover/popover.component';
22
+ export { SkyPopoverDirective as λ7 } from './lib/modules/popover/popover.directive';
23
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../libs/components/popovers/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,4DAA4D,CAAC;AAC3E,cAAc,mDAAmD,CAAC;AAClE,cAAc,+CAA+C,CAAC;AAC9D,cAAc,oDAAoD,CAAC;AACnE,cAAc,oDAAoD,CAAC;AACnE,cAAc,wCAAwC,CAAC;AAEvD,cAAc,sCAAsC,CAAC;AACrD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,6CAA6C,CAAC;AAC5D,cAAc,kDAAkD,CAAC;AACjE,cAAc,+CAA+C,CAAC;AAC9D,cAAc,8CAA8C,CAAC;AAC7D,cAAc,6CAA6C,CAAC;AAE5D,0FAA0F;AAC1F,2EAA2E;AAC3E,OAAO,EAAE,wBAAwB,IAAI,EAAE,EAAE,MAAM,gDAAgD,CAAC;AAChG,OAAO,EAAE,0BAA0B,IAAI,EAAE,EAAE,MAAM,kDAAkD,CAAC;AACpG,OAAO,EAAE,oBAAoB,IAAI,EAAE,EAAE,MAAM,2CAA2C,CAAC;AACvF,OAAO,EAAE,wBAAwB,IAAI,EAAE,EAAE,MAAM,gDAAgD,CAAC;AAChG,OAAO,EAAE,0BAA0B,IAAI,EAAE,EAAE,MAAM,iDAAiD,CAAC;AACnG,OAAO,EAAE,mBAAmB,IAAI,EAAE,EAAE,MAAM,yCAAyC,CAAC;AACpF,OAAO,EAAE,mBAAmB,IAAI,EAAE,EAAE,MAAM,yCAAyC,CAAC","sourcesContent":["export * from './lib/modules/dropdown/types/dropdown-horizontal-alignment';\nexport * from './lib/modules/dropdown/types/dropdown-menu-change';\nexport * from './lib/modules/dropdown/types/dropdown-message';\nexport * from './lib/modules/dropdown/types/dropdown-message-type';\nexport * from './lib/modules/dropdown/types/dropdown-trigger-type';\nexport * from './lib/modules/dropdown/dropdown.module';\n\nexport * from './lib/modules/popover/popover.module';\nexport * from './lib/modules/popover/types/popover-alignment';\nexport * from './lib/modules/popover/types/popover-message';\nexport * from './lib/modules/popover/types/popover-message-type';\nexport * from './lib/modules/popover/types/popover-placement';\nexport * from './lib/modules/popover/types/popover-position';\nexport * from './lib/modules/popover/types/popover-trigger';\n\n// Components and directives must be exported to support Angular's \"partial\" Ivy compiler.\n// Obscure names are used to indicate types are not part of the public API.\nexport { SkyDropdownItemComponent as λ1 } from './lib/modules/dropdown/dropdown-item.component';\nexport { SkyDropdownButtonComponent as λ2 } from './lib/modules/dropdown/dropdown-button.component';\nexport { SkyDropdownComponent as λ3 } from './lib/modules/dropdown/dropdown.component';\nexport { SkyDropdownMenuComponent as λ4 } from './lib/modules/dropdown/dropdown-menu.component';\nexport { SkyPopoverContentComponent as λ5 } from './lib/modules/popover/popover-content.component';\nexport { SkyPopoverComponent as λ6 } from './lib/modules/popover/popover.component';\nexport { SkyPopoverDirective as λ7 } from './lib/modules/popover/popover.directive';\n"]}
@@ -0,0 +1,14 @@
1
+ import { Component } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ export class SkyDropdownButtonComponent {
4
+ }
5
+ SkyDropdownButtonComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyDropdownButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
6
+ SkyDropdownButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: SkyDropdownButtonComponent, selector: "sky-dropdown-button", ngImport: i0, template: "<ng-content></ng-content>\n" });
7
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyDropdownButtonComponent, decorators: [{
8
+ type: Component,
9
+ args: [{
10
+ selector: 'sky-dropdown-button',
11
+ templateUrl: './dropdown-button.component.html',
12
+ }]
13
+ }] });
14
+ //# sourceMappingURL=dropdown-button.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dropdown-button.component.js","sourceRoot":"","sources":["../../../../../../../../libs/components/popovers/src/lib/modules/dropdown/dropdown-button.component.ts","../../../../../../../../libs/components/popovers/src/lib/modules/dropdown/dropdown-button.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;;AAM1C,MAAM,OAAO,0BAA0B;;wHAA1B,0BAA0B;4GAA1B,0BAA0B,2DCNvC,6BACA;4FDKa,0BAA0B;kBAJtC,SAAS;mBAAC;oBACT,QAAQ,EAAE,qBAAqB;oBAC/B,WAAW,EAAE,kCAAkC;iBAChD","sourcesContent":["import { Component } from '@angular/core';\n\n@Component({\n selector: 'sky-dropdown-button',\n templateUrl: './dropdown-button.component.html',\n})\nexport class SkyDropdownButtonComponent {}\n","<ng-content></ng-content>\n"]}
@@ -0,0 +1,14 @@
1
+ export function parseAffixHorizontalAlignment(alignment) {
2
+ switch (alignment) {
3
+ case 'center':
4
+ return 'center';
5
+ case 'left':
6
+ return 'left';
7
+ case 'right':
8
+ return 'right';
9
+ /* istanbul ignore next */
10
+ default:
11
+ throw `SkyAffixHorizontalAlignment does not have a matching value for '${alignment}'!`;
12
+ }
13
+ }
14
+ //# sourceMappingURL=dropdown-extensions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dropdown-extensions.js","sourceRoot":"","sources":["../../../../../../../../libs/components/popovers/src/lib/modules/dropdown/dropdown-extensions.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,6BAA6B,CAC3C,SAAyC;IAEzC,QAAQ,SAAS,EAAE;QACjB,KAAK,QAAQ;YACX,OAAO,QAAQ,CAAC;QAClB,KAAK,MAAM;YACT,OAAO,MAAM,CAAC;QAChB,KAAK,OAAO;YACV,OAAO,OAAO,CAAC;QACjB,0BAA0B;QAC1B;YACE,MAAM,mEAAmE,SAAS,IAAI,CAAC;KAC1F;AACH,CAAC","sourcesContent":["import { SkyAffixHorizontalAlignment } from '@skyux/core';\n\nimport { SkyDropdownHorizontalAlignment } from './types/dropdown-horizontal-alignment';\n\nexport function parseAffixHorizontalAlignment(\n alignment: SkyDropdownHorizontalAlignment\n): SkyAffixHorizontalAlignment {\n switch (alignment) {\n case 'center':\n return 'center';\n case 'left':\n return 'left';\n case 'right':\n return 'right';\n /* istanbul ignore next */\n default:\n throw `SkyAffixHorizontalAlignment does not have a matching value for '${alignment}'!`;\n }\n}\n"]}
@@ -0,0 +1,72 @@
1
+ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, Input, Renderer2, ViewEncapsulation, } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ import * as i1 from "@angular/common";
4
+ export class SkyDropdownItemComponent {
5
+ constructor(elementRef, changeDetector, renderer) {
6
+ this.elementRef = elementRef;
7
+ this.changeDetector = changeDetector;
8
+ this.renderer = renderer;
9
+ this.isActive = false;
10
+ this.isDisabled = false;
11
+ }
12
+ /**
13
+ * Specifies an ARIA role for the dropdown menu item
14
+ * [to support accessibility](https://developer.blackbaud.com/skyux/learn/accessibility)
15
+ * by indicating how the item functions and what it controls. For information about
16
+ * how an ARIA role indicates what an item represents on a web page, see the
17
+ * [WAI-ARIA roles model](https://www.w3.org/WAI/PF/aria/roles).
18
+ * @default "menuitem"
19
+ */
20
+ set ariaRole(value) {
21
+ this._ariaRole = value;
22
+ }
23
+ get ariaRole() {
24
+ return this._ariaRole || 'menuitem';
25
+ }
26
+ get buttonElement() {
27
+ return this.elementRef.nativeElement.querySelector('button,a');
28
+ }
29
+ ngAfterViewInit() {
30
+ this.isDisabled = !this.isFocusable();
31
+ // Make sure anchor elements are tab-able.
32
+ const buttonElement = this.buttonElement;
33
+ /* istanbul ignore else */
34
+ if (buttonElement) {
35
+ this.renderer.setAttribute(buttonElement, 'tabIndex', '0');
36
+ }
37
+ this.changeDetector.detectChanges();
38
+ }
39
+ focusElement(enableNativeFocus) {
40
+ this.isActive = true;
41
+ if (enableNativeFocus) {
42
+ this.buttonElement.focus();
43
+ }
44
+ this.changeDetector.detectChanges();
45
+ }
46
+ isFocusable() {
47
+ /*tslint:disable no-null-keyword */
48
+ const isFocusable = this.buttonElement &&
49
+ this.buttonElement.getAttribute('disabled') === null;
50
+ /*tslint:enable */
51
+ return isFocusable;
52
+ }
53
+ resetState() {
54
+ this.isActive = false;
55
+ this.changeDetector.markForCheck();
56
+ }
57
+ }
58
+ SkyDropdownItemComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyDropdownItemComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
59
+ SkyDropdownItemComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: SkyDropdownItemComponent, selector: "sky-dropdown-item", inputs: { ariaRole: "ariaRole" }, ngImport: i0, template: "<div\n class=\"sky-dropdown-item\"\n [attr.role]=\"ariaRole\"\n [ngClass]=\"{\n 'sky-dropdown-item-active': isActive,\n 'sky-dropdown-item-disabled': isDisabled\n }\"\n>\n <ng-content> </ng-content>\n</div>\n", styles: [".sky-dropdown-item{background-color:transparent;border:none;display:block;margin:4px;min-width:160px;text-align:left}.sky-dropdown-item.sky-dropdown-item-active,.sky-dropdown-item:hover{background-color:#eeeeef}.sky-dropdown-item.sky-dropdown-item-disabled{cursor:default}.sky-dropdown-item.sky-dropdown-item-disabled:hover{background-color:transparent}.sky-dropdown-item>a,.sky-dropdown-item>button{background-color:transparent;border:none;color:#212327;cursor:pointer;display:block;padding:3px 20px;text-align:left;width:100%}.sky-dropdown-item>a:hover,.sky-dropdown-item>button:hover{text-decoration:none}.sky-dropdown-item>a[disabled],.sky-dropdown-item>button[disabled]{color:#686c73}.sky-dropdown-item>a[disabled]:hover,.sky-dropdown-item>button[disabled]:hover{cursor:default}.sky-theme-modern .sky-dropdown-item{margin:0}.sky-theme-modern .sky-dropdown-item.sky-dropdown-item-active,.sky-theme-modern .sky-dropdown-item:hover{background-color:transparent}.sky-theme-modern .sky-dropdown-item>a,.sky-theme-modern .sky-dropdown-item>button{padding:8px 20px;transition:box-shadow .15s}.sky-theme-modern .sky-dropdown-item>a:hover,.sky-theme-modern .sky-dropdown-item>button:hover{outline:solid 1px #1870B8;outline-offset:-1px}.sky-theme-modern .sky-dropdown-item>a:focus,.sky-theme-modern .sky-dropdown-item>a:active,.sky-theme-modern .sky-dropdown-item>button:focus,.sky-theme-modern .sky-dropdown-item>button:active{outline:solid 2px #1870B8;outline-offset:-2px}.sky-theme-modern .sky-dropdown-item>a:focus:not(:active),.sky-theme-modern .sky-dropdown-item>button:focus:not(:active){box-shadow:0 1px 8px #0000004d}.sky-theme-modern.sky-theme-mode-dark .sky-dropdown-item>a,.sky-theme-modern.sky-theme-mode-dark .sky-dropdown-item>button{color:#fbfcfe}\n"], directives: [{ type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
60
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyDropdownItemComponent, decorators: [{
61
+ type: Component,
62
+ args: [{
63
+ selector: 'sky-dropdown-item',
64
+ templateUrl: './dropdown-item.component.html',
65
+ styleUrls: ['./dropdown-item.component.scss'],
66
+ changeDetection: ChangeDetectionStrategy.OnPush,
67
+ encapsulation: ViewEncapsulation.None,
68
+ }]
69
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: i0.Renderer2 }]; }, propDecorators: { ariaRole: [{
70
+ type: Input
71
+ }] } });
72
+ //# sourceMappingURL=dropdown-item.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dropdown-item.component.js","sourceRoot":"","sources":["../../../../../../../../libs/components/popovers/src/lib/modules/dropdown/dropdown-item.component.ts","../../../../../../../../libs/components/popovers/src/lib/modules/dropdown/dropdown-item.component.html"],"names":[],"mappings":"AAAA,OAAO,EAEL,uBAAuB,EACvB,iBAAiB,EACjB,SAAS,EACT,UAAU,EACV,KAAK,EACL,SAAS,EACT,iBAAiB,GAClB,MAAM,eAAe,CAAC;;;AASvB,MAAM,OAAO,wBAAwB;IA4BnC,YACS,UAAsB,EACrB,cAAiC,EACjC,QAAmB;QAFpB,eAAU,GAAV,UAAU,CAAY;QACrB,mBAAc,GAAd,cAAc,CAAmB;QACjC,aAAQ,GAAR,QAAQ,CAAW;QATtB,aAAQ,GAAG,KAAK,CAAC;QAEjB,eAAU,GAAG,KAAK,CAAC;IAQvB,CAAC;IA/BJ;;;;;;;OAOG;IACH,IACW,QAAQ,CAAC,KAAa;QAC/B,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;IACzB,CAAC;IAED,IAAW,QAAQ;QACjB,OAAO,IAAI,CAAC,SAAS,IAAI,UAAU,CAAC;IACtC,CAAC;IAED,IAAW,aAAa;QACtB,OAAO,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;IACjE,CAAC;IAcM,eAAe;QACpB,IAAI,CAAC,UAAU,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QAEtC,0CAA0C;QAC1C,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC;QACzC,0BAA0B;QAC1B,IAAI,aAAa,EAAE;YACjB,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,aAAa,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;SAC5D;QAED,IAAI,CAAC,cAAc,CAAC,aAAa,EAAE,CAAC;IACtC,CAAC;IAEM,YAAY,CAAC,iBAA0B;QAC5C,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QAErB,IAAI,iBAAiB,EAAE;YACrB,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;SAC5B;QAED,IAAI,CAAC,cAAc,CAAC,aAAa,EAAE,CAAC;IACtC,CAAC;IAEM,WAAW;QAChB,mCAAmC;QACnC,MAAM,WAAW,GACf,IAAI,CAAC,aAAa;YAClB,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;QACvD,kBAAkB;QAClB,OAAO,WAAW,CAAC;IACrB,CAAC;IAEM,UAAU;QACf,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;QACtB,IAAI,CAAC,cAAc,CAAC,YAAY,EAAE,CAAC;IACrC,CAAC;;sHArEU,wBAAwB;0GAAxB,wBAAwB,2FClBrC,6NAUA;4FDQa,wBAAwB;kBAPpC,SAAS;mBAAC;oBACT,QAAQ,EAAE,mBAAmB;oBAC7B,WAAW,EAAE,gCAAgC;oBAC7C,SAAS,EAAE,CAAC,gCAAgC,CAAC;oBAC7C,eAAe,EAAE,uBAAuB,CAAC,MAAM;oBAC/C,aAAa,EAAE,iBAAiB,CAAC,IAAI;iBACtC;yJAWY,QAAQ;sBADlB,KAAK","sourcesContent":["import {\n AfterViewInit,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n ElementRef,\n Input,\n Renderer2,\n ViewEncapsulation,\n} from '@angular/core';\n\n@Component({\n selector: 'sky-dropdown-item',\n templateUrl: './dropdown-item.component.html',\n styleUrls: ['./dropdown-item.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n})\nexport class SkyDropdownItemComponent implements AfterViewInit {\n /**\n * Specifies an ARIA role for the dropdown menu item\n * [to support accessibility](https://developer.blackbaud.com/skyux/learn/accessibility)\n * by indicating how the item functions and what it controls. For information about\n * how an ARIA role indicates what an item represents on a web page, see the\n * [WAI-ARIA roles model](https://www.w3.org/WAI/PF/aria/roles).\n * @default \"menuitem\"\n */\n @Input()\n public set ariaRole(value: string) {\n this._ariaRole = value;\n }\n\n public get ariaRole(): string {\n return this._ariaRole || 'menuitem';\n }\n\n public get buttonElement(): HTMLButtonElement {\n return this.elementRef.nativeElement.querySelector('button,a');\n }\n\n public isActive = false;\n\n public isDisabled = false;\n\n private _ariaRole: string;\n\n public constructor(\n public elementRef: ElementRef,\n private changeDetector: ChangeDetectorRef,\n private renderer: Renderer2\n ) {}\n\n public ngAfterViewInit(): void {\n this.isDisabled = !this.isFocusable();\n\n // Make sure anchor elements are tab-able.\n const buttonElement = this.buttonElement;\n /* istanbul ignore else */\n if (buttonElement) {\n this.renderer.setAttribute(buttonElement, 'tabIndex', '0');\n }\n\n this.changeDetector.detectChanges();\n }\n\n public focusElement(enableNativeFocus: boolean): void {\n this.isActive = true;\n\n if (enableNativeFocus) {\n this.buttonElement.focus();\n }\n\n this.changeDetector.detectChanges();\n }\n\n public isFocusable(): boolean {\n /*tslint:disable no-null-keyword */\n const isFocusable =\n this.buttonElement &&\n this.buttonElement.getAttribute('disabled') === null;\n /*tslint:enable */\n return isFocusable;\n }\n\n public resetState(): void {\n this.isActive = false;\n this.changeDetector.markForCheck();\n }\n}\n","<div\n class=\"sky-dropdown-item\"\n [attr.role]=\"ariaRole\"\n [ngClass]=\"{\n 'sky-dropdown-item-active': isActive,\n 'sky-dropdown-item-disabled': isDisabled\n }\"\n>\n <ng-content> </ng-content>\n</div>\n"]}
@@ -0,0 +1,307 @@
1
+ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChildren, ElementRef, EventEmitter, Input, Optional, Output, QueryList, ViewEncapsulation, } from '@angular/core';
2
+ import { fromEvent as observableFromEvent, Subject } from 'rxjs';
3
+ import { takeUntil } from 'rxjs/operators';
4
+ import { SkyDropdownComponent } from './dropdown.component';
5
+ import { SkyDropdownItemComponent } from './dropdown-item.component';
6
+ import { SkyDropdownMessageType } from './types/dropdown-message-type';
7
+ import * as i0 from "@angular/core";
8
+ import * as i1 from "./dropdown.component";
9
+ let nextId = 0;
10
+ export class SkyDropdownMenuComponent {
11
+ constructor(changeDetector, elementRef, dropdownComponent) {
12
+ this.changeDetector = changeDetector;
13
+ this.elementRef = elementRef;
14
+ this.dropdownComponent = dropdownComponent;
15
+ /**
16
+ * Fires when the dropdown menu's active index or selected item changes. This event provides an
17
+ * observable to emit changes, and the response is of
18
+ * the SkyDropdownMenuChange type.
19
+ */
20
+ this.menuChanges = new EventEmitter();
21
+ this.dropdownMenuId = `sky-dropdown-menu-${++nextId}`;
22
+ this.ngUnsubscribe = new Subject();
23
+ this._menuIndex = 0;
24
+ }
25
+ /**
26
+ * Specifies an ARIA role for the dropdown menu
27
+ * [to support accessibility](https://developer.blackbaud.com/skyux/learn/accessibility)
28
+ * by indicating how the dropdown menu functions and what it controls. The dropdown button
29
+ * inherits this value to set its `aria-haspopup` property. For information
30
+ * about how an ARIA role indicates what an item represents on a web page, see the
31
+ * [WAI-ARIA roles model](https://www.w3.org/WAI/PF/aria/roles).
32
+ * @default "menu"
33
+ */
34
+ set ariaRole(value) {
35
+ this._ariaRole = value;
36
+ }
37
+ get ariaRole() {
38
+ return this._ariaRole || 'menu';
39
+ }
40
+ /**
41
+ * Indicates whether to use the browser's native focus function when users navigate through menu
42
+ * items with the keyboard. To disable the native focus function, set this property to `false`.
43
+ * For example, to let users interact with the dropdown menu but keep the keyboard focus on a
44
+ * different element, set this property to `false`.
45
+ * @default true
46
+ */
47
+ set useNativeFocus(value) {
48
+ this._useNativeFocus = value;
49
+ }
50
+ get useNativeFocus() {
51
+ if (this._useNativeFocus === undefined) {
52
+ return true;
53
+ }
54
+ return this._useNativeFocus;
55
+ }
56
+ get hasFocusableItems() {
57
+ const found = this.menuItems.find((item) => item.isFocusable());
58
+ return found !== undefined;
59
+ }
60
+ set menuIndex(value) {
61
+ if (value < 0) {
62
+ value = this.menuItems.length - 1;
63
+ }
64
+ if (value >= this.menuItems.length) {
65
+ value = 0;
66
+ }
67
+ this._menuIndex = value;
68
+ }
69
+ get menuIndex() {
70
+ return this._menuIndex;
71
+ }
72
+ ngAfterContentInit() {
73
+ /* istanbul ignore else */
74
+ if (this.dropdownComponent) {
75
+ this.dropdownComponent.menuId = this.dropdownMenuId;
76
+ this.dropdownComponent.menuAriaRole = this.ariaRole;
77
+ this.dropdownComponent.messageStream
78
+ .pipe(takeUntil(this.ngUnsubscribe))
79
+ .subscribe((message) => {
80
+ /* tslint:disable-next-line:switch-default */
81
+ switch (message.type) {
82
+ case SkyDropdownMessageType.Open:
83
+ case SkyDropdownMessageType.Close:
84
+ this.reset();
85
+ break;
86
+ case SkyDropdownMessageType.FocusFirstItem:
87
+ this.focusFirstItem();
88
+ break;
89
+ case SkyDropdownMessageType.FocusNextItem:
90
+ this.focusNextItem();
91
+ break;
92
+ case SkyDropdownMessageType.FocusPreviousItem:
93
+ this.focusPreviousItem();
94
+ break;
95
+ case SkyDropdownMessageType.FocusLastItem:
96
+ this.focusLastItem();
97
+ break;
98
+ }
99
+ });
100
+ this.menuChanges
101
+ .pipe(takeUntil(this.ngUnsubscribe))
102
+ .subscribe((change) => {
103
+ // Close the dropdown when a menu item is selected.
104
+ if (change.selectedItem) {
105
+ this.sendMessage(SkyDropdownMessageType.Close);
106
+ this.sendMessage(SkyDropdownMessageType.FocusTriggerButton);
107
+ }
108
+ if (change.items) {
109
+ // Update the popover style and position whenever the number of items changes.
110
+ this.sendMessage(SkyDropdownMessageType.Reposition);
111
+ }
112
+ });
113
+ }
114
+ // Reset dropdown whenever the menu items change.
115
+ this.menuItems.changes
116
+ .pipe(takeUntil(this.ngUnsubscribe))
117
+ .subscribe((items) => {
118
+ this.reset();
119
+ this.menuChanges.emit({
120
+ items: items.toArray(),
121
+ });
122
+ });
123
+ this.addEventListeners();
124
+ }
125
+ ngOnDestroy() {
126
+ this.ngUnsubscribe.next();
127
+ this.ngUnsubscribe.complete();
128
+ this.ngUnsubscribe = undefined;
129
+ }
130
+ focusFirstItem() {
131
+ if (!this.hasFocusableItems) {
132
+ return;
133
+ }
134
+ this.menuIndex = 0;
135
+ const firstItem = this.getItemByIndex(this.menuIndex);
136
+ if (firstItem && firstItem.isFocusable()) {
137
+ this.focusItem(firstItem);
138
+ }
139
+ else {
140
+ this.focusNextItem();
141
+ }
142
+ }
143
+ focusLastItem() {
144
+ if (!this.hasFocusableItems) {
145
+ return;
146
+ }
147
+ this.menuIndex = this.menuItems.length - 1;
148
+ const lastItem = this.getItemByIndex(this.menuIndex);
149
+ if (lastItem && lastItem.isFocusable()) {
150
+ this.focusItem(lastItem);
151
+ }
152
+ else {
153
+ this.focusPreviousItem();
154
+ }
155
+ }
156
+ focusPreviousItem() {
157
+ if (!this.hasFocusableItems) {
158
+ return;
159
+ }
160
+ this.menuIndex--;
161
+ const previousItem = this.getItemByIndex(this.menuIndex);
162
+ if (previousItem && previousItem.isFocusable()) {
163
+ this.focusItem(previousItem);
164
+ }
165
+ else {
166
+ this.focusPreviousItem();
167
+ }
168
+ }
169
+ focusNextItem() {
170
+ if (!this.hasFocusableItems) {
171
+ return;
172
+ }
173
+ this.menuIndex++;
174
+ const nextItem = this.getItemByIndex(this.menuIndex);
175
+ if (nextItem && nextItem.isFocusable()) {
176
+ this.focusItem(nextItem);
177
+ }
178
+ else {
179
+ this.focusNextItem();
180
+ }
181
+ }
182
+ reset() {
183
+ this._menuIndex = -1;
184
+ this.resetItemsActiveState();
185
+ this.changeDetector.markForCheck();
186
+ }
187
+ resetItemsActiveState() {
188
+ this.menuItems.forEach((item) => {
189
+ item.resetState();
190
+ });
191
+ }
192
+ focusItem(item) {
193
+ this.resetItemsActiveState();
194
+ item.focusElement(this.useNativeFocus);
195
+ this.menuChanges.emit({
196
+ activeIndex: this.menuIndex,
197
+ });
198
+ }
199
+ getItemByIndex(index) {
200
+ return this.menuItems.find((item, i) => {
201
+ return i === index;
202
+ });
203
+ }
204
+ selectItemByEventTarget(target) {
205
+ const selectedItem = this.menuItems.find((item, i) => {
206
+ const found = item.elementRef.nativeElement.contains(target);
207
+ if (found) {
208
+ this.menuIndex = i;
209
+ this.menuChanges.next({
210
+ activeIndex: this.menuIndex,
211
+ });
212
+ }
213
+ return found;
214
+ });
215
+ /* istanbul ignore else */
216
+ if (selectedItem) {
217
+ this.menuChanges.next({
218
+ selectedItem,
219
+ });
220
+ }
221
+ }
222
+ sendMessage(type) {
223
+ this.dropdownComponent.messageStream.next({ type });
224
+ }
225
+ addEventListeners() {
226
+ const dropdownMenuElement = this.elementRef.nativeElement;
227
+ observableFromEvent(dropdownMenuElement, 'click')
228
+ .pipe(takeUntil(this.ngUnsubscribe))
229
+ .subscribe((event) => {
230
+ this.selectItemByEventTarget(event.target);
231
+ });
232
+ observableFromEvent(dropdownMenuElement, 'keydown')
233
+ .pipe(takeUntil(this.ngUnsubscribe))
234
+ .subscribe((event) => {
235
+ const key = event.key.toLowerCase();
236
+ /*tslint:disable-next-line:switch-default*/
237
+ switch (key) {
238
+ case 'escape':
239
+ this.sendMessage(SkyDropdownMessageType.Close);
240
+ this.sendMessage(SkyDropdownMessageType.FocusTriggerButton);
241
+ event.stopPropagation();
242
+ event.preventDefault();
243
+ break;
244
+ case 'arrowdown':
245
+ case 'down':
246
+ this.focusNextItem();
247
+ event.preventDefault();
248
+ break;
249
+ case 'arrowup':
250
+ case 'up':
251
+ this.focusPreviousItem();
252
+ event.preventDefault();
253
+ break;
254
+ case 'tab':
255
+ if (this.dropdownComponent.dismissOnBlur) {
256
+ this.sendMessage(SkyDropdownMessageType.Close);
257
+ }
258
+ this.sendMessage(SkyDropdownMessageType.FocusTriggerButton);
259
+ break;
260
+ }
261
+ });
262
+ observableFromEvent(dropdownMenuElement, 'mouseenter')
263
+ .pipe(takeUntil(this.ngUnsubscribe))
264
+ .subscribe(() => {
265
+ this.dropdownComponent.isMouseEnter = true;
266
+ });
267
+ observableFromEvent(dropdownMenuElement, 'mouseleave')
268
+ .pipe(takeUntil(this.ngUnsubscribe))
269
+ .subscribe(() => {
270
+ this.dropdownComponent.isMouseEnter = false;
271
+ // Allow the dropdown component to set isMouseEnter before checking if the close action
272
+ // should be taken.
273
+ setTimeout(() => {
274
+ if (this.dropdownComponent.trigger === 'hover' &&
275
+ this.dropdownComponent.isMouseEnter === false) {
276
+ this.sendMessage(SkyDropdownMessageType.Close);
277
+ }
278
+ });
279
+ });
280
+ }
281
+ }
282
+ SkyDropdownMenuComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyDropdownMenuComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: i1.SkyDropdownComponent, optional: true }], target: i0.ɵɵFactoryTarget.Component });
283
+ SkyDropdownMenuComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: SkyDropdownMenuComponent, selector: "sky-dropdown-menu", inputs: { ariaLabelledBy: "ariaLabelledBy", ariaRole: "ariaRole", useNativeFocus: "useNativeFocus" }, outputs: { menuChanges: "menuChanges" }, queries: [{ propertyName: "menuItems", predicate: SkyDropdownItemComponent, descendants: true }], ngImport: i0, template: "<div\n class=\"sky-dropdown-menu sky-shadow sky-elevation-4\"\n [attr.aria-labelledby]=\"ariaLabelledBy\"\n [attr.role]=\"ariaRole\"\n [id]=\"dropdownMenuId\"\n>\n <ng-content> </ng-content>\n</div>\n", styles: [".sky-dropdown-menu{overflow-y:auto;overflow-x:hidden;min-height:35px;max-height:calc(50vh - 50px);display:flex;flex-direction:column;background-color:#fff}.sky-dropdown-menu button{overflow:hidden;text-overflow:ellipsis}.sky-theme-modern.sky-theme-mode-dark .sky-dropdown-menu{background-color:#252a2e;color:#fff}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
284
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyDropdownMenuComponent, decorators: [{
285
+ type: Component,
286
+ args: [{
287
+ selector: 'sky-dropdown-menu',
288
+ templateUrl: './dropdown-menu.component.html',
289
+ styleUrls: ['./dropdown-menu.component.scss'],
290
+ changeDetection: ChangeDetectionStrategy.OnPush,
291
+ encapsulation: ViewEncapsulation.None,
292
+ }]
293
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: i1.SkyDropdownComponent, decorators: [{
294
+ type: Optional
295
+ }] }]; }, propDecorators: { ariaLabelledBy: [{
296
+ type: Input
297
+ }], ariaRole: [{
298
+ type: Input
299
+ }], useNativeFocus: [{
300
+ type: Input
301
+ }], menuChanges: [{
302
+ type: Output
303
+ }], menuItems: [{
304
+ type: ContentChildren,
305
+ args: [SkyDropdownItemComponent, { descendants: true }]
306
+ }] } });
307
+ //# sourceMappingURL=dropdown-menu.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dropdown-menu.component.js","sourceRoot":"","sources":["../../../../../../../../libs/components/popovers/src/lib/modules/dropdown/dropdown-menu.component.ts","../../../../../../../../libs/components/popovers/src/lib/modules/dropdown/dropdown-menu.component.html"],"names":[],"mappings":"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","sourcesContent":["import {\n AfterContentInit,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n ContentChildren,\n ElementRef,\n EventEmitter,\n Input,\n OnDestroy,\n Optional,\n Output,\n QueryList,\n ViewEncapsulation,\n} from '@angular/core';\n\nimport { fromEvent as observableFromEvent, Subject } from 'rxjs';\n\nimport { takeUntil } from 'rxjs/operators';\n\nimport { SkyDropdownComponent } from './dropdown.component';\n\nimport { SkyDropdownItemComponent } from './dropdown-item.component';\n\nimport { SkyDropdownMenuChange } from './types/dropdown-menu-change';\n\nimport { SkyDropdownMessage } from './types/dropdown-message';\n\nimport { SkyDropdownMessageType } from './types/dropdown-message-type';\n\nlet nextId = 0;\n\n@Component({\n selector: 'sky-dropdown-menu',\n templateUrl: './dropdown-menu.component.html',\n styleUrls: ['./dropdown-menu.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n})\nexport class SkyDropdownMenuComponent implements AfterContentInit, OnDestroy {\n /**\n * Specifies the HTML element ID (without the leading `#`) of the element that labels\n * the dropdown menu. This sets the dropdown menu's `aria-labelledby` attribute\n * [to support accessibility](https://developer.blackbaud.com/skyux/learn/accessibility).\n */\n @Input()\n public ariaLabelledBy: string;\n\n /**\n * Specifies an ARIA role for the dropdown menu\n * [to support accessibility](https://developer.blackbaud.com/skyux/learn/accessibility)\n * by indicating how the dropdown menu functions and what it controls. The dropdown button\n * inherits this value to set its `aria-haspopup` property. For information\n * about how an ARIA role indicates what an item represents on a web page, see the\n * [WAI-ARIA roles model](https://www.w3.org/WAI/PF/aria/roles).\n * @default \"menu\"\n */\n @Input()\n public set ariaRole(value: string) {\n this._ariaRole = value;\n }\n\n public get ariaRole(): string {\n return this._ariaRole || 'menu';\n }\n\n /**\n * Indicates whether to use the browser's native focus function when users navigate through menu\n * items with the keyboard. To disable the native focus function, set this property to `false`.\n * For example, to let users interact with the dropdown menu but keep the keyboard focus on a\n * different element, set this property to `false`.\n * @default true\n */\n @Input()\n public set useNativeFocus(value: boolean) {\n this._useNativeFocus = value;\n }\n\n public get useNativeFocus(): boolean {\n if (this._useNativeFocus === undefined) {\n return true;\n }\n\n return this._useNativeFocus;\n }\n\n /**\n * Fires when the dropdown menu's active index or selected item changes. This event provides an\n * observable to emit changes, and the response is of\n * the SkyDropdownMenuChange type.\n */\n @Output()\n public menuChanges = new EventEmitter<SkyDropdownMenuChange>();\n\n public dropdownMenuId: string = `sky-dropdown-menu-${++nextId}`;\n\n private get hasFocusableItems(): boolean {\n const found = this.menuItems.find((item) => item.isFocusable());\n return found !== undefined;\n }\n\n public set menuIndex(value: number) {\n if (value < 0) {\n value = this.menuItems.length - 1;\n }\n\n if (value >= this.menuItems.length) {\n value = 0;\n }\n\n this._menuIndex = value;\n }\n\n public get menuIndex(): number {\n return this._menuIndex;\n }\n\n @ContentChildren(SkyDropdownItemComponent, { descendants: true })\n public menuItems: QueryList<SkyDropdownItemComponent>;\n\n private ngUnsubscribe = new Subject();\n\n private _ariaRole: string;\n\n private _menuIndex = 0;\n\n private _useNativeFocus: boolean;\n\n constructor(\n private changeDetector: ChangeDetectorRef,\n private elementRef: ElementRef,\n @Optional() private dropdownComponent: SkyDropdownComponent\n ) {}\n\n public ngAfterContentInit(): void {\n /* istanbul ignore else */\n if (this.dropdownComponent) {\n this.dropdownComponent.menuId = this.dropdownMenuId;\n this.dropdownComponent.menuAriaRole = this.ariaRole;\n\n this.dropdownComponent.messageStream\n .pipe(takeUntil(this.ngUnsubscribe))\n .subscribe((message: SkyDropdownMessage) => {\n /* tslint:disable-next-line:switch-default */\n switch (message.type) {\n case SkyDropdownMessageType.Open:\n case SkyDropdownMessageType.Close:\n this.reset();\n break;\n\n case SkyDropdownMessageType.FocusFirstItem:\n this.focusFirstItem();\n break;\n\n case SkyDropdownMessageType.FocusNextItem:\n this.focusNextItem();\n break;\n\n case SkyDropdownMessageType.FocusPreviousItem:\n this.focusPreviousItem();\n break;\n\n case SkyDropdownMessageType.FocusLastItem:\n this.focusLastItem();\n break;\n }\n });\n\n this.menuChanges\n .pipe(takeUntil(this.ngUnsubscribe))\n .subscribe((change: SkyDropdownMenuChange) => {\n // Close the dropdown when a menu item is selected.\n if (change.selectedItem) {\n this.sendMessage(SkyDropdownMessageType.Close);\n this.sendMessage(SkyDropdownMessageType.FocusTriggerButton);\n }\n\n if (change.items) {\n // Update the popover style and position whenever the number of items changes.\n this.sendMessage(SkyDropdownMessageType.Reposition);\n }\n });\n }\n\n // Reset dropdown whenever the menu items change.\n this.menuItems.changes\n .pipe(takeUntil(this.ngUnsubscribe))\n .subscribe((items: QueryList<SkyDropdownItemComponent>) => {\n this.reset();\n this.menuChanges.emit({\n items: items.toArray(),\n });\n });\n\n this.addEventListeners();\n }\n\n public ngOnDestroy(): void {\n this.ngUnsubscribe.next();\n this.ngUnsubscribe.complete();\n this.ngUnsubscribe = undefined;\n }\n\n public focusFirstItem(): void {\n if (!this.hasFocusableItems) {\n return;\n }\n\n this.menuIndex = 0;\n\n const firstItem = this.getItemByIndex(this.menuIndex);\n if (firstItem && firstItem.isFocusable()) {\n this.focusItem(firstItem);\n } else {\n this.focusNextItem();\n }\n }\n\n public focusLastItem(): void {\n if (!this.hasFocusableItems) {\n return;\n }\n\n this.menuIndex = this.menuItems.length - 1;\n\n const lastItem = this.getItemByIndex(this.menuIndex);\n if (lastItem && lastItem.isFocusable()) {\n this.focusItem(lastItem);\n } else {\n this.focusPreviousItem();\n }\n }\n\n public focusPreviousItem(): void {\n if (!this.hasFocusableItems) {\n return;\n }\n\n this.menuIndex--;\n\n const previousItem = this.getItemByIndex(this.menuIndex);\n if (previousItem && previousItem.isFocusable()) {\n this.focusItem(previousItem);\n } else {\n this.focusPreviousItem();\n }\n }\n\n public focusNextItem() {\n if (!this.hasFocusableItems) {\n return;\n }\n\n this.menuIndex++;\n\n const nextItem = this.getItemByIndex(this.menuIndex);\n if (nextItem && nextItem.isFocusable()) {\n this.focusItem(nextItem);\n } else {\n this.focusNextItem();\n }\n }\n\n public reset(): void {\n this._menuIndex = -1;\n this.resetItemsActiveState();\n this.changeDetector.markForCheck();\n }\n\n private resetItemsActiveState() {\n this.menuItems.forEach((item: SkyDropdownItemComponent) => {\n item.resetState();\n });\n }\n\n private focusItem(item: SkyDropdownItemComponent): void {\n this.resetItemsActiveState();\n item.focusElement(this.useNativeFocus);\n this.menuChanges.emit({\n activeIndex: this.menuIndex,\n });\n }\n\n private getItemByIndex(index: number): SkyDropdownItemComponent {\n return this.menuItems.find((item: any, i: number) => {\n return i === index;\n });\n }\n\n private selectItemByEventTarget(target: EventTarget): void {\n const selectedItem = this.menuItems.find(\n (item: SkyDropdownItemComponent, i: number) => {\n const found = item.elementRef.nativeElement.contains(target);\n\n if (found) {\n this.menuIndex = i;\n this.menuChanges.next({\n activeIndex: this.menuIndex,\n });\n }\n\n return found;\n }\n );\n\n /* istanbul ignore else */\n if (selectedItem) {\n this.menuChanges.next({\n selectedItem,\n });\n }\n }\n\n private sendMessage(type: SkyDropdownMessageType): void {\n this.dropdownComponent.messageStream.next({ type });\n }\n\n private addEventListeners(): void {\n const dropdownMenuElement = this.elementRef.nativeElement;\n\n observableFromEvent(dropdownMenuElement, 'click')\n .pipe(takeUntil(this.ngUnsubscribe))\n .subscribe((event: MouseEvent) => {\n this.selectItemByEventTarget(event.target);\n });\n\n observableFromEvent(dropdownMenuElement, 'keydown')\n .pipe(takeUntil(this.ngUnsubscribe))\n .subscribe((event: KeyboardEvent) => {\n const key = event.key.toLowerCase();\n\n /*tslint:disable-next-line:switch-default*/\n switch (key) {\n case 'escape':\n this.sendMessage(SkyDropdownMessageType.Close);\n this.sendMessage(SkyDropdownMessageType.FocusTriggerButton);\n event.stopPropagation();\n event.preventDefault();\n break;\n\n case 'arrowdown':\n case 'down':\n this.focusNextItem();\n event.preventDefault();\n break;\n\n case 'arrowup':\n case 'up':\n this.focusPreviousItem();\n event.preventDefault();\n break;\n\n case 'tab':\n if (this.dropdownComponent.dismissOnBlur) {\n this.sendMessage(SkyDropdownMessageType.Close);\n }\n this.sendMessage(SkyDropdownMessageType.FocusTriggerButton);\n break;\n }\n });\n\n observableFromEvent(dropdownMenuElement, 'mouseenter')\n .pipe(takeUntil(this.ngUnsubscribe))\n .subscribe(() => {\n this.dropdownComponent.isMouseEnter = true;\n });\n\n observableFromEvent(dropdownMenuElement, 'mouseleave')\n .pipe(takeUntil(this.ngUnsubscribe))\n .subscribe(() => {\n this.dropdownComponent.isMouseEnter = false;\n // Allow the dropdown component to set isMouseEnter before checking if the close action\n // should be taken.\n setTimeout(() => {\n if (\n this.dropdownComponent.trigger === 'hover' &&\n this.dropdownComponent.isMouseEnter === false\n ) {\n this.sendMessage(SkyDropdownMessageType.Close);\n }\n });\n });\n }\n}\n","<div\n class=\"sky-dropdown-menu sky-shadow sky-elevation-4\"\n [attr.aria-labelledby]=\"ariaLabelledBy\"\n [attr.role]=\"ariaRole\"\n [id]=\"dropdownMenuId\"\n>\n <ng-content> </ng-content>\n</div>\n"]}