# -*- coding: utf-8 -*- """ 渲染框架相关组件 """ import reflex as rx from application.state.frame import FrameState # 初始化侧边栏图标导航按钮字典 sidebar_icon_nav_buttons = { "conversation": {"icon": "message-circle-more", "text": "对话"}, "knowledge_base": {"icon": "book-open", "text": "知识库"}, } def render_brand_logo(width: str = "24px", height: str = "24px") -> rx.Component: """ 渲染品牌 Logo :param width: 宽度,默认为 24px :param height: 高度,默认为 24px """ return rx.image( src="/assets/logo.png", width=width, height=height, object_fit="contain", # 等比缩放 ) def render_sidebar_icon_nav_button( sidebar_icon_nav_button: str, ) -> rx.Component: """ 渲染侧边栏图标导航按钮 :param sidebar_icon_nav_button: 侧边栏图标导航按钮 """ # 侧边栏图标导航按钮图标 icon = sidebar_icon_nav_buttons[sidebar_icon_nav_button]["icon"] # 侧边栏图标导航按钮标签 text = sidebar_icon_nav_buttons[sidebar_icon_nav_button]["text"] # 若选中侧边栏图标导航按钮图标非指定图标导航按钮图标则正常渲染,否则高亮渲染 return rx.cond( FrameState.sidebar_icon_nav_button != sidebar_icon_nav_button, # 正常渲染 rx.button( rx.vstack( rx.icon(icon, size=18), rx.text(text, font_size="10px"), spacing="2", align_items="center", ), width="100%", justify_content="center", variant="surface", color_scheme="blue", on_click=lambda: FrameState.switch_active_sidebar_tab( sidebar_icon_nav_button ), padding_y="10px", ), # 高亮渲染 rx.button( rx.vstack( rx.icon(icon, size=18), rx.text(text, size="8"), spacing="2", align_items="center", ), width="100%", justify_content="center", variant="soft", color_scheme="blue", padding_y="10px", ), ) def render_sidebar() -> rx.Component: """ 渲染侧边栏 """ return rx.box( rx.vstack( # 顶部 rx.vstack( # 品牌LOGO和名称 rx.vstack( # 渲染品牌 Logo render_brand_logo(), rx.text( "MarsHelper", font_size="18px", weight="bold", color=rx.color("mauve", 12), ), spacing="4", margin_bottom="16px", ), # 分隔线 rx.divider(color=rx.color("mauve", 3), margin_bottom="16px"), # 渲染侧边栏图标导航按钮:对话 render_sidebar_icon_nav_button("conversation"), # 渲染侧边栏图标导航按钮:知识库 render_sidebar_icon_nav_button("knowledge_base"), spacing="6", # 垂直间距 ), width="80px", height="100vh", padding_y="20px", # 水平内边距 padding_x="8px", # 垂直内边距 align_items="stretch", justify_content="space-between", ), width="80px", min_width="80px", background="transparent", # 透明背景 position="sticky", # 粘性定位 top=0, # 页面滚动时侧边栏固定于顶部 )