Skip to content

Commit

Permalink
Add new delayOnChange option to quickly open subsequent tooltips (#63)
Browse files Browse the repository at this point in the history
* Add new `delayOnChange` option

* Fixed tests
  • Loading branch information
lepolt authored and Duncan Walker committed May 21, 2016
1 parent ee59a38 commit da2ab6a
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 3 deletions.
2 changes: 2 additions & 0 deletions addon/mixins/components/tooltips.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export default Ember.Mixin.create({
'content',
'duration',
'delay',
'delayOnChange',
'effectClass',
'event',
'hideOn',
Expand All @@ -51,6 +52,7 @@ export default Ember.Mixin.create({
tooltipShowOn: null,
tooltipSpacing: 10,
tooltipDelay: 0,
tooltipDelayOnChange: true, // tooltips should listen to the above `delay` option by default
tooltipTabIndex: 0, // A positive integer (to enable) or -1 (to disable)
tooltipTypeClass: null,
tooltipVisibility: null, // for manual-mode triggering
Expand Down
13 changes: 11 additions & 2 deletions addon/utils/render-tooltip.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default function renderTooltip(domElement, options, context) {

const $domElement = $(domElement);
const parsedOptions = parseTooltipOptions(options);
const { content, duration, event, hideOn, tabIndex, showOn, delay } = parsedOptions;
const { content, duration, event, hideOn, tabIndex, showOn, delay, delayOnChange } = parsedOptions;
const tooltipId = `tooltip-${tooltipIndex}`;

let $tooltip, tooltip;
Expand Down Expand Up @@ -55,6 +55,15 @@ export default function renderTooltip(domElement, options, context) {
run.cancel(tooltip._hideTimer);

if (shouldShow) {

let showTooltipDelay = delay;
if (!delayOnChange) {
// If the `delayOnChange` property is set to false, we don't want to delay opening this tooltip if there is
// already a tooltip visible in the DOM. Check that here and adjust the delay as needed.
let visibleTooltips = Ember.$('.tooltip').length;
showTooltipDelay = visibleTooltips ? 0 : delay;
}

tooltip._delayTimer = run.later(function() {
tooltip.show();
$tooltip.attr('aria-hidden', false);
Expand All @@ -70,7 +79,7 @@ export default function renderTooltip(domElement, options, context) {
hide the tooltop before the duration */
tooltip._hideTimer = hideTimer;
}
}, delay);
}, showTooltipDelay);
} else {
tooltip.hide();
$tooltip.attr('aria-hidden', true);
Expand Down
45 changes: 45 additions & 0 deletions tests/acceptance/tooltip-delay-open-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,48 @@ test('Setting the delay property should wait before making tooltip visible', fun
});

});

test('Setting the delayOnChange property should make tooltip visible immediately if another tooltip is open', function(assert) {
const delay = 1000;

assert.expect(4);

visit('/tooltip-delay-open');

let tooltip = 'delay-on-change-2';
let start = Date.now();

mouseOver(tooltip);
andThen(function() {
let end = Date.now();
let diff = end - start;

assert.equal(Ember.$('.tooltip').length, 1, 'The tooltip should be added to the DOM on hover with delayOnChange set to false and no other tooltips visible');
assert.ok(diff > delay, 'The tooltip should be visible after 1000ms in the default delayOnChange test');

mouseOut(tooltip);
});

andThen(function() {
tooltip = 'delay-on-change-1';

mouseOver(tooltip);
andThen(function() {
tooltip = 'delay-on-change-2';
start = Date.now();

assert.equal(Ember.$('.tooltip').length, 1, 'The first tooltip should be added to the DOM like normal');

mouseOver(tooltip);
andThen(function() {
let end = Date.now();
let diff = end - start;

assert.ok(diff < delay, 'The tooltip should be visible before 1000ms with delayOnChange set to false and another tooltip already visible');
});

});

});

});
16 changes: 16 additions & 0 deletions tests/dummy/app/snippets/tooltip-delay-open-3.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{{!-- BEGIN-SNIPPET tooltip-delay-open-3 --}}
{{#test-component
tooltipContent='This will open after 1000ms'
tooltipDelay=1000
}}
Hover over me first
{{/test-component}}

{{#test-component
tooltipContent='This will open immediately if there is already another tooltip visible, otherwise will delay 1000ms'
tooltipDelay=1000
tooltipDelayOnChange=false
}}
Hover over me second
{{/test-component}}
{{!-- END-SNIPPET --}}
22 changes: 22 additions & 0 deletions tests/dummy/app/templates/tooltip-delay-open.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,29 @@
}}
</li>

<li>
{{#test-component
data-test='delay-on-change-1'
tooltipContent='This will open after 1000ms'
tooltipDelay=1000
}}
Hover over me first
{{/test-component}}

{{#test-component
data-test='delay-on-change-2'
tooltipContent='This will open immediately if there is already another tooltip visible, otherwise will delay 1000ms'
tooltipDelay=1000
tooltipDelayOnChange=false
}}
Hover over me second
{{/test-component}}
</li>

</ul>

{{code-snippet name='tooltip-delay-open-1.hbs'}}
{{code-snippet name='tooltip-delay-open-2.hbs'}}

<div>Using `delayOnChange=false` with `delay`</div>
{{code-snippet name='tooltip-delay-open-3.hbs'}}
5 changes: 4 additions & 1 deletion tests/unit/mixins/components/tooltips-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ test('The mixin adds the public properties', function(assert) {
'content',
'duration',
'delay',
'delayOnChange',
'effectClass',
'event',
'hideOn',
Expand All @@ -35,6 +36,8 @@ test('The mixin adds the public properties', function(assert) {
tooltipAuto: true,
tooltipContent: null,
tooltipDuration: null,
tooltipDelay: 0,
tooltipDelayOnChange: true,
tooltipEffectClass: 'slide',
tooltipEvent: 'hover',
tooltipHideOn: null,
Expand All @@ -46,7 +49,7 @@ test('The mixin adds the public properties', function(assert) {
tooltipVisibility: null,
};

assert.expect(14);
assert.expect(16);

Object.keys(expectedProperties).forEach(function(expectedProperty) {
const expectedValue = expectedProperties[expectedProperty];
Expand Down

0 comments on commit da2ab6a

Please sign in to comment.