File tree Expand file tree Collapse file tree 4 files changed +158
-19
lines changed Expand file tree Collapse file tree 4 files changed +158
-19
lines changed Original file line number Diff line number Diff line change 1+ import { Upload } from "lucide-react" ;
2+ import { ReactNode , useState } from "react" ;
3+
4+ interface DropZoneProps {
5+ onDrop ?: ( file : File ) => void ;
6+ children : ReactNode ;
7+ }
8+
9+ export const DropZone = ( { onDrop, children } : DropZoneProps ) => {
10+ const [ isDragging , setIsDragging ] = useState ( false ) ;
11+
12+ const handleOnDrop = ( e : React . DragEvent < HTMLDivElement > ) => {
13+ e . preventDefault ( ) ;
14+ setIsDragging ( false ) ;
15+ const file = e . dataTransfer . files [ 0 ] ;
16+ if ( file ) {
17+ onDrop ?.( file ) ;
18+ }
19+ } ;
20+
21+ return (
22+ < div
23+ onDrop = { handleOnDrop }
24+ onDragOver = { ( e ) => {
25+ setIsDragging ( true ) ;
26+ e . preventDefault ( ) ;
27+ } }
28+ onDragEnter = { ( ) => setIsDragging ( true ) }
29+ onDragLeave = { ( ) => setIsDragging ( false ) }
30+ data-drag = { isDragging ? "true" : "false" }
31+ className = "relative"
32+ >
33+ { children }
34+ < div
35+ data-drag = { isDragging ? "true" : "false" }
36+ className = "
37+ invisible data-[drag=true]:visible opacity-0 data-[drag=true]:opacity-80
38+ absolute flex w-full h-full top-0 left-0 p-2 bg-white
39+ transition-opacity duration-200
40+ "
41+ >
42+ < div
43+ className = "
44+ flex flex-col items-center justify-center gap-4
45+ w-full h-full
46+ border-2 border-dashed border-joe-green-600 rounded-lg text-lg
47+ "
48+ >
49+ < div > Drop JSON file here</ div >
50+ < div >
51+ < Upload />
52+ </ div >
53+ </ div >
54+ </ div >
55+ </ div >
56+ ) ;
57+ } ;
Original file line number Diff line number Diff line change 99 findSmallestNode ,
1010 generateNormalizedPathNode ,
1111} from "@/lib/normalized-path" ;
12+ import { DropZone } from "../drop-zone" ;
1213
1314export const JSONEditor = ( ) => {
1415 const { document, setDocument, jsonDocument } = useJSONPath ( ) ;
@@ -63,25 +64,36 @@ export const JSONEditor = () => {
6364 setDocument ( value || "" ) ;
6465 } ;
6566
67+ const handleOnDrop = ( file : File ) => {
68+ const reader = new FileReader ( ) ;
69+ reader . onload = ( event ) => {
70+ const content = event . target ?. result as string ;
71+ setDocument ( content ) ;
72+ } ;
73+ reader . readAsText ( file ) ;
74+ } ;
75+
6676 return (
67- < Editor
68- className = { cn ( "border-2" , jsonDocument . error && "border-red-400" ) }
69- height = "600px"
70- path = "json"
71- defaultLanguage = "json"
72- value = { document }
73- loading = "Loading..."
74- onMount = { handleEditorDidMount }
75- onChange = { handleOnChange }
76- options = { {
77- wordWrap : "on" ,
78- minimap : {
79- enabled : false ,
80- } ,
81- scrollBeyondLastLine : false ,
82- formatOnPaste : true ,
83- formatOnType : true ,
84- } }
85- />
77+ < DropZone onDrop = { handleOnDrop } >
78+ < Editor
79+ className = { cn ( "border-2" , jsonDocument . error && "border-red-400" ) }
80+ height = "600px"
81+ path = "json"
82+ defaultLanguage = "json"
83+ value = { document }
84+ loading = "Loading..."
85+ onMount = { handleEditorDidMount }
86+ onChange = { handleOnChange }
87+ options = { {
88+ wordWrap : "on" ,
89+ minimap : {
90+ enabled : false ,
91+ } ,
92+ scrollBeyondLastLine : false ,
93+ formatOnPaste : true ,
94+ formatOnType : true ,
95+ } }
96+ />
97+ </ DropZone >
8698 ) ;
8799} ;
Original file line number Diff line number Diff line change 1+ import { useRef } from "react" ;
2+ import { Button } from "./ui/button" ;
3+ import { useJSONPath } from "@/hooks/use-jsonpath" ;
4+
5+ export const ImportFile = ( ) => {
6+ const { setDocument } = useJSONPath ( ) ;
7+ const inputRef = useRef < HTMLInputElement > ( null ) ;
8+
9+ const handleOnClick = ( ) => {
10+ inputRef . current ?. click ( ) ;
11+ } ;
12+
13+ const handleOnInput = ( event : React . ChangeEvent < HTMLInputElement > ) => {
14+ const file = event . target . files ?. [ 0 ] ;
15+ if ( file ) {
16+ const reader = new FileReader ( ) ;
17+ reader . onload = ( event ) => {
18+ const content = event . target ?. result as string ;
19+ setDocument ( content ) ;
20+ } ;
21+ reader . readAsText ( file ) ;
22+ }
23+ } ;
24+
25+ return (
26+ < div >
27+ < Button variant = "outline" onClick = { handleOnClick } >
28+ Import File
29+ </ Button >
30+ < input
31+ ref = { inputRef }
32+ className = "hidden"
33+ type = "file"
34+ onInput = { handleOnInput }
35+ accept = "
36+ application/jsonjson,
37+ .jsonl,
38+ .ndjson,
39+ .geojson,
40+ .topojson,
41+ .jwt,
42+ .webmanifest,
43+ .har,
44+ .mcstructure,
45+ .eslintrc,
46+ .prettierrc,
47+ .babelrc,
48+ .code-snippets,
49+ .ipynb,
50+ .vg,
51+ .vl,
52+ .template,
53+ application/json,
54+ application/geo+json,
55+ application/x-ndjson,
56+ application/jsonlines,
57+ application/schema+json,
58+ application/jwt,
59+ application/feed+json,
60+ application/vnd.oai.openapi+json,
61+ application/vnd.swagger+json,
62+ application/manifest+json,
63+ application/x-ipynb+json,
64+ "
65+ > </ input >
66+ </ div >
67+ ) ;
68+ } ;
Original file line number Diff line number Diff line change @@ -4,6 +4,7 @@ import { Result } from "./editor/result";
44import { OutputPathSwitch } from "./output-path-switch" ;
55import { useJSONPath } from "@/hooks/use-jsonpath" ;
66import { DownloadButton } from "./download-button" ;
7+ import { ImportFile } from "./import-file" ;
78
89export const JSONPathOnlineEvaluator = ( ) => {
910 const { outputPaths, setOutputPaths } = useJSONPath ( ) ;
@@ -16,6 +17,7 @@ export const JSONPathOnlineEvaluator = () => {
1617 < div >
1718 < div className = "flex justify-between items-center mb-1" >
1819 < h2 className = "py-1 text-xl text-joe-green-950" > Document</ h2 >
20+ < ImportFile />
1921 </ div >
2022 < JSONEditor />
2123 </ div >
You can’t perform that action at this time.
0 commit comments