on master help sign in
ui: refactor button to show tooltip on hover
491156btomholford
src/components/Buttons.js+2−7
@@ -3,7 +3,6 @@ import { Button } from 'indigo-react';
3import { Icon } from '@tlon/indigo-react';
3import { Icon } from '@tlon/indigo-react';
4
4
5import { blinkIf } from './Blinky';
5import { blinkIf } from './Blinky';
6−import WithTooltip from './WithTooltip';
7
6
8// NOTE: the -> is correct because inter recognizes the pair
7// NOTE: the -> is correct because inter recognizes the pair
9export const ForwardButton = ({ loading, ...props }) => (
8export const ForwardButton = ({ loading, ...props }) => (
@@ -26,13 +25,9 @@ export const OfflineButton = props => (
26 </OutButton>
25 </OutButton>
27);
26);
28
27
29−export const CopyButton = ({ didCopy = false, ...props }) => (
28+export const CopyButton = props => (
30 <Button
29 <Button
31− accessory={
32− <WithTooltip content={didCopy ? 'Copied!' : 'Copy'}>
33− <Icon icon="Copy" size="18px" color={'black'} />
30+ accessory={<Icon icon="Copy" size="18px" color={'black'} />}
34− </WithTooltip>
35− }
36 {...props}
31 {...props}
37 />
32 />
38);
33);
src/components/CopyButtonWide.tsx+9−8
@@ -1,17 +1,18 @@
1import React from 'react';
1import React from 'react';
2import { CopyButton as BaseCopyButton } from 'components/Buttons';
2import { CopyButton as BaseCopyButton } from 'components/Buttons';
3import useCopiable from 'lib/useCopiable';
3import useCopiable from 'lib/useCopiable';
4+import WithTooltip, { TooltipPosition } from './WithTooltip';
4
5
5export function CopyButtonWide({ text, children, ...rest }) {
6export function CopyButtonWide({ text, children, ...rest }) {
6 const [doCopy, didCopy] = useCopiable(text);
7 const [doCopy, didCopy] = useCopiable(text);
7 return (
8 return (
8− <BaseCopyButton
9+ <WithTooltip
9− as="span"
10+ content={didCopy ? 'Copied!' : 'Copy'}
11+ className={'rel full nowrap'}
12+ position={TooltipPosition.TopRight}>
10− onClick={doCopy}
13+ <BaseCopyButton as="span" onClick={doCopy} text={text} {...rest}>
11− didCopy={didCopy}
12− text={text}
13− {...rest}>
14− {children}
14+ {children}
15− </BaseCopyButton>
15+ </BaseCopyButton>
16+ </WithTooltip>
16 );
17 );
17}
18}
src/components/WithTooltip.jsdeleted−23
@@ -1,23 +0,0 @@
1−import React, { useState, useCallback } from 'react';
2−
3−export default function WithTooltip({ content, children }) {
4− const [isHovered, setHovered] = useState(false);
5− const onMouseEnter = useCallback(() => setHovered(true), []);
6− const onMouseLeave = useCallback(() => setHovered(false), []);
7−
8− return (
9− <div
10− className="rel nowrap inline-block"
11− onMouseEnter={onMouseEnter}
12− onMouseLeave={onMouseLeave}>
13− {children}
14− {isHovered && (
15− <div
16− className="abs mb1 bg-black white ph4 pv2 r4"
17− style={{ bottom: '100%' }}>
18− {content}
19− </div>
20− )}
21− </div>
22− );
23−}
src/components/WithTooltip.tsxnew file+53
@@ -0,0 +1,53 @@
1+import React, { useState, useCallback } from 'react';
2+import { useMemo } from 'react';
3+
4+export enum TooltipPosition {
5+ Top,
6+ TopRight,
7+ // Add more as necessary here and in #positionStyle
8+}
9+
10+type WithTooltipArgs = {
11+ content: string;
12+ children: React.ReactNode;
13+ className?: string | undefined;
14+ position?: TooltipPosition;
15+};
16+
17+export default function WithTooltip({
18+ content,
19+ children,
20+ className,
21+ position = TooltipPosition.Top,
22+}: WithTooltipArgs) {
23+ const [isHovered, setHovered] = useState(false);
24+ const onMouseEnter = useCallback(() => setHovered(true), []);
25+ const onMouseLeave = useCallback(() => setHovered(false), []);
26+
27+ const positionStyle = useMemo(() => {
28+ switch (position) {
29+ case TooltipPosition.Top:
30+ return { bottom: '100%' };
31+ case TooltipPosition.TopRight:
32+ return { bottom: '90%', left: '90%' };
33+ default:
34+ return { bottom: '100%' };
35+ }
36+ }, [position]);
37+
38+ return (
39+ <div
40+ className={className || 'rel nowrap inline-block'}
41+ onMouseEnter={onMouseEnter}
42+ onMouseLeave={onMouseLeave}>
43+ {children}
44+ {isHovered && (
45+ <div
46+ className="abs mb1 bg-black white ph4 pv2 r4"
47+ style={positionStyle}>
48+ {content}
49+ </div>
50+ )}
51+ </div>
52+ );
53+}
src/views/UrbitOS/AccessCode.tsx+1−3
@@ -14,9 +14,7 @@ const AccessCode = ({ code }: AccessCodeArgs) => {
14 detail="This is your code to access Urbit OS"
14 detail="This is your code to access Urbit OS"
15 as={CopyButtonWide}
15 as={CopyButtonWide}
16 text={code}
16 text={code}
17− data-testid="access-code"
17+ data-testid="access-code">
18− // Allow the Copy Button Tooltip to flow over the Grid border
19− style={{ overflow: 'unset' }}>
20 Access Key
18 Access Key
21 </Grid.Item>
19 </Grid.Item>
22 </>
20 </>