1111from pcweb .pages .faq import faq
1212from pcweb .pages .framework .framework import framework
1313from pcweb .pages .hosting .hosting import hosting_landing
14+ from pcweb .pages .use_cases .finance import finance_use_case_page
1415from pcweb .pages .use_cases .use_cases import use_cases_page
1516
1617from ...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+
347468def 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