From 75d4279355ac86ce6a89dff92d1541529a2c5572 Mon Sep 17 00:00:00 2001 From: CrudeCreations Date: Mon, 1 Apr 2024 17:41:17 +0100 Subject: [PATCH 1/7] feat: basic CopyPath component --- app/components/CopyPathButton.tsx | 34 +++++++++++++++++++++++++++ app/components/InfoHeader.tsx | 30 +++++++++++++++++------ app/utilities/programmingLanguages.ts | 16 +++++++++++++ 3 files changed, 73 insertions(+), 7 deletions(-) create mode 100644 app/components/CopyPathButton.tsx create mode 100644 app/utilities/programmingLanguages.ts diff --git a/app/components/CopyPathButton.tsx b/app/components/CopyPathButton.tsx new file mode 100644 index 000000000..bf4f6db66 --- /dev/null +++ b/app/components/CopyPathButton.tsx @@ -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 ( + + {copied ? ( + Copied! + ) : ( +
+ + Copy Path +
+ )} +
+ ); +} diff --git a/app/components/InfoHeader.tsx b/app/components/InfoHeader.tsx index d7bbebb50..80b94d393 100644 --- a/app/components/InfoHeader.tsx +++ b/app/components/InfoHeader.tsx @@ -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="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" } +
+ +
setHovering(true)} - onMouseLeave={() => setHovering(false)} + onMouseEnter={() => setHoveringValue(true)} + onMouseLeave={() => setHoveringValue(false)} > {isSelectedLeafNode && ( {selectedNode.name === "$ref" && checkPathExists(json, newPath) ? ( @@ -90,7 +106,7 @@ export function InfoHeader({ relatedPaths }: InfoHeaderProps) { )}
{ + 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("") + } +} \ No newline at end of file From 50968ceb09a5812d63449c6ce1871f1c77389b3f Mon Sep 17 00:00:00 2001 From: CrudeCreations Date: Mon, 1 Apr 2024 18:01:06 +0100 Subject: [PATCH 2/7] feat: better styling for CopyPath --- app/components/InfoHeader.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/components/InfoHeader.tsx b/app/components/InfoHeader.tsx index 80b94d393..0130b42eb 100644 --- a/app/components/InfoHeader.tsx +++ b/app/components/InfoHeader.tsx @@ -59,7 +59,7 @@ export function InfoHeader({ relatedPaths }: InfoHeaderProps) { return (
setHoveringKey(true)} onMouseLeave={() => setHoveringKey(false)} > @@ -68,7 +68,7 @@ export function InfoHeader({ relatedPaths }: InfoHeaderProps) { }`}> { selectedName ?? "nothing" } -
Date: Tue, 2 Apr 2024 23:25:49 +0100 Subject: [PATCH 3/7] feat: more options for programming langugages --- app/utilities/programmingLanguages.ts | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/app/utilities/programmingLanguages.ts b/app/utilities/programmingLanguages.ts index f7c425ad6..238b7ac35 100644 --- a/app/utilities/programmingLanguages.ts +++ b/app/utilities/programmingLanguages.ts @@ -1,16 +1,20 @@ import { PathComponent } from "@jsonhero/path" -export const enum languages { +export enum languages { javascript = "javascript", python = "python" } -export const get_path_value = (language: languages, paths: PathComponent[]): string => { +export const defaultLangauge = languages.javascript + +export const getPathValue = (language: languages, variableName: string, useOptChaining: boolean, paths: PathComponent[]): string => { + const path_base = variableName switch(language) { case languages.python: - return paths.slice(1).map(p => p.isArray ? `[${p.toString()}]` : `["${p.toString()}"]`).join("") + return `${path_base}${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("") + return `${path_base}${paths.slice(1).map(p => p.isArray ? `${useOptChaining ? "?[" : "["}${p.toString()}]` : `${useOptChaining ? "?." : "."}${p.toString()}`).join("")}` } -} \ No newline at end of file +} + From 22738c5c8c9fa69cc3a719030239ed4872d5bc98 Mon Sep 17 00:00:00 2001 From: CrudeCreations Date: Tue, 2 Apr 2024 23:26:11 +0100 Subject: [PATCH 4/7] feat: language preference --- app/components/PreferencesProvider.tsx | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/app/components/PreferencesProvider.tsx b/app/components/PreferencesProvider.tsx index 95b4148d0..a30333a78 100644 --- a/app/components/PreferencesProvider.tsx +++ b/app/components/PreferencesProvider.tsx @@ -1,16 +1,21 @@ import {createContext, Dispatch, ReactNode, SetStateAction, useContext, useEffect, useState} from 'react'; +import { languages } from '~/utilities/programmingLanguages'; interface Preferences { indent: number; + language: languages; } const PreferencesDefaults: Preferences = { indent: 2, + language: languages.javascript }; +type PartialPreferences = Partial; + type PreferencesContextType = [ - Preferences | undefined, - Dispatch> + PartialPreferences, + Dispatch> ]; const PreferencesContext = createContext(undefined); @@ -30,7 +35,7 @@ export function PreferencesProvider({ }: { children: ReactNode; }) { - const [preferences, setPreferences] = useState(); + const [preferences, setPreferences] = useState(PreferencesDefaults); useEffect(() => { const preferences = loadPreferences(); @@ -39,7 +44,7 @@ export function PreferencesProvider({ useEffect(() => { if (preferences === undefined) return; - savePreferences(preferences); + savePreferences(preferences as Preferences); }, [preferences]); return ( From 97f4bc7c37a83570eca968bef62073eb05506452 Mon Sep 17 00:00:00 2001 From: CrudeCreations Date: Tue, 2 Apr 2024 23:26:27 +0100 Subject: [PATCH 5/7] feat: copypathpreferences --- app/components/CopyPathButton.tsx | 48 +++++++++++++++++-- app/components/CopyPathPreferences.tsx | 64 ++++++++++++++++++++++++++ 2 files changed, 108 insertions(+), 4 deletions(-) create mode 100644 app/components/CopyPathPreferences.tsx diff --git a/app/components/CopyPathButton.tsx b/app/components/CopyPathButton.tsx index bf4f6db66..57950c5b7 100644 --- a/app/components/CopyPathButton.tsx +++ b/app/components/CopyPathButton.tsx @@ -1,9 +1,13 @@ -import { ClipboardIcon } from "@heroicons/react/outline"; +import { ClipboardIcon, CogIcon } from "@heroicons/react/outline"; import { useCallback, useState } from "react"; import { CopyText } from "./CopyText"; import { Body } from "./Primitives/Body"; +import { Dialog, DialogTrigger, DialogContent } from "./UI/Dialog"; import { PathComponent } from '@jsonhero/path' -import { get_path_value, languages } from "~/utilities/programmingLanguages"; +import { getPathValue, languages } from "~/utilities/programmingLanguages"; +import classnames from "~/utilities/classnames"; +import { CopyPathPreferences } from "./CopyPathPreferences"; +import { usePreferences } from "./PreferencesProvider"; export type CopyPathButtonProps = { heroPathComponents: PathComponent[]; @@ -12,7 +16,11 @@ export type CopyPathButtonProps = { export function CopyPathButton({ heroPathComponents, className }: CopyPathButtonProps) { const [copied, setCopied] = useState(false); - const [language, setLanguage] = useState(languages.javascript) + const [settingsOpen, setSettingsOpen] = useState(false) + const [preferences] = usePreferences() + const [variableName, setVariableName] = useState(""); + const [useOptChaining, setUseOptionalChaining] = useState(false); + const onCopied = useCallback(() => { setCopied(true); const timeout = setTimeout(() => { @@ -20,7 +28,8 @@ export function CopyPathButton({ heroPathComponents, className }: CopyPathButton }, 1500); }, [heroPathComponents]); return ( - + <> + {copied ? ( Copied! ) : ( @@ -30,5 +39,36 @@ export function CopyPathButton({ heroPathComponents, className }: CopyPathButton
)} + + setSettingsOpen(true)} + > +
+
+ +   +
+
+
+ setSettingsOpen(false)} + className={classnames( + "fixed z-50", + "w-[95vw] max-w-2xl rounded-lg", + "top-0 left-[50%] -translate-x-[50%]", + "mt-[60px]", + "bg-white border-[1px] border-slate-500 dark:border-slate-700 dark:bg-slate-800" + )} + > + + +
+ ); } diff --git a/app/components/CopyPathPreferences.tsx b/app/components/CopyPathPreferences.tsx new file mode 100644 index 000000000..368fc5779 --- /dev/null +++ b/app/components/CopyPathPreferences.tsx @@ -0,0 +1,64 @@ +import { languages } from "~/utilities/programmingLanguages" +import { usePreferences } from "./PreferencesProvider" +import { Body } from "./Primitives/Body"; +import { useState } from "react"; + +export type CopyPathPreferencesProps = { + variableName: string; + onVariableNameChange: (value: string) => void; + useOptChaining: boolean; + onUseOptionalChainingChange: (value: boolean) => void; +} + +export function CopyPathPreferences({variableName, onVariableNameChange, useOptChaining, onUseOptionalChainingChange}: CopyPathPreferencesProps) { + const [preferences, setPreferences] = usePreferences(); + + return ( +
+
+ + +
+
+ + onVariableNameChange(e.target.value)} + /> +
+
+ + onUseOptionalChainingChange(e.target.checked)} + /> +
+
) +} \ No newline at end of file From 3f826b7281b54c5fc393558c85061dedc6bd8d50 Mon Sep 17 00:00:00 2001 From: CrudeCreations Date: Sun, 7 Apr 2024 17:16:45 +0100 Subject: [PATCH 6/7] feat: preference styling and canUseOptionalChaining --- app/components/CopyPathPreferences.tsx | 85 ++++++++++++++------------ app/utilities/programmingLanguages.ts | 5 ++ 2 files changed, 50 insertions(+), 40 deletions(-) diff --git a/app/components/CopyPathPreferences.tsx b/app/components/CopyPathPreferences.tsx index 368fc5779..18e376d7a 100644 --- a/app/components/CopyPathPreferences.tsx +++ b/app/components/CopyPathPreferences.tsx @@ -1,64 +1,69 @@ -import { languages } from "~/utilities/programmingLanguages" +import { languages, canUseOptChaining } from "~/utilities/programmingLanguages" import { usePreferences } from "./PreferencesProvider" -import { Body } from "./Primitives/Body"; -import { useState } from "react"; export type CopyPathPreferencesProps = { - variableName: string; - onVariableNameChange: (value: string) => void; - useOptChaining: boolean; - onUseOptionalChainingChange: (value: boolean) => void; + variableName: string + onVariableNameChange: (value: string) => void + useOptChaining: boolean + onUseOptionalChainingChange: (value: boolean) => void } -export function CopyPathPreferences({variableName, onVariableNameChange, useOptChaining, onUseOptionalChainingChange}: CopyPathPreferencesProps) { - const [preferences, setPreferences] = usePreferences(); +export function CopyPathPreferences({ + variableName, + onVariableNameChange, + useOptChaining, + onUseOptionalChainingChange, +}: CopyPathPreferencesProps) { + const [preferences, setPreferences] = usePreferences() return ( -
-
-
+ ) +} + diff --git a/app/utilities/programmingLanguages.ts b/app/utilities/programmingLanguages.ts index 238b7ac35..d9e0de337 100644 --- a/app/utilities/programmingLanguages.ts +++ b/app/utilities/programmingLanguages.ts @@ -5,6 +5,11 @@ export enum languages { python = "python" } +export const canUseOptChaining = { + [languages.javascript]: true, + [languages.python]: false, +} + export const defaultLangauge = languages.javascript export const getPathValue = (language: languages, variableName: string, useOptChaining: boolean, paths: PathComponent[]): string => { From f00a329e4e25e0d3eb016779507c39f36fbdc499 Mon Sep 17 00:00:00 2001 From: CrudeCreations Date: Sun, 7 Apr 2024 17:20:42 +0100 Subject: [PATCH 7/7] fix: styling borked --- app/components/CopyPathPreferences.tsx | 111 +++++++++++++------------ 1 file changed, 59 insertions(+), 52 deletions(-) diff --git a/app/components/CopyPathPreferences.tsx b/app/components/CopyPathPreferences.tsx index 18e376d7a..fb303fcfe 100644 --- a/app/components/CopyPathPreferences.tsx +++ b/app/components/CopyPathPreferences.tsx @@ -1,12 +1,13 @@ -import { languages, canUseOptChaining } from "~/utilities/programmingLanguages" -import { usePreferences } from "./PreferencesProvider" +import { languages, canUseOptChaining } from "~/utilities/programmingLanguages"; +import { usePreferences } from "./PreferencesProvider"; +import { useState } from "react"; export type CopyPathPreferencesProps = { - variableName: string - onVariableNameChange: (value: string) => void - useOptChaining: boolean - onUseOptionalChainingChange: (value: boolean) => void -} + variableName: string; + onVariableNameChange: (value: string) => void; + useOptChaining: boolean; + onUseOptionalChainingChange: (value: boolean) => void; +}; export function CopyPathPreferences({ variableName, @@ -14,56 +15,62 @@ export function CopyPathPreferences({ useOptChaining, onUseOptionalChainingChange, }: CopyPathPreferencesProps) { - const [preferences, setPreferences] = usePreferences() + const [preferences, setPreferences] = usePreferences(); return (
-

Copy Path Preferences

+

+ Copy Path Preferences +

-
- - - { canUseOptChaining[preferences.language || languages.javascript] && - - } -
-
- - onVariableNameChange(e.target.value)} - /> - { canUseOptChaining[preferences.language || languages.javascript] && - onUseOptionalChainingChange(e.target.checked)} - /> + + + + onVariableNameChange(e.target.value)} + /> + {canUseOptChaining[preferences.language || languages.javascript] && ( + <> + + onUseOptionalChainingChange(e.target.checked)} + /> + + )}
- ) + ); } -