Convert editor styles to TypeScript

Nathan Sobo created

Change summary

styles/app.ts        | 201 ---------------------------------------------
styles/components.ts |   4 
styles/editor.ts     | 143 ++++++++++++++++++++++++++++++++
styles/theme.ts      |  65 ++++++++++++++
4 files changed, 214 insertions(+), 199 deletions(-)

Detailed changes

styles/app.ts 🔗

@@ -1,13 +1,15 @@
 import { backgroundColor } from "./components";
 import selectorModal from "./selector-modal";
 import workspace from "./workspace";
+import editor from "./editor";
 import Theme from "./theme";
 
 export default function app(theme: Theme): Object {
   return {
     selector: selectorModal(theme),
     workspace: workspace(theme),
-    chat_panel: {
+    editor: editor(theme),
+    chatPanel: {
       extends: "$panel",
       channel_name: {
         extends: "$text.primary",
@@ -169,203 +171,6 @@ export default function app(theme: Theme): Object {
         extends: "$contacts_panel.project",
       },
     },
-    editor: {
-      active_line_background: "$state.active_line",
-      background: backgroundColor(theme, 300),
-      code_actions_indicator: "$text.muted.color",
-      diff_background_deleted: "$state.deleted_line",
-      diff_background_inserted: "$state.inserted_line",
-      document_highlight_read_background: "#99999920",
-      document_highlight_write_background: "#99999916",
-      error_color: "$status.bad",
-      guest_selections: "$selection.guests",
-      gutter_background: backgroundColor(theme, 300),
-      gutter_padding_factor: 2.5,
-      highlighted_line_background: "$state.highlighted_line",
-      line_number: "$text.muted.color",
-      line_number_active: "$text.primary.color",
-      rename_fade: 0.6,
-      selection: "$selection.host",
-      text_color: "$text.secondary.color",
-      unnecessary_code_fade: 0.5,
-      autocomplete: {
-        background: "$surface.100",
-        corner_radius: 6,
-        padding: 6,
-        border: {
-          color: "$border.secondary",
-          width: 2,
-        },
-        hovered_item: {
-          background: "$state.hover",
-          extends: "$editor.autocomplete.item",
-        },
-        item: {
-          corner_radius: 6,
-          padding: {
-            bottom: 2,
-            left: 6,
-            right: 6,
-            top: 2,
-          },
-        },
-        margin: {
-          left: -14,
-        },
-        match_highlight: {
-          color: "$editor.syntax.keyword.color",
-          weight: "$editor.syntax.keyword.weight",
-        },
-        selected_item: {
-          background: "$state.selected",
-          extends: "$editor.autocomplete.item",
-        },
-      },
-      diagnostic_header: {
-        background: "$editor.background",
-        icon_width_factor: 1.5,
-        text_scale_factor: 0.857,
-        border: {
-          bottom: true,
-          color: "$border.secondary",
-          top: true,
-          width: 1,
-        },
-        code: {
-          extends: "$text.muted",
-          size: 14,
-          margin: {
-            left: 10,
-          },
-        },
-        message: {
-          highlight_text: {
-            extends: "$text.primary",
-            size: 14,
-            weight: "bold",
-          },
-          text: {
-            extends: "$text.secondary",
-            size: 14,
-          },
-        },
-      },
-      diagnostic_path_header: {
-        background: "$state.active_line",
-        text_scale_factor: 0.857,
-        filename: {
-          extends: "$text.primary",
-          size: 14,
-        },
-        path: {
-          extends: "$text.muted",
-          size: 14,
-          margin: {
-            left: 12,
-          },
-        },
-      },
-      error_diagnostic: {
-        text_scale_factor: 0.857,
-        header: {
-          border: {
-            color: "$border.primary",
-            top: true,
-            width: 1,
-          },
-        },
-        message: {
-          highlight_text: {
-            color: "$status.bad",
-            extends: "$text.secondary",
-            size: 14,
-            weight: "bold",
-          },
-          text: {
-            color: "$status.bad",
-            extends: "$text.secondary",
-            size: 14,
-          },
-        },
-      },
-      hint_diagnostic: {
-        extends: "$editor.error_diagnostic",
-        message: {
-          highlight_text: {
-            color: "$status.info",
-          },
-          text: {
-            color: "$status.info",
-          },
-        },
-      },
-      information_diagnostic: {
-        extends: "$editor.error_diagnostic",
-        message: {
-          highlight_text: {
-            color: "$status.info",
-          },
-          text: {
-            color: "$status.info",
-          },
-        },
-      },
-      invalid_error_diagnostic: {
-        extends: "$editor.error_diagnostic",
-        message: {
-          highlight_text: {
-            color: "$text.muted.color",
-          },
-          text: {
-            color: "$text.muted.color",
-          },
-        },
-      },
-      invalid_hint_diagnostic: {
-        extends: "$editor.hint_diagnostic",
-        message: {
-          highlight_text: {
-            color: "$text.muted.color",
-          },
-          text: {
-            color: "$text.muted.color",
-          },
-        },
-      },
-      invalid_information_diagnostic: {
-        extends: "$editor.information_diagnostic",
-        message: {
-          highlight_text: {
-            color: "$text.muted.color",
-          },
-          text: {
-            color: "$text.muted.color",
-          },
-        },
-      },
-      invalid_warning_diagnostic: {
-        extends: "$editor.warning_diagnostic",
-        message: {
-          highlight_text: {
-            color: "$text.muted.color",
-          },
-          text: {
-            color: "$text.muted.color",
-          },
-        },
-      },
-      warning_diagnostic: {
-        extends: "$editor.error_diagnostic",
-        message: {
-          highlight_text: {
-            color: "$status.warn",
-          },
-          text: {
-            color: "$status.warn",
-          },
-        },
-      },
-    },
     project_diagnostics: {
       background: backgroundColor(theme, 300),
       tab_icon_spacing: 4,

styles/components.ts 🔗

@@ -3,10 +3,12 @@ import core from "./core";
 import { Color } from "./lib";
 import Theme, { BackgroundColor, Weight } from "./theme";
 
+export type TextColor = keyof Theme["textColor"];
+
 export function text(
   theme: Theme,
   fontFamily: keyof typeof core.fontFamily,
-  color: keyof Theme["textColor"],
+  color: TextColor,
   properties?: { size?: keyof typeof core["fontSize"]; weight?: Weight }
 ) {
   const sizeKey = properties.size || fontFamily === "sans" ? "sm" : "md";

styles/editor.ts 🔗

@@ -0,0 +1,143 @@
+import {
+  backgroundColor,
+  border,
+  iconColor,
+  player,
+  text,
+  TextColor,
+} from "./components";
+import Theme from "./theme";
+
+export default function editor(theme: Theme) {
+  const autocompleteItem = {
+    cornerRadius: 6,
+    padding: {
+      bottom: 2,
+      left: 6,
+      right: 6,
+      top: 2,
+    },
+  };
+
+  function diagnostic(theme: Theme, color: TextColor) {
+    return {
+      textScaleFactor: 0.857,
+      header: {
+        border: border(theme, "primary", {
+          top: true,
+        }),
+      },
+      message: {
+        text: {
+          ...text(theme, "sans", color),
+          size: 14,
+        },
+        highlightText: {
+          ...text(theme, "sans", color, { weight: "bold" }),
+          size: 14,
+        },
+      },
+    };
+  }
+
+  return {
+    textColor: theme.textColor.secondary.value,
+    background: backgroundColor(theme, 300),
+    activeLineBackground: theme.editor.line.active.value,
+    codeActionsIndicator: iconColor(theme, "secondary"),
+    diffBackgroundDeleted: backgroundColor(theme, "error"),
+    diffBackgroundInserted: backgroundColor(theme, "ok"),
+    documentHighlightReadBackground: theme.editor.highlight.occurrence.value,
+    documentHighlightWriteBackground: theme.editor.highlight.occurrence.value,
+    errorColor: theme.textColor.error,
+    gutterBackground: backgroundColor(theme, 300),
+    gutterPaddingFactor: 2.5,
+    highlightedLineBackground: theme.editor.line.highlighted.value,
+    lineNumber: theme.editor.gutter.primary.value,
+    lineNumberActive: theme.editor.gutter.active,
+    renameFade: 0.6,
+    unnecessaryCodeFade: 0.5,
+    selection: player(theme, 1).selection,
+    guestSelections: [
+      player(theme, 2).selection,
+      player(theme, 3).selection,
+      player(theme, 4).selection,
+      player(theme, 5).selection,
+      player(theme, 6).selection,
+      player(theme, 7).selection,
+      player(theme, 8).selection,
+    ],
+    autocomplete: {
+      background: backgroundColor(theme, 100),
+      cornerRadius: 6,
+      padding: 6,
+      border: border(theme, "secondary"),
+      item: autocompleteItem,
+      hoveredItem: {
+        ...autocompleteItem,
+        background: backgroundColor(theme, 100, "hover"),
+      },
+      margin: {
+        left: -14,
+      },
+      matchHighlight: {
+        color: theme.syntax.keyword.color.value,
+        weight: theme.syntax.keyword.weight.value,
+      },
+      selectedItem: {
+        ...autocompleteItem,
+        background: backgroundColor(theme, 100, "active"),
+      },
+    },
+    diagnosticHeader: {
+      background: theme.editor.background.value,
+      iconWidthFactor: 1.5,
+      textScaleFactor: 0.857,
+      border: border(theme, "secondary", {
+        bottom: true,
+        top: true,
+      }),
+      code: {
+        ...text(theme, "mono", "muted"),
+        size: 14,
+        margin: {
+          left: 10,
+        },
+      },
+      message: {
+        highlightText: {
+          ...text(theme, "sans", "primary"),
+          size: 14,
+          weight: "bold",
+        },
+        text: {
+          ...text(theme, "sans", "secondary"),
+          size: 14,
+        },
+      },
+    },
+    diagnosticPathHeader: {
+      background: theme.editor.line.active,
+      textScaleFactor: 0.857,
+      filename: {
+        ...text(theme, "mono", "primary"),
+        size: 14,
+      },
+      path: {
+        ...text(theme, "mono", "muted"),
+        size: 14,
+        margin: {
+          left: 12,
+        },
+      },
+    },
+    errorDiagnostic: diagnostic(theme, "error"),
+    warningDiagnostic: diagnostic(theme, "warning"),
+    informationDiagnostic: diagnostic(theme, "info"),
+    hintDiagnostic: diagnostic(theme, "info"),
+    invalidErrorDiagnostic: diagnostic(theme, "muted"),
+    invalidHintDiagnostic: diagnostic(theme, "muted"),
+    invalidInformationDiagnostic: diagnostic(theme, "muted"),
+    invalidWarningDiagnostic: diagnostic(theme, "muted"),
+  };
+}

styles/theme.ts 🔗

@@ -52,6 +52,10 @@ export default interface Theme {
     100: BackgroundColor;
     300: BackgroundColor;
     500: BackgroundColor;
+    ok: BackgroundColor;
+    error: BackgroundColor;
+    warning: BackgroundColor;
+    info: BackgroundColor;
   };
   borderColor: {
     primary: {
@@ -134,6 +138,66 @@ export default interface Theme {
       value: Color;
     };
   };
+  editor: {
+    background: {
+      value: Color;
+    };
+    indent_guide: {
+      value: Color;
+    };
+    indent_guide_active: {
+      value: Color;
+    };
+    line: {
+      active: {
+        value: Color;
+      };
+      highlighted: {
+        value: Color;
+      };
+      inserted: {
+        value: Color;
+      };
+      deleted: {
+        value: Color;
+      };
+      modified: {
+        value: Color;
+      };
+    };
+    highlight: {
+      selection: {
+        value: Color;
+      };
+      occurrence: {
+        value: Color;
+      };
+      activeOccurrence: {
+        value: Color;
+      };
+      matchingBracket: {
+        value: Color;
+      };
+      match: {
+        value: Color;
+      };
+      activeMatch: {
+        value: Color;
+      };
+      related: {
+        value: Color;
+      };
+    };
+    gutter: {
+      primary: {
+        value: Color;
+      };
+      active: {
+        value: Color;
+      };
+    };
+  };
+
   syntax: {
     primary: SyntaxHighlightStyle;
     comment: SyntaxHighlightStyle;
@@ -151,6 +215,7 @@ export default interface Theme {
     boolean: SyntaxHighlightStyle;
     predictive: SyntaxHighlightStyle;
   };
+
   player: {
     1: Player;
     2: Player;