import './css/BorderLayout.css'; import classNames from 'classnames/bind'; import PropTypes from 'prop-types'; /** * 边框布局 * @author tengge / https://github.com/tengge1 */ class BorderLayout extends React.Component { constructor(props) { super(props); const children = this.props.children; const north = children && children.filter(n => n.props.region === 'north')[0]; const south = children && children.filter(n => n.props.region === 'south')[0]; const west = children && children.filter(n => n.props.region === 'west')[0]; const east = children && children.filter(n => n.props.region === 'east')[0]; const center = children && children.filter(n => n.props.region === 'center')[0]; const northSplit = north && north.props.split || false; const southSplit = south && south.props.split || false; const westSplit = west && west.props.split || false; const eastSplit = east && east.props.split || false; const northCollapsed = north && north.props.collapsed || false; const southCollapsed = south && south.props.collapsed || false; const westCollapsed = west && west.props.collapsed || false; const eastCollapsed = east && east.props.collapsed || false; const onNorthToggle = north && north.props.onToggle || null; const onSouthToggle = south && south.props.onToggle || null; const onWestToggle = west && west.props.onToggle || null; const onEastToggle = east && east.props.onToggle || null; this.northRef = React.createRef(); this.southRef = React.createRef(); this.westRef = React.createRef(); this.eastRef = React.createRef(); this.state = { northSplit, southSplit, westSplit, eastSplit, northCollapsed, southCollapsed, westCollapsed, eastCollapsed, }; this.handleNorthClick = this.handleNorthClick.bind(this, onNorthToggle); this.handleSouthClick = this.handleSouthClick.bind(this, onSouthToggle); this.handleWestClick = this.handleWestClick.bind(this, onWestToggle); this.handleEastClick = this.handleEastClick.bind(this, onEastToggle); this.handleTransitionEnd = this.handleTransitionEnd.bind(this, onNorthToggle, onSouthToggle, onWestToggle, onEastToggle); } handleNorthClick() { if (!this.state.northSplit) { return; } this.setState((state, props) => { const collapsed = !state.northCollapsed; const dom = this.northRef.current; const height = dom.clientHeight; if (collapsed) { dom.style.marginTop = `-${height - 8}px`; } else { dom.style.marginTop = null; } return { northCollapsed: collapsed, }; }); } handleSouthClick() { if (!this.state.southSplit) { return; } this.setState((state, props) => { const collapsed = !state.southCollapsed; const dom = this.southRef.current; const height = dom.clientHeight; if (collapsed) { dom.style.marginBottom = `-${height - 8}px`; } else { dom.style.marginBottom = null; } return { southCollapsed: collapsed, }; }); } handleWestClick() { if (!this.state.westSplit) { return; } const dom = this.westRef.current; this.setState((state, props) => { const collapsed = !state.westCollapsed; const width = dom.clientWidth; if (collapsed) { dom.style.marginLeft = `-${width - 8}px`; } else { dom.style.marginLeft = null; } return { westCollapsed: collapsed, }; }); } handleEastClick() { if (!this.state.eastSplit) { return; } this.setState((state, props) => { const collapsed = !state.eastCollapsed; const dom = this.eastRef.current; const width = dom.clientWidth; if (collapsed) { dom.style.marginRight = `-${width - 8}px`; } else { dom.style.marginRight = null; } return { eastCollapsed: collapsed, }; }); } handleTransitionEnd(onNorthToggle, onSouthToggle, onWestToggle, onEastToggle, event) { const region = event.target.getAttribute('region'); switch (region) { case 'north': onNorthToggle && onNorthToggle(!this.state.northCollapsed); break; case 'south': onSouthToggle && onSouthToggle(!this.state.southCollapsed); break; case 'west': onWestToggle && onWestToggle(!this.state.westCollapsed); break; case 'east': onEastToggle && onEastToggle(!this.state.eastCollapsed); break; } } render() { const { className, style, children } = this.props; let north = [], south = [], west = [], east = [], center = [], others = []; children && children.forEach(n => { switch (n.props.region) { case 'north': north.push(n); break; case 'south': south.push(n); break; case 'west': west.push(n); break; case 'east': east.push(n); break; case 'center': center.push(n); break; default: others.push(n); break; } }); if (center.length === 0) { console.warn(`BorderLayout: center region is not defined.`); } // north region const northRegion = north.length > 0 && (
{north}
{this.state.northSplit &&
}
); // south region const southRegion = south.length > 0 && (
{this.state.southSplit &&
}
{south}
); // west region const westRegion = west.length > 0 && (
{west}
{this.state.westSplit &&
}
); // east region const eastRegion = east.length > 0 && (
{east}
); // center region const centerRegion = center.length > 0 && (
{center}
); const otherRegion = others.length > 0 && others; return
{northRegion}
{westRegion} {centerRegion} {eastRegion}
{southRegion} {otherRegion}
; } } BorderLayout.propTypes = { className: PropTypes.string, style: PropTypes.object, children: PropTypes.node, }; BorderLayout.defaultProps = { className: null, style: null, children: null, }; export default BorderLayout;