@progress/kendo-angular-scrollview
Version:
A ScrollView Component for Angular
1,046 lines (1,026 loc) • 40.3 kB
JavaScript
/**-----------------------------------------------------------------------------------------
* Copyright © 2025 Progress Software Corporation. All rights reserved.
* Licensed under commercial license. See LICENSE.md in the project root for more information
*-------------------------------------------------------------------------------------------*/
import * as i0 from '@angular/core';
import { EventEmitter, Component, Input, Output, Directive, forwardRef, TemplateRef, ContentChild, ViewChild, HostBinding, NgModule } from '@angular/core';
import { trigger, state, style, transition, animate } from '@angular/animations';
import { Keys, DraggableDirective } from '@progress/kendo-angular-common';
import { validatePackage } from '@progress/kendo-licensing';
import * as i1 from '@progress/kendo-angular-l10n';
import { ComponentMessages, LocalizationService, L10N_PREFIX } from '@progress/kendo-angular-l10n';
import { chevronLeftIcon, chevronRightIcon } from '@progress/kendo-svg-icons';
import { Subscription } from 'rxjs';
import { NgFor, NgClass, NgStyle, NgTemplateOutlet, NgIf } from '@angular/common';
import { IconWrapperComponent, IconsService } from '@progress/kendo-angular-icons';
/**
* @hidden
*/
var Dir;
(function (Dir) {
Dir[Dir["Next"] = 1] = "Next";
Dir[Dir["Prev"] = -1] = "Prev";
})(Dir || (Dir = {}));
/**
* @hidden
*/
const packageMetadata = {
name: '@progress/kendo-angular-scrollview',
productName: 'Kendo UI for Angular',
productCode: 'KENDOUIANGULAR',
productCodes: ['KENDOUIANGULAR'],
publishDate: 1743579883,
version: '18.4.0',
licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
};
/** @hidden */
const iterator = getIterator();
// TODO: Move to kendo-common
function getIterator() {
if (typeof Symbol === 'function' && Symbol.iterator) {
return Symbol.iterator;
}
const keys = Object.getOwnPropertyNames(Map.prototype);
const proto = Map.prototype;
for (let i = 0; i < keys.length; ++i) {
const key = keys[i];
if (key !== 'entries' && key !== 'size' && proto[key] === proto.entries) {
return key;
}
}
}
const EMPTY_OBJ = {};
/**
* @hidden
*/
class DataResultIterator {
source;
index;
endless;
pageIndex;
rtl = false;
constructor(source, index, endless, pageIndex, rtl) {
this.source = source ? source : [];
this.index = index ? index : 0;
this.endless = endless;
this.pageIndex = pageIndex;
this.rtl = rtl;
}
get data() {
const itemCount = this.total;
let result;
if (this.endless) {
result = [
this.source[(this.index - 1 + itemCount) % itemCount],
this.source[this.index % itemCount],
this.source[(this.index + 1 + itemCount) % itemCount]
];
}
else {
const data = [EMPTY_OBJ, ...this.source, EMPTY_OBJ];
result = data.slice(this.index, this.index + 3);
}
if (this.pageIndex !== null) {
const isForward = this.pageIndex > this.index;
result[isForward ? 2 : 0] = this.source[this.pageIndex];
}
return this.rtl ? result.reverse() : result;
}
get total() {
return this.source.length;
}
canMoveNext() {
return (this.endless || (this.index < this.total - 1));
}
canMovePrev() {
return (this.endless || this.index > 0);
}
[iterator]() {
return this.data[iterator]();
}
}
/**
* @hidden
*/
class DataCollection {
accessor;
constructor(accessor) {
this.accessor = accessor;
}
get length() { return this.accessor().data.length; }
get total() { return this.accessor().total; }
item(index) {
return this.accessor().data[index];
}
canMoveNext() {
return this.accessor().canMoveNext();
}
canMovePrev() {
return this.accessor().canMovePrev();
}
[Symbol.iterator]() {
return this.accessor()[Symbol.iterator]();
}
}
/* eslint-disable @typescript-eslint/no-explicit-any */
/**
* @hidden
*/
class ScrollViewPagerComponent {
localization;
activeIndex;
data;
pagerIndexChange = new EventEmitter();
constructor(localization) {
this.localization = localization;
}
itemClass(idx) {
return {
'k-primary': idx === this.activeIndex
};
}
indexChange(selectedIndex) {
this.pagerIndexChange.emit(selectedIndex);
}
pagerButtonLabel(itemIndex) {
const localizationMsg = this.localization.get('pagerButtonLabel') || '';
return this.replaceMessagePlaceholder(localizationMsg, 'itemIndex', itemIndex.toString());
}
replaceMessagePlaceholder(message, name, value) {
return message.replace(new RegExp(`\{\\s*${name}\\s*\}`, 'g'), value);
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ScrollViewPagerComponent, deps: [{ token: i1.LocalizationService }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ScrollViewPagerComponent, isStandalone: true, selector: "kendo-scrollview-pager", inputs: { activeIndex: "activeIndex", data: "data" }, outputs: { pagerIndexChange: "pagerIndexChange" }, ngImport: i0, template: `
<div class="k-scrollview-nav">
<span [attr.aria-label]="pagerButtonLabel(i + 1)" role="button" class="k-link" *ngFor="let item of data; let i = index"
[ngClass]="itemClass(i)"
(click)="indexChange(i)">
</span>
</div>
`, isInline: true, dependencies: [{ kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ScrollViewPagerComponent, decorators: [{
type: Component,
args: [{
selector: 'kendo-scrollview-pager',
template: `
<div class="k-scrollview-nav">
<span [attr.aria-label]="pagerButtonLabel(i + 1)" role="button" class="k-link" *ngFor="let item of data; let i = index"
[ngClass]="itemClass(i)"
(click)="indexChange(i)">
</span>
</div>
`,
standalone: true,
imports: [NgFor, NgClass]
}]
}], ctorParameters: function () { return [{ type: i1.LocalizationService }]; }, propDecorators: { activeIndex: [{
type: Input
}], data: [{
type: Input
}], pagerIndexChange: [{
type: Output
}] } });
/**
* @hidden
*/
class ScrollViewMessages extends ComponentMessages {
/**
* The label of the buttons in the ScrollView pager. By default they follow the pattern 'Item {itemIndex}'.
* The default label text when the current item is 1 will be 'Item 1'.
*/
pagerButtonLabel;
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ScrollViewMessages, deps: null, target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: ScrollViewMessages, selector: "kendo-scrollview-messages-base", inputs: { pagerButtonLabel: "pagerButtonLabel" }, usesInheritance: true, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ScrollViewMessages, decorators: [{
type: Directive,
args: [{
// eslint-disable-next-line @angular-eslint/directive-selector
selector: 'kendo-scrollview-messages-base'
}]
}], propDecorators: { pagerButtonLabel: [{
type: Input
}] } });
/**
* @hidden
*/
class LocalizedMessagesDirective extends ScrollViewMessages {
service;
constructor(service) {
super();
this.service = service;
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: LocalizedMessagesDirective, deps: [{ token: i1.LocalizationService }], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: LocalizedMessagesDirective, isStandalone: true, selector: "[kendoScrollViewLocalizedMessages]", providers: [
{
provide: ScrollViewMessages,
useExisting: forwardRef(() => LocalizedMessagesDirective)
}
], usesInheritance: true, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: LocalizedMessagesDirective, decorators: [{
type: Directive,
args: [{
providers: [
{
provide: ScrollViewMessages,
useExisting: forwardRef(() => LocalizedMessagesDirective)
}
],
selector: '[kendoScrollViewLocalizedMessages]',
standalone: true
}]
}], ctorParameters: function () { return [{ type: i1.LocalizationService }]; } });
/* eslint-disable @typescript-eslint/no-inferrable-types */
/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable @typescript-eslint/no-explicit-any */
let idx = 0;
/**
* Represents the [Kendo UI ScrollView component for Angular]({% slug overview_scrollview %}).
*
* @example
* ```ts
*
* _@Component({
* selector: 'my-app',
* template: `
* <kendo-scrollview
* [data]="items"
* [width]="width"
* [height]="height"
* [endless]="endless"
* [pageable]="pageable">
* <ng-template let-item="item">
* <h2 class="demo-title">{{item.title}}</h2>
* <img src='{{item.url}}' alt='{{item.title}}' [ngStyle]="{minWidth: width}" draggable="false" />
* </ng-template>
* </kendo-scrollview>
* `,
* styles: [`
* .k-scrollview-wrap {
* margin: 0 auto;
* }
* .demo-title {
* position: absolute;
* top: 0;
* left: 0;
* right: 0;
* margin: 0;
* padding: 15px;
* color: #fff;
* background-color: rgba(0,0,0,.4);
* text-align: center;
* font-size: 24px;
* }
* `]
* })
*
* class AppComponent {
* public width: string = "600px";
* public height: string = "400px";
* public endless: boolean = false;
* public pageable: boolean = false;
* public items: any[] = [
* { title: 'Flower', url: 'https://bit.ly/2cJjYuB' },
* { title: 'Mountain', url: 'https://bit.ly/2cTBNaL' },
* { title: 'Sky', url: 'https://bit.ly/2cJl3Cx' }
* ];
* }
* ```
*/
class ScrollViewComponent {
element;
localization;
ngZone;
renderer;
/**
* @hidden
*/
chevronLeftIcon = chevronLeftIcon;
/**
* @hidden
*/
chevronRightIcon = chevronRightIcon;
/**
* Provides the data source for the ScrollView ([see example]({% slug datasources_scrollview %})).
*/
data = [];
/**
* Represents the current item index ([see example]({% slug activeitems_scrollview %})).
*/
set activeIndex(value) {
this.index = this._activeIndex = value;
}
get activeIndex() {
return this._activeIndex;
}
/**
* Sets the width of the ScrollView ([see example]({% slug dimensions_scrollview %})).
* By default, the width is not set and you have to explicitly define the `width` value.
*/
width;
/**
* Sets the height of the ScrollView ([see example]({% slug dimensions_scrollview %})).
* By default, the height is not set and you have to explicitly define the `height` value.
*/
height;
/**
* Enables or disables the endless scrolling mode in which the data source items are endlessly looped
* ([see example]({% slug endlessscrolling_scrollview %})). By default, `endless` is set to `false`
* and the endless scrolling mode is disabled.
*/
endless = false;
/**
* Sets `pagerOverlay` to one of three possible values: `dark`, `light` or `none`.
* By default, the pager overlay is set to `none`.
*/
pagerOverlay = 'none';
/**
* Enables or disables the built-in animations ([see example]({% slug animations_scrollview %})).
* By default, `animate` is set to `true` and animations are enabled.
*/
animate = true;
/**
* Enables or disables the built-in pager ([see example]({% slug paging_scrollview %})).
* By default, `pageable` is set to `false` and paging is disabled.
*/
pageable = false;
/**
* Enables or disables the built-in navigation arrows ([see example]({% slug arrows_scrollview %})).
* By default, `arrows` is set to `false` and arrows are disabled.
*/
arrows = false;
/**
* Fires after the current item is changed.
*/
itemChanged = new EventEmitter();
/**
* Fires after the activeIndex has changed. Allows for two-way binding of the activeIndex property.
*/
activeIndexChange = new EventEmitter();
itemTemplateRef;
itemWrapper;
prevButton;
nextButton;
scrollViewClass = true;
scrollViewRole = 'application';
scrollViewRoleDescription = 'carousel';
get scrollViewLightOverlayClass() {
return this.pagerOverlay === 'light';
}
get scrollViewDarkOverlayClass() {
return this.pagerOverlay === 'dark';
}
get hostWidth() { return this.width; }
get hostHeight() { return this.height; }
tabIndex = 0;
ariaLive = 'assertive';
get dir() {
return this.direction;
}
touchAction = 'pan-y pinch-zoom';
animationState = null;
view = new DataCollection(() => new DataResultIterator(this.data, this.activeIndex, this.endless, this.pageIndex, this.isRTL));
/**
* @hidden
*/
scrollviewId;
isDataSourceEmpty = false;
subs = new Subscription();
_activeIndex = 0;
index = 0;
initialTouchCoordinate;
pageIndex = null;
transforms = ['translateX(-100%)', 'translateX(0%)', 'translateX(100%)'];
get direction() {
return this.localization.rtl ? 'rtl' : 'ltr';
}
constructor(element, localization, ngZone, renderer) {
this.element = element;
this.localization = localization;
this.ngZone = ngZone;
this.renderer = renderer;
validatePackage(packageMetadata);
}
ngOnInit() {
this.subs.add(this.renderer.listen(this.element.nativeElement, 'keydown', event => this.keyDown(event)));
if (this.arrows) {
this.scrollviewId = `k-scrollview-wrap-${++idx}`;
}
}
ngOnDestroy() {
this.subs.unsubscribe();
}
ngOnChanges(_) {
if (this.data && this.data.length === 0) {
this.activeIndex = Math.max(Math.min(this.activeIndex, this.view.total - 1), 0);
}
}
/**
* Navigates the ScrollView to the previous item.
*/
prev() {
this.navigate(Dir.Prev);
}
/**
* Navigates the ScrollView to the next item.
*/
next() {
this.navigate(Dir.Next);
}
/**
* @hidden
*/
transitionEndHandler(e) {
this.animationState = null;
if (e.toState === 'left' || e.toState === 'right') {
if (this.pageIndex !== null) {
this.activeIndex = this.pageIndex;
this.pageIndex = null;
}
this.activeIndex = this.index;
this.activeIndexChange.emit(this.activeIndex);
this.itemChanged.emit({ index: this.activeIndex, item: this.view.item(1) });
}
}
/**
* @hidden
*/
handlePress(e) {
this.initialTouchCoordinate = e.pageX;
}
/**
* @hidden
*/
handleDrag(e) {
const deltaX = e.pageX - this.initialTouchCoordinate;
if (!this.animationState && !this.isDragForbidden(deltaX) && this.draggedInsideBounds(deltaX)) {
this.renderer.setStyle(this.itemWrapper.nativeElement, 'transform', `translateX(${deltaX}px)`);
}
}
/**
* @hidden
*/
handleRelease(e) {
const deltaX = e.pageX - this.initialTouchCoordinate;
if (this.isDragForbidden(deltaX)) {
return;
}
this.ngZone.run(() => {
if (this.draggedEnoughToNavigate(deltaX)) {
if (this.isRTL) {
this.changeIndex(deltaX < 0 ? Dir.Prev : Dir.Next);
}
else {
this.changeIndex(deltaX > 0 ? Dir.Prev : Dir.Next);
}
if (!this.animate) {
this.renderer.removeStyle(this.itemWrapper.nativeElement, 'transform');
this.activeIndexChange.emit(this.activeIndex);
this.itemChanged.emit({ index: this.activeIndex, item: this.view.item(1) });
}
}
else {
if (this.animate && deltaX) {
this.animationState = 'center';
}
else {
this.renderer.removeStyle(this.itemWrapper.nativeElement, 'transform');
}
}
});
}
/**
* @hidden
*/
pageChange(idx) {
if (!this.animationState && this.activeIndex !== idx) {
if (this.animate) {
this.pageIndex = idx;
if (this.isRTL) {
this.animationState = (this.pageIndex > this.index ? 'right' : 'left');
}
else {
this.animationState = (this.pageIndex > this.index ? 'left' : 'right');
}
}
else {
this.activeIndex = idx;
}
}
}
/**
* @hidden
*/
inlineListItemStyles(idx) {
return {
'height': this.height,
'transform': this.transforms[idx],
'width': '100%',
'position': 'absolute',
'top': '0',
'left': '0'
};
}
/**
* @hidden
*/
displayLeftArrow() {
let isNotBorderItem;
if (this.isRTL) {
isNotBorderItem = this.activeIndex + 1 < this.view.total;
}
else {
isNotBorderItem = this.activeIndex > 0;
}
return (this.endless || isNotBorderItem) && this.view.total > 0;
}
/**
* @hidden
*/
leftArrowClick() {
if (this.isRTL) {
this.next();
}
else {
this.prev();
}
}
/**
* @hidden
*/
displayRightArrow() {
let isNotBorderItem;
if (this.isRTL) {
isNotBorderItem = this.activeIndex > 0;
}
else {
isNotBorderItem = this.activeIndex + 1 < this.view.total;
}
return (this.endless || isNotBorderItem) && this.view.total > 0;
}
/**
* @hidden
*/
rightArrowClick() {
if (this.isRTL) {
this.prev();
}
else {
this.next();
}
}
draggedInsideBounds(deltaX) {
return Math.abs(deltaX) <= this.element.nativeElement.offsetWidth;
}
draggedEnoughToNavigate(deltaX) {
return Math.abs(deltaX) > (this.element.nativeElement.offsetWidth / 2);
}
isDragForbidden(deltaX) {
let pastEnd;
if (this.isRTL) {
pastEnd = deltaX < 0 && deltaX !== 0;
}
else {
pastEnd = deltaX > 0 && deltaX !== 0;
}
const isEndReached = ((this.activeIndex === 0 && pastEnd) || (this.activeIndex === this.view.total - 1 && !pastEnd));
return !this.endless && isEndReached;
}
keyDown(e) {
const keyCode = e.keyCode;
if (keyCode === Keys.ArrowLeft) {
if (this.isRTL) {
this.next();
return;
}
this.prev();
}
else if (keyCode === Keys.ArrowRight) {
if (this.isRTL) {
this.prev();
return;
}
this.next();
}
if (this.arrows && keyCode === Keys.Space || keyCode === Keys.Enter) {
const prevButton = this.prevButton?.nativeElement;
const nextButton = this.nextButton?.nativeElement;
const activeElement = document.activeElement;
const isPrevButtonFocused = activeElement === prevButton;
const isNextButtonFocused = activeElement === nextButton;
if (isPrevButtonFocused) {
if (this.isRTL) {
this.next();
return;
}
this.prev();
}
else if (isNextButtonFocused) {
if (this.isRTL) {
this.prev();
return;
}
this.next();
}
}
}
navigate(direction) {
if (this.isDataSourceEmpty || this.animationState) {
return;
}
this.changeIndex(direction);
if (!this.animate) {
this.activeIndexChange.emit(this.activeIndex);
this.itemChanged.emit({ index: this.activeIndex, item: this.view.item(1) });
}
}
changeIndex(direction) {
if (direction === Dir.Next && this.view.canMoveNext()) {
this.index = (this.index + 1) % this.view.total;
if (this.animate) {
this.animationState = this.isRTL ? 'right' : 'left';
}
else {
this.activeIndex = this.index;
}
}
else if (direction === Dir.Prev && this.view.canMovePrev()) {
this.index = this.index === 0 ? this.view.total - 1 : this.index - 1;
if (this.animate) {
this.animationState = this.isRTL ? 'left' : 'right';
}
else {
this.activeIndex = this.index;
}
}
}
get isRTL() {
return this.direction === 'rtl';
}
get prevButtonArrowIcon() {
return this.direction === 'ltr' ? 'chevron-left' : 'chevron-right';
}
get nextButtonArrowIcon() {
return this.direction === 'ltr' ? 'chevron-right' : 'chevron-left';
}
get prevButtonArrowSVGIcon() {
return this.direction === 'ltr' ? this.chevronLeftIcon : this.chevronRightIcon;
}
get nextButtonArrowSVGIcon() {
return this.direction === 'ltr' ? this.chevronRightIcon : this.chevronLeftIcon;
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ScrollViewComponent, deps: [{ token: i0.ElementRef }, { token: i1.LocalizationService }, { token: i0.NgZone }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ScrollViewComponent, isStandalone: true, selector: "kendo-scrollview", inputs: { data: "data", activeIndex: "activeIndex", width: "width", height: "height", endless: "endless", pagerOverlay: "pagerOverlay", animate: "animate", pageable: "pageable", arrows: "arrows" }, outputs: { itemChanged: "itemChanged", activeIndexChange: "activeIndexChange" }, host: { properties: { "class.k-scrollview": "this.scrollViewClass", "attr.role": "this.scrollViewRole", "attr.aria-roledescription": "this.scrollViewRoleDescription", "class.k-scrollview-light": "this.scrollViewLightOverlayClass", "class.k-scrollview-dark": "this.scrollViewDarkOverlayClass", "style.width": "this.hostWidth", "style.height": "this.hostHeight", "attr.tabindex": "this.tabIndex", "attr.aria-live": "this.ariaLive", "attr.dir": "this.dir", "style.touch-action": "this.touchAction" } }, providers: [
LocalizationService,
{
provide: L10N_PREFIX,
useValue: 'kendo.scrollview'
}
], queries: [{ propertyName: "itemTemplateRef", first: true, predicate: TemplateRef, descendants: true }], viewQueries: [{ propertyName: "itemWrapper", first: true, predicate: ["itemWrapper"], descendants: true }, { propertyName: "prevButton", first: true, predicate: ["prevButton"], descendants: true }, { propertyName: "nextButton", first: true, predicate: ["nextButton"], descendants: true }], exportAs: ["kendoScrollView"], usesOnChanges: true, ngImport: i0, template: `
<ng-container kendoScrollViewLocalizedMessages
i18n-pagerButtonLabel="kendo.scrollview.pagerButtonLabel|The label for the buttons inside the ScrollView Pager"
pagerButtonLabel="{{ 'Item {itemIndex}' }}">
<ng-container>
<div class="k-scrollview-wrap k-scrollview-animate"
#itemWrapper
role="list"
[id]="scrollviewId"
[ ]="animationState"
( .done)="transitionEndHandler($event)"
kendoDraggable
(kendoDrag)="handleDrag($event)"
(kendoPress)="handlePress($event)"
(kendoRelease)="handleRelease($event)"
>
<div class="k-scrollview-view"
*ngFor="let item of view;let i=index"
role="listitem"
aria-roledescription="slide"
[ngStyle]="inlineListItemStyles(i)"
[attr.aria-hidden]="i !== 1"
>
<ng-template
[ngTemplateOutlet]="itemTemplateRef"
[ngTemplateOutletContext]="{ item: item }">
</ng-template>
</div>
</div>
<div class='k-scrollview-elements'
[ngStyle]="{'height': height}"
*ngIf="!isDataSourceEmpty && (pageable||arrows)">
<span
#prevButton
class="k-scrollview-prev"
role="button"
[attr.aria-controls]="scrollviewId"
aria-label="previous"
*ngIf="arrows && displayLeftArrow()"
(click)="leftArrowClick()">
<kendo-icon-wrapper
size="xxxlarge"
[name]="prevButtonArrowIcon"
[svgIcon]="prevButtonArrowSVGIcon"
>
</kendo-icon-wrapper>
</span>
<span
#nextButton
class="k-scrollview-next"
role="button"
[attr.aria-controls]="scrollviewId"
aria-label="next"
*ngIf="arrows && displayRightArrow()"
(click)="rightArrowClick()">
<kendo-icon-wrapper
size="xxxlarge"
[name]="nextButtonArrowIcon"
[svgIcon]="nextButtonArrowSVGIcon"
>
</kendo-icon-wrapper>
</span>
<kendo-scrollview-pager
class='k-scrollview-nav-wrap'
*ngIf="pageable"
(pagerIndexChange)="pageChange($event)"
[data]="data"
[activeIndex]="activeIndex">
</kendo-scrollview-pager>
</div>
<div class="k-sr-only" aria-live="polite"></div>
`, isInline: true, dependencies: [{ kind: "directive", type: LocalizedMessagesDirective, selector: "[kendoScrollViewLocalizedMessages]" }, { kind: "directive", type: DraggableDirective, selector: "[kendoDraggable]", inputs: ["enableDrag"], outputs: ["kendoPress", "kendoDrag", "kendoRelease"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }, { kind: "component", type: ScrollViewPagerComponent, selector: "kendo-scrollview-pager", inputs: ["activeIndex", "data"], outputs: ["pagerIndexChange"] }], animations: [
trigger('animateTo', [
state('center, left, right', style({ transform: 'translateX(0)' })),
transition('* => right', [
animate('300ms ease-out', style({ transform: 'translateX(100%)' }))
]),
transition('* => left', [
animate('300ms ease-out', style({ transform: 'translateX(-100%)' }))
]),
transition('* => center', [
animate('300ms ease-out')
])
])
] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ScrollViewComponent, decorators: [{
type: Component,
args: [{
animations: [
trigger('animateTo', [
state('center, left, right', style({ transform: 'translateX(0)' })),
transition('* => right', [
animate('300ms ease-out', style({ transform: 'translateX(100%)' }))
]),
transition('* => left', [
animate('300ms ease-out', style({ transform: 'translateX(-100%)' }))
]),
transition('* => center', [
animate('300ms ease-out')
])
])
],
exportAs: 'kendoScrollView',
providers: [
LocalizationService,
{
provide: L10N_PREFIX,
useValue: 'kendo.scrollview'
}
],
selector: 'kendo-scrollview',
template: `
<ng-container kendoScrollViewLocalizedMessages
i18n-pagerButtonLabel="kendo.scrollview.pagerButtonLabel|The label for the buttons inside the ScrollView Pager"
pagerButtonLabel="{{ 'Item {itemIndex}' }}">
<ng-container>
<div class="k-scrollview-wrap k-scrollview-animate"
#itemWrapper
role="list"
[id]="scrollviewId"
[ ]="animationState"
( .done)="transitionEndHandler($event)"
kendoDraggable
(kendoDrag)="handleDrag($event)"
(kendoPress)="handlePress($event)"
(kendoRelease)="handleRelease($event)"
>
<div class="k-scrollview-view"
*ngFor="let item of view;let i=index"
role="listitem"
aria-roledescription="slide"
[ngStyle]="inlineListItemStyles(i)"
[attr.aria-hidden]="i !== 1"
>
<ng-template
[ngTemplateOutlet]="itemTemplateRef"
[ngTemplateOutletContext]="{ item: item }">
</ng-template>
</div>
</div>
<div class='k-scrollview-elements'
[ngStyle]="{'height': height}"
*ngIf="!isDataSourceEmpty && (pageable||arrows)">
<span
#prevButton
class="k-scrollview-prev"
role="button"
[attr.aria-controls]="scrollviewId"
aria-label="previous"
*ngIf="arrows && displayLeftArrow()"
(click)="leftArrowClick()">
<kendo-icon-wrapper
size="xxxlarge"
[name]="prevButtonArrowIcon"
[svgIcon]="prevButtonArrowSVGIcon"
>
</kendo-icon-wrapper>
</span>
<span
#nextButton
class="k-scrollview-next"
role="button"
[attr.aria-controls]="scrollviewId"
aria-label="next"
*ngIf="arrows && displayRightArrow()"
(click)="rightArrowClick()">
<kendo-icon-wrapper
size="xxxlarge"
[name]="nextButtonArrowIcon"
[svgIcon]="nextButtonArrowSVGIcon"
>
</kendo-icon-wrapper>
</span>
<kendo-scrollview-pager
class='k-scrollview-nav-wrap'
*ngIf="pageable"
(pagerIndexChange)="pageChange($event)"
[data]="data"
[activeIndex]="activeIndex">
</kendo-scrollview-pager>
</div>
<div class="k-sr-only" aria-live="polite"></div>
`,
standalone: true,
imports: [LocalizedMessagesDirective, DraggableDirective, NgFor, NgStyle, NgTemplateOutlet, NgIf, IconWrapperComponent, ScrollViewPagerComponent]
}]
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i1.LocalizationService }, { type: i0.NgZone }, { type: i0.Renderer2 }]; }, propDecorators: { data: [{
type: Input
}], activeIndex: [{
type: Input
}], width: [{
type: Input
}], height: [{
type: Input
}], endless: [{
type: Input
}], pagerOverlay: [{
type: Input
}], animate: [{
type: Input
}], pageable: [{
type: Input
}], arrows: [{
type: Input
}], itemChanged: [{
type: Output
}], activeIndexChange: [{
type: Output
}], itemTemplateRef: [{
type: ContentChild,
args: [TemplateRef]
}], itemWrapper: [{
type: ViewChild,
args: ['itemWrapper']
}], prevButton: [{
type: ViewChild,
args: ['prevButton']
}], nextButton: [{
type: ViewChild,
args: ['nextButton']
}], scrollViewClass: [{
type: HostBinding,
args: ['class.k-scrollview']
}], scrollViewRole: [{
type: HostBinding,
args: ['attr.role']
}], scrollViewRoleDescription: [{
type: HostBinding,
args: ['attr.aria-roledescription']
}], scrollViewLightOverlayClass: [{
type: HostBinding,
args: ['class.k-scrollview-light']
}], scrollViewDarkOverlayClass: [{
type: HostBinding,
args: ['class.k-scrollview-dark']
}], hostWidth: [{
type: HostBinding,
args: ['style.width']
}], hostHeight: [{
type: HostBinding,
args: ['style.height']
}], tabIndex: [{
type: HostBinding,
args: ['attr.tabindex']
}], ariaLive: [{
type: HostBinding,
args: ['attr.aria-live']
}], dir: [{
type: HostBinding,
args: ['attr.dir']
}], touchAction: [{
type: HostBinding,
args: ['style.touch-action']
}] } });
/**
* Custom component messages override default component messages
* ([see example](slug:rtl_scrollview#toc-custom-messages)).
*/
class CustomMessagesComponent extends ScrollViewMessages {
service;
constructor(service) {
super();
this.service = service;
}
get override() {
return true;
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CustomMessagesComponent, deps: [{ token: i1.LocalizationService }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: CustomMessagesComponent, isStandalone: true, selector: "kendo-scrollview-messages", providers: [
{
provide: ScrollViewMessages,
useExisting: forwardRef(() => CustomMessagesComponent)
}
], usesInheritance: true, ngImport: i0, template: ``, isInline: true });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CustomMessagesComponent, decorators: [{
type: Component,
args: [{
providers: [
{
provide: ScrollViewMessages,
useExisting: forwardRef(() => CustomMessagesComponent)
}
],
selector: 'kendo-scrollview-messages',
template: ``,
standalone: true
}]
}], ctorParameters: function () { return [{ type: i1.LocalizationService }]; } });
/**
* Utility array that contains all `@progress/kendo-angular-scrollview` related components and directives
*/
const KENDO_SCROLLVIEW = [
ScrollViewComponent,
CustomMessagesComponent
];
//IMPORTANT: NgModule export kept for backwards compatibility
/**
* Represents the [NgModule](link:site.data.urls.angular['ngmoduleapi'])
* definition for the ScrollView component.
*
* @example
*
* ```ts-no-run
* // Import the ScrollView module
* import { ScrollViewModule } from '@progress/kendo-angular-scrollview';
*
* // The browser platform with a compiler
* import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
*
* import { NgModule } from '@angular/core';
*
* // Import the app component
* import { AppComponent } from './app.component';
*
* // Define the app module
* _@NgModule({
* declarations: [AppComponent], // declare app component
* imports: [BrowserModule, ScrollViewModule], // import ScrollView module
* bootstrap: [AppComponent]
* })
* export class AppModule {}
*
* // Compile and launch the module
* platformBrowserDynamic().bootstrapModule(AppModule);
*
* ```
*/
class ScrollViewModule {
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ScrollViewModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: ScrollViewModule, imports: [ScrollViewComponent, CustomMessagesComponent], exports: [ScrollViewComponent, CustomMessagesComponent] });
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ScrollViewModule, providers: [IconsService], imports: [ScrollViewComponent] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ScrollViewModule, decorators: [{
type: NgModule,
args: [{
imports: [...KENDO_SCROLLVIEW],
exports: [...KENDO_SCROLLVIEW],
providers: [IconsService]
}]
}] });
/**
* Generated bundle index. Do not edit.
*/
export { CustomMessagesComponent, KENDO_SCROLLVIEW, ScrollViewComponent, ScrollViewModule, ScrollViewPagerComponent };