mirror of
https://github.com/gristlabs/grist-core.git
synced 2026-03-02 04:09:24 +00:00
(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:
@@ -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};
|
||||
}
|
||||
`);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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};
|
||||
}
|
||||
`);
|
||||
|
||||
@@ -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, `
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
`);
|
||||
|
||||
@@ -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};
|
||||
`);
|
||||
|
||||
@@ -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;
|
||||
`);
|
||||
|
||||
@@ -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};
|
||||
}
|
||||
`);
|
||||
|
||||
@@ -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);
|
||||
`);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user