New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

An example with two columns scrollable? #283

Open
kud opened this Issue Dec 5, 2018 · 17 comments

Comments

Projects
None yet
2 participants
@kud

kud commented Dec 5, 2018

Do you think it could be possible to make an example with two columns scrollable?

This is my try but I don't get it

  • index.js
import styles from "./index.module.css"

import React from "react"
import PropTypes from "prop-types"
import Waypoint from "react-waypoint"
import randomColor from "randomcolor"

function getRandomInt(min, max) {
  min = Math.ceil(min)
  max = Math.floor(max)

  return Math.floor(Math.random() * (max - min)) + min
}

class Block extends React.Component {
  render() {
    return (
      <div id={this.props.id} ref={this.props.innerRef} style={{
        height: getRandomInt(200, 1200) + "px",
        backgroundColor: randomColor({ seed: this.props.i*10 }),
        fontWeight: "bold",
        fontSize: "20px",
        color: "white",
        padding: "20px",
        textShadow: "0px 0px 1px black",
        borderBottom: "4px dashed white",
        display: "block",
      }}>
        {this.props.id}
      </div>
    )
  }
}

Block.propTypes = {
  innerRef: PropTypes.func.isRequired,
  id: PropTypes.string.isRequired,
  i: PropTypes.any.isRequired,
}

const BlockWithRef = React.forwardRef((props, ref) => {
  return <Block innerRef={ref} {...props} />
})

class SandboxPage extends React.Component {
  handleEnterA = (el, props) => {
    console.log("A: ENTER", el)
  }

  handleLeaveA = (el, props) => {
    console.log("A: LEAVE", el)
  }

  handleEnterB = (el, props) => {
    console.log("B: ENTER", el)
  }

  handleLeaveB = (el, props) => {
    console.log("B: LEAVE", el)
  }

  render() {
    return (
      <div className={styles.main} id="main">
        <div className={styles.column} id="A">
          {Array.from({length: 31}, (_, el) => (
            <Waypoint
              key={`A-${el}`}
              onEnter={(props) => { this.handleEnterA(el, props) }}
              onLeave={(props) => { this.handleLeaveA(el, props) }}
              fireOnRapidScroll
              topOffset="100px"
            >
              <BlockWithRef id={`A-${el}`} i={el} />
            </Waypoint>
          ))}
        </div>

        <div className={styles.column} id="B">
          {Array.from({length: 31}, (_, el) => (
            <Waypoint
                key={`B-${el}`}
                onEnter={(props) => { this.handleEnterB(el, props) }}
                onLeave={(props) => { this.handleLeaveB(el, props) }}
                fireOnRapidScroll
            >
              <BlockWithRef id={`B-${el}`} i={el} />
            </Waypoint>
          ))}
        </div>
      </div>
    )
  }
}

export default SandboxPage
  • index.module.css
.main {
  display: grid;
  grid-template-columns: repeat(2, 1fr)
}

.column {
  overflow-y: scroll;
  height: 100vh;
}

Thank you

@trotzig

This comment has been minimized.

Collaborator

trotzig commented Dec 6, 2018

Can you describe more specifically what's not working? Is it that the waypoints aren't firing at all? Or perhaps firing at the wrong time?

@kud

This comment has been minimized.

kud commented Dec 6, 2018

I'd like to trigger enter and leave on each column, but nothing happens now.

kapture 2018-12-06 at 12 18 15

@kud

This comment has been minimized.

kud commented Dec 6, 2018

Each block should trigger "enter" and "leave" but nothing happens and I've tried to change the scrollableAncestor, it didn't fix it.

@trotzig

This comment has been minimized.

Collaborator

trotzig commented Dec 6, 2018

If you add the debug prop to the waypoints, the console log might contain some information that can help you resolve this.

@kud

This comment has been minimized.

kud commented Dec 6, 2018

I already did it but to be honest, no :(

What do you think I should check there?

@kud

This comment has been minimized.

kud commented Dec 6, 2018

By any chance, is there a conflict with css grid or flexbox?

@trotzig

This comment has been minimized.

Collaborator

trotzig commented Dec 6, 2018

This shouldn't be because of flexbox or css grid. In the debug output, I would check that the scrollable ancestor is set to the right elements (the .column divs).

@kud

This comment has been minimized.

kud commented Dec 6, 2018

My trouble is here and I don't know why yet:

.column {
/*   overflow-y: auto; */
/*   height: 100vh; */
}

as seen, disabled works. But I don't have my both scrolls, i've got a global scroll on the page.

@kud

This comment has been minimized.

kud commented Dec 6, 2018

Yeah I wanted to check the scrollableAncestor, the problem is I only see that in the debug:

image

and I don't get it. It makes me think it's "window" there and no .column but I'm not sure at all.

Sorry for the live debug. (that's why I wanted to create a chat, haha)

@kud

This comment has been minimized.

kud commented Dec 6, 2018

OH MY GOD. I understand now why you think the debug mode could help me.

On Chrome (canary) I don't have the same result, which there helps me, yes:

image

We've got a "bug" with Firefox (Nightly); either it's firefox which displays not enough, or it's the way you display the debug.

@kud

This comment has been minimized.

kud commented Dec 6, 2018

Oh god, it's worst. It's not about debugging, it's about how the scrollableAncestor is detected on chrome and firefox.

@kud

This comment has been minimized.

kud commented Dec 6, 2018

image

image

I don't get the same result on firefox and chrome, the element is "visible", not "auto".

@kud

This comment has been minimized.

kud commented Dec 6, 2018

For a reason I don't explain yet, firefox has some troubles there:

function () {
      function _findScrollableAncestor() {
        var _props = this.props,
            horizontal = _props.horizontal,
            scrollableAncestor = _props.scrollableAncestor;


        if (scrollableAncestor) {
          return resolveScrollableAncestorProp(scrollableAncestor);
        }

        var node = this._ref;

        while (node.parentNode) {
          node = node.parentNode;

          if (node === document.body) {
            // We've reached all the way to the root node.
            return window;
          }

          var style = window.getComputedStyle(node);
          var overflowDirec = horizontal ? style.getPropertyValue('overflow-x') : style.getPropertyValue('overflow-y');
          var overflow = overflowDirec || style.getPropertyValue('overflow');

          // right here, firefox thinks it's "visible" on the first instance of the loop, where chrome says "auto"

          if (overflow === 'auto' || overflow === 'scroll') {
            return node;
          }
        }

        // A scrollable ancestor element was not found, which means that we need to
        // do stuff on window.
        return window;
      }

      return _findScrollableAncestor;
    }()
@kud

This comment has been minimized.

kud commented Dec 6, 2018

And the weirdest thing is it works well there: https://jsfiddle.net/_kud/u76b40Lr/5/

@trotzig

This comment has been minimized.

Collaborator

trotzig commented Dec 6, 2018

I wonder if the styles are applied asynchronously some way? Do things change if you inject styles earlier somehow?

@trotzig

This comment has been minimized.

Collaborator

trotzig commented Dec 6, 2018

By the way, thanks for being so persistent here. I appreciate you trying to pin this down!

@kud

This comment has been minimized.

kud commented Dec 6, 2018

Thank you @trotzig your component is amazing, I use it all the time. However, here I have to understand why it doesn't work like I'd to.

My goal here is to have two synchronised scrolls depending on where you are on ONE scroll.

But to be fair I think this discussion should be in a chat. :)

And about your note, the weird thing is that I've got hot reload, and when hot reload runs (like when I save my file), my render runs once again and seems to make it work. So I really wonder if I don't have a problem with the lifecycle on React but it's still weird it only happens on Firefox for the moment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment