mirror of
https://github.com/FoggedLens/iD.git
synced 2026-03-31 09:19:25 +02:00
Update semicombo reordering (re: #7024):
Don't try reordering multiCombo fields Fix offset behavior for full-width semicombos Use grab/grabbing cursor style Keep dragged chip above others
This commit is contained in:
@@ -1557,20 +1557,28 @@ a.hide-toggle {
|
||||
margin-left: 6px;
|
||||
}
|
||||
|
||||
.form-field-input-multicombo li.chips {
|
||||
.form-field-input-multicombo li.chip {
|
||||
background-color: #eff2f7;
|
||||
border: 1px solid #ccd5e3;
|
||||
line-height: 25px;
|
||||
max-width: 100%;
|
||||
}
|
||||
[dir='ltr'] .form-field-input-multicombo li.chips {
|
||||
[dir='ltr'] .form-field-input-multicombo li.chip {
|
||||
padding: 2px 0px 2px 5px;
|
||||
}
|
||||
[dir='rtl'] .form-field-input-multicombo li.chips {
|
||||
[dir='rtl'] .form-field-input-multicombo li.chip {
|
||||
padding: 2px 5px 2px 0px;
|
||||
}
|
||||
.form-field-input-multicombo li.chip.draggable {
|
||||
cursor: grab;
|
||||
}
|
||||
.form-field-input-multicombo li.chip.dragging {
|
||||
opacity: 0.75;
|
||||
z-index: 3000;
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
.form-field-input-multicombo li.chips span {
|
||||
.form-field-input-multicombo li.chip span {
|
||||
display: block;
|
||||
flex: 1 1 auto;
|
||||
overflow: hidden;
|
||||
@@ -1604,7 +1612,7 @@ a.hide-toggle {
|
||||
border-radius: 4px !important;
|
||||
}
|
||||
|
||||
.form-field-input-multicombo .full-line-chips li.chips {
|
||||
.form-field-input-multicombo .full-line-chips li.chip {
|
||||
width: 100%;
|
||||
}
|
||||
.form-field-input-multicombo .full-line-chips .input-wrap {
|
||||
|
||||
@@ -431,7 +431,7 @@ export function uiFieldCombo(field, context) {
|
||||
|
||||
|
||||
// Render chips
|
||||
var chips = container.selectAll('.chips')
|
||||
var chips = container.selectAll('.chip')
|
||||
.data(_multiData);
|
||||
|
||||
chips.exit()
|
||||
@@ -439,125 +439,12 @@ export function uiFieldCombo(field, context) {
|
||||
|
||||
var enter = chips.enter()
|
||||
.insert('li', '.input-wrap')
|
||||
.attr('class', 'chips');
|
||||
|
||||
enter.style('cursor', 'move');
|
||||
.attr('class', 'chip')
|
||||
.classed('draggable', isSemi);
|
||||
|
||||
// allow drag and drop re-ordering of chips
|
||||
var dragOrigin, targetIndex;
|
||||
enter.call(d3_drag()
|
||||
.on('start', function() {
|
||||
dragOrigin = {
|
||||
x: d3_event.x,
|
||||
y: d3_event.y
|
||||
};
|
||||
targetIndex = null;
|
||||
})
|
||||
.on('drag', function(d, index) {
|
||||
var x = d3_event.x - dragOrigin.x,
|
||||
y = d3_event.y - dragOrigin.y;
|
||||
|
||||
if (!d3_select(this).classed('dragging') &&
|
||||
// don't display drag until dragging beyond a distance threshold
|
||||
Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)) <= 5) return;
|
||||
|
||||
d3_select(this)
|
||||
.classed('dragging', true);
|
||||
|
||||
targetIndex = null;
|
||||
var targetIndexOffsetTop = null;
|
||||
var draggedTagWidth = d3_select(this).node().offsetWidth;
|
||||
|
||||
if (field.id === 'destination_oneway') { // meaning tags are full width
|
||||
container.selectAll('.chips')
|
||||
.style('transform', function(d2, index2) {
|
||||
var node = d3_select(this).node();
|
||||
|
||||
if (index === index2) {
|
||||
return 'translate(' + x + 'px, ' + y + 'px)';
|
||||
// move the dragged tag up the order
|
||||
} else if (index2 > index && d3_event.y > node.offsetTop - node.offsetHeight) {
|
||||
if (targetIndex === null || index2 > targetIndex) {
|
||||
targetIndex = index2;
|
||||
}
|
||||
return 'translateY(-100%)';
|
||||
// move the dragged tag down the order
|
||||
} else if (index2 < index && d3_event.y < node.offsetTop) {
|
||||
if (targetIndex === null || index2 < targetIndex) {
|
||||
targetIndex = index2;
|
||||
}
|
||||
return 'translateY(100%)';
|
||||
}
|
||||
return null;
|
||||
});
|
||||
} else {
|
||||
container.selectAll('.chips')
|
||||
.each(function(d2, index2) {
|
||||
var node = d3_select(this).node();
|
||||
|
||||
// check the cursor is in the bounding box
|
||||
if (
|
||||
index !== index2 &&
|
||||
d3_event.x < node.offsetLeft + (node.offsetWidth / 2) &&
|
||||
d3_event.x > node.offsetLeft - (node.offsetWidth / 2) &&
|
||||
d3_event.y < node.offsetTop + node.offsetHeight &&
|
||||
d3_event.y > node.offsetTop
|
||||
) {
|
||||
targetIndex = index2;
|
||||
targetIndexOffsetTop = node.offsetTop;
|
||||
}
|
||||
});
|
||||
|
||||
container.selectAll('.chips')
|
||||
.style('transform', function(d2, index2) {
|
||||
var node = d3_select(this).node();
|
||||
|
||||
if (index === index2) {
|
||||
return 'translate(' + x + 'px, ' + y + 'px)';
|
||||
}
|
||||
|
||||
// only translate tags in the same row
|
||||
if (node.offsetTop === targetIndexOffsetTop) {
|
||||
if (index2 < index && index2 >= targetIndex) {
|
||||
return 'translateX(' + draggedTagWidth + 'px)';
|
||||
} else if (index2 > index && index2 <= targetIndex) {
|
||||
return 'translateX(-' + draggedTagWidth + 'px)';
|
||||
}
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
})
|
||||
.on('end', function(d, index) {
|
||||
if (!d3_select(this).classed('dragging')) {
|
||||
return;
|
||||
}
|
||||
|
||||
d3_select(this)
|
||||
.classed('dragging', false);
|
||||
|
||||
container.selectAll('.chips')
|
||||
.style('transform', null);
|
||||
|
||||
if (targetIndex !== null) {
|
||||
var element = _multiData[index];
|
||||
_multiData.splice(index, 1);
|
||||
_multiData.splice(targetIndex, 0, element);
|
||||
|
||||
var t = {};
|
||||
|
||||
if (_multiData.length) {
|
||||
t[field.key] = _multiData.map(function(element) {
|
||||
return element.key;
|
||||
}).join(';');
|
||||
} else {
|
||||
t[field.key] = undefined;
|
||||
}
|
||||
|
||||
dispatch.call('change', this, t);
|
||||
}
|
||||
})
|
||||
);
|
||||
if (isSemi) { // only semiCombo values are ordered
|
||||
registerDragAndDrop(enter);
|
||||
}
|
||||
|
||||
enter.append('span');
|
||||
enter.append('a');
|
||||
@@ -577,6 +464,125 @@ export function uiFieldCombo(field, context) {
|
||||
}
|
||||
};
|
||||
|
||||
function registerDragAndDrop(selection) {
|
||||
|
||||
// allow drag and drop re-ordering of chips
|
||||
var dragOrigin, targetIndex;
|
||||
selection.call(d3_drag()
|
||||
.on('start', function() {
|
||||
dragOrigin = {
|
||||
x: d3_event.x,
|
||||
y: d3_event.y
|
||||
};
|
||||
targetIndex = null;
|
||||
})
|
||||
.on('drag', function(d, index) {
|
||||
var x = d3_event.x - dragOrigin.x,
|
||||
y = d3_event.y - dragOrigin.y;
|
||||
|
||||
if (!d3_select(this).classed('dragging') &&
|
||||
// don't display drag until dragging beyond a distance threshold
|
||||
Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)) <= 5) return;
|
||||
|
||||
d3_select(this)
|
||||
.classed('dragging', true);
|
||||
|
||||
targetIndex = null;
|
||||
var targetIndexOffsetTop = null;
|
||||
var draggedTagWidth = d3_select(this).node().offsetWidth;
|
||||
|
||||
if (field.id === 'destination_oneway') { // meaning tags are full width
|
||||
container.selectAll('.chip')
|
||||
.style('transform', function(d2, index2) {
|
||||
var node = d3_select(this).node();
|
||||
|
||||
if (index === index2) {
|
||||
return 'translate(' + x + 'px, ' + y + 'px)';
|
||||
// move the dragged tag up the order
|
||||
} else if (index2 > index && d3_event.y > node.offsetTop) {
|
||||
if (targetIndex === null || index2 > targetIndex) {
|
||||
targetIndex = index2;
|
||||
}
|
||||
return 'translateY(-100%)';
|
||||
// move the dragged tag down the order
|
||||
} else if (index2 < index && d3_event.y < node.offsetTop + node.offsetHeight) {
|
||||
if (targetIndex === null || index2 < targetIndex) {
|
||||
targetIndex = index2;
|
||||
}
|
||||
return 'translateY(100%)';
|
||||
}
|
||||
return null;
|
||||
});
|
||||
} else {
|
||||
container.selectAll('.chip')
|
||||
.each(function(d2, index2) {
|
||||
var node = d3_select(this).node();
|
||||
|
||||
// check the cursor is in the bounding box
|
||||
if (
|
||||
index !== index2 &&
|
||||
d3_event.x < node.offsetLeft + (node.offsetWidth / 2) &&
|
||||
d3_event.x > node.offsetLeft - (node.offsetWidth / 2) &&
|
||||
d3_event.y < node.offsetTop + node.offsetHeight &&
|
||||
d3_event.y > node.offsetTop
|
||||
) {
|
||||
targetIndex = index2;
|
||||
targetIndexOffsetTop = node.offsetTop;
|
||||
}
|
||||
})
|
||||
.style('transform', function(d2, index2) {
|
||||
var node = d3_select(this).node();
|
||||
|
||||
if (index === index2) {
|
||||
return 'translate(' + x + 'px, ' + y + 'px)';
|
||||
}
|
||||
|
||||
// only translate tags in the same row
|
||||
if (node.offsetTop === targetIndexOffsetTop) {
|
||||
if (index2 < index && index2 >= targetIndex) {
|
||||
return 'translateX(' + draggedTagWidth + 'px)';
|
||||
} else if (index2 > index && index2 <= targetIndex) {
|
||||
return 'translateX(-' + draggedTagWidth + 'px)';
|
||||
}
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
})
|
||||
.on('end', function(d, index) {
|
||||
if (!d3_select(this).classed('dragging')) {
|
||||
return;
|
||||
}
|
||||
|
||||
d3_select(this)
|
||||
.classed('dragging', false);
|
||||
|
||||
container.selectAll('.chip')
|
||||
.style('transform', null);
|
||||
|
||||
if (typeof targetIndex === 'number') {
|
||||
var element = _multiData[index];
|
||||
_multiData.splice(index, 1);
|
||||
_multiData.splice(targetIndex, 0, element);
|
||||
|
||||
var t = {};
|
||||
|
||||
if (_multiData.length) {
|
||||
t[field.key] = _multiData.map(function(element) {
|
||||
return element.key;
|
||||
}).join(';');
|
||||
} else {
|
||||
t[field.key] = undefined;
|
||||
}
|
||||
|
||||
dispatch.call('change', this, t);
|
||||
}
|
||||
dragOrigin = undefined;
|
||||
targetIndex = undefined;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
combo.focus = function() {
|
||||
input.node().focus();
|
||||
|
||||
Reference in New Issue
Block a user