johnwalley / allotment

A React component for resizable split views
https://allotment.mulberryhousesoftware.com/
MIT License
988 stars 55 forks source link

How do customize Sash component? #280

Open unematiii opened 2 years ago

unematiii commented 2 years ago

Ideally I would like to customize resize handle (Sash) component as follows:

What is the best way to achieve all the above?

MrHeer commented 2 years ago

I have the same question. Is there any way now? @johnwalley

unematiii commented 2 years ago

@MrHeer I was able to do all of that with Re-Flex.

MrHeer commented 2 years ago

That's great, thank you.

jo0ger commented 2 years ago

I have the same question. Is there any way now? @johnwalley

johnwalley commented 2 years ago

Thanks everyone for the interest in this feature. It's the next major feature I'd like to implement and ship.

It's a significant change so it will need some design and will take some time. If you're interested in the details it's mostly because VS Code doesn't support this so we need a way of adding the separator/gutter while still maintaining compatibility with how VS Code does things. Basically, VS Code's split view does't have the concept of a separator/gutter at all and it's up to the pane content to display something sensible.

If this is a blocker for anyone adopting the library I would suggest going with another library right now as I can't give a guarantee on the timeline for this feature. But thanks again for taking the time and showing interest with your feedback 🙏 .

MrHeer commented 2 years ago
nightire commented 2 years ago
  • I used a mediocre approach in my project. sash receives a splitter, which synchronously modifies the relevant properties with the sash during layout. These splitters are placed in a container, just like the container of sash.

Do you have a working demo? It's hard to grasp your idea just by the above descriptions.

MrHeer commented 2 years ago

I just synchronously modifies the relevant properties of the handler with the sash during layout.

  /**
   * Layout the sash. The sash will size and position itself
   * based on its provided {@link SashLayoutProvider layout provider}.
   */
  public layout(): void {
    const setProperty = (property: string, value: number) => {
      this.el.style.setProperty(property, `${value}px`);
      if (this.handle) {
        this.handle.style.setProperty(property, `${value}px`);
      }
    };

    const setPropertyWithSize = (property: string, value: number) => {
      this.el.style.setProperty(property, `${value - this.size / 2}px`);
      if (this.handle) {
        this.handle.style.setProperty(
          property,
          `${value - this.handleSize / 2}px`
        );
      }
    };

    if (this.orientation === Orientation.Vertical) {
      const verticalProvider = this
        .layoutProvider as VerticalSashLayoutProvider;

      const left = verticalProvider.getVerticalSashLeft(this);
      setPropertyWithSize("left", left);

      if (verticalProvider.getVerticalSashTop) {
        const top = verticalProvider.getVerticalSashTop(this);
        setProperty("top", top);
      }

      if (verticalProvider.getVerticalSashHeight) {
        const height = verticalProvider.getVerticalSashHeight(this);
        setProperty("height", height);
      }
    } else {
      const horizontalProvider = this
        .layoutProvider as HorizontalSashLayoutProvider;

      const top = horizontalProvider.getHorizontalSashTop(this);
      setPropertyWithSize("top", top);

      if (horizontalProvider.getHorizontalSashLeft) {
        const left = horizontalProvider.getHorizontalSashLeft(this);
        setProperty("left", left);
      }

      if (horizontalProvider.getHorizontalSashWidth) {
        const width = horizontalProvider.getHorizontalSashWidth(this);
        setProperty("width", width);
      }
    }
  }
nightire commented 2 years ago

I just synchronously modifies the relevant properties of the handler with the sash during layout.

I see, thank you.

johnwalley commented 2 years ago

Hi guys. Just to let you know I am keeping an eye on this issue (and the related #253) and I appreciate the discussion and code examples.

I think one of the main reasons this isn't simple is that there are several places in the code which assume that if you sum up the pane sizes they should add up to the container size. With real splitters this is no longer the case.

If I can find several uninterrupted hours to delve deep into the code I'd hope to get a proof of concept out.

Oh, and in terms of tracking progress and project management this feature is linked to #253 rather than this issue just because it arrived first.

MrHeer commented 2 years ago

I think one of the main reasons this isn't simple is that there are several places in the code which assume that if you sum up the pane sizes they should add up to the container size. With real splitters this is no longer the case.

Your right, my solution just for my requirement, It's not a real splitter. It's more like a attachment for sash.

andreasnett commented 2 years ago

I'd love it if there was a possibility to animate the left property of the sash. Currently I'm not able to get it working. Maybe I'm missing something @johnwalley ?

johnwalley commented 2 years ago

@andreasnett Could you describe in a bit more detail what you'd like to see? I don't currently expose much in the way of customisation for the sashes.

Here's an exaggerated example with a 2s transition on the left property of the sash and pane.

Jun-21-2022 17-50-11

andreasnett commented 2 years ago

Thanks for your reply. I tried transitioning the width property of the pane and the left property of the sash. Pane transition is looking nice, but the sash doesn't work as expected:

  1. Unlike in your gif here, when fireing the mouseup event, the sash snaps into place. I really can't tell why it's different in yours.
  2. From what I've tried it is not possible to use Allotments snap property to close the center pane. I've therefore done this in a conditional render with redux state fashion. When opening or closing the pane, transitioning the left property on the sash seems to take no effect.

The goal here is to animate the closing of the center pane in such a manner that the border of the pane and the sash move together.