Skip to content

Commit e7a53c0

Browse files
Merge pull request #30 from sreeram-venkitesh/add-demo-and-copy-json-functionality
Added demo json and functionality to copy output json string
2 parents 4514710 + 993e5e7 commit e7a53c0

File tree

6 files changed

+139
-26
lines changed

6 files changed

+139
-26
lines changed

components/Button.jsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import React from "react";
12
import { motion } from "framer-motion";
23
import classnames from "classnames";
34

@@ -11,6 +12,8 @@ const Button = ({
1112
href = "",
1213
to = "",
1314
type = "button",
15+
icon = null,
16+
iconSize = 16,
1417
...otherProps
1518
}) => {
1619
let Parent, elementSpecificProps;
@@ -31,6 +34,8 @@ const Button = ({
3134
if (!disabled) onClick();
3235
};
3336

37+
const Icon = icon || React.Fragment;
38+
3439
return (
3540
<Parent
3641
onClick={handleClick}
@@ -48,6 +53,7 @@ const Button = ({
4853
{...elementSpecificProps}
4954
>
5055
{label && <span>{label}</span>}
56+
{icon && <Icon size={iconSize} className="cs-ui-btn__icon" />}
5157
</Parent>
5258
);
5359
};

components/constants.js

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,27 @@ export const FOOTER_MESSAGES = [
33
"Penguins Propose and Stick Together for Life",
44
"Baby Sloths Are Addicted to Cuddling",
55
"A Group of Bunnies Is Called a Fluffle",
6-
];
6+
];
7+
8+
export const DEMO_JSON_STRING = {
9+
glossary: {
10+
title: "example glossary",
11+
GlossDiv: {
12+
title: "S",
13+
GlossList: {
14+
GlossEntry: {
15+
ID: "SGML",
16+
SortAs: "SGML",
17+
GlossTerm: "Standard Generalized Markup Language",
18+
Acronym: "SGML",
19+
Abbrev: "ISO 8879:1986",
20+
GlossDef: {
21+
para: "A meta-markup language, used to create markup languages such as DocBook.",
22+
GlossSeeAlso: ["GML", "XML"],
23+
},
24+
GlossSee: "markup",
25+
},
26+
},
27+
},
28+
},
29+
};

icons/Copy.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/** Icons generated by create-react-icons. Don't edit this file directly. **/
2+
import React from "react";
3+
import PropTypes from "prop-types";
4+
5+
export function Copy(props) {
6+
const { size, color, ...other } = props;
7+
return (
8+
<svg
9+
viewBox="0 0 24 24"
10+
fill="none"
11+
height={size}
12+
width={size}
13+
title="copy-ico"
14+
{...other}
15+
>
16+
<path
17+
d="M5.167 16C3.97 16 3 15.03 3 13.833V5.167C3 3.97 3.97 3 5.167 3H13.834C15.03 3 16 3.97 16 5.167"
18+
stroke={color}
19+
strokeWidth="1.5"
20+
strokeLinecap="round"
21+
strokeLinejoin="round"
22+
/>
23+
<path
24+
d="M18.833 21H10.166C8.97 21 8 20.03 8 18.833V10.166C8 8.97 8.97 8 10.167 8H18.834C20.03 8 21 8.97 21 10.167V18.834C21 20.03 20.03 21 18.833 21V21Z"
25+
stroke={color}
26+
strokeWidth="1.5"
27+
strokeLinecap="round"
28+
strokeLinejoin="round"
29+
/>
30+
</svg>
31+
);
32+
}
33+
34+
Copy.defaultProps = {
35+
color: "currentColor",
36+
size: 24,
37+
};
38+
39+
Copy.propTypes = {
40+
color: PropTypes.string,
41+
size: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
42+
};

pages/index.js

Lines changed: 64 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,26 @@ import CodeMirror from "@uiw/react-codemirror";
33
import { javascript } from "@codemirror/lang-javascript";
44
import { createTheme } from "@uiw/codemirror-themes";
55
import { EditorView } from "@codemirror/view";
6-
76
import Head from "next/head";
87
import Toastr from "../components/Toastr";
98
import { ToastContainer } from "react-toastify";
109
import Button from "../components/Button";
1110

1211
import { CODE_EDITOR_THEME } from "../constants/theme";
12+
import { DEMO_JSON_STRING } from "../components/constants";
13+
import { Copy } from "../icons/Copy";
1314

1415
export default function Home() {
15-
const [inputString, setInputString] = useState("");
16+
const [inputString, setInputString] = useState(
17+
JSON.stringify(DEMO_JSON_STRING)
18+
);
1619
const [outputString, setOutputString] = useState("");
1720

21+
let editorExtensions = [javascript({ jsx: true }), EditorView.lineWrapping];
22+
1823
const handleFormat = () => {
1924
try {
20-
setOutputString(JSON.stringify(JSON.parse(inputString), null, 4));
25+
setOutputString(JSON.stringify(JSON.parse(inputString), null, 2));
2126
} catch (error) {
2227
Toastr.error("Enter Valid JSON");
2328
}
@@ -31,14 +36,28 @@ export default function Home() {
3136
const handleDownload = () => {
3237
const element = document.createElement("a");
3338
const file = new Blob([outputString], {
34-
type: "text/plain;charset=utf-8",
39+
type: "text/json",
3540
});
3641
element.href = URL.createObjectURL(file);
37-
element.download = "json.txt";
42+
element.download = "json.json";
3843
document.body.appendChild(element);
3944
element.click();
4045
};
4146

47+
const handleCopy = () => {
48+
try {
49+
navigator.clipboard.writeText(outputString);
50+
Toastr.success("Copied to clipboard");
51+
} catch (error) {
52+
Toastr.error("Could not Copy. Try again");
53+
}
54+
};
55+
56+
const handleDemoJson = () => {
57+
setInputString(JSON.stringify(DEMO_JSON_STRING));
58+
setOutputString("");
59+
};
60+
4261
useEffect(() => {
4362
inputString === "" && setOutputString("");
4463
}, [inputString]);
@@ -56,28 +75,50 @@ export default function Home() {
5675
<p className="text-2xl text-center">JSON STYLE</p>
5776
<div className="space-y-3 flex-col">
5877
<div className="flex space-x-3 h-90">
59-
<CodeMirror
60-
autoFocus
61-
height="548px"
62-
theme="dark"
63-
value={inputString}
64-
extensions={[javascript({ jsx: true })]}
65-
onChange={(e) => setInputString(e)}
66-
className="w-1/2 mt-7 h-full"
67-
/>
68-
<CodeMirror
69-
height="548px"
70-
theme={createTheme(CODE_EDITOR_THEME)}
71-
editable={false}
72-
value={outputString}
73-
extensions={[javascript({ jsx: true }), EditorView.lineWrapping]}
74-
className="w-1/2 mt-7 overflow-auto h-full"
75-
/>
78+
<div className="w-full bg-[#282c34]">
79+
<Button
80+
size="small"
81+
style="text"
82+
label="Demo JSON"
83+
onClick={handleDemoJson}
84+
/>
85+
<CodeMirror
86+
autoFocus
87+
height="548px"
88+
theme="dark"
89+
value={inputString}
90+
extensions={editorExtensions}
91+
onChange={(e) => setInputString(e)}
92+
className="h-full mt-1"
93+
/>
94+
</div>
95+
<div className="w-full bg-[#282c34]">
96+
<Button
97+
size="small"
98+
style="text"
99+
onClick={handleCopy}
100+
icon={Copy}
101+
className="float-right"
102+
disabled={outputString === ""}
103+
/>
104+
<CodeMirror
105+
height="548px"
106+
theme={createTheme(CODE_EDITOR_THEME)}
107+
editable={false}
108+
value={outputString}
109+
extensions={editorExtensions}
110+
className="overflow-auto h-full mt-7"
111+
/>
112+
</div>
76113
</div>
77114
<div className="flex bg-zinc-800 space-x-3 px-3 py-3 rounded spacy-x-2">
78115
<Button label="Format" onClick={handleFormat} />
79116
<Button label="Clear" onClick={handleClear} />
80-
<Button label="Download" onClick={handleDownload} />
117+
<Button
118+
label="Download"
119+
onClick={handleDownload}
120+
disabled={outputString === ""}
121+
/>
81122
</div>
82123
</div>
83124
{/* <Footer /> */}

styles/abstracts/_variable.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ $font-sm: 14px;
99
$font-semibold: 600;
1010

1111
// Font Size
12+
$text-sm: 12px;
1213
$text-base: 16px;
1314

1415
// Border Radius

styles/components/_button.scss

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,14 @@
3434
}
3535

3636
&-text {
37-
color: $gray-900;
37+
color: $white;
3838
}
3939
}
4040

4141
//size
4242
.button--size {
4343
&-small {
44-
font-size: $text-base;
44+
font-size: $text-sm;
4545
padding: 4px 8px;
4646
}
4747

0 commit comments

Comments
 (0)