Skip to content

Commit 2f545fd

Browse files
authored
feat(dioxus): responsive menus (#29)
1 parent c7a662f commit 2f545fd

File tree

3 files changed

+105
-45
lines changed

3 files changed

+105
-45
lines changed

assets/tailwind.css

+6
Original file line numberDiff line numberDiff line change
@@ -705,6 +705,9 @@
705705
.text-green-800 {
706706
color: var(--color-green-800);
707707
}
708+
.text-indigo-500 {
709+
color: var(--color-indigo-500);
710+
}
708711
.text-indigo-700 {
709712
color: var(--color-indigo-700);
710713
}
@@ -787,6 +790,9 @@
787790
--tw-ease: var(--ease-out);
788791
transition-timing-function: var(--ease-out);
789792
}
793+
.\[r\3 �t�\3 �W�Y�\]F��i�\f ��\.SD\,\1e _\\\:\2 \] {
794+
r�t��W�Y�]F��i���.SD,_\: ;
795+
}
790796
.hover\:border-gray-300 {
791797
&:hover {
792798
@media (hover: hover) {

src/components/home.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ pub(crate) fn Home() -> Element {
1313
div { class: "prose max-w-none",
1414
h1 { class: "text-4xl font-bold text-gray-900 mb-4", "Satoshi Escrow" }
1515
p { class: "text-xl text-gray-600 mb-8",
16-
"Satoshi Escrow: A Bitcoin non-custodial peer-to-peer dispute resolution using only Nostr keys."
16+
"A Bitcoin non-custodial peer-to-peer dispute resolution using only Nostr keys."
1717
}
1818
div { class: "mt-5",
1919
a {

src/components/navbar.rs

+98-44
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,15 @@ use crate::{LOGO, Route};
77
/// Shared navbar component.
88
#[component]
99
pub(crate) fn Navbar() -> Element {
10+
// Get the current route
11+
let route = use_route::<Route>();
12+
13+
// Helper function to determine if a link is active
14+
let is_active = |path: Route| -> bool { route == path };
15+
16+
// Add state to track if mobile menu is open
17+
let mut is_menu_open = use_signal(|| false);
18+
1019
rsx! {
1120
nav {
1221
div { class: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8",
@@ -16,38 +25,70 @@ pub(crate) fn Navbar() -> Element {
1625
r#type: "button",
1726
class: "inline-flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-indigo-500",
1827
aria_controls: "mobile-menu",
19-
aria_expanded: "false",
28+
aria_expanded: "{is_menu_open}",
29+
onclick: move |_| is_menu_open.set(!is_menu_open()),
2030
span { class: "sr-only", "Menu" }
2131
i {
22-
svg {
23-
xmlns: "http://www.w3.org/2000/svg",
24-
width: "24",
25-
height: "24",
26-
view_box: "0 0 24 24",
27-
fill: "none",
28-
stroke: "currentColor",
29-
"stroke-width": "2",
30-
"stroke-linecap": "round",
31-
"stroke-linejoin": "round",
32-
class: "lucide lucide-menu",
32+
// Show different icon based on menu state
33+
if *is_menu_open.read() {
34+
// X icon when menu is open
35+
svg {
36+
xmlns: "http://www.w3.org/2000/svg",
37+
width: "24",
38+
height: "24",
39+
view_box: "0 0 24 24",
40+
fill: "none",
41+
stroke: "currentColor",
42+
"stroke-width": "2",
43+
"stroke-linecap": "round",
44+
"stroke-linejoin": "round",
45+
class: "lucide lucide-x",
3346

34-
line {
35-
x1: "4",
36-
x2: "20",
37-
y1: "12",
38-
y2: "12",
39-
}
40-
line {
41-
x1: "4",
42-
x2: "20",
43-
y1: "6",
44-
y2: "6",
47+
line {
48+
x1: "18",
49+
x2: "6",
50+
y1: "6",
51+
y2: "18",
52+
}
53+
line {
54+
x1: "6",
55+
x2: "18",
56+
y1: "6",
57+
y2: "18",
58+
}
4559
}
46-
line {
47-
x1: "4",
48-
x2: "20",
49-
y1: "18",
50-
y2: "18",
60+
} else {
61+
// Hamburger icon when menu is closed
62+
svg {
63+
xmlns: "http://www.w3.org/2000/svg",
64+
width: "24",
65+
height: "24",
66+
view_box: "0 0 24 24",
67+
fill: "none",
68+
stroke: "currentColor",
69+
"stroke-width": "2",
70+
"stroke-linecap": "round",
71+
"stroke-linejoin": "round",
72+
class: "lucide lucide-menu",
73+
74+
line {
75+
x1: "4",
76+
x2: "20",
77+
y1: "12",
78+
y2: "12",
79+
}
80+
line {
81+
x1: "4",
82+
x2: "20",
83+
y1: "6",
84+
y2: "6",
85+
}
86+
line {
87+
x1: "4",
88+
x2: "20",
89+
y1: "18",
90+
y2: "18",
91+
}
5192
}
5293
}
5394
}
@@ -65,37 +106,42 @@ pub(crate) fn Navbar() -> Element {
65106
div { class: "hidden sm:ml-6 sm:flex sm:space-x-8",
66107
Link {
67108
id: "home",
68-
class: "border-indigo-500 text-gray-900 inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium",
109+
class: if is_active(Route::Home {}) { "border-indigo-500 text-gray-900 inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium" } else { "border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700 inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium" },
110+
aria_current: if is_active(Route::Home {}) { "page" } else { "" },
69111
to: Route::Home {},
70112
"Home"
71113
}
72114
Link {
73-
id: "create",
74-
class: "border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700 inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium",
115+
class: if is_active(Route::Create {}) { "border-indigo-500 text-gray-900 inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium" } else { "border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700 inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium" },
116+
aria_current: if is_active(Route::Create {}) { "page" } else { "" },
75117
to: Route::Create {},
76118
"Create"
77119
}
78120
Link {
79121
id: "sign",
80-
class: "border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700 inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium",
122+
class: if is_active(Route::Sign {}) { "border-indigo-500 text-gray-900 inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium" } else { "border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700 inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium" },
123+
aria_current: if is_active(Route::Sign {}) { "page" } else { "" },
81124
to: Route::Sign {},
82125
"Sign"
83126
}
84127
Link {
85128
id: "combine",
86-
class: "border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700 inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium",
129+
class: if is_active(Route::Combine {}) { "border-indigo-500 text-gray-900 inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium" } else { "border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700 inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium" },
130+
aria_current: if is_active(Route::Combine {}) { "page" } else { "" },
87131
to: Route::Combine {},
88132
"Combine"
89133
}
90134
Link {
91135
id: "broadcast",
92-
class: "border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700 inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium",
136+
class: if is_active(Route::Broadcast {}) { "border-indigo-500 text-gray-900 inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium" } else { "border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700 inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium" },
137+
aria_current: if is_active(Route::Broadcast {}) { "page" } else { "" },
93138
to: Route::Broadcast {},
94139
"Broadcast"
95140
}
96141
Link {
97142
id: "spend",
98-
class: "border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700 inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium",
143+
class: if is_active(Route::Spend {}) { "border-indigo-500 text-gray-900 inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium" } else { "border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700 inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium" },
144+
aria_current: if is_active(Route::Spend {}) { "page" } else { "" },
99145
to: Route::Spend {},
100146
"Spend"
101147
}
@@ -104,7 +150,8 @@ pub(crate) fn Navbar() -> Element {
104150
div { class: "flex",
105151
Link {
106152
id: "settings",
107-
class: "p-2 rounded-full text-gray-500 hover:text-gray-700 focus:outline-none",
153+
class: if is_active(Route::Settings {}) { "p-2 rounded-full text-indigo-500 focus:outline-none" } else { "p-2 rounded-full text-gray-500 hover:text-gray-700 focus:outline-none" },
154+
aria_current: if is_active(Route::Settings {}) { "page" } else { "" },
108155
to: Route::Settings {},
109156
i {
110157
svg {
@@ -140,42 +187,49 @@ pub(crate) fn Navbar() -> Element {
140187
}
141188
}
142189
}
143-
div { id: "mobile-menu", class: "sm:hidden",
190+
div {
191+
id: "mobile-menu",
192+
class: if *is_menu_open.read() { "sm:hidden" } else { "hidden sm:hidden" },
144193
div { class: "pt-2 pb-3 space-y-1",
145194
Link {
146195
id: "home",
147-
class: "bg-indigo-50 border-indigo-500 text-indigo-700 block pl-3 pr-4 py-2 border-l-4 text-base font-medium",
148-
aria_current: "page",
196+
class: if is_active(Route::Home {}) { "bg-indigo-50 border-indigo-500 text-indigo-700 block pl-3 pr-4 py-2 border-l-4 text-base font-medium" } else { "border-transparent text-gray-600 hover:bg-gray-50 hover:border-gray-300 hover:text-gray-800 block pl-3 pr-4 py-2 border-l-4 text-base font-medium" },
197+
aria_current: if is_active(Route::Home {}) { "page" } else { "" },
149198
to: Route::Home {},
150199
"Home"
151200
}
152201
Link {
153202
id: "create",
154-
class: "border-transparent text-gray-600 hover:bg-gray-50 hover:border-gray-300 hover:text-gray-800 block pl-3 pr-4 py-2 border-l-4 text-base font-medium",
203+
class: if is_active(Route::Create {}) { "bg-indigo-50 border-indigo-500 text-indigo-700 block pl-3 pr-4 py-2 border-l-4 text-base font-medium" } else { "border-transparent text-gray-600 hover:bg-gray-50 hover:border-gray-300 hover:text-gray-800 block pl-3 pr-4 py-2 border-l-4 text-base font-medium" },
204+
aria_current: if is_active(Route::Create {}) { "page" } else { "" },
155205
to: Route::Create {},
156206
"Create"
157207
}
158208
Link {
159209
id: "sign",
160-
class: "border-transparent text-gray-600 hover:bg-gray-50 hover:border-gray-300 hover:text-gray-800 block pl-3 pr-4 py-2 border-l-4 text-base font-medium",
210+
class: if is_active(Route::Sign {}) { "bg-indigo-50 border-indigo-500 text-indigo-700 block pl-3 pr-4 py-2 border-l-4 text-base font-medium" } else { "border-transparent text-gray-600 hover:bg-gray-50 hover:border-gray-300 hover:text-gray-800 block pl-3 pr-4 py-2 border-l-4 text-base font-medium" },
211+
aria_current: if is_active(Route::Sign {}) { "page" } else { "" },
161212
to: Route::Sign {},
162213
"Sign"
163214
}
164215
Link {
165216
id: "combine",
166-
class: "border-transparent text-gray-600 hover:bg-gray-50 hover:border-gray-300 hover:text-gray-800 block pl-3 pr-4 py-2 border-l-4 text-base font-medium",
217+
class: if is_active(Route::Combine {}) { "bg-indigo-50 border-indigo-500 text-indigo-700 block pl-3 pr-4 py-2 border-l-4 text-base font-medium" } else { "border-transparent text-gray-600 hover:bg-gray-50 hover:border-gray-300 hover:text-gray-800 block pl-3 pr-4 py-2 border-l-4 text-base font-medium" },
218+
aria_current: if is_active(Route::Combine {}) { "page" } else { "" },
167219
to: Route::Combine {},
168220
"Combine"
169221
}
170222
Link {
171223
id: "broadcast",
172-
class: "border-transparent text-gray-600 hover:bg-gray-50 hover:border-gray-300 hover:text-gray-800 block pl-3 pr-4 py-2 border-l-4 text-base font-medium",
224+
class: if is_active(Route::Broadcast {}) { "bg-indigo-50 border-indigo-500 text-indigo-700 block pl-3 pr-4 py-2 border-l-4 text-base font-medium" } else { "border-transparent text-gray-600 hover:bg-gray-50 hover:border-gray-300 hover:text-gray-800 block pl-3 pr-4 py-2 border-l-4 text-base font-medium" },
225+
aria_current: if is_active(Route::Broadcast {}) { "page" } else { "" },
173226
to: Route::Broadcast {},
174227
"Broadcast"
175228
}
176229
Link {
177230
id: "spend",
178-
class: "border-transparent text-gray-600 hover:bg-gray-50 hover:border-gray-300 hover:text-gray-800 block pl-3 pr-4 py-2 border-l-4 text-base font-medium",
231+
class: if is_active(Route::Spend {}) { "bg-indigo-50 border-indigo-500 text-indigo-700 block pl-3 pr-4 py-2 border-l-4 text-base font-medium" } else { "border-transparent text-gray-600 hover:bg-gray-50 hover:border-gray-300 hover:text-gray-800 block pl-3 pr-4 py-2 border-l-4 text-base font-medium" },
232+
aria_current: if is_active(Route::Spend {}) { "page" } else { "" },
179233
to: Route::Spend {},
180234
"Spend"
181235
}

0 commit comments

Comments
 (0)