editor.ts

  1import Theme from "../themes/common/theme";
  2import {
  3  backgroundColor,
  4  border,
  5  borderColor,
  6  iconColor,
  7  player,
  8  popoverShadow,
  9  text,
 10  TextColor,
 11} from "./components";
 12import hoverPopover from "./hoverPopover";
 13
 14export default function editor(theme: Theme) {
 15  const autocompleteItem = {
 16    cornerRadius: 6,
 17    padding: {
 18      bottom: 2,
 19      left: 6,
 20      right: 6,
 21      top: 2,
 22    },
 23  };
 24
 25  function diagnostic(theme: Theme, color: TextColor) {
 26    return {
 27      textScaleFactor: 0.857,
 28      header: {
 29        border: border(theme, "primary", {
 30          top: true,
 31        }),
 32      },
 33      message: {
 34        text: text(theme, "sans", color, { size: "sm" }),
 35        highlightText: text(theme, "sans", color, {
 36          size: "sm",
 37          weight: "bold",
 38        }),
 39      },
 40    };
 41  }
 42
 43  const syntax: any = {};
 44  for (const syntaxKey in theme.syntax) {
 45    const style = theme.syntax[syntaxKey];
 46    syntax[syntaxKey] = {
 47      color: style.color,
 48      weight: style.weight,
 49      underline: style.underline,
 50      italic: style.italic,
 51    };
 52  }
 53
 54  return {
 55    textColor: theme.syntax.primary.color,
 56    background: backgroundColor(theme, 500),
 57    activeLineBackground: theme.editor.line.active,
 58    codeActions: {
 59      indicator: iconColor(theme, "secondary"),
 60      verticalScale: 0.618
 61    },
 62    diffBackgroundDeleted: backgroundColor(theme, "error"),
 63    diffBackgroundInserted: backgroundColor(theme, "ok"),
 64    documentHighlightReadBackground: theme.editor.highlight.occurrence,
 65    documentHighlightWriteBackground: theme.editor.highlight.activeOccurrence,
 66    errorColor: theme.textColor.error,
 67    gutterBackground: backgroundColor(theme, 500),
 68    gutterPaddingFactor: 3.5,
 69    highlightedLineBackground: theme.editor.line.highlighted,
 70    lineNumber: theme.editor.gutter.primary,
 71    lineNumberActive: theme.editor.gutter.active,
 72    renameFade: 0.6,
 73    unnecessaryCodeFade: 0.5,
 74    selection: player(theme, 1).selection,
 75    guestSelections: [
 76      player(theme, 2).selection,
 77      player(theme, 3).selection,
 78      player(theme, 4).selection,
 79      player(theme, 5).selection,
 80      player(theme, 6).selection,
 81      player(theme, 7).selection,
 82      player(theme, 8).selection,
 83    ],
 84    autocomplete: {
 85      background: backgroundColor(theme, 500),
 86      cornerRadius: 8,
 87      padding: 4,
 88      border: border(theme, "secondary"),
 89      shadow: popoverShadow(theme),
 90      item: autocompleteItem,
 91      hoveredItem: {
 92        ...autocompleteItem,
 93        background: backgroundColor(theme, 500, "hovered"),
 94      },
 95      margin: {
 96        left: -14,
 97      },
 98      matchHighlight: text(theme, "mono", "feature"),
 99      selectedItem: {
100        ...autocompleteItem,
101        background: backgroundColor(theme, 500, "active"),
102      },
103    },
104    diagnosticHeader: {
105      background: backgroundColor(theme, 300),
106      iconWidthFactor: 1.5,
107      textScaleFactor: 0.857, // NateQ: Will we need dynamic sizing for text? If so let's create tokens for these.
108      border: border(theme, "secondary", {
109        bottom: true,
110        top: true,
111      }),
112      code: {
113        ...text(theme, "mono", "secondary", { size: "sm" }),
114        margin: {
115          left: 10,
116        },
117      },
118      message: {
119        highlightText: text(theme, "sans", "primary", {
120          size: "sm",
121          weight: "bold",
122        }),
123        text: text(theme, "sans", "secondary", { size: "sm" }),
124      },
125    },
126    diagnosticPathHeader: {
127      background: theme.editor.line.active,
128      textScaleFactor: 0.857,
129      filename: text(theme, "mono", "primary", { size: "sm" }),
130      path: {
131        ...text(theme, "mono", "muted", { size: "sm" }),
132        margin: {
133          left: 12,
134        },
135      },
136    },
137    errorDiagnostic: diagnostic(theme, "error"),
138    warningDiagnostic: diagnostic(theme, "warning"),
139    informationDiagnostic: diagnostic(theme, "info"),
140    hintDiagnostic: diagnostic(theme, "info"),
141    invalidErrorDiagnostic: diagnostic(theme, "secondary"),
142    invalidHintDiagnostic: diagnostic(theme, "secondary"),
143    invalidInformationDiagnostic: diagnostic(theme, "secondary"),
144    invalidWarningDiagnostic: diagnostic(theme, "secondary"),
145    hoverPopover: hoverPopover(theme),
146    linkDefinition: {
147      color: theme.syntax.linkUri.color,
148      underline: theme.syntax.linkUri.underline,
149    },
150    jumpIcon: {
151      color: iconColor(theme, "secondary"),
152      iconWidth: 20,
153      buttonWidth: 20,
154      cornerRadius: 6,
155      padding: {
156        top: 6,
157        bottom: 6,
158        left: 6,
159        right: 6,
160      },
161      hover: {
162        color: iconColor(theme, "active"),
163        background: backgroundColor(theme, "on500"),
164      },
165    },
166    compositionMark: {
167      underline: {
168        thickness: 1.0,
169        color: borderColor(theme, "active")
170      },
171    },
172    syntax,
173  };
174}