Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add useTooltip hook #631

Merged
merged 5 commits into from
Feb 24, 2020
Merged

Add useTooltip hook #631

merged 5 commits into from
Feb 24, 2020

Conversation

ptmx
Copy link
Contributor

@ptmx ptmx commented Feb 22, 2020

🚀 Enhancements

💥 Breaking Changes

  • This PR introduces useState, which requires bumping the peerDep for react to ^16.8.0-0

📝 Documentation

  • Update vx-tooltip readme to include the new useTooltip hook, and recommend a state management approach depending on use case (specifically: recommending useTooltip for functional components, or withTooltip for class components)
  • Rewrite the BarStack demo to use useTooltip instead of withTooltip, so there is an example of each approach to managing tooltip state in the gallery (BarStack for useTooltip, BarStackHorizontal for withTooltip)

🏠 Internal

  • Rewrote withTooltip in terms of useTooltip, to avoid maintaining multiple different implementations

@ptmx ptmx requested a review from williaster February 22, 2020 05:14
packages/vx-tooltip/package.json Show resolved Hide resolved
tooltipOpen,
showTooltip,
hideTooltip,
} = useTooltip();
Copy link

@ktmud ktmud Feb 22, 2020

Choose a reason for hiding this comment

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

Is it possible to create a “Tooltip” class and return a tooltip instance with the hook? const [tooltip, updateTooltip] = useTooltip() feels more consistent to how people would use other hooks. It’s also more scalable in case we want to add more API to the tooltip.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think returning an object of the same props that are passed via withTooltip makes sense.

I've seen several examples of hooks that use this pattern (e.g., react-three-fiber's useThree hook), and it would avoid a breaking change for withTooltip.

Copy link
Collaborator

@williaster williaster left a comment

Choose a reason for hiding this comment

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

This looks great to me @ptmx! 🙌 Thanks for the addition of THE FIRST HOOK, for refactoring the HOC, and for such great docs! 💯

I think refactoring the HOC to use the hook internally is the right move. The only reason I can think of not to do this is if there are significant perf differences between HOCs + hooks, but I've never looked into this.

Hopefully just the start of hooks for vx 👯

showTooltip,
}: ShowProvidedProps & WithTooltipProvidedProps<TooltipData>) => {
}: ShowProvidedProps) => {
const {
Copy link
Collaborator

Choose a reason for hiding this comment

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

thanks for updating the source file, too. working on an improvement to not need to duplicate source + this string (I've tried a few things but if you have any thoughts lmk 😄 )

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This stuck out to me as something to come back to as well. It might be doable with raw-loader or raw.macro but I didn't have time to dig into it more deeply. Now this has me curious so I'll look into it later in the week if I have a chance 🤔

Copy link
Collaborator

Choose a reason for hiding this comment

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

sounds good! Created #632 to track this, I'll update status there if I start work on it. raw.macro looks interesting, linked to how react-window does it in the issue as well 👍

tooltipOpen,
showTooltip,
hideTooltip,
} = useTooltip();
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think returning an object of the same props that are passed via withTooltip makes sense.

I've seen several examples of hooks that use this pattern (e.g., react-three-fiber's useThree hook), and it would avoid a breaking change for withTooltip.

containerProps,
);
}
return renderContainer(<BaseComponent {...props} {...tooltipProps} />, containerProps);
Copy link
Collaborator

Choose a reason for hiding this comment

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

just noting that previously we spread the WrappedComponent props after tooltipProps, so this might result in a change in behavior if a consumer did pass an overlapping prop. I'm not really sure this is a big concern, but would prevent doing things like overriding tooltipOpen 🤷‍♂ any thoughts on this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, good catch! I agree it's not super likely that any consumers are relying on that behavior now, but in the absence of a reason to change it I think it makes sense to stay consistent with the existing behavior. Will update shortly.

Copy link
Collaborator

Choose a reason for hiding this comment

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

sounds good, thanks!

type UpdateTooltipArgs<TooltipData> = UseTooltipState<TooltipData>;

export default function useTooltip<TooltipData = {}>(): UseTooltipParams<TooltipData> {
const [{ tooltipOpen, tooltipLeft, tooltipTop, tooltipData }, setTooltipState] = useState<
Copy link
Collaborator

Choose a reason for hiding this comment

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

Since they're mostly updated together, I agree that a single useState with all state is better than storing each variable separately in different hooks 👍

@williaster williaster merged commit 00e59b9 into airbnb:master Feb 24, 2020
@williaster
Copy link
Collaborator

this is now published under 0.0.195

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants