Create a split panel that is draggable, inspired by the user interface of CodeSandbox's console

Interested in creating a draggable split panel for an editor that behaves similar to the Console panel in CodeSandbox?

  1. Clicking on Console expands the panel and toggles the arrow to show ArrowDown for closing.
  2. The border of the panel should be draggable.
  3. If you click on Console while the panel is expanded, it will close and the arrow will change to ArrowUp for expanding again.

I currently have some code (https://codesandbox.io/s/reset-forked-ivebxf?file=/src/App.js) from https://github.com/johnwalley/allotment. It can expand and close the panel, but there are issues with resizing. I want the arrow to reflect the direction of the panel when resizing - up for expansion and down for closing.

If you have any suggestions or know how to achieve this, please share. I'm also open to using other react libraries for this feature.

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 &nbsp;
                  {this.state.toExpand ? "ArrowUp" : "ArrowDown"}
                </div>
              </Allotment.Pane>
            )}
            {this.state.toExpand && (
              <Allotment.Pane preferredSize="0%">
                <div
                  onClick={() => {
                    this.setState({ toExpand: !this.state.toExpand });
                  }}
                >
                  Console &nbsp;
                  {this.state.toExpand ? "ArrowUp" : "ArrowDown"}
                </div>
              </Allotment.Pane>
            )}
          </Allotment>
        </div>
      </div>
    );
  }
}

Answer №1

Utilize the onChange callback function within the Allotment component to implement a solution. Here is my approach:

class CustomApp extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      expandArea: true
    };
    this.customRef = React.createRef();
  }

  handleUpdate = (dimensions) => {
    if (dimensions.length > 1) {
      if (dimensions[1] < 31) {
        this.setState({ expandArea: true });
      } else {
        this.setState({ expandArea: false });
      }
    }
  };

  render() {
    return (
      <div>
        <div className={styles.wrapper}>
          <Allotment vertical onChange={this.handleUpdate} ref={this.customRef}>
            <Allotment.Pane>Main Content</Allotment.Pane>
            <Allotment.Pane preferredSize="0%">
              <div
                onClick={() => {
                  if (this.state.expandArea) {
                    this.customRef.current.resize([50, 50]);
                  } else {
                    this.customRef.current.resize([10000, 0]);
                  }
                }}
              >
                Console  
                {this.state.expandArea ? "Expand" : "Collapse"}
              </div>
            </Allotment.Pane>
          </Allotment>
        </div>
      </div>
    );
  }
}

Answer №2

<Allotment modify={}/> element includes a modify event to track changes. It is necessary to establish a specific threshold (such as 400 in this example or based on window height) to alter the Arrow Mark value.

<Allotment vertical modify={this.adjustSize}>

adjustSize = (e) => {
    if (e[0] > 400) { // set your preferred threshold
      console.log(e[0]);
      this.setState({ toExpand: !this.state.toExpand });
    }
  };

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Issue with Firebase Offline on IOS: isPersistenceEnabled function is not functioning as expected

In my AppDelegate, I have the following code snippet: func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { FirebaseApp.configure() Database.database().isPersistence ...

implement a listener for scrolling using the specified identifier

Hey, I'm having trouble adding a scroll listener by ID. It works with WINDOW, but it doesn't seem to work in a custom scroll element. Here's the code snippet: componentDidMount() { const scrollPanel = document.getElementById('scrol ...

Ways to Turn Off CSS Vertical Menu Flyout Animation

I'm new to HTML Lists and trying to figure out how to disable the "Hover flyout effect" so that all sub items are listed vertically below the main item while remaining visible. Can someone please help me understand which specific CSS properties can be ...

Managing broken images within an internet browser

Is there a way to hide the broken image icon, similar to what's shown at '', when no image is displayed? I've set up a comment section using PHP and CSS that allows users to leave comments and upload photos. However, if a user decides t ...

Creating Elements with Full Screen Width Instead of Parent Width Using CSS

Is it possible to make an element's width the full width of the screen instead of the parent's width? If so, how can this be achieved? <header> <nav class="navbar navbar-inverse navbar-fixed-top" data-tap-toggle="false ...

Using innerHTML in React to remove child nodes Tutorial

I'm encountering slow performance when unmounting over 30,000 components on a page using conditional rendering triggered by a button click. This process takes around 10+ seconds and causes the page to hang. Interestingly, setting the parent container& ...

Struggling to update state using useState in ReactJS - value remains unchanged

I am facing an issue with updating an id from two tables using a table component that is being used twice on the same page. When I click on a row, the id should be updated to the parent component. I have attempted to set it to a constant using the useState ...

Effective methods to prevent the `translate` transform from triggering an element to be perceived as position relative?

I am encountering an issue with an absolutely positioned div that is nested within a statically-positioned parent container. I noticed that when I apply the transform: translateY(-50%) property to the container, the child element behaves as if it were bein ...

Error: Property 'onclick' cannot be set on a null object

JavaScript isn't my strong suit, so I'm struggling to solve this issue. The console is showing me the following error message: Uncaught TypeError: Cannot set property 'onclick' of null <script> var modal = document.getE ...

Error: The property 'inputItem' is not recognized on type 'EventTarget' - Utilizing Semantic-Ui, React, and Typescript

Currently, I'm utilizing React, Typescript, and Semantic UI react components. My aim is to clear the input field after successfully adding an item. While debugging, I've noticed the event.currentTarget.inputName.value which I wish to set to an em ...

ReactJS issue: Unexpected warning about having a unique "key" prop for each child in a list

What a glorious day! Unfortunately, my view is obstructed by this pesky obstacle: https://i.sstatic.net/ODemS.png I've exhausted all my options (except asking for help ._.) and scoured every corner. Alas, the desired outcome remains elusive :'( ...

Leveraging the Power of jsPDF in Your Google Apps Scripts

Is it feasible to integrate jsPDF into a Google Apps Script project? I am attempting to create documents using templated HTML, but certain CSS styles like background-color do not translate to PDF when using the getAs() function. Given the limitations of ...

Why isn't my React image updating its source right away? What are some solutions to this issue?

I currently have a basic <img> tag with a specified src attribute. <img src={src} /> When I update the src attribute from, let's say /1.jpg to /2.jpg, there is a delay in loading the new image. React still displays the old image (/1.jpg) ...

Is there a way to keep my <nav> positioned in the top right corner of my header?

I'm in the process of setting up a fresh homepage and I've implemented the code below: menu { width: 100%; height: 60px; background: rgb(0, 0, 0); z-index: 2; position: fixed; } #content { margin: 0 auto; width: 1024px; height: ...

How can I prevent the expansion of elements in a drop-down menu when using display:

I've been struggling to implement a drop-down feature in my menu. The issue is that when I use display: flex, hovering over the drop-down also expands all other boxes without drop-downs. Any ideas on how to fix this easily? Additionally, is there a w ...

Issue with page layout arises due to a problem with AngularJS directive

I recently downloaded the Ace Admin template from As I tried to integrate it into my AngularJS project, I encountered a problem when using specific parts of the template in custom directives. To isolate and simplify the issue, I created a plunker at https ...

Introducing React JSX via a nifty bookmarklet

Looking to convert code found in an HTML file into a bookmarklet? Here's the code snippets involved: <script src="JSXTransformer-0.13.3.js"></script> <script src="react-0.13.3.js"></script> <script type="text/jsx;harmony=tr ...

Utilizing React JS to dynamically populate a table with data from an external JSON file

As a newcomer to the realm of React, I am facing challenges in displaying my JSON data in a table. class GetUnassignedUsers extends React.Component { constructor () { super(); this.state = { data:[] }; } com ...

Creating an inclusive h1 header with a logo: A step-by-step guide

Is there a way to have a logo linked to the homepage and also have an h1 element that is invisible? This is my current layout: <header id="pageHeader"> <h1> <a href="<?php bloginfo('url'); ?>"> & ...

The JavaScript script to retrieve the background color is malfunctioning

I am currently working on developing a highlighting feature for an HTML table that will dynamically change the row colors on mouseover. Below is the code snippet I have been using, but it seems to be experiencing some issues. Any assistance would be greatl ...