UNPKG

ng-devui

Version:

DevUI components based on Angular

736 lines (727 loc) 48.1 kB
import * as i4 from '@angular/common'; import { CommonModule } from '@angular/common'; import * as i0 from '@angular/core'; import { EventEmitter, Directive, Input, Output, Injectable, Component, ChangeDetectionStrategy, Host, SkipSelf, HostBinding, ContentChildren, ViewChildren, NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; import * as i5 from 'ng-devui/popover'; import { PopoverModule } from 'ng-devui/popover'; import * as i3 from 'ng-devui/i18n'; import { Subject, Subscription } from 'rxjs'; import { takeUntil, map, tap, filter, switchMap } from 'rxjs/operators'; class ResizeDirective { constructor(el, ngZone) { this.el = el; this.ngZone = ngZone; // 是否允许拖动 this.enableResize = true; // 按下事件,mousedown,touchstart等 this.pressEvent = new EventEmitter(); // 拖动中事件,mousemove,touchmove等 this.dragEvent = new EventEmitter(); // 释放事件,mouseup,touchend等 this.releaseEvent = new EventEmitter(); this.bind = (el, event, callback) => el.addEventListener && el.addEventListener(event, callback); this.unbind = (el, event, callback) => el && el.removeEventListener && el.removeEventListener(event, callback); this.mousedown = (e) => { this.bind(document, 'mousemove', this.mousemove); this.bind(document, 'mouseup', this.mouseup); this.pressEvent.emit(this.normalizeEvent(e)); }; this.mousemove = (e) => { this.dragEvent.emit(this.normalizeEvent(e)); }; this.mouseup = (e) => { this.unbind(document, 'mousemove', this.mousemove); this.unbind(document, 'mouseup', this.mouseup); this.releaseEvent.emit(this.normalizeEvent(e)); }; this.touchstart = (e) => { this.bind(document, 'touchmove', this.touchmove); this.bind(document, 'touchend', this.touchend); if (e.touches.length === 1) { this.pressEvent.emit(this.normalizeEvent(e)); } }; this.touchmove = (e) => { if (e.touches.length === 1) { this.dragEvent.emit(this.normalizeEvent(e)); } }; this.touchend = (e) => { this.unbind(document, 'touchmove', this.touchmove); this.unbind(document, 'touchend', this.touchend); if (e.touches.length === 0) { this.releaseEvent.emit(this.normalizeEvent(e)); } }; } ngOnInit() { if (this.enableResize) { this.ngZone.runOutsideAngular(() => { this.bindEvent(); }); } } ngOnDestroy() { if (this.enableResize) { this.unbind(this.el.nativeElement, 'mousedown', this.mousedown); this.unbind(this.el.nativeElement, 'touchstart', this.touchstart); } } bindEvent() { const element = this.el.nativeElement; // 绑定mousedown事件 this.bind(element, 'mousedown', this.mousedown); // 绑定触屏事件 this.bind(element, 'touchstart', this.touchstart); } // 返回常用位置信息 normalizeEvent(e) { // 判断事件类型,用于计算位置坐标 if (e.type.match(/touch/)) { return { pageX: e.changedTouches[0].pageX, pageY: e.changedTouches[0].pageY, clientX: e.changedTouches[0].clientX, clientY: e.changedTouches[0].clientY, type: e.type, originalEvent: e, isTouch: true }; } return { pageX: e.pageX, pageY: e.pageY, clientX: e.clientX, clientY: e.clientY, offsetX: e.offsetX, offsetY: e.offsetY, type: e.type, originalEvent: e }; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ResizeDirective, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: ResizeDirective, selector: "[dResize]", inputs: { enableResize: "enableResize" }, outputs: { pressEvent: "pressEvent", dragEvent: "dragEvent", releaseEvent: "releaseEvent" }, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ResizeDirective, decorators: [{ type: Directive, args: [{ selector: '[dResize]' }] }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.NgZone }], propDecorators: { enableResize: [{ type: Input }], pressEvent: [{ type: Output }], dragEvent: [{ type: Output }], releaseEvent: [{ type: Output }] } }); class SplitterService { constructor() { this.paneCount = 0; this.paneChangeSubject = new Subject(); } // 配置pane信息,panes列表,方向,容器大小,方便后续计算使用 configPane({ panes, orientation, containerSize }) { this.panes = panes; this.panes.forEach((pane, index) => { pane.order = index * 2; pane.orientation = orientation; }); this.paneCount = this.panes.length; this.containerSize = containerSize; } // 按下的时候计算pane的size信息 dragState(splitbarIndex) { const prev = this.getPane(splitbarIndex); const next = this.getPane(splitbarIndex + 1); const total = prev.computedSize + next.computedSize; return { prev: { index: splitbarIndex, initialSize: prev.computedSize, // 设置有最小值,直接取值,如果没有设置就用两个pane总和减去相邻pane的最大值,都没设置(NAN)在取0 minSize: this.toPixels(prev.minSize) || total - this.toPixels(next.maxSize) || 0, // 设置有最大值,直接取值,如果没有设置就用两个pane总和减去相邻pane的最小值,都没设置(NAN)在取两个pane总和 maxSize: this.toPixels(prev.maxSize) || total - this.toPixels(next.minSize) || total, }, next: { index: splitbarIndex + 1, initialSize: next.computedSize, minSize: this.toPixels(next.minSize) || total - this.toPixels(prev.maxSize) || 0, maxSize: this.toPixels(next.maxSize) || total - this.toPixels(prev.minSize) || total, }, }; } // 设置pane大小 setSize(state, distance) { const prev = this.getPane(state.prev.index); const next = this.getPane(state.next.index); if (prev.size && next.size) { // 相邻的两个pane都指定了size,需要同时修改size this.resize(state.prev, distance); this.resize(state.next, -distance); } else if (next.size) { // 如果 next pane,指定了size就修改next pane this.resize(state.next, -distance); } else { // 最后不管pre pane,有没有指定,都修改 pre pane this.resize(state.prev, distance); } } // 大小限制函数,(max)小于最小值时取最小值, (min)大于最大值时取最大值 clamp(minSize, maxSize, initialSize) { return Math.min(maxSize, Math.max(minSize, initialSize)); } // resize pane的大小 resize(paneState, moveSize) { const pane = this.getPane(paneState.index); const splitterSize = this.containerSize(); const newSize = this.clamp(paneState.minSize, paneState.maxSize, paneState.initialSize + moveSize); let size = ''; if (this.isPercent(pane.size)) { size = (100 * newSize) / splitterSize + '%'; } else { size = newSize + 'px'; } pane.size = size; pane.sizeChange.emit(size); } // 判断pane是否可以调整大小,只要有一边设置了不可调整或者收起,相邻pane调整就失效 isResizable(splitBarIndex) { const prevPane = this.getPane(splitBarIndex); const nextPane = this.getPane(splitBarIndex + 1); const paneCollapsed = prevPane.collapsed || nextPane.collapsed; return prevPane.resizable && nextPane.resizable && !paneCollapsed; } // 判断分割条是否是固定的,只要有一边不能调整, 就是禁用状态固定bar isStaticBar(splitBarIndex) { const prevPane = this.getPane(splitBarIndex); const nextPane = this.getPane(splitBarIndex + 1); return !(prevPane.resizable && nextPane.resizable); } // 获取pane,防止没有初始化的时候调用内部方法取值 getPane(index) { if (!this.panes || index < 0 || index >= this.panes.length) { throw new Error('no pane can return.'); } return this.panes[index]; } getBar(index) { if (!this.bars || index < 0 || index >= this.bars.length) { return; } return this.bars[index]; } // 判断是不是百分比设置宽度 isPercent(size) { return /%$/.test(size); } // 计算时把百分比转换为像素 toPixels(size) { // 值不满足转换时,result为NAN,方便计算最小、最大宽度判断 let result = parseFloat(size); if (this.isPercent(size)) { result = (this.containerSize() * result) / 100; } return result; } // 切换pane展开,收起 togglePane(paneIndex, nearPaneIndex, lockStatus) { const pane = this.getPane(paneIndex); const nearPane = this.getPane(nearPaneIndex); if (pane.collapsible) { pane._collapsed = lockStatus ? pane._collapsed : !pane._collapsed; pane.toggleCollapseClass(); nearPane.toggleNearPaneFlexGrow(pane._collapsed); pane.collapsedChange.emit(pane._collapsed); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SplitterService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SplitterService }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SplitterService, decorators: [{ type: Injectable }] }); class SplitterBarComponent { set splitBarSize(size) { this._splitBarSize = size; this.renderer.setStyle(this.el.nativeElement, 'flex-basis', size); } get splitBarSize() { return this._splitBarSize; } get class() { let bindClass = 'devui-splitter-bar devui-splitter-bar-' + this.orientation; if (!this.splitter.isStaticBar(this.index)) { bindClass += ' resizable'; } else { this.renderer.setStyle(this.el.nativeElement, 'flex-basis', this.disabledBarSize); } return bindClass; } constructor(el, splitter, renderer, resize, cdr, cdrSelf, i18n) { this.el = el; this.splitter = splitter; this.renderer = renderer; this.resize = resize; this.cdr = cdr; this.cdrSelf = cdrSelf; this.i18n = i18n; this.subscriptions = new Subscription(); // 移动的时候,阻止事件冒泡 this.stopPropagation = ({ originalEvent: event }) => { event.stopPropagation(); if (event.cancelable) { event.preventDefault(); } }; // 处理移动过程中的数据流, 合并到pressEvent事件流中 this.moveStream = (resize) => (mouseDown) => resize.dragEvent.pipe(takeUntil(resize.releaseEvent), map(({ pageX, pageY }) => ({ originalX: mouseDown.pageX, originalY: mouseDown.pageY, pageX, pageY, }))); this.splitter.paneChangeSubject.subscribe(() => { this.initialCollapseStatus(); this.cdr.detectChanges(); this.cdrSelf.detectChanges(); }); this.splitterText = this.i18n.getI18nText().splitter; this.subscriptions.add(this.i18n.langChange().subscribe((data) => { this.splitterText = data.splitter; })); } ngOnInit() { let state; const resizeListener = this.resize.pressEvent .pipe(tap(this.stopPropagation), filter(() => this.splitter.isResizable(this.index)), tap(() => { state = this.splitter.dragState(this.index); }), switchMap(this.moveStream(this.resize))) .subscribe(({ pageX, pageY, originalX, originalY }) => { let distance; if (this.orientation === 'vertical') { distance = pageY - originalY; } else { distance = pageX - originalX; } this.splitter.setSize(state, distance); }); this.subscriptions.add(resizeListener); } ngAfterViewInit() { this.initialCollapseStatus(); } ngOnDestroy() { this.subscriptions.unsubscribe(); this.splitter.paneChangeSubject.unsubscribe(); } initialCollapseStatus() { this.collapsePrePane(true); this.collapseNextPane(true); } collapsePrePane(lockStatus) { this.splitter.togglePane(this.index, this.index + 1, lockStatus); this.toggleResize(); this.hidePrevIsCovered(); } collapseNextPane(lockStatus) { this.splitter.togglePane(this.index + 1, this.index, lockStatus); this.toggleResize(); this.hideNextIsCovered(); } queryPanes(index, nearIndex) { const pane = this.splitter.getPane(index); const nearPane = this.splitter.getPane(nearIndex); return { pane, nearPane }; } // 切换是否允许拖拽,收起时不能拖拽 toggleResize() { const { pane, nearPane } = this.queryPanes(this.index, this.index + 1); const isCollapsed = pane.collapsed || nearPane.collapsed; if (isCollapsed) { this.renderer.addClass(this.el.nativeElement, 'none-resizable'); } else { this.renderer.removeClass(this.el.nativeElement, 'none-resizable'); } } // 计算前面板收起操作样式 get prevClass() { const { pane, nearPane } = this.queryPanes(this.index, this.index + 1); this.preTip = pane.collapsed ? this.splitterText.expand : this.splitterText.collapse; // 第一个面板或者其它面板折叠方向不是向后的显示操作按钮 const showIcon = pane.collapseDirection !== 'after' || this.index === 0; return this.generateCollapseClass(pane, nearPane, showIcon); } // 计算相邻面板收起操作样式 get nextClass() { const { pane, nearPane } = this.queryPanes(this.index + 1, this.index); this.nextTip = pane.collapsed ? this.splitterText.expand : this.splitterText.collapse; // 最后一个面板或者其它面板折叠方向不是向前的显示操作按钮 const showIcon = pane.collapseDirection !== 'before' || this.index + 1 === this.splitter.paneCount - 1; return this.generateCollapseClass(pane, nearPane, showIcon); } // 生成拼接样式 generateClass(classes) { return Object.keys(classes) .filter((c) => classes[c]) .join(' '); } // 根据当前状态生成收起按钮样式 generateCollapseClass(pane, nearPane, showIcon) { // 是否允许收起 const isCollapsible = pane.collapsible && showIcon; // 当前收起状态 const isCollapsed = pane.collapsed; // 一个pane收起的时候,隐藏相邻pane的收起按钮 const isNearPaneCollapsed = nearPane.collapsed; return this.generateClass({ 'devui-collapse': isCollapsible, collapsed: isCollapsed, hidden: isNearPaneCollapsed, }); } hidePrevIsCovered() { const pane = this.splitter.getPane(this.index); const prevBar = this.splitter.getBar(this.index - 1); const prevBarDom = prevBar?.el.nativeElement.querySelector('.prev'); if (prevBarDom) { const rules = [pane.collapsed, pane.collapsible, pane.collapseDirection === 'before']; if (rules.includes(false)) { prevBarDom.classList.remove('hidden'); } else { prevBarDom.classList.add('hidden'); } } } hideNextIsCovered() { const pane = this.splitter.getPane(this.index + 1); const nextBar = this.splitter.getBar(this.index + 1); const nextBarDom = nextBar?.el.nativeElement.querySelector('.next'); if (nextBarDom) { const rules = [pane.collapsed, pane.collapsible, pane.collapseDirection === 'after']; if (rules.includes(false)) { nextBarDom.classList.remove('hidden'); } else { nextBarDom.classList.add('hidden'); } } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SplitterBarComponent, deps: [{ token: i0.ElementRef }, { token: SplitterService }, { token: i0.Renderer2 }, { token: ResizeDirective, host: true }, { token: i0.ChangeDetectorRef, skipSelf: true }, { token: i0.ChangeDetectorRef }, { token: i3.I18nService }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: SplitterBarComponent, selector: "d-splitter-bar", inputs: { index: "index", orientation: "orientation", showCollapseButton: "showCollapseButton", collapsePosLeft: "collapsePosLeft", collapsePosTop: "collapsePosTop", splitBarSize: "splitBarSize", disabledBarSize: "disabledBarSize" }, host: { properties: { "class": "this.class" } }, ngImport: i0, template: "<div\n class=\"prev\"\n *ngIf=\"showCollapseButton\"\n dPopover\n [style.left]=\"collapsePosLeft\"\n [style.top]=\"collapsePosTop\"\n [trigger]=\"'hover'\"\n [controlled]=\"true\"\n [ngClass]=\"prevClass\"\n [content]=\"preTip\"\n [showAnimation]=\"false\"\n [mouseEnterDelay]=\"100\"\n [mouseLeaveDelay]=\"0\"\n (click)=\"collapsePrePane()\"\n (touchstart)=\"collapsePrePane()\"\n></div>\n<div class=\"devui-resize-handle\"></div>\n<div\n class=\"next\"\n *ngIf=\"showCollapseButton\"\n dPopover\n [trigger]=\"'hover'\"\n [controlled]=\"true\"\n [ngClass]=\"nextClass\"\n [content]=\"nextTip\"\n (click)=\"collapseNextPane()\"\n (touchstart)=\"collapseNextPane()\"\n></div>\n", styles: [":host.devui-splitter-bar{background-color:var(--devui-dividing-line, #f0f0f0);display:flex;position:relative;align-items:center;justify-content:center;flex-grow:0;flex-shrink:0}:host.devui-splitter-bar .devui-collapse{background-color:var(--devui-line, #dbdbdb);position:absolute;z-index:15;cursor:pointer}:host.devui-splitter-bar .devui-collapse:before,:host.devui-splitter-bar .devui-collapse:after{content:\"\";width:10px;height:2px;background:#fff;display:block;position:absolute}:host.devui-splitter-bar .devui-collapse:hover{background-color:var(--devui-brand-hover, #3979f9)}:host.devui-splitter-bar-horizontal .devui-collapse{width:12px;height:30px}:host.devui-splitter-bar-horizontal .devui-collapse.prev.hidden,:host.devui-splitter-bar-horizontal .devui-collapse.next.hidden{display:none}:host.devui-splitter-bar-horizontal .devui-collapse.prev{border-radius:0 var(--devui-border-radius-feedback, 4px) var(--devui-border-radius-feedback, 4px) 0;left:100%}:host.devui-splitter-bar-horizontal .devui-collapse.prev:before,:host.devui-splitter-bar-horizontal .devui-collapse.prev.collapsed:before{top:9px;left:1px}:host.devui-splitter-bar-horizontal .devui-collapse.prev:before{transform:rotate(-70deg)}:host.devui-splitter-bar-horizontal .devui-collapse.prev.collapsed:before{transform:rotate(70deg)}:host.devui-splitter-bar-horizontal .devui-collapse.prev:after,:host.devui-splitter-bar-horizontal .devui-collapse.prev.collapsed:after{top:18px;left:1px}:host.devui-splitter-bar-horizontal .devui-collapse.prev:after{transform:rotate(70deg)}:host.devui-splitter-bar-horizontal .devui-collapse.prev.collapsed:after{transform:rotate(-70deg)}:host.devui-splitter-bar-horizontal .devui-collapse.next{border-radius:var(--devui-border-radius-feedback, 4px) 0 0 var(--devui-border-radius-feedback, 4px);right:100%}:host.devui-splitter-bar-horizontal .devui-collapse.next:before,:host.devui-splitter-bar-horizontal .devui-collapse.next.collapsed:before{top:9px;right:1px}:host.devui-splitter-bar-horizontal .devui-collapse.next:before{transform:rotate(70deg)}:host.devui-splitter-bar-horizontal .devui-collapse.next.collapsed:before{transform:rotate(-70deg)}:host.devui-splitter-bar-horizontal .devui-collapse.next:after,:host.devui-splitter-bar-horizontal .devui-collapse.next.collapsed:after{top:18px;right:1px}:host.devui-splitter-bar-horizontal .devui-collapse.next:after{transform:rotate(-70deg)}:host.devui-splitter-bar-horizontal .devui-collapse.next.collapsed:after{transform:rotate(70deg)}:host.devui-splitter-bar-vertical .devui-collapse{height:12px;width:30px}:host.devui-splitter-bar-vertical .devui-collapse.prev.hidden,:host.devui-splitter-bar-vertical .devui-collapse.next.hidden{display:none}:host.devui-splitter-bar-vertical .devui-collapse.prev{border-radius:0 0 var(--devui-border-radius-feedback, 4px) var(--devui-border-radius-feedback, 4px);top:100%}:host.devui-splitter-bar-vertical .devui-collapse.prev:before,:host.devui-splitter-bar-vertical .devui-collapse.prev.collapsed:before{bottom:5px;left:5px}:host.devui-splitter-bar-vertical .devui-collapse.prev:before{transform:rotate(-20deg)}:host.devui-splitter-bar-vertical .devui-collapse.prev.collapsed:before{transform:rotate(20deg)}:host.devui-splitter-bar-vertical .devui-collapse.prev:after,:host.devui-splitter-bar-vertical .devui-collapse.prev.collapsed:after{bottom:5px;left:14px}:host.devui-splitter-bar-vertical .devui-collapse.prev:after{transform:rotate(20deg)}:host.devui-splitter-bar-vertical .devui-collapse.prev.collapsed:after{transform:rotate(-20deg)}:host.devui-splitter-bar-vertical .devui-collapse.next{border-radius:var(--devui-border-radius-feedback, 4px) var(--devui-border-radius-feedback, 4px) 0 0;bottom:100%}:host.devui-splitter-bar-vertical .devui-collapse.next:before,:host.devui-splitter-bar-vertical .devui-collapse.next.collapsed:before{top:5px;left:5px}:host.devui-splitter-bar-vertical .devui-collapse.next:before{transform:rotate(20deg)}:host.devui-splitter-bar-vertical .devui-collapse.next.collapsed:before{transform:rotate(-20deg);top:5px;left:5px}:host.devui-splitter-bar-vertical .devui-collapse.next:after,:host.devui-splitter-bar-vertical .devui-collapse.next.collapsed:after{top:5px;left:14px}:host.devui-splitter-bar-vertical .devui-collapse.next:after{transform:rotate(-20deg)}:host.devui-splitter-bar-vertical .devui-collapse.next.collapsed:after{transform:rotate(20deg)}:host.devui-splitter-bar-horizontal.resizable:not(.none-resizable):hover,:host.devui-splitter-bar-horizontal.resizable:not(.none-resizable):focus,:host.devui-splitter-bar-horizontal.resizable:not(.none-resizable):active,:host.devui-splitter-bar-vertical.resizable:not(.none-resizable):hover,:host.devui-splitter-bar-vertical.resizable:not(.none-resizable):focus,:host.devui-splitter-bar-vertical.resizable:not(.none-resizable):active{background-color:var(--devui-brand-hover, #3979f9)}:host.devui-splitter-bar-horizontal.resizable:not(.none-resizable):after,:host.devui-splitter-bar-vertical.resizable:not(.none-resizable):after{content:\"\";display:block;position:absolute;z-index:10}:host.devui-splitter-bar-horizontal.resizable{cursor:col-resize}:host.devui-splitter-bar-horizontal.resizable:after{cursor:col-resize;height:100%;width:10px;top:0}:host.devui-splitter-bar-vertical.resizable{cursor:row-resize}:host.devui-splitter-bar-vertical.resizable:after{cursor:row-resize;width:100%;height:10px;left:0}\n"], dependencies: [{ kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.PopoverDirective, selector: "[dPopover]", inputs: ["content", "controlled", "position", "showAnimation", "showAnimate", "scrollElement", "autoHideCoefficient", "appendToBody", "zIndex", "popType", "popMaxWidth", "trigger", "hoverToContent", "hoverDelayTime", "popoverStyle", "mouseEnterDelay", "mouseLeaveDelay", "visible"], exportAs: ["dPopover"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SplitterBarComponent, decorators: [{ type: Component, args: [{ selector: 'd-splitter-bar', changeDetection: ChangeDetectionStrategy.OnPush, preserveWhitespaces: false, template: "<div\n class=\"prev\"\n *ngIf=\"showCollapseButton\"\n dPopover\n [style.left]=\"collapsePosLeft\"\n [style.top]=\"collapsePosTop\"\n [trigger]=\"'hover'\"\n [controlled]=\"true\"\n [ngClass]=\"prevClass\"\n [content]=\"preTip\"\n [showAnimation]=\"false\"\n [mouseEnterDelay]=\"100\"\n [mouseLeaveDelay]=\"0\"\n (click)=\"collapsePrePane()\"\n (touchstart)=\"collapsePrePane()\"\n></div>\n<div class=\"devui-resize-handle\"></div>\n<div\n class=\"next\"\n *ngIf=\"showCollapseButton\"\n dPopover\n [trigger]=\"'hover'\"\n [controlled]=\"true\"\n [ngClass]=\"nextClass\"\n [content]=\"nextTip\"\n (click)=\"collapseNextPane()\"\n (touchstart)=\"collapseNextPane()\"\n></div>\n", styles: [":host.devui-splitter-bar{background-color:var(--devui-dividing-line, #f0f0f0);display:flex;position:relative;align-items:center;justify-content:center;flex-grow:0;flex-shrink:0}:host.devui-splitter-bar .devui-collapse{background-color:var(--devui-line, #dbdbdb);position:absolute;z-index:15;cursor:pointer}:host.devui-splitter-bar .devui-collapse:before,:host.devui-splitter-bar .devui-collapse:after{content:\"\";width:10px;height:2px;background:#fff;display:block;position:absolute}:host.devui-splitter-bar .devui-collapse:hover{background-color:var(--devui-brand-hover, #3979f9)}:host.devui-splitter-bar-horizontal .devui-collapse{width:12px;height:30px}:host.devui-splitter-bar-horizontal .devui-collapse.prev.hidden,:host.devui-splitter-bar-horizontal .devui-collapse.next.hidden{display:none}:host.devui-splitter-bar-horizontal .devui-collapse.prev{border-radius:0 var(--devui-border-radius-feedback, 4px) var(--devui-border-radius-feedback, 4px) 0;left:100%}:host.devui-splitter-bar-horizontal .devui-collapse.prev:before,:host.devui-splitter-bar-horizontal .devui-collapse.prev.collapsed:before{top:9px;left:1px}:host.devui-splitter-bar-horizontal .devui-collapse.prev:before{transform:rotate(-70deg)}:host.devui-splitter-bar-horizontal .devui-collapse.prev.collapsed:before{transform:rotate(70deg)}:host.devui-splitter-bar-horizontal .devui-collapse.prev:after,:host.devui-splitter-bar-horizontal .devui-collapse.prev.collapsed:after{top:18px;left:1px}:host.devui-splitter-bar-horizontal .devui-collapse.prev:after{transform:rotate(70deg)}:host.devui-splitter-bar-horizontal .devui-collapse.prev.collapsed:after{transform:rotate(-70deg)}:host.devui-splitter-bar-horizontal .devui-collapse.next{border-radius:var(--devui-border-radius-feedback, 4px) 0 0 var(--devui-border-radius-feedback, 4px);right:100%}:host.devui-splitter-bar-horizontal .devui-collapse.next:before,:host.devui-splitter-bar-horizontal .devui-collapse.next.collapsed:before{top:9px;right:1px}:host.devui-splitter-bar-horizontal .devui-collapse.next:before{transform:rotate(70deg)}:host.devui-splitter-bar-horizontal .devui-collapse.next.collapsed:before{transform:rotate(-70deg)}:host.devui-splitter-bar-horizontal .devui-collapse.next:after,:host.devui-splitter-bar-horizontal .devui-collapse.next.collapsed:after{top:18px;right:1px}:host.devui-splitter-bar-horizontal .devui-collapse.next:after{transform:rotate(-70deg)}:host.devui-splitter-bar-horizontal .devui-collapse.next.collapsed:after{transform:rotate(70deg)}:host.devui-splitter-bar-vertical .devui-collapse{height:12px;width:30px}:host.devui-splitter-bar-vertical .devui-collapse.prev.hidden,:host.devui-splitter-bar-vertical .devui-collapse.next.hidden{display:none}:host.devui-splitter-bar-vertical .devui-collapse.prev{border-radius:0 0 var(--devui-border-radius-feedback, 4px) var(--devui-border-radius-feedback, 4px);top:100%}:host.devui-splitter-bar-vertical .devui-collapse.prev:before,:host.devui-splitter-bar-vertical .devui-collapse.prev.collapsed:before{bottom:5px;left:5px}:host.devui-splitter-bar-vertical .devui-collapse.prev:before{transform:rotate(-20deg)}:host.devui-splitter-bar-vertical .devui-collapse.prev.collapsed:before{transform:rotate(20deg)}:host.devui-splitter-bar-vertical .devui-collapse.prev:after,:host.devui-splitter-bar-vertical .devui-collapse.prev.collapsed:after{bottom:5px;left:14px}:host.devui-splitter-bar-vertical .devui-collapse.prev:after{transform:rotate(20deg)}:host.devui-splitter-bar-vertical .devui-collapse.prev.collapsed:after{transform:rotate(-20deg)}:host.devui-splitter-bar-vertical .devui-collapse.next{border-radius:var(--devui-border-radius-feedback, 4px) var(--devui-border-radius-feedback, 4px) 0 0;bottom:100%}:host.devui-splitter-bar-vertical .devui-collapse.next:before,:host.devui-splitter-bar-vertical .devui-collapse.next.collapsed:before{top:5px;left:5px}:host.devui-splitter-bar-vertical .devui-collapse.next:before{transform:rotate(20deg)}:host.devui-splitter-bar-vertical .devui-collapse.next.collapsed:before{transform:rotate(-20deg);top:5px;left:5px}:host.devui-splitter-bar-vertical .devui-collapse.next:after,:host.devui-splitter-bar-vertical .devui-collapse.next.collapsed:after{top:5px;left:14px}:host.devui-splitter-bar-vertical .devui-collapse.next:after{transform:rotate(-20deg)}:host.devui-splitter-bar-vertical .devui-collapse.next.collapsed:after{transform:rotate(20deg)}:host.devui-splitter-bar-horizontal.resizable:not(.none-resizable):hover,:host.devui-splitter-bar-horizontal.resizable:not(.none-resizable):focus,:host.devui-splitter-bar-horizontal.resizable:not(.none-resizable):active,:host.devui-splitter-bar-vertical.resizable:not(.none-resizable):hover,:host.devui-splitter-bar-vertical.resizable:not(.none-resizable):focus,:host.devui-splitter-bar-vertical.resizable:not(.none-resizable):active{background-color:var(--devui-brand-hover, #3979f9)}:host.devui-splitter-bar-horizontal.resizable:not(.none-resizable):after,:host.devui-splitter-bar-vertical.resizable:not(.none-resizable):after{content:\"\";display:block;position:absolute;z-index:10}:host.devui-splitter-bar-horizontal.resizable{cursor:col-resize}:host.devui-splitter-bar-horizontal.resizable:after{cursor:col-resize;height:100%;width:10px;top:0}:host.devui-splitter-bar-vertical.resizable{cursor:row-resize}:host.devui-splitter-bar-vertical.resizable:after{cursor:row-resize;width:100%;height:10px;left:0}\n"] }] }], ctorParameters: () => [{ type: i0.ElementRef }, { type: SplitterService }, { type: i0.Renderer2 }, { type: ResizeDirective, decorators: [{ type: Host }] }, { type: i0.ChangeDetectorRef, decorators: [{ type: SkipSelf }] }, { type: i0.ChangeDetectorRef }, { type: i3.I18nService }], propDecorators: { index: [{ type: Input }], orientation: [{ type: Input }], showCollapseButton: [{ type: Input }], collapsePosLeft: [{ type: Input }], collapsePosTop: [{ type: Input }], splitBarSize: [{ type: Input }], disabledBarSize: [{ type: Input }], class: [{ type: HostBinding, args: ['class'] }] } }); class SplitterPaneComponent { set collapsed(newCollapsed) { if (this._collapsed !== newCollapsed) { this._collapsed = newCollapsed; this.splitter.paneChangeSubject.next(true); } } get collapsed() { return this._collapsed; } set size(newSize) { this._size = newSize; this.widthBeforeShrink = newSize; this.renderer.setStyle(this.element, 'flex-basis', newSize); const paneFixedClass = 'devui-splitter-pane-fixed'; if (this.size) { // 设置 flex-grow 和 flex-shrink this.renderer.addClass(this.element, paneFixedClass); } else { this.renderer.removeClass(this.element, paneFixedClass); } } get size() { return this._size; } set order(paneOrder) { this._order = paneOrder; this.setOrderStyles(); } get order() { return this._order; } constructor(splitter, el, renderer) { this.splitter = splitter; this.el = el; this.renderer = renderer; // 当前panel是否可调整大小 this.resizable = true; // 面板是否可折叠 this.collapsible = false; // 是否折叠收缩 this.shrink = false; // 折叠收缩后宽度 this.shrinkWidth = 36; // 面板初始化是否折叠,默认不折叠 this._collapsed = false; // 非边缘面板折叠方向,before只生成向前折叠的按钮,after生成向后折叠按钮,both生成两个 this.collapseDirection = 'both'; // 大小改变事件 this.sizeChange = new EventEmitter(); // 收起和展开事件 this.collapsedChange = new EventEmitter(); // 收缩和展开事件 this.shrinkStatusChange = new EventEmitter(); this.paneClass = true; this._order = 0; // flex布局下pane位置 this.element = this.el.nativeElement; } ngOnChanges(changes) { if ((changes.collapsible && !changes.collapsible.isFirstChange()) || (changes.resizable && !changes.resizable.isFirstChange())) { this.splitter.paneChangeSubject.next(true); } } // 设置order setOrderStyles() { this.renderer.setStyle(this.element, 'order', this.order); } // 获取当前pane大小 get computedSize() { if (this.orientation === 'vertical') { return this.element.offsetHeight; } else { return this.element.offsetWidth; } } // 收起时隐藏当前pane toggleCollapseClass() { const paneHiddenClass = 'devui-splitter-pane-hidden'; if (!this._collapsed) { this.renderer.removeClass(this.element, paneHiddenClass); } else { this.renderer.addClass(this.element, paneHiddenClass); } if (this._collapsed && this.shrink) { this.renderer.removeClass(this.element, paneHiddenClass); this.renderer.setStyle(this.element, 'flex-basis', `${this.shrinkWidth}px`); this.shrinkStatusChange.emit(true); } else { this.renderer.setStyle(this.element, 'flex-basis', this.widthBeforeShrink); this.shrinkStatusChange.emit(false); } } // 收起时用于改变相邻pane的flex-grow属性来改变非自适应pane的size toggleNearPaneFlexGrow(collapsed) { const flexGrowClass = 'devui-splitter-pane-grow'; const hasFlexGrowClass = this.element.classList.contains(flexGrowClass); if (hasFlexGrowClass) { this.renderer.removeClass(this.element, flexGrowClass); } else if (collapsed) { this.renderer.addClass(this.element, flexGrowClass); } } ngAfterViewChecked() { // 视图检查完对resizeable pane设置flex属性 if (!this.size && !this.resizable) { this.renderer.addClass(this.element, 'devui-splitter-pane-fixed'); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SplitterPaneComponent, deps: [{ token: SplitterService }, { token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: SplitterPaneComponent, selector: "d-splitter-pane", inputs: { minSize: "minSize", maxSize: "maxSize", resizable: "resizable", collapsible: "collapsible", shrink: "shrink", shrinkWidth: "shrinkWidth", collapsed: "collapsed", collapseDirection: "collapseDirection", size: "size" }, outputs: { sizeChange: "sizeChange", collapsedChange: "collapsedChange", shrinkStatusChange: "shrinkStatusChange" }, host: { properties: { "class.devui-splitter-pane": "this.paneClass" } }, usesOnChanges: true, ngImport: i0, template: "<ng-content></ng-content>\n", styles: [":host.devui-splitter-pane{position:relative;flex:1 1 auto;display:block;min-width:0;max-width:100%;min-height:0;max-height:100%}:host.devui-splitter-pane-fixed{flex-grow:0;flex-shrink:0}:host.devui-splitter-pane-grow{flex-grow:1!important}:host.devui-splitter-pane-hidden{flex:0!important;overflow:hidden!important}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SplitterPaneComponent, decorators: [{ type: Component, args: [{ selector: 'd-splitter-pane', changeDetection: ChangeDetectionStrategy.OnPush, preserveWhitespaces: false, template: "<ng-content></ng-content>\n", styles: [":host.devui-splitter-pane{position:relative;flex:1 1 auto;display:block;min-width:0;max-width:100%;min-height:0;max-height:100%}:host.devui-splitter-pane-fixed{flex-grow:0;flex-shrink:0}:host.devui-splitter-pane-grow{flex-grow:1!important}:host.devui-splitter-pane-hidden{flex:0!important;overflow:hidden!important}\n"] }] }], ctorParameters: () => [{ type: SplitterService }, { type: i0.ElementRef }, { type: i0.Renderer2 }], propDecorators: { minSize: [{ type: Input }], maxSize: [{ type: Input }], resizable: [{ type: Input }], collapsible: [{ type: Input }], shrink: [{ type: Input }], shrinkWidth: [{ type: Input }], collapsed: [{ type: Input }], collapseDirection: [{ type: Input }], size: [{ type: Input }], sizeChange: [{ type: Output }], collapsedChange: [{ type: Output }], shrinkStatusChange: [{ type: Output }], paneClass: [{ type: HostBinding, args: ['class.devui-splitter-pane'] }] } }); class SplitterComponent { get class() { return 'devui-splitter devui-splitter-' + this.orientation; } constructor(el, splitter, cdr) { this.el = el; this.splitter = splitter; this.cdr = cdr; // 指定Splitter中窗格的方向,默认水平分割。 this.orientation = 'horizontal'; // 分隔条大小 this.splitBarSize = '2px'; // pane设置为不可调整大小时,生效 this.disabledBarSize = '1px'; // 是否显示展开/收缩按钮 this.showCollapseButton = true; } ngOnChanges(changes) { if (changes.orientation && !changes.orientation.isFirstChange()) { this.reconfigure(); } } ngAfterContentInit() { this.reconfigure(); // contentChildren 变化时,触发重新设置pane this.paneChangesSubscription = this.panes.changes.subscribe((panes) => { this.reconfigure(); this.cdr.detectChanges(); }); } toggleCollapsed(index = 0) { const target = this.splitterBars.toArray()[index]; target.collapsePrePane(); this.cdr.detectChanges(); } ngOnDestroy() { if (this.paneChangesSubscription) { this.paneChangesSubscription.unsubscribe(); } } // 配置pane reconfigure() { this.splitter.configPane({ panes: this.panes.toArray(), orientation: this.orientation, // 内容投影进组件之后,组件还没有渲染出dom,此时获取不到宽度,此处设置一个回调函数 containerSize: () => { if (this.orientation === 'vertical') { return this.el.nativeElement.clientHeight; } else { return this.el.nativeElement.clientWidth; } }, }); // 投影后获取panes才能循环渲染出bar setTimeout(() => { if (this.splitterBars.length) { this.splitter.bars = this.splitterBars.toArray(); } }); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SplitterComponent, deps: [{ token: i0.ElementRef }, { token: SplitterService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: SplitterComponent, selector: "d-splitter", inputs: { orientation: "orientation", splitBarSize: "splitBarSize", disabledBarSize: "disabledBarSize", showCollapseButton: "showCollapseButton", collapsePosLeft: "collapsePosLeft", collapsePosTop: "collapsePosTop" }, host: { properties: { "class": "this.class" } }, providers: [SplitterService], queries: [{ propertyName: "panes", predicate: SplitterPaneComponent }], viewQueries: [{ propertyName: "splitterBars", predicate: ["bar"], descendants: true }], exportAs: ["dSplitter"], usesOnChanges: true, ngImport: i0, template: "<ng-content select=\"d-splitter-pane\"></ng-content>\n<ng-container *ngFor=\"let pane of panes; let index = index; let last = last\">\n <d-splitter-bar\n #bar\n dResize\n [style.order]=\"index * 2 + 1\"\n *ngIf=\"!last\"\n [index]=\"index\"\n [splitBarSize]=\"splitBarSize\"\n [disabledBarSize]=\"disabledBarSize\"\n [orientation]=\"orientation\"\n [showCollapseButton]=\"showCollapseButton\"\n [collapsePosLeft]=\"collapsePosLeft\"\n [collapsePosTop]=\"collapsePosTop\"\n >\n </d-splitter-bar>\n</ng-container>\n", styles: [":host{display:flex;width:100%;height:auto;position:relative;border-radius:var(--devui-border-radius, 2px)}:host.devui-splitter-horizontal{flex-direction:row}:host.devui-splitter-vertical{flex-direction:column}\n"], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: SplitterBarComponent, selector: "d-splitter-bar", inputs: ["index", "orientation", "showCollapseButton", "collapsePosLeft", "collapsePosTop", "splitBarSize", "disabledBarSize"] }, { kind: "directive", type: ResizeDirective, selector: "[dResize]", inputs: ["enableResize"], outputs: ["pressEvent", "dragEvent", "releaseEvent"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SplitterComponent, decorators: [{ type: Component, args: [{ selector: 'd-splitter', exportAs: 'dSplitter', changeDetection: ChangeDetectionStrategy.OnPush, providers: [SplitterService], preserveWhitespaces: false, template: "<ng-content select=\"d-splitter-pane\"></ng-content>\n<ng-container *ngFor=\"let pane of panes; let index = index; let last = last\">\n <d-splitter-bar\n #bar\n dResize\n [style.order]=\"index * 2 + 1\"\n *ngIf=\"!last\"\n [index]=\"index\"\n [splitBarSize]=\"splitBarSize\"\n [disabledBarSize]=\"disabledBarSize\"\n [orientation]=\"orientation\"\n [showCollapseButton]=\"showCollapseButton\"\n [collapsePosLeft]=\"collapsePosLeft\"\n [collapsePosTop]=\"collapsePosTop\"\n >\n </d-splitter-bar>\n</ng-container>\n", styles: [":host{display:flex;width:100%;height:auto;position:relative;border-radius:var(--devui-border-radius, 2px)}:host.devui-splitter-horizontal{flex-direction:row}:host.devui-splitter-vertical{flex-direction:column}\n"] }] }], ctorParameters: () => [{ type: i0.ElementRef }, { type: SplitterService }, { type: i0.ChangeDetectorRef }], propDecorators: { orientation: [{ type: Input }], splitBarSize: [{ type: Input }], disabledBarSize: [{ type: Input }], showCollapseButton: [{ type: Input }], collapsePosLeft: [{ type: Input }], collapsePosTop: [{ type: Input }], class: [{ type: HostBinding, args: ['class'] }], panes: [{ type: ContentChildren, args: [SplitterPaneComponent] }], splitterBars: [{ type: ViewChildren, args: ['bar'] }] } }); class SplitterModule { static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SplitterModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); } static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: SplitterModule, declarations: [SplitterComponent, SplitterPaneComponent, SplitterBarComponent, ResizeDirective], imports: [CommonModule, FormsModule, PopoverModule], exports: [SplitterComponent, SplitterPaneComponent, SplitterBarComponent, ResizeDirective] }); } static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SplitterModule, imports: [CommonModule, FormsModule, PopoverModule] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SplitterModule, decorators: [{ type: NgModule, args: [{ imports: [ CommonModule, FormsModule, PopoverModule ], exports: [ SplitterComponent, SplitterPaneComponent, SplitterBarComponent, ResizeDirective ], declarations: [ SplitterComponent, SplitterPaneComponent, SplitterBarComponent, ResizeDirective ], providers: [] }] }] }); /** * Generated bundle index. Do not edit. */ export { ResizeDirective, SplitterBarComponent, SplitterComponent, SplitterModule, SplitterPaneComponent, SplitterService }; //# sourceMappingURL=ng-devui-splitter.mjs.map