7575from xy_docs .sidebar import (
7676 CHART_FAMILY_SIDEBAR_SECTIONS ,
7777 CHART_GALLERY_SIDEBAR_LINK ,
78- INTEGRATION_LINK_ICONS ,
7978 PIE_DOCS_ROUTE ,
8079 POLAR_DOCS_ROUTE ,
8180 POLAR_DOCS_ROUTES ,
9493import xy
9594from xy .components import _MARK_APPLIERS , _POLAR_INERT_AXIS_KEYWORDS
9695
97- SITEMAP_NAMESPACE = {"sitemap" : "https://www.sitemaps.org/schemas/sitemap/0.9" }
9896DOCS_APP_ROOT = Path (__file__ ).resolve ().parent .parent
9997DOCS_ROOT = DOCS_APP_ROOT .parent
10098EXPORTED_SITEMAP = DOCS_APP_ROOT / ".web" / "public" / "sitemap.xml"
@@ -179,7 +177,9 @@ def _sitemap_routes(sitemap_path: Path) -> set[str]:
179177 root = ET .parse (sitemap_path ).getroot ()
180178 return {
181179 route
182- for location in root .findall ("sitemap:url/sitemap:loc" , SITEMAP_NAMESPACE )
180+ for location in root .findall (
181+ "{http://www.sitemaps.org/schemas/sitemap/0.9}url/{http://www.sitemaps.org/schemas/sitemap/0.9}loc"
182+ )
183183 if location .text is not None
184184 if (route := _normalize_xy_docs_path (location .text .strip ())) is not None
185185 }
@@ -838,8 +838,8 @@ def test_sdf_plot_grid_is_cached_and_uses_reflex_toolbar_tokens() -> None:
838838
839839 rendered = str (xy_sdf_plot_grid (config ))
840840 expected_tokens = {
841- "--chart-text" : "var(--secondary-11 )" ,
842- "--chart-focus" : "var(--primary-9 )" ,
841+ "--chart-text" : "var(--muted-foreground )" ,
842+ "--chart-focus" : "var(--ring )" ,
843843 }
844844
845845 for name , value in expected_tokens .items ():
@@ -1610,14 +1610,14 @@ def test_chart_gallery_grid_renders_every_type_as_inline_svg(
16101610 assert rendered .count ("max-width: 88rem" ) == 1
16111611 assert rendered .count ("2xl:grid-cols-3" ) == 9
16121612 assert rendered .count ("aspect-[320/232]" ) == 35
1613- assert rendered .count ("shadow-large " ) == 35
1613+ assert rendered .count ("shadow-small " ) == 35
16141614 assert rendered .count ("transition-bg" ) == 35
1615- assert "--gallery-preview-surface: #fff " in rendered
1616- assert "--gallery-preview-fill: #efeaff " in rendered
1617- assert "--gallery-preview-soft: #dccfff " in rendered
1618- assert "--gallery-preview-bar: #dccfff " in rendered
1619- assert "--gallery-preview-stroke: #a790f0 " in rendered
1620- assert "--gallery-preview-strong: #8067d7 " in rendered
1615+ assert "--gallery-preview-surface: var(--muted) " in rendered
1616+ assert "--gallery-preview-fill: var(--accent) " in rendered
1617+ assert "--gallery-preview-soft: var(--border) " in rendered
1618+ assert "--gallery-preview-bar: var(--subtle-foreground) " in rendered
1619+ assert "--gallery-preview-stroke: var(--muted-foreground) " in rendered
1620+ assert "--gallery-preview-strong: var(--foreground) " in rendered
16211621 assert "--gallery-preview-muted" not in rendered
16221622 assert "object-contain" not in rendered
16231623 assert "object-center" not in rendered
@@ -2151,7 +2151,7 @@ def test_inline_svg_gallery_validator_requires_every_styled_preview(tmp_path: Pa
21512151 """Accept only the complete code-native gallery in the production route."""
21522152 module_path = tmp_path / "route.jsx"
21532153 preview = 'viewBox=\\ "0 0 320 232\\ "'
2154- surface = "gallery-preview-surface aspect-[320/232] shadow-large "
2154+ surface = "gallery-preview-surface aspect-[320/232] shadow-small "
21552155 expected = check_html_routes .INLINE_SVG_PREVIEW_COUNT
21562156 module_path .write_text (preview * expected + surface , encoding = "utf-8" )
21572157
@@ -2238,7 +2238,7 @@ def test_xy_sidebar_reuses_memoized_official_navigation_rows() -> None:
22382238
22392239 assert "/core-concepts/axes-and-scales/" in instance
22402240 assert re .findall (
2241- r'jsx\(RadixThemesText,\{as:"p",className:"m-0 text-sm font-\[525 \]"\},"([^"]+)"\)' ,
2241+ r'jsx\(RadixThemesText,\{as:"p",className:"m-0 text-sm font-\[475 \]"\},"([^"]+)"\)' ,
22422242 rendered ,
22432243 ) == [
22442244 row_title
@@ -2263,22 +2263,26 @@ def test_xy_sidebar_reuses_memoized_official_navigation_rows() -> None:
22632263 title != "Integrations" and bool (leaves )
22642264 for title , _landing_route , _icon , leaves in grouped_sections
22652265 )
2266- direct_link_count = len (INTEGRATION_LINK_ICONS ) + 1
2266+ direct_link_count = sum (
2267+ len (leaves ) if title == "Integrations" else int (not leaves )
2268+ for title , _landing_route , _icon , leaves in grouped_sections
2269+ )
2270+
22672271 assert rendered .count ('jsx("details"' ) == accordion_count
22682272 assert rendered .count ('jsx("summary"' ) == accordion_count
22692273 assert rendered .count ("group/details" ) == accordion_count
22702274 assert rendered .count ("guideMarginClass" ) == expected_leaf_count
22712275 assert (
22722276 rendered .count (
2273- "absolute left-0 top-1/2 -z-10 h-8 w-full -translate-y-1/2 rounded-lg bg-secondary-3 "
2277+ "absolute left-0 top-1/2 -z-10 h-8 w-full -translate-y-1/2 rounded-lg bg-accent "
22742278 )
22752279 == direct_link_count
22762280 )
22772281 assert (
22782282 rendered .count (
22792283 "ml-[2.5rem] flex h-8 w-[calc(100%-2.5rem)] items-center "
2280- "justify-start text-secondary-11 transition-colors "
2281- "group-hover:text-primary-10 dark:group-hover:text-primary-9 "
2284+ "justify-start text-muted-foreground transition-colors "
2285+ "group-hover:text-primary-hover dark:group-hover:text-primary "
22822286 "xl:max-w-[14rem]"
22832287 )
22842288 == direct_link_count
@@ -2374,7 +2378,7 @@ def test_xy_sidebar_reuses_memoized_official_navigation_rows() -> None:
23742378 "LucideNotebookTabs" ,
23752379 "LucideChartNoAxesCombined" ,
23762380 ):
2377- assert icon in rendered
2381+ assert icon not in rendered
23782382 assert "LucidePlug" not in rendered
23792383 assert rendered .count ('"aria-current":((' ) == direct_link_count
23802384 assert ">XY<" not in rendered
@@ -2400,12 +2404,13 @@ def test_xy_sidebar_opens_only_the_current_chart_family(
24002404 chart_families = (* CHART_FAMILY_SIDEBAR_SECTIONS , POLAR_SIDEBAR_SECTION )
24012405 open_groups = [
24022406 title
2403- for title , landing_route , icon , leaves in chart_families
2404- if "open:true" in str (_section_items (title , landing_route , icon , leaves , route )[0 ])
2407+ for title , landing_route , _icon , leaves in chart_families
2408+ if "open:true" in str (_section_items (title , landing_route , leaves , route )[0 ])
24052409 ]
24062410
24072411 assert open_groups == ([] if expected_open_group is None else [expected_open_group ])
2408- gallery_link = str (_section_items (* CHART_GALLERY_SIDEBAR_LINK , route )[0 ])
2412+ title , landing_route , _icon , leaves = CHART_GALLERY_SIDEBAR_LINK
2413+ gallery_link = str (_section_items (title , landing_route , leaves , route )[0 ])
24092414 assert 'jsx("details"' not in gallery_link
24102415 assert ('"aria-current":(true ? "page"' in gallery_link ) == (
24112416 route == CHART_GALLERY_SIDEBAR_LINK [1 ]
@@ -2419,11 +2424,12 @@ def test_xy_navbar_uses_xy_links_github_and_the_official_drawer() -> None:
24192424
24202425 rendered = str (xy_docs_navbar ._definition .component )
24212426
2422- assert 'href :"/"' in rendered
2427+ assert 'to :"/"' in rendered
24232428 assert '"aria-label":"Reflex XY"' in rendered
24242429 assert "M29 16H32V10H39V7H32V4H39V1H29V16" in rendered
2425- assert 'href:"/docs/xy/"' in rendered
2426- assert 'href:"/docs/xy/integrations/reflex/"' in rendered
2430+ assert 'to:"/"' in rendered
2431+ assert 'href:"/docs/"' in rendered
2432+ assert 'to:"/integrations/reflex/"' in rendered
24272433 assert "Overview" in rendered
24282434 assert "Reflex Integration" in rendered
24292435 assert 'variant:"ghost"},"Build with AI"' not in rendered
@@ -2434,18 +2440,21 @@ def test_xy_navbar_uses_xy_links_github_and_the_official_drawer() -> None:
24342440 assert "Discord Community" not in rendered
24352441 assert 'variant:"primary"' in rendered
24362442 assert "View XY on GitHub -" not in rendered
2437- assert rendered .count ("View XY on GitHub" ) == 2
2443+ assert rendered .count ("View XY on GitHub" ) == 4
24382444 assert 'target:"_blank"' in rendered
24392445 assert 'rel:"noopener noreferrer"' in rendered
2440- assert "Open sidebar" in rendered
2446+ from xy_docs .navbar import _mobile_navigation
2447+
2448+ assert str (_mobile_navigation ()) in rendered
24412449 assert "Menu01Icon" in rendered
24422450 assert "Cancel01Icon" in rendered
24432451 assert "Mobile documentation navigation" not in rendered
24442452 assert "<details" not in rendered
24452453 assert "<summary" not in rendered
24462454 assert XY_REPOSITORY_URL in rendered
2447- assert "XY's initial launch is here" in rendered
2448- assert "Get started" in rendered
2455+ from reflex_site_shared .views .hosting_banner import hosting_banner
2456+
2457+ assert str (hosting_banner ()) in rendered
24492458 assert "Reserve your spot" not in rendered
24502459 assert "https://luma.com/a1ty77bt" not in rendered
24512460 assert "Reflex Agent Toolkit is launching" not in rendered
@@ -2982,3 +2991,78 @@ def test_documented_factories_describe_every_parameter() -> None:
29822991 "Chart" ,
29832992 parameter .name ,
29842993 )
2994+
2995+
2996+ def test_xy_navbar_uses_early_mobile_breakpoint_and_current_section () -> None :
2997+ """Keep section selection accessible and desktop links hidden below 1280px."""
2998+ from xy_docs .navbar import _menu_item , _navigation_menu
2999+
3000+ menu = _navigation_menu ()
3001+ assert "hidden xl:flex" in str (menu .children [0 ].class_name )
3002+ assert "xl:hidden" in str (menu .children [1 ].children [- 1 ].class_name )
3003+ link = _menu_item ("Overview" , "/docs/xy/" ).children [0 ]
3004+ assert '"aria-current"' in str (link )
3005+
3006+
3007+ def test_xy_navbar_internal_links_preserve_client_navigation () -> None :
3008+ """Internal section changes keep the document and announcement mounted."""
3009+ from xy_docs .navbar import _menu_item
3010+
3011+ item = _menu_item ("Reflex Integration" , "/docs/xy/integrations/reflex/" )
3012+ assert type (item .children [0 ]).__name__ == "ReactRouterLink"
3013+ assert str (item .children [0 ].to ).strip ('"' ) == "/integrations/reflex/"
3014+ assert "inset_0_-1px" not in str (item .class_name )
3015+
3016+
3017+ def test_xy_code_blocks_use_shared_docs_syntax_theme () -> None :
3018+ """Normal and demo code use the same syntax palette as Reflex docs."""
3019+ from xy_docs .code import code_block
3020+
3021+ rendered = str (code_block ("print('hello')" , "python" ))
3022+ assert "github-light-high-contrast" in rendered
3023+ assert "github-dark-high-contrast" in rendered
3024+
3025+
3026+ @pytest .mark .parametrize (
3027+ ("namespace" , "accepted" ),
3028+ [
3029+ ("http://www.sitemaps.org/schemas/sitemap/0.9" , True ),
3030+ ("https://www.sitemaps.org/schemas/sitemap/0.9" , False ),
3031+ ("https://example.com/invalid" , False ),
3032+ ("" , False ),
3033+ ],
3034+ )
3035+ def test_sitemap_validator_requires_standard_namespace (
3036+ tmp_path : Path , namespace : str , accepted : bool
3037+ ) -> None :
3038+ """Only sitemap elements in the standard HTTP namespace supply locations."""
3039+ import runpy
3040+
3041+ sitemap_locations = runpy .run_path (str (DOCS_APP_ROOT / "scripts/check_sitemap.py" ))[
3042+ "sitemap_locations"
3043+ ]
3044+
3045+ path = tmp_path / "sitemap.xml"
3046+ location = "https://reflex.dev/docs/xy/"
3047+ path .write_text (f'<urlset xmlns="{ namespace } "><url><loc>{ location } </loc></url></urlset>' )
3048+ assert sitemap_locations (path ) == ([location ] if accepted else [])
3049+
3050+
3051+ @pytest .mark .parametrize (
3052+ "path" , ["/" , "/index" , "/overview/installation/" , "/docs/xy/overview/installation/" ]
3053+ )
3054+ def test_overview_navbar_marks_child_routes_current (
3055+ monkeypatch : pytest .MonkeyPatch , path : str
3056+ ) -> None :
3057+ """Overview descendants retain the active section indicator."""
3058+ from types import SimpleNamespace
3059+
3060+ import reflex as rx
3061+ from xy_docs .navbar import _menu_item
3062+
3063+ monkeypatch .setattr (
3064+ rx , "State" , SimpleNamespace (router = SimpleNamespace (page = SimpleNamespace (path = path )))
3065+ )
3066+ item = _menu_item ("Overview" , "/docs/xy/" )
3067+ assert '"aria-current":(true ? "page" : null)' in str (item .children [0 ])
3068+ assert "inset_0_-1px" not in str (item .class_name )
0 commit comments