legacy-chips.mjs 68 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399
  1. import { SPACE, BACKSPACE, DELETE, TAB, hasModifierKey, ENTER } from '@angular/cdk/keycodes';
  2. import * as i0 from '@angular/core';
  3. import { InjectionToken, Directive, EventEmitter, Optional, Inject, Attribute, ContentChild, Input, Output, Component, ViewEncapsulation, ChangeDetectionStrategy, Self, ContentChildren, NgModule } from '@angular/core';
  4. import * as i3 from '@angular/material/core';
  5. import { mixinTabIndex, mixinColor, mixinDisableRipple, RippleRenderer, MAT_RIPPLE_GLOBAL_OPTIONS, mixinErrorState, MatCommonModule, ErrorStateMatcher } from '@angular/material/core';
  6. import { coerceBooleanProperty } from '@angular/cdk/coercion';
  7. import * as i1 from '@angular/cdk/platform';
  8. import { DOCUMENT } from '@angular/common';
  9. import { ANIMATION_MODULE_TYPE } from '@angular/platform-browser/animations';
  10. import { Subject, merge } from 'rxjs';
  11. import { take, takeUntil, startWith } from 'rxjs/operators';
  12. import { FocusKeyManager } from '@angular/cdk/a11y';
  13. import * as i1$1 from '@angular/cdk/bidi';
  14. import { SelectionModel } from '@angular/cdk/collections';
  15. import * as i2 from '@angular/forms';
  16. import { Validators } from '@angular/forms';
  17. import { MatLegacyFormFieldControl } from '@angular/material/legacy-form-field';
  18. /**
  19. * Event object emitted by MatChip when selected or deselected.
  20. * @deprecated Use `MatChipSelectionChange` from `@angular/material/chips` instead. See https://material.angular.io/guide/mdc-migration for information about migrating.
  21. * @breaking-change 17.0.0
  22. */
  23. class MatLegacyChipSelectionChange {
  24. constructor(
  25. /** Reference to the chip that emitted the event. */
  26. source,
  27. /** Whether the chip that emitted the event is selected. */
  28. selected,
  29. /** Whether the selection change was a result of a user interaction. */
  30. isUserInput = false) {
  31. this.source = source;
  32. this.selected = selected;
  33. this.isUserInput = isUserInput;
  34. }
  35. }
  36. /**
  37. * Injection token that can be used to reference instances of `MatChipRemove`. It serves as
  38. * alternative token to the actual `MatChipRemove` class which could cause unnecessary
  39. * retention of the class and its directive metadata.
  40. * @deprecated Use `MAT_CHIP_REMOVE` from `@angular/material/chips` instead. See https://material.angular.io/guide/mdc-migration for information about migrating.
  41. * @breaking-change 17.0.0
  42. */
  43. const MAT_LEGACY_CHIP_REMOVE = new InjectionToken('MatChipRemove');
  44. /**
  45. * Injection token that can be used to reference instances of `MatChipAvatar`. It serves as
  46. * alternative token to the actual `MatChipAvatar` class which could cause unnecessary
  47. * retention of the class and its directive metadata.
  48. * @deprecated Use `MAT_CHIP_AVATAR` from `@angular/material/chips` instead. See https://material.angular.io/guide/mdc-migration for information about migrating.
  49. * @breaking-change 17.0.0
  50. */
  51. const MAT_LEGACY_CHIP_AVATAR = new InjectionToken('MatChipAvatar');
  52. /**
  53. * Injection token that can be used to reference instances of `MatChipTrailingIcon`. It serves as
  54. * alternative token to the actual `MatChipTrailingIcon` class which could cause unnecessary
  55. * retention of the class and its directive metadata.
  56. * @deprecated Use `MAT_CHIP_TRAILING_ICON` from `@angular/material/chips` instead. See https://material.angular.io/guide/mdc-migration for information about migrating.
  57. * @breaking-change 17.0.0
  58. */
  59. const MAT_LEGACY_CHIP_TRAILING_ICON = new InjectionToken('MatChipTrailingIcon');
  60. // Boilerplate for applying mixins to MatChip.
  61. /** @docs-private */
  62. class MatChipBase {
  63. constructor(_elementRef) {
  64. this._elementRef = _elementRef;
  65. }
  66. }
  67. const _MatChipMixinBase = mixinTabIndex(mixinColor(mixinDisableRipple(MatChipBase), 'primary'), -1);
  68. /**
  69. * Dummy directive to add CSS class to chip avatar.
  70. * @docs-private
  71. * @deprecated Use `MatChipAvatar` from `@angular/material/chips` instead. See https://material.angular.io/guide/mdc-migration for information about migrating.
  72. * @breaking-change 17.0.0
  73. */
  74. class MatLegacyChipAvatar {
  75. static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: MatLegacyChipAvatar, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
  76. static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.0", type: MatLegacyChipAvatar, selector: "mat-chip-avatar, [matChipAvatar]", host: { classAttribute: "mat-chip-avatar" }, providers: [{ provide: MAT_LEGACY_CHIP_AVATAR, useExisting: MatLegacyChipAvatar }], ngImport: i0 }); }
  77. }
  78. i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: MatLegacyChipAvatar, decorators: [{
  79. type: Directive,
  80. args: [{
  81. selector: 'mat-chip-avatar, [matChipAvatar]',
  82. host: { 'class': 'mat-chip-avatar' },
  83. providers: [{ provide: MAT_LEGACY_CHIP_AVATAR, useExisting: MatLegacyChipAvatar }],
  84. }]
  85. }] });
  86. /**
  87. * Dummy directive to add CSS class to chip trailing icon.
  88. * @docs-private
  89. * @deprecated Use `MatChipTrailingIcon` from `@angular/material/chips` instead. See https://material.angular.io/guide/mdc-migration for information about migrating.
  90. * @breaking-change 17.0.0
  91. */
  92. class MatLegacyChipTrailingIcon {
  93. static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: MatLegacyChipTrailingIcon, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
  94. static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.0", type: MatLegacyChipTrailingIcon, selector: "mat-chip-trailing-icon, [matChipTrailingIcon]", host: { classAttribute: "mat-chip-trailing-icon" }, providers: [{ provide: MAT_LEGACY_CHIP_TRAILING_ICON, useExisting: MatLegacyChipTrailingIcon }], ngImport: i0 }); }
  95. }
  96. i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: MatLegacyChipTrailingIcon, decorators: [{
  97. type: Directive,
  98. args: [{
  99. selector: 'mat-chip-trailing-icon, [matChipTrailingIcon]',
  100. host: { 'class': 'mat-chip-trailing-icon' },
  101. providers: [{ provide: MAT_LEGACY_CHIP_TRAILING_ICON, useExisting: MatLegacyChipTrailingIcon }],
  102. }]
  103. }] });
  104. /**
  105. * Material Design styled chip directive. Used inside the MatChipList component.
  106. * @deprecated Use `MatChip` from `@angular/material/chips` instead. See https://material.angular.io/guide/mdc-migration for information about migrating.
  107. * @breaking-change 17.0.0
  108. */
  109. class MatLegacyChip extends _MatChipMixinBase {
  110. /**
  111. * Whether ripples are disabled on interaction
  112. * @docs-private
  113. */
  114. get rippleDisabled() {
  115. return (this.disabled ||
  116. this.disableRipple ||
  117. this._animationsDisabled ||
  118. !!this.rippleConfig.disabled);
  119. }
  120. /** Whether the chip is selected. */
  121. get selected() {
  122. return this._selected;
  123. }
  124. set selected(value) {
  125. const coercedValue = coerceBooleanProperty(value);
  126. if (coercedValue !== this._selected) {
  127. this._selected = coercedValue;
  128. this._dispatchSelectionChange();
  129. }
  130. }
  131. /** The value of the chip. Defaults to the content inside `<mat-chip>` tags. */
  132. get value() {
  133. return this._value !== undefined ? this._value : this._elementRef.nativeElement.textContent;
  134. }
  135. set value(value) {
  136. this._value = value;
  137. }
  138. /**
  139. * Whether or not the chip is selectable. When a chip is not selectable,
  140. * changes to its selected state are always ignored. By default a chip is
  141. * selectable, and it becomes non-selectable if its parent chip list is
  142. * not selectable.
  143. */
  144. get selectable() {
  145. return this._selectable && this.chipListSelectable;
  146. }
  147. set selectable(value) {
  148. this._selectable = coerceBooleanProperty(value);
  149. }
  150. /** Whether the chip is disabled. */
  151. get disabled() {
  152. return this._chipListDisabled || this._disabled;
  153. }
  154. set disabled(value) {
  155. this._disabled = coerceBooleanProperty(value);
  156. }
  157. /**
  158. * Determines whether or not the chip displays the remove styling and emits (removed) events.
  159. */
  160. get removable() {
  161. return this._removable;
  162. }
  163. set removable(value) {
  164. this._removable = coerceBooleanProperty(value);
  165. }
  166. /** The ARIA selected applied to the chip. */
  167. get ariaSelected() {
  168. // Remove the `aria-selected` when the chip is deselected in single-selection mode, because
  169. // it adds noise to NVDA users where "not selected" will be read out for each chip.
  170. return this.selectable && (this._chipListMultiple || this.selected)
  171. ? this.selected.toString()
  172. : null;
  173. }
  174. constructor(elementRef, _ngZone, platform, globalRippleOptions, _changeDetectorRef, _document, animationMode, tabIndex) {
  175. super(elementRef);
  176. this._ngZone = _ngZone;
  177. this._changeDetectorRef = _changeDetectorRef;
  178. /** Whether the chip has focus. */
  179. this._hasFocus = false;
  180. /** Whether the chip list is selectable */
  181. this.chipListSelectable = true;
  182. /** Whether the chip list is in multi-selection mode. */
  183. this._chipListMultiple = false;
  184. /** Whether the chip list as a whole is disabled. */
  185. this._chipListDisabled = false;
  186. /** ARIA role that should be applied to the chip. */
  187. this.role = 'option';
  188. this._selected = false;
  189. this._selectable = true;
  190. this._disabled = false;
  191. this._removable = true;
  192. /** Emits when the chip is focused. */
  193. this._onFocus = new Subject();
  194. /** Emits when the chip is blurred. */
  195. this._onBlur = new Subject();
  196. /** Emitted when the chip is selected or deselected. */
  197. this.selectionChange = new EventEmitter();
  198. /** Emitted when the chip is destroyed. */
  199. this.destroyed = new EventEmitter();
  200. /** Emitted when a chip is to be removed. */
  201. this.removed = new EventEmitter();
  202. this._addHostClassName();
  203. // Dynamically create the ripple target, append it within the chip, and use it as the
  204. // chip's ripple target. Adding the class '.mat-chip-ripple' ensures that it will have
  205. // the proper styles.
  206. this._chipRippleTarget = _document.createElement('div');
  207. this._chipRippleTarget.classList.add('mat-chip-ripple');
  208. this._elementRef.nativeElement.appendChild(this._chipRippleTarget);
  209. this._chipRipple = new RippleRenderer(this, _ngZone, this._chipRippleTarget, platform);
  210. this._chipRipple.setupTriggerEvents(elementRef);
  211. this.rippleConfig = globalRippleOptions || {};
  212. this._animationsDisabled = animationMode === 'NoopAnimations';
  213. this.tabIndex = tabIndex != null ? parseInt(tabIndex) || -1 : -1;
  214. }
  215. _addHostClassName() {
  216. const basicChipAttrName = 'mat-basic-chip';
  217. const element = this._elementRef.nativeElement;
  218. if (element.hasAttribute(basicChipAttrName) ||
  219. element.tagName.toLowerCase() === basicChipAttrName) {
  220. element.classList.add(basicChipAttrName);
  221. return;
  222. }
  223. else {
  224. element.classList.add('mat-standard-chip');
  225. }
  226. }
  227. ngOnDestroy() {
  228. this.destroyed.emit({ chip: this });
  229. this._chipRipple._removeTriggerEvents();
  230. }
  231. /** Selects the chip. */
  232. select() {
  233. if (!this._selected) {
  234. this._selected = true;
  235. this._dispatchSelectionChange();
  236. this._changeDetectorRef.markForCheck();
  237. }
  238. }
  239. /** Deselects the chip. */
  240. deselect() {
  241. if (this._selected) {
  242. this._selected = false;
  243. this._dispatchSelectionChange();
  244. this._changeDetectorRef.markForCheck();
  245. }
  246. }
  247. /** Select this chip and emit selected event */
  248. selectViaInteraction() {
  249. if (!this._selected) {
  250. this._selected = true;
  251. this._dispatchSelectionChange(true);
  252. this._changeDetectorRef.markForCheck();
  253. }
  254. }
  255. /** Toggles the current selected state of this chip. */
  256. toggleSelected(isUserInput = false) {
  257. this._selected = !this.selected;
  258. this._dispatchSelectionChange(isUserInput);
  259. this._changeDetectorRef.markForCheck();
  260. return this.selected;
  261. }
  262. /** Allows for programmatic focusing of the chip. */
  263. focus() {
  264. if (!this._hasFocus) {
  265. this._elementRef.nativeElement.focus();
  266. this._onFocus.next({ chip: this });
  267. }
  268. this._hasFocus = true;
  269. }
  270. /**
  271. * Allows for programmatic removal of the chip. Called by the MatChipList when the DELETE or
  272. * BACKSPACE keys are pressed.
  273. *
  274. * Informs any listeners of the removal request. Does not remove the chip from the DOM.
  275. */
  276. remove() {
  277. if (this.removable) {
  278. this.removed.emit({ chip: this });
  279. }
  280. }
  281. /** Handles click events on the chip. */
  282. _handleClick(event) {
  283. if (this.disabled) {
  284. event.preventDefault();
  285. }
  286. }
  287. /** Handle custom key presses. */
  288. _handleKeydown(event) {
  289. if (this.disabled) {
  290. return;
  291. }
  292. switch (event.keyCode) {
  293. case DELETE:
  294. case BACKSPACE:
  295. // If we are removable, remove the focused chip
  296. this.remove();
  297. // Always prevent so page navigation does not occur
  298. event.preventDefault();
  299. break;
  300. case SPACE:
  301. // If we are selectable, toggle the focused chip
  302. if (this.selectable) {
  303. this.toggleSelected(true);
  304. }
  305. // Always prevent space from scrolling the page since the list has focus
  306. event.preventDefault();
  307. break;
  308. }
  309. }
  310. _blur() {
  311. // When animations are enabled, Angular may end up removing the chip from the DOM a little
  312. // earlier than usual, causing it to be blurred and throwing off the logic in the chip list
  313. // that moves focus not the next item. To work around the issue, we defer marking the chip
  314. // as not focused until the next time the zone stabilizes.
  315. this._ngZone.onStable.pipe(take(1)).subscribe(() => {
  316. this._ngZone.run(() => {
  317. this._hasFocus = false;
  318. this._onBlur.next({ chip: this });
  319. });
  320. });
  321. }
  322. _dispatchSelectionChange(isUserInput = false) {
  323. this.selectionChange.emit({
  324. source: this,
  325. isUserInput,
  326. selected: this._selected,
  327. });
  328. }
  329. static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: MatLegacyChip, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }, { token: i1.Platform }, { token: MAT_RIPPLE_GLOBAL_OPTIONS, optional: true }, { token: i0.ChangeDetectorRef }, { token: DOCUMENT }, { token: ANIMATION_MODULE_TYPE, optional: true }, { token: 'tabindex', attribute: true }], target: i0.ɵɵFactoryTarget.Directive }); }
  330. static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.0", type: MatLegacyChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: { color: "color", disableRipple: "disableRipple", tabIndex: "tabIndex", role: "role", selected: "selected", value: "value", selectable: "selectable", disabled: "disabled", removable: "removable" }, outputs: { selectionChange: "selectionChange", destroyed: "destroyed", removed: "removed" }, host: { listeners: { "click": "_handleClick($event)", "keydown": "_handleKeydown($event)", "focus": "focus()", "blur": "_blur()" }, properties: { "attr.tabindex": "disabled ? null : tabIndex", "attr.role": "role", "class.mat-chip-selected": "selected", "class.mat-chip-with-avatar": "avatar", "class.mat-chip-with-trailing-icon": "trailingIcon || removeIcon", "class.mat-chip-disabled": "disabled", "class._mat-animation-noopable": "_animationsDisabled", "attr.disabled": "disabled || null", "attr.aria-disabled": "disabled.toString()", "attr.aria-selected": "ariaSelected" }, classAttribute: "mat-chip mat-focus-indicator" }, queries: [{ propertyName: "avatar", first: true, predicate: MAT_LEGACY_CHIP_AVATAR, descendants: true }, { propertyName: "trailingIcon", first: true, predicate: MAT_LEGACY_CHIP_TRAILING_ICON, descendants: true }, { propertyName: "removeIcon", first: true, predicate: MAT_LEGACY_CHIP_REMOVE, descendants: true }], exportAs: ["matChip"], usesInheritance: true, ngImport: i0 }); }
  331. }
  332. i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: MatLegacyChip, decorators: [{
  333. type: Directive,
  334. args: [{
  335. selector: `mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]`,
  336. inputs: ['color', 'disableRipple', 'tabIndex'],
  337. exportAs: 'matChip',
  338. host: {
  339. 'class': 'mat-chip mat-focus-indicator',
  340. '[attr.tabindex]': 'disabled ? null : tabIndex',
  341. '[attr.role]': 'role',
  342. '[class.mat-chip-selected]': 'selected',
  343. '[class.mat-chip-with-avatar]': 'avatar',
  344. '[class.mat-chip-with-trailing-icon]': 'trailingIcon || removeIcon',
  345. '[class.mat-chip-disabled]': 'disabled',
  346. '[class._mat-animation-noopable]': '_animationsDisabled',
  347. '[attr.disabled]': 'disabled || null',
  348. '[attr.aria-disabled]': 'disabled.toString()',
  349. '[attr.aria-selected]': 'ariaSelected',
  350. '(click)': '_handleClick($event)',
  351. '(keydown)': '_handleKeydown($event)',
  352. '(focus)': 'focus()',
  353. '(blur)': '_blur()',
  354. },
  355. }]
  356. }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.NgZone }, { type: i1.Platform }, { type: undefined, decorators: [{
  357. type: Optional
  358. }, {
  359. type: Inject,
  360. args: [MAT_RIPPLE_GLOBAL_OPTIONS]
  361. }] }, { type: i0.ChangeDetectorRef }, { type: undefined, decorators: [{
  362. type: Inject,
  363. args: [DOCUMENT]
  364. }] }, { type: undefined, decorators: [{
  365. type: Optional
  366. }, {
  367. type: Inject,
  368. args: [ANIMATION_MODULE_TYPE]
  369. }] }, { type: undefined, decorators: [{
  370. type: Attribute,
  371. args: ['tabindex']
  372. }] }]; }, propDecorators: { avatar: [{
  373. type: ContentChild,
  374. args: [MAT_LEGACY_CHIP_AVATAR]
  375. }], trailingIcon: [{
  376. type: ContentChild,
  377. args: [MAT_LEGACY_CHIP_TRAILING_ICON]
  378. }], removeIcon: [{
  379. type: ContentChild,
  380. args: [MAT_LEGACY_CHIP_REMOVE]
  381. }], role: [{
  382. type: Input
  383. }], selected: [{
  384. type: Input
  385. }], value: [{
  386. type: Input
  387. }], selectable: [{
  388. type: Input
  389. }], disabled: [{
  390. type: Input
  391. }], removable: [{
  392. type: Input
  393. }], selectionChange: [{
  394. type: Output
  395. }], destroyed: [{
  396. type: Output
  397. }], removed: [{
  398. type: Output
  399. }] } });
  400. /**
  401. * Applies proper (click) support and adds styling for use with the Material Design "cancel" icon
  402. * available at https://material.io/icons/#ic_cancel.
  403. *
  404. * Example:
  405. *
  406. * `<mat-chip>
  407. * <mat-icon matChipRemove>cancel</mat-icon>
  408. * </mat-chip>`
  409. *
  410. * You *may* use a custom icon, but you may need to override the `mat-chip-remove` positioning
  411. * styles to properly center the icon within the chip.
  412. *
  413. * @deprecated Use `MatChipRemove` from `@angular/material/chips` instead. See https://material.angular.io/guide/mdc-migration for information about migrating.
  414. * @breaking-change 17.0.0
  415. */
  416. class MatLegacyChipRemove {
  417. constructor(_parentChip, elementRef) {
  418. this._parentChip = _parentChip;
  419. if (elementRef.nativeElement.nodeName === 'BUTTON') {
  420. elementRef.nativeElement.setAttribute('type', 'button');
  421. }
  422. }
  423. /** Calls the parent chip's public `remove()` method if applicable. */
  424. _handleClick(event) {
  425. const parentChip = this._parentChip;
  426. if (parentChip.removable && !parentChip.disabled) {
  427. parentChip.remove();
  428. }
  429. // We need to stop event propagation because otherwise the event will bubble up to the
  430. // form field and cause the `onContainerClick` method to be invoked. This method would then
  431. // reset the focused chip that has been focused after chip removal. Usually the parent
  432. // the parent click listener of the `MatChip` would prevent propagation, but it can happen
  433. // that the chip is being removed before the event bubbles up.
  434. event.stopPropagation();
  435. event.preventDefault();
  436. }
  437. static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: MatLegacyChipRemove, deps: [{ token: MatLegacyChip }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
  438. static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.0", type: MatLegacyChipRemove, selector: "[matChipRemove]", host: { listeners: { "click": "_handleClick($event)" }, classAttribute: "mat-chip-remove mat-chip-trailing-icon" }, providers: [{ provide: MAT_LEGACY_CHIP_REMOVE, useExisting: MatLegacyChipRemove }], ngImport: i0 }); }
  439. }
  440. i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: MatLegacyChipRemove, decorators: [{
  441. type: Directive,
  442. args: [{
  443. selector: '[matChipRemove]',
  444. host: {
  445. 'class': 'mat-chip-remove mat-chip-trailing-icon',
  446. '(click)': '_handleClick($event)',
  447. },
  448. providers: [{ provide: MAT_LEGACY_CHIP_REMOVE, useExisting: MatLegacyChipRemove }],
  449. }]
  450. }], ctorParameters: function () { return [{ type: MatLegacyChip }, { type: i0.ElementRef }]; } });
  451. /**
  452. * Injection token to be used to override the default options for the chips module.
  453. * @deprecated Use `MAT_CHIPS_DEFAULT_OPTIONS` from `@angular/material/chips` instead. See https://material.angular.io/guide/mdc-migration for information about migrating.
  454. * @breaking-change 17.0.0
  455. */
  456. const MAT_LEGACY_CHIPS_DEFAULT_OPTIONS = new InjectionToken('mat-chips-default-options');
  457. // Boilerplate for applying mixins to MatChipList.
  458. /** @docs-private */
  459. const _MatChipListBase = mixinErrorState(class {
  460. constructor(_defaultErrorStateMatcher, _parentForm, _parentFormGroup,
  461. /**
  462. * Form control bound to the component.
  463. * Implemented as part of `MatFormFieldControl`.
  464. * @docs-private
  465. */
  466. ngControl) {
  467. this._defaultErrorStateMatcher = _defaultErrorStateMatcher;
  468. this._parentForm = _parentForm;
  469. this._parentFormGroup = _parentFormGroup;
  470. this.ngControl = ngControl;
  471. /**
  472. * Emits whenever the component state changes and should cause the parent
  473. * form-field to update. Implemented as part of `MatFormFieldControl`.
  474. * @docs-private
  475. */
  476. this.stateChanges = new Subject();
  477. }
  478. });
  479. // Increasing integer for generating unique ids for chip-list components.
  480. let nextUniqueId$1 = 0;
  481. /**
  482. * Change event object that is emitted when the chip list value has changed.
  483. * @deprecated Use `MatChipListChange` from `@angular/material/chips` instead. See https://material.angular.io/guide/mdc-migration for information about migrating.
  484. * @breaking-change 17.0.0
  485. */
  486. class MatLegacyChipListChange {
  487. constructor(
  488. /** Chip list that emitted the event. */
  489. source,
  490. /** Value of the chip list when the event was emitted. */
  491. value) {
  492. this.source = source;
  493. this.value = value;
  494. }
  495. }
  496. /**
  497. * A material design chips component (named ChipList for its similarity to the List component).
  498. * @deprecated Use `MatChipList` from `@angular/material/chips` instead. See https://material.angular.io/guide/mdc-migration for information about migrating.
  499. * @breaking-change 17.0.0
  500. */
  501. class MatLegacyChipList extends _MatChipListBase {
  502. /** The array of selected chips inside chip list. */
  503. get selected() {
  504. return this.multiple ? this._selectionModel?.selected || [] : this._selectionModel?.selected[0];
  505. }
  506. /** The ARIA role applied to the chip list. */
  507. get role() {
  508. if (this._explicitRole) {
  509. return this._explicitRole;
  510. }
  511. return this.empty ? null : 'listbox';
  512. }
  513. set role(role) {
  514. this._explicitRole = role;
  515. }
  516. /** Whether the user should be allowed to select multiple chips. */
  517. get multiple() {
  518. return this._multiple;
  519. }
  520. set multiple(value) {
  521. this._multiple = coerceBooleanProperty(value);
  522. this._syncChipsState();
  523. }
  524. /**
  525. * A function to compare the option values with the selected values. The first argument
  526. * is a value from an option. The second is a value from the selection. A boolean
  527. * should be returned.
  528. */
  529. get compareWith() {
  530. return this._compareWith;
  531. }
  532. set compareWith(fn) {
  533. this._compareWith = fn;
  534. if (this._selectionModel) {
  535. // A different comparator means the selection could change.
  536. this._initializeSelection();
  537. }
  538. }
  539. /**
  540. * Implemented as part of MatFormFieldControl.
  541. * @docs-private
  542. */
  543. get value() {
  544. return this._value;
  545. }
  546. set value(value) {
  547. this.writeValue(value);
  548. this._value = value;
  549. }
  550. /**
  551. * Implemented as part of MatFormFieldControl.
  552. * @docs-private
  553. */
  554. get id() {
  555. return this._chipInput ? this._chipInput.id : this._uid;
  556. }
  557. /**
  558. * Implemented as part of MatFormFieldControl.
  559. * @docs-private
  560. */
  561. get required() {
  562. return this._required ?? this.ngControl?.control?.hasValidator(Validators.required) ?? false;
  563. }
  564. set required(value) {
  565. this._required = coerceBooleanProperty(value);
  566. this.stateChanges.next();
  567. }
  568. /**
  569. * Implemented as part of MatFormFieldControl.
  570. * @docs-private
  571. */
  572. get placeholder() {
  573. return this._chipInput ? this._chipInput.placeholder : this._placeholder;
  574. }
  575. set placeholder(value) {
  576. this._placeholder = value;
  577. this.stateChanges.next();
  578. }
  579. /** Whether any chips or the matChipInput inside of this chip-list has focus. */
  580. get focused() {
  581. return (this._chipInput && this._chipInput.focused) || this._hasFocusedChip();
  582. }
  583. /**
  584. * Implemented as part of MatFormFieldControl.
  585. * @docs-private
  586. */
  587. get empty() {
  588. return (!this._chipInput || this._chipInput.empty) && (!this.chips || this.chips.length === 0);
  589. }
  590. /**
  591. * Implemented as part of MatFormFieldControl.
  592. * @docs-private
  593. */
  594. get shouldLabelFloat() {
  595. return !this.empty || this.focused;
  596. }
  597. /**
  598. * Implemented as part of MatFormFieldControl.
  599. * @docs-private
  600. */
  601. get disabled() {
  602. return this.ngControl ? !!this.ngControl.disabled : this._disabled;
  603. }
  604. set disabled(value) {
  605. this._disabled = coerceBooleanProperty(value);
  606. this._syncChipsState();
  607. }
  608. /**
  609. * Whether or not this chip list is selectable. When a chip list is not selectable,
  610. * the selected states for all the chips inside the chip list are always ignored.
  611. */
  612. get selectable() {
  613. return this._selectable;
  614. }
  615. set selectable(value) {
  616. this._selectable = coerceBooleanProperty(value);
  617. this._syncChipsState();
  618. }
  619. set tabIndex(value) {
  620. this._userTabIndex = value;
  621. this._tabIndex = value;
  622. }
  623. /** Combined stream of all of the child chips' selection change events. */
  624. get chipSelectionChanges() {
  625. return merge(...this.chips.map(chip => chip.selectionChange));
  626. }
  627. /** Combined stream of all of the child chips' focus change events. */
  628. get chipFocusChanges() {
  629. return merge(...this.chips.map(chip => chip._onFocus));
  630. }
  631. /** Combined stream of all of the child chips' blur change events. */
  632. get chipBlurChanges() {
  633. return merge(...this.chips.map(chip => chip._onBlur));
  634. }
  635. /** Combined stream of all of the child chips' remove change events. */
  636. get chipRemoveChanges() {
  637. return merge(...this.chips.map(chip => chip.destroyed));
  638. }
  639. constructor(_elementRef, _changeDetectorRef, _dir, _parentForm, _parentFormGroup, _defaultErrorStateMatcher, ngControl) {
  640. super(_defaultErrorStateMatcher, _parentForm, _parentFormGroup, ngControl);
  641. this._elementRef = _elementRef;
  642. this._changeDetectorRef = _changeDetectorRef;
  643. this._dir = _dir;
  644. /**
  645. * Implemented as part of MatFormFieldControl.
  646. * @docs-private
  647. */
  648. this.controlType = 'mat-chip-list';
  649. /**
  650. * When a chip is destroyed, we store the index of the destroyed chip until the chips
  651. * query list notifies about the update. This is necessary because we cannot determine an
  652. * appropriate chip that should receive focus until the array of chips updated completely.
  653. */
  654. this._lastDestroyedChipIndex = null;
  655. /** Subject that emits when the component has been destroyed. */
  656. this._destroyed = new Subject();
  657. /** Uid of the chip list */
  658. this._uid = `mat-chip-list-${nextUniqueId$1++}`;
  659. /** Tab index for the chip list. */
  660. this._tabIndex = 0;
  661. /**
  662. * User defined tab index.
  663. * When it is not null, use user defined tab index. Otherwise use _tabIndex
  664. */
  665. this._userTabIndex = null;
  666. /** Function when touched */
  667. this._onTouched = () => { };
  668. /** Function when changed */
  669. this._onChange = () => { };
  670. this._multiple = false;
  671. this._compareWith = (o1, o2) => o1 === o2;
  672. this._disabled = false;
  673. /** Orientation of the chip list. */
  674. this.ariaOrientation = 'horizontal';
  675. this._selectable = true;
  676. /** Event emitted when the selected chip list value has been changed by the user. */
  677. this.change = new EventEmitter();
  678. /**
  679. * Event that emits whenever the raw value of the chip-list changes. This is here primarily
  680. * to facilitate the two-way binding for the `value` input.
  681. * @docs-private
  682. */
  683. this.valueChange = new EventEmitter();
  684. if (this.ngControl) {
  685. this.ngControl.valueAccessor = this;
  686. }
  687. }
  688. ngAfterContentInit() {
  689. this._keyManager = new FocusKeyManager(this.chips)
  690. .withWrap()
  691. .withVerticalOrientation()
  692. .withHomeAndEnd()
  693. .withHorizontalOrientation(this._dir ? this._dir.value : 'ltr');
  694. if (this._dir) {
  695. this._dir.change
  696. .pipe(takeUntil(this._destroyed))
  697. .subscribe(dir => this._keyManager.withHorizontalOrientation(dir));
  698. }
  699. this._keyManager.tabOut.subscribe(() => this._allowFocusEscape());
  700. // When the list changes, re-subscribe
  701. this.chips.changes.pipe(startWith(null), takeUntil(this._destroyed)).subscribe(() => {
  702. if (this.disabled || !this.selectable) {
  703. // Since this happens after the content has been
  704. // checked, we need to defer it to the next tick.
  705. Promise.resolve().then(() => {
  706. this._syncChipsState();
  707. });
  708. }
  709. this._resetChips();
  710. // Reset chips selected/deselected status
  711. this._initializeSelection();
  712. // Check to see if we need to update our tab index
  713. this._updateTabIndex();
  714. // Check to see if we have a destroyed chip and need to refocus
  715. this._updateFocusForDestroyedChips();
  716. this.stateChanges.next();
  717. });
  718. }
  719. ngOnInit() {
  720. this._selectionModel = new SelectionModel(this.multiple, undefined, false);
  721. this.stateChanges.next();
  722. }
  723. ngDoCheck() {
  724. if (this.ngControl) {
  725. // We need to re-evaluate this on every change detection cycle, because there are some
  726. // error triggers that we can't subscribe to (e.g. parent form submissions). This means
  727. // that whatever logic is in here has to be super lean or we risk destroying the performance.
  728. this.updateErrorState();
  729. if (this.ngControl.disabled !== this._disabled) {
  730. this.disabled = !!this.ngControl.disabled;
  731. }
  732. }
  733. }
  734. ngOnDestroy() {
  735. this._keyManager?.destroy();
  736. this._destroyed.next();
  737. this._destroyed.complete();
  738. this.stateChanges.complete();
  739. this._dropSubscriptions();
  740. }
  741. /** Associates an HTML input element with this chip list. */
  742. registerInput(inputElement) {
  743. this._chipInput = inputElement;
  744. // We use this attribute to match the chip list to its input in test harnesses.
  745. // Set the attribute directly here to avoid "changed after checked" errors.
  746. this._elementRef.nativeElement.setAttribute('data-mat-chip-input', inputElement.id);
  747. }
  748. /**
  749. * Implemented as part of MatFormFieldControl.
  750. * @docs-private
  751. */
  752. setDescribedByIds(ids) {
  753. if (ids.length) {
  754. this._elementRef.nativeElement.setAttribute('aria-describedby', ids.join(' '));
  755. }
  756. else {
  757. this._elementRef.nativeElement.removeAttribute('aria-describedby');
  758. }
  759. }
  760. // Implemented as part of ControlValueAccessor.
  761. writeValue(value) {
  762. if (this.chips) {
  763. this._setSelectionByValue(value, false);
  764. }
  765. }
  766. // Implemented as part of ControlValueAccessor.
  767. registerOnChange(fn) {
  768. this._onChange = fn;
  769. }
  770. // Implemented as part of ControlValueAccessor.
  771. registerOnTouched(fn) {
  772. this._onTouched = fn;
  773. }
  774. // Implemented as part of ControlValueAccessor.
  775. setDisabledState(isDisabled) {
  776. this.disabled = isDisabled;
  777. this.stateChanges.next();
  778. }
  779. /**
  780. * Implemented as part of MatFormFieldControl.
  781. * @docs-private
  782. */
  783. onContainerClick(event) {
  784. if (!this._originatesFromChip(event)) {
  785. this.focus();
  786. }
  787. }
  788. /**
  789. * Focuses the first non-disabled chip in this chip list, or the associated input when there
  790. * are no eligible chips.
  791. */
  792. focus(options) {
  793. if (this.disabled) {
  794. return;
  795. }
  796. // TODO: ARIA says this should focus the first `selected` chip if any are selected.
  797. // Focus on first element if there's no chipInput inside chip-list
  798. if (this._chipInput && this._chipInput.focused) {
  799. // do nothing
  800. }
  801. else if (this.chips.length > 0) {
  802. this._keyManager.setFirstItemActive();
  803. this.stateChanges.next();
  804. }
  805. else {
  806. this._focusInput(options);
  807. this.stateChanges.next();
  808. }
  809. }
  810. /** Attempt to focus an input if we have one. */
  811. _focusInput(options) {
  812. if (this._chipInput) {
  813. this._chipInput.focus(options);
  814. }
  815. }
  816. /**
  817. * Pass events to the keyboard manager. Available here for tests.
  818. */
  819. _keydown(event) {
  820. const target = event.target;
  821. if (target && target.classList.contains('mat-chip')) {
  822. this._keyManager.onKeydown(event);
  823. this.stateChanges.next();
  824. }
  825. }
  826. /**
  827. * Check the tab index as you should not be allowed to focus an empty list.
  828. */
  829. _updateTabIndex() {
  830. // If we have 0 chips, we should not allow keyboard focus
  831. this._tabIndex = this._userTabIndex || (this.chips.length === 0 ? -1 : 0);
  832. }
  833. /**
  834. * If the amount of chips changed, we need to update the
  835. * key manager state and focus the next closest chip.
  836. */
  837. _updateFocusForDestroyedChips() {
  838. // Move focus to the closest chip. If no other chips remain, focus the chip-list itself.
  839. if (this._lastDestroyedChipIndex != null) {
  840. if (this.chips.length) {
  841. const newChipIndex = Math.min(this._lastDestroyedChipIndex, this.chips.length - 1);
  842. this._keyManager.setActiveItem(newChipIndex);
  843. }
  844. else {
  845. this.focus();
  846. }
  847. }
  848. this._lastDestroyedChipIndex = null;
  849. }
  850. /**
  851. * Utility to ensure all indexes are valid.
  852. *
  853. * @param index The index to be checked.
  854. * @returns True if the index is valid for our list of chips.
  855. */
  856. _isValidIndex(index) {
  857. return index >= 0 && index < this.chips.length;
  858. }
  859. _setSelectionByValue(value, isUserInput = true) {
  860. this._clearSelection();
  861. this.chips.forEach(chip => chip.deselect());
  862. if (Array.isArray(value)) {
  863. value.forEach(currentValue => this._selectValue(currentValue, isUserInput));
  864. this._sortValues();
  865. }
  866. else {
  867. const correspondingChip = this._selectValue(value, isUserInput);
  868. // Shift focus to the active item. Note that we shouldn't do this in multiple
  869. // mode, because we don't know what chip the user interacted with last.
  870. if (correspondingChip) {
  871. if (isUserInput) {
  872. this._keyManager.setActiveItem(correspondingChip);
  873. }
  874. }
  875. }
  876. }
  877. /**
  878. * Finds and selects the chip based on its value.
  879. * @returns Chip that has the corresponding value.
  880. */
  881. _selectValue(value, isUserInput = true) {
  882. const correspondingChip = this.chips.find(chip => {
  883. return chip.value != null && this._compareWith(chip.value, value);
  884. });
  885. if (correspondingChip) {
  886. isUserInput ? correspondingChip.selectViaInteraction() : correspondingChip.select();
  887. this._selectionModel.select(correspondingChip);
  888. }
  889. return correspondingChip;
  890. }
  891. _initializeSelection() {
  892. // Defer setting the value in order to avoid the "Expression
  893. // has changed after it was checked" errors from Angular.
  894. Promise.resolve().then(() => {
  895. if (this.ngControl || this._value) {
  896. this._setSelectionByValue(this.ngControl ? this.ngControl.value : this._value, false);
  897. this.stateChanges.next();
  898. }
  899. });
  900. }
  901. /**
  902. * Deselects every chip in the list.
  903. * @param skip Chip that should not be deselected.
  904. */
  905. _clearSelection(skip) {
  906. this._selectionModel.clear();
  907. this.chips.forEach(chip => {
  908. if (chip !== skip) {
  909. chip.deselect();
  910. }
  911. });
  912. this.stateChanges.next();
  913. }
  914. /**
  915. * Sorts the model values, ensuring that they keep the same
  916. * order that they have in the panel.
  917. */
  918. _sortValues() {
  919. if (this._multiple) {
  920. this._selectionModel.clear();
  921. this.chips.forEach(chip => {
  922. if (chip.selected) {
  923. this._selectionModel.select(chip);
  924. }
  925. });
  926. this.stateChanges.next();
  927. }
  928. }
  929. /** Emits change event to set the model value. */
  930. _propagateChanges(fallbackValue) {
  931. let valueToEmit = null;
  932. if (Array.isArray(this.selected)) {
  933. valueToEmit = this.selected.map(chip => chip.value);
  934. }
  935. else {
  936. valueToEmit = this.selected ? this.selected.value : fallbackValue;
  937. }
  938. this._value = valueToEmit;
  939. this.change.emit(new MatLegacyChipListChange(this, valueToEmit));
  940. this.valueChange.emit(valueToEmit);
  941. this._onChange(valueToEmit);
  942. this._changeDetectorRef.markForCheck();
  943. }
  944. /** When blurred, mark the field as touched when focus moved outside the chip list. */
  945. _blur() {
  946. if (!this._hasFocusedChip()) {
  947. this._keyManager.setActiveItem(-1);
  948. }
  949. if (!this.disabled) {
  950. if (this._chipInput) {
  951. // If there's a chip input, we should check whether the focus moved to chip input.
  952. // If the focus is not moved to chip input, mark the field as touched. If the focus moved
  953. // to chip input, do nothing.
  954. // Timeout is needed to wait for the focus() event trigger on chip input.
  955. setTimeout(() => {
  956. if (!this.focused) {
  957. this._markAsTouched();
  958. }
  959. });
  960. }
  961. else {
  962. // If there's no chip input, then mark the field as touched.
  963. this._markAsTouched();
  964. }
  965. }
  966. }
  967. /** Mark the field as touched */
  968. _markAsTouched() {
  969. this._onTouched();
  970. this._changeDetectorRef.markForCheck();
  971. this.stateChanges.next();
  972. }
  973. /**
  974. * Removes the `tabindex` from the chip list and resets it back afterwards, allowing the
  975. * user to tab out of it. This prevents the list from capturing focus and redirecting
  976. * it back to the first chip, creating a focus trap, if it user tries to tab away.
  977. */
  978. _allowFocusEscape() {
  979. if (this._tabIndex !== -1) {
  980. this._tabIndex = -1;
  981. setTimeout(() => {
  982. this._tabIndex = this._userTabIndex || 0;
  983. this._changeDetectorRef.markForCheck();
  984. });
  985. }
  986. }
  987. _resetChips() {
  988. this._dropSubscriptions();
  989. this._listenToChipsFocus();
  990. this._listenToChipsSelection();
  991. this._listenToChipsRemoved();
  992. }
  993. _dropSubscriptions() {
  994. if (this._chipFocusSubscription) {
  995. this._chipFocusSubscription.unsubscribe();
  996. this._chipFocusSubscription = null;
  997. }
  998. if (this._chipBlurSubscription) {
  999. this._chipBlurSubscription.unsubscribe();
  1000. this._chipBlurSubscription = null;
  1001. }
  1002. if (this._chipSelectionSubscription) {
  1003. this._chipSelectionSubscription.unsubscribe();
  1004. this._chipSelectionSubscription = null;
  1005. }
  1006. if (this._chipRemoveSubscription) {
  1007. this._chipRemoveSubscription.unsubscribe();
  1008. this._chipRemoveSubscription = null;
  1009. }
  1010. }
  1011. /** Listens to user-generated selection events on each chip. */
  1012. _listenToChipsSelection() {
  1013. this._chipSelectionSubscription = this.chipSelectionChanges.subscribe(event => {
  1014. event.source.selected
  1015. ? this._selectionModel.select(event.source)
  1016. : this._selectionModel.deselect(event.source);
  1017. // For single selection chip list, make sure the deselected value is unselected.
  1018. if (!this.multiple) {
  1019. this.chips.forEach(chip => {
  1020. if (!this._selectionModel.isSelected(chip) && chip.selected) {
  1021. chip.deselect();
  1022. }
  1023. });
  1024. }
  1025. if (event.isUserInput) {
  1026. this._propagateChanges();
  1027. }
  1028. });
  1029. }
  1030. /** Listens to user-generated selection events on each chip. */
  1031. _listenToChipsFocus() {
  1032. this._chipFocusSubscription = this.chipFocusChanges.subscribe(event => {
  1033. let chipIndex = this.chips.toArray().indexOf(event.chip);
  1034. if (this._isValidIndex(chipIndex)) {
  1035. this._keyManager.updateActiveItem(chipIndex);
  1036. }
  1037. this.stateChanges.next();
  1038. });
  1039. this._chipBlurSubscription = this.chipBlurChanges.subscribe(() => {
  1040. this._blur();
  1041. this.stateChanges.next();
  1042. });
  1043. }
  1044. _listenToChipsRemoved() {
  1045. this._chipRemoveSubscription = this.chipRemoveChanges.subscribe(event => {
  1046. const chip = event.chip;
  1047. const chipIndex = this.chips.toArray().indexOf(event.chip);
  1048. // In case the chip that will be removed is currently focused, we temporarily store
  1049. // the index in order to be able to determine an appropriate sibling chip that will
  1050. // receive focus.
  1051. if (this._isValidIndex(chipIndex) && chip._hasFocus) {
  1052. this._lastDestroyedChipIndex = chipIndex;
  1053. }
  1054. });
  1055. }
  1056. /** Checks whether an event comes from inside a chip element. */
  1057. _originatesFromChip(event) {
  1058. let currentElement = event.target;
  1059. while (currentElement && currentElement !== this._elementRef.nativeElement) {
  1060. if (currentElement.classList.contains('mat-chip')) {
  1061. return true;
  1062. }
  1063. currentElement = currentElement.parentElement;
  1064. }
  1065. return false;
  1066. }
  1067. /** Checks whether any of the chips is focused. */
  1068. _hasFocusedChip() {
  1069. return this.chips && this.chips.some(chip => chip._hasFocus);
  1070. }
  1071. /** Syncs the list's state with the individual chips. */
  1072. _syncChipsState() {
  1073. if (this.chips) {
  1074. this.chips.forEach(chip => {
  1075. chip._chipListDisabled = this._disabled;
  1076. chip._chipListMultiple = this.multiple;
  1077. chip.chipListSelectable = this._selectable;
  1078. });
  1079. }
  1080. }
  1081. static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: MatLegacyChipList, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: i1$1.Directionality, optional: true }, { token: i2.NgForm, optional: true }, { token: i2.FormGroupDirective, optional: true }, { token: i3.ErrorStateMatcher }, { token: i2.NgControl, optional: true, self: true }], target: i0.ɵɵFactoryTarget.Component }); }
  1082. static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.0", type: MatLegacyChipList, selector: "mat-chip-list", inputs: { role: "role", userAriaDescribedBy: ["aria-describedby", "userAriaDescribedBy"], errorStateMatcher: "errorStateMatcher", multiple: "multiple", compareWith: "compareWith", value: "value", required: "required", placeholder: "placeholder", disabled: "disabled", ariaOrientation: ["aria-orientation", "ariaOrientation"], selectable: "selectable", tabIndex: "tabIndex" }, outputs: { change: "change", valueChange: "valueChange" }, host: { attributes: { "ngSkipHydration": "" }, listeners: { "focus": "focus()", "blur": "_blur()", "keydown": "_keydown($event)" }, properties: { "attr.tabindex": "disabled ? null : _tabIndex", "attr.aria-required": "role ? required : null", "attr.aria-disabled": "disabled.toString()", "attr.aria-invalid": "errorState", "attr.aria-multiselectable": "multiple", "attr.role": "role", "class.mat-chip-list-disabled": "disabled", "class.mat-chip-list-invalid": "errorState", "class.mat-chip-list-required": "required", "attr.aria-orientation": "ariaOrientation", "id": "_uid" }, classAttribute: "mat-chip-list" }, providers: [{ provide: MatLegacyFormFieldControl, useExisting: MatLegacyChipList }], queries: [{ propertyName: "chips", predicate: MatLegacyChip, descendants: true }], exportAs: ["matChipList"], usesInheritance: true, ngImport: i0, template: `<div class="mat-chip-list-wrapper"><ng-content></ng-content></div>`, isInline: true, styles: [".mat-chip{position:relative;box-sizing:border-box;-webkit-tap-highlight-color:rgba(0,0,0,0);border:none;-webkit-appearance:none;-moz-appearance:none}.mat-chip::before{margin:calc(calc(var(--mat-focus-indicator-border-width, 3px) + 2px) * -1)}.mat-standard-chip{transition:box-shadow 280ms cubic-bezier(0.4, 0, 0.2, 1);display:inline-flex;padding:7px 12px;border-radius:16px;align-items:center;cursor:default;min-height:32px;height:1px}.mat-standard-chip._mat-animation-noopable{transition:none !important;animation:none !important}.mat-standard-chip .mat-chip-remove{border:none;-webkit-appearance:none;-moz-appearance:none;padding:0;background:none}.mat-standard-chip .mat-chip-remove.mat-icon,.mat-standard-chip .mat-chip-remove .mat-icon{width:18px;height:18px;font-size:18px}.mat-standard-chip::after{top:0;left:0;right:0;bottom:0;position:absolute;border-radius:inherit;opacity:0;content:\"\";pointer-events:none;transition:opacity 200ms cubic-bezier(0.35, 0, 0.25, 1)}.mat-standard-chip:hover::after{opacity:.12}.mat-standard-chip:focus{outline:none}.mat-standard-chip:focus::after{opacity:.16}.cdk-high-contrast-active .mat-standard-chip{outline:solid 1px}.cdk-high-contrast-active .mat-standard-chip.mat-chip-selected{outline-width:3px}.mat-standard-chip.mat-chip-disabled::after{opacity:0}.mat-standard-chip.mat-chip-disabled .mat-chip-remove,.mat-standard-chip.mat-chip-disabled .mat-chip-trailing-icon{cursor:default}.mat-standard-chip.mat-chip-with-trailing-icon.mat-chip-with-avatar,.mat-standard-chip.mat-chip-with-avatar{padding-top:0;padding-bottom:0}.mat-standard-chip.mat-chip-with-trailing-icon.mat-chip-with-avatar{padding-right:8px;padding-left:0}[dir=rtl] .mat-standard-chip.mat-chip-with-trailing-icon.mat-chip-with-avatar{padding-left:8px;padding-right:0}.mat-standard-chip.mat-chip-with-trailing-icon{padding-top:7px;padding-bottom:7px;padding-right:8px;padding-left:12px}[dir=rtl] .mat-standard-chip.mat-chip-with-trailing-icon{padding-left:8px;padding-right:12px}.mat-standard-chip.mat-chip-with-avatar{padding-left:0;padding-right:12px}[dir=rtl] .mat-standard-chip.mat-chip-with-avatar{padding-right:0;padding-left:12px}.mat-standard-chip .mat-chip-avatar{width:24px;height:24px;margin-right:8px;margin-left:4px}[dir=rtl] .mat-standard-chip .mat-chip-avatar{margin-left:8px;margin-right:4px}.mat-standard-chip .mat-chip-remove,.mat-standard-chip .mat-chip-trailing-icon{width:18px;height:18px;cursor:pointer}.mat-standard-chip .mat-chip-remove,.mat-standard-chip .mat-chip-trailing-icon{margin-left:8px;margin-right:0}[dir=rtl] .mat-standard-chip .mat-chip-remove,[dir=rtl] .mat-standard-chip .mat-chip-trailing-icon{margin-right:8px;margin-left:0}.mat-chip-ripple{top:0;left:0;right:0;bottom:0;position:absolute;pointer-events:none;border-radius:inherit;overflow:hidden;transform:translateZ(0)}.mat-chip-list-wrapper{display:flex;flex-direction:row;flex-wrap:wrap;align-items:center;margin:-4px}.mat-chip-list-wrapper input.mat-input-element,.mat-chip-list-wrapper .mat-standard-chip{margin:4px}.mat-chip-list-stacked .mat-chip-list-wrapper{flex-direction:column;align-items:flex-start}.mat-chip-list-stacked .mat-chip-list-wrapper .mat-standard-chip{width:100%}.mat-chip-avatar{border-radius:50%;justify-content:center;align-items:center;display:flex;overflow:hidden;object-fit:cover}input.mat-chip-input{width:150px;margin:4px;flex:1 0 150px}"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
  1083. }
  1084. i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: MatLegacyChipList, decorators: [{
  1085. type: Component,
  1086. args: [{ selector: 'mat-chip-list', template: `<div class="mat-chip-list-wrapper"><ng-content></ng-content></div>`, exportAs: 'matChipList', host: {
  1087. '[attr.tabindex]': 'disabled ? null : _tabIndex',
  1088. '[attr.aria-required]': 'role ? required : null',
  1089. '[attr.aria-disabled]': 'disabled.toString()',
  1090. '[attr.aria-invalid]': 'errorState',
  1091. '[attr.aria-multiselectable]': 'multiple',
  1092. '[attr.role]': 'role',
  1093. '[class.mat-chip-list-disabled]': 'disabled',
  1094. '[class.mat-chip-list-invalid]': 'errorState',
  1095. '[class.mat-chip-list-required]': 'required',
  1096. '[attr.aria-orientation]': 'ariaOrientation',
  1097. 'class': 'mat-chip-list',
  1098. '(focus)': 'focus()',
  1099. '(blur)': '_blur()',
  1100. '(keydown)': '_keydown($event)',
  1101. '[id]': '_uid',
  1102. 'ngSkipHydration': '',
  1103. }, providers: [{ provide: MatLegacyFormFieldControl, useExisting: MatLegacyChipList }], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".mat-chip{position:relative;box-sizing:border-box;-webkit-tap-highlight-color:rgba(0,0,0,0);border:none;-webkit-appearance:none;-moz-appearance:none}.mat-chip::before{margin:calc(calc(var(--mat-focus-indicator-border-width, 3px) + 2px) * -1)}.mat-standard-chip{transition:box-shadow 280ms cubic-bezier(0.4, 0, 0.2, 1);display:inline-flex;padding:7px 12px;border-radius:16px;align-items:center;cursor:default;min-height:32px;height:1px}.mat-standard-chip._mat-animation-noopable{transition:none !important;animation:none !important}.mat-standard-chip .mat-chip-remove{border:none;-webkit-appearance:none;-moz-appearance:none;padding:0;background:none}.mat-standard-chip .mat-chip-remove.mat-icon,.mat-standard-chip .mat-chip-remove .mat-icon{width:18px;height:18px;font-size:18px}.mat-standard-chip::after{top:0;left:0;right:0;bottom:0;position:absolute;border-radius:inherit;opacity:0;content:\"\";pointer-events:none;transition:opacity 200ms cubic-bezier(0.35, 0, 0.25, 1)}.mat-standard-chip:hover::after{opacity:.12}.mat-standard-chip:focus{outline:none}.mat-standard-chip:focus::after{opacity:.16}.cdk-high-contrast-active .mat-standard-chip{outline:solid 1px}.cdk-high-contrast-active .mat-standard-chip.mat-chip-selected{outline-width:3px}.mat-standard-chip.mat-chip-disabled::after{opacity:0}.mat-standard-chip.mat-chip-disabled .mat-chip-remove,.mat-standard-chip.mat-chip-disabled .mat-chip-trailing-icon{cursor:default}.mat-standard-chip.mat-chip-with-trailing-icon.mat-chip-with-avatar,.mat-standard-chip.mat-chip-with-avatar{padding-top:0;padding-bottom:0}.mat-standard-chip.mat-chip-with-trailing-icon.mat-chip-with-avatar{padding-right:8px;padding-left:0}[dir=rtl] .mat-standard-chip.mat-chip-with-trailing-icon.mat-chip-with-avatar{padding-left:8px;padding-right:0}.mat-standard-chip.mat-chip-with-trailing-icon{padding-top:7px;padding-bottom:7px;padding-right:8px;padding-left:12px}[dir=rtl] .mat-standard-chip.mat-chip-with-trailing-icon{padding-left:8px;padding-right:12px}.mat-standard-chip.mat-chip-with-avatar{padding-left:0;padding-right:12px}[dir=rtl] .mat-standard-chip.mat-chip-with-avatar{padding-right:0;padding-left:12px}.mat-standard-chip .mat-chip-avatar{width:24px;height:24px;margin-right:8px;margin-left:4px}[dir=rtl] .mat-standard-chip .mat-chip-avatar{margin-left:8px;margin-right:4px}.mat-standard-chip .mat-chip-remove,.mat-standard-chip .mat-chip-trailing-icon{width:18px;height:18px;cursor:pointer}.mat-standard-chip .mat-chip-remove,.mat-standard-chip .mat-chip-trailing-icon{margin-left:8px;margin-right:0}[dir=rtl] .mat-standard-chip .mat-chip-remove,[dir=rtl] .mat-standard-chip .mat-chip-trailing-icon{margin-right:8px;margin-left:0}.mat-chip-ripple{top:0;left:0;right:0;bottom:0;position:absolute;pointer-events:none;border-radius:inherit;overflow:hidden;transform:translateZ(0)}.mat-chip-list-wrapper{display:flex;flex-direction:row;flex-wrap:wrap;align-items:center;margin:-4px}.mat-chip-list-wrapper input.mat-input-element,.mat-chip-list-wrapper .mat-standard-chip{margin:4px}.mat-chip-list-stacked .mat-chip-list-wrapper{flex-direction:column;align-items:flex-start}.mat-chip-list-stacked .mat-chip-list-wrapper .mat-standard-chip{width:100%}.mat-chip-avatar{border-radius:50%;justify-content:center;align-items:center;display:flex;overflow:hidden;object-fit:cover}input.mat-chip-input{width:150px;margin:4px;flex:1 0 150px}"] }]
  1104. }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: i1$1.Directionality, decorators: [{
  1105. type: Optional
  1106. }] }, { type: i2.NgForm, decorators: [{
  1107. type: Optional
  1108. }] }, { type: i2.FormGroupDirective, decorators: [{
  1109. type: Optional
  1110. }] }, { type: i3.ErrorStateMatcher }, { type: i2.NgControl, decorators: [{
  1111. type: Optional
  1112. }, {
  1113. type: Self
  1114. }] }]; }, propDecorators: { role: [{
  1115. type: Input
  1116. }], userAriaDescribedBy: [{
  1117. type: Input,
  1118. args: ['aria-describedby']
  1119. }], errorStateMatcher: [{
  1120. type: Input
  1121. }], multiple: [{
  1122. type: Input
  1123. }], compareWith: [{
  1124. type: Input
  1125. }], value: [{
  1126. type: Input
  1127. }], required: [{
  1128. type: Input
  1129. }], placeholder: [{
  1130. type: Input
  1131. }], disabled: [{
  1132. type: Input
  1133. }], ariaOrientation: [{
  1134. type: Input,
  1135. args: ['aria-orientation']
  1136. }], selectable: [{
  1137. type: Input
  1138. }], tabIndex: [{
  1139. type: Input
  1140. }], change: [{
  1141. type: Output
  1142. }], valueChange: [{
  1143. type: Output
  1144. }], chips: [{
  1145. type: ContentChildren,
  1146. args: [MatLegacyChip, {
  1147. // We need to use `descendants: true`, because Ivy will no longer match
  1148. // indirect descendants if it's left as false.
  1149. descendants: true,
  1150. }]
  1151. }] } });
  1152. // Increasing integer for generating unique ids.
  1153. let nextUniqueId = 0;
  1154. /**
  1155. * Directive that adds chip-specific behaviors to an input element inside `<mat-form-field>`.
  1156. * May be placed inside or outside of an `<mat-chip-list>`.
  1157. * @deprecated Use `MatChipInput` from `@angular/material/chips` instead. See https://material.angular.io/guide/mdc-migration for information about migrating.
  1158. * @breaking-change 17.0.0
  1159. */
  1160. class MatLegacyChipInput {
  1161. /** Register input for chip list */
  1162. set chipList(value) {
  1163. if (value) {
  1164. this._chipList = value;
  1165. this._chipList.registerInput(this);
  1166. }
  1167. }
  1168. /**
  1169. * Whether or not the chipEnd event will be emitted when the input is blurred.
  1170. */
  1171. get addOnBlur() {
  1172. return this._addOnBlur;
  1173. }
  1174. set addOnBlur(value) {
  1175. this._addOnBlur = coerceBooleanProperty(value);
  1176. }
  1177. /** Whether the input is disabled. */
  1178. get disabled() {
  1179. return this._disabled || (this._chipList && this._chipList.disabled);
  1180. }
  1181. set disabled(value) {
  1182. this._disabled = coerceBooleanProperty(value);
  1183. }
  1184. /** Whether the input is empty. */
  1185. get empty() {
  1186. return !this.inputElement.value;
  1187. }
  1188. constructor(_elementRef, defaultOptions) {
  1189. this._elementRef = _elementRef;
  1190. /** Whether the control is focused. */
  1191. this.focused = false;
  1192. this._addOnBlur = false;
  1193. /** Emitted when a chip is to be added. */
  1194. this.chipEnd = new EventEmitter();
  1195. /** The input's placeholder text. */
  1196. this.placeholder = '';
  1197. /** Unique id for the input. */
  1198. this.id = `mat-chip-list-input-${nextUniqueId++}`;
  1199. this._disabled = false;
  1200. this.inputElement = this._elementRef.nativeElement;
  1201. this.separatorKeyCodes = defaultOptions.separatorKeyCodes;
  1202. }
  1203. ngOnChanges() {
  1204. this._chipList.stateChanges.next();
  1205. }
  1206. ngOnDestroy() {
  1207. this.chipEnd.complete();
  1208. }
  1209. ngAfterContentInit() {
  1210. this._focusLastChipOnBackspace = this.empty;
  1211. }
  1212. /** Utility method to make host definition/tests more clear. */
  1213. _keydown(event) {
  1214. if (event) {
  1215. // Allow the user's focus to escape when they're tabbing forward. Note that we don't
  1216. // want to do this when going backwards, because focus should go back to the first chip.
  1217. if (event.keyCode === TAB && !hasModifierKey(event, 'shiftKey')) {
  1218. this._chipList._allowFocusEscape();
  1219. }
  1220. // To prevent the user from accidentally deleting chips when pressing BACKSPACE continuously,
  1221. // We focus the last chip on backspace only after the user has released the backspace button,
  1222. // and the input is empty (see behaviour in _keyup)
  1223. if (event.keyCode === BACKSPACE && this._focusLastChipOnBackspace) {
  1224. this._chipList._keyManager.setLastItemActive();
  1225. event.preventDefault();
  1226. return;
  1227. }
  1228. else {
  1229. this._focusLastChipOnBackspace = false;
  1230. }
  1231. }
  1232. this._emitChipEnd(event);
  1233. }
  1234. /**
  1235. * Pass events to the keyboard manager. Available here for tests.
  1236. */
  1237. _keyup(event) {
  1238. // Allow user to move focus to chips next time he presses backspace
  1239. if (!this._focusLastChipOnBackspace && event.keyCode === BACKSPACE && this.empty) {
  1240. this._focusLastChipOnBackspace = true;
  1241. event.preventDefault();
  1242. }
  1243. }
  1244. /** Checks to see if the blur should emit the (chipEnd) event. */
  1245. _blur() {
  1246. if (this.addOnBlur) {
  1247. this._emitChipEnd();
  1248. }
  1249. this.focused = false;
  1250. // Blur the chip list if it is not focused
  1251. if (!this._chipList.focused) {
  1252. this._chipList._blur();
  1253. }
  1254. this._chipList.stateChanges.next();
  1255. }
  1256. _focus() {
  1257. this.focused = true;
  1258. this._focusLastChipOnBackspace = this.empty;
  1259. this._chipList.stateChanges.next();
  1260. }
  1261. /** Checks to see if the (chipEnd) event needs to be emitted. */
  1262. _emitChipEnd(event) {
  1263. if (!this.inputElement.value && !!event) {
  1264. this._chipList._keydown(event);
  1265. }
  1266. if (!event || this._isSeparatorKey(event)) {
  1267. this.chipEnd.emit({
  1268. input: this.inputElement,
  1269. value: this.inputElement.value,
  1270. chipInput: this,
  1271. });
  1272. event?.preventDefault();
  1273. }
  1274. }
  1275. _onInput() {
  1276. // Let chip list know whenever the value changes.
  1277. this._chipList.stateChanges.next();
  1278. }
  1279. /** Focuses the input. */
  1280. focus(options) {
  1281. this.inputElement.focus(options);
  1282. }
  1283. /** Clears the input */
  1284. clear() {
  1285. this.inputElement.value = '';
  1286. this._focusLastChipOnBackspace = true;
  1287. }
  1288. /** Checks whether a keycode is one of the configured separators. */
  1289. _isSeparatorKey(event) {
  1290. return !hasModifierKey(event) && new Set(this.separatorKeyCodes).has(event.keyCode);
  1291. }
  1292. static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: MatLegacyChipInput, deps: [{ token: i0.ElementRef }, { token: MAT_LEGACY_CHIPS_DEFAULT_OPTIONS }], target: i0.ɵɵFactoryTarget.Directive }); }
  1293. static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.0", type: MatLegacyChipInput, selector: "input[matChipInputFor]", inputs: { chipList: ["matChipInputFor", "chipList"], addOnBlur: ["matChipInputAddOnBlur", "addOnBlur"], separatorKeyCodes: ["matChipInputSeparatorKeyCodes", "separatorKeyCodes"], placeholder: "placeholder", id: "id", disabled: "disabled" }, outputs: { chipEnd: "matChipInputTokenEnd" }, host: { listeners: { "keydown": "_keydown($event)", "keyup": "_keyup($event)", "blur": "_blur()", "focus": "_focus()", "input": "_onInput()" }, properties: { "id": "id", "attr.disabled": "disabled || null", "attr.placeholder": "placeholder || null", "attr.aria-invalid": "_chipList && _chipList.ngControl ? _chipList.ngControl.invalid : null", "attr.aria-required": "_chipList && _chipList.required || null" }, classAttribute: "mat-chip-input mat-input-element" }, exportAs: ["matChipInput", "matChipInputFor"], usesOnChanges: true, ngImport: i0 }); }
  1294. }
  1295. i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: MatLegacyChipInput, decorators: [{
  1296. type: Directive,
  1297. args: [{
  1298. selector: 'input[matChipInputFor]',
  1299. exportAs: 'matChipInput, matChipInputFor',
  1300. host: {
  1301. 'class': 'mat-chip-input mat-input-element',
  1302. '(keydown)': '_keydown($event)',
  1303. '(keyup)': '_keyup($event)',
  1304. '(blur)': '_blur()',
  1305. '(focus)': '_focus()',
  1306. '(input)': '_onInput()',
  1307. '[id]': 'id',
  1308. '[attr.disabled]': 'disabled || null',
  1309. '[attr.placeholder]': 'placeholder || null',
  1310. '[attr.aria-invalid]': '_chipList && _chipList.ngControl ? _chipList.ngControl.invalid : null',
  1311. '[attr.aria-required]': '_chipList && _chipList.required || null',
  1312. },
  1313. }]
  1314. }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: undefined, decorators: [{
  1315. type: Inject,
  1316. args: [MAT_LEGACY_CHIPS_DEFAULT_OPTIONS]
  1317. }] }]; }, propDecorators: { chipList: [{
  1318. type: Input,
  1319. args: ['matChipInputFor']
  1320. }], addOnBlur: [{
  1321. type: Input,
  1322. args: ['matChipInputAddOnBlur']
  1323. }], separatorKeyCodes: [{
  1324. type: Input,
  1325. args: ['matChipInputSeparatorKeyCodes']
  1326. }], chipEnd: [{
  1327. type: Output,
  1328. args: ['matChipInputTokenEnd']
  1329. }], placeholder: [{
  1330. type: Input
  1331. }], id: [{
  1332. type: Input
  1333. }], disabled: [{
  1334. type: Input
  1335. }] } });
  1336. const CHIP_DECLARATIONS = [
  1337. MatLegacyChipList,
  1338. MatLegacyChip,
  1339. MatLegacyChipInput,
  1340. MatLegacyChipRemove,
  1341. MatLegacyChipAvatar,
  1342. MatLegacyChipTrailingIcon,
  1343. ];
  1344. /**
  1345. * @deprecated Use `MatChipsModule` from `@angular/material/chips` instead. See https://material.angular.io/guide/mdc-migration for information about migrating.
  1346. * @breaking-change 17.0.0
  1347. */
  1348. class MatLegacyChipsModule {
  1349. static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: MatLegacyChipsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
  1350. static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.0.0", ngImport: i0, type: MatLegacyChipsModule, declarations: [MatLegacyChipList,
  1351. MatLegacyChip,
  1352. MatLegacyChipInput,
  1353. MatLegacyChipRemove,
  1354. MatLegacyChipAvatar,
  1355. MatLegacyChipTrailingIcon], imports: [MatCommonModule], exports: [MatLegacyChipList,
  1356. MatLegacyChip,
  1357. MatLegacyChipInput,
  1358. MatLegacyChipRemove,
  1359. MatLegacyChipAvatar,
  1360. MatLegacyChipTrailingIcon] }); }
  1361. static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: MatLegacyChipsModule, providers: [
  1362. ErrorStateMatcher,
  1363. {
  1364. provide: MAT_LEGACY_CHIPS_DEFAULT_OPTIONS,
  1365. useValue: {
  1366. separatorKeyCodes: [ENTER],
  1367. },
  1368. },
  1369. ], imports: [MatCommonModule] }); }
  1370. }
  1371. i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: MatLegacyChipsModule, decorators: [{
  1372. type: NgModule,
  1373. args: [{
  1374. imports: [MatCommonModule],
  1375. exports: CHIP_DECLARATIONS,
  1376. declarations: CHIP_DECLARATIONS,
  1377. providers: [
  1378. ErrorStateMatcher,
  1379. {
  1380. provide: MAT_LEGACY_CHIPS_DEFAULT_OPTIONS,
  1381. useValue: {
  1382. separatorKeyCodes: [ENTER],
  1383. },
  1384. },
  1385. ],
  1386. }]
  1387. }] });
  1388. /**
  1389. * Generated bundle index. Do not edit.
  1390. */
  1391. export { MAT_LEGACY_CHIPS_DEFAULT_OPTIONS, MAT_LEGACY_CHIP_AVATAR, MAT_LEGACY_CHIP_REMOVE, MAT_LEGACY_CHIP_TRAILING_ICON, MatLegacyChip, MatLegacyChipAvatar, MatLegacyChipInput, MatLegacyChipList, MatLegacyChipListChange, MatLegacyChipRemove, MatLegacyChipSelectionChange, MatLegacyChipTrailingIcon, MatLegacyChipsModule };
  1392. //# sourceMappingURL=legacy-chips.mjs.map