WIP Split resizer into 2 part "Resizer" and the "Threesizer"
parent
4f0988cc21
commit
0311f299af
|
@ -3,43 +3,23 @@ import classnames from 'classnames'
|
|||
import uuid from 'uuid'
|
||||
import _ from 'lodash'
|
||||
|
||||
import ResizeDivision from 'src/shared/components/ResizeDivision'
|
||||
import ResizeHalf from 'src/shared/components/ResizeHalf'
|
||||
import ResizeHandle from 'src/shared/components/ResizeHandle'
|
||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||
import {
|
||||
MIN_DIVISIONS,
|
||||
HANDLE_HORIZONTAL,
|
||||
HANDLE_VERTICAL,
|
||||
} from 'src/shared/constants/'
|
||||
|
||||
const initialDragEvent = {
|
||||
percentX: 0,
|
||||
percentY: 0,
|
||||
mouseX: null,
|
||||
mouseY: null,
|
||||
}
|
||||
import {HANDLE_HORIZONTAL, HANDLE_VERTICAL} from 'src/shared/constants/index'
|
||||
|
||||
interface State {
|
||||
activeHandleID: string
|
||||
divisions: DivisionState[]
|
||||
dragDirection: string
|
||||
dragEvent: any
|
||||
}
|
||||
|
||||
interface Division {
|
||||
name?: string
|
||||
render: () => ReactElement<any>
|
||||
minPixels?: number
|
||||
}
|
||||
|
||||
interface DivisionState extends Division {
|
||||
id: string
|
||||
size: number
|
||||
minPixels?: number
|
||||
topPercent: number
|
||||
bottomPercent: number
|
||||
isDragging: boolean
|
||||
}
|
||||
|
||||
interface Props {
|
||||
divisions: Division[]
|
||||
orientation: string
|
||||
topHalf: () => ReactElement<any>
|
||||
topMinPixels: number
|
||||
bottomHalf: () => ReactElement<any>
|
||||
bottomMinPixels: number
|
||||
orientation?: string
|
||||
containerClass: string
|
||||
}
|
||||
|
||||
|
@ -56,10 +36,9 @@ class Resizer extends Component<Props, State> {
|
|||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
activeHandleID: null,
|
||||
divisions: this.initialDivisions,
|
||||
dragEvent: initialDragEvent,
|
||||
dragDirection: '',
|
||||
topPercent: 0.5,
|
||||
bottomPercent: 0.5,
|
||||
isDragging: false,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,15 +81,14 @@ class Resizer extends Component<Props, State> {
|
|||
}
|
||||
|
||||
public render() {
|
||||
const {activeHandleID, divisions} = this.state
|
||||
const {orientation} = this.props
|
||||
|
||||
if (divisions.length < MIN_DIVISIONS) {
|
||||
console.error(
|
||||
`There must be at least ${MIN_DIVISIONS}' divisions in Resizer`
|
||||
)
|
||||
return
|
||||
}
|
||||
const {isDragging, topPercent, bottomPercent} = this.state
|
||||
const {
|
||||
topHalf,
|
||||
topMinPixels,
|
||||
bottomHalf,
|
||||
bottomMinPixels,
|
||||
orientation,
|
||||
} = this.props
|
||||
|
||||
return (
|
||||
<div
|
||||
|
@ -120,21 +98,23 @@ class Resizer extends Component<Props, State> {
|
|||
onMouseMove={this.handleDrag}
|
||||
ref={r => (this.containerRef = r)}
|
||||
>
|
||||
{divisions.map((d, i) => (
|
||||
<ResizeDivision
|
||||
key={d.id}
|
||||
id={d.id}
|
||||
name={d.name}
|
||||
size={d.size}
|
||||
draggable={i > 0}
|
||||
minPixels={d.minPixels}
|
||||
orientation={orientation}
|
||||
activeHandleID={activeHandleID}
|
||||
onHandleStartDrag={this.handleStartDrag}
|
||||
maxPercent={this.maximumHeightPercent}
|
||||
render={this.props.divisions[i].render}
|
||||
/>
|
||||
))}
|
||||
<ResizeHalf
|
||||
percent={topPercent}
|
||||
minPixels={topMinPixels}
|
||||
render={topHalf}
|
||||
orientation={orientation}
|
||||
/>
|
||||
<ResizeHandle
|
||||
onStartDrag={this.handleStartDrag}
|
||||
isDragging={isDragging}
|
||||
orientation={orientation}
|
||||
/>
|
||||
<ResizeHalf
|
||||
percent={bottomPercent}
|
||||
minPixels={bottomMinPixels}
|
||||
render={bottomHalf}
|
||||
orientation={orientation}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -149,39 +129,23 @@ class Resizer extends Component<Props, State> {
|
|||
|
||||
private get className(): string {
|
||||
const {orientation, containerClass} = this.props
|
||||
const {activeHandleID} = this.state
|
||||
|
||||
return classnames(`resize--container ${containerClass}`, {
|
||||
'resize--dragging': activeHandleID,
|
||||
horizontal: orientation === HANDLE_HORIZONTAL,
|
||||
vertical: orientation === HANDLE_VERTICAL,
|
||||
})
|
||||
}
|
||||
|
||||
private get initialDivisions() {
|
||||
const {divisions} = this.props
|
||||
|
||||
const size = 1 / divisions.length
|
||||
|
||||
return divisions.map(d => ({
|
||||
...d,
|
||||
id: uuid.v4(),
|
||||
size,
|
||||
minPixels: d.minPixels || 0,
|
||||
}))
|
||||
}
|
||||
|
||||
private handleStartDrag = (activeHandleID, e: MouseEvent<HTMLElement>) => {
|
||||
const dragEvent = this.mousePosWithinContainer(e)
|
||||
this.setState({activeHandleID, dragEvent})
|
||||
private handleStartDrag = () => {
|
||||
this.setState({isDragging: true})
|
||||
}
|
||||
|
||||
private handleStopDrag = () => {
|
||||
this.setState({activeHandleID: '', dragEvent: initialDragEvent})
|
||||
this.setState({isDragging: false})
|
||||
}
|
||||
|
||||
private handleMouseLeave = () => {
|
||||
this.setState({activeHandleID: '', dragEvent: initialDragEvent})
|
||||
this.setState({isDragging: false})
|
||||
}
|
||||
|
||||
private mousePosWithinContainer = (e: MouseEvent<HTMLElement>) => {
|
||||
|
@ -242,24 +206,6 @@ class Resizer extends Component<Props, State> {
|
|||
return yMinPixels / height
|
||||
}
|
||||
|
||||
private get maximumHeightPercent(): number {
|
||||
if (!this.containerRef) {
|
||||
return 1
|
||||
}
|
||||
|
||||
const {divisions} = this.state
|
||||
const {height} = this.containerRef.getBoundingClientRect()
|
||||
|
||||
const totalMinPixels = divisions.reduce(
|
||||
(acc, div) => acc + div.minPixels,
|
||||
0
|
||||
)
|
||||
|
||||
const maximumPixels = height - totalMinPixels
|
||||
|
||||
return this.minPercentY(maximumPixels)
|
||||
}
|
||||
|
||||
private handleDrag = (e: MouseEvent<HTMLElement>) => {
|
||||
const {activeHandleID} = this.state
|
||||
if (!activeHandleID) {
|
||||
|
@ -283,143 +229,6 @@ class Resizer extends Component<Props, State> {
|
|||
private isAtMinHeight = (division: DivisionState): boolean => {
|
||||
return division.size <= this.minPercentY(division.minPixels)
|
||||
}
|
||||
|
||||
private get move() {
|
||||
const {activeHandleID} = this.state
|
||||
|
||||
const activePosition = _.findIndex(
|
||||
this.state.divisions,
|
||||
d => d.id === activeHandleID
|
||||
)
|
||||
|
||||
return {
|
||||
up: this.up(activePosition),
|
||||
down: this.down(activePosition),
|
||||
left: this.left(activePosition),
|
||||
right: this.right(activePosition),
|
||||
}
|
||||
}
|
||||
|
||||
private up = activePosition => () => {
|
||||
const divisions = this.state.divisions.map((d, i, divs) => {
|
||||
const before = i < activePosition
|
||||
const current = i === activePosition
|
||||
const after = i === activePosition + 1
|
||||
|
||||
if (before) {
|
||||
const below = divs[i + 1]
|
||||
const aboveCurrent = i === activePosition - 1
|
||||
|
||||
if (this.isAtMinHeight(below) || aboveCurrent) {
|
||||
return {...d, size: this.shorter(d.size)}
|
||||
}
|
||||
}
|
||||
|
||||
if (current) {
|
||||
const stayStill = divs.every((div, idx) => {
|
||||
if (idx >= i) {
|
||||
return true
|
||||
}
|
||||
|
||||
return this.isAtMinHeight(div)
|
||||
})
|
||||
|
||||
if (stayStill) {
|
||||
return {...d}
|
||||
}
|
||||
|
||||
return {...d, size: this.taller(d.size)}
|
||||
}
|
||||
|
||||
if (after) {
|
||||
return {...d}
|
||||
}
|
||||
|
||||
return {...d}
|
||||
})
|
||||
|
||||
this.setState({divisions: this.cleanDivisions(divisions)})
|
||||
}
|
||||
|
||||
private down = activePosition => () => {
|
||||
const divisions = this.state.divisions.map((d, i, divs) => {
|
||||
const before = i === activePosition - 1
|
||||
const current = i === activePosition
|
||||
const after = i > activePosition
|
||||
|
||||
if (before) {
|
||||
return {...d, size: this.taller(d.size)}
|
||||
}
|
||||
|
||||
if (current) {
|
||||
return {...d, size: this.shorter(d.size)}
|
||||
}
|
||||
|
||||
if (after) {
|
||||
const above = divs[i - 1]
|
||||
|
||||
if (this.isAtMinHeight(above)) {
|
||||
return {...d, size: this.shorter(d.size)}
|
||||
}
|
||||
}
|
||||
|
||||
return {...d}
|
||||
})
|
||||
|
||||
this.setState({divisions: this.cleanDivisions(divisions)})
|
||||
}
|
||||
|
||||
private left = activePosition => () => {
|
||||
const divisions = this.state.divisions.map((d, i) => {
|
||||
const before = i === activePosition - 1
|
||||
const active = i === activePosition
|
||||
|
||||
if (before) {
|
||||
return {...d, size: d.size - this.percentChangeX}
|
||||
} else if (active) {
|
||||
return {...d, size: d.size + this.percentChangeX}
|
||||
}
|
||||
|
||||
return d
|
||||
})
|
||||
|
||||
this.setState({divisions})
|
||||
}
|
||||
|
||||
private right = activePosition => () => {
|
||||
const divisions = this.state.divisions.map((d, i) => {
|
||||
const before = i === activePosition - 1
|
||||
const active = i === activePosition
|
||||
|
||||
if (before) {
|
||||
return {...d, size: d.size + this.percentChangeX}
|
||||
} else if (active) {
|
||||
return {...d, size: d.size - this.percentChangeX}
|
||||
}
|
||||
|
||||
return d
|
||||
})
|
||||
|
||||
this.setState({divisions})
|
||||
}
|
||||
|
||||
private enforceSize = (size, minPixels): number => {
|
||||
const minPercent = this.minPercent(minPixels)
|
||||
|
||||
let enforcedSize = size
|
||||
if (size < minPercent) {
|
||||
enforcedSize = minPercent
|
||||
}
|
||||
|
||||
return enforcedSize
|
||||
}
|
||||
|
||||
private cleanDivisions = divisions => {
|
||||
return divisions.map(d => {
|
||||
const size = this.enforceSize(d.size, d.minPixels)
|
||||
return {...d, size}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export default Resizer
|
||||
|
|
|
@ -72,7 +72,8 @@ class Division extends PureComponent<Props> {
|
|||
const {orientation, maxPercent, minPixels, size} = this.props
|
||||
|
||||
const sizePercent = `${size * HUNDRED}%`
|
||||
const max = `${maxPercent * HUNDRED}%`
|
||||
// const max = `${maxPercent * HUNDRED}%`
|
||||
const max = '100%'
|
||||
|
||||
if (orientation === HANDLE_VERTICAL) {
|
||||
return {
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
import React, {PureComponent, ReactElement} from 'react'
|
||||
import classnames from 'classnames'
|
||||
|
||||
import {
|
||||
HANDLE_VERTICAL,
|
||||
HANDLE_HORIZONTAL,
|
||||
HUNDRED,
|
||||
} from 'src/shared/constants/'
|
||||
|
||||
interface Props {
|
||||
percent: number
|
||||
minPixels: number
|
||||
render: () => ReactElement<any>
|
||||
orientation: string
|
||||
}
|
||||
|
||||
class ResizerHalf extends PureComponent<Props> {
|
||||
public render() {
|
||||
const {render} = this.props
|
||||
|
||||
return (
|
||||
<div className={this.className} style={this.style}>
|
||||
{render()}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
private get style() {
|
||||
const {orientation, minPixels, percent} = this.props
|
||||
|
||||
const size = `${percent * HUNDRED}%`
|
||||
|
||||
if (orientation === HANDLE_VERTICAL) {
|
||||
return {
|
||||
top: '0',
|
||||
width: size,
|
||||
minWidth: minPixels,
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
left: '0',
|
||||
height: size,
|
||||
minHeight: minPixels,
|
||||
}
|
||||
}
|
||||
|
||||
private get className(): string {
|
||||
const {orientation} = this.props
|
||||
|
||||
return classnames('resizer--half', {
|
||||
vertical: orientation === HANDLE_VERTICAL,
|
||||
horizontal: orientation === HANDLE_HORIZONTAL,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export default ResizerHalf
|
|
@ -0,0 +1,456 @@
|
|||
import React, {Component, ReactElement, MouseEvent} from 'react'
|
||||
import classnames from 'classnames'
|
||||
import uuid from 'uuid'
|
||||
import _ from 'lodash'
|
||||
|
||||
import ResizeDivision from 'src/shared/components/ResizeDivision'
|
||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||
import {
|
||||
MIN_DIVISIONS,
|
||||
HANDLE_HORIZONTAL,
|
||||
HANDLE_VERTICAL,
|
||||
} from 'src/shared/constants/'
|
||||
|
||||
const initialDragEvent = {
|
||||
percentX: 0,
|
||||
percentY: 0,
|
||||
mouseX: null,
|
||||
mouseY: null,
|
||||
}
|
||||
|
||||
interface State {
|
||||
activeHandleID: string
|
||||
divisions: DivisionState[]
|
||||
dragDirection: string
|
||||
dragEvent: any
|
||||
}
|
||||
|
||||
interface Division {
|
||||
name?: string
|
||||
render: () => ReactElement<any>
|
||||
minPixels?: number
|
||||
}
|
||||
|
||||
interface DivisionState extends Division {
|
||||
id: string
|
||||
size: number
|
||||
minPixels?: number
|
||||
}
|
||||
|
||||
interface Props {
|
||||
divisions: Division[]
|
||||
orientation: string
|
||||
containerClass: string
|
||||
}
|
||||
|
||||
@ErrorHandling
|
||||
class Resizer extends Component<Props, State> {
|
||||
public static defaultProps: Partial<Props> = {
|
||||
orientation: HANDLE_HORIZONTAL,
|
||||
}
|
||||
|
||||
private containerRef: HTMLElement
|
||||
private percentChangeX: number = 0
|
||||
private percentChangeY: number = 0
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
activeHandleID: null,
|
||||
divisions: this.initialDivisions,
|
||||
dragEvent: initialDragEvent,
|
||||
dragDirection: '',
|
||||
}
|
||||
}
|
||||
|
||||
public componentDidUpdate(__, prevState) {
|
||||
const {dragEvent} = this.state
|
||||
const {orientation} = this.props
|
||||
|
||||
if (_.isEqual(dragEvent, prevState.dragEvent)) {
|
||||
return
|
||||
}
|
||||
|
||||
this.percentChangeX = this.pixelsToPercentX(
|
||||
prevState.dragEvent.mouseX,
|
||||
dragEvent.mouseX
|
||||
)
|
||||
|
||||
this.percentChangeY = this.pixelsToPercentY(
|
||||
prevState.dragEvent.mouseY,
|
||||
dragEvent.mouseY
|
||||
)
|
||||
|
||||
if (orientation === HANDLE_VERTICAL) {
|
||||
const left = dragEvent.percentX < prevState.dragEvent.percentX
|
||||
|
||||
if (left) {
|
||||
return this.move.left()
|
||||
}
|
||||
|
||||
return this.move.right()
|
||||
}
|
||||
|
||||
const up = dragEvent.percentY < prevState.dragEvent.percentY
|
||||
const down = dragEvent.percentY > prevState.dragEvent.percentY
|
||||
|
||||
if (up) {
|
||||
return this.move.up()
|
||||
} else if (down) {
|
||||
return this.move.down()
|
||||
}
|
||||
}
|
||||
|
||||
public render() {
|
||||
const {activeHandleID, divisions} = this.state
|
||||
const {orientation} = this.props
|
||||
|
||||
if (divisions.length < MIN_DIVISIONS) {
|
||||
console.error(
|
||||
`There must be at least ${MIN_DIVISIONS}' divisions in Resizer`
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={this.className}
|
||||
onMouseLeave={this.handleMouseLeave}
|
||||
onMouseUp={this.handleStopDrag}
|
||||
onMouseMove={this.handleDrag}
|
||||
ref={r => (this.containerRef = r)}
|
||||
>
|
||||
{divisions.map((d, i) => (
|
||||
<ResizeDivision
|
||||
key={d.id}
|
||||
id={d.id}
|
||||
name={d.name}
|
||||
size={d.size}
|
||||
draggable={i > 0}
|
||||
minPixels={d.minPixels}
|
||||
orientation={orientation}
|
||||
activeHandleID={activeHandleID}
|
||||
onHandleStartDrag={this.handleStartDrag}
|
||||
maxPercent={this.maximumHeightPercent}
|
||||
render={this.props.divisions[i].render}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
private minPercent = (minPixels: number): number => {
|
||||
if (this.props.orientation === HANDLE_VERTICAL) {
|
||||
return this.minPercentX(minPixels)
|
||||
}
|
||||
|
||||
return this.minPercentY(minPixels)
|
||||
}
|
||||
|
||||
private get className(): string {
|
||||
const {orientation, containerClass} = this.props
|
||||
const {activeHandleID} = this.state
|
||||
|
||||
return classnames(`resize--container ${containerClass}`, {
|
||||
'resize--dragging': activeHandleID,
|
||||
horizontal: orientation === HANDLE_HORIZONTAL,
|
||||
vertical: orientation === HANDLE_VERTICAL,
|
||||
})
|
||||
}
|
||||
|
||||
private get initialDivisions() {
|
||||
const {divisions} = this.props
|
||||
|
||||
const size = 1 / divisions.length
|
||||
|
||||
return divisions.map(d => ({
|
||||
...d,
|
||||
id: uuid.v4(),
|
||||
size,
|
||||
minPixels: d.minPixels || 0,
|
||||
}))
|
||||
}
|
||||
|
||||
private handleStartDrag = (activeHandleID, e: MouseEvent<HTMLElement>) => {
|
||||
const dragEvent = this.mousePosWithinContainer(e)
|
||||
this.setState({activeHandleID, dragEvent})
|
||||
}
|
||||
|
||||
private handleStopDrag = () => {
|
||||
this.setState({activeHandleID: '', dragEvent: initialDragEvent})
|
||||
}
|
||||
|
||||
private handleMouseLeave = () => {
|
||||
this.setState({activeHandleID: '', dragEvent: initialDragEvent})
|
||||
}
|
||||
|
||||
private mousePosWithinContainer = (e: MouseEvent<HTMLElement>) => {
|
||||
const {pageY, pageX} = e
|
||||
const {top, left, width, height} = this.containerRef.getBoundingClientRect()
|
||||
|
||||
const mouseX = pageX - left
|
||||
const mouseY = pageY - top
|
||||
|
||||
const percentX = mouseX / width
|
||||
const percentY = mouseY / height
|
||||
|
||||
return {
|
||||
mouseX,
|
||||
mouseY,
|
||||
percentX,
|
||||
percentY,
|
||||
}
|
||||
}
|
||||
|
||||
private pixelsToPercentX = (startValue, endValue) => {
|
||||
if (!startValue) {
|
||||
return 0
|
||||
}
|
||||
|
||||
const delta = startValue - endValue
|
||||
const {width} = this.containerRef.getBoundingClientRect()
|
||||
|
||||
return Math.abs(delta / width)
|
||||
}
|
||||
|
||||
private pixelsToPercentY = (startValue, endValue) => {
|
||||
if (!startValue) {
|
||||
return 0
|
||||
}
|
||||
|
||||
const delta = startValue - endValue
|
||||
const {height} = this.containerRef.getBoundingClientRect()
|
||||
|
||||
return Math.abs(delta / height)
|
||||
}
|
||||
|
||||
private minPercentX = (xMinPixels: number): number => {
|
||||
if (!this.containerRef) {
|
||||
return 0
|
||||
}
|
||||
const {width} = this.containerRef.getBoundingClientRect()
|
||||
|
||||
return xMinPixels / width
|
||||
}
|
||||
|
||||
private minPercentY = (yMinPixels: number): number => {
|
||||
if (!this.containerRef) {
|
||||
return 0
|
||||
}
|
||||
|
||||
const {height} = this.containerRef.getBoundingClientRect()
|
||||
return yMinPixels / height
|
||||
}
|
||||
|
||||
private get maximumHeightPercent(): number {
|
||||
if (!this.containerRef) {
|
||||
return 1
|
||||
}
|
||||
|
||||
const {divisions} = this.state
|
||||
const {height} = this.containerRef.getBoundingClientRect()
|
||||
|
||||
const totalMinPixels = divisions.reduce(
|
||||
(acc, div) => acc + div.minPixels,
|
||||
0
|
||||
)
|
||||
|
||||
const maximumPixels = height - totalMinPixels
|
||||
|
||||
return this.minPercentY(maximumPixels)
|
||||
}
|
||||
|
||||
private handleDrag = (e: MouseEvent<HTMLElement>) => {
|
||||
const {activeHandleID} = this.state
|
||||
if (!activeHandleID) {
|
||||
return
|
||||
}
|
||||
|
||||
const dragEvent = this.mousePosWithinContainer(e)
|
||||
this.setState({dragEvent})
|
||||
}
|
||||
|
||||
private taller = (size: number): number => {
|
||||
const newSize = size + this.percentChangeY
|
||||
return Number(newSize.toFixed(3))
|
||||
}
|
||||
|
||||
private shorter = (size: number): number => {
|
||||
const newSize = size - this.percentChangeY
|
||||
return Number(newSize.toFixed(3))
|
||||
}
|
||||
|
||||
private isAtMinHeight = (division: DivisionState): boolean => {
|
||||
return division.size <= this.minPercentY(division.minPixels)
|
||||
}
|
||||
|
||||
private get move() {
|
||||
const {activeHandleID} = this.state
|
||||
|
||||
const activePosition = _.findIndex(
|
||||
this.state.divisions,
|
||||
d => d.id === activeHandleID
|
||||
)
|
||||
|
||||
return {
|
||||
up: this.up(activePosition),
|
||||
down: this.down(activePosition),
|
||||
left: this.left(activePosition),
|
||||
right: this.right(activePosition),
|
||||
}
|
||||
}
|
||||
|
||||
private up = activePosition => () => {
|
||||
const divisions = this.state.divisions.map((d, i, divs) => {
|
||||
const before = i < activePosition
|
||||
const current = i === activePosition
|
||||
|
||||
if (before) {
|
||||
const below = divs[i + 1]
|
||||
const aboveCurrent = i === activePosition - 1
|
||||
|
||||
const belowIsCurrent = below.id === divs[activePosition].id
|
||||
|
||||
if (belowIsCurrent) {
|
||||
return {...d}
|
||||
}
|
||||
|
||||
if (this.isAtMinHeight(below) || aboveCurrent) {
|
||||
const size = this.shorter(d.size)
|
||||
if (size < 0) {
|
||||
debugger
|
||||
}
|
||||
|
||||
return {...d, size}
|
||||
}
|
||||
}
|
||||
|
||||
if (current) {
|
||||
const stayStill = divs.every((div, idx) => {
|
||||
if (idx >= i) {
|
||||
return true
|
||||
}
|
||||
|
||||
return this.isAtMinHeight(div)
|
||||
})
|
||||
|
||||
if (stayStill) {
|
||||
return {...d}
|
||||
}
|
||||
|
||||
return {...d, size: this.taller(d.size)}
|
||||
}
|
||||
|
||||
return {...d}
|
||||
})
|
||||
|
||||
this.setState({divisions})
|
||||
}
|
||||
|
||||
private down = activePosition => () => {
|
||||
const divisions = this.state.divisions.map((d, i, divs) => {
|
||||
const before = i === activePosition - 1
|
||||
const current = i === activePosition
|
||||
const after = i > activePosition
|
||||
|
||||
if (before) {
|
||||
return {...d, size: this.taller(d.size)}
|
||||
}
|
||||
|
||||
if (current) {
|
||||
return {...d, size: this.shorter(d.size)}
|
||||
}
|
||||
|
||||
if (after) {
|
||||
const above = divs[i - 1]
|
||||
|
||||
if (this.isAtMinHeight(d)) {
|
||||
return {...d}
|
||||
}
|
||||
|
||||
if (this.isAtMinHeight(above)) {
|
||||
return {...d, size: this.shorter(d.size)}
|
||||
}
|
||||
}
|
||||
|
||||
return {...d}
|
||||
})
|
||||
|
||||
this.setState({divisions})
|
||||
}
|
||||
|
||||
private left = activePosition => () => {
|
||||
const divisions = this.state.divisions.map((d, i) => {
|
||||
const before = i === activePosition - 1
|
||||
const active = i === activePosition
|
||||
|
||||
if (before) {
|
||||
return {...d, size: d.size - this.percentChangeX}
|
||||
} else if (active) {
|
||||
return {...d, size: d.size + this.percentChangeX}
|
||||
}
|
||||
|
||||
return d
|
||||
})
|
||||
|
||||
this.setState({divisions})
|
||||
}
|
||||
|
||||
private right = activePosition => () => {
|
||||
const divisions = this.state.divisions.map((d, i) => {
|
||||
const before = i === activePosition - 1
|
||||
const active = i === activePosition
|
||||
|
||||
if (before) {
|
||||
return {...d, size: d.size + this.percentChangeX}
|
||||
} else if (active) {
|
||||
return {...d, size: d.size - this.percentChangeX}
|
||||
}
|
||||
|
||||
return d
|
||||
})
|
||||
|
||||
this.setState({divisions})
|
||||
}
|
||||
|
||||
private enforceSize = (size, minPixels): number => {
|
||||
const minPercent = this.minPercent(minPixels)
|
||||
|
||||
let enforcedSize = size
|
||||
if (size < minPercent) {
|
||||
enforcedSize = minPercent
|
||||
}
|
||||
|
||||
return enforcedSize
|
||||
}
|
||||
|
||||
private cleanDivisions = divisions => {
|
||||
const minSizes = divisions.map(d => {
|
||||
const size = this.enforceSize(d.size, d.minPixels)
|
||||
return {...d, size}
|
||||
})
|
||||
|
||||
const sumSizes = minSizes.reduce((acc, div, i) => {
|
||||
if (i <= divisions.length - 1) {
|
||||
return acc + div.size
|
||||
}
|
||||
|
||||
return acc
|
||||
}, 0)
|
||||
|
||||
const under100percent = 1 - sumSizes > 0
|
||||
const over100percent = 1 - sumSizes < 0
|
||||
|
||||
if (under100percent) {
|
||||
minSizes[divisions.length - 1].size += Math.abs(1 - sumSizes)
|
||||
}
|
||||
|
||||
if (over100percent) {
|
||||
minSizes[divisions.length - 1].size -= Math.abs(1 - sumSizes)
|
||||
}
|
||||
|
||||
return minSizes
|
||||
}
|
||||
}
|
||||
|
||||
export default Resizer
|
|
@ -52,9 +52,18 @@ $resizer-color-kapacitor: $c-rainforest;
|
|||
height: 100%;
|
||||
}
|
||||
|
||||
.resizer--division {
|
||||
.resizer--division:nth-child(1) {
|
||||
border-color: #0f0;
|
||||
}
|
||||
.resizer--division:nth-child(2) {
|
||||
border-color: #0ff;
|
||||
}
|
||||
.resizer--division:nth-child(3) {
|
||||
border-color: #00f;
|
||||
}
|
||||
.resizer--division:nth-child(4) {
|
||||
border-color: #f0f;
|
||||
}
|
||||
}
|
||||
|
||||
.resizer--full-size {
|
||||
|
|
Loading…
Reference in New Issue