(core) Add dark mode to user preferences

Summary:
Adds initial implementation of dark mode. Preferences for dark mode are
available on the account settings page. Dark mode is currently a beta feature
as there are still some small bugs to squash and a few remaining UI elements
to style.

Test Plan: Browser tests.

Reviewers: jarek

Reviewed By: jarek

Subscribers: paulfitz, jarek

Differential Revision: https://phab.getgrist.com/D3587
This commit is contained in:
George Gevoian
2022-09-05 18:51:57 -07:00
parent d7b3fb972c
commit ec157dc469
122 changed files with 3616 additions and 1075 deletions

View File

@@ -3,7 +3,7 @@ import {GristDoc} from 'app/client/components/GristDoc';
import {ViewFieldRec} from 'app/client/models/entities/ViewFieldRec';
import {textButton} from 'app/client/ui2018/buttons';
import {ColorOption, colorSelect} from 'app/client/ui2018/ColorSelect';
import {colors, vars} from 'app/client/ui2018/cssVars';
import {theme, vars} from 'app/client/ui2018/cssVars';
import {ConditionalStyle} from 'app/client/widgets/ConditionalStyle';
import {Disposable, dom, DomContents, fromKo, MultiHolder, Observable, styled} from 'grainjs';
@@ -67,6 +67,7 @@ const cssLine = styled('div', `
`);
const cssLabel = styled('div', `
color: ${theme.text};
text-transform: uppercase;
font-size: ${vars.xsmallFontSize};
`);
@@ -83,6 +84,6 @@ const cssRow = styled('div', `
margin-top: 24px;
}
&-disabled {
color: ${colors.slate};
color: ${theme.disabledText};
}
`);

View File

@@ -2,7 +2,7 @@ import {createGroup} from 'app/client/components/commands';
import {ACIndexImpl, ACItem, ACResults, buildHighlightedDom, normalizeText, HighlightFunc} from 'app/client/lib/ACIndex';
import {IAutocompleteOptions} from 'app/client/lib/autocomplete';
import {IToken, TokenField, tokenFieldStyles} from 'app/client/lib/TokenField';
import {colors, testId} from 'app/client/ui2018/cssVars';
import {colors, testId, theme} from 'app/client/ui2018/cssVars';
import {menuCssClass} from 'app/client/ui2018/menus';
import {createMobileButtons, getButtonMargins} from 'app/client/widgets/EditorButtons';
import {EditorPlacement} from 'app/client/widgets/EditorPlacement';
@@ -253,7 +253,7 @@ export class ChoiceListEditor extends NewBaseEditor {
}
const cssCellEditor = styled('div', `
background-color: white;
background-color: ${theme.cellEditorBg};
font-family: var(--grist-font-family-data);
font-size: var(--grist-medium-font-size);
`);
@@ -332,7 +332,7 @@ const cssInputSizer = styled('div', `
// Set z-index to be higher than the 1000 set for .cell_editor.
export const cssChoiceList = styled('div', `
z-index: 1001;
box-shadow: 0 0px 8px 0 rgba(38,38,51,0.6);
box-shadow: 0 0px 8px 0 ${theme.menuShadow};
overflow-y: auto;
padding: 8px 0 0 0;
--weaseljs-menu-item-padding: 8px 16px;

View File

@@ -2,7 +2,7 @@ import {IToken, TokenField} from 'app/client/lib/TokenField';
import {cssBlockedCursor} from 'app/client/ui/RightPanelStyles';
import {basicButton, primaryButton} from 'app/client/ui2018/buttons';
import {colorButton, ColorOption} from 'app/client/ui2018/ColorSelect';
import {colors, testId} from 'app/client/ui2018/cssVars';
import {colors, testId, theme} from 'app/client/ui2018/cssVars';
import {editableLabel} from 'app/client/ui2018/editableLabel';
import {icon} from 'app/client/ui2018/icons';
import {ChoiceOptionsByName, IChoiceOptions} from 'app/client/widgets/ChoiceTextBox';
@@ -422,17 +422,17 @@ const cssListBox = styled('div', `
line-height: 1.5;
padding-left: 4px;
padding-right: 4px;
border: 1px solid ${colors.hover};
border: 1px solid ${theme.choiceEntryBorderHover};
border-radius: 4px;
background-color: white;
background-color: ${theme.choiceEntryBg};
`);
const cssListBoxInactive = styled(cssListBox, `
cursor: pointer;
border: 1px solid ${colors.darkGrey};
border: 1px solid ${theme.choiceEntryBorder};
&:hover:not(&-disabled) {
border: 1px solid ${colors.hover};
border: 1px solid ${theme.choiceEntryBorderHover};
}
&-disabled {
opacity: 0.6;
@@ -445,7 +445,7 @@ const cssListRow = styled('div', `
margin-bottom: 4px;
padding: 4px 8px;
color: ${colors.dark};
background-color: ${colors.mediumGrey};
background-color: ${colors.mediumGreyOpaque};
border-radius: 3px;
text-overflow: ellipsis;
`);
@@ -510,6 +510,7 @@ const cssEditableLabel = styled('div', `
`);
const cssTokenInput = styled('input', `
background-color: ${theme.choiceEntryBg};
padding-top: 4px;
padding-bottom: 4px;
overflow: hidden;

View File

@@ -1,8 +1,8 @@
import {dom, DomContents, DomElementArg, styled} from "grainjs";
import {colors, vars} from "app/client/ui2018/cssVars";
import {Style} from 'app/client/models/Styles';
import {colors, theme, vars} from 'app/client/ui2018/cssVars';
import {dom, DomContents, DomElementArg, styled} from 'grainjs';
export const DEFAULT_FILL_COLOR = colors.mediumGreyOpaque.value;
export const DEFAULT_FILL_COLOR = colors.mediumGreyOpaque.value!;
export const DEFAULT_TEXT_COLOR = '#000000';
export interface IChoiceTokenOptions extends Style {
@@ -70,8 +70,7 @@ export const cssChoiceACItem = styled('li', `
cursor: pointer;
&.selected {
background-color: ${colors.mediumGreyOpaque};
color: ${colors.dark};
background-color: ${theme.autocompleteChoiceSelectedBg};
}
&-with-new {
scroll-margin-bottom: ${ADD_NEW_HEIGHT};
@@ -79,15 +78,11 @@ export const cssChoiceACItem = styled('li', `
&-new {
display: flex;
align-items: center;
color: ${colors.slate};
position: sticky;
bottom: 0px;
height: ${ADD_NEW_HEIGHT};
background-color: white;
border-top: 1px solid ${colors.mediumGreyOpaque};
background-color: ${theme.menuBg};
border-top: 1px solid ${theme.menuBorder};
scroll-margin-bottom: initial;
}
&-new.selected {
color: ${colors.lightGrey};
}
`);

View File

@@ -6,7 +6,7 @@ import {Style} from 'app/client/models/Styles';
import {cssFieldFormula} from 'app/client/ui/FieldConfig';
import {textButton} from 'app/client/ui2018/buttons';
import {ColorOption, colorSelect} from 'app/client/ui2018/ColorSelect';
import {colors, vars} from 'app/client/ui2018/cssVars';
import {theme, vars} from 'app/client/ui2018/cssVars';
import {icon} from 'app/client/ui2018/icons';
import {setupEditorCleanup} from 'app/client/widgets/FieldEditor';
import {cssError, openFormulaEditor} from 'app/client/widgets/FormulaEditor';
@@ -197,12 +197,12 @@ export class ConditionalStyle extends Disposable {
const cssIcon = styled(icon, `
flex: 0 0 auto;
--icon-color: ${colors.slate};
`);
const cssLabel = styled('div', `
text-transform: uppercase;
margin: 16px 16px 12px 16px;
color: ${theme.text};
font-size: ${vars.xsmallFontSize};
`);
@@ -214,7 +214,7 @@ const cssRow = styled('div', `
margin-top: 24px;
}
&-disabled {
color: ${colors.slate};
color: ${theme.disabledText};
}
`);
@@ -224,9 +224,9 @@ const cssRemoveButton = styled(cssIcon, `
margin-right: 0px;
transform: translateY(4px);
cursor: pointer;
--icon-color: ${colors.slate};
--icon-color: ${theme.controlSecondaryFg};
&:hover {
--icon-color: ${colors.lightGreen};
--icon-color: ${theme.controlPrimaryFg};
}
`);
@@ -244,7 +244,7 @@ const cssRuleList = styled('div', `
`);
const cssErrorBorder = styled('div', `
border-color: ${colors.error};
border-color: ${theme.inputInvalid};
`);
const cssRuleError = styled(cssError, `

View File

@@ -12,7 +12,7 @@
}
.fieldbuilder_settings {
background-color: #e8e8e8;
background-color: var(--grist-theme-right-panel-field-settings-bg, #e8e8e8);
margin: 1rem -1px -4px -1px;
padding-bottom: 1px;
}
@@ -28,5 +28,5 @@
float: right;
padding: 0 1rem;
border-radius: 5px;
background-color: lightgrey;
background-color: var(--grist-theme-right-panel-field-settings-button-bg, lightgrey);
}

View File

@@ -17,7 +17,7 @@ import { CombinedStyle, Style } from 'app/client/models/Styles';
import { FieldSettingsMenu } from 'app/client/ui/FieldMenus';
import { cssBlockedCursor, cssLabel, cssRow } from 'app/client/ui/RightPanelStyles';
import { buttonSelect } from 'app/client/ui2018/buttonSelect';
import { colors } from 'app/client/ui2018/cssVars';
import { theme } from 'app/client/ui2018/cssVars';
import { IOptionFull, menu, select } from 'app/client/ui2018/menus';
import { DiffBox } from 'app/client/widgets/DiffBox';
import { buildErrorDom } from 'app/client/widgets/ErrorDom';
@@ -494,10 +494,8 @@ export class FieldBuilder extends Disposable {
if (this.isDisposed()) { return null; }
const fromRules = computedRule()?.style?.fillColor;
let fill = fromRules || this.field.fillColor();
// If user set white color - remove it to play nice with zebra strips.
// If there is no color we are using fully transparent white color (for tests mainly).
fill = fill ? fill.toUpperCase() : fill;
return (fill === '#FFFFFF' ? '' : fill) || '';
return fill || '';
})).onlyNotifyUnequal();
const fontBold = buildFontOptions(this, computedRule, 'fontBold');
@@ -641,6 +639,6 @@ const cssTypeSelectMenu = styled('div', `
`);
const cssSeparator = styled('div', `
border-bottom: 1px solid ${colors.mediumGrey};
border-bottom: 1px solid ${theme.pagePanelsBorder};
margin-top: 16px;
`);

View File

@@ -2,7 +2,7 @@ import * as AceEditor from 'app/client/components/AceEditor';
import {createGroup} from 'app/client/components/commands';
import {DataRowModel} from 'app/client/models/DataRowModel';
import {ViewFieldRec} from 'app/client/models/entities/ViewFieldRec';
import {colors, testId} from 'app/client/ui2018/cssVars';
import {colors, testId, theme} from 'app/client/ui2018/cssVars';
import {icon} from 'app/client/ui2018/icons';
import {createMobileButtons, getButtonMargins} from 'app/client/widgets/EditorButtons';
import {EditorPlacement, ISize} from 'app/client/widgets/EditorPlacement';
@@ -427,5 +427,5 @@ const cssCollapseIcon = styled(icon, `
`);
export const cssError = styled('div', `
color: ${colors.error};
color: ${theme.errorText};
`);

View File

@@ -5,7 +5,7 @@ import {ViewFieldRec} from 'app/client/models/entities/ViewFieldRec';
import {reportError} from 'app/client/models/errors';
import {cssLabel, cssRow} from 'app/client/ui/RightPanelStyles';
import {ISelectorOption, makeButtonSelect} from 'app/client/ui2018/buttonSelect';
import {colors, testId} from 'app/client/ui2018/cssVars';
import {testId, theme} from 'app/client/ui2018/cssVars';
import {icon} from 'app/client/ui2018/icons';
import {NTextBox} from 'app/client/widgets/NTextBox';
import {clamp} from 'app/common/gutil';
@@ -153,8 +153,8 @@ function decimals(
const cssDecimalsBox = styled('div', `
position: relative;
flex: auto;
--icon-color: ${colors.slate};
color: ${colors.slate};
--icon-color: ${theme.lightText};
color: ${theme.lightText};
font-weight: normal;
display: flex;
align-items: center;
@@ -171,9 +171,10 @@ const cssNumLabel = styled('div', `
const cssNumInput = styled('input', `
padding: 4px 32px 4px 40px;
border: 1px solid ${colors.darkGrey};
border: 1px solid ${theme.inputBorder};
border-radius: 3px;
color: ${colors.dark};
background-color: ${theme.inputBg};
color: ${theme.inputFg};
width: 100%;
text-align: right;
appearance: none;
@@ -191,13 +192,14 @@ const cssSpinner = styled('div', `
`);
const cssSpinnerBtn = styled('div', `
--icon-color: ${theme.controlSecondaryFg};
flex: 1 1 0px;
min-height: 0px;
position: relative;
cursor: pointer;
overflow: hidden;
&:hover {
--icon-color: ${colors.dark};
--icon-color: ${theme.controlSecondaryHoverFg};
}
`);
@@ -213,11 +215,11 @@ const cssSpinnerBottom = styled(icon, `
const cssModeSelect = styled(makeButtonSelect, `
flex: 4 4 0px;
background-color: white;
background-color: ${theme.inputBg};
`);
const cssSignSelect = styled(makeButtonSelect, `
flex: 1 1 0px;
background-color: white;
background-color: ${theme.inputBg};
margin-left: 16px;
`);

View File

@@ -2,7 +2,7 @@ import { ACResults, buildHighlightedDom, normalizeText, HighlightFunc } from 'ap
import { Autocomplete } from 'app/client/lib/autocomplete';
import { ICellItem } from 'app/client/models/ColumnACIndexes';
import { reportError } from 'app/client/models/errors';
import { colors, testId, vars } from 'app/client/ui2018/cssVars';
import { colors, testId, theme, vars } from 'app/client/ui2018/cssVars';
import { icon } from 'app/client/ui2018/icons';
import { menuCssClass } from 'app/client/ui2018/menus';
import { FieldOptions } from 'app/client/widgets/NewBaseEditor';
@@ -171,25 +171,26 @@ const cssRefItem = styled('li', `
outline: none;
padding: var(--weaseljs-menu-item-padding, 8px 24px);
cursor: pointer;
color: ${theme.menuItemFg};
&.selected {
background-color: var(--weaseljs-selected-background-color, #5AC09C);
color: var(--weaseljs-selected-color, white);
background-color: ${theme.menuItemSelectedBg};
color: ${theme.menuItemSelectedFg};
}
&-with-new {
scroll-margin-bottom: ${addNewHeight};
}
&-new {
color: ${colors.slate};
color: ${theme.lightText};
position: sticky;
bottom: 0px;
height: ${addNewHeight};
background-color: white;
border-top: 1px solid ${colors.mediumGrey};
background-color: ${theme.menuBg};
border-top: 1px solid ${theme.menuBorder};
scroll-margin-bottom: initial;
}
&-new.selected {
color: ${colors.lightGrey};
color: ${theme.menuItemSelectedFg};
}
`);
@@ -221,8 +222,8 @@ const cssRefEditIcon = styled(icon, `
`);
const cssMatchText = styled('span', `
color: ${colors.lightGreen};
color: ${theme.autocompleteMatchText};
.selected > & {
color: ${colors.lighterGreen};
color: ${theme.autocompleteSelectedMatchText};
}
`);

View File

@@ -3,7 +3,7 @@ import { ACItem, ACResults, normalizeText, HighlightFunc } from 'app/client/lib/
import { IAutocompleteOptions } from 'app/client/lib/autocomplete';
import { IToken, TokenField, tokenFieldStyles } from 'app/client/lib/TokenField';
import { reportError } from 'app/client/models/errors';
import { colors, testId } from 'app/client/ui2018/cssVars';
import { colors, testId, theme } from 'app/client/ui2018/cssVars';
import { menuCssClass } from 'app/client/ui2018/menus';
import { cssChoiceToken } from 'app/client/widgets/ChoiceToken';
import { createMobileButtons, getButtonMargins } from 'app/client/widgets/EditorButtons';
@@ -286,7 +286,7 @@ export class ReferenceListEditor extends NewBaseEditor {
}
const cssCellEditor = styled('div', `
background-color: white;
background-color: ${theme.cellEditorBg};
font-family: var(--grist-font-family-data);
font-size: var(--grist-medium-font-size);
`);

View File

@@ -1,7 +1,8 @@
.record-add .field_clip {
background-color: inherit;
background-color: var(--grist-theme-table-add-new-bg, inherit);
}
.transform_field {
color: black;
background-color: #FEFFE8;
}

View File

@@ -5,11 +5,11 @@
}
.default_editor {
box-shadow: 0 0 3px 2px var(--grist-color-cursor);
box-shadow: 0 0 3px 2px var(--grist-theme-cursor, var(--grist-color-cursor));
}
.readonly_editor {
box-shadow: 0 0 3px 2px var(--grist-color-slate);
box-shadow: 0 0 3px 2px var(--grist-theme-cursor-readonly, var(--grist-color-slate));
}
/* make room for lock icon */
@@ -42,7 +42,7 @@
/* Make overflow hidden, since editor might be 1 pixel bigger due to fix for devices
* with different pixel ratio */
.formula_editor {
background-color: white;
background-color: var(--grist-theme-formula-editor-bg, white);
padding: 4px 0 2px 21px;
z-index: 10;
overflow: hidden;
@@ -63,7 +63,7 @@
}
.celleditor_cursor_editor {
background-color: white;
background-color: var(--grist-theme-cell-editor-bg, white);
/* the following are copied from .field_clip */
padding: 3px 3px 0px 3px;
@@ -82,7 +82,8 @@
border: none;
resize: none;
z-index: 10;
color: black;
background-color: var(--grist-theme-cell-editor-bg, unset);
color: var(--grist-theme-cell-editor-fg, black);
/* Inherit styles, same as for .celleditor_content_measure, to ensure that sizes correspond. */
font-family: inherit;