sidenav.mjs 74 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157
  1. import { FocusTrapFactory, FocusMonitor, InteractivityChecker } from '@angular/cdk/a11y';
  2. import { Directionality } from '@angular/cdk/bidi';
  3. import { coerceBooleanProperty, coerceNumberProperty } from '@angular/cdk/coercion';
  4. import { ESCAPE, hasModifierKey } from '@angular/cdk/keycodes';
  5. import { Platform } from '@angular/cdk/platform';
  6. import { CdkScrollable, ScrollDispatcher, ViewportRuler, CdkScrollableModule } from '@angular/cdk/scrolling';
  7. import { DOCUMENT } from '@angular/common';
  8. import * as i0 from '@angular/core';
  9. import { InjectionToken, inject, ChangeDetectorRef, ElementRef, NgZone, Component, ChangeDetectionStrategy, ViewEncapsulation, Renderer2, EventEmitter, Injector, afterNextRender, Input, Output, ViewChild, ANIMATION_MODULE_TYPE, QueryList, ContentChildren, ContentChild, NgModule } from '@angular/core';
  10. import { Subject, fromEvent, merge } from 'rxjs';
  11. import { filter, map, mapTo, takeUntil, take, startWith, debounceTime } from 'rxjs/operators';
  12. import { M as MatCommonModule } from './common-module-WayjW0Pb.mjs';
  13. /**
  14. * Throws an exception when two MatDrawer are matching the same position.
  15. * @docs-private
  16. */
  17. function throwMatDuplicatedDrawerError(position) {
  18. throw Error(`A drawer was already declared for 'position="${position}"'`);
  19. }
  20. /** Configures whether drawers should use auto sizing by default. */
  21. const MAT_DRAWER_DEFAULT_AUTOSIZE = new InjectionToken('MAT_DRAWER_DEFAULT_AUTOSIZE', {
  22. providedIn: 'root',
  23. factory: MAT_DRAWER_DEFAULT_AUTOSIZE_FACTORY,
  24. });
  25. /**
  26. * Used to provide a drawer container to a drawer while avoiding circular references.
  27. * @docs-private
  28. */
  29. const MAT_DRAWER_CONTAINER = new InjectionToken('MAT_DRAWER_CONTAINER');
  30. /**
  31. * @docs-private
  32. * @deprecated No longer used, will be removed.
  33. * @breaking-change 21.0.0
  34. */
  35. function MAT_DRAWER_DEFAULT_AUTOSIZE_FACTORY() {
  36. return false;
  37. }
  38. class MatDrawerContent extends CdkScrollable {
  39. _platform = inject(Platform);
  40. _changeDetectorRef = inject(ChangeDetectorRef);
  41. _container = inject(MatDrawerContainer);
  42. constructor() {
  43. const elementRef = inject(ElementRef);
  44. const scrollDispatcher = inject(ScrollDispatcher);
  45. const ngZone = inject(NgZone);
  46. super(elementRef, scrollDispatcher, ngZone);
  47. }
  48. ngAfterContentInit() {
  49. this._container._contentMarginChanges.subscribe(() => {
  50. this._changeDetectorRef.markForCheck();
  51. });
  52. }
  53. /** Determines whether the content element should be hidden from the user. */
  54. _shouldBeHidden() {
  55. // In some modes the content is pushed based on the width of the opened sidenavs, however on
  56. // the server we can't measure the sidenav so the margin is always zero. This can cause the
  57. // content to jump around when it's rendered on the server and hydrated on the client. We
  58. // avoid it by hiding the content on the initial render and then showing it once the sidenav
  59. // has been measured on the client.
  60. if (this._platform.isBrowser) {
  61. return false;
  62. }
  63. const { start, end } = this._container;
  64. return ((start != null && start.mode !== 'over' && start.opened) ||
  65. (end != null && end.mode !== 'over' && end.opened));
  66. }
  67. static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: MatDrawerContent, deps: [], target: i0.ɵɵFactoryTarget.Component });
  68. static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.6", type: MatDrawerContent, isStandalone: true, selector: "mat-drawer-content", host: { properties: { "style.margin-left.px": "_container._contentMargins.left", "style.margin-right.px": "_container._contentMargins.right", "class.mat-drawer-content-hidden": "_shouldBeHidden()" }, classAttribute: "mat-drawer-content" }, providers: [
  69. {
  70. provide: CdkScrollable,
  71. useExisting: MatDrawerContent,
  72. },
  73. ], usesInheritance: true, ngImport: i0, template: '<ng-content></ng-content>', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
  74. }
  75. i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: MatDrawerContent, decorators: [{
  76. type: Component,
  77. args: [{
  78. selector: 'mat-drawer-content',
  79. template: '<ng-content></ng-content>',
  80. host: {
  81. 'class': 'mat-drawer-content',
  82. '[style.margin-left.px]': '_container._contentMargins.left',
  83. '[style.margin-right.px]': '_container._contentMargins.right',
  84. '[class.mat-drawer-content-hidden]': '_shouldBeHidden()',
  85. },
  86. changeDetection: ChangeDetectionStrategy.OnPush,
  87. encapsulation: ViewEncapsulation.None,
  88. providers: [
  89. {
  90. provide: CdkScrollable,
  91. useExisting: MatDrawerContent,
  92. },
  93. ],
  94. }]
  95. }], ctorParameters: () => [] });
  96. /**
  97. * This component corresponds to a drawer that can be opened on the drawer container.
  98. */
  99. class MatDrawer {
  100. _elementRef = inject(ElementRef);
  101. _focusTrapFactory = inject(FocusTrapFactory);
  102. _focusMonitor = inject(FocusMonitor);
  103. _platform = inject(Platform);
  104. _ngZone = inject(NgZone);
  105. _renderer = inject(Renderer2);
  106. _interactivityChecker = inject(InteractivityChecker);
  107. _doc = inject(DOCUMENT, { optional: true });
  108. _container = inject(MAT_DRAWER_CONTAINER, { optional: true });
  109. _focusTrap = null;
  110. _elementFocusedBeforeDrawerWasOpened = null;
  111. _eventCleanups;
  112. /** Whether the view of the component has been attached. */
  113. _isAttached;
  114. /** Anchor node used to restore the drawer to its initial position. */
  115. _anchor;
  116. /** The side that the drawer is attached to. */
  117. get position() {
  118. return this._position;
  119. }
  120. set position(value) {
  121. // Make sure we have a valid value.
  122. value = value === 'end' ? 'end' : 'start';
  123. if (value !== this._position) {
  124. // Static inputs in Ivy are set before the element is in the DOM.
  125. if (this._isAttached) {
  126. this._updatePositionInParent(value);
  127. }
  128. this._position = value;
  129. this.onPositionChanged.emit();
  130. }
  131. }
  132. _position = 'start';
  133. /** Mode of the drawer; one of 'over', 'push' or 'side'. */
  134. get mode() {
  135. return this._mode;
  136. }
  137. set mode(value) {
  138. this._mode = value;
  139. this._updateFocusTrapState();
  140. this._modeChanged.next();
  141. }
  142. _mode = 'over';
  143. /** Whether the drawer can be closed with the escape key or by clicking on the backdrop. */
  144. get disableClose() {
  145. return this._disableClose;
  146. }
  147. set disableClose(value) {
  148. this._disableClose = coerceBooleanProperty(value);
  149. }
  150. _disableClose = false;
  151. /**
  152. * Whether the drawer should focus the first focusable element automatically when opened.
  153. * Defaults to false in when `mode` is set to `side`, otherwise defaults to `true`. If explicitly
  154. * enabled, focus will be moved into the sidenav in `side` mode as well.
  155. * @breaking-change 14.0.0 Remove boolean option from autoFocus. Use string or AutoFocusTarget
  156. * instead.
  157. */
  158. get autoFocus() {
  159. const value = this._autoFocus;
  160. // Note that usually we don't allow autoFocus to be set to `first-tabbable` in `side` mode,
  161. // because we don't know how the sidenav is being used, but in some cases it still makes
  162. // sense to do it. The consumer can explicitly set `autoFocus`.
  163. if (value == null) {
  164. if (this.mode === 'side') {
  165. return 'dialog';
  166. }
  167. else {
  168. return 'first-tabbable';
  169. }
  170. }
  171. return value;
  172. }
  173. set autoFocus(value) {
  174. if (value === 'true' || value === 'false' || value == null) {
  175. value = coerceBooleanProperty(value);
  176. }
  177. this._autoFocus = value;
  178. }
  179. _autoFocus;
  180. /**
  181. * Whether the drawer is opened. We overload this because we trigger an event when it
  182. * starts or end.
  183. */
  184. get opened() {
  185. return this._opened;
  186. }
  187. set opened(value) {
  188. this.toggle(coerceBooleanProperty(value));
  189. }
  190. _opened = false;
  191. /** How the sidenav was opened (keypress, mouse click etc.) */
  192. _openedVia;
  193. /** Emits whenever the drawer has started animating. */
  194. _animationStarted = new Subject();
  195. /** Emits whenever the drawer is done animating. */
  196. _animationEnd = new Subject();
  197. /** Event emitted when the drawer open state is changed. */
  198. openedChange =
  199. // Note this has to be async in order to avoid some issues with two-bindings (see #8872).
  200. new EventEmitter(/* isAsync */ true);
  201. /** Event emitted when the drawer has been opened. */
  202. _openedStream = this.openedChange.pipe(filter(o => o), map(() => { }));
  203. /** Event emitted when the drawer has started opening. */
  204. openedStart = this._animationStarted.pipe(filter(() => this.opened), mapTo(undefined));
  205. /** Event emitted when the drawer has been closed. */
  206. _closedStream = this.openedChange.pipe(filter(o => !o), map(() => { }));
  207. /** Event emitted when the drawer has started closing. */
  208. closedStart = this._animationStarted.pipe(filter(() => !this.opened), mapTo(undefined));
  209. /** Emits when the component is destroyed. */
  210. _destroyed = new Subject();
  211. /** Event emitted when the drawer's position changes. */
  212. // tslint:disable-next-line:no-output-on-prefix
  213. onPositionChanged = new EventEmitter();
  214. /** Reference to the inner element that contains all the content. */
  215. _content;
  216. /**
  217. * An observable that emits when the drawer mode changes. This is used by the drawer container to
  218. * to know when to when the mode changes so it can adapt the margins on the content.
  219. */
  220. _modeChanged = new Subject();
  221. _injector = inject(Injector);
  222. _changeDetectorRef = inject(ChangeDetectorRef);
  223. constructor() {
  224. this.openedChange.pipe(takeUntil(this._destroyed)).subscribe((opened) => {
  225. if (opened) {
  226. if (this._doc) {
  227. this._elementFocusedBeforeDrawerWasOpened = this._doc.activeElement;
  228. }
  229. this._takeFocus();
  230. }
  231. else if (this._isFocusWithinDrawer()) {
  232. this._restoreFocus(this._openedVia || 'program');
  233. }
  234. });
  235. /**
  236. * Listen to `keydown` events outside the zone so that change detection is not run every
  237. * time a key is pressed. Instead we re-enter the zone only if the `ESC` key is pressed
  238. * and we don't have close disabled.
  239. */
  240. this._ngZone.runOutsideAngular(() => {
  241. const element = this._elementRef.nativeElement;
  242. fromEvent(element, 'keydown')
  243. .pipe(filter(event => {
  244. return event.keyCode === ESCAPE && !this.disableClose && !hasModifierKey(event);
  245. }), takeUntil(this._destroyed))
  246. .subscribe(event => this._ngZone.run(() => {
  247. this.close();
  248. event.stopPropagation();
  249. event.preventDefault();
  250. }));
  251. this._eventCleanups = [
  252. this._renderer.listen(element, 'transitionrun', this._handleTransitionEvent),
  253. this._renderer.listen(element, 'transitionend', this._handleTransitionEvent),
  254. this._renderer.listen(element, 'transitioncancel', this._handleTransitionEvent),
  255. ];
  256. });
  257. this._animationEnd.subscribe(() => {
  258. this.openedChange.emit(this._opened);
  259. });
  260. }
  261. /**
  262. * Focuses the provided element. If the element is not focusable, it will add a tabIndex
  263. * attribute to forcefully focus it. The attribute is removed after focus is moved.
  264. * @param element The element to focus.
  265. */
  266. _forceFocus(element, options) {
  267. if (!this._interactivityChecker.isFocusable(element)) {
  268. element.tabIndex = -1;
  269. // The tabindex attribute should be removed to avoid navigating to that element again
  270. this._ngZone.runOutsideAngular(() => {
  271. const callback = () => {
  272. cleanupBlur();
  273. cleanupMousedown();
  274. element.removeAttribute('tabindex');
  275. };
  276. const cleanupBlur = this._renderer.listen(element, 'blur', callback);
  277. const cleanupMousedown = this._renderer.listen(element, 'mousedown', callback);
  278. });
  279. }
  280. element.focus(options);
  281. }
  282. /**
  283. * Focuses the first element that matches the given selector within the focus trap.
  284. * @param selector The CSS selector for the element to set focus to.
  285. */
  286. _focusByCssSelector(selector, options) {
  287. let elementToFocus = this._elementRef.nativeElement.querySelector(selector);
  288. if (elementToFocus) {
  289. this._forceFocus(elementToFocus, options);
  290. }
  291. }
  292. /**
  293. * Moves focus into the drawer. Note that this works even if
  294. * the focus trap is disabled in `side` mode.
  295. */
  296. _takeFocus() {
  297. if (!this._focusTrap) {
  298. return;
  299. }
  300. const element = this._elementRef.nativeElement;
  301. // When autoFocus is not on the sidenav, if the element cannot be focused or does
  302. // not exist, focus the sidenav itself so the keyboard navigation still works.
  303. // We need to check that `focus` is a function due to Universal.
  304. switch (this.autoFocus) {
  305. case false:
  306. case 'dialog':
  307. return;
  308. case true:
  309. case 'first-tabbable':
  310. afterNextRender(() => {
  311. const hasMovedFocus = this._focusTrap.focusInitialElement();
  312. if (!hasMovedFocus && typeof element.focus === 'function') {
  313. element.focus();
  314. }
  315. }, { injector: this._injector });
  316. break;
  317. case 'first-heading':
  318. this._focusByCssSelector('h1, h2, h3, h4, h5, h6, [role="heading"]');
  319. break;
  320. default:
  321. this._focusByCssSelector(this.autoFocus);
  322. break;
  323. }
  324. }
  325. /**
  326. * Restores focus to the element that was originally focused when the drawer opened.
  327. * If no element was focused at that time, the focus will be restored to the drawer.
  328. */
  329. _restoreFocus(focusOrigin) {
  330. if (this.autoFocus === 'dialog') {
  331. return;
  332. }
  333. if (this._elementFocusedBeforeDrawerWasOpened) {
  334. this._focusMonitor.focusVia(this._elementFocusedBeforeDrawerWasOpened, focusOrigin);
  335. }
  336. else {
  337. this._elementRef.nativeElement.blur();
  338. }
  339. this._elementFocusedBeforeDrawerWasOpened = null;
  340. }
  341. /** Whether focus is currently within the drawer. */
  342. _isFocusWithinDrawer() {
  343. const activeEl = this._doc.activeElement;
  344. return !!activeEl && this._elementRef.nativeElement.contains(activeEl);
  345. }
  346. ngAfterViewInit() {
  347. this._isAttached = true;
  348. // Only update the DOM position when the sidenav is positioned at
  349. // the end since we project the sidenav before the content by default.
  350. if (this._position === 'end') {
  351. this._updatePositionInParent('end');
  352. }
  353. // Needs to happen after the position is updated
  354. // so the focus trap anchors are in the right place.
  355. if (this._platform.isBrowser) {
  356. this._focusTrap = this._focusTrapFactory.create(this._elementRef.nativeElement);
  357. this._updateFocusTrapState();
  358. }
  359. }
  360. ngOnDestroy() {
  361. this._eventCleanups.forEach(cleanup => cleanup());
  362. this._focusTrap?.destroy();
  363. this._anchor?.remove();
  364. this._anchor = null;
  365. this._animationStarted.complete();
  366. this._animationEnd.complete();
  367. this._modeChanged.complete();
  368. this._destroyed.next();
  369. this._destroyed.complete();
  370. }
  371. /**
  372. * Open the drawer.
  373. * @param openedVia Whether the drawer was opened by a key press, mouse click or programmatically.
  374. * Used for focus management after the sidenav is closed.
  375. */
  376. open(openedVia) {
  377. return this.toggle(true, openedVia);
  378. }
  379. /** Close the drawer. */
  380. close() {
  381. return this.toggle(false);
  382. }
  383. /** Closes the drawer with context that the backdrop was clicked. */
  384. _closeViaBackdropClick() {
  385. // If the drawer is closed upon a backdrop click, we always want to restore focus. We
  386. // don't need to check whether focus is currently in the drawer, as clicking on the
  387. // backdrop causes blurs the active element.
  388. return this._setOpen(/* isOpen */ false, /* restoreFocus */ true, 'mouse');
  389. }
  390. /**
  391. * Toggle this drawer.
  392. * @param isOpen Whether the drawer should be open.
  393. * @param openedVia Whether the drawer was opened by a key press, mouse click or programmatically.
  394. * Used for focus management after the sidenav is closed.
  395. */
  396. toggle(isOpen = !this.opened, openedVia) {
  397. // If the focus is currently inside the drawer content and we are closing the drawer,
  398. // restore the focus to the initially focused element (when the drawer opened).
  399. if (isOpen && openedVia) {
  400. this._openedVia = openedVia;
  401. }
  402. const result = this._setOpen(isOpen,
  403. /* restoreFocus */ !isOpen && this._isFocusWithinDrawer(), this._openedVia || 'program');
  404. if (!isOpen) {
  405. this._openedVia = null;
  406. }
  407. return result;
  408. }
  409. /**
  410. * Toggles the opened state of the drawer.
  411. * @param isOpen Whether the drawer should open or close.
  412. * @param restoreFocus Whether focus should be restored on close.
  413. * @param focusOrigin Origin to use when restoring focus.
  414. */
  415. _setOpen(isOpen, restoreFocus, focusOrigin) {
  416. if (isOpen === this._opened) {
  417. return Promise.resolve(isOpen ? 'open' : 'close');
  418. }
  419. this._opened = isOpen;
  420. if (this._container?._transitionsEnabled) {
  421. // Note: it's importatnt to set this as early as possible,
  422. // otherwise the animation can look glitchy in some cases.
  423. this._setIsAnimating(true);
  424. }
  425. else {
  426. // Simulate the animation events if animations are disabled.
  427. setTimeout(() => {
  428. this._animationStarted.next();
  429. this._animationEnd.next();
  430. });
  431. }
  432. this._elementRef.nativeElement.classList.toggle('mat-drawer-opened', isOpen);
  433. if (!isOpen && restoreFocus) {
  434. this._restoreFocus(focusOrigin);
  435. }
  436. // Needed to ensure that the closing sequence fires off correctly.
  437. this._changeDetectorRef.markForCheck();
  438. this._updateFocusTrapState();
  439. return new Promise(resolve => {
  440. this.openedChange.pipe(take(1)).subscribe(open => resolve(open ? 'open' : 'close'));
  441. });
  442. }
  443. /** Toggles whether the drawer is currently animating. */
  444. _setIsAnimating(isAnimating) {
  445. this._elementRef.nativeElement.classList.toggle('mat-drawer-animating', isAnimating);
  446. }
  447. _getWidth() {
  448. return this._elementRef.nativeElement.offsetWidth || 0;
  449. }
  450. /** Updates the enabled state of the focus trap. */
  451. _updateFocusTrapState() {
  452. if (this._focusTrap) {
  453. // Trap focus only if the backdrop is enabled. Otherwise, allow end user to interact with the
  454. // sidenav content.
  455. this._focusTrap.enabled = !!this._container?.hasBackdrop && this.opened;
  456. }
  457. }
  458. /**
  459. * Updates the position of the drawer in the DOM. We need to move the element around ourselves
  460. * when it's in the `end` position so that it comes after the content and the visual order
  461. * matches the tab order. We also need to be able to move it back to `start` if the sidenav
  462. * started off as `end` and was changed to `start`.
  463. */
  464. _updatePositionInParent(newPosition) {
  465. // Don't move the DOM node around on the server, because it can throw off hydration.
  466. if (!this._platform.isBrowser) {
  467. return;
  468. }
  469. const element = this._elementRef.nativeElement;
  470. const parent = element.parentNode;
  471. if (newPosition === 'end') {
  472. if (!this._anchor) {
  473. this._anchor = this._doc.createComment('mat-drawer-anchor');
  474. parent.insertBefore(this._anchor, element);
  475. }
  476. parent.appendChild(element);
  477. }
  478. else if (this._anchor) {
  479. this._anchor.parentNode.insertBefore(element, this._anchor);
  480. }
  481. }
  482. /** Event handler for animation events. */
  483. _handleTransitionEvent = (event) => {
  484. const element = this._elementRef.nativeElement;
  485. if (event.target === element) {
  486. this._ngZone.run(() => {
  487. if (event.type === 'transitionrun') {
  488. this._animationStarted.next(event);
  489. }
  490. else {
  491. // Don't toggle the animating state on `transitioncancel` since another animation should
  492. // start afterwards. This prevents the drawer from blinking if an animation is interrupted.
  493. if (event.type === 'transitionend') {
  494. this._setIsAnimating(false);
  495. }
  496. this._animationEnd.next(event);
  497. }
  498. });
  499. }
  500. };
  501. static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: MatDrawer, deps: [], target: i0.ɵɵFactoryTarget.Component });
  502. static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.6", type: MatDrawer, isStandalone: true, selector: "mat-drawer", inputs: { position: "position", mode: "mode", disableClose: "disableClose", autoFocus: "autoFocus", opened: "opened" }, outputs: { openedChange: "openedChange", _openedStream: "opened", openedStart: "openedStart", _closedStream: "closed", closedStart: "closedStart", onPositionChanged: "positionChanged" }, host: { properties: { "attr.align": "null", "class.mat-drawer-end": "position === \"end\"", "class.mat-drawer-over": "mode === \"over\"", "class.mat-drawer-push": "mode === \"push\"", "class.mat-drawer-side": "mode === \"side\"", "style.visibility": "(!_container && !opened) ? \"hidden\" : null", "attr.tabIndex": "(mode !== \"side\") ? \"-1\" : null" }, classAttribute: "mat-drawer" }, viewQueries: [{ propertyName: "_content", first: true, predicate: ["content"], descendants: true }], exportAs: ["matDrawer"], ngImport: i0, template: "<div class=\"mat-drawer-inner-container\" cdkScrollable #content>\r\n <ng-content></ng-content>\r\n</div>\r\n", dependencies: [{ kind: "directive", type: CdkScrollable, selector: "[cdk-scrollable], [cdkScrollable]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
  503. }
  504. i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: MatDrawer, decorators: [{
  505. type: Component,
  506. args: [{ selector: 'mat-drawer', exportAs: 'matDrawer', host: {
  507. 'class': 'mat-drawer',
  508. // must prevent the browser from aligning text based on value
  509. '[attr.align]': 'null',
  510. '[class.mat-drawer-end]': 'position === "end"',
  511. '[class.mat-drawer-over]': 'mode === "over"',
  512. '[class.mat-drawer-push]': 'mode === "push"',
  513. '[class.mat-drawer-side]': 'mode === "side"',
  514. // The styles that render the sidenav off-screen come from the drawer container. Prior to #30235
  515. // this was also done by the animations module which some internal tests seem to depend on.
  516. // Simulate it by toggling the `hidden` attribute instead.
  517. '[style.visibility]': '(!_container && !opened) ? "hidden" : null',
  518. // The sidenav container should not be focused on when used in side mode. See b/286459024 for
  519. // reference. Updates tabIndex of drawer/container to default to null if in side mode.
  520. '[attr.tabIndex]': '(mode !== "side") ? "-1" : null',
  521. }, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [CdkScrollable], template: "<div class=\"mat-drawer-inner-container\" cdkScrollable #content>\r\n <ng-content></ng-content>\r\n</div>\r\n" }]
  522. }], ctorParameters: () => [], propDecorators: { position: [{
  523. type: Input
  524. }], mode: [{
  525. type: Input
  526. }], disableClose: [{
  527. type: Input
  528. }], autoFocus: [{
  529. type: Input
  530. }], opened: [{
  531. type: Input
  532. }], openedChange: [{
  533. type: Output
  534. }], _openedStream: [{
  535. type: Output,
  536. args: ['opened']
  537. }], openedStart: [{
  538. type: Output
  539. }], _closedStream: [{
  540. type: Output,
  541. args: ['closed']
  542. }], closedStart: [{
  543. type: Output
  544. }], onPositionChanged: [{
  545. type: Output,
  546. args: ['positionChanged']
  547. }], _content: [{
  548. type: ViewChild,
  549. args: ['content']
  550. }] } });
  551. /**
  552. * `<mat-drawer-container>` component.
  553. *
  554. * This is the parent component to one or two `<mat-drawer>`s that validates the state internally
  555. * and coordinates the backdrop and content styling.
  556. */
  557. class MatDrawerContainer {
  558. _dir = inject(Directionality, { optional: true });
  559. _element = inject(ElementRef);
  560. _ngZone = inject(NgZone);
  561. _changeDetectorRef = inject(ChangeDetectorRef);
  562. _animationMode = inject(ANIMATION_MODULE_TYPE, { optional: true });
  563. _transitionsEnabled = false;
  564. /** All drawers in the container. Includes drawers from inside nested containers. */
  565. _allDrawers;
  566. /** Drawers that belong to this container. */
  567. _drawers = new QueryList();
  568. _content;
  569. _userContent;
  570. /** The drawer child with the `start` position. */
  571. get start() {
  572. return this._start;
  573. }
  574. /** The drawer child with the `end` position. */
  575. get end() {
  576. return this._end;
  577. }
  578. /**
  579. * Whether to automatically resize the container whenever
  580. * the size of any of its drawers changes.
  581. *
  582. * **Use at your own risk!** Enabling this option can cause layout thrashing by measuring
  583. * the drawers on every change detection cycle. Can be configured globally via the
  584. * `MAT_DRAWER_DEFAULT_AUTOSIZE` token.
  585. */
  586. get autosize() {
  587. return this._autosize;
  588. }
  589. set autosize(value) {
  590. this._autosize = coerceBooleanProperty(value);
  591. }
  592. _autosize = inject(MAT_DRAWER_DEFAULT_AUTOSIZE);
  593. /**
  594. * Whether the drawer container should have a backdrop while one of the sidenavs is open.
  595. * If explicitly set to `true`, the backdrop will be enabled for drawers in the `side`
  596. * mode as well.
  597. */
  598. get hasBackdrop() {
  599. return this._drawerHasBackdrop(this._start) || this._drawerHasBackdrop(this._end);
  600. }
  601. set hasBackdrop(value) {
  602. this._backdropOverride = value == null ? null : coerceBooleanProperty(value);
  603. }
  604. _backdropOverride;
  605. /** Event emitted when the drawer backdrop is clicked. */
  606. backdropClick = new EventEmitter();
  607. /** The drawer at the start/end position, independent of direction. */
  608. _start;
  609. _end;
  610. /**
  611. * The drawer at the left/right. When direction changes, these will change as well.
  612. * They're used as aliases for the above to set the left/right style properly.
  613. * In LTR, _left == _start and _right == _end.
  614. * In RTL, _left == _end and _right == _start.
  615. */
  616. _left;
  617. _right;
  618. /** Emits when the component is destroyed. */
  619. _destroyed = new Subject();
  620. /** Emits on every ngDoCheck. Used for debouncing reflows. */
  621. _doCheckSubject = new Subject();
  622. /**
  623. * Margins to be applied to the content. These are used to push / shrink the drawer content when a
  624. * drawer is open. We use margin rather than transform even for push mode because transform breaks
  625. * fixed position elements inside of the transformed element.
  626. */
  627. _contentMargins = { left: null, right: null };
  628. _contentMarginChanges = new Subject();
  629. /** Reference to the CdkScrollable instance that wraps the scrollable content. */
  630. get scrollable() {
  631. return this._userContent || this._content;
  632. }
  633. _injector = inject(Injector);
  634. constructor() {
  635. const platform = inject(Platform);
  636. const viewportRuler = inject(ViewportRuler);
  637. // If a `Dir` directive exists up the tree, listen direction changes
  638. // and update the left/right properties to point to the proper start/end.
  639. this._dir?.change.pipe(takeUntil(this._destroyed)).subscribe(() => {
  640. this._validateDrawers();
  641. this.updateContentMargins();
  642. });
  643. // Since the minimum width of the sidenav depends on the viewport width,
  644. // we need to recompute the margins if the viewport changes.
  645. viewportRuler
  646. .change()
  647. .pipe(takeUntil(this._destroyed))
  648. .subscribe(() => this.updateContentMargins());
  649. if (this._animationMode !== 'NoopAnimations' && platform.isBrowser) {
  650. this._ngZone.runOutsideAngular(() => {
  651. // Enable the animations after a delay in order to skip
  652. // the initial transition if a drawer is open by default.
  653. setTimeout(() => {
  654. this._element.nativeElement.classList.add('mat-drawer-transition');
  655. this._transitionsEnabled = true;
  656. }, 200);
  657. });
  658. }
  659. }
  660. ngAfterContentInit() {
  661. this._allDrawers.changes
  662. .pipe(startWith(this._allDrawers), takeUntil(this._destroyed))
  663. .subscribe((drawer) => {
  664. this._drawers.reset(drawer.filter(item => !item._container || item._container === this));
  665. this._drawers.notifyOnChanges();
  666. });
  667. this._drawers.changes.pipe(startWith(null)).subscribe(() => {
  668. this._validateDrawers();
  669. this._drawers.forEach((drawer) => {
  670. this._watchDrawerToggle(drawer);
  671. this._watchDrawerPosition(drawer);
  672. this._watchDrawerMode(drawer);
  673. });
  674. if (!this._drawers.length ||
  675. this._isDrawerOpen(this._start) ||
  676. this._isDrawerOpen(this._end)) {
  677. this.updateContentMargins();
  678. }
  679. this._changeDetectorRef.markForCheck();
  680. });
  681. // Avoid hitting the NgZone through the debounce timeout.
  682. this._ngZone.runOutsideAngular(() => {
  683. this._doCheckSubject
  684. .pipe(debounceTime(10), // Arbitrary debounce time, less than a frame at 60fps
  685. takeUntil(this._destroyed))
  686. .subscribe(() => this.updateContentMargins());
  687. });
  688. }
  689. ngOnDestroy() {
  690. this._contentMarginChanges.complete();
  691. this._doCheckSubject.complete();
  692. this._drawers.destroy();
  693. this._destroyed.next();
  694. this._destroyed.complete();
  695. }
  696. /** Calls `open` of both start and end drawers */
  697. open() {
  698. this._drawers.forEach(drawer => drawer.open());
  699. }
  700. /** Calls `close` of both start and end drawers */
  701. close() {
  702. this._drawers.forEach(drawer => drawer.close());
  703. }
  704. /**
  705. * Recalculates and updates the inline styles for the content. Note that this should be used
  706. * sparingly, because it causes a reflow.
  707. */
  708. updateContentMargins() {
  709. // 1. For drawers in `over` mode, they don't affect the content.
  710. // 2. For drawers in `side` mode they should shrink the content. We do this by adding to the
  711. // left margin (for left drawer) or right margin (for right the drawer).
  712. // 3. For drawers in `push` mode the should shift the content without resizing it. We do this by
  713. // adding to the left or right margin and simultaneously subtracting the same amount of
  714. // margin from the other side.
  715. let left = 0;
  716. let right = 0;
  717. if (this._left && this._left.opened) {
  718. if (this._left.mode == 'side') {
  719. left += this._left._getWidth();
  720. }
  721. else if (this._left.mode == 'push') {
  722. const width = this._left._getWidth();
  723. left += width;
  724. right -= width;
  725. }
  726. }
  727. if (this._right && this._right.opened) {
  728. if (this._right.mode == 'side') {
  729. right += this._right._getWidth();
  730. }
  731. else if (this._right.mode == 'push') {
  732. const width = this._right._getWidth();
  733. right += width;
  734. left -= width;
  735. }
  736. }
  737. // If either `right` or `left` is zero, don't set a style to the element. This
  738. // allows users to specify a custom size via CSS class in SSR scenarios where the
  739. // measured widths will always be zero. Note that we reset to `null` here, rather
  740. // than below, in order to ensure that the types in the `if` below are consistent.
  741. left = left || null;
  742. right = right || null;
  743. if (left !== this._contentMargins.left || right !== this._contentMargins.right) {
  744. this._contentMargins = { left, right };
  745. // Pull back into the NgZone since in some cases we could be outside. We need to be careful
  746. // to do it only when something changed, otherwise we can end up hitting the zone too often.
  747. this._ngZone.run(() => this._contentMarginChanges.next(this._contentMargins));
  748. }
  749. }
  750. ngDoCheck() {
  751. // If users opted into autosizing, do a check every change detection cycle.
  752. if (this._autosize && this._isPushed()) {
  753. // Run outside the NgZone, otherwise the debouncer will throw us into an infinite loop.
  754. this._ngZone.runOutsideAngular(() => this._doCheckSubject.next());
  755. }
  756. }
  757. /**
  758. * Subscribes to drawer events in order to set a class on the main container element when the
  759. * drawer is open and the backdrop is visible. This ensures any overflow on the container element
  760. * is properly hidden.
  761. */
  762. _watchDrawerToggle(drawer) {
  763. drawer._animationStarted.pipe(takeUntil(this._drawers.changes)).subscribe(() => {
  764. this.updateContentMargins();
  765. this._changeDetectorRef.markForCheck();
  766. });
  767. if (drawer.mode !== 'side') {
  768. drawer.openedChange
  769. .pipe(takeUntil(this._drawers.changes))
  770. .subscribe(() => this._setContainerClass(drawer.opened));
  771. }
  772. }
  773. /**
  774. * Subscribes to drawer onPositionChanged event in order to
  775. * re-validate drawers when the position changes.
  776. */
  777. _watchDrawerPosition(drawer) {
  778. // NOTE: We need to wait for the microtask queue to be empty before validating,
  779. // since both drawers may be swapping positions at the same time.
  780. drawer.onPositionChanged.pipe(takeUntil(this._drawers.changes)).subscribe(() => {
  781. afterNextRender({ read: () => this._validateDrawers() }, { injector: this._injector });
  782. });
  783. }
  784. /** Subscribes to changes in drawer mode so we can run change detection. */
  785. _watchDrawerMode(drawer) {
  786. drawer._modeChanged
  787. .pipe(takeUntil(merge(this._drawers.changes, this._destroyed)))
  788. .subscribe(() => {
  789. this.updateContentMargins();
  790. this._changeDetectorRef.markForCheck();
  791. });
  792. }
  793. /** Toggles the 'mat-drawer-opened' class on the main 'mat-drawer-container' element. */
  794. _setContainerClass(isAdd) {
  795. const classList = this._element.nativeElement.classList;
  796. const className = 'mat-drawer-container-has-open';
  797. if (isAdd) {
  798. classList.add(className);
  799. }
  800. else {
  801. classList.remove(className);
  802. }
  803. }
  804. /** Validate the state of the drawer children components. */
  805. _validateDrawers() {
  806. this._start = this._end = null;
  807. // Ensure that we have at most one start and one end drawer.
  808. this._drawers.forEach(drawer => {
  809. if (drawer.position == 'end') {
  810. if (this._end != null && (typeof ngDevMode === 'undefined' || ngDevMode)) {
  811. throwMatDuplicatedDrawerError('end');
  812. }
  813. this._end = drawer;
  814. }
  815. else {
  816. if (this._start != null && (typeof ngDevMode === 'undefined' || ngDevMode)) {
  817. throwMatDuplicatedDrawerError('start');
  818. }
  819. this._start = drawer;
  820. }
  821. });
  822. this._right = this._left = null;
  823. // Detect if we're LTR or RTL.
  824. if (this._dir && this._dir.value === 'rtl') {
  825. this._left = this._end;
  826. this._right = this._start;
  827. }
  828. else {
  829. this._left = this._start;
  830. this._right = this._end;
  831. }
  832. }
  833. /** Whether the container is being pushed to the side by one of the drawers. */
  834. _isPushed() {
  835. return ((this._isDrawerOpen(this._start) && this._start.mode != 'over') ||
  836. (this._isDrawerOpen(this._end) && this._end.mode != 'over'));
  837. }
  838. _onBackdropClicked() {
  839. this.backdropClick.emit();
  840. this._closeModalDrawersViaBackdrop();
  841. }
  842. _closeModalDrawersViaBackdrop() {
  843. // Close all open drawers where closing is not disabled and the mode is not `side`.
  844. [this._start, this._end]
  845. .filter(drawer => drawer && !drawer.disableClose && this._drawerHasBackdrop(drawer))
  846. .forEach(drawer => drawer._closeViaBackdropClick());
  847. }
  848. _isShowingBackdrop() {
  849. return ((this._isDrawerOpen(this._start) && this._drawerHasBackdrop(this._start)) ||
  850. (this._isDrawerOpen(this._end) && this._drawerHasBackdrop(this._end)));
  851. }
  852. _isDrawerOpen(drawer) {
  853. return drawer != null && drawer.opened;
  854. }
  855. // Whether argument drawer should have a backdrop when it opens
  856. _drawerHasBackdrop(drawer) {
  857. if (this._backdropOverride == null) {
  858. return !!drawer && drawer.mode !== 'side';
  859. }
  860. return this._backdropOverride;
  861. }
  862. static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: MatDrawerContainer, deps: [], target: i0.ɵɵFactoryTarget.Component });
  863. static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.6", type: MatDrawerContainer, isStandalone: true, selector: "mat-drawer-container", inputs: { autosize: "autosize", hasBackdrop: "hasBackdrop" }, outputs: { backdropClick: "backdropClick" }, host: { properties: { "class.mat-drawer-container-explicit-backdrop": "_backdropOverride" }, classAttribute: "mat-drawer-container" }, providers: [
  864. {
  865. provide: MAT_DRAWER_CONTAINER,
  866. useExisting: MatDrawerContainer,
  867. },
  868. ], queries: [{ propertyName: "_content", first: true, predicate: MatDrawerContent, descendants: true }, { propertyName: "_allDrawers", predicate: MatDrawer, descendants: true }], viewQueries: [{ propertyName: "_userContent", first: true, predicate: MatDrawerContent, descendants: true }], exportAs: ["matDrawerContainer"], ngImport: i0, template: "@if (hasBackdrop) {\n <div class=\"mat-drawer-backdrop\" (click)=\"_onBackdropClicked()\"\n [class.mat-drawer-shown]=\"_isShowingBackdrop()\"></div>\n}\n\n<ng-content select=\"mat-drawer\"></ng-content>\n\n<ng-content select=\"mat-drawer-content\">\n</ng-content>\n\n@if (!_content) {\n <mat-drawer-content>\n <ng-content></ng-content>\n </mat-drawer-content>\n}\n", styles: [".mat-drawer-container{position:relative;z-index:1;color:var(--mat-sidenav-content-text-color, var(--mat-sys-on-background));background-color:var(--mat-sidenav-content-background-color, var(--mat-sys-background));box-sizing:border-box;display:block;overflow:hidden}.mat-drawer-container[fullscreen]{top:0;left:0;right:0;bottom:0;position:absolute}.mat-drawer-container[fullscreen].mat-drawer-container-has-open{overflow:hidden}.mat-drawer-container.mat-drawer-container-explicit-backdrop .mat-drawer-side{z-index:3}.mat-drawer-container.ng-animate-disabled .mat-drawer-backdrop,.mat-drawer-container.ng-animate-disabled .mat-drawer-content,.ng-animate-disabled .mat-drawer-container .mat-drawer-backdrop,.ng-animate-disabled .mat-drawer-container .mat-drawer-content{transition:none}.mat-drawer-backdrop{top:0;left:0;right:0;bottom:0;position:absolute;display:block;z-index:3;visibility:hidden}.mat-drawer-backdrop.mat-drawer-shown{visibility:visible;background-color:var(--mat-sidenav-scrim-color, color-mix(in srgb, var(--mat-sys-neutral-variant20) 40%, transparent))}.mat-drawer-transition .mat-drawer-backdrop{transition-duration:400ms;transition-timing-function:cubic-bezier(0.25, 0.8, 0.25, 1);transition-property:background-color,visibility}@media(forced-colors: active){.mat-drawer-backdrop{opacity:.5}}.mat-drawer-content{position:relative;z-index:1;display:block;height:100%;overflow:auto}.mat-drawer-content.mat-drawer-content-hidden{opacity:0}.mat-drawer-transition .mat-drawer-content{transition-duration:400ms;transition-timing-function:cubic-bezier(0.25, 0.8, 0.25, 1);transition-property:transform,margin-left,margin-right}.mat-drawer{position:relative;z-index:4;color:var(--mat-sidenav-container-text-color, var(--mat-sys-on-surface-variant));box-shadow:var(--mat-sidenav-container-elevation-shadow, none);background-color:var(--mat-sidenav-container-background-color, var(--mat-sys-surface));border-top-right-radius:var(--mat-sidenav-container-shape, var(--mat-sys-corner-large));border-bottom-right-radius:var(--mat-sidenav-container-shape, var(--mat-sys-corner-large));width:var(--mat-sidenav-container-width, 360px);display:block;position:absolute;top:0;bottom:0;z-index:3;outline:0;box-sizing:border-box;overflow-y:auto;transform:translate3d(-100%, 0, 0)}@media(forced-colors: active){.mat-drawer,[dir=rtl] .mat-drawer.mat-drawer-end{border-right:solid 1px currentColor}}@media(forced-colors: active){[dir=rtl] .mat-drawer,.mat-drawer.mat-drawer-end{border-left:solid 1px currentColor;border-right:none}}.mat-drawer.mat-drawer-side{z-index:2}.mat-drawer.mat-drawer-end{right:0;transform:translate3d(100%, 0, 0);border-top-left-radius:var(--mat-sidenav-container-shape, var(--mat-sys-corner-large));border-bottom-left-radius:var(--mat-sidenav-container-shape, var(--mat-sys-corner-large));border-top-right-radius:0;border-bottom-right-radius:0}[dir=rtl] .mat-drawer{border-top-left-radius:var(--mat-sidenav-container-shape, var(--mat-sys-corner-large));border-bottom-left-radius:var(--mat-sidenav-container-shape, var(--mat-sys-corner-large));border-top-right-radius:0;border-bottom-right-radius:0;transform:translate3d(100%, 0, 0)}[dir=rtl] .mat-drawer.mat-drawer-end{border-top-right-radius:var(--mat-sidenav-container-shape, var(--mat-sys-corner-large));border-bottom-right-radius:var(--mat-sidenav-container-shape, var(--mat-sys-corner-large));border-top-left-radius:0;border-bottom-left-radius:0;left:0;right:auto;transform:translate3d(-100%, 0, 0)}.mat-drawer-transition .mat-drawer{transition:transform 400ms cubic-bezier(0.25, 0.8, 0.25, 1)}.mat-drawer:not(.mat-drawer-opened):not(.mat-drawer-animating){visibility:hidden;box-shadow:none}.mat-drawer:not(.mat-drawer-opened):not(.mat-drawer-animating) .mat-drawer-inner-container{display:none}.mat-drawer.mat-drawer-opened.mat-drawer-opened{transform:none}.mat-drawer-side{box-shadow:none;border-right-color:var(--mat-sidenav-container-divider-color, transparent);border-right-width:1px;border-right-style:solid}.mat-drawer-side.mat-drawer-end{border-left-color:var(--mat-sidenav-container-divider-color, transparent);border-left-width:1px;border-left-style:solid;border-right:none}[dir=rtl] .mat-drawer-side{border-left-color:var(--mat-sidenav-container-divider-color, transparent);border-left-width:1px;border-left-style:solid;border-right:none}[dir=rtl] .mat-drawer-side.mat-drawer-end{border-right-color:var(--mat-sidenav-container-divider-color, transparent);border-right-width:1px;border-right-style:solid;border-left:none}.mat-drawer-inner-container{width:100%;height:100%;overflow:auto}.mat-sidenav-fixed{position:fixed}\n"], dependencies: [{ kind: "component", type: MatDrawerContent, selector: "mat-drawer-content" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
  869. }
  870. i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: MatDrawerContainer, decorators: [{
  871. type: Component,
  872. args: [{ selector: 'mat-drawer-container', exportAs: 'matDrawerContainer', host: {
  873. 'class': 'mat-drawer-container',
  874. '[class.mat-drawer-container-explicit-backdrop]': '_backdropOverride',
  875. }, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, providers: [
  876. {
  877. provide: MAT_DRAWER_CONTAINER,
  878. useExisting: MatDrawerContainer,
  879. },
  880. ], imports: [MatDrawerContent], template: "@if (hasBackdrop) {\n <div class=\"mat-drawer-backdrop\" (click)=\"_onBackdropClicked()\"\n [class.mat-drawer-shown]=\"_isShowingBackdrop()\"></div>\n}\n\n<ng-content select=\"mat-drawer\"></ng-content>\n\n<ng-content select=\"mat-drawer-content\">\n</ng-content>\n\n@if (!_content) {\n <mat-drawer-content>\n <ng-content></ng-content>\n </mat-drawer-content>\n}\n", styles: [".mat-drawer-container{position:relative;z-index:1;color:var(--mat-sidenav-content-text-color, var(--mat-sys-on-background));background-color:var(--mat-sidenav-content-background-color, var(--mat-sys-background));box-sizing:border-box;display:block;overflow:hidden}.mat-drawer-container[fullscreen]{top:0;left:0;right:0;bottom:0;position:absolute}.mat-drawer-container[fullscreen].mat-drawer-container-has-open{overflow:hidden}.mat-drawer-container.mat-drawer-container-explicit-backdrop .mat-drawer-side{z-index:3}.mat-drawer-container.ng-animate-disabled .mat-drawer-backdrop,.mat-drawer-container.ng-animate-disabled .mat-drawer-content,.ng-animate-disabled .mat-drawer-container .mat-drawer-backdrop,.ng-animate-disabled .mat-drawer-container .mat-drawer-content{transition:none}.mat-drawer-backdrop{top:0;left:0;right:0;bottom:0;position:absolute;display:block;z-index:3;visibility:hidden}.mat-drawer-backdrop.mat-drawer-shown{visibility:visible;background-color:var(--mat-sidenav-scrim-color, color-mix(in srgb, var(--mat-sys-neutral-variant20) 40%, transparent))}.mat-drawer-transition .mat-drawer-backdrop{transition-duration:400ms;transition-timing-function:cubic-bezier(0.25, 0.8, 0.25, 1);transition-property:background-color,visibility}@media(forced-colors: active){.mat-drawer-backdrop{opacity:.5}}.mat-drawer-content{position:relative;z-index:1;display:block;height:100%;overflow:auto}.mat-drawer-content.mat-drawer-content-hidden{opacity:0}.mat-drawer-transition .mat-drawer-content{transition-duration:400ms;transition-timing-function:cubic-bezier(0.25, 0.8, 0.25, 1);transition-property:transform,margin-left,margin-right}.mat-drawer{position:relative;z-index:4;color:var(--mat-sidenav-container-text-color, var(--mat-sys-on-surface-variant));box-shadow:var(--mat-sidenav-container-elevation-shadow, none);background-color:var(--mat-sidenav-container-background-color, var(--mat-sys-surface));border-top-right-radius:var(--mat-sidenav-container-shape, var(--mat-sys-corner-large));border-bottom-right-radius:var(--mat-sidenav-container-shape, var(--mat-sys-corner-large));width:var(--mat-sidenav-container-width, 360px);display:block;position:absolute;top:0;bottom:0;z-index:3;outline:0;box-sizing:border-box;overflow-y:auto;transform:translate3d(-100%, 0, 0)}@media(forced-colors: active){.mat-drawer,[dir=rtl] .mat-drawer.mat-drawer-end{border-right:solid 1px currentColor}}@media(forced-colors: active){[dir=rtl] .mat-drawer,.mat-drawer.mat-drawer-end{border-left:solid 1px currentColor;border-right:none}}.mat-drawer.mat-drawer-side{z-index:2}.mat-drawer.mat-drawer-end{right:0;transform:translate3d(100%, 0, 0);border-top-left-radius:var(--mat-sidenav-container-shape, var(--mat-sys-corner-large));border-bottom-left-radius:var(--mat-sidenav-container-shape, var(--mat-sys-corner-large));border-top-right-radius:0;border-bottom-right-radius:0}[dir=rtl] .mat-drawer{border-top-left-radius:var(--mat-sidenav-container-shape, var(--mat-sys-corner-large));border-bottom-left-radius:var(--mat-sidenav-container-shape, var(--mat-sys-corner-large));border-top-right-radius:0;border-bottom-right-radius:0;transform:translate3d(100%, 0, 0)}[dir=rtl] .mat-drawer.mat-drawer-end{border-top-right-radius:var(--mat-sidenav-container-shape, var(--mat-sys-corner-large));border-bottom-right-radius:var(--mat-sidenav-container-shape, var(--mat-sys-corner-large));border-top-left-radius:0;border-bottom-left-radius:0;left:0;right:auto;transform:translate3d(-100%, 0, 0)}.mat-drawer-transition .mat-drawer{transition:transform 400ms cubic-bezier(0.25, 0.8, 0.25, 1)}.mat-drawer:not(.mat-drawer-opened):not(.mat-drawer-animating){visibility:hidden;box-shadow:none}.mat-drawer:not(.mat-drawer-opened):not(.mat-drawer-animating) .mat-drawer-inner-container{display:none}.mat-drawer.mat-drawer-opened.mat-drawer-opened{transform:none}.mat-drawer-side{box-shadow:none;border-right-color:var(--mat-sidenav-container-divider-color, transparent);border-right-width:1px;border-right-style:solid}.mat-drawer-side.mat-drawer-end{border-left-color:var(--mat-sidenav-container-divider-color, transparent);border-left-width:1px;border-left-style:solid;border-right:none}[dir=rtl] .mat-drawer-side{border-left-color:var(--mat-sidenav-container-divider-color, transparent);border-left-width:1px;border-left-style:solid;border-right:none}[dir=rtl] .mat-drawer-side.mat-drawer-end{border-right-color:var(--mat-sidenav-container-divider-color, transparent);border-right-width:1px;border-right-style:solid;border-left:none}.mat-drawer-inner-container{width:100%;height:100%;overflow:auto}.mat-sidenav-fixed{position:fixed}\n"] }]
  881. }], ctorParameters: () => [], propDecorators: { _allDrawers: [{
  882. type: ContentChildren,
  883. args: [MatDrawer, {
  884. // We need to use `descendants: true`, because Ivy will no longer match
  885. // indirect descendants if it's left as false.
  886. descendants: true,
  887. }]
  888. }], _content: [{
  889. type: ContentChild,
  890. args: [MatDrawerContent]
  891. }], _userContent: [{
  892. type: ViewChild,
  893. args: [MatDrawerContent]
  894. }], autosize: [{
  895. type: Input
  896. }], hasBackdrop: [{
  897. type: Input
  898. }], backdropClick: [{
  899. type: Output
  900. }] } });
  901. class MatSidenavContent extends MatDrawerContent {
  902. static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: MatSidenavContent, deps: null, target: i0.ɵɵFactoryTarget.Component });
  903. static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.6", type: MatSidenavContent, isStandalone: true, selector: "mat-sidenav-content", host: { classAttribute: "mat-drawer-content mat-sidenav-content" }, providers: [
  904. {
  905. provide: CdkScrollable,
  906. useExisting: MatSidenavContent,
  907. },
  908. ], usesInheritance: true, ngImport: i0, template: '<ng-content></ng-content>', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
  909. }
  910. i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: MatSidenavContent, decorators: [{
  911. type: Component,
  912. args: [{
  913. selector: 'mat-sidenav-content',
  914. template: '<ng-content></ng-content>',
  915. host: {
  916. 'class': 'mat-drawer-content mat-sidenav-content',
  917. },
  918. changeDetection: ChangeDetectionStrategy.OnPush,
  919. encapsulation: ViewEncapsulation.None,
  920. providers: [
  921. {
  922. provide: CdkScrollable,
  923. useExisting: MatSidenavContent,
  924. },
  925. ],
  926. }]
  927. }] });
  928. class MatSidenav extends MatDrawer {
  929. /** Whether the sidenav is fixed in the viewport. */
  930. get fixedInViewport() {
  931. return this._fixedInViewport;
  932. }
  933. set fixedInViewport(value) {
  934. this._fixedInViewport = coerceBooleanProperty(value);
  935. }
  936. _fixedInViewport = false;
  937. /**
  938. * The gap between the top of the sidenav and the top of the viewport when the sidenav is in fixed
  939. * mode.
  940. */
  941. get fixedTopGap() {
  942. return this._fixedTopGap;
  943. }
  944. set fixedTopGap(value) {
  945. this._fixedTopGap = coerceNumberProperty(value);
  946. }
  947. _fixedTopGap = 0;
  948. /**
  949. * The gap between the bottom of the sidenav and the bottom of the viewport when the sidenav is in
  950. * fixed mode.
  951. */
  952. get fixedBottomGap() {
  953. return this._fixedBottomGap;
  954. }
  955. set fixedBottomGap(value) {
  956. this._fixedBottomGap = coerceNumberProperty(value);
  957. }
  958. _fixedBottomGap = 0;
  959. static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: MatSidenav, deps: null, target: i0.ɵɵFactoryTarget.Component });
  960. static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.6", type: MatSidenav, isStandalone: true, selector: "mat-sidenav", inputs: { fixedInViewport: "fixedInViewport", fixedTopGap: "fixedTopGap", fixedBottomGap: "fixedBottomGap" }, host: { properties: { "attr.tabIndex": "(mode !== \"side\") ? \"-1\" : null", "attr.align": "null", "class.mat-drawer-end": "position === \"end\"", "class.mat-drawer-over": "mode === \"over\"", "class.mat-drawer-push": "mode === \"push\"", "class.mat-drawer-side": "mode === \"side\"", "class.mat-sidenav-fixed": "fixedInViewport", "style.top.px": "fixedInViewport ? fixedTopGap : null", "style.bottom.px": "fixedInViewport ? fixedBottomGap : null" }, classAttribute: "mat-drawer mat-sidenav" }, providers: [{ provide: MatDrawer, useExisting: MatSidenav }], exportAs: ["matSidenav"], usesInheritance: true, ngImport: i0, template: "<div class=\"mat-drawer-inner-container\" cdkScrollable #content>\r\n <ng-content></ng-content>\r\n</div>\r\n", dependencies: [{ kind: "directive", type: CdkScrollable, selector: "[cdk-scrollable], [cdkScrollable]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
  961. }
  962. i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: MatSidenav, decorators: [{
  963. type: Component,
  964. args: [{ selector: 'mat-sidenav', exportAs: 'matSidenav', host: {
  965. 'class': 'mat-drawer mat-sidenav',
  966. // The sidenav container should not be focused on when used in side mode. See b/286459024 for
  967. // reference. Updates tabIndex of drawer/container to default to null if in side mode.
  968. '[attr.tabIndex]': '(mode !== "side") ? "-1" : null',
  969. // must prevent the browser from aligning text based on value
  970. '[attr.align]': 'null',
  971. '[class.mat-drawer-end]': 'position === "end"',
  972. '[class.mat-drawer-over]': 'mode === "over"',
  973. '[class.mat-drawer-push]': 'mode === "push"',
  974. '[class.mat-drawer-side]': 'mode === "side"',
  975. '[class.mat-sidenav-fixed]': 'fixedInViewport',
  976. '[style.top.px]': 'fixedInViewport ? fixedTopGap : null',
  977. '[style.bottom.px]': 'fixedInViewport ? fixedBottomGap : null',
  978. }, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [CdkScrollable], providers: [{ provide: MatDrawer, useExisting: MatSidenav }], template: "<div class=\"mat-drawer-inner-container\" cdkScrollable #content>\r\n <ng-content></ng-content>\r\n</div>\r\n" }]
  979. }], propDecorators: { fixedInViewport: [{
  980. type: Input
  981. }], fixedTopGap: [{
  982. type: Input
  983. }], fixedBottomGap: [{
  984. type: Input
  985. }] } });
  986. class MatSidenavContainer extends MatDrawerContainer {
  987. _allDrawers = undefined;
  988. // We need an initializer here to avoid a TS error.
  989. _content = undefined;
  990. static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: MatSidenavContainer, deps: null, target: i0.ɵɵFactoryTarget.Component });
  991. static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.6", type: MatSidenavContainer, isStandalone: true, selector: "mat-sidenav-container", host: { properties: { "class.mat-drawer-container-explicit-backdrop": "_backdropOverride" }, classAttribute: "mat-drawer-container mat-sidenav-container" }, providers: [
  992. {
  993. provide: MAT_DRAWER_CONTAINER,
  994. useExisting: MatSidenavContainer,
  995. },
  996. {
  997. provide: MatDrawerContainer,
  998. useExisting: MatSidenavContainer,
  999. },
  1000. ], queries: [{ propertyName: "_content", first: true, predicate: MatSidenavContent, descendants: true }, { propertyName: "_allDrawers", predicate: MatSidenav, descendants: true }], exportAs: ["matSidenavContainer"], usesInheritance: true, ngImport: i0, template: "@if (hasBackdrop) {\n <div class=\"mat-drawer-backdrop\" (click)=\"_onBackdropClicked()\"\n [class.mat-drawer-shown]=\"_isShowingBackdrop()\"></div>\n}\n\n<ng-content select=\"mat-sidenav\"></ng-content>\n\n<ng-content select=\"mat-sidenav-content\">\n</ng-content>\n\n@if (!_content) {\n <mat-sidenav-content>\n <ng-content></ng-content>\n </mat-sidenav-content>\n}\n", styles: [".mat-drawer-container{position:relative;z-index:1;color:var(--mat-sidenav-content-text-color, var(--mat-sys-on-background));background-color:var(--mat-sidenav-content-background-color, var(--mat-sys-background));box-sizing:border-box;display:block;overflow:hidden}.mat-drawer-container[fullscreen]{top:0;left:0;right:0;bottom:0;position:absolute}.mat-drawer-container[fullscreen].mat-drawer-container-has-open{overflow:hidden}.mat-drawer-container.mat-drawer-container-explicit-backdrop .mat-drawer-side{z-index:3}.mat-drawer-container.ng-animate-disabled .mat-drawer-backdrop,.mat-drawer-container.ng-animate-disabled .mat-drawer-content,.ng-animate-disabled .mat-drawer-container .mat-drawer-backdrop,.ng-animate-disabled .mat-drawer-container .mat-drawer-content{transition:none}.mat-drawer-backdrop{top:0;left:0;right:0;bottom:0;position:absolute;display:block;z-index:3;visibility:hidden}.mat-drawer-backdrop.mat-drawer-shown{visibility:visible;background-color:var(--mat-sidenav-scrim-color, color-mix(in srgb, var(--mat-sys-neutral-variant20) 40%, transparent))}.mat-drawer-transition .mat-drawer-backdrop{transition-duration:400ms;transition-timing-function:cubic-bezier(0.25, 0.8, 0.25, 1);transition-property:background-color,visibility}@media(forced-colors: active){.mat-drawer-backdrop{opacity:.5}}.mat-drawer-content{position:relative;z-index:1;display:block;height:100%;overflow:auto}.mat-drawer-content.mat-drawer-content-hidden{opacity:0}.mat-drawer-transition .mat-drawer-content{transition-duration:400ms;transition-timing-function:cubic-bezier(0.25, 0.8, 0.25, 1);transition-property:transform,margin-left,margin-right}.mat-drawer{position:relative;z-index:4;color:var(--mat-sidenav-container-text-color, var(--mat-sys-on-surface-variant));box-shadow:var(--mat-sidenav-container-elevation-shadow, none);background-color:var(--mat-sidenav-container-background-color, var(--mat-sys-surface));border-top-right-radius:var(--mat-sidenav-container-shape, var(--mat-sys-corner-large));border-bottom-right-radius:var(--mat-sidenav-container-shape, var(--mat-sys-corner-large));width:var(--mat-sidenav-container-width, 360px);display:block;position:absolute;top:0;bottom:0;z-index:3;outline:0;box-sizing:border-box;overflow-y:auto;transform:translate3d(-100%, 0, 0)}@media(forced-colors: active){.mat-drawer,[dir=rtl] .mat-drawer.mat-drawer-end{border-right:solid 1px currentColor}}@media(forced-colors: active){[dir=rtl] .mat-drawer,.mat-drawer.mat-drawer-end{border-left:solid 1px currentColor;border-right:none}}.mat-drawer.mat-drawer-side{z-index:2}.mat-drawer.mat-drawer-end{right:0;transform:translate3d(100%, 0, 0);border-top-left-radius:var(--mat-sidenav-container-shape, var(--mat-sys-corner-large));border-bottom-left-radius:var(--mat-sidenav-container-shape, var(--mat-sys-corner-large));border-top-right-radius:0;border-bottom-right-radius:0}[dir=rtl] .mat-drawer{border-top-left-radius:var(--mat-sidenav-container-shape, var(--mat-sys-corner-large));border-bottom-left-radius:var(--mat-sidenav-container-shape, var(--mat-sys-corner-large));border-top-right-radius:0;border-bottom-right-radius:0;transform:translate3d(100%, 0, 0)}[dir=rtl] .mat-drawer.mat-drawer-end{border-top-right-radius:var(--mat-sidenav-container-shape, var(--mat-sys-corner-large));border-bottom-right-radius:var(--mat-sidenav-container-shape, var(--mat-sys-corner-large));border-top-left-radius:0;border-bottom-left-radius:0;left:0;right:auto;transform:translate3d(-100%, 0, 0)}.mat-drawer-transition .mat-drawer{transition:transform 400ms cubic-bezier(0.25, 0.8, 0.25, 1)}.mat-drawer:not(.mat-drawer-opened):not(.mat-drawer-animating){visibility:hidden;box-shadow:none}.mat-drawer:not(.mat-drawer-opened):not(.mat-drawer-animating) .mat-drawer-inner-container{display:none}.mat-drawer.mat-drawer-opened.mat-drawer-opened{transform:none}.mat-drawer-side{box-shadow:none;border-right-color:var(--mat-sidenav-container-divider-color, transparent);border-right-width:1px;border-right-style:solid}.mat-drawer-side.mat-drawer-end{border-left-color:var(--mat-sidenav-container-divider-color, transparent);border-left-width:1px;border-left-style:solid;border-right:none}[dir=rtl] .mat-drawer-side{border-left-color:var(--mat-sidenav-container-divider-color, transparent);border-left-width:1px;border-left-style:solid;border-right:none}[dir=rtl] .mat-drawer-side.mat-drawer-end{border-right-color:var(--mat-sidenav-container-divider-color, transparent);border-right-width:1px;border-right-style:solid;border-left:none}.mat-drawer-inner-container{width:100%;height:100%;overflow:auto}.mat-sidenav-fixed{position:fixed}\n"], dependencies: [{ kind: "component", type: MatSidenavContent, selector: "mat-sidenav-content" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
  1001. }
  1002. i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: MatSidenavContainer, decorators: [{
  1003. type: Component,
  1004. args: [{ selector: 'mat-sidenav-container', exportAs: 'matSidenavContainer', host: {
  1005. 'class': 'mat-drawer-container mat-sidenav-container',
  1006. '[class.mat-drawer-container-explicit-backdrop]': '_backdropOverride',
  1007. }, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, providers: [
  1008. {
  1009. provide: MAT_DRAWER_CONTAINER,
  1010. useExisting: MatSidenavContainer,
  1011. },
  1012. {
  1013. provide: MatDrawerContainer,
  1014. useExisting: MatSidenavContainer,
  1015. },
  1016. ], imports: [MatSidenavContent], template: "@if (hasBackdrop) {\n <div class=\"mat-drawer-backdrop\" (click)=\"_onBackdropClicked()\"\n [class.mat-drawer-shown]=\"_isShowingBackdrop()\"></div>\n}\n\n<ng-content select=\"mat-sidenav\"></ng-content>\n\n<ng-content select=\"mat-sidenav-content\">\n</ng-content>\n\n@if (!_content) {\n <mat-sidenav-content>\n <ng-content></ng-content>\n </mat-sidenav-content>\n}\n", styles: [".mat-drawer-container{position:relative;z-index:1;color:var(--mat-sidenav-content-text-color, var(--mat-sys-on-background));background-color:var(--mat-sidenav-content-background-color, var(--mat-sys-background));box-sizing:border-box;display:block;overflow:hidden}.mat-drawer-container[fullscreen]{top:0;left:0;right:0;bottom:0;position:absolute}.mat-drawer-container[fullscreen].mat-drawer-container-has-open{overflow:hidden}.mat-drawer-container.mat-drawer-container-explicit-backdrop .mat-drawer-side{z-index:3}.mat-drawer-container.ng-animate-disabled .mat-drawer-backdrop,.mat-drawer-container.ng-animate-disabled .mat-drawer-content,.ng-animate-disabled .mat-drawer-container .mat-drawer-backdrop,.ng-animate-disabled .mat-drawer-container .mat-drawer-content{transition:none}.mat-drawer-backdrop{top:0;left:0;right:0;bottom:0;position:absolute;display:block;z-index:3;visibility:hidden}.mat-drawer-backdrop.mat-drawer-shown{visibility:visible;background-color:var(--mat-sidenav-scrim-color, color-mix(in srgb, var(--mat-sys-neutral-variant20) 40%, transparent))}.mat-drawer-transition .mat-drawer-backdrop{transition-duration:400ms;transition-timing-function:cubic-bezier(0.25, 0.8, 0.25, 1);transition-property:background-color,visibility}@media(forced-colors: active){.mat-drawer-backdrop{opacity:.5}}.mat-drawer-content{position:relative;z-index:1;display:block;height:100%;overflow:auto}.mat-drawer-content.mat-drawer-content-hidden{opacity:0}.mat-drawer-transition .mat-drawer-content{transition-duration:400ms;transition-timing-function:cubic-bezier(0.25, 0.8, 0.25, 1);transition-property:transform,margin-left,margin-right}.mat-drawer{position:relative;z-index:4;color:var(--mat-sidenav-container-text-color, var(--mat-sys-on-surface-variant));box-shadow:var(--mat-sidenav-container-elevation-shadow, none);background-color:var(--mat-sidenav-container-background-color, var(--mat-sys-surface));border-top-right-radius:var(--mat-sidenav-container-shape, var(--mat-sys-corner-large));border-bottom-right-radius:var(--mat-sidenav-container-shape, var(--mat-sys-corner-large));width:var(--mat-sidenav-container-width, 360px);display:block;position:absolute;top:0;bottom:0;z-index:3;outline:0;box-sizing:border-box;overflow-y:auto;transform:translate3d(-100%, 0, 0)}@media(forced-colors: active){.mat-drawer,[dir=rtl] .mat-drawer.mat-drawer-end{border-right:solid 1px currentColor}}@media(forced-colors: active){[dir=rtl] .mat-drawer,.mat-drawer.mat-drawer-end{border-left:solid 1px currentColor;border-right:none}}.mat-drawer.mat-drawer-side{z-index:2}.mat-drawer.mat-drawer-end{right:0;transform:translate3d(100%, 0, 0);border-top-left-radius:var(--mat-sidenav-container-shape, var(--mat-sys-corner-large));border-bottom-left-radius:var(--mat-sidenav-container-shape, var(--mat-sys-corner-large));border-top-right-radius:0;border-bottom-right-radius:0}[dir=rtl] .mat-drawer{border-top-left-radius:var(--mat-sidenav-container-shape, var(--mat-sys-corner-large));border-bottom-left-radius:var(--mat-sidenav-container-shape, var(--mat-sys-corner-large));border-top-right-radius:0;border-bottom-right-radius:0;transform:translate3d(100%, 0, 0)}[dir=rtl] .mat-drawer.mat-drawer-end{border-top-right-radius:var(--mat-sidenav-container-shape, var(--mat-sys-corner-large));border-bottom-right-radius:var(--mat-sidenav-container-shape, var(--mat-sys-corner-large));border-top-left-radius:0;border-bottom-left-radius:0;left:0;right:auto;transform:translate3d(-100%, 0, 0)}.mat-drawer-transition .mat-drawer{transition:transform 400ms cubic-bezier(0.25, 0.8, 0.25, 1)}.mat-drawer:not(.mat-drawer-opened):not(.mat-drawer-animating){visibility:hidden;box-shadow:none}.mat-drawer:not(.mat-drawer-opened):not(.mat-drawer-animating) .mat-drawer-inner-container{display:none}.mat-drawer.mat-drawer-opened.mat-drawer-opened{transform:none}.mat-drawer-side{box-shadow:none;border-right-color:var(--mat-sidenav-container-divider-color, transparent);border-right-width:1px;border-right-style:solid}.mat-drawer-side.mat-drawer-end{border-left-color:var(--mat-sidenav-container-divider-color, transparent);border-left-width:1px;border-left-style:solid;border-right:none}[dir=rtl] .mat-drawer-side{border-left-color:var(--mat-sidenav-container-divider-color, transparent);border-left-width:1px;border-left-style:solid;border-right:none}[dir=rtl] .mat-drawer-side.mat-drawer-end{border-right-color:var(--mat-sidenav-container-divider-color, transparent);border-right-width:1px;border-right-style:solid;border-left:none}.mat-drawer-inner-container{width:100%;height:100%;overflow:auto}.mat-sidenav-fixed{position:fixed}\n"] }]
  1017. }], propDecorators: { _allDrawers: [{
  1018. type: ContentChildren,
  1019. args: [MatSidenav, {
  1020. // We need to use `descendants: true`, because Ivy will no longer match
  1021. // indirect descendants if it's left as false.
  1022. descendants: true,
  1023. }]
  1024. }], _content: [{
  1025. type: ContentChild,
  1026. args: [MatSidenavContent]
  1027. }] } });
  1028. class MatSidenavModule {
  1029. static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: MatSidenavModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
  1030. static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.6", ngImport: i0, type: MatSidenavModule, imports: [MatCommonModule,
  1031. CdkScrollableModule,
  1032. MatDrawer,
  1033. MatDrawerContainer,
  1034. MatDrawerContent,
  1035. MatSidenav,
  1036. MatSidenavContainer,
  1037. MatSidenavContent], exports: [CdkScrollableModule,
  1038. MatCommonModule,
  1039. MatDrawer,
  1040. MatDrawerContainer,
  1041. MatDrawerContent,
  1042. MatSidenav,
  1043. MatSidenavContainer,
  1044. MatSidenavContent] });
  1045. static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: MatSidenavModule, imports: [MatCommonModule,
  1046. CdkScrollableModule, CdkScrollableModule,
  1047. MatCommonModule] });
  1048. }
  1049. i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: MatSidenavModule, decorators: [{
  1050. type: NgModule,
  1051. args: [{
  1052. imports: [
  1053. MatCommonModule,
  1054. CdkScrollableModule,
  1055. MatDrawer,
  1056. MatDrawerContainer,
  1057. MatDrawerContent,
  1058. MatSidenav,
  1059. MatSidenavContainer,
  1060. MatSidenavContent,
  1061. ],
  1062. exports: [
  1063. CdkScrollableModule,
  1064. MatCommonModule,
  1065. MatDrawer,
  1066. MatDrawerContainer,
  1067. MatDrawerContent,
  1068. MatSidenav,
  1069. MatSidenavContainer,
  1070. MatSidenavContent,
  1071. ],
  1072. }]
  1073. }] });
  1074. /**
  1075. * Animations used by the Material drawers.
  1076. * @docs-private
  1077. * @deprecated No longer used, will be removed.
  1078. * @breaking-change 21.0.0
  1079. */
  1080. const matDrawerAnimations = {
  1081. // Represents
  1082. // trigger('transform', [
  1083. // // We remove the `transform` here completely, rather than setting it to zero, because:
  1084. // // 1. Having a transform can cause elements with ripples or an animated
  1085. // // transform to shift around in Chrome with an RTL layout (see #10023).
  1086. // // 2. 3d transforms causes text to appear blurry on IE and Edge.
  1087. // state(
  1088. // 'open, open-instant',
  1089. // style({
  1090. // 'transform': 'none',
  1091. // 'visibility': 'visible',
  1092. // }),
  1093. // ),
  1094. // state(
  1095. // 'void',
  1096. // style({
  1097. // // Avoids the shadow showing up when closed in SSR.
  1098. // 'box-shadow': 'none',
  1099. // 'visibility': 'hidden',
  1100. // }),
  1101. // ),
  1102. // transition('void => open-instant', animate('0ms')),
  1103. // transition(
  1104. // 'void <=> open, open-instant => void',
  1105. // animate('400ms cubic-bezier(0.25, 0.8, 0.25, 1)'),
  1106. // ),
  1107. // ])
  1108. /** Animation that slides a drawer in and out. */
  1109. transformDrawer: {
  1110. type: 7,
  1111. name: 'transform',
  1112. definitions: [
  1113. {
  1114. type: 0,
  1115. name: 'open, open-instant',
  1116. styles: {
  1117. type: 6,
  1118. styles: { transform: 'none', visibility: 'visible' },
  1119. offset: null,
  1120. },
  1121. },
  1122. {
  1123. type: 0,
  1124. name: 'void',
  1125. styles: {
  1126. type: 6,
  1127. styles: { 'box-shadow': 'none', visibility: 'hidden' },
  1128. offset: null,
  1129. },
  1130. },
  1131. {
  1132. type: 1,
  1133. expr: 'void => open-instant',
  1134. animation: { type: 4, styles: null, timings: '0ms' },
  1135. options: null,
  1136. },
  1137. {
  1138. type: 1,
  1139. expr: 'void <=> open, open-instant => void',
  1140. animation: {
  1141. type: 4,
  1142. styles: null,
  1143. timings: '400ms cubic-bezier(0.25, 0.8, 0.25, 1)',
  1144. },
  1145. options: null,
  1146. },
  1147. ],
  1148. options: {},
  1149. },
  1150. };
  1151. export { MAT_DRAWER_DEFAULT_AUTOSIZE, MAT_DRAWER_DEFAULT_AUTOSIZE_FACTORY, MatDrawer, MatDrawerContainer, MatDrawerContent, MatSidenav, MatSidenavContainer, MatSidenavContent, MatSidenavModule, matDrawerAnimations, throwMatDuplicatedDrawerError };
  1152. //# sourceMappingURL=sidenav.mjs.map