Skip to content

Commit 3ac2c47

Browse files
chore(insights): add mobile menu component with styles and update stats rendering in PriceFeeds
1 parent 4e034a6 commit 3ac2c47

File tree

19 files changed

+395
-53
lines changed

19 files changed

+395
-53
lines changed

apps/insights/.env.development

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
DISABLE_ACCESSIBILITY_REPORTING=true
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
@use "@pythnetwork/component-library/theme";
2+
3+
.mobileMenuTrigger {
4+
display: none;
5+
@include theme.mobile {
6+
display: block;
7+
}
8+
}
9+
10+
.mobileMenuOverlay {
11+
background: rgba(0,0,0,0.4);
12+
position: fixed;
13+
inset: 0;
14+
z-index: 999;
15+
}
16+
17+
.mobileMenuContainer {
18+
border-top-left-radius: theme.border-radius("2xl");
19+
border-top-right-radius: theme.border-radius("2xl");
20+
background: theme.color("background", "modal");
21+
position: absolute;
22+
bottom: 0;
23+
left: 0;
24+
right: 0;
25+
padding: 1rem;
26+
display: flex;
27+
flex-flow: column nowrap;
28+
gap: theme.spacing(4);
29+
}
30+
31+
.mobileMenuHandle {
32+
background: theme.color("background", "secondary");
33+
width: 33%;
34+
height: 6px;
35+
border-radius: theme.border-radius("full");
36+
align-self: center;
37+
}
38+
39+
.mobileThemeSwitcher {
40+
display: flex;
41+
flex-flow: row nowrap;
42+
justify-content: space-between;
43+
align-items: center;
44+
}
45+
46+
.mobileThemeSwitcherFeedback {
47+
display: flex;
48+
flex-flow: row nowrap;
49+
align-items: center;
50+
gap: theme.spacing(3);
51+
text-transform: capitalize;
52+
font-weight: theme.font-weight("medium");
53+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
'use client';
2+
import { Lifebuoy } from "@phosphor-icons/react/dist/ssr/Lifebuoy";
3+
import { List } from "@phosphor-icons/react/dist/ssr/List";
4+
import { X } from "@phosphor-icons/react/dist/ssr/X";
5+
import { Button } from "@pythnetwork/component-library/Button";
6+
import clsx from "clsx";
7+
import { useTheme } from "next-themes";
8+
import { useState } from "react";
9+
10+
import styles from "./mobile-menu.module.scss";
11+
import { SupportDrawer } from "../Root/support-drawer";
12+
import { ThemeSwitch } from "../Root/theme-switch";
13+
14+
15+
export const MobileMenu = ({
16+
className,
17+
...props
18+
}: {
19+
className?: string | string[];
20+
}) => {
21+
const { theme } = useTheme();
22+
const [isOpen, setIsOpen] = useState(false);
23+
24+
const toggleMenu = () => {
25+
setIsOpen(!isOpen);
26+
};
27+
28+
return (
29+
<div className={clsx(styles.mobileMenuTrigger, className)} {...props}>
30+
<Button variant="ghost" size="sm" afterIcon={List} rounded onPress={toggleMenu}>Menu</Button>
31+
{isOpen && (
32+
<div className={styles.mobileMenuOverlay}>
33+
<div className={styles.mobileMenuContainer}>
34+
<div className={styles.mobileMenuHandle} />
35+
<Button
36+
href="https://docs.pyth.network"
37+
size="md"
38+
rounded
39+
target="_blank"
40+
>
41+
Dev Docs
42+
</Button>
43+
<SupportDrawer>
44+
<Button beforeIcon={Lifebuoy} variant="ghost" size="md" rounded>
45+
Support
46+
</Button>
47+
</SupportDrawer>
48+
<div className={styles.mobileThemeSwitcher}><div>Theme</div>
49+
<div className={styles.mobileThemeSwitcherFeedback}>
50+
<div>{theme}</div>
51+
<ThemeSwitch />
52+
</div>
53+
</div>
54+
<Button variant="outline" afterIcon={X} rounded onPress={toggleMenu}>Close</Button>
55+
</div>
56+
</div>
57+
)}
58+
59+
</div>
60+
);
61+
};

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import { YesterdaysPricesProvider, ChangePercent } from "../ChangePercent";
2323
import { LivePrice } from "../LivePrices";
2424
import { PriceFeedIcon } from "../PriceFeedIcon";
2525
import { PriceFeedTag } from "../PriceFeedTag";
26+
import { Stats } from "../Stats";
2627

2728
const PRICE_FEEDS_ANCHOR = "priceFeeds";
2829

@@ -48,7 +49,7 @@ export const PriceFeeds = async () => {
4849
<div className={styles.priceFeeds}>
4950
<h1 className={styles.header}>Price Feeds</h1>
5051
<div className={styles.body}>
51-
<section className={styles.stats}>
52+
<Stats>
5253
<StatCard
5354
variant="primary"
5455
header="Active Feeds"
@@ -74,7 +75,7 @@ export const PriceFeeds = async () => {
7475
corner={<Info weight="fill" />}
7576
/>
7677
</AssetClassesDrawer>
77-
</section>
78+
</Stats>
7879
<YesterdaysPricesProvider
7980
feeds={Object.fromEntries(
8081
featuredRecentlyAdded.map(({ symbol, product }) => [
@@ -165,6 +166,7 @@ const FeaturedFeedsCard = <T extends ElementType>({
165166
}: FeaturedFeedsCardProps<T>) => (
166167
<Card {...props}>
167168
<div className={styles.featuredFeeds}>
169+
<Stats>
168170
{feeds.map((feed) => (
169171
<Card
170172
key={feed.product.price_account}
@@ -191,6 +193,7 @@ const FeaturedFeedsCard = <T extends ElementType>({
191193
</div>
192194
</Card>
193195
))}
196+
</Stats>
194197
</div>
195198
</Card>
196199
);

apps/insights/src/components/Root/footer.module.scss

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,30 @@
77
// XL
88
padding: theme.spacing(8) 0;
99

10+
@include theme.mobile {
11+
padding-bottom: theme.spacing(20);
12+
}
13+
1014
// bg-beige-100 sm:border-t sm:border-stone-300
1115

1216
.topContent {
1317
display: flex;
1418
gap: theme.spacing(6);
15-
19+
1620
// SM
1721
flex-flow: row nowrap;
1822
align-items: center;
1923
justify-content: space-between;
2024

25+
@media screen and (max-width: theme.breakpoint("sm")) {
26+
flex-flow: column nowrap;
27+
align-items: flex-start;
28+
}
29+
2130
@include theme.max-width;
2231

2332
// XL
24-
margin-bottom: theme.spacing(12);
33+
margin-bottom: theme.spacing(6);
2534

2635
// py-6
2736

@@ -79,6 +88,7 @@
7988
justify-content: flex-end;
8089
gap: theme.spacing(2);
8190

91+
8292
// justify-between
8393
}
8494
}

apps/insights/src/components/Root/footer.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { ArrowSquareOut } from "@phosphor-icons/react/dist/ssr/ArrowSquareOut";
12
import {
23
type Props as ButtonProps,
34
Button,
@@ -21,10 +22,10 @@ export const Footer = () => (
2122
<div className={styles.divider} />
2223
<div className={styles.help}>
2324
<SupportDrawer>
24-
<Link>Help</Link>
25+
<Link>Support</Link>
2526
</SupportDrawer>
2627
<Link href="https://docs.pyth.network" target="_blank">
27-
Documentation
28+
Documentation <ArrowSquareOut />
2829
</Link>
2930
</div>
3031
</div>

apps/insights/src/components/Root/header.module.scss

Lines changed: 45 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44
position: sticky;
55
top: 0;
66
width: 100%;
7-
background-color: theme.color("background", "nav-blur");
8-
backdrop-filter: blur(32px);
7+
background-color: theme.color("background", "primary");
8+
border-bottom: 1px solid theme.color("background", "secondary");
9+
// TODO: This causes that navigation is not fixed
10+
// backdrop-filter: blur(32px);
911

1012
.content {
1113
height: 100%;
@@ -16,18 +18,23 @@
1618

1719
.leftMenu {
1820
flex: none;
19-
gap: theme.spacing(6);
21+
gap: theme.spacing(4);
22+
position: relative;
2023

2124
@include theme.row;
2225

2326
.logoLink {
2427
padding: theme.spacing(3);
25-
margin: -#{theme.spacing(3)};
2628
color: theme.color("foreground");
29+
30+
@include theme.desktop {
31+
position: absolute;
32+
left: -#{theme.spacing(16)};
33+
}
2734

2835
.logoWrapper {
29-
width: theme.spacing(9);
30-
height: theme.spacing(9);
36+
width: theme.spacing(8);
37+
height: theme.spacing(8);
3138
position: relative;
3239

3340
.logo {
@@ -52,33 +59,46 @@
5259

5360
.rightMenu {
5461
flex: none;
62+
position: relative;
5563
gap: theme.spacing(2);
5664

5765
@include theme.row;
5866

59-
margin-right: -#{theme.button-padding("sm", false)};
60-
6167
.themeSwitch {
62-
margin-left: theme.spacing(1);
63-
}
64-
}
65-
66-
@media screen and (min-width: theme.$max-width + (2 * (theme.spacing(9) + theme.spacing(8) + theme.spacing(7)))) {
67-
.leftMenu {
68-
margin-left: -#{theme.spacing(9) + theme.spacing(7)};
69-
70-
.logoLink {
71-
margin-right: -#{theme.spacing(2)};
68+
position: relative;
69+
@include theme.mobile {
70+
display: none;
7271
}
73-
}
74-
75-
.rightMenu {
76-
margin-right: -#{theme.spacing(9) + theme.spacing(7)};
77-
78-
.themeSwitch {
79-
margin-left: theme.spacing(5);
72+
@include theme.desktop {
73+
display: block;
74+
position: absolute;
75+
right: -#{theme.spacing(16)};
8076
}
8177
}
8278
}
79+
// Reason: you can absolute position relatively to a container and disable this behavior on mobile
80+
// @media screen and (min-width: #{theme.$max-width + (2 * (theme.spacing(9) + theme.spacing(8) + theme.spacing(7)))}) {
81+
// .leftMenu {
82+
// margin-left: -#{theme.spacing(9) + theme.spacing(7)};
83+
84+
// .logoLink {
85+
// margin-right: -#{theme.spacing(2)};
86+
// }
87+
// }
88+
89+
// .rightMenu {
90+
// margin-right: -#{theme.spacing(9) + theme.spacing(7)};
91+
92+
// .themeSwitch {
93+
// margin-left: theme.spacing(5);
94+
// }
95+
// }
96+
// }
97+
}
98+
}
99+
100+
.hideOnMobile {
101+
@include theme.mobile {
102+
display: none;
83103
}
84104
}
Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
'use client';
2+
13
import { Lifebuoy } from "@phosphor-icons/react/dist/ssr/Lifebuoy";
24
import { Button } from "@pythnetwork/component-library/Button";
35
import { Link } from "@pythnetwork/component-library/Link";
@@ -10,6 +12,7 @@ import { SearchButton } from "./search-button";
1012
import { SupportDrawer } from "./support-drawer";
1113
import { MainNavTabs } from "./tabs";
1214
import { ThemeSwitch } from "./theme-switch";
15+
import { MobileMenu } from "../MobileMenu/mobile-menu.v2";
1316

1417
export const Header = ({ className, ...props }: ComponentProps<"header">) => (
1518
<header className={clsx(styles.header, className)} {...props}>
@@ -25,22 +28,29 @@ export const Header = ({ className, ...props }: ComponentProps<"header">) => (
2528
<MainNavTabs />
2629
</div>
2730
<div className={styles.rightMenu}>
28-
<SupportDrawer>
29-
<Button beforeIcon={Lifebuoy} variant="ghost" size="sm" rounded>
30-
Support
31-
</Button>
32-
</SupportDrawer>
31+
<div className={styles.hideOnMobile}>
32+
<SupportDrawer>
33+
<Button beforeIcon={Lifebuoy} variant="ghost" size="sm" rounded>
34+
Support
35+
</Button>
36+
</SupportDrawer>
37+
</div>
3338
<SearchButton />
34-
<Button
35-
href="https://docs.pyth.network"
36-
size="sm"
37-
rounded
38-
target="_blank"
39-
>
40-
Dev Docs
41-
</Button>
39+
<div className={styles.hideOnMobile}>
40+
<Button
41+
href="https://docs.pyth.network"
42+
size="sm"
43+
rounded
44+
target="_blank"
45+
>
46+
Dev Docs
47+
</Button>
48+
</div>
4249
<ThemeSwitch className={styles.themeSwitch ?? ""} />
50+
<MobileMenu />
4351
</div>
4452
</div>
4553
</header>
4654
);
55+
56+

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ $header-height: theme.spacing(20);
77
headerHeight: $header-height;
88
}
99

10+
11+
1012
.root {
1113
scroll-padding-top: $header-height;
1214
overflow-x: hidden;

0 commit comments

Comments
 (0)