From 62113dcf7429a6dea36df3c0236fcb0825ddbc8b Mon Sep 17 00:00:00 2001 From: Martin Raifer Date: Tue, 8 Nov 2022 18:39:00 +0100 Subject: [PATCH] improve icons in comboboxes: update while typing, fix spacings also makes sure checkbox & radio are aligned with the left padding of the respective input fields --- css/80_app.css | 8 +++--- modules/ui/combobox.js | 7 +++-- modules/ui/fields/combo.js | 58 +++++++++++++++++++++++--------------- 3 files changed, 45 insertions(+), 28 deletions(-) diff --git a/css/80_app.css b/css/80_app.css index c2c895544..17772d623 100644 --- a/css/80_app.css +++ b/css/80_app.css @@ -228,7 +228,7 @@ input[type="checkbox"], input[type="radio"] { width: 14px; height: 14px; - margin-right: 5px; + margin-right: 6px; cursor: pointer; vertical-align: middle; } @@ -1744,11 +1744,13 @@ a.hide-toggle { align-self: center; vertical-align: middle; z-index: 1; - text-align: center; + padding-left: 11px; } .ideditor[dir='rtl'] .form-field-input-combo .tag-value-icon { margin-right: 0; margin-left: -30px; + padding-left: 0; + padding-right: 11px; } .tag-value-icon .icon { width: 11px; @@ -1838,7 +1840,6 @@ a.hide-toggle { } .form-field-input-check > input[type="checkbox"] { flex: 0 1 auto; - width: 20px; margin-top: 0; } .form-field-input-check > span { @@ -1931,7 +1932,6 @@ a.hide-toggle { } .form-field-input-radio > label > input[type="radio"] { flex: 0 1 auto; - width: 20px; } .form-field-input-radio > label > span { flex: 1 1 auto; diff --git a/modules/ui/combobox.js b/modules/ui/combobox.js index 956f6beb1..7d4963cac 100644 --- a/modules/ui/combobox.js +++ b/modules/ui/combobox.js @@ -16,7 +16,7 @@ import { utilGetSetValue, utilRebind, utilTriggerEvent } from '../util'; var _comboHideTimerID; export function uiCombobox(context, klass) { - var dispatch = d3_dispatch('accept', 'cancel'); + var dispatch = d3_dispatch('accept', 'cancel', 'update'); var container = context.container(); var _suggestions = []; @@ -273,7 +273,8 @@ export function uiCombobox(context, klass) { // pick new _selected index = Math.max(Math.min(index + dir, _suggestions.length - 1), 0); _selected = _suggestions[index].value; - input.property('value', _selected); + utilGetSetValue(input, _selected); + dispatch.call('update'); } render(); @@ -371,6 +372,7 @@ export function uiCombobox(context, klass) { var bestVal = suggestionValues[bestIndex]; input.property('value', bestVal); input.node().setSelectionRange(val.length, bestVal.length); + dispatch.call('update'); return bestVal; } } @@ -460,6 +462,7 @@ export function uiCombobox(context, klass) { thiz.setSelectionRange(val.length, val.length); dispatch.call('cancel', thiz); + hide(); } diff --git a/modules/ui/fields/combo.js b/modules/ui/fields/combo.js index b3a06cc60..17e2c50cd 100644 --- a/modules/ui/fields/combo.js +++ b/modules/ui/fields/combo.js @@ -182,7 +182,7 @@ export function uiFieldCombo(field, context) { key: v, value: stringsField.t('options.' + v, { default: v }), title: v, - display: beautifyDisplay(stringsField.t.append('options.' + v, { default: v }), v), + display: addComboboxIcons(stringsField.t.append('options.' + v, { default: v }), v), klass: stringsField.hasTextForStringId('options.' + v) ? '' : 'raw-option' }; }); @@ -261,7 +261,7 @@ export function uiFieldCombo(field, context) { return { key: k, value: label, - display: beautifyDisplay(stringsField.t.append('options.' + k, { default: k }), k), + display: addComboboxIcons(stringsField.t.append('options.' + k, { default: k }), k), title: isLocalizable ? k : (d.title !== label ? d.title : ''), klass: isLocalizable ? '' : 'raw-option' }; @@ -275,13 +275,15 @@ export function uiFieldCombo(field, context) { } // adds icons to tag values which have one - function beautifyDisplay(disp, value) { - if (valueIcons[field.key] && valueIcons[field.key].indexOf(value) !== -1) { + function addComboboxIcons(disp, value) { + if (valueIcons[field.key]) { return function(selection) { - selection + var span = selection .insert('span', ':first-child') - .attr('class', 'tag-value-icon') - .call(svgIcon('#iD-crossing_markings-' + value.replace(':', '_'))); + .attr('class', 'tag-value-icon'); + if (valueIcons[field.key].indexOf(value) !== -1) { + span.call(svgIcon('#iD-' + field.key.replace(/:/g, '_') + '-' + value.replace(/:/g, '_'))); + } disp.call(this, selection); }; } @@ -453,7 +455,10 @@ export function uiFieldCombo(field, context) { _input .on('change', change) - .on('blur', change); + .on('blur', change) + .on('input', function() { + updateIcon(utilGetSetValue(_input)); + }); _input .on('keydown.field', function(d3_event) { @@ -475,8 +480,30 @@ export function uiFieldCombo(field, context) { _input .on('focus', function() { _container.classed('active', true); }); } + + _combobox + .on('cancel', function() { + _input.node().blur(); + }) + .on('update', function() { + updateIcon(utilGetSetValue(_input)); + }); } + function updateIcon(value) { + if (valueIcons[field.key]) { + _container.selectAll('.tag-value-icon').remove(); + var iconSelector = _container.selectAll('.tag-value-icon') + .data([value]) + .enter() + .insert('div', 'input') + .attr('class', 'tag-value-icon'); + if (valueIcons[field.key].indexOf(value) !== -1) { + iconSelector + .call(svgIcon('#iD-' + field.key.replace(/:/g, '_') + '-' + value.replace(/:/g, '_'))); + } + } + } combo.tags = function(tags) { _tags = tags; @@ -658,20 +685,7 @@ export function uiFieldCombo(field, context) { } }); - if (valueIcons[field.key]) { - _container.selectAll('.tag-value-icon').remove(); - var value = tags[field.key]; - if (valueIcons[field.key].indexOf(value) !== -1) { - var iconSelector = _container.selectAll('.tag-value-icon') - .data([value]); - - iconSelector - .enter() - .insert('div', 'input') - .attr('class', 'tag-value-icon') - .call(svgIcon('#iD-crossing_markings-' + value.replace(':', '_'))); - } - } + updateIcon(tags[field.key]); } };