From 3d808f67f1b03dfbbd17f87bce538a6ec4815cab Mon Sep 17 00:00:00 2001 From: Florent Date: Tue, 13 Jun 2023 19:14:01 +0200 Subject: [PATCH] Visually identify that a field is a drop-down list (single choice) #491 (#525) * Visually identify that a field is a drop-down list (single choice) #491 --------- Co-authored-by: Florent --- app/client/widgets/ChoiceEditor.js | 24 +++++++++++++++++++++--- app/client/widgets/ChoiceTextBox.ts | 13 ++++++++++++- app/client/widgets/TextEditor.js | 2 +- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/app/client/widgets/ChoiceEditor.js b/app/client/widgets/ChoiceEditor.js index 85f4facb..1e7aef72 100644 --- a/app/client/widgets/ChoiceEditor.js +++ b/app/client/widgets/ChoiceEditor.js @@ -7,9 +7,10 @@ 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} = require('app/client/ui2018/cssVars'); +const {testId, colors} = require('app/client/ui2018/cssVars'); const {choiceToken, cssChoiceACItem} = require('app/client/widgets/ChoiceToken'); -const {dom} = require('grainjs'); +const {dom, styled} = require('grainjs'); +const {icon} = require('../ui2018/icons'); /** * ChoiceEditor - TextEditor with a dropdown for possible choices. @@ -19,7 +20,10 @@ function ChoiceEditor(options) { this.choices = options.field.widgetOptionsJson.peek().choices || []; this.choiceOptions = options.field.widgetOptionsJson.peek().choiceOptions || {}; - + if (!options.readonly && options.field.viewSection().parentKey() === "single") { + this.cellEditorDiv.classList.add(cssChoiceEditor.className); + this.cellEditorDiv.appendChild(cssChoiceEditIcon('Dropdown')); + } // Whether to include a button to show a new choice. // TODO: Disable when the user cannot change column configuration. this.enableAddNew = true; @@ -107,4 +111,18 @@ ChoiceEditor.prototype.maybeShowAddNew = function(result, text) { return result; } +const cssChoiceEditIcon = styled(icon, ` + background-color: ${colors.slate}; + position: absolute; + top: 0; + left: 0; + margin: 3px 3px 0 3px; +`); + +const cssChoiceEditor = styled('div', ` + & > .celleditor_text_editor, & > .celleditor_content_measure { + padding-left: 18px; + } +`); + module.exports = ChoiceEditor; diff --git a/app/client/widgets/ChoiceTextBox.ts b/app/client/widgets/ChoiceTextBox.ts index e8635d70..558328fc 100644 --- a/app/client/widgets/ChoiceTextBox.ts +++ b/app/client/widgets/ChoiceTextBox.ts @@ -4,7 +4,8 @@ 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 {testId} from 'app/client/ui2018/cssVars'; +import {colors, testId} 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 {NTextBox} from 'app/client/widgets/NTextBox'; @@ -45,9 +46,13 @@ export class ChoiceTextBox extends NTextBox { public buildDom(row: DataRowModel) { const value = row.cells[this.field.colId()]; + const isSingle = this.field.viewSection().parentKey() === "single"; + const maybeDropDownCssChoiceEditIcon = isSingle ? cssChoiceEditIcon('Dropdown') : null; + return cssChoiceField( cssChoiceTextWrapper( dom.style('justify-content', (use) => use(this.alignment) === 'right' ? 'flex-end' : use(this.alignment)), + maybeDropDownCssChoiceEditIcon, dom.domComputed((use) => { if (this.isDisposed() || use(row._isAddRow)) { return null; } @@ -150,3 +155,9 @@ const cssChoiceText = styled('div', ` height: min-content; line-height: 16px; `); + +const cssChoiceEditIcon = styled(icon, ` + background-color: ${colors.slate}; + display: block; + height: inherit; +`); diff --git a/app/client/widgets/TextEditor.js b/app/client/widgets/TextEditor.js index 0dee97d4..593317c4 100644 --- a/app/client/widgets/TextEditor.js +++ b/app/client/widgets/TextEditor.js @@ -39,7 +39,7 @@ function TextEditor(options) { this.dom = dom('div.default_editor', kd.toggleClass("readonly_editor", options.readonly), - dom('div.celleditor_cursor_editor', dom.testId('TextEditor_editor'), + this.cellEditorDiv = dom('div.celleditor_cursor_editor', dom.testId('TextEditor_editor'), testId('widget-text-editor'), // new-style testId matches NTextEditor, for more uniform tests. this.contentSizer = dom('div.celleditor_content_measure'), this.textInput = dom('textarea.celleditor_text_editor',