diff --git a/src/features/json-yaml/JsonYamlPage.tsx b/src/features/json-yaml/JsonYamlPage.tsx index a057429..c574a1e 100644 --- a/src/features/json-yaml/JsonYamlPage.tsx +++ b/src/features/json-yaml/JsonYamlPage.tsx @@ -1,62 +1,172 @@ -import type { JSX } from "react"; +import type { ChangeEvent, JSX, KeyboardEvent, ReactNode, UIEvent } from "react"; import { useMemo, useState } from "react"; -import { ArrowLeftRight, Copy, RotateCcw } from "lucide-react"; +import * as DropdownMenu from "@radix-ui/react-dropdown-menu"; +import { + ArrowLeftRight, + Check, + CheckCircle2, + ChevronDown, + ChevronRight, + Code2, + Copy, + Download, + FileCode2, + FileJson2, + ListTree, + RotateCcw, + TriangleAlert, + WrapText, +} from "lucide-react"; +import { cn } from "@/shared/lib/cn"; import { Button } from "@/shared/ui/button"; import { Tooltip } from "@/shared/ui/tooltip"; +import { PaneHeader, ToolSurface, ToolToolbar } from "@/shared/components/ToolSurface"; import { - PaneHeader, - ToolOutput, - ToolSurface, - ToolTextarea, - ToolToolbar, - ToolTitle, -} from "@/shared/components/ToolSurface"; -import { convertJsonYaml, type JsonYamlDirection } from "./json-yaml.service"; + convertJsonYaml, + type JsonYamlDirection, + type JsonYamlIndent, + type JsonYamlResult, + type JsonYamlStats, +} from "./json-yaml.service"; + +type ConverterView = "text" | "tree"; +type SyntaxKind = "json" | "yaml"; + +const initialJson = `{ + "name": "Forge", + "local": true, + "tools": ["json", "yaml", "diff"], + "release": { + "channel": "developer", + "features": { + "convert": true, + "treeView": true + } + } +}`; export function JsonYamlPage(): JSX.Element { const [direction, setDirection] = useState("json-to-yaml"); - const [input, setInput] = useState( - '{"name":"Forge","category":"Developer tools","local":true}', + const [input, setInput] = useState(initialJson); + const [indent, setIndent] = useState(2); + const [view, setView] = useState("text"); + const [resultLineWrap, setResultLineWrap] = useState(true); + const result = useMemo( + () => convertJsonYaml(input, direction, indent), + [direction, indent, input], ); - const result = useMemo(() => convertJsonYaml(input, direction), [direction, input]); + const outputLineCount = result.value ? result.value.split(/\r\n|\n|\r/).length : 0; + const inputSyntax = direction === "json-to-yaml" ? "json" : "yaml"; + const outputSyntax = direction === "json-to-yaml" ? "yaml" : "json"; function swapDirection(): void { setDirection((value) => (value === "json-to-yaml" ? "yaml-to-json" : "json-to-yaml")); - setInput(result.value); + + if (result.value) { + setInput(result.value); + } } async function copyOutput(): Promise { await navigator.clipboard.writeText(result.value); } + function downloadOutput(): void { + const blob = new Blob([result.value], { + type: + direction === "json-to-yaml" + ? "application/yaml;charset=utf-8" + : "application/json;charset=utf-8", + }); + const url = URL.createObjectURL(blob); + const anchor = document.createElement("a"); + + anchor.href = url; + anchor.download = + direction === "json-to-yaml" ? "forge-data.yaml" : "forge-data.json"; + anchor.click(); + URL.revokeObjectURL(url); + } + return ( - - - +
+