Skip to content

Commit 6aa4bbc

Browse files
committed
Merge remote-tracking branch 'origin/main' into claude/selenium-to-playwright-migration-7qluV
2 parents 7c7ce5e + 6d6ff1f commit 6aa4bbc

37 files changed

Lines changed: 1550 additions & 816 deletions

File tree

.github/scripts/dispatch_release/detect.sh

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
set -euo pipefail
33

44
declare -A MAP=(
5-
[reflex]=reflex
65
[hatch_reflex_pyi]=hatch-reflex-pyi
76
[reflex_base]=reflex-base
87
[reflex_components_code]=reflex-components-code
@@ -20,7 +19,7 @@ declare -A MAP=(
2019
[reflex_docgen]=reflex-docgen
2120
[reflex_hosting_cli]=reflex-hosting-cli
2221
)
23-
ORDER=(reflex hatch_reflex_pyi reflex_base reflex_components_code reflex_components_core reflex_components_dataeditor reflex_components_gridjs reflex_components_lucide reflex_components_markdown reflex_components_moment reflex_components_plotly reflex_components_radix reflex_components_react_player reflex_components_recharts reflex_components_sonner reflex_docgen reflex_hosting_cli)
22+
ORDER=(hatch_reflex_pyi reflex_base reflex_components_code reflex_components_core reflex_components_dataeditor reflex_components_gridjs reflex_components_lucide reflex_components_markdown reflex_components_moment reflex_components_plotly reflex_components_radix reflex_components_react_player reflex_components_recharts reflex_components_sonner reflex_docgen reflex_hosting_cli)
2423

2524
PACKAGES=()
2625
for key in "${ORDER[@]}"; do

.github/scripts/dispatch_release/plan.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,29 @@ def main() -> None:
176176
"tag": tag,
177177
})
178178

179+
# reflex is not independently releasable via dispatch: when reflex-base is
180+
# released, reflex is released alongside it with a matching version. The
181+
# publish workflow pins reflex-base exactly when building reflex.
182+
reflex_base_release = next(
183+
(r for r in releases if r["package"] == "reflex-base"), None
184+
)
185+
if reflex_base_release is not None:
186+
reflex_version = reflex_base_release["next"]
187+
reflex_tag = f"v{reflex_version}"
188+
if tag_exists(reflex_tag):
189+
fail(f"tag {reflex_tag} already exists")
190+
current_reflex = pick_latest("v")
191+
display = current_reflex if current_reflex is not None else "<none>"
192+
summary_rows.append(
193+
f"| `reflex` | `{display}` | `{reflex_version}` | `{reflex_tag}` |"
194+
)
195+
releases.append({
196+
"package": "reflex",
197+
"current": current_reflex or "",
198+
"next": reflex_version,
199+
"tag": reflex_tag,
200+
})
201+
179202
with pathlib.Path(github_step_summary).open("a") as f:
180203
f.write("\n".join(summary_rows) + "\n")
181204
with pathlib.Path(github_output).open("a") as f:

.github/workflows/dispatch_release.yml

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ on:
1111
description: "Release action"
1212
required: true
1313
type: choice
14-
default: new-prerelease-patch
14+
# default is continued-prerelease to prevent accidental releases.
15+
default: continued-prerelease
1516
options:
1617
- new-prerelease-patch
1718
- new-prerelease-minor
@@ -22,10 +23,6 @@ on:
2223
- release-patch
2324
- release-minor
2425
- release-major
25-
reflex:
26-
description: "reflex"
27-
type: boolean
28-
default: false
2926
hatch_reflex_pyi:
3027
description: "hatch-reflex-pyi"
3128
type: boolean
@@ -104,7 +101,6 @@ jobs:
104101
- uses: actions/checkout@v6
105102
- id: detect
106103
env:
107-
reflex: ${{ inputs.reflex }}
108104
hatch_reflex_pyi: ${{ inputs.hatch_reflex_pyi }}
109105
reflex_base: ${{ inputs.reflex_base }}
110106
reflex_components_code: ${{ inputs.reflex_components_code }}

.github/workflows/publish.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
name: Publish to PyPI
22

3+
run-name: Publish ${{ github.event.release.tag_name || inputs.tag }}
4+
35
on:
46
release:
57
types: [published]
@@ -36,6 +38,7 @@ jobs:
3638
if [[ "$TAG" =~ ^v([0-9].*)$ ]]; then
3739
echo "package=reflex" >> "$GITHUB_OUTPUT"
3840
echo "build_dir=." >> "$GITHUB_OUTPUT"
41+
echo "version=${BASH_REMATCH[1]}" >> "$GITHUB_OUTPUT"
3942
elif [[ "$TAG" =~ ^(.+)-v([0-9].*)$ ]]; then
4043
PACKAGE="${BASH_REMATCH[1]}"
4144
if [ ! -d "packages/$PACKAGE" ]; then
@@ -44,11 +47,23 @@ jobs:
4447
fi
4548
echo "package=$PACKAGE" >> "$GITHUB_OUTPUT"
4649
echo "build_dir=packages/$PACKAGE" >> "$GITHUB_OUTPUT"
50+
echo "version=${BASH_REMATCH[2]}" >> "$GITHUB_OUTPUT"
4751
else
4852
echo "Error: Tag '$TAG' does not match expected format (v* or <package>-v*)"
4953
exit 1
5054
fi
5155
56+
- name: Pin reflex-base to exact version
57+
if: steps.parse.outputs.package == 'reflex'
58+
run: |
59+
VERSION="${{ steps.parse.outputs.version }}"
60+
if ! grep -q '"reflex-base >= ' pyproject.toml; then
61+
echo "Error: expected 'reflex-base >= ...' dependency in pyproject.toml"
62+
exit 1
63+
fi
64+
sed -i 's|"reflex-base >= [^"]*"|"reflex-base == '"$VERSION"'"|' pyproject.toml
65+
grep '"reflex-base' pyproject.toml
66+
5267
- name: Build
5368
run: uv build --directory "${{ steps.parse.outputs.build_dir }}"
5469

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ repos:
44
hooks:
55
- id: ruff-format
66
name: ruff-format
7-
entry: ruff format --preview
7+
entry: ruff format
88
language: system
99
types_or: [python, markdown]
1010
require_serial: true

CONTRIBUTING.md

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
# Reflex Contributing Guidelines
22

3-
For an extensive guide on the different ways to contribute to Reflex see our [Contributing Guide on Notion](https://www.notion.so/reflex-dev/2107ab2bc166497db951b8d742748284?v=f0eaff78fa984b5ab15d204af58907d7).
4-
53
## Running a Local Build of Reflex
64

75
Here is a quick guide on how to run Reflex repo locally so you can start contributing to the project.
@@ -110,6 +108,33 @@ We welcome AI-assisted contributions, but they must meet the same quality bar as
110108
- All added/changed lines MUST have unit or integration test coverage with _real_ assertions. No untested code, no bogus test code.
111109
- PRs with merge conflicts or failing tests will not be reviewed or merged. The maintainers do not spend time on PRs that are not in a ready state. If you need attention on a PR that is not ready, mention the maintainers in a comment.
112110

111+
## 📝 Contributing to the Docs
112+
113+
The Reflex documentation lives in this repo under [`docs/`](https://github.com/reflex-dev/reflex/tree/main/docs). All doc pages are plain Markdown files in [`docs/`](https://github.com/reflex-dev/reflex/tree/main/docs), and the docs site itself (a Reflex app that renders them) lives in [`docs/app/`](https://github.com/reflex-dev/reflex/tree/main/docs/app). If you're fixing a typo, clarifying an explanation, or adding a new page, you can do it all in this repo by editing the relevant `.md` file.
114+
115+
**1. Run the docs site locally:**
116+
117+
```bash
118+
cd docs/app
119+
uv sync
120+
uv run reflex run
121+
```
122+
123+
Then open [http://localhost:3000/docs/](http://localhost:3000/docs/). The dev server picks up changes to the `.md` files in `docs/` so you can preview edits live.
124+
125+
**2. Speed up dev builds with the page whitelist (optional):**
126+
127+
By default the dev server compiles every page, which can be slow. To only compile the pages you're working on, edit `docs/app/reflex_docs/whitelist.py` and add paths to `WHITELISTED_PAGES`:
128+
129+
```python
130+
WHITELISTED_PAGES = [
131+
"/getting-started/introduction",
132+
"/components/props",
133+
]
134+
```
135+
136+
Paths must start with `/`, have no trailing slash, and are prefix-matched. An empty list builds everything. Restart the dev server after editing.
137+
113138
## Editing Templates
114139

115140
To edit the templates in Reflex you can do so in two way.

docs/app/assets/tailwind-theme.css

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1699,6 +1699,14 @@
16991699
/* padding: 0rem 0.125rem 0rem 0.125rem; */
17001700
}
17011701

1702+
/* Override Radix Code (rt-Code) accent coloring so inline code matches slate theme */
1703+
code.rt-Code,
1704+
code.rt-Code.rt-variant-soft,
1705+
.rt-Code.rt-variant-soft {
1706+
color: var(--c-slate-11) !important;
1707+
background-color: var(--c-slate-3) !important;
1708+
}
1709+
17021710
.code-error-style {
17031711
font-family: var(--font-jetbrains);
17041712
font-size: 0.835rem;
@@ -1803,6 +1811,44 @@
18031811
}
18041812
}
18051813

1814+
.code-block button,
1815+
.code-block > button {
1816+
border: none !important;
1817+
border-width: 0 !important;
1818+
background: transparent !important;
1819+
background-color: transparent !important;
1820+
opacity: 0 !important;
1821+
transition: opacity 0.15s ease-out !important;
1822+
pointer-events: none;
1823+
display: inline-flex !important;
1824+
align-items: center !important;
1825+
gap: 0.375rem !important;
1826+
font-size: 0.8125rem !important;
1827+
font-weight: 500 !important;
1828+
color: var(--c-slate-11) !important;
1829+
top: 8px !important;
1830+
right: 12px !important;
1831+
padding: 6px 8px !important;
1832+
}
1833+
1834+
.code-block button::after,
1835+
.code-block > button::after {
1836+
content: "Copy";
1837+
}
1838+
1839+
.code-block:hover button,
1840+
.code-block:hover > button,
1841+
.code-block button:focus-visible {
1842+
opacity: 1 !important;
1843+
pointer-events: auto;
1844+
}
1845+
1846+
.code-block button:hover,
1847+
.code-block > button:hover {
1848+
background: var(--c-slate-3) !important;
1849+
background-color: var(--c-slate-3) !important;
1850+
}
1851+
18061852

18071853
.tab-style {
18081854
color: var(--c-slate-9);
@@ -1814,6 +1860,89 @@
18141860
letter-spacing: -0.01094rem;
18151861
}
18161862

1863+
.pill-tab-list {
1864+
display: inline-flex !important;
1865+
gap: 2px !important;
1866+
padding: 4px !important;
1867+
background: var(--c-slate-3) !important;
1868+
border-radius: 10px !important;
1869+
border-bottom: none !important;
1870+
box-shadow: none !important;
1871+
width: fit-content !important;
1872+
max-width: 100%;
1873+
overflow-x: auto;
1874+
}
1875+
1876+
.pill-tab-list::before,
1877+
.pill-tab-list::after {
1878+
display: none !important;
1879+
content: none !important;
1880+
}
1881+
1882+
.pill-tab {
1883+
appearance: none !important;
1884+
background: transparent !important;
1885+
background-color: transparent !important;
1886+
border: none !important;
1887+
padding: 8px 16px !important;
1888+
font-size: 0.9375rem !important;
1889+
font-weight: 450 !important;
1890+
color: var(--c-slate-11) !important;
1891+
border-radius: 7px !important;
1892+
cursor: pointer;
1893+
white-space: nowrap;
1894+
transition: color 0.12s, background-color 0.12s, box-shadow 0.12s;
1895+
letter-spacing: 0 !important;
1896+
line-height: 1.25rem !important;
1897+
box-shadow: none !important;
1898+
}
1899+
1900+
.pill-tab::before,
1901+
.pill-tab::after,
1902+
.pill-tab:hover::before,
1903+
.pill-tab:hover::after,
1904+
.pill-tab[data-state='active']::before,
1905+
.pill-tab[data-state='active']::after,
1906+
.pill-tab[data-state='active']:hover::before,
1907+
.pill-tab[data-state='active']:hover::after {
1908+
background: transparent !important;
1909+
background-color: transparent !important;
1910+
box-shadow: none !important;
1911+
content: none !important;
1912+
display: none !important;
1913+
}
1914+
1915+
.pill-tab:hover {
1916+
color: var(--c-slate-11) !important;
1917+
background: transparent !important;
1918+
}
1919+
1920+
.pill-tab .rt-BaseTabListTriggerInner,
1921+
.pill-tab:hover .rt-BaseTabListTriggerInner,
1922+
.pill-tab:focus-visible .rt-BaseTabListTriggerInner,
1923+
.pill-tab:focus-visible:hover .rt-BaseTabListTriggerInner {
1924+
background-color: transparent !important;
1925+
background: transparent !important;
1926+
}
1927+
1928+
.pill-tab[data-state='active'],
1929+
.pill-tab[data-state='active']:hover {
1930+
color: var(--c-slate-12) !important;
1931+
font-weight: 500 !important;
1932+
background: var(--c-slate-1) !important;
1933+
background-color: var(--c-slate-1) !important;
1934+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08) !important;
1935+
}
1936+
1937+
:where(.dark, .dark *) .pill-tab[data-state='active'] {
1938+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4) !important;
1939+
}
1940+
1941+
.tab-style:hover:not([data-state='active'])::before {
1942+
background: transparent !important;
1943+
background-color: transparent !important;
1944+
}
1945+
18171946
.tab-style:hover {
18181947
color: var(--c-slate-11);
18191948
}

docs/app/pyproject.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@ lint.ignore = [
9090
lint.pydocstyle.convention = "google"
9191
lint.allowed-confusables = ['']
9292

93+
[tool.ruff.format]
94+
preview = true
95+
9396
[tool.codespell]
9497
skip = "data/*"
9598

0 commit comments

Comments
 (0)