feat: Custom accent color (#4897)

* types

* Working, but messy

* Add InputColor component

* types

* Show default theme values when not customized

* Support custom theme on team sign-in page

* Payload validation

* Custom theme on shared documents

* Improve theme validation

* Team -> Workspace in settings
This commit is contained in:
Tom Moor
2023-02-19 10:43:03 -05:00
committed by GitHub
parent 7c05b7326a
commit 70beb7524f
45 changed files with 684 additions and 390 deletions

View File

@@ -1,7 +1,8 @@
import { darken, lighten } from "polished";
import { DefaultTheme, Colors } from "styled-components";
import breakpoints from "./breakpoints";
const colors = {
const defaultColors: Colors = {
transparent: "transparent",
almostBlack: "#111319",
lightBlack: "#2F3336",
@@ -13,7 +14,7 @@ const colors = {
smoke: "#F4F7FA",
smokeLight: "#F9FBFC",
smokeDark: "#E8EBED",
white: "#FFF",
white: "#FFFFFF",
white05: "rgba(255, 255, 255, 0.05)",
white10: "rgba(255, 255, 255, 0.1)",
white50: "rgba(255, 255, 255, 0.5)",
@@ -23,7 +24,7 @@ const colors = {
black10: "rgba(0, 0, 0, 0.1)",
black50: "rgba(0, 0, 0, 0.50)",
black75: "rgba(0, 0, 0, 0.75)",
primary: "#0366d6",
accent: "#0366d6",
yellow: "#EDBA07",
warmGrey: "#EDF2F7",
searchHighlight: "#FDEA9B",
@@ -52,178 +53,196 @@ const spacing = {
sidebarMaxWidth: 400,
};
export const base = {
...colors,
...spacing,
fontFamily:
"-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen, Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif",
fontFamilyMono:
"'SFMono-Regular',Consolas,'Liberation Mono', Menlo, Courier,monospace",
fontWeight: 400,
backgroundTransition: "background 100ms ease-in-out",
selected: colors.primary,
buttonBackground: colors.primary,
buttonText: colors.white,
textHighlight: "#FDEA9B",
textHighlightForeground: colors.almostBlack,
code: colors.lightBlack,
codeComment: "#6a737d",
codePunctuation: "#5e6687",
codeNumber: "#d73a49",
codeProperty: "#c08b30",
codeTag: "#3d8fd1",
codeString: "#032f62",
codeSelector: "#6679cc",
codeAttr: "#c76b29",
codeEntity: "#22a2c9",
codeKeyword: "#d73a49",
codeFunction: "#6f42c1",
codeStatement: "#22a2c9",
codePlaceholder: "#3d8fd1",
codeInserted: "#202746",
codeImportant: "#c94922",
noticeInfoBackground: colors.primary,
noticeInfoText: colors.almostBlack,
noticeTipBackground: "#F5BE31",
noticeTipText: colors.almostBlack,
noticeWarningBackground: "#d73a49",
noticeWarningText: colors.almostBlack,
breakpoints,
const buildBaseTheme = (input: Partial<Colors>) => {
const colors = {
...defaultColors,
...input,
};
return {
fontFamily:
"-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen, Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif",
fontFamilyMono:
"'SFMono-Regular',Consolas,'Liberation Mono', Menlo, Courier,monospace",
fontWeight: 400,
backgroundTransition: "background 100ms ease-in-out",
accentText: colors.white,
selected: colors.accent,
textHighlight: "#FDEA9B",
textHighlightForeground: colors.almostBlack,
code: colors.lightBlack,
codeComment: "#6a737d",
codePunctuation: "#5e6687",
codeNumber: "#d73a49",
codeProperty: "#c08b30",
codeTag: "#3d8fd1",
codeString: "#032f62",
codeSelector: "#6679cc",
codeAttr: "#c76b29",
codeEntity: "#22a2c9",
codeKeyword: "#d73a49",
codeFunction: "#6f42c1",
codeStatement: "#22a2c9",
codePlaceholder: "#3d8fd1",
codeInserted: "#202746",
codeImportant: "#c94922",
noticeInfoBackground: colors.accent,
noticeInfoText: colors.almostBlack,
noticeTipBackground: "#F5BE31",
noticeTipText: colors.almostBlack,
noticeWarningBackground: "#d73a49",
noticeWarningText: colors.almostBlack,
breakpoints,
...colors,
...spacing,
};
};
export const light = {
...base,
isDark: false,
background: colors.white,
secondaryBackground: colors.warmGrey,
link: colors.primary,
cursor: colors.almostBlack,
text: colors.almostBlack,
textSecondary: colors.slateDark,
textTertiary: colors.slate,
textDiffInserted: colors.almostBlack,
textDiffInsertedBackground: "rgba(18, 138, 41, 0.16)",
textDiffDeleted: colors.slateDark,
textDiffDeletedBackground: "#ffebe9",
placeholder: "#a2b2c3",
sidebarBackground: colors.warmGrey,
sidebarActiveBackground: "#d7e0ea",
sidebarControlHoverBackground: "rgb(138 164 193 / 20%)",
sidebarDraftBorder: darken("0.25", colors.warmGrey),
sidebarText: "rgb(78, 92, 110)",
backdrop: "rgba(0, 0, 0, 0.2)",
shadow: "rgba(0, 0, 0, 0.2)",
export const buildLightTheme = (input: Partial<Colors>): DefaultTheme => {
const colors = buildBaseTheme(input);
modalBackdrop: colors.black10,
modalBackground: colors.white,
modalShadow:
"0 4px 8px rgb(0 0 0 / 8%), 0 2px 4px rgb(0 0 0 / 0%), 0 30px 40px rgb(0 0 0 / 8%)",
return {
...colors,
isDark: false,
background: colors.white,
secondaryBackground: colors.warmGrey,
link: colors.accent,
cursor: colors.almostBlack,
text: colors.almostBlack,
textSecondary: colors.slateDark,
textTertiary: colors.slate,
textDiffInserted: colors.almostBlack,
textDiffInsertedBackground: "rgba(18, 138, 41, 0.16)",
textDiffDeleted: colors.slateDark,
textDiffDeletedBackground: "#ffebe9",
placeholder: "#a2b2c3",
sidebarBackground: colors.warmGrey,
sidebarActiveBackground: "#d7e0ea",
sidebarControlHoverBackground: "rgb(138 164 193 / 20%)",
sidebarDraftBorder: darken("0.25", colors.warmGrey),
sidebarText: "rgb(78, 92, 110)",
backdrop: "rgba(0, 0, 0, 0.2)",
shadow: "rgba(0, 0, 0, 0.2)",
menuItemSelected: colors.warmGrey,
menuBackground: colors.white,
menuShadow:
"0 0 0 1px rgb(0 0 0 / 2%), 0 4px 8px rgb(0 0 0 / 8%), 0 2px 4px rgb(0 0 0 / 0%), 0 30px 40px rgb(0 0 0 / 8%)",
divider: colors.slateLight,
titleBarDivider: colors.slateLight,
inputBorder: colors.slateLight,
inputBorderFocused: colors.slate,
listItemHoverBackground: colors.warmGrey,
toolbarHoverBackground: colors.black,
toolbarBackground: colors.almostBlack,
toolbarInput: colors.white10,
toolbarItem: colors.white,
tableDivider: colors.smokeDark,
tableSelected: colors.primary,
tableSelectedBackground: "#E5F7FF",
buttonNeutralBackground: colors.white,
buttonNeutralText: colors.almostBlack,
buttonNeutralBorder: darken(0.15, colors.white),
tooltipBackground: colors.almostBlack,
tooltipText: colors.white,
toastBackground: colors.almostBlack,
toastText: colors.white,
quote: colors.slateLight,
codeBackground: colors.smoke,
codeBorder: colors.smokeDark,
embedBorder: colors.slateLight,
horizontalRule: colors.smokeDark,
progressBarBackground: colors.slateLight,
scrollbarBackground: colors.smoke,
scrollbarThumb: darken(0.15, colors.smokeDark),
modalBackdrop: colors.black10,
modalBackground: colors.white,
modalShadow:
"0 4px 8px rgb(0 0 0 / 8%), 0 2px 4px rgb(0 0 0 / 0%), 0 30px 40px rgb(0 0 0 / 8%)",
menuItemSelected: colors.warmGrey,
menuBackground: colors.white,
menuShadow:
"0 0 0 1px rgb(0 0 0 / 2%), 0 4px 8px rgb(0 0 0 / 8%), 0 2px 4px rgb(0 0 0 / 0%), 0 30px 40px rgb(0 0 0 / 8%)",
divider: colors.slateLight,
titleBarDivider: colors.slateLight,
inputBorder: colors.slateLight,
inputBorderFocused: colors.slate,
listItemHoverBackground: colors.warmGrey,
toolbarHoverBackground: colors.black,
toolbarBackground: colors.almostBlack,
toolbarInput: colors.white10,
toolbarItem: colors.white,
tableDivider: colors.smokeDark,
tableSelected: colors.accent,
tableSelectedBackground: "#E5F7FF",
buttonNeutralBackground: colors.white,
buttonNeutralText: colors.almostBlack,
buttonNeutralBorder: darken(0.15, colors.white),
tooltipBackground: colors.almostBlack,
tooltipText: colors.white,
toastBackground: colors.almostBlack,
toastText: colors.white,
quote: colors.slateLight,
codeBackground: colors.smoke,
codeBorder: colors.smokeDark,
embedBorder: colors.slateLight,
horizontalRule: colors.smokeDark,
progressBarBackground: colors.slateLight,
scrollbarBackground: colors.smoke,
scrollbarThumb: darken(0.15, colors.smokeDark),
};
};
export const dark = {
...base,
isDark: true,
background: colors.almostBlack,
secondaryBackground: colors.black50,
link: "#137FFB",
text: colors.almostWhite,
cursor: colors.almostWhite,
textSecondary: lighten(0.1, colors.slate),
textTertiary: colors.slate,
textDiffInserted: colors.almostWhite,
textDiffInsertedBackground: "rgba(63,185,80,0.3)",
textDiffDeleted: darken(0.1, colors.almostWhite),
textDiffDeletedBackground: "rgba(248,81,73,0.15)",
placeholder: colors.slateDark,
sidebarBackground: colors.veryDarkBlue,
sidebarActiveBackground: lighten(0.02, colors.almostBlack),
sidebarControlHoverBackground: colors.white10,
sidebarDraftBorder: darken("0.35", colors.slate),
sidebarText: colors.slate,
backdrop: "rgba(0, 0, 0, 0.5)",
shadow: "rgba(0, 0, 0, 0.6)",
export const buildDarkTheme = (input: Partial<Colors>): DefaultTheme => {
const colors = buildBaseTheme(input);
modalBackdrop: colors.black50,
modalBackground: "#1f2128",
modalShadow:
"0 0 0 1px rgba(0, 0, 0, 0.1), 0 8px 16px rgba(0, 0, 0, 0.3), 0 2px 4px rgba(0, 0, 0, 0.08)",
return {
...colors,
isDark: true,
background: colors.almostBlack,
secondaryBackground: colors.black50,
link: "#137FFB",
text: colors.almostWhite,
cursor: colors.almostWhite,
textSecondary: lighten(0.1, colors.slate),
textTertiary: colors.slate,
textDiffInserted: colors.almostWhite,
textDiffInsertedBackground: "rgba(63,185,80,0.3)",
textDiffDeleted: darken(0.1, colors.almostWhite),
textDiffDeletedBackground: "rgba(248,81,73,0.15)",
placeholder: colors.slateDark,
sidebarBackground: colors.veryDarkBlue,
sidebarActiveBackground: lighten(0.02, colors.almostBlack),
sidebarControlHoverBackground: colors.white10,
sidebarDraftBorder: darken("0.35", colors.slate),
sidebarText: colors.slate,
backdrop: "rgba(0, 0, 0, 0.5)",
shadow: "rgba(0, 0, 0, 0.6)",
menuItemSelected: lighten(0.1, "#1f2128"),
menuBackground: "#1f2128",
menuShadow:
"0 0 0 1px rgba(0, 0, 0, 0.1), 0 8px 16px rgba(0, 0, 0, 0.3), 0 2px 4px rgba(0, 0, 0, 0.08)",
divider: lighten(0.1, colors.almostBlack),
titleBarDivider: darken(0.4, colors.slate),
inputBorder: colors.slateDark,
inputBorderFocused: colors.slate,
listItemHoverBackground: colors.white10,
toolbarHoverBackground: colors.slate,
toolbarBackground: colors.white,
toolbarInput: colors.black10,
toolbarItem: colors.lightBlack,
tableDivider: colors.lightBlack,
tableSelected: colors.primary,
tableSelectedBackground: "#002333",
buttonNeutralBackground: colors.almostBlack,
buttonNeutralText: colors.white,
buttonNeutralBorder: colors.slateDark,
tooltipBackground: colors.white,
tooltipText: colors.lightBlack,
toastBackground: colors.white,
toastText: colors.lightBlack,
quote: colors.almostWhite,
code: colors.almostWhite,
codeBackground: colors.black75,
codeBorder: colors.black50,
codeString: "#3d8fd1",
embedBorder: colors.black50,
horizontalRule: lighten(0.1, colors.almostBlack),
noticeInfoText: colors.white,
noticeTipText: colors.white,
noticeWarningText: colors.white,
progressBarBackground: colors.slate,
scrollbarBackground: colors.black,
scrollbarThumb: colors.lightBlack,
modalBackdrop: colors.black50,
modalBackground: "#1f2128",
modalShadow:
"0 0 0 1px rgba(0, 0, 0, 0.1), 0 8px 16px rgba(0, 0, 0, 0.3), 0 2px 4px rgba(0, 0, 0, 0.08)",
menuItemSelected: lighten(0.1, "#1f2128"),
menuBackground: "#1f2128",
menuShadow:
"0 0 0 1px rgba(0, 0, 0, 0.1), 0 8px 16px rgba(0, 0, 0, 0.3), 0 2px 4px rgba(0, 0, 0, 0.08)",
divider: lighten(0.1, colors.almostBlack),
titleBarDivider: darken(0.4, colors.slate),
inputBorder: colors.slateDark,
inputBorderFocused: colors.slate,
listItemHoverBackground: colors.white10,
toolbarHoverBackground: colors.slate,
toolbarBackground: colors.white,
toolbarInput: colors.black10,
toolbarItem: colors.lightBlack,
tableDivider: colors.lightBlack,
tableSelected: colors.accent,
tableSelectedBackground: "#002333",
buttonNeutralBackground: colors.almostBlack,
buttonNeutralText: colors.white,
buttonNeutralBorder: colors.slateDark,
tooltipBackground: colors.white,
tooltipText: colors.lightBlack,
toastBackground: colors.white,
toastText: colors.lightBlack,
quote: colors.almostWhite,
code: colors.almostWhite,
codeBackground: colors.black75,
codeBorder: colors.black50,
codeString: "#3d8fd1",
embedBorder: colors.black50,
horizontalRule: lighten(0.1, colors.almostBlack),
noticeInfoText: colors.white,
noticeTipText: colors.white,
noticeWarningText: colors.white,
progressBarBackground: colors.slate,
scrollbarBackground: colors.black,
scrollbarThumb: colors.lightBlack,
};
};
export const lightMobile = light;
export const buildPitchBlackTheme = (input: Partial<Colors>) => {
const colors = buildDarkTheme(input);
export const darkMobile = {
...dark,
background: colors.black,
codeBackground: colors.almostBlack,
return {
...colors,
background: colors.black,
codeBackground: colors.almostBlack,
};
};
export default light;
export const light = buildLightTheme(defaultColors);
export default light as DefaultTheme;