Skip to content

Commit b67594b

Browse files
committed
navbar
1 parent 91b2c6a commit b67594b

File tree

1 file changed

+243
-53
lines changed

1 file changed

+243
-53
lines changed

pcweb/components/docpage/navbar/navbar.py

Lines changed: 243 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from pcweb.pages.faq import faq
1212
from pcweb.pages.framework.framework import framework
1313
from pcweb.pages.hosting.hosting import hosting_landing
14+
from pcweb.pages.use_cases.finance import finance_use_case_page
1415
from pcweb.pages.use_cases.use_cases import use_cases_page
1516

1617
from ...link_button import resources_button
@@ -64,6 +65,19 @@ def link_item(name: str, url: str, active_str: str = ""):
6465
elif active_str == "hosting" or active_str == "cloud":
6566
active = router_path.contains("cloud") | router_path.contains("hosting")
6667

68+
elif active_str == "products":
69+
is_docs = router_path.contains("docs")
70+
is_open_source_page = router_path.contains("open-source")
71+
not_cloud = ~(router_path.contains("cloud") | router_path.contains("hosting"))
72+
not_ai_builder = ~router_path.contains("ai-builder")
73+
is_framework = (is_docs & not_cloud & not_ai_builder) | is_open_source_page
74+
active = (
75+
router_path.contains("ai-builder")
76+
| router_path.contains("cloud")
77+
| router_path.contains("hosting")
78+
| is_framework
79+
)
80+
6781
elif active_str == "pricing":
6882
active = router_path.contains("pricing")
6983

@@ -344,23 +358,160 @@ def _resource_section_column(
344358
)
345359

346360

361+
def solutions_section():
362+
_app_types_items = [
363+
{
364+
"label": "Internal Tools",
365+
"url": use_cases_page.path,
366+
"icon": "Settings01Icon",
367+
},
368+
{
369+
"label": "Data & AI",
370+
"url": use_cases_page.path,
371+
"icon": "Database02Icon",
372+
},
373+
{
374+
"label": "External Apps",
375+
"url": use_cases_page.path,
376+
"icon": "UserGroupIcon",
377+
},
378+
]
379+
380+
_industries_items = [
381+
{
382+
"label": "Finance",
383+
"url": finance_use_case_page.path,
384+
"icon": "CreditCardPosIcon",
385+
},
386+
{
387+
"label": "Healthcare",
388+
"url": use_cases_page.path,
389+
"icon": "HealthIcon",
390+
},
391+
{
392+
"label": "Consulting",
393+
"url": use_cases_page.path,
394+
"icon": "MentoringIcon",
395+
},
396+
{
397+
"label": "Enterprise",
398+
"url": use_cases_page.path,
399+
"icon": "Building03Icon",
400+
},
401+
]
402+
403+
def _link_button(label: str, url: str, icon: str) -> rx.Component:
404+
return rx.el.a(
405+
resources_button(
406+
ui.icon(icon, size=16, class_name="flex-shrink-0"),
407+
label,
408+
size="md",
409+
variant="transparent",
410+
class_name="justify-start w-full items-center gap-3",
411+
),
412+
to=url,
413+
class_name="w-full",
414+
)
415+
416+
def _solutions_section_column(
417+
section_title: str, solution_item: list[dict[str, str]]
418+
):
419+
return rx.box(
420+
rx.box(
421+
rx.text(
422+
section_title,
423+
class_name="text-sm text-slate-12 font-semibold px-2.5 py-1 pb-2",
424+
),
425+
*[
426+
_link_button(item["label"], item["url"], item["icon"])
427+
for item in solution_item
428+
],
429+
class_name="flex flex-col w-full p-2",
430+
),
431+
class_name="flex flex-col w-full max-w-[9.1875rem]",
432+
)
433+
434+
return ui.navigation_menu.content(
435+
_solutions_section_column("App Types", _app_types_items),
436+
_solutions_section_column("Industries", _industries_items),
437+
# Grid card
438+
rx.box(
439+
rx.el.a(
440+
rx.box(
441+
rx.text(
442+
"Get a personalized demo for your company",
443+
class_name="text-slate-12 text-base font-semibold break-words leading-tight flex-1 min-w-0",
444+
),
445+
rx.el.button(
446+
rx.icon("chevron-right", class_name="text-secondary-11 size-4"),
447+
class_name="size-6 group-hover:bg-secondary-3 transition-colors rounded-md flex items-center justify-center flex-shrink-0 mt-0.5",
448+
),
449+
class_name="flex flex-row items-start gap-2 justify-between mb-1 w-full",
450+
),
451+
rx.text(
452+
"See how Reflex can help your team build apps.",
453+
class_name="text-secondary-11 text-sm font-medium break-words leading-relaxed w-full",
454+
),
455+
to="/pricing",
456+
class_name="w-[16.5rem] h-full rounded-md shadow-small bg-white-1 dark:bg-m-slate-14 border border-slate-4 dark:border-m-slate-12 flex flex-col gap-2.5 pt-6 pb-6 pl-5 pr-6 relative border-solid group overflow-hidden",
457+
),
458+
class_name="flex flex-col pt-4 pb-2 pl-3 pr-6 flex-shrink-0 overflow-hidden h-full",
459+
),
460+
unstyled=True,
461+
class_name=ui.cn(
462+
ui.navigation_menu.class_names.CONTENT,
463+
"flex flex-row gap-4 rounded-xl w-[37rem] font-sans overflow-hidden pt-1.5 pb-1.5 pl-1.5 pr-3",
464+
),
465+
)
466+
467+
347468
def new_menu_trigger(
348469
title: str, url: str | None = None, active_str: str = ""
349470
) -> rx.Component:
350471
if url:
351472
return ui.navigation_menu.trigger(link_item(title, url, active_str))
473+
474+
router_path = rx.State.router.page.path
475+
active = False
476+
477+
if active_str == "products":
478+
is_docs = router_path.contains("docs")
479+
is_open_source_page = router_path.contains("open-source")
480+
not_cloud = ~(router_path.contains("cloud") | router_path.contains("hosting"))
481+
not_ai_builder = ~router_path.contains("ai-builder")
482+
is_framework = (is_docs & not_cloud & not_ai_builder) | is_open_source_page
483+
active = (
484+
router_path.contains("ai-builder")
485+
| router_path.contains("cloud")
486+
| router_path.contains("hosting")
487+
| is_framework
488+
)
489+
elif active_str:
490+
active = router_path.contains(active_str)
491+
492+
common_cn = "p-[1.406rem_0px] font-medium text-sm transition-colors"
493+
active_cn = "shadow-[inset_0_-0.5px_0_0_var(--c-violet-9)] text-violet-9 group-hover:text-violet-9"
494+
unactive_cn = "shadow-none text-secondary-11 group-hover:text-secondary-12"
495+
352496
return ui.navigation_menu.trigger(
353497
rx.box(
354498
rx.text(
355499
title,
356-
class_name="p-[1.406rem_0px] font-medium text-sm text-secondary-11 group-hover:text-secondary-12 transition-colors",
500+
class_name=common_cn + " " + rx.cond(active, active_cn, unactive_cn),
357501
),
358502
rx.icon(
359503
"chevron-down",
360-
class_name="chevron size-5 !text-secondary-11 group-hover:!text-secondary-12 py-1 mr-0 transition-all ease-out",
504+
class_name=rx.cond(
505+
active,
506+
"chevron size-5 !text-violet-9 group-hover:!text-violet-9 py-1 mr-0 transition-all ease-out",
507+
"chevron size-5 !text-secondary-11 group-hover:!text-secondary-12 py-1 mr-0 transition-all ease-out",
508+
),
361509
aria_hidden="true",
362510
),
363-
class_name="flex-row items-center gap-x-1 group user-select-none cursor-pointer xl:flex hidden",
511+
class_name=ui.cn(
512+
"flex-row items-center gap-x-1 group user-select-none cursor-pointer xl:flex hidden",
513+
common_cn,
514+
),
364515
on_click=rx.stop_propagation,
365516
),
366517
style={
@@ -419,10 +570,85 @@ def doc_section():
419570
)
420571

421572

422-
def new_component_section() -> rx.Component:
573+
def products_section():
423574
from pcweb.pages.docs import ai_builder as ai_builder_pages
424575
from pcweb.pages.docs import hosting as hosting_page
425576

577+
return rx.cond(
578+
rx.State.router.page.path.contains("docs")
579+
| rx.State.router.page.path.contains("ai-builder")
580+
| rx.State.router.page.path.contains("cloud"),
581+
ui.navigation_menu.content(
582+
resource_item(
583+
"AI Builder",
584+
ai_builder_pages.overview.best_practices.path,
585+
"MagicWand01Icon",
586+
0,
587+
),
588+
resource_item(
589+
"Open Source",
590+
getting_started.introduction.path,
591+
"SourceCodeCircleIcon",
592+
0,
593+
),
594+
resource_item(
595+
"Cloud",
596+
hosting_page.deploy_quick_start.path,
597+
"CloudServerIcon",
598+
0,
599+
),
600+
unstyled=True,
601+
class_name=ui.cn(
602+
ui.navigation_menu.class_names.CONTENT,
603+
"flex flex-col gap-1.5 m-0 p-1.5 w-[280px] min-w-max h-auto",
604+
),
605+
),
606+
ui.navigation_menu.content(
607+
rx.el.a(
608+
rx.box(
609+
ui.icon(
610+
"MagicWand01Icon",
611+
size=16,
612+
class_name="flex-shrink-0 text-secondary-11",
613+
),
614+
rx.text(
615+
"AI Builder",
616+
class_name="font-small text-secondary-11 truncate text-start w-[150px]",
617+
),
618+
rx.icon(
619+
tag="chevron_right",
620+
size=14,
621+
stroke_width=2,
622+
class_name="flex-shrink-0 text-slate-8 ml-auto",
623+
),
624+
class_name="flex flex-row flex-nowrap items-center gap-4 hover:bg-secondary-3 px-[1.125rem] py-2 rounded-md w-full transition-colors",
625+
),
626+
class_name="w-full text-secondary-11 hover:text-secondary-11",
627+
href=REFLEX_BUILD_URL,
628+
is_external=True,
629+
),
630+
resource_item(
631+
"Open Source",
632+
framework.path,
633+
"SourceCodeCircleIcon",
634+
0,
635+
),
636+
resource_item(
637+
"Cloud",
638+
hosting_landing.path,
639+
"CloudServerIcon",
640+
0,
641+
),
642+
unstyled=True,
643+
class_name=ui.cn(
644+
ui.navigation_menu.class_names.CONTENT,
645+
"flex flex-col gap-1.5 m-0 p-1.5 w-[280px] min-w-max h-auto",
646+
),
647+
),
648+
)
649+
650+
651+
def new_component_section() -> rx.Component:
426652
return ui.navigation_menu.root(
427653
ui.navigation_menu.list(
428654
ui.navigation_menu.item(
@@ -446,56 +672,14 @@ def new_component_section() -> rx.Component:
446672
unstyled=True,
447673
),
448674
),
449-
rx.cond(
450-
rx.State.router.page.path.contains("docs")
451-
| rx.State.router.page.path.contains("ai-builder")
452-
| rx.State.router.page.path.contains("cloud"),
453-
ui.navigation_menu.list(
454-
ui.navigation_menu.item(
455-
render_=link_item(
456-
"AI Builder",
457-
ai_builder_pages.overview.best_practices.path,
458-
"builder",
459-
),
460-
unstyled=True,
461-
),
462-
ui.navigation_menu.item(
463-
render_=link_item(
464-
"Open Source",
465-
getting_started.introduction.path,
466-
"framework",
467-
),
468-
unstyled=True,
469-
class_name="whitespace-nowrap",
470-
),
471-
ui.navigation_menu.item(
472-
render_=link_item(
473-
"Cloud", hosting_page.deploy_quick_start.path, "hosting"
474-
),
475-
unstyled=True,
476-
),
477-
class_name="xl:flex hidden flex-row items-center gap-0 lg:gap-5 2xl:gap-7 m-0 h-full list-none",
478-
),
479-
ui.navigation_menu.list(
480-
ui.navigation_menu.item(
481-
render_=link_item(
482-
"AI Builder",
483-
REFLEX_BUILD_URL,
484-
"builder",
485-
),
486-
unstyled=True,
487-
),
488-
ui.navigation_menu.item(
489-
render_=link_item("Open Source", framework.path, "framework"),
490-
class_name="whitespace-nowrap",
491-
unstyled=True,
492-
),
493-
ui.navigation_menu.item(
494-
render_=link_item("Cloud", hosting_landing.path, "hosting"),
495-
unstyled=True,
496-
),
497-
class_name="xl:flex hidden flex-row items-center gap-0 lg:gap-5 2xl:gap-7 m-0 h-full list-none",
675+
ui.navigation_menu.list(
676+
ui.navigation_menu.item(
677+
new_menu_trigger("Product", active_str="products"),
678+
products_section(),
679+
class_name="cursor-pointer",
680+
unstyled=True,
498681
),
682+
class_name="xl:flex hidden flex-row items-center gap-0 lg:gap-5 2xl:gap-7 m-0 h-full list-none",
499683
),
500684
ui.navigation_menu.item(
501685
new_menu_trigger("Docs"),
@@ -516,6 +700,12 @@ def new_component_section() -> rx.Component:
516700
class_name="cursor-pointer",
517701
unstyled=True,
518702
),
703+
ui.navigation_menu.item(
704+
new_menu_trigger("Solutions", active_str="use-cases"),
705+
solutions_section(),
706+
class_name="cursor-pointer",
707+
unstyled=True,
708+
),
519709
ui.navigation_menu.item(
520710
ui.navigation_menu.item(
521711
render_=link_item(

0 commit comments

Comments
 (0)