Skip to content

Commit 996bb95

Browse files
Enhance navigation menu demo to match Base UI example
- Add missing props to NavigationMenuRoot (delay, close_delay, actions_ref, on_open_change_complete) - Update all component prop descriptions to match Base UI documentation exactly - Create comprehensive demo with Overview and Handbook dropdowns - Add rich content with links, titles, and descriptions - Update ClassNames for better styling and transitions - Include Portal structure for proper positioning - Fix syntax error: use rx.el instead of rx.html for HTML elements Co-Authored-By: Carlos Cutillas <[email protected]>
1 parent 18451bc commit 996bb95

File tree

2 files changed

+97
-15
lines changed

2 files changed

+97
-15
lines changed

demo/demo/demo.py

Lines changed: 77 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,87 @@ def index() -> rx.Component:
6161
ui.navigation_menu.root(
6262
ui.navigation_menu.list(
6363
ui.navigation_menu.item(
64-
ui.navigation_menu.trigger("Home", on_click=lambda: rx.toast.success("Home clicked")),
64+
ui.navigation_menu.trigger(
65+
"Overview",
66+
ui.navigation_menu.icon("▼"),
67+
),
68+
ui.navigation_menu.content(
69+
rx.el.ul(
70+
rx.el.li(
71+
ui.navigation_menu.link(
72+
rx.el.h3("Quick Start", class_name="font-medium text-sm"),
73+
rx.el.p("Install and assemble your first component.", class_name="text-xs text-secondary-11"),
74+
href="/quick-start",
75+
on_click=lambda: rx.toast.success("Quick Start clicked"),
76+
class_name="block p-3 rounded hover:bg-secondary-3",
77+
)
78+
),
79+
rx.el.li(
80+
ui.navigation_menu.link(
81+
rx.el.h3("Accessibility", class_name="font-medium text-sm"),
82+
rx.el.p("Learn how we build accessible components.", class_name="text-xs text-secondary-11"),
83+
href="/accessibility",
84+
on_click=lambda: rx.toast.success("Accessibility clicked"),
85+
class_name="block p-3 rounded hover:bg-secondary-3",
86+
)
87+
),
88+
rx.el.li(
89+
ui.navigation_menu.link(
90+
rx.el.h3("Releases", class_name="font-medium text-sm"),
91+
rx.el.p("See what's new in the latest versions.", class_name="text-xs text-secondary-11"),
92+
href="/releases",
93+
on_click=lambda: rx.toast.success("Releases clicked"),
94+
class_name="block p-3 rounded hover:bg-secondary-3",
95+
)
96+
),
97+
class_name="grid grid-cols-2 gap-2 w-96 p-2",
98+
)
99+
),
65100
),
66101
ui.navigation_menu.item(
67-
ui.navigation_menu.trigger("About", on_click=lambda: rx.toast.success("About clicked")),
102+
ui.navigation_menu.trigger(
103+
"Handbook",
104+
ui.navigation_menu.icon("▼"),
105+
),
106+
ui.navigation_menu.content(
107+
rx.el.ul(
108+
rx.el.li(
109+
ui.navigation_menu.link(
110+
rx.el.h3("Styling", class_name="font-medium text-sm"),
111+
rx.el.p("Components can be styled with CSS, Tailwind, or CSS-in-JS.", class_name="text-xs text-secondary-11"),
112+
href="/styling",
113+
on_click=lambda: rx.toast.success("Styling clicked"),
114+
class_name="block p-3 rounded hover:bg-secondary-3",
115+
)
116+
),
117+
rx.el.li(
118+
ui.navigation_menu.link(
119+
rx.el.h3("Animation", class_name="font-medium text-sm"),
120+
rx.el.p("Components can be animated with CSS or JavaScript.", class_name="text-xs text-secondary-11"),
121+
href="/animation",
122+
on_click=lambda: rx.toast.success("Animation clicked"),
123+
class_name="block p-3 rounded hover:bg-secondary-3",
124+
)
125+
),
126+
class_name="flex flex-col gap-2 w-80 p-2",
127+
)
128+
),
68129
),
69130
ui.navigation_menu.item(
70-
ui.navigation_menu.trigger("Contact", on_click=lambda: rx.toast.success("Contact clicked")),
131+
ui.navigation_menu.link(
132+
"GitHub",
133+
href="https://github.com/reflex-dev/reflex-ui",
134+
on_click=lambda: rx.toast.success("GitHub clicked"),
135+
),
136+
),
137+
),
138+
ui.navigation_menu.portal(
139+
ui.navigation_menu.positioner(
140+
ui.navigation_menu.popup(
141+
ui.navigation_menu.arrow(),
142+
ui.navigation_menu.viewport(),
143+
),
144+
side_offset=10,
71145
),
72146
),
73147
),

reflex_ui/components/base/navigation_menu.py

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,15 @@ class ClassNames:
2222
ROOT = "relative"
2323
LIST = "flex items-center gap-1"
2424
ITEM = "relative"
25-
TRIGGER = "flex items-center gap-1 px-3 py-2 text-sm font-medium rounded-md hover:bg-secondary-3 focus:outline-none focus-visible:ring-1 focus-visible:ring-primary-4 cursor-pointer select-none"
26-
CONTENT = "absolute top-full left-0 mt-1 min-w-48 origin-top-left border border-secondary-a4 bg-secondary-1 shadow-large rounded-md p-1 z-50 transition-[transform,scale,opacity] data-[ending-style]:scale-95 data-[starting-style]:scale-95 data-[ending-style]:opacity-0 data-[starting-style]:opacity-0"
27-
LINK = "block px-3 py-2 text-sm text-secondary-12 hover:bg-secondary-3 rounded-sm cursor-pointer select-none outline-none focus:bg-secondary-3"
28-
ICON = "size-4 text-secondary-10"
25+
TRIGGER = "flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-md hover:bg-secondary-3 focus:outline-none focus-visible:ring-1 focus-visible:ring-primary-4 cursor-pointer select-none transition-colors"
26+
CONTENT = "absolute top-full left-0 mt-2 min-w-64 origin-top-left border border-secondary-a4 bg-secondary-1 shadow-large rounded-lg p-2 z-50 transition-[transform,scale,opacity] data-[ending-style]:scale-95 data-[starting-style]:scale-95 data-[ending-style]:opacity-0 data-[starting-style]:opacity-0"
27+
LINK = "block px-3 py-2 text-sm text-secondary-12 hover:bg-secondary-3 rounded-md cursor-pointer select-none outline-none focus:bg-secondary-3 transition-colors"
28+
ICON = "size-4 text-secondary-10 transition-transform data-[popup-open]:rotate-180"
2929
PORTAL = "relative"
3030
POSITIONER = "outline-none"
3131
POPUP = "outline-none"
32-
VIEWPORT = "relative overflow-hidden"
33-
ARROW = "data-[side=bottom]:top-[-8px] data-[side=left]:right-[-13px] data-[side=left]:rotate-90 data-[side=right]:left-[-13px] data-[side=right]:-rotate-90 data-[side=top]:bottom-[-8px] data-[side=top]:rotate-180"
32+
VIEWPORT = "relative overflow-hidden rounded-lg"
33+
ARROW = "fill-secondary-1 stroke-secondary-a4 data-[side=bottom]:top-[-8px] data-[side=left]:right-[-13px] data-[side=left]:rotate-90 data-[side=right]:left-[-13px] data-[side=right]:-rotate-90 data-[side=top]:bottom-[-8px] data-[side=top]:rotate-180"
3434
BACKDROP = "fixed inset-0 z-40"
3535

3636

@@ -58,6 +58,14 @@ class NavigationMenuRoot(NavigationMenuBaseComponent):
5858

5959
orientation: Var[LiteralNavigationMenuOrientation]
6060

61+
delay: Var[int]
62+
63+
close_delay: Var[int]
64+
65+
actions_ref: Var[str]
66+
67+
on_open_change_complete: EventHandler[passthrough_event_spec(bool)]
68+
6169
# The render prop.
6270
render_: Var[Component]
6371

@@ -70,7 +78,7 @@ def create(cls, *children, **props) -> BaseUIComponent:
7078

7179

7280
class NavigationMenuList(NavigationMenuBaseComponent):
73-
"""Contains the navigation menu items. Renders a <ul> element."""
81+
"""Contains a list of navigation menu items. Renders a <div> element."""
7482

7583
tag = "NavigationMenu.List"
7684

@@ -86,7 +94,7 @@ def create(cls, *children, **props) -> BaseUIComponent:
8694

8795

8896
class NavigationMenuItem(NavigationMenuBaseComponent):
89-
"""Contains all parts of a navigation menu item. Renders a <li> element."""
97+
"""An individual navigation menu item. Renders a <div> element."""
9098

9199
tag = "NavigationMenu.Item"
92100

@@ -104,7 +112,7 @@ def create(cls, *children, **props) -> BaseUIComponent:
104112

105113

106114
class NavigationMenuTrigger(NavigationMenuBaseComponent):
107-
"""The button that toggles the content. Renders a <button> element."""
115+
"""Opens the navigation menu popup when hovered or clicked, revealing the associated content. Renders a <button> element."""
108116

109117
tag = "NavigationMenu.Trigger"
110118

@@ -123,7 +131,7 @@ def create(cls, *children, **props) -> BaseUIComponent:
123131

124132

125133
class NavigationMenuContent(NavigationMenuBaseComponent):
126-
"""Contains the content associated with each trigger. Renders a <div> element."""
134+
"""A container for the content of the navigation menu item that is moved into the popup when the item is active. Renders a <div> element."""
127135

128136
tag = "NavigationMenu.Content"
129137

@@ -139,7 +147,7 @@ def create(cls, *children, **props) -> BaseUIComponent:
139147

140148

141149
class NavigationMenuLink(NavigationMenuBaseComponent):
142-
"""A navigational link. Renders an <a> element."""
150+
"""A link in the navigation menu that can be used to navigate to a different page or section. Renders an <a> element."""
143151

144152
tag = "NavigationMenu.Link"
145153

@@ -157,7 +165,7 @@ def create(cls, *children, **props) -> BaseUIComponent:
157165

158166

159167
class NavigationMenuIcon(NavigationMenuBaseComponent):
160-
"""An optional icon to render alongside the trigger text. Renders a <span> element."""
168+
"""An icon that indicates that the trigger button opens a menu. Renders a <span> element."""
161169

162170
tag = "NavigationMenu.Icon"
163171

0 commit comments

Comments
 (0)