Skip to content
Open
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
31 changes: 26 additions & 5 deletions native/templates/_intro.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,35 @@

from components.core.hugeicon import hi
from components.ui.button import button, button_variants
from native.registry.components import COMPONENT_REGISTRY
from native.templates._copy_btn import generate_component_id

COPY_ICON_SVG = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" color="currentColor" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M9 15C9 12.1716 9 10.7574 9.87868 9.87868C10.7574 9 12.1716 9 15 9L16 9C18.8284 9 20.2426 9 21.1213 9.87868C22 10.7574 22 12.1716 22 15V16C22 18.8284 22 20.2426 21.1213 21.1213C20.2426 22 18.8284 22 16 22H15C12.1716 22 10.7574 22 9.87868 21.1213C9 20.2426 9 18.8284 9 16L9 15Z"/><path d="M16.9999 9C16.9975 6.04291 16.9528 4.51121 16.092 3.46243C15.9258 3.25989 15.7401 3.07418 15.5376 2.90796C14.4312 2 12.7875 2 9.5 2C6.21252 2 4.56878 2 3.46243 2.90796C3.25989 3.07417 3.07418 3.25989 2.90796 3.46243C2 4.56878 2 6.21252 2 9.5C2 12.7875 2 14.4312 2.90796 15.5376C3.07417 15.7401 3.25989 15.9258 3.46243 16.092C4.51121 16.9528 6.04291 16.9975 9 16.9999"/></svg>'
TICK_ICON_SVG = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" color="currentColor" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M5 14.5C5 14.5 6.5 14.5 8.5 18C8.5 18 14.0588 8.83333 19 7"/></svg>'


def _usage_demo(slug: str):
demo_id = generate_component_id()
icon_id = f"icon-{demo_id}"

commands = {
"buridan": f"buridan add {slug}",
"uv": f"uv run buridan add {slug}",
"pip": f"python -m buridan add {slug}",
}
return _install_block(commands)


def _init_demo():
"""Install block for utilities shipped via `buridan init` (no registry entry)."""
commands = {
"buridan": "buridan init",
"uv": "uv run buridan init",
"pip": "python -m buridan init",
}
return _install_block(commands)


def _install_block(commands: dict[str, str]):
demo_id = generate_component_id()
icon_id = f"icon-{demo_id}"

def view_button(view: str, label: str):
return button(
Expand Down Expand Up @@ -101,6 +115,13 @@ def intro(raw_arg):
title, description = intro.split(",", 1)
slug = title.strip().lower().replace(" ", "_")

if slug in COMPONENT_REGISTRY:
install_block = _usage_demo(slug)
noun = "component"
else:
install_block = _init_demo()
noun = "utility"

return rx.el.div(
rx.el.div(
rx.el.h1(
Expand All @@ -121,10 +142,10 @@ def intro(raw_arg):
p(
span("Command to install the "),
strong(title.strip()),
span(" component."),
span(f" {noun}."),
class_name="text-sm text-muted-foreground",
),
_usage_demo(slug),
install_block,
class_name="w-full flex flex-col items-start gap-4",
),
class_name="flex flex-col gap-6 mb-10",
Expand Down
92 changes: 92 additions & 0 deletions tests/test_intro_token.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
"""Tests for the INTRO token rendered by `native.templates._intro.intro`.

Regression coverage for a bug where the Shimmer docs page
(`docs/utilities/shimmer.md`) carries an `--INTRO([Shimmer, ...])--` token
but `shimmer` is not a `COMPONENT_REGISTRY` entry — it is a pure-CSS
utility injected into `globals.css` by `buridan init` via
`cli.main.UTILITIES_BUNDLE`.

Root cause: `intro()` derived `slug = title.lower().replace(" ", "_")`
and unconditionally rendered `buridan add {slug}`, assuming every INTRO'd
page is a registry component. For `shimmer` that produced copyable
commands which the CLI rejects with
`Warning: Component 'shimmer' not found in registry.` and exit code 1,
directly contradicting the page's own prose ("you already have shimmer"
via `buridan init`).

Fix: `intro()` now branches on `slug in COMPONENT_REGISTRY`. Registry
components still get `buridan add <slug>`; non-registry utilities get
`buridan init` (the command that actually ships the utility).
"""

from __future__ import annotations

from pathlib import Path

import reflex as rx

from native.engine.parser import parse_and_render
from native.registry.components import COMPONENT_REGISTRY
from native.templates._intro import intro

_SHIMMER_DOC = (
Path(__file__).resolve().parent.parent / "docs" / "utilities" / "shimmer.md"
)

REGISTRY_COMPONENT = "button"


def test_intro_non_registry_utility_renders_init_not_add() -> None:
"""A non-registry INTRO title (e.g. Shimmer) must render `buridan init`
install commands, never `buridan add <slug>` — the latter prints
"Component '<slug>' not found in registry." and exits 1.
"""
component = intro(
"[Shimmer, Utilities for adding a shimmer effect to text elements.]",
)
rendered = repr(component)

assert "buridan init" in rendered
assert "uv run buridan init" in rendered
assert "python -m buridan init" in rendered

assert "buridan add shimmer" not in rendered
assert "uv run buridan add shimmer" not in rendered
assert "python -m buridan add shimmer" not in rendered


def test_intro_registry_component_renders_add_not_init() -> None:
"""Regression: a registry component (e.g. Button) must keep rendering
`buridan add <slug>` install commands — the fix must not reroute
real components onto the `buridan init` path.
"""
assert REGISTRY_COMPONENT in COMPONENT_REGISTRY

component = intro(f"[{REGISTRY_COMPONENT.title()}, A clickable button.]")
rendered = repr(component)

assert f"buridan add {REGISTRY_COMPONENT}" in rendered
assert f"uv run buridan add {REGISTRY_COMPONENT}" in rendered
assert f"python -m buridan add {REGISTRY_COMPONENT}" in rendered

assert "buridan init" not in rendered


def test_parse_and_render_shimmer_doc_has_no_broken_add_command() -> None:
"""End-to-end: rendering the real `docs/utilities/shimmer.md` through
the production parser pipeline produces the init install block and
never produces the broken `buridan add shimmer` string anywhere in
the rendered component tree.
"""
pieces = parse_and_render(_SHIMMER_DOC.read_text())
assert pieces, "shimmer.md should render at least one component"
assert all(isinstance(p, rx.Component) for p in pieces)

joined = "".join(repr(p) for p in pieces)
assert "buridan add shimmer" not in joined
assert "uv run buridan add shimmer" not in joined
assert "python -m buridan add shimmer" not in joined

assert "buridan init" in joined
assert "uv run buridan init" in joined
assert "python -m buridan init" in joined