Skip to content

[ARGG-1157][BpkTooltip]: Migrate tooltip to floating-ui #3485

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

Merged
merged 12 commits into from
Apr 10, 2025

Conversation

olliecurtis
Copy link
Member

Migrating the underlying library of theBpkTooltip to use the maintainers replacement library floating-ui, a much more lightweight library and has a lot of functionality built in that means we can remove our use of custom built react Portals!

This is one PR of a few to update components away from popperjs to floating-ui so can be used as a base!

Changes here are as follows:

  • Removed TooltipPortal, as we no longer need to use our custom React Portal implementation as this is handled via floating-ui
  • Removed the renderTarget prop as this is longer needed to apply where in the DOM the tooltip should be and is located by floating-ui relative to the target
  • Removed the portalStyle and portalClassName as these are no longer required as we aren't using a custom portal
  • Removed the popperModifiers property as these no longer have an effect on the component
  • Removed className property to prevent overriding of component
  • Converted component to Typescript and generated types
  • Removed snapshot testing as this is unreliable and not best practice
  • Added visual testing

Migration guide:

The main changes for this component is removing properties that have minor to no impact to the current functionality of the component.

So remove use of the following properties: renderTarget, portalStyle, portalClassName, popperModifiers and className.

Should the design/style not be fit for purpose please align with design to make sure they use the component as expected before getting in touch.

Remember to include the following changes:

  • Ensure the PR title includes the name of the component you are changing so it's clear in the release notes for consumers of the changes in the version e.g [KOA-123][BpkButton] Updating the colour
  • README.md (If you have created a new component)
  • Component README.md
  • Tests
  • Storybook examples created/updated
  • For breaking changes or deprecating components/properties, migration guides added to the description of the PR. If the guide has large changes, consider creating a new Markdown page inside the component's docs folder and link it here

@olliecurtis olliecurtis added the major Breaking change label Jun 3, 2024
Copy link

github-actions bot commented Jun 3, 2024

Visit https://backpack.github.io/storybook-prs/3485 to see this build running in a browser.

1 similar comment
Copy link

github-actions bot commented Jun 3, 2024

Visit https://backpack.github.io/storybook-prs/3485 to see this build running in a browser.

Copy link

github-actions bot commented Jun 3, 2024

Warnings
⚠️

Package source files (e.g. packages/package-name/src/Component.js) were updated, but snapshots weren't. Have you checked that the tests still pass?

⚠️

Package source files (e.g. packages/package-name/src/Component.tsx) were updated, but type files weren't. Have you checked that no types have changed?

Browser support

If this is a visual change, make sure you've tested it in multiple browsers.

Generated by 🚫 dangerJS against e1b9683

Copy link

github-actions bot commented Jun 3, 2024

Visit https://backpack.github.io/storybook-prs/3485 to see this build running in a browser.

1 similar comment
Copy link

github-actions bot commented Jun 4, 2024

Visit https://backpack.github.io/storybook-prs/3485 to see this build running in a browser.

@olliecurtis olliecurtis force-pushed the ARGG-1157-tooltip-to-floating-ui branch from dbb5c17 to 35587fb Compare June 4, 2024 09:15
Copy link

github-actions bot commented Jun 4, 2024

Visit https://backpack.github.io/storybook-prs/3485 to see this build running in a browser.

@olliecurtis olliecurtis force-pushed the ARGG-1157-tooltip-to-floating-ui branch from 35587fb to 1b0b280 Compare June 4, 2024 12:53
Copy link

github-actions bot commented Jun 4, 2024

Visit https://backpack.github.io/storybook-prs/3485 to see this build running in a browser.

@olliecurtis olliecurtis force-pushed the ARGG-1157-tooltip-to-floating-ui branch from 1b0b280 to 6ec9e40 Compare June 4, 2024 14:36
Copy link

github-actions bot commented Jun 4, 2024

Visit https://backpack.github.io/storybook-prs/3485 to see this build running in a browser.

3 similar comments
Copy link

github-actions bot commented Jun 4, 2024

Visit https://backpack.github.io/storybook-prs/3485 to see this build running in a browser.

Copy link

Visit https://backpack.github.io/storybook-prs/3485 to see this build running in a browser.

Copy link

Visit https://backpack.github.io/storybook-prs/3485 to see this build running in a browser.

*/
ariaLabel: string;
/**
* "target" should be a DOM element with a "ref" attached to it.
Copy link
Contributor

Choose a reason for hiding this comment

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

is that still the case?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes this is still the case, we will still want people to pass through a ReactElement and not a function like document.getElementById which is what the popover did, but the tooltip was never built to support that only

<div>
   My target
</div>

Copy link
Contributor

Choose a reason for hiding this comment

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

I mean the ref part with a "ref" attached to it. . I see we're using floating ui to set the ref so I don't think the consumer has to? https://github.com/Skyscanner/backpack/pull/3485/files#diff-2702cb346943a8761bb30c82e1a61efeae40297ed8cee8028da4376b719dc73cR132-R138

Also interesting that you can clone an element and attach a ref to it 😮 I think that's new-ish, I think a few years ago it was not possible

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah gotcha! Let me do a test with removing that target ref and see what magic happens!

Also interesting that you can clone an element and attach a ref to it 😮 I think that's new-ish, I think a few years ago it was not possible

Interesting didn't realise it was a newer feature! I guess it is just a property to a DOM element so is easy to add this prop as any other?

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah gotcha! Let me do a test with removing that target ref and see what magic happens!

Cool, have you checked that?

Interesting didn't realise it was a newer feature! I guess it is just a property to a DOM element so is easy to add this prop as any other?

Yeah, I remember it wasn't possible before, but not sure why 🤔

Copy link
Member Author

Choose a reason for hiding this comment

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

Had a check and yes ref can be removed so will update the PR now

Copy link

Visit https://backpack.github.io/storybook-prs/3485 to see this build running in a browser.

2 similar comments
Copy link

Visit https://backpack.github.io/storybook-prs/3485 to see this build running in a browser.

Copy link

Visit https://backpack.github.io/storybook-prs/3485 to see this build running in a browser.

@olliecurtis olliecurtis requested a review from anambl July 15, 2024 14:45
Copy link

Visit https://backpack.github.io/storybook-prs/3485 to see this build running in a browser.

2 similar comments
Copy link

Visit https://backpack.github.io/storybook-prs/3485 to see this build running in a browser.

Copy link

github-actions bot commented Dec 4, 2024

Visit https://backpack.github.io/storybook-prs/3485 to see this build running in a browser.

@anambl
Copy link
Contributor

anambl commented Feb 10, 2025

@olliecurtis Are we still doing this, or can we close it?

@olliecurtis
Copy link
Member Author

@olliecurtis Are we still doing this, or can we close it?

Yep we still want to be doing this and its still a valid PR just needs review 😄 as popperjs is deprecated and no longer supported

c.c. @anambl

@skyscanner-backpack-bot
Copy link

Visit https://backpack.github.io/storybook-prs/3485 to see this build running in a browser.

@anambl
Copy link
Contributor

anambl commented Feb 10, 2025

@olliecurtis Are we still doing this, or can we close it?

Yep we still want to be doing this and its still a valid PR just needs review 😄 as popperjs is deprecated and no longer supported

c.c. @anambl

Awesome! There was a conversation here and a question from me - not sure if you've had a look at that? The reason I asked it is because I remember adding those changes and making the ref required, but not sure if it's still needed with the new library.

Also as we now have a release schedule in place, we won't be able to just merge as is. I think that given this PR was created before we implemented the release schedule, we have 2 options:

  • if there aren't too many usages of it, we could merge it in March directly.
  • if there are, or we aren't sure, we will need to make it backwards compatible.
    What do you think?

@olliecurtis
Copy link
Member Author

Will check out the comment and remind myself on whats going on there to respond to you!

Also as we now have a release schedule in place, we won't be able to just merge as is. I think that given this PR was created before we implemented the release schedule, we have 2 options:

  • if there aren't too many usages of it, we could merge it in March directly.
  • if there are, or we aren't sure, we will need to make it backwards compatible.

What do you think?

I can check the numbers but from my memory this should work with backwards compatibility and not require too much rework from a consumer, as this was done to manage the impact the same as the BpkPopover when we did the same migration as we didn't want to interfer with the flow but also need to migrate from this unsupported library as it introduces a security risk now popperjs isn't supported :)

@skyscanner-backpack-bot
Copy link

Visit https://backpack.github.io/storybook-prs/3485 to see this build running in a browser.

1 similar comment
@skyscanner-backpack-bot
Copy link

Visit https://backpack.github.io/storybook-prs/3485 to see this build running in a browser.

@olliecurtis olliecurtis force-pushed the ARGG-1157-tooltip-to-floating-ui branch from b93e93a to a486065 Compare April 8, 2025 08:38
@skyscanner-backpack-bot
Copy link

Visit https://backpack.github.io/storybook-prs/3485 to see this build running in a browser.

@olliecurtis
Copy link
Member Author

Also as we now have a release schedule in place, we won't be able to just merge as is. I think that given this PR was created before we implemented the release schedule, we have 2 options:

  • if there aren't too many usages of it, we could merge it in March directly.
  • if there are, or we aren't sure, we will need to make it backwards compatible.

What do you think?

@anambl I did checking on the changes in my PR and how consumers use it and the impact to this is that it still works as previous :) as the changes here are removing the BpkTooltipPortal and what I did was carry the props across to the BpkTooltip main file as they are now collapsed and still provide critical functionality

@skyscanner-backpack-bot
Copy link

Visit https://backpack.github.io/storybook-prs/3485 to see this build running in a browser.

1 similar comment
@skyscanner-backpack-bot
Copy link

Visit https://backpack.github.io/storybook-prs/3485 to see this build running in a browser.

@skyscanner-backpack-bot
Copy link

Visit https://backpack.github.io/storybook-prs/3485 to see this build running in a browser.

Copy link
Contributor

@GCpigsic GCpigsic left a comment

Choose a reason for hiding this comment

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

Work well in my local, LGTM

role: 'tooltip',
ref: refs.setReference,
...getReferenceProps(),
});
Copy link
Contributor

Choose a reason for hiding this comment

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

works well 👍
image

ref={arrowRef}
context={context}
id={ARROW_ID}
className={arrowClassNames}
Copy link
Contributor

Choose a reason for hiding this comment

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

I just thought we could use the width, height, and fill of the FloatingArrow directly so that we don't need arrowClassNames.
https://floating-ui.com/docs/floatingarrow#height
but unfortunately, in backpack-foundations, it doesn't export spacing token (sm, md,xl ...) .
So i think using arrowClassNames is ok

Copy link
Member Author

Choose a reason for hiding this comment

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

I tried using these directly but they had issues with actually styling the arrow and broke the styling of it, so this approach was chosen to ensure the arrow could match the style and colour of the box :)

@gert-janvercauteren
Copy link
Contributor

gert-janvercauteren commented Apr 9, 2025

Hi @olliecurtis late to the party :(
Can we make the tooltip content copyable? As in, you can move the mouse pointer to the tooltip content, and it will stay so you can select text.

It's one of the things reported (multiple times) on the recent Accessibility audit :D

It seems that floating UI does support this, is this simple enough to add to our implementation?
https://floating-ui.com/docs/react-examples

Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot reviewed 9 out of 12 changed files in this pull request and generated 1 comment.

Files not reviewed (3)
  • packages/bpk-component-tooltip/src/BpkTooltip.module.scss: Language not supported
  • packages/bpk-component-tooltip/src/snapshots/BpkTooltip-test.tsx.snap: Language not supported
  • packages/bpk-component-tooltip/src/snapshots/BpkTooltipPortal-test.tsx.snap: Language not supported

role,
]);

const targetWithAccessibilityProps = cloneElement(target, {
Copy link
Preview

Copilot AI Apr 9, 2025

Choose a reason for hiding this comment

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

The target element is being assigned a role of 'tooltip', but according to ARIA guidelines the tooltip container (not the target) should have role 'tooltip'. Consider removing the role from the target and instead use aria-describedby on the target to reference the tooltip content.

Copilot is powered by AI, so mistakes are possible. Review output carefully before use.

@olliecurtis
Copy link
Member Author

Hi @olliecurtis late to the party :( Can we make the tooltip content copyable? As in, you can move the mouse pointer to the tooltip content, and it will stay so you can select text.

It's one of the things reported (multiple times) on the recent Accessibility audit :D

It seems that floating UI does support this, is this simple enough to add to our implementation? https://floating-ui.com/docs/react-examples

Hey @gert-janvercauteren

I can take a look here! I guess for an interaction such as this, this is where we would advocate for using the BpkPopover instead of the tooltip if there is content inside that wishes to be copied of interacted with. :) What would be your thoughts for advocating for that in those scenarios?

If we decide to add this functionality, can we possibly defer that to a separate minor PR to add functionality so we don't block this going in during the current major cycle and its becomes a year (total time since open) before this is closed off? I can quickly spin that PR up once this one goes through so its not forgotten about and still goes in swiftly

}: TooltipProps) => {
const classNames = getClassName('bpk-tooltip', className);
}: Props) => {
const [isOpenState, setIsOpenState] = useState(isOpen);
Copy link
Contributor

@Faye-Xiao Faye-Xiao Apr 9, 2025

Choose a reason for hiding this comment

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

Not blocker:
Hi @olliecurtis, I noticed that you introduced the FloatingPortal and the isOpen property to manage its state. This made me think about the controlled mode of BpkTooltip and its related code.

In theory, BpkTooltip should not be used in situations where the parent component controls whether it is open or closed. Allowing this might lead to scenarios where the isOpen state does not change when the FloatingPortal unmounts in certain situations. Have we stated this somewhere? 🤔
I'm not quite sure if it is used in the right way by consumers. I have worked on an experimental feature named CE Budget filter which used a BpkPopover(similar implementation, we got that implementation from another squad due to a feature ownership change) and met this question. I know that's not the right way to use it. I feel like we need to highlight that to designers and engineers.

@Faye-Xiao
Copy link
Contributor

Hi @gert-janvercauteren for this comment, can we make it to the later PR? This PR is more focused on the core code migration.

@Faye-Xiao
Copy link
Contributor

Hi @gert-janvercauteren for this comment, can we make it to the later PR? This PR is more focused on the core code migration.

Made an offline chat. The functionality mentioned in Gert's comments is missing from the original component. That's not a blocker of this PR. That would be introduced in later PR.

@skyscanner-backpack-bot
Copy link

Visit https://backpack.github.io/storybook-prs/3485 to see this build running in a browser.

@Faye-Xiao Faye-Xiao merged commit 53f06f8 into main Apr 10, 2025
9 checks passed
@Faye-Xiao Faye-Xiao deleted the ARGG-1157-tooltip-to-floating-ui branch April 10, 2025 07:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
major Breaking change
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants