fix(webapp): avoid mutating render inputs

This commit is contained in:
Chris Arderne
2026-08-19 17:28:23 +01:00
parent f9338b0e48
commit beba646d1a
3 changed files with 16 additions and 16 deletions
+10 -10
View File
@@ -221,35 +221,35 @@ export const CodeBlock = forwardRef<HTMLDivElement, CodeBlockProps>(
const [modalCopied, setModalCopied] = useState(false);
const [isModalOpen, setIsModalOpen] = useState(false);
const [isWrapped, setIsWrapped] = useState(wrap);
const normalizedCode = code?.trim() ?? "";
const onCopied = useCallback(
(event: React.MouseEvent<HTMLButtonElement>) => {
event.preventDefault();
event.stopPropagation();
navigator.clipboard.writeText(code);
navigator.clipboard.writeText(normalizedCode);
setCopied(true);
setTimeout(() => {
setCopied(false);
}, 1500);
},
[code]
[normalizedCode]
);
const onModalCopied = useCallback(
(event: React.MouseEvent<HTMLButtonElement>) => {
event.preventDefault();
event.stopPropagation();
navigator.clipboard.writeText(code);
navigator.clipboard.writeText(normalizedCode);
setModalCopied(true);
setTimeout(() => {
setModalCopied(false);
}, 1500);
},
[code]
[normalizedCode]
);
code = code?.trim() ?? "";
const lineCount = code.split("\n").length;
const lineCount = normalizedCode.split("\n").length;
const maxLineWidth = lineCount.toString().length;
let maxHeight: string | undefined = undefined;
if (maxLines && lineCount > maxLines) {
@@ -345,7 +345,7 @@ export const CodeBlock = forwardRef<HTMLDivElement, CodeBlockProps>(
{shouldHighlight ? (
<HighlightCode
theme={theme}
code={code}
code={normalizedCode}
language={language}
showLineNumbers={showLineNumbers}
highlightLines={highlightLines}
@@ -373,7 +373,7 @@ export const CodeBlock = forwardRef<HTMLDivElement, CodeBlockProps>(
)}
dir="ltr"
>
{highlightSearchText(code, searchTerm)}
{highlightSearchText(normalizedCode, searchTerm)}
</pre>
</div>
)}
@@ -400,7 +400,7 @@ export const CodeBlock = forwardRef<HTMLDivElement, CodeBlockProps>(
{shouldHighlight ? (
<HighlightCode
theme={theme}
code={code}
code={normalizedCode}
language={language}
showLineNumbers={showLineNumbers}
highlightLines={highlightLines}
@@ -415,7 +415,7 @@ export const CodeBlock = forwardRef<HTMLDivElement, CodeBlockProps>(
className="overflow-auto px-3 py-3 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control"
>
<pre className="relative mr-2 p-2 font-mono text-base leading-relaxed" dir="ltr">
{highlightSearchText(code, searchTerm)}
{highlightSearchText(normalizedCode, searchTerm)}
</pre>
</div>
)}
@@ -187,7 +187,7 @@ export function ReportFindingLine({
* entities mono, verdict phrases bright and medium, everything else dimmed.
* Colour stays reserved for severity, so emphasis here is weight only.
*/
const QUANTITY_RE = /~?\d[\d,.]*\s?(?:%|×|\/min|ms\b|s\b|min\b|h\b)?/g;
const QUANTITY_RE = /~?\d[\d,.]*\s?(?:%|×|\/min|ms\b|s\b|min\b|h\b)?/;
const VERDICT_PHRASES = [
"not your code",
@@ -249,7 +249,6 @@ export function ReportProse({ text, entities }: { text: string; entities?: strin
segments = splitBy(
segments,
(t) => {
QUANTITY_RE.lastIndex = 0;
const m = QUANTITY_RE.exec(t);
return m && m[0].trim().length > 0 ? { start: m.index, end: m.index + m[0].length } : null;
},
@@ -413,19 +413,20 @@ function SelectGroupedRenderer<TItem>({
) => React.ReactNode;
enableItemShortcuts: boolean;
}) {
let count = 0;
return (
<>
{items.map((section, index) => {
const previousItem = items.at(index - 1);
count += previousItem ? previousItem.items.length : 0;
const startIndex = items
.slice(0, index)
.reduce((count, previousSection) => count + previousSection.items.length, 0);
return (
<Fragment key={index}>
{children(section.items as ItemFromSection<TItem>[], {
shortcutsEnabled: enableItemShortcuts,
section: {
title: section.title,
startIndex: count - 1,
startIndex,
count: section.items.length,
},
})}