(core) Polish dark mode and remove beta tag

Summary:
Polishes support for dark mode and enables syncing with the OS theme
by default.

Test Plan: Manual.

Reviewers: JakubSerafin

Reviewed By: JakubSerafin

Subscribers: JakubSerafin

Differential Revision: https://phab.getgrist.com/D4041
This commit is contained in:
George Gevoian
2023-09-21 12:57:58 -04:00
parent d1826987bb
commit 273b976cab
87 changed files with 979 additions and 651 deletions

View File

@@ -16,7 +16,7 @@ const cssMemoInput = styled('input', `
border-radius: 3px;
border: 1px solid transparent;
cursor: pointer;
color: ${theme.accentText};
color: ${theme.controlFg};
background-color: ${theme.inputBg};
caret-color : ${theme.inputFg};
font: 12px 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace;
@@ -29,7 +29,7 @@ const cssMemoInput = styled('input', `
&:not(&-disabled):focus-within {
outline: none !important;
cursor: text;
box-shadow: inset 0 0 0 1px ${theme.accentBorder};
border-color: ${theme.accentBorder};
box-shadow: inset 0 0 0 1px ${theme.controlFg};
border-color: ${theme.controlFg};
}
`);

View File

@@ -1,4 +1,4 @@
import {colors} from 'app/client/ui2018/cssVars';
import {theme} from 'app/client/ui2018/cssVars';
import {icon} from 'app/client/ui2018/icons';
import {IOption, select} from 'app/client/ui2018/menus';
import {MaybeObsArray, Observable, styled} from 'grainjs';
@@ -19,7 +19,7 @@ export const cssSelect = styled(select, `
cursor: pointer;
&:hover, &:focus, &.weasel-popup-open, &-active {
border: 1px solid ${colors.darkGrey};
border: 1px solid ${theme.selectButtonBorder};
box-shadow: none;
}
`);

View File

@@ -2,7 +2,7 @@
* Implements a widget showing 3-state boxes for permissions
* (for Allow / Deny / Pass-Through).
*/
import {colors, testId} from 'app/client/ui2018/cssVars';
import {colors, testId, theme} from 'app/client/ui2018/cssVars';
import {cssIconButton, icon} from 'app/client/ui2018/icons';
import {menu, menuIcon, menuItem} from 'app/client/ui2018/menus';
import {PartialPermissionSet, PartialPermissionValue} from 'app/common/ACLPermissions';
@@ -155,8 +155,8 @@ const cssBit = styled('div', `
border-radius: 2px;
font-size: 13px;
font-weight: 500;
border: 1px dashed ${colors.darkGrey};
color: ${colors.darkGrey};
border: 1px dashed ${theme.accessRulesTableBodyLightFg};
color: ${theme.accessRulesTableBodyLightFg};
cursor: pointer;
display: flex;

View File

@@ -2,6 +2,16 @@
background-color: var(--grist-theme-ace-editor-bg, white);
}
.ace_editor .ace_placeholder {
font-family: Monaco, Menlo, "Ubuntu Mono", Consolas, "Source Code Pro", source-code-pro, monospace;
font-size: 11px;
color: var(--grist-theme-text-light, #929299);
font-style: italic;
white-space: nowrap;
opacity: 1.0;
transform: none;
}
.ace_grist_link_hidden {
display: none;
}

View File

@@ -31,7 +31,7 @@
}
.action_desc {
color: var(--grist-theme-document-history-activity-text-light, unset);
color: var(--grist-theme-document-history-activity-text, unset);
}
.action_log_item.undone > .action_info,
@@ -68,37 +68,38 @@
text-align: center;
margin-top: 0;
padding-top: 0;
color: var(--grist-theme-document-history-activity-text, #000);
color: var(--grist-theme-document-history-activity-text-light, #333);
}
.action_log_table td {
border-left: 1px solid #888;
border-right: 1px solid #888;
border-bottom: 1px solid #888;
border-top: 1px solid #888;
border: 1px solid var(--grist-theme-document-history-table-border, lightgray);
cursor: pointer;
}
.action_log_table th {
border-top: 1px solid #ccc;
border-left: 1px solid #ccc;
border-right: 1px solid #ccc;
color: #888;
border-top: 1px solid var(--grist-theme-document-history-table-border-light, #D9D9D9);
border-left: 1px solid var(--grist-theme-document-history-table-border-light, #D9D9D9);
border-right: 1px solid var(--grist-theme-document-history-table-border-light, #D9D9D9);
color: var(--grist-theme-document-history-table-header-fg, #000);
}
.action_log_table th:first-child {
border: none;
border-bottom: 1px solid #ccc;
border-bottom: 1px solid var(--grist-theme-document-history-table-border-light, #D9D9D9);
}
.action_log_table td:first-child {
border: none;
border-left: 1px solid #ccc;
border-bottom: 1px solid #ccc;
color: #888;
border-left: 1px solid var(--grist-theme-document-history-table-border-light, #D9D9D9);
border-bottom: 1px solid var(--grist-theme-document-history-table-border-light, #D9D9D9);
color: var(--grist-theme-document-history-table-header-fg, #000);
cursor: inherit;
}
.action_log_table td:not(:first-child) {
background-color: var(--grist-theme-table-body-bg);
}
.action_log_table td, .action_log_table th {
padding-left: 3px;
padding-right: 3px;
@@ -127,3 +128,7 @@
.action_comment {
display: none;
}
.action_info {
color: var(--grist-theme-document-history-activity-text-light, #929299);
}

View File

@@ -10,15 +10,15 @@ import * as ko from 'knockout';
import koArray from 'app/client/lib/koArray';
import {KoArray} from 'app/client/lib/koArray';
import * as koDom from 'app/client/lib/koDom';
import * as koForm from 'app/client/lib/koForm';
import {GristDoc} from 'app/client/components/GristDoc';
import {ActionGroup} from 'app/common/ActionGroup';
import {ActionSummary, asTabularDiffs, defunctTableName, getAffectedTables,
LabelDelta} from 'app/common/ActionSummary';
import {CellDelta, TabularDiff} from 'app/common/TabularDiff';
import {DomContents, IDomComponent} from 'grainjs';
import {DomContents, fromKo, IDomComponent} from 'grainjs';
import {makeT} from 'app/client/lib/localization';
import {labeledSquareCheckbox} from 'app/client/ui2018/checkbox';
/**
*
@@ -230,10 +230,12 @@ export class ActionLog extends dispose.Disposable implements IDomComponent {
this._loadActionSummaries().catch(() => gristNotify(t("Action Log failed to load")));
return dom('div.action_log',
{tabIndex: '-1'},
dom('div.preference_item',
koForm.checkbox(this._showAllTables,
dom.testId('ActionLog_allTables'),
dom('span.preference_desc', 'All tables'))),
dom('div',
labeledSquareCheckbox(fromKo(this._showAllTables),
t('All tables'),
dom.testId('ActionLog_allTables'),
),
),
dom('div.action_log_load',
koDom.show(() => this._loading()),
'Loading...'),

View File

@@ -97,6 +97,8 @@ export class ColumnTransform extends Disposable {
}));
}
return this.editor.buildDom((aceObj: any) => {
aceObj.setOptions({placeholder: 'Enter formula.'});
aceObj.setHighlightActiveLine(false);
this.editor.adjustContentToWidth();
this.editor.attachSaveCommand();
aceObj.on('change', () => {

View File

@@ -97,8 +97,25 @@
margin-right: 2px;
}
.detail-buttons {
display: flex;
align-items: center;
gap: 4px;
}
.detail-left, .detail-right, .detail-add-btn {
--icon-color: var(--grist-theme-control-secondary-fg, #929299);
padding: 3px;
border-radius: 4px;
}
.detail-left.disabled, .detail-right.disabled, .detail-add-btn.disabled {
cursor: default !important;
--icon-color: var(--grist-theme-control-secondary-disabled-fg, #D9D9D9);
}
.detail-button:not(.disabled):hover {
cursor: pointer;
background-color: var(--grist-theme-hover, rgba(217,217,217,0.6));
}
.detail-add-grp {

View File

@@ -6,6 +6,7 @@ const kd = require('app/client/lib/koDom');
const koDomScrolly = require('app/client/lib/koDomScrolly');
const {renderAllRows} = require('app/client/components/Printing');
const {isNarrowScreen} = require('app/client/ui2018/cssVars');
const {icon} = require('app/client/ui2018/icons');
require('app/client/lib/koUtil'); // Needed for subscribeInit.
@@ -381,28 +382,29 @@ DetailView.prototype.buildTitleControls = function() {
kd.text(() => this._isAddRow() ? 'Add record' :
`${this.cursor.rowIndex() + 1} of ${this.getLastDataRowIndex() + 1}`)
),
dom('div.btn-group.btn-group-xs',
dom('div.btn.btn-default.detail-left',
dom('span.glyphicon.glyphicon-chevron-left'),
dom('div.detail-buttons',
dom('div.detail-button.detail-left',
icon('ArrowLeft'),
dom.on('click', () => { this.cursor.rowIndex(this.cursor.rowIndex() - 1); }),
kd.toggleClass('disabled', () => this.cursor.rowIndex() === 0)
kd.toggleClass('disabled', () => this.cursor.rowIndex() === 0),
dom.testId('detailView_detail_left'),
),
dom('div.btn.btn-default.detail-right',
dom('span.glyphicon.glyphicon-chevron-right'),
dom('div.detail-button.detail-right',
icon('ArrowRight'),
dom.on('click', () => { this.cursor.rowIndex(this.cursor.rowIndex() + 1); }),
kd.toggleClass('disabled', () => this.cursor.rowIndex() >= this.viewData.all().length - 1)
)
),
dom('div.btn-group.btn-group-xs.detail-add-grp',
dom('div.btn.btn-default.detail-add-btn',
dom('span.glyphicon.glyphicon-plus'),
kd.toggleClass('disabled', () => this.cursor.rowIndex() >= this.viewData.all().length - 1),
dom.testId('detailView_detail_right'),
),
dom('div.detail-button.detail-add-btn',
icon('Plus'),
dom.on('click', () => {
let addRowIndex = this.viewData.getRowIndex('new');
this.cursor.rowIndex(addRowIndex);
}),
kd.toggleClass('disabled', () => this.viewData.getRowId(this.cursor.rowIndex()) === 'new')
)
)
kd.toggleClass('disabled', () => this.viewData.getRowId(this.cursor.rowIndex()) === 'new'),
dom.testId('detailView_detail_add'),
),
),
))
);
};

View File

@@ -71,7 +71,7 @@
width: 4rem; /* Also should match width for .gridview_header_corner, and the overlay elements */
flex: none;
border-bottom: 1px solid var(--grist-theme-table-header-border-dark, var(--grist-color-dark-grey));
border-bottom: 1px solid var(--grist-theme-table-header-border, lightgray);
color: var(--grist-theme-table-header-fg, unset);
background-color: var(--grist-theme-table-header-bg, var(--grist-color-light-grey));
z-index: 20; /* goes over data cells */
@@ -102,7 +102,7 @@
* do not want !important, as it interferes with row selection.
*/
.gridview_data_row_num {
background-color: var(--grist-theme-table-header-bg , var(--grist-color-light-grey)) !important;
background-color: var(--grist-color-light-grey) !important;
}
.gridview_header_backdrop_top {
display: none;
@@ -111,7 +111,7 @@
display: none;
}
.gridview_data_header {
background-color: var(--grist-theme-table-header-bg, var(--grist-color-light-grey)) !important;
background-color: var(--grist-color-light-grey) !important;
}
.print-widget .gridview_header_backdrop_left, .print-widget .gridview_data_corner_overlay {
display: none;
@@ -127,15 +127,15 @@
display: table-header-group;
break-inside: avoid;
position: static;
border-top: 1px solid var(--grist-theme-table-header-border-dark, var(--grist-color-dark-grey));
border-left: 1px solid var(--grist-theme-table-header-border-dark, var(--grist-color-dark-grey));
border-top: 1px solid var(--grist-color-dark-grey);
border-left: 1px solid var(--grist-color-dark-grey);
}
.print-widget .gridview_data_header {
padding-left: 4rem !important;
}
.print-widget .gridview_data_pane .print-all-rows {
display: table-row-group;
border-left: 1px solid var(--grist-theme-table-body-border, var(--grist-color-dark-grey));
border-left: 1px solid var(--grist-color-dark-grey);
}
.print-widget .gridview_data_pane .print-row {
display: table-row;

View File

@@ -1,44 +0,0 @@
.preference_mask {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: 10;
background-color: rgba(1, 1, 1, 0.3);
}
.preference_window {
position: absolute;
background-color: white;
display: inline-block;
padding: 10px 20px;
width: 60%;
margin: 20%;
box-shadow: 0px 1px 3px 0px rgba(0,0,0,0.8);
}
.preference_title {
color: #546e7a;
text-align: left;
border-bottom: 1px solid rgba(0,0,0,.12);
font-family: 'Roboto', Helvetica, Arial, sans-serif;
width: 100%;
height: 40px;
}
.preference_content {
width: 100%;
font-size: 1.4rem;
}
.preference_desc {
color: var(--grist-theme-document-history-activity-text, unset);
margin-left: 5px;
cursor: pointer;
font-weight: normal;
}
.preference_footer > .kf_elem {
flex: 1 1 100%;
}

View File

@@ -152,7 +152,7 @@ const cssSectionWrapper = styled('div', `
border-bottom-right-radius: 0px;
& .viewsection_content {
margin: 0px;
margin-top: 12px;
margin-top: 8px;
}
& .viewsection_title {
padding: 0px 12px;

View File

@@ -4,14 +4,13 @@ import * as tableUtil from 'app/client/lib/tableUtil';
import {ColumnRec, DocModel, ViewFieldRec} from 'app/client/models/DocModel';
import {KoSaveableObservable} from 'app/client/models/modelUtil';
import {cssFieldEntry, cssFieldLabel} from 'app/client/ui/VisibleFieldsConfig';
import {colors, testId} from 'app/client/ui2018/cssVars';
import {testId, theme} from 'app/client/ui2018/cssVars';
import {icon} from 'app/client/ui2018/icons';
import {menuText} from 'app/client/ui2018/menus';
import {menu, menuItem, menuText} from 'app/client/ui2018/menus';
import {FieldBuilder} from 'app/client/widgets/FieldBuilder';
import * as gutil from 'app/common/gutil';
import {Disposable, dom, fromKo, styled} from 'grainjs';
import ko from 'knockout';
import {menu, menuItem} from 'popweasel';
import {makeT} from 'app/client/lib/localization';
const t = makeT('RefSelect');
@@ -89,7 +88,7 @@ export class RefSelect extends Disposable {
testId('ref-select'),
dom.forEach(fromKo(this._added.getObservable()), (col) =>
cssFieldEntry(
cssFieldLabel(dom.text(col.label)),
cssColumnLabel(dom.text(col.label)),
cssRemoveIcon('Remove',
dom.on('click', () => this._removeFormulaField(col)),
testId('ref-select-remove'),
@@ -233,15 +232,15 @@ const cssEmptyMenuText = styled(menuText, `
const cssAddLink = styled('div', `
display: flex;
cursor: pointer;
color: ${colors.lightGreen};
--icon-color: ${colors.lightGreen};
color: ${theme.controlFg};
--icon-color: ${theme.controlFg};
&:not(:first-child) {
margin-top: 8px;
}
&:hover, &:focus, &:active {
color: ${colors.darkGreen};
--icon-color: ${colors.darkGreen};
color: ${theme.controlHoverFg};
--icon-color: ${theme.controlHoverFg};
}
`);
@@ -258,3 +257,7 @@ const cssRemoveIcon = styled(icon, `
display: block;
}
`);
const cssColumnLabel = styled(cssFieldLabel, `
line-height: 16px;
`);

View File

@@ -6,7 +6,7 @@ import {ViewFieldRec} from 'app/client/models/entities/ViewFieldRec';
import {UserError} from 'app/client/models/errors';
import {ALL, RowsChanged, SortedRowSet} from "app/client/models/rowset";
import {showTransientTooltip} from 'app/client/ui/tooltips';
import {colors, isNarrowScreen, isNarrowScreenObs, theme, vars} from 'app/client/ui2018/cssVars';
import {isNarrowScreen, isNarrowScreenObs, theme, vars} from 'app/client/ui2018/cssVars';
import {icon} from 'app/client/ui2018/icons';
import {CellValue} from 'app/common/DocActions';
import {isEmptyList, isListType, isRefListType} from "app/common/gristTypes";
@@ -314,7 +314,7 @@ const cssSummaryPart = styled('div', `
left: 0;
bottom: 0;
right: 0;
background-color: ${colors.mediumGrey};
background-color: ${theme.tableCellSummaryBg};
opacity: 0.8;
z-index: -1;
}

View File

@@ -160,9 +160,10 @@ export async function prepTransformColInfo(docModel: DocModel, origCol: ColumnRe
// trouble than desired behavior. For many choices, recommend using a Ref to helper table.
const columnData = tableData.getDistinctValues(sourceCol.colId(), 100);
if (columnData) {
columnData.delete("");
columnData.delete(null);
widgetOptions = {...widgetOptions, choices: Array.from(columnData, String)};
const choices = Array.from(columnData, String).filter((choice) => {
return choice !== null && choice.trim() !== '';
});
widgetOptions = {...widgetOptions, choices};
}
}
break;
@@ -178,11 +179,12 @@ export async function prepTransformColInfo(docModel: DocModel, origCol: ColumnRe
value = String(decodeObject(value)).trim();
const tags: unknown[] = (value.startsWith('[') && gutil.safeJsonParse(value, null)) || csvDecodeRow(value);
for (const tag of tags) {
choices.add(String(tag).trim());
const choice = String(tag).trim();
if (choice === '') { continue; }
choices.add(choice);
if (choices.size > 100) { break; } // Don't suggest excessively many choices.
}
}
choices.delete("");
widgetOptions = {...widgetOptions, choices: Array.from(choices)};
}
break;

View File

@@ -131,13 +131,12 @@ ViewConfigTab.prototype._buildAdvancedSettingsDom = function() {
kd.style('margin-top', '1.5rem')
),
kf.row(kd.hide(isCollapsed),
kf.label('Table ', dom('b', kd.text(table.tableId)), ':')
),
kf.row(kd.hide(isCollapsed),
kf.buttonGroup(kf.button(() => this._makeOnDemand(table),
dom('div', primaryButton(
kd.text(() => table.onDemand() ? t("Unmark On-Demand") : t("Make On-Demand")),
dom.testId('ViewConfig_onDemandBtn')
))
kd.style('margin-top', '1rem'),
dom.on('click', () => this._makeOnDemand(table)),
dom.testId('ViewConfig_onDemandBtn'),
)),
),
];
});

View File

@@ -9,14 +9,15 @@
align-items: center;
gap: 8px;
align-self: flex-start;
margin-top: -1px;
}
.viewsection_title {
align-items: center;
flex-shrink: 0;
cursor: default;
height: 24px;
min-height: 24px;
margin-left: -16px; /* to include drag handle that shows up on hover */
margin-bottom: 4px;
white-space: nowrap;
}

View File

@@ -456,7 +456,7 @@ const cssLayoutWrapper = styled('div', `
}
&-active .viewsection_content {
margin: 0px;
margin-top: 12px;
margin-top: 8px;
}
&-active .viewsection_title {
padding: 0px 12px;

View File

@@ -7,7 +7,7 @@ import {cssIcon} from 'app/client/ui/RightPanelStyles';
import {makeCollapsedLayoutMenu} from 'app/client/ui/ViewLayoutMenu';
import {cssDotsIconWrapper, cssMenu, viewSectionMenu} from 'app/client/ui/ViewSectionMenu';
import {buildWidgetTitle} from 'app/client/ui/WidgetTitle';
import {colors, isNarrowScreenObs, mediaSmall, testId, theme} from 'app/client/ui2018/cssVars';
import {isNarrowScreenObs, mediaSmall, testId, theme} from 'app/client/ui2018/cssVars';
import {icon} from 'app/client/ui2018/icons';
import {menu} from 'app/client/ui2018/menus';
import {getWidgetTypes} from "app/client/ui/widgetTypesMap";
@@ -128,7 +128,6 @@ const cssTestClick = styled(`div`, `
`);
const cssSigmaIcon = styled(icon, `
bottom: 1px;
margin-right: 5px;
background-color: ${theme.lightText}
`);
@@ -186,8 +185,7 @@ const cssViewLeafInactive = styled('div', `
// z-index ensure it's above the resizer line, since it's hard to grab otherwise
const cssDragIcon = styled(icon, `
visibility: hidden;
--icon-color: ${colors.slate};
top: -1px;
--icon-color: ${theme.lightText};
z-index: 100;
.viewsection_title:hover &.layout_grabbable {
@@ -204,7 +202,7 @@ const cssResizing = styled('div', `
`);
const cssMiniSection = styled('div.mini_section_container', `
--icon-color: ${colors.lightGreen};
--icon-color: ${theme.accentIcon};
display: flex;
align-items: center;
padding-right: 8px;

View File

@@ -350,7 +350,8 @@ const cssBehavioralPromptModal = styled('div', `
@media ${mediaXSmall} {
& {
width: 320px;
/* Allocate 32px of space for the left and right margins. */
width: calc(100% - 64px);
}
}
`);

View File

@@ -12,6 +12,7 @@
border-style: none;
border-color: var(--grist-theme-table-body-border, var(--grist-color-dark-grey));
border-left-style: solid; /* left border, against rownumbers div, always on */
border-left-color: var(--grist-theme-table-header-border, lightgray);
border-bottom-width: 1px; /* style: none, set by record-hlines*/
/* Record background is white (or theme default) by default.
It gets overridden by the add row, zebra stripes.
@@ -203,11 +204,11 @@
text-align: center;
cursor: pointer;
/* Column headers always show vertical gridlines, to make it clear how to resize them */
border-right-color: var(--grist-theme-table-header-border-dark, var(--grist-color-dark-grey));
border-right-color: var(--grist-theme-table-header-border, lightgray);
}
.column_names.record {
border-left-color: var(--grist-theme-table-header-border, var(--grist-color-dark-grey));
border-left-color: var(--grist-theme-table-header-border, lightgray);
}
.column_name.selected > .selection {

View File

@@ -3,6 +3,7 @@ import {ACIndex, ACItem, ACResults, buildHighlightedDom, normalizeText} from "ap
import {cssSelectItem} from "app/client/lib/ACSelect";
import {Autocomplete, IAutocompleteOptions} from "app/client/lib/autocomplete";
import {colors, testId, theme} from "app/client/ui2018/cssVars";
import {icon} from "app/client/ui2018/icons";
import {menuCssClass} from "app/client/ui2018/menus";
import {
cssEmailInput,
@@ -104,7 +105,7 @@ export function buildACMemberEmail(
const renderSearchItem = (item: ACUserItem, highlightFunc: any): HTMLLIElement => (item?.isNew ? cssSelectItem(
cssMemberListItem(
cssUserImagePlus(
"+",
cssPlusIcon('Plus'),
cssUserImage.cls("-large"),
cssUserImagePlus.cls('-invalid', (use) => !use(enableAdd),
)),
@@ -199,3 +200,8 @@ const cssUserImagePlus = styled(cssUserImage, `
color: ${theme.menuItemSelectedBg};
}
`);
const cssPlusIcon = styled(icon, `
width: 20px;
height: 20px;
`);

View File

@@ -652,14 +652,14 @@ const cssToken = styled('div', `
position: relative;
flex: none;
border-radius: 3px;
background-color: ${colors.mediumGreyOpaque};
background-color: ${theme.choiceTokenBg};
padding: 4px;
margin: 3px 2px;
user-select: none;
cursor: grab;
&.selected {
background-color: ${colors.darkGrey};
background-color: ${theme.choiceTokenSelectedBg};
}
&.token-dragging {
pointer-events: none;
@@ -710,7 +710,7 @@ const cssDragTarget = styled('div', `
&:hover::after {
content: "";
position: absolute;
background-color: ${colors.lightGreen};
background-color: ${theme.controlFg};
width: 2px;
top: 0px;
bottom: 0px;
@@ -740,7 +740,7 @@ const cssVerticalDragTarget = styled('div', `
&:hover::after {
content: "";
position: absolute;
background-color: ${colors.lightGreen};
background-color: ${theme.controlFg};
height: 2px;
top: -5px;
bottom: 0px;

View File

@@ -335,6 +335,7 @@ div:hover > .kf_tooltip {
color: #606060;
overflow: hidden;
margin-top: 3px;
padding: 1px;
}
@@ -362,11 +363,11 @@ div:hover > .kf_tooltip {
}
.kf_spinner_arrow.up {
border-top: none;
border-bottom: 5px solid #606060;
border-bottom: 5px solid var(--grist-theme-numeric-spinner-fg, #606060);
margin: 2px auto;
}
.kf_spinner_arrow.down {
border-top: 5px solid #606060;
border-top: 5px solid var(--grist-theme-numeric-spinner-fg, #606060);
border-bottom: none;
margin: 1px auto 2px auto;
}

View File

@@ -26,6 +26,7 @@ import {getGristConfig} from 'app/common/urlUtils';
import {getOrgName, isTemplatesOrg, Organization, OrgError, UserAPI, UserAPIImpl} from 'app/common/UserAPI';
import {getUserPrefObs, getUserPrefsObs, markAsSeen, markAsUnSeen} from 'app/client/models/UserPrefs';
import {bundleChanges, Computed, Disposable, Observable, subscribe} from 'grainjs';
import isEqual from 'lodash/isEqual';
const t = makeT('AppModel');
@@ -311,9 +312,7 @@ export class AppModelImpl extends Disposable implements AppModel {
) {
super();
this._applyTheme();
this.autoDispose(this.currentTheme.addListener(() => this._applyTheme()));
this._setTheme();
this._recordSignUpIfIsNewUser();
const state = urlState().state.get();
@@ -488,14 +487,16 @@ export class AppModelImpl extends Disposable implements AppModel {
);
}
/**
* Applies a theme based on the user's current theme preferences.
*/
private _applyTheme() {
private _setTheme() {
// Custom CSS is incompatible with custom themes.
if (getGristConfig().enableCustomCss) { return; }
attachCssThemeVars(this.currentTheme.get());
this.autoDispose(this.currentTheme.addListener((newTheme, oldTheme) => {
if (isEqual(newTheme, oldTheme)) { return; }
attachCssThemeVars(newTheme);
}));
}
}

View File

@@ -18,7 +18,8 @@ import {getGristConfig} from 'app/common/urlUtils';
import {FullUser} from 'app/common/UserAPI';
import {detectCurrentLang, makeT} from 'app/client/lib/localization';
import {translateLocale} from 'app/client/ui/LanguageMenu';
import {Computed, Disposable, dom, domComputed, makeTestId, Observable, styled} from 'grainjs';
import {getPageTitleSuffix} from 'app/common/gristUrls';
import {Computed, Disposable, dom, domComputed, makeTestId, Observable, styled, subscribe} from 'grainjs';
const testId = makeTestId('test-account-page-');
const t = makeT('AccountPage');
@@ -27,6 +28,7 @@ const t = makeT('AccountPage');
* Creates the account page where a user can manage their profile settings.
*/
export class AccountPage extends Disposable {
private readonly _currentPage = Computed.create(this, urlState().state, (_use, s) => s.account);
private _apiKey = Observable.create<string>(this, '');
private _userObs = Observable.create<FullUser|null>(this, null);
private _isEditingName = Observable.create(this, false);
@@ -37,6 +39,7 @@ export class AccountPage extends Disposable {
constructor(private _appModel: AppModel) {
super();
this._setPageTitle();
this._fetchAll().catch(reportError);
}
@@ -228,6 +231,18 @@ designed to ensure that you're the only person who can access your account, even
testId('username-warning'),
);
}
private _setPageTitle() {
this.autoDispose(subscribe(this._currentPage, (_use, page): string => {
const suffix = getPageTitleSuffix(getGristConfig());
switch (page) {
case undefined:
case 'account': {
return document.title = `Account${suffix}`;
}
}
}));
}
}
/**

View File

@@ -100,10 +100,3 @@ export const dataRow = styled('div', `
align-items: baseline;
gap: 2px;
`);
export const betaTag = styled('span', `
text-transform: uppercase;
vertical-align: super;
font-size: ${vars.xsmallFontSize};
color: ${theme.accentText};
`);

View File

@@ -354,11 +354,6 @@ export function columnFilterMenu(owner: IDisposableOwner, opts: IFilterMenuOptio
gristDoc.behavioralPromptsManager.attachTip('filterButtons', {
popupOptions: {
attach: null,
modifiers: {
flip: {
behavior: ['right', 'top'],
},
},
placement: 'right',
},
}),

View File

@@ -55,6 +55,7 @@ const cssTextArea = styled(textarea, `
border-radius: 3px;
padding: 3px 7px;
min-height: calc(3em * 1.5);
resize: none;
&::placeholder {
color: ${theme.inputPlaceholderFg};

View File

@@ -470,18 +470,17 @@ const cssToggleButton = styled(cssIconButton, `
margin-left: 8px;
background-color: ${theme.rightPanelToggleButtonDisabledBg};
box-shadow: inset 0 0 0 1px ${theme.inputBorder};
cursor: pointer;
&-selected, &-selected:hover {
box-shadow: none;
background-color: ${theme.rightPanelToggleButtonEnabledBg};
--icon-color: ${theme.rightPanelToggleButtonEnabledFg};
}
&-selected:hover {
--icon-color: ${theme.rightPanelToggleButtonEnabledHoverFg};
}
&-disabled, &-disabled:hover {
--icon-color: ${theme.rightPanelToggleButtonDisabledFg};
cursor: not-allowed;
background-color: ${theme.rightPanelToggleButtonDisabledBg};
--icon-color: ${theme.iconDisabled};
}
`);

View File

@@ -293,7 +293,7 @@ export class FloatingPopup extends Disposable {
const body = cssPopup(
{tabIndex: '-1'},
cssPopup.cls('-auto', this._options.autoHeight ?? false),
dom.style('min-height', `${this._minHeight}px`),
dom.style('min-height', use => use(this._isMinimized) ? 'unset' : `${this._minHeight}px`),
cssPopupHeader(
cssBottomHandle(testId('move-handle')),
dom.maybe(use => !use(this._isMinimized), () => {

View File

@@ -1,7 +1,7 @@
import {bigPrimaryButton as gristBigPrimaryButton,
bigPrimaryButtonLink as gristBigPrimaryButtonLink,
textButton as gristTextButton} from 'app/client/ui2018/buttons';
import {colors, mediaXSmall, theme} from 'app/client/ui2018/cssVars';
import {mediaXSmall, theme} from 'app/client/ui2018/cssVars';
import {textInput} from 'app/client/ui/inputs';
import {styled} from 'grainjs';
@@ -61,15 +61,15 @@ export const googleButton = styled('button', `
font-weight: 500;
line-height: 16px;
padding: 16px;
color: ${colors.dark};
background-color: ${colors.lightGrey};
border: 1px solid ${colors.darkGrey};
color: ${theme.loginPageGoogleButtonFg};
background-color: ${theme.loginPageGoogleButtonBg};
border: 1px solid ${theme.loginPageGoogleButtonBorder};
border-radius: 4px;
cursor: pointer;
width: 100%;
&:hover {
background-color: ${colors.mediumGrey};
background-color: ${theme.loginPageGoogleButtonBgHover};
}
`);

View File

@@ -9,6 +9,7 @@ import {find as findInTree, fromTableData, TreeItemRecord, TreeRecord,
TreeTableData} from 'app/client/models/TreeModel';
import {TreeViewComponent} from 'app/client/ui/TreeViewComponent';
import {cssRadioCheckboxOptions, radioCheckboxOption} from 'app/client/ui2018/checkbox';
import {theme} from 'app/client/ui2018/cssVars';
import {cssLink} from 'app/client/ui2018/links';
import {ISaveModalOptions, saveModal} from 'app/client/ui2018/modals';
import {buildCensoredPage, buildPageDom, PageActions} from 'app/client/ui2018/pages';
@@ -175,8 +176,8 @@ const cssWarning = styled('div', `
`);
const cssTableName = styled('div', `
color: black;
background-color: #eee;
color: ${theme.choiceTokenFg};
background-color: ${theme.choiceTokenBg};
padding: 3px 6px;
border-radius: 4px;
`);

View File

@@ -263,7 +263,7 @@ const cssPinnedDocDesc = styled(cssPinnedDocTimestamp, `
const cssImage = styled('img', `
position: relative;
background-color: ${colors.light};
background-color: ${colors.dark};
height: 100%;
width: 100%;
object-fit: scale-down;

View File

@@ -311,7 +311,6 @@ export class RightPanel extends Disposable {
]),
cssLabel(t("TRANSFORM")),
dom.maybe<FieldBuilder|null>(fieldBuilder, builder => builder.buildTransformDom()),
dom.maybe(isMultiSelect, () => disabledSection()),
testId('panel-transform'),
),
this._disableIfReadonly(),

View File

@@ -15,6 +15,7 @@ export const cssLabel = styled('div', `
`);
export const cssHelp = styled('div', `
color: ${theme.lightText};
margin: -8px 16px 12px 16px;
font-style: italic;
font-size: ${vars.xsmallFontSize};

View File

@@ -376,12 +376,11 @@ const cssMenuIconLink = styled('a', `
display: block;
flex: none;
padding: 8px 24px;
--icon-color: ${theme.controlFg};
background-color: ${theme.menuBg};
--icon-color: ${theme.menuItemLinkFg};
&:hover {
background-color: ${theme.menuItemLinkselectedBg};
--icon-color: ${theme.menuItemLinkSelectedFg};
background-color: ${theme.hover};
--icon-color: ${theme.controlHoverFg};
}
`);

View File

@@ -263,7 +263,8 @@ const cssContributeButtonCloseButton = styled(tokenFieldStyles.cssDeleteButton,
const cssCard = styled('div', `
width: 297px;
padding: 24px;
background: #DCF4EB;
color: ${theme.announcementPopupFg};
background: ${theme.announcementPopupBg};
border-radius: 4px;
align-self: flex-start;
position: sticky;
@@ -310,10 +311,10 @@ const cssCloseButton = styled('div', `
padding: 4px;
border-radius: 4px;
cursor: pointer;
--icon-color: ${colors.slate};
--icon-color: ${theme.popupCloseButtonFg};
&:hover {
background-color: ${colors.mediumGreyOpaque};
background-color: ${theme.hover};
}
`);

View File

@@ -13,16 +13,17 @@ import {mediaSmall, theme, vars} from 'app/client/ui2018/cssVars';
import {icon} from 'app/client/ui2018/icons';
import {cssLink} from 'app/client/ui2018/links';
import {loadingSpinner} from 'app/client/ui2018/loaders';
import {commonUrls} from 'app/common/gristUrls';
import {commonUrls, getPageTitleSuffix} from 'app/common/gristUrls';
import {TelemetryPrefsWithSources} from 'app/common/InstallAPI';
import {getGristConfig} from 'app/common/urlUtils';
import {Computed, Disposable, dom, makeTestId, Observable, styled} from 'grainjs';
import {Computed, Disposable, dom, makeTestId, Observable, styled, subscribe} from 'grainjs';
const testId = makeTestId('test-support-grist-page-');
const t = makeT('SupportGristPage');
export class SupportGristPage extends Disposable {
private readonly _currentPage = Computed.create(this, urlState().state, (_use, s) => s.supportGrist);
private readonly _model: TelemetryModel = new TelemetryModelImpl(this._appModel);
private readonly _optInToTelemetry = Computed.create(this, this._model.prefs,
(_use, prefs) => {
@@ -37,6 +38,7 @@ export class SupportGristPage extends Disposable {
constructor(private _appModel: AppModel) {
super();
this._setPageTitle();
this._model.fetchTelemetryPrefs().catch(reportError);
}
@@ -186,6 +188,18 @@ export class SupportGristPage extends Disposable {
testId('sponsorship-section'),
);
}
private _setPageTitle() {
this.autoDispose(subscribe(this._currentPage, (_use, page): string => {
const suffix = getPageTitleSuffix(getGristConfig());
switch (page) {
case undefined:
case 'support-grist': {
return document.title = `Support Grist${suffix}`;
}
}
}));
}
}
function telemetryHelpCenterLink() {

View File

@@ -1,5 +1,5 @@
import {docUrl, urlState} from 'app/client/models/gristUrlState';
import {colors} from 'app/client/ui2018/cssVars';
import {theme} from 'app/client/ui2018/cssVars';
import {Document, Workspace} from 'app/common/UserAPI';
import {dom, makeTestId, styled} from 'grainjs';
import {HomeModel, ViewSettings} from 'app/client/models/HomeModel';
@@ -63,7 +63,7 @@ const cssDocName = styled(css.docName, `
const cssDocRowDetails = styled('div', `
margin: 0 16px;
line-height: 1.6;
color: ${colors.slate};
color: ${theme.lightText};
`);
const cssTemplateDocs = styled('div', `

View File

@@ -2,6 +2,7 @@ import {makeT} from 'app/client/lib/localization';
import {AppModel} from 'app/client/models/AppModel';
import * as css from 'app/client/ui/AccountPageCss';
import {labeledSquareCheckbox} from 'app/client/ui2018/checkbox';
import {prefersDarkModeObs} from 'app/client/ui2018/cssVars';
import {select} from 'app/client/ui2018/menus';
import {ThemeAppearance} from 'app/common/ThemePrefs';
import {Computed, Disposable, dom, makeTestId, styled} from 'grainjs';
@@ -12,21 +13,30 @@ const t = makeT('ThemeConfig');
export class ThemeConfig extends Disposable {
private _themePrefs = this._appModel.themePrefs;
private _appearance = Computed.create(this, this._themePrefs, (_use, prefs) => {
return prefs.appearance;
}).onWrite((value) => this._updateAppearance(value));
private _syncWithOS = Computed.create(this, this._themePrefs, (_use, prefs) => {
return prefs.syncWithOS;
}).onWrite((value) => this._updateSyncWithOS(value));
private _appearance = Computed.create(this,
this._themePrefs,
this._syncWithOS,
prefersDarkModeObs(),
(_use, prefs, syncWithOS, prefersDarkMode) => {
if (syncWithOS) {
return prefersDarkMode ? 'dark' : 'light';
} else {
return prefs.appearance;
}
})
.onWrite((value) => this._updateAppearance(value));
constructor(private _appModel: AppModel) {
super();
}
public buildDom() {
return dom('div',
css.subHeader(t("Appearance "), css.betaTag('Beta')),
css.subHeader(t("Appearance ")),
css.dataRow(
cssAppearanceSelect(
select(
@@ -35,6 +45,9 @@ export class ThemeConfig extends Disposable {
{value: 'light', label: 'Light'},
{value: 'dark', label: 'Dark'},
],
{
disabled: this._syncWithOS,
},
),
testId('appearance'),
),

View File

@@ -263,7 +263,7 @@ const cssFilterMenuWrapper = styled('div', `
border-radius: 3px;
align-items: center;
&-unsaved {
border: 1px solid ${theme.accentBorder};
border: ${theme.controlBorder};
}
& .${cssMenu.className} {
border: none;
@@ -364,11 +364,8 @@ const cssSaveTextButton = styled('div', `
cursor: pointer;
font-size: ${vars.mediumFontSize};
padding: 0px 5px;
border-right: 1px solid ${theme.accentBorder};
&-accent {
color: ${theme.accentText};
}
color: ${theme.controlFg};
border-right: ${theme.controlBorder};
`);
const cssRevertIconButton = styled('div', `

View File

@@ -1,8 +1,8 @@
import {dom, IDomArgs, Observable, styled} from 'grainjs';
// Shadow css settings for member scroll top and bottom.
const SHADOW_TOP = 'inset 0 4px 6px 0 rgba(217,217,217,0.4)';
const SHADOW_BTM = 'inset 0 -4px 6px 0 rgba(217,217,217,0.4)';
const SHADOW_TOP = 'inset 0 4px 6px 0 var(--grist-theme-scroll-shadow, rgba(217,217,217,0.4))';
const SHADOW_BTM = 'inset 0 -4px 6px 0 var(--grist-theme-scroll-shadow, rgba(217,217,217,0.4))';
/**
* Creates a scroll div used in the UserManager and moveDoc menus to display

View File

@@ -274,9 +274,11 @@ interface PickerComponentOptions {
}
class PickerComponent extends Disposable {
private _color = Computed.create(this,
this._model.obs,
(use, val) => (val || this._options.defaultColor).toUpperCase().slice(0, 7));
private _colorHex = Computed.create(this, this._model.obs, (_use, val) =>
val?.toUpperCase().slice(0, 7));
private _colorCss = Computed.create(this, this._colorHex, (_use, color) =>
color || this._options.defaultColor);
constructor(
private _model: PickerModel<string|undefined>,
@@ -286,7 +288,7 @@ class PickerComponent extends Disposable {
public buildDom() {
const title = this._options.title;
const colorText = Computed.create(null, use => use(this._color) || this._options.noneText);
const colorText = Computed.create(null, use => use(this._colorHex) || this._options.noneText);
return [
cssHeaderRow(title),
cssControlRow(
@@ -294,14 +296,15 @@ class PickerComponent extends Disposable {
dom.update(
cssColorSquare(
cssLightBorder.cls(''),
dom.style('background-color', this._color),
dom.style('background-color', this._colorCss),
cssNoneIcon('Empty',
dom.hide(use => Boolean(use(this._color)) === true)
dom.hide(use => Boolean(use(this._colorCss)))
),
testId(`${title}-color-square`),
),
cssColorInput(
{type: 'color'},
dom.attr('value', this._color),
dom.attr('value', use => use(this._model.obs) ?? ''),
dom.on('input', (ev, elem) => this._setValue(elem.value || undefined)),
testId(`${title}-input`),
),
@@ -321,7 +324,7 @@ class PickerComponent extends Disposable {
)
),
cssEmptyBox(
cssEmptyBox.cls('-selected', (use) => !use(this._color)),
cssEmptyBox.cls('-selected', (use) => !use(this._colorCss)),
dom.on('click', () => this._setValue(undefined)),
dom.hide(!this._options.allowsNone),
cssNoneIcon('Empty'),
@@ -333,7 +336,7 @@ class PickerComponent extends Disposable {
cssColorSquare(
dom.style('background-color', color),
cssLightBorder.cls('', isLight(index)),
cssColorSquare.cls('-selected', (use) => use(this._color) === color),
cssColorSquare.cls('-selected', (use) => use(this._colorHex) === color),
dom.style('outline-color', isLight(index) ? '' : color),
dom.on('click', () => this._setValue(color)),
testId(`color-${color}`),
@@ -381,8 +384,6 @@ class FontComponent extends Disposable {
const cssFontOptions = styled('div', `
display: flex;
gap: 1px;
background: ${theme.colorSelectFontOptionsBorder};
border: 1px solid ${theme.colorSelectFontOptionsBorder};
`);
@@ -390,10 +391,13 @@ const cssFontOption = styled('div', `
display: grid;
place-items: center;
flex-grow: 1;
background: ${theme.colorSelectFontOptionBg};
--icon-color: ${theme.colorSelectFontOptionFg};
height: 24px;
cursor: pointer;
&:not(:last-child) {
border-right: 1px solid ${theme.colorSelectFontOptionsBorder};
}
&:hover:not(&-selected) {
background: ${theme.colorSelectFontOptionBgHover};
}

View File

@@ -146,6 +146,11 @@ export const cssButtonSelect = styled('div', `
/* Vars */
color: ${theme.text};
flex: 1 1 0;
&-disabled {
opacity: 0.4;
pointer-events: none;
}
`);
const cssSelectorBtn = styled('div', `
@@ -187,6 +192,7 @@ const cssSelectorBtn = styled('div', `
}
&:hover:not(&-selected) {
background-color: ${theme.buttonGroupBgHover};
border: 1px solid ${theme.buttonGroupBorderHover};
z-index: 5; /* Update z-index so selected borders take precedent */
}
@@ -218,14 +224,6 @@ const cssSelectorBtn = styled('div', `
border: none;
background-color: ${theme.hover};
}
.${cssButtonSelect.className}-disabled > &,
.${cssButtonSelect.className}-disabled > &:hover {
--icon-color: ${theme.rightPanelToggleButtonDisabledFg};
color: ${theme.rightPanelToggleButtonDisabledFg};
background-color: ${theme.rightPanelToggleButtonDisabledBg};
border-color: ${theme.buttonGroupBorder};
pointer-events: none;
}
`);
const cssSelectorLabel = styled('span', `

View File

@@ -109,7 +109,8 @@ export const textButton = styled(cssButton, `
text-align: left;
background-color: inherit !important;
&:disabled {
color: ${theme.controlPrimaryDisabled};
color: ${theme.controlPrimaryBg};
opacity: 0.4;
}
`);

View File

@@ -199,7 +199,7 @@ export const cssRadioCheckboxOptions = styled('div', `
const cssBlockCheckbox = styled('div', `
display: flex;
padding: 10px 8px;
border: 1px solid ${theme.modalBorder};
border: 1px solid ${theme.controlSecondaryDisabledFg};
border-radius: 3px;
cursor: pointer;
& input::before, & input::after {
@@ -207,7 +207,7 @@ const cssBlockCheckbox = styled('div', `
left: unset;
}
&:hover {
border-color: ${theme.accentBorder};
border-color: ${theme.controlFg};
}
&-block {
pointer-events: none;

View File

@@ -245,8 +245,6 @@ export const theme = {
'black'),
tooltipCloseButtonHoverBg: new CustomProp('theme-tooltip-close-button-hover-bg', undefined,
'white'),
tooltipPopupHeaderFg: new CustomProp('theme-tooltip-popup-header-fg', undefined, colors.light),
tooltipPopupHeaderBg: new CustomProp('theme-tooltip-popup-header-bg', undefined, colors.lightGreen),
/* Modals */
modalBg: new CustomProp('theme-modal-bg', undefined, 'white'),
@@ -290,6 +288,7 @@ export const theme = {
/* Cell Editor */
cellEditorFg: new CustomProp('theme-cell-editor-fg', undefined, colors.dark),
cellEditorPlaceholderFg: new CustomProp('theme-cell-editor-placeholder-fg', undefined, colors.slate),
cellEditorBg: new CustomProp('theme-cell-editor-bg', undefined, colors.light),
/* Cursor */
@@ -298,14 +297,12 @@ export const theme = {
cursorReadonly: new CustomProp('theme-cursor-readonly', undefined, colors.slate),
/* Tables */
tableHeaderFg: new CustomProp('theme-table-header-fg', undefined, 'unset'),
tableHeaderSelectedFg: new CustomProp('theme-table-header-selected-fg', undefined, 'unset'),
tableHeaderFg: new CustomProp('theme-table-header-fg', undefined, '#000'),
tableHeaderSelectedFg: new CustomProp('theme-table-header-selected-fg', undefined, '#000'),
tableHeaderBg: new CustomProp('theme-table-header-bg', undefined, colors.lightGrey),
tableHeaderSelectedBg: new CustomProp('theme-table-header-selected-bg', undefined,
colors.mediumGreyOpaque),
tableHeaderBorder: new CustomProp('theme-table-header-border', undefined, 'lightgray'),
tableHeaderBorderDark: new CustomProp('theme-table-header-border-dark', undefined,
colors.darkGrey),
tableBodyBg: new CustomProp('theme-table-body-bg', undefined, 'white'),
tableBodyBorder: new CustomProp('theme-table-body-border', undefined, colors.darkGrey),
tableAddNewBg: new CustomProp('theme-table-add-new-bg', undefined, 'inherit'),
@@ -314,6 +311,7 @@ export const theme = {
'#999999'),
tableDragDropIndicator: new CustomProp('theme-table-drag-drop-indicator', undefined, 'gray'),
tableDragDropShadow: new CustomProp('theme-table-drag-drop-shadow', undefined, '#F0F0F0'),
tableCellSummaryBg: new CustomProp('theme-table-cell-summary-bg', undefined, colors.mediumGrey),
/* Cards */
cardCompactWidgetBg: new CustomProp('theme-card-compact-widget-bg', undefined,
@@ -339,7 +337,7 @@ export const theme = {
selection: new CustomProp('theme-selection', undefined, colors.selection),
selectionDarker: new CustomProp('theme-selection-darker', undefined, 'rgba(22,179,120,0.25)'),
selectionDarkest: new CustomProp('theme-selection-darkest', undefined, 'rgba(22,179,120,0.35)'),
selectionOpaqueFg: new CustomProp('theme-selection-opaque-fg', undefined, 'unset'),
selectionOpaqueFg: new CustomProp('theme-selection-opaque-fg', undefined, 'black'),
selectionOpaqueBg: new CustomProp('theme-selection-opaque-bg', undefined,
colors.selectionOpaque),
selectionOpaqueDarkBg: new CustomProp('theme-selection-opaque-dark-bg', undefined,
@@ -371,6 +369,8 @@ export const theme = {
controlPrimaryFg: new CustomProp('theme-control-primary-fg', undefined, vars.primaryFg),
controlPrimaryBg: new CustomProp('theme-control-primary-bg', undefined, vars.primaryBg),
controlSecondaryFg: new CustomProp('theme-control-secondary-fg', undefined, colors.slate),
controlSecondaryDisabledFg: new CustomProp('theme-control-secondary-disabled-fg',
undefined, colors.darkGrey),
controlHoverFg: new CustomProp('theme-control-hover-fg', undefined, vars.controlFgHover),
controlPrimaryHoverBg: new CustomProp('theme-control-primary-hover-bg', undefined,
vars.primaryBgHover),
@@ -380,8 +380,6 @@ export const theme = {
colors.darkGrey),
controlDisabledFg: new CustomProp('theme-control-disabled-fg', undefined, colors.light),
controlDisabledBg: new CustomProp('theme-control-disabled-bg', undefined, colors.slate),
controlPrimaryDisabled: new CustomProp('theme-control-primary-disabled', undefined,
colors.inactiveCursor),
controlBorder: new CustomProp('theme-control-border', undefined, vars.controlBorder),
/* Checkboxes */
@@ -464,8 +462,6 @@ export const theme = {
undefined, colors.light),
rightPanelToggleButtonEnabledBg: new CustomProp('theme-right-panel-toggle-button-enabled-bg',
undefined, colors.dark),
rightPanelToggleButtonEnabledHoverFg: new CustomProp(
'theme-right-panel-toggle-button-enabled-hover-fg', undefined, colors.darkGrey),
rightPanelToggleButtonDisabledFg: new CustomProp('theme-right-panel-toggle-button-disabled-fg',
undefined, colors.light),
rightPanelToggleButtonDisabledBg: new CustomProp('theme-right-panel-toggle-button-disabled-bg',
@@ -487,9 +483,15 @@ export const theme = {
documentHistorySnapshotBorder: new CustomProp('theme-document-history-snapshot-border',
undefined, colors.mediumGrey),
documentHistoryActivityText: new CustomProp('theme-document-history-activity-text', undefined,
'unset'),
colors.dark),
documentHistoryActivityLightText: new CustomProp('theme-document-history-activity-text-light',
undefined, '#333333'),
documentHistoryTableHeaderFg: new CustomProp('theme-document-history-table-header-fg',
undefined, '#000'),
documentHistoryTableBorder: new CustomProp('theme-document-history-table-border',
undefined, 'lightgray'),
documentHistoryTableBorderLight: new CustomProp('theme-document-history-table-border-light',
undefined, '#D9D9D9'),
/* Accents */
accentIcon: new CustomProp('theme-accent-icon', undefined, colors.lightGreen),
@@ -509,6 +511,16 @@ export const theme = {
inputReadonlyBg: new CustomProp('theme-input-readonly-bg', undefined, colors.lightGrey),
inputReadonlyBorder: new CustomProp('theme-input-readonly-border', undefined, colors.mediumGreyOpaque),
/* Choice Tokens */
choiceTokenFg: new CustomProp('theme-choice-token-fg', undefined, '#000000'),
choiceTokenBlankFg: new CustomProp('theme-choice-token-blank-fg', undefined, colors.slate),
choiceTokenBg: new CustomProp('theme-choice-token-bg', undefined, colors.mediumGreyOpaque),
choiceTokenSelectedBg: new CustomProp('theme-choice-token-selected-bg', undefined, colors.darkGrey),
choiceTokenSelectedBorder: new CustomProp('theme-choice-token-selected-border', undefined, colors.lightGreen),
choiceTokenInvalidFg: new CustomProp('theme-choice-token-invalid-fg', undefined, '#000000'),
choiceTokenInvalidBg: new CustomProp('theme-choice-token-invalid-bg', undefined, 'white'),
choiceTokenInvalidBorder: new CustomProp('theme-choice-token-invalid-border', undefined, colors.error),
/* Choice Entry */
choiceEntryBg: new CustomProp('theme-choice-entry-bg', undefined, 'white'),
choiceEntryBorder: new CustomProp('theme-choice-entry-border', undefined, colors.darkGrey),
@@ -519,7 +531,6 @@ export const theme = {
selectButtonFg: new CustomProp('theme-select-button-fg', undefined, colors.dark),
selectButtonPlaceholderFg: new CustomProp('theme-select-button-placeholder-fg', undefined,
colors.slate),
selectButtonDisabledFg: new CustomProp('theme-select-button-disabled-fg', undefined, 'grey'),
selectButtonBg: new CustomProp('theme-select-button-bg', undefined, 'white'),
selectButtonBorder: new CustomProp('theme-select-button-border', undefined, colors.darkGrey),
selectButtonBorderInvalid: new CustomProp('theme-select-button-border-invalid', undefined,
@@ -529,7 +540,7 @@ export const theme = {
menuText: new CustomProp('theme-menu-text', undefined, colors.slate),
menuLightText: new CustomProp('theme-menu-light-text', undefined, colors.slate),
menuBg: new CustomProp('theme-menu-bg', undefined, 'white'),
menuSubheaderFg: new CustomProp('theme-menu-subheader-fg', undefined, 'unset'),
menuSubheaderFg: new CustomProp('theme-menu-subheader-fg', undefined, colors.dark),
menuBorder: new CustomProp('theme-menu-border', undefined, colors.mediumGreyOpaque),
menuShadow: new CustomProp('theme-menu-shadow', undefined, 'rgba(38, 38, 51, 0.6)'),
@@ -540,19 +551,20 @@ export const theme = {
menuItemDisabledFg: new CustomProp('theme-menu-item-disabled-fg', undefined, '#D9D9D9'),
menuItemIconFg: new CustomProp('theme-menu-item-icon-fg', undefined, colors.slate),
menuItemIconSelectedFg: new CustomProp('theme-menu-item-icon-selected-fg', undefined, 'white'),
menuItemLinkFg: new CustomProp('theme-menu-item-link-fg', undefined, colors.lightGreen),
menuItemLinkSelectedFg: new CustomProp('theme-menu-item-link-selected-fg', undefined,
colors.darkGreen),
menuItemLinkselectedBg: new CustomProp('theme-menu-item-link-selected-bg', undefined,
colors.mediumGreyOpaque),
/* Autocomplete */
autocompleteMatchText: new CustomProp('theme-autocomplete-match-text', undefined,
colors.lightGreen),
autocompleteSelectedMatchText: new CustomProp('theme-autocomplete-selected-match-text',
undefined, colors.lighterGreen),
autocompleteChoiceSelectedBg: new CustomProp('theme-autocomplete-item-selected-bg', undefined,
autocompleteItemSelectedBg: new CustomProp('theme-autocomplete-item-selected-bg', undefined,
colors.mediumGreyOpaque),
autocompleteAddNewCircleFg: new CustomProp('theme-autocomplete-add-new-circle-fg', undefined,
colors.light),
autocompleteAddNewCircleBg: new CustomProp('theme-autocomplete-add-new-circle-bg', undefined,
colors.lightGreen),
autocompleteAddNewCircleSelectedBg: new CustomProp(
'theme-autocomplete-add-new-circle-selected-bg', undefined, colors.darkGreen),
/* Search */
searchBorder: new CustomProp('theme-search-border', undefined, 'grey'),
@@ -594,7 +606,7 @@ export const theme = {
widgetPickerPrimaryBg: new CustomProp('theme-widget-picker-primary-bg', undefined, 'white'),
widgetPickerSecondaryBg: new CustomProp('theme-widget-picker-secondary-bg', undefined,
colors.lightGrey),
widgetPickerItemFg: new CustomProp('theme-widget-picker-item-fg', undefined, 'unset'),
widgetPickerItemFg: new CustomProp('theme-widget-picker-item-fg', undefined, colors.dark),
widgetPickerItemSelectedBg: new CustomProp('theme-widget-picker-item-selected-bg', undefined,
colors.mediumGrey),
widgetPickerItemDisabledBg: new CustomProp('theme-widget-picker-item-disabled-bg', undefined,
@@ -651,7 +663,9 @@ export const theme = {
/* Button Groups */
buttonGroupFg: new CustomProp('theme-button-group-fg', undefined, colors.dark),
buttonGroupLightFg: new CustomProp('theme-button-group-light-fg', undefined, colors.slate),
buttonGroupBg: new CustomProp('theme-button-group-bg', undefined, 'unset'),
buttonGroupBg: new CustomProp('theme-button-group-bg', undefined, 'transparent'),
buttonGroupBgHover: new CustomProp('theme-button-group-bg-hover', undefined,
colors.hover),
buttonGroupIcon: new CustomProp('theme-button-group-icon', undefined, colors.slate),
buttonGroupBorder: new CustomProp('theme-button-group-border', undefined, colors.darkGrey),
buttonGroupBorderHover: new CustomProp('theme-button-group-border-hover', undefined,
@@ -670,6 +684,8 @@ export const theme = {
colors.mediumGrey),
accessRulesTableBodyFg: new CustomProp('theme-access-rules-table-body-fg', undefined,
colors.dark),
accessRulesTableBodyLightFg: new CustomProp('theme-access-rules-table-body-light-fg', undefined,
colors.darkGrey),
accessRulesTableBorder: new CustomProp('theme-access-rules-table-border', undefined,
colors.slate),
accessRulesColumnListBorder: new CustomProp('theme-access-rules-column-list-border', undefined,
@@ -694,7 +710,7 @@ export const theme = {
undefined, colors.cursor),
/* Cells */
cellFg: new CustomProp('theme-cell-fg', undefined, 'unset'),
cellFg: new CustomProp('theme-cell-fg', undefined, 'black'),
cellBg: new CustomProp('theme-cell-bg', undefined, '#FFFFFF00'),
cellZebraBg: new CustomProp('theme-cell-zebra-bg', undefined, '#F8F8F8'),
@@ -772,13 +788,11 @@ export const theme = {
undefined, colors.darkGrey),
colorSelectFontOptionFg: new CustomProp('theme-color-select-font-option-fg',
undefined, colors.dark),
colorSelectFontOptionBg: new CustomProp('theme-color-select-font-option-bg',
undefined, colors.light),
colorSelectFontOptionBgHover: new CustomProp('theme-color-select-font-option-bg-hover',
undefined, colors.lightGrey),
colorSelectFontOptionFgSelected: new CustomProp('theme-color-select-font-option-selected-fg',
colorSelectFontOptionFgSelected: new CustomProp('theme-color-select-font-option-fg-selected',
undefined, colors.light),
colorSelectFontOptionBgSelected: new CustomProp('theme-color-select-font-option-selected-bg',
colorSelectFontOptionBgSelected: new CustomProp('theme-color-select-font-option-bg-selected',
undefined, colors.dark),
colorSelectColorSquareBorder: new CustomProp('theme-color-select-color-square-border',
undefined, '#D9D9D9'),
@@ -807,6 +821,14 @@ export const theme = {
loginPageBg: new CustomProp('theme-login-page-bg', undefined, 'white'),
loginPageBackdrop: new CustomProp('theme-login-page-backdrop', undefined, '#F5F8FA'),
loginPageLine: new CustomProp('theme-login-page-line', undefined, colors.lightGrey),
loginPageGoogleButtonFg: new CustomProp('theme-login-page-google-button-fg', undefined,
colors.dark),
loginPageGoogleButtonBg: new CustomProp('theme-login-page-google-button-bg', undefined,
colors.lightGrey),
loginPageGoogleButtonBgHover: new CustomProp('theme-login-page-google-button-bg-hover',
undefined, colors.mediumGrey),
loginPageGoogleButtonBorder: new CustomProp('theme-login-page-google-button-border', undefined,
colors.darkGrey),
/* Formula Assistant */
formulaAssistantHeaderBg: new CustomProp(
@@ -815,6 +837,42 @@ export const theme = {
'theme-formula-assistant-border', undefined, colors.darkGrey),
formulaAssistantPreformattedTextBg: new CustomProp(
'theme-formula-assistant-preformatted-text-bg', undefined, colors.lightGrey),
/* Attachments */
attachmentsEditorButtonFg: new CustomProp(
'theme-attachments-editor-button-fg', undefined, colors.darkGreen),
attachmentsEditorButtonHoverFg: new CustomProp(
'theme-attachments-editor-button-hover-fg', undefined, colors.lightGreen),
attachmentsEditorButtonBg: new CustomProp(
'theme-attachments-editor-button-bg', undefined, colors.light),
attachmentsEditorButtonHoverBg: new CustomProp(
'theme-attachments-editor-button-hover-bg', undefined, colors.mediumGreyOpaque),
attachmentsEditorButtonBorder: new CustomProp(
'theme-attachments-editor-button-border', undefined, colors.darkGrey),
attachmentsEditorButtonIcon: new CustomProp(
'theme-attachments-editor-button-icon', undefined, colors.slate),
attachmentsEditorBorder: new CustomProp(
'theme-attachments-editor-border', undefined, colors.mediumGreyOpaque),
attachmentsCellIconFg: new CustomProp(
'theme-attachments-cell-icon-fg', undefined, 'white'),
attachmentsCellIconBg: new CustomProp(
'theme-attachments-cell-icon-bg', undefined, '#D9D9D9'),
attachmentsCellIconHoverBg: new CustomProp(
'theme-attachments-cell-icon-hover-bg', undefined, '#929299'),
/* Announcement Popups */
announcementPopupFg: new CustomProp('theme-announcement-popup-fg', undefined, '#000000'),
announcementPopupBg: new CustomProp('theme-announcement-popup-bg', undefined, '#DCF4EB'),
/* Switches */
switchSliderFg: new CustomProp('theme-switch-slider-fg', undefined, '#ccc'),
switchCircleFg: new CustomProp('theme-switch-circle-fg', undefined, 'white'),
/* Toggle Checkboxes */
toggleCheckboxFg: new CustomProp('theme-toggle-checkbox-fg', undefined, '#606060'),
/* Numeric Spinners */
numericSpinnerFg: new CustomProp('theme-numeric-spinner-fg', undefined, '#606060'),
};
const cssColors = values(colors).map(v => v.decl()).join('\n');
@@ -1038,7 +1096,7 @@ function getCssThemeBackgroundProperties(appearance: ThemeAppearance) {
* pollute the document with in-line styles.
*/
function getOrCreateStyleElement(id: string) {
let style = document.head.querySelector(id);
let style = document.head.querySelector(`#${id}`);
if (style) { return style; }
style = document.createElement('style');
style.setAttribute('id', id);

View File

@@ -1,6 +1,6 @@
import {findLinks} from 'app/client/lib/textUtils';
import { sameDocumentUrlState, urlState } from 'app/client/models/gristUrlState';
import { colors, hideInPrintView, testId, theme } from 'app/client/ui2018/cssVars';
import { hideInPrintView, testId, theme } from 'app/client/ui2018/cssVars';
import {cssIconBackground, icon} from 'app/client/ui2018/icons';
import { CellValue } from 'app/plugin/GristData';
import { dom, DomArg, IDomArgs, Observable, styled } from 'grainjs';
@@ -95,7 +95,7 @@ const cssMaybeWrap = styled('span', `
// A gentle transition effect on hover in, and the same effect on hover out with a little delay.
export const cssHoverIn = (parentClass: string) => styled('span', `
--icon-color: var(--grist-actual-cell-color, ${colors.lightGreen});
--icon-color: var(--grist-actual-cell-color, ${theme.link});
margin: -1px 2px 2px 0;
border-radius: 3px;
transition-property: background-color;
@@ -103,7 +103,7 @@ export const cssHoverIn = (parentClass: string) => styled('span', `
transition-duration: 150ms;
transition-delay: 90ms;
.${parentClass}:hover & {
--icon-background: ${colors.lightGreen};
--icon-background: ${theme.link};
--icon-color: white;
transition-duration: 80ms;
transition-delay: 0ms;
@@ -113,5 +113,5 @@ export const cssHoverIn = (parentClass: string) => styled('span', `
const cssHoverInText = cssHoverIn(cssMaybeWrap.className);
const linkColor = styled('span', `
color: var(--grist-actual-cell-color, ${colors.lightGreen});;
color: var(--grist-actual-cell-color, ${theme.link});
`);

View File

@@ -178,7 +178,7 @@ const cssPageInitial = styled('div', `
&-emoji {
background-color: ${theme.pageInitialsEmojiBg};
box-shadow: 0 0 0 1px var(--grist-theme-left-panel-page-emoji-outline, var(--grist-color-dark-grey));
box-shadow: 0 0 0 1px ${theme.pageInitialsEmojiOutline};
font-size: 15px;
overflow: hidden;
color: ${theme.text};

View File

@@ -42,8 +42,8 @@ export const cssSelectBtn = styled('div', `
}
&.disabled, &-disabled {
--icon-color: ${theme.selectButtonDisabledFg};
color: ${theme.selectButtonDisabledFg};
cursor: pointer;
opacity: 0.4;
pointer-events: none;
cursor: default;
}
`);

View File

@@ -1,20 +1,20 @@
var dispose = require('../lib/dispose');
const {theme} = require('app/client/ui2018/cssVars');
const {CellStyle} = require('app/client/widgets/CellStyle');
const {dom} = require('grainjs');
/**
* AbstractWidget - The base of the inheritance tree for widgets.
* @param {Function} field - The RowModel for this view field.
* @param {string|undefined} options.defaultTextColor - A hex value to set the default text color
* for the widget. Omit defaults to '#000000'.
* @param {string|undefined} options.defaultTextColor - CSS value of the default
* text color for the widget. Defaults to the current theme's cell fg color.
*
*/
function AbstractWidget(field, opts = {}) {
this.field = field;
this.options = field.widgetOptionsJson;
const {defaultTextColor = '#000000'} = opts;
this.defaultTextColor = defaultTextColor;
this.valueFormatter = this.field.visibleColFormatter;
this.defaultTextColor = opts.defaultTextColor || '#000000';
this.defaultTextColor = opts.defaultTextColor ?? theme.cellFg.toString();
}
dispose.makeDisposable(AbstractWidget);

View File

@@ -9,7 +9,7 @@ import {selectFiles, uploadFiles} from 'app/client/lib/uploads';
import {DocData} from 'app/client/models/DocData';
import {MetaTableData} from 'app/client/models/TableData';
import {basicButton, basicButtonLink, cssButtonGroup} from 'app/client/ui2018/buttons';
import {colors, testId, vars} from 'app/client/ui2018/cssVars';
import {testId, theme, vars} from 'app/client/ui2018/cssVars';
import {editableLabel} from 'app/client/ui2018/editableLabel';
import {icon} from 'app/client/ui2018/icons';
import {IModalControl, modal} from 'app/client/ui2018/modals';
@@ -315,12 +315,12 @@ const cssCloseButton = styled('div', `
padding: 6px;
border-radius: 32px;
cursor: pointer;
background-color: ${colors.light};
--icon-color: ${colors.lightGreen};
background-color: ${theme.attachmentsEditorButtonBg};
--icon-color: ${theme.attachmentsEditorButtonFg};
&:hover {
background-color: ${colors.mediumGreyOpaque};
--icon-color: ${colors.darkGreen};
background-color: ${theme.attachmentsEditorButtonHoverBg};
--icon-color: ${theme.attachmentsEditorButtonHoverFg};
}
`);
@@ -336,10 +336,10 @@ const cssTitle = styled('div', `
overflow: hidden;
&:hover {
outline: 1px solid ${colors.slate};
outline: 1px solid ${theme.lightText};
}
&:focus-within {
outline: 1px solid ${colors.darkGreen};
outline: 1px solid ${theme.controlFg};
}
`);
@@ -362,13 +362,14 @@ const cssFileButtons = styled(cssButtonGroup, `
`);
const cssButton = styled(basicButton, `
background-color: ${colors.light};
color: ${theme.attachmentsEditorButtonFg};
background-color: ${theme.attachmentsEditorButtonBg};
font-weight: normal;
padding: 0 16px;
border-top: none;
border-right: none;
border-bottom: none;
border-left: 1px solid ${colors.darkGrey};
border-left: 1px solid ${theme.attachmentsEditorButtonBorder};
display: flex;
align-items: center;
@@ -376,13 +377,14 @@ const cssButton = styled(basicButton, `
border: none;
}
&:hover {
background-color: ${colors.mediumGreyOpaque};
border-color: ${colors.darkGrey};
color: ${theme.attachmentsEditorButtonHoverFg};
background-color: ${theme.attachmentsEditorButtonHoverBg};
border-color: ${theme.attachmentsEditorButtonBorder};
}
`);
const cssButtonIcon = styled(icon, `
--icon-color: ${colors.slate};
--icon-color: ${theme.attachmentsEditorButtonIcon};
margin-right: 4px;
`);
@@ -397,11 +399,11 @@ const cssNextArrow = styled('div', `
padding: 6px;
border-radius: 32px;
cursor: pointer;
background-color: ${colors.lightGreen};
--icon-color: ${colors.light};
background-color: ${theme.controlPrimaryBg};
--icon-color: ${theme.controlPrimaryFg};
&:hover {
background-color: ${colors.darkGreen};
background-color: ${theme.controlPrimaryHoverBg};
}
&-left {
transform: rotateY(180deg);
@@ -453,7 +455,7 @@ const cssDetails = styled('div', `
`);
const cssDragArea = styled(cssContent, `
border: 2px dashed ${colors.mediumGreyOpaque};
border: 2px dashed ${theme.attachmentsEditorBorder};
height: calc(100% - 96px);
margin-top: 64px;
padding: 0px;

View File

@@ -3,7 +3,7 @@ import * as commands from 'app/client/components/commands';
import {dragOverClass} from 'app/client/lib/dom';
import {selectFiles, uploadFiles} from 'app/client/lib/uploads';
import {cssRow} from 'app/client/ui/RightPanelStyles';
import {colors, testId, vars} from 'app/client/ui2018/cssVars';
import {colors, testId, theme, vars} from 'app/client/ui2018/cssVars';
import {NewAbstractWidget} from 'app/client/widgets/NewAbstractWidget';
import {encodeQueryParams} from 'app/common/gutil';
import {ViewFieldRec} from 'app/client/models/entities/ViewFieldRec';
@@ -191,16 +191,16 @@ const cssAttachmentIcon = styled('div.glyphicon.glyphicon-paperclip', `
top: 2px;
left: 2px;
padding: 2px;
background-color: #D0D0D0;
color: white;
background-color: ${theme.attachmentsCellIconBg};
color: ${theme.attachmentsCellIconFg};
border-radius: 2px;
border: none;
cursor: pointer;
box-shadow: 0 0 0 1px white;
box-shadow: 0 0 0 1px ${theme.cellEditorBg};
z-index: 1;
&:hover {
background-color: #3290BF;
background-color: ${theme.attachmentsCellIconHoverBg};
}
&-hover {
@@ -222,12 +222,12 @@ const cssAttachmentPreview = styled('div', `
justify-content: center;
z-index: 0;
&:hover {
border-color: ${colors.lightGreen};
border-color: ${theme.cursor};
}
`);
const cssSizeLabel = styled('div', `
color: ${colors.slate};
color: ${theme.lightText};
margin-right: 9px;
`);

View File

@@ -15,7 +15,7 @@ export class CellStyle extends Disposable {
constructor(
private _field: ViewFieldRec,
private _gristDoc: GristDoc,
private _defaultTextColor: string
private _defaultTextColor: string|undefined
) {
super();
}
@@ -51,21 +51,26 @@ export class CellStyle extends Disposable {
});
return colorSelect(
{
textColor: new ColorOption(
{ color: headerTextColor, defaultColor: this._defaultTextColor, noneText: 'default' }
),
fillColor: new ColorOption(
{ color: headerFillColor, allowsNone: true, noneText: 'none' }
),
textColor: new ColorOption({
color: headerTextColor,
defaultColor: theme.tableHeaderFg.toString(),
noneText: 'default',
}),
fillColor: new ColorOption({
color: headerFillColor,
allowsNone: true,
noneText: 'none',
}),
fontBold: headerFontBold,
fontItalic: headerFontItalic,
fontUnderline: headerFontUnderline,
fontStrikethrough: headerFontStrikethrough
}, {
onSave: () => options.save(),
onRevert: () => options.revert(),
placeholder: use => use(hasMixedStyle) ? t('Mixed style') : t('Default header style')
}
},
{
onSave: () => options.save(),
onRevert: () => options.revert(),
placeholder: use => use(hasMixedStyle) ? t('Mixed style') : t('Default header style')
}
);
}),
)];
@@ -97,12 +102,16 @@ export class CellStyle extends Disposable {
});
return colorSelect(
{
textColor: new ColorOption(
{ color: textColor, defaultColor: this._defaultTextColor, noneText: 'default'}
),
fillColor: new ColorOption(
{ color: fillColor, allowsNone: true, noneText: 'none'}
),
textColor: new ColorOption({
color: textColor,
defaultColor: this._defaultTextColor,
noneText: 'default',
}),
fillColor: new ColorOption({
color: fillColor,
allowsNone: true,
noneText: 'none',
}),
fontBold: fontBold,
fontItalic: fontItalic,
fontUnderline: fontUnderline,

View File

@@ -42,8 +42,8 @@
position: relative;
width: 3px;
height: 12px;
background-color: var(--grist-actual-cell-color, #606060);
border: 1px solid var(--grist-actual-cell-color, #606060);
background-color: var(--grist-actual-cell-color, var(--grist-theme-toggle-checkbox-fg, #606060));
border: 1px solid var(--grist-actual-cell-color, var(--grist-theme-toggle-checkbox-fg, #606060));
left: 3px;
top: -5px;
}
@@ -52,7 +52,7 @@
position: relative;
width: 3px;
height: 3px;
background-color: var(--grist-actual-cell-color, #606060);
border: 1px solid var(--grist-actual-cell-color, #606060);
background-color: var(--grist-actual-cell-color, var(--grist-theme-toggle-checkbox-fg, #606060));
border: 1px solid var(--grist-actual-cell-color, var(--grist-theme-toggle-checkbox-fg, #606060));
top: 7px;
}

View File

@@ -7,7 +7,7 @@ const {ACIndexImpl, buildHighlightedDom} = require('app/client/lib/ACIndex');
const {ChoiceItem, cssChoiceList, cssMatchText, cssPlusButton,
cssPlusIcon} = require('app/client/widgets/ChoiceListEditor');
const {menuCssClass} = require('app/client/ui2018/menus');
const {testId, colors} = require('app/client/ui2018/cssVars');
const {testId, theme} = require('app/client/ui2018/cssVars');
const {choiceToken, cssChoiceACItem} = require('app/client/widgets/ChoiceToken');
const {dom, styled} = require('grainjs');
const {icon} = require('../ui2018/icons');
@@ -34,7 +34,13 @@ _.extend(ChoiceEditor.prototype, TextEditor.prototype);
ChoiceEditor.prototype.getCellValue = function() {
const selectedItem = this.autocomplete && this.autocomplete.getSelectedItem();
return selectedItem ? selectedItem.label : TextEditor.prototype.getCellValue.call(this);
if (selectedItem) {
return selectedItem.label;
} else if (this.textInput.value.trim() === '') {
return null;
} else {
return TextEditor.prototype.getCellValue.call(this);
}
}
ChoiceEditor.prototype.renderACItem = function(item, highlightFunc) {
@@ -60,7 +66,7 @@ ChoiceEditor.prototype.attach = function(cellElem) {
// Don't create autocomplete if readonly.
if (this.options.readonly) { return; }
const acItems = this.choices.map(c => new ChoiceItem(c, false));
const acItems = this.choices.map(c => new ChoiceItem(c, false, false));
const acIndex = new ACIndexImpl(acItems);
const acOptions = {
popperOptions: {
@@ -100,7 +106,7 @@ ChoiceEditor.prototype.maybeShowAddNew = function(result, text) {
const trimmedText = text.trim();
if (!this.enableAddNew || !trimmedText) { return result; }
const addNewItem = new ChoiceItem(trimmedText, false, true);
const addNewItem = new ChoiceItem(trimmedText, false, false, true);
if (result.items.find((item) => item.cleanText === addNewItem.cleanText)) {
return result;
}
@@ -112,7 +118,7 @@ ChoiceEditor.prototype.maybeShowAddNew = function(result, text) {
}
const cssChoiceEditIcon = styled(icon, `
background-color: ${colors.slate};
background-color: ${theme.lightText};
position: absolute;
top: 0;
left: 0;

View File

@@ -33,17 +33,19 @@ export class ChoiceListCell extends ChoiceTextBox {
if (!val) { return null; }
// Handle any unexpected values we might get (non-array, or array with non-strings).
const tokens: unknown[] = Array.isArray(val) ? val : [val];
return tokens.map(token =>
choiceToken(
String(token),
return tokens.map(token => {
const isBlank = String(token).trim() === '';
return choiceToken(
isBlank ? '[Blank]' : String(token),
{
...(choiceOptionsByName.get(String(token)) || {}),
invalid: !choiceSet.has(String(token)),
blank: String(token).trim() === '',
},
dom.cls(cssToken.className),
testId('choice-list-cell-token')
)
);
);
});
}),
);
}

View File

@@ -21,6 +21,7 @@ export class ChoiceItem implements ACItem, IToken {
constructor(
public label: string,
public isInvalid: boolean, // If set, this token is not one of the valid choices.
public isBlank: boolean, // If set, this token is blank.
public isNew?: boolean, // If set, this is a choice to be added to the config.
) {}
}
@@ -50,7 +51,7 @@ export class ChoiceListEditor extends NewBaseEditor {
const choices: string[] = options.field.widgetOptionsJson.peek().choices || [];
this._choiceOptionsByName = options.field.widgetOptionsJson
.peek().choiceOptions || {};
const acItems = choices.map(c => new ChoiceItem(c, false));
const acItems = choices.map(c => new ChoiceItem(c, false, false));
const choiceSet = new Set(choices);
const acIndex = new ACIndexImpl<ChoiceItem>(acItems);
@@ -67,21 +68,26 @@ export class ChoiceListEditor extends NewBaseEditor {
// If starting to edit by typing in a string, ignore previous tokens.
const cellValue = decodeObject(options.cellValue);
const startLabels: unknown[] = options.editValue !== undefined || !Array.isArray(cellValue) ? [] : cellValue;
const startTokens = startLabels.map(label => new ChoiceItem(String(label), !choiceSet.has(String(label))));
const startTokens = startLabels.map(label => new ChoiceItem(
String(label),
!choiceSet.has(String(label)),
String(label).trim() === ''
));
this._tokenField = TokenField.ctor<ChoiceItem>().create(this, {
initialValue: startTokens,
renderToken: item => [
item.label,
item.isBlank ? '[Blank]' : item.label,
dom.style('background-color', getRenderFillColor(this._choiceOptionsByName[item.label])),
dom.style('color', getRenderTextColor(this._choiceOptionsByName[item.label])),
dom.cls('font-bold', this._choiceOptionsByName[item.label]?.fontBold ?? false),
dom.cls('font-underline', this._choiceOptionsByName[item.label]?.fontUnderline ?? false),
dom.cls('font-italic', this._choiceOptionsByName[item.label]?.fontItalic ?? false),
dom.cls('font-strikethrough', this._choiceOptionsByName[item.label]?.fontStrikethrough ?? false),
cssChoiceToken.cls('-invalid', item.isInvalid)
cssChoiceToken.cls('-invalid', item.isInvalid),
cssChoiceToken.cls('-blank', item.isBlank),
],
createToken: label => new ChoiceItem(label, !choiceSet.has(label)),
createToken: label => new ChoiceItem(label, !choiceSet.has(label), label.trim() === ''),
acOptions,
openAutocompleteOnFocus: true,
readonly : options.readonly,
@@ -222,7 +228,7 @@ export class ChoiceListEditor extends NewBaseEditor {
const trimmedText = text.trim();
if (!this._enableAddNew || !trimmedText) { return result; }
const addNewItem = new ChoiceItem(trimmedText, false, true);
const addNewItem = new ChoiceItem(trimmedText, false, false, true);
if (result.items.find((item) => item.cleanText === addNewItem.cleanText)) {
return result;
}
@@ -277,7 +283,7 @@ export const cssToken = styled(tokenFieldStyles.cssToken, `
white-space: pre;
&.selected {
box-shadow: inset 0 0 0 1px ${colors.lightGreen};
box-shadow: inset 0 0 0 1px ${theme.choiceTokenSelectedBorder};
}
`);
@@ -341,7 +347,7 @@ export const cssChoiceList = styled('div', `
const cssReadonlyStyle = styled('div', `
padding-left: 16px;
background: white;
background: ${theme.cellEditorBg};
`);
export const cssMatchText = styled('span', `
@@ -349,20 +355,21 @@ export const cssMatchText = styled('span', `
`);
export const cssPlusButton = styled('div', `
display: inline-block;
display: flex;
width: 20px;
height: 20px;
border-radius: 20px;
margin-right: 8px;
text-align: center;
background-color: ${colors.lightGreen};
color: ${colors.light};
align-items: center;
justify-content: center;
background-color: ${theme.autocompleteAddNewCircleBg};
color: ${theme.autocompleteAddNewCircleFg};
.selected > & {
background-color: ${colors.darkGreen};
background-color: ${theme.autocompleteAddNewCircleSelectedBg};
}
`);
export const cssPlusIcon = styled(icon, `
background-color: ${colors.light};
background-color: ${theme.autocompleteAddNewCircleFg};
`);

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, theme} from 'app/client/ui2018/cssVars';
import {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';
@@ -492,7 +492,7 @@ const cssListBoxInactive = styled(cssListBox, `
border: 1px solid ${theme.choiceEntryBorderHover};
}
&-disabled {
opacity: 0.6;
opacity: 0.4;
}
`);
@@ -501,8 +501,8 @@ const cssListRow = styled('div', `
margin-top: 4px;
margin-bottom: 4px;
padding: 4px 8px;
color: ${colors.dark};
background-color: ${colors.mediumGreyOpaque};
color: ${theme.choiceTokenFg};
background-color: ${theme.choiceTokenBg};
border-radius: 3px;
text-overflow: ellipsis;
`);
@@ -521,7 +521,7 @@ const cssToken = styled(cssListRow, `
cursor: grab;
&.selected {
background-color: ${colors.darkGrey};
background-color: ${theme.choiceTokenSelectedBg};
}
&.token-dragging {
pointer-events: none;
@@ -619,8 +619,9 @@ const cssDeleteButton = styled('div', `
`);
const cssDeleteIcon = styled(icon, `
--icon-color: ${colors.slate};
--icon-color: ${theme.text};
opacity: 0.6;
&:hover {
--icon-color: ${colors.dark};
opacity: 1.0;
}
`);

View File

@@ -4,10 +4,10 @@ import {ViewFieldRec} from 'app/client/models/entities/ViewFieldRec';
import {KoSaveableObservable} from 'app/client/models/modelUtil';
import {Style} from 'app/client/models/Styles';
import {cssLabel, cssRow} from 'app/client/ui/RightPanelStyles';
import {colors, testId} from 'app/client/ui2018/cssVars';
import {testId, theme} from 'app/client/ui2018/cssVars';
import {icon} from 'app/client/ui2018/icons';
import {ChoiceListEntry} from 'app/client/widgets/ChoiceListEntry';
import {choiceToken, DEFAULT_FILL_COLOR, DEFAULT_TEXT_COLOR} from 'app/client/widgets/ChoiceToken';
import {choiceToken, DEFAULT_BACKGROUND_COLOR, DEFAULT_COLOR} from 'app/client/widgets/ChoiceToken';
import {NTextBox} from 'app/client/widgets/NTextBox';
import {Computed, dom, styled} from 'grainjs';
@@ -18,11 +18,11 @@ export type ChoiceOptionsByName = Map<string, IChoiceOptions | undefined>;
const t = makeT('ChoiceTextBox');
export function getRenderFillColor(choiceOptions?: IChoiceOptions) {
return choiceOptions?.fillColor ?? DEFAULT_FILL_COLOR;
return choiceOptions?.fillColor ?? DEFAULT_BACKGROUND_COLOR;
}
export function getRenderTextColor(choiceOptions?: IChoiceOptions) {
return choiceOptions?.textColor ?? DEFAULT_TEXT_COLOR;
return choiceOptions?.textColor ?? DEFAULT_COLOR;
}
/**
@@ -157,7 +157,7 @@ const cssChoiceText = styled('div', `
`);
const cssChoiceEditIcon = styled(icon, `
background-color: ${colors.slate};
background-color: ${theme.lightText};
display: block;
height: inherit;
`);

View File

@@ -1,12 +1,13 @@
import {Style} from 'app/client/models/Styles';
import {colors, theme, vars} from 'app/client/ui2018/cssVars';
import {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_TEXT_COLOR = '#000000';
export const DEFAULT_BACKGROUND_COLOR = theme.choiceTokenBg.toString();
export const DEFAULT_COLOR = theme.choiceTokenFg.toString();
export interface IChoiceTokenOptions extends Style {
invalid?: boolean;
blank?: boolean;
}
/**
@@ -29,16 +30,17 @@ export function choiceToken(
...args: DomElementArg[]
): DomContents {
const {fillColor, textColor, fontBold, fontItalic, fontUnderline,
fontStrikethrough, invalid} = options;
fontStrikethrough, invalid, blank} = options;
return cssChoiceToken(
label,
dom.style('background-color', fillColor ?? DEFAULT_FILL_COLOR),
dom.style('color', textColor ?? DEFAULT_TEXT_COLOR),
dom.style('background-color', fillColor ?? DEFAULT_BACKGROUND_COLOR),
dom.style('color', textColor ?? DEFAULT_COLOR),
dom.cls('font-bold', fontBold ?? false),
dom.cls('font-underline', fontUnderline ?? false),
dom.cls('font-italic', fontItalic ?? false),
dom.cls('font-strikethrough', fontStrikethrough ?? false),
invalid ? cssChoiceToken.cls('-invalid') : null,
blank ? cssChoiceToken.cls('-blank') : null,
...args
);
}
@@ -52,8 +54,12 @@ export const cssChoiceToken = styled('div', `
white-space: pre;
&-invalid {
background-color: white !important;
box-shadow: inset 0 0 0 1px ${colors.error};
color: ${theme.choiceTokenInvalidFg} !important;
background-color: ${theme.choiceTokenInvalidBg} !important;
box-shadow: inset 0 0 0 1px ${theme.choiceTokenInvalidBorder};
}
&-blank {
color: ${theme.lightText} !important;
}
`);
@@ -70,7 +76,7 @@ export const cssChoiceACItem = styled('li', `
cursor: pointer;
&.selected {
background-color: ${theme.autocompleteChoiceSelectedBg};
background-color: ${theme.autocompleteItemSelectedBg};
}
&-with-new {
scroll-margin-bottom: ${ADD_NEW_HEIGHT};

View File

@@ -33,6 +33,14 @@
box-shadow: 0 2px 20px 0 var(--grist-theme-menu-shadow, rgba(38, 38, 51, 0.6));
}
.datepicker-dropdown.datepicker-orient-top:after {
border-top: 6px solid var(--grist-theme-menu-bg, #fff);
}
.datepicker-dropdown.datepicker-orient-bottom:after {
border-bottom: 6px solid var(--grist-theme-menu-bg, #fff);
}
.datepicker .prev:hover,
.datepicker .next:hover,
.datepicker .datepicker-switch:hover,

View File

@@ -1,5 +1,5 @@
import {isDesktop} from 'app/client/lib/browserInfo';
import {colors} from 'app/client/ui2018/cssVars';
import {colors, theme} from 'app/client/ui2018/cssVars';
import {icon} from 'app/client/ui2018/icons';
import {IEditorCommandGroup} from 'app/client/widgets/NewBaseEditor';
import {dom, styled} from 'grainjs';
@@ -25,7 +25,7 @@ const cssFinishBtn = styled('div', `
padding: 8px;
position: absolute;
top: -8px;
--icon-color: white;
--icon-color: ${theme.controlPrimaryFg};
`);
const cssCancelBtn = styled(cssFinishBtn, `
@@ -34,7 +34,7 @@ const cssCancelBtn = styled(cssFinishBtn, `
`);
const cssSaveBtn = styled(cssFinishBtn, `
--icon-background-color: ${colors.lightGreen};
--icon-background-color: ${theme.controlPrimaryBg};
right: -40px;
`);

View File

@@ -1,6 +1,6 @@
import {makeT} from 'app/client/lib/localization';
import {ITooltipControl, showTooltip, tooltipCloseButton} from 'app/client/ui/tooltips';
import {colors, testId} from 'app/client/ui2018/cssVars';
import {testId, theme} from 'app/client/ui2018/cssVars';
import {icon} from 'app/client/ui2018/icons';
import {cssLink} from 'app/client/ui2018/links';
import {dom, styled} from 'grainjs';
@@ -29,7 +29,7 @@ export function showTooltipToCreateFormula(editorDom: HTMLElement, convert: () =
const cssConvertTooltip = styled('div', `
display: flex;
align-items: center;
--icon-color: ${colors.lightGreen};
--icon-color: ${theme.controlFg};
& > .${cssLink.className} {
margin-left: 8px;

View File

@@ -1,14 +1,14 @@
.transform_editor {
width: 90%;
margin: 5px auto;
border: 1px solid #DDDDDD;
min-height: 28px;
margin: 8px 16px;
padding: 5px 6px;
background-color: var(--grist-theme-ace-editor-bg, white);
border: 1px solid var(--grist-theme-input-border, #D9D9D9);
border-radius: 3px;
}
.transform_menu {
padding: 5px 0;
margin: 5px;
border-top: 1px solid rgba(200, 200, 200, .3);
border-bottom: 1px solid rgba(200, 200, 200, .3);
padding-bottom: 8px;
}
.fieldbuilder_settings {

View File

@@ -20,6 +20,7 @@ import { CombinedStyle, Style } from 'app/client/models/Styles';
import { COMMENTS } from 'app/client/models/features';
import { FieldSettingsMenu } from 'app/client/ui/FieldMenus';
import { cssBlockedCursor, cssLabel, cssRow } from 'app/client/ui/RightPanelStyles';
import { textButton } from 'app/client/ui2018/buttons';
import { buttonSelect, cssButtonSelect } from 'app/client/ui2018/buttonSelect';
import { theme } from 'app/client/ui2018/cssVars';
import { IOptionFull, menu, select } from 'app/client/ui2018/menus';
@@ -308,6 +309,7 @@ export class FieldBuilder extends Disposable {
grainjsDom.cls('tour-type-selector'),
grainjsDom.cls(cssBlockedCursor.className, use =>
use(this.origColumn.disableModifyBase) ||
use(this._isTransformingFormula) ||
(use(this.field.config.multiselect) && !use(allFormulas))
),
),
@@ -415,18 +417,18 @@ export class FieldBuilder extends Disposable {
this.columnTransform.finalize().catch(reportError);
}
}),
kf.row(
15, kf.label(t('Apply Formula to Data')),
3, kf.buttonGroup(
kf.checkButton(transformButton,
dom('span.glyphicon.glyphicon-flash'),
dom.testId("FieldBuilder_editTransform"),
testId('edit-transform'),
kd.toggleClass('disabled', () => this._isTransformingType() || this.origColumn.isFormula() ||
this.origColumn.disableModifyBase())
)
)
),
cssRow(
textButton(t('Apply Formula to Data'),
dom.on('click', () => transformButton(true)),
kd.hide(this._isTransformingFormula),
kd.boolAttr('disabled', () =>
this._isTransformingType() ||
this.origColumn.isFormula() ||
this.origColumn.disableModifyBase() ||
this.field.config.multiselect()),
dom.testId("FieldBuilder_editTransform"),
testId('edit-transform'),
)),
kd.maybe(this._isTransformingFormula, () => {
return this.columnTransform!.buildDom();
})

View File

@@ -1,7 +1,7 @@
import { DataRowModel } from 'app/client/models/DataRowModel';
import { ViewFieldRec } from 'app/client/models/entities/ViewFieldRec';
import { constructUrl } from 'app/client/models/gristUrlState';
import { colors, testId } from 'app/client/ui2018/cssVars';
import { testId, theme } from 'app/client/ui2018/cssVars';
import { cssIconBackground, icon } from 'app/client/ui2018/icons';
import { cssHoverIn, gristLink } from 'app/client/ui2018/links';
import { NTextBox } from 'app/client/widgets/NTextBox';
@@ -15,7 +15,7 @@ import { Computed, dom, styled } from 'grainjs';
*/
export class HyperLinkTextBox extends NTextBox {
constructor(field: ViewFieldRec) {
super(field, {defaultTextColor: colors.lightGreen.value});
super(field, {defaultTextColor: theme.link.toString()});
}
public buildDom(row: DataRowModel) {
@@ -49,7 +49,7 @@ function _formatValue(value: CellValue): string {
}
const cssFieldClip = styled('div.field_clip', `
color: var(--grist-actual-cell-color, ${colors.lightGreen});
color: var(--grist-actual-cell-color, ${theme.link});
`);
const cssHoverOnField = cssHoverIn(cssFieldClip.className);

View File

@@ -7,6 +7,7 @@ import {GristDoc} from 'app/client/components/GristDoc';
import {DocData} from 'app/client/models/DocData';
import {ViewFieldRec} from 'app/client/models/entities/ViewFieldRec';
import {SaveableObjObservable} from 'app/client/models/modelUtil';
import {theme} from 'app/client/ui2018/cssVars';
import {CellStyle} from 'app/client/widgets/CellStyle';
import {BaseFormatter} from 'app/common/ValueFormatter';
import {
@@ -19,7 +20,10 @@ import {
} from 'grainjs';
export interface Options {
// A hex value to set the default widget text color. Default to '#000000' if omitted.
/**
* CSS value of the default widget text color. Defaults to the current theme's
* cell fg color.
*/
defaultTextColor?: string;
}
@@ -44,13 +48,13 @@ export abstract class NewAbstractWidget extends Disposable {
protected valueFormatter: Observable<BaseFormatter>;
protected textColor: Observable<string>;
protected fillColor: Observable<string>;
protected readonly defaultTextColor: string;
protected readonly defaultTextColor: string|undefined = this._opts.defaultTextColor
?? theme.cellFg.toString();
constructor(protected field: ViewFieldRec, opts: Options = {}) {
constructor(protected field: ViewFieldRec, private _opts: Options = {}) {
super();
this.options = field.widgetOptionsJson;
this.valueFormatter = fromKo(field.formatter);
this.defaultTextColor = opts?.defaultTextColor || '#000000';
}
/**

View File

@@ -172,7 +172,7 @@ const cssDecimalsBox = styled('div', `
margin-right: 16px;
}
&-disabled {
background-color: ${theme.rightPanelToggleButtonDisabledBg};
opacity: 0.4;
pointer-events: none;
}
`);

View File

@@ -2,7 +2,7 @@ import {makeT} from 'app/client/lib/localization';
import {DataRowModel} from 'app/client/models/DataRowModel';
import {ViewFieldRec} from 'app/client/models/entities/ViewFieldRec';
import {cssLabel, cssRow} from 'app/client/ui/RightPanelStyles';
import {colors, hideInPrintView, testId} from 'app/client/ui2018/cssVars';
import {hideInPrintView, testId, theme} from 'app/client/ui2018/cssVars';
import {icon} from 'app/client/ui2018/icons';
import {IOptionFull, select} from 'app/client/ui2018/menus';
import {NTextBox} from 'app/client/widgets/NTextBox';
@@ -119,12 +119,12 @@ export class Reference extends NTextBox {
const cssRefIcon = styled(icon, `
float: left;
background-color: ${colors.slate};
--icon-color: ${theme.lightText};
margin: -1px 2px 2px 0;
`);
const cssRef = styled('div.field_clip', `
&-blank {
color: ${colors.slate}
color: ${theme.lightText}
}
`);

View File

@@ -2,7 +2,7 @@ import { ACResults, buildHighlightedDom, HighlightFunc, normalizeText } 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, theme, vars } from 'app/client/ui2018/cssVars';
import { 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';
@@ -181,6 +181,8 @@ const cssRefItem = styled('li', `
scroll-margin-bottom: ${addNewHeight};
}
&-new {
display: flex;
align-items: center;
color: ${theme.lightText};
position: sticky;
bottom: 0px;
@@ -195,26 +197,27 @@ const cssRefItem = styled('li', `
`);
export const cssPlusButton = styled('div', `
display: inline-block;
display: flex;
width: 20px;
height: 20px;
border-radius: 20px;
margin-right: 8px;
text-align: center;
background-color: ${colors.lightGreen};
color: ${colors.light};
align-items: center;
justify-content: center;
background-color: ${theme.autocompleteAddNewCircleBg};
color: ${theme.autocompleteAddNewCircleFg};
.selected > & {
background-color: ${colors.darkGreen};
background-color: ${theme.autocompleteAddNewCircleSelectedBg};
}
`);
export const cssPlusIcon = styled(icon, `
background-color: ${colors.light};
background-color: ${theme.autocompleteAddNewCircleFg};
`);
const cssRefEditIcon = styled(icon, `
background-color: ${colors.slate};
background-color: ${theme.lightText};
position: absolute;
top: 0;
left: 0;

View File

@@ -1,5 +1,5 @@
import {DataRowModel} from 'app/client/models/DataRowModel';
import {colors, testId} from 'app/client/ui2018/cssVars';
import {testId} from 'app/client/ui2018/cssVars';
import {isList} from 'app/common/gristTypes';
import {dom} from 'grainjs';
import {cssChoiceList, cssToken} from "app/client/widgets/ChoiceListCell";
@@ -51,7 +51,7 @@ export class ReferenceList extends Reference {
return choiceToken(
isBlankReference ? '[Blank]' : token,
{
textColor: isBlankReference ? colors.slate.value : undefined
blank: isBlankReference,
},
dom.cls(cssToken.className),
testId('ref-list-cell-token')

View File

@@ -298,7 +298,6 @@ const cssTokenField = styled(tokenFieldStyles.cssTokenField, `
padding: 0 3px;
height: min-content;
min-height: 22px;
color: black;
flex-wrap: wrap;
`);
@@ -307,13 +306,14 @@ const cssToken = styled(tokenFieldStyles.cssToken, `
margin: 2px;
line-height: 16px;
white-space: pre;
color: ${theme.choiceTokenFg};
&.selected {
box-shadow: inset 0 0 0 1px ${colors.lightGreen};
box-shadow: inset 0 0 0 1px ${theme.choiceTokenSelectedBorder};
}
&-blank {
color: ${colors.slate};
color: ${theme.lightText};
}
`);

View File

@@ -12,7 +12,7 @@
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
background-color: var(--grist-theme-switch-slider-fg, #ccc);
border-radius: 17px;
}
@@ -28,7 +28,7 @@
width: 13px;
left: 2px;
bottom: 2px;
background-color: white;
background-color: var(--grist-theme-switch-circle-fg, white);
border-radius: 17px;
}

View File

@@ -91,6 +91,10 @@
line-height: inherit;
}
.celleditor_text_editor::placeholder {
color: var(--grist-theme-cell-editor-placeholder-fg, unset);
}
.celleditor_content_measure {
position: absolute;
left: 0;

View File

@@ -3,6 +3,7 @@ import { DataRowModel } from 'app/client/models/DataRowModel';
import { ViewFieldRec } from 'app/client/models/entities/ViewFieldRec';
import { KoSaveableObservable } from 'app/client/models/modelUtil';
import { NewAbstractWidget, Options } from 'app/client/widgets/NewAbstractWidget';
import { theme } from 'app/client/ui2018/cssVars';
import { dom } from 'grainjs';
/**
@@ -28,7 +29,7 @@ abstract class ToggleBase extends NewAbstractWidget {
export class ToggleCheckBox extends ToggleBase {
constructor(field: ViewFieldRec, _options: Options = {}) {
super(field, {defaultTextColor: '#606060'});
super(field, {defaultTextColor: theme.toggleCheckboxFg.toString()});
}
public buildDom(row: DataRowModel) {