Skip to content

Commit 8031d3e

Browse files
committed
fix(Tooltip): fix overlapping and use tippy singletons where applicable
1 parent 4534009 commit 8031d3e

File tree

7 files changed

+183
-103
lines changed

7 files changed

+183
-103
lines changed

packages/app/src/app/pages/Sandbox/Editor/Header/Buttons/RefreshButton/UpdateFound/UpdateFound.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ const useInterval = (callback = () => {}, delay: number) => {
2323
};
2424

2525
export const UpdateFound = (props: any) => {
26-
const [isVisible, setVisibility] = useState(true);
27-
useInterval(() => setVisibility(false), isVisible ? 60000 : null);
26+
const [visible, setVisibility] = useState(true);
27+
useInterval(() => setVisibility(false), visible ? 60000 : null);
2828

2929
return (
3030
<UpdateContainer {...props}>
@@ -36,8 +36,8 @@ export const UpdateFound = (props: any) => {
3636
onClick={() => document.location.reload()}
3737
/>
3838
}
39-
isVisible={isVisible}
40-
trigger={isVisible ? 'manual' : 'mouseenter focus'}
39+
visible={visible}
40+
trigger={visible ? 'manual' : 'mouseenter focus'}
4141
arrow
4242
distance={15}
4343
>

packages/app/src/app/pages/Sandbox/Editor/Navigation/Navigation.tsx

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
import Tooltip from '@codesandbox/common/lib/components/Tooltip';
1+
import Tooltip, {
2+
SingletonTooltip,
3+
} from '@codesandbox/common/lib/components/Tooltip';
4+
import { TippyProps } from '@tippy.js/react';
5+
26
import React, { FunctionComponent } from 'react';
37
import PlusIcon from 'react-icons/lib/go/plus';
48

@@ -45,10 +49,12 @@ const IDS_TO_ICONS = {
4549
type IconProps = {
4650
item: INavigationItem;
4751
isDisabled?: boolean;
52+
singleton: TippyProps['singleton'];
4853
};
4954
const IconComponent: FunctionComponent<IconProps> = ({
5055
item: { id, name },
5156
isDisabled,
57+
singleton,
5258
}) => {
5359
const {
5460
actions: {
@@ -63,7 +69,7 @@ const IconComponent: FunctionComponent<IconProps> = ({
6369
const selected = !workspaceHidden && id === openedWorkspaceItem;
6470

6571
return (
66-
<Tooltip placement="right" content={name}>
72+
<Tooltip content={name} singleton={singleton}>
6773
<IconContainer
6874
isDisabled={isDisabled}
6975
selected={selected}
@@ -97,15 +103,26 @@ export const Navigation: FunctionComponent<Props> = ({
97103

98104
return (
99105
<Container topOffset={topOffset} bottomOffset={bottomOffset}>
100-
{shownItems.map(item => (
101-
<IconComponent key={item.id} item={item} />
102-
))}
106+
<SingletonTooltip placement="right">
107+
{singleton => (
108+
<>
109+
{shownItems.map(item => (
110+
<IconComponent key={item.id} item={item} singleton={singleton} />
111+
))}
103112

104-
{disabledItems.length > 0 && <Separator />}
113+
{disabledItems.length > 0 && <Separator />}
105114

106-
{disabledItems.map(item => (
107-
<IconComponent key={item.id} item={item} isDisabled />
108-
))}
115+
{disabledItems.map(item => (
116+
<IconComponent
117+
key={item.id}
118+
item={item}
119+
singleton={singleton}
120+
isDisabled
121+
/>
122+
))}
123+
</>
124+
)}
125+
</SingletonTooltip>
109126
</Container>
110127
);
111128
};

packages/app/src/app/pages/Sandbox/Editor/Workspace/Dependencies/VersionEntry/index.tsx

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ import ArrowDropDown from 'react-icons/lib/md/keyboard-arrow-down';
55
import ArrowDropUp from 'react-icons/lib/md/keyboard-arrow-up';
66
import algoliasearch from 'algoliasearch/lite';
77
import compareVersions from 'compare-versions';
8-
import Tooltip from '@codesandbox/common/lib/components/Tooltip';
8+
import Tooltip, {
9+
SingletonTooltip,
10+
} from '@codesandbox/common/lib/components/Tooltip';
911
import { formatVersion } from '@codesandbox/common/lib/utils/ci';
1012

1113
import { EntryContainer, IconArea, Icon } from '../../elements';
@@ -137,24 +139,39 @@ export class VersionEntry extends React.PureComponent<Props, State> {
137139

138140
{hovering && (
139141
<IconArea>
140-
<Tooltip
141-
content={open ? 'Hide sizes' : 'Show sizes'}
142-
style={{ outline: 'none' }}
143-
>
144-
<Icon onClick={this.handleOpen}>
145-
{open ? <ArrowDropUp /> : <ArrowDropDown />}
146-
</Icon>
147-
</Tooltip>
148-
<Tooltip content="Update to latest" style={{ outline: 'none' }}>
149-
<Icon onClick={this.handleRefresh}>
150-
<RefreshIcon />
151-
</Icon>
152-
</Tooltip>
153-
<Tooltip content="Remove" style={{ outline: 'none' }}>
154-
<Icon onClick={this.handleRemove}>
155-
<CrossIcon />
156-
</Icon>
157-
</Tooltip>
142+
<SingletonTooltip>
143+
{singleton => (
144+
<>
145+
<Tooltip
146+
content={open ? 'Hide sizes' : 'Show sizes'}
147+
style={{ outline: 'none' }}
148+
singleton={singleton}
149+
>
150+
<Icon onClick={this.handleOpen}>
151+
{open ? <ArrowDropUp /> : <ArrowDropDown />}
152+
</Icon>
153+
</Tooltip>
154+
<Tooltip
155+
content="Update to latest"
156+
style={{ outline: 'none' }}
157+
singleton={singleton}
158+
>
159+
<Icon onClick={this.handleRefresh}>
160+
<RefreshIcon />
161+
</Icon>
162+
</Tooltip>
163+
<Tooltip
164+
content="Remove"
165+
style={{ outline: 'none' }}
166+
singleton={singleton}
167+
>
168+
<Icon onClick={this.handleRemove}>
169+
<CrossIcon />
170+
</Icon>
171+
</Tooltip>
172+
</>
173+
)}
174+
</SingletonTooltip>
158175
</IconArea>
159176
)}
160177
</EntryContainer>

packages/app/src/app/pages/Sandbox/Editor/Workspace/Files/DirectoryEntry/Entry/EditIcons/index.js

Lines changed: 51 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ import AddDirectoryIcon from 'react-icons/lib/md/create-new-folder';
77
import UploadFileIcon from 'react-icons/lib/md/file-upload';
88
import DownloadIcon from 'react-icons/lib/md/file-download';
99

10-
import Tooltip from '@codesandbox/common/lib/components/Tooltip';
10+
import Tooltip, {
11+
SingletonTooltip,
12+
} from '@codesandbox/common/lib/components/Tooltip';
1113

1214
import { Icon } from '../../../../elements';
1315
import { Container } from './elements';
@@ -40,48 +42,54 @@ function EditIcons({
4042
<div className={className}>
4143
{(hovering || (window.__isTouch && active) || forceShow) && (
4244
<Container>
43-
{onDownload && (
44-
<Tooltip content="Export to ZIP">
45-
<Icon onClick={handleClick(onDownload)}>
46-
<DownloadIcon />
47-
</Icon>
48-
</Tooltip>
49-
)}
50-
{onUploadFile && (
51-
<Tooltip content="Upload Files">
52-
<Icon onClick={handleClick(onUploadFile)}>
53-
<UploadFileIcon />
54-
</Icon>
55-
</Tooltip>
56-
)}
57-
{onEdit && (
58-
<Tooltip content="Rename">
59-
<Icon onClick={handleClick(onEdit)}>
60-
<EditIcon />
61-
</Icon>
62-
</Tooltip>
63-
)}
64-
{onCreateFile && (
65-
<Tooltip content="New File">
66-
<Icon onClick={handleClick(onCreateFile)}>
67-
<AddFileIcon />
68-
</Icon>
69-
</Tooltip>
70-
)}
71-
{onCreateDirectory && (
72-
<Tooltip content="New Directory">
73-
<Icon onClick={handleClick(onCreateDirectory)}>
74-
<AddDirectoryIcon />
75-
</Icon>
76-
</Tooltip>
77-
)}
78-
{onDelete && (
79-
<Tooltip content="Delete">
80-
<Icon onClick={handleClick(onDelete)}>
81-
<CrossIcon />
82-
</Icon>
83-
</Tooltip>
84-
)}
45+
<SingletonTooltip>
46+
{singleton => (
47+
<>
48+
{onDownload && (
49+
<Tooltip content="Export to ZIP" singleton={singleton}>
50+
<Icon onClick={handleClick(onDownload)}>
51+
<DownloadIcon />
52+
</Icon>
53+
</Tooltip>
54+
)}
55+
{onUploadFile && (
56+
<Tooltip content="Upload Files" singleton={singleton}>
57+
<Icon onClick={handleClick(onUploadFile)}>
58+
<UploadFileIcon />
59+
</Icon>
60+
</Tooltip>
61+
)}
62+
{onEdit && (
63+
<Tooltip content="Rename" singleton={singleton}>
64+
<Icon onClick={handleClick(onEdit)}>
65+
<EditIcon />
66+
</Icon>
67+
</Tooltip>
68+
)}
69+
{onCreateFile && (
70+
<Tooltip content="New File" singleton={singleton}>
71+
<Icon onClick={handleClick(onCreateFile)}>
72+
<AddFileIcon />
73+
</Icon>
74+
</Tooltip>
75+
)}
76+
{onCreateDirectory && (
77+
<Tooltip content="New Directory" singleton={singleton}>
78+
<Icon onClick={handleClick(onCreateDirectory)}>
79+
<AddDirectoryIcon />
80+
</Icon>
81+
</Tooltip>
82+
)}
83+
{onDelete && (
84+
<Tooltip content="Delete" singleton={singleton}>
85+
<Icon onClick={handleClick(onDelete)}>
86+
<CrossIcon />
87+
</Icon>
88+
</Tooltip>
89+
)}
90+
</>
91+
)}
92+
</SingletonTooltip>
8593
</Container>
8694
)}
8795
</div>

packages/common/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
"@codesandbox/notifications": "^1.0.6",
4646
"@codesandbox/template-icons": "^1.0.1",
4747
"@sentry/browser": "^5.9.0",
48-
"@tippy.js/react": "^2.1.1",
48+
"@tippy.js/react": "^3.1.1",
4949
"babel-plugin-preval": "^3.0.1",
5050
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.2",
5151
"codesandbox-api": "^0.0.22",
Lines changed: 50 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,61 @@
11
import React from 'react';
2-
import { createGlobalStyle } from 'styled-components';
3-
import Tippy from '@tippy.js/react';
2+
import styled from 'styled-components';
3+
import Tippy, { useSingleton } from '@tippy.js/react';
4+
import { animateFill, Props } from 'tippy.js';
45
import theme from '../../theme';
56

6-
const GlobalStyle = createGlobalStyle`
7+
import 'tippy.js/dist/tippy.css';
8+
import 'tippy.js/dist/backdrop.css';
9+
import 'tippy.js/animations/shift-away.css';
10+
11+
const defaultProps: Partial<Props> = {
12+
delay: [500, 100],
13+
boundary: 'window',
14+
animateFill: true,
15+
plugins: [animateFill],
16+
};
17+
18+
const mainStyles = `
19+
background-color: rgb(21, 24, 25);
20+
721
.tippy-backdrop {
822
background-color: rgb(21, 24, 25);
923
}
24+
`;
25+
26+
const MainTippy = styled(Tippy)`
27+
${mainStyles}
28+
`;
1029

11-
.tippy-tooltip.update-theme {
12-
background-color: ${theme.green()};
13-
border-radius: 2px;
14-
padding: 0;
30+
const UpdateTippy = styled(Tippy)`
31+
background-color: ${theme.green()};
32+
border-radius: 2px;
33+
padding: 0;
1534
16-
.tippy-arrow {
17-
border-bottom-color: ${theme.green()};
18-
}
35+
.tippy-arrow {
36+
border-bottom-color: ${theme.green()};
1937
}
2038
`;
2139

22-
const Tooltip = ({ children, style = {}, content, ...props }) => (
23-
<>
24-
<GlobalStyle />
25-
<Tippy delay={[500, 0]} content={content} {...props}>
40+
export const SingletonTooltip = styled(
41+
({ children, style = {}, content, ...props }) => {
42+
const singleton = useSingleton({
43+
...defaultProps,
44+
updateDuration: 250,
45+
...props,
46+
});
47+
48+
return children(singleton);
49+
}
50+
)`
51+
${mainStyles}
52+
`;
53+
54+
const Tooltip = ({ children, style = {}, content, ...props }) => {
55+
const TippyComponent = props.theme === 'update' ? UpdateTippy : MainTippy;
56+
57+
return (
58+
<TippyComponent content={content} {...defaultProps} {...props}>
2659
<span
2760
style={{
2861
outlineColor: 'transparent',
@@ -31,8 +64,8 @@ const Tooltip = ({ children, style = {}, content, ...props }) => (
3164
>
3265
{children}
3366
</span>
34-
</Tippy>
35-
</>
36-
);
67+
</TippyComponent>
68+
);
69+
};
3770

3871
export default Tooltip;

0 commit comments

Comments
 (0)