Add uiFieldHelp component, currently just for turn restrictions field

This commit is contained in:
Bryan Housel
2018-02-23 15:09:05 -05:00
parent 7fa27217b6
commit 57d2aee6c8
5 changed files with 195 additions and 58 deletions
+16 -1
View File
@@ -1266,6 +1266,7 @@ a.hide-toggle {
border-top: 0;
border-radius: 0 0 4px 4px;
overflow: hidden;
position: relative;
}
.form-field textarea {
@@ -1988,7 +1989,7 @@ div.combobox {
}
.combobox-caret::after {
content:"";
content: "";
height: 0; width: 0;
position: absolute;
left: 0; right: 0; bottom: 0; top: 0;
@@ -1998,6 +1999,20 @@ div.combobox {
border-right: 5px solid transparent;
}
/* Field Help */
.field-help-body {
display: block;
position: absolute;
overflow: hidden;
top: 0;
width: 100%;
height: 100%;
z-index: 2;
padding: 10px;
background: rgba(255,255,255,0.95);
}
/* Raw Tag Editor */
.tag-list {
+41 -20
View File
@@ -11,6 +11,7 @@ import {
import { textDirection } from '../util/locale';
import { svgIcon } from '../svg';
import { uiFieldHelp } from './field_help';
import { uiFields } from './fields';
import { uiTagReference } from './tag_reference';
import { utilRebind } from '../util';
@@ -25,11 +26,11 @@ export function uiField(context, presetField, entity, options) {
info: true
}, options);
var dispatch = d3_dispatch('change'),
field = _clone(presetField),
show = options.show,
state = '',
tags = {};
var dispatch = d3_dispatch('change');
var field = _clone(presetField);
var _show = options.show;
var _state = '';
var _tags = {};
field.impl = uiFields[field.type](field, context)
@@ -48,14 +49,14 @@ export function uiField(context, presetField, entity, options) {
if (!entity) return false;
var original = context.graph().base().entities[entity.id];
return _some(field.keys, function(key) {
return original ? tags[key] !== original.tags[key] : tags[key];
return original ? _tags[key] !== original.tags[key] : _tags[key];
});
}
function isPresent() {
return _some(field.keys, function(key) {
return tags[key];
return _tags[key];
});
}
@@ -65,8 +66,8 @@ export function uiField(context, presetField, entity, options) {
d3_event.preventDefault();
if (!entity) return false;
var original = context.graph().base().entities[entity.id],
t = {};
var original = context.graph().base().entities[entity.id];
var t = {};
d.keys.forEach(function(key) {
t[key] = original ? original.tags[key] : undefined;
});
@@ -143,14 +144,25 @@ export function uiField(context, presetField, entity, options) {
.classed('modified', isModified())
.classed('present', isPresent())
.each(function(d) {
var reference, help;
// instantiate field help
if (options.wrap && field.type === 'restrictions') {
help = uiFieldHelp('restrictions');
if (_state === 'hover') {
help.showing(false);
}
}
// instantiate tag reference
if (options.wrap && options.info) {
var referenceKey = d.key;
if (d.type === 'multiCombo') { // lookup key without the trailing ':'
referenceKey = referenceKey.replace(/:$/, '');
}
var reference = uiTagReference(d.reference || { key: referenceKey }, context);
if (state === 'hover') {
reference = uiTagReference(d.reference || { key: referenceKey }, context);
if (_state === 'hover') {
reference.showing(false);
}
}
@@ -158,35 +170,44 @@ export function uiField(context, presetField, entity, options) {
d3_select(this)
.call(d.impl);
if (options.wrap && options.info) {
// add field help components
if (help) {
d3_select(this)
.call(help.body)
.select('.form-label-button-wrap')
.call(help.button);
}
// add tag reference components
if (reference) {
d3_select(this)
.call(reference.body)
.select('.form-label-button-wrap')
.call(reference.button);
}
d.impl.tags(tags);
d.impl.tags(_tags);
});
};
field.state = function(_) {
if (!arguments.length) return state;
state = _;
if (!arguments.length) return _state;
_state = _;
return field;
};
field.tags = function(_) {
if (!arguments.length) return tags;
tags = _;
if (!arguments.length) return _tags;
_tags = _;
return field;
};
field.show = function() {
show = true;
if (field.default && field.key && tags[field.key] !== field.default) {
_show = true;
if (field.default && field.key && _tags[field.key] !== field.default) {
var t = {};
t[field.key] = field.default;
dispatch.call('change', this, t);
@@ -195,7 +216,7 @@ export function uiField(context, presetField, entity, options) {
field.isShown = function() {
return show || _some(field.keys, function(key) { return !!tags[key]; });
return _show || _some(field.keys, function(key) { return !!_tags[key]; });
};
+101
View File
@@ -0,0 +1,101 @@
import {
event as d3_event,
select as d3_select
} from 'd3-selection';
import { t } from '../util/locale';
import { svgIcon } from '../svg';
export function uiFieldHelp(fieldName) {
var fieldHelp = {};
var _body = d3_select(null);
var _showing;
function show() {
_body
.classed('hide', false)
.transition()
.duration(200)
.style('height', '100%');
_showing = true;
}
function hide() {
_body
.transition()
.duration(200)
.style('height', '0px')
.on('end', function () {
_body.classed('hide', true);
});
_showing = false;
}
fieldHelp.button = function(selection) {
var button = selection.selectAll('.field-help-button')
.data([0]);
// enter/update
button.enter()
.append('button')
.attr('class', 'field-help-button')
.attr('tabindex', -1)
.call(svgIcon('#icon-help'))
.merge(button)
.on('click', function () {
d3_event.stopPropagation();
d3_event.preventDefault();
if (_showing) {
hide();
} else {
show();
}
});
};
fieldHelp.body = function(selection) {
// this control expects the field to have a preset-input-wrap div
var wrap = selection.selectAll('.preset-input-wrap');
if (wrap.empty()) return;
_body = wrap.selectAll('.field-help-body')
.data([0]);
var enter = _body.enter()
.append('div')
.attr('class', 'field-help-body cf hide')
.style('height', '0px');
//debug
for (var i = 0; i < 15; i++) {
enter
.append('p')
.attr('class', 'field-help-description')
.text('lorem ipsum');
}
_body = _body
.merge(enter);
if (_showing === false) {
hide();
}
};
fieldHelp.showing = function(_) {
if (!arguments.length) return _showing;
_showing = _;
return fieldHelp;
};
return fieldHelp;
}
+1
View File
@@ -19,6 +19,7 @@ export { uiEntityEditor } from './entity_editor';
export { uiFeatureInfo } from './feature_info';
export { uiFeatureList } from './feature_list';
export { uiField } from './field';
export { uiFieldHelp } from './field_help';
export { uiFlash } from './flash';
export { uiFormFields } from './form_fields';
export { uiFullScreen } from './full_screen';
+36 -37
View File
@@ -13,17 +13,18 @@ import { svgIcon } from '../svg';
export function uiTagReference(tag) {
var taginfo = services.taginfo,
tagReference = {},
button = d3_select(null),
body = d3_select(null),
loaded,
showing;
var taginfo = services.taginfo;
var tagReference = {};
var _button = d3_select(null);
var _body = d3_select(null);
var _loaded;
var _showing;
function findLocal(data) {
var locale = utilDetect().locale.toLowerCase(),
localized;
var locale = utilDetect().locale.toLowerCase();
var localized;
if (locale !== 'pt-br') { // see #3776, prefer 'pt' over 'pt-br'
localized = _find(data, function(d) {
@@ -52,7 +53,7 @@ export function uiTagReference(tag) {
function load(param) {
if (!taginfo) return;
button
_button
.classed('tag-reference-loading', true);
taginfo.docs(param, function show(err, data) {
@@ -61,13 +62,13 @@ export function uiTagReference(tag) {
docs = findLocal(data);
}
body.html('');
_body.html('');
if (!docs || !docs.title) {
if (param.hasOwnProperty('value')) {
load(_omit(param, 'value')); // retry with key only
} else {
body
_body
.append('p')
.attr('class', 'tag-reference-description')
.text(t('inspector.no_documentation_key'));
@@ -77,7 +78,7 @@ export function uiTagReference(tag) {
}
if (docs.image && docs.image.thumb_url_prefix) {
body
_body
.append('img')
.attr('class', 'tag-reference-wiki-image')
.attr('src', docs.image.thumb_url_prefix + '100' + docs.image.thumb_url_suffix)
@@ -87,12 +88,12 @@ export function uiTagReference(tag) {
done();
}
body
_body
.append('p')
.attr('class', 'tag-reference-description')
.text(docs.description || t('inspector.documentation_redirect'));
body
_body
.append('a')
.attr('class', 'tag-reference-link')
.attr('target', '_blank')
@@ -104,7 +105,7 @@ export function uiTagReference(tag) {
// Add link to info about "good changeset comments" - #2923
if (param.key === 'comment') {
body
_body
.append('a')
.attr('class', 'tag-reference-comment-link')
.attr('target', '_blank')
@@ -119,54 +120,54 @@ export function uiTagReference(tag) {
function done() {
loaded = true;
_loaded = true;
button
_button
.classed('tag-reference-loading', false);
body
_body
.classed('expanded', true)
.transition()
.duration(200)
.style('max-height', '200px')
.style('opacity', '1');
showing = true;
_showing = true;
}
function hide() {
body
_body
.transition()
.duration(200)
.style('max-height', '0px')
.style('opacity', '0')
.on('end', function () {
body.classed('expanded', false);
_body.classed('expanded', false);
});
showing = false;
_showing = false;
}
tagReference.button = function(selection) {
button = selection.selectAll('.tag-reference-button')
_button = selection.selectAll('.tag-reference-button')
.data([0]);
button = button.enter()
_button = _button.enter()
.append('button')
.attr('class', 'tag-reference-button')
.attr('tabindex', -1)
.call(svgIcon('#icon-inspect'))
.merge(button);
.merge(_button);
button
_button
.on('click', function () {
d3_event.stopPropagation();
d3_event.preventDefault();
if (showing) {
if (_showing) {
hide();
} else if (loaded) {
} else if (_loaded) {
done();
} else {
load(tag);
@@ -176,31 +177,29 @@ export function uiTagReference(tag) {
tagReference.body = function(selection) {
var tagid = tag.rtype || (tag.key + '-' + tag.value);
body = selection.selectAll('.tag-reference-body')
_body = selection.selectAll('.tag-reference-body')
.data([tagid], function(d) { return d; });
body.exit()
_body.exit()
.remove();
body = body.enter()
_body = _body.enter()
.append('div')
.attr('class', 'tag-reference-body cf')
.style('max-height', '0')
.style('opacity', '0')
.merge(body);
.merge(_body);
if (showing === false) {
if (_showing === false) {
hide();
}
};
tagReference.showing = function(_) {
if (!arguments.length) return showing;
showing = _;
if (!arguments.length) return _showing;
_showing = _;
return tagReference;
};