JavaScript Development Space

Get a List of All Files in a Folder And All Subfolders using Electron and React

Add to your RSS feed9 November 20233 min read
Get a List of All Files in a Folder And All Subfolders using Electron and React

To get a list of all files in a folder and its subfolders using Electron and React, you can use the Input Event to read the directory and file information. Here's a basic example of how you can achieve this:

1. First, make sure you have Electron and React installed in your project:

npm create @quick-start/electron

Then follow the prompts!

1 ✔ Project name: … <electron-app>
2 ✔ Select a framework: › react
3 ✔ Add TypeScript? … Yes
4 ✔ Add Electron updater plugin? … No
5 ✔ Enable Electron download mirror proxy? … No
6
7 Done.

Current folders structure Electron Vite Initialization Options

2. Add Tailwind to Electron:

npm install -D tailwindcss

then...

npx tailwindcss init

Configure your template paths

Add the paths to all of your template files in your tailwind.config.js file.

js
1 /** @type {import('tailwindcss').Config} */
2 module.exports = {
3 content: ['./src/renderer/index.html', './src/renderer/src/**/*.{js,ts,jsx,tsx}'],
4 };

Add the Tailwind directives to your src/renderer/src/assets/index.css files

1 @tailwind base;
2 @tailwind components;
3 @tailwind utilities;

Now add postcss.config.js file to your root directory.

js
1 module.exports = {
2 plugins: {
3 tailwindcss: {},
4 },
5 };

Modify your src/preload/index.ts file to set an api route

js
1 import { contextBridge } from 'electron';
2 import { electronAPI } from '@electron-toolkit/preload';
3 import * as fs from 'fs';
4
5 const api = {
6 readdirS: async (path: string): Promise<Dirent[]> =>
7 await fs.readdirSync(path, { encoding: 'utf-8', withFileTypes: true }),
8 isDirectory: (path: string): boolean => fs.lstatSync(path).isDirectory(),
9 };
10
11 if (process.contextIsolated) {
12 try {
13 contextBridge.exposeInMainWorld('electron', electronAPI);
14 contextBridge.exposeInMainWorld('api', api);
15 } catch (error) {
16 console.error(error);
17 }
18 } else {
19 // @ts-ignore (define in dts)
20 window.electron = electronAPI;
21 // @ts-ignore (define in dts)
22 window.api = api;
23 }

Now add this code to App.ts inside the renderer folder

js
1 import { useState } from 'react'
2
3 function App(): JSX.Element {
4 const [files, setFiles] = useState<string[]>([])
5
6 const folderOnChange = async (e: ChangeEvent<HTMLInputElement>) => {
7 if (!e.target.files?.length) return
8 const files: FileList = e.target.files
9 const folderPath = files[0].path
10 const dotIdx = folderPath.lastIndexOf('\\')
11 let folder
12 if (!dotIdx) {
13 folder = folderPath
14 } else {
15 folder = folderPath.substring(0, dotIdx)
16 }
17 const filesAndFolders = await getFiles(folder)
18 setFiles(filesAndFolders)
19 }
20 async function getFiles(dir, files = []): string[] {
21 // Get an array of all files and directories in the passed directory using fs.readdirSync
22 const fileList = await api.readdirS(dir)
23 // Create the full path of the file/directory by concatenating the passed directory and file/directory name
24 for (const file of Array.from(fileList)) {
25 const name = `${dir}\\${file.name}`
26 // Check if the current file/directory is a directory using fs.statSync
27 if (api.isDirectory(name)) {
28 // If it is a directory, recursively call the getFiles function with the directory path and the files array
29 getFiles(name, files)
30 } else {
31 // If it is a file, push the full path to the files array
32 files.push(name)
33 }
34 }
35 return files
36 }
37 return (
38 <div className="container">
39 <div className="flex items-center justify-center w-full mt-5">
40 <label
41 className="flex items-center justify-center w-[216px] h-[45px] border border-gray-300 border-dashed
42 rounded-lg cursor-pointer
43 bg-gray-100 hover:bg-gray-250 dark:hover:bg-bray-400 dark:bg-gray-500 dark:hover:bg-gray-250
44 hover:shadow-lg dark:hover:shadow-gray-400 hover:rotate-44"
45 >
46 <svg
47 width="24"
48 height="24"
49 viewBox="0 0 24 24"
50 fill="none"
51 xmlns="http://www.w3.org/2000/svg"
52 >
53 <path
54 d="M12 10V16M15 13H9M22 10V17C22 19.2091 20.2091 21 18 21H6C3.79086 21 2 19.2091 2 17V7C2 4.79086 3.79086 3 6 3H8.66667C9.53215 3 10.3743 3.28071 11.0667 3.8L12.9333 5.2C13.6257 5.71929 14.4679 6 15.3333 6H18C20.2091 6 22 7.79086 22 10Z"
55 stroke="currentColor"
56 strokeWidth="1.5"
57 strokeLinecap="round"
58 strokeLinejoin="round"
59 className="stroke-gray-500 dark:stroke-gray-400"
60 />
61 </svg>
62
63 <p className="mb-1 pl-2 text-sm text-gray-500 dark:text-gray-400">
64 <span className="font-semibold">Select a folder</span>
65 </p>
66 <input
67 type="file"
68 className="hidden"
69 directory=""
70 webkitdirectory=""
71 onChange={folderOnChange}
72 />
73 </label>
74 </span>
75
76 <div className="relative overflow-x-auto">
77 <table className="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400">
78 <thead className="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
79 <tr>
80 <th scope="col" className="px-6 py-3">
81 File name
82 </th>
83 </tr>
84 </thead>
85 <tbody>
86 {files.length > 0 &&
87 files.map((file) => {
88 return (
89 <tr
90 className="bg-white border-b dark:bg-gray-800 dark:border-gray-700"
91 key={file}
92 >
93 <th
94 scope="row"
95 className="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white"
96 >
97 {file}
98 </th>
99 </tr>
100 )
101 })}
102 </tbody>
103 </table>
104 </span>
105 </span>
106 )
107 }
108
109 export default App

Run your app:

npm run dev

This example assumes that you have a basic understanding of Electron and React. Also, note that this example doesn't handle errors, and in a production environment, you should implement error handling for better robustness.

Related Posts:

JavaScript Development Space

© 2024 JavaScript Development Space - Master JS and NodeJS. All rights reserved.