반응형

https://codesandbox.io/s/explorer-l44v98?file=/index.js

 

Explorer - CodeSandbox

Explorer by fir0j using antd, react, react-dom, react-icons, react-scripts, styled-components

codesandbox.io

 

위 소스는 자식이 2개 이상 있으면 2개가 한꺼번에 오픈되는 에러 있음, 아래는 에러 수정한 버젼

import React, { Fragment, useEffect, useState } from "react";
import { IoMdArrowDropright } from "react-icons/io";
import { MdArrowDropDown } from "react-icons/md";
import styled from "styled-components";

const SelectParent = styled.div`
  padding: 7px 7px;
  background-color: darkblue;
  width: max-content;
  border-radius: 4px;
  margin-top: 4px;
  font-weight: bolder;
  color: white;
  cursor: pointer;
`;

const Selectname = styled.div`
  margin-top: 5px;
  padding: 7px 7px;
  width: fit-content;
  border-radius: 4px;
  cursor: default;
  color: darkblue;
  :hover {
    background-color: #bdbaba3c;
  }
`;

const Explorer = ({ parent = [], onParentClick, onNameClick /*expandOnHover = false*/ }) => {
  const [newData, setNewData] = useState([]);

  useEffect(() => {
    setNewData(parent.map((n) => ({ ...n, expand: false })));
  }, [parent]);

  const handleClickOnParent = (e, data) => {
    e.stopPropagation();
    if (onParentClick && onParentClick instanceof Function) onParentClick(data);

    const clickIdx = newData.findIndex((n) => data.name === n.name);
    const clickItem = newData.find((n) => data.name === n.name);

    setNewData([...newData.slice(0, clickIdx), { ...clickItem, expand: !clickItem.expand }, ...newData.slice(clickIdx + 1, newData.length)]);
  };

  const handleClickOnName = (e, data) => {
    e.stopPropagation();

    if (onNameClick && onNameClick instanceof Function) onNameClick(data);
  };

  return (
    <>
      {newData.map((item) => (
        <Fragment key={item.name}>
          {item.children && item.children.length ? (
            <Fragment /*key={index}*/>
              <SelectParent /*onMouseOver={() => (expandOnHover ? setExpand(true) : {})}*/ onClick={(e) => handleClickOnParent(e, item)}>
                {item.name} <span>{!item.expand ? <IoMdArrowDropright /> : <MdArrowDropDown />} </span>
              </SelectParent>

              {item.expand ? (
                <div style={{ paddingLeft: "1.5rem" }}>
                  <Explorer parent={item.children} onParentClick={onParentClick} onNameClick={onNameClick} /*expandOnHover={expandOnHover}*/ />
                </div>
              ) : null}
            </Fragment>
          ) : (
            <Selectname onClick={(e) => handleClickOnName(e, item)}>{item.name}</Selectname>
          )}
        </Fragment>
      ))}
    </>
  );
};

export default Explorer;
반응형

+ Recent posts