Roo-Code/webview-ui/src/components/CodeAccordian.tsx

85 lines
2.6 KiB
TypeScript

import { memo, useMemo } from "react"
import { getLanguageFromPath } from "../utils/getLanguageFromPath"
import CodeBlock from "./CodeBlock"
interface CodeAccordianProps {
code?: string
diff?: string
language?: string | undefined
path?: string
isExpanded: boolean
onToggleExpand: () => void
}
/*
We need to remove leading non-alphanumeric characters from the path in order for our leading ellipses trick to work.
^: Anchors the match to the start of the string.
[^a-zA-Z0-9]+: Matches one or more characters that are not alphanumeric.
The replace method removes these matched characters, effectively trimming the string up to the first alphanumeric character.
*/
const removeLeadingNonAlphanumeric = (path: string): string => path.replace(/^[^a-zA-Z0-9]+/, "")
const CodeAccordian = ({ code, diff, language, path, isExpanded, onToggleExpand }: CodeAccordianProps) => {
const inferredLanguage = useMemo(
() => code && (language ?? (path ? getLanguageFromPath(path) : undefined)),
[path, language, code]
)
return (
<div
style={{
borderRadius: 3,
backgroundColor: "var(--vscode-editor-background)",
overflow: "hidden", // This ensures the inner scrollable area doesn't overflow the rounded corners
border: "1px solid var(--vscode-editorGroup-border)",
}}>
{path && (
<div
style={{
color: "var(--vscode-descriptionForeground)",
display: "flex",
justifyContent: "space-between",
alignItems: "center",
padding: "6px 10px",
cursor: "pointer",
}}
onClick={onToggleExpand}>
<span
style={{
whiteSpace: "nowrap",
overflow: "hidden",
textOverflow: "ellipsis",
marginRight: "8px",
fontSize: "11px",
// trick to get ellipsis at beginning of string
direction: "rtl",
textAlign: "left",
}}>
{removeLeadingNonAlphanumeric(path) + "\u200E"}
</span>
<span className={`codicon codicon-chevron-${isExpanded ? "up" : "down"}`}></span>
</div>
)}
{(!path || isExpanded) && (
<div
//className="code-block-scrollable" this doesn't seem to be necessary anymore, on silicon macs it shows the native mac scrollbar instead of the vscode styled one
style={{
overflowX: "auto",
overflowY: "hidden",
maxWidth: "100%",
}}>
<CodeBlock
source={`${"```"}${diff !== undefined ? "diff" : inferredLanguage}\n${(
code ??
diff ??
""
).trim()}\n${"```"}`}
/>
</div>
)}
</div>
)
}
// memo does shallow comparison of props, so if you need it to re-render when a nested object changes, you need to pass a custom comparison function
export default memo(CodeAccordian)