@fundamental-ngx/cdk 0.61.2-rc.4 → 0.61.2-rc.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { INJECTOR, ElementRef, isDevMode, InjectionToken, EventEmitter, inject, NgZone, DestroyRef, Input, Output, Directive, NgModule, Injectable, signal, DOCUMENT, Optional, Inject, booleanAttribute, output, Renderer2, PLATFORM_ID, input, effect, Self, SkipSelf, computed, ChangeDetectorRef, ContentChildren, forwardRef, HostListener, HostBinding, linkedSignal, Injector, model, contentChildren, runInInjectionContext, untracked, ContentChild, QueryList, ViewContainerRef, TemplateRef, ViewChild, Component, NgModuleFactory, Pipe } from '@angular/core';
2
+ import { INJECTOR, ElementRef, isDevMode, InjectionToken, EventEmitter, inject, NgZone, DestroyRef, Input, Output, Directive, NgModule, Injectable, signal, DOCUMENT, Optional, Inject, booleanAttribute, output, Renderer2, PLATFORM_ID, input, effect, Self, SkipSelf, computed, ChangeDetectorRef, ContentChildren, forwardRef, HostListener, HostBinding, linkedSignal, Injector, model, contentChildren, runInInjectionContext, untracked, ContentChild, QueryList, numberAttribute, ViewContainerRef, TemplateRef, ViewChild, Component, NgModuleFactory, Pipe } from '@angular/core';
3
3
  import { RIGHT_ARROW, DOWN_ARROW, LEFT_ARROW, UP_ARROW, SPACE, ESCAPE, DELETE, ENTER, MAC_ENTER, TAB, HOME, END, ALT, CONTROL, META, SHIFT, BACKSPACE, A, C, V, X, PAGE_UP, PAGE_DOWN, DASH, NUMPAD_MINUS, NUMPAD_ZERO, NUMPAD_ONE, NUMPAD_TWO, NUMPAD_THREE, NUMPAD_FOUR, NUMPAD_FIVE, NUMPAD_SIX, NUMPAD_SEVEN, NUMPAD_EIGHT, NUMPAD_NINE, F2, F7, hasModifierKey } from '@angular/cdk/keycodes';
4
4
  import { takeUntilDestroyed, outputToObservable } from '@angular/core/rxjs-interop';
5
5
  import { Observable, NEVER, fromEvent, switchMap, map as map$1, Subject, BehaviorSubject, merge as merge$1, combineLatest, ReplaySubject, firstValueFrom, startWith as startWith$1, Subscription, isObservable, of, tap as tap$1, filter as filter$1, take as take$1 } from 'rxjs';
@@ -2522,22 +2522,28 @@ class FocusableItemDirective {
2522
2522
  }
2523
2523
  /** @hidden */
2524
2524
  enableTabbableElements() {
2525
- if (this._tabbableElements.size === 0) {
2525
+ const size = this._tabbableElements.size;
2526
+ if (size === 0) {
2526
2527
  return;
2527
2528
  }
2528
- this._tabbableElements.forEach((tabIndex, element) => (element.tabIndex = tabIndex));
2529
+ for (const [element, tabIndex] of this._tabbableElements) {
2530
+ element.tabIndex = tabIndex;
2531
+ }
2529
2532
  this._tabbable = false;
2530
2533
  }
2531
2534
  /** @hidden */
2532
2535
  disableTabbableElements() {
2533
2536
  // Since we cannot select by tabindex attribute (links, inputs, buttons might not have one but still can be focusable),
2534
2537
  // Select all elements from the cell and filter by tabIndex property.
2535
- Array.from(this.elementRef.nativeElement.querySelectorAll('*'))
2536
- .filter((elm) => elm.tabIndex >= 0)
2537
- .forEach((elm) => {
2538
- this._tabbableElements.set(elm, elm.tabIndex);
2539
- elm.tabIndex = -1;
2540
- });
2538
+ const allElements = this.elementRef.nativeElement.querySelectorAll('*');
2539
+ const length = allElements.length;
2540
+ for (let i = 0; i < length; i++) {
2541
+ const elm = allElements[i];
2542
+ if (elm.tabIndex >= 0) {
2543
+ this._tabbableElements.set(elm, elm.tabIndex);
2544
+ elm.tabIndex = -1;
2545
+ }
2546
+ }
2541
2547
  }
2542
2548
  /** @hidden */
2543
2549
  async _onFocusin() {
@@ -2553,10 +2559,11 @@ class FocusableItemDirective {
2553
2559
  }
2554
2560
  }
2555
2561
  const activeEl = this._document.activeElement;
2556
- if (activeEl === this.elementRef.nativeElement) {
2562
+ const nativeElement = this.elementRef.nativeElement;
2563
+ if (activeEl === nativeElement) {
2557
2564
  this._parentFocusableItemFocused.emit();
2558
2565
  }
2559
- else if (activeEl && activeEl !== this.elementRef.nativeElement && this._checker.isFocusable(activeEl)) {
2566
+ else if (activeEl && this._checker.isFocusable(activeEl)) {
2560
2567
  this.focusableChildElementFocused.emit();
2561
2568
  }
2562
2569
  }
@@ -2890,13 +2897,14 @@ class FocusableListDirective {
2890
2897
  return;
2891
2898
  }
2892
2899
  const items = this._focusableItems();
2893
- items.forEach((item, index) => {
2894
- item._position = {
2900
+ const totalCols = items.length;
2901
+ for (let index = 0; index < totalCols; index++) {
2902
+ items[index]._position = {
2895
2903
  ...gridPosition,
2896
2904
  colIndex: index,
2897
- totalCols: items.length
2905
+ totalCols
2898
2906
  };
2899
- });
2907
+ }
2900
2908
  });
2901
2909
  }
2902
2910
  /** @hidden */
@@ -2986,7 +2994,11 @@ class FocusableListDirective {
2986
2994
  }
2987
2995
  /** @hidden */
2988
2996
  _setItemsTabbable(state) {
2989
- this._focusableItems().forEach((item) => item.setTabbable(state));
2997
+ const items = this._focusableItems();
2998
+ const length = items.length;
2999
+ for (let i = 0; i < length; i++) {
3000
+ items[i].setTabbable(state);
3001
+ }
2990
3002
  }
2991
3003
  /** @hidden */
2992
3004
  _setGridPosition(position) {
@@ -3006,29 +3018,44 @@ class FocusableListDirective {
3006
3018
  }
3007
3019
  keyManager.skipPredicate((i) => !isItemFocusable(i));
3008
3020
  this._keyManager = keyManager;
3009
- const focusListenerDestroyers = items.map((item, index) => this._renderer.listen(getItemElement(item), 'focus', () => {
3010
- const directiveItem = this._focusableItems()[index];
3011
- if (!directiveItem) {
3012
- return;
3013
- }
3014
- const gridPosition = this._gridPosition();
3015
- if (gridPosition) {
3016
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
3017
- this._gridItemFocused$.next(directiveItem._position);
3018
- }
3019
- const id = getItemElement(item)?.id ?? null;
3020
- this.itemFocused.emit({ index, total: items.length, id });
3021
- this._focusableItems().forEach((i) => i.setTabbable(i === directiveItem));
3022
- this._keyManager?.setActiveItem(index);
3023
- }));
3024
- merge$1(...items.map((item) => item.keydown))
3021
+ const itemsLength = items.length;
3022
+ const focusListenerDestroyers = new Array(itemsLength);
3023
+ const keydownObservables = new Array(itemsLength);
3024
+ for (let index = 0; index < itemsLength; index++) {
3025
+ const item = items[index];
3026
+ keydownObservables[index] = item.keydown;
3027
+ focusListenerDestroyers[index] = this._renderer.listen(getItemElement(item), 'focus', () => {
3028
+ const directiveItem = this._focusableItems()[index];
3029
+ if (!directiveItem) {
3030
+ return;
3031
+ }
3032
+ const gridPosition = this._gridPosition();
3033
+ if (gridPosition) {
3034
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
3035
+ this._gridItemFocused$.next(directiveItem._position);
3036
+ }
3037
+ const id = getItemElement(item)?.id ?? null;
3038
+ this.itemFocused.emit({ index, total: itemsLength, id });
3039
+ const focusableItems = this._focusableItems();
3040
+ const focusableItemsLength = focusableItems.length;
3041
+ for (let i = 0; i < focusableItemsLength; i++) {
3042
+ focusableItems[i].setTabbable(focusableItems[i] === directiveItem);
3043
+ }
3044
+ this._keyManager?.setActiveItem(index);
3045
+ });
3046
+ }
3047
+ merge$1(...keydownObservables)
3025
3048
  .pipe(tap((event) => {
3026
3049
  // Already handled
3027
3050
  if (event.defaultPrevented) {
3028
3051
  return;
3029
3052
  }
3030
3053
  this._keyManager?.onKeydown(event);
3031
- }), takeUntil(merge$1(this._refreshItems$, destroyObservable(this._destroyRef))), finalize(() => focusListenerDestroyers.forEach((d) => d())))
3054
+ }), takeUntil(merge$1(this._refreshItems$, destroyObservable(this._destroyRef))), finalize(() => {
3055
+ for (let i = 0; i < focusListenerDestroyers.length; i++) {
3056
+ focusListenerDestroyers[i]();
3057
+ }
3058
+ }))
3032
3059
  .subscribe();
3033
3060
  }
3034
3061
  /** @hidden */
@@ -3135,10 +3162,15 @@ class FocusableGridDirective {
3135
3162
  this._focusableLists.changes
3136
3163
  .pipe(startWith$1(this._focusableLists), takeUntilDestroyed(this._destroyRef))
3137
3164
  .subscribe((lists) => {
3138
- lists.forEach((list, index) => {
3139
- list._setGridPosition({ rowIndex: index, totalRows: this._focusableLists.length });
3140
- this._watchListItems(list);
3141
- });
3165
+ const totalRows = this._focusableLists.length;
3166
+ const listsLength = lists.length;
3167
+ for (let i = 0; i < listsLength; i++) {
3168
+ const list = lists.get(i);
3169
+ if (list) {
3170
+ list._setGridPosition({ rowIndex: i, totalRows });
3171
+ this._watchListItems(list);
3172
+ }
3173
+ }
3142
3174
  });
3143
3175
  this._focusableItems.changes
3144
3176
  .pipe(startWith$1(this._focusableItems), takeUntilDestroyed(this._destroyRef))
@@ -3146,21 +3178,40 @@ class FocusableGridDirective {
3146
3178
  this._handleItemSubscriptions(items.toArray());
3147
3179
  });
3148
3180
  this._focusableLists.changes
3149
- .pipe(startWith$1(this._focusableLists), switchMap((queryList) => merge$1(...queryList.toArray().map((list) => list._gridListFocused$))), takeUntilDestroyed(this._destroyRef))
3181
+ .pipe(startWith$1(this._focusableLists), switchMap((queryList) => {
3182
+ const lists = queryList.toArray();
3183
+ return merge$1(...lists.map((list) => list._gridListFocused$));
3184
+ }), takeUntilDestroyed(this._destroyRef))
3150
3185
  .subscribe((focusedEvent) => {
3151
3186
  this.rowFocused.emit(focusedEvent);
3152
- this._focusableLists.forEach((list) => list.setTabbable(false));
3153
- this._focusableLists.forEach((list) => list._setItemsTabbable(false));
3187
+ const lists = this._focusableLists.toArray();
3188
+ const listsLength = lists.length;
3189
+ for (let i = 0; i < listsLength; i++) {
3190
+ const list = lists[i];
3191
+ list.setTabbable(false);
3192
+ list._setItemsTabbable(false);
3193
+ }
3154
3194
  });
3155
3195
  this._focusableLists.changes
3156
- .pipe(startWith$1(this._focusableLists), switchMap((queryList) => merge$1(...queryList.toArray().map((list) => list._gridItemFocused$))), takeUntilDestroyed(this._destroyRef))
3196
+ .pipe(startWith$1(this._focusableLists), switchMap((queryList) => {
3197
+ const lists = queryList.toArray();
3198
+ return merge$1(...lists.map((list) => list._gridItemFocused$));
3199
+ }), takeUntilDestroyed(this._destroyRef))
3157
3200
  .subscribe((focusedEvent) => {
3158
3201
  this.itemFocused.emit(focusedEvent);
3159
- this._focusableLists.forEach((list) => list.setTabbable(false));
3160
- this._focusableLists.forEach((list) => list._setItemsTabbable(false));
3202
+ const lists = this._focusableLists.toArray();
3203
+ const listsLength = lists.length;
3204
+ for (let i = 0; i < listsLength; i++) {
3205
+ const list = lists[i];
3206
+ list.setTabbable(false);
3207
+ list._setItemsTabbable(false);
3208
+ }
3161
3209
  });
3162
3210
  this._focusableLists.changes
3163
- .pipe(startWith$1(this._focusableLists), switchMap((queryList) => merge$1(...queryList.toArray().map((list) => list._keydown$))), takeUntilDestroyed(this._destroyRef))
3211
+ .pipe(startWith$1(this._focusableLists), switchMap((queryList) => {
3212
+ const lists = queryList.toArray();
3213
+ return merge$1(...lists.map((list) => list._keydown$));
3214
+ }), takeUntilDestroyed(this._destroyRef))
3164
3215
  .subscribe(({ event, list, activeItemIndex }) => this._onKeydown(event, list, activeItemIndex));
3165
3216
  }
3166
3217
  /**
@@ -3184,10 +3235,11 @@ class FocusableGridDirective {
3184
3235
  let nextRowIndex;
3185
3236
  let nextRowItemIndex = activeItemIndex ?? 0;
3186
3237
  let scrollIntoView;
3238
+ const listItemsLength = list._focusableItems().length;
3187
3239
  const isFirstItemLtr = activeItemIndex === 0 && this.contentDirection !== 'rtl';
3188
- const isLastItemRtl = activeItemIndex === list._focusableItems().length - 1 && this.contentDirection === 'rtl';
3240
+ const isLastItemRtl = activeItemIndex === listItemsLength - 1 && this.contentDirection === 'rtl';
3189
3241
  const isFirstItemRtl = activeItemIndex === 0 && this.contentDirection === 'rtl';
3190
- const isLastItemLtr = activeItemIndex === list._focusableItems().length - 1 && this.contentDirection !== 'rtl';
3242
+ const isLastItemLtr = activeItemIndex === listItemsLength - 1 && this.contentDirection !== 'rtl';
3191
3243
  switch (event.keyCode) {
3192
3244
  case UP_ARROW:
3193
3245
  event.preventDefault();
@@ -3246,36 +3298,48 @@ class FocusableGridDirective {
3246
3298
  }
3247
3299
  /** @hidden */
3248
3300
  _handleItemSubscriptions(items) {
3249
- items.forEach((item) => {
3301
+ const itemsLength = items.length;
3302
+ for (let i = 0; i < itemsLength; i++) {
3303
+ const item = items[i];
3250
3304
  if (!(item instanceof FocusableItemDirective) || this._subscribedItems.has(item)) {
3251
- return;
3305
+ continue;
3252
3306
  }
3253
3307
  this._subscribedItems.add(item);
3254
3308
  outputToObservable(item.focusableChildElementFocused)
3255
3309
  .pipe(takeUntilDestroyed(this._destroyRef))
3256
3310
  .subscribe(() => {
3257
- this._focusableLists.forEach((focusableList) => {
3258
- focusableList._focusableItems().forEach((focusableItem) => {
3311
+ const lists = this._focusableLists.toArray();
3312
+ const listsLength = lists.length;
3313
+ for (let j = 0; j < listsLength; j++) {
3314
+ const focusableItems = lists[j]._focusableItems();
3315
+ const focusableItemsLength = focusableItems.length;
3316
+ for (let k = 0; k < focusableItemsLength; k++) {
3317
+ const focusableItem = focusableItems[k];
3259
3318
  focusableItem.setTabbable(false);
3260
3319
  focusableItem.enableTabbableElements();
3261
- });
3262
- });
3320
+ }
3321
+ }
3263
3322
  });
3264
3323
  outputToObservable(item._parentFocusableItemFocused)
3265
3324
  .pipe(takeUntilDestroyed(this._destroyRef))
3266
3325
  .subscribe(() => {
3267
- this._focusableLists.forEach((focusableList) => {
3268
- focusableList._focusableItems().forEach((focusableItem) => {
3326
+ const lists = this._focusableLists.toArray();
3327
+ const listsLength = lists.length;
3328
+ for (let j = 0; j < listsLength; j++) {
3329
+ const focusableItems = lists[j]._focusableItems();
3330
+ const focusableItemsLength = focusableItems.length;
3331
+ for (let k = 0; k < focusableItemsLength; k++) {
3332
+ const focusableItem = focusableItems[k];
3269
3333
  if (item !== focusableItem) {
3270
3334
  focusableItem.disableTabbableElements();
3271
3335
  }
3272
3336
  else {
3273
3337
  focusableItem.enableTabbableElements();
3274
3338
  }
3275
- });
3276
- });
3339
+ }
3340
+ }
3277
3341
  });
3278
- });
3342
+ }
3279
3343
  }
3280
3344
  /** @hidden */
3281
3345
  _watchListItems(list) {
@@ -5143,62 +5207,61 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImpor
5143
5207
  }]
5144
5208
  }] });
5145
5209
 
5210
+ const DEFAULT_TRUNCATE_WIDTH = 200;
5146
5211
  class TruncateDirective {
5147
5212
  /**
5148
- * Width in pixel for truncation of an element , by default
5213
+ * Root native element
5149
5214
  */
5150
- set fdkTruncateWidth(value) {
5151
- this._customWidthCount = coerceNumberProperty(value);
5215
+ get rootElement() {
5216
+ return this._elementRef.nativeElement;
5152
5217
  }
5153
5218
  /** @hidden */
5154
- constructor(_elementRef) {
5155
- this._elementRef = _elementRef;
5219
+ constructor() {
5220
+ /**
5221
+ * Width in pixel for truncation of an element, by default 200
5222
+ */
5223
+ this.fdkTruncateWidth = input(DEFAULT_TRUNCATE_WIDTH, { ...(ngDevMode ? { debugName: "fdkTruncateWidth" } : {}), transform: numberAttribute });
5156
5224
  /**
5157
5225
  * Truncating state
5158
5226
  */
5159
- this.fdkTruncateState = false;
5227
+ this.fdkTruncateState = input(false, ...(ngDevMode ? [{ debugName: "fdkTruncateState" }] : []));
5160
5228
  /** @hidden */
5161
- this._customWidthCount = 200;
5229
+ this._elementRef = inject(ElementRef);
5162
5230
  /** @hidden */
5163
- this.takeDefaultStyleOnce = true;
5164
- }
5165
- /**
5166
- * Root native element
5167
- */
5168
- get rootElement() {
5169
- return this._elementRef.nativeElement;
5231
+ this._defaultStyleCaptured = false;
5232
+ effect(() => {
5233
+ const state = this.fdkTruncateState();
5234
+ const width = this.fdkTruncateWidth();
5235
+ untracked(() => this._truncate(state, width));
5236
+ });
5170
5237
  }
5171
5238
  /**
5172
5239
  * Method saves default style of target element before first truncate.
5173
5240
  */
5174
5241
  setDefaultStyle() {
5175
- if (this.takeDefaultStyleOnce) {
5242
+ if (!this._defaultStyleCaptured) {
5176
5243
  this._defaultStyle = this._truncateTarget.style.cssText;
5177
- this.takeDefaultStyleOnce = false;
5244
+ this._defaultStyleCaptured = true;
5178
5245
  }
5179
5246
  }
5180
5247
  /** @hidden */
5181
5248
  ngAfterViewInit() {
5182
5249
  if (this.rootElement) {
5183
- this._truncate();
5250
+ this._truncate(this.fdkTruncateState(), this.fdkTruncateWidth());
5184
5251
  }
5185
5252
  }
5186
5253
  /** @hidden */
5187
- ngOnChanges() {
5188
- this._truncate();
5189
- }
5190
- /** @hidden */
5191
- _truncate() {
5254
+ _truncate(state, width) {
5192
5255
  this._truncateTarget = this.rootElement;
5193
5256
  if (!this._truncateTarget) {
5194
5257
  return;
5195
5258
  }
5196
5259
  this.setDefaultStyle();
5197
- this._truncationStyle = `${this._defaultStyle} max-width: ${this._customWidthCount}px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;`;
5198
- this._truncateTarget.style.cssText = this.fdkTruncateState ? this._truncationStyle : this._defaultStyle;
5260
+ const truncationStyle = `${this._defaultStyle} max-width: ${width}px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;`;
5261
+ this._truncateTarget.style.cssText = state ? truncationStyle : this._defaultStyle;
5199
5262
  }
5200
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TruncateDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
5201
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.0", type: TruncateDirective, isStandalone: true, selector: "[fdkTruncate]", inputs: { fdkTruncateWidth: "fdkTruncateWidth", fdkTruncateState: "fdkTruncateState" }, usesOnChanges: true, ngImport: i0 }); }
5263
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TruncateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
5264
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.0", type: TruncateDirective, isStandalone: true, selector: "[fdkTruncate]", inputs: { fdkTruncateWidth: { classPropertyName: "fdkTruncateWidth", publicName: "fdkTruncateWidth", isSignal: true, isRequired: false, transformFunction: null }, fdkTruncateState: { classPropertyName: "fdkTruncateState", publicName: "fdkTruncateState", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
5202
5265
  }
5203
5266
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TruncateDirective, decorators: [{
5204
5267
  type: Directive,
@@ -5206,11 +5269,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImpor
5206
5269
  selector: '[fdkTruncate]',
5207
5270
  standalone: true
5208
5271
  }]
5209
- }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { fdkTruncateWidth: [{
5210
- type: Input
5211
- }], fdkTruncateState: [{
5212
- type: Input
5213
- }] } });
5272
+ }], ctorParameters: () => [], propDecorators: { fdkTruncateWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fdkTruncateWidth", required: false }] }], fdkTruncateState: [{ type: i0.Input, args: [{ isSignal: true, alias: "fdkTruncateState", required: false }] }] } });
5214
5273
  class TruncatedTitleDirective {
5215
5274
  /** @hidden */
5216
5275
  constructor(_elRef) {