diff --git a/README.md b/README.md index fb646c0a..ed6afff1 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,15 @@ The tooltip will always be rendered on its parent element unless you specify the ``` +or the `targetElement` attribute: + +```hbs + + Here is some more info + +``` + + Tooltips and popovers are lazy rendered. That means the are only rendered in the DOM once the user interacts with the [target element](#targetid). Options can be set on the `` as attributes: @@ -92,7 +101,7 @@ Documentation for supported options is located [here](#options). Popovers can be created with the `` component, which is added to apps just like ``. -Popovers support the same target behavior as tooltips; popovers will render on their parent element unless a `targetId` is supplied. +Popovers support the same target behavior as tooltips; popovers will render on their parent element unless a `targetId` or `targetElement` is supplied. All the [options](#options) passed to tooltip components can be passed to popover components: @@ -138,6 +147,7 @@ Options are set as attributes on the tooltip/popover components. Current tooltip - [showOn](#showon) - [spacing](#spacing) - [targetId](#targetid) +- [targetElement](#targetelement) - [text](#text) - [tooltipClass](#tooltipclass) @@ -493,6 +503,20 @@ For example, if you want to show a tooltip over a button when the user hovers ov ``` +#### `targetElement` + +| Type | Default | +|---------|--------------------------------------| +| Element | null (parent element of the tooltip) | + +This behaves the same as the [target](#target) attribute, except is used to specify the target element itself, rather than a selector for finding the target element. If both `targetElement` and `targetId` are specified, `targetId` will take precedence. + +```hbs + + Here is some more info + +``` + #### `text` | Type | Default | diff --git a/addon/components/ember-tooltip-base.js b/addon/components/ember-tooltip-base.js index 0fe20078..7dda4589 100644 --- a/addon/components/ember-tooltip-base.js +++ b/addon/components/ember-tooltip-base.js @@ -86,6 +86,7 @@ export default Component.extend({ side: 'top', spacing: 10, targetId: null, + targetElement: null, layout, updateFor: null, popperOptions: null, @@ -162,7 +163,7 @@ export default Component.extend({ }), // eslint-disable-next-line ember/require-computed-property-dependencies - target: computed('targetId', function () { + target: computed('targetId', 'targetElement', function () { const targetId = this.get('targetId'); let target; @@ -176,7 +177,7 @@ export default Component.extend({ }); } } else { - target = this.element.parentNode; + target = this.get('targetElement') || this.element.parentNode; } return target; diff --git a/tests/integration/components/target-test.js b/tests/integration/components/target-test.js index 8237e7e2..9e063dc9 100644 --- a/tests/integration/components/target-test.js +++ b/tests/integration/components/target-test.js @@ -1,7 +1,7 @@ import { hbs } from 'ember-cli-htmlbars'; import { module, test } from 'qunit'; import { setupRenderingTest } from 'ember-qunit'; -import { render, triggerEvent, find } from '@ember/test-helpers'; +import { render, triggerEvent, find, settled } from '@ember/test-helpers'; import { findTooltip, findTooltipTarget, @@ -10,7 +10,7 @@ import { module('Integration | Component | target', function (hooks) { setupRenderingTest(hooks); - test('ember-tooltip target test', async function (assert) { + test('ember-tooltip targetId test', async function (assert) { assert.expect(4); await render(hbs` @@ -50,4 +50,56 @@ module('Integration | Component | target', function (hooks) { `The tooltip ID should match the target's aria-describedby attribute` ); }); + + test('ember-tooltip targetElement test', async function (assert) { + assert.expect(1); + + this.set('showTooltip', false); + + await render(hbs` +
+ {{#if this.showTooltip}} + {{ember-tooltip targetElement=this.targetElement}} + {{/if}} + `); + + const expectedTarget = find('#some-target'); + this.set('targetElement', expectedTarget); + + this.set('showTooltip', true); + await settled(); + + const target = findTooltipTarget(); + assert.equal( + expectedTarget, + target, + 'The element with ID equal to targetID should be the tooltip target' + ); + }); + + test('ember-tooltip targetId takes precedence over targetElement', async function (assert) { + assert.expect(1); + + this.set('showTooltip', false); + + await render(hbs` +
+
+ {{#if this.showTooltip}} + {{ember-tooltip targetId="some-target" targetElement=this.targetElement}} + {{/if}} + `); + + this.set('targetElement', find('#other-target')); + this.set('showTooltip', true); + await settled(); + + const expectedTarget = find('#some-target'); + const target = findTooltipTarget(); + assert.equal( + expectedTarget, + target, + 'The element with ID equal to targetID should be the tooltip target' + ); + }); });