Skip to content

Conversation

@fhqvst
Copy link
Contributor

@fhqvst fhqvst commented Dec 15, 2025

Summary

In this PR we add a simple tooltip to the price chart.

Rationale

How has this been tested?

  • Current tests cover my changes
  • Added new tests
  • Manually tested the code

@linear
Copy link

linear bot commented Dec 15, 2025

@fhqvst fhqvst self-assigned this Dec 15, 2025
@vercel
Copy link

vercel bot commented Dec 15, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
component-library Ready Ready Preview, Comment Dec 17, 2025 2:36pm
insights Ready Ready Preview, Comment Dec 17, 2025 2:36pm
5 Skipped Deployments
Project Deployment Review Updated (UTC)
api-reference Skipped Skipped Dec 17, 2025 2:36pm
developer-hub Skipped Skipped Dec 17, 2025 2:36pm
entropy-explorer Skipped Skipped Dec 17, 2025 2:36pm
proposals Skipped Skipped Dec 17, 2025 2:36pm
staking Skipped Skipped Dec 17, 2025 2:36pm

@fhqvst fhqvst force-pushed the fhqvst/ui-379-chart-add-tooltip-hover-card branch from 6c9bbf4 to f01ba24 Compare December 16, 2025 14:28
@vercel vercel bot temporarily deployed to Preview – developer-hub December 16, 2025 14:28 Inactive
@vercel vercel bot temporarily deployed to Preview – staking December 16, 2025 14:28 Inactive
@vercel vercel bot temporarily deployed to Preview – api-reference December 16, 2025 14:28 Inactive
@vercel vercel bot temporarily deployed to Preview – entropy-explorer December 16, 2025 14:28 Inactive
@vercel vercel bot temporarily deployed to Preview – proposals December 16, 2025 14:28 Inactive
const priceValue = priceData.value;
const date = new Date(Number(param.time) * 1000);
const formattedDate = dateFormatter.format(date);
const formattedPrice = priceFormatter.format(priceValue);
Copy link
Contributor

Choose a reason for hiding this comment

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

okay, I see that it might not be possible to use the React Aria component, since we're tying into the Trading View widget's events.

we may be able to still leverage the useTooltip() hook, though, to ensure proper a11y is maintained for it, though 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The price chart itself is a canvas, so I'm not sure what we can actually do here when it comes to a11y. The tooltip kinda assumes the user is able to interact with a price line within the canvas by using their mouse. The tooltip contains no interactive elements.

If anything we should update the aria-label of the <canvas> itself, but yeah...

Copy link
Collaborator

@cprussin cprussin left a comment

Choose a reason for hiding this comment

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

Looking great but let's stick to react & react-aria Tooltip if possible.

Even if react-aria isn't possible, using react to render the tooltip and just having the callback set state that controls the visibility of it should be completely doable without the awkward manual html string interpolation and dropping to manual DOM building.

Comment on lines 457 to 474
tooltip.innerHTML = `
<table class="${styles.tooltipTable ?? ""}">
<tbody>
<tr>
<td colspan="2">${formattedDate}</td>
</tr>
<tr>
<tr>
<td>Price</td>
<td>${formattedPrice}</td>
</tr>
<tr>
<td>Confidence</td>
<td>${confidenceText}</td>
</tr>
</tbody>
</table>
`;
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm pretty sure you can do this with react & react-aria by using a react-aria Tooltip component, and just use this callback to set state that controls the position & visibility of the tooltip. That would clean up the code considerably and remove a lot of the awkward manual html building, plus you'd get all the accessibility niceness of react-aria.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

so we're in a bit of a special case since the chart contents live within an (inaccessible) canvas element.

looking at https://react-aria.adobe.com/Tooltip i actually don't see that they add any specific aria- tags to the tooltip element itself. instead i'd guess most of what they do is add focus/hover handlers to the trigger element, but again, since our trigger element lives within the canvas (an discrete point in the chart) this becomes useless to us.

formattedConfidence = ${priceFormatter.format(confidenceHighData.value - priceValue)}`;
}

const hoverCardRect = hoverCard.getBoundingClientRect();
Copy link
Contributor

Choose a reason for hiding this comment

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

if you can, I would recommend setting up resize observers for the hoverCard and chartElem. calling getBoundingClientRect() can cause full page reflows, which, given how often this event might occur (while the user is moving the mouse), could be computationally expensive and could impact performance on lower-end hardware.

we could use resize observers for each of these elems and do setState() for the required rect values instead to avoid 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.

yeah i like the ResizeObserver idea, i'll have a look

Copy link
Contributor Author

@fhqvst fhqvst Dec 17, 2025

Choose a reason for hiding this comment

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

i'm realizing this makes the code quite a bit more complex, since we now need to store:

  • size of hover card
  • size of container
  • x/y position of hovered point

...and then recalculate the position when any of these change.

since the performance benefit is probably negligible i think a much simpler approach is to just hard-code the height/width of the hover card.

the size of the container we can get from chartData.chart.options().width since we already have a resize observer that sets that property, and so we can avoid calling getBoundingClientRect() completely

Copy link
Contributor

@benduran benduran left a comment

Choose a reason for hiding this comment

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

Left some comments. Please take a look. Otherwise, I like the cleanliness after the most recent pass! Approved to unblock

LGTM

@fhqvst fhqvst force-pushed the fhqvst/ui-379-chart-add-tooltip-hover-card branch from c9b42b1 to b0e1c1c Compare December 17, 2025 14:34
@vercel vercel bot temporarily deployed to Preview – staking December 17, 2025 14:34 Inactive
@vercel vercel bot temporarily deployed to Preview – api-reference December 17, 2025 14:34 Inactive
@vercel vercel bot temporarily deployed to Preview – entropy-explorer December 17, 2025 14:34 Inactive
@vercel vercel bot temporarily deployed to Preview – developer-hub December 17, 2025 14:34 Inactive
@vercel vercel bot temporarily deployed to Preview – proposals December 17, 2025 14:34 Inactive
Copy link
Collaborator

@cprussin cprussin left a comment

Choose a reason for hiding this comment

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

Nice, much cleaner IMO

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.

4 participants