Merge pull request #98 from hashicorp/fix-dropdown-click-inside

Fix dropdown click inside
This commit is contained in:
Susmitha Girumala authored and GitHub committed 2020-07-30 11:20:12 -04:00
commit a22ed70ae1
6 files changed
+77 -4

No files matched your search

@@ -12,13 +12,15 @@ export default Component.extend({
/**
* Closes the details element by setting its `open` attribute to `false`.
* While the details element handles open/close functionality without
* JavaScript, we include this helper action to ensure that when the user
* clicks _outside_ of the element, it still closes.
* While the details element handles open/close functionality when clicking
* directly on the summar elemenet without JavaScript, we include this helper
* action to ensure that when the user clicks _outside_ of the element,
* or _inside_ the content, it still closes.
* @param {HTMLElement} element
*/
@action
close(element) {
if (element.open) element.open = false;
if (element.parentElement.open) element.parentElement.open = false;
},
});
@@ -0,0 +1,20 @@
import { modifier } from 'ember-modifier';
/**
* Used to detect clicks occuring _inside_ the modified element.
* This is useful especially for dropdowns to toggle content visibility
* when the user clicks an item.
*/
export default modifier((element, [callback]) => {
function handleClick(event) {
if (element.contains(event.target)) {
callback(element, event);
}
}
element.addEventListener('click', handleClick, false);
return () => {
element.removeEventListener('click', handleClick, false);
};
});
@@ -22,7 +22,7 @@
</summary>
<div class="rose-dropdown-content">
<div class="rose-dropdown-content" {{on-click-inside this.close}}>
{{yield (hash
link=(component "link-to" class="rose-dropdown-link")
button=(component "rose/button" style="dropdown")
@@ -0,0 +1 @@
export { default } from 'rose/modifiers/on-click-inside';
@@ -67,4 +67,17 @@ module('Integration | Component | rose/dropdown', function (hooks) {
await click('#wrapper');
assert.notOk(find('#dropdown').open);
});
test('it is closed when inside content is clicked', async function (assert) {
await render(hbs`
<Rose::Dropdown as |dropdown|>
<dropdown.button>Button</dropdown.button>
</Rose::Dropdown>
`);
await click('summary');
assert.ok(find('.rose-dropdown').open);
await click('button');
assert.notOk(find('.rose-dropdown').open);
});
});
@@ -0,0 +1,37 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render, click } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';
module('Integration | Modifier | on-click-inside', function (hooks) {
setupRenderingTest(hooks);
test('it fires event when inside is clicked', async function (assert) {
assert.expect(2);
this.set('clickedInside', (element) => {
assert.ok(element);
assert.equal(element.id, 'inside');
});
await render(hbs`
<div id="outside"></div>
<div id="inside" {{on-click-inside this.clickedInside}}>
<div id="item" />
</div>
`);
await click('#item');
});
test('it does not fire event when outside is clicked', async function (assert) {
assert.expect(0);
this.set('clickedInside', () => {
assert.ok(true);
});
await render(hbs`
<div id="outside"></div>
<div id="inside" {{on-click-inside this.clickedInside}}>
<div id="item" />
</div>
`);
await click('#outside');
});
});