Skip to content

feat: add delay prop to Tooltip#143

Merged
eddywashere merged 3 commits intoreactstrap:masterfrom
alisd23:tooltip-delay-prop
Sep 18, 2016
Merged

feat: add delay prop to Tooltip#143
eddywashere merged 3 commits intoreactstrap:masterfrom
alisd23:tooltip-delay-prop

Conversation

@alisd23
Copy link
Copy Markdown
Contributor

@alisd23 alisd23 commented Sep 15, 2016

Previous delay was a harcoded value of 250ms for the hide, and no delay for the
show.
New prop delay allows for either an object of form:
{ show: 100, hide: 200 } or simply a number to set these delays.
Default is { show: 0, hide: 250 }

Closes #115

Comment thread src/Tooltip.js Outdated
toggle: PropTypes.func,
children: PropTypes.node
children: PropTypes.node,
delay: PropTypes.oneOfType([PropTypes.object, PropTypes.number])
Copy link
Copy Markdown
Member

@TheSharpieOne TheSharpieOne Sep 15, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use PropTypes.shape to define the object instead of just the generic object since you are mandating that show and hide have to be a number in getDelay. It avoids the NaN check and would give developers a specific message when they don't use the right shape.

If you do not use shape and keep the NaN check, then you should probably add a test for when something other than a number is passed.

Speaking of tests, I don't really see one that tests what happens when only hide or show(not both) are in the object. The code does account for this scenario, but the tests do not ensure it works (in the future, someone may break this and without tests, no one will know)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah good idea, I'll use shape instead. And I can add a couple of tests to check that the hide or show defaults are picked up 👍

Comment thread src/Tooltip.js
onTimeout() {
if (this.props.isOpen) {
this.toggle();
getDelay(key) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of running this on every mouse over and mouse leave, why not do this when it mounts and each time props update. It will help avoid overhead.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's true that that would reduce some overhead, but I feel the tiny performance increase would not be worth complicating the code with extra lifecycle logic.

It's only a couple of direct accesses from the props and an if statement, and mouseover and mouseleave events aren't realistically going to happen very often unless the user is flailing the mouse around.

Comment thread src/Tooltip.js Outdated
clearTimeout(this._hideTimeout);
}
if (this._showTimeout) {
clearTimeout(this._showTimeout);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to clear out this.showTimeout and this.hideTimeout. You can simply set them to undefined. Without clearing them out, they will still be truthy and thus, every click after the have been set will trigger the clearTimeout, even if the timeout has already been cleared.

Copy link
Copy Markdown
Member

@TheSharpieOne TheSharpieOne Sep 15, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If fact, everywhere you use clearTimeout you will have this problem. It needs to clear the timeout and unset the var that contains the timeout id (this._showTimeout and this.hideTimeout).
Also, when the timeout triggers the function (show/hide) they need to clear the var containing their respective timeout id (this._showTimeout and this.hideTimeout respectfully).
It would probably be useful to have a helper method to do this. like clearShowTimeout and clearHideTimeout since this code is already duplicated in a few places.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that's true, it would run clearTimeout unnecessarily. That must have already been an issue before this PR though, because there was no unsetting of the timeout property either. But I may as well include that change in this PR just to tidy it up.

@alisd23 alisd23 force-pushed the tooltip-delay-prop branch 2 times, most recently from ddc1164 to dd9fd68 Compare September 16, 2016 12:46
@TheSharpieOne
Copy link
Copy Markdown
Member

When delay={{ show: 200 }}, hide would be undefined from getDelay. This is probably not wanted.
Testing this is the test I was previously talking about.

@alisd23
Copy link
Copy Markdown
Contributor Author

alisd23 commented Sep 16, 2016

Well now the propType for delay is shape({ show: number, hide: number }), there will be a warning if the user doesn't supply both. Is that not enough? I think you were right before, it's better to tell the dev their input is wrong than hide it and choose a value for them.

@TheSharpieOne
Copy link
Copy Markdown
Member

TheSharpieOne commented Sep 16, 2016

I think the shape will ensure that there are no extra properties/the properties are of the type defined, but it will not ensure that the properties are there. You have to add isRequired to ensure they are there. Something like http://stackoverflow.com/a/26924696/1873485

Edit: Sorry, I didn't mean to indicate that this should be done here, but it illustrate the difference between defining the shape and mandating the shape by showing how to require the props.

Previous delay was harcoded value of 250ms for the 'hide', and 0 for the
'show'.
New prop 'delay' allows for either an object of form: { show: 100, hide:
200 } or simply a number to set these delays.
Default is { show: 0, hide: 250 }

Closes reactstrap#115
@alisd23
Copy link
Copy Markdown
Contributor Author

alisd23 commented Sep 17, 2016

@TheSharpieOne Ok I think this is ready

@eddywashere
Copy link
Copy Markdown
Member

If { show: 0, hide: 250 } is the default, I would assume setting {hide: 0} would result in: { show: 0, hide: 0 }. It doesn't need to be part of this pr since adding it wouldn't introduce a breaking change.

Comment thread test/Tooltip.spec.js
expect(isOpen).toBe(false);
});
});

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this comment mentions adding a test here for partial delay object. It's fine to add a test case that expects an error, and then fix in another pr or grab the value from the default object which I'd like to eventually be the way this works.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep OK fair enough, it should be a quick fix so I'll just get it in this PR.

@eddywashere
Copy link
Copy Markdown
Member

thanks for working through this @alisd23 & @TheSharpieOne

Comment thread docs/lib/Components/TooltipsPage.js Outdated
tether: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
// optionally overide tether config http://tether.io/#options
delay: PropTypes.oneOfType([
PropTypes.shape({ show: PropTypes.number.isRequired, hide: PropTypes.number.isRequired }),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tiny thing. Docs still showing it was required.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Damn good catch

Copy link
Copy Markdown
Member

@TheSharpieOne TheSharpieOne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Copy Markdown
Member

@eddywashere eddywashere left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@eddywashere eddywashere merged commit b18fb74 into reactstrap:master Sep 18, 2016
@eddywashere eddywashere mentioned this pull request Sep 28, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants