Skip to content

Commit f1e7b67

Browse files
Merge branch 'main' into compiler-hooks
2 parents 620c84d + f41f9cb commit f1e7b67

313 files changed

Lines changed: 23508 additions & 4019 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/check_outdated_dependencies.yml

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -52,32 +52,18 @@ jobs:
5252
- uses: ./.github/actions/setup_build_env
5353
with:
5454
python-version: 3.13
55-
run-uv-sync: true
5655

57-
- name: Clone Reflex Website Repo
58-
uses: actions/checkout@v4
59-
with:
60-
repository: reflex-dev/reflex-web
61-
ref: main
62-
path: reflex-web
63-
- name: Compile pyproject.toml into requirements.txt
64-
working-directory: ./reflex-web
65-
run: |
66-
uv pip compile pyproject.toml --no-annotate --no-header --no-deps --output-file requirements.txt
67-
uv pip list --format=json | jq -r '"^" + .[].name + "[ =]"' > installed_patterns.txt
68-
grep -ivf installed_patterns.txt requirements.txt > requirements.txt.tmp && mv requirements.txt.tmp requirements.txt
69-
rm installed_patterns.txt
70-
- name: Install Requirements for reflex-web
71-
working-directory: ./reflex-web
72-
run: uv pip install -r requirements.txt
73-
- name: Init Website for reflex-web
74-
working-directory: ./reflex-web
75-
run: uv run reflex init
56+
- name: Install Requirements for reflex-docs
57+
working-directory: ./docs/app
58+
run: uv sync
59+
- name: Init Website for reflex-docs
60+
working-directory: ./docs/app
61+
run: uv run --active --no-sync reflex init
7662
- name: Run Website and Check for errors
7763
run: |
78-
uv run bash scripts/integration.sh ./reflex-web dev
64+
uv run --active --no-sync bash scripts/integration.sh ./docs/app prod
7965
- name: Check outdated frontend dependencies
80-
working-directory: ./reflex-web/.web
66+
working-directory: ./docs/app/.web
8167
run: |
8268
raw_outdated=$(/home/runner/.local/share/reflex/bun/bin/bun outdated)
8369
outdated=$(echo "$raw_outdated" | grep -vE '\|\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\|' || true)

.github/workflows/integration_tests.yml

Lines changed: 3 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -146,55 +146,10 @@ jobs:
146146
with:
147147
node-version: 22
148148

149-
# Build git+https deps as wheels outside sfw (avoids sfw MITM cert issues
150-
# with git), then install everything else through sfw for scanning.
151-
# TODO: revisit when https://github.com/SocketDev/sfw-free/issues/30 is resolved.
152-
- name: Pre-install git dependencies (outside sfw)
153-
run: |
154-
# Install git+https deps directly without sfw to avoid MITM cert issues.
155-
# Their transitive registry deps will still be scanned by sfw uv sync.
156-
grep -oP 'git\+https://[^"]+' uv.lock | sort -u > "$RUNNER_TEMP/git-deps.txt" || true
157-
if [ -s "$RUNNER_TEMP/git-deps.txt" ]; then
158-
echo "Installing git dependencies:"
159-
cat "$RUNNER_TEMP/git-deps.txt"
160-
uv pip install --no-deps -r "$RUNNER_TEMP/git-deps.txt"
161-
else
162-
echo "No git dependencies found."
163-
fi
164-
- name: Install Dependencies (scanned by Socket.dev)
149+
- name: Install reflex-docs dependencies
150+
working-directory: ./docs/app
165151
run: sfw uv sync
166152

167-
# TODO: revisit when https://github.com/SocketDev/sfw-free/issues/30 is resolved.
168-
- name: Pre-install reflex-docs git dependencies (outside sfw)
169-
working-directory: ./docs/app
170-
run: |
171-
# Replace reflex-dev/reflex git deps with plain package names (PR version is pre-installed)
172-
sed -i -E 's|"([a-zA-Z0-9_-]+)\s*@\s*git\+https://github\.com/reflex-dev/reflex@[^"]*"|"\1"|g' pyproject.toml
173-
# Install git+https deps from pyproject.toml before pip compile resolves them.
174-
# Exclude reflex itself — the PR version is already installed.
175-
grep -oP 'git\+https://[^"'"'"']+' pyproject.toml | sort -u > git-requirements.txt || true
176-
if [ -s git-requirements.txt ]; then
177-
echo "Installing git dependencies:"
178-
cat git-requirements.txt
179-
uv pip install --no-deps -r git-requirements.txt
180-
fi
181-
- name: Compile and install reflex-docs requirements (scanned by Socket.dev)
182-
working-directory: ./docs/app
183-
run: |
184-
sfw uv pip compile pyproject.toml --no-annotate --no-header --no-deps --output-file requirements.txt
185-
uv pip list --format=json | jq -r '"^" + .[].name + "[ =]"' > installed_patterns.txt
186-
grep -ivf installed_patterns.txt requirements.txt > requirements.txt.tmp && mv requirements.txt.tmp requirements.txt
187-
rm installed_patterns.txt
188-
if [ -s requirements.txt ]; then
189-
sfw uv pip install -r requirements.txt
190-
fi
191-
- name: Verify installed reflex version matches this checkout
192-
run: |
193-
expected_sha="$(git rev-parse --short=8 HEAD)"
194-
installed_version="$(uv run --active --no-sync python -c 'import importlib.metadata as metadata; print(metadata.version("reflex"))')"
195-
echo "Expected checkout SHA: $expected_sha"
196-
echo "Installed reflex version: $installed_version"
197-
[[ "$installed_version" == *"+$expected_sha" ]]
198153
- name: Init Website for reflex-docs
199154
working-directory: ./docs/app
200155
run: uv run --active --no-sync reflex init
@@ -259,18 +214,9 @@ jobs:
259214
- uses: ./.github/actions/setup_build_env
260215
with:
261216
python-version: ${{ matrix.python-version }}
262-
run-uv-sync: true
263-
264-
- name: Install reflex-docs dependencies
265-
working-directory: ./docs/app
266-
run: |
267-
uv pip compile pyproject.toml --no-annotate --no-header --no-deps --output-file requirements.txt
268-
uv pip list --format=json | jq -r '"^" + .[].name + "[ =]"' > installed_patterns.txt
269-
grep -ivf installed_patterns.txt requirements.txt > requirements.txt.tmp && mv requirements.txt.tmp requirements.txt
270-
rm installed_patterns.txt
271217
- name: Install Requirements for reflex-docs
272218
working-directory: ./docs/app
273-
run: uv pip install -r requirements.txt
219+
run: uv sync
274220
- name: Init Website for reflex-docs
275221
working-directory: ./docs/app
276222
run: uv run --active --no-sync reflex init

.pre-commit-config.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ repos:
88
- args:
99
- --fix
1010
- --exit-non-zero-on-fix
11-
exclude: ^integration/benchmarks/
11+
exclude: ^(integration/benchmarks/|docs/app/)
1212
id: ruff-check
1313
repo: https://github.com/astral-sh/ruff-pre-commit
1414
rev: v0.15.6
@@ -45,6 +45,7 @@ repos:
4545
- '2'
4646
- --indent-style
4747
- space
48+
exclude: (\.css$|docs/app/)
4849
id: biome-format
4950
repo: https://github.com/biomejs/pre-commit
5051
rev: v0.6.1

docs/app/assets/chakra_color_mode_provider.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export default function ChakraColorModeProvider({ children }) {
2020
const allowedModes = ["light", "dark", "system"];
2121
if (!allowedModes.includes(mode)) {
2222
console.error(
23-
`Invalid color mode "${mode}". Defaulting to "${defaultColorMode}".`
23+
`Invalid color mode "${mode}". Defaulting to "${defaultColorMode}".`,
2424
);
2525
mode = defaultColorMode;
2626
}
Lines changed: 64 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,82 @@
1-
'use client'
1+
"use client";
22

3-
import { cn } from 'clsx-for-tailwind'
4-
import React, { useCallback, useState } from 'react'
3+
import { cn } from "clsx-for-tailwind";
4+
import React, { useCallback, useState } from "react";
55

6-
type ButtonVariant = 'primary' | 'destructive' | 'outline' | 'ghost'
7-
type ButtonSize = 'xs' | 'sm' | 'md' | 'lg' | 'icon-xs' | 'icon-sm' | 'icon-md' | 'icon-lg'
6+
type ButtonVariant = "primary" | "destructive" | "outline" | "ghost";
7+
type ButtonSize =
8+
| "xs"
9+
| "sm"
10+
| "md"
11+
| "lg"
12+
| "icon-xs"
13+
| "icon-sm"
14+
| "icon-md"
15+
| "icon-lg";
816

917
interface GradientButtonProps
1018
extends React.ButtonHTMLAttributes<HTMLButtonElement> {
11-
children: React.ReactNode
12-
variant?: ButtonVariant
13-
size?: ButtonSize
14-
className?: string
15-
nativeButton?: boolean
19+
children: React.ReactNode;
20+
variant?: ButtonVariant;
21+
size?: ButtonSize;
22+
className?: string;
23+
nativeButton?: boolean;
1624
}
1725

1826
const BASE_CLASSES =
19-
'relative inline-flex items-center justify-center whitespace-nowrap transition-colors disabled:cursor-not-allowed disabled:border disabled:border-m-slate-4/80 disabled:bg-m-slate-3 disabled:text-m-slate-8 [&_svg]:pointer-events-none [&_svg:not([class*="size-"])]:size-4 shrink-0 [&_svg]:shrink-0 cursor-pointer box-border font-[525] overflow-hidden'
27+
'relative inline-flex items-center justify-center whitespace-nowrap transition-colors disabled:cursor-not-allowed disabled:border disabled:border-m-slate-4/80 disabled:bg-m-slate-3 disabled:text-m-slate-8 [&_svg]:pointer-events-none [&_svg:not([class*="size-"])]:size-4 shrink-0 [&_svg]:shrink-0 cursor-pointer box-border font-[525] overflow-hidden';
2028

2129
const VARIANT_CLASSES: Record<ButtonVariant, string> = {
2230
primary:
23-
'bg-primary-9 text-primary-2 dark:text-primary-contrast hover:bg-primary-10 shadow-[0_0_1px_var(--primary-9,#6E56CF)_inset,0_2px_0_0_rgba(255,255,255,0.22)_inset]',
24-
destructive: 'bg-destructive-9 hover:bg-destructive-10 text-primary-contrast',
31+
"bg-primary-9 text-primary-2 dark:text-primary-contrast hover:bg-primary-10 shadow-[0_0_1px_var(--primary-9,#6E56CF)_inset,0_2px_0_0_rgba(255,255,255,0.22)_inset]",
32+
destructive: "bg-destructive-9 hover:bg-destructive-10 text-primary-contrast",
2533
outline:
26-
'shadow-[0_-1px_0_0_rgba(0,0,0,0.08)_inset,0_0_0_1px_rgba(0,0,0,0.08)_inset,0_1px_2px_0_rgba(0,0,0,0.02),0_1px_4px_0_rgba(0,0,0,0.02)] dark:shadow-[0_1px_0_0_rgba(255,255,255,0.16)_inset] bg-white dark:bg-m-slate-10 hover:bg-m-slate-2 dark:hover:bg-m-slate-9 text-m-slate-12 dark:text-m-slate-3',
27-
ghost: 'text-m-slate-12 dark:text-m-slate-3 hover:text-primary-10 dark:hover:text-primary-9',
28-
}
34+
"shadow-[0_-1px_0_0_rgba(0,0,0,0.08)_inset,0_0_0_1px_rgba(0,0,0,0.08)_inset,0_1px_2px_0_rgba(0,0,0,0.02),0_1px_4px_0_rgba(0,0,0,0.02)] dark:shadow-[0_1px_0_0_rgba(255,255,255,0.16)_inset] bg-white dark:bg-m-slate-10 hover:bg-m-slate-2 dark:hover:bg-m-slate-9 text-m-slate-12 dark:text-m-slate-3",
35+
ghost:
36+
"text-m-slate-12 dark:text-m-slate-3 hover:text-primary-10 dark:hover:text-primary-9",
37+
};
2938

3039
const SIZE_CLASSES: Record<ButtonSize, string> = {
31-
xs: 'px-1.5 h-7 rounded-lg gap-1.5 text-sm',
32-
sm: 'px-2 h-8 rounded-lg gap-2 text-sm',
33-
md: 'px-2.5 h-9 rounded-[0.625rem] gap-2 text-sm',
34-
lg: 'px-3 h-10 rounded-[0.625rem] gap-2.5 text-base',
35-
'icon-xs': 'size-7 rounded-lg',
36-
'icon-sm': 'size-8 rounded-lg',
37-
'icon-md': 'size-9 rounded-[0.625rem]',
38-
'icon-lg': 'size-10 rounded-[0.625rem]',
39-
}
40+
xs: "px-1.5 h-7 rounded-lg gap-1.5 text-sm",
41+
sm: "px-2 h-8 rounded-lg gap-2 text-sm",
42+
md: "px-2.5 h-9 rounded-[0.625rem] gap-2 text-sm",
43+
lg: "px-3 h-10 rounded-[0.625rem] gap-2.5 text-base",
44+
"icon-xs": "size-7 rounded-lg",
45+
"icon-sm": "size-8 rounded-lg",
46+
"icon-md": "size-9 rounded-[0.625rem]",
47+
"icon-lg": "size-10 rounded-[0.625rem]",
48+
};
4049

4150
export function GradientButton({
4251
children,
43-
variant = 'primary',
44-
size = 'md',
52+
variant = "primary",
53+
size = "md",
4554
className,
4655
nativeButton = true,
4756
...props
4857
}: GradientButtonProps) {
49-
const [isMouseOver, setIsMouseOver] = useState(false)
50-
const [x, setX] = useState(0)
51-
const [y, setY] = useState(0)
58+
const [isMouseOver, setIsMouseOver] = useState(false);
59+
const [x, setX] = useState(0);
60+
const [y, setY] = useState(0);
5261

5362
const handleMouseMove = useCallback<
5463
React.MouseEventHandler<HTMLButtonElement>
5564
>((e) => {
56-
const button = e.currentTarget
57-
const rect = button.getBoundingClientRect()
58-
setX(e.clientX - rect.left)
59-
setY(e.clientY - rect.top)
60-
}, [])
65+
const button = e.currentTarget;
66+
const rect = button.getBoundingClientRect();
67+
setX(e.clientX - rect.left);
68+
setY(e.clientY - rect.top);
69+
}, []);
6170

6271
const handleMouseEnter = useCallback(() => {
63-
setIsMouseOver(true)
64-
}, [])
72+
setIsMouseOver(true);
73+
}, []);
6574

6675
const handleMouseLeave = useCallback(() => {
67-
setIsMouseOver(false)
68-
}, [])
76+
setIsMouseOver(false);
77+
}, []);
6978

70-
const Component = nativeButton ? 'button' : 'div'
79+
const Component = nativeButton ? "button" : "div";
7180

7281
return (
7382
<Component
@@ -79,34 +88,36 @@ export function GradientButton({
7988
BASE_CLASSES,
8089
VARIANT_CLASSES[variant],
8190
SIZE_CLASSES[size],
82-
className
91+
className,
8392
)}
8493
>
85-
{variant === 'primary' ? (
94+
{variant === "primary" ? (
8695
<>
8796
<span
8897
className="block absolute rounded-full pointer-events-none"
8998
style={{
90-
width: '2.75rem',
91-
height: '2.75rem',
99+
width: "2.75rem",
100+
height: "2.75rem",
92101
left: x,
93102
top: y,
94-
transform: 'translate(-50%, -50%) translateZ(0)',
95-
background: '#EB8E90',
96-
mixBlendMode: 'plus-lighter',
97-
filter: 'blur(28px)',
103+
transform: "translate(-50%, -50%) translateZ(0)",
104+
background: "#EB8E90",
105+
mixBlendMode: "plus-lighter",
106+
filter: "blur(28px)",
98107
opacity: isMouseOver ? 1 : 0,
99-
transition: 'opacity 0.3s ease',
100-
willChange: 'transform, opacity',
108+
transition: "opacity 0.3s ease",
109+
willChange: "transform, opacity",
101110
}}
102111
/>
103-
<span className="inline-flex z-10 relative items-center gap-[inherit]">{children}</span>
112+
<span className="inline-flex z-10 relative items-center gap-[inherit]">
113+
{children}
114+
</span>
104115
</>
105116
) : (
106117
children
107118
)}
108119
</Component>
109-
)
120+
);
110121
}
111122

112-
export default GradientButton
123+
export default GradientButton;

0 commit comments

Comments
 (0)