Skip to content

Commit a43baf9

Browse files
authored
feat: Introducing light and dark mode (#344)
1 parent 0df0268 commit a43baf9

File tree

15 files changed

+234
-64
lines changed

15 files changed

+234
-64
lines changed
Lines changed: 37 additions & 0 deletions
Loading
Lines changed: 5 additions & 0 deletions
Loading

services/explorer-ui/src/assets/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import AztecIcon from "./aztec-icon.svg?react";
22
import AztecIconWhite from "./aztec-icon-white.svg?react";
33
import BackgroundArt from "./background-art.svg?react";
4+
import BackgroundArtDark from "./background-art-dark.svg?react";
45
import CopyIcon from "./copy-icon.svg?react";
56
import SuccessIcon from "./success-icon.svg?react";
67
import ObscuraLogoWhite from "./obscura-logo-white.svg?react";
@@ -15,6 +16,7 @@ export {
1516
AztecIcon,
1617
LoadingIcon,
1718
BackgroundArt,
19+
BackgroundArtDark,
1820
AztecIconWhite,
1921
ObscuraLogoWhite,
2022
CopyIcon,

services/explorer-ui/src/components/copy-text.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ export const CopyableText: FC<Props> = ({
3535
{textArea ? (
3636
<Textarea className="text-sm flex-grow" value={text} readOnly />
3737
) : (
38-
<span className="relative inline-block font-mono ">{text}</span>
38+
<span className="relative inline-block font-mono dark:text-white">{text}</span>
3939
)}
40-
<CopyIcon className="cursor-pointer" onClick={handleCopy} />
40+
<CopyIcon className="cursor-pointer hover:opacity-80 dark:text-gray-300" onClick={handleCopy} />
4141
</div>
4242
</div>
4343
);

services/explorer-ui/src/components/header.tsx

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { routes } from "~/routes/__root.tsx";
77
import { MagicDevLink } from "./magic-dev-link";
88
import { Button } from "./ui";
99
import { ChicmozHomeLink } from "./ui/chicmoz-home-link";
10+
import { ThemeToggle } from "./theme-toggle";
1011

1112
export const Header = () => {
1213
const navigate = useNavigate();
@@ -48,8 +49,8 @@ export const Header = () => {
4849
setHasNoResults(true);
4950
}
5051
}
51-
if (error) setHasNoResults(true);
52-
if (!data && isSuccess) setHasNoResults(true);
52+
if (error) { setHasNoResults(true); }
53+
if (!data && isSuccess) { setHasNoResults(true); }
5354
}, [data, error, isSuccess, navigate, fetchStatus]);
5455

5556
const handleOnChange = (value: string) => {
@@ -65,16 +66,15 @@ export const Header = () => {
6566
<div className="mx-auto px-4 mt-10 max-w-[1440px] md:px-[70px]">
6667
<div className="flex flex-col w-full items-center bg-purple-light rounded-[40px] py-4 pr-4 md:pl-10">
6768
<div
68-
className={`w-full transition-all duration-300 ease-in-out ${
69-
isMenuOpen ? "rounded-b-3xl" : ""
70-
}`}
69+
className={`w-full transition-all duration-300 ease-in-out ${isMenuOpen ? "rounded-b-3xl" : ""
70+
}`}
7171
>
7272
{/* Header */}
7373
<div className="w-full mx-auto">
7474
{/* Desktop Navigation */}
7575
<div className="hidden md:flex md:w-full md:items-center md:justify-between ">
7676
<div className="flex items-baseline">
77-
<ChicmozHomeLink textClasses="hidden md:block pr-6" />
77+
<ChicmozHomeLink textClasses="hidden md:block pr-6 self-center" />
7878
<MagicDevLink textClasses="hidden md:block" />
7979
</div>
8080
<div className="flex justify-center items-center w-1/2 sm:w-1/3 ">
@@ -93,11 +93,12 @@ export const Header = () => {
9393
<Link
9494
key={item.name}
9595
to={item.path}
96-
className="text-secondary hover:text-white transition-colors"
96+
className="text-white hover:text-white transition-colors"
9797
>
9898
{item.name}
9999
</Link>
100100
))}
101+
<ThemeToggle />
101102
</div>
102103
</div>
103104

@@ -114,9 +115,9 @@ export const Header = () => {
114115
>
115116
<span className="flex items-center">
116117
{isMenuOpen ? (
117-
<X className="h-6 w-6 mr-2 text-secondary" />
118+
<X className="h-6 w-6 mr-2 text-white" />
118119
) : (
119-
<Menu className="h-6 w-6 mr-2 text-secondary" />
120+
<Menu className="h-6 w-6 mr-2 text-white" />
120121
)}
121122
</span>
122123
</Button>
@@ -126,9 +127,8 @@ export const Header = () => {
126127
{/* Mobile Menu Content */}
127128
<div
128129
className={`md:hidden overflow-hidden transition-all duration-300 ease-in-out
129-
${
130-
isMenuOpen ? "max-h-[400px] opacity-100" : "max-h-0 opacity-0"
131-
}`}
130+
${isMenuOpen ? "max-h-[400px] opacity-100" : "max-h-0 opacity-0"
131+
}`}
132132
>
133133
<div className="px-4 py-4 space-y-3">
134134
{/* Search bar */}
@@ -144,6 +144,11 @@ export const Header = () => {
144144
/>
145145
</div>
146146

147+
<div className="flex items-center justify-between pt-2">
148+
<span className="text-white mr-2">Toggle theme:</span>
149+
<ThemeToggle />
150+
</div>
151+
147152
{/* Navigation Items */}
148153
<div className="flex flex-col space-y-2">
149154
{navigationItems.map((item) => (

services/explorer-ui/src/components/info-badge.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,14 @@ export const InfoBadge: FC<InfoBadgeProps> = ({
1414
error,
1515
}) => {
1616
const text = useMemo(() => {
17-
if (error) return error.message;
18-
if (data) return data;
17+
if (error) { return error.message; }
18+
if (data) { return data; }
1919
return "No Data";
2020
}, [data, error]);
21+
2122
return (
22-
<div className="flex flex-col bg-white w-full justify-between rounded-lg shadow-md p-4 ">
23-
<p className="text-sm">{title}</p>
23+
<div className="flex flex-col bg-white w-full justify-between rounded-lg shadow-md p-4">
24+
<p className="text-sm text-primary dark:text-white">{title}</p>
2425
{isLoading ? (
2526
<Loader amount={1} />
2627
) : (

services/explorer-ui/src/components/info-display/key-value-row.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,21 +35,22 @@ export const KeyValueRow: FC<KeyValueRowProps> = ({
3535
else if (extLink) { displayType = DisplayType.EXTERNAL_LINK; }
3636
else if (label.includes("status")) { displayType = DisplayType.BADGE; }
3737

38-
const commonTextClasses = "text-sm flex-grow text-end justify-end";
38+
const commonTextClasses = "text-sm flex-grow text-end justify-end ";
39+
3940
return (
4041
<div
4142
key={label}
42-
className={`flex items-center gap-2 py-3 ${!isLast ? "border-b border-gray-200" : ""
43+
className={`flex items-center gap-2 py-3 ${!isLast ? "border-b border-gray-200 dark:border-gray-700" : ""
4344
}`}
4445
>
45-
<span className="text-gray-600 w-1/3">{label}</span>
46+
<span className="text-gray-600 dark:text-gray-300 w-1/3">{label}</span>
4647
{displayType === DisplayType.TEXT && (
4748
<span className={commonTextClasses}>{value}</span>
4849
)}
4950
{displayType === DisplayType.LINK && (
5051
<Link
5152
to={link}
52-
className={`${commonTextClasses} text-primary-600 text-primary cursor-pointer`}
53+
className={`${commonTextClasses} text-primary-600 text-primary cursor-pointer hover:opacity-80`}
5354
>
5455
{value.startsWith("0x") ? truncateHashString(value) : value}
5556
<span className="ml-1">🔗</span>
@@ -73,7 +74,7 @@ export const KeyValueRow: FC<KeyValueRowProps> = ({
7374
href={extLink}
7475
target="_blank"
7576
rel="noreferrer"
76-
className={`${commonTextClasses} text-primary-600 text-primary cursor-pointer`}
77+
className={`${commonTextClasses} text-primary-600 text-primary cursor-pointer hover:opacity-80`}
7778
>
7879
{value}
7980
<span className="ml-1">↗️</span>

services/explorer-ui/src/components/magic-dev-link.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ Reason: ${systemHealth.reason}`}
2525
return (
2626
<div className={className}>
2727
<Link to={routes.dev.route} className="flex flex-row items-center">
28-
<p className={`${textClasses} font-space-grotesk text-secondary`}>
28+
<p className={`${textClasses} font-space-grotesk text-white`}>
2929
{L2_NETWORK_ID}
3030
</p>
3131
<CustomTooltip content={tooltipContent}>
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { MoonIcon, SunIcon } from "lucide-react";
2+
import { useTheme as useNextTheme } from "next-themes";
3+
import { Button } from "./ui/button";
4+
import { useEffect, useState } from "react";
5+
6+
export function ThemeToggle() {
7+
const { theme, setTheme } = useNextTheme();
8+
const [mounted, setMounted] = useState(false);
9+
10+
// Avoid hydration mismatch by only rendering after mount
11+
useEffect(() => {
12+
setMounted(true);
13+
}, []);
14+
15+
if (!mounted) {
16+
return <Button variant="ghost" size="icon" className="w-9 px-0" />;
17+
}
18+
19+
return (
20+
<Button
21+
variant="ghost"
22+
size="icon"
23+
className="w-9 px-0 text-white hover:text-white hover:bg-purple-light/20"
24+
onClick={() => setTheme(theme === "dark" ? "light" : "dark")}
25+
aria-label="Toggle theme"
26+
>
27+
{theme === "dark" ? (
28+
<SunIcon className="h-5 w-5" />
29+
) : (
30+
<MoonIcon className="h-5 w-5" />
31+
)}
32+
</Button>
33+
);
34+
}

services/explorer-ui/src/components/ui/input.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ import { CrossIcon, LoadingIcon, SearchIcon } from "~/assets";
33

44
import { cn } from "~/lib/utils";
55

6-
export interface InputProps
7-
extends React.InputHTMLAttributes<HTMLInputElement> {}
6+
export type InputProps = React.InputHTMLAttributes<HTMLInputElement>
87

98
const Input = React.forwardRef<HTMLInputElement, InputProps>(
109
({ className, type, ...props }, ref) => {
@@ -32,7 +31,7 @@ export interface SearchInputProps
3231
const SearchInput = React.forwardRef<HTMLInputElement, SearchInputProps>(
3332
({ className, type, onIconClick, isLoading, noResults, ...props }, ref) => {
3433
return (
35-
<div className="flex items-center pl-3 w-full bg-white rounded-md focus-visible:ring-1 focus-visible:ring-ring">
34+
<div className="flex items-center pl-3 gap-1 w-full bg-white rounded-md focus-visible:ring-1 focus-visible:ring-ring">
3635
{noResults ? (
3736
<div>
3837
<CrossIcon />

0 commit comments

Comments
 (0)