(core) Fixing click-away bug for the cell color widget

Summary:
After introducing multi columns operation, color picker
could save a cell style for a wrong column, if the save operation
was triggered by user clicking on one of the cells.

Test Plan: Updated

Reviewers: georgegevoian

Reviewed By: georgegevoian

Differential Revision: https://phab.getgrist.com/D3668
This commit is contained in:
Jarosław Sadziński
2022-10-24 12:06:24 +02:00
parent 82eb5b3f76
commit 7c8db90aef
6 changed files with 205 additions and 126 deletions

View File

@@ -1,20 +1,13 @@
import {allCommands} from 'app/client/components/commands';
import {GristDoc} from 'app/client/components/GristDoc';
import {ViewFieldRec} from 'app/client/models/entities/ViewFieldRec';
import {Style} from 'app/client/models/Styles';
import {textButton} from 'app/client/ui2018/buttons';
import {ColorOption, colorSelect} from 'app/client/ui2018/ColorSelect';
import {theme, vars} from 'app/client/ui2018/cssVars';
import {ConditionalStyle} from 'app/client/widgets/ConditionalStyle';
import {Computed, Disposable, dom, DomContents, fromKo, MultiHolder, Observable, styled} from 'grainjs';
import {Computed, Disposable, dom, DomContents, fromKo, styled} from 'grainjs';
export class CellStyle extends Disposable {
private _textColor: Observable<string|undefined>;
private _fillColor: Observable<string|undefined>;
private _fontBold: Observable<boolean|undefined>;
private _fontUnderline: Observable<boolean|undefined>;
private _fontItalic: Observable<boolean|undefined>;
private _fontStrikethrough: Observable<boolean|undefined>;
constructor(
private _field: ViewFieldRec,
@@ -22,55 +15,53 @@ export class CellStyle extends Disposable {
private _defaultTextColor: string
) {
super();
this._textColor = fromKo(this._field.config.textColor);
this._fillColor = fromKo(this._field.config.fillColor);
this._fontBold = fromKo(this._field.config.fontBold);
this._fontUnderline = fromKo(this._field.config.fontUnderline);
this._fontItalic = fromKo(this._field.config.fontItalic);
this._fontStrikethrough = fromKo(this._field.config.fontStrikethrough);
}
public buildDom(): DomContents {
const holder = new MultiHolder();
const hasMixedStyle = Computed.create(holder, use => {
if (!use(this._field.config.multiselect)) { return false; }
const commonStyle = [
use(this._field.config.options.mixed('textColor')),
use(this._field.config.options.mixed('fillColor')),
use(this._field.config.options.mixed('fontBold')),
use(this._field.config.options.mixed('fontUnderline')),
use(this._field.config.options.mixed('fontItalic')),
use(this._field.config.options.mixed('fontStrikethrough'))
];
return commonStyle.some(Boolean);
});
let state: Style[]|null = null;
return [
cssLine(
cssLabel('CELL STYLE', dom.autoDispose(holder)),
cssLabel('CELL STYLE'),
cssButton('Open row styles', dom.on('click', allCommands.viewTabOpen.run)),
),
cssRow(
colorSelect(
{
textColor: new ColorOption(
{ color: this._textColor, defaultColor: this._defaultTextColor, noneText: 'default'}
),
fillColor: new ColorOption(
{ color: this._fillColor, allowsNone: true, noneText: 'none'}
),
fontBold: this._fontBold,
fontItalic: this._fontItalic,
fontUnderline: this._fontUnderline,
fontStrikethrough: this._fontStrikethrough
}, {
// Calling `field.config.options.save()` saves all options at once.
onSave: () => this._field.config.options.save(),
onOpen: () => state = this._field.config.copyStyles(),
onRevert: () => this._field.config.setStyles(state),
placeholder: use => use(hasMixedStyle) ? 'Mixed style' : 'Default cell style'
}
)
dom.domComputedOwned(fromKo(this._field.config.style), (holder, options) => {
const textColor = fromKo(options.prop("textColor"));
const fillColor = fromKo(options.prop("fillColor"));
const fontBold = fromKo(options.prop("fontBold"));
const fontUnderline = fromKo(options.prop("fontUnderline"));
const fontItalic = fromKo(options.prop("fontItalic"));
const fontStrikethrough = fromKo(options.prop("fontStrikethrough"));
const hasMixedStyle = Computed.create(holder, use => {
if (!use(this._field.config.multiselect)) { return false; }
const commonStyle = [
use(options.mixed('textColor')),
use(options.mixed('fillColor')),
use(options.mixed('fontBold')),
use(options.mixed('fontUnderline')),
use(options.mixed('fontItalic')),
use(options.mixed('fontStrikethrough'))
];
return commonStyle.some(Boolean);
});
return colorSelect(
{
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,
fontStrikethrough: fontStrikethrough
}, {
onSave: () => options.save(),
onRevert: () => options.revert(),
placeholder: use => use(hasMixedStyle) ? 'Mixed style' : 'Default cell style'
}
);
}),
),
dom.create(ConditionalStyle, "Cell Style", this._field, this._gristDoc, fromKo(this._field.config.multiselect))
];