Skip to content

Commit b9ac11d

Browse files
update
1 parent ff95c40 commit b9ac11d

10 files changed

Lines changed: 261 additions & 129 deletions

File tree

packages/react/index.d.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1233,7 +1233,7 @@ export type MultiSelectExtendData<T = unknown> = {
12331233
oldFile?: Record<string, MultiSelectExtendDataItem<T>>;
12341234
newFile?: Record<string, MultiSelectExtendDataItem<T>>;
12351235
};
1236-
export interface DiffViewWithMultiSelectProps<T = unknown> extends Omit<DiffViewProps<T>, "extendData" | "renderExtendLine" | "onAddWidgetClick"> {
1236+
export interface DiffViewWithMultiSelectProps<T = unknown> extends Omit<DiffViewProps<T>, "extendData" | "renderExtendLine" | "renderWidgetLine" | "onAddWidgetClick"> {
12371237
/**
12381238
* Enable multi-select feature
12391239
* @default true
@@ -1262,10 +1262,13 @@ export interface DiffViewWithMultiSelectProps<T = unknown> extends Omit<DiffView
12621262
fromLineNumber?: number;
12631263
side: SplitSide;
12641264
}) => void;
1265-
/**
1266-
* Render function for extended lines (comments)
1267-
* Similar to DiffView's renderExtendLine but with fromLine info
1268-
*/
1265+
renderWidgetLine?: (props: {
1266+
lineNumber: number;
1267+
fromLineNumber: number;
1268+
side: SplitSide;
1269+
diffFile: DiffFile;
1270+
onClose: () => void;
1271+
}) => ReactNode;
12691272
renderExtendLine?: (props: {
12701273
lineNumber: number;
12711274
fromLineNumber: number;

packages/react/src/components/DiffViewWithMultiSelect.tsx

Lines changed: 69 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useCallback, useEffect, useMemo, useRef, useImperativeHandle, useState, forwardRef } from "react";
1+
import { useCallback, useEffect, useMemo, useRef, useImperativeHandle, forwardRef } from "react";
22

33
import { multiSelectClassNames, createDiffMultiSelectManager } from "..";
44
import { useCallbackRef } from "../hooks/useCallbackRef";
@@ -40,7 +40,7 @@ export type MultiSelectExtendData<T = unknown> = {
4040

4141
export interface DiffViewWithMultiSelectProps<T = unknown> extends Omit<
4242
DiffViewProps<T>,
43-
"extendData" | "renderExtendLine" | "onAddWidgetClick"
43+
"extendData" | "renderExtendLine" | "renderWidgetLine" | "onAddWidgetClick"
4444
> {
4545
/**
4646
* Enable multi-select feature
@@ -72,10 +72,14 @@ export interface DiffViewWithMultiSelectProps<T = unknown> extends Omit<
7272

7373
onAddWidgetClick?: (props: { lineNumber: number; fromLineNumber?: number; side: SplitSide }) => void;
7474

75-
/**
76-
* Render function for extended lines (comments)
77-
* Similar to DiffView's renderExtendLine but with fromLine info
78-
*/
75+
renderWidgetLine?: (props: {
76+
lineNumber: number;
77+
fromLineNumber: number;
78+
side: SplitSide;
79+
diffFile: DiffFile;
80+
onClose: () => void;
81+
}) => ReactNode;
82+
7983
renderExtendLine?: (props: {
8084
lineNumber: number;
8185
fromLineNumber: number;
@@ -94,6 +98,8 @@ export interface DiffViewWithMultiSelectRef {
9498
setPreselectedLines: (lines: { old: number[]; new: number[] }) => void;
9599
}
96100

101+
type MultiResult = ReturnType<typeof extendDataToPreselectedLines>;
102+
97103
/* eslint-disable @typescript-eslint/no-unnecessary-type-constraint */
98104
const InternalDiffViewWithMultiSelect = <T extends unknown>(
99105
props: DiffViewWithMultiSelectProps<T>,
@@ -105,6 +111,7 @@ const InternalDiffViewWithMultiSelect = <T extends unknown>(
105111
onMultiSelectComplete,
106112
onMultiSelectChange,
107113
scopeMultiSelectToHunk,
114+
renderWidgetLine,
108115
renderExtendLine,
109116
onAddWidgetClick,
110117
diffViewMode = DiffModeEnum.SplitGitHub,
@@ -121,12 +128,17 @@ const InternalDiffViewWithMultiSelect = <T extends unknown>(
121128
const diffViewRef = useRef<{ getDiffFileInstance: () => DiffFile | null }>(null);
122129
const managerRef = useRef<DiffMultiSelectManager | null>(null);
123130

124-
const [multiResult, setMultiResult] = useState<ReturnType<typeof extendDataToPreselectedLines>>();
131+
const multiResultRef = useRef<MultiResult>(undefined);
125132

126133
const isUnifiedMode = !(diffViewMode & DiffModeEnum.Split);
127134

135+
const updateMultiResult = useCallback((result?: MultiResult) => {
136+
multiResultRef.current = result;
137+
managerRef.current?.setPreselectedLines(result || { old: [], new: [] });
138+
}, []);
139+
128140
useUpdateEffect(() => {
129-
setMultiResult(undefined);
141+
updateMultiResult(undefined);
130142
}, [props.diffViewWrap, diffViewMode]);
131143

132144
const getDiffFile = useCallback(() => {
@@ -161,10 +173,10 @@ const InternalDiffViewWithMultiSelect = <T extends unknown>(
161173
memoSelectComplete?.(result);
162174
const finalResult = {
163175
[result.range.side as "old" | "new"]: [result.range.startLineNumber, result.range.endLineNumber],
164-
} as typeof multiResult;
165-
setMultiResult(finalResult);
176+
} as MultiResult;
177+
updateMultiResult(finalResult);
166178
} else {
167-
setMultiResult(undefined);
179+
updateMultiResult(undefined);
168180
}
169181
},
170182
scopeToHunk: memoScopeSelectToHunk,
@@ -182,17 +194,15 @@ const InternalDiffViewWithMultiSelect = <T extends unknown>(
182194
managerRef.current?.destroy();
183195
managerRef.current = null;
184196
};
185-
}, [enableMultiSelect, isUnifiedMode, memoScopeSelectToHunk, memoSelectChange, memoSelectComplete, getDiffFile]);
186-
187-
useEffect(() => {
188-
if (managerRef.current) {
189-
if (multiResult) {
190-
managerRef.current.setPreselectedLines(multiResult);
191-
} else {
192-
managerRef.current.setPreselectedLines({ old: [], new: [] });
193-
}
194-
}
195-
}, [multiResult]);
197+
}, [
198+
enableMultiSelect,
199+
isUnifiedMode,
200+
memoScopeSelectToHunk,
201+
memoSelectChange,
202+
memoSelectComplete,
203+
getDiffFile,
204+
updateMultiResult,
205+
]);
196206

197207
const convertedExtendData = useMemo(() => {
198208
if (!extendData) return undefined;
@@ -248,6 +258,36 @@ const InternalDiffViewWithMultiSelect = <T extends unknown>(
248258
[renderExtendLine, extendData]
249259
);
250260

261+
const internalRenderWidgetLine = useCallback(
262+
({
263+
lineNumber,
264+
side,
265+
diffFile,
266+
onClose,
267+
}: {
268+
lineNumber: number;
269+
side: SplitSide;
270+
diffFile: DiffFile;
271+
onClose: () => void;
272+
}) => {
273+
if (!renderWidgetLine) return null;
274+
275+
const sideKey = side === SplitSide.old ? "old" : "new";
276+
const multiResultItem = multiResultRef.current?.[sideKey] as number[];
277+
const fromLineNumber = multiResultItem ? Math.min(...multiResultItem) : lineNumber;
278+
const toLineNumber = multiResultItem ? Math.max(...multiResultItem) : lineNumber;
279+
280+
return renderWidgetLine({
281+
lineNumber: toLineNumber,
282+
fromLineNumber,
283+
side,
284+
diffFile,
285+
onClose,
286+
});
287+
},
288+
[renderWidgetLine]
289+
);
290+
251291
const getSelectionResult = useCallback(() => {
252292
return managerRef.current?.getSelectionResult() ?? null;
253293
}, []);
@@ -266,9 +306,7 @@ const InternalDiffViewWithMultiSelect = <T extends unknown>(
266306
managerRef.current?.clearSelection();
267307
}, []);
268308

269-
const setPreselectedLines = useCallback((lines: { old: number[]; new: number[] }) => {
270-
setMultiResult(lines);
271-
}, []);
309+
const setPreselectedLines = updateMultiResult;
272310

273311
useImperativeHandle(
274312
ref,
@@ -291,6 +329,7 @@ const InternalDiffViewWithMultiSelect = <T extends unknown>(
291329
extendData={convertedExtendData}
292330
onAddWidgetClick={(lineNum: number, side: SplitSide) => {
293331
managerRef.current?.clearSelection();
332+
const multiResult = multiResultRef.current;
294333
if (multiResult) {
295334
const currentSide = SplitSide[side] as unknown as "new" | "old";
296335
const currentMultiResult = multiResult[currentSide] as number[];
@@ -300,7 +339,7 @@ const InternalDiffViewWithMultiSelect = <T extends unknown>(
300339
const max = Math.max(...currentMultiResult);
301340
if (max === lineNum) {
302341
const finalResult = { [currentSide]: currentMultiResult };
303-
setMultiResult(finalResult as typeof multiResult);
342+
updateMultiResult(finalResult as MultiResult);
304343
onAddWidgetClick?.({ lineNumber: max, fromLineNumber: Math.min(...currentMultiResult), side });
305344
return;
306345
}
@@ -313,7 +352,7 @@ const InternalDiffViewWithMultiSelect = <T extends unknown>(
313352
const otherSideLineNum = side === SplitSide.old ? unifiedItem.newLineNumber : unifiedItem.oldLineNumber;
314353
if (max === otherSideLineNum) {
315354
const finalResult = { [otherSide]: otherMultiResult };
316-
setMultiResult(finalResult as typeof multiResult);
355+
updateMultiResult(finalResult as MultiResult);
317356
onAddWidgetClick?.({
318357
lineNumber: max,
319358
fromLineNumber: Math.min(...otherMultiResult),
@@ -322,12 +361,14 @@ const InternalDiffViewWithMultiSelect = <T extends unknown>(
322361
return;
323362
}
324363
}
325-
setMultiResult({ old: [], new: [] });
364+
updateMultiResult(undefined);
326365
onAddWidgetClick?.({ lineNumber: lineNum, fromLineNumber: lineNum, side });
327366
} else {
367+
updateMultiResult(undefined);
328368
onAddWidgetClick?.({ lineNumber: lineNum, fromLineNumber: lineNum, side });
329369
}
330370
}}
371+
renderWidgetLine={renderWidgetLine ? internalRenderWidgetLine : undefined}
331372
renderExtendLine={renderExtendLine ? internalRenderExtendLine : undefined}
332373
/>
333374
</div>

packages/solid/index.d.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1159,8 +1159,9 @@ export type DiffViewWithMultiSelectProps<T> = {
11591159
fromLineNumber?: number;
11601160
side: SplitSide;
11611161
}) => void;
1162-
renderWidgetLine?: ({ diffFile, side, lineNumber, onClose, }: {
1162+
renderWidgetLine?: ({ diffFile, side, lineNumber, fromLineNumber, onClose, }: {
11631163
lineNumber: number;
1164+
fromLineNumber: number;
11641165
side: SplitSide;
11651166
diffFile: DiffFile;
11661167
onClose: () => void;

0 commit comments

Comments
 (0)