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
Tooltip component #27
Conversation
4e96b51
to
963d6ff
Compare
packages/ui/src/Tooltip.tsx
Outdated
}, []) | ||
|
||
return ( | ||
<div onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave} className={styles.container}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Try setting this div's position to relative
. It changes how the tooltip looks. We cannot control the parent layout and where the tooltip is going to be used. Should we try to work around it? I briefly tried strategy: fixed
, but it was buggy during scrolling.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we try adding various edge cases to our stories?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What edge cases do you have in mind?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just an idea, I'm not sure how doable is it in Storybook. Could we position a tooltip to the corners so that we make sure a tooltip opens in the visible part of the screen? This is the most common problem with it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this just re-testing of something that Popper.js has already covered?
Guys,
It is not that elegant, but it significantly simplifies the code and removes the need for extra layout. To mitigate the disabled button issue if we see it in our stories, we could not really disable the button, but just make it look disabled. |
@aigoncharov I don't mind using a render props as a solution. As long as it simplifies the layout I'm in.
But I don't like this, it seems like we would start bending the rules set by standard. I would rather wrap disabled buttons and add a comment. |
963d6ff
to
4ac1177
Compare
Actually this was my first implementation of this Tooltip, but then I though you won't like this approach. I'm all for it! ❤️ Or maybe we can support both cases? |
5bd532e
to
0c28756
Compare
setupTests.base.ts
Outdated
@@ -10,11 +10,13 @@ beforeEach(() => { | |||
jest.spyOn(console, 'error').mockImplementation((...args) => { | |||
isConsoleErrorOrWarning = true | |||
originalError(...args) | |||
console.log('ERROR', ...args) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need it? We already do console.error and console.warn via originalError and originalWarn?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, this shouldn't be there, good catch!
packages/ui/src/Tooltip.module.scss
Outdated
.wrapper { | ||
max-width: c.$tooltipMaxWidth; | ||
word-wrap: break-word; | ||
.tooltip-sr { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For consistency with other stylesheets
.tooltip-sr { | |
.tooltipSr { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated manually 👍
packages/ui/src/Tooltip.module.scss
Outdated
background: c.$colorNeutralLighter; | ||
border: c.$borderWidth solid c.$colorNeutralLight; | ||
border-radius: c.$borderRadius; | ||
font-size: inherit; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you think we need to inherit the font-size? I figured it would be the same for all tooltips
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, I don't know what I was thinking 🤷♂️ Removed 👍
packages/ui/src/Help.tsx
Outdated
className={cn(styles.container, className, { | ||
[styles.padding]: padding === 'default', | ||
})} | ||
aria-describedby={tooltipId} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Should we move it to the Icon
? I feel like we are describing the icon actually
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I'm not sure, but probably it makes more sense on icon. Updated 👍
) | ||
|
||
Button.displayName = 'Button' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need this one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ESLint requires explicit displayName
when using forwardRef
.
packages/ui/src/Button.tsx
Outdated
@@ -44,10 +46,11 @@ export type ButtonAccessibleIconRightProps = | |||
} | |||
|
|||
export type ButtonDisabledProps = | |||
| ({ disabledTooltip: string } & Required<Pick<ButtonHTMLAttributes<HTMLButtonElement>, 'disabled'>>) | |||
| ({ disabledTooltip: string; disabledTooltipId: string } & Required<Pick<ButtonHTMLAttributes<HTMLButtonElement>, 'disabled'>>) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need to pass it? Couldn't we always generate it internally?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can, removed 👍
[styles.secondary]: kind === 'secondary', | ||
[styles.transparent]: kind === 'transparent', | ||
})} | ||
disabled={disabled} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we add aria-describedby
here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, good catch, added 👍
helperText: 'A long time ago in a galaxy far, far away....', | ||
className: styles.helperText, | ||
// This has to be wrapper in act() - you can find an explanation in Tooltip test file. | ||
await act(async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it still have to be wrapped in act? I thought mountAndCheckA11Y
now does that automatically
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does not, it's just a leftover when mountAndCheckA11Y
didn't do it automatically. Removed 👍
packages/ui/src/Tooltip.module.scss
Outdated
|
||
&::after { | ||
border-top: c.$tooltipArrowSize solid c.$colorNeutralLighter; | ||
transform: translateY(-2px); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
transform: translateY(-2px); | |
transform: translateY(-(c.$tooltipArrowSize / 3)); |
packages/ui/src/Tooltip.module.scss
Outdated
|
||
&::after { | ||
border-right: c.$tooltipArrowSize solid c.$colorNeutralLighter; | ||
transform: translateX(-4px); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
transform: translateX(-4px); | |
transform: translateX(-(c.$tooltipArrowSize / 3 * 2)); |
packages/ui/src/Tooltip.module.scss
Outdated
|
||
&::after { | ||
border-bottom: c.$tooltipArrowSize solid c.$colorNeutralLighter; | ||
transform: translateY(-4px); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
transform: translateY(-4px); | |
transform: translateY(-(c.$tooltipArrowSize / 3 * 2)); |
packages/ui/src/Tooltip.module.scss
Outdated
|
||
&::after { | ||
border-left: c.$tooltipArrowSize solid c.$colorNeutralLighter; | ||
transform: translateX(-2px); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
transform: translateX(-2px); | |
transform: translateX(-(c.$tooltipArrowSize / 3)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great job! Love how it looks in the end!
} | ||
|
||
export const AutoPlacement = () => ( | ||
<div className={utilStyles.wrapperCentered}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we add more padding so the screenshots are not cropped?
expect(tooltip.exists()).toBeTruthy() | ||
expect(tooltip.props()).toEqual(expectedProps) | ||
expect(tooltip.exists(Child)).toBeTruthy() | ||
expect(wrapper.findDataTest('tooltip-overlay').hasClass('hidden')).toBeFalsy() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit
expect(wrapper.findDataTest('tooltip-overlay').hasClass('hidden')).toBeFalsy() | |
expect(wrapper.findDataTest('tooltip-overlay').hasClass(styles.hidden)).toBeFalsy() |
const Child = () => <div /> | ||
expect(wrapper.findDataTest('tooltip-reference').exists()).toBeTruthy() | ||
expect(tooltipOverlay.exists()).toBeTruthy() | ||
expect(tooltipOverlay.text()).toEqual('Tooltip content') | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
expect(tooltipOverlay.hasClass(styles.hidden)).toBeTruthy() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Great job 👏
TODO:
Closes #13.