Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: copy path button #181

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
feat: basic CopyPath component
  • Loading branch information
CrudeCreations committed Apr 1, 2024

Verified

This commit was signed with the committer’s verified signature.
JoshuaVandaele Joshua Vandaële
commit 75d4279355ac86ce6a89dff92d1541529a2c5572
34 changes: 34 additions & 0 deletions app/components/CopyPathButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { ClipboardIcon } from "@heroicons/react/outline";
import { useCallback, useState } from "react";
import { CopyText } from "./CopyText";
import { Body } from "./Primitives/Body";
import { PathComponent } from '@jsonhero/path'
import { get_path_value, languages } from "~/utilities/programmingLanguages";

export type CopyPathButtonProps = {
heroPathComponents: PathComponent[];
className?: string;
};

export function CopyPathButton({ heroPathComponents, className }: CopyPathButtonProps) {
const [copied, setCopied] = useState(false);
const [language, setLanguage] = useState(languages.javascript)
const onCopied = useCallback(() => {
setCopied(true);
const timeout = setTimeout(() => {
setCopied(false);
}, 1500);
}, [heroPathComponents]);
return (
<CopyText className={`${className}`} value={get_path_value(language, heroPathComponents)} onCopied={onCopied}>
{copied ? (
<Body>Copied!</Body>
) : (
<div className="flex items-center">
<ClipboardIcon className="h-4 w-4 mr-[2px]" />
<Body>Copy Path</Body>
</div>
)}
</CopyText>
);
}
30 changes: 23 additions & 7 deletions app/components/InfoHeader.tsx
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@ import { concatenated, getHierarchicalTypes } from "~/utilities/dataType";
import { formatRawValue } from "~/utilities/formatter";
import { isNullable } from "~/utilities/nullable";
import { CopyTextButton } from "./CopyTextButton";
import { CopyPathButton } from "./CopyPathButton";
import { Body } from "./Primitives/Body";
import { LargeMono } from "./Primitives/LargeMono";
import { Title } from "./Primitives/Title";
@@ -45,7 +46,8 @@ export function InfoHeader({ relatedPaths }: InfoHeaderProps) {
return isNullable(relatedPaths, json);
}, [relatedPaths, json]);

const [hovering, setHovering] = useState(false);
const [hoveringKey, setHoveringKey] = useState(false);
const [hoveringValue, setHoveringValue] = useState(false);
console.warn(selectedInfo);

const newPath = formattedSelectedInfo.replace(/^#/, "$").replace(/\//g, ".");
@@ -56,10 +58,24 @@ export function InfoHeader({ relatedPaths }: InfoHeaderProps) {

return (
<div className="mb-4 pb-4">
<div className="flex items-center">
<Title className="flex-1 mr-2 overflow-hidden overflow-ellipsis break-words text-slate-700 transition dark:text-slate-200">
<div
className="flex items-center"
onMouseEnter={() => setHoveringKey(true)}
onMouseLeave={() => setHoveringKey(false)}
>
<Title className={`flex-1 mr-2 overflow-hidden overflow-ellipsis break-words text-slate-700 transition dark:text-slate-200 ${
hoveringKey ? "bg-slate-100 dark:bg-slate-700" : "bg-transparent"
}`}>
{ selectedName ?? "nothing" }
</Title>
<div className={`flex justify-end h-full w-fit transition ${
hoveringKey ? "opacity-100" : "opacity-0"
}`}>
<CopyPathButton
className="bg-slate-200 hover:bg-slate-300 h-fit mr-1 px-2 py-0.5 rounded-sm transition hover:cursor-pointer dark:text-white dark:bg-slate-600 dark:hover:bg-slate-500"
heroPathComponents={selectedHeroPath.components}
/>
</div>
<div>
<ValueIcon
monochrome
@@ -70,13 +86,13 @@ export function InfoHeader({ relatedPaths }: InfoHeaderProps) {
</div>
<div
className="relative w-full h-full"
onMouseEnter={() => setHovering(true)}
onMouseLeave={() => setHovering(false)}
onMouseEnter={() => setHoveringValue(true)}
onMouseLeave={() => setHoveringValue(false)}
>
{isSelectedLeafNode && (
<LargeMono
className={`z-10 py-1 mb-1 text-slate-800 overflow-ellipsis break-words transition rounded-sm dark:text-slate-300 ${
hovering ? "bg-slate-100 dark:bg-slate-700" : "bg-transparent"
hoveringValue ? "bg-slate-100 dark:bg-slate-700" : "bg-transparent"
}`}
>
{selectedNode.name === "$ref" && checkPathExists(json, newPath) ? (
@@ -90,7 +106,7 @@ export function InfoHeader({ relatedPaths }: InfoHeaderProps) {
)}
<div
className={`absolute top-1 right-0 flex justify-end h-full w-fit transition ${
hovering ? "opacity-100" : "opacity-0"
hoveringValue ? "opacity-100" : "opacity-0"
}`}
>
<CopyTextButton
16 changes: 16 additions & 0 deletions app/utilities/programmingLanguages.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { PathComponent } from "@jsonhero/path"

export const enum languages {
javascript = "javascript",
python = "python"
}

export const get_path_value = (language: languages, paths: PathComponent[]): string => {
switch(language) {
case languages.python:
return paths.slice(1).map(p => p.isArray ? `[${p.toString()}]` : `["${p.toString()}"]`).join("")
case languages.javascript:
default:
return paths.slice(1).map(p => p.isArray ? `[${p.toString()}]` : `.${p.toString()}`).join("")
}
}