Skip to content

Commit 184788b

Browse files
committed
refactor: CodeEditor - diff minimap improvements, add selection color tokens
1 parent 844c079 commit 184788b

File tree

9 files changed

+79
-39
lines changed

9 files changed

+79
-39
lines changed

src/Common/CodeMirror/CodeEditor.constants.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,5 @@ export const READ_ONLY_TOOLTIP_TIMEOUT = 2000
3232
export const CODE_EDITOR_FONT_SIZE = 15
3333

3434
export const CODE_EDITOR_LINE_HEIGHT = 1.4
35+
36+
export const CODE_EDITOR_MIN_OVERLAY_HEIGHT = 20

src/Common/CodeMirror/CodeEditor.theme.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ export const getCodeEditorTheme = (isDark: boolean) => {
8282
gutterForeground: 'var(--N500)',
8383
gutterBorder: 'transparent',
8484
lineHighlight: 'var(--active-line)',
85+
selection: 'var(--selection-color)',
86+
selectionMatch: 'var(--selection-match-color)',
8587
},
8688
styles,
8789
theme: isDark ? 'dark' : 'light',

src/Common/CodeMirror/CodeEditor.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ const CodeEditor = <DiffView extends boolean = false>({
7575
onFocus,
7676
autoFocus,
7777
disableSearch = false,
78-
showDiffMinimap,
7978
}: CodeEditorProps<DiffView>) => {
8079
// HOOKS
8180
const { appTheme } = useTheme()
@@ -255,7 +254,6 @@ const CodeEditor = <DiffView extends boolean = false>({
255254
modifiedViewExtensions={modifiedViewExtensions}
256255
extensions={extensions}
257256
diffMinimapExtensions={diffMinimapExtensions}
258-
showDiffMinimap={showDiffMinimap}
259257
/>
260258
</CodeEditorContext.Provider>
261259
)

src/Common/CodeMirror/CodeEditorRenderer.tsx

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ export const CodeEditorRenderer = ({
4848
extensions,
4949
autoFocus,
5050
diffMinimapExtensions,
51-
showDiffMinimap = true,
5251
}: CodeEditorRendererProps) => {
5352
// CONTEXTS
5453
const { value, lhsValue, diffMode } = useCodeEditorContext()
@@ -197,15 +196,13 @@ export const CodeEditorRenderer = ({
197196
extensions={modifiedViewExtensions}
198197
/>
199198
</CodeMirrorMerge>
200-
{showDiffMinimap && (
201-
<DiffMinimap
202-
key={codeEditorDiffViewKey}
203-
theme={theme}
204-
codeEditorTheme={codeEditorTheme}
205-
view={codeMirrorMergeRef.current?.view}
206-
diffMinimapExtensions={diffMinimapExtensions}
207-
/>
208-
)}
199+
<DiffMinimap
200+
key={codeEditorDiffViewKey}
201+
theme={theme}
202+
codeEditorTheme={codeEditorTheme}
203+
view={codeMirrorMergeRef.current?.view}
204+
diffMinimapExtensions={diffMinimapExtensions}
205+
/>
209206
</div>
210207
) : (
211208
<div

src/Common/CodeMirror/Extensions/diffMinimap.tsx renamed to src/Common/CodeMirror/Extensions/DiffMinimap.tsx

Lines changed: 42 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
import { useEffect, useMemo, useRef, useState } from 'react'
2-
import { EditorView } from '@uiw/react-codemirror'
32
import CodeMirrorMerge, { CodeMirrorMergeRef } from 'react-codemirror-merge'
43

54
import { getComponentSpecificThemeClass } from '@Shared/Providers'
5+
import { useDebouncedEffect } from '@Common/DebouncedSearch/Utils'
66

77
import { DiffMinimapProps } from '../types'
8-
import { CODE_EDITOR_FONT_SIZE, CODE_EDITOR_LINE_HEIGHT } from '../CodeEditor.constants'
8+
import { CODE_EDITOR_FONT_SIZE, CODE_EDITOR_LINE_HEIGHT, CODE_EDITOR_MIN_OVERLAY_HEIGHT } from '../CodeEditor.constants'
9+
import { useCodeEditorContext } from '../CodeEditor.context'
10+
import { updateDiffMinimapValues } from '../utils'
11+
12+
export const DiffMinimap = ({ view, diffMinimapExtensions, codeEditorTheme, theme }: DiffMinimapProps) => {
13+
// CONTEXTS
14+
const { lhsValue, value } = useCodeEditorContext()
915

10-
export const DiffMinimap = ({ view, state, diffMinimapExtensions, codeEditorTheme, theme }: DiffMinimapProps) => {
1116
// STATES
1217
const [overlayTop, setOverlayTop] = useState<number>(0)
1318
const [overlayHeight, setOverlayHeight] = useState<number>(50)
@@ -24,12 +29,27 @@ export const DiffMinimap = ({ view, state, diffMinimapExtensions, codeEditorThem
2429
const componentSpecificThemeClass = getComponentSpecificThemeClass(theme)
2530

2631
const scalingFactor = useMemo(() => {
27-
if (view?.dom) {
28-
return view.dom.clientHeight / view.dom.scrollHeight
32+
if (view) {
33+
return Math.min(view.dom.clientHeight / view.dom.scrollHeight, 1)
2934
}
3035

3136
return 1
32-
}, [view?.a.state.doc.length, view?.b.state.doc.length])
37+
}, [lhsValue, value])
38+
39+
// SETTING INITIAL DIFF MINI MAP VALUES
40+
useEffect(() => {
41+
setTimeout(() => {
42+
updateDiffMinimapValues(minimapEditorRef.current?.view, value, lhsValue)
43+
}, 0)
44+
}, [])
45+
46+
useDebouncedEffect(
47+
() => {
48+
updateDiffMinimapValues(minimapEditorRef.current?.view, value, lhsValue)
49+
},
50+
300,
51+
[value, lhsValue, scalingFactor],
52+
)
3353

3454
// Update the overlay position and size
3555
const updateOverlay = () => {
@@ -40,11 +60,13 @@ export const DiffMinimap = ({ view, state, diffMinimapExtensions, codeEditorThem
4060
const { clientHeight, scrollHeight, scrollTop } = view.dom
4161
const minimapHeight = minimapContainerRef.current.clientHeight
4262

43-
const _overlayHeight = (clientHeight / scrollHeight) * minimapHeight
44-
const _overlayTop = (scrollTop / scrollHeight) * minimapHeight
63+
let computedHeight = (clientHeight / scrollHeight) * minimapHeight
64+
if (computedHeight < CODE_EDITOR_MIN_OVERLAY_HEIGHT) {
65+
computedHeight = CODE_EDITOR_MIN_OVERLAY_HEIGHT
66+
}
4567

46-
setOverlayHeight(_overlayHeight)
47-
setOverlayTop(_overlayTop)
68+
setOverlayHeight(computedHeight)
69+
setOverlayTop((scrollTop / scrollHeight) * (minimapHeight - computedHeight))
4870
}
4971

5072
useEffect(() => {
@@ -93,18 +115,18 @@ export const DiffMinimap = ({ view, state, diffMinimapExtensions, codeEditorThem
93115
}
94116

95117
useEffect(() => {
96-
if (view?.dom) {
118+
if (view) {
97119
const { dom } = view
98120
dom.addEventListener('scroll', handleDiffScroll)
99121
}
100122

101123
return () => {
102-
if (view?.dom) {
124+
if (view) {
103125
const { dom } = view
104126
dom.removeEventListener('scroll', handleDiffScroll)
105127
}
106128
}
107-
}, [view])
129+
}, [])
108130

109131
useEffect(() => {
110132
if (isDragging) {
@@ -132,13 +154,6 @@ export const DiffMinimap = ({ view, state, diffMinimapExtensions, codeEditorThem
132154
view.dom.scrollTo({ top: scrollRatio * (scrollHeight - clientHeight) })
133155
}
134156

135-
const minimapTheme = EditorView.theme({
136-
'&.cm-editor': {
137-
fontSize: `${scalingFactor * CODE_EDITOR_FONT_SIZE}px`,
138-
lineHeight: `${scalingFactor * CODE_EDITOR_LINE_HEIGHT}`,
139-
},
140-
})
141-
142157
return (
143158
<div
144159
ref={minimapContainerRef}
@@ -150,20 +165,23 @@ export const DiffMinimap = ({ view, state, diffMinimapExtensions, codeEditorThem
150165
theme={codeEditorTheme}
151166
className="code-editor__mini-map dc__overflow-hidden w-100"
152167
gutter={false}
168+
destroyRerender={false}
169+
style={{
170+
fontSize: `${scalingFactor * CODE_EDITOR_FONT_SIZE}px`,
171+
lineHeight: `${scalingFactor * CODE_EDITOR_LINE_HEIGHT}`,
172+
}}
153173
>
154174
<CodeMirrorMerge.Original
155175
basicSetup={false}
156-
value={state.lhsCode}
157176
readOnly
158177
editable={false}
159-
extensions={[...diffMinimapExtensions, minimapTheme]}
178+
extensions={diffMinimapExtensions}
160179
/>
161180
<CodeMirrorMerge.Modified
162181
basicSetup={false}
163-
value={state.code}
164182
readOnly
165183
editable={false}
166-
extensions={[...diffMinimapExtensions, minimapTheme]}
184+
extensions={diffMinimapExtensions}
167185
/>
168186
</CodeMirrorMerge>
169187
<div

src/Common/CodeMirror/Extensions/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,4 @@ export * from './yamlParseLinter'
1818
export * from './readOnlyTooltip'
1919
export * from './findAndReplace'
2020
export * from './yamlHighlight'
21-
export * from './diffMinimap'
21+
export * from './DiffMinimap'

src/Common/CodeMirror/codeEditor.scss

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,9 @@
246246
pointer-events: none;
247247

248248
.cm-editor {
249+
font-size: inherit;
250+
line-height: inherit;
251+
249252
&.cm-merge-a .cm-changedLine,
250253
.cm-deletedChunk,
251254
&.cm-merge-a .cm-changedText,

src/Common/CodeMirror/types.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ export type CodeEditorProps<DiffView extends boolean = false> = {
7878
disableSearch?: boolean
7979
diffView?: DiffView
8080
theme?: AppThemeType
81-
showDiffMinimap?: boolean
8281
} & CodeEditorPropsBasedOnDiffView<DiffView>
8382

8483
export interface GetCodeEditorHeightReturnType {
@@ -136,7 +135,6 @@ export type CodeEditorRendererProps = Required<
136135
| 'onBlur'
137136
| 'onFocus'
138137
| 'autoFocus'
139-
| 'showDiffMinimap'
140138
>
141139
> &
142140
Required<Pick<CodeEditorDiffBaseProps, 'isOriginalModifiable'>> & {

src/Common/CodeMirror/utils.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import { json, jsonLanguage, jsonParseLinter } from '@codemirror/lang-json'
2424
import { yaml, yamlLanguage } from '@codemirror/lang-yaml'
2525
import { shell } from '@codemirror/legacy-modes/mode/shell'
2626
import { dockerFile } from '@codemirror/legacy-modes/mode/dockerfile'
27+
import { CodeMirrorMergeRef } from 'react-codemirror-merge'
2728

2829
import { ReactComponent as ICCaretDown } from '@Icons/ic-caret-down.svg'
2930

@@ -135,6 +136,27 @@ export const getUpdatedSearchMatchesCount = (newQuery: SearchQuery, view: Editor
135136
return updatedMatchesCount
136137
}
137138

139+
export const updateDiffMinimapValues = (view: CodeMirrorMergeRef['view'], value: string, lhsValue: string) => {
140+
if (!view) {
141+
return
142+
}
143+
144+
const currentLhsValue = view.a.state.doc.toString()
145+
const currentRhsValue = view.b.state.doc.toString()
146+
147+
if (currentRhsValue !== value) {
148+
view.b.dispatch({
149+
changes: { from: 0, to: currentRhsValue.length, insert: value || '' },
150+
})
151+
}
152+
153+
if (currentLhsValue !== lhsValue) {
154+
view.a.dispatch({
155+
changes: { from: 0, to: currentLhsValue.length, insert: lhsValue || '' },
156+
})
157+
}
158+
}
159+
138160
// DOM HELPERS
139161
export const getFoldGutterElement = (open: boolean) => {
140162
const icon = document.createElement('span')

0 commit comments

Comments
 (0)