@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.
@@ -28,8 +28,8 @@ const packageMetadata = {
28
28
  name: '@progress/kendo-angular-layout',
29
29
  productName: 'Kendo UI for Angular',
30
30
  productCodes: ['KENDOUIANGULAR', 'KENDOUICOMPLETE'],
31
- publishDate: 1736180615,
32
- version: '17.3.0-develop.2',
31
+ publishDate: 1736777760,
32
+ version: '18.0.0-develop.10',
33
33
  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'
34
34
  };
35
35
 
@@ -3068,7 +3068,12 @@ const isTabClosable = (tab, tabStripClosable) => {
3068
3068
  * Checks if the TabStrip scroll buttons will be rendered. Depends on the value of the TabStrip scrollable settings.
3069
3069
  */
3070
3070
  const tabStripHasScrollButtons = (scrollableSettings) => {
3071
- return scrollableSettings.enabled && scrollableSettings.scrollButtons !== 'hidden';
3071
+ const visible = scrollableSettings.enabled && scrollableSettings.scrollButtons !== 'hidden';
3072
+ const position = scrollableSettings.scrollButtonsPosition;
3073
+ return {
3074
+ visible,
3075
+ position
3076
+ };
3072
3077
  };
3073
3078
  /**
3074
3079
  * @hidden
@@ -3352,16 +3357,6 @@ class ScrollService {
3352
3357
  get tabsOverflow() {
3353
3358
  return this.tablistOverflowSize > 0;
3354
3359
  }
3355
- get scrollButtonsSize() {
3356
- if (!this.owner.hasScrollButtons) {
3357
- return 0;
3358
- }
3359
- const prevRect = this.owner.prevScrollButton.hostBoundingClientRect;
3360
- const prevSize = isTablistHorizontal(this.owner.tabPosition) ? prevRect.width : prevRect.height;
3361
- const nextRect = this.owner.nextScrollButton.hostBoundingClientRect;
3362
- const nextSize = isTablistHorizontal(this.owner.tabPosition) ? nextRect.width : nextRect.height;
3363
- return prevSize + nextSize;
3364
- }
3365
3360
  constructor(ngZone) {
3366
3361
  this.ngZone = ngZone;
3367
3362
  }
@@ -3373,7 +3368,7 @@ class ScrollService {
3373
3368
  const currentPrevButtonActive = !this.isDisabled('prev');
3374
3369
  const currentNextButtonActive = !this.isDisabled('next');
3375
3370
  const calculatedPrevButtonActive = this.position > 0 && this.tablistOverflowSize > 0;
3376
- const calculatedNextButtonActive = this.position < this.tablistOverflowSize + this.scrollButtonsSize && this.tablistOverflowSize > 0;
3371
+ const calculatedNextButtonActive = this.position < this.tablistOverflowSize && this.tablistOverflowSize > 0;
3377
3372
  if (calculatedPrevButtonActive !== currentPrevButtonActive) {
3378
3373
  this.ngZone.run(() => this.toggleButtonActiveState('prev', calculatedPrevButtonActive));
3379
3374
  }
@@ -3437,19 +3432,8 @@ class ScrollService {
3437
3432
  return activeTabStart - tablistStart;
3438
3433
  }
3439
3434
  }
3440
- onMouseScroll(event) {
3441
- event.preventDefault();
3442
- if (!mouseScrollEnabled(this.owner.scrollable)) {
3443
- return;
3444
- }
3445
- const direction = event.deltaY < 0 ? 'prev' : 'next';
3446
- this.calculateListPosition(direction, this.owner.scrollable.mouseScrollSpeed);
3447
- if (isTablistHorizontal(this.owner.tabPosition)) {
3448
- this.tablistElement.scrollLeft = this.position;
3449
- }
3450
- else {
3451
- this.tablistElement.scrollTop = this.position;
3452
- }
3435
+ onScroll(e) {
3436
+ this.position = isTablistHorizontal(this.owner.tabPosition) ? e.target.scrollLeft : e.target.scrollTop;
3453
3437
  this.toggleScrollButtonsState();
3454
3438
  }
3455
3439
  scrollTabs(direction) {
@@ -3463,13 +3447,12 @@ class ScrollService {
3463
3447
  this.toggleScrollButtonsState();
3464
3448
  }
3465
3449
  calculateListPosition(direction, scrollSpeed) {
3466
- const adjustedMaxScroll = this.tablistOverflowSize + this.scrollButtonsSize;
3467
3450
  if (direction === 'prev' && this.position > 0) {
3468
3451
  this.position = this.position - scrollSpeed <= 0 ? 0 : this.position - scrollSpeed;
3469
3452
  }
3470
- else if (direction === 'next' && this.position < adjustedMaxScroll) {
3471
- if (this.position + scrollSpeed > adjustedMaxScroll) {
3472
- this.position = adjustedMaxScroll;
3453
+ else if (direction === 'next' && this.position < this.tablistOverflowSize) {
3454
+ if (this.position + scrollSpeed > this.tablistOverflowSize) {
3455
+ this.position = this.tablistOverflowSize;
3473
3456
  return;
3474
3457
  }
3475
3458
  this.position += scrollSpeed;
@@ -3487,7 +3470,7 @@ class ScrollService {
3487
3470
  toggleButtonActiveState(buttonType, active) {
3488
3471
  this.scrollButtonActiveStateChange.next({ buttonType, active });
3489
3472
  }
3490
- isDisabled = (buttonType) => this.owner[`${buttonType}ScrollButton`].host.nativeElement.classList.contains('k-disabled');
3473
+ isDisabled = (buttonType) => this.owner[`${buttonType}ScrollButton`]?.host.nativeElement.classList.contains('k-disabled');
3491
3474
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ScrollService, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
3492
3475
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ScrollService });
3493
3476
  }
@@ -3498,12 +3481,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
3498
3481
  /**
3499
3482
  * @hidden
3500
3483
  */
3501
- const normalizeSettings = ({ enabled = true, scrollButtons = 'auto', mouseScroll = true, buttonScrollSpeed = BUTTON_SCROLL_SPEED, mouseScrollSpeed = MOUSE_SCROLL_SPEED, prevButtonIcon, nextButtonIcon, prevSVGButtonIcon, nextSVGButtonIcon }) => ({
3484
+ const normalizeSettings = ({ enabled = true, scrollButtons = 'auto', mouseScroll = true, buttonScrollSpeed = BUTTON_SCROLL_SPEED, mouseScrollSpeed = MOUSE_SCROLL_SPEED, scrollButtonsPosition = 'split', prevButtonIcon, nextButtonIcon, prevSVGButtonIcon, nextSVGButtonIcon }) => ({
3502
3485
  enabled,
3503
3486
  scrollButtons,
3504
3487
  mouseScroll,
3505
3488
  buttonScrollSpeed,
3506
3489
  mouseScrollSpeed,
3490
+ scrollButtonsPosition,
3507
3491
  prevButtonIcon,
3508
3492
  nextButtonIcon,
3509
3493
  prevSVGButtonIcon,
@@ -3772,7 +3756,7 @@ class TabComponent {
3772
3756
  this.tabClose.emit(closeArgs);
3773
3757
  }
3774
3758
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TabComponent, deps: [{ token: i1.LocalizationService }], target: i0.ɵɵFactoryTarget.Component });
3775
- 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: `
3759
+ 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: `
3776
3760
  <ng-container *ngIf="!tab.tabTemplate; else tabTemplate">
3777
3761
  <span class="k-link" *ngIf="!tab.tabTitle">
3778
3762
  <span class="k-link-text">{{ tab.title }}</span>
@@ -3856,6 +3840,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
3856
3840
  }], hostClasses: [{
3857
3841
  type: HostBinding,
3858
3842
  args: ['class.k-item']
3843
+ }, {
3844
+ type: HostBinding,
3845
+ args: ['class.k-tabstrip-item']
3859
3846
  }], activeClass: [{
3860
3847
  type: HostBinding,
3861
3848
  args: ['attr.aria-selected']
@@ -4004,12 +3991,52 @@ class TabStripComponent {
4004
3991
  this._scrollableSettings = normalizeScrollableSettings(value);
4005
3992
  if (this.tablist) {
4006
3993
  this.toggleScrollButtons(this.scrollService.tabsOverflow);
4007
- this.attachWheelHandler(this.tablist.nativeElement);
3994
+ if (this.isScrollable && this.mouseScrollEnabled) {
3995
+ this.attachTablistScrollHandler(this.tablist.nativeElement);
3996
+ }
4008
3997
  }
4009
3998
  }
4010
3999
  get scrollable() {
4011
4000
  return this._scrollableSettings;
4012
4001
  }
4002
+ /**
4003
+ * Specifies the size of the TabStrip.
4004
+ * ([see example](slug:api_layout_tabstripcomponent#toc-size).
4005
+ *
4006
+ * The possible values are:
4007
+ * * `small`
4008
+ * * `medium` (Default)
4009
+ * * `large`
4010
+ * * `none`
4011
+ */
4012
+ set size(value) {
4013
+ switch (value) {
4014
+ case 'small':
4015
+ this.renderer.removeClass(this.wrapper.nativeElement, 'k-tabstrip-md');
4016
+ this.renderer.removeClass(this.wrapper.nativeElement, 'k-tabstrip-lg');
4017
+ this.renderer.addClass(this.wrapper.nativeElement, 'k-tabstrip-sm');
4018
+ break;
4019
+ case 'medium':
4020
+ this.renderer.removeClass(this.wrapper.nativeElement, 'k-tabstrip-sm');
4021
+ this.renderer.removeClass(this.wrapper.nativeElement, 'k-tabstrip-lg');
4022
+ this.renderer.addClass(this.wrapper.nativeElement, 'k-tabstrip-md');
4023
+ break;
4024
+ case 'large':
4025
+ this.renderer.removeClass(this.wrapper.nativeElement, 'k-tabstrip-md');
4026
+ this.renderer.removeClass(this.wrapper.nativeElement, 'k-tabstrip-sm');
4027
+ this.renderer.addClass(this.wrapper.nativeElement, 'k-tabstrip-lg');
4028
+ break;
4029
+ case 'none':
4030
+ this.renderer.removeClass(this.wrapper.nativeElement, 'k-tabstrip-md');
4031
+ this.renderer.removeClass(this.wrapper.nativeElement, 'k-tabstrip-lg');
4032
+ this.renderer.removeClass(this.wrapper.nativeElement, 'k-tabstrip-sm');
4033
+ }
4034
+ this._size = value;
4035
+ this.ngZone.onStable.pipe(take(1)).subscribe(() => this.onResize());
4036
+ }
4037
+ get size() {
4038
+ return this._size;
4039
+ }
4013
4040
  /**
4014
4041
  * Defines the name for an existing font icon in the Kendo UI theme for the close icon.
4015
4042
  */
@@ -4071,6 +4098,9 @@ class TabStripComponent {
4071
4098
  get tabStripScrollable() {
4072
4099
  return this._scrollableSettings.enabled;
4073
4100
  }
4101
+ get tabStripScrollableOverlay() {
4102
+ return this._scrollableSettings.enabled && !this.hasScrollButtons.visible;
4103
+ }
4074
4104
  /**
4075
4105
  * A query list of all declared tabs.
4076
4106
  */
@@ -4107,6 +4137,7 @@ class TabStripComponent {
4107
4137
  tabStripId = guid();
4108
4138
  tabsChangesSub;
4109
4139
  activeStateChangeSub;
4140
+ _size = 'medium';
4110
4141
  constructor(localization, renderer, wrapper, tabstripService, scrollService, ngZone) {
4111
4142
  this.localization = localization;
4112
4143
  this.renderer = renderer;
@@ -4119,7 +4150,7 @@ class TabStripComponent {
4119
4150
  this.tabstripService.owner = this;
4120
4151
  this.scrollService.owner = this;
4121
4152
  this.subscriptions.add(this.scrollService.scrollButtonActiveStateChange.subscribe((activeButtonSettings) => {
4122
- if (this.hasScrollButtons) {
4153
+ if (this.hasScrollButtons.visible) {
4123
4154
  const action = activeButtonSettings.active ? 'remove' : 'add';
4124
4155
  this.renderer[`${action}Class`](this[`${activeButtonSettings.buttonType}ScrollButton`].host.nativeElement, 'k-disabled');
4125
4156
  }
@@ -4147,6 +4178,7 @@ class TabStripComponent {
4147
4178
  this.scrollService.toggleScrollButtonsState();
4148
4179
  });
4149
4180
  });
4181
+ this.isScrollable && !this.hasScrollButtons.visible && this.setScrollableOverlayClasses();
4150
4182
  }
4151
4183
  ngOnChanges(changes) {
4152
4184
  if (!isDocumentAvailable()) {
@@ -4162,7 +4194,7 @@ class TabStripComponent {
4162
4194
  this.subscriptions = new Subscription();
4163
4195
  this.subscriptionsArePresent = false;
4164
4196
  this.activeStateChangeSub = this.scrollService.scrollButtonActiveStateChange.subscribe((activeButtonSettings) => {
4165
- if (this.hasScrollButtons) {
4197
+ if (this.hasScrollButtons.visible) {
4166
4198
  const action = activeButtonSettings.active ? 'remove' : 'add';
4167
4199
  this.renderer[`${action}Class`](this[`${activeButtonSettings.buttonType}ScrollButton`].host.nativeElement, 'k-disabled');
4168
4200
  }
@@ -4291,7 +4323,7 @@ class TabStripComponent {
4291
4323
  resetTabFocus(this.tabs);
4292
4324
  }));
4293
4325
  if (this.isScrollable && this.mouseScrollEnabled) {
4294
- this.attachWheelHandler(tablist);
4326
+ this.attachTablistScrollHandler(tablist);
4295
4327
  }
4296
4328
  this.subscriptionsArePresent = true;
4297
4329
  }
@@ -4312,30 +4344,53 @@ class TabStripComponent {
4312
4344
  this.prevScrollButton.toggle(true);
4313
4345
  this.nextScrollButton.toggle(true);
4314
4346
  }
4315
- if (scrollButtonsArePresent && alwaysVisible) {
4347
+ if (scrollButtonsArePresent) {
4316
4348
  this.ngZone.runOutsideAngular(() => {
4317
4349
  this.scrollService.toggleScrollButtonsState();
4318
4350
  });
4319
4351
  }
4320
4352
  });
4321
4353
  }
4322
- attachWheelHandler(tablist) {
4354
+ attachTablistScrollHandler(tablist) {
4323
4355
  this.ngZone.runOutsideAngular(() => {
4324
- this.subscriptions.add(this.renderer.listen(tablist, 'wheel', (wheelEvent) => {
4356
+ this.subscriptions.add(this.renderer.listen(tablist, 'scroll', (e) => {
4325
4357
  const scrollEvent = new TabScrollEvent({
4326
- originalEvent: wheelEvent
4358
+ originalEvent: e
4327
4359
  });
4328
4360
  this.tabScroll.emit(scrollEvent);
4329
4361
  const isTabStripScrollEventPrevented = scrollEvent.isDefaultPrevented();
4330
4362
  if (isTabStripScrollEventPrevented || !this.scrollService.tabsOverflow) {
4331
4363
  return;
4332
4364
  }
4333
- this.scrollService.onMouseScroll(wheelEvent);
4365
+ if (!this.hasScrollButtons.visible) {
4366
+ this.setScrollableOverlayClasses();
4367
+ }
4368
+ this.scrollService.onScroll(e);
4334
4369
  }));
4335
4370
  });
4336
4371
  }
4372
+ setScrollableOverlayClasses() {
4373
+ const wrapper = this.wrapper.nativeElement;
4374
+ const container = this.tablist?.nativeElement;
4375
+ if (!container) {
4376
+ return;
4377
+ }
4378
+ const scrollOffset = isTablistHorizontal(this.tabPosition) ? container.scrollLeft : container.scrollTop;
4379
+ if (scrollOffset === 0) {
4380
+ this.renderer.removeClass(wrapper, 'k-tabstrip-scrollable-end');
4381
+ this.renderer.addClass(wrapper, 'k-tabstrip-scrollable-start');
4382
+ }
4383
+ else if (scrollOffset > 0 && scrollOffset < this.scrollService.tablistOverflowSize) {
4384
+ this.renderer.removeClass(wrapper, 'k-tabstrip-scrollable-end');
4385
+ this.renderer.removeClass(wrapper, 'k-tabstrip-scrollable-start');
4386
+ }
4387
+ else {
4388
+ this.renderer.removeClass(wrapper, 'k-tabstrip-scrollable-start');
4389
+ this.renderer.addClass(wrapper, 'k-tabstrip-scrollable-end');
4390
+ }
4391
+ }
4337
4392
  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: TabStripService }, { token: ScrollService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
4338
- 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: [
4393
+ 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: [
4339
4394
  TabStripService,
4340
4395
  ScrollService,
4341
4396
  LocalizationService,
@@ -4369,10 +4424,10 @@ class TabStripComponent {
4369
4424
  <ng-container *ngTemplateOutlet="heading"></ng-container>
4370
4425
  </ng-container>
4371
4426
  <ng-template #heading>
4372
- <div class="k-tabstrip-items-wrapper" [ngClass]="itemsWrapperClass">
4427
+ <div class="k-tabstrip-items-wrapper" [class.k-tabstrip-items-wrapper-scroll]="mouseScrollEnabled" [ngClass]="itemsWrapperClass">
4373
4428
  <span
4374
4429
  role="button"
4375
- *ngIf="hasScrollButtons"
4430
+ *ngIf="hasScrollButtons.visible && hasScrollButtons.position !== 'end'"
4376
4431
  #prevScrollButton
4377
4432
  kendoTabStripScrollableButton
4378
4433
  [scrollable]="scrollable"
@@ -4380,9 +4435,30 @@ class TabStripComponent {
4380
4435
  [prev]="true"
4381
4436
  [title]="localization.get('previousTabButton')"
4382
4437
  (tabScroll)="tabScroll.emit($event)"
4383
- class="k-icon-button k-button k-button-md k-button-flat k-button-flat-base"
4384
- (onClick)="onScrollButtonClick($event)">
4385
- </span>
4438
+ class="k-icon-button k-button k-button-flat k-button-flat-base"
4439
+ [ngClass]="{
4440
+ 'k-button-sm': size === 'small',
4441
+ 'k-button-md': size === 'medium' || !size,
4442
+ 'k-button-lg': size === 'large'
4443
+ }"
4444
+ (onClick)="onScrollButtonClick($event)"></span>
4445
+ <span
4446
+ role="button"
4447
+ *ngIf="hasScrollButtons.visible && hasScrollButtons.position === 'start'"
4448
+ #nextScrollButton
4449
+ kendoTabStripScrollableButton
4450
+ [scrollable]="scrollable"
4451
+ [tabPosition]="tabPosition"
4452
+ [prev]="false"
4453
+ [title]="localization.get('nextTabButton')"
4454
+ (tabScroll)="tabScroll.emit($event)"
4455
+ class="k-icon-button k-button k-button-flat k-button-flat-base"
4456
+ [ngClass]="{
4457
+ 'k-button-sm': size === 'small',
4458
+ 'k-button-md': size === 'medium' || !size,
4459
+ 'k-button-lg': size === 'large'
4460
+ }"
4461
+ (onClick)="onScrollButtonClick($event)"></span>
4386
4462
  <ul role="tablist" #tablist
4387
4463
  class="k-reset k-tabstrip-items"
4388
4464
  [ngClass]="{
@@ -4390,7 +4466,8 @@ class TabStripComponent {
4390
4466
  'k-tabstrip-items-center': tabAlignment === 'center',
4391
4467
  'k-tabstrip-items-end': tabAlignment === 'end',
4392
4468
  'k-tabstrip-items-stretched': tabAlignment === 'stretched',
4393
- 'k-tabstrip-items-justify': tabAlignment === 'justify'
4469
+ 'k-tabstrip-items-justify': tabAlignment === 'justify',
4470
+ 'k-tabstrip-items-scroll': mouseScrollEnabled
4394
4471
  }"
4395
4472
  [attr.aria-orientation]="tabPosition === 'left' || tabPosition === 'right' ? 'vertical' : 'horizontal'"
4396
4473
  >
@@ -4417,7 +4494,24 @@ class TabStripComponent {
4417
4494
  </ul>
4418
4495
  <span
4419
4496
  role="button"
4420
- *ngIf="hasScrollButtons"
4497
+ *ngIf="hasScrollButtons.visible && hasScrollButtons.position === 'end'"
4498
+ #prevScrollButton
4499
+ kendoTabStripScrollableButton
4500
+ [scrollable]="scrollable"
4501
+ [tabPosition]="tabPosition"
4502
+ [prev]="true"
4503
+ [title]="localization.get('previousTabButton')"
4504
+ (tabScroll)="tabScroll.emit($event)"
4505
+ class="k-icon-button k-button k-button-flat k-button-flat-base"
4506
+ [ngClass]="{
4507
+ 'k-button-sm': size === 'small',
4508
+ 'k-button-md': size === 'medium' || !size,
4509
+ 'k-button-lg': size === 'large'
4510
+ }"
4511
+ (onClick)="onScrollButtonClick($event)"></span>
4512
+ <span
4513
+ role="button"
4514
+ *ngIf="hasScrollButtons.visible && hasScrollButtons.position !== 'start'"
4421
4515
  #nextScrollButton
4422
4516
  kendoTabStripScrollableButton
4423
4517
  [scrollable]="scrollable"
@@ -4425,7 +4519,12 @@ class TabStripComponent {
4425
4519
  [prev]="false"
4426
4520
  [title]="localization.get('nextTabButton')"
4427
4521
  (tabScroll)="tabScroll.emit($event)"
4428
- class="k-icon-button k-button k-button-md k-button-flat k-button-flat-base"
4522
+ class="k-icon-button k-button k-button-flat k-button-flat-base"
4523
+ [ngClass]="{
4524
+ 'k-button-sm': size === 'small',
4525
+ 'k-button-md': size === 'medium' || !size,
4526
+ 'k-button-lg': size === 'large'
4527
+ }"
4429
4528
  (onClick)="onScrollButtonClick($event)"></span>
4430
4529
  </div>
4431
4530
  </ng-template>
@@ -4508,10 +4607,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
4508
4607
  <ng-container *ngTemplateOutlet="heading"></ng-container>
4509
4608
  </ng-container>
4510
4609
  <ng-template #heading>
4511
- <div class="k-tabstrip-items-wrapper" [ngClass]="itemsWrapperClass">
4610
+ <div class="k-tabstrip-items-wrapper" [class.k-tabstrip-items-wrapper-scroll]="mouseScrollEnabled" [ngClass]="itemsWrapperClass">
4512
4611
  <span
4513
4612
  role="button"
4514
- *ngIf="hasScrollButtons"
4613
+ *ngIf="hasScrollButtons.visible && hasScrollButtons.position !== 'end'"
4515
4614
  #prevScrollButton
4516
4615
  kendoTabStripScrollableButton
4517
4616
  [scrollable]="scrollable"
@@ -4519,9 +4618,30 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
4519
4618
  [prev]="true"
4520
4619
  [title]="localization.get('previousTabButton')"
4521
4620
  (tabScroll)="tabScroll.emit($event)"
4522
- class="k-icon-button k-button k-button-md k-button-flat k-button-flat-base"
4523
- (onClick)="onScrollButtonClick($event)">
4524
- </span>
4621
+ class="k-icon-button k-button k-button-flat k-button-flat-base"
4622
+ [ngClass]="{
4623
+ 'k-button-sm': size === 'small',
4624
+ 'k-button-md': size === 'medium' || !size,
4625
+ 'k-button-lg': size === 'large'
4626
+ }"
4627
+ (onClick)="onScrollButtonClick($event)"></span>
4628
+ <span
4629
+ role="button"
4630
+ *ngIf="hasScrollButtons.visible && hasScrollButtons.position === 'start'"
4631
+ #nextScrollButton
4632
+ kendoTabStripScrollableButton
4633
+ [scrollable]="scrollable"
4634
+ [tabPosition]="tabPosition"
4635
+ [prev]="false"
4636
+ [title]="localization.get('nextTabButton')"
4637
+ (tabScroll)="tabScroll.emit($event)"
4638
+ class="k-icon-button k-button k-button-flat k-button-flat-base"
4639
+ [ngClass]="{
4640
+ 'k-button-sm': size === 'small',
4641
+ 'k-button-md': size === 'medium' || !size,
4642
+ 'k-button-lg': size === 'large'
4643
+ }"
4644
+ (onClick)="onScrollButtonClick($event)"></span>
4525
4645
  <ul role="tablist" #tablist
4526
4646
  class="k-reset k-tabstrip-items"
4527
4647
  [ngClass]="{
@@ -4529,7 +4649,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
4529
4649
  'k-tabstrip-items-center': tabAlignment === 'center',
4530
4650
  'k-tabstrip-items-end': tabAlignment === 'end',
4531
4651
  'k-tabstrip-items-stretched': tabAlignment === 'stretched',
4532
- 'k-tabstrip-items-justify': tabAlignment === 'justify'
4652
+ 'k-tabstrip-items-justify': tabAlignment === 'justify',
4653
+ 'k-tabstrip-items-scroll': mouseScrollEnabled
4533
4654
  }"
4534
4655
  [attr.aria-orientation]="tabPosition === 'left' || tabPosition === 'right' ? 'vertical' : 'horizontal'"
4535
4656
  >
@@ -4556,7 +4677,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
4556
4677
  </ul>
4557
4678
  <span
4558
4679
  role="button"
4559
- *ngIf="hasScrollButtons"
4680
+ *ngIf="hasScrollButtons.visible && hasScrollButtons.position === 'end'"
4681
+ #prevScrollButton
4682
+ kendoTabStripScrollableButton
4683
+ [scrollable]="scrollable"
4684
+ [tabPosition]="tabPosition"
4685
+ [prev]="true"
4686
+ [title]="localization.get('previousTabButton')"
4687
+ (tabScroll)="tabScroll.emit($event)"
4688
+ class="k-icon-button k-button k-button-flat k-button-flat-base"
4689
+ [ngClass]="{
4690
+ 'k-button-sm': size === 'small',
4691
+ 'k-button-md': size === 'medium' || !size,
4692
+ 'k-button-lg': size === 'large'
4693
+ }"
4694
+ (onClick)="onScrollButtonClick($event)"></span>
4695
+ <span
4696
+ role="button"
4697
+ *ngIf="hasScrollButtons.visible && hasScrollButtons.position !== 'start'"
4560
4698
  #nextScrollButton
4561
4699
  kendoTabStripScrollableButton
4562
4700
  [scrollable]="scrollable"
@@ -4564,7 +4702,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
4564
4702
  [prev]="false"
4565
4703
  [title]="localization.get('nextTabButton')"
4566
4704
  (tabScroll)="tabScroll.emit($event)"
4567
- class="k-icon-button k-button k-button-md k-button-flat k-button-flat-base"
4705
+ class="k-icon-button k-button k-button-flat k-button-flat-base"
4706
+ [ngClass]="{
4707
+ 'k-button-sm': size === 'small',
4708
+ 'k-button-md': size === 'medium' || !size,
4709
+ 'k-button-lg': size === 'large'
4710
+ }"
4568
4711
  (onClick)="onScrollButtonClick($event)"></span>
4569
4712
  </div>
4570
4713
  </ng-template>
@@ -4606,6 +4749,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
4606
4749
  type: Input
4607
4750
  }], scrollable: [{
4608
4751
  type: Input
4752
+ }], size: [{
4753
+ type: Input
4609
4754
  }], closeIcon: [{
4610
4755
  type: Input
4611
4756
  }], closeIconClass: [{
@@ -4625,7 +4770,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
4625
4770
  args: ['class.k-tabstrip']
4626
4771
  }, {
4627
4772
  type: HostBinding,
4628
- args: ['class.k-header']
4773
+ args: ['class.k-tabstrip-md']
4629
4774
  }], tabsAtTop: [{
4630
4775
  type: HostBinding,
4631
4776
  args: ['class.k-tabstrip-top']
@@ -4644,21 +4789,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
4644
4789
  }], tabStripScrollable: [{
4645
4790
  type: HostBinding,
4646
4791
  args: ['class.k-tabstrip-scrollable']
4792
+ }], tabStripScrollableOverlay: [{
4793
+ type: HostBinding,
4794
+ args: ['class.k-tabstrip-scrollable-overlay']
4647
4795
  }], tabs: [{
4648
4796
  type: ContentChildren,
4649
4797
  args: [TabStripTabComponent]
4650
4798
  }], tablist: [{
4651
4799
  type: ViewChild,
4652
- args: ['tablist', { static: false }]
4800
+ args: ['tablist']
4653
4801
  }], tabHeaderContainers: [{
4654
4802
  type: ViewChildren,
4655
4803
  args: ['tabHeaderContainer', { read: ElementRef }]
4656
4804
  }], prevScrollButton: [{
4657
4805
  type: ViewChild,
4658
- args: ['prevScrollButton', { static: false }]
4806
+ args: ['prevScrollButton']
4659
4807
  }], nextScrollButton: [{
4660
4808
  type: ViewChild,
4661
- args: ['nextScrollButton', { static: false }]
4809
+ args: ['nextScrollButton']
4662
4810
  }] } });
4663
4811
 
4664
4812
  /**
package/index.d.ts CHANGED
@@ -22,8 +22,9 @@ export { TabAlignment } from './tabstrip/models/tab-alignment';
22
22
  export { TabStripScrollButtonsVisibility } from './tabstrip/models/scroll-buttons-visibility';
23
23
  export { LocalizedTabStripMessagesDirective } from './tabstrip/localization/localized-messages.directive';
24
24
  export { TabStripCustomMessagesComponent } from './tabstrip/localization/custom-messages.component';
25
- export { TabStripScrollableSettings } from './tabstrip/models/scrollable-settings';
25
+ export { TabStripScrollableSettings, TabStripScrollButtonsPosition } from './tabstrip/models/scrollable-settings';
26
26
  export { TabTemplateDirective } from './tabstrip/directives/tab.directive';
27
+ export { TabStripSize } from './tabstrip/models/size';
27
28
  export * from './tabstrip/events';
28
29
  export { DrawerComponent } from './drawer/drawer.component';
29
30
  export { DrawerContainerComponent } from './drawer/drawer-container.component';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@progress/kendo-angular-layout",
3
- "version": "17.3.0-develop.2",
3
+ "version": "18.0.0-develop.10",
4
4
  "description": "Kendo UI for Angular Layout Package - a collection of components to create professional application layoyts",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "author": "Progress",
@@ -39,17 +39,17 @@
39
39
  "@angular/core": "16 - 19",
40
40
  "@angular/platform-browser": "16 - 19",
41
41
  "@progress/kendo-licensing": "^1.0.2",
42
- "@progress/kendo-angular-common": "17.3.0-develop.2",
43
- "@progress/kendo-angular-l10n": "17.3.0-develop.2",
44
- "@progress/kendo-angular-progressbar": "17.3.0-develop.2",
45
- "@progress/kendo-angular-icons": "17.3.0-develop.2",
46
- "@progress/kendo-angular-buttons": "17.3.0-develop.2",
47
- "@progress/kendo-angular-intl": "17.3.0-develop.2",
42
+ "@progress/kendo-angular-common": "18.0.0-develop.10",
43
+ "@progress/kendo-angular-l10n": "18.0.0-develop.10",
44
+ "@progress/kendo-angular-progressbar": "18.0.0-develop.10",
45
+ "@progress/kendo-angular-icons": "18.0.0-develop.10",
46
+ "@progress/kendo-angular-buttons": "18.0.0-develop.10",
47
+ "@progress/kendo-angular-intl": "18.0.0-develop.10",
48
48
  "rxjs": "^6.5.3 || ^7.0.0"
49
49
  },
50
50
  "dependencies": {
51
51
  "tslib": "^2.3.1",
52
- "@progress/kendo-angular-schematics": "17.3.0-develop.2",
52
+ "@progress/kendo-angular-schematics": "18.0.0-develop.10",
53
53
  "@progress/kendo-draggable": "^3.0.2"
54
54
  },
55
55
  "schematics": "./schematics/collection.json",
@@ -14,14 +14,14 @@ export interface TabStripScrollableSettings {
14
14
  */
15
15
  enabled?: boolean;
16
16
  /**
17
- * Determines whether the TabStrip scroll buttons visibility mode. The possible options are:
17
+ * Determines the TabStrip scroll buttons visibility mode. The possible options are:
18
18
  * - 'auto'(default) - The scroll buttons will be rendered only when the tabs list overflows its container.
19
19
  * - 'visible' - The scroll buttons will be always visible.
20
20
  * - 'hidden' - No scroll buttons will be rendered.
21
21
  */
22
22
  scrollButtons?: TabStripScrollButtonsVisibility;
23
23
  /**
24
- * Determines whether the TabStrip will be scrolled with the mouse wheel.
24
+ * Determines whether the TabStrip will be scrolled with the mouse or other pointer devices such as touchpads and touch screens.
25
25
  * @default true
26
26
  */
27
27
  mouseScroll?: boolean;
@@ -31,8 +31,8 @@ export interface TabStripScrollableSettings {
31
31
  */
32
32
  buttonScrollSpeed?: number;
33
33
  /**
34
- * Sets the tab list scroll speed in pixels when scrolling via the mouse wheel.
35
- * @default 10
34
+ * Deprecated in v.18.0.0 and will be removed in v.19.0.0 of the `@progress/kendo-angular-layout` package.
35
+ * The scroll speed will naturally follow the user behavior and concrete device specifics.
36
36
  */
37
37
  mouseScrollSpeed?: number;
38
38
  /**
@@ -57,7 +57,18 @@ export interface TabStripScrollableSettings {
57
57
  * The input can take either an [existing Kendo SVG icon](slug:svgicon_list) or a custom one.
58
58
  */
59
59
  nextSVGButtonIcon?: SVGIcon;
60
+ /**
61
+ * Determines the TabStrip scroll buttons position. The possible options are:
62
+ * - 'start'&mdash;The scroll buttons will be rendered at the start before all tabs.
63
+ * - 'end'&mdash;The scroll buttons will be rendered at the end after all tabs.
64
+ * - 'split'(default)&mdash;The scroll buttons will be rendered at each side of the tabs.
65
+ */
66
+ scrollButtonsPosition?: TabStripScrollButtonsPosition;
60
67
  }
68
+ /**
69
+ * The available options for the `scrollButtonsPosition` option.
70
+ */
71
+ export type TabStripScrollButtonsPosition = 'start' | 'end' | 'split';
61
72
  /**
62
73
  * @hidden
63
74
  */
@@ -0,0 +1,8 @@
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
+ /**
6
+ * Specifies the possible sizes of the TabStrip ([see example](slug:sizing_tabstrip)).
7
+ */
8
+ export type TabStripSize = 'small' | 'medium' | 'large' | 'none';