Skip to content

Commit 172d86f

Browse files
shreyakurian02sreeram-venkitesh
authored andcommitted
Added indentation and upload functionality
1 parent a1b0a16 commit 172d86f

File tree

6 files changed

+430
-13
lines changed

6 files changed

+430
-13
lines changed

components/constants.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,11 @@ export const DEMO_JSON_STRING = {
2727
},
2828
},
2929
};
30+
31+
export const INDENTATION_SPACE_OPTIONS = [
32+
{ label: 2, value: 2 },
33+
{ label: 3, value: 3 },
34+
{ label: 4, value: 4 },
35+
];
36+
37+
export const DEFAULT_INDENTATION_SPACE = { label: 2, value: 2 };

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"next": "13.0.6",
2121
"react": "18.2.0",
2222
"react-dom": "18.2.0",
23+
"react-select": "^4.3.1",
2324
"react-toastify": "^9.1.1",
2425
"sass": "^1.57.1"
2526
},

pages/index.js

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useEffect, useState } from "react";
1+
import { useEffect, useState, useRef } from "react";
22
import CodeMirror from "@uiw/react-codemirror";
33
import { javascript } from "@codemirror/lang-javascript";
44
import { createTheme } from "@uiw/codemirror-themes";
@@ -7,9 +7,14 @@ import Head from "next/head";
77
import Toastr from "../components/Toastr";
88
import { ToastContainer } from "react-toastify";
99
import Button from "../components/Button";
10+
import Select from "react-select";
1011

1112
import { CODE_EDITOR_THEME } from "../constants/theme";
12-
import { DEMO_JSON_STRING } from "../components/constants";
13+
import {
14+
DEFAULT_INDENTATION_SPACE,
15+
DEMO_JSON_STRING,
16+
INDENTATION_SPACE_OPTIONS,
17+
} from "../components/constants";
1318
import { Copy } from "../icons/Copy";
1419
import Header from "../components/Header";
1520

@@ -19,11 +24,16 @@ export default function Home() {
1924
);
2025
const [outputString, setOutputString] = useState("");
2126

27+
const hiddenFileInput = useRef(null);
28+
const selectRef = useRef(null);
29+
2230
let editorExtensions = [javascript({ jsx: true }), EditorView.lineWrapping];
2331

24-
const handleFormat = () => {
32+
const handleFormat = (indentationSpace = 2) => {
2533
try {
26-
setOutputString(JSON.stringify(JSON.parse(inputString), null, 2));
34+
setOutputString(
35+
JSON.stringify(JSON.parse(inputString), null, indentationSpace)
36+
);
2737
} catch (error) {
2838
Toastr.error("Enter Valid JSON");
2939
}
@@ -59,6 +69,13 @@ export default function Home() {
5969
setOutputString("");
6070
};
6171

72+
const handleUpload = (e) => {
73+
const fileReader = new FileReader();
74+
fileReader.readAsText(e.target.files[0], "UTF-8");
75+
fileReader.onload = (e) => setInputString(e.target.result);
76+
setOutputString("");
77+
};
78+
6279
useEffect(() => {
6380
inputString === "" && setOutputString("");
6481
}, [inputString]);
@@ -73,7 +90,7 @@ export default function Home() {
7390

7491
<main className="h-screen flex flex-col justify-between bg-zinc-900 p-5">
7592
<ToastContainer theme="dark" />
76-
<Header/>
93+
<Header />
7794
<div className="space-y-3 grow flex flex-col">
7895
<div className="flex grow space-x-3">
7996
<div className="w-full bg-[#282c34]">
@@ -113,13 +130,35 @@ export default function Home() {
113130
</div>
114131
</div>
115132
<div className="flex justify-end bg-zinc-800 space-x-3 px-3 py-3 rounded">
116-
<Button label="Format" onClick={handleFormat} />
133+
<Button
134+
label="Format"
135+
onClick={() => handleFormat(selectRef.current.state.value.value)}
136+
/>
117137
<Button label="Clear" onClick={handleClear} />
118138
<Button
119139
label="Download"
120140
onClick={handleDownload}
121141
disabled={outputString === ""}
122142
/>
143+
<Button
144+
onClick={() => hiddenFileInput.current.click()}
145+
label="Upload"
146+
/>
147+
<input
148+
type="file"
149+
style={{ display: "none" }}
150+
ref={hiddenFileInput}
151+
onChange={handleUpload}
152+
/>
153+
<Select
154+
ref={selectRef}
155+
classNamePrefix="react-select"
156+
onChange={(e) => handleFormat(e.value)}
157+
className={"react-select__container"}
158+
menuPlacement="top"
159+
options={INDENTATION_SPACE_OPTIONS}
160+
defaultValue={DEFAULT_INDENTATION_SPACE}
161+
/>
123162
</div>
124163
</div>
125164
{/* <Footer /> */}

styles/application.scss

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44

55
@import "./abstracts/variable";
66
@import "./base/index";
7+
@import "react-toastify/dist/ReactToastify.min.css";
78

89
// components
910
@import "./components/button";
1011
@import "./components/textarea";
11-
@import "react-toastify/dist/ReactToastify.min.css";
12+
@import "./components/select";

styles/components/_select.scss

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
.react-select__single-value {
2+
color: white;
3+
}
4+
5+
.react-select__container,
6+
.react-select__menu-portal {
7+
.react-select__control.react-select__control--is-focused {
8+
border: none !important;
9+
outline: none !important;
10+
box-shadow: none;
11+
}
12+
13+
.react-select__control {
14+
background-color: $secondary;
15+
border: none;
16+
color: white;
17+
}
18+
19+
.react-select__value-container {
20+
padding: 0 8px;
21+
min-height: 40px;
22+
23+
&.react-select__value-container--has-value {
24+
padding: 6px 12px;
25+
}
26+
}
27+
28+
.react-select__indicator-separator {
29+
display: none;
30+
}
31+
32+
.react-select__menu {
33+
background-color: #b14b74b9;
34+
35+
.react-select__option--is-focused {
36+
background-color: #461629b9;
37+
}
38+
39+
.react-select__option--is-selected {
40+
background-color: #2e111db9;
41+
}
42+
}
43+
}

0 commit comments

Comments
 (0)