From 7bdebf4c935ce81aa4f93aca4e5a4f232c363b8e Mon Sep 17 00:00:00 2001 From: James Ritchie Date: Thu, 1 May 2025 13:26:59 +0100 Subject: [PATCH 1/4] Code blocks have an optional text-wrap button --- .../app/assets/icons/TextInlineIcon.tsx | 41 ++++++++ apps/webapp/app/assets/icons/TextWrapIcon.tsx | 34 +++++++ apps/webapp/app/components/code/CodeBlock.tsx | 96 +++++++++++++------ 3 files changed, 140 insertions(+), 31 deletions(-) create mode 100644 apps/webapp/app/assets/icons/TextInlineIcon.tsx create mode 100644 apps/webapp/app/assets/icons/TextWrapIcon.tsx diff --git a/apps/webapp/app/assets/icons/TextInlineIcon.tsx b/apps/webapp/app/assets/icons/TextInlineIcon.tsx new file mode 100644 index 0000000000..538d9768d0 --- /dev/null +++ b/apps/webapp/app/assets/icons/TextInlineIcon.tsx @@ -0,0 +1,41 @@ +export function TextInlineIcon({ className }: { className?: string }) { + return ( + + + + + + + + ); +} diff --git a/apps/webapp/app/assets/icons/TextWrapIcon.tsx b/apps/webapp/app/assets/icons/TextWrapIcon.tsx new file mode 100644 index 0000000000..ac37867e82 --- /dev/null +++ b/apps/webapp/app/assets/icons/TextWrapIcon.tsx @@ -0,0 +1,34 @@ +export function TextWrapIcon({ className }: { className?: string }) { + return ( + + + + + + + ); +} diff --git a/apps/webapp/app/components/code/CodeBlock.tsx b/apps/webapp/app/components/code/CodeBlock.tsx index eb133105b9..c29c81a8b0 100644 --- a/apps/webapp/app/components/code/CodeBlock.tsx +++ b/apps/webapp/app/components/code/CodeBlock.tsx @@ -3,11 +3,13 @@ import { Clipboard, ClipboardCheck } from "lucide-react"; import type { Language, PrismTheme } from "prism-react-renderer"; import { Highlight, Prism } from "prism-react-renderer"; import { forwardRef, ReactNode, useCallback, useEffect, useState } from "react"; +import { TextWrapIcon } from "~/assets/icons/TextWrapIcon"; import { cn } from "~/utils/cn"; import { Button } from "../primitives/Buttons"; import { Dialog, DialogContent, DialogHeader, DialogTitle } from "../primitives/Dialog"; import { Paragraph } from "../primitives/Paragraph"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "../primitives/Tooltip"; +import { TextInlineIcon } from "~/assets/icons/TextInlineIcon"; //This is a fork of https://github.com/mantinedev/mantine/blob/master/src/mantine-prism/src/Prism/Prism.tsx //it didn't support highlighting lines by dimming the rest of the code, or animations on the highlighting @@ -31,6 +33,9 @@ type CodeBlockProps = { /** Show copy to clipboard button */ showCopyButton?: boolean; + /** Show text wrapping button */ + showTextWrapping?: boolean; + /** Display line numbers */ showLineNumbers?: boolean; @@ -183,6 +188,7 @@ export const CodeBlock = forwardRef( ( { showCopyButton = true, + showTextWrapping = true, showLineNumbers = true, showOpenInModal = true, highlightedRanges, @@ -202,6 +208,7 @@ export const CodeBlock = forwardRef( const [copied, setCopied] = useState(false); const [modalCopied, setModalCopied] = useState(false); const [isModalOpen, setIsModalOpen] = useState(false); + const [isWrapped, setIsWrapped] = useState(false); const onCopied = useCallback( (event: React.MouseEvent) => { @@ -263,6 +270,25 @@ export const CodeBlock = forwardRef( showChrome ? "right-1.5 top-1.5" : "top-2.5" )} > + {showTextWrapping && ( + + + setIsWrapped(!isWrapped)} + className="transition-colors focus-custom hover:cursor-pointer hover:text-text-bright" + > + {isWrapped ? ( + + ) : ( + + )} + + + {isWrapped ? "Inline text" : "Wrap text"} + + + + )} {showCopyButton && ( @@ -311,16 +337,27 @@ export const CodeBlock = forwardRef( maxLineWidth={maxLineWidth} className="px-2 py-3" preClassName="text-xs" + isWrapped={isWrapped} /> ) : (
-
+              
                 {code}
               
@@ -355,6 +392,7 @@ export const CodeBlock = forwardRef( maxLineWidth={maxLineWidth} className="min-h-full" preClassName="text-sm" + isWrapped={isWrapped} /> ) : (
{ - // This ensures the language definitions are loaded Promise.all([ //@ts-ignore import("prismjs/components/prism-json"), @@ -434,16 +473,23 @@ function HighlightCode({ ]).then(() => setIsLoaded(true)); }, []); + const containerClasses = cn( + "px-3 py-3 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600", + !isWrapped && "overflow-x-auto", + isWrapped && "overflow-y-auto", + className + ); + + const preClasses = cn( + "relative mr-2 font-mono leading-relaxed", + preClassName, + isWrapped && "[&_span]:whitespace-pre-wrap [&_span]:break-all" + ); + if (!isLoaded) { return ( -
-
{code}
+
+
{code}
); } @@ -457,22 +503,8 @@ function HighlightCode({ getLineProps, getTokenProps, }) => ( -
-
+        
+
             {tokens
               .map((line, index) => {
                 if (index === tokens.length - 1 && line.length === 1 && line[0].content === "\n") {
@@ -495,7 +527,8 @@ function HighlightCode({
                     {...lineProps}
                     className={cn(
                       "flex w-full justify-start transition-opacity duration-500",
-                      lineProps.className
+                      lineProps.className,
+                      isWrapped && "flex-wrap"
                     )}
                     style={{
                       opacity: shouldDim ? dimAmount : undefined,
@@ -504,9 +537,10 @@ function HighlightCode({
                   >
                     {showLineNumbers && (
                       
Date: Thu, 1 May 2025 13:43:59 +0100 Subject: [PATCH 2/4] =?UTF-8?q?Wrap=20=E2=80=9Cwords=E2=80=9D,=20not=20?= =?UTF-8?q?=E2=80=9Call=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/webapp/app/components/code/CodeBlock.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/webapp/app/components/code/CodeBlock.tsx b/apps/webapp/app/components/code/CodeBlock.tsx index c29c81a8b0..0e1085df07 100644 --- a/apps/webapp/app/components/code/CodeBlock.tsx +++ b/apps/webapp/app/components/code/CodeBlock.tsx @@ -354,7 +354,7 @@ export const CodeBlock = forwardRef(
@@ -483,7 +483,7 @@ function HighlightCode({
   const preClasses = cn(
     "relative mr-2 font-mono leading-relaxed",
     preClassName,
-    isWrapped && "[&_span]:whitespace-pre-wrap [&_span]:break-all"
+    isWrapped && "[&_span]:whitespace-pre-wrap [&_span]:break-words"
   );
 
   if (!isLoaded) {

From 9eef0a26608238aaf580f65b1909af66fe5f2395 Mon Sep 17 00:00:00 2001
From: James Ritchie 
Date: Thu, 1 May 2025 14:03:04 +0100
Subject: [PATCH 3/4] wrapping is default false

---
 apps/webapp/app/components/code/CodeBlock.tsx        | 2 +-
 apps/webapp/app/components/runs/v3/PacketDisplay.tsx | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/apps/webapp/app/components/code/CodeBlock.tsx b/apps/webapp/app/components/code/CodeBlock.tsx
index 0e1085df07..171127dee4 100644
--- a/apps/webapp/app/components/code/CodeBlock.tsx
+++ b/apps/webapp/app/components/code/CodeBlock.tsx
@@ -188,7 +188,7 @@ export const CodeBlock = forwardRef(
   (
     {
       showCopyButton = true,
-      showTextWrapping = true,
+      showTextWrapping = false,
       showLineNumbers = true,
       showOpenInModal = true,
       highlightedRanges,
diff --git a/apps/webapp/app/components/runs/v3/PacketDisplay.tsx b/apps/webapp/app/components/runs/v3/PacketDisplay.tsx
index 430402c89e..4da733f2c0 100644
--- a/apps/webapp/app/components/runs/v3/PacketDisplay.tsx
+++ b/apps/webapp/app/components/runs/v3/PacketDisplay.tsx
@@ -44,6 +44,7 @@ export function PacketDisplay({
           code={data}
           maxLines={20}
           showLineNumbers={false}
+          showTextWrapping
         />
       );
     }

From 3012de8c8d3aafa58802093047343ae7dd1dce0e Mon Sep 17 00:00:00 2001
From: James Ritchie 
Date: Thu, 1 May 2025 17:05:32 +0100
Subject: [PATCH 4/4] Change the wording in the tooltip

---
 apps/webapp/app/components/code/CodeBlock.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/apps/webapp/app/components/code/CodeBlock.tsx b/apps/webapp/app/components/code/CodeBlock.tsx
index 171127dee4..ca6200a18b 100644
--- a/apps/webapp/app/components/code/CodeBlock.tsx
+++ b/apps/webapp/app/components/code/CodeBlock.tsx
@@ -284,7 +284,7 @@ export const CodeBlock = forwardRef(
                     )}
                   
                   
-                    {isWrapped ? "Inline text" : "Wrap text"}
+                    {isWrapped ? "Unwrap" : "Wrap"}