Skip to content

Commit a0b43cd

Browse files
fix cli component
1 parent 0ed9a41 commit a0b43cd

File tree

7 files changed

+110
-22
lines changed

7 files changed

+110
-22
lines changed

packages/cli/src/components/DiffSplitView.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ export const DiffSplitView = memo(({ diffFile }: { diffFile: DiffFile }) => {
2626

2727
const lines = getSplitContentLines(diffFile);
2828

29+
if (!columns) return null;
30+
2931
return (
3032
<>
3133
{lines.map((line) => (

packages/cli/src/components/DiffUnifiedView.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ export const DiffUnifiedView = memo(({ diffFile }: { diffFile: DiffFile }) => {
2929

3030
const lines = getUnifiedContentLine(diffFile);
3131

32+
if (!columns) return null;
33+
3234
return (
3335
<>
3436
{lines.map((item) => (

packages/cli/src/components/DiffView.tsx

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import { DiffViewContext } from "./DiffViewContext";
1212
import { createDiffConfigStore } from "./tools";
1313

1414
import type { DiffHighlighter, DiffHighlighterLang } from "@git-diff-view/core";
15+
import type { DOMElement } from "ink";
16+
import type { RefObject } from "react";
1517

1618
_cacheMap.name = "@git-diff-view/cli";
1719

@@ -23,6 +25,7 @@ export type DiffViewProps = {
2325
newFile?: { fileName?: string | null; fileLang?: DiffHighlighterLang | string | null; content?: string | null };
2426
hunks: string[];
2527
};
28+
width?: number;
2629
diffFile?: DiffFile;
2730
diffViewMode?: DiffModeEnum;
2831
diffViewTheme?: "light" | "dark";
@@ -49,9 +52,10 @@ type DiffViewProps_2 = Omit<DiffViewProps, "data"> & {
4952
const InternalDiffView = (
5053
props: Omit<DiffViewProps, "data"> & {
5154
isMounted: boolean;
55+
wrapperRef?: RefObject<DOMElement>;
5256
}
5357
) => {
54-
const { diffFile, diffViewMode, diffViewHighlight, isMounted } = props;
58+
const { diffFile, diffViewMode, diffViewHighlight, isMounted, wrapperRef } = props;
5559

5660
const diffFileId = useMemo(() => diffFile.getId(), [diffFile]);
5761

@@ -79,6 +83,13 @@ const InternalDiffView = (
7983
}
8084
}, [useDiffContext, diffViewHighlight, diffViewMode, diffFileId, isMounted]);
8185

86+
useEffect(() => {
87+
const { wrapper, setWrapper } = useDiffContext.getReadonlyState();
88+
if (wrapperRef.current !== wrapper.current) {
89+
setWrapper(wrapperRef.current);
90+
}
91+
});
92+
8293
const value = useMemo(() => ({ useDiffContext }), [useDiffContext]);
8394

8495
return (
@@ -102,8 +113,10 @@ const InternalDiffView = (
102113

103114
const MemoedInternalDiffView = memo(InternalDiffView);
104115

105-
const DiffViewWithRef = (props: DiffViewProps) => {
106-
const { registerHighlighter, data, diffViewTheme, diffFile: _diffFile, ...restProps } = props;
116+
const DiffViewContainer = (props: DiffViewProps) => {
117+
const { registerHighlighter, data, diffViewTheme, diffFile: _diffFile, width, ...restProps } = props;
118+
119+
const ref = useRef<DOMElement>(null);
107120

108121
const diffFile = useMemo(() => {
109122
if (_diffFile) {
@@ -167,22 +180,30 @@ const DiffViewWithRef = (props: DiffViewProps) => {
167180
if (!diffFile) return null;
168181

169182
return (
170-
<MemoedInternalDiffView
171-
key={diffFile.getId()}
172-
{...restProps}
173-
diffFile={diffFile}
174-
isMounted={isMounted}
175-
diffViewTheme={diffViewTheme}
176-
diffViewMode={restProps.diffViewMode || DiffModeEnum.SplitGitHub}
177-
/>
183+
<Box
184+
ref={ref}
185+
width={width}
186+
flexGrow={typeof width === "number" ? undefined : 1}
187+
flexShrink={typeof width === "number" ? 0 : undefined}
188+
>
189+
<MemoedInternalDiffView
190+
key={diffFile.getId()}
191+
{...restProps}
192+
wrapperRef={ref}
193+
diffFile={diffFile}
194+
isMounted={isMounted}
195+
diffViewTheme={diffViewTheme}
196+
diffViewMode={restProps.diffViewMode || DiffModeEnum.SplitGitHub}
197+
/>
198+
</Box>
178199
);
179200
};
180201

181202
// type helper function
182203
function ReactDiffView(props: DiffViewProps_1): JSX.Element;
183204
function ReactDiffView(props: DiffViewProps_2): JSX.Element;
184205
function ReactDiffView(props: DiffViewProps) {
185-
return <DiffViewWithRef {...props} />;
206+
return <DiffViewContainer {...props} />;
186207
}
187208

188209
export const DiffView = ReactDiffView;

packages/cli/src/components/tools.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
import { createStore, ref } from "reactivity-store";
1+
import { createStore, markRaw, ref } from "reactivity-store";
22

33
import type { DiffModeEnum, DiffViewProps } from "./DiffView";
44
import type { DiffLine } from "@git-diff-view/core";
5+
import type { DOMElement } from "ink";
6+
import type { Ref, UseSelectorWithStore } from "reactivity-store";
57

68
export const createDiffConfigStore = (props: DiffViewProps & { isMounted: boolean }, diffFileId: string) => {
79
return createStore(() => {
@@ -13,6 +15,10 @@ export const createDiffConfigStore = (props: DiffViewProps & { isMounted: boolea
1315

1416
const setMode = (_mode: DiffModeEnum) => (mode.value = _mode);
1517

18+
const wrapper = ref<{ current: DOMElement }>(markRaw({ current: null }));
19+
20+
const setWrapper = (_wrapper?: DOMElement) => (wrapper.value = markRaw({ current: _wrapper }));
21+
1622
const mounted = ref(props.isMounted);
1723

1824
const setMounted = (_mounted: boolean) => (mounted.value = _mounted);
@@ -26,12 +32,26 @@ export const createDiffConfigStore = (props: DiffViewProps & { isMounted: boolea
2632
setId,
2733
mode,
2834
setMode,
35+
wrapper,
36+
setWrapper,
2937
mounted,
3038
setMounted,
3139
enableHighlight,
3240
setEnableHighlight,
3341
};
34-
});
42+
// fix rollup type error
43+
}) as UseSelectorWithStore<{
44+
id: Ref<string>;
45+
setId: (id: string) => void;
46+
mode: Ref<DiffModeEnum>;
47+
setMode: (mode: DiffModeEnum) => void;
48+
wrapper: Ref<{ current: DOMElement }>;
49+
setWrapper: (wrapper?: DOMElement) => void;
50+
mounted: Ref<boolean>;
51+
setMounted: (mounted: boolean) => void;
52+
enableHighlight: Ref<boolean>;
53+
setEnableHighlight: (enableHighlight: boolean) => void;
54+
}>;
3555
};
3656

3757
export const getCurrentLineRow = ({ content, width }: { content: string; width: number }) => {

packages/cli/src/hooks/useTerminalSize.ts

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1+
import { measureElement } from "ink";
12
import { useEffect, useState } from "react";
23

4+
import { useDiffViewContext } from "../components/DiffViewContext";
5+
6+
import type { DOMElement } from "ink";
7+
38
const TERMINAL_PADDING_X = 4;
49

510
const getValidColumns = (columns: number): number => {
@@ -11,24 +16,40 @@ const getValidColumns = (columns: number): number => {
1116
};
1217

1318
export function useTerminalSize(): { columns: number; rows: number } {
19+
const { useDiffContext } = useDiffViewContext();
20+
21+
const wrapper = useDiffContext((s) => s.wrapper);
22+
1423
const [size, setSize] = useState({
15-
columns: getValidColumns((process.stdout.columns || 60) - TERMINAL_PADDING_X),
24+
columns: 0,
1625
rows: process.stdout.rows || 20,
1726
});
1827

1928
useEffect(() => {
2029
function updateSize() {
30+
const terminalWidth = getValidColumns((process.stdout.columns || 60) - TERMINAL_PADDING_X);
31+
32+
let width = terminalWidth;
33+
34+
if (wrapper.current) {
35+
width = getValidColumns(measureElement(wrapper.current as DOMElement).width);
36+
}
37+
38+
width = Math.min(width, terminalWidth);
39+
2140
setSize({
22-
columns: getValidColumns((process.stdout.columns || 60) - TERMINAL_PADDING_X),
41+
columns: width,
2342
rows: process.stdout.rows || 20,
2443
});
2544
}
2645

46+
updateSize();
47+
2748
process.stdout.on("resize", updateSize);
2849
return () => {
2950
process.stdout.off("resize", updateSize);
3051
};
31-
}, []);
52+
}, [wrapper]);
3253

3354
return size;
3455
}

packages/cli/test/index.mjs

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { getDiffViewHighlighter } from "@git-diff-view/shiki";
2-
import { createElement } from "@my-react/react";
3-
import { render } from "@my-react/react-terminal";
4-
// import { render } from "ink";
5-
// import { createElement } from "react";
2+
// import { createElement } from "@my-react/react";
3+
// import { render } from "@my-react/react-terminal";
4+
import { render } from "ink";
5+
import { createElement } from "react";
66

77
import { DiffView, DiffModeEnum } from "@git-diff-view/cli";
88

@@ -61,13 +61,34 @@ index 5b301628..15aac42f 100644
6161

6262
getDiffViewHighlighter().then((highlighter) => {
6363
render(
64+
// createElement(
65+
// Box,
66+
// { flexShrink: 0, flexGrow: 1 },
67+
// null,
68+
// createElement(DiffView, {
69+
// data: { hunks: [hunks], newFile: { fileLang: "tsx" } },
70+
// diffViewTheme: "light",
71+
// diffViewHighlight: true,
72+
// diffViewMode: DiffModeEnum.SplitGitLab,
73+
// }),
74+
// createElement(Box, { flexGrow: 1, flexShrink: 0 }, createElement(Text, null, "Diff View: Split Mode")),
75+
// createElement(DiffView, {
76+
// data: { hunks: [hunks], newFile: { fileLang: "tsx" } },
77+
// width: 60,
78+
// diffViewTheme: "light",
79+
// diffViewHighlight: true,
80+
// registerHighlighter: highlighter,
81+
// diffViewMode: DiffModeEnum.Split,
82+
// }),
6483
createElement(DiffView, {
65-
data: { hunks: [hunks], newFile: { fileLang: 'tsx' } },
84+
data: { hunks: [hunks], newFile: { fileLang: "tsx" } },
85+
width: 80,
6686
diffViewTheme: "light",
6787
diffViewHighlight: true,
6888
registerHighlighter: highlighter,
6989
diffViewMode: DiffModeEnum.Split,
7090
})
91+
// )
7192
);
7293
});
7394

scripts/build.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ const start = async () => {
113113
await buildUtils();
114114
await buildCore();
115115
await buildFile();
116+
await buildCli();
116117
await buildReact();
117118
await buildSolid();
118119
await buildSvelte();

0 commit comments

Comments
 (0)