11/* eslint-disable @typescript-eslint/ban-ts-comment */
22import { type DiffFile , getSplitContentLines } from "@git-diff-view/core" ;
33import { diffAsideWidthName , diffFontSizeName , removeAllSelection } from "@git-diff-view/utils" ;
4- import { Fragment , memo , useCallback , useMemo } from "react" ;
4+ import { Fragment , memo , useMemo , useRef } from "react" ;
55import * as React from "react" ;
66// SEE https://github.com/facebook/react/pull/25231
77import { useSyncExternalStore } from "use-sync-external-store/shim/index.js" ;
@@ -14,37 +14,15 @@ import { DiffSplitExtendLine } from "./DiffSplitExtendLineWrap";
1414import { DiffSplitHunkLine } from "./DiffSplitHunkLineWrap" ;
1515import { DiffSplitWidgetLine } from "./DiffSplitWidgetLineWrap" ;
1616import { useDiffViewContext } from "./DiffViewContext" ;
17- import { createDiffSplitConfigStore } from "./tools" ;
1817
1918import type { MouseEventHandler } from "react" ;
20- import type { Ref , UseSelectorWithStore } from "reactivity-store" ;
21-
22- const Style = ( {
23- useSelector,
24- id,
25- } : {
26- useSelector : UseSelectorWithStore < { splitRef : Ref < SplitSide > } > ;
27- id : string ;
28- } ) => {
29- const splitRef = useSelector ( ( s ) => s . splitRef ) ;
30-
31- return (
32- < style data-select-style >
33- { splitRef === SplitSide . old
34- ? `#${ id } [data-side="${ SplitSide [ SplitSide . new ] } "] {user-select: none} \n #${ id } [data-state="extend"] {user-select: none} \n #${ id } [data-state="hunk"] {user-select: none} \n #${ id } [data-state="widget"] {user-select: none}`
35- : splitRef === SplitSide . new
36- ? `#${ id } [data-side="${ SplitSide [ SplitSide . old ] } "] {user-select: none} \n #${ id } [data-state="extend"] {user-select: none} \n #${ id } [data-state="hunk"] {user-select: none} \n #${ id } [data-state="widget"] {user-select: none}`
37- : "" }
38- </ style >
39- ) ;
40- } ;
4119
4220export const DiffSplitViewWrap = memo ( ( { diffFile } : { diffFile : DiffFile } ) => {
4321 const splitLineLength = Math . max ( diffFile . splitLineLength , diffFile . fileLineLength ) ;
4422
4523 const { useDiffContext } = useDiffViewContext ( ) ;
4624
47- const useSplitConfig = useMemo ( ( ) => createDiffSplitConfigStore ( ) , [ ] ) ;
25+ const ref = useRef < HTMLStyleElement > ( null ) ;
4826
4927 const { fontSize, enableAddWidget, enableHighlight } = useDiffContext . useShallowStableSelector ( ( s ) => ( {
5028 fontSize : s . fontSize ,
@@ -54,10 +32,30 @@ export const DiffSplitViewWrap = memo(({ diffFile }: { diffFile: DiffFile }) =>
5432
5533 useSyncExternalStore ( diffFile . subscribe , diffFile . getUpdateCount , diffFile . getUpdateCount ) ;
5634
57- const onMouseDown = useCallback < MouseEventHandler < HTMLTableSectionElement > > ( ( e ) => {
58- let ele = e . target ;
35+ const font = useMemo ( ( ) => ( { fontSize : fontSize + "px" , fontFamily : "Menlo, Consolas, monospace" } ) , [ fontSize ] ) ;
5936
60- const setSelectSide = useSplitConfig . getReadonlyState ( ) . setSplit ;
37+ const _width = useTextWidth ( {
38+ text : splitLineLength . toString ( ) ,
39+ font,
40+ } ) ;
41+
42+ const width = Math . max ( 40 , _width + 25 ) ;
43+
44+ const lines = getSplitContentLines ( diffFile ) ;
45+
46+ const setStyle = ( side : SplitSide ) => {
47+ if ( ! ref . current ) return ;
48+ if ( ! side ) {
49+ ref . current . textContent = "" ;
50+ } else {
51+ const id = `diff-root${ diffFile . getId ( ) } ` ;
52+ const targetSide = side === SplitSide . old ? SplitSide . new : SplitSide . old ;
53+ ref . current . textContent = `#${ id } [data-side="${ SplitSide [ targetSide ] } "] {user-select: none} \n#${ id } [data-state="extend"] {user-select: none} \n#${ id } [data-state="hunk"] {user-select: none} \n#${ id } [data-state="widget"] {user-select: none}` ;
54+ }
55+ } ;
56+
57+ const onMouseDown : MouseEventHandler < HTMLTableSectionElement > = ( e ) => {
58+ let ele = e . target ;
6159
6260 // need remove all the selection
6361 if ( ele && ele instanceof HTMLElement && ele . nodeName === "BUTTON" ) {
@@ -69,12 +67,12 @@ export const DiffSplitViewWrap = memo(({ diffFile }: { diffFile: DiffFile }) =>
6967 const state = ele . getAttribute ( "data-state" ) ;
7068 const side = ele . getAttribute ( "data-side" ) ;
7169 if ( side ) {
72- setSelectSide ( SplitSide [ side ] ) ;
70+ setStyle ( SplitSide [ side ] ) ;
7371 removeAllSelection ( ) ;
7472 }
7573 if ( state ) {
7674 if ( state === "extend" || state === "hunk" || state === "widget" ) {
77- setSelectSide ( undefined ) ;
75+ setStyle ( undefined ) ;
7876 removeAllSelection ( ) ;
7977 return ;
8078 } else {
@@ -84,19 +82,7 @@ export const DiffSplitViewWrap = memo(({ diffFile }: { diffFile: DiffFile }) =>
8482
8583 ele = ele . parentElement ;
8684 }
87- // eslint-disable-next-line react-hooks/exhaustive-deps
88- } , [ ] ) ;
89-
90- const font = useMemo ( ( ) => ( { fontSize : fontSize + "px" , fontFamily : "Menlo, Consolas, monospace" } ) , [ fontSize ] ) ;
91-
92- const _width = useTextWidth ( {
93- text : splitLineLength . toString ( ) ,
94- font,
95- } ) ;
96-
97- const width = Math . max ( 40 , _width + 25 ) ;
98-
99- const lines = getSplitContentLines ( diffFile ) ;
85+ } ;
10086
10187 return (
10288 < div className = "split-diff-view split-diff-view-wrap w-full" >
@@ -109,7 +95,7 @@ export const DiffSplitViewWrap = memo(({ diffFile }: { diffFile: DiffFile }) =>
10995 fontSize : `var(${ diffFontSizeName } )` ,
11096 } }
11197 >
112- < Style useSelector = { useSplitConfig } id = { `diff-root ${ diffFile . getId ( ) } ` } />
98+ < style data-select-style ref = { ref } />
11399 < table className = "diff-table w-full table-fixed border-collapse border-spacing-0" >
114100 < colgroup >
115101 < col className = "diff-table-old-num-col" width = { Math . round ( width ) } />
0 commit comments