Skip to content

Commit 4067acc

Browse files
authored
Merge pull request #2435 from pyth-network/cprussin/ui-79-replace-price-feed-key-copy-button-component
feat(insights): implement new CopyButton design
2 parents 4c1dbf6 + 26f756f commit 4067acc

File tree

12 files changed

+68
-62
lines changed

12 files changed

+68
-62
lines changed

apps/insights/src/components/CopyButton/index.module.scss

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,31 @@
11
@use "@pythnetwork/component-library/theme";
22

33
.copyButton {
4+
display: inline-flex;
5+
flex-flow: row nowrap;
6+
align-items: center;
7+
justify-content: center;
8+
gap: 0.5em;
9+
background: transparent;
10+
transition-property: background-color, color, border-color, outline-color;
11+
transition-duration: 100ms;
12+
transition-timing-function: linear;
13+
border: 1px solid transparent;
14+
outline-offset: 0;
15+
outline: theme.spacing(1) solid transparent;
16+
-webkit-tap-highlight-color: transparent;
17+
border-radius: theme.border-radius("base");
18+
cursor: pointer;
19+
line-height: 150%;
20+
padding-left: 0.5em;
21+
padding-right: 0.5em;
22+
margin-left: -0.5em;
23+
margin-right: -0.5em;
24+
425
.iconContainer {
526
position: relative;
27+
height: 1em;
28+
width: 1em;
629

730
.copyIcon {
831
opacity: 0.5;
@@ -24,13 +47,26 @@
2447
}
2548
}
2649

27-
&[data-is-copied] .iconContainer {
28-
.copyIcon {
29-
opacity: 0;
30-
}
50+
&[data-focus-visible] {
51+
border-color: theme.color("focus");
52+
outline-color: theme.color("focus-dim");
53+
}
3154

32-
.checkIcon {
33-
opacity: 1;
55+
&[data-hovered] {
56+
background-color: theme.color("button", "outline", "background", "hover");
57+
}
58+
59+
&[data-is-copied] {
60+
background-color: theme.color("states", "info", "background");
61+
62+
.iconContainer {
63+
.copyIcon {
64+
opacity: 0;
65+
}
66+
67+
.checkIcon {
68+
opacity: 1;
69+
}
3470
}
3571
}
3672
}

apps/insights/src/components/CopyButton/index.tsx

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,20 @@
33
import { Check } from "@phosphor-icons/react/dist/ssr/Check";
44
import { Copy } from "@phosphor-icons/react/dist/ssr/Copy";
55
import { useLogger } from "@pythnetwork/app-logger";
6-
import {
7-
type Props as ButtonProps,
8-
Button,
9-
} from "@pythnetwork/component-library/Button";
10-
import type { Button as UnstyledButton } from "@pythnetwork/component-library/unstyled/Button";
6+
import { Button } from "@pythnetwork/component-library/unstyled/Button";
117
import clsx from "clsx";
12-
import { useCallback, useEffect, useState } from "react";
8+
import { type ComponentProps, useCallback, useEffect, useState } from "react";
139

1410
import styles from "./index.module.scss";
1511

12+
const COPY_INDICATOR_TIME = 1000;
13+
1614
type OwnProps = {
1715
text: string;
1816
};
1917

2018
type Props = Omit<
21-
ButtonProps<typeof UnstyledButton>,
19+
ComponentProps<typeof Button>,
2220
keyof OwnProps | "onPress" | "afterIcon"
2321
> &
2422
OwnProps;
@@ -46,7 +44,7 @@ export const CopyButton = ({ text, children, className, ...props }: Props) => {
4644
if (isCopied) {
4745
const timeout = setTimeout(() => {
4846
setIsCopied(false);
49-
}, 2000);
47+
}, COPY_INDICATOR_TIME);
5048
return () => {
5149
clearTimeout(timeout);
5250
};
@@ -59,16 +57,18 @@ export const CopyButton = ({ text, children, className, ...props }: Props) => {
5957
<Button
6058
onPress={copy}
6159
className={clsx(styles.copyButton, className)}
62-
afterIcon={({ className, ...props }) => (
63-
<div className={clsx(styles.iconContainer, className)} {...props}>
64-
<Copy className={styles.copyIcon} />
65-
<Check className={styles.checkIcon} />
66-
</div>
67-
)}
6860
{...(isCopied && { "data-is-copied": true })}
6961
{...props}
7062
>
71-
{children}
63+
{(...args) => (
64+
<>
65+
{typeof children === "function" ? children(...args) : children}
66+
<div className={styles.iconContainer}>
67+
<Copy className={styles.copyIcon} />
68+
<Check className={styles.checkIcon} />
69+
</div>
70+
</>
71+
)}
7272
</Button>
7373
);
7474
};

apps/insights/src/components/EntityList/index.module.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
outline-color 100ms linear,
1717
background-color 100ms linear;
1818
-webkit-tap-highlight-color: transparent;
19+
cursor: pointer;
1920

2021
&[data-focus-visible] {
2122
outline: theme.spacing(0.5) solid theme.color("focus");

apps/insights/src/components/PriceFeed/layout.module.scss

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@
3030
.rightGroup {
3131
display: flex;
3232
flex-flow: row nowrap;
33-
align-items: center;
34-
gap: theme.spacing(2);
33+
align-items: stretch;
34+
gap: theme.spacing(4);
3535

3636
& > * {
3737
flex: 1 1 0;

apps/insights/src/components/PriceFeed/layout.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,6 @@ export const PriceFeedLayout = async ({ children, params }: Props) => {
6868
<PriceFeedTag className={styles.priceFeedTag} symbol={feed.symbol} />
6969
<div className={styles.rightGroup}>
7070
<FeedKey
71-
variant="ghost"
72-
size="sm"
7371
className={styles.feedKey ?? ""}
7472
feedKey={feed.product.price_account}
7573
/>

apps/insights/src/components/PriceFeeds/price-feeds-card.module.scss

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,4 @@
2020
display: none;
2121
}
2222
}
23-
24-
.feedKey {
25-
margin: -#{theme.button-padding("sm", false)};
26-
}
2723
}

apps/insights/src/components/PriceFeeds/price-feeds-card.tsx

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -143,12 +143,7 @@ const ResolvedPriceFeedsCard = ({ priceFeeds, ...props }: Props) => {
143143
priceFeedName: <PriceFeedTag compact symbol={symbol} />,
144144
assetClass: <AssetClassTag symbol={symbol} />,
145145
priceFeedId: (
146-
<FeedKey
147-
size="xs"
148-
variant="ghost"
149-
feedKey={key}
150-
className={styles.feedKey ?? ""}
151-
/>
146+
<FeedKey feedKey={key} className={styles.feedKey ?? ""} />
152147
),
153148
},
154149
}),

apps/insights/src/components/Publisher/layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ export const PublishersLayout = async ({ children, params }: Props) => {
105105
items={[
106106
{ href: "/", label: "Home" },
107107
{ href: "/publishers", label: "Publishers" },
108-
{ label: <PublisherKey size="sm" publisherKey={key} /> },
108+
{ label: <PublisherKey publisherKey={key} /> },
109109
]}
110110
/>
111111
</div>

apps/insights/src/components/PublisherKey/index.module.scss

Lines changed: 0 additions & 9 deletions
This file was deleted.
Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
import clsx from "clsx";
21
import type { ComponentProps } from "react";
32

4-
import styles from "./index.module.scss";
53
import { CopyButton } from "../CopyButton";
64

75
type KeyProps = Omit<
@@ -11,17 +9,8 @@ type KeyProps = Omit<
119
publisherKey: string;
1210
};
1311

14-
export const PublisherKey = ({
15-
publisherKey,
16-
className,
17-
...props
18-
}: KeyProps) => (
19-
<CopyButton
20-
variant="ghost"
21-
className={clsx(styles.publisherKey, className)}
22-
text={publisherKey}
23-
{...props}
24-
>
12+
export const PublisherKey = ({ publisherKey, ...props }: KeyProps) => (
13+
<CopyButton text={publisherKey} {...props}>
2514
{`${publisherKey.slice(0, 4)}...${publisherKey.slice(-4)}`}
2615
</CopyButton>
2716
);

0 commit comments

Comments
 (0)