mirror of
https://github.com/ershisan99/DevToysWeb.git
synced 2025-12-16 12:32:48 +00:00
feat: implement text diff tool
This commit is contained in:
@@ -1,10 +1,11 @@
|
|||||||
|
import { PropsWithChildren } from "react";
|
||||||
import { Metadata } from "next";
|
import { Metadata } from "next";
|
||||||
|
|
||||||
import { toolGroups } from "@/config/tools";
|
import { toolGroups } from "@/config/tools";
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: toolGroups.text.tools.inspector_and_case_converter.longTitle,
|
title: toolGroups.text.tools.diff.longTitle,
|
||||||
description: toolGroups.text.tools.inspector_and_case_converter.description,
|
description: toolGroups.text.tools.diff.description,
|
||||||
robots: {
|
robots: {
|
||||||
googleBot: {
|
googleBot: {
|
||||||
index: true,
|
index: true,
|
||||||
@@ -12,6 +13,6 @@ export const metadata: Metadata = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function Layout({ children }: { children: React.ReactNode }) {
|
export default function Layout({ children }: PropsWithChildren) {
|
||||||
return children;
|
return children;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,16 +5,13 @@ import { Panel, PanelGroup } from "react-resizable-panels";
|
|||||||
|
|
||||||
import { PERSISTENCE_KEY } from "@/config/persistence-keys";
|
import { PERSISTENCE_KEY } from "@/config/persistence-keys";
|
||||||
import { toolGroups } from "@/config/tools";
|
import { toolGroups } from "@/config/tools";
|
||||||
import { cn } from "@/lib/style";
|
|
||||||
import { DiffEditor } from "@/components/ui/diff-editor";
|
import { DiffEditor } from "@/components/ui/diff-editor";
|
||||||
import { Editor } from "@/components/ui/editor";
|
import { Editor } from "@/components/ui/editor";
|
||||||
import * as Button from "@/components/buttons";
|
import * as Button from "@/components/buttons";
|
||||||
import { Configuration } from "@/components/configuration";
|
import { Configuration } from "@/components/configuration";
|
||||||
import { Configurations } from "@/components/configurations";
|
import { Configurations } from "@/components/configurations";
|
||||||
import { ControlMenu } from "@/components/control-menu";
|
import { ControlMenu } from "@/components/control-menu";
|
||||||
import * as Icon from "@/components/icons";
|
|
||||||
import * as icons from "@/components/icons";
|
import * as icons from "@/components/icons";
|
||||||
import { Rows } from "@/components/icons";
|
|
||||||
import { LabeledSwitch } from "@/components/labeled-switch";
|
import { LabeledSwitch } from "@/components/labeled-switch";
|
||||||
import { PageRootSection } from "@/components/page-root-section";
|
import { PageRootSection } from "@/components/page-root-section";
|
||||||
import { PageSection } from "@/components/page-section";
|
import { PageSection } from "@/components/page-section";
|
||||||
@@ -69,6 +66,7 @@ export default function Page() {
|
|||||||
),
|
),
|
||||||
[setInput1, clearInput1]
|
[setInput1, clearInput1]
|
||||||
);
|
);
|
||||||
|
|
||||||
const input2Control = useMemo(
|
const input2Control = useMemo(
|
||||||
() => (
|
() => (
|
||||||
<ControlMenu
|
<ControlMenu
|
||||||
@@ -93,16 +91,15 @@ export default function Page() {
|
|||||||
[diffFullHeight, toggleFullHeight]
|
[diffFullHeight, toggleFullHeight]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const hiddenInFullHeightMode = useMemo(() => (diffFullHeight ? "hidden" : ""), [diffFullHeight]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageRootSection
|
<PageRootSection className="h-full" title={toolGroups.text.tools.diff.longTitle}>
|
||||||
className="h-full"
|
<PageSection title="Configuration" className={hiddenInFullHeightMode}>
|
||||||
title={toolGroups.text.tools.inspector_and_case_converter.longTitle}
|
|
||||||
>
|
|
||||||
<PageSection title="Configuration" className={cn(diffFullHeight && "hidden")}>
|
|
||||||
<Configurations list={[inlineModeConfig]} />
|
<Configurations list={[inlineModeConfig]} />
|
||||||
</PageSection>
|
</PageSection>
|
||||||
<PanelGroup direction="vertical" autoSaveId={PERSISTENCE_KEY.panels.textDiff.vertical}>
|
<PanelGroup direction="vertical" autoSaveId={PERSISTENCE_KEY.panels.textDiff.vertical}>
|
||||||
<Panel maxSize={VERTICAL_PANEL_MAX_SIZE} className={cn(diffFullHeight && "hidden")}>
|
<Panel maxSize={VERTICAL_PANEL_MAX_SIZE} className={hiddenInFullHeightMode}>
|
||||||
<PanelGroup
|
<PanelGroup
|
||||||
direction="horizontal"
|
direction="horizontal"
|
||||||
autoSaveId={PERSISTENCE_KEY.panels.textDiff.horizontal}
|
autoSaveId={PERSISTENCE_KEY.panels.textDiff.horizontal}
|
||||||
@@ -121,7 +118,7 @@ export default function Page() {
|
|||||||
</Panel>
|
</Panel>
|
||||||
</PanelGroup>
|
</PanelGroup>
|
||||||
</Panel>
|
</Panel>
|
||||||
<PanelResizeHandle direction="horizontal" className={cn(diffFullHeight && "hidden")} />
|
<PanelResizeHandle direction="horizontal" className={hiddenInFullHeightMode} />
|
||||||
<Panel maxSize={diffPanelMaxSize}>
|
<Panel maxSize={diffPanelMaxSize}>
|
||||||
<PageSection className="h-full" title="Difference" control={diffControl}>
|
<PageSection className="h-full" title="Difference" control={diffControl}>
|
||||||
<DiffEditor
|
<DiffEditor
|
||||||
|
|||||||
30
components/ui/diff-editor.tsx
Normal file
30
components/ui/diff-editor.tsx
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { ComponentPropsWithoutRef, forwardRef } from "react";
|
||||||
|
import { DiffEditor as MonacoDiffEditor } from "@monaco-editor/react";
|
||||||
|
import { useTheme } from "next-themes";
|
||||||
|
|
||||||
|
export type EditorProps = ComponentPropsWithoutRef<typeof MonacoDiffEditor>;
|
||||||
|
|
||||||
|
export const DiffEditor = forwardRef<HTMLTextAreaElement, EditorProps>(
|
||||||
|
({ options, theme, ...props }, ref) => {
|
||||||
|
const { theme: appTheme } = useTheme();
|
||||||
|
const themeToUse = theme ?? (appTheme === "light" ? "light" : "vs-dark");
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MonacoDiffEditor
|
||||||
|
{...{ ref }}
|
||||||
|
theme={themeToUse}
|
||||||
|
options={{
|
||||||
|
tabFocusMode: true,
|
||||||
|
automaticLayout: true,
|
||||||
|
scrollBeyondLastLine: false,
|
||||||
|
...options, // NOTE: merge shallowly
|
||||||
|
}}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
DiffEditor.displayName = "Editor";
|
||||||
@@ -139,10 +139,10 @@ export const toolGroups = {
|
|||||||
},
|
},
|
||||||
diff: {
|
diff: {
|
||||||
Icon: icons.Diff,
|
Icon: icons.Diff,
|
||||||
shortTitle: "Text diff",
|
shortTitle: "Text Diff",
|
||||||
longTitle: "Text Inspector & Case Converter",
|
longTitle: "Text Comparer",
|
||||||
description: "Analyze text and convert it to a different case",
|
description: "Compare two texts and highlight the differences",
|
||||||
keywords: "case converter convert text inspector inspect",
|
keywords: "text comparer compare diff highlight",
|
||||||
href: "/text/diff",
|
href: "/text/diff",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user