Created
September 22, 2025 04:50
-
-
Save Jaid/84cfa97744dbd8a816d6102e816a3973 to your computer and use it in GitHub Desktop.
Revisions
-
Jaid created this gist
Sep 22, 2025 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,174 @@ import type { OnMount } from "@monaco-editor/react"; import type { FileRejection } from "react-dropzone"; import Editor from "@monaco-editor/react"; import React, { useCallback, useRef, useState } from "react"; import { useDropzone } from "react-dropzone"; import { useHotkeys } from "react-hotkeys-hook"; import * as YAML from "yaml"; interface YamlEditorProps { black: boolean; initialValue: string; onDataChange: (data: any) => void; useGlobalHotkeys?: boolean; } const YamlEditor: React.FC<YamlEditorProps> = (props) => { const editorRef = useRef<any>(null); const [code, setCode] = useState(props.initialValue); const handleEditorDidMount: OnMount = (editor, monaco) => { editorRef.current = editor; if (props.black) { monaco.editor.defineTheme(`custom`, { base: `vs-dark`, inherit: true, rules: [], colors: { "editor.background": `#000000`, }, }); monaco.editor.setTheme(`custom`); } editor.addAction({ id: `copy-as-json`, label: `Copy as JSON`, contextMenuGroupId: `navigation`, contextMenuOrder: 1.5, run: (ed) => { const val = ed.getValue(); try { const parsed = YAML.parse(val); const jsonStr = JSON.stringify(parsed, null, 2); navigator.clipboard .writeText(jsonStr) .then(() => { console.log(`Copied as JSON`); }) .catch((error) => { console.error(`Failed to copy: `, error); }); } catch (error) { console.error(`Invalid YAML: `, error); alert(`Invalid YAML, cannot copy as JSON`); } }, }); }; const updateContent = (newCode: string) => { setCode(newCode); try { const parsedData = YAML.parse(newCode); if (Array.isArray(parsedData)) { props.onDataChange(parsedData); } } catch (error) { console.error(`Invalid YAML:`, error); } }; const onDrop = useCallback( async ( acceptedFiles: Array<File>, fileRejections: Array<FileRejection> ) => { if (fileRejections.length > 0) { console.error(`File rejected:`, fileRejections); return; } const file = acceptedFiles[0]; try { const text = await file.text(); let yamlText = text; if (file.name.endsWith(`.json`)) { const jsonData = JSON.parse(text); yamlText = YAML.stringify(jsonData); } else if (file.name.endsWith(`.jsonl`)) { const lines = text.trim().split(`\n`); const jsonData = lines.map((line) => JSON.parse(line)); yamlText = YAML.stringify(jsonData); } updateContent(yamlText); } catch (error) { console.error(`Error processing dropped file:`, error); } }, [] ); const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop, noClick: true, noKeyboard: true, multiple: false, accept: { "text/yaml": [`.yaml`, `.yml`], "application/json": [`.json`], "application/jsonl": [`.jsonl`], }, }); if (props.useGlobalHotkeys) { useHotkeys( `e`, (e) => { e.preventDefault(); editorRef.current?.focus(); }, { enableOnFormTags: true } ); } return ( <div {...getRootProps()} style={{ position: `relative`, height: `100%`, width: `100%`, }} > <input {...getInputProps()} /> {isDragActive && ( <div style={{ position: `absolute`, top: 0, left: 0, right: 0, bottom: 0, background: `rgba(20, 20, 20, 0.85)`, display: `flex`, alignItems: `center`, justifyContent: `center`, zIndex: 10, border: `2px dashed #555`, borderRadius: `8px`, color: `#ccc`, fontSize: `1.2rem`, pointerEvents: `none`, }} > Drop YAML, JSON, or JSONL file here </div> )} <Editor defaultLanguage="yaml" value={code} onMount={handleEditorDidMount} onChange={(value) => updateContent(value ?? ``)} theme="vs-dark" options={{ minimap: { enabled: false }, stickyScroll: { enabled: false }, lineNumbers: `off`, fontFamily: `JetBrainsMono NF, monospace`, tabSize: 2, dragAndDrop: false, accessibilitySupport: `off`, guides: { indentation: false }, lineHeight: 1.3, renderWhitespace: `trailing`, wordWrap: `on`, }} /> </div> ); }; export default YamlEditor;