ng-devui
Version:
DevUI components based on Angular
230 lines (224 loc) • 21.7 kB
JavaScript
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