Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions draftlogs/8164_fix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Fix modebar hover and active colors for custom SVG icons with multiple paths [[#8164](https://github.com/plotly/plotly.js/pull/8164)]
12 changes: 4 additions & 8 deletions src/components/modebar/modebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -261,14 +261,10 @@ proto.updateActiveButton = function(buttonClicked) {
// (e.g. during the handling when a modebar button is clicked)
var updateButtonStyle = function(button, isActive) {
var style = fullLayout.modebar;
var childEl = button.querySelector('.icon path');
if(childEl) {
if(isActive || button.matches(':hover')) {
childEl.style.fill = style.activecolor;
} else {
childEl.style.fill = style.color;
}
}
var fill = (isActive || button.matches(':hover')) ? style.activecolor : style.color;
button.querySelectorAll('.icon path').forEach(function(childEl) {
childEl.style.fill = fill;
});
};

// Use 'data-toggle' and 'buttonClicked' to toggle buttons
Expand Down
21 changes: 9 additions & 12 deletions src/lib/dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ function deleteRelatedStyleRule(uid) {
* in which case, the active style remains even when it's no longer hovered.
* @param {string} selector selector for button elements to be styled when hovered
* @param {string} activeSelector selector used to determine if selected element is active
* @param {string} childSelector the child element on which the styling needs to be updated
* @param {string} childSelector the child elements on which the styling needs to be updated
* @param {string} activeStyle style that has to be applied when 'hovered' or 'active'
* @param {string} inactiveStyle style that has to be applied when not 'hovered' nor 'active'
*/
Expand All @@ -119,21 +119,18 @@ function setStyleOnHover(selector, activeSelector, childSelector, activeStyle, i
// style in a strict CSP-compliant manner.
el.addEventListener('mouseenter', function() {
var hoverStyle = this._hoverStyle;
var childEl = this.querySelector(childSelector);
if(childEl) {
this.querySelectorAll(childSelector).forEach(function(childEl) {
childEl.style[hoverStyle.activeStyleParts[0]] = hoverStyle.activeStyleParts[1];
}
});
});
el.addEventListener('mouseleave', function() {
var hoverStyle = this._hoverStyle;
var childEl = this.querySelector(childSelector);
if(childEl) {
if(activeSelector && this.matches(activeSelector)) {
childEl.style[hoverStyle.activeStyleParts[0]] = hoverStyle.activeStyleParts[1];
} else {
childEl.style[hoverStyle.inactiveStyleParts[0]] = hoverStyle.inactiveStyleParts[1];
}
}
var styleParts = (activeSelector && this.matches(activeSelector)) ?
hoverStyle.activeStyleParts :
hoverStyle.inactiveStyleParts;
this.querySelectorAll(childSelector).forEach(function(childEl) {
childEl.style[styleParts[0]] = styleParts[1];
});
});
el.setAttribute(eventAddedAttrName, true);
}
Expand Down
39 changes: 39 additions & 0 deletions test/jasmine/tests/modebar_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1644,6 +1644,45 @@ describe('ModeBar', function() {
.then(done, done.fail);
});

it('applies icon colors to every path of a multi-path custom svg icon', function(done) {
var icon = {
svg: '<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 1000 1000">' +
'<path d="M0,0 L500,0 L500,500 Z"/>' +
'<path d="M500,500 L1000,500 L1000,1000 Z"/>' +
'</svg>'
};

function checkAllPaths(btn, color) {
var paths = btn.querySelectorAll('.icon path');
expect(paths.length).toBe(2);
paths.forEach(function(p) {
expect(window.getComputedStyle(p).fill).toBe(color);
});
}

Plotly.newPlot(gd, [], {
modebar: {
color: colors[0],
activecolor: colors[1]
}
}, {
modeBarButtonsToAdd: [{
name: 'multi-path',
icon: icon,
click: function() {}
}]
})
.then(function() {
var btn = gd._fullLayout._modeBar.element.querySelector('[data-title="multi-path"]');
checkAllPaths(btn, colors[0]);
btn.dispatchEvent(new window.MouseEvent('mouseenter'));
checkAllPaths(btn, colors[1]);
btn.dispatchEvent(new window.MouseEvent('mouseleave'));
checkAllPaths(btn, colors[0]);
})
.then(done, done.fail);
});

it('changes background color (displayModeBar: hover)', function(done) {
Plotly.newPlot(gd, [], {modebar: { bgcolor: colors[0]}})
.then(function() {
Expand Down