New copy to clipboard shortcut feature and footer icon (#27)
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
import { useHotkeys } from "react-hotkeys-hook";
|
||||
import { useSelectedInfo } from "../hooks/useSelectedInfo";
|
||||
|
||||
export function CopySelectedNodeShortcut() {
|
||||
const selectedInfo = useSelectedInfo();
|
||||
|
||||
useHotkeys(
|
||||
'shift+c,shift+C',
|
||||
(e) => {
|
||||
e.preventDefault();
|
||||
const selectedJSON = selectedInfo?.name === "string"
|
||||
? selectedInfo?.value
|
||||
: JSON.stringify(selectedInfo?.value, null, 2);
|
||||
navigator.clipboard.writeText(selectedJSON);
|
||||
},
|
||||
[selectedInfo]
|
||||
);
|
||||
|
||||
return <></>;
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import { ArrowKeysIcon } from "./Icons/ArrowKeysIcon";
|
||||
import { CopyShortcutIcon } from "./Icons/CopyShortcutIcon";
|
||||
import { EscapeKeyIcon } from "./Icons/EscapeKeyIcon";
|
||||
import { SquareBracketsIcon } from "./Icons/SquareBracketsIcon";
|
||||
import { Body } from "./Primitives/Body";
|
||||
@@ -26,6 +27,12 @@ export function Footer() {
|
||||
Reset path
|
||||
</Body>
|
||||
</li>
|
||||
<li className="flex items-center">
|
||||
<CopyShortcutIcon className="transition text-slate-300 dark:text-slate-500" />
|
||||
<Body className="pl-2 pr-4 text-slate-800 transition dark:text-white">
|
||||
Copy selected node
|
||||
</Body>
|
||||
</li>
|
||||
</ol>
|
||||
<ThemeModeToggler />
|
||||
</footer>
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
export function CopyShortcutIcon(props: React.SVGProps<SVGSVGElement>) {
|
||||
return (
|
||||
<svg
|
||||
className={props.className}
|
||||
width="30"
|
||||
height="14"
|
||||
viewBox="0 0 30 14"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<rect width="14" height="14" rx="1.53846" fill="currentColor" />
|
||||
<rect x="16" width="14" height="14" rx="1.53846" fill="currentColor" />
|
||||
<path
|
||||
d="M5.64,10.22H8.25V7a.39.39,0,0,1,.38-.39H10l-3-3L4,6.65H5.26A.39.39,0,0,1,5.64,7v3.18Zm3,.78H5.26a.38.38,0,0,1-.39-.39V7.43H3.11a.39.39,0,0,1-.28-.66L6.72,2.86a.39.39,0,0,1,.55,0l3.88,3.91a.38.38,0,0,1-.27.66H9v3.18a.38.38,0,0,1-.39.39Z"
|
||||
stroke="#0f172a" strokeWidth="0.35px" fill="#0f172a"
|
||||
/>
|
||||
<path
|
||||
d="M23.81,9.52a1.66,1.66,0,0,0,.53-.27,1.57,1.57,0,0,0,.35-.42,1.07,1.07,0,0,0,.13-.53h1.6a2.26,2.26,0,0,1-.25,1,2.87,2.87,0,0,1-.7.85,3.35,3.35,0,0,1-1,.58,3.56,3.56,0,0,1-1.22.21,3.73,3.73,0,0,1-1.55-.31,3.2,3.2,0,0,1-1.11-.84,3.61,3.61,0,0,1-.67-1.22,4.91,4.91,0,0,1-.23-1.5V6.88a4.91,4.91,0,0,1,.23-1.5,3.54,3.54,0,0,1,.67-1.22,3.33,3.33,0,0,1,1.11-.84,3.94,3.94,0,0,1,2.83-.09,3,3,0,0,1,1,.59,2.66,2.66,0,0,1,.67.92,2.94,2.94,0,0,1,.23,1.17h-1.6a1.48,1.48,0,0,0-.45-1.07,1.65,1.65,0,0,0-.52-.33,1.75,1.75,0,0,0-.65-.12,1.59,1.59,0,0,0-1.44.78,2.27,2.27,0,0,0-.31.8,4.53,4.53,0,0,0-.09.91v.24a4.63,4.63,0,0,0,.09.92,2.46,2.46,0,0,0,.3.8,1.67,1.67,0,0,0,.56.56,1.63,1.63,0,0,0,.89.22A2.05,2.05,0,0,0,23.81,9.52Z"
|
||||
fill="#0f172a"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
} from "../hooks/useJsonColumnView";
|
||||
import { useHotkeys } from "react-hotkeys-hook";
|
||||
import { Columns } from "./Columns";
|
||||
import { CopySelectedNodeShortcut } from "./CopySelectedNode";
|
||||
|
||||
export function JsonColumnView() {
|
||||
const { getColumnViewProps, columns } = useJsonColumnViewState();
|
||||
@@ -67,5 +68,7 @@ function KeyboardShortcuts() {
|
||||
[api]
|
||||
);
|
||||
|
||||
return <></>;
|
||||
return <>
|
||||
<CopySelectedNodeShortcut />
|
||||
</>;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
} from "~/hooks/useJsonColumnView";
|
||||
import { JsonTreeViewNode, useJsonTreeViewContext } from "~/hooks/useJsonTree";
|
||||
import { VirtualNode } from "~/hooks/useVirtualTree";
|
||||
import { CopySelectedNodeShortcut } from "./CopySelectedNode";
|
||||
import { Body } from "./Primitives/Body";
|
||||
import { Mono } from "./Primitives/Mono";
|
||||
|
||||
@@ -78,31 +79,34 @@ export function JsonTreeView() {
|
||||
}, [treeRef.current]);
|
||||
|
||||
return (
|
||||
<div
|
||||
className="text-white w-full"
|
||||
ref={parentRef}
|
||||
style={{
|
||||
height: `calc(100vh - 106px)`,
|
||||
overflowY: "auto",
|
||||
overflowX: "hidden",
|
||||
}}
|
||||
>
|
||||
<>
|
||||
<CopySelectedNodeShortcut />
|
||||
<div
|
||||
className="relative w-full outline-none"
|
||||
style={{ height: `${tree.totalSize}px` }}
|
||||
{...tree.getTreeProps()}
|
||||
ref={treeRef}
|
||||
className="text-white w-full"
|
||||
ref={parentRef}
|
||||
style={{
|
||||
height: `calc(100vh - 106px)`,
|
||||
overflowY: "auto",
|
||||
overflowX: "hidden",
|
||||
}}
|
||||
>
|
||||
{tree.nodes.map((virtualNode) => (
|
||||
<TreeViewNode
|
||||
virtualNode={virtualNode}
|
||||
key={virtualNode.node.id}
|
||||
onToggle={(node, e) => tree.toggleNode(node.id, e)}
|
||||
selectedNodeId={selectedNodeId}
|
||||
/>
|
||||
))}
|
||||
<div
|
||||
className="relative w-full outline-none"
|
||||
style={{ height: `${tree.totalSize}px` }}
|
||||
{...tree.getTreeProps()}
|
||||
ref={treeRef}
|
||||
>
|
||||
{tree.nodes.map((virtualNode) => (
|
||||
<TreeViewNode
|
||||
virtualNode={virtualNode}
|
||||
key={virtualNode.node.id}
|
||||
onToggle={(node, e) => tree.toggleNode(node.id, e)}
|
||||
selectedNodeId={selectedNodeId}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user