Skip to content

Commit 5ca2e5f

Browse files
fix
1 parent 3c8b960 commit 5ca2e5f

22 files changed

+923
-19
lines changed

packages/solid/src/components/DiffAddWidget.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import type { DiffFile, SplitSide } from "@git-diff-view/core";
44

55
export const DiffSplitAddWidget = (props: {
66
index: number;
7-
className?: string;
7+
class?: string;
88
lineNumber: number;
99
diffFile: DiffFile;
1010
side: SplitSide;
@@ -15,7 +15,7 @@ export const DiffSplitAddWidget = (props: {
1515
<div
1616
class={
1717
"diff-add-widget-wrapper invisible select-none transition-transform hover:scale-110 group-hover:visible" +
18-
(props.className ? " " + props.className : "")
18+
(props.class ? " " + props.class : "")
1919
}
2020
style={{
2121
width: `calc(var(${diffFontSizeName}) * 1.4)`,

packages/solid/src/components/DiffContent.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,7 @@ const DiffSyntax = (props: {
326326

327327
export const DiffContent = (props: {
328328
rawLine: string;
329+
plainLine?: File["plainFile"][number];
329330
syntaxLine?: File["syntaxFile"][number];
330331
diffLine?: DiffLine;
331332
diffFile: DiffFile;
@@ -369,6 +370,7 @@ export const DiffContent = (props: {
369370
operator={getIsAdded() ? "add" : getIsDelete() ? "del" : undefined}
370371
rawLine={props.rawLine}
371372
diffLine={props.diffLine}
373+
plainLine={props.plainLine}
372374
enableWrap={props.enableWrap}
373375
enableTemplate={getIsEnableTemplate()}
374376
/>

packages/solid/src/components/DiffExpand.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
1-
export const ExpandDown = (props: { className: string }) => {
1+
export const ExpandDown = (props: { class: string }) => {
22
return (
3-
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" class={props.className}>
3+
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" class={props.class}>
44
<path d="m8.177 14.323 2.896-2.896a.25.25 0 0 0-.177-.427H8.75V7.764a.75.75 0 1 0-1.5 0V11H5.104a.25.25 0 0 0-.177.427l2.896 2.896a.25.25 0 0 0 .354 0ZM2.25 5a.75.75 0 0 0 0-1.5h-.5a.75.75 0 0 0 0 1.5h.5ZM6 4.25a.75.75 0 0 1-.75.75h-.5a.75.75 0 0 1 0-1.5h.5a.75.75 0 0 1 .75.75ZM8.25 5a.75.75 0 0 0 0-1.5h-.5a.75.75 0 0 0 0 1.5h.5ZM12 4.25a.75.75 0 0 1-.75.75h-.5a.75.75 0 0 1 0-1.5h.5a.75.75 0 0 1 .75.75Zm2.25.75a.75.75 0 0 0 0-1.5h-.5a.75.75 0 0 0 0 1.5h.5Z" />
55
</svg>
66
);
77
};
88

9-
export const ExpandUp = (props: { className?: string }) => {
9+
export const ExpandUp = (props: { class?: string }) => {
1010
return (
11-
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" class={props.className}>
11+
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" class={props.class}>
1212
<path d="M7.823 1.677 4.927 4.573A.25.25 0 0 0 5.104 5H7.25v3.236a.75.75 0 1 0 1.5 0V5h2.146a.25.25 0 0 0 .177-.427L8.177 1.677a.25.25 0 0 0-.354 0ZM13.75 11a.75.75 0 0 0 0 1.5h.5a.75.75 0 0 0 0-1.5h-.5Zm-3.75.75a.75.75 0 0 1 .75-.75h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1-.75-.75ZM7.75 11a.75.75 0 0 0 0 1.5h.5a.75.75 0 0 0 0-1.5h-.5ZM4 11.75a.75.75 0 0 1 .75-.75h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1-.75-.75ZM1.75 11a.75.75 0 0 0 0 1.5h.5a.75.75 0 0 0 0-1.5h-.5Z" />
1313
</svg>
1414
);
1515
};
1616

17-
export const ExpandAll = (props: { className?: string }) => {
17+
export const ExpandAll = (props: { class?: string }) => {
1818
return (
19-
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" class={props.className}>
19+
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" class={props.class}>
2020
<path d="m8.177.677 2.896 2.896a.25.25 0 0 1-.177.427H8.75v1.25a.75.75 0 0 1-1.5 0V4H5.104a.25.25 0 0 1-.177-.427L7.823.677a.25.25 0 0 1 .354 0ZM7.25 10.75a.75.75 0 0 1 1.5 0V12h2.146a.25.25 0 0 1 .177.427l-2.896 2.896a.25.25 0 0 1-.354 0l-2.896-2.896A.25.25 0 0 1 5.104 12H7.25v-1.25Zm-5-2a.75.75 0 0 0 0-1.5h-.5a.75.75 0 0 0 0 1.5h.5ZM6 8a.75.75 0 0 1-.75.75h-.5a.75.75 0 0 1 0-1.5h.5A.75.75 0 0 1 6 8Zm2.25.75a.75.75 0 0 0 0-1.5h-.5a.75.75 0 0 0 0 1.5h.5ZM12 8a.75.75 0 0 1-.75.75h-.5a.75.75 0 0 1 0-1.5h.5A.75.75 0 0 1 12 8Zm2.25.75a.75.75 0 0 0 0-1.5h-.5a.75.75 0 0 0 0 1.5h.5Z" />
2121
</svg>
2222
);
Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
import { checkDiffLineIncludeChange, DiffLineType, SplitSide, type DiffFile } from "@git-diff-view/core";
2+
import {
3+
borderColorName,
4+
emptyBGName,
5+
expandLineNumberColorName,
6+
getContentBG,
7+
getLineNumberBG,
8+
plainLineNumberColorName,
9+
} from "@git-diff-view/utils";
10+
import { createEffect, createSignal, onCleanup, Show } from "solid-js";
11+
12+
import { useEnableAddWidget, useEnableHighlight, useOnAddWidgetClick } from "../hooks";
13+
14+
import { DiffSplitAddWidget } from "./DiffAddWidget";
15+
import { DiffContent } from "./DiffContent";
16+
import { useDiffWidgetContext } from "./DiffWidgetContext";
17+
18+
export const DiffSplitContentLine = (props: { index: number; diffFile: DiffFile; lineNumber: number }) => {
19+
const [_, setWidget] = useDiffWidgetContext() || [];
20+
21+
const enableAddWidget = useEnableAddWidget();
22+
23+
const enableHighlight = useEnableHighlight();
24+
25+
const onAddWidgetClick = useOnAddWidgetClick();
26+
27+
const [oldLine, setOldLine] = createSignal(props.diffFile.getSplitLeftLine(props.index));
28+
29+
const [newLine, setNewLine] = createSignal(props.diffFile.getSplitRightLine(props.index));
30+
31+
const [oldSyntaxLine, setOldSyntaxLine] = createSignal(props.diffFile.getOldSyntaxLine(oldLine()?.lineNumber || 0));
32+
33+
const [newSyntaxLine, setNewSyntaxLine] = createSignal(props.diffFile.getNewSyntaxLine(newLine()?.lineNumber || 0));
34+
35+
const [oldPlainLine, setOldPlainLine] = createSignal(props.diffFile.getOldPlainLine(oldLine()?.lineNumber || 0));
36+
37+
const [newPlainLine, setNewPlainLine] = createSignal(props.diffFile.getNewPlainLine(newLine()?.lineNumber || 0));
38+
39+
const [hasDiff, setHasDiff] = createSignal(!!oldLine()?.diff || !!newLine()?.diff);
40+
41+
const [hasChange, setHasChange] = createSignal(
42+
checkDiffLineIncludeChange(oldLine().diff) || checkDiffLineIncludeChange(newLine().diff)
43+
);
44+
45+
const [hasHidden, setHasHidden] = createSignal(oldLine()?.isHidden && newLine()?.isHidden);
46+
47+
const [oldLineIsDelete, setOldLineIsDelete] = createSignal(oldLine()?.diff?.type === DiffLineType.Delete);
48+
49+
const [newLineIsAdded, setNewLineIsAdded] = createSignal(newLine()?.diff?.type === DiffLineType.Add);
50+
51+
createEffect(() => {
52+
const init = () => {
53+
setOldLine(props.diffFile.getSplitLeftLine(props.index));
54+
setNewLine(props.diffFile.getSplitRightLine(props.index));
55+
setOldSyntaxLine(props.diffFile.getOldSyntaxLine(oldLine()?.lineNumber || 0));
56+
setNewSyntaxLine(props.diffFile.getNewSyntaxLine(newLine()?.lineNumber || 0));
57+
setOldPlainLine(props.diffFile.getOldPlainLine(oldLine()?.lineNumber || 0));
58+
setNewPlainLine(props.diffFile.getNewPlainLine(newLine()?.lineNumber || 0));
59+
setHasDiff(!!oldLine()?.diff || !!newLine()?.diff);
60+
setHasChange(checkDiffLineIncludeChange(oldLine().diff) || checkDiffLineIncludeChange(newLine().diff));
61+
setHasHidden(oldLine()?.isHidden && newLine()?.isHidden);
62+
setOldLineIsDelete(oldLine()?.diff?.type === DiffLineType.Delete);
63+
setNewLineIsAdded(newLine()?.diff?.type === DiffLineType.Add);
64+
};
65+
66+
init();
67+
68+
const cb = props.diffFile.subscribe(init);
69+
70+
onCleanup(cb);
71+
});
72+
73+
const onOpenAddWidget = (lineNumber: number, side: SplitSide) => setWidget?.({ side: side, lineNumber: lineNumber });
74+
75+
return (
76+
<Show when={!hasHidden()}>
77+
<tr data-line={props.lineNumber} data-state={hasDiff() ? "diff" : "plain"} class="diff-line">
78+
{oldLine().lineNumber ? (
79+
<>
80+
<td
81+
class="diff-line-old-num group relative w-[1%] min-w-[40px] select-none pl-[10px] pr-[10px] text-right align-top"
82+
style={{
83+
"background-color": getLineNumberBG(false, oldLineIsDelete(), hasDiff()),
84+
color: `var(${hasDiff() ? plainLineNumberColorName : expandLineNumberColorName})`,
85+
}}
86+
>
87+
{hasDiff() && enableAddWidget() && (
88+
<DiffSplitAddWidget
89+
index={props.index}
90+
lineNumber={oldLine().lineNumber || 0}
91+
side={SplitSide.old}
92+
diffFile={props.diffFile}
93+
onWidgetClick={onAddWidgetClick}
94+
class="absolute left-[100%] z-[1] translate-x-[-50%]"
95+
onOpenAddWidget={onOpenAddWidget}
96+
/>
97+
)}
98+
<span data-line-num={oldLine().lineNumber} style={{ opacity: hasChange() ? undefined : 0.5 }}>
99+
{oldLine().lineNumber}
100+
</span>
101+
</td>
102+
<td
103+
class="diff-line-old-content group relative pr-[10px] align-top"
104+
style={{ "background-color": getContentBG(false, oldLineIsDelete(), hasDiff()) }}
105+
data-side={SplitSide[SplitSide.old]}
106+
>
107+
{hasDiff() && enableAddWidget() && (
108+
<DiffSplitAddWidget
109+
index={props.index}
110+
lineNumber={oldLine().lineNumber || 0}
111+
side={SplitSide.old}
112+
diffFile={props.diffFile}
113+
onWidgetClick={onAddWidgetClick}
114+
class="absolute right-[100%] z-[1] translate-x-[50%]"
115+
onOpenAddWidget={onOpenAddWidget}
116+
/>
117+
)}
118+
<DiffContent
119+
enableWrap={true}
120+
diffFile={props.diffFile}
121+
rawLine={oldLine().value || ""}
122+
diffLine={oldLine().diff}
123+
plainLine={oldPlainLine()}
124+
syntaxLine={oldSyntaxLine()}
125+
enableHighlight={!!enableHighlight()}
126+
/>
127+
</td>
128+
</>
129+
) : (
130+
<td
131+
class="diff-line-old-placeholder select-none"
132+
style={{ "background-color": `var(${emptyBGName})` }}
133+
colspan={2}
134+
>
135+
<span>&ensp;</span>
136+
</td>
137+
)}
138+
{newLine().lineNumber ? (
139+
<>
140+
<td
141+
class="diff-line-new-num group relative w-[1%] min-w-[40px] select-none border-l-[1px] pl-[10px] pr-[10px] text-right align-top"
142+
style={{
143+
"background-color": getLineNumberBG(newLineIsAdded(), false, hasDiff()),
144+
color: `var(${hasDiff() ? plainLineNumberColorName : expandLineNumberColorName})`,
145+
"border-left-color": `var(${borderColorName})`,
146+
"border-left-style": "solid",
147+
}}
148+
>
149+
{hasDiff() && enableAddWidget() && (
150+
<DiffSplitAddWidget
151+
index={props.index}
152+
lineNumber={newLine().lineNumber || 0}
153+
side={SplitSide.new}
154+
diffFile={props.diffFile}
155+
// TODO test
156+
onWidgetClick={onAddWidgetClick}
157+
class="absolute left-[100%] z-[1] translate-x-[-50%]"
158+
onOpenAddWidget={onOpenAddWidget}
159+
/>
160+
)}
161+
<span data-line-num={newLine().lineNumber} style={{ opacity: hasChange() ? undefined : 0.5 }}>
162+
{newLine().lineNumber}
163+
</span>
164+
</td>
165+
<td
166+
class="diff-line-new-content group relative pr-[10px] align-top"
167+
style={{ "background-color": getContentBG(newLineIsAdded(), false, hasDiff()) }}
168+
data-side={SplitSide[SplitSide.new]}
169+
>
170+
{hasDiff() && enableAddWidget() && (
171+
<DiffSplitAddWidget
172+
index={props.index}
173+
lineNumber={newLine().lineNumber || 0}
174+
side={SplitSide.new}
175+
diffFile={props.diffFile}
176+
onWidgetClick={onAddWidgetClick}
177+
class="absolute right-[100%] z-[1] translate-x-[50%]"
178+
onOpenAddWidget={onOpenAddWidget}
179+
/>
180+
)}
181+
<DiffContent
182+
enableWrap={true}
183+
diffFile={props.diffFile}
184+
rawLine={newLine().value || ""}
185+
diffLine={newLine().diff}
186+
plainLine={newPlainLine()}
187+
syntaxLine={newSyntaxLine()}
188+
enableHighlight={!!enableHighlight()}
189+
/>
190+
</td>
191+
</>
192+
) : (
193+
<td
194+
class="diff-line-new-placeholder select-none border-l-[1px]"
195+
style={{
196+
"background-color": `var(${emptyBGName})`,
197+
"border-left-color": `var(${borderColorName})`,
198+
"border-left-style": "solid",
199+
}}
200+
colspan={2}
201+
>
202+
<span>&ensp;</span>
203+
</td>
204+
)}
205+
</tr>
206+
</Show>
207+
);
208+
};
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import { SplitSide, type DiffFile } from "@git-diff-view/core";
2+
import { borderColorName, emptyBGName } from "@git-diff-view/utils";
3+
import { createEffect, createSignal, onCleanup, Show } from "solid-js";
4+
5+
import { useExtendData, useRenderExtend } from "../hooks";
6+
7+
export const DiffSplitExtendLine = (props: { index: number; diffFile: DiffFile; lineNumber: number }) => {
8+
const extendData = useExtendData();
9+
10+
const renderExtend = useRenderExtend();
11+
12+
const [oldLine, setOldLine] = createSignal(props.diffFile.getSplitLeftLine(props.index));
13+
14+
const [newLine, setNewLine] = createSignal(props.diffFile.getSplitRightLine(props.index));
15+
16+
const [enableExpand, setEnableExpand] = createSignal(props.diffFile.getExpandEnabled());
17+
18+
const [oldLineExtend, setOldLineExtend] = createSignal(extendData()?.oldFile?.[oldLine()?.lineNumber || ""]);
19+
20+
const [newLineExtend, setNewLineExtend] = createSignal(extendData()?.newFile?.[newLine()?.lineNumber || ""]);
21+
22+
const checkIsShow = () => {
23+
const oldExtend = oldLineExtend();
24+
const newExtend = newLineExtend();
25+
const oldLineData = oldLine();
26+
const newLineData = newLine();
27+
const enableExpandValue = enableExpand();
28+
const renderExtendValue = renderExtend();
29+
30+
return (
31+
(oldExtend || newExtend) &&
32+
((!oldLineData?.isHidden && !newLineData?.isHidden) || enableExpandValue) &&
33+
renderExtendValue
34+
);
35+
};
36+
37+
const [currentIsShow, setCurrentIsShow] = createSignal(!!checkIsShow());
38+
39+
createEffect(() => {
40+
const init = () => {
41+
setOldLine(props.diffFile.getSplitLeftLine(props.index));
42+
setNewLine(props.diffFile.getSplitRightLine(props.index));
43+
setEnableExpand(props.diffFile.getExpandEnabled());
44+
setOldLineExtend(extendData()?.oldFile?.[oldLine()?.lineNumber || ""]);
45+
setNewLineExtend(extendData()?.newFile?.[newLine()?.lineNumber || ""]);
46+
setCurrentIsShow(!!checkIsShow());
47+
};
48+
49+
init();
50+
51+
const cb = props.diffFile.subscribe(init);
52+
53+
onCleanup(cb);
54+
});
55+
56+
return (
57+
<Show when={currentIsShow()}>
58+
<tr data-line={`${props.lineNumber}-extend`} data-state="extend" class="diff-line diff-line-extend">
59+
{renderExtend() ? (
60+
<td class="diff-line-extend-old-content p-0" colspan={2}>
61+
<div class="diff-line-extend-wrapper">
62+
{renderExtend()?.({
63+
diffFile: props.diffFile,
64+
side: SplitSide.old,
65+
lineNumber: oldLine()?.lineNumber || 0,
66+
data: oldLineExtend()?.data,
67+
onUpdate: props.diffFile.notifyAll,
68+
})}
69+
</div>
70+
</td>
71+
) : (
72+
<td
73+
class="diff-line-extend-old-placeholder select-none p-0"
74+
style={{ "background-color": `var(${emptyBGName})` }}
75+
colspan={2}
76+
/>
77+
)}
78+
{renderExtend() ? (
79+
<td
80+
class="diff-line-extend-new-content border-l-[1px] p-0"
81+
colspan={2}
82+
style={{ "border-left-color": `var(${borderColorName})`, "border-left-style": "solid" }}
83+
>
84+
<div class="diff-line-extend-wrapper">
85+
{renderExtend()?.({
86+
diffFile: props.diffFile,
87+
side: SplitSide.new,
88+
lineNumber: newLine()?.lineNumber || 0,
89+
data: newLineExtend()?.data,
90+
onUpdate: props.diffFile.notifyAll,
91+
})}
92+
</div>
93+
</td>
94+
) : (
95+
<td
96+
class="diff-line-extend-new-placeholder select-none border-l-[1px] p-0"
97+
style={{
98+
"background-color": `var(${emptyBGName})`,
99+
"border-left-color": `var(${borderColorName})`,
100+
"border-left-style": "solid",
101+
}}
102+
colspan={2}
103+
/>
104+
)}
105+
</tr>
106+
</Show>
107+
);
108+
};

0 commit comments

Comments
 (0)