@fsegurai/codemirror-theme-high-contrast-light 6.0.0

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/src/index.ts ADDED
@@ -0,0 +1,481 @@
1
+ import { EditorView } from '@codemirror/view';
2
+ import { Extension } from '@codemirror/state';
3
+ import { HighlightStyle, syntaxHighlighting } from '@codemirror/language';
4
+ import { tags as t } from '@lezer/highlight';
5
+
6
+ import {
7
+ applyMergeRevertStyles,
8
+ generalContent,
9
+ generalDiff,
10
+ generalGutter,
11
+ generalLine,
12
+ generalMatching,
13
+ generalPanel,
14
+ generalPlaceholder,
15
+ generalScroller,
16
+ generalSearchField,
17
+ generalTooltip,
18
+ IMergeRevertStyles,
19
+ } from './utils';
20
+
21
+ /**
22
+ * High Contrast Light theme color definitions
23
+ * -------------------------------------------
24
+ * Maximum contrast theme for accessibility (light variant)
25
+ */
26
+
27
+ // Base colors - Pure white and black for maximum contrast
28
+ const base00 = '#ffffff', // Background - pure white
29
+ base01 = '#e0e0e0', // Selection background
30
+ base02 = '#707070', // Comments - medium grey
31
+ base03 = '#505050', // Dark grey
32
+ base04 = '#000000', // Foreground - pure black
33
+
34
+ // High contrast accent colors for a light background
35
+ darkBlue = '#0000ff',
36
+ darkCyan = '#008080',
37
+ darkGreen = '#008000',
38
+ darkRed = '#c80000',
39
+ darkMagenta = '#800080',
40
+ darkOrange = '#d04800',
41
+ darkPurple = '#6600cc',
42
+ darkBrown = '#7c3400';
43
+
44
+ // UI specific colors
45
+ const invalid = darkRed,
46
+ lightBackground = base00,
47
+ background = base00,
48
+ tooltipBackground = '#f0f0f0',
49
+ selection = '#0078d4',
50
+ selectionMatch = '#0078d480',
51
+ cursor = darkBlue,
52
+ activeBracketBg = '#e0e0e0',
53
+ activeBracketBorder = darkCyan,
54
+ diagnosticWarning = darkOrange,
55
+ linkColor = darkBlue,
56
+ visitedLinkColor = darkPurple;
57
+
58
+ // Diff/merge specific colors
59
+ const addedBackground = '#00800040',
60
+ removedBackground = '#c8000040',
61
+ addedText = darkGreen,
62
+ removedText = darkRed;
63
+
64
+ /**
65
+ * Enhanced editor theme styles for High Contrast Light
66
+ */
67
+ const highContrastLightTheme = EditorView.theme(
68
+ {
69
+ // Base editor styles
70
+ '&': {
71
+ color: base04,
72
+ backgroundColor: background,
73
+ fontSize: generalContent.fontSize,
74
+ fontFamily: generalContent.fontFamily,
75
+ border: `2px solid ${base04}`,
76
+ },
77
+
78
+ // Content and cursor
79
+ '.cm-content': {
80
+ caretColor: cursor,
81
+ lineHeight: generalContent.lineHeight,
82
+ },
83
+ '.cm-cursor, .cm-dropCursor': {
84
+ borderLeftColor: cursor,
85
+ borderLeftWidth: '3px',
86
+ },
87
+ '.cm-fat-cursor': {
88
+ backgroundColor: cursor,
89
+ color: background,
90
+ border: `2px solid ${base04}`,
91
+ },
92
+
93
+ // Selection
94
+ '&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection':
95
+ {
96
+ backgroundColor: '#4d90fe',
97
+ outline: `2px solid ${darkBlue}`,
98
+ },
99
+
100
+ // Make sure selection appears above active line
101
+ '.cm-selectionLayer': {
102
+ zIndex: 100,
103
+ },
104
+
105
+ // Search functionality
106
+ '.cm-searchMatch': {
107
+ backgroundColor: '#ffff00',
108
+ outline: `2px solid ${darkOrange}`,
109
+ color: base04,
110
+ borderRadius: generalSearchField.borderRadius,
111
+
112
+ '& span': {
113
+ color: base04,
114
+ },
115
+ },
116
+ '.cm-searchMatch.cm-searchMatch-selected': {
117
+ backgroundColor: darkOrange,
118
+ color: base00,
119
+ padding: generalSearchField.padding,
120
+ outline: `2px solid ${base04}`,
121
+
122
+ '& span': {
123
+ color: base00,
124
+ },
125
+ },
126
+ '.cm-search.cm-panel.cm-textfield': {
127
+ color: base04,
128
+ backgroundColor: base00,
129
+ border: `2px solid ${base04}`,
130
+ borderRadius: generalSearchField.borderRadius,
131
+ padding: generalSearchField.padding,
132
+ },
133
+
134
+ // Panels
135
+ '.cm-panels': {
136
+ backgroundColor: lightBackground,
137
+ color: base04,
138
+ borderRadius: '4px',
139
+ border: `2px solid ${base04}`,
140
+ },
141
+ '.cm-panels.cm-panels-top': {
142
+ borderBottom: `2px solid ${base04}`,
143
+ },
144
+ '.cm-panels.cm-panels-bottom': {
145
+ borderTop: `2px solid ${base04}`,
146
+ },
147
+ '.cm-panel button': {
148
+ backgroundColor: tooltipBackground,
149
+ color: darkBlue,
150
+ border: `2px solid ${base04}`,
151
+ borderRadius: generalPanel.borderRadius,
152
+ padding: generalPanel.padding,
153
+ },
154
+ '.cm-panel button:hover': {
155
+ backgroundColor: base01,
156
+ border: `2px solid ${darkBlue}`,
157
+ },
158
+
159
+ // Line highlighting
160
+ '.cm-activeLine': {
161
+ backgroundColor: '#ffffccba',
162
+ borderRadius: generalLine.borderRadius,
163
+ borderLeft: `3px solid ${darkBlue}`,
164
+ borderRight: `1px solid ${base02}`,
165
+ zIndex: 1,
166
+ },
167
+
168
+ // Gutters
169
+ '.cm-gutters': {
170
+ backgroundColor: lightBackground,
171
+ color: base03,
172
+ border: generalGutter.border,
173
+ borderRight: `2px solid ${base04}`,
174
+ paddingRight: generalGutter.paddingRight,
175
+ },
176
+ '.cm-activeLineGutter': {
177
+ backgroundColor: base01,
178
+ color: darkBlue,
179
+ fontWeight: 'bold',
180
+ border: `1px solid ${base02}`,
181
+ },
182
+ '.cm-lineNumbers': {
183
+ fontSize: generalGutter.fontSize,
184
+ lineHeight: generalGutter.lineHeight,
185
+ },
186
+ '.cm-foldGutter': {
187
+ fontSize: generalGutter.fontSize,
188
+ lineHeight: generalGutter.lineHeight,
189
+ },
190
+ '.cm-foldGutter .cm-gutterElement': {
191
+ color: base03,
192
+ cursor: 'pointer',
193
+ },
194
+ '.cm-foldGutter .cm-gutterElement:hover': {
195
+ color: darkCyan,
196
+ },
197
+
198
+ // Diff/Merge View Styles
199
+ '.cm-insertedLine': {
200
+ textDecoration: generalDiff.insertedTextDecoration,
201
+ backgroundColor: addedBackground,
202
+ color: addedText,
203
+ padding: generalDiff.insertedLinePadding,
204
+ borderRadius: generalDiff.borderRadious,
205
+ border: `2px solid ${addedText}`,
206
+ },
207
+ 'ins.cm-insertedLine, ins.cm-insertedLine:not(:has(.cm-changedText))': {
208
+ textDecoration: generalDiff.insertedTextDecoration,
209
+ backgroundColor: `${addedBackground} !important`,
210
+ color: addedText,
211
+ padding: generalDiff.insertedLinePadding,
212
+ borderRadius: generalDiff.borderRadious,
213
+ border: `2px solid ${addedText}`,
214
+ },
215
+ 'ins.cm-insertedLine .cm-changedText': {
216
+ background: 'transparent !important',
217
+ },
218
+
219
+ '.cm-deletedLine': {
220
+ textDecoration: generalDiff.deletedTextDecoration,
221
+ backgroundColor: removedBackground,
222
+ color: removedText,
223
+ padding: generalDiff.insertedLinePadding,
224
+ borderRadius: generalDiff.borderRadious,
225
+ border: `2px solid ${removedText}`,
226
+ },
227
+ 'del.cm-deletedLine, del, del:not(:has(.cm-deletedText))': {
228
+ textDecoration: generalDiff.deletedTextDecoration,
229
+ backgroundColor: `${removedBackground} !important`,
230
+ color: removedText,
231
+ padding: generalDiff.insertedLinePadding,
232
+ borderRadius: generalDiff.borderRadious,
233
+ border: `2px solid ${removedText}`,
234
+ },
235
+ 'del .cm-deletedText, del .cm-changedText': {
236
+ background: 'transparent !important',
237
+ },
238
+
239
+ // Tooltips and autocomplete
240
+ '.cm-tooltip': {
241
+ backgroundColor: tooltipBackground,
242
+ border: `2px solid ${darkBlue}`,
243
+ borderRadius: generalTooltip.borderRadius,
244
+ padding: generalTooltip.padding,
245
+ color: base04,
246
+ },
247
+ '.cm-tooltip-autocomplete': {
248
+ '& > ul': {
249
+ backgroundColor: tooltipBackground,
250
+ border: `2px solid ${base04}`,
251
+ },
252
+ '& > ul > li': {
253
+ padding: generalTooltip.padding,
254
+ lineHeight: generalTooltip.lineHeight,
255
+ },
256
+ '& > ul > li[aria-selected]': {
257
+ backgroundColor: selection,
258
+ color: base00,
259
+ borderRadius: generalTooltip.borderRadiusSelected,
260
+ border: `2px solid ${darkBlue}`,
261
+ },
262
+ '& > ul > li > span.cm-completionIcon': {
263
+ color: darkCyan,
264
+ paddingRight: generalTooltip.paddingRight,
265
+ },
266
+ '& > ul > li > span.cm-completionDetail': {
267
+ color: darkOrange,
268
+ fontStyle: 'italic',
269
+ },
270
+ },
271
+ '.cm-tooltip .cm-tooltip-arrow:before': {
272
+ borderTopColor: 'transparent',
273
+ borderBottomColor: 'transparent',
274
+ },
275
+ '.cm-tooltip .cm-tooltip-arrow:after': {
276
+ borderTopColor: darkBlue,
277
+ borderBottomColor: darkBlue,
278
+ },
279
+
280
+ // Diagnostics styling
281
+ '.cm-diagnostic': {
282
+ '&-error': {
283
+ borderLeft: `4px solid ${darkRed}`,
284
+ backgroundColor: '#ff000020',
285
+ },
286
+ '&-warning': {
287
+ borderLeft: `4px solid ${diagnosticWarning}`,
288
+ backgroundColor: '#ff990020',
289
+ },
290
+ '&-info': {
291
+ borderLeft: `4px solid ${linkColor}`,
292
+ backgroundColor: '#0000ff20',
293
+ },
294
+ },
295
+ '.cm-lintPoint-error': {
296
+ borderBottom: `3px wavy ${darkRed}`,
297
+ },
298
+ '.cm-lintPoint-warning': {
299
+ borderBottom: `3px wavy ${diagnosticWarning}`,
300
+ },
301
+
302
+ // Matching brackets
303
+ '.cm-matchingBracket': {
304
+ backgroundColor: activeBracketBg,
305
+ outline: `2px solid ${activeBracketBorder}`,
306
+ borderRadius: generalMatching.borderRadius,
307
+ },
308
+ '.cm-nonmatchingBracket': {
309
+ backgroundColor: '#ff000030',
310
+ outline: `2px solid ${invalid}`,
311
+ borderRadius: generalMatching.borderRadius,
312
+ },
313
+
314
+ // Selection matches
315
+ '.cm-selectionMatch': {
316
+ backgroundColor: selectionMatch,
317
+ outline: `2px solid ${darkBlue}50`,
318
+ borderRadius: generalMatching.borderRadius,
319
+ },
320
+
321
+ // Fold placeholder
322
+ '.cm-foldPlaceholder': {
323
+ backgroundColor: tooltipBackground,
324
+ color: darkBlue,
325
+ border: `2px solid ${darkBlue}`,
326
+ borderRadius: generalPlaceholder.borderRadius,
327
+ padding: generalPlaceholder.padding,
328
+ margin: generalPlaceholder.margin,
329
+ },
330
+
331
+ // Focus outline
332
+ '&.cm-focused': {
333
+ outline: `3px solid ${darkBlue}`,
334
+ outlineOffset: '2px',
335
+ },
336
+
337
+ // Scrollbars
338
+ '& .cm-scroller::-webkit-scrollbar': {
339
+ width: generalScroller.width,
340
+ height: generalScroller.height,
341
+ },
342
+ '& .cm-scroller::-webkit-scrollbar-track': {
343
+ background: lightBackground,
344
+ border: `2px solid ${base04}`,
345
+ },
346
+ '& .cm-scroller::-webkit-scrollbar-thumb': {
347
+ backgroundColor: base03,
348
+ border: `2px solid ${base04}`,
349
+ borderRadius: generalScroller.borderRadius,
350
+ },
351
+ '& .cm-scroller::-webkit-scrollbar-thumb:hover': {
352
+ backgroundColor: darkBlue,
353
+ },
354
+
355
+ // Ghost text
356
+ '.cm-ghostText': {
357
+ opacity: '0.7',
358
+ color: base02,
359
+ },
360
+ },
361
+ { dark: false },
362
+ );
363
+
364
+ /**
365
+ * Enhanced syntax highlighting for High Contrast Light theme
366
+ */
367
+ const highContrastLightHighlightStyle = HighlightStyle.define([
368
+ // Keywords and control flow
369
+ { tag: t.keyword, color: darkMagenta, fontWeight: 'bold' },
370
+ { tag: t.controlKeyword, color: darkMagenta, fontWeight: 'bold' },
371
+ { tag: t.moduleKeyword, color: darkMagenta, fontWeight: 'bold' },
372
+
373
+ // Names and variables
374
+ { tag: [t.name, t.deleted, t.character, t.macroName], color: base04 },
375
+ { tag: [t.variableName], color: base04 },
376
+ { tag: [t.propertyName], color: darkBlue, fontStyle: 'normal' },
377
+
378
+ // Classes and types
379
+ { tag: [t.typeName], color: darkCyan },
380
+ { tag: [t.className], color: darkCyan, fontStyle: 'italic' },
381
+ { tag: [t.namespace], color: darkOrange, fontStyle: 'italic' },
382
+
383
+ // Operators and punctuation
384
+ { tag: [t.operator, t.operatorKeyword], color: darkCyan },
385
+ { tag: [t.bracket], color: darkBrown },
386
+ { tag: [t.brace], color: darkCyan },
387
+ { tag: [t.punctuation], color: base04 },
388
+
389
+ // Functions and parameters
390
+ { tag: [t.function(t.variableName), t.labelName], color: darkBlue },
391
+ { tag: [t.definition(t.function(t.variableName))], color: darkBlue },
392
+ { tag: [t.definition(t.variableName)], color: darkOrange },
393
+
394
+ // Constants and literals
395
+ { tag: t.number, color: darkOrange },
396
+ { tag: t.changed, color: darkOrange },
397
+ { tag: t.annotation, color: darkRed, fontStyle: 'italic' },
398
+ { tag: t.modifier, color: darkPurple, fontStyle: 'italic' },
399
+ { tag: t.self, color: darkRed },
400
+ { tag: [t.color, t.constant(t.name), t.standard(t.name)], color: darkOrange },
401
+ { tag: [t.atom, t.bool, t.special(t.variableName)], color: darkOrange },
402
+
403
+ // Strings and regex
404
+ { tag: [t.processingInstruction, t.inserted], color: darkGreen },
405
+ { tag: [t.special(t.string), t.regexp], color: darkMagenta },
406
+ { tag: t.string, color: darkGreen },
407
+
408
+ // Punctuation and structure
409
+ { tag: t.definition(t.typeName), color: darkCyan, fontWeight: 'bold' },
410
+ { tag: [t.definition(t.name), t.separator], color: darkBlue },
411
+
412
+ // Comments and documentation
413
+ { tag: t.meta, color: base02 },
414
+ { tag: t.comment, fontStyle: 'italic', color: base02 },
415
+ { tag: t.docComment, fontStyle: 'italic', color: base02 },
416
+
417
+ // HTML/XML elements
418
+ { tag: [t.tagName], color: darkMagenta },
419
+ { tag: [t.attributeName], color: darkCyan },
420
+
421
+ // Markdown and text formatting
422
+ { tag: [t.heading], fontWeight: 'bold', color: darkMagenta },
423
+ { tag: [t.strong], fontWeight: 'bold', color: darkOrange },
424
+ { tag: [t.emphasis], fontStyle: 'italic', color: darkMagenta },
425
+
426
+ // Links and URLs
427
+ {
428
+ tag: [t.link],
429
+ color: visitedLinkColor,
430
+ fontWeight: '500',
431
+ textDecoration: 'underline',
432
+ textUnderlinePosition: 'under',
433
+ },
434
+ {
435
+ tag: [t.url],
436
+ color: linkColor,
437
+ textDecoration: 'underline',
438
+ textUnderlineOffset: '2px',
439
+ },
440
+
441
+ // Special states
442
+ {
443
+ tag: [t.invalid],
444
+ color: darkRed,
445
+ textDecoration: 'underline wavy',
446
+ borderBottom: `2px wavy ${darkRed}`,
447
+ },
448
+ { tag: [t.strikethrough], color: darkRed, textDecoration: 'line-through' },
449
+
450
+ // Enhanced syntax highlighting
451
+ { tag: t.constant(t.name), color: darkOrange },
452
+ { tag: t.deleted, color: darkRed },
453
+ { tag: t.squareBracket, color: darkBrown },
454
+ { tag: t.angleBracket, color: darkCyan },
455
+
456
+ // Additional specific styles
457
+ { tag: t.monospace, color: darkBlue, fontStyle: 'italic' },
458
+ { tag: [t.contentSeparator], color: darkPurple },
459
+ { tag: t.quote, color: darkPurple },
460
+ ]);
461
+
462
+ /**
463
+ * Combined High Contrast Light theme extension
464
+ */
465
+ const highContrastLight: Extension = [
466
+ highContrastLightTheme,
467
+ syntaxHighlighting(highContrastLightHighlightStyle),
468
+ ];
469
+
470
+ /**
471
+ * High Contrast Light merge revert styles configuration
472
+ */
473
+ const highContrastLightMergeStyles: IMergeRevertStyles = {
474
+ backgroundColor: lightBackground,
475
+ borderColor: darkBlue,
476
+ buttonColor: darkBlue,
477
+ buttonHoverColor: darkOrange,
478
+ };
479
+
480
+ export { highContrastLight, highContrastLightMergeStyles, applyMergeRevertStyles };
481
+
package/src/utils.ts ADDED
@@ -0,0 +1,126 @@
1
+ // Helper module for styling options
2
+ export const generalContent = {
3
+ fontSize: '14px',
4
+ fontFamily: 'JetBrains Mono, Consolas, monospace',
5
+ lineHeight: '1.6',
6
+ };
7
+
8
+ export const generalCursor = {
9
+ borderLeftWidth: '2px',
10
+ };
11
+
12
+ export const generalDiff = {
13
+ insertedTextDecoration: 'none',
14
+ deletedTextDecoration: 'line-through',
15
+ insertedLinePadding: '1px 3px',
16
+ borderRadious: '3px',
17
+ ins_del_linePadding: '1px 3px',
18
+ };
19
+
20
+ export const generalGutter = {
21
+ border: 'none',
22
+ paddingRight: '8px',
23
+ fontSize: '0.9em',
24
+ fontWeight: '500',
25
+ lineHeight: '1.78', // Adjusted to compensate for 0.9em fontSize (1.6 / 0.9 ≈ 1.78)
26
+ };
27
+
28
+ export const generalPanel = {
29
+ border: 'none',
30
+ borderRadius: '4px',
31
+ padding: '2px 10px',
32
+ };
33
+
34
+ export const generalLine = {
35
+ borderRadius: '2px',
36
+ };
37
+
38
+ export const generalMatching = {
39
+ borderRadius: '2px',
40
+ };
41
+
42
+ export const generalPlaceholder = {
43
+ borderRadius: '4px',
44
+ padding: '0 5px',
45
+ margin: '0 2px',
46
+ };
47
+
48
+ export const generalScroller = {
49
+ width: '12px',
50
+ height: '12px',
51
+ borderRadius: '6px',
52
+ };
53
+
54
+ export const generalSearchField = {
55
+ borderRadius: '4px',
56
+ padding: '2px 6px',
57
+ };
58
+
59
+ export const generalTooltip = {
60
+ borderRadius: '4px',
61
+ borderRadiusSelected: '3px',
62
+ lineHeight: '1.3',
63
+ padding: '4px 8px',
64
+ paddingRight: '8px',
65
+ };
66
+
67
+ //---------------------------------------
68
+
69
+ // Interface for merge revert styling options
70
+ export interface IMergeRevertStyles {
71
+ backgroundColor: string
72
+ borderColor: string
73
+ buttonColor: string
74
+ buttonHoverColor: string
75
+ }
76
+
77
+ /**
78
+ * Function to apply merge revert styles for a theme
79
+ * @param styles Styles for the merge revert buttons
80
+ * @param styles.backgroundColor Background color of the revert area
81
+ * @param styles.borderColor Border color of the revert area
82
+ * @param styles.buttonColor Color of the revert buttons
83
+ * @param styles.buttonHoverColor Hover color of the revert buttons
84
+ */
85
+ export function applyMergeRevertStyles(styles: IMergeRevertStyles) {
86
+ // Create a stylesheet
87
+ const styleEl = document.createElement('style');
88
+ styleEl.id = 'cm-merge-revert-styles';
89
+
90
+ // Define CSS with the theme-specific values
91
+ styleEl.textContent = `
92
+ .cm-merge-revert {
93
+ display: flex;
94
+ flex-direction: column;
95
+ align-items: center;
96
+ justify-content: flex-start;
97
+ padding: 4px;
98
+ background-color: ${styles.backgroundColor};
99
+ border-left: 1px solid ${styles.borderColor};
100
+ border-right: 1px solid ${styles.borderColor};
101
+ width: 32px;
102
+ }
103
+
104
+ .cm-merge-revert button {
105
+ width: 100%;
106
+ height: auto;
107
+ background-color: transparent;
108
+ border: none;
109
+ color: ${styles.buttonColor};
110
+ cursor: pointer;
111
+ margin: 0 auto;
112
+ font-size: 20px;
113
+ }
114
+
115
+ .cm-merge-revert button:hover {
116
+ background-color: ${styles.buttonHoverColor};
117
+ }
118
+ `;
119
+
120
+ // Remove any existing merge styles
121
+ const existingStyle = document.getElementById('cm-merge-revert-styles');
122
+ if (existingStyle) existingStyle.remove();
123
+
124
+ // Add the new styles
125
+ document.head.appendChild(styleEl);
126
+ }