Преглед изворни кода

feat: refactor CodeBlock to use LightweightCodeBlock component for improved styling

Yuki Takei пре 1 месец
родитељ
комит
1834f13bfd

+ 11 - 56
apps/app/src/components/ReactMarkdownComponents/CodeBlock.tsx

@@ -1,41 +1,9 @@
-import type { ComponentType, CSSProperties, JSX, ReactNode } from 'react';
+import type { ComponentType, JSX, ReactNode } from 'react';
 import { startTransition, useEffect, useState } from 'react';
 
-import styles from './CodeBlock.module.scss';
-
-// Hardcoded container styles from the oneDark Prism theme.
-// fontFamily is intentionally omitted so the page's default monospace font is used.
-const preStyle: CSSProperties = {
-  background: 'hsl(220, 13%, 18%)',
-  color: 'hsl(220, 14%, 71%)',
-  textShadow: '0 1px rgba(0, 0, 0, 0.3)',
-  direction: 'ltr',
-  textAlign: 'left',
-  whiteSpace: 'pre',
-  wordSpacing: 'normal',
-  wordBreak: 'normal',
-  lineHeight: '1.5',
-  tabSize: 2,
-  hyphens: 'none',
-  padding: '1em',
-  margin: '0.5em 0',
-  overflow: 'auto',
-  borderRadius: '0.3em',
-};
+import { LightweightCodeBlock } from './LightweightCodeBlock';
 
-const codeStyle: CSSProperties = {
-  background: 'hsl(220, 13%, 18%)',
-  color: 'hsl(220, 14%, 71%)',
-  textShadow: '0 1px rgba(0, 0, 0, 0.3)',
-  direction: 'ltr',
-  textAlign: 'left',
-  whiteSpace: 'pre',
-  wordSpacing: 'normal',
-  wordBreak: 'normal',
-  lineHeight: '1.5',
-  tabSize: 2,
-  hyphens: 'none',
-};
+import styles from './CodeBlock.module.scss';
 
 type PrismHighlighterProps = { lang: string; children: ReactNode };
 
@@ -82,32 +50,19 @@ function extractChildrenToIgnoreReactNode(children: ReactNode): ReactNode {
       .join('');
   }
 
-  // object
+  // React element or object with nested children
   if (typeof children === 'object') {
-    const grandChildren =
-      (children as any).children ?? (children as any).props.children;
+    const childObj = children as {
+      children?: ReactNode;
+      props?: { children?: ReactNode };
+    };
+    const grandChildren = childObj.children ?? childObj.props?.children;
     return extractChildrenToIgnoreReactNode(grandChildren);
   }
 
   return String(children).replace(/\n$/, '');
 }
 
-function LightweightCodeBlock({
-  lang,
-  children,
-}: {
-  lang: string;
-  children: ReactNode;
-}): JSX.Element {
-  return (
-    <div style={preStyle}>
-      <code className={`language-${lang}`} style={codeStyle}>
-        {children}
-      </code>
-    </div>
-  );
-}
-
 function CodeBlockSubstance({
   lang,
   children,
@@ -171,8 +126,8 @@ export const CodeBlock = (props: CodeBlockProps): JSX.Element => {
   }
 
   const match = /language-(\w+)(:?.+)?/.exec(className || '');
-  const lang = match && match[1] ? match[1] : '';
-  const name = match && match[2] ? match[2].slice(1) : null;
+  const lang = match?.[1] ? match[1] : '';
+  const name = match?.[2] ? match[2].slice(1) : null;
 
   return (
     <>

+ 51 - 0
apps/app/src/components/ReactMarkdownComponents/LightweightCodeBlock.tsx

@@ -0,0 +1,51 @@
+import type { CSSProperties, JSX, ReactNode } from 'react';
+
+// Hardcoded container styles from the oneDark Prism theme.
+// fontFamily is intentionally omitted so the page's default monospace font is used.
+export const preStyle: CSSProperties = {
+  background: 'hsl(220, 13%, 18%)',
+  color: 'hsl(220, 14%, 71%)',
+  textShadow: '0 1px rgba(0, 0, 0, 0.3)',
+  direction: 'ltr',
+  textAlign: 'left',
+  whiteSpace: 'pre',
+  wordSpacing: 'normal',
+  wordBreak: 'normal',
+  lineHeight: '1.5',
+  tabSize: 2,
+  hyphens: 'none',
+  padding: '1em',
+  margin: '0.5em 0',
+  overflow: 'auto',
+  borderRadius: '0.3em',
+};
+
+export const codeStyle: CSSProperties = {
+  background: 'hsl(220, 13%, 18%)',
+  color: 'hsl(220, 14%, 71%)',
+  textShadow: '0 1px rgba(0, 0, 0, 0.3)',
+  direction: 'ltr',
+  textAlign: 'left',
+  whiteSpace: 'pre',
+  wordSpacing: 'normal',
+  wordBreak: 'normal',
+  lineHeight: '1.5',
+  tabSize: 2,
+  hyphens: 'none',
+};
+
+export const LightweightCodeBlock = ({
+  lang,
+  children,
+}: {
+  lang: string;
+  children: ReactNode;
+}): JSX.Element => {
+  return (
+    <div style={preStyle}>
+      <code className={`language-${lang}`} style={codeStyle}>
+        {children}
+      </code>
+    </div>
+  );
+};