Skip to content

Conversation

@aqandrew
Copy link
Contributor

@aqandrew aqandrew commented Sep 30, 2025

closes #19974

Copy link
Contributor

@buenos-nachos buenos-nachos left a comment

Choose a reason for hiding this comment

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

Things look good so far. Just had a few comments

Comment on lines 49 to 51
expect(await screen.findByRole("tooltip")).toHaveTextContent(
/Latency not available/i,
);
Copy link
Contributor

Choose a reason for hiding this comment

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

This is partly personal taste, but I just want to make sure you know that findByRole basically functions as a form of assertion by itself, because if the selector fails to find the element in some period of time, the test will fail

But I feel like here, this has a problem of causing flakes in the future, if we start needing to add more tooltip content. The findByRole call will find the first tooltip it can, and then we assert that it has specific content. So if a new tooltip gets introduced, and it happens to be earlier in the DOM tree, this test will start breaking

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Didn't know that about findByRole, thank you. I could've sworn that the Radix tooltip's DOM structure made the original assertion fail, but I just reverted it back and it seems to be working again.

const [selectedPresetIndex, setSelectedPresetIndex] = useState(0);
// Build options and keep default label/value in sync
useEffect(() => {
useEffectEvent(() => {
Copy link
Contributor

@buenos-nachos buenos-nachos Oct 15, 2025

Choose a reason for hiding this comment

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

I was a bit rushed, so I didn't go through the full file to see what might be causing some of the infinite renders, but basically, with useEffectEvent, you want to do two things:

  1. Identify the reactive dependencies – the things that should be treated as synchronization cues between React and an external system. These should stay out of the useEffectEvent callback, and should still be included in the useEffect dependency array
  2. Identify the "incidental" dependencies – the things that you need to perform all necessary calculations, but that shouldn't be treated as synchronization cues themselves. These should all go in the useEffectEvent callback

Copy link
Contributor

@buenos-nachos buenos-nachos Oct 15, 2025

Choose a reason for hiding this comment

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

Until we upgrade to React 19.2, we should include the effect event callback in the useEffect dependency array for correctness, but the value will never trigger re-renders by itself. But once we upgrade, we should be able to remove useEffectEvent from all dependency arrays (assuming Biome updates their rules like ESLint did)

open = false,
...contentProps
}) => {
const [isOpen, setIsOpen] = useState(open);
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it's fine to have state here, but the current implementation will cause bugs. If the open prop ever changes during re-renders, then we won't ever acknowledge it, because we'll be driving everything via the isOpen state instead

I think this will work

const MiniTooltip: FC<MiniTooltipProps> = ({
  // No default assignment
	open,
  // Also destructure onOpenChange, even if it's not defined
  onOpenChange,
	...contentProps
}) => {
	const [isOpen, setIsOpen] = useState(false);
  const activeIsOpen = open ?? isOpen;

  // Sync state change to both so that if the component ever flips from
  // controlled to uncontrolled, the other piece of state won't be lagging behind
  const handleOpenChange = (newOpen: boolean) => {
    setIsOpen(newOpen);
    onOpenChange?.(newOpen);
  };

@github-actions github-actions bot added the stale This issue is like stale bread. label Oct 24, 2025
@github-actions github-actions bot closed this Oct 27, 2025
aqandrew added a commit that referenced this pull request Nov 25, 2025
…20849)

for #19974 

Redo of #20027, this time splitting it into multiple PRs + using our
existing `Tooltip` component instead of creating a new component (see
below). This PR covers the most basic usage of the MUI Tooltip, i.e.,
the tooltip content is a string literal.

~~Adds a global `TooltipProvider` to `AppProviders` and our Storybook
decorators, so that we don't have to render a `TooltipProvider` for
every tooltip instance. Removing redundant `TooltipProvider`s will be
another separate PR~~ <- this was done by #20869
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stale This issue is like stale bread.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

replace MUI tooltip component with new Tooltip

3 participants