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
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 = "";
}
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
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"
)
];
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;
`;
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)