From afdc982863b6cca573f1db58e1795aa8c45fabca Mon Sep 17 00:00:00 2001 From: schererleander Date: Fri, 30 May 2025 01:01:17 +0200 Subject: rewrite site --- src/components/CodeSnippet.tsx | 94 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 src/components/CodeSnippet.tsx (limited to 'src/components/CodeSnippet.tsx') diff --git a/src/components/CodeSnippet.tsx b/src/components/CodeSnippet.tsx new file mode 100644 index 0000000..73ac1e7 --- /dev/null +++ b/src/components/CodeSnippet.tsx @@ -0,0 +1,94 @@ +import React, { useState, useMemo, useCallback } from 'react'; + +interface CodeSnippetProps { + code: string; + initialLines?: number; +} + +const ExpandIcon = () => ( + + + +); + +const CollapseIcon = () => ( + + + +); + +const CopyIcon = () => ( + + + +); + +export const CodeSnippet: React.FC = React.memo( + ({ code, initialLines = 5 }) => { + const [expanded, setExpanded] = useState(false); + const [copied, setCopied] = useState(false); + + const lines = useMemo(() => code.split('\n'), [code]); + const shouldTruncate = useMemo( + () => lines.length > initialLines, + [lines.length, initialLines] + ); + const displayedLines = useMemo( + () => (expanded || !shouldTruncate ? lines : lines.slice(0, initialLines)), + [expanded, shouldTruncate, lines, initialLines] + ); + + const toggleExpanded = useCallback( + () => setExpanded(prev => !prev), + [] + ); + + const handleCopy = useCallback(() => { + navigator.clipboard.writeText(code) + .then(() => { + setCopied(true); + setTimeout(() => setCopied(false), 2000); + }) + .catch(() => {}); + }, [code]); + + return ( +
+ {shouldTruncate && ( +
+ + +
+ )} + +
+          {displayedLines.map((line, idx) => (
+            
+ + {idx + 1} + + {line} +
+ ))} + {shouldTruncate && !expanded && ( +
...
+ )} +
+
+ ); + } +); + +export default CodeSnippet; \ No newline at end of file -- cgit v1.3.1