Skip to content
This repository was archived by the owner on Nov 6, 2018. It is now read-only.

Commit 5973a14

Browse files
committed
feat: support themeable decorations (light vs. dark styles)
Decorations may now specify different styles for light vs. dark themes. The light/dark styles override the base styles when there is overlap.
1 parent a79ccc5 commit 5973a14

File tree

3 files changed

+136
-14
lines changed

3 files changed

+136
-14
lines changed

src/client/providers/decoration.test.ts

+64-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@ import { of } from 'rxjs'
33
import { TestScheduler } from 'rxjs/testing'
44
import { TextDocumentIdentifier } from '../../client/types/textDocument'
55
import { TextDocumentDecoration } from '../../protocol/plainTypes'
6-
import { getDecorations, ProvideTextDocumentDecorationSignature } from './decoration'
6+
import {
7+
decorationAttachmentStyleForTheme,
8+
decorationStyleForTheme,
9+
getDecorations,
10+
ProvideTextDocumentDecorationSignature,
11+
} from './decoration'
712
import { FIXTURE as COMMON_FIXTURE } from './registry.test'
813

914
const FIXTURE = {
@@ -125,3 +130,61 @@ describe('getDecorations', () => {
125130
))
126131
})
127132
})
133+
134+
describe('decorationStyleForTheme', () => {
135+
const FIXTURE_RANGE = { start: { line: 1, character: 2 }, end: { line: 3, character: 4 } }
136+
137+
it('supports no theme overrides', () =>
138+
assert.deepStrictEqual(decorationStyleForTheme({ range: FIXTURE_RANGE, backgroundColor: 'red' }, true), {
139+
range: FIXTURE_RANGE, // it's not necessary that range is included, but it saves an object allocation
140+
backgroundColor: 'red',
141+
}))
142+
143+
it('applies light theme overrides', () =>
144+
assert.deepStrictEqual(
145+
decorationStyleForTheme(
146+
{ range: FIXTURE_RANGE, backgroundColor: 'red', light: { backgroundColor: 'blue' } },
147+
true
148+
),
149+
{
150+
backgroundColor: 'blue',
151+
}
152+
))
153+
154+
it('applies dark theme overrides', () =>
155+
assert.deepStrictEqual(
156+
decorationStyleForTheme(
157+
{
158+
range: FIXTURE_RANGE,
159+
backgroundColor: 'red',
160+
light: { backgroundColor: 'blue' },
161+
dark: { backgroundColor: 'green' },
162+
},
163+
false
164+
),
165+
{
166+
backgroundColor: 'green',
167+
}
168+
))
169+
})
170+
171+
describe('decorationAttachmentStyleForTheme', () => {
172+
it('supports no theme overrides', () =>
173+
assert.deepStrictEqual(decorationAttachmentStyleForTheme({ color: 'red' }, true), { color: 'red' }))
174+
175+
it('applies light theme overrides', () =>
176+
assert.deepStrictEqual(decorationAttachmentStyleForTheme({ color: 'red', light: { color: 'blue' } }, true), {
177+
color: 'blue',
178+
}))
179+
180+
it('applies dark theme overrides', () =>
181+
assert.deepStrictEqual(
182+
decorationAttachmentStyleForTheme(
183+
{ color: 'red', light: { color: 'blue' }, dark: { color: 'green' } },
184+
false
185+
),
186+
{
187+
color: 'green',
188+
}
189+
))
190+
})

src/client/providers/decoration.ts

+37
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import { combineLatest, Observable } from 'rxjs'
22
import { map, switchMap } from 'rxjs/operators'
3+
import {
4+
DecorationAttachmentRenderOptions,
5+
ThemableDecorationAttachmentStyle,
6+
ThemableDecorationStyle,
7+
} from 'sourcegraph'
38
import { TextDocumentIdentifier } from '../../client/types/textDocument'
49
import { TextDocumentDecoration } from '../../protocol/plainTypes'
510
import { FeatureProviderRegistry } from './registry'
@@ -40,3 +45,35 @@ export function getDecorations(
4045
)
4146
.pipe(map(flattenAndCompact))
4247
}
48+
49+
/**
50+
* Resolves the actual styles to use for the attachment based on the current theme.
51+
*/
52+
export function decorationStyleForTheme(
53+
attachment: TextDocumentDecoration,
54+
isLightTheme: boolean
55+
): ThemableDecorationStyle {
56+
const overrides = isLightTheme ? attachment.light : attachment.dark
57+
if (!overrides) {
58+
return attachment
59+
}
60+
// Discard non-ThemableDecorationStyle properties so they aren't included in result.
61+
const { range, isWholeLine, after, light, dark, ...base } = attachment
62+
return { ...base, ...overrides }
63+
}
64+
65+
/**
66+
* Resolves the actual styles to use for the attachment based on the current theme.
67+
*/
68+
export function decorationAttachmentStyleForTheme(
69+
attachment: DecorationAttachmentRenderOptions,
70+
isLightTheme: boolean
71+
): ThemableDecorationAttachmentStyle {
72+
const overrides = isLightTheme ? attachment.light : attachment.dark
73+
if (!overrides) {
74+
return attachment
75+
}
76+
// Discard non-ThemableDecorationAttachmentStyle properties so they aren't included in result.
77+
const { contentText, hoverMessage, linkURL, light, dark, ...base } = attachment
78+
return { ...base, ...overrides }
79+
}

src/sourcegraph.d.ts

+35-13
Original file line numberDiff line numberDiff line change
@@ -409,11 +409,28 @@ declare module 'sourcegraph' {
409409
*/
410410
export type ViewComponent = CodeEditor
411411

412+
/**
413+
* A style for a {@link TextDocumentDecoration}.
414+
*/
415+
export interface ThemableDecorationStyle {
416+
/** The CSS background-color property value for the line. */
417+
backgroundColor?: string
418+
419+
/** The CSS border property value for the line. */
420+
border?: string
421+
422+
/** The CSS border-color property value for the line. */
423+
borderColor?: string
424+
425+
/** The CSS border-width property value for the line. */
426+
borderWidth?: string
427+
}
428+
412429
/**
413430
* A text document decoration changes the appearance of a range in the document and/or adds other content to
414431
* it.
415432
*/
416-
export interface TextDocumentDecoration {
433+
export interface TextDocumentDecoration extends ThemableDecorationStyle {
417434
/**
418435
* The range that the decoration applies to. Currently, decorations are
419436
* only applied only on the start line, and the entire line. Multiline
@@ -430,27 +447,26 @@ declare module 'sourcegraph' {
430447
/** Content to display after the range. */
431448
after?: DecorationAttachmentRenderOptions
432449

433-
/** The CSS background-color property value for the line. */
434-
backgroundColor?: string
435-
436-
/** The CSS border property value for the line. */
437-
border?: string
438-
439-
/** The CSS border-color property value for the line. */
440-
borderColor?: string
450+
/** Overwrite style for light themes. */
451+
light?: ThemableDecorationStyle
441452

442-
/** The CSS border-width property value for the line. */
443-
borderWidth?: string
453+
/** Overwrite style for dark themes. */
454+
dark?: ThemableDecorationStyle
444455
}
445456

446-
/** A decoration attachment adds content after a {@link TextDocumentDecoration}. */
447-
export interface DecorationAttachmentRenderOptions {
457+
/**
458+
* A style for {@link DecorationAttachmentRenderOptions}.
459+
*/
460+
export interface ThemableDecorationAttachmentStyle {
448461
/** The CSS background-color property value for the attachment. */
449462
backgroundColor?: string
450463

451464
/** The CSS color property value for the attachment. */
452465
color?: string
466+
}
453467

468+
/** A decoration attachment adds content after a {@link TextDocumentDecoration}. */
469+
export interface DecorationAttachmentRenderOptions extends ThemableDecorationAttachmentStyle {
454470
/** Text to display in the attachment. */
455471
contentText?: string
456472

@@ -459,6 +475,12 @@ declare module 'sourcegraph' {
459475

460476
/** If set, the attachment becomes a link with this destination URL. */
461477
linkURL?: string
478+
479+
/** Overwrite style for light themes. */
480+
light?: ThemableDecorationAttachmentStyle
481+
482+
/** Overwrite style for dark themes. */
483+
dark?: ThemableDecorationAttachmentStyle
462484
}
463485

464486
/**

0 commit comments

Comments
 (0)