Skip to content

Commit ce91424

Browse files
authored
Fix duplicate tooltips on IconButton (#661)
* Check for existing outer tooltip on IconButton * Loosen check for hasOuterTooltip
1 parent a6beb6b commit ce91424

File tree

4 files changed

+73
-3
lines changed

4 files changed

+73
-3
lines changed

packages/components/src/Button/IconButton.test.tsx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import React from 'react'
2929
import noop from 'lodash/noop'
3030
import { assertSnapshot, renderWithTheme } from '@looker/components-test-utils'
3131
import { fireEvent } from '@testing-library/react'
32+
import { Tooltip } from '../Tooltip'
3233
import { IconButton } from './IconButton'
3334

3435
test('IconButton default', () => {
@@ -113,3 +114,25 @@ test('IconButton tooltipDisabled actually disables tooltip', () => {
113114
const notTooltip = container.querySelector('p') // Get Tooltip content
114115
expect(notTooltip).toBeNull()
115116
})
117+
118+
test('IconButton built-in tooltip defers to outer tooltip', () => {
119+
const tooltip = 'Add to favorites'
120+
const label = 'Mark as my Favorite'
121+
const { getByText, getByTitle } = renderWithTheme(
122+
<Tooltip content={tooltip}>
123+
{(eventHandlers, ref) => (
124+
<IconButton
125+
tooltipDisabled
126+
label={label}
127+
icon="Favorite"
128+
{...eventHandlers}
129+
ref={ref}
130+
/>
131+
)}
132+
</Tooltip>
133+
)
134+
135+
fireEvent.mouseOver(getByTitle('Favorite'))
136+
expect(getByText(tooltip)).toBeInTheDocument()
137+
expect(getByText(label)).toHaveStyle('height: 1px')
138+
})

packages/components/src/Button/IconButton.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
2525
*/
2626

27+
import some from 'lodash/some'
28+
import isFunction from 'lodash/isFunction'
2729
import styled, { css } from 'styled-components'
2830
import {
2931
CompatibleHTMLProps,
@@ -126,13 +128,19 @@ const IconButtonComponent = forwardRef(
126128
...rest
127129
} = props
128130

131+
// any of the hover/focus handlers being present disables built-in tooltip
132+
const hasOuterTooltip = some(
133+
[propsOnFocus, propsOnBlur, propsOnMouseOver, propsOnMouseOut],
134+
isFunction
135+
)
136+
129137
const {
130138
ref,
131139
tooltip,
132140
eventHandlers: { onFocus, onBlur, onMouseOver, onMouseOut },
133141
} = useTooltip({
134142
content: label,
135-
disabled: tooltipDisabled,
143+
disabled: tooltipDisabled || hasOuterTooltip,
136144
placement: tooltipPlacement,
137145
})
138146

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
MIT License
3+
Copyright (c) 2020 Looker Data Sciences, Inc.
4+
Permission is hereby granted, free of charge, to any person obtaining a copy
5+
of this software and associated documentation files (the "Software"), to deal
6+
in the Software without restriction, including without limitation the rights
7+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
copies of the Software, and to permit persons to whom the Software is
9+
furnished to do so, subject to the following conditions:
10+
The above copyright notice and this permission notice shall be included in all
11+
copies or substantial portions of the Software.
12+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
17+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
18+
SOFTWARE.
19+
*/
20+
21+
import React from 'react'
22+
import { Box, IconButton, Tooltip } from '@looker/components'
23+
24+
export function TooltipDemo() {
25+
return (
26+
<Box p="xxxlarge">
27+
<Tooltip content="Start editing" placement="top">
28+
{(eventHandlers, ref) => (
29+
<IconButton
30+
icon="Edit"
31+
label="Edit something"
32+
{...eventHandlers}
33+
ref={ref}
34+
/>
35+
)}
36+
</Tooltip>
37+
</Box>
38+
)
39+
}

packages/playground/src/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ import { GlobalStyle } from '@looker/components'
2424
import { theme } from '@looker/design-tokens'
2525
import { ThemeProvider } from 'styled-components'
2626

27-
import { ComboboxDemo } from './Select/ComboboxDemo'
27+
import { TooltipDemo } from './Tooltip/TooltipDemo'
2828

2929
const App: React.FC = () => {
3030
return (
3131
<ThemeProvider theme={theme}>
3232
<GlobalStyle />
33-
<ComboboxDemo />
33+
<TooltipDemo />
3434
</ThemeProvider>
3535
)
3636
}

0 commit comments

Comments
 (0)