javascriptreactjsreact-grid-layout

Limiting containers to three fixed sizes


I'm looking at the react-grid-layout which is based on Material Design's 12 column grid. Is there a way to provide pre-defined sizes for containers to stick to the following 3 sizes: 1 full width (12 cols), half grid (6 cols) or 1/3 grid (4 cols)?

Sandbox


Solution

  • My guess is that when you say container, you're referring to the layout items. If that is the case, use a custom onResize method. Using the sandbox code you have from your question:

    export default class ShowcaseLayout extends React.Component {
      constructor(props) {
        ...
        // add the line below
        this.onResize = this.onResize.bind(this);
      }
    
      ...
    
      // add the method
      onResize(layout, oldLayoutItem, layoutItem, placeholder) {
        // `oldLayoutItem` contains the state of the item before the resize.
        // You can modify `layoutItem` to enforce constraints.
        const allowableW = this.props.cols[this.state.currentBreakpoint] - oldLayoutItem.x
        if (layoutItem.w <= 4) {
          layoutItem.w = 4;
          placeholder.w = 4;
        } else if (layoutItem.w <= 6) {
          layoutItem.w = allowableW < 6 ? 4 : 6;
          placeholder.w = allowableW < 6 ? 4 : 6;
        } else {
          layoutItem.w = allowableW < 12 ? 6 : 12;
          placeholder.w = allowableW < 12 ? 6 : 12;
        }
      }
    
      render() {
        return (
          <div>
            ...
            <ResponsiveReactGridLayout
              ...
              {/* bind method to component */}
              onResize={this.onResize}
            >
              {this.generateDOM()}
            </ResponsiveReactGridLayout>
          </div>
        );
      }
    }
    
    ShowcaseLayout.propTypes = {
      onLayoutChange: PropTypes.func.isRequired
    };
    
    ShowcaseLayout.defaultProps = {
      ...
      // ensure your breakpoints have a minimum of 4 columns
      cols: { lg: 12, md: 10, sm: 6, xs: 4, xxs: 4 },
    };
    
    function generateLayout() {
      return _.map(_.range(0, 25), function (item, i) {
        var y = Math.ceil(Math.random() * 4) + 1;
        return {
          x: (_.random(0, 5) * 2) % 12,
          y: Math.floor(i / 6) * y,
          // set item's default width to 4
          w: 4,
          h: y,
          i: i.toString(),
          static: Math.random() < 0.05
        };
      });
    }
    

    DEMO