accordion.js 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. /**
  2. * @license
  3. * Copyright Google LLC All Rights Reserved.
  4. *
  5. * Use of this source code is governed by an MIT-style license that can be
  6. * found in the LICENSE file at https://angular.io/license
  7. */
  8. import { coerceBooleanProperty } from '@angular/cdk/coercion';
  9. import { Directive, Input, Output, EventEmitter, Optional, ChangeDetectorRef, SkipSelf, NgModule } from '@angular/core';
  10. import { Subject, Subscription } from 'rxjs';
  11. import { UniqueSelectionDispatcher } from '@angular/cdk/collections';
  12. /**
  13. * @fileoverview added by tsickle
  14. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  15. */
  16. /**
  17. * Used to generate unique ID for each accordion.
  18. * @type {?}
  19. */
  20. let nextId = 0;
  21. /**
  22. * Directive whose purpose is to manage the expanded state of CdkAccordionItem children.
  23. */
  24. class CdkAccordion {
  25. constructor() {
  26. /**
  27. * Emits when the state of the accordion changes
  28. */
  29. this._stateChanges = new Subject();
  30. /**
  31. * Stream that emits true/false when openAll/closeAll is triggered.
  32. */
  33. this._openCloseAllActions = new Subject();
  34. /**
  35. * A readonly id value to use for unique selection coordination.
  36. */
  37. this.id = `cdk-accordion-${nextId++}`;
  38. this._multi = false;
  39. }
  40. /**
  41. * Whether the accordion should allow multiple expanded accordion items simultaneously.
  42. * @return {?}
  43. */
  44. get multi() { return this._multi; }
  45. /**
  46. * @param {?} multi
  47. * @return {?}
  48. */
  49. set multi(multi) { this._multi = coerceBooleanProperty(multi); }
  50. /**
  51. * Opens all enabled accordion items in an accordion where multi is enabled.
  52. * @return {?}
  53. */
  54. openAll() {
  55. this._openCloseAll(true);
  56. }
  57. /**
  58. * Closes all enabled accordion items in an accordion where multi is enabled.
  59. * @return {?}
  60. */
  61. closeAll() {
  62. this._openCloseAll(false);
  63. }
  64. /**
  65. * @param {?} changes
  66. * @return {?}
  67. */
  68. ngOnChanges(changes) {
  69. this._stateChanges.next(changes);
  70. }
  71. /**
  72. * @return {?}
  73. */
  74. ngOnDestroy() {
  75. this._stateChanges.complete();
  76. }
  77. /**
  78. * @private
  79. * @param {?} expanded
  80. * @return {?}
  81. */
  82. _openCloseAll(expanded) {
  83. if (this.multi) {
  84. this._openCloseAllActions.next(expanded);
  85. }
  86. }
  87. }
  88. CdkAccordion.decorators = [
  89. { type: Directive, args: [{
  90. selector: 'cdk-accordion, [cdkAccordion]',
  91. exportAs: 'cdkAccordion',
  92. },] },
  93. ];
  94. CdkAccordion.propDecorators = {
  95. multi: [{ type: Input }]
  96. };
  97. /**
  98. * @fileoverview added by tsickle
  99. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  100. */
  101. /**
  102. * Used to generate unique ID for each accordion item.
  103. * @type {?}
  104. */
  105. let nextId$1 = 0;
  106. const ɵ0 = undefined;
  107. /**
  108. * An basic directive expected to be extended and decorated as a component. Sets up all
  109. * events and attributes needed to be managed by a CdkAccordion parent.
  110. */
  111. class CdkAccordionItem {
  112. /**
  113. * @param {?} accordion
  114. * @param {?} _changeDetectorRef
  115. * @param {?} _expansionDispatcher
  116. */
  117. constructor(accordion, _changeDetectorRef, _expansionDispatcher) {
  118. this.accordion = accordion;
  119. this._changeDetectorRef = _changeDetectorRef;
  120. this._expansionDispatcher = _expansionDispatcher;
  121. /**
  122. * Subscription to openAll/closeAll events.
  123. */
  124. this._openCloseAllSubscription = Subscription.EMPTY;
  125. /**
  126. * Event emitted every time the AccordionItem is closed.
  127. */
  128. this.closed = new EventEmitter();
  129. /**
  130. * Event emitted every time the AccordionItem is opened.
  131. */
  132. this.opened = new EventEmitter();
  133. /**
  134. * Event emitted when the AccordionItem is destroyed.
  135. */
  136. this.destroyed = new EventEmitter();
  137. /**
  138. * Emits whenever the expanded state of the accordion changes.
  139. * Primarily used to facilitate two-way binding.
  140. * \@docs-private
  141. */
  142. this.expandedChange = new EventEmitter();
  143. /**
  144. * The unique AccordionItem id.
  145. */
  146. this.id = `cdk-accordion-child-${nextId$1++}`;
  147. this._expanded = false;
  148. this._disabled = false;
  149. /**
  150. * Unregister function for _expansionDispatcher.
  151. */
  152. this._removeUniqueSelectionListener = (/**
  153. * @return {?}
  154. */
  155. () => { });
  156. this._removeUniqueSelectionListener =
  157. _expansionDispatcher.listen((/**
  158. * @param {?} id
  159. * @param {?} accordionId
  160. * @return {?}
  161. */
  162. (id, accordionId) => {
  163. if (this.accordion && !this.accordion.multi &&
  164. this.accordion.id === accordionId && this.id !== id) {
  165. this.expanded = false;
  166. }
  167. }));
  168. // When an accordion item is hosted in an accordion, subscribe to open/close events.
  169. if (this.accordion) {
  170. this._openCloseAllSubscription = this._subscribeToOpenCloseAllActions();
  171. }
  172. }
  173. /**
  174. * Whether the AccordionItem is expanded.
  175. * @return {?}
  176. */
  177. get expanded() { return this._expanded; }
  178. /**
  179. * @param {?} expanded
  180. * @return {?}
  181. */
  182. set expanded(expanded) {
  183. expanded = coerceBooleanProperty(expanded);
  184. // Only emit events and update the internal value if the value changes.
  185. if (this._expanded !== expanded) {
  186. this._expanded = expanded;
  187. this.expandedChange.emit(expanded);
  188. if (expanded) {
  189. this.opened.emit();
  190. /**
  191. * In the unique selection dispatcher, the id parameter is the id of the CdkAccordionItem,
  192. * the name value is the id of the accordion.
  193. * @type {?}
  194. */
  195. const accordionId = this.accordion ? this.accordion.id : this.id;
  196. this._expansionDispatcher.notify(this.id, accordionId);
  197. }
  198. else {
  199. this.closed.emit();
  200. }
  201. // Ensures that the animation will run when the value is set outside of an `@Input`.
  202. // This includes cases like the open, close and toggle methods.
  203. this._changeDetectorRef.markForCheck();
  204. }
  205. }
  206. /**
  207. * Whether the AccordionItem is disabled.
  208. * @return {?}
  209. */
  210. get disabled() { return this._disabled; }
  211. /**
  212. * @param {?} disabled
  213. * @return {?}
  214. */
  215. set disabled(disabled) { this._disabled = coerceBooleanProperty(disabled); }
  216. /**
  217. * Emits an event for the accordion item being destroyed.
  218. * @return {?}
  219. */
  220. ngOnDestroy() {
  221. this.opened.complete();
  222. this.closed.complete();
  223. this.destroyed.emit();
  224. this.destroyed.complete();
  225. this._removeUniqueSelectionListener();
  226. this._openCloseAllSubscription.unsubscribe();
  227. }
  228. /**
  229. * Toggles the expanded state of the accordion item.
  230. * @return {?}
  231. */
  232. toggle() {
  233. if (!this.disabled) {
  234. this.expanded = !this.expanded;
  235. }
  236. }
  237. /**
  238. * Sets the expanded state of the accordion item to false.
  239. * @return {?}
  240. */
  241. close() {
  242. if (!this.disabled) {
  243. this.expanded = false;
  244. }
  245. }
  246. /**
  247. * Sets the expanded state of the accordion item to true.
  248. * @return {?}
  249. */
  250. open() {
  251. if (!this.disabled) {
  252. this.expanded = true;
  253. }
  254. }
  255. /**
  256. * @private
  257. * @return {?}
  258. */
  259. _subscribeToOpenCloseAllActions() {
  260. return this.accordion._openCloseAllActions.subscribe((/**
  261. * @param {?} expanded
  262. * @return {?}
  263. */
  264. expanded => {
  265. // Only change expanded state if item is enabled
  266. if (!this.disabled) {
  267. this.expanded = expanded;
  268. }
  269. }));
  270. }
  271. }
  272. CdkAccordionItem.decorators = [
  273. { type: Directive, args: [{
  274. selector: 'cdk-accordion-item, [cdkAccordionItem]',
  275. exportAs: 'cdkAccordionItem',
  276. providers: [
  277. // Provide CdkAccordion as undefined to prevent nested accordion items from registering
  278. // to the same accordion.
  279. { provide: CdkAccordion, useValue: ɵ0 },
  280. ],
  281. },] },
  282. ];
  283. /** @nocollapse */
  284. CdkAccordionItem.ctorParameters = () => [
  285. { type: CdkAccordion, decorators: [{ type: Optional }, { type: SkipSelf }] },
  286. { type: ChangeDetectorRef },
  287. { type: UniqueSelectionDispatcher }
  288. ];
  289. CdkAccordionItem.propDecorators = {
  290. closed: [{ type: Output }],
  291. opened: [{ type: Output }],
  292. destroyed: [{ type: Output }],
  293. expandedChange: [{ type: Output }],
  294. expanded: [{ type: Input }],
  295. disabled: [{ type: Input }]
  296. };
  297. /**
  298. * @fileoverview added by tsickle
  299. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  300. */
  301. class CdkAccordionModule {
  302. }
  303. CdkAccordionModule.decorators = [
  304. { type: NgModule, args: [{
  305. exports: [CdkAccordion, CdkAccordionItem],
  306. declarations: [CdkAccordion, CdkAccordionItem],
  307. },] },
  308. ];
  309. /**
  310. * @fileoverview added by tsickle
  311. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  312. */
  313. /**
  314. * @fileoverview added by tsickle
  315. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  316. */
  317. export { CdkAccordionItem, CdkAccordion, CdkAccordionModule };
  318. //# sourceMappingURL=accordion.js.map