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