I would like to make a draggable split panel for an editor. Its behavior is mainly like Console
panel of CodeSandbox:
- When we click on
Console
, the panel is expanded, and the arrow becomesArrowDown
for closing. - The border of the panel is dragabble.
- When we click on
Console
on an expanded panel, the panel is closed, and the arrow becomesArrowUp
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>
);
}
}
CodePudding user response:
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>
);
}
}
CodePudding user response:
<Allotment onChange={}/>
component has an onChange event to identity each changes. You have to make one trigger point (400 in my case or you can calculate as per window height) and change value of Arrow Mark
<Allotment vertical onChange={this.changeSize}>
changeSize = (e) => {
if (e[0] > 400) { // use your desired trigger
console.log(e[0]);
this.setState({ toExpand: !this.state.toExpand });
}
};