Skip to content

Commit

Permalink
Merge pull request #1718 from kaliber5/fix-popover-actions
Browse files Browse the repository at this point in the history
Call onShow(n)/onHide/onHidden when controlling tooltips and popovers programmatically
  • Loading branch information
simonihmig committed Jan 8, 2022
2 parents 75ec792 + fc58958 commit b7eb9c7
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 21 deletions.
10 changes: 5 additions & 5 deletions addon/components/bs-contextual-help.js
Original file line number Diff line number Diff line change
Expand Up @@ -670,17 +670,17 @@ export default class ContextualHelp extends Component {
this.triggerTargetElement = this.getTriggerTargetElement();
this.addListeners();
if (this.visible) {
next(this, this.show, true);
next(this, this.show);
}
});
}

@action
showOrHide(visible) {
if (visible) {
this.show();
showOrHide() {
if (this.args.visible) {
next(this, this.show);
} else {
this.hide();
next(this, this.hide);
}
}

Expand Down
1 change: 1 addition & 0 deletions addon/components/bs-popover.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@
{{/let}}
{{/if}}
{{did-insert this.setup}}
{{did-update this.showOrHide @visible}}
3 changes: 2 additions & 1 deletion addon/components/bs-tooltip.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,5 @@
</Element>
{{/let}}
{{/if}}
{{did-insert this.setup}}
{{did-insert this.setup}}
{{did-update this.showOrHide @visible}}
88 changes: 88 additions & 0 deletions tests/integration/components/bs-popover-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,94 @@ module('Integration | Component | bs-popover', function (hooks) {
assert.dom('#wrapper .popover').exists({ count: 1 }, 'Popover exists in place.');
});

test('it calls onShow/onShown actions when showing popover by event [fade=false]', async function (assert) {
let showAction = sinon.spy();
this.set('show', showAction);
let shownAction = sinon.spy();
this.set('shown', shownAction);
await render(
hbs`<div id="target"><BsPopover @title="Dummy" @fade={{false}} @onShow={{this.show}} @onShown={{this.shown}} /></div>`
);
await click('#target');
assert.ok(showAction.calledOnce, 'show action has been called');
assert.ok(shownAction.calledOnce, 'shown action has been called');
});

test('it calls onShow/onShown actions when showing popover programmatically [fade=false]', async function (assert) {
let showAction = sinon.spy();
this.set('show', showAction);
let shownAction = sinon.spy();
this.set('shown', shownAction);
this.set('visible', false);
await render(
hbs`<div id="target"><BsPopover @title="Dummy" @visible={{this.visible}} @fade={{false}} @onShow={{this.show}} @onShown={{this.shown}} /></div>`
);
this.set('visible', true);
await settled();
assert.ok(showAction.calledOnce, 'show action has been called');
assert.ok(shownAction.calledOnce, 'shown action has been called');
});

test('it aborts showing if onShow action returns false', async function (assert) {
let showAction = sinon.stub();
showAction.returns(false);
this.set('show', showAction);
let shownAction = sinon.spy();
this.set('shown', shownAction);
await render(
hbs`<div id="target"><BsPopover @title="Dummy" @fade={{false}} @onShow={{this.show}} @onShown={{this.shown}} /></div>`
);
await click('#target');
assert.ok(showAction.calledOnce, 'show action has been called');
assert.ok(shownAction.notCalled, 'show action has not been called');
assert.dom('.popover').doesNotExist('popover is not visible');
});

test('it calls onHide/onHidden actions when hiding popover by event [fade=false]', async function (assert) {
let hideAction = sinon.spy();
this.set('hide', hideAction);
let hiddenAction = sinon.spy();
this.set('hidden', hiddenAction);
await render(
hbs`<div id="target"><BsPopover @title="Dummy" @fade={{false}} @onHide={{this.hide}} @onHidden={{this.hidden}} /></div>`
);
await click('#target');
await click('#target');
assert.ok(hideAction.calledOnce, 'hide action has been called');
assert.ok(hiddenAction.calledOnce, 'hidden action was called');
});

test('it calls onHide/onHidden actions when hiding popover programmatically [fade=false]', async function (assert) {
let hideAction = sinon.spy();
this.set('hide', hideAction);
let hiddenAction = sinon.spy();
this.set('hidden', hiddenAction);
this.set('visible', true);
await render(
hbs`<div id="target"><BsPopover @visible={{this.visible}} @title="Dummy" @fade={{false}} @onHide={{this.hide}} @onHidden={{this.hidden}} /></div>`
);
this.set('visible', false);
await settled();
assert.ok(hideAction.calledOnce, 'hide action has been called');
assert.ok(hiddenAction.calledOnce, 'hidden action was called');
});

test('it aborts hiding if onHide action returns false', async function (assert) {
let hideAction = sinon.stub();
hideAction.returns(false);
this.set('hide', hideAction);
let hiddenAction = sinon.spy();
this.set('hidden', hiddenAction);
await render(
hbs`<div id="target"><BsPopover @title="Dummy" @fade={{false}} @onHide={{this.hide}} @onHidden={{this.hidden}} /></div>`
);
await click('#target');
await click('#target');
assert.ok(hideAction.calledOnce, 'hide action has been called');
assert.ok(hiddenAction.notCalled, 'hidden action has not been called');
assert.dom('.popover').exists({ count: 1 }, 'popover is visible');
});

test('it passes accessibility checks', async function (assert) {
await render(hbs`
<button type="button">
Expand Down
60 changes: 45 additions & 15 deletions tests/integration/components/bs-tooltip-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,56 +143,86 @@ module('Integration | Component | bs-tooltip', function (hooks) {
assert.dom('.tooltip').doesNotExist('tooltip is not visible');
});

test('it calls onShow/onShown actions when showing tooltip [fade=false]', async function (assert) {
test('it calls onShow/onShown actions when showing tooltip by event [fade=false]', async function (assert) {
let showAction = sinon.spy();
this.actions.show = showAction;
this.set('show', showAction);
let shownAction = sinon.spy();
this.actions.shown = shownAction;
this.set('shown', shownAction);
await render(
hbs`<div id="target"><BsTooltip @title="Dummy" @fade={{false}} @onShow={{action "show"}} @onShown={{action "shown"}} /></div>`
hbs`<div id="target"><BsTooltip @title="Dummy" @fade={{false}} @onShow={{this.show}} @onShown={{this.shown}} /></div>`
);
await triggerEvent('#target', 'mouseenter');
assert.ok(showAction.calledOnce, 'show action has been called');
assert.ok(shownAction.calledOnce, 'show action has been called');
assert.ok(shownAction.calledOnce, 'shown action has been called');
});

test('it calls onShow/onShown actions when showing tooltip programmatically [fade=false]', async function (assert) {
let showAction = sinon.spy();
this.set('show', showAction);
let shownAction = sinon.spy();
this.set('shown', shownAction);
this.set('visible', false);
await render(
hbs`<div id="target"><BsTooltip @title="Dummy" @visible={{this.visible}} @fade={{false}} @onShow={{this.show}} @onShown={{this.shown}} /></div>`
);
this.set('visible', true);
await settled();
assert.ok(showAction.calledOnce, 'show action has been called');
assert.ok(shownAction.calledOnce, 'shown action has been called');
});

test('it aborts showing if onShow action returns false', async function (assert) {
let showAction = sinon.stub();
showAction.returns(false);
this.actions.show = showAction;
this.set('show', showAction);
let shownAction = sinon.spy();
this.actions.shown = shownAction;
this.set('shown', shownAction);
await render(
hbs`<div id="target"><BsTooltip @title="Dummy" @fade={{false}} @onShow={{action "show"}} @onShown={{action "shown"}} /></div>`
hbs`<div id="target"><BsTooltip @title="Dummy" @fade={{false}} @onShow={{this.show}} @onShown={{this.shown}} /></div>`
);
await triggerEvent('#target', 'mouseenter');
assert.ok(showAction.calledOnce, 'show action has been called');
assert.notOk(shownAction.calledOnce, 'show action has not been called');
assert.dom('.tooltip').doesNotExist('tooltip is not visible');
});

test('it calls onHide/onHidden actions when hiding tooltip [fade=false]', async function (assert) {
test('it calls onHide/onHidden actions when hiding tooltip by event [fade=false]', async function (assert) {
let hideAction = sinon.spy();
this.actions.hide = hideAction;
this.set('hide', hideAction);
let hiddenAction = sinon.spy();
this.actions.hidden = hiddenAction;
this.set('hidden', hiddenAction);
await render(
hbs`<div id="target"><BsTooltip @title="Dummy" @fade={{false}} @onHide={{action "hide"}} @onHidden={{action "hidden"}} /></div>`
hbs`<div id="target"><BsTooltip @title="Dummy" @fade={{false}} @onHide={{this.hide}} @onHidden={{this.hidden}} /></div>`
);
await triggerEvent('#target', 'mouseenter');
await triggerEvent('#target', 'mouseleave');
assert.ok(hideAction.calledOnce, 'hide action has been called');
assert.ok(hiddenAction.calledOnce, 'hidden action was called');
});

test('it calls onHide/onHidden actions when hiding tooltip programmatically [fade=false]', async function (assert) {
let hideAction = sinon.spy();
this.set('hide', hideAction);
let hiddenAction = sinon.spy();
this.set('hidden', hiddenAction);
this.set('visible', true);
await render(
hbs`<div id="target"><BsTooltip @visible={{this.visible}} @title="Dummy" @fade={{false}} @onHide={{this.hide}} @onHidden={{this.hidden}} /></div>`
);
this.set('visible', false);
await settled();
assert.ok(hideAction.calledOnce, 'hide action has been called');
assert.ok(hiddenAction.calledOnce, 'hidden action was called');
});

test('it aborts hiding if onHide action returns false', async function (assert) {
let hideAction = sinon.stub();
hideAction.returns(false);
this.actions.hide = hideAction;
this.set('hide', hideAction);
let hiddenAction = sinon.spy();
this.actions.hidden = hiddenAction;
this.set('hidden', hiddenAction);
await render(
hbs`<div id="target"><BsTooltip @title="Dummy" @fade={{false}} @onHide={{action "hide"}} @onHidden={{action "hidden"}} /></div>`
hbs`<div id="target"><BsTooltip @title="Dummy" @fade={{false}} @onHide={{this.hide}} @onHidden={{this.hidden}} /></div>`
);
await triggerEvent('#target', 'mouseenter');
await triggerEvent('#target', 'mouseleave');
Expand Down

0 comments on commit b7eb9c7

Please sign in to comment.