The Old County
The Old County

Reputation: 109

nextjs - initializsing masonry layout correctly with dynamic import

I'm trying to create some dashboards in nextjs - and I have started a project with masonry layout - but I can't seem to get it to initialize.

I've tried setting it in the useEffect - but its not doing anything.

https://codesandbox.io/p/devbox/ldpqcx

"use client";
import React, { useState, useEffect } from "react";
import dynamic from "next/dynamic";

export default function MasonryUI() {
  const msnry = "";

  useEffect(() => {
    const Masonry = dynamic(() => import("masonry-layout"), { ssr: false });
    var msnry = new Masonry(".grid", {
      itemSelector: ".grid-item",
      columnWidth: 200,
    });
    console.log("msnry", msnry);
  }, [msnry]);

  return (
    <>
      <h1>Masonry - columnWidth</h1>

      <div className="grid">
        <div className="grid-item"></div>
        <div className="grid-item grid-item--width2 grid-item--height2"></div>
        <div className="grid-item grid-item--height3"></div>
        <div className="grid-item grid-item--height2"></div>
        <div className="grid-item grid-item--width3"></div>
        <div className="grid-item"></div>
        <div className="grid-item"></div>
        <div className="grid-item grid-item--height2"></div>
        <div className="grid-item grid-item--width2 grid-item--height3"></div>
        <div className="grid-item"></div>
        <div className="grid-item grid-item--height2"></div>
        <div className="grid-item"></div>
        <div className="grid-item grid-item--width2 grid-item--height2"></div>
        <div className="grid-item grid-item--width2"></div>
        <div className="grid-item"></div>
        <div className="grid-item grid-item--height2"></div>
        <div className="grid-item"></div>
        <div className="grid-item"></div>
        <div className="grid-item grid-item--height3"></div>
        <div className="grid-item grid-item--height2"></div>
        <div className="grid-item"></div>
        <div className="grid-item"></div>
        <div className="grid-item grid-item--height2"></div>
      </div>
    </>
  );
}

this had no impact

import Masonry from "masonry-layout"; // Direct import of Masonry

export default function MasonryUI() {
  useEffect(() => {
    if (typeof window !== "undefined") {
      const element = document.querySelector(".grid");
      if (element) {
        const masonryInstance = new Masonry(element, {
          itemSelector: ".grid-item",
          columnWidth: 200,
        });
        console.log("masonryInstance", masonryInstance);
      }
    }
  }, []); // Not any need it's unnecessary

Upvotes: 0

Views: 96

Answers (1)

The Old County
The Old County

Reputation: 109

This seems to be the solution

-- there was a class on main -- used regular instance and import of masonry -- created a type

https://codesandbox.io/p/devbox/affectionate-dijkstra-forked-kvwplk

"use client";

import React, { useState, useEffect } from "react";
import Masonry from "masonry-layout"; // Direct import of Masonry

export default function MasonryUI() {
  useEffect(() => {
    var element = document.querySelector(".grid");
    if (element) {
      const masonryInstance = new Masonry(element, {
        itemSelector: ".grid-item",
        columnWidth: 200,
      });
      console.log("masonryInstance", masonryInstance);
    }
  }, []); // Removed msnry dependency as it's unnecessary

  return (
    <>
      <h1>Masonry - columnWidth</h1>

      <div className="grid" style={{ border: "2px solid black" }}>
        <div className="grid-item">Hi there</div>
        <div className="grid-item grid-item--width2 grid-item--height2">
          Hi there
        </div>
        <div className="grid-item grid-item--height3">Hi there</div>
        <div className="grid-item grid-item--height2">Hi there</div>
        <div className="grid-item grid-item--width3">Hi there</div>
        <div className="grid-item">Hi there</div>
        <div className="grid-item">Hi there</div>
        <div className="grid-item grid-item--height2">Hi there</div>
        <div className="grid-item grid-item--width2 grid-item--height3">
          Hi there
        </div>
        <div className="grid-item">Hi there</div>
        <div className="grid-item grid-item--height2">Hi there</div>
        <div className="grid-item">Hi there</div>
        <div className="grid-item grid-item--width2 grid-item--height2">
          Hi there
        </div>
        <div className="grid-item grid-item--width2">Hi there</div>
        <div className="grid-item">Hi there</div>
        <div className="grid-item grid-item--height2">Hi there</div>
        <div className="grid-item">Hi there</div>
        <div className="grid-item">Hi there</div>
        <div className="grid-item grid-item--height3">Neil</div>
        <div className="grid-item grid-item--height2">Petal</div>
        <div className="grid-item">Hello</div>
        <div className="grid-item">John</div>
        <div className="grid-item grid-item--height2"></div>
      </div>
    </>
  );
}

also creating a type

// types/masonry-layout.d.ts
declare module "masonry-layout" {
  export default class Masonry {
    constructor(element: Element, options?: MasonryOptions);
    layout(): void;
    reloadItems(): void;
    destroy(): void;
  }

  interface MasonryOptions {
    itemSelector?: string;
    columnWidth?: number | string | Element;
    gutter?: number;
    percentPosition?: boolean;
    stamp?: string;
    fitWidth?: boolean;
    originLeft?: boolean;
    originTop?: boolean;
    transitionDuration?: string;
    resize?: boolean;
    initLayout?: boolean;
  }
}

Upvotes: 0

Related Questions