Refactor #3965 - For Splitter
parent
b752ba69e9
commit
6b3fe54feb
|
@ -0,0 +1,103 @@
|
||||||
|
<script>
|
||||||
|
import BaseComponent from 'primevue/basecomponent';
|
||||||
|
import { useStyle } from 'primevue/usestyle';
|
||||||
|
|
||||||
|
const styles = `
|
||||||
|
.p-splitter {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-splitter-vertical {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-splitter-gutter {
|
||||||
|
flex-grow: 0;
|
||||||
|
flex-shrink: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
cursor: col-resize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-splitter-horizontal.p-splitter-resizing {
|
||||||
|
cursor: col-resize;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-splitter-horizontal > .p-splitter-gutter > .p-splitter-gutter-handle {
|
||||||
|
height: 24px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-splitter-horizontal > .p-splitter-gutter {
|
||||||
|
cursor: col-resize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-splitter-vertical.p-splitter-resizing {
|
||||||
|
cursor: row-resize;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-splitter-vertical > .p-splitter-gutter {
|
||||||
|
cursor: row-resize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-splitter-vertical > .p-splitter-gutter > .p-splitter-gutter-handle {
|
||||||
|
width: 24px;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const classes = {
|
||||||
|
root: ({ props }) => ['p-splitter p-component', 'p-splitter-' + props.layout],
|
||||||
|
gutter: 'p-splitter-gutter',
|
||||||
|
gutterHandler: 'p-splitter-gutter-handle'
|
||||||
|
};
|
||||||
|
|
||||||
|
const inlineStyles = {
|
||||||
|
root: ({ props }) => [{ display: 'flex', 'flex-wrap': 'nowrap' }, props.layout === 'vertical' ? { 'flex-direction': 'column' } : '']
|
||||||
|
};
|
||||||
|
|
||||||
|
const { load: loadStyle, unload: unloadStyle } = useStyle(styles, { id: 'primevue_splitter_style', manual: true });
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'BaseSplitter',
|
||||||
|
extends: BaseComponent,
|
||||||
|
props: {
|
||||||
|
layout: {
|
||||||
|
type: String,
|
||||||
|
default: 'horizontal'
|
||||||
|
},
|
||||||
|
gutterSize: {
|
||||||
|
type: Number,
|
||||||
|
default: 4
|
||||||
|
},
|
||||||
|
stateKey: {
|
||||||
|
type: String,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
stateStorage: {
|
||||||
|
type: String,
|
||||||
|
default: 'session'
|
||||||
|
},
|
||||||
|
step: {
|
||||||
|
type: Number,
|
||||||
|
default: 5
|
||||||
|
}
|
||||||
|
},
|
||||||
|
css: {
|
||||||
|
classes,
|
||||||
|
inlineStyles
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
isUnstyled: {
|
||||||
|
immediate: true,
|
||||||
|
handler(newValue) {
|
||||||
|
!newValue && loadStyle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -119,6 +119,11 @@ export interface SplitterProps {
|
||||||
* @type {SplitterPassThroughOptions}
|
* @type {SplitterPassThroughOptions}
|
||||||
*/
|
*/
|
||||||
pt?: SplitterPassThroughOptions;
|
pt?: SplitterPassThroughOptions;
|
||||||
|
/**
|
||||||
|
* When enabled, it removes component related styles in the core.
|
||||||
|
* @defaultValue false
|
||||||
|
*/
|
||||||
|
unstyled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,54 +1,34 @@
|
||||||
<template>
|
<template>
|
||||||
<div :class="containerClass" v-bind="ptm('root')">
|
<div :class="cx('root')" :style="sx('root')" :data-p-resizing="false" v-bind="ptm('root')">
|
||||||
<template v-for="(panel, i) of panels" :key="i">
|
<template v-for="(panel, i) of panels" :key="i">
|
||||||
<component :is="panel" tabindex="-1"></component>
|
<component :is="panel" tabindex="-1"></component>
|
||||||
<div
|
<div
|
||||||
v-if="i !== panels.length - 1"
|
v-if="i !== panels.length - 1"
|
||||||
class="p-splitter-gutter"
|
ref="gutter"
|
||||||
|
:class="cx('gutter')"
|
||||||
role="separator"
|
role="separator"
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
@mousedown="onGutterMouseDown($event, i)"
|
@mousedown="onGutterMouseDown($event, i)"
|
||||||
@touchstart="onGutterTouchStart($event, i)"
|
@touchstart="onGutterTouchStart($event, i)"
|
||||||
@touchmove="onGutterTouchMove($event, i)"
|
@touchmove="onGutterTouchMove($event, i)"
|
||||||
@touchend="onGutterTouchEnd($event, i)"
|
@touchend="onGutterTouchEnd($event, i)"
|
||||||
|
:data-p-gutter-resizing="false"
|
||||||
v-bind="ptm('gutter')"
|
v-bind="ptm('gutter')"
|
||||||
>
|
>
|
||||||
<div class="p-splitter-gutter-handle" tabindex="0" :style="gutterStyle" :aria-orientation="layout" :aria-valuenow="prevSize" @keyup="onGutterKeyUp" @keydown="onGutterKeyDown($event, i)" v-bind="ptm('gutterhandler')"></div>
|
<div :class="cx('gutterHandler')" tabindex="0" :style="[gutterStyle]" :aria-orientation="layout" :aria-valuenow="prevSize" @keyup="onGutterKeyUp" @keydown="onGutterKeyDown($event, i)" v-bind="ptm('gutterHandler')"></div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import BaseComponent from 'primevue/basecomponent';
|
|
||||||
import { DomHandler, ObjectUtils } from 'primevue/utils';
|
import { DomHandler, ObjectUtils } from 'primevue/utils';
|
||||||
|
import BaseSplitter from './BaseSplitter.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Splitter',
|
name: 'Splitter',
|
||||||
extends: BaseComponent,
|
extends: BaseSplitter,
|
||||||
emits: ['resizestart', 'resizeend'],
|
emits: ['resizestart', 'resizeend'],
|
||||||
props: {
|
|
||||||
layout: {
|
|
||||||
type: String,
|
|
||||||
default: 'horizontal'
|
|
||||||
},
|
|
||||||
gutterSize: {
|
|
||||||
type: Number,
|
|
||||||
default: 4
|
|
||||||
},
|
|
||||||
stateKey: {
|
|
||||||
type: String,
|
|
||||||
default: null
|
|
||||||
},
|
|
||||||
stateStorage: {
|
|
||||||
type: String,
|
|
||||||
default: 'session'
|
|
||||||
},
|
|
||||||
step: {
|
|
||||||
type: Number,
|
|
||||||
default: 5
|
|
||||||
}
|
|
||||||
},
|
|
||||||
dragging: false,
|
dragging: false,
|
||||||
mouseMoveListener: null,
|
mouseMoveListener: null,
|
||||||
mouseUpListener: null,
|
mouseUpListener: null,
|
||||||
|
@ -78,7 +58,7 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!initialized) {
|
if (!initialized) {
|
||||||
let children = [...this.$el.children].filter((child) => DomHandler.hasClass(child, 'p-splitter-panel'));
|
let children = [...this.$el.children].filter((child) => child.getAttribute('data-pc-name') === 'splitterpanel');
|
||||||
let _panelSizes = [];
|
let _panelSizes = [];
|
||||||
|
|
||||||
this.panels.map((panel, i) => {
|
this.panels.map((panel, i) => {
|
||||||
|
@ -124,8 +104,8 @@ export default {
|
||||||
|
|
||||||
this.prevPanelIndex = index;
|
this.prevPanelIndex = index;
|
||||||
this.$emit('resizestart', { originalEvent: event, sizes: this.panelSizes });
|
this.$emit('resizestart', { originalEvent: event, sizes: this.panelSizes });
|
||||||
DomHandler.addClass(this.gutterElement, 'p-splitter-gutter-resizing');
|
this.$refs.gutter[index].setAttribute('data-p-gutter-resizing', true);
|
||||||
DomHandler.addClass(this.$el, 'p-splitter-resizing');
|
this.$el.setAttribute('data-p-resizing', true);
|
||||||
},
|
},
|
||||||
onResize(event, step, isKeyDown) {
|
onResize(event, step, isKeyDown) {
|
||||||
let newPos, newPrevPanelSize, newNextPanelSize;
|
let newPos, newPrevPanelSize, newNextPanelSize;
|
||||||
|
@ -161,8 +141,8 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$emit('resizeend', { originalEvent: event, sizes: this.panelSizes });
|
this.$emit('resizeend', { originalEvent: event, sizes: this.panelSizes });
|
||||||
DomHandler.removeClass(this.gutterElement, 'p-splitter-gutter-resizing');
|
this.$refs.gutter.forEach((gutter) => gutter.setAttribute('data-p-gutter-resizing', false));
|
||||||
DomHandler.removeClass(this.$el, 'p-splitter-resizing');
|
this.$el.setAttribute('data-p-resizing', false);
|
||||||
this.clear();
|
this.clear();
|
||||||
},
|
},
|
||||||
repeat(event, index, step) {
|
repeat(event, index, step) {
|
||||||
|
@ -347,7 +327,7 @@ export default {
|
||||||
|
|
||||||
if (stateString) {
|
if (stateString) {
|
||||||
this.panelSizes = JSON.parse(stateString);
|
this.panelSizes = JSON.parse(stateString);
|
||||||
let children = [...this.$el.children].filter((child) => DomHandler.hasClass(child, 'p-splitter-panel'));
|
let children = [...this.$el.children].filter((child) => child.getAttribute('data-pc-name') === 'splitterpanel');
|
||||||
|
|
||||||
children.forEach((child, i) => {
|
children.forEach((child, i) => {
|
||||||
child.style.flexBasis = 'calc(' + this.panelSizes[i] + '% - ' + (this.panels.length - 1) * this.gutterSize + 'px)';
|
child.style.flexBasis = 'calc(' + this.panelSizes[i] + '% - ' + (this.panels.length - 1) * this.gutterSize + 'px)';
|
||||||
|
@ -360,9 +340,6 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
containerClass() {
|
|
||||||
return ['p-splitter p-component', 'p-splitter-' + this.layout];
|
|
||||||
},
|
|
||||||
panels() {
|
panels() {
|
||||||
const panels = [];
|
const panels = [];
|
||||||
|
|
||||||
|
@ -390,64 +367,3 @@ export default {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
|
||||||
.p-splitter {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.p-splitter-vertical {
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.p-splitter-panel {
|
|
||||||
flex-grow: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.p-splitter-panel-nested {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.p-splitter-panel .p-splitter {
|
|
||||||
flex-grow: 1;
|
|
||||||
border: 0 none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.p-splitter-gutter {
|
|
||||||
flex-grow: 0;
|
|
||||||
flex-shrink: 0;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
cursor: col-resize;
|
|
||||||
}
|
|
||||||
|
|
||||||
.p-splitter-horizontal.p-splitter-resizing {
|
|
||||||
cursor: col-resize;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.p-splitter-horizontal > .p-splitter-gutter > .p-splitter-gutter-handle {
|
|
||||||
height: 24px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.p-splitter-horizontal > .p-splitter-gutter {
|
|
||||||
cursor: col-resize;
|
|
||||||
}
|
|
||||||
|
|
||||||
.p-splitter-vertical.p-splitter-resizing {
|
|
||||||
cursor: row-resize;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.p-splitter-vertical > .p-splitter-gutter {
|
|
||||||
cursor: row-resize;
|
|
||||||
}
|
|
||||||
|
|
||||||
.p-splitter-vertical > .p-splitter-gutter > .p-splitter-gutter-handle {
|
|
||||||
width: 24px;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
<script>
|
||||||
|
import BaseComponent from 'primevue/basecomponent';
|
||||||
|
import { useStyle } from 'primevue/usestyle';
|
||||||
|
|
||||||
|
const styles = `
|
||||||
|
.p-splitter-panel {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-splitter-panel-nested {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-splitter-panel .p-splitter {
|
||||||
|
flex-grow: 1;
|
||||||
|
border: 0 none;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const classes = {
|
||||||
|
root: ({ instance }) => ['p-splitter-panel', { 'p-splitter-panel-nested': instance.isNested }]
|
||||||
|
};
|
||||||
|
|
||||||
|
const { load: loadStyle, unload: unloadStyle } = useStyle(styles, { id: 'primevue_splitterpanel_style', manual: true });
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'BaseSplitterPanel',
|
||||||
|
extends: BaseComponent,
|
||||||
|
props: {
|
||||||
|
size: {
|
||||||
|
type: Number,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
minSize: {
|
||||||
|
type: Number,
|
||||||
|
default: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
css: {
|
||||||
|
classes
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
isUnstyled: {
|
||||||
|
immediate: true,
|
||||||
|
handler(newValue) {
|
||||||
|
!newValue && loadStyle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -54,6 +54,11 @@ export interface SplitterPanelProps {
|
||||||
* @type {SplitterPanelPassThroughOptions}
|
* @type {SplitterPanelPassThroughOptions}
|
||||||
*/
|
*/
|
||||||
pt?: SplitterPanelPassThroughOptions;
|
pt?: SplitterPanelPassThroughOptions;
|
||||||
|
/**
|
||||||
|
* When enabled, it removes component related styles in the core.
|
||||||
|
* @defaultValue false
|
||||||
|
*/
|
||||||
|
unstyled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,29 +1,16 @@
|
||||||
<template>
|
<template>
|
||||||
<div ref="container" :class="containerClass" v-bind="ptm('root')">
|
<div ref="container" :class="cx('root')" data-pc-name="splitterpanel" v-bind="ptm('root')">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import BaseComponent from 'primevue/basecomponent';
|
import BaseSplitterPanel from './BaseSplitterPanel.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'SplitterPanel',
|
name: 'SplitterPanel',
|
||||||
extends: BaseComponent,
|
extends: BaseSplitterPanel,
|
||||||
props: {
|
|
||||||
size: {
|
|
||||||
type: Number,
|
|
||||||
default: null
|
|
||||||
},
|
|
||||||
minSize: {
|
|
||||||
type: Number,
|
|
||||||
default: null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
computed: {
|
||||||
containerClass() {
|
|
||||||
return ['p-splitter-panel', { 'p-splitter-panel-nested': this.isNested }];
|
|
||||||
},
|
|
||||||
isNested() {
|
isNested() {
|
||||||
return this.$slots.default().some((child) => {
|
return this.$slots.default().some((child) => {
|
||||||
return child.type.name === 'Splitter';
|
return child.type.name === 'Splitter';
|
||||||
|
|
Loading…
Reference in New Issue