Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/ai_builder/overview/best_practices.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Reflex Build: Best Practices

> A comprehensive guide to working effectively with AI Builder. This guide outlines how to get the most reliable and efficient results when working with the AI Builder inside Reflex Build. The key to success is clarity, structure, and iteration.
A comprehensive guide to working effectively with AI Builder. This guide outlines how to get the most reliable and efficient results when working with the AI Builder inside Reflex Build. The key to success is clarity, structure, and iteration.

---

Expand Down
31 changes: 19 additions & 12 deletions docs/app/reflex_docs/docgen_pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -335,8 +335,11 @@ def transform_list_item(self, item: ListItem) -> rx.Component:
def quote(self, block: QuoteBlock) -> rx.Component:
children = [self.transform_block(b) for b in block.children]
return rx.box(
*children,
class_name="border-l-[3px] border-slate-4 pl-6 mt-2 mb-6",
rx.box(
*children,
padding_left="2rem",
),
class_name="border-l-[3px] border-slate-4 mt-2 mb-6",
)

def table(self, block: TableBlock) -> rx.Component:
Expand Down Expand Up @@ -654,18 +657,22 @@ def _render_quote_directive(self, block: DirectiveBlock) -> rx.Component:
role = text.split(":", 1)[1].strip()

return rx.box(
rx.text(
'"',
*quote_parts,
'"',
class_name="text-slate-11 font-base italic",
),
rx.box(
rx.text(name, class_name="text-slate-11 font-base"),
rx.text(role, class_name="text-slate-10 font-base"),
class_name="flex flex-col gap-0.5",
rx.text(
'"',
*quote_parts,
'"',
class_name="text-slate-11 font-base italic",
),
rx.box(
rx.text(name, class_name="text-slate-11 font-base"),
rx.text(role, class_name="text-slate-10 font-base"),
class_name="flex flex-col gap-0.5",
),
padding_left="2rem",
class_name="flex flex-col gap-4",
),
class_name="flex flex-col gap-4 border-l-[3px] border-slate-4 pl-6 mt-2 mb-6",
class_name="flex flex-col gap-4 border-l-[3px] border-slate-4 mt-2 mb-6",
)

def _render_tabs(self, block: DirectiveBlock) -> rx.Component:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ def ai_builder_section() -> rx.Component:
src=f"{REFLEX_ASSETS_CDN}docs/{rx.color_mode_cond('light', 'dark')}/getting_started.svg",
class_name="w-full h-auto pb-8",
),
href=ai_builder_pages.overview.best_practices.path,
href=ai_builder_pages.overview.what_is_reflex_build.path,
),
card(
title="Integrations",
Expand Down
10 changes: 9 additions & 1 deletion docs/app/reflex_docs/templates/docpage/docpage.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@
from reflex_site_shared.utils.docpage import right_sidebar_item_highlight
from reflex_site_shared.views.footer import dark_mode_toggle

ACRONYMS = {"ai": "AI", "api": "API", "cli": "CLI", "ide": "IDE", "mcp": "MCP"}


def format_title_with_acronyms(text: str) -> str:
"""Format title-cased text while preserving known acronyms."""
title = to_title_case(to_snake_case(text), sep=" ")
return " ".join(ACRONYMS.get(word.lower(), word) for word in title.split(" "))


class FeedbackState(rx.State):
"""Minimal stub for feedback buttons (full implementation removed)."""
Expand Down Expand Up @@ -586,7 +594,7 @@ def breadcrumb(path: str, nav_sidebar: rx.Component, doc_content: str | None = N
# Add the breadcrumb item to the list
breadcrumbs.append(
rx.el.a(
to_title_case(to_snake_case(segment), sep=" "),
format_title_with_acronyms(segment),
class_name="min-h-8 flex items-center text-sm font-[525] text-m-slate-12 dark:text-m-slate-3 last:text-m-slate-7 dark:last:text-m-slate-6 hover:text-primary-10 dark:hover:text-primary-9"
+ (" truncate" if i == len(segments) - 1 else ""),
underline="none",
Expand Down
23 changes: 9 additions & 14 deletions docs/app/reflex_docs/templates/docpage/sidebar/sidebar.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,25 +243,20 @@ def calculate_index(sidebar_items, url: str) -> list[int]:
sidebar_items = (
sidebar_items if isinstance(sidebar_items, list) else [sidebar_items]
)
index_list = []

if not url:
return index_list
return []

url = url.rstrip("/") + "/"
for item in sidebar_items:
item.link = item.link.rstrip("/") + "/"
sub = 0
for i, item in enumerate(sidebar_items):
if not item.children:
sub += 1
if item.link == url:
return [i - sub]
item_link = item.link.rstrip("/") + "/" if item.link else ""
if item_link == url:
return [i]
index = calculate_index(item.children, url)
if index:
return [i - sub, *index]
return [i, *index]

return index_list
return []


def append_to_items(items, flat_items):
Expand Down Expand Up @@ -434,7 +429,7 @@ def sidebar_comp(
from reflex_docs.pages.docs.library import library
from reflex_docs.pages.docs.recipes_overview import overview

_path = rx.State.router.page.path
_path = rx.State.router.page.raw_path
_is_docs_hosting = _path.startswith("/docs/hosting/") | _path.startswith(
"/hosting/"
)
Expand All @@ -458,7 +453,7 @@ def sidebar_comp(
rx.el.ul(
sidebar_category(
"AI Builder",
ai_builder_pages.overview.best_practices.path,
ai_builder_pages.overview.what_is_reflex_build.path,
"bot",
0,
),
Expand Down Expand Up @@ -546,7 +541,7 @@ def sidebar_comp(
rx.el.ul(
create_sidebar_section(
"Overview",
ai_builder_pages.overview.best_practices.path,
ai_builder_pages.overview.what_is_reflex_build.path,
ai_builder_overview_items,
ai_builder_overview_index,
url,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ def get_sidebar_items_ai_builder_overview():
create_item(
"Overview",
children=[
ai_builder.overview.best_practices,
ai_builder.overview.what_is_reflex_build,
ai_builder.overview.best_practices,
ai_builder.overview.tutorial,
ai_builder.overview.templates,
],
Expand Down
22 changes: 18 additions & 4 deletions docs/app/reflex_docs/views/docs_navbar.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,19 +65,29 @@ def logo() -> rx.Component:


def menu_item(text: str, href: str, active_str: str = "") -> rx.Component:
router_path = rx.State.router.page.path
router_path = rx.State.router.page.raw_path
active_cn = "shadow-[inset_0_-1px_0_0_var(--primary-10)] [&_button]:text-primary-10 [&_div]:text-primary-10"

# For paths starting with "/" (like Start), use exact match
# For "framework", it's the default - active when in /docs but not matching other sections
# For other segments (like "ai"), use contains
if active_str.startswith("/"):
if active_str == "/":
active = (router_path == "/") | (router_path == "/index")
active = (
(router_path == "/")
| (router_path == "/index")
| (router_path == "/docs")
| (router_path == "/docs/")
)
else:
active = router_path == active_str
elif active_str == "framework":
is_overview = (router_path == "/") | (router_path == "/index")
is_overview = (
(router_path == "/")
| (router_path == "/index")
| (router_path == "/docs")
| (router_path == "/docs/")
)
is_ai_builder = router_path.startswith("/ai/") | router_path.startswith(
"/docs/ai/"
)
Expand Down Expand Up @@ -110,7 +120,11 @@ def navigation_menu() -> rx.Component:
return ui.navigation_menu.root(
ui.navigation_menu.list(
menu_item("Overview", "/", "/"),
menu_item("Build with AI", ai_builder.overview.best_practices.path, "ai"),
menu_item(
"Build with AI",
ai_builder.overview.what_is_reflex_build.path,
"ai",
),
menu_item("Framework", getting_started.introduction.path, "framework"),
menu_item("Cloud", hosting.deploy_quick_start.path, "hosting"),
class_name="flex flex-row items-center gap-2 m-0 h-full list-none",
Expand Down
42 changes: 42 additions & 0 deletions docs/app/tests/test_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,45 @@ def test_ai_builder_routes_use_ai_prefix(routes_fixture):
assert "/ai-builder/integrations/ai-onboarding/" not in paths
assert "/ai-builder/integrations/mcp-overview/" not in paths
assert "/ai-builder/integrations/skills/" not in paths


def test_ai_overview_sidebar_order_and_active_index():
from reflex_docs.pages.docs import ai_builder
from reflex_docs.templates.docpage.sidebar.sidebar import calculate_index
from reflex_docs.templates.docpage.sidebar.sidebar_items.ai import (
ai_builder_overview_items,
)

overview_children = ai_builder_overview_items[0].children

assert overview_children[0].link == ai_builder.overview.what_is_reflex_build.path
assert overview_children[1].link == ai_builder.overview.best_practices.path
assert (
calculate_index(
ai_builder_overview_items,
ai_builder.overview.best_practices.path,
)
== [0, 1]
)


def test_sidebar_index_matches_rendered_item_positions():
from reflex_docs.templates.docpage.sidebar.sidebar import calculate_index
from reflex_docs.templates.docpage.sidebar.state import SideBarItem

items = [
SideBarItem(names="Intro", link="/intro/"),
SideBarItem(
names="Group",
children=[SideBarItem(names="Target", link="/target/")],
),
]

assert calculate_index(items, "/target/") == [1, 0]


def test_breadcrumb_titles_preserve_acronyms():
from reflex_docs.templates.docpage.docpage import format_title_with_acronyms

assert format_title_with_acronyms("ai") == "AI"
assert format_title_with_acronyms("mcp-overview") == "MCP Overview"
Loading