I would like to make a draggable split panel for an editor. Its behavior is mainly like Console
panel of CodeSandbox:
Console
, the panel is expanded, and the arrow becomes ArrowDown
for closing.Console
on an expanded panel, the panel is closed, and the arrow becomes ArrowUp
for expanding.I have the following code (https://codesandbox.io/s/reset-forked-ivebxf?file=/src/App.js) by https://github.com/johnwalley/allotment. It can expand and close the panel, but there is a conflict with resizing. When the panel is closed, we drag the border up, I would like the arrow to become ArrowDown
. Similarly, when the panel is open, we drag the border down to the bottom, I would like the arrow to be ArrowUp
.
Does anyone know how to do so? I'm open to other react libraries too.
import React from "react";
import { Allotment } from "allotment";
import "allotment/dist/style.css";
import styles from "./App.module.css";
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
toExpand: true
};
}
render() {
return (
<div>
<div className={styles.container}>
<Allotment vertical>
<Allotment.Pane>abc</Allotment.Pane>
{!this.state.toExpand && (
<Allotment.Pane preferredSize="50%">
<div
onClick={() => {
this.setState({ toExpand: !this.state.toExpand });
}}
>
Console
{this.state.toExpand ? "ArrowUp" : "ArrowDown"}
</div>
</Allotment.Pane>
)}
{this.state.toExpand && (
<Allotment.Pane preferredSize="0%">
<div
onClick={() => {
this.setState({ toExpand: !this.state.toExpand });
}}
>
Console
{this.state.toExpand ? "ArrowUp" : "ArrowDown"}
</div>
</Allotment.Pane>
)}
</Allotment>
</div>
</div>
);
}
}
You can use onChange callback function of Allotment component. My solution is as follows:
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
toExpand: true
};
this.myRef = React.createRef();
}
handleChange = (sizes) => {
if (sizes.length > 1) {
if (sizes[1] < 31) {
this.setState({ toExpand: true });
} else {
this.setState({ toExpand: false });
}
}
};
render() {
return (
<div>
<div className={styles.container}>
<Allotment vertical onChange={this.handleChange} ref={this.myRef}>
<Allotment.Pane>Main Area</Allotment.Pane>
<Allotment.Pane preferredSize="0%">
<div
onClick={() => {
if (this.state.toExpand) {
this.myRef.current.resize([50, 50]);
} else {
this.myRef.current.resize([10000, 0]);
}
}}
>
Console
{this.state.toExpand ? "ArrowUp" : "ArrowDown"}
</div>
</Allotment.Pane>
</Allotment>
</div>
</div>
);
}
}