DEV Community

Cover image for Building a File directory display component using React
vigneshiyergithub
vigneshiyergithub

Posted on • Edited on

Building a File directory display component using React

What is this post about ?

Hello fellow humanoids. Today we will try to implement a basic file directory display component. This post won't be focused much on the styling rather the bare minimum logic required.

Check out the app here : File Viewer

File Viewer app

Content

  • File data structure
  • Generating Directory contents
  • Displaying File Viewer

Lets go deep dive into each one and explore how it was implemented.

File data structure

export class File {
  constructor(fileName, childFiles, fileType) {
    this.fileName = fileName;
    this.childFiles = childFiles;
    this.fileType = fileType;
  }

  fileName = "";
  childFiles = [];
  fileType = "";
}
Enter fullscreen mode Exit fullscreen mode

Generating Directory contents

Let's check out the basic file structure that we are planning to showcase in this example

 src
   |-components
       |-first.js
       |-second.js
       |-third.js
       |-fourth.exe
       |-fifth.doc
       |-sixth.txt 
   |-App.js
Enter fullscreen mode Exit fullscreen mode

Once you have visualized the file structure, now it's time to
initialize the files variable with the data structure we defined above

const COMPONENTS = [
  "first.js",
  "second.js",
  "third.js",
  "fourth.exe",
  "fifth.doc",
  "six.txt"
];

const files = [
  new File(
    "src",
    [
      new File(
        "components",
        [...COMPONENTS].map((comp) => new File(comp, [], "file")),
        "directory"
      ),
      new File("App.js", [], "file")
    ],
    "directory"
  )
];
Enter fullscreen mode Exit fullscreen mode

Displaying File Viewer

const FileViewer = () => {
  console.log(files);
  return (
    <Wrapper>
      <FileViewerContainer>
        {files.map((file, index) => {
          return <FilesViewer file={file} key={index} level={0} />;
        })}
      </FileViewerContainer>
    </Wrapper>
  );
};

const FilesViewer = ({ file, level }) => {
  const { fileType, childFiles, fileName } = file;
  const [expanded, setExpanded] = useState(false);
  const onToggle = () => {
    setExpanded((ex) => !ex);
  };
  return (
    <>
      <FilesContainer paddingLeft={`${(level + 1) * 2}rem`}>
        {fileType === "directory" && (
          <IconContainer onClick={onToggle}>
            {expanded ? <ExpandLessIcon /> : <ExpandMoreIcon />}
          </IconContainer>
        )}
        <FileTitle>{fileName}</FileTitle>
      </FilesContainer>
      {childFiles.length > 0 &&
        expanded &&
        file.childFiles.map((childFile, index) => {
          return <FilesViewer file={childFile} key={index} level={level + 1} />;
        })}
    </>
  );
};

const IconContainer = styled.div`
  align-self: center;
  cursor: pointer;
`;

const ExpandLessIcon = styled(MdExpandLess)`
  width: 2rem;
  align-self: center;
`;

const ExpandMoreIcon = styled(MdExpandMore)`
  width: 2rem;
  align-self: center;
`;

const Wrapper = styled.div`
  height: 100vh;
  width: 100vw;
  display: flex;
  justify-content: center;
  align-items: center;
`;

const FileViewerContainer = styled.div`
  width: 60vw;
  max-height: 80vh;
  display: flex;
  flex-direction: column;
  background: hsl(210deg, 30%, 8%);
  border: 1px solid hsl(210deg, 15%, 20%);
  border-radius: 1rem;
  color: #e9dd78;
  overflow-y: auto;
  justify-content: center;
`;

const FilesContainer = styled.div`
  width: fit-content;
  height: 3rem;
  padding-left: ${(props) => props?.paddingLeft ?? 0};
  display: flex;
  flex-direction: row;
`;

const FileTitle = styled.div`
  font-size: x-large;
  align-self: center;
`;
Enter fullscreen mode Exit fullscreen mode

Conclusion

This app was made as part of learning new components which are used in real life applications.
Stay safe and lend a hand to another :)

Top comments (0)