UNPKG

ng-devui

Version:

DevUI components based on Angular

230 lines (224 loc) 21.7 kB
import * as i1 from '@angular/common'; import { CommonModule } from '@angular/common'; import * as i0 from '@angular/core'; import { Component, EventEmitter, ChangeDetectionStrategy, Input, Output, ContentChildren, NgModule } from '@angular/core'; class CarouselItemComponent { static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CarouselItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: CarouselItemComponent, selector: "d-carousel-item", ngImport: i0, template: `<ng-content></ng-content>`, isInline: true }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CarouselItemComponent, decorators: [{ type: Component, args: [{ selector: 'd-carousel-item', template: `<ng-content></ng-content>`, preserveWhitespaces: false, }] }] }); class CarouselComponent { constructor(el, renderer, cdr) { this.el = el; this.renderer = renderer; this.cdr = cdr; // 切换箭头的显示方式 this.arrowTrigger = 'hover'; // 是否自动播放 this.autoplay = false; // 默认自动播放间隔时间 this.autoplaySpeed = 3000; // 卡片切换动画速度,单位ms this.transitionSpeed = 500; // 卡片高度 this.height = '100%'; // 是否显示面板指示器 this.showDots = true; // 面板指示器位置 this.dotPosition = 'bottom'; // 指示器触发滚动方式 this.dotTrigger = 'click'; // 当前激活面板索引,默认从0开始 this.activeIndex = 0; // 卡片切换时,返回当前卡片索引,索引从0开始 this.activeIndexChange = new EventEmitter(); this.showArrow = false; } ngOnInit() { this.showArrow = this.arrowTrigger === 'always'; this.itemContainer = this.el.nativeElement.querySelector('.devui-carousel-item-container'); } ngOnChanges(changes) { const { arrowTrigger, activeIndex } = changes; if (arrowTrigger && !arrowTrigger.isFirstChange()) { this.showArrow = this.arrowTrigger === 'always'; } if (activeIndex && activeIndex.currentValue !== this.currentIndex && !activeIndex.isFirstChange()) { this.translatePosition(this.activeIndex); } if (!this.autoplay || !this.autoplaySpeed) { this.clearScheduledTransition(); } else { this.autoScheduleTransition(); } } // 切换箭头监听事件,用于处理hover方式 arrowMouseEvent(type) { if (this.arrowTrigger !== 'hover') { return; } if (type === 'enter') { this.showArrow = true; } else { this.showArrow = false; } } // 向前切换 prev() { this.goTo(this.activeIndex - 1); } // 向后切换 next() { this.goTo(this.activeIndex + 1); } // 指定跳转位置 goTo(index) { if (index === this.activeIndex) { return; } this.renderer.setStyle(this.itemContainer, 'transition', `left ${this.transitionSpeed}ms ease`); if (index < 0 && this.activeIndex === 0) { // 第一个卡片向前切换 this.activeIndex = this.itemCount - 1; const targetEl = this.el.nativeElement.querySelectorAll('d-carousel-item')[this.activeIndex]; this.adjustPosition(targetEl, true); this.translatePosition(-1); this.adjustTransition(targetEl); } else if (index >= this.itemCount && this.activeIndex === this.itemCount - 1) { // 最后一个卡片向后切换 this.activeIndex = 0; const targetEl = this.el.nativeElement.querySelectorAll('d-carousel-item')[this.activeIndex]; this.adjustPosition(targetEl, false); this.translatePosition(this.itemCount); this.adjustTransition(targetEl); } else { const idx = index > this.itemCount - 1 ? this.itemCount - 1 : index; this.activeIndex = index < 0 ? 0 : idx; this.translatePosition(this.activeIndex); } this.activeIndexChange.emit(this.activeIndex); this.currentIndex = this.activeIndex; this.cdr.detectChanges(); this.autoScheduleTransition(); } // 指示器触发切换函数 switchStep(index, type) { if (type === this.dotTrigger) { this.goTo(index); } } // 调整首尾翻页后的动画 adjustTransition(targetEl) { setTimeout(() => { this.renderer.removeStyle(this.itemContainer, 'transition'); this.renderer.removeStyle(targetEl, 'transform'); this.translatePosition(this.activeIndex); }, this.transitionSpeed); } // 调整首尾翻动时的位置 adjustPosition(targetEl, firstToLast) { const wrapperRect = this.el.nativeElement.querySelector('.devui-carousel-item-wrapper').getBoundingClientRect(); this.renderer.setStyle(targetEl, 'transform', `translateX(${(firstToLast ? -this.itemCount : this.itemCount) * wrapperRect.width}px)`); } // 翻页位移 translatePosition(size) { this.renderer.setStyle(this.itemContainer, 'left', `${-size * 100}%`); } // 初始化container的宽度 initCarouselWidth() { this.itemCount = this.items.length; this.renderer.setStyle(this.itemContainer, 'width', `${this.itemCount * 100}%`); } // 自动轮播调度任务 autoScheduleTransition() { this.clearScheduledTransition(); if (this.autoplay && this.autoplaySpeed) { this.scheduledId = setTimeout(() => { this.next(); }, this.autoplaySpeed); } } // 清除自动轮播任务 clearScheduledTransition() { if (this.scheduledId) { clearTimeout(this.scheduledId); this.scheduledId = null; } } ngAfterContentInit() { this.initCarouselWidth(); this.translatePosition(this.activeIndex); this.renderer.setStyle(this.itemContainer, 'transition', `left ${this.transitionSpeed}ms ease`); // contentChildren 变化时,触发重新设置pane this.items.changes.subscribe((items) => { if (items.length !== this.itemCount) { this.activeIndex = 0; this.initCarouselWidth(); this.translatePosition(this.activeIndex); } }); } ngOnDestroy() { // 组件销毁时清理掉当前的定时任务 this.clearScheduledTransition(); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CarouselComponent, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: CarouselComponent, selector: "d-carousel", inputs: { arrowTrigger: "arrowTrigger", autoplay: "autoplay", autoplaySpeed: "autoplaySpeed", transitionSpeed: "transitionSpeed", height: "height", showDots: "showDots", dotPosition: "dotPosition", dotTrigger: "dotTrigger", activeIndex: "activeIndex" }, outputs: { activeIndexChange: "activeIndexChange" }, queries: [{ propertyName: "items", predicate: CarouselItemComponent }], exportAs: ["dCarousel"], usesOnChanges: true, ngImport: i0, template: "<div\n class=\"devui-carousel-container\"\n [style.height]=\"height\"\n (mouseenter)=\"arrowMouseEvent('enter')\"\n (mouseleave)=\"arrowMouseEvent('leave')\"\n>\n <!-- carousel arrow -->\n <div class=\"devui-carousel-arrow\" *ngIf=\"arrowTrigger !== 'never' && showArrow\">\n <button class=\"arrow-left\" (click)=\"prev()\">\n <svg width=\"18px\" height=\"18px\" viewBox=\"0 0 16 16\" version=\"1.1\">\n <g stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n <polygon\n fill=\"#293040\"\n fill-rule=\"nonzero\"\n points=\"10.7071068 12.2928932 9.29289322 13.7071068 3.58578644 8 9.29289322 2.29289322 10.7071068 3.70710678 6.41421356 8\"\n ></polygon>\n </g>\n </svg>\n </button>\n <button class=\"arrow-right\" (click)=\"next()\">\n <svg width=\"18px\" height=\"18px\" viewBox=\"0 0 16 16\" version=\"1.1\">\n <g stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n <polygon\n fill=\"#293040\"\n fill-rule=\"nonzero\"\n transform=\"translate(8.146447, 8.000000) scale(-1, 1) translate(-8.146447, -8.000000) \"\n points=\"11.7071068 12.2928932 10.2928932 13.7071068 4.58578644 8 10.2928932 2.29289322 11.7071068 3.70710678 7.41421356 8\"\n ></polygon>\n </g>\n </svg>\n </button>\n </div>\n <!-- carousel items -->\n <div class=\"devui-carousel-item-wrapper\">\n <div class=\"devui-carousel-item-container\">\n <ng-content select=\"d-carousel-item\"></ng-content>\n </div>\n </div>\n <!-- carousel dots -->\n <ul class=\"devui-carousel-dots {{ dotPosition }}\" *ngIf=\"items?.length > 1 && showDots\">\n <li\n class=\"dot-item\"\n (click)=\"switchStep(index, 'click')\"\n (mouseenter)=\"switchStep(index, 'hover')\"\n [ngClass]=\"{ active: activeIndex === index }\"\n *ngFor=\"let item of items; let index = index\"\n >\n <span class=\"dot-item-active-progress\" [ngStyle]=\"{ 'transition-duration': transitionSpeed + 'ms' }\"></span>\n </li>\n </ul>\n</div>\n", styles: [".devui-carousel-container{display:block;position:relative}.devui-carousel-container .devui-carousel-arrow{position:absolute;width:100%;top:50%}.devui-carousel-container .devui-carousel-arrow .arrow-left{position:absolute;top:-18px;z-index:2;cursor:pointer;width:36px;height:36px;border-radius:100%;background:var(--devui-highlight-overlay, rgba(255, 255, 255, .8));box-shadow:var(--devui-shadow-length-hover, 0 8px 24px 0) var(--devui-hover-shadow, rgba(0, 0, 0, .16));display:inline-flex;align-items:center;justify-content:center;left:10px}.devui-carousel-container .devui-carousel-arrow .arrow-left:hover{background:var(--devui-area, #f3f3f3)}.devui-carousel-container .devui-carousel-arrow .arrow-left svg polygon{fill:var(--devui-text, #191919)}.devui-carousel-container .devui-carousel-arrow .arrow-right{position:absolute;top:-18px;z-index:2;cursor:pointer;width:36px;height:36px;border-radius:100%;background:var(--devui-highlight-overlay, rgba(255, 255, 255, .8));box-shadow:var(--devui-shadow-length-hover, 0 8px 24px 0) var(--devui-hover-shadow, rgba(0, 0, 0, .16));display:inline-flex;align-items:center;justify-content:center;right:10px}.devui-carousel-container .devui-carousel-arrow .arrow-right:hover{background:var(--devui-area, #f3f3f3)}.devui-carousel-container .devui-carousel-arrow .arrow-right svg polygon{fill:var(--devui-text, #191919)}.devui-carousel-container .devui-carousel-item-wrapper{position:relative;overflow:hidden;height:100%}.devui-carousel-container .devui-carousel-item-wrapper .devui-carousel-item-container{display:flex;height:100%;position:relative}.devui-carousel-container .devui-carousel-item-wrapper .devui-carousel-item-container ::ng-deep d-carousel-item{flex:1;position:relative;height:100%}.devui-carousel-container .devui-carousel-dots{position:absolute;display:flex;justify-content:center;width:100%}.devui-carousel-container .devui-carousel-dots.bottom{bottom:8px}.devui-carousel-container .devui-carousel-dots.top{top:8px}.devui-carousel-container .devui-carousel-dots .dot-item{width:6px;height:6px;border-radius:var(--devui-border-radius-feedback, 4px);margin-right:8px;background:var(--devui-icon-fill, #595959);cursor:pointer}.devui-carousel-container .devui-carousel-dots .dot-item .dot-item-active-progress{width:0;display:inline-block;position:absolute}.devui-carousel-container .devui-carousel-dots .dot-item:hover{background:var(--devui-icon-fill-hover, #191919)}.devui-carousel-container .devui-carousel-dots .dot-item.active{width:24px;background-color:var(--devui-icon-fill, #595959);transition:all var(--devui-animation-duration-fast, .1s) var(--devui-animation-ease-in-out-smooth, cubic-bezier(.645, .045, .355, 1))}.devui-carousel-container .devui-carousel-dots .dot-item.active .dot-item-active-progress{width:24px;height:6px;background-color:var(--devui-icon-fill-active, #191919);border-radius:var(--devui-border-radius-feedback, 4px);transition-property:width;transition-timing-function:var(--devui-animation-ease-out, cubic-bezier(.16, .75, .5, 1))}.devui-carousel-container .devui-carousel-arrow .arrow-left,.devui-carousel-container .devui-carousel-arrow .arrow-right{transition:background-color var(--devui-animation-duration-slow, .3s) var(--devui-animation-ease-in-out-smooth, cubic-bezier(.645, .045, .355, 1))}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CarouselComponent, decorators: [{ type: Component, args: [{ selector: 'd-carousel', exportAs: 'dCarousel', changeDetection: ChangeDetectionStrategy.OnPush, preserveWhitespaces: false, template: "<div\n class=\"devui-carousel-container\"\n [style.height]=\"height\"\n (mouseenter)=\"arrowMouseEvent('enter')\"\n (mouseleave)=\"arrowMouseEvent('leave')\"\n>\n <!-- carousel arrow -->\n <div class=\"devui-carousel-arrow\" *ngIf=\"arrowTrigger !== 'never' && showArrow\">\n <button class=\"arrow-left\" (click)=\"prev()\">\n <svg width=\"18px\" height=\"18px\" viewBox=\"0 0 16 16\" version=\"1.1\">\n <g stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n <polygon\n fill=\"#293040\"\n fill-rule=\"nonzero\"\n points=\"10.7071068 12.2928932 9.29289322 13.7071068 3.58578644 8 9.29289322 2.29289322 10.7071068 3.70710678 6.41421356 8\"\n ></polygon>\n </g>\n </svg>\n </button>\n <button class=\"arrow-right\" (click)=\"next()\">\n <svg width=\"18px\" height=\"18px\" viewBox=\"0 0 16 16\" version=\"1.1\">\n <g stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n <polygon\n fill=\"#293040\"\n fill-rule=\"nonzero\"\n transform=\"translate(8.146447, 8.000000) scale(-1, 1) translate(-8.146447, -8.000000) \"\n points=\"11.7071068 12.2928932 10.2928932 13.7071068 4.58578644 8 10.2928932 2.29289322 11.7071068 3.70710678 7.41421356 8\"\n ></polygon>\n </g>\n </svg>\n </button>\n </div>\n <!-- carousel items -->\n <div class=\"devui-carousel-item-wrapper\">\n <div class=\"devui-carousel-item-container\">\n <ng-content select=\"d-carousel-item\"></ng-content>\n </div>\n </div>\n <!-- carousel dots -->\n <ul class=\"devui-carousel-dots {{ dotPosition }}\" *ngIf=\"items?.length > 1 && showDots\">\n <li\n class=\"dot-item\"\n (click)=\"switchStep(index, 'click')\"\n (mouseenter)=\"switchStep(index, 'hover')\"\n [ngClass]=\"{ active: activeIndex === index }\"\n *ngFor=\"let item of items; let index = index\"\n >\n <span class=\"dot-item-active-progress\" [ngStyle]=\"{ 'transition-duration': transitionSpeed + 'ms' }\"></span>\n </li>\n </ul>\n</div>\n", styles: [".devui-carousel-container{display:block;position:relative}.devui-carousel-container .devui-carousel-arrow{position:absolute;width:100%;top:50%}.devui-carousel-container .devui-carousel-arrow .arrow-left{position:absolute;top:-18px;z-index:2;cursor:pointer;width:36px;height:36px;border-radius:100%;background:var(--devui-highlight-overlay, rgba(255, 255, 255, .8));box-shadow:var(--devui-shadow-length-hover, 0 8px 24px 0) var(--devui-hover-shadow, rgba(0, 0, 0, .16));display:inline-flex;align-items:center;justify-content:center;left:10px}.devui-carousel-container .devui-carousel-arrow .arrow-left:hover{background:var(--devui-area, #f3f3f3)}.devui-carousel-container .devui-carousel-arrow .arrow-left svg polygon{fill:var(--devui-text, #191919)}.devui-carousel-container .devui-carousel-arrow .arrow-right{position:absolute;top:-18px;z-index:2;cursor:pointer;width:36px;height:36px;border-radius:100%;background:var(--devui-highlight-overlay, rgba(255, 255, 255, .8));box-shadow:var(--devui-shadow-length-hover, 0 8px 24px 0) var(--devui-hover-shadow, rgba(0, 0, 0, .16));display:inline-flex;align-items:center;justify-content:center;right:10px}.devui-carousel-container .devui-carousel-arrow .arrow-right:hover{background:var(--devui-area, #f3f3f3)}.devui-carousel-container .devui-carousel-arrow .arrow-right svg polygon{fill:var(--devui-text, #191919)}.devui-carousel-container .devui-carousel-item-wrapper{position:relative;overflow:hidden;height:100%}.devui-carousel-container .devui-carousel-item-wrapper .devui-carousel-item-container{display:flex;height:100%;position:relative}.devui-carousel-container .devui-carousel-item-wrapper .devui-carousel-item-container ::ng-deep d-carousel-item{flex:1;position:relative;height:100%}.devui-carousel-container .devui-carousel-dots{position:absolute;display:flex;justify-content:center;width:100%}.devui-carousel-container .devui-carousel-dots.bottom{bottom:8px}.devui-carousel-container .devui-carousel-dots.top{top:8px}.devui-carousel-container .devui-carousel-dots .dot-item{width:6px;height:6px;border-radius:var(--devui-border-radius-feedback, 4px);margin-right:8px;background:var(--devui-icon-fill, #595959);cursor:pointer}.devui-carousel-container .devui-carousel-dots .dot-item .dot-item-active-progress{width:0;display:inline-block;position:absolute}.devui-carousel-container .devui-carousel-dots .dot-item:hover{background:var(--devui-icon-fill-hover, #191919)}.devui-carousel-container .devui-carousel-dots .dot-item.active{width:24px;background-color:var(--devui-icon-fill, #595959);transition:all var(--devui-animation-duration-fast, .1s) var(--devui-animation-ease-in-out-smooth, cubic-bezier(.645, .045, .355, 1))}.devui-carousel-container .devui-carousel-dots .dot-item.active .dot-item-active-progress{width:24px;height:6px;background-color:var(--devui-icon-fill-active, #191919);border-radius:var(--devui-border-radius-feedback, 4px);transition-property:width;transition-timing-function:var(--devui-animation-ease-out, cubic-bezier(.16, .75, .5, 1))}.devui-carousel-container .devui-carousel-arrow .arrow-left,.devui-carousel-container .devui-carousel-arrow .arrow-right{transition:background-color var(--devui-animation-duration-slow, .3s) var(--devui-animation-ease-in-out-smooth, cubic-bezier(.645, .045, .355, 1))}\n"] }] }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.ChangeDetectorRef }], propDecorators: { arrowTrigger: [{ type: Input }], autoplay: [{ type: Input }], autoplaySpeed: [{ type: Input }], transitionSpeed: [{ type: Input }], height: [{ type: Input }], showDots: [{ type: Input }], dotPosition: [{ type: Input }], dotTrigger: [{ type: Input }], activeIndex: [{ type: Input }], activeIndexChange: [{ type: Output }], items: [{ type: ContentChildren, args: [CarouselItemComponent] }] } }); class CarouselModule { static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CarouselModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); } static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: CarouselModule, declarations: [CarouselComponent, CarouselItemComponent], imports: [CommonModule], exports: [CarouselComponent, CarouselItemComponent] }); } static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CarouselModule, imports: [CommonModule] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CarouselModule, decorators: [{ type: NgModule, args: [{ declarations: [CarouselComponent, CarouselItemComponent], imports: [CommonModule], exports: [CarouselComponent, CarouselItemComponent], providers: [], }] }] }); /** * Generated bundle index. Do not edit. */ export { CarouselComponent, CarouselItemComponent, CarouselModule }; //# sourceMappingURL=ng-devui-carousel.mjs.map