77 diffAsideWidthName ,
88 borderColorName ,
99} from "@git-diff-view/utils" ;
10- import { memo , useEffect , useRef } from "react" ;
10+ import { memo , useEffect , useRef , useState } from "react" ;
1111import * as React from "react" ;
1212import { useSyncExternalStore } from "use-sync-external-store/shim/index.js" ;
1313
@@ -19,21 +19,43 @@ import { DiffSplitViewLine } from "./DiffSplitViewLineNormal_v2";
1919
2020import type { MouseEventHandler } from "react" ;
2121
22- const onMouseDown : MouseEventHandler < HTMLTableSectionElement > = ( e ) => {
23- const ele = e . target ;
24-
25- // need remove all the selection
26- if ( ele && ele instanceof HTMLElement && ele . nodeName === "BUTTON" ) {
27- removeAllSelection ( ) ;
28- return ;
29- }
30- } ;
31-
32- export const DiffSplitViewTable = ( { side, diffFile } : { side : SplitSide ; diffFile : DiffFile } ) => {
22+ export const DiffSplitViewTable = ( {
23+ side,
24+ diffFile,
25+ onSelect,
26+ } : {
27+ side : SplitSide ;
28+ diffFile : DiffFile ;
29+ onSelect ?: ( side : SplitSide ) => void ;
30+ } ) => {
3331 const className = side === SplitSide . new ? "new-diff-table" : "old-diff-table" ;
3432
3533 const lines = getSplitLines ( diffFile ) ;
3634
35+ const onMouseDown : MouseEventHandler < HTMLTableSectionElement > = ( e ) => {
36+ let ele = e . target as HTMLElement ;
37+
38+ if ( ele && ele ?. nodeName === "BUTTON" ) {
39+ removeAllSelection ( ) ;
40+ return ;
41+ }
42+
43+ while ( ele && ele instanceof HTMLElement ) {
44+ const state = ele . getAttribute ( "data-state" ) ;
45+ if ( state ) {
46+ if ( state === "extend" || state === "hunk" || state === "widget" ) {
47+ onSelect ?.( undefined ) ;
48+ removeAllSelection ( ) ;
49+ } else {
50+ onSelect ?.( side ) ;
51+ removeAllSelection ( ) ;
52+ }
53+ return ;
54+ }
55+ ele = ele . parentElement ;
56+ }
57+ } ;
58+
3759 return (
3860 < div className = { className + " w-max min-w-full" } data-mode = { SplitSide [ side ] } >
3961 < div className = "diff-table-body leading-[1.6]" onMouseDownCapture = { onMouseDown } >
@@ -55,6 +77,8 @@ export const DiffSplitViewNormal = memo(({ diffFile }: { diffFile: DiffFile }) =
5577
5678 const ref2 = useRef < HTMLDivElement > ( null ) ;
5779
80+ const [ side , setSide ] = useState < SplitSide > ( ) ;
81+
5882 const splitLineLength = Math . max ( diffFile . splitLineLength , diffFile . fileLineLength ) ;
5983
6084 const { useDiffContext } = useDiffViewContext ( ) ;
@@ -82,8 +106,15 @@ export const DiffSplitViewNormal = memo(({ diffFile }: { diffFile: DiffFile }) =
82106
83107 const width = Math . max ( 40 , _width + 25 ) ;
84108
109+ const id = `diff-root${ diffFile . getId ( ) } ` ;
110+
85111 return (
86112 < div className = "split-diff-view split-diff-view-normal flex w-full basis-[50%]" >
113+ < style data-select-style >
114+ { side
115+ ? `#${ id } [data-state="extend"] {user-select: none} \n #${ id } [data-state="hunk"] {user-select: none} \n #${ id } [data-state="widget"] {user-select: none}`
116+ : "" }
117+ </ style >
87118 < div
88119 className = "old-diff-table-wrapper diff-table-scroll-container w-full overflow-x-auto overflow-y-hidden"
89120 ref = { ref1 }
@@ -95,7 +126,7 @@ export const DiffSplitViewNormal = memo(({ diffFile }: { diffFile: DiffFile }) =
95126 fontSize : `var(${ diffFontSizeName } )` ,
96127 } }
97128 >
98- < DiffSplitViewTable side = { SplitSide . old } diffFile = { diffFile } />
129+ < DiffSplitViewTable side = { SplitSide . old } diffFile = { diffFile } onSelect = { setSide } />
99130 </ div >
100131 < div className = "diff-split-line w-[1.5px]" style = { { backgroundColor : `var(${ borderColorName } )` } } />
101132 < div
@@ -109,7 +140,7 @@ export const DiffSplitViewNormal = memo(({ diffFile }: { diffFile: DiffFile }) =
109140 fontSize : `var(${ diffFontSizeName } )` ,
110141 } }
111142 >
112- < DiffSplitViewTable side = { SplitSide . new } diffFile = { diffFile } />
143+ < DiffSplitViewTable side = { SplitSide . new } diffFile = { diffFile } onSelect = { setSide } />
113144 </ div >
114145 </ div >
115146 ) ;
0 commit comments