Skip to content
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

Deep nested list #493

Open
elvonkh opened this issue Aug 27, 2021 · 2 comments
Open

Deep nested list #493

elvonkh opened this issue Aug 27, 2021 · 2 comments
Labels

Comments

@elvonkh
Copy link

elvonkh commented Aug 27, 2021

I am using muuri-react and I want to make deep nested sortable list like in the image below
image
I am using following code to generate nested list

import { MuuriComponent } from "muuri-react";
import React, { useCallback, useEffect, useState } from "react";
import CollectionItem from "./CollectionItem";
import { useGrid } from "muuri-react";

const sortedColl = [
  {
    id: "1db3cf0f-1705-4d24-a279-368d9ceb3a89",
    title: "New",
    children: [
      {
        id: "f653da27-7cba-4a94-9f3e-d08988d87348",
        title: "Dresses",
      },
      {
        id: "cce17318-21e6-42fa-9dc2-f60affd22e0a",
        title: "Dresses",
        children: [
          {
            id: "3f445f24-1000-415e-93f5-f59db4985dc2",
            title: "Dresses",
            children: [
              {
                id: "7510d247-5774-4bbc-8094-67ab5c530a16",
                title: "Clothing",
              },
            ],
          },
        ],
      },
    ],
  },
  {
    id: "91f27837-e17d-4064-96f6-51ff1aa8facb",
    title: "New",
  },

  {
    id: "3f445f24-1000-415e-93f5-f59db4985dc2",
    title: "Dresses",
  },
];
const coll =  [
  {
    id: "1db3cf0f-1705-4d24-a279-368d9ceb3a89",
    title: "New",
    
  },
  {
    id: "7510d247-5774-4bbc-8094-67ab5c530a16",
    title: "Clothing",
  },
  {
    id: "91f27837-e17d-4064-96f6-51ff1aa8facb",
    title: "New",
  },
  {
    id: "3f445f24-1000-415e-93f5-f59db4985dc2",
    title: "Dresses",
  },
];

function useSend(setItems, collections) {
  return useCallback(
    ({ key, fromId, toId, fromIndex, toIndex }) => {
      const blockPathTo = getBlockPath(toId);
      const blockPathFrom = getBlockPath(fromId);
      console.log(blockPathFrom);
      console.log(blockPathTo);
      if (fromId === "available") {
        console.log(collections, key);
        const item = collections.find(
          (collectionItem) => collectionItem.id === key
        );
        item.id = uuidv4();
        setItems((currentList) => {
          const tempList = [...currentList];
          console.log('tempList', tempList)
          if (blockPathTo?.length === 0) {
            console.log('Block path is empty')
            tempList.splice(toIndex, 0, item);
          } else {
            
          }
          // const newList = addItemRecursively(currentList, blockPathTo, toIndex, item)
          return tempList;
        });
        // const item = collections.find(
        //   (collectionItem) => collectionItem.id === key
        // );
        // item.id = uuid();
        return;
      }
      setItems((currentList) => {
        const item = findItemRecursively(currentList, key);
        removeRecursivelyFromChildren(
          currentList,
          blockPathFrom,
          fromIndex,
          item
        );
      });
    },
    [collections]
  );
}

export default function DndCollections() {
  const [collections, setCollections] = useState([]);
  const [sortedCollections, setSortedCollections] = useState(sortedColl);

  const sortedListOptions = {
    onSend: useSend(setSortedCollections, collections),
  };
  const MuuriWrapper = React.memo(({ item, blockIndex }) => {
    let id = "sorted";
    let blockIndexStringified = "-";
    if (Array.isArray(blockIndex)) {
      blockIndexStringified += blockIndex.join("-");
    }
    id += blockIndexStringified;
    const handleClass = `handle${blockIndexStringified}`;
    return (
      <MuuriComponent
        {...sortedListOptions}
        groupIds={["sortedList"]}
        dragSort={{ groupId: "sortedList" }}
        id={id}
        dragEnabled
        dragStartPredicate={{
          handle: "." + handleClass,
        }}
      >
        {item?.children.map((childItem, childIdx) => (
          <Item
            blockIndex={[...blockIndex, childIdx]}
            handleClass={handleClass}
            item={childItem}
            key={childItem.id}
          />
        ))}
      </MuuriComponent>
    );
  });

  const Item = React.memo(({ item, blockIndex, handleClass = "handle" }) => {
    
    return (
      <div
        style={{
          background: "white",
          boxSizing: "border-box",
          maxWidth: "100%",
          overflow: "hidden",
        }}
      >
        <CollectionItem
          item={item}
          handleClass={handleClass}
        />
        {item?.children?.length && (
          <div style={{ marginLeft: "2rem", height: itemHeight + "px" }}>
            <MuuriWrapper item={item} blockIndex={blockIndex} />
          </div>
        )}
      </div>
    );
  });


  const children = sortedCollections.map((item, index) => (
    <Item blockIndex={[index]} key={item.id} item={item} />
  ));

  return (<Card title="All collections" sectioned>
        {collections?.length && (
          <MuuriComponent
            id="available"
            dragEnabled
            groupIds={["LIST"]}
            dragSort={{ groupId: "LIST" }}
            dragPlaceholder={{
              enabled: true,
              createElement(item) {
                const placeholder = document.createElement("div");
                placeholder.innerHTML = "<div></div>";
                return placeholder;
              },
            }}
            onSend={onAvailableSend}
          >
            {collections.map((item, index) => (
              <div
                key={item.id}
                style={{
                  background: "white",
                  boxSizing: "border-box",
                  maxWidth: "100%",
                  overflow: "hidden",
                }}
              >
                <CollectionItem item={item} handleClass="handle" />
              </div>
            ))}
          </MuuriComponent>
        )}
      </Card>
      <Card title="Sorted collections" sectioned>
        <MuuriComponent
          groupIds={["LIST", "sortedList"]}
          dragSort={{ groupId: "sortedList" }}
          id="sorted"
          dragEnabled
          dragStartPredicate={{ handle: ".handle" }}
          {...sortedListOptions}
        >
          {children}
        </MuuriComponent>
      </Card>
  );
}

@EminQasimov
Copy link

EminQasimov commented Sep 6, 2021

@elvonkh , hi, does muuri-react work with latest react versions(17)?
paol-imi/muuri-react#50
paol-imi/muuri-react#59

or do you use fork version of it? https://github.com/adamerose/muuri-react
btwn, your example looks similar with dndkit examples -
https://5fc05e08a4a65d0021ae0bf2-gngonedmxi.chromatic.com/?path=/story/examples-tree-sortable--all-features

@alexandrsek
Copy link

alexandrsek commented Sep 23, 2021

Hello! Sorry for being a little off topic, but I had a similar task to make a nested drag and drop navigation menu and tried many DnD packages like DnDKit, react-beautiful-dnd and etc...

I found a solution using a package called "atlaskit/tree". It required some tweaks to data structure, but in the end it solved this problem for me perfectly. The documentation is not the best so I recommend reading source code on the bitbucket

Docs and examples: https://atlaskit.atlassian.com/packages/confluence/tree
BitBucket: https://bitbucket.org/atlassian/atlaskit-mk-2/src/master/packages/core/tree/src/

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

No branches or pull requests

4 participants