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
4 changes: 2 additions & 2 deletions .github/workflows/check_outdated_dependencies.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@ jobs:
echo "Outdated:"
echo "$outdated"

filtered_outdated=$(echo "$outdated" | grep -vE 'pyright|ruff' || true)
filtered_outdated=$(echo "$outdated" | grep -vE 'ty|ruff' || true)

if [ ! -z "$filtered_outdated" ]; then
echo "Outdated dependencies found:"
echo "$filtered_outdated"
exit 1
else
echo "All dependencies are up to date. (pyright and ruff are ignored)"
echo "All dependencies are up to date. (ty and ruff are ignored)"
fi

frontend:
Expand Down
7 changes: 4 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,12 @@ repos:
require_serial: true
- repo: local
hooks:
- id: pyright
name: pyright
entry: uv run --no-sync pyright
- id: ty
name: ty
entry: ty check
language: system
types: [python]
pass_filenames: false
require_serial: true
- repo: https://github.com/biomejs/pre-commit
rev: 19865851e014cbe6138e295365f95ca51bf953f8 # v0.6.1
Expand Down
4 changes: 2 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ uv run pytest tests/units --cov --no-cov-on-fail --cov-report= # unit tests (>
uv run pytest tests/integration # integration tests (slow)
uv run ruff check . # lint
uv run ruff format . # format
uv run pyright reflex tests # type check
uv run ty check # type check
uv run python scripts/make_pyi.py # regenerate .pyi stubs
uv run pre-commit run --all-files # all pre-commit hooks
```
Expand Down Expand Up @@ -122,7 +122,7 @@ if TYPE_CHECKING:
Before submitting:
1. Tests pass with adequate coverage
2. `uv run ruff check .` and `uv run ruff format .` clean
3. `uv run pyright reflex tests` passes
3. `uv run ty check` passes
4. `pyi_hashes.json` updated if components changed
5. Documentation updated if user-facing behavior changed
6. Deprecation warnings added if breaking changes introduced
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ Next make sure all the following tests pass. This ensures that every new change

```bash
uv run ruff check .
uv run pyright reflex tests
uv run ty check
```

Finally, run `ruff` to format your code.
Expand All @@ -82,7 +82,7 @@ Finally, run `ruff` to format your code.
uv run ruff format .
```

Consider installing git pre-commit hooks so Ruff, Pyright, and `make_pyi` will run automatically before each commit.
Consider installing git pre-commit hooks so Ruff, ty, and `make_pyi` will run automatically before each commit.

```bash
uv run pre-commit install
Expand Down
9 changes: 7 additions & 2 deletions docs/app/agent_files/_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@
from dataclasses import dataclass
from pathlib import Path
from types import SimpleNamespace, UnionType
from typing import Any, Literal, Union, get_args, get_origin
from typing import TYPE_CHECKING, Any, Literal, Union, get_args, get_origin

from reflex.constants import Dirs
from reflex_base.config import get_config
from reflex_base.plugins import CommonContext, Plugin
from typing_extensions import Unpack

if TYPE_CHECKING:
from reflex_base.components.component import Component

MCP_DOC_PATHS = {
"ai/integrations/mcp-installation.md",
"ai/integrations/mcp-overview.md",
Expand Down Expand Up @@ -373,7 +376,9 @@ def _component_from_frontmatter_ref(component_ref: str):
raise ValueError(msg)


def _component_refs_from_source(source_path: Path) -> tuple[tuple[type, str], ...]:
def _component_refs_from_source(
source_path: Path,
) -> tuple[tuple[type["Component"], str], ...]:
"""Return component classes and display refs from a markdown source file."""
from reflex_docgen.markdown import parse_document

Expand Down
6 changes: 4 additions & 2 deletions docs/app/reflex_docs/components/hint.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
from typing import Literal

import reflex as rx


def hint(
text: str,
content: rx.Component,
side: str = "top",
align: str = "center",
side: Literal["bottom", "left", "right", "top"] = "top",
align: Literal["center", "end", "start"] = "center",
active: bool = False,
class_name: str = "",
**props,
Expand Down
23 changes: 20 additions & 3 deletions docs/app/reflex_docs/pages/docs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
from collections import defaultdict, namedtuple
from pathlib import Path
from types import SimpleNamespace
from typing import Any

import reflex as rx
import reflex.utils.format
from reflex_components_core.core.cond import Cond
from reflex_docgen.markdown import parse_document

Expand Down Expand Up @@ -304,7 +306,10 @@ def register_doc(virtual_doc: str, comp):
route = doc_route_from_path(virtual_doc)

build_nested_namespace(
docs_ns, path, title, Route(path=route, title=title2, component=lambda: "")
docs_ns,
path,
title,
Route(path=route, title=title2, component=rx.fragment),
)

if comp is not None:
Expand All @@ -328,5 +333,17 @@ def register_doc(virtual_doc: str, comp):
get_component_docgen(_virtual, _actual, doc_title_from_path(_virtual)),
)

for name, ns in docs_ns.__dict__.items():
globals()[name] = ns

def __getattr__(name: str) -> Any:
"""Expose ``docs_ns`` sub-namespaces (``ai_builder``, ``enterprise``, ...).

These names are populated lazily from the on-disk markdown layout, so
static analysers can't see them via the normal ``globals()`` write loop.
PEP 562 ``__getattr__`` lets ty resolve ``from reflex_docs.pages.docs import
ai_builder`` to ``Any`` instead of an unresolved-import error.
"""
try:
return docs_ns.__dict__[name]
except KeyError as exc:
msg = f"module {__name__!r} has no attribute {name!r}"
raise AttributeError(msg) from exc
13 changes: 0 additions & 13 deletions docs/app/reflex_docs/pages/docs/api_reference/plugins.py

This file was deleted.

13 changes: 0 additions & 13 deletions docs/app/reflex_docs/pages/docs/api_reference/utils.py

This file was deleted.

13 changes: 7 additions & 6 deletions docs/app/reflex_docs/pages/docs/cloud_cliref.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,8 @@ def process(
command: CommandInfoDict | MultiCommandInfoDict,
prefix: str | None,
override_name: str | None,
) -> Element:
"""Convert a Click command to a Markdown element."""
) -> None:
"""Convert a Click command to a Markdown element and record it in ``cli_to_doc``."""
actual_name = override_name or command["name"]
full_name = prefix + " " + actual_name if prefix and actual_name else actual_name
cli_to_doc[full_name] = Section((
Expand Down Expand Up @@ -253,20 +253,21 @@ def process(
)


def process_command(command: click.Command, name: str) -> str:
def process_command(command: click.Command, name: str) -> None:
"""Convert a Click command to a Markdown text representation."""
with click.Context(command) as ctx:
process(ctx.to_info_dict()["command"], None, name)


cli_command: click.Command = cli
if find_spec("typer") is not None and find_spec("typer.main") is not None:
import typer # pyright: ignore[reportMissingImports]
import typer

if isinstance(cli, typer.Typer):
cli = typer.main.get_command(cli)
cli_command = typer.main.get_command(cli)

# Iterate over each command configuration
process_command(cli, "reflex")
process_command(cli_command, "reflex")


REFLEX_PREFIX = "reflex"
Expand Down
35 changes: 16 additions & 19 deletions docs/app/reflex_docs/pages/docs/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,21 @@
import textwrap
from pathlib import Path
from types import UnionType
from typing import Literal, Union, _GenericAlias, get_args, get_origin
from typing import (
Any,
Literal,
Union,
_GenericAlias, # ty:ignore[unresolved-import]
get_args,
get_origin,
)

import reflex as rx
import reflex_components_internal as ui
from reflex.components.base.fragment import Fragment
from reflex.components.component import Component
from reflex.components.radix.primitives.base import RadixPrimitiveComponent
from reflex.components.radix.themes.base import RadixThemesComponent
from reflex_base.components.component import Component
from reflex_components_core.base.fragment import Fragment
from reflex_components_radix.primitives.base import RadixPrimitiveComponent
from reflex_components_radix.themes.base import RadixThemesComponent
from reflex_docgen import (
EventHandlerDocumentation,
PropDocumentation,
Expand All @@ -28,16 +35,6 @@
)
from reflex_docs.templates.docpage import docpage, h1_comp, h2_comp


def get_code_style(color: str):
return {
"color": rx.color(color, 11),
"border_radius": "0.25rem",
"border": f"1px solid {rx.color(color, 5)}",
"background": rx.color(color, 3),
}


# Mapping from types to colors.
TYPE_COLORS = {
"int": "red",
Expand Down Expand Up @@ -336,7 +333,7 @@ def prop_docs(
color = TYPE_COLORS.get(short_type_name, "gray")

description = prop.description or ""
is_long_row = len(description) > 160 or (
is_long_row = len(description) > 160 or bool(
literal_values and len(literal_values) > 8 and prop.name not in common_types
)

Expand Down Expand Up @@ -389,7 +386,7 @@ def prop_docs(
[
rx.code(
f'"{v}"',
color_scheme=color,
color_scheme=color, # ty:ignore[invalid-argument-type]
variant="soft",
class_name="code-style leading-normal text-nowrap",
)
Expand All @@ -399,7 +396,7 @@ def prop_docs(
else [
rx.code(
type_name,
color_scheme=color,
color_scheme=color, # ty:ignore[invalid-argument-type]
variant="soft",
class_name="code-style leading-normal whitespace-normal break-words",
)
Expand Down Expand Up @@ -515,7 +512,7 @@ def generate_props(
if prop.name.startswith("on_"): # ignore event trigger props
continue
cells, is_long_row, expanded_name, expanded = prop_docs(prop, component)
row_props = {
row_props: dict[str, Any] = {
"class_name": ui.cn(
"border-b border-slate-4 last:border-b-0 transition-colors hover:bg-slate-2",
"group cursor-pointer" if is_long_row else "",
Expand Down
12 changes: 0 additions & 12 deletions docs/app/reflex_docs/pages/docs/enterprise.py

This file was deleted.

1 change: 1 addition & 0 deletions docs/app/reflex_docs/pages/docs/recipes_overview.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import reflex as rx
import reflex.utils.format

from reflex_docs.templates.docpage import docpage, h1_comp, h2_comp, text_comp_2

Expand Down
44 changes: 20 additions & 24 deletions docs/app/reflex_docs/pages/docs/source.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,30 +24,26 @@ def format_fields(
headers: list[str],
fields: tuple[FieldDocumentation, ...],
) -> rx.Component:
return (
rx.table.root(
rx.table.header(
rx.table.row(*[
rx.table.column_header_cell(
header, class_name=table_header_class_name
)
for header in headers
])
),
rx.table.body(
*[
rx.table.row(
rx.table.cell(
format_field(field),
),
rx.table.cell(
render_markdown(field.description or ""),
class_name="font-small text-slate-11",
),
)
for field in fields
],
),
return rx.table.root(
rx.table.header(
rx.table.row(*[
rx.table.column_header_cell(header, class_name=table_header_class_name)
for header in headers
])
),
rx.table.body(
*[
rx.table.row(
rx.table.cell(
format_field(field),
),
rx.table.cell(
render_markdown(field.description or ""),
class_name="font-small text-slate-11",
),
)
for field in fields
],
),
)

Expand Down
8 changes: 6 additions & 2 deletions docs/app/reflex_docs/pages/docs_landing/views/ai_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def get_integration_path() -> list:
else:
tag = ""

description = post.get("description", "").strip()
description = str(post.get("description") or "").strip()
title = key.replace("_", " ").title()

if title == "Open Ai":
Expand All @@ -67,7 +67,11 @@ def get_integration_path() -> list:


def card(
title: str, description: str, content: str, href: str, enteprise_only: bool = False
title: str,
description: str,
content: rx.Component,
href: str,
enteprise_only: bool = False,
) -> rx.Component:
return rx.el.div(
rx.el.span(
Expand Down
Loading
Loading