@progress/kendo-angular-buttons 21.4.1-develop.1 → 22.0.0-develop.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/fesm2022/progress-kendo-angular-buttons.mjs +105 -105
  2. package/listbutton/list-button.d.ts +1 -1
  3. package/package.json +11 -19
  4. package/splitbutton/localization/messages.d.ts +1 -1
  5. package/esm2022/button/button-settings.mjs +0 -5
  6. package/esm2022/button/button.component.mjs +0 -558
  7. package/esm2022/button/button.module.mjs +0 -43
  8. package/esm2022/button/button.service.mjs +0 -22
  9. package/esm2022/button/selection-settings.mjs +0 -5
  10. package/esm2022/buttongroup/buttongroup.component.mjs +0 -340
  11. package/esm2022/buttongroup/buttongroup.module.mjs +0 -49
  12. package/esm2022/buttons.module.mjs +0 -58
  13. package/esm2022/chip/chip-content-click-event-args.interface.mjs +0 -5
  14. package/esm2022/chip/chip-list-remove-event-args.interface.mjs +0 -5
  15. package/esm2022/chip/chip-list.component.mjs +0 -360
  16. package/esm2022/chip/chip-remove-event-args.interface.mjs +0 -5
  17. package/esm2022/chip/chip.component.mjs +0 -585
  18. package/esm2022/chip/chip.module.mjs +0 -45
  19. package/esm2022/chip/models/avatar-settings.interface.mjs +0 -5
  20. package/esm2022/chip/models/selection.mjs +0 -5
  21. package/esm2022/common/models/arrow-settings.mjs +0 -5
  22. package/esm2022/common/models/fillmode.mjs +0 -5
  23. package/esm2022/common/models/rounded.mjs +0 -5
  24. package/esm2022/common/models/size.mjs +0 -5
  25. package/esm2022/common/models/styling-classes.mjs +0 -5
  26. package/esm2022/common/models/theme-color.mjs +0 -5
  27. package/esm2022/common/models.mjs +0 -10
  28. package/esm2022/direction.mjs +0 -5
  29. package/esm2022/directives.mjs +0 -176
  30. package/esm2022/dropdownbutton/dropdownbutton.component.mjs +0 -482
  31. package/esm2022/dropdownbutton/dropdownbutton.module.mjs +0 -50
  32. package/esm2022/floatingactionbutton/animations/animations.mjs +0 -33
  33. package/esm2022/floatingactionbutton/dial-item.component.mjs +0 -161
  34. package/esm2022/floatingactionbutton/dial-list.component.mjs +0 -98
  35. package/esm2022/floatingactionbutton/floatingactionbutton.component.mjs +0 -954
  36. package/esm2022/floatingactionbutton/floatingactionbutton.module.mjs +0 -47
  37. package/esm2022/floatingactionbutton/models/align.mjs +0 -5
  38. package/esm2022/floatingactionbutton/models/item-animation.interface.mjs +0 -5
  39. package/esm2022/floatingactionbutton/models/item-click.event.mjs +0 -5
  40. package/esm2022/floatingactionbutton/models/item.interface.mjs +0 -5
  41. package/esm2022/floatingactionbutton/models/offset.mjs +0 -5
  42. package/esm2022/floatingactionbutton/models/position-mode.mjs +0 -5
  43. package/esm2022/floatingactionbutton/templates/dial-item-template.directive.mjs +0 -37
  44. package/esm2022/floatingactionbutton/templates/fab-template.directive.mjs +0 -38
  45. package/esm2022/floatingactionbutton/utils.mjs +0 -38
  46. package/esm2022/focusable/focus.service.mjs +0 -38
  47. package/esm2022/focusable/focusable.directive.mjs +0 -67
  48. package/esm2022/index.mjs +0 -33
  49. package/esm2022/listbutton/button-item-template.directive.mjs +0 -47
  50. package/esm2022/listbutton/container.service.mjs +0 -18
  51. package/esm2022/listbutton/list-button.mjs +0 -461
  52. package/esm2022/listbutton/list-item-model.mjs +0 -5
  53. package/esm2022/listbutton/list.component.mjs +0 -177
  54. package/esm2022/listbutton/popup-settings.mjs +0 -5
  55. package/esm2022/navigation/key-events.mjs +0 -13
  56. package/esm2022/navigation/navigation-action.mjs +0 -20
  57. package/esm2022/navigation/navigation-config.mjs +0 -9
  58. package/esm2022/navigation/navigation.service.mjs +0 -111
  59. package/esm2022/package-metadata.mjs +0 -16
  60. package/esm2022/preventable-event.mjs +0 -25
  61. package/esm2022/progress-kendo-angular-buttons.mjs +0 -8
  62. package/esm2022/speechtotextbutton/models/error-event.mjs +0 -5
  63. package/esm2022/speechtotextbutton/models/integration-mode.mjs +0 -5
  64. package/esm2022/speechtotextbutton/models/result-event.mjs +0 -5
  65. package/esm2022/speechtotextbutton/models/speechtotextbutton-settings.mjs +0 -5
  66. package/esm2022/speechtotextbutton/speechtotextbutton.component.mjs +0 -532
  67. package/esm2022/speechtotextbutton/speechtotextbutton.module.mjs +0 -31
  68. package/esm2022/splitbutton/localization/custom-messages.component.mjs +0 -40
  69. package/esm2022/splitbutton/localization/localized-messages.directive.mjs +0 -39
  70. package/esm2022/splitbutton/localization/messages.mjs +0 -50
  71. package/esm2022/splitbutton/splitbutton.component.mjs +0 -761
  72. package/esm2022/splitbutton/splitbutton.module.mjs +0 -37
  73. package/esm2022/util.mjs +0 -108
@@ -1,954 +0,0 @@
1
- /**-----------------------------------------------------------------------------------------
2
- * Copyright © 2026 Progress Software Corporation. All rights reserved.
3
- * Licensed under commercial license. See LICENSE.md in the project root for more information
4
- *-------------------------------------------------------------------------------------------*/
5
- import { AnimationBuilder } from '@angular/animations';
6
- import { Component, ElementRef, EventEmitter, HostBinding, Input, Output, NgZone, Renderer2, ViewChild, ContentChild, TemplateRef } from '@angular/core';
7
- import { merge, Subscription } from 'rxjs';
8
- import { take } from 'rxjs/operators';
9
- import { L10N_PREFIX, LocalizationService } from '@progress/kendo-angular-l10n';
10
- import { validatePackage } from '@progress/kendo-licensing';
11
- import { packageMetadata } from '../package-metadata';
12
- import { guid, isDocumentAvailable, normalizeKeys } from '@progress/kendo-angular-common';
13
- import { PopupService } from '@progress/kendo-angular-popup';
14
- import { FocusService } from '../focusable/focus.service';
15
- import { NavigationAction } from '../navigation/navigation-action';
16
- import { NAVIGATION_CONFIG } from '../navigation/navigation-config';
17
- import { NavigationService } from '../navigation/navigation.service';
18
- import { closest, isPresent } from '../util';
19
- import { getAnchorAlign, getPopupAlign } from './utils';
20
- import { closeAnimation, openAnimation } from './animations/animations';
21
- import { PreventableEvent } from '../preventable-event';
22
- import { DialItemTemplateDirective } from './templates/dial-item-template.directive';
23
- import { FloatingActionButtonTemplateDirective } from './templates/fab-template.directive';
24
- import { DialListComponent } from './dial-list.component';
25
- import { IconWrapperComponent } from '@progress/kendo-angular-icons';
26
- import { EventsOutsideAngularDirective } from '@progress/kendo-angular-common';
27
- import { NgClass, NgTemplateOutlet } from '@angular/common';
28
- import * as i0 from "@angular/core";
29
- import * as i1 from "../focusable/focus.service";
30
- import * as i2 from "../navigation/navigation.service";
31
- import * as i3 from "@progress/kendo-angular-popup";
32
- import * as i4 from "@angular/animations";
33
- import * as i5 from "@progress/kendo-angular-l10n";
34
- const NAVIGATION_SETTINGS = {
35
- useLeftRightArrows: false
36
- };
37
- const NAVIGATION_SETTINGS_PROVIDER = {
38
- provide: NAVIGATION_CONFIG,
39
- useValue: NAVIGATION_SETTINGS
40
- };
41
- const SIZE_CLASSES = {
42
- small: 'k-fab-sm',
43
- medium: 'k-fab-md',
44
- large: 'k-fab-lg'
45
- };
46
- const ROUNDED_CLASSES = {
47
- small: 'k-rounded-sm',
48
- medium: 'k-rounded-md',
49
- large: 'k-rounded-lg',
50
- full: 'k-rounded-full'
51
- };
52
- const FILLMODE_CLASS = 'k-fab-solid';
53
- const DEFAULT_DURATION = 180;
54
- const DEFAULT_ITEM_GAP = 90;
55
- const DEFAULT_OFFSET = '16px';
56
- const DEFAULT_ROUNDED = 'full';
57
- const DEFAULT_SIZE = 'medium';
58
- const DEFAULT_THEME_COLOR = 'primary';
59
- /**
60
- * Represents the Kendo UI FloatingActionButton component for Angular.
61
- * Use it to represent the primary or most common action in an application.
62
- *
63
- * @example
64
- * ```html
65
- * <kendo-floatingactionbutton
66
- * [icon]="'plus'"
67
- * [text]="'Add'"
68
- * [align]="{ horizontal: 'end', vertical: 'bottom' }">
69
- * </kendo-floatingactionbutton>
70
- * ```
71
- */
72
- export class FloatingActionButtonComponent {
73
- renderer;
74
- element;
75
- focusService;
76
- navigationService;
77
- ngZone;
78
- popupService;
79
- builder;
80
- localizationService;
81
- get fixedClass() {
82
- return this.positionMode === 'fixed';
83
- }
84
- get absoluteClass() {
85
- return this.positionMode === 'absolute';
86
- }
87
- direction;
88
- button;
89
- popupTemplate;
90
- dialItemTemplate;
91
- fabTemplate;
92
- /**
93
- * Specifies the theme color of the FloatingActionButton ([see example](slug:appearance_floatingactionbutton#theme-colors)).
94
- * @default "primary"
95
- */
96
- set themeColor(themeColor) {
97
- const newThemeColor = themeColor || DEFAULT_THEME_COLOR;
98
- this.handleClasses(newThemeColor, 'themeColor');
99
- this._themeColor = newThemeColor;
100
- }
101
- get themeColor() {
102
- return this._themeColor;
103
- }
104
- /**
105
- * Specifies the size of the FloatingActionButton ([see example](slug:appearance_floatingactionbutton#size)).
106
- * @default "medium"
107
- */
108
- set size(size) {
109
- const newSize = size || DEFAULT_SIZE;
110
- this.handleClasses(newSize, 'size');
111
- this._size = newSize;
112
- }
113
- get size() {
114
- return this._size;
115
- }
116
- /**
117
- * Specifies the border radius of the FloatingActionButton ([see example](slug:appearance_floatingactionbutton#roundness)).
118
- *
119
- * @default "full"
120
- */
121
- set rounded(rounded) {
122
- const newRounded = rounded || DEFAULT_ROUNDED;
123
- this.handleClasses(newRounded, 'rounded');
124
- this._rounded = newRounded;
125
- }
126
- get rounded() {
127
- return this._rounded;
128
- }
129
- /**
130
- * Specifies whether the FloatingActionButton is disabled.
131
- * @default false
132
- */
133
- set disabled(disabled) {
134
- this._disabled = disabled;
135
- }
136
- get disabled() {
137
- return this._disabled;
138
- }
139
- /**
140
- * Specifies the alignment of the FloatingActionButton ([see example](slug:positioning_floatingactionbutton#alignment)).
141
- * @default { horizontal: 'end', vertical: 'top' }
142
- */
143
- set align(align) {
144
- this._align = Object.assign(this._align, align);
145
- }
146
- get align() {
147
- return this._align;
148
- }
149
- /**
150
- * Specifies the offset position of the FloatingActionButton ([see example]({% slug positioning_floatingactionbutton %}#offset)).
151
- * @default { x: '16px', y: '16px' }
152
- */
153
- set offset(offset) {
154
- this._offset = Object.assign(this._offset, offset);
155
- this.offsetStyles();
156
- }
157
- get offset() {
158
- return this._offset;
159
- }
160
- /**
161
- * Specifies the position mode of the FloatingActionButton ([see example](slug:positioning_floatingactionbutton#position-mode)).
162
- * @default "fixed"
163
- */
164
- positionMode = 'fixed';
165
- /**
166
- * Defines the name of an existing icon in a Kendo UI theme.
167
- */
168
- icon;
169
- /**
170
- * Defines an [`SVGIcon`](slug:api_icons_svgicon) to be rendered within the FloatingActionButton.
171
- */
172
- svgIcon;
173
- /**
174
- * Defines a CSS class or multiple classes for custom icons.
175
- */
176
- iconClass;
177
- /**
178
- * The CSS classes that will be rendered on the main button.
179
- * Supports the type of values that are supported by [`ngClass`](link:site.data.urls.angular['ngclassapi']).
180
- */
181
- buttonClass;
182
- /**
183
- * The CSS classes that will be rendered on the dial items `ul` element.
184
- * Supports the type of values that are supported by [`ngClass`](link:site.data.urls.angular['ngclassapi']).
185
- */
186
- dialClass;
187
- /**
188
- * Specifies the text content of the FloatingActionButton.
189
- */
190
- text;
191
- /**
192
- * Specifies the animation settings of the FloatingActionButton dial items.
193
- * @default true
194
- */
195
- dialItemAnimation = true;
196
- /**
197
- * Specifies the [`tabIndex`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex) of the FloatingActionButton.
198
- * @default 0
199
- */
200
- tabIndex = 0;
201
- /**
202
- * Specifies the collection of dial items rendered in the FloatingActionButton popup.
203
- */
204
- dialItems = [];
205
- /**
206
- * Fires when the FloatingActionButton is blurred.
207
- */
208
- onBlur = new EventEmitter();
209
- /**
210
- * Fires when the FloatingActionButton is focused.
211
- */
212
- onFocus = new EventEmitter();
213
- /**
214
- * Fires when a dial item is clicked.
215
- */
216
- dialItemClick = new EventEmitter();
217
- /**
218
- * Fires when the popup is about to open. This event is preventable
219
- * ([more information and example](slug:events_floatingactionbutton)).
220
- */
221
- open = new EventEmitter();
222
- /**
223
- * Fires when the popup is about to close. This event is preventable
224
- * ([more information and example](slug:events_floatingactionbutton)).
225
- */
226
- close = new EventEmitter();
227
- /**
228
- * @hidden
229
- */
230
- get componentTabIndex() {
231
- return this.disabled ? (-1) : this.tabIndex;
232
- }
233
- /**
234
- * @hidden
235
- */
236
- id = `k-${guid()}`;
237
- /**
238
- * @hidden
239
- */
240
- dialListId = `k-dial-list-${guid()}`;
241
- _themeColor = DEFAULT_THEME_COLOR;
242
- _size = DEFAULT_SIZE;
243
- _rounded = DEFAULT_ROUNDED;
244
- _disabled = false;
245
- _align = { horizontal: 'end', vertical: 'bottom' };
246
- _offset = { x: DEFAULT_OFFSET, y: DEFAULT_OFFSET };
247
- subscriptions = new Subscription();
248
- popupMouseDownListener;
249
- rtl = false;
250
- animationEnd = new EventEmitter();
251
- popupRef;
252
- initialSetup = true;
253
- focusChangedProgrammatically = false;
254
- constructor(renderer, element, focusService, navigationService, ngZone, popupService, builder, localizationService) {
255
- this.renderer = renderer;
256
- this.element = element;
257
- this.focusService = focusService;
258
- this.navigationService = navigationService;
259
- this.ngZone = ngZone;
260
- this.popupService = popupService;
261
- this.builder = builder;
262
- this.localizationService = localizationService;
263
- validatePackage(packageMetadata);
264
- this.subscribeNavigationEvents();
265
- this.subscriptions.add(this.localizationService.changes.subscribe(({ rtl }) => {
266
- this.rtl = rtl;
267
- this.direction = this.rtl ? 'rtl' : 'ltr';
268
- }));
269
- }
270
- ngAfterViewInit() {
271
- ['size', 'rounded', 'themeColor'].forEach(option => this.handleClasses(this[option], option));
272
- this.renderer.addClass(this.element.nativeElement, this.alignClass());
273
- this.offsetStyles();
274
- this.initialSetup = false;
275
- }
276
- ngOnDestroy() {
277
- this.subscriptions.unsubscribe();
278
- if (this.isOpen) {
279
- this.toggleDial(false);
280
- }
281
- }
282
- /**
283
- * Indicates whether the FloatingActionButton is currently open.
284
- */
285
- get isOpen() { return isPresent(this.popupRef); }
286
- /**
287
- * Focuses the FloatingActionButton.
288
- */
289
- focus() {
290
- if (isDocumentAvailable()) {
291
- this.focusChangedProgrammatically = true;
292
- this.button.nativeElement.focus();
293
- this.focusChangedProgrammatically = false;
294
- }
295
- }
296
- /**
297
- * Blurs the FloatingActionButton.
298
- */
299
- blur() {
300
- if (isDocumentAvailable()) {
301
- this.focusChangedProgrammatically = true;
302
- this.button.nativeElement.blur();
303
- this.focusChangedProgrammatically = false;
304
- }
305
- }
306
- /**
307
- * Toggles the visibility of the FloatingActionButton dial items popup.
308
- *
309
- * If you use the `toggleDial` method to open or close the dial items,
310
- * the `open` and `close` events do not fire ([more information and examples](slug:openstate_floatingactionbutton)).
311
- *
312
- * @param open - The state of dial items popup.
313
- */
314
- toggleDial(open) {
315
- if (this.disabled || !this.hasDialItems) {
316
- return;
317
- }
318
- const shouldOpen = isPresent(open) ? open : !this.isOpen;
319
- if (this.disabled || shouldOpen === this.isOpen) {
320
- return;
321
- }
322
- if (shouldOpen) {
323
- setTimeout(() => this.openDial());
324
- }
325
- else {
326
- this.closeDial();
327
- }
328
- }
329
- /**
330
- * @hidden
331
- */
332
- get ariaExpanded() {
333
- return this.hasDialItems ? this.isOpen : undefined;
334
- }
335
- /**
336
- * @hidden
337
- */
338
- get ariaHasPopup() {
339
- return this.hasDialItems ? 'menu' : undefined;
340
- }
341
- /**
342
- * @hidden
343
- */
344
- get ariaControls() {
345
- if (!this.hasDialItems) {
346
- return undefined;
347
- }
348
- return this.isOpen ? this.dialListId : undefined;
349
- }
350
- /**
351
- * @hidden
352
- */
353
- get iconClasses() {
354
- const classes = [];
355
- if (this.iconClass) {
356
- classes.push(`${this.iconClass}`);
357
- }
358
- if (this.icon) {
359
- classes.push(`k-fab-icon k-icon k-i-${this.icon}`);
360
- }
361
- return classes;
362
- }
363
- /**
364
- * @hidden
365
- */
366
- clickHandler() {
367
- if (this.disabled || !this.hasDialItems) {
368
- return;
369
- }
370
- this.ngZone.run(() => {
371
- const shouldOpen = !this.isOpen;
372
- this.toggleDialWithEvents(shouldOpen);
373
- });
374
- }
375
- /**
376
- * @hidden
377
- */
378
- pointerdownHandler(e) {
379
- if (this.isOpen) {
380
- e.preventDefault();
381
- this.focus();
382
- }
383
- }
384
- /**
385
- * @hidden
386
- */
387
- keyDownHandler(event) {
388
- if (this.disabled) {
389
- return;
390
- }
391
- const focused = this.focusService.focused || 0;
392
- const code = normalizeKeys(event);
393
- const action = this.navigationService.process({
394
- altKey: event.altKey,
395
- current: focused,
396
- code: code,
397
- max: this.dialItems ? this.dialItems.length - 1 : 0,
398
- min: 0,
399
- flipNavigation: this.align.vertical === 'bottom'
400
- });
401
- if (action !== NavigationAction.Undefined && action !== NavigationAction.Tab) {
402
- event.preventDefault();
403
- }
404
- if (action === NavigationAction.Tab && event.target.closest(`#${this.dialListId}`)) {
405
- this.focus();
406
- }
407
- if (action === NavigationAction.EnterUp && !this.hasDialItems) {
408
- this.button.nativeElement.click();
409
- }
410
- else if (action === NavigationAction.Open || action === NavigationAction.Close) {
411
- const toggleDial = action === NavigationAction.Open;
412
- this.ngZone.run(() => {
413
- this.toggleDialWithEvents(toggleDial);
414
- });
415
- }
416
- }
417
- /**
418
- * @hidden
419
- */
420
- onItemClick(event) {
421
- const item = closest(event.target, '.k-fab-item');
422
- if (!item) {
423
- return;
424
- }
425
- const index = parseInt(item.getAttribute('data-fab-item-index'));
426
- this.emitItemClick(index);
427
- }
428
- /**
429
- * @hidden
430
- */
431
- focusHandler() {
432
- if (!this.disabled && !this.focusChangedProgrammatically) {
433
- this.onFocus.emit();
434
- }
435
- }
436
- /**
437
- * @hidden
438
- */
439
- blurHandler(e) {
440
- const focusInList = e.relatedTarget && (e.relatedTarget.closest(`#${this.dialListId}`));
441
- if (focusInList) {
442
- return;
443
- }
444
- if (!this.focusChangedProgrammatically) {
445
- this.onBlur.emit();
446
- }
447
- this.toggleDialWithEvents(false);
448
- }
449
- /**
450
- * @hidden
451
- */
452
- focusOutHandler(e) {
453
- const focusInList = e.relatedTarget && (e.relatedTarget.closest(`#${this.dialListId}`));
454
- const focusOnButton = e.relatedTarget === this.button.nativeElement;
455
- const shouldClose = !focusInList && !focusOnButton;
456
- if (shouldClose) {
457
- this.toggleDialWithEvents(false);
458
- if (!this.focusChangedProgrammatically) {
459
- this.onBlur.emit();
460
- }
461
- }
462
- }
463
- /**
464
- * @hidden
465
- */
466
- onNavigationEnterPress() {
467
- this.ngZone.run(() => {
468
- if (this.isOpen) {
469
- const focusedIndex = this.focusService.focused;
470
- const focusedItem = this.dialItems[focusedIndex];
471
- if (focusedItem?.disabled) {
472
- return;
473
- }
474
- if (isPresent(focusedIndex) && focusedIndex !== -1) {
475
- this.onEnterPressed();
476
- return;
477
- }
478
- }
479
- if (!this.isOpen && isDocumentAvailable()) {
480
- this.toggleDialWithEvents(true);
481
- this.focus();
482
- }
483
- });
484
- }
485
- /**
486
- * @hidden
487
- */
488
- onNavigationClose() {
489
- if (this.isOpen) {
490
- this.ngZone.run(() => {
491
- this.toggleDialWithEvents(false);
492
- this.focus();
493
- });
494
- }
495
- }
496
- handleClasses(inputValue, input) {
497
- if (isPresent(this.button) && (this[input] !== inputValue || this.initialSetup)) {
498
- const button = this.button.nativeElement;
499
- const classesToRemove = {
500
- themeColor: `${FILLMODE_CLASS}-${this.themeColor}`,
501
- size: SIZE_CLASSES[this.size],
502
- rounded: ROUNDED_CLASSES[this.rounded]
503
- };
504
- const classesToAdd = {
505
- themeColor: inputValue !== 'none' ? `${FILLMODE_CLASS}-${inputValue}` : '',
506
- size: SIZE_CLASSES[inputValue],
507
- rounded: ROUNDED_CLASSES[inputValue]
508
- };
509
- this.renderer.removeClass(button, classesToRemove[input]);
510
- if (classesToAdd[input]) {
511
- this.renderer.addClass(button, classesToAdd[input]);
512
- }
513
- }
514
- }
515
- onEnterPressed() {
516
- const index = this.focusService.focused;
517
- this.emitItemClick(index);
518
- }
519
- emitItemClick(index) {
520
- const item = this.dialItems[index];
521
- if (item && !item.disabled) {
522
- const clickEventArgs = { item: item, index: index };
523
- this.dialItemClick.emit(clickEventArgs);
524
- this.toggleDialWithEvents(false);
525
- this.focusService.focused = index;
526
- }
527
- this.focus();
528
- }
529
- subscribeNavigationEvents() {
530
- this.subscriptions.add(this.navigationService.navigate.subscribe(this.onArrowKeyNavigate.bind(this)));
531
- this.subscriptions.add(this.navigationService.enter.subscribe(this.onNavigationEnterPress.bind(this)));
532
- this.subscriptions.add(merge(this.navigationService.close, this.navigationService.esc).subscribe(this.onNavigationClose.bind(this)));
533
- }
534
- onArrowKeyNavigate({ index }) {
535
- this.focusService.focus(index);
536
- }
537
- alignClass() {
538
- return `k-pos-${this.align.vertical}-${this.align.horizontal}`;
539
- }
540
- toggleDialWithEvents(open) {
541
- if (open === this.isOpen) {
542
- return;
543
- }
544
- const event = new PreventableEvent();
545
- if (open) {
546
- this.open.emit(event);
547
- }
548
- else {
549
- this.close.emit(event);
550
- }
551
- if (event.isDefaultPrevented()) {
552
- return;
553
- }
554
- if (open) {
555
- this.openDial();
556
- }
557
- else {
558
- this.closeDial();
559
- }
560
- }
561
- openPopup() {
562
- if (this.isOpen) {
563
- return;
564
- }
565
- const isIconFab = this.icon && !this.text;
566
- const rtl = this.rtl;
567
- const align = this.align;
568
- this.popupRef = this.popupService.open({
569
- anchor: this.element.nativeElement,
570
- animate: false,
571
- content: this.popupTemplate,
572
- anchorAlign: getAnchorAlign(align, rtl),
573
- popupAlign: getPopupAlign(align, rtl),
574
- popupClass: 'k-fab-popup k-popup-transparent'
575
- });
576
- const popupElement = this.popupRef.popupElement;
577
- this.renderer.setStyle(popupElement, 'box-shadow', 'none');
578
- if (isIconFab) {
579
- this.subscriptions.add(this.popupRef.popupOpen.subscribe(() => this.positionPopup()));
580
- }
581
- this.ngZone.runOutsideAngular(() => {
582
- this.popupMouseDownListener = this.renderer.listen(popupElement, 'mousedown', (event) => {
583
- event.preventDefault();
584
- });
585
- });
586
- this.subscriptions.add(this.popupRef.popupAnchorViewportLeave.subscribe(() => this.toggleDialWithEvents(false)));
587
- }
588
- closePopup() {
589
- if (this.isOpen) {
590
- if (this.popupMouseDownListener) {
591
- this.popupMouseDownListener();
592
- }
593
- this.popupRef.close();
594
- this.popupRef = null;
595
- }
596
- }
597
- openDial() {
598
- this.openPopup();
599
- this.focusService.focus(0);
600
- if (this.dialItemAnimation && this.isValidAnimation()) {
601
- this.playAnimation(true);
602
- }
603
- this.renderer.setAttribute(this.button.nativeElement, 'aria-expanded', 'true');
604
- }
605
- closeDial() {
606
- if (this.dialItemAnimation && this.isValidAnimation()) {
607
- this.playAnimation(false);
608
- this.animationEnd.pipe(take(1)).subscribe(() => this.closePopup());
609
- }
610
- else {
611
- this.closePopup();
612
- }
613
- this.renderer.setAttribute(this.button.nativeElement, 'aria-expanded', 'false');
614
- this.focusService.resetFocus();
615
- }
616
- isValidAnimation() {
617
- const animation = this.dialItemAnimation;
618
- if (typeof animation !== 'boolean') {
619
- return animation.duration !== 0;
620
- }
621
- return true;
622
- }
623
- positionPopup() {
624
- if (this.dialItemTemplate) {
625
- return;
626
- }
627
- if (!this.popupRef) {
628
- return;
629
- }
630
- const fab = this.element.nativeElement;
631
- const fabWidth = fab.getBoundingClientRect().width;
632
- const popupEl = this.popupRef.popupElement;
633
- const icon = popupEl.querySelector('.k-fab-item-icon');
634
- if (!icon) {
635
- return;
636
- }
637
- const iconWidth = icon.getBoundingClientRect().width;
638
- const left = (fabWidth / 2) - (iconWidth / 2);
639
- const popupLeft = popupEl.getBoundingClientRect().left;
640
- const isEndAlign = this.align.horizontal === 'end';
641
- const leftValue = isEndAlign ? (popupLeft - left) : (left + popupLeft);
642
- const rtlLeftValue = isEndAlign ? (left + popupLeft) : (popupLeft - left);
643
- popupEl.style.left = this.rtl ? `${rtlLeftValue}px` : `${leftValue}px`;
644
- }
645
- offsetStyles() {
646
- const hostElement = this.element.nativeElement;
647
- this.renderer.setStyle(hostElement, this.horizontalPosition, this.horizontalOffset);
648
- this.renderer.setStyle(hostElement, this.verticalPosition, this.verticalOffset);
649
- }
650
- get hasDialItems() {
651
- return isPresent(this.dialItems) && this.dialItems.length !== 0;
652
- }
653
- /**
654
- * Gets the CSS prop name of the selected vertical position (`top`/`bottom`);
655
- */
656
- get verticalPosition() {
657
- return {
658
- top: 'top',
659
- middle: 'top',
660
- bottom: 'bottom'
661
- }[this.align.vertical];
662
- }
663
- /**
664
- * Gets the offset according to the selected vertical position.
665
- */
666
- get verticalOffset() {
667
- if (this.align.vertical === 'middle') {
668
- return this.offset.y === DEFAULT_OFFSET ? '50%' : `calc(50% + ${this.offset.y})`;
669
- }
670
- return this.offset.y;
671
- }
672
- /**
673
- * Gets the CSS prop name of the selected horizontal position (`left`/`right`);
674
- */
675
- get horizontalPosition() {
676
- const { horizontal } = this.align;
677
- return {
678
- end: this.rtl ? 'left' : 'right',
679
- center: 'left',
680
- start: this.rtl ? 'right' : 'left'
681
- }[horizontal];
682
- }
683
- /**
684
- * Gets the offset according to the selected horizontal position.
685
- */
686
- get horizontalOffset() {
687
- if (this.align.horizontal === 'center') {
688
- return this.offset.x === DEFAULT_OFFSET ? '50%' : `calc(50% + ${this.offset.x})`;
689
- }
690
- return this.offset.x;
691
- }
692
- playerFor(element, animation) {
693
- const factory = this.builder.build(animation);
694
- return factory.create(element);
695
- }
696
- playAnimation(open) {
697
- const durationSettings = this.durationSettings();
698
- const animationSettings = {
699
- duration: durationSettings.duration,
700
- gap: durationSettings.gap,
701
- align: this.align
702
- };
703
- const animation = open ? openAnimation(animationSettings) : closeAnimation(animationSettings);
704
- let player = this.playerFor(this.popupRef.popupElement, animation);
705
- player.play();
706
- player.onDone(() => {
707
- if (player) {
708
- this.animationEnd.emit();
709
- player.destroy();
710
- player = null;
711
- }
712
- });
713
- }
714
- durationSettings() {
715
- return {
716
- duration: this.animationDuration(),
717
- gap: this.animationGap()
718
- };
719
- }
720
- animationGap() {
721
- const animation = this.dialItemAnimation;
722
- if (typeof animation !== 'boolean' && isPresent(animation.gap)) {
723
- return animation.gap;
724
- }
725
- return DEFAULT_ITEM_GAP;
726
- }
727
- animationDuration() {
728
- const animation = this.dialItemAnimation;
729
- if (typeof animation !== 'boolean' && isPresent(animation.duration)) {
730
- return animation.duration;
731
- }
732
- return DEFAULT_DURATION;
733
- }
734
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: FloatingActionButtonComponent, deps: [{ token: i0.Renderer2 }, { token: i0.ElementRef }, { token: i1.FocusService }, { token: i2.NavigationService }, { token: i0.NgZone }, { token: i3.PopupService }, { token: i4.AnimationBuilder }, { token: i5.LocalizationService }], target: i0.ɵɵFactoryTarget.Component });
735
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: FloatingActionButtonComponent, isStandalone: true, selector: "kendo-floatingactionbutton", inputs: { themeColor: "themeColor", size: "size", rounded: "rounded", disabled: "disabled", align: "align", offset: "offset", positionMode: "positionMode", icon: "icon", svgIcon: "svgIcon", iconClass: "iconClass", buttonClass: "buttonClass", dialClass: "dialClass", text: "text", dialItemAnimation: "dialItemAnimation", tabIndex: "tabIndex", dialItems: "dialItems" }, outputs: { onBlur: "blur", onFocus: "focus", dialItemClick: "dialItemClick", open: "open", close: "close" }, host: { properties: { "class.k-pos-fixed": "this.fixedClass", "class.k-pos-absolute": "this.absoluteClass", "attr.dir": "this.direction" } }, providers: [
736
- FocusService,
737
- NavigationService,
738
- NAVIGATION_SETTINGS_PROVIDER,
739
- LocalizationService,
740
- {
741
- provide: L10N_PREFIX,
742
- useValue: 'kendo.floatingactionbutton'
743
- }
744
- ], queries: [{ propertyName: "dialItemTemplate", first: true, predicate: DialItemTemplateDirective, descendants: true }, { propertyName: "fabTemplate", first: true, predicate: FloatingActionButtonTemplateDirective, descendants: true }], viewQueries: [{ propertyName: "button", first: true, predicate: ["button"], descendants: true, static: true }, { propertyName: "popupTemplate", first: true, predicate: ["popupTemplate"], descendants: true, static: true }], ngImport: i0, template: `
745
- <button
746
- #button
747
- [attr.id]="id"
748
- [tabIndex]="componentTabIndex"
749
- type="button"
750
- class="k-fab k-fab-solid"
751
- [class.k-disabled]="disabled"
752
- [ngClass]="buttonClass"
753
- [disabled]="disabled"
754
- [attr.aria-disabled]="disabled"
755
- [attr.aria-expanded]="ariaExpanded"
756
- [attr.aria-haspopup]="ariaHasPopup"
757
- [attr.aria-controls]="ariaControls"
758
- (focus)="focusHandler()"
759
- (blur)="blurHandler($event)"
760
- [kendoEventsOutsideAngular]="{
761
- keydown: keyDownHandler,
762
- click: clickHandler,
763
- pointerdown: pointerdownHandler
764
- }"
765
- [scope]="this"
766
- >
767
- @if (fabTemplate) {
768
- <ng-template
769
- [ngTemplateOutlet]="fabTemplate?.templateRef"
770
- >
771
- </ng-template>
772
- }
773
-
774
- @if (!fabTemplate) {
775
- @if (icon || iconClass || svgIcon) {
776
- <kendo-icon-wrapper
777
- [name]="icon"
778
- innerCssClass="k-fab-icon"
779
- [customFontClass]="iconClass"
780
- [svgIcon]="svgIcon"></kendo-icon-wrapper>
781
- }
782
- @if (text) {
783
- <span class="k-fab-text">{{ text }}</span>
784
- }
785
- }
786
- </button>
787
-
788
- <ng-template #popupTemplate>
789
- <ul
790
- kendoDialList
791
- role="menu"
792
- [id]="dialListId"
793
- [ngClass]="dialClass"
794
- [dialItems]="dialItems"
795
- [dialItemTemplate]='dialItemTemplate?.templateRef'
796
- [align]="align"
797
- [attr.aria-labelledby]="id"
798
- (click)="onItemClick($event)"
799
- [kendoEventsOutsideAngular]="{
800
- keydown: keyDownHandler.bind(this),
801
- focusout: focusOutHandler.bind(this)
802
- }"
803
- >
804
- </ul>
805
- </ng-template>
806
- `, isInline: true, dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: EventsOutsideAngularDirective, selector: "[kendoEventsOutsideAngular]", inputs: ["kendoEventsOutsideAngular", "scope"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }, { kind: "component", type: DialListComponent, selector: "[kendoDialList]", inputs: ["dialItems", "dialItemTemplate", "align"] }] });
807
- }
808
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: FloatingActionButtonComponent, decorators: [{
809
- type: Component,
810
- args: [{
811
- selector: 'kendo-floatingactionbutton',
812
- providers: [
813
- FocusService,
814
- NavigationService,
815
- NAVIGATION_SETTINGS_PROVIDER,
816
- LocalizationService,
817
- {
818
- provide: L10N_PREFIX,
819
- useValue: 'kendo.floatingactionbutton'
820
- }
821
- ],
822
- template: `
823
- <button
824
- #button
825
- [attr.id]="id"
826
- [tabIndex]="componentTabIndex"
827
- type="button"
828
- class="k-fab k-fab-solid"
829
- [class.k-disabled]="disabled"
830
- [ngClass]="buttonClass"
831
- [disabled]="disabled"
832
- [attr.aria-disabled]="disabled"
833
- [attr.aria-expanded]="ariaExpanded"
834
- [attr.aria-haspopup]="ariaHasPopup"
835
- [attr.aria-controls]="ariaControls"
836
- (focus)="focusHandler()"
837
- (blur)="blurHandler($event)"
838
- [kendoEventsOutsideAngular]="{
839
- keydown: keyDownHandler,
840
- click: clickHandler,
841
- pointerdown: pointerdownHandler
842
- }"
843
- [scope]="this"
844
- >
845
- @if (fabTemplate) {
846
- <ng-template
847
- [ngTemplateOutlet]="fabTemplate?.templateRef"
848
- >
849
- </ng-template>
850
- }
851
-
852
- @if (!fabTemplate) {
853
- @if (icon || iconClass || svgIcon) {
854
- <kendo-icon-wrapper
855
- [name]="icon"
856
- innerCssClass="k-fab-icon"
857
- [customFontClass]="iconClass"
858
- [svgIcon]="svgIcon"></kendo-icon-wrapper>
859
- }
860
- @if (text) {
861
- <span class="k-fab-text">{{ text }}</span>
862
- }
863
- }
864
- </button>
865
-
866
- <ng-template #popupTemplate>
867
- <ul
868
- kendoDialList
869
- role="menu"
870
- [id]="dialListId"
871
- [ngClass]="dialClass"
872
- [dialItems]="dialItems"
873
- [dialItemTemplate]='dialItemTemplate?.templateRef'
874
- [align]="align"
875
- [attr.aria-labelledby]="id"
876
- (click)="onItemClick($event)"
877
- [kendoEventsOutsideAngular]="{
878
- keydown: keyDownHandler.bind(this),
879
- focusout: focusOutHandler.bind(this)
880
- }"
881
- >
882
- </ul>
883
- </ng-template>
884
- `,
885
- standalone: true,
886
- imports: [NgClass, EventsOutsideAngularDirective, NgTemplateOutlet, IconWrapperComponent, DialListComponent]
887
- }]
888
- }], ctorParameters: () => [{ type: i0.Renderer2 }, { type: i0.ElementRef }, { type: i1.FocusService }, { type: i2.NavigationService }, { type: i0.NgZone }, { type: i3.PopupService }, { type: i4.AnimationBuilder }, { type: i5.LocalizationService }], propDecorators: { fixedClass: [{
889
- type: HostBinding,
890
- args: ['class.k-pos-fixed']
891
- }], absoluteClass: [{
892
- type: HostBinding,
893
- args: ['class.k-pos-absolute']
894
- }], direction: [{
895
- type: HostBinding,
896
- args: ['attr.dir']
897
- }], button: [{
898
- type: ViewChild,
899
- args: ['button', { static: true }]
900
- }], popupTemplate: [{
901
- type: ViewChild,
902
- args: ['popupTemplate', { static: true }]
903
- }], dialItemTemplate: [{
904
- type: ContentChild,
905
- args: [DialItemTemplateDirective, { static: false }]
906
- }], fabTemplate: [{
907
- type: ContentChild,
908
- args: [FloatingActionButtonTemplateDirective, { static: false }]
909
- }], themeColor: [{
910
- type: Input
911
- }], size: [{
912
- type: Input
913
- }], rounded: [{
914
- type: Input
915
- }], disabled: [{
916
- type: Input
917
- }], align: [{
918
- type: Input
919
- }], offset: [{
920
- type: Input
921
- }], positionMode: [{
922
- type: Input
923
- }], icon: [{
924
- type: Input
925
- }], svgIcon: [{
926
- type: Input
927
- }], iconClass: [{
928
- type: Input
929
- }], buttonClass: [{
930
- type: Input
931
- }], dialClass: [{
932
- type: Input
933
- }], text: [{
934
- type: Input
935
- }], dialItemAnimation: [{
936
- type: Input
937
- }], tabIndex: [{
938
- type: Input
939
- }], dialItems: [{
940
- type: Input
941
- }], onBlur: [{
942
- type: Output,
943
- args: ['blur']
944
- }], onFocus: [{
945
- type: Output,
946
- args: ['focus']
947
- }], dialItemClick: [{
948
- type: Output,
949
- args: ['dialItemClick']
950
- }], open: [{
951
- type: Output
952
- }], close: [{
953
- type: Output
954
- }] } });