theme.ts 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. import { EditorView } from '@codemirror/view'
  2. import { Compartment, TransactionSpec } from '@codemirror/state'
  3. export type FontFamily = 'monaco' | 'lucida'
  4. export type LineHeight = 'compact' | 'normal' | 'wide'
  5. export type Options = {
  6. fontSize: number
  7. fontFamily: FontFamily
  8. lineHeight: LineHeight
  9. }
  10. const optionsThemeConf = new Compartment()
  11. export const theme = (options: Options) => [
  12. optionsThemeConf.of(createThemeFromOptions(options)),
  13. ]
  14. export const lineHeights: Record<LineHeight, number> = {
  15. compact: 1.33,
  16. normal: 1.6,
  17. wide: 2,
  18. }
  19. const fontFamilies: Record<FontFamily, string[]> = {
  20. monaco: ['Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'monospace'],
  21. lucida: ['Lucida Console', 'Source Code Pro', 'monospace'],
  22. }
  23. const createThemeFromOptions = ({
  24. fontSize = 12,
  25. fontFamily = 'monaco',
  26. lineHeight = 'normal',
  27. }: Options) => {
  28. // Theme styles that depend on settings
  29. const fontFamilyValue = fontFamilies[fontFamily]?.join(', ')
  30. return [
  31. EditorView.theme({
  32. '&.cm-editor': {
  33. '--font-size': `${fontSize}px`,
  34. '--source-font-family': fontFamilyValue,
  35. '--line-height': lineHeights[lineHeight],
  36. },
  37. '.cm-content': {
  38. fontSize: 'var(--font-size)',
  39. fontFamily: 'var(--source-font-family)',
  40. lineHeight: 'var(--line-height)',
  41. color: '#000',
  42. },
  43. '.cm-gutters': {
  44. fontSize: 'var(--font-size)',
  45. lineHeight: 'var(--line-height)',
  46. },
  47. '.cm-tooltip': {
  48. // Set variables for tooltips, which are outside the editor
  49. '--font-size': `${fontSize}px`,
  50. '--source-font-family': fontFamilyValue,
  51. // NOTE: fontFamily is not set here, as most tooltips use the UI font
  52. fontSize: 'var(--font-size)',
  53. },
  54. '.cm-lineNumbers': {
  55. fontFamily: 'var(--source-font-family)',
  56. },
  57. }),
  58. ]
  59. }
  60. export const setOptionsTheme = (options: Options): TransactionSpec => {
  61. return {
  62. effects: optionsThemeConf.reconfigure(createThemeFromOptions(options)),
  63. }
  64. }