@progress/kendo-angular-layout 17.3.0-develop.2 → 18.0.0-develop.10

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.
package/esm2022/index.mjs CHANGED
@@ -11,6 +11,7 @@ export { PanelBarExpandMode } from './panelbar/panelbar-expand-mode';
11
11
  export * from './panelbar/events';
12
12
  export { SplitterComponent } from './splitter/splitter.component';
13
13
  export { SplitterPaneComponent } from './splitter/splitter-pane.component';
14
+ // TabStrip exports
14
15
  export { TabStripComponent } from './tabstrip/tabstrip.component';
15
16
  export { TabStripTabComponent } from './tabstrip/models/tabstrip-tab.component';
16
17
  export { TabContentDirective } from './tabstrip/directives/tab-content.directive';
@@ -9,7 +9,7 @@ export const packageMetadata = {
9
9
  name: '@progress/kendo-angular-layout',
10
10
  productName: 'Kendo UI for Angular',
11
11
  productCodes: ['KENDOUIANGULAR', 'KENDOUICOMPLETE'],
12
- publishDate: 1736180615,
13
- version: '17.3.0-develop.2',
12
+ publishDate: 1736777760,
13
+ version: '18.0.0-develop.10',
14
14
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/?utm_medium=product&utm_source=kendoangular&utm_campaign=kendo-ui-angular-purchase-license-keys-warning'
15
15
  };
@@ -6,12 +6,13 @@ import { BUTTON_SCROLL_SPEED, MOUSE_SCROLL_SPEED } from "../constants";
6
6
  /**
7
7
  * @hidden
8
8
  */
9
- const normalizeSettings = ({ enabled = true, scrollButtons = 'auto', mouseScroll = true, buttonScrollSpeed = BUTTON_SCROLL_SPEED, mouseScrollSpeed = MOUSE_SCROLL_SPEED, prevButtonIcon, nextButtonIcon, prevSVGButtonIcon, nextSVGButtonIcon }) => ({
9
+ const normalizeSettings = ({ enabled = true, scrollButtons = 'auto', mouseScroll = true, buttonScrollSpeed = BUTTON_SCROLL_SPEED, mouseScrollSpeed = MOUSE_SCROLL_SPEED, scrollButtonsPosition = 'split', prevButtonIcon, nextButtonIcon, prevSVGButtonIcon, nextSVGButtonIcon }) => ({
10
10
  enabled,
11
11
  scrollButtons,
12
12
  mouseScroll,
13
13
  buttonScrollSpeed,
14
14
  mouseScrollSpeed,
15
+ scrollButtonsPosition,
15
16
  prevButtonIcon,
16
17
  nextButtonIcon,
17
18
  prevSVGButtonIcon,
@@ -0,0 +1,5 @@
1
+ /**-----------------------------------------------------------------------------------------
2
+ * Copyright © 2025 Progress Software Corporation. All rights reserved.
3
+ * Licensed under commercial license. See LICENSE.md in the project root for more information
4
+ *-------------------------------------------------------------------------------------------*/
5
+ export {};
@@ -81,7 +81,7 @@ export class TabComponent {
81
81
  this.tabClose.emit(closeArgs);
82
82
  }
83
83
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TabComponent, deps: [{ token: i1.LocalizationService }], target: i0.ɵɵFactoryTarget.Component });
84
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: TabComponent, isStandalone: true, selector: "[kendoTabStripTab]", inputs: { tab: "tab", index: "index", tabStripClosable: "tabStripClosable", tabStripCloseIcon: "tabStripCloseIcon", customTabstripCloseIcon: "customTabstripCloseIcon", closeSVGIcon: "closeSVGIcon" }, outputs: { tabClose: "tabClose" }, host: { properties: { "class.k-item": "this.hostClasses", "attr.aria-selected": "this.activeClass", "class.k-active": "this.activeClass", "attr.aria-disabled": "this.disabledClass", "class.k-disabled": "this.disabledClass", "class.k-focus": "this.focusedClass", "attr.tabindex": "this.tabIndex" } }, ngImport: i0, template: `
84
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: TabComponent, isStandalone: true, selector: "[kendoTabStripTab]", inputs: { tab: "tab", index: "index", tabStripClosable: "tabStripClosable", tabStripCloseIcon: "tabStripCloseIcon", customTabstripCloseIcon: "customTabstripCloseIcon", closeSVGIcon: "closeSVGIcon" }, outputs: { tabClose: "tabClose" }, host: { properties: { "class.k-item": "this.hostClasses", "class.k-tabstrip-item": "this.hostClasses", "attr.aria-selected": "this.activeClass", "class.k-active": "this.activeClass", "attr.aria-disabled": "this.disabledClass", "class.k-disabled": "this.disabledClass", "class.k-focus": "this.focusedClass", "attr.tabindex": "this.tabIndex" } }, ngImport: i0, template: `
85
85
  <ng-container *ngIf="!tab.tabTemplate; else tabTemplate">
86
86
  <span class="k-link" *ngIf="!tab.tabTitle">
87
87
  <span class="k-link-text">{{ tab.title }}</span>
@@ -165,6 +165,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
165
165
  }], hostClasses: [{
166
166
  type: HostBinding,
167
167
  args: ['class.k-item']
168
+ }, {
169
+ type: HostBinding,
170
+ args: ['class.k-tabstrip-item']
168
171
  }], activeClass: [{
169
172
  type: HostBinding,
170
173
  args: ['attr.aria-selected']
@@ -6,7 +6,7 @@ import { DEFAULT_SCROLL_BEHAVIOR } from './constants';
6
6
  import { Injectable, NgZone } from '@angular/core';
7
7
  import { isDocumentAvailable } from '@progress/kendo-angular-common';
8
8
  import { Subject } from 'rxjs';
9
- import { getActiveTab, isTablistHorizontal, mouseScrollEnabled } from './util';
9
+ import { getActiveTab, isTablistHorizontal } from './util';
10
10
  import * as i0 from "@angular/core";
11
11
  /**
12
12
  * @hidden
@@ -37,16 +37,6 @@ export class ScrollService {
37
37
  get tabsOverflow() {
38
38
  return this.tablistOverflowSize > 0;
39
39
  }
40
- get scrollButtonsSize() {
41
- if (!this.owner.hasScrollButtons) {
42
- return 0;
43
- }
44
- const prevRect = this.owner.prevScrollButton.hostBoundingClientRect;
45
- const prevSize = isTablistHorizontal(this.owner.tabPosition) ? prevRect.width : prevRect.height;
46
- const nextRect = this.owner.nextScrollButton.hostBoundingClientRect;
47
- const nextSize = isTablistHorizontal(this.owner.tabPosition) ? nextRect.width : nextRect.height;
48
- return prevSize + nextSize;
49
- }
50
40
  constructor(ngZone) {
51
41
  this.ngZone = ngZone;
52
42
  }
@@ -58,7 +48,7 @@ export class ScrollService {
58
48
  const currentPrevButtonActive = !this.isDisabled('prev');
59
49
  const currentNextButtonActive = !this.isDisabled('next');
60
50
  const calculatedPrevButtonActive = this.position > 0 && this.tablistOverflowSize > 0;
61
- const calculatedNextButtonActive = this.position < this.tablistOverflowSize + this.scrollButtonsSize && this.tablistOverflowSize > 0;
51
+ const calculatedNextButtonActive = this.position < this.tablistOverflowSize && this.tablistOverflowSize > 0;
62
52
  if (calculatedPrevButtonActive !== currentPrevButtonActive) {
63
53
  this.ngZone.run(() => this.toggleButtonActiveState('prev', calculatedPrevButtonActive));
64
54
  }
@@ -122,19 +112,8 @@ export class ScrollService {
122
112
  return activeTabStart - tablistStart;
123
113
  }
124
114
  }
125
- onMouseScroll(event) {
126
- event.preventDefault();
127
- if (!mouseScrollEnabled(this.owner.scrollable)) {
128
- return;
129
- }
130
- const direction = event.deltaY < 0 ? 'prev' : 'next';
131
- this.calculateListPosition(direction, this.owner.scrollable.mouseScrollSpeed);
132
- if (isTablistHorizontal(this.owner.tabPosition)) {
133
- this.tablistElement.scrollLeft = this.position;
134
- }
135
- else {
136
- this.tablistElement.scrollTop = this.position;
137
- }
115
+ onScroll(e) {
116
+ this.position = isTablistHorizontal(this.owner.tabPosition) ? e.target.scrollLeft : e.target.scrollTop;
138
117
  this.toggleScrollButtonsState();
139
118
  }
140
119
  scrollTabs(direction) {
@@ -148,13 +127,12 @@ export class ScrollService {
148
127
  this.toggleScrollButtonsState();
149
128
  }
150
129
  calculateListPosition(direction, scrollSpeed) {
151
- const adjustedMaxScroll = this.tablistOverflowSize + this.scrollButtonsSize;
152
130
  if (direction === 'prev' && this.position > 0) {
153
131
  this.position = this.position - scrollSpeed <= 0 ? 0 : this.position - scrollSpeed;
154
132
  }
155
- else if (direction === 'next' && this.position < adjustedMaxScroll) {
156
- if (this.position + scrollSpeed > adjustedMaxScroll) {
157
- this.position = adjustedMaxScroll;
133
+ else if (direction === 'next' && this.position < this.tablistOverflowSize) {
134
+ if (this.position + scrollSpeed > this.tablistOverflowSize) {
135
+ this.position = this.tablistOverflowSize;
158
136
  return;
159
137
  }
160
138
  this.position += scrollSpeed;
@@ -172,7 +150,7 @@ export class ScrollService {
172
150
  toggleButtonActiveState(buttonType, active) {
173
151
  this.scrollButtonActiveStateChange.next({ buttonType, active });
174
152
  }
175
- isDisabled = (buttonType) => this.owner[`${buttonType}ScrollButton`].host.nativeElement.classList.contains('k-disabled');
153
+ isDisabled = (buttonType) => this.owner[`${buttonType}ScrollButton`]?.host.nativeElement.classList.contains('k-disabled');
176
154
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ScrollService, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
177
155
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ScrollService });
178
156
  }
@@ -90,12 +90,52 @@ export class TabStripComponent {
90
90
  this._scrollableSettings = normalizeScrollableSettings(value);
91
91
  if (this.tablist) {
92
92
  this.toggleScrollButtons(this.scrollService.tabsOverflow);
93
- this.attachWheelHandler(this.tablist.nativeElement);
93
+ if (this.isScrollable && this.mouseScrollEnabled) {
94
+ this.attachTablistScrollHandler(this.tablist.nativeElement);
95
+ }
94
96
  }
95
97
  }
96
98
  get scrollable() {
97
99
  return this._scrollableSettings;
98
100
  }
101
+ /**
102
+ * Specifies the size of the TabStrip.
103
+ * ([see example](slug:api_layout_tabstripcomponent#toc-size).
104
+ *
105
+ * The possible values are:
106
+ * * `small`
107
+ * * `medium` (Default)
108
+ * * `large`
109
+ * * `none`
110
+ */
111
+ set size(value) {
112
+ switch (value) {
113
+ case 'small':
114
+ this.renderer.removeClass(this.wrapper.nativeElement, 'k-tabstrip-md');
115
+ this.renderer.removeClass(this.wrapper.nativeElement, 'k-tabstrip-lg');
116
+ this.renderer.addClass(this.wrapper.nativeElement, 'k-tabstrip-sm');
117
+ break;
118
+ case 'medium':
119
+ this.renderer.removeClass(this.wrapper.nativeElement, 'k-tabstrip-sm');
120
+ this.renderer.removeClass(this.wrapper.nativeElement, 'k-tabstrip-lg');
121
+ this.renderer.addClass(this.wrapper.nativeElement, 'k-tabstrip-md');
122
+ break;
123
+ case 'large':
124
+ this.renderer.removeClass(this.wrapper.nativeElement, 'k-tabstrip-md');
125
+ this.renderer.removeClass(this.wrapper.nativeElement, 'k-tabstrip-sm');
126
+ this.renderer.addClass(this.wrapper.nativeElement, 'k-tabstrip-lg');
127
+ break;
128
+ case 'none':
129
+ this.renderer.removeClass(this.wrapper.nativeElement, 'k-tabstrip-md');
130
+ this.renderer.removeClass(this.wrapper.nativeElement, 'k-tabstrip-lg');
131
+ this.renderer.removeClass(this.wrapper.nativeElement, 'k-tabstrip-sm');
132
+ }
133
+ this._size = value;
134
+ this.ngZone.onStable.pipe(take(1)).subscribe(() => this.onResize());
135
+ }
136
+ get size() {
137
+ return this._size;
138
+ }
99
139
  /**
100
140
  * Defines the name for an existing font icon in the Kendo UI theme for the close icon.
101
141
  */
@@ -157,6 +197,9 @@ export class TabStripComponent {
157
197
  get tabStripScrollable() {
158
198
  return this._scrollableSettings.enabled;
159
199
  }
200
+ get tabStripScrollableOverlay() {
201
+ return this._scrollableSettings.enabled && !this.hasScrollButtons.visible;
202
+ }
160
203
  /**
161
204
  * A query list of all declared tabs.
162
205
  */
@@ -193,6 +236,7 @@ export class TabStripComponent {
193
236
  tabStripId = guid();
194
237
  tabsChangesSub;
195
238
  activeStateChangeSub;
239
+ _size = 'medium';
196
240
  constructor(localization, renderer, wrapper, tabstripService, scrollService, ngZone) {
197
241
  this.localization = localization;
198
242
  this.renderer = renderer;
@@ -205,7 +249,7 @@ export class TabStripComponent {
205
249
  this.tabstripService.owner = this;
206
250
  this.scrollService.owner = this;
207
251
  this.subscriptions.add(this.scrollService.scrollButtonActiveStateChange.subscribe((activeButtonSettings) => {
208
- if (this.hasScrollButtons) {
252
+ if (this.hasScrollButtons.visible) {
209
253
  const action = activeButtonSettings.active ? 'remove' : 'add';
210
254
  this.renderer[`${action}Class`](this[`${activeButtonSettings.buttonType}ScrollButton`].host.nativeElement, 'k-disabled');
211
255
  }
@@ -233,6 +277,7 @@ export class TabStripComponent {
233
277
  this.scrollService.toggleScrollButtonsState();
234
278
  });
235
279
  });
280
+ this.isScrollable && !this.hasScrollButtons.visible && this.setScrollableOverlayClasses();
236
281
  }
237
282
  ngOnChanges(changes) {
238
283
  if (!isDocumentAvailable()) {
@@ -248,7 +293,7 @@ export class TabStripComponent {
248
293
  this.subscriptions = new Subscription();
249
294
  this.subscriptionsArePresent = false;
250
295
  this.activeStateChangeSub = this.scrollService.scrollButtonActiveStateChange.subscribe((activeButtonSettings) => {
251
- if (this.hasScrollButtons) {
296
+ if (this.hasScrollButtons.visible) {
252
297
  const action = activeButtonSettings.active ? 'remove' : 'add';
253
298
  this.renderer[`${action}Class`](this[`${activeButtonSettings.buttonType}ScrollButton`].host.nativeElement, 'k-disabled');
254
299
  }
@@ -377,7 +422,7 @@ export class TabStripComponent {
377
422
  resetTabFocus(this.tabs);
378
423
  }));
379
424
  if (this.isScrollable && this.mouseScrollEnabled) {
380
- this.attachWheelHandler(tablist);
425
+ this.attachTablistScrollHandler(tablist);
381
426
  }
382
427
  this.subscriptionsArePresent = true;
383
428
  }
@@ -398,30 +443,53 @@ export class TabStripComponent {
398
443
  this.prevScrollButton.toggle(true);
399
444
  this.nextScrollButton.toggle(true);
400
445
  }
401
- if (scrollButtonsArePresent && alwaysVisible) {
446
+ if (scrollButtonsArePresent) {
402
447
  this.ngZone.runOutsideAngular(() => {
403
448
  this.scrollService.toggleScrollButtonsState();
404
449
  });
405
450
  }
406
451
  });
407
452
  }
408
- attachWheelHandler(tablist) {
453
+ attachTablistScrollHandler(tablist) {
409
454
  this.ngZone.runOutsideAngular(() => {
410
- this.subscriptions.add(this.renderer.listen(tablist, 'wheel', (wheelEvent) => {
455
+ this.subscriptions.add(this.renderer.listen(tablist, 'scroll', (e) => {
411
456
  const scrollEvent = new TabScrollEvent({
412
- originalEvent: wheelEvent
457
+ originalEvent: e
413
458
  });
414
459
  this.tabScroll.emit(scrollEvent);
415
460
  const isTabStripScrollEventPrevented = scrollEvent.isDefaultPrevented();
416
461
  if (isTabStripScrollEventPrevented || !this.scrollService.tabsOverflow) {
417
462
  return;
418
463
  }
419
- this.scrollService.onMouseScroll(wheelEvent);
464
+ if (!this.hasScrollButtons.visible) {
465
+ this.setScrollableOverlayClasses();
466
+ }
467
+ this.scrollService.onScroll(e);
420
468
  }));
421
469
  });
422
470
  }
471
+ setScrollableOverlayClasses() {
472
+ const wrapper = this.wrapper.nativeElement;
473
+ const container = this.tablist?.nativeElement;
474
+ if (!container) {
475
+ return;
476
+ }
477
+ const scrollOffset = isTablistHorizontal(this.tabPosition) ? container.scrollLeft : container.scrollTop;
478
+ if (scrollOffset === 0) {
479
+ this.renderer.removeClass(wrapper, 'k-tabstrip-scrollable-end');
480
+ this.renderer.addClass(wrapper, 'k-tabstrip-scrollable-start');
481
+ }
482
+ else if (scrollOffset > 0 && scrollOffset < this.scrollService.tablistOverflowSize) {
483
+ this.renderer.removeClass(wrapper, 'k-tabstrip-scrollable-end');
484
+ this.renderer.removeClass(wrapper, 'k-tabstrip-scrollable-start');
485
+ }
486
+ else {
487
+ this.renderer.removeClass(wrapper, 'k-tabstrip-scrollable-start');
488
+ this.renderer.addClass(wrapper, 'k-tabstrip-scrollable-end');
489
+ }
490
+ }
423
491
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TabStripComponent, deps: [{ token: i1.LocalizationService }, { token: i0.Renderer2 }, { token: i0.ElementRef }, { token: i2.TabStripService }, { token: i3.ScrollService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
424
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: TabStripComponent, isStandalone: true, selector: "kendo-tabstrip", inputs: { height: "height", animate: "animate", tabAlignment: "tabAlignment", tabPosition: "tabPosition", keepTabContent: "keepTabContent", closable: "closable", scrollable: "scrollable", closeIcon: "closeIcon", closeIconClass: "closeIconClass", closeSVGIcon: "closeSVGIcon", showContentArea: "showContentArea" }, outputs: { tabSelect: "tabSelect", tabClose: "tabClose", tabScroll: "tabScroll" }, host: { properties: { "class.k-tabstrip": "this.hostClasses", "class.k-header": "this.hostClasses", "class.k-tabstrip-top": "this.tabsAtTop", "class.k-tabstrip-right": "this.tabsAtRight", "class.k-tabstrip-bottom": "this.tabsAtBottom", "class.k-tabstrip-left": "this.tabsAtLeft", "attr.dir": "this.dir", "class.k-tabstrip-scrollable": "this.tabStripScrollable" } }, providers: [
492
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: TabStripComponent, isStandalone: true, selector: "kendo-tabstrip", inputs: { height: "height", animate: "animate", tabAlignment: "tabAlignment", tabPosition: "tabPosition", keepTabContent: "keepTabContent", closable: "closable", scrollable: "scrollable", size: "size", closeIcon: "closeIcon", closeIconClass: "closeIconClass", closeSVGIcon: "closeSVGIcon", showContentArea: "showContentArea" }, outputs: { tabSelect: "tabSelect", tabClose: "tabClose", tabScroll: "tabScroll" }, host: { properties: { "class.k-tabstrip": "this.hostClasses", "class.k-tabstrip-md": "this.hostClasses", "class.k-tabstrip-top": "this.tabsAtTop", "class.k-tabstrip-right": "this.tabsAtRight", "class.k-tabstrip-bottom": "this.tabsAtBottom", "class.k-tabstrip-left": "this.tabsAtLeft", "attr.dir": "this.dir", "class.k-tabstrip-scrollable": "this.tabStripScrollable", "class.k-tabstrip-scrollable-overlay": "this.tabStripScrollableOverlay" } }, providers: [
425
493
  TabStripService,
426
494
  ScrollService,
427
495
  LocalizationService,
@@ -455,10 +523,10 @@ export class TabStripComponent {
455
523
  <ng-container *ngTemplateOutlet="heading"></ng-container>
456
524
  </ng-container>
457
525
  <ng-template #heading>
458
- <div class="k-tabstrip-items-wrapper" [ngClass]="itemsWrapperClass">
526
+ <div class="k-tabstrip-items-wrapper" [class.k-tabstrip-items-wrapper-scroll]="mouseScrollEnabled" [ngClass]="itemsWrapperClass">
459
527
  <span
460
528
  role="button"
461
- *ngIf="hasScrollButtons"
529
+ *ngIf="hasScrollButtons.visible && hasScrollButtons.position !== 'end'"
462
530
  #prevScrollButton
463
531
  kendoTabStripScrollableButton
464
532
  [scrollable]="scrollable"
@@ -466,9 +534,30 @@ export class TabStripComponent {
466
534
  [prev]="true"
467
535
  [title]="localization.get('previousTabButton')"
468
536
  (tabScroll)="tabScroll.emit($event)"
469
- class="k-icon-button k-button k-button-md k-button-flat k-button-flat-base"
470
- (onClick)="onScrollButtonClick($event)">
471
- </span>
537
+ class="k-icon-button k-button k-button-flat k-button-flat-base"
538
+ [ngClass]="{
539
+ 'k-button-sm': size === 'small',
540
+ 'k-button-md': size === 'medium' || !size,
541
+ 'k-button-lg': size === 'large'
542
+ }"
543
+ (onClick)="onScrollButtonClick($event)"></span>
544
+ <span
545
+ role="button"
546
+ *ngIf="hasScrollButtons.visible && hasScrollButtons.position === 'start'"
547
+ #nextScrollButton
548
+ kendoTabStripScrollableButton
549
+ [scrollable]="scrollable"
550
+ [tabPosition]="tabPosition"
551
+ [prev]="false"
552
+ [title]="localization.get('nextTabButton')"
553
+ (tabScroll)="tabScroll.emit($event)"
554
+ class="k-icon-button k-button k-button-flat k-button-flat-base"
555
+ [ngClass]="{
556
+ 'k-button-sm': size === 'small',
557
+ 'k-button-md': size === 'medium' || !size,
558
+ 'k-button-lg': size === 'large'
559
+ }"
560
+ (onClick)="onScrollButtonClick($event)"></span>
472
561
  <ul role="tablist" #tablist
473
562
  class="k-reset k-tabstrip-items"
474
563
  [ngClass]="{
@@ -476,7 +565,8 @@ export class TabStripComponent {
476
565
  'k-tabstrip-items-center': tabAlignment === 'center',
477
566
  'k-tabstrip-items-end': tabAlignment === 'end',
478
567
  'k-tabstrip-items-stretched': tabAlignment === 'stretched',
479
- 'k-tabstrip-items-justify': tabAlignment === 'justify'
568
+ 'k-tabstrip-items-justify': tabAlignment === 'justify',
569
+ 'k-tabstrip-items-scroll': mouseScrollEnabled
480
570
  }"
481
571
  [attr.aria-orientation]="tabPosition === 'left' || tabPosition === 'right' ? 'vertical' : 'horizontal'"
482
572
  >
@@ -503,7 +593,24 @@ export class TabStripComponent {
503
593
  </ul>
504
594
  <span
505
595
  role="button"
506
- *ngIf="hasScrollButtons"
596
+ *ngIf="hasScrollButtons.visible && hasScrollButtons.position === 'end'"
597
+ #prevScrollButton
598
+ kendoTabStripScrollableButton
599
+ [scrollable]="scrollable"
600
+ [tabPosition]="tabPosition"
601
+ [prev]="true"
602
+ [title]="localization.get('previousTabButton')"
603
+ (tabScroll)="tabScroll.emit($event)"
604
+ class="k-icon-button k-button k-button-flat k-button-flat-base"
605
+ [ngClass]="{
606
+ 'k-button-sm': size === 'small',
607
+ 'k-button-md': size === 'medium' || !size,
608
+ 'k-button-lg': size === 'large'
609
+ }"
610
+ (onClick)="onScrollButtonClick($event)"></span>
611
+ <span
612
+ role="button"
613
+ *ngIf="hasScrollButtons.visible && hasScrollButtons.position !== 'start'"
507
614
  #nextScrollButton
508
615
  kendoTabStripScrollableButton
509
616
  [scrollable]="scrollable"
@@ -511,7 +618,12 @@ export class TabStripComponent {
511
618
  [prev]="false"
512
619
  [title]="localization.get('nextTabButton')"
513
620
  (tabScroll)="tabScroll.emit($event)"
514
- class="k-icon-button k-button k-button-md k-button-flat k-button-flat-base"
621
+ class="k-icon-button k-button k-button-flat k-button-flat-base"
622
+ [ngClass]="{
623
+ 'k-button-sm': size === 'small',
624
+ 'k-button-md': size === 'medium' || !size,
625
+ 'k-button-lg': size === 'large'
626
+ }"
515
627
  (onClick)="onScrollButtonClick($event)"></span>
516
628
  </div>
517
629
  </ng-template>
@@ -594,10 +706,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
594
706
  <ng-container *ngTemplateOutlet="heading"></ng-container>
595
707
  </ng-container>
596
708
  <ng-template #heading>
597
- <div class="k-tabstrip-items-wrapper" [ngClass]="itemsWrapperClass">
709
+ <div class="k-tabstrip-items-wrapper" [class.k-tabstrip-items-wrapper-scroll]="mouseScrollEnabled" [ngClass]="itemsWrapperClass">
598
710
  <span
599
711
  role="button"
600
- *ngIf="hasScrollButtons"
712
+ *ngIf="hasScrollButtons.visible && hasScrollButtons.position !== 'end'"
601
713
  #prevScrollButton
602
714
  kendoTabStripScrollableButton
603
715
  [scrollable]="scrollable"
@@ -605,9 +717,30 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
605
717
  [prev]="true"
606
718
  [title]="localization.get('previousTabButton')"
607
719
  (tabScroll)="tabScroll.emit($event)"
608
- class="k-icon-button k-button k-button-md k-button-flat k-button-flat-base"
609
- (onClick)="onScrollButtonClick($event)">
610
- </span>
720
+ class="k-icon-button k-button k-button-flat k-button-flat-base"
721
+ [ngClass]="{
722
+ 'k-button-sm': size === 'small',
723
+ 'k-button-md': size === 'medium' || !size,
724
+ 'k-button-lg': size === 'large'
725
+ }"
726
+ (onClick)="onScrollButtonClick($event)"></span>
727
+ <span
728
+ role="button"
729
+ *ngIf="hasScrollButtons.visible && hasScrollButtons.position === 'start'"
730
+ #nextScrollButton
731
+ kendoTabStripScrollableButton
732
+ [scrollable]="scrollable"
733
+ [tabPosition]="tabPosition"
734
+ [prev]="false"
735
+ [title]="localization.get('nextTabButton')"
736
+ (tabScroll)="tabScroll.emit($event)"
737
+ class="k-icon-button k-button k-button-flat k-button-flat-base"
738
+ [ngClass]="{
739
+ 'k-button-sm': size === 'small',
740
+ 'k-button-md': size === 'medium' || !size,
741
+ 'k-button-lg': size === 'large'
742
+ }"
743
+ (onClick)="onScrollButtonClick($event)"></span>
611
744
  <ul role="tablist" #tablist
612
745
  class="k-reset k-tabstrip-items"
613
746
  [ngClass]="{
@@ -615,7 +748,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
615
748
  'k-tabstrip-items-center': tabAlignment === 'center',
616
749
  'k-tabstrip-items-end': tabAlignment === 'end',
617
750
  'k-tabstrip-items-stretched': tabAlignment === 'stretched',
618
- 'k-tabstrip-items-justify': tabAlignment === 'justify'
751
+ 'k-tabstrip-items-justify': tabAlignment === 'justify',
752
+ 'k-tabstrip-items-scroll': mouseScrollEnabled
619
753
  }"
620
754
  [attr.aria-orientation]="tabPosition === 'left' || tabPosition === 'right' ? 'vertical' : 'horizontal'"
621
755
  >
@@ -642,7 +776,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
642
776
  </ul>
643
777
  <span
644
778
  role="button"
645
- *ngIf="hasScrollButtons"
779
+ *ngIf="hasScrollButtons.visible && hasScrollButtons.position === 'end'"
780
+ #prevScrollButton
781
+ kendoTabStripScrollableButton
782
+ [scrollable]="scrollable"
783
+ [tabPosition]="tabPosition"
784
+ [prev]="true"
785
+ [title]="localization.get('previousTabButton')"
786
+ (tabScroll)="tabScroll.emit($event)"
787
+ class="k-icon-button k-button k-button-flat k-button-flat-base"
788
+ [ngClass]="{
789
+ 'k-button-sm': size === 'small',
790
+ 'k-button-md': size === 'medium' || !size,
791
+ 'k-button-lg': size === 'large'
792
+ }"
793
+ (onClick)="onScrollButtonClick($event)"></span>
794
+ <span
795
+ role="button"
796
+ *ngIf="hasScrollButtons.visible && hasScrollButtons.position !== 'start'"
646
797
  #nextScrollButton
647
798
  kendoTabStripScrollableButton
648
799
  [scrollable]="scrollable"
@@ -650,7 +801,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
650
801
  [prev]="false"
651
802
  [title]="localization.get('nextTabButton')"
652
803
  (tabScroll)="tabScroll.emit($event)"
653
- class="k-icon-button k-button k-button-md k-button-flat k-button-flat-base"
804
+ class="k-icon-button k-button k-button-flat k-button-flat-base"
805
+ [ngClass]="{
806
+ 'k-button-sm': size === 'small',
807
+ 'k-button-md': size === 'medium' || !size,
808
+ 'k-button-lg': size === 'large'
809
+ }"
654
810
  (onClick)="onScrollButtonClick($event)"></span>
655
811
  </div>
656
812
  </ng-template>
@@ -692,6 +848,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
692
848
  type: Input
693
849
  }], scrollable: [{
694
850
  type: Input
851
+ }], size: [{
852
+ type: Input
695
853
  }], closeIcon: [{
696
854
  type: Input
697
855
  }], closeIconClass: [{
@@ -711,7 +869,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
711
869
  args: ['class.k-tabstrip']
712
870
  }, {
713
871
  type: HostBinding,
714
- args: ['class.k-header']
872
+ args: ['class.k-tabstrip-md']
715
873
  }], tabsAtTop: [{
716
874
  type: HostBinding,
717
875
  args: ['class.k-tabstrip-top']
@@ -730,19 +888,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
730
888
  }], tabStripScrollable: [{
731
889
  type: HostBinding,
732
890
  args: ['class.k-tabstrip-scrollable']
891
+ }], tabStripScrollableOverlay: [{
892
+ type: HostBinding,
893
+ args: ['class.k-tabstrip-scrollable-overlay']
733
894
  }], tabs: [{
734
895
  type: ContentChildren,
735
896
  args: [TabStripTabComponent]
736
897
  }], tablist: [{
737
898
  type: ViewChild,
738
- args: ['tablist', { static: false }]
899
+ args: ['tablist']
739
900
  }], tabHeaderContainers: [{
740
901
  type: ViewChildren,
741
902
  args: ['tabHeaderContainer', { read: ElementRef }]
742
903
  }], prevScrollButton: [{
743
904
  type: ViewChild,
744
- args: ['prevScrollButton', { static: false }]
905
+ args: ['prevScrollButton']
745
906
  }], nextScrollButton: [{
746
907
  type: ViewChild,
747
- args: ['nextScrollButton', { static: false }]
908
+ args: ['nextScrollButton']
748
909
  }] } });
@@ -32,7 +32,12 @@ export const isTabClosable = (tab, tabStripClosable) => {
32
32
  * Checks if the TabStrip scroll buttons will be rendered. Depends on the value of the TabStrip scrollable settings.
33
33
  */
34
34
  export const tabStripHasScrollButtons = (scrollableSettings) => {
35
- return scrollableSettings.enabled && scrollableSettings.scrollButtons !== 'hidden';
35
+ const visible = scrollableSettings.enabled && scrollableSettings.scrollButtons !== 'hidden';
36
+ const position = scrollableSettings.scrollButtonsPosition;
37
+ return {
38
+ visible,
39
+ position
40
+ };
36
41
  };
37
42
  /**
38
43
  * @hidden