nikitaeverywhere / react-xmasonry

Simple, minimalistic and featured native masonry layout for React JS.
https://zitros.github.io/react-xmasonry
MIT License
91 stars 12 forks source link

Can't get number of columns on resize #7

Closed gaddafirusli closed 6 years ago

gaddafirusli commented 6 years ago

Hey ZitRos. Thanks for providing this wonderful thing. I'm using this in my electron + react project :)

I'm trying to get the number of columns with this.xMasonry.columns. It works great on load. But I'm having trouble trying to get the number when user resized the window as there's no callback method on resize. Is there a way to retrieve the number when the column count changed?

nikitaeverywhere commented 6 years ago

Hello Gaddafi and congrats on the first issue! Thank you for reporting this, interesting catch.

Currently XMasonry does not provide anything like onResize callback. My very first idea was that introducing onResize prop may lead to some bad effects as infinite looping when used improperly. But I agree definitely, there should be something to let the UI know that the number of columns/sizes has changed.

The possible use case I can think of, is, for example, giving the proper widths to blocks to reach the desired look. I am wondering if this is your case.

Anyway, on your opinion, what will be the best option to implement? onResize callback sounds good. If I would think about implementing onResize, I will put XMasonry React Component instance as a first argument, e.g:

class Test extends React.Component {

  columns = 1;  

  render () {
    return <XMasonry onResize={ (xm) => this.columns !== xm.columns && this.columns = xm.columns && updateUI() }>
      { /* updates UI only when column count changes */ }
    </XMasonry>
  }

}

Then, onResize will work every time when XMasonry container width changes.

gaddafirusli commented 6 years ago

Thank you!

I'm using images in my xblock. To reduce the messy effect with the slow loading image, I'm specifying the height to the image container based on the image ratio (provided by my API). So, in order to calculate the height, I need to get the current width of the xblock element. But since I can't get the value, I'm using containerWidth / columnCount. Works great, except when the column count changed.

I'm not sure what's good for the implementation. I'm sure u have better context than me. If you're worried about the improper used of onResize, maybe it'd be would be enough to just exposed the number. As long as we can get the column count (or column width) when the number changed, that would be great. What do u think?

nikitaeverywhere commented 6 years ago

If I were you, having the ratios of the images I will go with fixed CSS ratio approach, exactly as it is in the Articles Demo on XMasonry demo pages. Doesn't this work for you?

gaddafirusli commented 6 years ago

Yeah, I saw that. But I prefer to use img rather than background-image for the photos - for performance reason, and also so that user can drag/drop photos out of the app.

nikitaeverywhere commented 6 years ago

No problems - just fix the ratio of the image container using fixed CSS ratio, and specify width: 100% in the image itself! (image container must be position: relative)

Just as it is in the example, but put <img> to the container instead of its background.

gaddafirusli commented 6 years ago

Won't work in my case because every image have different ratio.

nikitaeverywhere commented 6 years ago

Why won't it work?

gaddafirusli commented 6 years ago

Oh wow I don't know why I forgot that I can pass the padding-top as an inline style. I just implemented your solution and it works great! Thank you for your time - and sorry for turning this into a CSS/JS lesson 😅

nikitaeverywhere commented 6 years ago

No worries! I am happy that we solved this :) Good luck!