New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
EZP-27782: All tabs, from unrelated blocks, become unselected after clicking on any other tab #36
EZP-27782: All tabs, from unrelated blocks, become unselected after clicking on any other tab #36
Conversation
mixins/js/ez-tabs.js
Outdated
forEach.call(this.querySelectorAll('.' + TAB_IS_SELECTED), function (element) { | ||
element.classList.remove(TAB_IS_SELECTED); | ||
}); | ||
[].forEach.call(selectedTabs, (element) => element.classList.remove(TAB_IS_SELECTED)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
however I don't find the line here particular easy to read, one thing is the short form for functions which I'm not used to, but even Array.prototype would have been cleaner then the empty array. But thats somewhat a style preference, and if this is more the style things are done now I can perhaps get used to it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with @andrerom on [].forEach
vs. Array.prototype.forEach
, especially given this change is completely unrelated to the issue (and useless) so to keep the patch as short as possible, I would only change the first parameter of forEach.call
.
that said thanks to the web components polyfill, you can even use forEach
method directly on NodeList returned by querySelectorAll
.
(see #30 (comment))
For fat arrow vs. regular function
, we tend to use fat arrow to avoid using bind
but that's fine this way as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of searching in whole page document.
normally we don't search in the whole page but only within the custom element on which ez-tabs
mixin is applied.
So I guess to reproduce the issue you must have 2 different series of tabs in a custom element having this mixin, right ? Could you please add in the PR description a minimal markup example to reproduce the issue ?
mixins/js/ez-tabs.js
Outdated
@@ -1,5 +1,5 @@ | |||
window.eZ = window.eZ || {}; | |||
|
|||
/* jshint esversion:6 */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that's not needed normally, see https://github.com/ezsystems/hybrid-platform-ui-core-components/blob/master/.eslintrc.json#L8
I've just notice the jshint
part, we don't use jshint here, so please remove that line.
mixins/js/ez-tabs.js
Outdated
@@ -107,23 +107,25 @@ window.eZ = window.eZ || {}; | |||
* | |||
* @param {HTMLElement} panel | |||
* @param {HTMLElement} tabsLabel | |||
* @param event {Event} click event |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for consistency please put the type first
mixins/js/ez-tabs.js
Outdated
forEach.call(this.querySelectorAll('.' + TAB_IS_SELECTED), function (element) { | ||
element.classList.remove(TAB_IS_SELECTED); | ||
}); | ||
[].forEach.call(selectedTabs, (element) => element.classList.remove(TAB_IS_SELECTED)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with @andrerom on [].forEach
vs. Array.prototype.forEach
, especially given this change is completely unrelated to the issue (and useless) so to keep the patch as short as possible, I would only change the first parameter of forEach.call
.
that said thanks to the web components polyfill, you can even use forEach
method directly on NodeList returned by querySelectorAll
.
(see #30 (comment))
For fat arrow vs. regular function
, we tend to use fat arrow to avoid using bind
but that's fine this way as well.
@dpobel updated description and corrected minor issues pointed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
besides the inline comment, you also need to write a unit test where you reproduce the issue when there are several .ez-tabs
elements.
mixins/js/ez-tabs.js
Outdated
@@ -78,7 +78,7 @@ window.eZ = window.eZ || {}; | |||
|
|||
e.preventDefault(); | |||
if ( this._dispatchTabChange(label, panel) ) { | |||
this._changeTab(panel, label); | |||
this._changeTab(panel, label, e); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of passing the event object until _unselectTab
, I think you should compute the tab container here to have:
const tabContainer = e.target.closest('.ez-tabs');
this._changeTab(tabContainer, panel, label);
…licking on any other tab
@dpobel I've added updated tests. Any comments are welcome. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
weird TravisCI did not run on this PR, I've changed a settings let's see if it sees the PR when you'll push changes (also rebase on master so that you get a small fix to npm run lint
5b545c3).
But in any case please run the tests locally (https://github.com/ezsystems/hybrid-platform-ui-core-components/blob/master/README.md#developers-tasks)
@@ -107,21 +109,24 @@ window.eZ = window.eZ || {}; | |||
* | |||
* @param {HTMLElement} panel | |||
* @param {HTMLElement} tabsLabel | |||
* @param {HTMLElement} tabs container DOM node |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the parameter name is tabsContainer
not tabs
|
||
tabsLabel.classList.add(TAB_IS_SELECTED); | ||
panel.classList.add(TAB_IS_SELECTED); | ||
} | ||
|
||
/** | ||
* Unselects currently selected tabs | ||
* | ||
* @param {HTMLElement} tabs container DOM node |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same on doc parameter name
</template> | ||
</test-fixture> | ||
|
||
<test-fixture id="AdvancedTestFixture"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's not really an advanced test but a regression test for the case where there are several tabs series, so I would call it SeveralTabsSeriesTestFixture
</div> | ||
</div> | ||
</ez-test-tabs> | ||
<ez-test-tabs> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
with this markup, you don't test the bug you are fixing which is happening is you have several tabs series in the custom element where Tabs mixin is applied. So you should have only one ez-test-tabs
element with at least 2 tabs markup.
bubbles: true, | ||
})); | ||
} | ||
element = fixture('BasicTestFixture'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this needs to be inside beforeEach
so that each test starts with a fresh element/markup (see https://www.polymer-project.org/2.0/docs/tools/tests#test-fixtures)
const CLASS_TAB_SELECTED = 'is-tab-selected'; | ||
const SELECTOR_TAB_SELECTED = '.is-tab-selected'; | ||
|
||
element = fixture('AdvancedTestFixture'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should be in beforeEach
as well
@@ -105,4 +103,38 @@ describe('ez-tabs', function () { | |||
}); | |||
}); | |||
}); | |||
|
|||
describe('switch tab in a correct container', function () { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
describe('several tabs series', function () {
panel = element.querySelector(link.getAttribute('href')); | ||
}); | ||
|
||
it('should change tab in a correct tabs container', function () { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually here we want to test 2 things so I think you should write 2 tests:
should change tab
which should be the same as'switch tab' / 'should change tab'
(so you should extract the code of it in a function for instance calledtestChangeTab
and call it in both cases)should leave others tabs intact
which will also calltestChangeTab
but in addition check that the other tabs have not changed (for that the easiest is probably to compare.innerHTML
of the other tab container before and after the tab change)
<div class="ez-tabs-panel" id="tab2"> | ||
Some other content | ||
</div> | ||
<ez-asynchronous-block id="async-tab"></ez-asynchronous-block> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since mixins/js/ez-tabs.js
is also included in this file, you need to add the SeveralTabsSeriesTestFixture
here as well (but make sure to use ez-content-view
not ez-test-tabs
)
<div class="ez-tabs-panel" id="tab2"> | ||
Some other content | ||
</div> | ||
<ez-asynchronous-block id="async-tab"></ez-asynchronous-block> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and same here, mixins/js/ez-tabs.js
is included in this file as well so a SeveralTabsSeriesTestFixture
is needed
https://jira.ez.no/browse/EZP-27782
Now, the script is looking for the closest tabs container that contains selected tabs instead of searching in whole page document.
The HTML markup where an issue had been spotted: