Skip to content

Commit

Permalink
refactor(splitbox): do not use flex anymore, use absolute position
Browse files Browse the repository at this point in the history
  • Loading branch information
bubkoo committed Dec 13, 2019
1 parent 343b398 commit 071f748
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 48 deletions.
70 changes: 57 additions & 13 deletions packages/x6-components/src/split-box/box.tsx
Expand Up @@ -2,23 +2,64 @@ import React from 'react'

export class Box extends React.PureComponent<Box.Props> {
render() {
const { className, split, size, refIt } = this.props
const {
refIt,
className,
index,
currentSize,
oppositeSize,
vertical,
} = this.props

const style = {
display: 'flex',
flexShrink: 0,
overflow: 'hidden',
position: 'relative',
...this.props.style,
overflow: 'hidden',
position: 'absolute',
zIndex: 1,
} as React.CSSProperties

if (size != null) {
if (split === 'vertical') {
style.width = size
if (vertical) {
style.bottom = 0
style.top = 0
} else {
style.left = 0
style.right = 0
}

if (currentSize != null) {
if (vertical) {
style.width = currentSize
if (index === 1) {
style.left = 0
} else {
style.right = 0
}
} else {
style.height = size
style.height = currentSize
if (index === 1) {
style.top = 0
} else {
style.bottom = 0
}
}
} else {
style.flex = 1
if (vertical) {
if (index === 1) {
style.left = 0
style.right = oppositeSize
} else {
style.left = oppositeSize
style.right = 0
}
} else {
if (index === 1) {
style.top = 0
style.bottom = oppositeSize
} else {
style.top = oppositeSize
style.bottom = 0
}
}
}

return (
Expand All @@ -31,10 +72,13 @@ export class Box extends React.PureComponent<Box.Props> {

export namespace Box {
export interface Props {
className?: string
size?: number | string
split?: 'vertical' | 'horizontal'
style?: React.CSSProperties
className?: string
currentSize?: number | string
oppositeSize?: number | string
index: 1 | 2
vertical: boolean
isPrimary: boolean
refIt: React.LegacyRef<HTMLDivElement>
}
}
6 changes: 4 additions & 2 deletions packages/x6-components/src/split-box/resizer.tsx
Expand Up @@ -24,7 +24,7 @@ export class Resizer extends React.PureComponent<Resizer.Props> {
onMouseMove = (
deltaX: number,
deltaY: number,
pos: MouseMoveTracker.ClientPosition
pos: MouseMoveTracker.ClientPosition,
) => {
if (this.props.onMouseMove != null) {
this.props.onMouseMove(deltaX, deltaY, pos)
Expand Down Expand Up @@ -58,6 +58,7 @@ export class Resizer extends React.PureComponent<Resizer.Props> {
style={style}
className={className}
onClick={this.onClick}
ref={this.props.refIt}
onDoubleClick={this.onDoubleClick}
onMouseDown={this.onMouseDown}
/>
Expand All @@ -69,13 +70,14 @@ export namespace Resizer {
export interface Props {
className?: string
style?: React.CSSProperties
refIt: React.LegacyRef<HTMLDivElement>
onClick?: (e: React.MouseEvent) => void
onDoubleClick?: (e: React.MouseEvent) => void
onMouseDown: (e: React.MouseEvent) => void
onMouseMove?: (
deltaX: number,
deltaY: number,
pos: MouseMoveTracker.ClientPosition
pos: MouseMoveTracker.ClientPosition,
) => void
onMouseMoveEnd?: () => void
}
Expand Down
105 changes: 78 additions & 27 deletions packages/x6-components/src/split-box/splitbox.tsx
Expand Up @@ -12,6 +12,7 @@ export class SplitBox extends React.PureComponent<
private box1Elem: HTMLDivElement
private box2Elem: HTMLDivElement
private maskElem: HTMLDivElement
private resizerElem: HTMLDivElement

private minSize: number
private maxSize: number
Expand All @@ -32,11 +33,7 @@ export class SplitBox extends React.PureComponent<
getNextState(props: SplitBox.Props): SplitBox.State {
const { size, defaultSize, primary } = props
const initialSize =
size !== undefined
? size
: defaultSize !== undefined
? defaultSize
: undefined
size != null ? size : defaultSize != null ? defaultSize : '25%'

return {
box1Size: primary === 'first' ? initialSize : undefined,
Expand Down Expand Up @@ -111,11 +108,31 @@ export class SplitBox extends React.PureComponent<
}

setPrimarySize(size: number) {
const styleName = this.isVertical() ? 'width' : 'height'
const primaryBox = this.isPrimaryFirst() ? this.box1Elem : this.box2Elem
const isFirstPrimary = this.isPrimaryFirst()
const primaryBox = isFirstPrimary ? this.box1Elem : this.box2Elem
const secondBox = isFirstPrimary ? this.box2Elem : this.box1Elem
const resizerElem = this.resizerElem

primaryBox.style.flex = 'none'
primaryBox.style[styleName] = `${size}px`
const value = `${size}px`
if (this.isVertical()) {
primaryBox.style.width = value
if (isFirstPrimary) {
secondBox.style.left = value
resizerElem.style.left = value
} else {
secondBox.style.right = value
resizerElem.style.right = value
}
} else {
primaryBox.style.height = value
if (isFirstPrimary) {
secondBox.style.top = value
resizerElem.style.top = value
} else {
secondBox.style.bottom = value
resizerElem.style.bottom = value
}
}
}

updateCursor(size: number, minSize: number, maxSize: number) {
Expand Down Expand Up @@ -218,18 +235,23 @@ export class SplitBox extends React.PureComponent<
this.container = container
}

refResizer = (elem: HTMLDivElement) => {
this.resizerElem = elem
}

renderBox(baseCls: string, index: 1 | 2) {
const primary = index === 1 ? 'first' : 'second'
const isPrimary = this.props.primary === primary
const size = index === 1 ? this.state.box1Size : this.state.box2Size
const currentSize = index === 1 ? this.state.box1Size : this.state.box2Size
const oppositeSize = index === 1 ? this.state.box2Size : this.state.box1Size
const style = {
...this.props.boxStyle,
...(isPrimary ? this.props.primaryBoxStyle : this.props.secondBoxStyle),
}

const classes = classNames(
`${baseCls}-item`,
isPrimary ? `${baseCls}-item-primary` : `${baseCls}-item-second`
isPrimary ? `${baseCls}-item-primary` : `${baseCls}-item-second`,
)

const ref = (elem: HTMLDivElement) => {
Expand All @@ -246,51 +268,79 @@ export class SplitBox extends React.PureComponent<
<Box
key={`box${index}`}
refIt={ref}
size={size}
style={style}
index={index}
className={classes}
split={this.props.split}
currentSize={currentSize}
oppositeSize={oppositeSize}
vertical={this.isVertical()}
isPrimary={isPrimary}
>
{children[index - 1]}
</Box>
)
}

renderResizer(baseCls: string) {
const style: React.CSSProperties = {
...this.props.resizerStyle,
}

style.position = 'absolute'
style.zIndex = 2
if (this.isVertical()) {
style.top = 0
style.bottom = 0

if (this.props.resizable === true) {
style.cursor = 'col-resize'
}

if (this.isPrimaryFirst()) {
style.left = this.state.box1Size
} else {
style.right = this.state.box2Size
}
} else {
style.left = 0
style.right = 0

if (this.props.resizable === true) {
style.cursor = 'row-resize'
}

if (this.isPrimaryFirst()) {
style.top = this.state.box1Size
} else {
style.bottom = this.state.box2Size
}
}

return (
<Resizer
key="resizer"
style={style}
className={`${baseCls}-resizer`}
style={this.props.resizerStyle}
refIt={this.refResizer}
onClick={this.props.onResizerClick}
onDoubleClick={this.props.onResizerDoubleClick}
onMouseDown={this.onMouseDown}
onMouseMove={this.onMouseMove}
onMouseMoveEnd={this.onMouseMoveEnd}
onDoubleClick={this.props.onResizerDoubleClick}
/>
)
}

render() {
const style: React.CSSProperties = {
flex: 1,
flexShrink: 0,
display: 'flex',
...this.props.style,
overflow: 'hidden',
position: 'relative',
width: '100%',
height: '100%',
...this.props.style,
}

if (this.props.split === 'vertical') {
style.flexDirection = 'row'
} else {
style.flexDirection = 'column'
}

const baseCls = `${this.props.prefixCls}-split-box`

const classes = classNames(baseCls, `${baseCls}-${this.props.split}`, {
[`${baseCls}-disabled`]: !this.props.resizable,
})
Expand Down Expand Up @@ -332,11 +382,12 @@ export namespace SplitBox {
onResizerDoubleClick?: () => void
}

export const defaultProps = {
export const defaultProps: Props = {
resizable: true,
split: 'vertical',
primary: 'first',
prefixCls: 'x6',
defaultSize: '25%',
}

export interface State {
Expand Down
6 changes: 0 additions & 6 deletions packages/x6-components/src/split-box/style/index.less
Expand Up @@ -4,21 +4,15 @@

.@{splitBox-prefix-cls} {
&-vertical > &-resizer {
position: relative;
z-index: 9;
width: 4px;
margin: 0 -2px;
background: transparent;
cursor: col-resize;
}

&-horizontal > &-resizer {
position: relative;
z-index: 9;
height: 4px;
margin: -2px;
background: transparent;
cursor: row-resize;
}

&-disabled > &-resizer {
Expand Down

0 comments on commit 071f748

Please sign in to comment.