@git-diff-view/react 0.0.25 → 0.0.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.development.js +543 -376
- package/dist/cjs/index.development.js.map +1 -1
- package/dist/cjs/index.production.js +543 -376
- package/dist/cjs/index.production.js.map +1 -1
- package/dist/css/diff-view-pure.css +5 -1
- package/dist/css/diff-view.css +6 -2
- package/dist/esm/index.mjs +485 -321
- package/dist/esm/index.mjs.map +1 -1
- package/index.d.ts +317 -23
- package/package.json +8 -7
- package/src/_base.css +3 -0
- package/src/_base_pure.css +2 -0
- package/src/_com.css +172 -0
- package/src/_theme.css +2 -0
- package/src/components/DiffAddWidget.tsx +86 -0
- package/src/components/DiffContent.tsx +367 -0
- package/src/components/DiffContent_v2.tsx +344 -0
- package/src/components/DiffExpand.tsx +25 -0
- package/src/components/DiffNoNewLine.tsx +10 -0
- package/src/components/DiffSplitContentLineNormal.tsx +164 -0
- package/src/components/DiffSplitContentLineWrap.tsx +234 -0
- package/src/components/DiffSplitExtendLineNormal.tsx +150 -0
- package/src/components/DiffSplitExtendLineWrap.tsx +133 -0
- package/src/components/DiffSplitHunkLineNormal.tsx +316 -0
- package/src/components/DiffSplitHunkLineWrap.tsx +340 -0
- package/src/components/DiffSplitView.tsx +46 -0
- package/src/components/DiffSplitViewNormal.tsx +205 -0
- package/src/components/DiffSplitViewWrap.tsx +141 -0
- package/src/components/DiffSplitWidgetLineNormal.tsx +149 -0
- package/src/components/DiffSplitWidgetLineWrap.tsx +127 -0
- package/src/components/DiffUnifiedContentLine.tsx +342 -0
- package/src/components/DiffUnifiedExtendLine.tsx +103 -0
- package/src/components/DiffUnifiedHunkLine.tsx +148 -0
- package/src/components/DiffUnifiedView.tsx +159 -0
- package/src/components/DiffUnifiedWidgetLine.tsx +104 -0
- package/src/components/DiffView.tsx +365 -0
- package/src/components/DiffViewContext.ts +11 -0
- package/src/components/DiffWidgetContext.ts +17 -0
- package/src/components/tools.ts +132 -0
- package/src/components/v2/DiffSplitContentLineNormal_v2.tsx +152 -0
- package/src/components/v2/DiffSplitContentLineWrap_v2.tsx +259 -0
- package/src/components/v2/DiffSplitExtendLineNormal_v2.tsx +146 -0
- package/src/components/v2/DiffSplitExtendLineWrap_v2.tsx +123 -0
- package/src/components/v2/DiffSplitHunkLineNormal_v2.tsx +302 -0
- package/src/components/v2/DiffSplitHunkLineWrap_v2.tsx +326 -0
- package/src/components/v2/DiffSplitViewLineNormal_v2.tsx +33 -0
- package/src/components/v2/DiffSplitViewLineWrap_v2.tsx +24 -0
- package/src/components/v2/DiffSplitViewNormal_v2.tsx +159 -0
- package/src/components/v2/DiffSplitViewWrap_v2.tsx +104 -0
- package/src/components/v2/DiffSplitView_v2.tsx +47 -0
- package/src/components/v2/DiffSplitWidgetLineNormal_v2.tsx +132 -0
- package/src/components/v2/DiffSplitWidgetLineWrap_v2.tsx +119 -0
- package/src/global.d.ts +12 -0
- package/src/hooks/useCallbackRef.ts +18 -0
- package/src/hooks/useDomWidth.ts +67 -0
- package/src/hooks/useIsMounted.ts +11 -0
- package/src/hooks/useSafeLayout.ts +5 -0
- package/src/hooks/useSyncHeight.ts +87 -0
- package/src/hooks/useTextWidth.ts +27 -0
- package/src/hooks/useUnmount.ts +10 -0
- package/src/index.ts +3 -0
- package/src/tailwind.css +3 -0
- package/src/tailwind_pure.css +3 -0
- package/styles/diff-view-pure.css +5 -1
- package/styles/diff-view.css +6 -2
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { emptyBGName } from "@git-diff-view/utils";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
|
|
4
|
+
import { useDomWidth } from "../../hooks/useDomWidth";
|
|
5
|
+
import { useSyncHeight } from "../../hooks/useSyncHeight";
|
|
6
|
+
import { SplitSide } from "../DiffView";
|
|
7
|
+
import { useDiffViewContext } from "../DiffViewContext";
|
|
8
|
+
import { useDiffWidgetContext } from "../DiffWidgetContext";
|
|
9
|
+
|
|
10
|
+
import type { DiffFile } from "@git-diff-view/core";
|
|
11
|
+
|
|
12
|
+
const InternalDiffSplitWidgetLine = ({
|
|
13
|
+
index,
|
|
14
|
+
side,
|
|
15
|
+
diffFile,
|
|
16
|
+
lineNumber,
|
|
17
|
+
}: {
|
|
18
|
+
index: number;
|
|
19
|
+
side: SplitSide;
|
|
20
|
+
diffFile: DiffFile;
|
|
21
|
+
lineNumber: number;
|
|
22
|
+
}) => {
|
|
23
|
+
const { useWidget } = useDiffWidgetContext();
|
|
24
|
+
|
|
25
|
+
const { useDiffContext } = useDiffViewContext();
|
|
26
|
+
|
|
27
|
+
const oldLine = diffFile.getSplitLeftLine(index);
|
|
28
|
+
|
|
29
|
+
const newLine = diffFile.getSplitRightLine(index);
|
|
30
|
+
|
|
31
|
+
const widgetSide = useWidget.getReadonlyState().widgetSide;
|
|
32
|
+
|
|
33
|
+
const widgetLineNumber = useWidget.getReadonlyState().widgetLineNumber;
|
|
34
|
+
|
|
35
|
+
const setWidget = useWidget.getReadonlyState().setWidget;
|
|
36
|
+
|
|
37
|
+
const oldLineWidget = oldLine.lineNumber && widgetSide === SplitSide.old && widgetLineNumber === oldLine.lineNumber;
|
|
38
|
+
|
|
39
|
+
const newLineWidget = newLine.lineNumber && widgetSide === SplitSide.new && widgetLineNumber === newLine.lineNumber;
|
|
40
|
+
|
|
41
|
+
const currentLine = side === SplitSide.old ? oldLine : newLine;
|
|
42
|
+
|
|
43
|
+
const otherSide = side === SplitSide.old ? SplitSide.new : SplitSide.old;
|
|
44
|
+
|
|
45
|
+
const currentHasWidget = side === SplitSide.old ? oldLineWidget : newLineWidget;
|
|
46
|
+
|
|
47
|
+
const hasWidget = oldLineWidget || newLineWidget;
|
|
48
|
+
|
|
49
|
+
const renderWidgetLine = useDiffContext.useShallowStableSelector((s) => s.renderWidgetLine);
|
|
50
|
+
|
|
51
|
+
useSyncHeight({
|
|
52
|
+
wrapper: `div[data-state="widget"][data-line="${lineNumber}-widget"]`,
|
|
53
|
+
selector: `div[data-line="${lineNumber}-widget-content"]`,
|
|
54
|
+
side: SplitSide[currentHasWidget ? side : otherSide],
|
|
55
|
+
enable: hasWidget && typeof renderWidgetLine === "function",
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
const width = useDomWidth({
|
|
59
|
+
selector: side === SplitSide.old ? ".old-diff-table-wrapper" : ".new-diff-table-wrapper",
|
|
60
|
+
enable: !!currentHasWidget && typeof renderWidgetLine === "function",
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
if (!renderWidgetLine) return null;
|
|
64
|
+
|
|
65
|
+
return (
|
|
66
|
+
<div
|
|
67
|
+
data-line={`${lineNumber}-widget`}
|
|
68
|
+
data-state="widget"
|
|
69
|
+
data-side={SplitSide[side]}
|
|
70
|
+
className="diff-line diff-line-widget"
|
|
71
|
+
>
|
|
72
|
+
{currentHasWidget ? (
|
|
73
|
+
<div className={`diff-line-widget-${SplitSide[side]}-content p-0`}>
|
|
74
|
+
<div
|
|
75
|
+
data-line={`${lineNumber}-widget-content`}
|
|
76
|
+
data-side={SplitSide[side]}
|
|
77
|
+
className="diff-line-widget-wrapper sticky left-0 z-[1]"
|
|
78
|
+
style={{ width }}
|
|
79
|
+
>
|
|
80
|
+
{width > 0 &&
|
|
81
|
+
renderWidgetLine?.({
|
|
82
|
+
diffFile,
|
|
83
|
+
side,
|
|
84
|
+
lineNumber: currentLine.lineNumber,
|
|
85
|
+
onClose: () => setWidget({}),
|
|
86
|
+
})}
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
) : (
|
|
90
|
+
<div
|
|
91
|
+
className={`diff-line-widget-${SplitSide[side]}-placeholder h-full select-none p-0`}
|
|
92
|
+
style={{ backgroundColor: `var(${emptyBGName})` }}
|
|
93
|
+
>
|
|
94
|
+
<div data-line={`${lineNumber}-widget-content`} data-side={SplitSide[side]} />
|
|
95
|
+
</div>
|
|
96
|
+
)}
|
|
97
|
+
</div>
|
|
98
|
+
);
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
export const DiffSplitWidgetLine = ({
|
|
102
|
+
index,
|
|
103
|
+
diffFile,
|
|
104
|
+
side,
|
|
105
|
+
lineNumber,
|
|
106
|
+
}: {
|
|
107
|
+
index: number;
|
|
108
|
+
side: SplitSide;
|
|
109
|
+
diffFile: DiffFile;
|
|
110
|
+
lineNumber: number;
|
|
111
|
+
}) => {
|
|
112
|
+
const { useWidget } = useDiffWidgetContext();
|
|
113
|
+
|
|
114
|
+
const { widgetLineNumber, widgetSide } = useWidget.useShallowStableSelector((s) => ({
|
|
115
|
+
widgetLineNumber: s.widgetLineNumber,
|
|
116
|
+
widgetSide: s.widgetSide,
|
|
117
|
+
}));
|
|
118
|
+
|
|
119
|
+
const oldLine = diffFile.getSplitLeftLine(index);
|
|
120
|
+
|
|
121
|
+
const newLine = diffFile.getSplitRightLine(index);
|
|
122
|
+
|
|
123
|
+
const oldLineWidget = oldLine.lineNumber && widgetSide === SplitSide.old && widgetLineNumber === oldLine.lineNumber;
|
|
124
|
+
|
|
125
|
+
const newLineWidget = newLine.lineNumber && widgetSide === SplitSide.new && widgetLineNumber === newLine.lineNumber;
|
|
126
|
+
|
|
127
|
+
const currentIsShow = oldLineWidget || newLineWidget;
|
|
128
|
+
|
|
129
|
+
if (!currentIsShow) return null;
|
|
130
|
+
|
|
131
|
+
return <InternalDiffSplitWidgetLine index={index} diffFile={diffFile} side={side} lineNumber={lineNumber} />;
|
|
132
|
+
};
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { borderColorName, emptyBGName } from "@git-diff-view/utils";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
|
|
4
|
+
import { SplitSide } from "../DiffView";
|
|
5
|
+
import { useDiffViewContext } from "../DiffViewContext";
|
|
6
|
+
import { useDiffWidgetContext } from "../DiffWidgetContext";
|
|
7
|
+
|
|
8
|
+
import type { DiffFile } from "@git-diff-view/core";
|
|
9
|
+
|
|
10
|
+
const InternalDiffSplitWidgetLine = ({
|
|
11
|
+
index,
|
|
12
|
+
diffFile,
|
|
13
|
+
lineNumber,
|
|
14
|
+
oldLineWidget,
|
|
15
|
+
newLineWidget,
|
|
16
|
+
}: {
|
|
17
|
+
index: number;
|
|
18
|
+
diffFile: DiffFile;
|
|
19
|
+
lineNumber: number;
|
|
20
|
+
oldLineWidget: boolean;
|
|
21
|
+
newLineWidget: boolean;
|
|
22
|
+
}) => {
|
|
23
|
+
const { useWidget } = useDiffWidgetContext();
|
|
24
|
+
|
|
25
|
+
const setWidget = useWidget.getReadonlyState().setWidget;
|
|
26
|
+
|
|
27
|
+
const { useDiffContext } = useDiffViewContext();
|
|
28
|
+
|
|
29
|
+
const renderWidgetLine = useDiffContext.useShallowStableSelector((s) => s.renderWidgetLine);
|
|
30
|
+
|
|
31
|
+
const oldLine = diffFile.getSplitLeftLine(index);
|
|
32
|
+
|
|
33
|
+
const newLine = diffFile.getSplitRightLine(index);
|
|
34
|
+
|
|
35
|
+
if (!renderWidgetLine) return null;
|
|
36
|
+
|
|
37
|
+
const oldWidgetRendered =
|
|
38
|
+
oldLineWidget &&
|
|
39
|
+
renderWidgetLine?.({
|
|
40
|
+
diffFile,
|
|
41
|
+
side: SplitSide.old,
|
|
42
|
+
lineNumber: oldLine.lineNumber,
|
|
43
|
+
onClose: () => setWidget({}),
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const newWidgetRendered =
|
|
47
|
+
newLineWidget &&
|
|
48
|
+
renderWidgetLine?.({
|
|
49
|
+
diffFile,
|
|
50
|
+
side: SplitSide.new,
|
|
51
|
+
lineNumber: newLine.lineNumber,
|
|
52
|
+
onClose: () => setWidget({}),
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<div data-line={`${lineNumber}-widget`} data-state="widget" className="diff-line diff-line-widget flex">
|
|
57
|
+
{oldWidgetRendered ? (
|
|
58
|
+
<div className="diff-line-widget-old-content w-[50%] p-0">
|
|
59
|
+
<div className="diff-line-widget-wrapper">{oldWidgetRendered}</div>
|
|
60
|
+
</div>
|
|
61
|
+
) : (
|
|
62
|
+
<div
|
|
63
|
+
className="diff-line-widget-old-placeholder w-[50%] select-none p-0"
|
|
64
|
+
style={{ backgroundColor: `var(${emptyBGName})` }}
|
|
65
|
+
/>
|
|
66
|
+
)}
|
|
67
|
+
<div className="diff-split-line w-[1px] flex-shrink-0" style={{ backgroundColor: `var(${borderColorName})` }} />
|
|
68
|
+
{newWidgetRendered ? (
|
|
69
|
+
<div className="diff-line-widget-new-content w-[50%] p-0">
|
|
70
|
+
<div className="diff-line-widget-wrapper">{newWidgetRendered}</div>
|
|
71
|
+
</div>
|
|
72
|
+
) : (
|
|
73
|
+
<div
|
|
74
|
+
className="diff-line-widget-new-placeholder w-[50%] select-none p-0"
|
|
75
|
+
style={{ backgroundColor: `var(${emptyBGName})` }}
|
|
76
|
+
/>
|
|
77
|
+
)}
|
|
78
|
+
</div>
|
|
79
|
+
);
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export const DiffSplitWidgetLine = ({
|
|
83
|
+
index,
|
|
84
|
+
diffFile,
|
|
85
|
+
lineNumber,
|
|
86
|
+
}: {
|
|
87
|
+
index: number;
|
|
88
|
+
diffFile: DiffFile;
|
|
89
|
+
lineNumber: number;
|
|
90
|
+
}) => {
|
|
91
|
+
const { useWidget } = useDiffWidgetContext();
|
|
92
|
+
|
|
93
|
+
const { widgetLineNumber, widgetSide } = useWidget.useShallowStableSelector((s) => ({
|
|
94
|
+
widgetLineNumber: s.widgetLineNumber,
|
|
95
|
+
widgetSide: s.widgetSide,
|
|
96
|
+
}));
|
|
97
|
+
|
|
98
|
+
const oldLine = diffFile.getSplitLeftLine(index);
|
|
99
|
+
|
|
100
|
+
const newLine = diffFile.getSplitRightLine(index);
|
|
101
|
+
|
|
102
|
+
const oldLineWidget = oldLine.lineNumber && widgetSide === SplitSide.old && widgetLineNumber === oldLine.lineNumber;
|
|
103
|
+
|
|
104
|
+
const newLineWidget = newLine.lineNumber && widgetSide === SplitSide.new && widgetLineNumber === newLine.lineNumber;
|
|
105
|
+
|
|
106
|
+
const currentIsShow = oldLineWidget || newLineWidget;
|
|
107
|
+
|
|
108
|
+
if (!currentIsShow) return null;
|
|
109
|
+
|
|
110
|
+
return (
|
|
111
|
+
<InternalDiffSplitWidgetLine
|
|
112
|
+
index={index}
|
|
113
|
+
diffFile={diffFile}
|
|
114
|
+
lineNumber={lineNumber}
|
|
115
|
+
oldLineWidget={oldLineWidget}
|
|
116
|
+
newLineWidget={newLineWidget}
|
|
117
|
+
/>
|
|
118
|
+
);
|
|
119
|
+
};
|
package/src/global.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { useCallback, useRef } from "react";
|
|
2
|
+
|
|
3
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
4
|
+
export const useCallbackRef = <T extends Function>(cb?: T): T => {
|
|
5
|
+
const cbRef = useRef(cb);
|
|
6
|
+
|
|
7
|
+
cbRef.current = cb;
|
|
8
|
+
|
|
9
|
+
const stableCallback = useCallback((...args: any[]) => {
|
|
10
|
+
if (args.length) {
|
|
11
|
+
return cbRef.current?.(...args);
|
|
12
|
+
} else {
|
|
13
|
+
return cbRef.current?.();
|
|
14
|
+
}
|
|
15
|
+
}, []) as unknown as T;
|
|
16
|
+
|
|
17
|
+
return stableCallback;
|
|
18
|
+
};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
|
|
3
|
+
import { useDiffViewContext } from "../components/DiffViewContext";
|
|
4
|
+
|
|
5
|
+
export type ObserveElement = HTMLElement & {
|
|
6
|
+
__observeCallback: Set<() => void>;
|
|
7
|
+
__observeInstance: ResizeObserver;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export const useDomWidth = ({ selector, enable }: { selector: string; enable: boolean }) => {
|
|
11
|
+
const [width, setWidth] = useState(0);
|
|
12
|
+
|
|
13
|
+
const { useDiffContext } = useDiffViewContext();
|
|
14
|
+
|
|
15
|
+
const { id, mounted } = useDiffContext.useShallowStableSelector((s) => ({ id: s.id, mounted: s.mounted }));
|
|
16
|
+
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
if (enable) {
|
|
19
|
+
const container = document.querySelector(`#diff-root${id}`);
|
|
20
|
+
|
|
21
|
+
const wrapper = container?.querySelector(selector);
|
|
22
|
+
|
|
23
|
+
if (!wrapper) return;
|
|
24
|
+
|
|
25
|
+
const typedWrapper = wrapper as ObserveElement;
|
|
26
|
+
|
|
27
|
+
const cb = () => {
|
|
28
|
+
const rect = wrapper?.getBoundingClientRect();
|
|
29
|
+
setWidth(rect?.width ?? 0);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
cb();
|
|
33
|
+
|
|
34
|
+
const cleanCb = () => {
|
|
35
|
+
typedWrapper.__observeCallback.delete(cb);
|
|
36
|
+
if (typedWrapper.__observeCallback.size === 0) {
|
|
37
|
+
typedWrapper.__observeInstance?.disconnect();
|
|
38
|
+
typedWrapper.removeAttribute("data-observe");
|
|
39
|
+
delete typedWrapper.__observeCallback;
|
|
40
|
+
delete typedWrapper.__observeInstance;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
if (typedWrapper.__observeCallback) {
|
|
45
|
+
typedWrapper.__observeCallback.add(cb);
|
|
46
|
+
|
|
47
|
+
return () => cleanCb();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
typedWrapper.__observeCallback = new Set();
|
|
51
|
+
|
|
52
|
+
typedWrapper.__observeCallback.add(cb);
|
|
53
|
+
|
|
54
|
+
const observer = new ResizeObserver(() => typedWrapper.__observeCallback.forEach((cb) => cb()));
|
|
55
|
+
|
|
56
|
+
typedWrapper.__observeInstance = observer;
|
|
57
|
+
|
|
58
|
+
observer.observe(typedWrapper);
|
|
59
|
+
|
|
60
|
+
typedWrapper.setAttribute("data-observe", "height");
|
|
61
|
+
|
|
62
|
+
return () => cleanCb();
|
|
63
|
+
}
|
|
64
|
+
}, [selector, enable, id, mounted]);
|
|
65
|
+
|
|
66
|
+
return width;
|
|
67
|
+
};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
|
|
3
|
+
import { useDiffViewContext } from "../components/DiffViewContext";
|
|
4
|
+
|
|
5
|
+
import type { ObserveElement } from "./useDomWidth";
|
|
6
|
+
|
|
7
|
+
export const useSyncHeight = ({
|
|
8
|
+
selector,
|
|
9
|
+
wrapper,
|
|
10
|
+
side,
|
|
11
|
+
enable,
|
|
12
|
+
}: {
|
|
13
|
+
selector: string;
|
|
14
|
+
wrapper?: string;
|
|
15
|
+
side: string;
|
|
16
|
+
enable: boolean;
|
|
17
|
+
}) => {
|
|
18
|
+
const { useDiffContext } = useDiffViewContext();
|
|
19
|
+
|
|
20
|
+
const { id, mounted } = useDiffContext.useShallowStableSelector((s) => ({ id: s.id, mounted: s.mounted }));
|
|
21
|
+
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
if (enable) {
|
|
24
|
+
const container = document.querySelector(`#diff-root${id}`);
|
|
25
|
+
|
|
26
|
+
const elements = Array.from(container?.querySelectorAll(selector) || []);
|
|
27
|
+
|
|
28
|
+
const wrappers = wrapper ? Array.from(container?.querySelectorAll(wrapper) || []) : elements;
|
|
29
|
+
|
|
30
|
+
if (elements.length === 2 && wrappers.length === 2) {
|
|
31
|
+
const ele1 = elements[0] as HTMLElement;
|
|
32
|
+
const ele2 = elements[1] as HTMLElement;
|
|
33
|
+
|
|
34
|
+
const wrapper1 = wrappers[0] as HTMLElement;
|
|
35
|
+
const wrapper2 = wrappers[1] as HTMLElement;
|
|
36
|
+
|
|
37
|
+
const target = ele1.getAttribute("data-side") === side ? ele1 : ele2;
|
|
38
|
+
|
|
39
|
+
const typedTarget = target as ObserveElement;
|
|
40
|
+
|
|
41
|
+
const cb = () => {
|
|
42
|
+
ele1.style.height = "auto";
|
|
43
|
+
ele2.style.height = "auto";
|
|
44
|
+
const rect1 = ele1.getBoundingClientRect();
|
|
45
|
+
const rect2 = ele2.getBoundingClientRect();
|
|
46
|
+
const maxHeight = Math.max(rect1.height, rect2.height);
|
|
47
|
+
wrapper1.style.height = maxHeight + "px";
|
|
48
|
+
wrapper2.style.height = maxHeight + "px";
|
|
49
|
+
wrapper1.setAttribute("data-sync-height", String(maxHeight));
|
|
50
|
+
wrapper2.setAttribute("data-sync-height", String(maxHeight));
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
cb();
|
|
54
|
+
|
|
55
|
+
const cleanCb = () => {
|
|
56
|
+
typedTarget.__observeCallback.delete(cb);
|
|
57
|
+
if (typedTarget.__observeCallback.size === 0) {
|
|
58
|
+
typedTarget.__observeInstance?.disconnect();
|
|
59
|
+
typedTarget.removeAttribute("data-observe");
|
|
60
|
+
delete typedTarget.__observeCallback;
|
|
61
|
+
delete typedTarget.__observeInstance;
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
if (typedTarget.__observeCallback) {
|
|
66
|
+
typedTarget.__observeCallback.add(cb);
|
|
67
|
+
|
|
68
|
+
return () => cleanCb();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
typedTarget.__observeCallback = new Set();
|
|
72
|
+
|
|
73
|
+
typedTarget.__observeCallback.add(cb);
|
|
74
|
+
|
|
75
|
+
const observer = new ResizeObserver(() => typedTarget.__observeCallback.forEach((cb) => cb()));
|
|
76
|
+
|
|
77
|
+
typedTarget.__observeInstance = observer;
|
|
78
|
+
|
|
79
|
+
observer.observe(target);
|
|
80
|
+
|
|
81
|
+
target.setAttribute("data-observe", "height");
|
|
82
|
+
|
|
83
|
+
return () => cleanCb();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}, [selector, enable, side, id, wrapper, mounted]);
|
|
87
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { getTextMeasureInstance } from "@git-diff-view/utils";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
|
|
4
|
+
import { useSafeLayout } from "./useSafeLayout";
|
|
5
|
+
|
|
6
|
+
export const useTextWidth = ({
|
|
7
|
+
text,
|
|
8
|
+
font,
|
|
9
|
+
}: {
|
|
10
|
+
text: string;
|
|
11
|
+
font: { fontFamily?: string; fontStyle?: string; fontSize?: string };
|
|
12
|
+
}) => {
|
|
13
|
+
const [width, setWidth] = useState(() => {
|
|
14
|
+
const fontSize = parseInt(font.fontSize);
|
|
15
|
+
let baseSize = 6;
|
|
16
|
+
baseSize += fontSize > 10 ? (fontSize - 10) * 0.6 : 0;
|
|
17
|
+
return baseSize * text.length;
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
useSafeLayout(() => {
|
|
21
|
+
const width = getTextMeasureInstance().measure(text, font);
|
|
22
|
+
|
|
23
|
+
setWidth(width);
|
|
24
|
+
}, [text, font]);
|
|
25
|
+
|
|
26
|
+
return width;
|
|
27
|
+
};
|
package/src/index.ts
ADDED
package/src/tailwind.css
ADDED
|
@@ -255,7 +255,7 @@
|
|
|
255
255
|
}
|
|
256
256
|
.diff-tailwindcss-wrapper .\!text-red-500 {
|
|
257
257
|
--tw-text-opacity: 1 !important;
|
|
258
|
-
color: rgb(239 68 68 / var(--tw-text-opacity)) !important;
|
|
258
|
+
color: rgb(239 68 68 / var(--tw-text-opacity, 1)) !important;
|
|
259
259
|
}
|
|
260
260
|
.diff-tailwindcss-wrapper .opacity-\[0\.5\] {
|
|
261
261
|
opacity: 0.5;
|
|
@@ -280,7 +280,9 @@
|
|
|
280
280
|
--diff-plain-content--: #ffffff;
|
|
281
281
|
--diff-expand-content--: #fafafa;
|
|
282
282
|
--diff-plain-lineNumber--: #fafafa;
|
|
283
|
+
--diff-expand-lineNumber--: #fafafa;
|
|
283
284
|
--diff-plain-lineNumber-color--: #555555;
|
|
285
|
+
--diff-expand-lineNumber-color--: #555555;
|
|
284
286
|
--diff-hunk-content--: #ddf4ff;
|
|
285
287
|
--diff-hunk-lineNumber--: #c7ecff;
|
|
286
288
|
--diff-hunk-lineNumber-hover--: #0969da;
|
|
@@ -307,7 +309,9 @@
|
|
|
307
309
|
--diff-plain-content--: #0d1117;
|
|
308
310
|
--diff-expand-content--: #161b22;
|
|
309
311
|
--diff-plain-lineNumber--: #161b22;
|
|
312
|
+
--diff-expand-lineNumber--: #161b22;
|
|
310
313
|
--diff-plain-lineNumber-color--: #a0aaab;
|
|
314
|
+
--diff-expand-lineNumber-color--: #a0aaab;
|
|
311
315
|
--diff-hunk-content--: #131d2e;
|
|
312
316
|
--diff-hunk-lineNumber--: #204274;
|
|
313
317
|
--diff-hunk-lineNumber-hover--: #1f6feb;
|
package/styles/diff-view.css
CHANGED
|
@@ -105,7 +105,7 @@
|
|
|
105
105
|
--tw-contain-paint: ;
|
|
106
106
|
--tw-contain-style: ;
|
|
107
107
|
}/*
|
|
108
|
-
! tailwindcss v3.4.
|
|
108
|
+
! tailwindcss v3.4.17 | MIT License | https://tailwindcss.com
|
|
109
109
|
*//*
|
|
110
110
|
1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
|
|
111
111
|
2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)
|
|
@@ -761,7 +761,7 @@ video {
|
|
|
761
761
|
}
|
|
762
762
|
.diff-tailwindcss-wrapper .\!text-red-500 {
|
|
763
763
|
--tw-text-opacity: 1 !important;
|
|
764
|
-
color: rgb(239 68 68 / var(--tw-text-opacity)) !important;
|
|
764
|
+
color: rgb(239 68 68 / var(--tw-text-opacity, 1)) !important;
|
|
765
765
|
}
|
|
766
766
|
.diff-tailwindcss-wrapper .opacity-\[0\.5\] {
|
|
767
767
|
opacity: 0.5;
|
|
@@ -786,7 +786,9 @@ video {
|
|
|
786
786
|
--diff-plain-content--: #ffffff;
|
|
787
787
|
--diff-expand-content--: #fafafa;
|
|
788
788
|
--diff-plain-lineNumber--: #fafafa;
|
|
789
|
+
--diff-expand-lineNumber--: #fafafa;
|
|
789
790
|
--diff-plain-lineNumber-color--: #555555;
|
|
791
|
+
--diff-expand-lineNumber-color--: #555555;
|
|
790
792
|
--diff-hunk-content--: #ddf4ff;
|
|
791
793
|
--diff-hunk-lineNumber--: #c7ecff;
|
|
792
794
|
--diff-hunk-lineNumber-hover--: #0969da;
|
|
@@ -813,7 +815,9 @@ video {
|
|
|
813
815
|
--diff-plain-content--: #0d1117;
|
|
814
816
|
--diff-expand-content--: #161b22;
|
|
815
817
|
--diff-plain-lineNumber--: #161b22;
|
|
818
|
+
--diff-expand-lineNumber--: #161b22;
|
|
816
819
|
--diff-plain-lineNumber-color--: #a0aaab;
|
|
820
|
+
--diff-expand-lineNumber-color--: #a0aaab;
|
|
817
821
|
--diff-hunk-content--: #131d2e;
|
|
818
822
|
--diff-hunk-lineNumber--: #204274;
|
|
819
823
|
--diff-hunk-lineNumber-hover--: #1f6feb;
|