Merge remote-tracking branch 'origin/main' into include_step_attribute_in_input
This commit is contained in:
commit
1c70fab11a
1
.github/CODEOWNERS
vendored
Normal file
1
.github/CODEOWNERS
vendored
Normal file
@ -0,0 +1 @@
|
||||
@reflex-dev/reflex-team
|
1
.github/ISSUE_TEMPLATE/bug_report.md
vendored
1
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -2,7 +2,6 @@
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
19
.github/ISSUE_TEMPLATE/enhancement_request.md
vendored
Normal file
19
.github/ISSUE_TEMPLATE/enhancement_request.md
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
---
|
||||
name: Enhancement Request
|
||||
about: Suggest an enhancement for an existing Reflex feature.
|
||||
title: ''
|
||||
labels: 'enhancement'
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
**Describe the Enhancement you want**
|
||||
A clear and concise description of what the improvement does.
|
||||
|
||||
- Which feature do you want to improve? (and what problem does it have)
|
||||
|
||||
- What is the benefit of the enhancement?
|
||||
|
||||
- Show an example/usecase were the improvement are needed.
|
||||
|
||||
**Additional context**
|
||||
Add any other context here.
|
18
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
18
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
---
|
||||
name: Feature Request
|
||||
about: Suggest a new feature for Reflex
|
||||
title: ''
|
||||
labels: 'feature request'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the Features**
|
||||
A clear and concise description of what the features does.
|
||||
|
||||
- What is the purpose of the feature?
|
||||
|
||||
- Show an example / use cases for the new feature.
|
||||
|
||||
**Additional context**
|
||||
Add any other context here.
|
2
.github/actions/setup_build_env/action.yml
vendored
2
.github/actions/setup_build_env/action.yml
vendored
@ -18,7 +18,7 @@ inputs:
|
||||
poetry-version:
|
||||
description: 'Poetry version to install'
|
||||
required: false
|
||||
default: '1.3.1'
|
||||
default: '1.8.3'
|
||||
run-poetry-install:
|
||||
description: 'Whether to run poetry install on current dir'
|
||||
required: false
|
||||
|
6
.github/workflows/benchmarks.yml
vendored
6
.github/workflows/benchmarks.yml
vendored
@ -80,7 +80,7 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# Show OS combos first in GUI
|
||||
os: [ubuntu-latest, windows-latest, macos-12]
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
python-version: ['3.9.18', '3.10.13', '3.11.5', '3.12.0']
|
||||
exclude:
|
||||
- os: windows-latest
|
||||
@ -92,7 +92,7 @@ jobs:
|
||||
python-version: '3.9.18'
|
||||
- os: macos-latest
|
||||
python-version: '3.10.13'
|
||||
- os: macos-12
|
||||
- os: macos-latest
|
||||
python-version: '3.12.0'
|
||||
include:
|
||||
- os: windows-latest
|
||||
@ -155,7 +155,7 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# Show OS combos first in GUI
|
||||
os: [ubuntu-latest, windows-latest, macos-12]
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
python-version: ['3.11.5']
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
9
.github/workflows/check_node_latest.yml
vendored
9
.github/workflows/check_node_latest.yml
vendored
@ -14,11 +14,14 @@ env:
|
||||
|
||||
jobs:
|
||||
check_latest_node:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ['3.12']
|
||||
split_index: [1, 2]
|
||||
node-version: ['node']
|
||||
fail-fast: false
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/setup_build_env
|
||||
@ -30,11 +33,11 @@ jobs:
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- run: |
|
||||
poetry run uv pip install pyvirtualdisplay pillow
|
||||
poetry run uv pip install pyvirtualdisplay pillow pytest-split
|
||||
poetry run playwright install --with-deps
|
||||
- run: |
|
||||
poetry run pytest tests/test_node_version.py
|
||||
poetry run pytest tests/integration
|
||||
poetry run pytest tests/integration --splits 2 --group ${{matrix.split_index}}
|
||||
|
||||
|
||||
|
||||
|
88
.github/workflows/check_outdated_dependencies.yml
vendored
Normal file
88
.github/workflows/check_outdated_dependencies.yml
vendored
Normal file
@ -0,0 +1,88 @@
|
||||
name: check-outdated-dependencies
|
||||
|
||||
on:
|
||||
push: # This will trigger the action when a pull request is opened or updated.
|
||||
branches:
|
||||
- 'release/**' # This will trigger the action when any branch starting with "release/" is created.
|
||||
workflow_dispatch: # Allow manual triggering if needed.
|
||||
|
||||
jobs:
|
||||
backend:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- uses: ./.github/actions/setup_build_env
|
||||
with:
|
||||
python-version: '3.9'
|
||||
run-poetry-install: true
|
||||
create-venv-at-path: .venv
|
||||
|
||||
- name: Check outdated backend dependencies
|
||||
run: |
|
||||
outdated=$(poetry show -oT)
|
||||
echo "Outdated:"
|
||||
echo "$outdated"
|
||||
|
||||
filtered_outdated=$(echo "$outdated" | grep -vE 'pyright|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)"
|
||||
fi
|
||||
|
||||
|
||||
frontend:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/setup_build_env
|
||||
with:
|
||||
python-version: '3.10.11'
|
||||
run-poetry-install: true
|
||||
create-venv-at-path: .venv
|
||||
- name: Clone Reflex Website Repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: reflex-dev/reflex-web
|
||||
ref: main
|
||||
path: reflex-web
|
||||
- name: Install Requirements for reflex-web
|
||||
working-directory: ./reflex-web
|
||||
run: poetry run uv pip install -r requirements.txt
|
||||
- name: Install additional dependencies for DB access
|
||||
run: poetry run uv pip install psycopg
|
||||
- name: Init Website for reflex-web
|
||||
working-directory: ./reflex-web
|
||||
run: poetry run reflex init
|
||||
- name: Run Website and Check for errors
|
||||
run: |
|
||||
poetry run bash scripts/integration.sh ./reflex-web dev
|
||||
- name: Check outdated frontend dependencies
|
||||
working-directory: ./reflex-web/.web
|
||||
run: |
|
||||
raw_outdated=$(/home/runner/.local/share/reflex/bun/bin/bun outdated)
|
||||
outdated=$(echo "$raw_outdated" | grep -vE '\|\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\|' || true)
|
||||
echo "Outdated:"
|
||||
echo "$outdated"
|
||||
|
||||
# Ignore 3rd party dependencies that are not updated.
|
||||
filtered_outdated=$(echo "$outdated" | grep -vE 'Package|@chakra-ui|lucide-react|@splinetool/runtime|ag-grid-react|framer-motion|react-markdown|remark-math|remark-gfm|rehype-katex|rehype-raw|remark-unwrap-images' || true)
|
||||
no_extra=$(echo "$filtered_outdated" | grep -vE '\|\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-' || true)
|
||||
|
||||
|
||||
if [ ! -z "$no_extra" ]; then
|
||||
echo "Outdated dependencies found:"
|
||||
echo "$filtered_outdated"
|
||||
exit 1
|
||||
else
|
||||
echo "All dependencies are up to date. (3rd party packages are ignored)"
|
||||
fi
|
||||
|
21
.github/workflows/integration_app_harness.yml
vendored
21
.github/workflows/integration_app_harness.yml
vendored
@ -6,13 +6,13 @@ concurrency:
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ['main']
|
||||
branches: ["main"]
|
||||
paths-ignore:
|
||||
- '**/*.md'
|
||||
- "**/*.md"
|
||||
pull_request:
|
||||
branches: ['main']
|
||||
branches: ["main"]
|
||||
paths-ignore:
|
||||
- '**/*.md'
|
||||
- "**/*.md"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
@ -23,8 +23,10 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
state_manager: ['redis', 'memory']
|
||||
python-version: ['3.11.5', '3.12.0']
|
||||
runs-on: ubuntu-latest
|
||||
python-version: ['3.11.5', '3.12.0', '3.13.0']
|
||||
split_index: [1, 2]
|
||||
fail-fast: false
|
||||
runs-on: ubuntu-22.04
|
||||
services:
|
||||
# Label used to access the service container
|
||||
redis:
|
||||
@ -45,13 +47,14 @@ jobs:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
run-poetry-install: true
|
||||
create-venv-at-path: .venv
|
||||
- run: poetry run uv pip install pyvirtualdisplay pillow
|
||||
- run: poetry run uv pip install pyvirtualdisplay pillow pytest-split
|
||||
- name: Run app harness tests
|
||||
env:
|
||||
SCREENSHOT_DIR: /tmp/screenshots
|
||||
SCREENSHOT_DIR: /tmp/screenshots/${{ matrix.state_manager }}/${{ matrix.python-version }}/${{ matrix.split_index }}
|
||||
REDIS_URL: ${{ matrix.state_manager == 'redis' && 'redis://localhost:6379' || '' }}
|
||||
run: |
|
||||
poetry run pytest tests/integration
|
||||
poetry run playwright install --with-deps
|
||||
poetry run pytest tests/integration --splits 2 --group ${{matrix.split_index}}
|
||||
- uses: actions/upload-artifact@v4
|
||||
name: Upload failed test screenshots
|
||||
if: always()
|
||||
|
84
.github/workflows/integration_tests.yml
vendored
84
.github/workflows/integration_tests.yml
vendored
@ -42,8 +42,8 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# Show OS combos first in GUI
|
||||
os: [ubuntu-latest, windows-latest, macos-12]
|
||||
python-version: ['3.9.18', '3.10.13', '3.11.5', '3.12.0']
|
||||
os: [ubuntu-latest, windows-latest]
|
||||
python-version: ['3.9.18', '3.10.13', '3.11.5', '3.12.0', '3.13.0']
|
||||
exclude:
|
||||
- os: windows-latest
|
||||
python-version: '3.10.13'
|
||||
@ -73,7 +73,7 @@ jobs:
|
||||
run: |
|
||||
poetry run uv pip install -r requirements.txt
|
||||
- name: Install additional dependencies for DB access
|
||||
run: poetry run uv pip install psycopg2-binary
|
||||
run: poetry run uv pip install psycopg
|
||||
- name: Check export --backend-only before init for counter example
|
||||
working-directory: ./reflex-examples/counter
|
||||
run: |
|
||||
@ -122,7 +122,7 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# Show OS combos first in GUI
|
||||
os: [ubuntu-latest, windows-latest, macos-12]
|
||||
os: [ubuntu-latest]
|
||||
python-version: ['3.10.11', '3.11.4']
|
||||
|
||||
env:
|
||||
@ -145,9 +145,9 @@ jobs:
|
||||
|
||||
- name: Install Requirements for reflex-web
|
||||
working-directory: ./reflex-web
|
||||
run: poetry run uv pip install -r requirements.txt
|
||||
run: poetry run uv pip install $(grep -ivE "reflex " requirements.txt)
|
||||
- name: Install additional dependencies for DB access
|
||||
run: poetry run uv pip install psycopg2-binary
|
||||
run: poetry run uv pip install psycopg
|
||||
- name: Init Website for reflex-web
|
||||
working-directory: ./reflex-web
|
||||
run: poetry run reflex init
|
||||
@ -161,4 +161,74 @@ jobs:
|
||||
poetry run python benchmarks/benchmark_web_size.py --os "${{ matrix.os }}"
|
||||
--python-version "${{ matrix.python-version }}" --commit-sha "${{ github.sha }}"
|
||||
--pr-id "${{ github.event.pull_request.id }}" --branch-name "${{ github.head_ref || github.ref_name }}"
|
||||
--app-name "reflex-web" --path ./reflex-web/.web
|
||||
--app-name "reflex-web" --path ./reflex-web/.web
|
||||
|
||||
rx-shout-from-template:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/setup_build_env
|
||||
with:
|
||||
python-version: '3.11.4'
|
||||
run-poetry-install: true
|
||||
create-venv-at-path: .venv
|
||||
- name: Create app directory
|
||||
run: mkdir rx-shout-from-template
|
||||
- name: Init reflex-web from template
|
||||
run: poetry run reflex init --template https://github.com/masenf/rx_shout
|
||||
working-directory: ./rx-shout-from-template
|
||||
- name: ignore reflex pin in requirements
|
||||
run: sed -i -e '/reflex==/d' requirements.txt
|
||||
working-directory: ./rx-shout-from-template
|
||||
- name: Install additional dependencies
|
||||
run: poetry run uv pip install -r requirements.txt
|
||||
working-directory: ./rx-shout-from-template
|
||||
- name: Run Website and Check for errors
|
||||
run: |
|
||||
# Check that npm is home
|
||||
npm -v
|
||||
poetry run bash scripts/integration.sh ./rx-shout-from-template prod
|
||||
|
||||
|
||||
reflex-web-macos:
|
||||
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version: ['3.11.5', '3.12.0']
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/setup_build_env
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
run-poetry-install: true
|
||||
create-venv-at-path: .venv
|
||||
- name: Clone Reflex Website Repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: reflex-dev/reflex-web
|
||||
ref: main
|
||||
path: reflex-web
|
||||
- name: Install Requirements for reflex-web
|
||||
working-directory: ./reflex-web
|
||||
run: poetry run uv pip install -r requirements.txt
|
||||
- name: Install additional dependencies for DB access
|
||||
run: poetry run uv pip install psycopg
|
||||
- name: Init Website for reflex-web
|
||||
working-directory: ./reflex-web
|
||||
run: poetry run reflex init
|
||||
- name: Run Website and Check for errors
|
||||
run: |
|
||||
# Check that npm is home
|
||||
npm -v
|
||||
poetry run bash scripts/integration.sh ./reflex-web prod
|
||||
- name: Measure and upload .web size
|
||||
run:
|
||||
poetry run python benchmarks/benchmark_web_size.py --os "${{ matrix.os }}"
|
||||
--python-version "${{ matrix.python-version }}" --commit-sha "${{ github.sha }}"
|
||||
--pr-id "${{ github.event.pull_request.id }}" --branch-name "${{ github.head_ref || github.ref_name }}"
|
||||
--app-name "reflex-web" --path ./reflex-web/.web
|
||||
|
34
.github/workflows/unit_tests.yml
vendored
34
.github/workflows/unit_tests.yml
vendored
@ -27,8 +27,8 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-12]
|
||||
python-version: ['3.9.18', '3.10.13', '3.11.5', '3.12.0']
|
||||
os: [ubuntu-latest, windows-latest]
|
||||
python-version: ['3.9.18', '3.10.13', '3.11.5', '3.12.0', '3.13.0']
|
||||
# Windows is a bit behind on Python version availability in Github
|
||||
exclude:
|
||||
- os: windows-latest
|
||||
@ -41,6 +41,7 @@ jobs:
|
||||
- os: windows-latest
|
||||
python-version: '3.9.13'
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
# Service containers to run with `runner-job`
|
||||
services:
|
||||
# Label used to access the service container
|
||||
@ -78,4 +79,31 @@ jobs:
|
||||
export PYTHONUNBUFFERED=1
|
||||
poetry run uv pip install "pydantic~=1.10"
|
||||
poetry run pytest tests/units --cov --no-cov-on-fail --cov-report=
|
||||
- run: poetry run coverage html
|
||||
- name: Generate coverage report
|
||||
run: poetry run coverage html
|
||||
|
||||
unit-tests-macos:
|
||||
timeout-minutes: 30
|
||||
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# Note: py39, py310 versions chosen due to available arm64 darwin builds.
|
||||
python-version: ['3.9.13', '3.10.11', '3.11.5', '3.12.0', '3.13.0']
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/setup_build_env
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
run-poetry-install: true
|
||||
create-venv-at-path: .venv
|
||||
- name: Run unit tests
|
||||
run: |
|
||||
export PYTHONUNBUFFERED=1
|
||||
poetry run pytest tests/units --cov --no-cov-on-fail --cov-report=
|
||||
- name: Run unit tests w/ pydantic v1
|
||||
run: |
|
||||
export PYTHONUNBUFFERED=1
|
||||
poetry run uv pip install "pydantic~=1.10"
|
||||
poetry run pytest tests/units --cov --no-cov-on-fail --cov-report=
|
@ -3,7 +3,7 @@ fail_fast: true
|
||||
repos:
|
||||
|
||||
- repo: https://github.com/charliermarsh/ruff-pre-commit
|
||||
rev: v0.4.10
|
||||
rev: v0.8.2
|
||||
hooks:
|
||||
- id: ruff-format
|
||||
args: [reflex, tests]
|
||||
@ -25,7 +25,7 @@ repos:
|
||||
rev: v1.1.313
|
||||
hooks:
|
||||
- id: pyright
|
||||
args: [integration, reflex, tests]
|
||||
args: [reflex, tests]
|
||||
language: system
|
||||
|
||||
- repo: https://github.com/terrencepreilly/darglint
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
---
|
||||
|
||||
[English](https://github.com/reflex-dev/reflex/blob/main/README.md) | [简体中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_cn/README.md) | [繁體中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_tw/README.md) | [Türkçe](https://github.com/reflex-dev/reflex/blob/main/docs/tr/README.md) | [हिंदी](https://github.com/reflex-dev/reflex/blob/main/docs/in/README.md) | [Português (Brasil)](https://github.com/reflex-dev/reflex/blob/main/docs/pt/pt_br/README.md) | [Italiano](https://github.com/reflex-dev/reflex/blob/main/docs/it/README.md) | [Español](https://github.com/reflex-dev/reflex/blob/main/docs/es/README.md) | [한국어](https://github.com/reflex-dev/reflex/blob/main/docs/kr/README.md) | [日本語](https://github.com/reflex-dev/reflex/blob/main/docs/ja/README.md) | [Deutsch](https://github.com/reflex-dev/reflex/blob/main/docs/de/README.md) | [Persian (پارسی)](https://github.com/reflex-dev/reflex/blob/main/docs/pe/README.md)
|
||||
[English](https://github.com/reflex-dev/reflex/blob/main/README.md) | [简体中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_cn/README.md) | [繁體中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_tw/README.md) | [Türkçe](https://github.com/reflex-dev/reflex/blob/main/docs/tr/README.md) | [हिंदी](https://github.com/reflex-dev/reflex/blob/main/docs/in/README.md) | [Português (Brasil)](https://github.com/reflex-dev/reflex/blob/main/docs/pt/pt_br/README.md) | [Italiano](https://github.com/reflex-dev/reflex/blob/main/docs/it/README.md) | [Español](https://github.com/reflex-dev/reflex/blob/main/docs/es/README.md) | [한국어](https://github.com/reflex-dev/reflex/blob/main/docs/kr/README.md) | [日本語](https://github.com/reflex-dev/reflex/blob/main/docs/ja/README.md) | [Deutsch](https://github.com/reflex-dev/reflex/blob/main/docs/de/README.md) | [Persian (پارسی)](https://github.com/reflex-dev/reflex/blob/main/docs/pe/README.md) | [Tiếng Việt](https://github.com/reflex-dev/reflex/blob/main/docs/vi/README.md)
|
||||
|
||||
---
|
||||
|
||||
@ -228,7 +228,7 @@ You can create a multi-page app by adding more pages.
|
||||
|
||||
<div align="center">
|
||||
|
||||
📑 [Docs](https://reflex.dev/docs/getting-started/introduction) | 🗞️ [Blog](https://reflex.dev/blog) | 📱 [Component Library](https://reflex.dev/docs/library) | 🖼️ [Gallery](https://reflex.dev/docs/gallery) | 🛸 [Deployment](https://reflex.dev/docs/hosting/deploy-quick-start)
|
||||
📑 [Docs](https://reflex.dev/docs/getting-started/introduction) | 🗞️ [Blog](https://reflex.dev/blog) | 📱 [Component Library](https://reflex.dev/docs/library) | 🖼️ [Templates](https://reflex.dev/templates/) | 🛸 [Deployment](https://reflex.dev/docs/hosting/deploy-quick-start)
|
||||
|
||||
</div>
|
||||
|
||||
|
@ -3,8 +3,8 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from utils import send_data_to_posthog
|
||||
|
||||
@ -28,7 +28,7 @@ def insert_benchmarking_data(
|
||||
send_data_to_posthog("lighthouse_benchmark", properties)
|
||||
|
||||
|
||||
def get_lighthouse_scores(directory_path: str) -> dict:
|
||||
def get_lighthouse_scores(directory_path: str | Path) -> dict:
|
||||
"""Extracts the Lighthouse scores from the JSON files in the specified directory.
|
||||
|
||||
Args:
|
||||
@ -38,24 +38,20 @@ def get_lighthouse_scores(directory_path: str) -> dict:
|
||||
dict: The Lighthouse scores.
|
||||
"""
|
||||
scores = {}
|
||||
|
||||
directory_path = Path(directory_path)
|
||||
try:
|
||||
for filename in os.listdir(directory_path):
|
||||
if filename.endswith(".json") and filename != "manifest.json":
|
||||
file_path = os.path.join(directory_path, filename)
|
||||
with open(file_path, "r") as file:
|
||||
data = json.load(file)
|
||||
# Extract scores and add them to the dictionary with the filename as key
|
||||
scores[data["finalUrl"].replace("http://localhost:3000/", "/")] = {
|
||||
"performance_score": data["categories"]["performance"]["score"],
|
||||
"accessibility_score": data["categories"]["accessibility"][
|
||||
"score"
|
||||
],
|
||||
"best_practices_score": data["categories"]["best-practices"][
|
||||
"score"
|
||||
],
|
||||
"seo_score": data["categories"]["seo"]["score"],
|
||||
}
|
||||
for filename in directory_path.iterdir():
|
||||
if filename.suffix == ".json" and filename.stem != "manifest":
|
||||
data = json.loads(filename.read_text())
|
||||
# Extract scores and add them to the dictionary with the filename as key
|
||||
scores[data["finalUrl"].replace("http://localhost:3000/", "/")] = {
|
||||
"performance_score": data["categories"]["performance"]["score"],
|
||||
"accessibility_score": data["categories"]["accessibility"]["score"],
|
||||
"best_practices_score": data["categories"]["best-practices"][
|
||||
"score"
|
||||
],
|
||||
"seo_score": data["categories"]["seo"]["score"],
|
||||
}
|
||||
except Exception as e:
|
||||
return {"error": e}
|
||||
|
||||
|
@ -2,11 +2,12 @@
|
||||
|
||||
import argparse
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from utils import get_directory_size, get_python_version, send_data_to_posthog
|
||||
|
||||
|
||||
def get_package_size(venv_path, os_name):
|
||||
def get_package_size(venv_path: Path, os_name):
|
||||
"""Get the size of a specified package.
|
||||
|
||||
Args:
|
||||
@ -26,14 +27,12 @@ def get_package_size(venv_path, os_name):
|
||||
|
||||
is_windows = "windows" in os_name
|
||||
|
||||
full_path = (
|
||||
["lib", f"python{python_version}", "site-packages"]
|
||||
package_dir: Path = (
|
||||
venv_path / "lib" / f"python{python_version}" / "site-packages"
|
||||
if not is_windows
|
||||
else ["Lib", "site-packages"]
|
||||
else venv_path / "Lib" / "site-packages"
|
||||
)
|
||||
|
||||
package_dir = os.path.join(venv_path, *full_path)
|
||||
if not os.path.exists(package_dir):
|
||||
if not package_dir.exists():
|
||||
raise ValueError(
|
||||
"Error: Virtual environment does not exist or is not activated."
|
||||
)
|
||||
@ -63,9 +62,9 @@ def insert_benchmarking_data(
|
||||
path: The path to the dir or file to check size.
|
||||
"""
|
||||
if "./dist" in path:
|
||||
size = get_directory_size(path)
|
||||
size = get_directory_size(Path(path))
|
||||
else:
|
||||
size = get_package_size(path, os_type_version)
|
||||
size = get_package_size(Path(path), os_type_version)
|
||||
|
||||
# Prepare the event data
|
||||
properties = {
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
import argparse
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from utils import get_directory_size, send_data_to_posthog
|
||||
|
||||
@ -28,7 +29,7 @@ def insert_benchmarking_data(
|
||||
pr_id: The id of the PR.
|
||||
path: The path to the dir or file to check size.
|
||||
"""
|
||||
size = get_directory_size(path)
|
||||
size = get_directory_size(Path(path))
|
||||
|
||||
# Prepare the event data
|
||||
properties = {
|
||||
|
@ -210,9 +210,9 @@ def app_with_one_page(
|
||||
Yields:
|
||||
an AppHarness instance
|
||||
"""
|
||||
root = tmp_path_factory.mktemp(f"app1")
|
||||
root = tmp_path_factory.mktemp("app1")
|
||||
|
||||
yield AppHarness.create(root=root, app_source=AppWithOnePage) # type: ignore
|
||||
yield AppHarness.create(root=root, app_source=AppWithOnePage)
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
@ -227,7 +227,7 @@ def app_with_ten_pages(
|
||||
Yields:
|
||||
an AppHarness instance
|
||||
"""
|
||||
root = tmp_path_factory.mktemp(f"app10")
|
||||
root = tmp_path_factory.mktemp("app10")
|
||||
yield AppHarness.create(
|
||||
root=root,
|
||||
app_source=functools.partial(
|
||||
@ -249,7 +249,7 @@ def app_with_hundred_pages(
|
||||
Yields:
|
||||
an AppHarness instance
|
||||
"""
|
||||
root = tmp_path_factory.mktemp(f"app100")
|
||||
root = tmp_path_factory.mktemp("app100")
|
||||
|
||||
yield AppHarness.create(
|
||||
root=root,
|
||||
@ -272,11 +272,11 @@ def app_with_thousand_pages(
|
||||
Yields:
|
||||
an AppHarness instance
|
||||
"""
|
||||
root = tmp_path_factory.mktemp(f"app1000")
|
||||
root = tmp_path_factory.mktemp("app1000")
|
||||
|
||||
yield AppHarness.create(
|
||||
root=root,
|
||||
app_source=functools.partial( # type: ignore
|
||||
app_source=functools.partial(
|
||||
AppWithThousandPages,
|
||||
render_comp=render_multiple_pages, # type: ignore
|
||||
),
|
||||
@ -295,7 +295,7 @@ def app_with_ten_thousand_pages(
|
||||
Yields:
|
||||
running AppHarness instance
|
||||
"""
|
||||
root = tmp_path_factory.mktemp(f"app10000")
|
||||
root = tmp_path_factory.mktemp("app10000")
|
||||
|
||||
yield AppHarness.create(
|
||||
root=root,
|
||||
|
@ -2,12 +2,13 @@
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
import httpx
|
||||
from httpx import HTTPError
|
||||
|
||||
|
||||
def get_python_version(venv_path, os_name):
|
||||
def get_python_version(venv_path: Path, os_name):
|
||||
"""Get the python version of python in a virtual env.
|
||||
|
||||
Args:
|
||||
@ -18,13 +19,13 @@ def get_python_version(venv_path, os_name):
|
||||
The python version.
|
||||
"""
|
||||
python_executable = (
|
||||
os.path.join(venv_path, "bin", "python")
|
||||
venv_path / "bin" / "python"
|
||||
if "windows" not in os_name
|
||||
else os.path.join(venv_path, "Scripts", "python.exe")
|
||||
else venv_path / "Scripts" / "python.exe"
|
||||
)
|
||||
try:
|
||||
output = subprocess.check_output(
|
||||
[python_executable, "--version"], stderr=subprocess.STDOUT
|
||||
[str(python_executable), "--version"], stderr=subprocess.STDOUT
|
||||
)
|
||||
python_version = output.decode("utf-8").strip().split()[1]
|
||||
return ".".join(python_version.split(".")[:-1])
|
||||
@ -32,7 +33,7 @@ def get_python_version(venv_path, os_name):
|
||||
return None
|
||||
|
||||
|
||||
def get_directory_size(directory):
|
||||
def get_directory_size(directory: Path):
|
||||
"""Get the size of a directory in bytes.
|
||||
|
||||
Args:
|
||||
@ -44,8 +45,8 @@ def get_directory_size(directory):
|
||||
total_size = 0
|
||||
for dirpath, _, filenames in os.walk(directory):
|
||||
for f in filenames:
|
||||
fp = os.path.join(dirpath, f)
|
||||
total_size += os.path.getsize(fp)
|
||||
fp = Path(dirpath) / f
|
||||
total_size += fp.stat().st_size
|
||||
return total_size
|
||||
|
||||
|
||||
|
@ -23,9 +23,9 @@
|
||||
# for example, pass `docker build --platform=linux/amd64 ...`
|
||||
|
||||
# Stage 1: init
|
||||
FROM python:3.11 as init
|
||||
FROM python:3.13 as init
|
||||
|
||||
ARG uv=/root/.cargo/bin/uv
|
||||
ARG uv=/root/.local/bin/uv
|
||||
|
||||
# Install `uv` for faster package boostrapping
|
||||
ADD --chmod=755 https://astral.sh/uv/install.sh /install.sh
|
||||
@ -48,11 +48,11 @@ RUN $uv pip install -r requirements.txt
|
||||
RUN reflex init
|
||||
|
||||
# Stage 2: copy artifacts into slim image
|
||||
FROM python:3.11-slim
|
||||
FROM python:3.13-slim
|
||||
WORKDIR /app
|
||||
RUN adduser --disabled-password --home /app reflex
|
||||
COPY --chown=reflex --from=init /app /app
|
||||
# Install libpq-dev for psycopg2 (skip if not using postgres).
|
||||
# Install libpq-dev for psycopg (skip if not using postgres).
|
||||
RUN apt-get update -y && apt-get install -y libpq-dev && rm -rf /var/lib/apt/lists/*
|
||||
USER reflex
|
||||
ENV PATH="/app/.venv/bin:$PATH" PYTHONUNBUFFERED=1
|
||||
|
@ -2,9 +2,9 @@
|
||||
# instance of a Reflex app.
|
||||
|
||||
# Stage 1: init
|
||||
FROM python:3.11 as init
|
||||
FROM python:3.13 as init
|
||||
|
||||
ARG uv=/root/.cargo/bin/uv
|
||||
ARG uv=/root/.local/bin/uv
|
||||
|
||||
# Install `uv` for faster package boostrapping
|
||||
ADD --chmod=755 https://astral.sh/uv/install.sh /install.sh
|
||||
@ -35,11 +35,11 @@ RUN rm -rf .web && mkdir .web
|
||||
RUN mv /tmp/_static .web/_static
|
||||
|
||||
# Stage 2: copy artifacts into slim image
|
||||
FROM python:3.11-slim
|
||||
FROM python:3.13-slim
|
||||
WORKDIR /app
|
||||
RUN adduser --disabled-password --home /app reflex
|
||||
COPY --chown=reflex --from=init /app /app
|
||||
# Install libpq-dev for psycopg2 (skip if not using postgres).
|
||||
# Install libpq-dev for psycopg (skip if not using postgres).
|
||||
RUN apt-get update -y && apt-get install -y libpq-dev && rm -rf /var/lib/apt/lists/*
|
||||
USER reflex
|
||||
ENV PATH="/app/.venv/bin:$PATH" PYTHONUNBUFFERED=1
|
||||
|
@ -15,7 +15,7 @@ services:
|
||||
|
||||
app:
|
||||
environment:
|
||||
DB_URL: postgresql+psycopg2://postgres:secret@db/postgres
|
||||
DB_URL: postgresql+psycopg://postgres:secret@db/postgres
|
||||
REDIS_URL: redis://redis:6379
|
||||
depends_on:
|
||||
- db
|
||||
|
3
docker-example/production-one-port/.dockerignore
Normal file
3
docker-example/production-one-port/.dockerignore
Normal file
@ -0,0 +1,3 @@
|
||||
.web
|
||||
!.web/bun.lockb
|
||||
!.web/package.json
|
14
docker-example/production-one-port/Caddyfile
Normal file
14
docker-example/production-one-port/Caddyfile
Normal file
@ -0,0 +1,14 @@
|
||||
:{$PORT}
|
||||
|
||||
encode gzip
|
||||
|
||||
@backend_routes path /_event/* /ping /_upload /_upload/*
|
||||
handle @backend_routes {
|
||||
reverse_proxy localhost:8000
|
||||
}
|
||||
|
||||
root * /srv
|
||||
route {
|
||||
try_files {path} {path}/ /404.html
|
||||
file_server
|
||||
}
|
62
docker-example/production-one-port/Dockerfile
Normal file
62
docker-example/production-one-port/Dockerfile
Normal file
@ -0,0 +1,62 @@
|
||||
# This Dockerfile is used to deploy a single-container Reflex app instance
|
||||
# to services like Render, Railway, Heroku, GCP, and others.
|
||||
|
||||
# If the service expects a different port, provide it here (f.e Render expects port 10000)
|
||||
ARG PORT=8080
|
||||
# Only set for local/direct access. When TLS is used, the API_URL is assumed to be the same as the frontend.
|
||||
ARG API_URL
|
||||
|
||||
# It uses a reverse proxy to serve the frontend statically and proxy to backend
|
||||
# from a single exposed port, expecting TLS termination to be handled at the
|
||||
# edge by the given platform.
|
||||
FROM python:3.13 as builder
|
||||
|
||||
RUN mkdir -p /app/.web
|
||||
RUN python -m venv /app/.venv
|
||||
ENV PATH="/app/.venv/bin:$PATH"
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Install python app requirements and reflex in the container
|
||||
COPY requirements.txt .
|
||||
RUN pip install -r requirements.txt
|
||||
|
||||
# Install reflex helper utilities like bun/fnm/node
|
||||
COPY rxconfig.py ./
|
||||
RUN reflex init
|
||||
|
||||
# Install pre-cached frontend dependencies (if exist)
|
||||
COPY *.web/bun.lockb *.web/package.json .web/
|
||||
RUN if [ -f .web/bun.lockb ]; then cd .web && ~/.local/share/reflex/bun/bin/bun install --frozen-lockfile; fi
|
||||
|
||||
# Copy local context to `/app` inside container (see .dockerignore)
|
||||
COPY . .
|
||||
|
||||
ARG PORT API_URL
|
||||
# Download other npm dependencies and compile frontend
|
||||
RUN API_URL=${API_URL:-http://localhost:$PORT} reflex export --loglevel debug --frontend-only --no-zip && mv .web/_static/* /srv/ && rm -rf .web
|
||||
|
||||
|
||||
# Final image with only necessary files
|
||||
FROM python:3.13-slim
|
||||
|
||||
# Install Caddy and redis server inside image
|
||||
RUN apt-get update -y && apt-get install -y caddy redis-server && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ARG PORT API_URL
|
||||
ENV PATH="/app/.venv/bin:$PATH" PORT=$PORT API_URL=${API_URL:-http://localhost:$PORT} REDIS_URL=redis://localhost PYTHONUNBUFFERED=1
|
||||
|
||||
WORKDIR /app
|
||||
COPY --from=builder /app /app
|
||||
COPY --from=builder /srv /srv
|
||||
|
||||
# Needed until Reflex properly passes SIGTERM on backend.
|
||||
STOPSIGNAL SIGKILL
|
||||
|
||||
EXPOSE $PORT
|
||||
|
||||
# Apply migrations before starting the backend.
|
||||
CMD [ -d alembic ] && reflex db migrate; \
|
||||
caddy start && \
|
||||
redis-server --daemonize yes && \
|
||||
exec reflex run --env prod --backend-only
|
37
docker-example/production-one-port/README.md
Normal file
37
docker-example/production-one-port/README.md
Normal file
@ -0,0 +1,37 @@
|
||||
# production-one-port
|
||||
|
||||
This docker deployment runs Reflex in prod mode, exposing a single HTTP port:
|
||||
* `8080` (`$PORT`) - Caddy server hosting the frontend statically and proxying requests to the backend.
|
||||
|
||||
The deployment also runs a local Redis server to store state for each user.
|
||||
|
||||
Conceptually it is similar to the `simple-one-port` example except it:
|
||||
* has layer caching for python, reflex, and node dependencies
|
||||
* uses multi-stage build to reduce the size of the final image
|
||||
|
||||
Using this method may be preferable for deploying in memory constrained
|
||||
environments, because it serves a static frontend export, rather than running
|
||||
the NextJS server via node.
|
||||
|
||||
## Build
|
||||
|
||||
```console
|
||||
docker build -t reflex-production-one-port .
|
||||
```
|
||||
|
||||
## Run
|
||||
|
||||
```console
|
||||
docker run -p 8080:8080 reflex-production-one-port
|
||||
```
|
||||
|
||||
Note that this container has _no persistence_ and will lose all data when
|
||||
stopped. You can use bind mounts or named volumes to persist the database and
|
||||
uploaded_files directories as needed.
|
||||
|
||||
## Usage
|
||||
|
||||
This container should be used with an existing load balancer or reverse proxy to
|
||||
terminate TLS.
|
||||
|
||||
It is also useful for deploying to simple app platforms, such as Render or Heroku.
|
@ -11,4 +11,4 @@ root * /srv
|
||||
route {
|
||||
try_files {path} {path}/ /404.html
|
||||
file_server
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
# It uses a reverse proxy to serve the frontend statically and proxy to backend
|
||||
# from a single exposed port, expecting TLS termination to be handled at the
|
||||
# edge by the given platform.
|
||||
FROM python:3.11
|
||||
FROM python:3.13
|
||||
|
||||
# If the service expects a different port, provide it here (f.e Render expects port 10000)
|
||||
ARG PORT=8080
|
||||
@ -38,4 +38,4 @@ EXPOSE $PORT
|
||||
CMD [ -d alembic ] && reflex db migrate; \
|
||||
caddy start && \
|
||||
redis-server --daemonize yes && \
|
||||
exec reflex run --env prod --backend-only
|
||||
exec reflex run --env prod --backend-only
|
||||
|
@ -1,5 +1,5 @@
|
||||
# This Dockerfile is used to deploy a simple single-container Reflex app instance.
|
||||
FROM python:3.12
|
||||
FROM python:3.13
|
||||
|
||||
RUN apt-get update && apt-get install -y redis-server && rm -rf /var/lib/apt/lists/*
|
||||
ENV REDIS_URL=redis://localhost PYTHONUNBUFFERED=1
|
||||
|
267
docs/vi/README.md
Normal file
267
docs/vi/README.md
Normal file
@ -0,0 +1,267 @@
|
||||
```diff
|
||||
+ Bạn đang tìm kiếm Pynecone? Bạn đã tìm đúng. Pynecone đã được đổi tên thành Reflex. +
|
||||
```
|
||||
|
||||
<div align="center">
|
||||
<img src="https://raw.githubusercontent.com/reflex-dev/reflex/main/docs/images/reflex_dark.svg#gh-light-mode-only" alt="Reflex Logo" width="300px">
|
||||
<img src="https://raw.githubusercontent.com/reflex-dev/reflex/main/docs/images/reflex_light.svg#gh-dark-mode-only" alt="Reflex Logo" width="300px">
|
||||
|
||||
<hr>
|
||||
|
||||
### **✨ Ứng dụng web hiệu suất cao, tùy chỉnh bằng Python thuần. Deploy trong vài giây. ✨**
|
||||
[](https://badge.fury.io/py/reflex)
|
||||

|
||||
[](https://reflex.dev/docs/getting-started/introduction)
|
||||
[](https://discord.gg/T5WSbC2YtQ)
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
[English](https://github.com/reflex-dev/reflex/blob/main/README.md) | [简体中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_cn/README.md) | [繁體中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_tw/README.md) | [Türkçe](https://github.com/reflex-dev/reflex/blob/main/docs/tr/README.md) | [हिंदी](https://github.com/reflex-dev/reflex/blob/main/docs/in/README.md) | [Português (Brasil)](https://github.com/reflex-dev/reflex/blob/main/docs/pt/pt_br/README.md) | [Italiano](https://github.com/reflex-dev/reflex/blob/main/docs/it/README.md) | [Español](https://github.com/reflex-dev/reflex/blob/main/docs/es/README.md) | [한국어](https://github.com/reflex-dev/reflex/blob/main/docs/kr/README.md) | [日本語](https://github.com/reflex-dev/reflex/blob/main/docs/ja/README.md) | [Deutsch](https://github.com/reflex-dev/reflex/blob/main/docs/de/README.md) | [Persian (پارسی)](https://github.com/reflex-dev/reflex/blob/main/docs/pe/README.md) | [Tiếng Việt](https://github.com/reflex-dev/reflex/blob/main/docs/vi/README.md)
|
||||
|
||||
---
|
||||
|
||||
# Reflex
|
||||
|
||||
Reflex là một thư viện để xây dựng ứng dụng web toàn bộ bằng Python thuần.
|
||||
|
||||
Các tính năng chính:
|
||||
* **Python thuần tuý** - Viết toàn bộ ứng dụng cả backend và frontend hoàn toàn bằng Python, không cần học JavaScript.
|
||||
* **Full Flexibility** - Reflex dễ dàng để bắt đầu, nhưng cũng có thể mở rộng lên các ứng dụng phức tạp.
|
||||
* **Deploy Instantly** - Sau khi xây dựng ứng dụng, bạn có thể triển khai bằng [một dòng lệnh](https://reflex.dev/docs/hosting/deploy-quick-start/) hoặc triển khai trên server của riêng bạn.
|
||||
|
||||
Đọc [bài viết về kiến trúc hệ thống](https://reflex.dev/blog/2024-03-21-reflex-architecture/#the-reflex-architecture) để hiểu rõ các hoạt động của Reflex.
|
||||
|
||||
## ⚙️ Cài đặt
|
||||
|
||||
Mở cửa sổ lệnh và chạy (Yêu cầu Python phiên bản 3.9+):
|
||||
|
||||
```bash
|
||||
pip install reflex
|
||||
```
|
||||
|
||||
## 🥳 Tạo ứng dụng đầu tiên
|
||||
|
||||
Cài đặt `reflex` cũng như cài đặt công cụ dòng lệnh `reflex`.
|
||||
|
||||
Kiểm tra việc cài đặt đã thành công hay chưa bằng cách tạo mới một ứng dụng. (Thay `my_app_name` bằng tên ứng dụng của bạn):
|
||||
|
||||
```bash
|
||||
mkdir my_app_name
|
||||
cd my_app_name
|
||||
reflex init
|
||||
```
|
||||
|
||||
Lệnh này tạo ra một ứng dụng mẫu trong một thư mục mới.
|
||||
|
||||
Bạn có thể chạy ứng dụng ở chế độ phát triển.
|
||||
|
||||
```bash
|
||||
reflex run
|
||||
```
|
||||
|
||||
Bạn có thể xem ứng dụng của bạn ở địa chỉ http://localhost:3000.
|
||||
|
||||
Bạn có thể thay đổi mã nguồn ở `my_app_name/my_app_name.py`. Reflex nhanh chóng làm mới và bạn có thể thấy thay đổi trên ứng dụng của bạn ngay lập tức khi bạn lưu file.
|
||||
|
||||
|
||||
## 🫧 Ứng dụng ví dụ
|
||||
|
||||
Bắt đầu với ví dụ: tạo một ứng dụng tạo ảnh bằng [DALL·E](https://platform.openai.com/docs/guides/images/image-generation?context=node). Để cho đơn giản, chúng ta sẽ sử dụng [OpenAI API](https://platform.openai.com/docs/api-reference/authentication), nhưng bạn có thể sử dụng model của chính bạn được triển khai trên local.
|
||||
|
||||
|
||||
|
||||
<div align="center">
|
||||
<img src="https://raw.githubusercontent.com/reflex-dev/reflex/main/docs/images/dalle.gif" alt="A frontend wrapper for DALL·E, shown in the process of generating an image." width="550" />
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
Đây là toàn bộ đoạn mã để xây dựng ứng dụng trên. Nó được viết hoàn toàn trong một file Python!
|
||||
|
||||
|
||||
|
||||
```python
|
||||
import reflex as rx
|
||||
import openai
|
||||
|
||||
openai_client = openai.OpenAI()
|
||||
|
||||
|
||||
class State(rx.State):
|
||||
"""The app state."""
|
||||
|
||||
prompt = ""
|
||||
image_url = ""
|
||||
processing = False
|
||||
complete = False
|
||||
|
||||
def get_image(self):
|
||||
"""Get the image from the prompt."""
|
||||
if self.prompt == "":
|
||||
return rx.window_alert("Prompt Empty")
|
||||
|
||||
self.processing, self.complete = True, False
|
||||
yield
|
||||
response = openai_client.images.generate(
|
||||
prompt=self.prompt, n=1, size="1024x1024"
|
||||
)
|
||||
self.image_url = response.data[0].url
|
||||
self.processing, self.complete = False, True
|
||||
|
||||
|
||||
def index():
|
||||
return rx.center(
|
||||
rx.vstack(
|
||||
rx.heading("DALL-E", font_size="1.5em"),
|
||||
rx.input(
|
||||
placeholder="Enter a prompt..",
|
||||
on_blur=State.set_prompt,
|
||||
width="25em",
|
||||
),
|
||||
rx.button(
|
||||
"Generate Image",
|
||||
on_click=State.get_image,
|
||||
width="25em",
|
||||
loading=State.processing
|
||||
),
|
||||
rx.cond(
|
||||
State.complete,
|
||||
rx.image(src=State.image_url, width="20em"),
|
||||
),
|
||||
align="center",
|
||||
),
|
||||
width="100%",
|
||||
height="100vh",
|
||||
)
|
||||
|
||||
# Add state and page to the app.
|
||||
app = rx.App()
|
||||
app.add_page(index, title="Reflex:DALL-E")
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Hãy phân tích chi tiết.
|
||||
|
||||
<div align="center">
|
||||
<img src="../images/dalle_colored_code_example.png" alt="Explaining the differences between backend and frontend parts of the DALL-E app." width="900" />
|
||||
</div>
|
||||
|
||||
|
||||
### **Reflex UI**
|
||||
|
||||
Bắt đầu với giao diện chính.
|
||||
|
||||
```python
|
||||
def index():
|
||||
return rx.center(
|
||||
...
|
||||
)
|
||||
```
|
||||
|
||||
Hàm `index` định nghĩa phần giao diện chính của ứng dụng.
|
||||
|
||||
Chúng tôi sử dụng các component (thành phần) khác nhau như `center`, `vstack`, `input` và `button` để xây dựng giao diện phía trước.
|
||||
Các component có thể được lồng vào nhau để tạo ra các bố cục phức tạp. Và bạn cũng có thể sử dụng từ khoá `args` để tận dụng đầy đủ sức mạnh của CSS.
|
||||
|
||||
Reflex có đến hơn [60 component được xây dựng sẵn](https://reflex.dev/docs/library) để giúp bạn bắt đầu. Chúng ta có thể tạo ra một component mới khá dễ dàng, thao khảo: [xây dựng component của riêng bạn](https://reflex.dev/docs/wrapping-react/overview/).
|
||||
|
||||
### **State**
|
||||
|
||||
Reflex biểu diễn giao diện bằng các hàm của state (trạng thái).
|
||||
|
||||
```python
|
||||
class State(rx.State):
|
||||
"""The app state."""
|
||||
prompt = ""
|
||||
image_url = ""
|
||||
processing = False
|
||||
complete = False
|
||||
|
||||
```
|
||||
|
||||
Một state định nghĩa các biến (được gọi là vars) có thể thay đổi trong một ứng dụng và cho phép các hàm có thể thay đổi chúng.
|
||||
|
||||
Tại đây state được cấu thành từ một `prompt` và `image_url`.
|
||||
Có cũng những biến boolean `processing` và `complete`
|
||||
để chỉ ra khi nào tắt nút (trong quá trình tạo hình ảnh)
|
||||
và khi nào hiển thị hình ảnh kết quả.
|
||||
|
||||
### **Event Handlers**
|
||||
|
||||
```python
|
||||
def get_image(self):
|
||||
"""Get the image from the prompt."""
|
||||
if self.prompt == "":
|
||||
return rx.window_alert("Prompt Empty")
|
||||
|
||||
self.processing, self.complete = True, False
|
||||
yield
|
||||
response = openai_client.images.generate(
|
||||
prompt=self.prompt, n=1, size="1024x1024"
|
||||
)
|
||||
self.image_url = response.data[0].url
|
||||
self.processing, self.complete = False, True
|
||||
```
|
||||
|
||||
Với các state, chúng ta định nghĩa các hàm có thể thay đổi state vars được gọi là event handlers. Event handler là cách chúng ta có thể thay đổi state trong Reflex. Chúng có thể là phản hồi khi người dùng thao tác, chằng hạn khi nhấn vào nút hoặc khi đang nhập trong text box. Các hành động này được gọi là event.
|
||||
|
||||
Ứng dụng DALL·E. của chúng ta có một event handler, `get_image` để lấy hình ảnh từ OpenAI API. Sử dụng từ khoá `yield` in ở giữa event handler để cập nhật giao diện. Hoặc giao diện có thể cập nhật ở cuối event handler.
|
||||
|
||||
### **Routing**
|
||||
|
||||
Cuối cùng, chúng ta định nghĩa một ứng dụng.
|
||||
|
||||
```python
|
||||
app = rx.App()
|
||||
```
|
||||
|
||||
Chúng ta thêm một trang ở đầu ứng dụng bằng index component. Chúng ta cũng thêm tiêu đề của ứng dụng để hiển thị lên trình duyệt.
|
||||
|
||||
|
||||
```python
|
||||
app.add_page(index, title="DALL-E")
|
||||
```
|
||||
|
||||
Bạn có thể tạo một ứng dụng nhiều trang bằng cách thêm trang.
|
||||
|
||||
## 📑 Tài liệu
|
||||
|
||||
<div align="center">
|
||||
|
||||
📑 [Docs](https://reflex.dev/docs/getting-started/introduction) | 🗞️ [Blog](https://reflex.dev/blog) | 📱 [Component Library](https://reflex.dev/docs/library) | 🖼️ [Gallery](https://reflex.dev/docs/gallery) | 🛸 [Deployment](https://reflex.dev/docs/hosting/deploy-quick-start)
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
## ✅ Status
|
||||
|
||||
Reflex phát hành vào tháng 12/2022 với tên là Pynecone.
|
||||
|
||||
Đến tháng 02/2024, chúng tôi tạo ra dịch vụ dưới phiên bản alpha! Trong thời gian này mọi người có thể triển khai ứng dụng hoàn toàn miễn phí. Xem [roadmap](https://github.com/reflex-dev/reflex/issues/2727) để biết thêm chi tiết.
|
||||
|
||||
Reflex ra phiên bản mới với các tính năng mới hàng tuần! Hãy :star: star và :eyes: watch repo này để thấy các cập nhật mới nhất.
|
||||
|
||||
## Contributing
|
||||
|
||||
Chúng tôi chào đón mọi đóng góp dù lớn hay nhỏ. Dưới đây là các cách để bắt đầu với cộng đồng Reflex.
|
||||
|
||||
- **Discord**: [Discord](https://discord.gg/T5WSbC2YtQ) của chúng tôi là nơi tốt nhất để nhờ sự giúp đỡ và thảo luận các bạn có thể đóng góp.
|
||||
- **GitHub Discussions**: Là cách tốt nhất để thảo luận về các tính năng mà bạn có thể đóng góp hoặc những điều bạn chưa rõ.
|
||||
- **GitHub Issues**: [Issues](https://github.com/reflex-dev/reflex/issues) là nơi tốt nhất để thông báo. Ngoài ra bạn có thể sửa chữa các vấn đề bằng cách tạo PR.
|
||||
|
||||
Chúng tôi luôn sẵn sàng tìm kiếm các contributor, bất kể kinh nghiệm. Để tham gia đóng góp, xin mời xem
|
||||
[CONTIBUTING.md](https://github.com/reflex-dev/reflex/blob/main/CONTRIBUTING.md)
|
||||
|
||||
|
||||
## Xin cảm ơn các Contributors:
|
||||
<a href="https://github.com/reflex-dev/reflex/graphs/contributors">
|
||||
<img src="https://contrib.rocks/image?repo=reflex-dev/reflex" />
|
||||
</a>
|
||||
|
||||
## License
|
||||
|
||||
Reflex là mã nguồn mở và sử dụng giấy phép [Apache License 2.0](LICENSE).
|
2053
poetry.lock
generated
2053
poetry.lock
generated
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "reflex"
|
||||
version = "0.6.1dev1"
|
||||
version = "0.6.7dev1"
|
||||
description = "Web apps in pure Python."
|
||||
license = "Apache-2.0"
|
||||
authors = [
|
||||
@ -27,7 +27,6 @@ packages = [
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.9"
|
||||
dill = ">=0.3.8,<0.4"
|
||||
fastapi = ">=0.96.0,!=0.111.0,!=0.111.1"
|
||||
gunicorn = ">=20.1.0,<24.0"
|
||||
jinja2 = ">=3.1.2,<4.0"
|
||||
@ -50,33 +49,35 @@ wrapt = [
|
||||
{version = ">=1.11.0,<2.0", python = "<3.11"},
|
||||
]
|
||||
packaging = ">=23.1,<25.0"
|
||||
reflex-hosting-cli = ">=0.1.2,<2.0"
|
||||
reflex-hosting-cli = ">=0.1.29,<2.0"
|
||||
charset-normalizer = ">=3.3.2,<4.0"
|
||||
wheel = ">=0.42.0,<1.0"
|
||||
build = ">=1.0.3,<2.0"
|
||||
setuptools = ">=69.1.1,<70.2"
|
||||
setuptools = ">=75.0"
|
||||
httpx = ">=0.25.1,<1.0"
|
||||
twine = ">=4.0.0,<6.0"
|
||||
twine = ">=4.0.0,<7.0"
|
||||
tomlkit = ">=0.12.4,<1.0"
|
||||
lazy_loader = ">=0.4"
|
||||
reflex-chakra = ">=0.6.0"
|
||||
typing_extensions = ">=4.6.0"
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
pytest = ">=7.1.2,<8.0"
|
||||
pytest = ">=7.1.2,<9.0"
|
||||
pytest-mock = ">=3.10.0,<4.0"
|
||||
pyright = ">=1.1.229,<1.1.335"
|
||||
darglint = ">=1.8.1,<2.0"
|
||||
dill = ">=0.3.8"
|
||||
toml = ">=0.10.2,<1.0"
|
||||
pytest-asyncio = ">=0.20.1,<0.22.0" # https://github.com/pytest-dev/pytest-asyncio/issues/706
|
||||
pytest-cov = ">=4.0.0,<5.0"
|
||||
ruff = "^0.4.9"
|
||||
pytest-asyncio = ">=0.24.0"
|
||||
pytest-cov = ">=4.0.0,<7.0"
|
||||
ruff = "0.8.2"
|
||||
pandas = ">=2.1.1,<3.0"
|
||||
pillow = ">=10.0.0,<11.0"
|
||||
pillow = ">=10.0.0,<12.0"
|
||||
plotly = ">=5.13.0,<6.0"
|
||||
asynctest = ">=0.13.0,<1.0"
|
||||
pre-commit = ">=3.2.1"
|
||||
selenium = ">=4.11.0,<5.0"
|
||||
pytest-benchmark = ">=4.0.0,<5.0"
|
||||
pytest-benchmark = ">=4.0.0,<6.0"
|
||||
playwright = ">=1.46.0"
|
||||
pytest-playwright = ">=0.5.1"
|
||||
|
||||
@ -91,8 +92,9 @@ build-backend = "poetry.core.masonry.api"
|
||||
|
||||
[tool.ruff]
|
||||
target-version = "py39"
|
||||
lint.select = ["B", "D", "E", "F", "I", "SIM", "W"]
|
||||
lint.ignore = ["B008", "D203", "D205", "D213", "D401", "D406", "D407", "E501", "F403", "F405", "F541"]
|
||||
lint.isort.split-on-trailing-comma = false
|
||||
lint.select = ["B", "D", "E", "F", "I", "SIM", "W", "RUF", "FURB", "ERA"]
|
||||
lint.ignore = ["B008", "D205", "E501", "F403", "SIM115", "RUF006", "RUF012"]
|
||||
lint.pydocstyle.convention = "google"
|
||||
|
||||
[tool.ruff.lint.per-file-ignores]
|
||||
@ -101,3 +103,7 @@ lint.pydocstyle.convention = "google"
|
||||
"reflex/.templates/*.py" = ["D100", "D103", "D104"]
|
||||
"*.pyi" = ["D301", "D415", "D417", "D418", "E742"]
|
||||
"*/blank.py" = ["I001"]
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
asyncio_default_fixture_loop_scope = "function"
|
||||
asyncio_mode = "auto"
|
||||
|
@ -1,16 +1,15 @@
|
||||
{% extends "web/pages/base_page.js.jinja2" %}
|
||||
|
||||
{% block early_imports %}
|
||||
import '/styles/styles.css'
|
||||
import '$/styles/styles.css'
|
||||
{% endblock %}
|
||||
|
||||
{% block declaration %}
|
||||
import { EventLoopProvider, StateProvider, defaultColorMode } from "/utils/context.js";
|
||||
import { EventLoopProvider, StateProvider, defaultColorMode } from "$/utils/context.js";
|
||||
import { ThemeProvider } from 'next-themes'
|
||||
import * as React from "react";
|
||||
import * as utils_context from "/utils/context.js";
|
||||
import * as utils_state from "/utils/state.js";
|
||||
import * as radix from "@radix-ui/themes";
|
||||
{% for library_alias, library_path in window_libraries %}
|
||||
import * as {{library_alias}} from "{{library_path}}";
|
||||
{% endfor %}
|
||||
|
||||
{% for custom_code in custom_codes %}
|
||||
{{custom_code}}
|
||||
@ -33,10 +32,9 @@ export default function MyApp({ Component, pageProps }) {
|
||||
React.useEffect(() => {
|
||||
// Make contexts and state objects available globally for dynamic eval'd components
|
||||
let windowImports = {
|
||||
"react": React,
|
||||
"@radix-ui/themes": radix,
|
||||
"/utils/context": utils_context,
|
||||
"/utils/state": utils_state,
|
||||
{% for library_alias, library_path in window_libraries %}
|
||||
"{{library_path}}": {{library_alias}},
|
||||
{% endfor %}
|
||||
};
|
||||
window["__reflex"] = windowImports;
|
||||
}, []);
|
||||
|
@ -8,20 +8,6 @@
|
||||
{% endfor %}
|
||||
|
||||
export const {{component.name}} = memo(({ {{-component.props|join(", ")-}} }) => {
|
||||
{% if component.name == "CodeBlock" and "language" in component.props %}
|
||||
if (language) {
|
||||
(async () => {
|
||||
try {
|
||||
const module = await import(`react-syntax-highlighter/dist/cjs/languages/prism/${language}`);
|
||||
SyntaxHighlighter.registerLanguage(language, module.default);
|
||||
} catch (error) {
|
||||
console.error(`Error importing language module for ${language}:`, error);
|
||||
}
|
||||
})();
|
||||
|
||||
|
||||
}
|
||||
{% endif %}
|
||||
{% for hook in component.hooks %}
|
||||
{{ hook }}
|
||||
{% endfor %}
|
||||
|
@ -36,14 +36,10 @@
|
||||
{# component: component dictionary #}
|
||||
{% macro render_tag(component) %}
|
||||
<{{component.name}} {{- render_props(component.props) }}>
|
||||
{%- if component.args is not none -%}
|
||||
{{- render_arg_content(component) }}
|
||||
{%- else -%}
|
||||
{{ component.contents }}
|
||||
{% for child in component.children %}
|
||||
{{ render(child) }}
|
||||
{% endfor %}
|
||||
{%- endif -%}
|
||||
{{ component.contents }}
|
||||
{% for child in component.children %}
|
||||
{{ render(child) }}
|
||||
{% endfor %}
|
||||
</{{component.name}}>
|
||||
{%- endmacro %}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { createContext, useContext, useMemo, useReducer, useState } from "react"
|
||||
import { applyDelta, Event, hydrateClientStorage, useEventLoop, refs } from "/utils/state.js"
|
||||
import { applyDelta, Event, hydrateClientStorage, useEventLoop, refs } from "$/utils/state.js"
|
||||
|
||||
{% if initial_state %}
|
||||
export const initialState = {{ initial_state|json_dumps }}
|
||||
@ -59,6 +59,8 @@ export const initialEvents = () => [
|
||||
{% else %}
|
||||
export const state_name = undefined
|
||||
|
||||
export const exception_state_name = undefined
|
||||
|
||||
export const onLoadInternalEvent = () => []
|
||||
|
||||
export const initialEvents = () => []
|
||||
|
@ -4,8 +4,8 @@ import {
|
||||
ColorModeContext,
|
||||
defaultColorMode,
|
||||
isDevMode,
|
||||
lastCompiledTimeStamp
|
||||
} from "/utils/context.js";
|
||||
lastCompiledTimeStamp,
|
||||
} from "$/utils/context.js";
|
||||
|
||||
export default function RadixThemesColorModeProvider({ children }) {
|
||||
const { theme, resolvedTheme, setTheme } = useTheme();
|
||||
@ -37,7 +37,7 @@ export default function RadixThemesColorModeProvider({ children }) {
|
||||
const allowedModes = ["light", "dark", "system"];
|
||||
if (!allowedModes.includes(mode)) {
|
||||
console.error(
|
||||
`Invalid color mode "${mode}". Defaulting to "${defaultColorMode}".`,
|
||||
`Invalid color mode "${mode}". Defaulting to "${defaultColorMode}".`
|
||||
);
|
||||
mode = defaultColorMode;
|
||||
}
|
||||
|
34
reflex/.templates/web/components/shiki/code.js
Normal file
34
reflex/.templates/web/components/shiki/code.js
Normal file
@ -0,0 +1,34 @@
|
||||
import { useEffect, useState } from "react"
|
||||
import { codeToHtml} from "shiki"
|
||||
|
||||
/**
|
||||
* Code component that uses Shiki to convert code to HTML and render it.
|
||||
*
|
||||
* @param code - The code to be highlighted.
|
||||
* @param theme - The theme to be used for highlighting.
|
||||
* @param language - The language of the code.
|
||||
* @param transformers - The transformers to be applied to the code.
|
||||
* @param decorations - The decorations to be applied to the code.
|
||||
* @param divProps - Additional properties to be passed to the div element.
|
||||
* @returns The rendered code block.
|
||||
*/
|
||||
export function Code ({code, theme, language, transformers, decorations, ...divProps}) {
|
||||
const [codeResult, setCodeResult] = useState("")
|
||||
useEffect(() => {
|
||||
async function fetchCode() {
|
||||
const result = await codeToHtml(code, {
|
||||
lang: language,
|
||||
theme,
|
||||
transformers,
|
||||
decorations
|
||||
});
|
||||
setCodeResult(result);
|
||||
}
|
||||
fetchCode();
|
||||
}, [code, language, theme, transformers, decorations]
|
||||
|
||||
)
|
||||
return (
|
||||
<div dangerouslySetInnerHTML={{__html: codeResult}} {...divProps} ></div>
|
||||
)
|
||||
}
|
@ -2,7 +2,8 @@
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"$/*": ["*"],
|
||||
"@/*": ["public/*"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
import axios from "axios";
|
||||
import io from "socket.io-client";
|
||||
import JSON5 from "json5";
|
||||
import env from "/env.json";
|
||||
import env from "$/env.json";
|
||||
import Cookies from "universal-cookie";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import Router, { useRouter } from "next/router";
|
||||
@ -12,10 +12,9 @@ import {
|
||||
onLoadInternalEvent,
|
||||
state_name,
|
||||
exception_state_name,
|
||||
} from "utils/context.js";
|
||||
import debounce from "/utils/helpers/debounce";
|
||||
import throttle from "/utils/helpers/throttle";
|
||||
import * as Babel from "@babel/standalone";
|
||||
} from "$/utils/context.js";
|
||||
import debounce from "$/utils/helpers/debounce";
|
||||
import throttle from "$/utils/helpers/throttle";
|
||||
|
||||
// Endpoint URLs.
|
||||
const EVENTURL = env.EVENT;
|
||||
@ -41,9 +40,6 @@ let event_processing = false;
|
||||
// Array holding pending events to be processed.
|
||||
const event_queue = [];
|
||||
|
||||
// Pending upload promises, by id
|
||||
const upload_controllers = {};
|
||||
|
||||
/**
|
||||
* Generate a UUID (Used for session tokens).
|
||||
* Taken from: https://stackoverflow.com/questions/105034/how-do-i-create-a-guid-uuid
|
||||
@ -139,8 +135,7 @@ export const evalReactComponent = async (component) => {
|
||||
if (!window.React && window.__reflex) {
|
||||
window.React = window.__reflex.react;
|
||||
}
|
||||
const output = Babel.transform(component, { presets: ["react"] }).code;
|
||||
const encodedJs = encodeURIComponent(output);
|
||||
const encodedJs = encodeURIComponent(component);
|
||||
const dataUri = "data:text/javascript;charset=utf-8," + encodedJs;
|
||||
const module = await eval(`import(dataUri)`);
|
||||
return module.default;
|
||||
@ -180,11 +175,6 @@ export const applyEvent = async (event, socket) => {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (event.name == "_console") {
|
||||
console.log(event.payload.message);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (event.name == "_remove_cookie") {
|
||||
cookies.remove(event.payload.key, { ...event.payload.options });
|
||||
queueEventIfSocketExists(initialEvents(), socket);
|
||||
@ -215,12 +205,6 @@ export const applyEvent = async (event, socket) => {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (event.name == "_set_clipboard") {
|
||||
const content = event.payload.content;
|
||||
navigator.clipboard.writeText(content);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (event.name == "_download") {
|
||||
const a = document.createElement("a");
|
||||
a.hidden = true;
|
||||
@ -235,11 +219,6 @@ export const applyEvent = async (event, socket) => {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (event.name == "_alert") {
|
||||
alert(event.payload.message);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (event.name == "_set_focus") {
|
||||
const ref =
|
||||
event.payload.ref in refs ? refs[event.payload.ref] : event.payload.ref;
|
||||
@ -256,9 +235,35 @@ export const applyEvent = async (event, socket) => {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (event.name == "_call_script") {
|
||||
if (
|
||||
event.name == "_call_function" &&
|
||||
typeof event.payload.function !== "string"
|
||||
) {
|
||||
try {
|
||||
const eval_result = eval(event.payload.javascript_code);
|
||||
const eval_result = event.payload.function();
|
||||
if (event.payload.callback) {
|
||||
if (!!eval_result && typeof eval_result.then === "function") {
|
||||
event.payload.callback(await eval_result);
|
||||
} else {
|
||||
event.payload.callback(eval_result);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.log("_call_function", e);
|
||||
if (window && window?.onerror) {
|
||||
window.onerror(e.message, null, null, null, e);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (event.name == "_call_script" || event.name == "_call_function") {
|
||||
try {
|
||||
const eval_result =
|
||||
event.name == "_call_script"
|
||||
? eval(event.payload.javascript_code)
|
||||
: eval(event.payload.function)();
|
||||
|
||||
if (event.payload.callback) {
|
||||
if (!!eval_result && typeof eval_result.then === "function") {
|
||||
eval(event.payload.callback)(await eval_result);
|
||||
@ -292,7 +297,7 @@ export const applyEvent = async (event, socket) => {
|
||||
if (socket) {
|
||||
socket.emit(
|
||||
"event",
|
||||
JSON.stringify(event, (k, v) => (v === undefined ? null : v))
|
||||
event,
|
||||
);
|
||||
return true;
|
||||
}
|
||||
@ -399,6 +404,8 @@ export const connect = async (
|
||||
transports: transports,
|
||||
autoUnref: false,
|
||||
});
|
||||
// Ensure undefined fields in events are sent as null instead of removed
|
||||
socket.current.io.encoder.replacer = (k, v) => (v === undefined ? null : v)
|
||||
|
||||
function checkVisibility() {
|
||||
if (document.visibilityState === "visible") {
|
||||
@ -435,8 +442,7 @@ export const connect = async (
|
||||
});
|
||||
|
||||
// On each received message, queue the updates and events.
|
||||
socket.current.on("event", async (message) => {
|
||||
const update = JSON5.parse(message);
|
||||
socket.current.on("event", async (update) => {
|
||||
for (const substate in update.delta) {
|
||||
dispatch[substate](update.delta[substate]);
|
||||
}
|
||||
@ -446,6 +452,10 @@ export const connect = async (
|
||||
queueEvents(update.events, socket);
|
||||
}
|
||||
});
|
||||
socket.current.on("reload", async (event) => {
|
||||
event_processing = false;
|
||||
queueEvents([...initialEvents(), event], socket);
|
||||
});
|
||||
|
||||
document.addEventListener("visibilitychange", checkVisibility);
|
||||
};
|
||||
@ -473,25 +483,42 @@ export const uploadFiles = async (
|
||||
return false;
|
||||
}
|
||||
|
||||
if (upload_controllers[upload_id]) {
|
||||
const upload_ref_name = `__upload_controllers_${upload_id}`
|
||||
|
||||
if (refs[upload_ref_name]) {
|
||||
console.log("Upload already in progress for ", upload_id);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Track how many partial updates have been processed for this upload.
|
||||
let resp_idx = 0;
|
||||
const eventHandler = (progressEvent) => {
|
||||
// handle any delta / event streamed from the upload event handler
|
||||
const event_callbacks = socket._callbacks.$event;
|
||||
// Whenever called, responseText will contain the entire response so far.
|
||||
const chunks = progressEvent.event.target.responseText.trim().split("\n");
|
||||
chunks.slice(resp_idx).map((chunk) => {
|
||||
// So only process _new_ chunks beyond resp_idx.
|
||||
chunks.slice(resp_idx).map((chunk_json) => {
|
||||
try {
|
||||
socket._callbacks.$event.map((f) => {
|
||||
f(chunk);
|
||||
const chunk = JSON5.parse(chunk_json);
|
||||
event_callbacks.map((f, ix) => {
|
||||
f(chunk)
|
||||
.then(() => {
|
||||
if (ix === event_callbacks.length - 1) {
|
||||
// Mark this chunk as processed.
|
||||
resp_idx += 1;
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
if (progressEvent.progress === 1) {
|
||||
// Chunk may be incomplete, so only report errors when full response is available.
|
||||
console.log("Error processing chunk", chunk, e);
|
||||
}
|
||||
return;
|
||||
});
|
||||
});
|
||||
resp_idx += 1;
|
||||
} catch (e) {
|
||||
if (progressEvent.progress === 1) {
|
||||
// Chunk may be incomplete, so only report errors when full response is available.
|
||||
console.log("Error parsing chunk", chunk, e);
|
||||
console.log("Error parsing chunk", chunk_json, e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -518,7 +545,7 @@ export const uploadFiles = async (
|
||||
});
|
||||
|
||||
// Send the file to the server.
|
||||
upload_controllers[upload_id] = controller;
|
||||
refs[upload_ref_name] = controller;
|
||||
|
||||
try {
|
||||
return await axios.post(getBackendURL(UPLOADURL), formdata, config);
|
||||
@ -538,19 +565,25 @@ export const uploadFiles = async (
|
||||
}
|
||||
return false;
|
||||
} finally {
|
||||
delete upload_controllers[upload_id];
|
||||
delete refs[upload_ref_name];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Create an event object.
|
||||
* @param name The name of the event.
|
||||
* @param payload The payload of the event.
|
||||
* @param handler The client handler to process event.
|
||||
* @param {string} name The name of the event.
|
||||
* @param {Object.<string, Any>} payload The payload of the event.
|
||||
* @param {Object.<string, (number|boolean)>} event_actions The actions to take on the event.
|
||||
* @param {string} handler The client handler to process event.
|
||||
* @returns The event object.
|
||||
*/
|
||||
export const Event = (name, payload = {}, handler = null) => {
|
||||
return { name, payload, handler };
|
||||
export const Event = (
|
||||
name,
|
||||
payload = {},
|
||||
event_actions = {},
|
||||
handler = null
|
||||
) => {
|
||||
return { name, payload, handler, event_actions };
|
||||
};
|
||||
|
||||
/**
|
||||
@ -676,6 +709,12 @@ export const useEventLoop = (
|
||||
if (!(args instanceof Array)) {
|
||||
args = [args];
|
||||
}
|
||||
|
||||
event_actions = events.reduce(
|
||||
(acc, e) => ({ ...acc, ...e.event_actions }),
|
||||
event_actions ?? {}
|
||||
);
|
||||
|
||||
const _e = args.filter((o) => o?.preventDefault !== undefined)[0];
|
||||
|
||||
if (event_actions?.preventDefault && _e?.preventDefault) {
|
||||
@ -685,6 +724,11 @@ export const useEventLoop = (
|
||||
_e.stopPropagation();
|
||||
}
|
||||
const combined_name = events.map((e) => e.name).join("+++");
|
||||
if (event_actions?.temporal) {
|
||||
if (!socket.current || !socket.current.connected) {
|
||||
return; // don't queue when the backend is not connected
|
||||
}
|
||||
}
|
||||
if (event_actions?.throttle) {
|
||||
// If throttle returns false, the events are not added to the queue.
|
||||
if (!throttle(combined_name, event_actions.throttle)) {
|
||||
@ -731,6 +775,7 @@ export const useEventLoop = (
|
||||
addEvents([
|
||||
Event(`${exception_state_name}.handle_frontend_exception`, {
|
||||
stack: error.stack,
|
||||
component_stack: "",
|
||||
}),
|
||||
]);
|
||||
return false;
|
||||
@ -741,7 +786,8 @@ export const useEventLoop = (
|
||||
window.onunhandledrejection = function (event) {
|
||||
addEvents([
|
||||
Event(`${exception_state_name}.handle_frontend_exception`, {
|
||||
stack: event.reason.stack,
|
||||
stack: event.reason?.stack,
|
||||
component_stack: "",
|
||||
}),
|
||||
]);
|
||||
return false;
|
||||
@ -761,7 +807,7 @@ export const useEventLoop = (
|
||||
connect(
|
||||
socket,
|
||||
dispatch,
|
||||
["websocket", "polling"],
|
||||
["websocket"],
|
||||
setConnectErrors,
|
||||
client_storage
|
||||
);
|
||||
@ -815,11 +861,20 @@ export const useEventLoop = (
|
||||
}
|
||||
};
|
||||
const change_complete = () => addEvents(onLoadInternalEvent());
|
||||
const change_error = () => {
|
||||
// Remove cached error state from router for this page, otherwise the
|
||||
// page will never send on_load events again.
|
||||
if (router.components[router.pathname].error) {
|
||||
delete router.components[router.pathname].error;
|
||||
}
|
||||
};
|
||||
router.events.on("routeChangeStart", change_start);
|
||||
router.events.on("routeChangeComplete", change_complete);
|
||||
router.events.on("routeChangeError", change_error);
|
||||
return () => {
|
||||
router.events.off("routeChangeStart", change_start);
|
||||
router.events.off("routeChangeComplete", change_complete);
|
||||
router.events.off("routeChangeError", change_error);
|
||||
};
|
||||
}, [router]);
|
||||
|
||||
|
@ -89,6 +89,8 @@ from reflex.utils import (
|
||||
lazy_loader,
|
||||
)
|
||||
|
||||
from .event import event as event
|
||||
|
||||
# import this here explicitly to avoid returning the page module since page attr has the
|
||||
# same name as page module(page.py)
|
||||
from .page import page as page
|
||||
@ -262,6 +264,7 @@ _MAPPING: dict = {
|
||||
"experimental": ["_x"],
|
||||
"admin": ["AdminDash"],
|
||||
"app": ["App", "UploadFile"],
|
||||
"assets": ["asset"],
|
||||
"base": ["Base"],
|
||||
"components.component": [
|
||||
"Component",
|
||||
@ -296,15 +299,19 @@ _MAPPING: dict = {
|
||||
"components.moment": ["MomentDelta", "moment"],
|
||||
"config": ["Config", "DBConfig"],
|
||||
"constants": ["Env"],
|
||||
"constants.colors": ["Color"],
|
||||
"event": [
|
||||
"EventChain",
|
||||
"EventHandler",
|
||||
"background",
|
||||
"call_script",
|
||||
"call_function",
|
||||
"run_script",
|
||||
"clear_local_storage",
|
||||
"clear_session_storage",
|
||||
"console_log",
|
||||
"download",
|
||||
"noop",
|
||||
"prevent_default",
|
||||
"redirect",
|
||||
"remove_cookie",
|
||||
@ -318,25 +325,28 @@ _MAPPING: dict = {
|
||||
"upload_files",
|
||||
"window_alert",
|
||||
],
|
||||
"middleware": ["middleware", "Middleware"],
|
||||
"model": ["session", "Model"],
|
||||
"state": [
|
||||
"var",
|
||||
"istate.storage": [
|
||||
"Cookie",
|
||||
"LocalStorage",
|
||||
"SessionStorage",
|
||||
],
|
||||
"middleware": ["middleware", "Middleware"],
|
||||
"model": ["asession", "session", "Model"],
|
||||
"state": [
|
||||
"var",
|
||||
"ComponentState",
|
||||
"State",
|
||||
"dynamic",
|
||||
],
|
||||
"istate.wrappers": ["get_state"],
|
||||
"style": ["Style", "toggle_color_mode"],
|
||||
"utils.imports": ["ImportVar"],
|
||||
"utils.imports": ["ImportDict", "ImportVar"],
|
||||
"utils.serializers": ["serializer"],
|
||||
"vars": ["Var"],
|
||||
"vars": ["Var", "field", "Field"],
|
||||
}
|
||||
|
||||
_SUBMODULES: set[str] = {
|
||||
"components",
|
||||
"event",
|
||||
"app",
|
||||
"style",
|
||||
"admin",
|
||||
|
@ -11,7 +11,6 @@ from . import base as base
|
||||
from . import compiler as compiler
|
||||
from . import components as components
|
||||
from . import config as config
|
||||
from . import event as event
|
||||
from . import model as model
|
||||
from . import style as style
|
||||
from . import testing as testing
|
||||
@ -20,6 +19,7 @@ from . import vars as vars
|
||||
from .admin import AdminDash as AdminDash
|
||||
from .app import App as App
|
||||
from .app import UploadFile as UploadFile
|
||||
from .assets import asset as asset
|
||||
from .base import Base as Base
|
||||
from .components import el as el
|
||||
from .components import lucide as lucide
|
||||
@ -153,19 +153,24 @@ from .components.suneditor import editor as editor
|
||||
from .config import Config as Config
|
||||
from .config import DBConfig as DBConfig
|
||||
from .constants import Env as Env
|
||||
from .constants.colors import Color as Color
|
||||
from .event import EventChain as EventChain
|
||||
from .event import EventHandler as EventHandler
|
||||
from .event import background as background
|
||||
from .event import call_function as call_function
|
||||
from .event import call_script as call_script
|
||||
from .event import clear_local_storage as clear_local_storage
|
||||
from .event import clear_session_storage as clear_session_storage
|
||||
from .event import console_log as console_log
|
||||
from .event import download as download
|
||||
from .event import event as event
|
||||
from .event import noop as noop
|
||||
from .event import prevent_default as prevent_default
|
||||
from .event import redirect as redirect
|
||||
from .event import remove_cookie as remove_cookie
|
||||
from .event import remove_local_storage as remove_local_storage
|
||||
from .event import remove_session_storage as remove_session_storage
|
||||
from .event import run_script as run_script
|
||||
from .event import scroll_to as scroll_to
|
||||
from .event import set_clipboard as set_clipboard
|
||||
from .event import set_focus as set_focus
|
||||
@ -174,22 +179,28 @@ from .event import stop_propagation as stop_propagation
|
||||
from .event import upload_files as upload_files
|
||||
from .event import window_alert as window_alert
|
||||
from .experimental import _x as _x
|
||||
from .istate.storage import Cookie as Cookie
|
||||
from .istate.storage import LocalStorage as LocalStorage
|
||||
from .istate.storage import SessionStorage as SessionStorage
|
||||
from .istate.wrappers import get_state as get_state
|
||||
from .middleware import Middleware as Middleware
|
||||
from .middleware import middleware as middleware
|
||||
from .model import Model as Model
|
||||
from .model import asession as asession
|
||||
from .model import session as session
|
||||
from .page import page as page
|
||||
from .state import ComponentState as ComponentState
|
||||
from .state import Cookie as Cookie
|
||||
from .state import LocalStorage as LocalStorage
|
||||
from .state import SessionStorage as SessionStorage
|
||||
from .state import State as State
|
||||
from .state import dynamic as dynamic
|
||||
from .state import var as var
|
||||
from .style import Style as Style
|
||||
from .style import toggle_color_mode as toggle_color_mode
|
||||
from .utils.imports import ImportDict as ImportDict
|
||||
from .utils.imports import ImportVar as ImportVar
|
||||
from .utils.serializers import serializer as serializer
|
||||
from .vars import Field as Field
|
||||
from .vars import Var as Var
|
||||
from .vars import field as field
|
||||
|
||||
del compat
|
||||
RADIX_THEMES_MAPPING: dict
|
||||
|
403
reflex/app.py
403
reflex/app.py
@ -6,23 +6,26 @@ import asyncio
|
||||
import concurrent.futures
|
||||
import contextlib
|
||||
import copy
|
||||
import dataclasses
|
||||
import functools
|
||||
import inspect
|
||||
import io
|
||||
import json
|
||||
import multiprocessing
|
||||
import os
|
||||
import platform
|
||||
import sys
|
||||
import traceback
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from types import SimpleNamespace
|
||||
from typing import (
|
||||
TYPE_CHECKING,
|
||||
Any,
|
||||
AsyncIterator,
|
||||
Callable,
|
||||
Coroutine,
|
||||
Dict,
|
||||
Generic,
|
||||
List,
|
||||
Optional,
|
||||
Set,
|
||||
@ -44,10 +47,9 @@ from starlette_admin.contrib.sqla.view import ModelView
|
||||
from reflex import constants
|
||||
from reflex.admin import AdminDash
|
||||
from reflex.app_mixins import AppMixin, LifespanMixin, MiddlewareMixin
|
||||
from reflex.base import Base
|
||||
from reflex.compiler import compiler
|
||||
from reflex.compiler import utils as compiler_utils
|
||||
from reflex.compiler.compiler import ExecutorSafeFunctions
|
||||
from reflex.compiler.compiler import ExecutorSafeFunctions, compile_theme
|
||||
from reflex.components.base.app_wrap import AppWrap
|
||||
from reflex.components.base.error_boundary import ErrorBoundary
|
||||
from reflex.components.base.fragment import Fragment
|
||||
@ -64,12 +66,19 @@ from reflex.components.core.client_side_routing import (
|
||||
)
|
||||
from reflex.components.core.upload import Upload, get_upload_dir
|
||||
from reflex.components.radix import themes
|
||||
from reflex.config import get_config
|
||||
from reflex.event import Event, EventHandler, EventSpec, window_alert
|
||||
from reflex.model import Model, get_db_status
|
||||
from reflex.page import (
|
||||
DECORATED_PAGES,
|
||||
from reflex.config import environment, get_config
|
||||
from reflex.event import (
|
||||
BASE_STATE,
|
||||
Event,
|
||||
EventHandler,
|
||||
EventSpec,
|
||||
EventType,
|
||||
IndividualEventType,
|
||||
get_hydrate_event,
|
||||
window_alert,
|
||||
)
|
||||
from reflex.model import Model, get_db_status
|
||||
from reflex.page import DECORATED_PAGES
|
||||
from reflex.route import (
|
||||
get_route_args,
|
||||
replace_brackets_with_keywords,
|
||||
@ -85,9 +94,12 @@ from reflex.state import (
|
||||
code_uses_state_contexts,
|
||||
)
|
||||
from reflex.utils import codespaces, console, exceptions, format, prerequisites, types
|
||||
from reflex.utils.exec import is_prod_mode, is_testing_env, should_skip_compile
|
||||
from reflex.utils.exec import is_prod_mode, is_testing_env
|
||||
from reflex.utils.imports import ImportVar
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from reflex.vars import Var
|
||||
|
||||
# Define custom types.
|
||||
ComponentCallable = Callable[[], Component]
|
||||
Reducer = Callable[[Event], Coroutine[Any, Any, StateUpdate]]
|
||||
@ -170,7 +182,23 @@ class OverlayFragment(Fragment):
|
||||
pass
|
||||
|
||||
|
||||
class App(MiddlewareMixin, LifespanMixin, Base):
|
||||
@dataclasses.dataclass(
|
||||
frozen=True,
|
||||
)
|
||||
class UnevaluatedPage(Generic[BASE_STATE]):
|
||||
"""An uncompiled page."""
|
||||
|
||||
component: Union[Component, ComponentCallable]
|
||||
route: str
|
||||
title: Union[Var, str, None]
|
||||
description: Union[Var, str, None]
|
||||
image: str
|
||||
on_load: Union[EventType[[], BASE_STATE], None]
|
||||
meta: List[Dict[str, str]]
|
||||
|
||||
|
||||
@dataclasses.dataclass()
|
||||
class App(MiddlewareMixin, LifespanMixin):
|
||||
"""The main Reflex app that encapsulates the backend and frontend.
|
||||
|
||||
Every Reflex app needs an app defined in its main module.
|
||||
@ -192,24 +220,26 @@ class App(MiddlewareMixin, LifespanMixin, Base):
|
||||
"""
|
||||
|
||||
# The global [theme](https://reflex.dev/docs/styling/theming/#theme) for the entire app.
|
||||
theme: Optional[Component] = themes.theme(accent_color="blue")
|
||||
theme: Optional[Component] = dataclasses.field(
|
||||
default_factory=lambda: themes.theme(accent_color="blue")
|
||||
)
|
||||
|
||||
# The [global style](https://reflex.dev/docs/styling/overview/#global-styles}) for the app.
|
||||
style: ComponentStyle = {}
|
||||
style: ComponentStyle = dataclasses.field(default_factory=dict)
|
||||
|
||||
# A list of URLs to [stylesheets](https://reflex.dev/docs/styling/custom-stylesheets/) to include in the app.
|
||||
stylesheets: List[str] = []
|
||||
stylesheets: List[str] = dataclasses.field(default_factory=list)
|
||||
|
||||
# A component that is present on every page (defaults to the Connection Error banner).
|
||||
overlay_component: Optional[Union[Component, ComponentCallable]] = (
|
||||
default_overlay_component()
|
||||
dataclasses.field(default_factory=default_overlay_component)
|
||||
)
|
||||
|
||||
# Error boundary component to wrap the app with.
|
||||
error_boundary: Optional[ComponentCallable] = default_error_boundary
|
||||
|
||||
# Components to add to the head of every page.
|
||||
head_components: List[Component] = []
|
||||
head_components: List[Component] = dataclasses.field(default_factory=list)
|
||||
|
||||
# The Socket.IO AsyncServer instance.
|
||||
sio: Optional[AsyncServer] = None
|
||||
@ -220,8 +250,13 @@ class App(MiddlewareMixin, LifespanMixin, Base):
|
||||
# Attributes to add to the html root tag of every page.
|
||||
html_custom_attrs: Optional[Dict[str, str]] = None
|
||||
|
||||
# A map from a route to an unevaluated page. PRIVATE.
|
||||
unevaluated_pages: Dict[str, UnevaluatedPage] = dataclasses.field(
|
||||
default_factory=dict
|
||||
)
|
||||
|
||||
# A map from a page route to the component to render. Users should use `add_page`. PRIVATE.
|
||||
pages: Dict[str, Component] = {}
|
||||
pages: Dict[str, Component] = dataclasses.field(default_factory=dict)
|
||||
|
||||
# The backend API object. PRIVATE.
|
||||
api: FastAPI = None # type: ignore
|
||||
@ -233,7 +268,9 @@ class App(MiddlewareMixin, LifespanMixin, Base):
|
||||
_state_manager: Optional[StateManager] = None
|
||||
|
||||
# Mapping from a route to event handlers to trigger when the page loads. PRIVATE.
|
||||
load_events: Dict[str, List[Union[EventHandler, EventSpec]]] = {}
|
||||
load_events: Dict[str, List[IndividualEventType[[], Any]]] = dataclasses.field(
|
||||
default_factory=dict
|
||||
)
|
||||
|
||||
# Admin dashboard to view and manage the database. PRIVATE.
|
||||
admin_dash: Optional[AdminDash] = None
|
||||
@ -242,7 +279,7 @@ class App(MiddlewareMixin, LifespanMixin, Base):
|
||||
event_namespace: Optional[EventNamespace] = None
|
||||
|
||||
# Background tasks that are currently running. PRIVATE.
|
||||
background_tasks: Set[asyncio.Task] = set()
|
||||
background_tasks: Set[asyncio.Task] = dataclasses.field(default_factory=set)
|
||||
|
||||
# Frontend Error Handler Function
|
||||
frontend_exception_handler: Callable[[Exception], None] = (
|
||||
@ -254,23 +291,14 @@ class App(MiddlewareMixin, LifespanMixin, Base):
|
||||
[Exception], Union[EventSpec, List[EventSpec], None]
|
||||
] = default_backend_exception_handler
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
def __post_init__(self):
|
||||
"""Initialize the app.
|
||||
|
||||
Args:
|
||||
**kwargs: Kwargs to initialize the app with.
|
||||
|
||||
Raises:
|
||||
ValueError: If the event namespace is not provided in the config.
|
||||
Also, if there are multiple client subclasses of rx.BaseState(Subclasses of rx.BaseState should consist
|
||||
of the DefaultState and the client app state).
|
||||
"""
|
||||
if "connect_error_component" in kwargs:
|
||||
raise ValueError(
|
||||
"`connect_error_component` is deprecated, use `overlay_component` instead"
|
||||
)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Special case to allow test cases have multiple subclasses of rx.BaseState.
|
||||
if not is_testing_env() and BaseState.__subclasses__() != [State]:
|
||||
# Only rx.State is allowed as Base State subclass.
|
||||
@ -336,6 +364,11 @@ class App(MiddlewareMixin, LifespanMixin, Base):
|
||||
max_http_buffer_size=constants.POLLING_MAX_HTTP_BUFFER_SIZE,
|
||||
ping_interval=constants.Ping.INTERVAL,
|
||||
ping_timeout=constants.Ping.TIMEOUT,
|
||||
json=SimpleNamespace(
|
||||
dumps=staticmethod(format.json_dumps),
|
||||
loads=staticmethod(json.loads),
|
||||
),
|
||||
transports=["websocket"],
|
||||
)
|
||||
elif getattr(self.sio, "async_mode", "") != "asgi":
|
||||
raise RuntimeError(
|
||||
@ -381,8 +414,8 @@ class App(MiddlewareMixin, LifespanMixin, Base):
|
||||
|
||||
def _add_optional_endpoints(self):
|
||||
"""Add optional api endpoints (_upload)."""
|
||||
# To upload files.
|
||||
if Upload.is_used:
|
||||
# To upload files.
|
||||
self.api.post(str(constants.Endpoint.UPLOAD))(upload(self))
|
||||
|
||||
# To access uploaded files.
|
||||
@ -403,7 +436,7 @@ class App(MiddlewareMixin, LifespanMixin, Base):
|
||||
allow_credentials=True,
|
||||
allow_methods=["*"],
|
||||
allow_headers=["*"],
|
||||
allow_origins=["*"],
|
||||
allow_origins=get_config().cors_allowed_origins,
|
||||
)
|
||||
|
||||
@property
|
||||
@ -431,36 +464,21 @@ class App(MiddlewareMixin, LifespanMixin, Base):
|
||||
The generated component.
|
||||
|
||||
Raises:
|
||||
VarOperationTypeError: When an invalid component var related function is passed.
|
||||
TypeError: When an invalid component function is passed.
|
||||
exceptions.MatchTypeError: If the return types of match cases in rx.match are different.
|
||||
"""
|
||||
from reflex.utils.exceptions import VarOperationTypeError
|
||||
|
||||
try:
|
||||
return component if isinstance(component, Component) else component()
|
||||
except exceptions.MatchTypeError:
|
||||
raise
|
||||
except TypeError as e:
|
||||
message = str(e)
|
||||
if "Var" in message:
|
||||
raise VarOperationTypeError(
|
||||
"You may be trying to use an invalid Python function on a state var. "
|
||||
"When referencing a var inside your render code, only limited var operations are supported. "
|
||||
"See the var operation docs here: https://reflex.dev/docs/vars/var-operations/"
|
||||
) from e
|
||||
raise e
|
||||
|
||||
def add_page(
|
||||
self,
|
||||
component: Component | ComponentCallable,
|
||||
component: Component | ComponentCallable | None = None,
|
||||
route: str | None = None,
|
||||
title: str | None = None,
|
||||
description: str | None = None,
|
||||
title: str | Var | None = None,
|
||||
description: str | Var | None = None,
|
||||
image: str = constants.DefaultPage.IMAGE,
|
||||
on_load: (
|
||||
EventHandler | EventSpec | list[EventHandler | EventSpec] | None
|
||||
) = None,
|
||||
on_load: EventType[[], BASE_STATE] | None = None,
|
||||
meta: list[dict[str, str]] = constants.DefaultPage.META_LIST,
|
||||
):
|
||||
"""Add a page to the app.
|
||||
@ -478,33 +496,49 @@ class App(MiddlewareMixin, LifespanMixin, Base):
|
||||
meta: The metadata of the page.
|
||||
|
||||
Raises:
|
||||
ValueError: When the specified route name already exists.
|
||||
PageValueError: When the component is not set for a non-404 page.
|
||||
RouteValueError: When the specified route name already exists.
|
||||
"""
|
||||
# If the route is not set, get it from the callable.
|
||||
if route is None:
|
||||
if not isinstance(component, Callable):
|
||||
raise ValueError("Route must be set if component is not a callable.")
|
||||
raise exceptions.RouteValueError(
|
||||
"Route must be set if component is not a callable."
|
||||
)
|
||||
# Format the route.
|
||||
route = format.format_route(component.__name__)
|
||||
else:
|
||||
route = format.format_route(route, format_case=False)
|
||||
|
||||
if route == constants.Page404.SLUG:
|
||||
if component is None:
|
||||
component = Default404Page.create()
|
||||
component = wait_for_client_redirect(self._generate_component(component))
|
||||
title = title or constants.Page404.TITLE
|
||||
description = description or constants.Page404.DESCRIPTION
|
||||
image = image or constants.Page404.IMAGE
|
||||
else:
|
||||
if component is None:
|
||||
raise exceptions.PageValueError(
|
||||
"Component must be set for a non-404 page."
|
||||
)
|
||||
|
||||
# Check if the route given is valid
|
||||
verify_route_validity(route)
|
||||
|
||||
if route in self.pages and os.getenv(constants.RELOAD_CONFIG):
|
||||
if route in self.unevaluated_pages and environment.RELOAD_CONFIG.is_set():
|
||||
# when the app is reloaded(typically for app harness tests), we should maintain
|
||||
# the latest render function of a route.This applies typically to decorated pages
|
||||
# since they are only added when app._compile is called.
|
||||
self.pages.pop(route)
|
||||
self.unevaluated_pages.pop(route)
|
||||
|
||||
if route in self.pages:
|
||||
if route in self.unevaluated_pages:
|
||||
route_name = (
|
||||
f"`{route}` or `/`"
|
||||
if route == constants.PageNames.INDEX_ROUTE
|
||||
else f"`{route}`"
|
||||
)
|
||||
raise ValueError(
|
||||
raise exceptions.RouteValueError(
|
||||
f"Duplicate page route {route_name} already exists. Make sure you do not have two"
|
||||
f" pages with the same route"
|
||||
)
|
||||
@ -514,59 +548,39 @@ class App(MiddlewareMixin, LifespanMixin, Base):
|
||||
state = self.state if self.state else State
|
||||
state.setup_dynamic_args(get_route_args(route))
|
||||
|
||||
# Generate the component if it is a callable.
|
||||
component = self._generate_component(component)
|
||||
if on_load:
|
||||
self.load_events[route] = (
|
||||
on_load if isinstance(on_load, list) else [on_load]
|
||||
)
|
||||
|
||||
# unpack components that return tuples in an rx.fragment.
|
||||
if isinstance(component, tuple):
|
||||
component = Fragment.create(*component)
|
||||
|
||||
# Ensure state is enabled if this page uses state.
|
||||
if self.state is None:
|
||||
if on_load or component._has_stateful_event_triggers():
|
||||
self._enable_state()
|
||||
else:
|
||||
for var in component._get_vars(include_children=True):
|
||||
var_data = var._get_all_var_data()
|
||||
if not var_data:
|
||||
continue
|
||||
if not var_data.state:
|
||||
continue
|
||||
self._enable_state()
|
||||
break
|
||||
|
||||
component = OverlayFragment.create(component)
|
||||
|
||||
meta_args = {
|
||||
"title": (
|
||||
title
|
||||
if title is not None
|
||||
else format.make_default_page_title(get_config().app_name, route)
|
||||
),
|
||||
"image": image,
|
||||
"meta": meta,
|
||||
}
|
||||
|
||||
if description is not None:
|
||||
meta_args["description"] = description
|
||||
|
||||
# Add meta information to the component.
|
||||
compiler_utils.add_meta(
|
||||
component,
|
||||
**meta_args,
|
||||
self.unevaluated_pages[route] = UnevaluatedPage(
|
||||
component=component,
|
||||
route=route,
|
||||
title=title,
|
||||
description=description,
|
||||
image=image,
|
||||
on_load=on_load,
|
||||
meta=meta,
|
||||
)
|
||||
|
||||
def _compile_page(self, route: str):
|
||||
"""Compile a page.
|
||||
|
||||
Args:
|
||||
route: The route of the page to compile.
|
||||
"""
|
||||
component, enable_state = compiler.compile_unevaluated_page(
|
||||
route, self.unevaluated_pages[route], self.state, self.style, self.theme
|
||||
)
|
||||
|
||||
if enable_state:
|
||||
self._enable_state()
|
||||
|
||||
# Add the page.
|
||||
self._check_routes_conflict(route)
|
||||
self.pages[route] = component
|
||||
|
||||
# Add the load events.
|
||||
if on_load:
|
||||
if not isinstance(on_load, list):
|
||||
on_load = [on_load]
|
||||
self.load_events[route] = on_load
|
||||
|
||||
def get_load_events(self, route: str) -> list[EventHandler | EventSpec]:
|
||||
def get_load_events(self, route: str) -> list[IndividualEventType[[], Any]]:
|
||||
"""Get the load events for a route.
|
||||
|
||||
Args:
|
||||
@ -625,9 +639,7 @@ class App(MiddlewareMixin, LifespanMixin, Base):
|
||||
title: str = constants.Page404.TITLE,
|
||||
image: str = constants.Page404.IMAGE,
|
||||
description: str = constants.Page404.DESCRIPTION,
|
||||
on_load: (
|
||||
EventHandler | EventSpec | list[EventHandler | EventSpec] | None
|
||||
) = None,
|
||||
on_load: EventType[[], BASE_STATE] | None = None,
|
||||
meta: list[dict[str, str]] = constants.DefaultPage.META_LIST,
|
||||
):
|
||||
"""Define a custom 404 page for any url having no match.
|
||||
@ -643,10 +655,14 @@ class App(MiddlewareMixin, LifespanMixin, Base):
|
||||
on_load: The event handler(s) that will be called each time the page load.
|
||||
meta: The metadata of the page.
|
||||
"""
|
||||
if component is None:
|
||||
component = Default404Page.create()
|
||||
console.deprecate(
|
||||
feature_name="App.add_custom_404_page",
|
||||
reason=f"Use app.add_page(component, route='/{constants.Page404.SLUG}') instead.",
|
||||
deprecation_version="0.6.7",
|
||||
removal_version="0.8.0",
|
||||
)
|
||||
self.add_page(
|
||||
component=wait_for_client_redirect(self._generate_component(component)),
|
||||
component=component,
|
||||
route=constants.Page404.SLUG,
|
||||
title=title or constants.Page404.TITLE,
|
||||
image=image or constants.Page404.IMAGE,
|
||||
@ -692,7 +708,7 @@ class App(MiddlewareMixin, LifespanMixin, Base):
|
||||
for i, tags in imports.items()
|
||||
if i not in constants.PackageJson.DEPENDENCIES
|
||||
and i not in constants.PackageJson.DEV_DEPENDENCIES
|
||||
and not any(i.startswith(prefix) for prefix in ["/", ".", "next/"])
|
||||
and not any(i.startswith(prefix) for prefix in ["/", "$/", ".", "next/"])
|
||||
and i != ""
|
||||
and any(tag.install for tag in tags)
|
||||
}
|
||||
@ -731,7 +747,7 @@ class App(MiddlewareMixin, LifespanMixin, Base):
|
||||
Whether the app should be compiled.
|
||||
"""
|
||||
# Check the environment variable.
|
||||
if should_skip_compile():
|
||||
if environment.REFLEX_SKIP_COMPILE.get():
|
||||
return False
|
||||
|
||||
nocompile = prerequisites.get_web_dir() / constants.NOCOMPILE_FILE
|
||||
@ -840,12 +856,31 @@ class App(MiddlewareMixin, LifespanMixin, Base):
|
||||
"""
|
||||
from reflex.utils.exceptions import ReflexRuntimeError
|
||||
|
||||
self.pages = {}
|
||||
|
||||
def get_compilation_time() -> str:
|
||||
return str(datetime.now().time()).split(".")[0]
|
||||
|
||||
# Render a default 404 page if the user didn't supply one
|
||||
if constants.Page404.SLUG not in self.pages:
|
||||
self.add_custom_404_page()
|
||||
if constants.Page404.SLUG not in self.unevaluated_pages:
|
||||
self.add_page(route=constants.Page404.SLUG)
|
||||
|
||||
# Fix up the style.
|
||||
self.style = evaluate_style_namespaces(self.style)
|
||||
|
||||
# Add the app wrappers.
|
||||
app_wrappers: Dict[tuple[int, str], Component] = {
|
||||
# Default app wrap component renders {children}
|
||||
(0, "AppWrap"): AppWrap.create()
|
||||
}
|
||||
|
||||
if self.theme is not None:
|
||||
# If a theme component was provided, wrap the app with it
|
||||
app_wrappers[(20, "Theme")] = self.theme
|
||||
|
||||
for route in self.unevaluated_pages:
|
||||
console.debug(f"Evaluating page: {route}")
|
||||
self._compile_page(route)
|
||||
|
||||
# Add the optional endpoints (_upload)
|
||||
self._add_optional_endpoints()
|
||||
@ -881,28 +916,15 @@ class App(MiddlewareMixin, LifespanMixin, Base):
|
||||
# Store the compile results.
|
||||
compile_results = []
|
||||
|
||||
# Add the app wrappers.
|
||||
app_wrappers: Dict[tuple[int, str], Component] = {
|
||||
# Default app wrap component renders {children}
|
||||
(0, "AppWrap"): AppWrap.create()
|
||||
}
|
||||
if self.theme is not None:
|
||||
# If a theme component was provided, wrap the app with it
|
||||
app_wrappers[(20, "Theme")] = self.theme
|
||||
|
||||
progress.advance(task)
|
||||
|
||||
# Fix up the style.
|
||||
self.style = evaluate_style_namespaces(self.style)
|
||||
|
||||
# Track imports and custom components found.
|
||||
all_imports = {}
|
||||
custom_components = set()
|
||||
|
||||
for _route, component in self.pages.items():
|
||||
# Merge the component style with the app style.
|
||||
component._add_style_recursive(self.style, self.theme)
|
||||
|
||||
# This has to happen before compiling stateful components as that
|
||||
# prevents recursive functions from reaching all components.
|
||||
for component in self.pages.values():
|
||||
# Add component._get_all_imports() to all_imports.
|
||||
all_imports.update(component._get_all_imports())
|
||||
|
||||
@ -912,8 +934,6 @@ class App(MiddlewareMixin, LifespanMixin, Base):
|
||||
# Add the custom components from the page to the set.
|
||||
custom_components |= component._get_all_custom_components()
|
||||
|
||||
progress.advance(task)
|
||||
|
||||
# Perform auto-memoization of stateful components.
|
||||
(
|
||||
stateful_components_path,
|
||||
@ -931,6 +951,8 @@ class App(MiddlewareMixin, LifespanMixin, Base):
|
||||
)
|
||||
compile_results.append((stateful_components_path, stateful_components_code))
|
||||
|
||||
progress.advance(task)
|
||||
|
||||
# Compile the root document before fork.
|
||||
compile_results.append(
|
||||
compiler.compile_document_root(
|
||||
@ -940,77 +962,49 @@ class App(MiddlewareMixin, LifespanMixin, Base):
|
||||
)
|
||||
)
|
||||
|
||||
# Compile the contexts before fork.
|
||||
compile_results.append(
|
||||
compiler.compile_contexts(self.state, self.theme),
|
||||
)
|
||||
# Fix #2992 by removing the top-level appearance prop
|
||||
if self.theme is not None:
|
||||
self.theme.appearance = None
|
||||
|
||||
app_root = self._app_root(app_wrappers=app_wrappers)
|
||||
|
||||
progress.advance(task)
|
||||
|
||||
# Prepopulate the global ExecutorSafeFunctions class with input data required by the compile functions.
|
||||
# This is required for multiprocessing to work, in presence of non-picklable inputs.
|
||||
for route, component in zip(self.pages, page_components):
|
||||
ExecutorSafeFunctions.COMPILE_PAGE_ARGS_BY_ROUTE[route] = (
|
||||
route,
|
||||
component,
|
||||
self.state,
|
||||
)
|
||||
|
||||
ExecutorSafeFunctions.COMPILE_APP_APP_ROOT = app_root
|
||||
ExecutorSafeFunctions.CUSTOM_COMPONENTS = custom_components
|
||||
ExecutorSafeFunctions.STYLE = self.style
|
||||
|
||||
# Use a forking process pool, if possible. Much faster, especially for large sites.
|
||||
# Fallback to ThreadPoolExecutor as something that will always work.
|
||||
executor = None
|
||||
if (
|
||||
platform.system() in ("Linux", "Darwin")
|
||||
and os.environ.get("REFLEX_COMPILE_PROCESSES") is not None
|
||||
and (number_of_processes := environment.REFLEX_COMPILE_PROCESSES.get())
|
||||
is not None
|
||||
):
|
||||
executor = concurrent.futures.ProcessPoolExecutor(
|
||||
max_workers=int(os.environ.get("REFLEX_COMPILE_PROCESSES", 0)) or None,
|
||||
max_workers=number_of_processes or None,
|
||||
mp_context=multiprocessing.get_context("fork"),
|
||||
)
|
||||
else:
|
||||
executor = concurrent.futures.ThreadPoolExecutor(
|
||||
max_workers=int(os.environ.get("REFLEX_COMPILE_THREADS", 0)) or None,
|
||||
max_workers=environment.REFLEX_COMPILE_THREADS.get() or None
|
||||
)
|
||||
|
||||
for route, component in zip(self.pages, page_components):
|
||||
ExecutorSafeFunctions.COMPONENTS[route] = component
|
||||
|
||||
ExecutorSafeFunctions.STATE = self.state
|
||||
|
||||
with executor:
|
||||
result_futures = []
|
||||
custom_components_future = None
|
||||
|
||||
def _mark_complete(_=None):
|
||||
progress.advance(task)
|
||||
|
||||
def _submit_work(fn, *args, **kwargs):
|
||||
f = executor.submit(fn, *args, **kwargs)
|
||||
f.add_done_callback(_mark_complete)
|
||||
result_futures.append(f)
|
||||
|
||||
# Compile all page components.
|
||||
# Compile the pre-compiled pages.
|
||||
for route in self.pages:
|
||||
_submit_work(ExecutorSafeFunctions.compile_page, route)
|
||||
|
||||
# Compile the app wrapper.
|
||||
_submit_work(ExecutorSafeFunctions.compile_app)
|
||||
|
||||
# Compile the custom components.
|
||||
custom_components_future = executor.submit(
|
||||
ExecutorSafeFunctions.compile_custom_components,
|
||||
)
|
||||
custom_components_future.add_done_callback(_mark_complete)
|
||||
_submit_work(
|
||||
ExecutorSafeFunctions.compile_page,
|
||||
route,
|
||||
)
|
||||
|
||||
# Compile the root stylesheet with base styles.
|
||||
_submit_work(compiler.compile_root_stylesheet, self.stylesheets)
|
||||
|
||||
# Compile the theme.
|
||||
_submit_work(ExecutorSafeFunctions.compile_theme)
|
||||
_submit_work(compile_theme, self.style)
|
||||
|
||||
# Compile the Tailwind config.
|
||||
if config.tailwind is not None:
|
||||
@ -1024,21 +1018,37 @@ class App(MiddlewareMixin, LifespanMixin, Base):
|
||||
# Wait for all compilation tasks to complete.
|
||||
for future in concurrent.futures.as_completed(result_futures):
|
||||
compile_results.append(future.result())
|
||||
progress.advance(task)
|
||||
|
||||
# Special case for custom_components, since we need the compiled imports
|
||||
# to install proper frontend packages.
|
||||
(
|
||||
*custom_components_result,
|
||||
custom_components_imports,
|
||||
) = custom_components_future.result()
|
||||
compile_results.append(custom_components_result)
|
||||
all_imports.update(custom_components_imports)
|
||||
app_root = self._app_root(app_wrappers=app_wrappers)
|
||||
|
||||
# Get imports from AppWrap components.
|
||||
all_imports.update(app_root._get_all_imports())
|
||||
|
||||
progress.advance(task)
|
||||
|
||||
# Compile the contexts.
|
||||
compile_results.append(
|
||||
compiler.compile_contexts(self.state, self.theme),
|
||||
)
|
||||
if self.theme is not None:
|
||||
# Fix #2992 by removing the top-level appearance prop
|
||||
self.theme.appearance = None
|
||||
progress.advance(task)
|
||||
|
||||
# Compile the app root.
|
||||
compile_results.append(
|
||||
compiler.compile_app(app_root),
|
||||
)
|
||||
progress.advance(task)
|
||||
|
||||
# Compile custom components.
|
||||
*custom_components_result, custom_components_imports = (
|
||||
compiler.compile_components(custom_components)
|
||||
)
|
||||
compile_results.append(custom_components_result)
|
||||
all_imports.update(custom_components_imports)
|
||||
|
||||
progress.advance(task)
|
||||
progress.stop()
|
||||
|
||||
@ -1172,7 +1182,7 @@ class App(MiddlewareMixin, LifespanMixin, Base):
|
||||
if hasattr(handler_fn, "__name__"):
|
||||
_fn_name = handler_fn.__name__
|
||||
else:
|
||||
_fn_name = handler_fn.__class__.__name__
|
||||
_fn_name = type(handler_fn).__name__
|
||||
|
||||
if isinstance(handler_fn, functools.partial):
|
||||
raise ValueError(
|
||||
@ -1275,6 +1285,21 @@ async def process(
|
||||
)
|
||||
# Get the state for the session exclusively.
|
||||
async with app.state_manager.modify_state(event.substate_token) as state:
|
||||
# When this is a brand new instance of the state, signal the
|
||||
# frontend to reload before processing it.
|
||||
if (
|
||||
not state.router_data
|
||||
and event.name != get_hydrate_event(state)
|
||||
and app.event_namespace is not None
|
||||
):
|
||||
await asyncio.create_task(
|
||||
app.event_namespace.emit(
|
||||
"reload",
|
||||
data=event,
|
||||
to=sid,
|
||||
)
|
||||
)
|
||||
return
|
||||
# re-assign only when the value is different
|
||||
if state.router_data != router_data:
|
||||
# assignment will recurse into substates and force recalculation of
|
||||
@ -1405,7 +1430,7 @@ def upload(app: App):
|
||||
if isinstance(func, EventHandler):
|
||||
if func.is_background:
|
||||
raise UploadTypeError(
|
||||
f"@rx.background is not supported for upload handler `{handler}`.",
|
||||
f"@rx.event(background=True) is not supported for upload handler `{handler}`.",
|
||||
)
|
||||
func = func.fn
|
||||
if isinstance(func, functools.partial):
|
||||
@ -1478,10 +1503,10 @@ class EventNamespace(AsyncNamespace):
|
||||
app: App
|
||||
|
||||
# Keep a mapping between socket ID and client token.
|
||||
token_to_sid: dict[str, str] = {}
|
||||
token_to_sid: dict[str, str]
|
||||
|
||||
# Keep a mapping between client token and socket ID.
|
||||
sid_to_token: dict[str, str] = {}
|
||||
sid_to_token: dict[str, str]
|
||||
|
||||
def __init__(self, namespace: str, app: App):
|
||||
"""Initialize the event namespace.
|
||||
@ -1491,6 +1516,8 @@ class EventNamespace(AsyncNamespace):
|
||||
app: The application object.
|
||||
"""
|
||||
super().__init__(namespace)
|
||||
self.token_to_sid = {}
|
||||
self.sid_to_token = {}
|
||||
self.app = app
|
||||
|
||||
def on_connect(self, sid, environ):
|
||||
@ -1521,7 +1548,7 @@ class EventNamespace(AsyncNamespace):
|
||||
"""
|
||||
# Creating a task prevents the update from being blocked behind other coroutines.
|
||||
await asyncio.create_task(
|
||||
self.emit(str(constants.SocketEvent.EVENT), update.json(), to=sid)
|
||||
self.emit(str(constants.SocketEvent.EVENT), update, to=sid)
|
||||
)
|
||||
|
||||
async def on_event(self, sid, data):
|
||||
@ -1534,9 +1561,11 @@ class EventNamespace(AsyncNamespace):
|
||||
sid: The Socket.IO session id.
|
||||
data: The event data.
|
||||
"""
|
||||
fields = json.loads(data)
|
||||
fields = data
|
||||
# Get the event.
|
||||
event = Event(**{k: v for k, v in fields.items() if k != "handler"})
|
||||
event = Event(
|
||||
**{k: v for k, v in fields.items() if k not in ("handler", "event_actions")}
|
||||
)
|
||||
|
||||
self.token_to_sid[event.token] = sid
|
||||
self.sid_to_token[sid] = event.token
|
||||
|
@ -4,6 +4,7 @@ from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import contextlib
|
||||
import dataclasses
|
||||
import functools
|
||||
import inspect
|
||||
from typing import Callable, Coroutine, Set, Union
|
||||
@ -16,11 +17,14 @@ from reflex.utils.exceptions import InvalidLifespanTaskType
|
||||
from .mixin import AppMixin
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class LifespanMixin(AppMixin):
|
||||
"""A Mixin that allow tasks to run during the whole app lifespan."""
|
||||
|
||||
# Lifespan tasks that are planned to run.
|
||||
lifespan_tasks: Set[Union[asyncio.Task, Callable]] = set()
|
||||
lifespan_tasks: Set[Union[asyncio.Task, Callable]] = dataclasses.field(
|
||||
default_factory=set
|
||||
)
|
||||
|
||||
@contextlib.asynccontextmanager
|
||||
async def _run_lifespan_tasks(self, app: FastAPI):
|
||||
|
@ -3,6 +3,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import dataclasses
|
||||
from typing import List
|
||||
|
||||
from reflex.event import Event
|
||||
@ -12,11 +13,12 @@ from reflex.state import BaseState, StateUpdate
|
||||
from .mixin import AppMixin
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class MiddlewareMixin(AppMixin):
|
||||
"""Middleware Mixin that allow to add middleware to the app."""
|
||||
|
||||
# Middleware to add to the app. Users should use `add_middleware`. PRIVATE.
|
||||
middleware: List[Middleware] = []
|
||||
middleware: List[Middleware] = dataclasses.field(default_factory=list)
|
||||
|
||||
def _init_mixin(self):
|
||||
self.middleware.append(HydrateMiddleware())
|
||||
|
@ -1,9 +1,10 @@
|
||||
"""Default mixin for all app mixins."""
|
||||
|
||||
from reflex.base import Base
|
||||
import dataclasses
|
||||
|
||||
|
||||
class AppMixin(Base):
|
||||
@dataclasses.dataclass
|
||||
class AppMixin:
|
||||
"""Define the base class for all app mixins."""
|
||||
|
||||
def _init_mixin(self):
|
||||
|
95
reflex/assets.py
Normal file
95
reflex/assets.py
Normal file
@ -0,0 +1,95 @@
|
||||
"""Helper functions for adding assets to the app."""
|
||||
|
||||
import inspect
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
from reflex import constants
|
||||
from reflex.config import EnvironmentVariables
|
||||
|
||||
|
||||
def asset(
|
||||
path: str,
|
||||
shared: bool = False,
|
||||
subfolder: Optional[str] = None,
|
||||
_stack_level: int = 1,
|
||||
) -> str:
|
||||
"""Add an asset to the app, either shared as a symlink or local.
|
||||
|
||||
Shared/External/Library assets:
|
||||
Place the file next to your including python file.
|
||||
Links the file to the app's external assets directory.
|
||||
|
||||
Example:
|
||||
```python
|
||||
# my_custom_javascript.js is a shared asset located next to the including python file.
|
||||
rx.script(src=rx.asset(path="my_custom_javascript.js", shared=True))
|
||||
rx.image(src=rx.asset(path="test_image.png", shared=True, subfolder="subfolder"))
|
||||
```
|
||||
|
||||
Local/Internal assets:
|
||||
Place the file in the app's assets/ directory.
|
||||
|
||||
Example:
|
||||
```python
|
||||
# local_image.png is an asset located in the app's assets/ directory. It cannot be shared when developing a library.
|
||||
rx.image(src=rx.asset(path="local_image.png"))
|
||||
```
|
||||
|
||||
Args:
|
||||
path: The relative path of the asset.
|
||||
subfolder: The directory to place the shared asset in.
|
||||
shared: Whether to expose the asset to other apps.
|
||||
_stack_level: The stack level to determine the calling file, defaults to
|
||||
the immediate caller 1. When using rx.asset via a helper function,
|
||||
increase this number for each helper function in the stack.
|
||||
|
||||
Raises:
|
||||
FileNotFoundError: If the file does not exist.
|
||||
ValueError: If subfolder is provided for local assets.
|
||||
|
||||
Returns:
|
||||
The relative URL to the asset.
|
||||
"""
|
||||
assets = constants.Dirs.APP_ASSETS
|
||||
backend_only = EnvironmentVariables.REFLEX_BACKEND_ONLY.get()
|
||||
|
||||
# Local asset handling
|
||||
if not shared:
|
||||
cwd = Path.cwd()
|
||||
src_file_local = cwd / assets / path
|
||||
if subfolder is not None:
|
||||
raise ValueError("Subfolder is not supported for local assets.")
|
||||
if not backend_only and not src_file_local.exists():
|
||||
raise FileNotFoundError(f"File not found: {src_file_local}")
|
||||
return f"/{path}"
|
||||
|
||||
# Shared asset handling
|
||||
# Determine the file by which the asset is exposed.
|
||||
frame = inspect.stack()[_stack_level]
|
||||
calling_file = frame.filename
|
||||
module = inspect.getmodule(frame[0])
|
||||
assert module is not None
|
||||
|
||||
external = constants.Dirs.EXTERNAL_APP_ASSETS
|
||||
src_file_shared = Path(calling_file).parent / path
|
||||
if not src_file_shared.exists():
|
||||
raise FileNotFoundError(f"File not found: {src_file_shared}")
|
||||
|
||||
caller_module_path = module.__name__.replace(".", "/")
|
||||
subfolder = f"{caller_module_path}/{subfolder}" if subfolder else caller_module_path
|
||||
|
||||
# Symlink the asset to the app's external assets directory if running frontend.
|
||||
if not backend_only:
|
||||
# Create the asset folder in the currently compiling app.
|
||||
asset_folder = Path.cwd() / assets / external / subfolder
|
||||
asset_folder.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
dst_file = asset_folder / path
|
||||
|
||||
if not dst_file.exists() and (
|
||||
not dst_file.is_symlink() or dst_file.resolve() != src_file_shared.resolve()
|
||||
):
|
||||
dst_file.symlink_to(src_file_shared)
|
||||
|
||||
return f"/{external}/{subfolder}/{path}"
|
@ -16,9 +16,6 @@ except ModuleNotFoundError:
|
||||
from pydantic.fields import ModelField # type: ignore
|
||||
|
||||
|
||||
from reflex import constants
|
||||
|
||||
|
||||
def validate_field_name(bases: List[Type["BaseModel"]], field_name: str) -> None:
|
||||
"""Ensure that the field's name does not shadow an existing attribute of the model.
|
||||
|
||||
@ -31,7 +28,8 @@ def validate_field_name(bases: List[Type["BaseModel"]], field_name: str) -> None
|
||||
"""
|
||||
from reflex.utils.exceptions import VarNameError
|
||||
|
||||
reload = os.getenv(constants.RELOAD_CONFIG) == "True"
|
||||
# can't use reflex.config.environment here cause of circular import
|
||||
reload = os.getenv("__RELOAD_CONFIG", "").lower() == "true"
|
||||
for base in bases:
|
||||
try:
|
||||
if not reload and getattr(base, field_name, None):
|
||||
@ -132,8 +130,8 @@ class Base(BaseModel): # pyright: ignore [reportUnboundVariable]
|
||||
Returns:
|
||||
The value of the field.
|
||||
"""
|
||||
if isinstance(key, str) and key in self.__fields__:
|
||||
if isinstance(key, str):
|
||||
# Seems like this function signature was wrong all along?
|
||||
# If the user wants a field that we know of, get it and pass it off to _get_value
|
||||
key = getattr(self, key)
|
||||
return getattr(self, key, key)
|
||||
return key
|
||||
|
@ -2,13 +2,13 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from typing import Dict, Iterable, Optional, Type, Union
|
||||
from typing import TYPE_CHECKING, Dict, Iterable, Optional, Tuple, Type, Union
|
||||
|
||||
from reflex import constants
|
||||
from reflex.compiler import templates, utils
|
||||
from reflex.components.base.fragment import Fragment
|
||||
from reflex.components.component import (
|
||||
BaseComponent,
|
||||
Component,
|
||||
@ -16,7 +16,7 @@ from reflex.components.component import (
|
||||
CustomComponent,
|
||||
StatefulComponent,
|
||||
)
|
||||
from reflex.config import get_config
|
||||
from reflex.config import environment, get_config
|
||||
from reflex.state import BaseState
|
||||
from reflex.style import SYSTEM_COLOR_MODE
|
||||
from reflex.utils.exec import is_prod_mode
|
||||
@ -40,6 +40,20 @@ def _compile_document_root(root: Component) -> str:
|
||||
)
|
||||
|
||||
|
||||
def _normalize_library_name(lib: str) -> str:
|
||||
"""Normalize the library name.
|
||||
|
||||
Args:
|
||||
lib: The library name to normalize.
|
||||
|
||||
Returns:
|
||||
The normalized library name.
|
||||
"""
|
||||
if lib == "react":
|
||||
return "React"
|
||||
return lib.replace("@", "").replace("/", "_").replace("-", "_")
|
||||
|
||||
|
||||
def _compile_app(app_root: Component) -> str:
|
||||
"""Compile the app template component.
|
||||
|
||||
@ -49,10 +63,20 @@ def _compile_app(app_root: Component) -> str:
|
||||
Returns:
|
||||
The compiled app.
|
||||
"""
|
||||
from reflex.components.dynamic import bundled_libraries
|
||||
|
||||
window_libraries = [
|
||||
(_normalize_library_name(name), name) for name in bundled_libraries
|
||||
] + [
|
||||
("utils_context", f"$/{constants.Dirs.UTILS}/context"),
|
||||
("utils_state", f"$/{constants.Dirs.UTILS}/state"),
|
||||
]
|
||||
|
||||
return templates.APP_ROOT.render(
|
||||
imports=utils.compile_imports(app_root._get_all_imports()),
|
||||
custom_codes=app_root._get_all_custom_code(),
|
||||
hooks={**app_root._get_all_hooks_internal(), **app_root._get_all_hooks()},
|
||||
window_libraries=window_libraries,
|
||||
render=app_root.render(),
|
||||
)
|
||||
|
||||
@ -103,8 +127,8 @@ def _compile_contexts(state: Optional[Type[BaseState]], theme: Component | None)
|
||||
|
||||
|
||||
def _compile_page(
|
||||
component: Component,
|
||||
state: Type[BaseState],
|
||||
component: BaseComponent,
|
||||
state: Type[BaseState] | None,
|
||||
) -> str:
|
||||
"""Compile the component given the app state.
|
||||
|
||||
@ -119,7 +143,7 @@ def _compile_page(
|
||||
imports = utils.compile_imports(imports)
|
||||
|
||||
# Compile the code to render the component.
|
||||
kwargs = {"state_name": state.get_name()} if state else {}
|
||||
kwargs = {"state_name": state.get_name()} if state is not None else {}
|
||||
|
||||
return templates.PAGE.render(
|
||||
imports=imports,
|
||||
@ -171,7 +195,7 @@ def _compile_root_stylesheet(stylesheets: list[str]) -> str:
|
||||
stylesheet_full_path = (
|
||||
Path.cwd() / constants.Dirs.APP_ASSETS / stylesheet.strip("/")
|
||||
)
|
||||
if not os.path.exists(stylesheet_full_path):
|
||||
if not stylesheet_full_path.exists():
|
||||
raise FileNotFoundError(
|
||||
f"The stylesheet file {stylesheet_full_path} does not exist."
|
||||
)
|
||||
@ -205,7 +229,7 @@ def _compile_components(
|
||||
"""
|
||||
imports = {
|
||||
"react": [ImportVar(tag="memo")],
|
||||
f"/{constants.Dirs.STATE_PATH}": [ImportVar(tag="E"), ImportVar(tag="isTrue")],
|
||||
f"$/{constants.Dirs.STATE_PATH}": [ImportVar(tag="E"), ImportVar(tag="isTrue")],
|
||||
}
|
||||
component_renders = []
|
||||
|
||||
@ -292,7 +316,7 @@ def _compile_stateful_components(
|
||||
# Don't import from the file that we're about to create.
|
||||
all_imports = utils.merge_imports(*all_import_dicts)
|
||||
all_imports.pop(
|
||||
f"/{constants.Dirs.UTILS}/{constants.PageNames.STATEFUL_COMPONENTS}", None
|
||||
f"$/{constants.Dirs.UTILS}/{constants.PageNames.STATEFUL_COMPONENTS}", None
|
||||
)
|
||||
|
||||
return templates.STATEFUL_COMPONENTS.render(
|
||||
@ -401,7 +425,7 @@ def compile_contexts(
|
||||
|
||||
|
||||
def compile_page(
|
||||
path: str, component: Component, state: Type[BaseState]
|
||||
path: str, component: BaseComponent, state: Type[BaseState] | None
|
||||
) -> tuple[str, str]:
|
||||
"""Compile a single page.
|
||||
|
||||
@ -503,7 +527,7 @@ def remove_tailwind_from_postcss() -> tuple[str, str]:
|
||||
|
||||
def purge_web_pages_dir():
|
||||
"""Empty out .web/pages directory."""
|
||||
if not is_prod_mode() and os.environ.get("REFLEX_PERSIST_WEB_DIR"):
|
||||
if not is_prod_mode() and environment.REFLEX_PERSIST_WEB_DIR.get():
|
||||
# Skip purging the web directory in dev mode if REFLEX_PERSIST_WEB_DIR is set.
|
||||
return
|
||||
|
||||
@ -511,6 +535,81 @@ def purge_web_pages_dir():
|
||||
utils.empty_dir(get_web_dir() / constants.Dirs.PAGES, keep_files=["_app.js"])
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from reflex.app import UnevaluatedPage
|
||||
|
||||
|
||||
def compile_unevaluated_page(
|
||||
route: str,
|
||||
page: UnevaluatedPage,
|
||||
state: Type[BaseState] | None = None,
|
||||
style: ComponentStyle | None = None,
|
||||
theme: Component | None = None,
|
||||
) -> Tuple[Component, bool]:
|
||||
"""Compiles an uncompiled page into a component and adds meta information.
|
||||
|
||||
Args:
|
||||
route: The route of the page.
|
||||
page: The uncompiled page object.
|
||||
state: The state of the app.
|
||||
style: The style of the page.
|
||||
theme: The theme of the page.
|
||||
|
||||
Returns:
|
||||
The compiled component and whether state should be enabled.
|
||||
"""
|
||||
# Generate the component if it is a callable.
|
||||
component = page.component
|
||||
component = component if isinstance(component, Component) else component()
|
||||
|
||||
# unpack components that return tuples in an rx.fragment.
|
||||
if isinstance(component, tuple):
|
||||
component = Fragment.create(*component)
|
||||
|
||||
component._add_style_recursive(style or {}, theme)
|
||||
|
||||
enable_state = False
|
||||
# Ensure state is enabled if this page uses state.
|
||||
if state is None:
|
||||
if page.on_load or component._has_stateful_event_triggers():
|
||||
enable_state = True
|
||||
else:
|
||||
for var in component._get_vars(include_children=True):
|
||||
var_data = var._get_all_var_data()
|
||||
if not var_data:
|
||||
continue
|
||||
if not var_data.state:
|
||||
continue
|
||||
enable_state = True
|
||||
break
|
||||
|
||||
from reflex.app import OverlayFragment
|
||||
from reflex.utils.format import make_default_page_title
|
||||
|
||||
component = OverlayFragment.create(component)
|
||||
|
||||
meta_args = {
|
||||
"title": (
|
||||
page.title
|
||||
if page.title is not None
|
||||
else make_default_page_title(get_config().app_name, route)
|
||||
),
|
||||
"image": page.image,
|
||||
"meta": page.meta,
|
||||
}
|
||||
|
||||
if page.description is not None:
|
||||
meta_args["description"] = page.description
|
||||
|
||||
# Add meta information to the component.
|
||||
utils.add_meta(
|
||||
component,
|
||||
**meta_args,
|
||||
)
|
||||
|
||||
return component, enable_state
|
||||
|
||||
|
||||
class ExecutorSafeFunctions:
|
||||
"""Helper class to allow parallelisation of parts of the compilation process.
|
||||
|
||||
@ -536,13 +635,12 @@ class ExecutorSafeFunctions:
|
||||
|
||||
"""
|
||||
|
||||
COMPILE_PAGE_ARGS_BY_ROUTE = {}
|
||||
COMPILE_APP_APP_ROOT: Component | None = None
|
||||
CUSTOM_COMPONENTS: set[CustomComponent] | None = None
|
||||
STYLE: ComponentStyle | None = None
|
||||
COMPONENTS: Dict[str, BaseComponent] = {}
|
||||
UNCOMPILED_PAGES: Dict[str, UnevaluatedPage] = {}
|
||||
STATE: Optional[Type[BaseState]] = None
|
||||
|
||||
@classmethod
|
||||
def compile_page(cls, route: str):
|
||||
def compile_page(cls, route: str) -> tuple[str, str]:
|
||||
"""Compile a page.
|
||||
|
||||
Args:
|
||||
@ -551,46 +649,45 @@ class ExecutorSafeFunctions:
|
||||
Returns:
|
||||
The path and code of the compiled page.
|
||||
"""
|
||||
return compile_page(*cls.COMPILE_PAGE_ARGS_BY_ROUTE[route])
|
||||
return compile_page(route, cls.COMPONENTS[route], cls.STATE)
|
||||
|
||||
@classmethod
|
||||
def compile_app(cls):
|
||||
"""Compile the app.
|
||||
def compile_unevaluated_page(
|
||||
cls,
|
||||
route: str,
|
||||
style: ComponentStyle,
|
||||
theme: Component | None,
|
||||
) -> tuple[str, Component, tuple[str, str]]:
|
||||
"""Compile an unevaluated page.
|
||||
|
||||
Args:
|
||||
route: The route of the page to compile.
|
||||
style: The style of the page.
|
||||
theme: The theme of the page.
|
||||
|
||||
Returns:
|
||||
The path and code of the compiled app.
|
||||
|
||||
Raises:
|
||||
ValueError: If the app root is not set.
|
||||
The route, compiled component, and compiled page.
|
||||
"""
|
||||
if cls.COMPILE_APP_APP_ROOT is None:
|
||||
raise ValueError("COMPILE_APP_APP_ROOT should be set")
|
||||
return compile_app(cls.COMPILE_APP_APP_ROOT)
|
||||
component, enable_state = compile_unevaluated_page(
|
||||
route, cls.UNCOMPILED_PAGES[route]
|
||||
)
|
||||
component = component if isinstance(component, Component) else component()
|
||||
component._add_style_recursive(style, theme)
|
||||
return route, component, compile_page(route, component, cls.STATE)
|
||||
|
||||
@classmethod
|
||||
def compile_custom_components(cls):
|
||||
"""Compile the custom components.
|
||||
|
||||
Returns:
|
||||
The path and code of the compiled custom components.
|
||||
|
||||
Raises:
|
||||
ValueError: If the custom components are not set.
|
||||
"""
|
||||
if cls.CUSTOM_COMPONENTS is None:
|
||||
raise ValueError("CUSTOM_COMPONENTS should be set")
|
||||
return compile_components(cls.CUSTOM_COMPONENTS)
|
||||
|
||||
@classmethod
|
||||
def compile_theme(cls):
|
||||
def compile_theme(cls, style: ComponentStyle | None) -> tuple[str, str]:
|
||||
"""Compile the theme.
|
||||
|
||||
Args:
|
||||
style: The style to compile.
|
||||
|
||||
Returns:
|
||||
The path and code of the compiled theme.
|
||||
|
||||
Raises:
|
||||
ValueError: If the style is not set.
|
||||
"""
|
||||
if cls.STYLE is None:
|
||||
if style is None:
|
||||
raise ValueError("STYLE should be set")
|
||||
return compile_theme(cls.STYLE)
|
||||
return compile_theme(style)
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
from typing import Any, Callable, Dict, Optional, Type, Union
|
||||
from urllib.parse import urlparse
|
||||
@ -29,7 +28,8 @@ from reflex.components.base import (
|
||||
Title,
|
||||
)
|
||||
from reflex.components.component import Component, ComponentStyle, CustomComponent
|
||||
from reflex.state import BaseState, Cookie, LocalStorage, SessionStorage
|
||||
from reflex.istate.storage import Cookie, LocalStorage, SessionStorage
|
||||
from reflex.state import BaseState
|
||||
from reflex.style import Style
|
||||
from reflex.utils import console, format, imports, path_ops
|
||||
from reflex.utils.imports import ImportVar, ParsedImportDict
|
||||
@ -83,6 +83,12 @@ def validate_imports(import_dict: ParsedImportDict):
|
||||
f"{_import.tag}/{_import.alias}" if _import.alias else _import.tag
|
||||
)
|
||||
if import_name in used_tags:
|
||||
already_imported = used_tags[import_name]
|
||||
if (already_imported[0] == "$" and already_imported[1:] == lib) or (
|
||||
lib[0] == "$" and lib[1:] == already_imported
|
||||
):
|
||||
used_tags[import_name] = lib if lib[0] == "$" else already_imported
|
||||
continue
|
||||
raise ValueError(
|
||||
f"Can not compile, the tag {import_name} is used multiple time from {lib} and {used_tags[import_name]}"
|
||||
)
|
||||
@ -457,16 +463,16 @@ def add_meta(
|
||||
return page
|
||||
|
||||
|
||||
def write_page(path: str, code: str):
|
||||
def write_page(path: str | Path, code: str):
|
||||
"""Write the given code to the given path.
|
||||
|
||||
Args:
|
||||
path: The path to write the code to.
|
||||
code: The code to write.
|
||||
"""
|
||||
path_ops.mkdir(os.path.dirname(path))
|
||||
with open(path, "w", encoding="utf-8") as f:
|
||||
f.write(code)
|
||||
path = Path(path)
|
||||
path_ops.mkdir(path.parent)
|
||||
path.write_text(code, encoding="utf-8")
|
||||
|
||||
|
||||
def empty_dir(path: str | Path, keep_files: list[str] | None = None):
|
||||
|
@ -3,10 +3,10 @@
|
||||
# ------------------- DO NOT EDIT ----------------------
|
||||
# This file was generated by `reflex/utils/pyi_generator.py`!
|
||||
# ------------------------------------------------------
|
||||
from typing import Any, Callable, Dict, Optional, Union, overload
|
||||
from typing import Any, Dict, Optional, Union, overload
|
||||
|
||||
from reflex.components.base.fragment import Fragment
|
||||
from reflex.event import EventHandler, EventSpec
|
||||
from reflex.event import BASE_STATE, EventType
|
||||
from reflex.style import Style
|
||||
from reflex.vars.base import Var
|
||||
|
||||
@ -21,42 +21,22 @@ class AppWrap(Fragment):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "AppWrap":
|
||||
"""Create a new AppWrap component.
|
||||
|
@ -4,10 +4,11 @@ from __future__ import annotations
|
||||
|
||||
from typing import Any, Iterator
|
||||
|
||||
from reflex.components.component import Component
|
||||
from reflex.components.component import Component, LiteralComponentVar
|
||||
from reflex.components.tags import Tag
|
||||
from reflex.components.tags.tagless import Tagless
|
||||
from reflex.vars import ArrayVar, BooleanVar, ObjectVar, Var
|
||||
from reflex.utils.imports import ParsedImportDict
|
||||
from reflex.vars import BooleanVar, ObjectVar, Var
|
||||
|
||||
|
||||
class Bare(Component):
|
||||
@ -31,11 +32,79 @@ class Bare(Component):
|
||||
contents = str(contents) if contents is not None else ""
|
||||
return cls(contents=contents) # type: ignore
|
||||
|
||||
def _get_all_hooks_internal(self) -> dict[str, None]:
|
||||
"""Include the hooks for the component.
|
||||
|
||||
Returns:
|
||||
The hooks for the component.
|
||||
"""
|
||||
hooks = super()._get_all_hooks_internal()
|
||||
if isinstance(self.contents, LiteralComponentVar):
|
||||
hooks |= self.contents._var_value._get_all_hooks_internal()
|
||||
return hooks
|
||||
|
||||
def _get_all_hooks(self) -> dict[str, None]:
|
||||
"""Include the hooks for the component.
|
||||
|
||||
Returns:
|
||||
The hooks for the component.
|
||||
"""
|
||||
hooks = super()._get_all_hooks()
|
||||
if isinstance(self.contents, LiteralComponentVar):
|
||||
hooks |= self.contents._var_value._get_all_hooks()
|
||||
return hooks
|
||||
|
||||
def _get_all_imports(self) -> ParsedImportDict:
|
||||
"""Include the imports for the component.
|
||||
|
||||
Returns:
|
||||
The imports for the component.
|
||||
"""
|
||||
imports = super()._get_all_imports()
|
||||
if isinstance(self.contents, LiteralComponentVar):
|
||||
var_data = self.contents._get_all_var_data()
|
||||
if var_data:
|
||||
imports |= {k: list(v) for k, v in var_data.imports}
|
||||
return imports
|
||||
|
||||
def _get_all_dynamic_imports(self) -> set[str]:
|
||||
"""Get dynamic imports for the component.
|
||||
|
||||
Returns:
|
||||
The dynamic imports.
|
||||
"""
|
||||
dynamic_imports = super()._get_all_dynamic_imports()
|
||||
if isinstance(self.contents, LiteralComponentVar):
|
||||
dynamic_imports |= self.contents._var_value._get_all_dynamic_imports()
|
||||
return dynamic_imports
|
||||
|
||||
def _get_all_custom_code(self) -> set[str]:
|
||||
"""Get custom code for the component.
|
||||
|
||||
Returns:
|
||||
The custom code.
|
||||
"""
|
||||
custom_code = super()._get_all_custom_code()
|
||||
if isinstance(self.contents, LiteralComponentVar):
|
||||
custom_code |= self.contents._var_value._get_all_custom_code()
|
||||
return custom_code
|
||||
|
||||
def _get_all_refs(self) -> set[str]:
|
||||
"""Get the refs for the children of the component.
|
||||
|
||||
Returns:
|
||||
The refs for the children.
|
||||
"""
|
||||
refs = super()._get_all_refs()
|
||||
if isinstance(self.contents, LiteralComponentVar):
|
||||
refs |= self.contents._var_value._get_all_refs()
|
||||
return refs
|
||||
|
||||
def _render(self) -> Tag:
|
||||
if isinstance(self.contents, Var):
|
||||
if isinstance(self.contents, (BooleanVar, ObjectVar, ArrayVar)):
|
||||
return Tagless(contents=f"{{{str(self.contents.to_string())}}}")
|
||||
return Tagless(contents=f"{{{str(self.contents)}}}")
|
||||
if isinstance(self.contents, (BooleanVar, ObjectVar)):
|
||||
return Tagless(contents=f"{{{self.contents.to_string()!s}}}")
|
||||
return Tagless(contents=f"{{{self.contents!s}}}")
|
||||
return Tagless(contents=str(self.contents))
|
||||
|
||||
def _get_vars(self, include_children: bool = False) -> Iterator[Var]:
|
||||
|
@ -3,10 +3,10 @@
|
||||
# ------------------- DO NOT EDIT ----------------------
|
||||
# This file was generated by `reflex/utils/pyi_generator.py`!
|
||||
# ------------------------------------------------------
|
||||
from typing import Any, Callable, Dict, Optional, Union, overload
|
||||
from typing import Any, Dict, Optional, Union, overload
|
||||
|
||||
from reflex.components.component import Component
|
||||
from reflex.event import EventHandler, EventSpec
|
||||
from reflex.event import BASE_STATE, EventType
|
||||
from reflex.style import Style
|
||||
from reflex.vars.base import Var
|
||||
|
||||
@ -21,42 +21,22 @@ class Body(Component):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "Body":
|
||||
"""Create the component.
|
||||
|
@ -3,10 +3,10 @@
|
||||
# ------------------- DO NOT EDIT ----------------------
|
||||
# This file was generated by `reflex/utils/pyi_generator.py`!
|
||||
# ------------------------------------------------------
|
||||
from typing import Any, Callable, Dict, Optional, Union, overload
|
||||
from typing import Any, Dict, Optional, Union, overload
|
||||
|
||||
from reflex.components.component import Component
|
||||
from reflex.event import EventHandler, EventSpec
|
||||
from reflex.event import BASE_STATE, EventType
|
||||
from reflex.style import Style
|
||||
from reflex.vars.base import Var
|
||||
|
||||
@ -21,42 +21,22 @@ class NextDocumentLib(Component):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "NextDocumentLib":
|
||||
"""Create the component.
|
||||
@ -88,42 +68,22 @@ class Html(NextDocumentLib):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "Html":
|
||||
"""Create the component.
|
||||
@ -154,42 +114,22 @@ class DocumentHead(NextDocumentLib):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "DocumentHead":
|
||||
"""Create the component.
|
||||
@ -220,42 +160,22 @@ class Main(NextDocumentLib):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "Main":
|
||||
"""Create the component.
|
||||
@ -286,42 +206,22 @@ class NextScript(NextDocumentLib):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "NextScript":
|
||||
"""Create the component.
|
||||
|
@ -2,16 +2,33 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import List
|
||||
from typing import Dict, Tuple
|
||||
|
||||
from reflex.compiler.compiler import _compile_component
|
||||
from reflex.components.component import Component
|
||||
from reflex.components.el import div, p
|
||||
from reflex.constants import Hooks, Imports
|
||||
from reflex.event import EventChain, EventHandler
|
||||
from reflex.utils.imports import ImportVar
|
||||
from reflex.components.datadisplay.logo import svg_logo
|
||||
from reflex.components.el import a, button, details, div, h2, hr, p, pre, summary
|
||||
from reflex.event import EventHandler, set_clipboard
|
||||
from reflex.state import FrontendEventExceptionState
|
||||
from reflex.vars.base import Var
|
||||
from reflex.vars.function import FunctionVar
|
||||
from reflex.vars.function import ArgsFunctionOperation
|
||||
|
||||
|
||||
def on_error_spec(
|
||||
error: Var[Dict[str, str]], info: Var[Dict[str, str]]
|
||||
) -> Tuple[Var[str], Var[str]]:
|
||||
"""The spec for the on_error event handler.
|
||||
|
||||
Args:
|
||||
error: The error message.
|
||||
info: Additional information about the error.
|
||||
|
||||
Returns:
|
||||
The arguments for the event handler.
|
||||
"""
|
||||
return (
|
||||
error.stack,
|
||||
info.componentStack,
|
||||
)
|
||||
|
||||
|
||||
class ErrorBoundary(Component):
|
||||
@ -21,59 +38,118 @@ class ErrorBoundary(Component):
|
||||
tag = "ErrorBoundary"
|
||||
|
||||
# Fired when the boundary catches an error.
|
||||
on_error: EventHandler[lambda error, info: [error, info]] = Var( # type: ignore
|
||||
"logFrontendError"
|
||||
).to(FunctionVar, EventChain)
|
||||
on_error: EventHandler[on_error_spec]
|
||||
|
||||
# Rendered instead of the children when an error is caught.
|
||||
Fallback_component: Var[Component] = Var(_js_expr="Fallback")._replace(
|
||||
_var_type=Component
|
||||
)
|
||||
fallback_render: Var[Component]
|
||||
|
||||
def add_imports(self) -> dict[str, list[ImportVar]]:
|
||||
"""Add imports for the component.
|
||||
@classmethod
|
||||
def create(cls, *children, **props):
|
||||
"""Create an ErrorBoundary component.
|
||||
|
||||
Args:
|
||||
*children: The children of the component.
|
||||
**props: The props of the component.
|
||||
|
||||
Returns:
|
||||
The imports to add.
|
||||
The ErrorBoundary component.
|
||||
"""
|
||||
return Imports.EVENTS
|
||||
|
||||
def add_hooks(self) -> List[str | Var]:
|
||||
"""Add hooks for the component.
|
||||
|
||||
Returns:
|
||||
The hooks to add.
|
||||
"""
|
||||
return [Hooks.EVENTS, Hooks.FRONTEND_ERRORS]
|
||||
|
||||
def add_custom_code(self) -> List[str]:
|
||||
"""Add custom Javascript code into the page that contains this component.
|
||||
|
||||
Custom code is inserted at module level, after any imports.
|
||||
|
||||
Returns:
|
||||
The custom code to add.
|
||||
"""
|
||||
fallback_container = div(
|
||||
p("Ooops...Unknown Reflex error has occured:"),
|
||||
p(
|
||||
Var(_js_expr="error.message"),
|
||||
color="red",
|
||||
),
|
||||
p("Please contact the support."),
|
||||
)
|
||||
|
||||
compiled_fallback = _compile_component(fallback_container)
|
||||
|
||||
return [
|
||||
f"""
|
||||
function Fallback({{ error, resetErrorBoundary }}) {{
|
||||
return (
|
||||
{compiled_fallback}
|
||||
);
|
||||
}}
|
||||
"""
|
||||
]
|
||||
if "on_error" not in props:
|
||||
props["on_error"] = FrontendEventExceptionState.handle_frontend_exception
|
||||
if "fallback_render" not in props:
|
||||
props["fallback_render"] = ArgsFunctionOperation.create(
|
||||
("event_args",),
|
||||
Var.create(
|
||||
div(
|
||||
div(
|
||||
div(
|
||||
h2(
|
||||
"An error occurred while rendering this page.",
|
||||
font_size="1.25rem",
|
||||
font_weight="bold",
|
||||
),
|
||||
p(
|
||||
"This is an error with the application itself.",
|
||||
opacity="0.75",
|
||||
),
|
||||
details(
|
||||
summary("Error message", padding="0.5rem"),
|
||||
div(
|
||||
div(
|
||||
pre(
|
||||
Var(
|
||||
_js_expr="event_args.error.stack",
|
||||
),
|
||||
),
|
||||
padding="0.5rem",
|
||||
width="fit-content",
|
||||
),
|
||||
width="100%",
|
||||
max_height="50vh",
|
||||
overflow="auto",
|
||||
background="#000",
|
||||
color="#fff",
|
||||
border_radius="0.25rem",
|
||||
),
|
||||
button(
|
||||
"Copy",
|
||||
on_click=set_clipboard(
|
||||
Var(_js_expr="event_args.error.stack"),
|
||||
),
|
||||
padding="0.35rem 0.75rem",
|
||||
margin="0.5rem",
|
||||
background="#fff",
|
||||
color="#000",
|
||||
border="1px solid #000",
|
||||
border_radius="0.25rem",
|
||||
font_weight="bold",
|
||||
),
|
||||
),
|
||||
display="flex",
|
||||
flex_direction="column",
|
||||
gap="1rem",
|
||||
max_width="50ch",
|
||||
border="1px solid #888888",
|
||||
border_radius="0.25rem",
|
||||
padding="1rem",
|
||||
),
|
||||
hr(
|
||||
border_color="currentColor",
|
||||
opacity="0.25",
|
||||
),
|
||||
a(
|
||||
div(
|
||||
"Built with ",
|
||||
svg_logo("currentColor"),
|
||||
display="flex",
|
||||
align_items="baseline",
|
||||
justify_content="center",
|
||||
font_family="monospace",
|
||||
gap="0.5rem",
|
||||
),
|
||||
href="https://reflex.dev",
|
||||
),
|
||||
display="flex",
|
||||
flex_direction="column",
|
||||
gap="1rem",
|
||||
),
|
||||
height="100%",
|
||||
width="100%",
|
||||
position="absolute",
|
||||
display="flex",
|
||||
align_items="center",
|
||||
justify_content="center",
|
||||
)
|
||||
),
|
||||
_var_type=Component,
|
||||
)
|
||||
else:
|
||||
props["fallback_render"] = ArgsFunctionOperation.create(
|
||||
("event_args",),
|
||||
props["fallback_render"],
|
||||
_var_type=Component,
|
||||
)
|
||||
return super().create(*children, **props)
|
||||
|
||||
|
||||
error_boundary = ErrorBoundary.create
|
||||
|
@ -3,73 +3,60 @@
|
||||
# ------------------- DO NOT EDIT ----------------------
|
||||
# This file was generated by `reflex/utils/pyi_generator.py`!
|
||||
# ------------------------------------------------------
|
||||
from typing import Any, Callable, Dict, List, Optional, Union, overload
|
||||
from typing import Any, Dict, Optional, Tuple, Union, overload
|
||||
|
||||
from reflex.components.component import Component
|
||||
from reflex.event import EventHandler, EventSpec
|
||||
from reflex.event import BASE_STATE, EventType
|
||||
from reflex.style import Style
|
||||
from reflex.utils.imports import ImportVar
|
||||
from reflex.vars.base import Var
|
||||
|
||||
def on_error_spec(
|
||||
error: Var[Dict[str, str]], info: Var[Dict[str, str]]
|
||||
) -> Tuple[Var[str], Var[str]]: ...
|
||||
|
||||
class ErrorBoundary(Component):
|
||||
def add_imports(self) -> dict[str, list[ImportVar]]: ...
|
||||
def add_hooks(self) -> List[str | Var]: ...
|
||||
def add_custom_code(self) -> List[str]: ...
|
||||
@overload
|
||||
@classmethod
|
||||
def create( # type: ignore
|
||||
cls,
|
||||
*children,
|
||||
Fallback_component: Optional[Union[Component, Var[Component]]] = None,
|
||||
fallback_render: Optional[Union[Component, Var[Component]]] = None,
|
||||
style: Optional[Style] = None,
|
||||
key: Optional[Any] = None,
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_error: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_error: Optional[
|
||||
Union[
|
||||
EventType[[], BASE_STATE],
|
||||
EventType[[str], BASE_STATE],
|
||||
EventType[[str, str], BASE_STATE],
|
||||
]
|
||||
] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "ErrorBoundary":
|
||||
"""Create the component.
|
||||
"""Create an ErrorBoundary component.
|
||||
|
||||
Args:
|
||||
*children: The children of the component.
|
||||
Fallback_component: Rendered instead of the children when an error is caught.
|
||||
on_error: Fired when the boundary catches an error.
|
||||
fallback_render: Rendered instead of the children when an error is caught.
|
||||
style: The style of the component.
|
||||
key: A unique key for the component.
|
||||
id: The id for the component.
|
||||
@ -79,7 +66,7 @@ class ErrorBoundary(Component):
|
||||
**props: The props of the component.
|
||||
|
||||
Returns:
|
||||
The component.
|
||||
The ErrorBoundary component.
|
||||
"""
|
||||
...
|
||||
|
||||
|
@ -3,10 +3,10 @@
|
||||
# ------------------- DO NOT EDIT ----------------------
|
||||
# This file was generated by `reflex/utils/pyi_generator.py`!
|
||||
# ------------------------------------------------------
|
||||
from typing import Any, Callable, Dict, Optional, Union, overload
|
||||
from typing import Any, Dict, Optional, Union, overload
|
||||
|
||||
from reflex.components.component import Component
|
||||
from reflex.event import EventHandler, EventSpec
|
||||
from reflex.event import BASE_STATE, EventType
|
||||
from reflex.style import Style
|
||||
from reflex.vars.base import Var
|
||||
|
||||
@ -21,42 +21,22 @@ class Fragment(Component):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "Fragment":
|
||||
"""Create the component.
|
||||
|
@ -3,10 +3,10 @@
|
||||
# ------------------- DO NOT EDIT ----------------------
|
||||
# This file was generated by `reflex/utils/pyi_generator.py`!
|
||||
# ------------------------------------------------------
|
||||
from typing import Any, Callable, Dict, Optional, Union, overload
|
||||
from typing import Any, Dict, Optional, Union, overload
|
||||
|
||||
from reflex.components.component import Component, MemoizationLeaf
|
||||
from reflex.event import EventHandler, EventSpec
|
||||
from reflex.event import BASE_STATE, EventType
|
||||
from reflex.style import Style
|
||||
from reflex.vars.base import Var
|
||||
|
||||
@ -21,42 +21,22 @@ class NextHeadLib(Component):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "NextHeadLib":
|
||||
"""Create the component.
|
||||
@ -87,42 +67,22 @@ class Head(NextHeadLib, MemoizationLeaf):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "Head":
|
||||
"""Create a new memoization leaf component.
|
||||
|
@ -3,10 +3,10 @@
|
||||
# ------------------- DO NOT EDIT ----------------------
|
||||
# This file was generated by `reflex/utils/pyi_generator.py`!
|
||||
# ------------------------------------------------------
|
||||
from typing import Any, Callable, Dict, Optional, Union, overload
|
||||
from typing import Any, Dict, Optional, Union, overload
|
||||
|
||||
from reflex.components.component import Component
|
||||
from reflex.event import EventHandler, EventSpec
|
||||
from reflex.event import BASE_STATE, EventType
|
||||
from reflex.style import Style
|
||||
from reflex.vars.base import Var
|
||||
|
||||
@ -23,42 +23,22 @@ class RawLink(Component):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "RawLink":
|
||||
"""Create the component.
|
||||
@ -98,42 +78,22 @@ class ScriptTag(Component):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "ScriptTag":
|
||||
"""Create the component.
|
||||
|
@ -3,10 +3,10 @@
|
||||
# ------------------- DO NOT EDIT ----------------------
|
||||
# This file was generated by `reflex/utils/pyi_generator.py`!
|
||||
# ------------------------------------------------------
|
||||
from typing import Any, Callable, Dict, Optional, Union, overload
|
||||
from typing import Any, Dict, Optional, Union, overload
|
||||
|
||||
from reflex.components.component import Component
|
||||
from reflex.event import EventHandler, EventSpec
|
||||
from reflex.event import BASE_STATE, EventType
|
||||
from reflex.style import Style
|
||||
from reflex.vars.base import Var
|
||||
|
||||
@ -22,42 +22,22 @@ class Title(Component):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "Title":
|
||||
"""Create the component.
|
||||
@ -93,42 +73,22 @@ class Meta(Component):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "Meta":
|
||||
"""Create the component.
|
||||
@ -169,42 +129,22 @@ class Description(Meta):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "Description":
|
||||
"""Create the component.
|
||||
@ -245,42 +185,22 @@ class Image(Meta):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "Image":
|
||||
"""Create the component.
|
||||
|
@ -8,7 +8,7 @@ from __future__ import annotations
|
||||
from typing import Literal
|
||||
|
||||
from reflex.components.component import Component
|
||||
from reflex.event import EventHandler
|
||||
from reflex.event import EventHandler, no_args_event_spec
|
||||
from reflex.vars.base import LiteralVar, Var
|
||||
|
||||
|
||||
@ -35,13 +35,13 @@ class Script(Component):
|
||||
)
|
||||
|
||||
# Triggered when the script is loading
|
||||
on_load: EventHandler[lambda: []]
|
||||
on_load: EventHandler[no_args_event_spec]
|
||||
|
||||
# Triggered when the script has loaded
|
||||
on_ready: EventHandler[lambda: []]
|
||||
on_ready: EventHandler[no_args_event_spec]
|
||||
|
||||
# Triggered when the script has errored
|
||||
on_error: EventHandler[lambda: []]
|
||||
on_error: EventHandler[no_args_event_spec]
|
||||
|
||||
@classmethod
|
||||
def create(cls, *children, **props) -> Component:
|
||||
|
@ -3,10 +3,10 @@
|
||||
# ------------------- DO NOT EDIT ----------------------
|
||||
# This file was generated by `reflex/utils/pyi_generator.py`!
|
||||
# ------------------------------------------------------
|
||||
from typing import Any, Callable, Dict, Literal, Optional, Union, overload
|
||||
from typing import Any, Dict, Literal, Optional, Union, overload
|
||||
|
||||
from reflex.components.component import Component
|
||||
from reflex.event import EventHandler, EventSpec
|
||||
from reflex.event import BASE_STATE, EventType
|
||||
from reflex.style import Style
|
||||
from reflex.vars.base import Var
|
||||
|
||||
@ -28,45 +28,25 @@ class Script(Component):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_error: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_load: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_ready: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_error: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_load: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_ready: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "Script":
|
||||
"""Create an inline or user-defined script.
|
||||
@ -85,6 +65,9 @@ class Script(Component):
|
||||
*children: The children of the component.
|
||||
src: Required unless inline script is used
|
||||
strategy: When the script will execute: afterInteractive (defer-like behavior) | beforeInteractive | lazyOnload (async-like behavior)
|
||||
on_load: Triggered when the script is loading
|
||||
on_ready: Triggered when the script has loaded
|
||||
on_error: Triggered when the script has errored
|
||||
style: The style of the component.
|
||||
key: A unique key for the component.
|
||||
id: The id for the component.
|
||||
|
@ -3,6 +3,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import copy
|
||||
import dataclasses
|
||||
import typing
|
||||
from abc import ABC, abstractmethod
|
||||
from functools import lru_cache, wraps
|
||||
@ -16,6 +17,7 @@ from typing import (
|
||||
Iterator,
|
||||
List,
|
||||
Optional,
|
||||
Sequence,
|
||||
Set,
|
||||
Type,
|
||||
Union,
|
||||
@ -36,13 +38,19 @@ from reflex.constants import (
|
||||
MemoizationMode,
|
||||
PageNames,
|
||||
)
|
||||
from reflex.constants.compiler import SpecialAttributes
|
||||
from reflex.constants.state import FRONTEND_EVENT_STATE
|
||||
from reflex.event import (
|
||||
EventCallback,
|
||||
EventChain,
|
||||
EventChainVar,
|
||||
EventHandler,
|
||||
EventSpec,
|
||||
EventVar,
|
||||
call_event_fn,
|
||||
call_event_handler,
|
||||
get_handler_args,
|
||||
no_args_event_spec,
|
||||
)
|
||||
from reflex.style import Style, format_as_emotion
|
||||
from reflex.utils import format, imports, types
|
||||
@ -54,7 +62,15 @@ from reflex.utils.imports import (
|
||||
parse_imports,
|
||||
)
|
||||
from reflex.vars import VarData
|
||||
from reflex.vars.base import LiteralVar, Var
|
||||
from reflex.vars.base import (
|
||||
CachedVarOperation,
|
||||
LiteralVar,
|
||||
Var,
|
||||
cached_property_no_lock,
|
||||
)
|
||||
from reflex.vars.function import ArgsFunctionOperation, FunctionStringVar
|
||||
from reflex.vars.number import ternary_operation
|
||||
from reflex.vars.object import ObjectVar
|
||||
from reflex.vars.sequence import LiteralArrayVar
|
||||
|
||||
|
||||
@ -142,11 +158,10 @@ class ComponentNamespace(SimpleNamespace):
|
||||
def __hash__(self) -> int:
|
||||
"""Get the hash of the namespace.
|
||||
|
||||
|
||||
Returns:
|
||||
The hash of the namespace.
|
||||
"""
|
||||
return hash(self.__class__.__name__)
|
||||
return hash(type(self).__name__)
|
||||
|
||||
|
||||
def evaluate_style_namespaces(style: ComponentStyle) -> dict:
|
||||
@ -171,6 +186,23 @@ ComponentStyle = Dict[
|
||||
ComponentChild = Union[types.PrimitiveType, Var, BaseComponent]
|
||||
|
||||
|
||||
def satisfies_type_hint(obj: Any, type_hint: Any) -> bool:
|
||||
"""Check if an object satisfies a type hint.
|
||||
|
||||
Args:
|
||||
obj: The object to check.
|
||||
type_hint: The type hint to check against.
|
||||
|
||||
Returns:
|
||||
Whether the object satisfies the type hint.
|
||||
"""
|
||||
if isinstance(obj, LiteralVar):
|
||||
return types._isinstance(obj._var_value, type_hint)
|
||||
if isinstance(obj, Var):
|
||||
return types._issubclass(obj._var_type, type_hint)
|
||||
return types._isinstance(obj, type_hint)
|
||||
|
||||
|
||||
class Component(BaseComponent, ABC):
|
||||
"""A component with style, event trigger and other props."""
|
||||
|
||||
@ -214,7 +246,7 @@ class Component(BaseComponent, ABC):
|
||||
_rename_props: Dict[str, str] = {}
|
||||
|
||||
# custom attribute
|
||||
custom_attrs: Dict[str, Union[Var, str]] = {}
|
||||
custom_attrs: Dict[str, Union[Var, Any]] = {}
|
||||
|
||||
# When to memoize this component and its children.
|
||||
_memoization_mode: MemoizationMode = MemoizationMode()
|
||||
@ -445,8 +477,7 @@ class Component(BaseComponent, ABC):
|
||||
)
|
||||
) or (
|
||||
# Else just check if the passed var type is valid.
|
||||
not passed_types
|
||||
and not types._issubclass(passed_type, expected_type, value)
|
||||
not passed_types and not satisfies_type_hint(value, expected_type)
|
||||
):
|
||||
value_name = value._js_expr if isinstance(value, Var) else value
|
||||
|
||||
@ -466,12 +497,24 @@ class Component(BaseComponent, ABC):
|
||||
kwargs["event_triggers"][key] = self._create_event_chain(
|
||||
value=value, # type: ignore
|
||||
args_spec=component_specific_triggers[key],
|
||||
key=key,
|
||||
)
|
||||
|
||||
# Remove any keys that were added as events.
|
||||
for key in kwargs["event_triggers"]:
|
||||
del kwargs[key]
|
||||
|
||||
# Place data_ and aria_ attributes into custom_attrs
|
||||
special_attributes = tuple(
|
||||
key
|
||||
for key in kwargs
|
||||
if key not in fields and SpecialAttributes.is_special(key)
|
||||
)
|
||||
if special_attributes:
|
||||
custom_attrs = kwargs.setdefault("custom_attrs", {})
|
||||
for key in special_attributes:
|
||||
custom_attrs[format.to_kebab_case(key)] = kwargs.pop(key)
|
||||
|
||||
# Add style props to the component.
|
||||
style = kwargs.get("style", {})
|
||||
if isinstance(style, List):
|
||||
@ -491,8 +534,6 @@ class Component(BaseComponent, ABC):
|
||||
**{attr: value for attr, value in kwargs.items() if attr not in fields},
|
||||
}
|
||||
)
|
||||
if "custom_attrs" not in kwargs:
|
||||
kwargs["custom_attrs"] = {}
|
||||
|
||||
# Convert class_name to str if it's list
|
||||
class_name = kwargs.get("class_name", "")
|
||||
@ -509,20 +550,22 @@ class Component(BaseComponent, ABC):
|
||||
|
||||
def _create_event_chain(
|
||||
self,
|
||||
args_spec: Any,
|
||||
args_spec: types.ArgsSpec | Sequence[types.ArgsSpec],
|
||||
value: Union[
|
||||
Var,
|
||||
EventHandler,
|
||||
EventSpec,
|
||||
List[Union[EventHandler, EventSpec]],
|
||||
List[Union[EventHandler, EventSpec, EventVar]],
|
||||
Callable,
|
||||
],
|
||||
key: Optional[str] = None,
|
||||
) -> Union[EventChain, Var]:
|
||||
"""Create an event chain from a variety of input types.
|
||||
|
||||
Args:
|
||||
args_spec: The args_spec of the event trigger being bound.
|
||||
value: The value to create the event chain from.
|
||||
key: The key of the event trigger being bound.
|
||||
|
||||
Returns:
|
||||
The event chain.
|
||||
@ -532,11 +575,16 @@ class Component(BaseComponent, ABC):
|
||||
"""
|
||||
# If it's an event chain var, return it.
|
||||
if isinstance(value, Var):
|
||||
if value._var_type is not EventChain:
|
||||
if isinstance(value, EventChainVar):
|
||||
return value
|
||||
elif isinstance(value, EventVar):
|
||||
value = [value]
|
||||
elif issubclass(value._var_type, (EventChain, EventSpec)):
|
||||
return self._create_event_chain(args_spec, value.guess_type(), key=key)
|
||||
else:
|
||||
raise ValueError(
|
||||
f"Invalid event chain: {repr(value)} of type {type(value)}"
|
||||
f"Invalid event chain: {value!s} of type {value._var_type}"
|
||||
)
|
||||
return value
|
||||
elif isinstance(value, EventChain):
|
||||
# Trust that the caller knows what they're doing passing an EventChain directly
|
||||
return value
|
||||
@ -547,91 +595,92 @@ class Component(BaseComponent, ABC):
|
||||
|
||||
# If the input is a list of event handlers, create an event chain.
|
||||
if isinstance(value, List):
|
||||
events: list[EventSpec] = []
|
||||
events: List[Union[EventSpec, EventVar]] = []
|
||||
for v in value:
|
||||
if isinstance(v, (EventHandler, EventSpec)):
|
||||
# Call the event handler to get the event.
|
||||
events.append(call_event_handler(v, args_spec))
|
||||
events.append(call_event_handler(v, args_spec, key=key))
|
||||
elif isinstance(v, Callable):
|
||||
# Call the lambda to get the event chain.
|
||||
result = call_event_fn(v, args_spec)
|
||||
result = call_event_fn(v, args_spec, key=key)
|
||||
if isinstance(result, Var):
|
||||
raise ValueError(
|
||||
f"Invalid event chain: {v}. Cannot use a Var-returning "
|
||||
"lambda inside an EventChain list."
|
||||
)
|
||||
events.extend(result)
|
||||
elif isinstance(v, EventVar):
|
||||
events.append(v)
|
||||
else:
|
||||
raise ValueError(f"Invalid event: {v}")
|
||||
|
||||
# If the input is a callable, create an event chain.
|
||||
elif isinstance(value, Callable):
|
||||
result = call_event_fn(value, args_spec)
|
||||
result = call_event_fn(value, args_spec, key=key)
|
||||
if isinstance(result, Var):
|
||||
# Recursively call this function if the lambda returned an EventChain Var.
|
||||
return self._create_event_chain(args_spec, result)
|
||||
events = result
|
||||
return self._create_event_chain(args_spec, result, key=key)
|
||||
events = [*result]
|
||||
|
||||
# Otherwise, raise an error.
|
||||
else:
|
||||
raise ValueError(f"Invalid event chain: {value}")
|
||||
|
||||
# Add args to the event specs if necessary.
|
||||
events = [e.with_args(get_handler_args(e)) for e in events]
|
||||
|
||||
# Collect event_actions from each spec
|
||||
event_actions = {}
|
||||
for e in events:
|
||||
event_actions.update(e.event_actions)
|
||||
events = [
|
||||
(e.with_args(get_handler_args(e)) if isinstance(e, EventSpec) else e)
|
||||
for e in events
|
||||
]
|
||||
|
||||
# Return the event chain.
|
||||
if isinstance(args_spec, Var):
|
||||
return EventChain(
|
||||
events=events,
|
||||
args_spec=None,
|
||||
event_actions=event_actions,
|
||||
event_actions={},
|
||||
)
|
||||
else:
|
||||
return EventChain(
|
||||
events=events,
|
||||
args_spec=args_spec,
|
||||
event_actions=event_actions,
|
||||
event_actions={},
|
||||
)
|
||||
|
||||
def get_event_triggers(self) -> Dict[str, Any]:
|
||||
def get_event_triggers(
|
||||
self,
|
||||
) -> Dict[str, types.ArgsSpec | Sequence[types.ArgsSpec]]:
|
||||
"""Get the event triggers for the component.
|
||||
|
||||
Returns:
|
||||
The event triggers.
|
||||
|
||||
"""
|
||||
default_triggers = {
|
||||
EventTriggers.ON_FOCUS: lambda: [],
|
||||
EventTriggers.ON_BLUR: lambda: [],
|
||||
EventTriggers.ON_CLICK: lambda: [],
|
||||
EventTriggers.ON_CONTEXT_MENU: lambda: [],
|
||||
EventTriggers.ON_DOUBLE_CLICK: lambda: [],
|
||||
EventTriggers.ON_MOUSE_DOWN: lambda: [],
|
||||
EventTriggers.ON_MOUSE_ENTER: lambda: [],
|
||||
EventTriggers.ON_MOUSE_LEAVE: lambda: [],
|
||||
EventTriggers.ON_MOUSE_MOVE: lambda: [],
|
||||
EventTriggers.ON_MOUSE_OUT: lambda: [],
|
||||
EventTriggers.ON_MOUSE_OVER: lambda: [],
|
||||
EventTriggers.ON_MOUSE_UP: lambda: [],
|
||||
EventTriggers.ON_SCROLL: lambda: [],
|
||||
EventTriggers.ON_MOUNT: lambda: [],
|
||||
EventTriggers.ON_UNMOUNT: lambda: [],
|
||||
default_triggers: Dict[str, types.ArgsSpec | Sequence[types.ArgsSpec]] = {
|
||||
EventTriggers.ON_FOCUS: no_args_event_spec,
|
||||
EventTriggers.ON_BLUR: no_args_event_spec,
|
||||
EventTriggers.ON_CLICK: no_args_event_spec,
|
||||
EventTriggers.ON_CONTEXT_MENU: no_args_event_spec,
|
||||
EventTriggers.ON_DOUBLE_CLICK: no_args_event_spec,
|
||||
EventTriggers.ON_MOUSE_DOWN: no_args_event_spec,
|
||||
EventTriggers.ON_MOUSE_ENTER: no_args_event_spec,
|
||||
EventTriggers.ON_MOUSE_LEAVE: no_args_event_spec,
|
||||
EventTriggers.ON_MOUSE_MOVE: no_args_event_spec,
|
||||
EventTriggers.ON_MOUSE_OUT: no_args_event_spec,
|
||||
EventTriggers.ON_MOUSE_OVER: no_args_event_spec,
|
||||
EventTriggers.ON_MOUSE_UP: no_args_event_spec,
|
||||
EventTriggers.ON_SCROLL: no_args_event_spec,
|
||||
EventTriggers.ON_MOUNT: no_args_event_spec,
|
||||
EventTriggers.ON_UNMOUNT: no_args_event_spec,
|
||||
}
|
||||
|
||||
# Look for component specific triggers,
|
||||
# e.g. variable declared as EventHandler types.
|
||||
for field in self.get_fields().values():
|
||||
if types._issubclass(field.type_, EventHandler):
|
||||
if types._issubclass(field.outer_type_, EventHandler):
|
||||
args_spec = None
|
||||
annotation = field.annotation
|
||||
if (metadata := getattr(annotation, "__metadata__", None)) is not None:
|
||||
args_spec = metadata[0]
|
||||
default_triggers[field.name] = args_spec or (lambda: [])
|
||||
default_triggers[field.name] = args_spec or (no_args_event_spec) # type: ignore
|
||||
return default_triggers
|
||||
|
||||
def __repr__(self) -> str:
|
||||
@ -1030,8 +1079,11 @@ class Component(BaseComponent, ABC):
|
||||
elif isinstance(event, EventChain):
|
||||
event_args = []
|
||||
for spec in event.events:
|
||||
for args in spec.args:
|
||||
event_args.extend(args)
|
||||
if isinstance(spec, EventSpec):
|
||||
for args in spec.args:
|
||||
event_args.extend(args)
|
||||
else:
|
||||
event_args.append(spec)
|
||||
yield event_trigger, event_args
|
||||
|
||||
def _get_vars(self, include_children: bool = False) -> list[Var]:
|
||||
@ -1058,7 +1110,7 @@ class Component(BaseComponent, ABC):
|
||||
vars.append(prop_var)
|
||||
|
||||
# Style keeps track of its own VarData instance, so embed in a temp Var that is yielded.
|
||||
if isinstance(self.style, dict) and self.style or isinstance(self.style, Var):
|
||||
if (isinstance(self.style, dict) and self.style) or isinstance(self.style, Var):
|
||||
vars.append(
|
||||
Var(
|
||||
_js_expr="style",
|
||||
@ -1105,8 +1157,17 @@ class Component(BaseComponent, ABC):
|
||||
for trigger in self.event_triggers.values():
|
||||
if isinstance(trigger, EventChain):
|
||||
for event in trigger.events:
|
||||
if event.handler.state_full_name:
|
||||
return True
|
||||
if isinstance(event, EventCallback):
|
||||
continue
|
||||
if isinstance(event, EventSpec):
|
||||
if (
|
||||
event.handler.state_full_name
|
||||
and event.handler.state_full_name != FRONTEND_EVENT_STATE
|
||||
):
|
||||
return True
|
||||
else:
|
||||
if event._var_state:
|
||||
return True
|
||||
elif isinstance(trigger, Var) and trigger._var_state:
|
||||
return True
|
||||
return False
|
||||
@ -1280,7 +1341,9 @@ class Component(BaseComponent, ABC):
|
||||
if self._get_ref_hook():
|
||||
# Handle hooks needed for attaching react refs to DOM nodes.
|
||||
_imports.setdefault("react", set()).add(ImportVar(tag="useRef"))
|
||||
_imports.setdefault(f"/{Dirs.STATE_PATH}", set()).add(ImportVar(tag="refs"))
|
||||
_imports.setdefault(f"$/{Dirs.STATE_PATH}", set()).add(
|
||||
ImportVar(tag="refs")
|
||||
)
|
||||
|
||||
if self._get_mount_lifecycle_hook():
|
||||
# Handle hooks for `on_mount` / `on_unmount`.
|
||||
@ -1402,7 +1465,9 @@ class Component(BaseComponent, ABC):
|
||||
"""
|
||||
ref = self.get_ref()
|
||||
if ref is not None:
|
||||
return f"const {ref} = useRef(null); {str(Var(_js_expr=ref).as_ref())} = {ref};"
|
||||
return (
|
||||
f"const {ref} = useRef(null); {Var(_js_expr=ref)._as_ref()!s} = {ref};"
|
||||
)
|
||||
|
||||
def _get_vars_hooks(self) -> dict[str, None]:
|
||||
"""Get the hooks required by vars referenced in this component.
|
||||
@ -1637,7 +1702,7 @@ class CustomComponent(Component):
|
||||
"""A custom user-defined component."""
|
||||
|
||||
# Use the components library.
|
||||
library = f"/{Dirs.COMPONENTS_PATH}"
|
||||
library = f"$/{Dirs.COMPONENTS_PATH}"
|
||||
|
||||
# The function that creates the component.
|
||||
component_fn: Callable[..., Component] = Component.create
|
||||
@ -1681,8 +1746,9 @@ class CustomComponent(Component):
|
||||
value = self._create_event_chain(
|
||||
value=value,
|
||||
args_spec=event_triggers_in_component_declaration.get(
|
||||
key, lambda: []
|
||||
key, no_args_event_spec
|
||||
),
|
||||
key=key,
|
||||
)
|
||||
self.props[format.to_camel_case(key)] = value
|
||||
continue
|
||||
@ -1855,6 +1921,11 @@ memo = custom_component
|
||||
class NoSSRComponent(Component):
|
||||
"""A dynamic component that is not rendered on the server."""
|
||||
|
||||
def _get_import_name(self) -> None | str:
|
||||
if not self.library:
|
||||
return None
|
||||
return f"${self.library}" if self.library.startswith("/") else self.library
|
||||
|
||||
def _get_imports(self) -> ParsedImportDict:
|
||||
"""Get the imports for the component.
|
||||
|
||||
@ -1868,8 +1939,9 @@ class NoSSRComponent(Component):
|
||||
_imports = super()._get_imports()
|
||||
|
||||
# Do NOT import the main library/tag statically.
|
||||
if self.library is not None:
|
||||
_imports[self.library] = [
|
||||
import_name = self._get_import_name()
|
||||
if import_name is not None:
|
||||
_imports[import_name] = [
|
||||
imports.ImportVar(
|
||||
tag=None,
|
||||
render=False,
|
||||
@ -1887,10 +1959,10 @@ class NoSSRComponent(Component):
|
||||
opts_fragment = ", { ssr: false });"
|
||||
|
||||
# extract the correct import name from library name
|
||||
if self.library is None:
|
||||
base_import_name = self._get_import_name()
|
||||
if base_import_name is None:
|
||||
raise ValueError("Undefined library for NoSSRComponent")
|
||||
|
||||
import_name = format.format_library_name(self.library)
|
||||
import_name = format.format_library_name(base_import_name)
|
||||
|
||||
library_import = f"const {self.alias if self.alias else self.tag} = dynamic(() => import('{import_name}')"
|
||||
mod_import = (
|
||||
@ -2205,7 +2277,7 @@ class StatefulComponent(BaseComponent):
|
||||
"""
|
||||
if self.rendered_as_shared:
|
||||
return {
|
||||
f"/{Dirs.UTILS}/{PageNames.STATEFUL_COMPONENTS}": [
|
||||
f"$/{Dirs.UTILS}/{PageNames.STATEFUL_COMPONENTS}": [
|
||||
ImportVar(tag=self.tag)
|
||||
]
|
||||
}
|
||||
@ -2315,3 +2387,203 @@ class MemoizationLeaf(Component):
|
||||
|
||||
|
||||
load_dynamic_serializer()
|
||||
|
||||
|
||||
class ComponentVar(Var[Component], python_types=BaseComponent):
|
||||
"""A Var that represents a Component."""
|
||||
|
||||
|
||||
def empty_component() -> Component:
|
||||
"""Create an empty component.
|
||||
|
||||
Returns:
|
||||
An empty component.
|
||||
"""
|
||||
from reflex.components.base.bare import Bare
|
||||
|
||||
return Bare.create("")
|
||||
|
||||
|
||||
def render_dict_to_var(tag: dict | Component | str, imported_names: set[str]) -> Var:
|
||||
"""Convert a render dict to a Var.
|
||||
|
||||
Args:
|
||||
tag: The render dict.
|
||||
imported_names: The names of the imported components.
|
||||
|
||||
Returns:
|
||||
The Var.
|
||||
"""
|
||||
if not isinstance(tag, dict):
|
||||
if isinstance(tag, Component):
|
||||
return render_dict_to_var(tag.render(), imported_names)
|
||||
return Var.create(tag)
|
||||
|
||||
if "iterable" in tag:
|
||||
function_return = Var.create(
|
||||
[
|
||||
render_dict_to_var(child.render(), imported_names)
|
||||
for child in tag["children"]
|
||||
]
|
||||
)
|
||||
|
||||
func = ArgsFunctionOperation.create(
|
||||
(tag["arg_var_name"], tag["index_var_name"]),
|
||||
function_return,
|
||||
)
|
||||
|
||||
return FunctionStringVar.create("Array.prototype.map.call").call(
|
||||
tag["iterable"]
|
||||
if not isinstance(tag["iterable"], ObjectVar)
|
||||
else tag["iterable"].items(),
|
||||
func,
|
||||
)
|
||||
|
||||
if tag["name"] == "match":
|
||||
element = tag["cond"]
|
||||
|
||||
conditionals = tag["default"]
|
||||
|
||||
for case in tag["match_cases"][::-1]:
|
||||
condition = case[0].to_string() == element.to_string()
|
||||
for pattern in case[1:-1]:
|
||||
condition = condition | (pattern.to_string() == element.to_string())
|
||||
|
||||
conditionals = ternary_operation(
|
||||
condition,
|
||||
case[-1],
|
||||
conditionals,
|
||||
)
|
||||
|
||||
return conditionals
|
||||
|
||||
if "cond" in tag:
|
||||
return ternary_operation(
|
||||
tag["cond"],
|
||||
render_dict_to_var(tag["true_value"], imported_names),
|
||||
render_dict_to_var(tag["false_value"], imported_names)
|
||||
if tag["false_value"] is not None
|
||||
else Var.create(None),
|
||||
)
|
||||
|
||||
props = {}
|
||||
|
||||
special_props = []
|
||||
|
||||
for prop_str in tag["props"]:
|
||||
if "=" not in prop_str:
|
||||
special_props.append(Var(prop_str).to(ObjectVar))
|
||||
continue
|
||||
prop = prop_str.index("=")
|
||||
key = prop_str[:prop]
|
||||
value = prop_str[prop + 2 : -1]
|
||||
props[key] = value
|
||||
|
||||
props = Var.create({Var.create(k): Var(v) for k, v in props.items()})
|
||||
|
||||
for prop in special_props:
|
||||
props = props.merge(prop)
|
||||
|
||||
contents = tag["contents"][1:-1] if tag["contents"] else None
|
||||
|
||||
raw_tag_name = tag.get("name")
|
||||
tag_name = Var(raw_tag_name or "Fragment")
|
||||
|
||||
tag_name = (
|
||||
Var.create(raw_tag_name)
|
||||
if raw_tag_name
|
||||
and raw_tag_name.split(".")[0] not in imported_names
|
||||
and raw_tag_name.lower() == raw_tag_name
|
||||
else tag_name
|
||||
)
|
||||
|
||||
return FunctionStringVar.create(
|
||||
"jsx",
|
||||
).call(
|
||||
tag_name,
|
||||
props,
|
||||
*([Var(contents)] if contents is not None else []),
|
||||
*[render_dict_to_var(child, imported_names) for child in tag["children"]],
|
||||
)
|
||||
|
||||
|
||||
@dataclasses.dataclass(
|
||||
eq=False,
|
||||
frozen=True,
|
||||
)
|
||||
class LiteralComponentVar(CachedVarOperation, LiteralVar, ComponentVar):
|
||||
"""A Var that represents a Component."""
|
||||
|
||||
_var_value: BaseComponent = dataclasses.field(default_factory=empty_component)
|
||||
|
||||
@cached_property_no_lock
|
||||
def _cached_var_name(self) -> str:
|
||||
"""Get the name of the var.
|
||||
|
||||
Returns:
|
||||
The name of the var.
|
||||
"""
|
||||
var_data = self._get_all_var_data()
|
||||
if var_data is not None:
|
||||
# flatten imports
|
||||
imported_names = {j.alias or j.name for i in var_data.imports for j in i[1]}
|
||||
else:
|
||||
imported_names = set()
|
||||
return str(render_dict_to_var(self._var_value.render(), imported_names))
|
||||
|
||||
@cached_property_no_lock
|
||||
def _cached_get_all_var_data(self) -> VarData | None:
|
||||
"""Get the VarData for the var.
|
||||
|
||||
Returns:
|
||||
The VarData for the var.
|
||||
"""
|
||||
return VarData.merge(
|
||||
VarData(
|
||||
imports={
|
||||
"@emotion/react": [
|
||||
ImportVar(tag="jsx"),
|
||||
],
|
||||
}
|
||||
),
|
||||
VarData(
|
||||
imports=self._var_value._get_all_imports(),
|
||||
),
|
||||
VarData(
|
||||
imports={
|
||||
"react": [
|
||||
ImportVar(tag="Fragment"),
|
||||
],
|
||||
}
|
||||
),
|
||||
)
|
||||
|
||||
def __hash__(self) -> int:
|
||||
"""Get the hash of the var.
|
||||
|
||||
Returns:
|
||||
The hash of the var.
|
||||
"""
|
||||
return hash((type(self).__name__, self._js_expr))
|
||||
|
||||
@classmethod
|
||||
def create(
|
||||
cls,
|
||||
value: Component,
|
||||
_var_data: VarData | None = None,
|
||||
):
|
||||
"""Create a var from a value.
|
||||
|
||||
Args:
|
||||
value: The value of the var.
|
||||
_var_data: Additional hooks and imports associated with the Var.
|
||||
|
||||
Returns:
|
||||
The var.
|
||||
"""
|
||||
return LiteralComponentVar(
|
||||
_js_expr="",
|
||||
_var_type=type(value),
|
||||
_var_data=_var_data,
|
||||
_var_value=value,
|
||||
)
|
||||
|
@ -66,8 +66,8 @@ class WebsocketTargetURL(Var):
|
||||
_js_expr="getBackendURL(env.EVENT).href",
|
||||
_var_data=VarData(
|
||||
imports={
|
||||
"/env.json": [ImportVar(tag="env", is_default=True)],
|
||||
f"/{Dirs.STATE_PATH}": [ImportVar(tag="getBackendURL")],
|
||||
"$/env.json": [ImportVar(tag="env", is_default=True)],
|
||||
f"$/{Dirs.STATE_PATH}": [ImportVar(tag="getBackendURL")],
|
||||
},
|
||||
),
|
||||
_var_type=WebsocketTargetURL,
|
||||
@ -109,8 +109,8 @@ class ConnectionToaster(Toaster):
|
||||
)
|
||||
|
||||
individual_hooks = [
|
||||
f"const toast_props = {str(LiteralVar.create(props))};",
|
||||
f"const [userDismissed, setUserDismissed] = useState(false);",
|
||||
f"const toast_props = {LiteralVar.create(props)!s};",
|
||||
"const [userDismissed, setUserDismissed] = useState(false);",
|
||||
FunctionStringVar(
|
||||
"useEffect",
|
||||
_var_data=VarData(
|
||||
@ -124,7 +124,7 @@ class ConnectionToaster(Toaster):
|
||||
Var(
|
||||
_js_expr=f"""
|
||||
() => {{
|
||||
if ({str(has_too_many_connection_errors)}) {{
|
||||
if ({has_too_many_connection_errors!s}) {{
|
||||
if (!userDismissed) {{
|
||||
toast.error(
|
||||
`Cannot connect to server: ${{{connection_error}}}.`,
|
||||
|
@ -3,14 +3,14 @@
|
||||
# ------------------- DO NOT EDIT ----------------------
|
||||
# This file was generated by `reflex/utils/pyi_generator.py`!
|
||||
# ------------------------------------------------------
|
||||
from typing import Any, Callable, Dict, Literal, Optional, Union, overload
|
||||
from typing import Any, Dict, Literal, Optional, Union, overload
|
||||
|
||||
from reflex.components.component import Component
|
||||
from reflex.components.el.elements.typography import Div
|
||||
from reflex.components.lucide.icon import Icon
|
||||
from reflex.components.sonner.toast import Toaster, ToastProps
|
||||
from reflex.constants.compiler import CompileVars
|
||||
from reflex.event import EventHandler, EventSpec
|
||||
from reflex.event import BASE_STATE, EventType
|
||||
from reflex.style import Style
|
||||
from reflex.utils.imports import ImportVar
|
||||
from reflex.vars import VarData
|
||||
@ -88,42 +88,22 @@ class ConnectionToaster(Toaster):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "ConnectionToaster":
|
||||
"""Create a connection toaster component.
|
||||
@ -168,42 +148,22 @@ class ConnectionBanner(Component):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "ConnectionBanner":
|
||||
"""Create a connection banner component.
|
||||
@ -227,42 +187,22 @@ class ConnectionModal(Component):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "ConnectionModal":
|
||||
"""Create a connection banner component.
|
||||
@ -287,42 +227,22 @@ class WifiOffPulse(Icon):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "WifiOffPulse":
|
||||
"""Create a wifi_off icon with an animated opacity pulse.
|
||||
@ -380,48 +300,28 @@ class ConnectionPulser(Div):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "ConnectionPulser":
|
||||
"""Create a connection pulser component.
|
||||
|
||||
Args:
|
||||
access_key: Provides a hint for generating a keyboard shortcut for the current element.
|
||||
access_key: Provides a hint for generating a keyboard shortcut for the current element.
|
||||
auto_capitalize: Controls whether and how text input is automatically capitalized as it is entered/edited by the user.
|
||||
content_editable: Indicates whether the element's content is editable.
|
||||
context_menu: Defines the ID of a <menu> element which will serve as the element's context menu.
|
||||
|
@ -21,10 +21,10 @@ route_not_found: Var = Var(_js_expr=constants.ROUTE_NOT_FOUND)
|
||||
class ClientSideRouting(Component):
|
||||
"""The client-side routing component."""
|
||||
|
||||
library = "/utils/client_side_routing"
|
||||
library = "$/utils/client_side_routing"
|
||||
tag = "useClientSideRouting"
|
||||
|
||||
def add_hooks(self) -> list[str]:
|
||||
def add_hooks(self) -> list[str | Var]:
|
||||
"""Get the hooks to render.
|
||||
|
||||
Returns:
|
||||
@ -66,4 +66,4 @@ class Default404Page(Component):
|
||||
tag = "Error"
|
||||
is_default = True
|
||||
|
||||
status_code: Var[int] = 404 # type: ignore
|
||||
status_code: Var[int] = Var.create(404)
|
||||
|
@ -3,17 +3,17 @@
|
||||
# ------------------- DO NOT EDIT ----------------------
|
||||
# This file was generated by `reflex/utils/pyi_generator.py`!
|
||||
# ------------------------------------------------------
|
||||
from typing import Any, Callable, Dict, Optional, Union, overload
|
||||
from typing import Any, Dict, Optional, Union, overload
|
||||
|
||||
from reflex.components.component import Component
|
||||
from reflex.event import EventHandler, EventSpec
|
||||
from reflex.event import BASE_STATE, EventType
|
||||
from reflex.style import Style
|
||||
from reflex.vars.base import Var
|
||||
|
||||
route_not_found: Var
|
||||
|
||||
class ClientSideRouting(Component):
|
||||
def add_hooks(self) -> list[str]: ...
|
||||
def add_hooks(self) -> list[str | Var]: ...
|
||||
def render(self) -> str: ...
|
||||
@overload
|
||||
@classmethod
|
||||
@ -25,42 +25,22 @@ class ClientSideRouting(Component):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "ClientSideRouting":
|
||||
"""Create the component.
|
||||
@ -94,42 +74,22 @@ class Default404Page(Component):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "Default404Page":
|
||||
"""Create the component.
|
||||
|
@ -2,11 +2,11 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Dict, List, Union
|
||||
from typing import Dict, List, Tuple, Union
|
||||
|
||||
from reflex.components.base.fragment import Fragment
|
||||
from reflex.components.tags.tag import Tag
|
||||
from reflex.event import EventChain, EventHandler
|
||||
from reflex.event import EventChain, EventHandler, passthrough_event_spec
|
||||
from reflex.utils.format import format_prop, wrap
|
||||
from reflex.utils.imports import ImportVar
|
||||
from reflex.vars import get_unique_variable_name
|
||||
@ -20,7 +20,7 @@ class Clipboard(Fragment):
|
||||
targets: Var[List[str]]
|
||||
|
||||
# Called when the user pastes data into the document. Data is a list of tuples of (mime_type, data). Binary types will be base64 encoded as a data uri.
|
||||
on_paste: EventHandler[lambda data: [data]]
|
||||
on_paste: EventHandler[passthrough_event_spec(List[Tuple[str, str]])]
|
||||
|
||||
# Save the original event actions for the on_paste event.
|
||||
on_paste_event_actions: Var[Dict[str, Union[bool, int]]]
|
||||
@ -51,7 +51,7 @@ class Clipboard(Fragment):
|
||||
return super().create(*children, **props)
|
||||
|
||||
def _exclude_props(self) -> list[str]:
|
||||
return super()._exclude_props() + ["on_paste", "on_paste_event_actions"]
|
||||
return [*super()._exclude_props(), "on_paste", "on_paste_event_actions"]
|
||||
|
||||
def _render(self) -> Tag:
|
||||
tag = super()._render()
|
||||
@ -67,7 +67,7 @@ class Clipboard(Fragment):
|
||||
The import dict for the component.
|
||||
"""
|
||||
return {
|
||||
"/utils/helpers/paste.js": ImportVar(
|
||||
"$/utils/helpers/paste.js": ImportVar(
|
||||
tag="usePasteHandler", is_default=True
|
||||
),
|
||||
}
|
||||
|
@ -3,10 +3,10 @@
|
||||
# ------------------- DO NOT EDIT ----------------------
|
||||
# This file was generated by `reflex/utils/pyi_generator.py`!
|
||||
# ------------------------------------------------------
|
||||
from typing import Any, Callable, Dict, List, Optional, Union, overload
|
||||
from typing import Any, Dict, List, Optional, Union, overload
|
||||
|
||||
from reflex.components.base.fragment import Fragment
|
||||
from reflex.event import EventHandler, EventSpec
|
||||
from reflex.event import BASE_STATE, EventType
|
||||
from reflex.style import Style
|
||||
from reflex.utils.imports import ImportVar
|
||||
from reflex.vars.base import Var
|
||||
@ -26,43 +26,28 @@ class Clipboard(Fragment):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_paste: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_paste: Optional[
|
||||
Union[
|
||||
EventType[[], BASE_STATE],
|
||||
EventType[[list[tuple[str, str]]], BASE_STATE],
|
||||
]
|
||||
] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "Clipboard":
|
||||
"""Create a Clipboard component.
|
||||
@ -70,6 +55,7 @@ class Clipboard(Fragment):
|
||||
Args:
|
||||
*children: The children of the component.
|
||||
targets: The element ids to attach the event listener to. Defaults to all child components or the document.
|
||||
on_paste: Called when the user pastes data into the document. Data is a list of tuples of (mime_type, data). Binary types will be base64 encoded as a data uri.
|
||||
on_paste_event_actions: Save the original event actions for the on_paste event.
|
||||
style: The style of the component.
|
||||
key: A unique key for the component.
|
||||
|
@ -15,7 +15,7 @@ from reflex.vars.base import LiteralVar, Var
|
||||
from reflex.vars.number import ternary_operation
|
||||
|
||||
_IS_TRUE_IMPORT: ImportDict = {
|
||||
f"/{Dirs.STATE_PATH}": [ImportVar(tag="isTrue")],
|
||||
f"$/{Dirs.STATE_PATH}": [ImportVar(tag="isTrue")],
|
||||
}
|
||||
|
||||
|
||||
@ -49,9 +49,9 @@ class Cond(MemoizationLeaf):
|
||||
The conditional component.
|
||||
"""
|
||||
# Wrap everything in fragments.
|
||||
if comp1.__class__.__name__ != "Fragment":
|
||||
if type(comp1).__name__ != "Fragment":
|
||||
comp1 = Fragment.create(comp1)
|
||||
if comp2 is None or comp2.__class__.__name__ != "Fragment":
|
||||
if comp2 is None or type(comp2).__name__ != "Fragment":
|
||||
comp2 = Fragment.create(comp2) if comp2 else Fragment.create()
|
||||
return Fragment.create(
|
||||
cls(
|
||||
@ -94,7 +94,7 @@ class Cond(MemoizationLeaf):
|
||||
).set(
|
||||
props=tag.format_props(),
|
||||
),
|
||||
cond_state=f"isTrue({str(self.cond)})",
|
||||
cond_state=f"isTrue({self.cond!s})",
|
||||
)
|
||||
|
||||
def add_imports(self) -> ImportDict:
|
||||
@ -171,6 +171,14 @@ def cond(condition: Any, c1: Any, c2: Any = None) -> Component | Var:
|
||||
)
|
||||
|
||||
|
||||
@overload
|
||||
def color_mode_cond(light: Component, dark: Component | None = None) -> Component: ... # type: ignore
|
||||
|
||||
|
||||
@overload
|
||||
def color_mode_cond(light: Any, dark: Any = None) -> Var: ...
|
||||
|
||||
|
||||
def color_mode_cond(light: Any, dark: Any = None) -> Var | Component:
|
||||
"""Create a component or Prop based on color_mode.
|
||||
|
||||
|
@ -6,7 +6,7 @@ from typing import Any, Type, Union
|
||||
|
||||
from reflex.components.component import Component
|
||||
from reflex.constants import EventTriggers
|
||||
from reflex.event import EventHandler
|
||||
from reflex.event import EventHandler, no_args_event_spec
|
||||
from reflex.vars import VarData
|
||||
from reflex.vars.base import Var
|
||||
|
||||
@ -46,7 +46,7 @@ class DebounceInput(Component):
|
||||
element: Var[Type[Component]]
|
||||
|
||||
# Fired when the input value changes
|
||||
on_change: EventHandler[lambda e0: [e0.value]]
|
||||
on_change: EventHandler[no_args_event_spec]
|
||||
|
||||
@classmethod
|
||||
def create(cls, *children: Component, **props: Any) -> Component:
|
||||
@ -118,7 +118,7 @@ class DebounceInput(Component):
|
||||
_var_type=Type[Component],
|
||||
_var_data=VarData(
|
||||
imports=child._get_imports(),
|
||||
hooks=child._get_hooks_internal(),
|
||||
hooks=child._get_all_hooks(),
|
||||
),
|
||||
),
|
||||
)
|
||||
@ -128,6 +128,10 @@ class DebounceInput(Component):
|
||||
component.event_triggers.update(child.event_triggers)
|
||||
component.children = child.children
|
||||
component._rename_props = child._rename_props
|
||||
outer_get_all_custom_code = component._get_all_custom_code
|
||||
component._get_all_custom_code = lambda: outer_get_all_custom_code().union(
|
||||
child._get_all_custom_code()
|
||||
)
|
||||
return component
|
||||
|
||||
def _render(self):
|
||||
|
@ -3,10 +3,10 @@
|
||||
# ------------------- DO NOT EDIT ----------------------
|
||||
# This file was generated by `reflex/utils/pyi_generator.py`!
|
||||
# ------------------------------------------------------
|
||||
from typing import Any, Callable, Dict, Optional, Type, Union, overload
|
||||
from typing import Any, Dict, Optional, Type, Union, overload
|
||||
|
||||
from reflex.components.component import Component
|
||||
from reflex.event import EventHandler, EventSpec
|
||||
from reflex.event import BASE_STATE, EventType
|
||||
from reflex.style import Style
|
||||
from reflex.vars.base import Var
|
||||
|
||||
@ -30,43 +30,23 @@ class DebounceInput(Component):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_change: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_change: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "DebounceInput":
|
||||
"""Create a DebounceInput component.
|
||||
|
@ -54,7 +54,7 @@ class Foreach(Component):
|
||||
iterable = LiteralVar.create(iterable)
|
||||
if iterable._var_type == Any:
|
||||
raise ForeachVarError(
|
||||
f"Could not foreach over var `{str(iterable)}` of type Any. "
|
||||
f"Could not foreach over var `{iterable!s}` of type Any. "
|
||||
"(If you are trying to foreach over a state var, add a type annotation to the var). "
|
||||
"See https://reflex.dev/docs/library/dynamic-rendering/foreach/"
|
||||
)
|
||||
|
@ -3,10 +3,10 @@
|
||||
# ------------------- DO NOT EDIT ----------------------
|
||||
# This file was generated by `reflex/utils/pyi_generator.py`!
|
||||
# ------------------------------------------------------
|
||||
from typing import Any, Callable, Dict, Optional, Union, overload
|
||||
from typing import Any, Dict, Optional, Union, overload
|
||||
|
||||
from reflex.components.el.elements.typography import Div
|
||||
from reflex.event import EventHandler, EventSpec
|
||||
from reflex.event import BASE_STATE, EventType
|
||||
from reflex.style import Style
|
||||
from reflex.vars.base import Var
|
||||
|
||||
@ -48,42 +48,22 @@ class Html(Div):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "Html":
|
||||
"""Create a html component.
|
||||
@ -91,7 +71,7 @@ class Html(Div):
|
||||
Args:
|
||||
*children: The children of the component.
|
||||
dangerouslySetInnerHTML: The HTML to render.
|
||||
access_key: Provides a hint for generating a keyboard shortcut for the current element.
|
||||
access_key: Provides a hint for generating a keyboard shortcut for the current element.
|
||||
auto_capitalize: Controls whether and how text input is automatically capitalized as it is entered/edited by the user.
|
||||
content_editable: Indicates whether the element's content is editable.
|
||||
context_menu: Defines the ID of a <menu> element which will serve as the element's context menu.
|
||||
|
@ -2,26 +2,34 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
from typing import Callable, ClassVar, Dict, List, Optional
|
||||
from typing import Any, Callable, ClassVar, Dict, List, Optional, Tuple
|
||||
|
||||
from reflex.components.component import Component, ComponentNamespace, MemoizationLeaf
|
||||
from reflex.components.base.fragment import Fragment
|
||||
from reflex.components.component import (
|
||||
Component,
|
||||
ComponentNamespace,
|
||||
MemoizationLeaf,
|
||||
StatefulComponent,
|
||||
)
|
||||
from reflex.components.el.elements.forms import Input
|
||||
from reflex.components.radix.themes.layout.box import Box
|
||||
from reflex.config import environment
|
||||
from reflex.constants import Dirs
|
||||
from reflex.constants.compiler import Hooks, Imports
|
||||
from reflex.event import (
|
||||
CallableEventSpec,
|
||||
EventChain,
|
||||
EventHandler,
|
||||
EventSpec,
|
||||
call_event_fn,
|
||||
call_script,
|
||||
parse_args_spec,
|
||||
run_script,
|
||||
)
|
||||
from reflex.utils import format
|
||||
from reflex.utils.imports import ImportVar
|
||||
from reflex.vars import VarData
|
||||
from reflex.vars.base import CallableVar, LiteralVar, Var
|
||||
from reflex.vars.base import CallableVar, Var, get_unique_variable_name
|
||||
from reflex.vars.sequence import LiteralStringVar
|
||||
|
||||
DEFAULT_UPLOAD_ID: str = "default"
|
||||
@ -29,7 +37,7 @@ DEFAULT_UPLOAD_ID: str = "default"
|
||||
upload_files_context_var_data: VarData = VarData(
|
||||
imports={
|
||||
"react": "useContext",
|
||||
f"/{Dirs.CONTEXTS_PATH}": "UploadFilesContext",
|
||||
f"$/{Dirs.CONTEXTS_PATH}": "UploadFilesContext",
|
||||
},
|
||||
hooks={
|
||||
"const [filesById, setFilesById] = useContext(UploadFilesContext);": None,
|
||||
@ -53,7 +61,7 @@ def upload_file(id_: str = DEFAULT_UPLOAD_ID) -> Var:
|
||||
id_var = LiteralStringVar.create(id_)
|
||||
var_name = f"""e => setFilesById(filesById => {{
|
||||
const updatedFilesById = Object.assign({{}}, filesById);
|
||||
updatedFilesById[{str(id_var)}] = e;
|
||||
updatedFilesById[{id_var!s}] = e;
|
||||
return updatedFilesById;
|
||||
}})
|
||||
"""
|
||||
@ -79,7 +87,7 @@ def selected_files(id_: str = DEFAULT_UPLOAD_ID) -> Var:
|
||||
"""
|
||||
id_var = LiteralStringVar.create(id_)
|
||||
return Var(
|
||||
_js_expr=f"(filesById[{str(id_var)}] ? filesById[{str(id_var)}].map((f) => (f.path || f.name)) : [])",
|
||||
_js_expr=f"(filesById[{id_var!s}] ? filesById[{id_var!s}].map((f) => (f.path || f.name)) : [])",
|
||||
_var_type=List[str],
|
||||
_var_data=VarData.merge(
|
||||
upload_files_context_var_data, id_var._get_all_var_data()
|
||||
@ -99,8 +107,9 @@ def clear_selected_files(id_: str = DEFAULT_UPLOAD_ID) -> EventSpec:
|
||||
"""
|
||||
# UploadFilesProvider assigns a special function to clear selected files
|
||||
# into the shared global refs object to make it accessible outside a React
|
||||
# component via `call_script` (otherwise backend could never clear files).
|
||||
return call_script(f"refs['__clear_selected_files']({id_!r})")
|
||||
# component via `run_script` (otherwise backend could never clear files).
|
||||
func = Var("__clear_selected_files")._as_ref()
|
||||
return run_script(f"{func}({id_!r})")
|
||||
|
||||
|
||||
def cancel_upload(upload_id: str) -> EventSpec:
|
||||
@ -112,9 +121,8 @@ def cancel_upload(upload_id: str) -> EventSpec:
|
||||
Returns:
|
||||
An event spec that cancels the upload when triggered.
|
||||
"""
|
||||
return call_script(
|
||||
f"upload_controllers[{str(LiteralVar.create(upload_id))}]?.abort()"
|
||||
)
|
||||
controller = Var(f"__upload_controllers_{upload_id}")._as_ref()
|
||||
return run_script(f"{controller}?.abort()")
|
||||
|
||||
|
||||
def get_upload_dir() -> Path:
|
||||
@ -125,9 +133,7 @@ def get_upload_dir() -> Path:
|
||||
"""
|
||||
Upload.is_used = True
|
||||
|
||||
uploaded_files_dir = Path(
|
||||
os.environ.get("REFLEX_UPLOADED_FILES_DIR", "./uploaded_files")
|
||||
)
|
||||
uploaded_files_dir = environment.REFLEX_UPLOADED_FILES_DIR.get()
|
||||
uploaded_files_dir.mkdir(parents=True, exist_ok=True)
|
||||
return uploaded_files_dir
|
||||
|
||||
@ -136,8 +142,8 @@ uploaded_files_url_prefix = Var(
|
||||
_js_expr="getBackendURL(env.UPLOAD)",
|
||||
_var_data=VarData(
|
||||
imports={
|
||||
f"/{Dirs.STATE_PATH}": "getBackendURL",
|
||||
"/env.json": ImportVar(tag="env", is_default=True),
|
||||
f"$/{Dirs.STATE_PATH}": "getBackendURL",
|
||||
"$/env.json": ImportVar(tag="env", is_default=True),
|
||||
}
|
||||
),
|
||||
).to(str)
|
||||
@ -157,7 +163,7 @@ def get_upload_url(file_path: str) -> Var[str]:
|
||||
return uploaded_files_url_prefix + "/" + file_path
|
||||
|
||||
|
||||
def _on_drop_spec(files: Var):
|
||||
def _on_drop_spec(files: Var) -> Tuple[Var[Any]]:
|
||||
"""Args spec for the on_drop event trigger.
|
||||
|
||||
Args:
|
||||
@ -166,24 +172,29 @@ def _on_drop_spec(files: Var):
|
||||
Returns:
|
||||
Signature for on_drop handler including the files to upload.
|
||||
"""
|
||||
return [files]
|
||||
return (files,)
|
||||
|
||||
|
||||
class UploadFilesProvider(Component):
|
||||
"""AppWrap component that provides a dict of selected files by ID via useContext."""
|
||||
|
||||
library = f"/{Dirs.CONTEXTS_PATH}"
|
||||
library = f"$/{Dirs.CONTEXTS_PATH}"
|
||||
tag = "UploadFilesProvider"
|
||||
|
||||
|
||||
class GhostUpload(Fragment):
|
||||
"""A ghost upload component."""
|
||||
|
||||
# Fired when files are dropped.
|
||||
on_drop: EventHandler[_on_drop_spec]
|
||||
|
||||
|
||||
class Upload(MemoizationLeaf):
|
||||
"""A file upload component."""
|
||||
|
||||
library = "react-dropzone@14.2.3"
|
||||
library = "react-dropzone@14.2.10"
|
||||
|
||||
tag = "ReactDropzone"
|
||||
|
||||
is_default = True
|
||||
tag = ""
|
||||
|
||||
# The list of accepted file types. This should be a dictionary of MIME types as keys and array of file formats as
|
||||
# values.
|
||||
@ -203,7 +214,7 @@ class Upload(MemoizationLeaf):
|
||||
min_size: Var[int]
|
||||
|
||||
# Whether to allow multiple files to be uploaded.
|
||||
multiple: Var[bool] = True # type: ignore
|
||||
multiple: Var[bool]
|
||||
|
||||
# Whether to disable click to upload.
|
||||
no_click: Var[bool]
|
||||
@ -234,6 +245,8 @@ class Upload(MemoizationLeaf):
|
||||
# Mark the Upload component as used in the app.
|
||||
cls.is_used = True
|
||||
|
||||
props.setdefault("multiple", True)
|
||||
|
||||
# Apply the default classname
|
||||
given_class_name = props.pop("class_name", [])
|
||||
if isinstance(given_class_name, str):
|
||||
@ -245,17 +258,6 @@ class Upload(MemoizationLeaf):
|
||||
upload_props = {
|
||||
key: value for key, value in props.items() if key in supported_props
|
||||
}
|
||||
# The file input to use.
|
||||
upload = Input.create(type="file")
|
||||
upload.special_props = [Var(_js_expr="{...getInputProps()}", _var_type=None)]
|
||||
|
||||
# The dropzone to use.
|
||||
zone = Box.create(
|
||||
upload,
|
||||
*children,
|
||||
**{k: v for k, v in props.items() if k not in supported_props},
|
||||
)
|
||||
zone.special_props = [Var(_js_expr="{...getRootProps()}", _var_type=None)]
|
||||
|
||||
# Create the component.
|
||||
upload_props["id"] = props.get("id", DEFAULT_UPLOAD_ID)
|
||||
@ -277,9 +279,75 @@ class Upload(MemoizationLeaf):
|
||||
),
|
||||
)
|
||||
upload_props["on_drop"] = on_drop
|
||||
|
||||
input_props_unique_name = get_unique_variable_name()
|
||||
root_props_unique_name = get_unique_variable_name()
|
||||
|
||||
event_var, callback_str = StatefulComponent._get_memoized_event_triggers(
|
||||
GhostUpload.create(on_drop=upload_props["on_drop"])
|
||||
)["on_drop"]
|
||||
|
||||
upload_props["on_drop"] = event_var
|
||||
|
||||
upload_props = {
|
||||
format.to_camel_case(key): value for key, value in upload_props.items()
|
||||
}
|
||||
|
||||
use_dropzone_arguments = Var.create(
|
||||
{
|
||||
"onDrop": event_var,
|
||||
**upload_props,
|
||||
}
|
||||
)
|
||||
|
||||
left_side = f"const {{getRootProps: {root_props_unique_name}, getInputProps: {input_props_unique_name}}} "
|
||||
right_side = f"useDropzone({use_dropzone_arguments!s})"
|
||||
|
||||
var_data = VarData.merge(
|
||||
VarData(
|
||||
imports=Imports.EVENTS,
|
||||
hooks={Hooks.EVENTS: None},
|
||||
),
|
||||
event_var._get_all_var_data(),
|
||||
use_dropzone_arguments._get_all_var_data(),
|
||||
VarData(
|
||||
hooks={
|
||||
callback_str: None,
|
||||
f"{left_side} = {right_side};": None,
|
||||
},
|
||||
imports={
|
||||
"react-dropzone": "useDropzone",
|
||||
**Imports.EVENTS,
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
# The file input to use.
|
||||
upload = Input.create(type="file")
|
||||
upload.special_props = [
|
||||
Var(
|
||||
_js_expr=f"{{...{input_props_unique_name}()}}",
|
||||
_var_type=None,
|
||||
_var_data=var_data,
|
||||
)
|
||||
]
|
||||
|
||||
# The dropzone to use.
|
||||
zone = Box.create(
|
||||
upload,
|
||||
*children,
|
||||
**{k: v for k, v in props.items() if k not in supported_props},
|
||||
)
|
||||
zone.special_props = [
|
||||
Var(
|
||||
_js_expr=f"{{...{root_props_unique_name}()}}",
|
||||
_var_type=None,
|
||||
_var_data=var_data,
|
||||
)
|
||||
]
|
||||
|
||||
return super().create(
|
||||
zone,
|
||||
**upload_props,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@ -297,11 +365,6 @@ class Upload(MemoizationLeaf):
|
||||
return (arg_value[0], placeholder)
|
||||
return arg_value
|
||||
|
||||
def _render(self):
|
||||
out = super()._render()
|
||||
out.args = ("getRootProps", "getInputProps")
|
||||
return out
|
||||
|
||||
@staticmethod
|
||||
def _get_app_wrap_components() -> dict[tuple[int, str], Component]:
|
||||
return {
|
||||
|
@ -4,15 +4,12 @@
|
||||
# This file was generated by `reflex/utils/pyi_generator.py`!
|
||||
# ------------------------------------------------------
|
||||
from pathlib import Path
|
||||
from typing import Any, Callable, ClassVar, Dict, List, Optional, Union, overload
|
||||
from typing import Any, ClassVar, Dict, List, Optional, Union, overload
|
||||
|
||||
from reflex.components.base.fragment import Fragment
|
||||
from reflex.components.component import Component, ComponentNamespace, MemoizationLeaf
|
||||
from reflex.constants import Dirs
|
||||
from reflex.event import (
|
||||
CallableEventSpec,
|
||||
EventHandler,
|
||||
EventSpec,
|
||||
)
|
||||
from reflex.event import BASE_STATE, CallableEventSpec, EventSpec, EventType
|
||||
from reflex.style import Style
|
||||
from reflex.utils.imports import ImportVar
|
||||
from reflex.vars import VarData
|
||||
@ -34,8 +31,8 @@ uploaded_files_url_prefix = Var(
|
||||
_js_expr="getBackendURL(env.UPLOAD)",
|
||||
_var_data=VarData(
|
||||
imports={
|
||||
f"/{Dirs.STATE_PATH}": "getBackendURL",
|
||||
"/env.json": ImportVar(tag="env", is_default=True),
|
||||
f"$/{Dirs.STATE_PATH}": "getBackendURL",
|
||||
"$/env.json": ImportVar(tag="env", is_default=True),
|
||||
}
|
||||
),
|
||||
).to(str)
|
||||
@ -53,42 +50,22 @@ class UploadFilesProvider(Component):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "UploadFilesProvider":
|
||||
"""Create the component.
|
||||
@ -108,6 +85,56 @@ class UploadFilesProvider(Component):
|
||||
"""
|
||||
...
|
||||
|
||||
class GhostUpload(Fragment):
|
||||
@overload
|
||||
@classmethod
|
||||
def create( # type: ignore
|
||||
cls,
|
||||
*children,
|
||||
style: Optional[Style] = None,
|
||||
key: Optional[Any] = None,
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_drop: Optional[
|
||||
Union[EventType[[], BASE_STATE], EventType[[Any], BASE_STATE]]
|
||||
] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "GhostUpload":
|
||||
"""Create the component.
|
||||
|
||||
Args:
|
||||
*children: The children of the component.
|
||||
on_drop: Fired when files are dropped.
|
||||
style: The style of the component.
|
||||
key: A unique key for the component.
|
||||
id: The id for the component.
|
||||
class_name: The class name for the component.
|
||||
autofocus: Whether the component should take the focus once the page is loaded
|
||||
custom_attrs: custom attribute
|
||||
**props: The props of the component.
|
||||
|
||||
Returns:
|
||||
The component.
|
||||
"""
|
||||
...
|
||||
|
||||
class Upload(MemoizationLeaf):
|
||||
is_used: ClassVar[bool] = False
|
||||
|
||||
@ -130,43 +157,25 @@ class Upload(MemoizationLeaf):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_drop: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_drop: Optional[
|
||||
Union[EventType[[], BASE_STATE], EventType[[Any], BASE_STATE]]
|
||||
] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "Upload":
|
||||
"""Create an upload component.
|
||||
@ -182,6 +191,7 @@ class Upload(MemoizationLeaf):
|
||||
no_click: Whether to disable click to upload.
|
||||
no_drag: Whether to disable drag and drop.
|
||||
no_keyboard: Whether to disable using the space/enter keys to upload.
|
||||
on_drop: Fired when files are dropped.
|
||||
style: The style of the component.
|
||||
key: A unique key for the component.
|
||||
id: The id for the component.
|
||||
@ -215,43 +225,25 @@ class StyledUpload(Upload):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_drop: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_drop: Optional[
|
||||
Union[EventType[[], BASE_STATE], EventType[[Any], BASE_STATE]]
|
||||
] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "StyledUpload":
|
||||
"""Create the styled upload component.
|
||||
@ -267,6 +259,7 @@ class StyledUpload(Upload):
|
||||
no_click: Whether to disable click to upload.
|
||||
no_drag: Whether to disable drag and drop.
|
||||
no_keyboard: Whether to disable using the space/enter keys to upload.
|
||||
on_drop: Fired when files are dropped.
|
||||
style: The style of the component.
|
||||
key: A unique key for the component.
|
||||
id: The id for the component.
|
||||
@ -300,43 +293,25 @@ class UploadNamespace(ComponentNamespace):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_drop: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_drop: Optional[
|
||||
Union[EventType[[], BASE_STATE], EventType[[Any], BASE_STATE]]
|
||||
] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "StyledUpload":
|
||||
"""Create the styled upload component.
|
||||
@ -352,6 +327,7 @@ class UploadNamespace(ComponentNamespace):
|
||||
no_click: Whether to disable click to upload.
|
||||
no_drag: Whether to disable drag and drop.
|
||||
no_keyboard: Whether to disable using the space/enter keys to upload.
|
||||
on_drop: Fired when files are dropped.
|
||||
style: The style of the component.
|
||||
key: A unique key for the component.
|
||||
id: The id for the component.
|
||||
|
@ -8,13 +8,14 @@ from typing import ClassVar, Dict, Literal, Optional, Union
|
||||
from reflex.components.component import Component, ComponentNamespace
|
||||
from reflex.components.core.cond import color_mode_cond
|
||||
from reflex.components.lucide.icon import Icon
|
||||
from reflex.components.markdown.markdown import _LANGUAGE, MarkdownComponentMap
|
||||
from reflex.components.radix.themes.components.button import Button
|
||||
from reflex.components.radix.themes.layout.box import Box
|
||||
from reflex.constants.colors import Color
|
||||
from reflex.event import set_clipboard
|
||||
from reflex.style import Style
|
||||
from reflex.utils import console, format
|
||||
from reflex.utils.imports import ImportDict, ImportVar
|
||||
from reflex.utils.imports import ImportVar
|
||||
from reflex.vars.base import LiteralVar, Var, VarData
|
||||
|
||||
LiteralCodeLanguage = Literal[
|
||||
@ -378,10 +379,10 @@ for theme_name in dir(Theme):
|
||||
setattr(Theme, theme_name, getattr(Theme, theme_name)._replace(_var_type=Theme))
|
||||
|
||||
|
||||
class CodeBlock(Component):
|
||||
class CodeBlock(Component, MarkdownComponentMap):
|
||||
"""A code block."""
|
||||
|
||||
library = "react-syntax-highlighter@15.5.0"
|
||||
library = "react-syntax-highlighter@15.6.0"
|
||||
|
||||
tag = "PrismAsyncLight"
|
||||
|
||||
@ -391,7 +392,7 @@ class CodeBlock(Component):
|
||||
theme: Var[Union[Theme, str]] = Theme.one_light
|
||||
|
||||
# The language to use.
|
||||
language: Var[LiteralCodeLanguage] = "python" # type: ignore
|
||||
language: Var[LiteralCodeLanguage] = Var.create("python")
|
||||
|
||||
# The code to display.
|
||||
code: Var[str]
|
||||
@ -411,53 +412,22 @@ class CodeBlock(Component):
|
||||
# Props passed down to the code tag.
|
||||
code_tag_props: Var[Dict[str, str]]
|
||||
|
||||
def add_imports(self) -> ImportDict:
|
||||
"""Add imports for the CodeBlock component.
|
||||
# Whether a copy button should appear.
|
||||
can_copy: Optional[bool] = False
|
||||
|
||||
Returns:
|
||||
The import dict.
|
||||
"""
|
||||
imports_: ImportDict = {}
|
||||
|
||||
if (
|
||||
self.language is not None
|
||||
and (language_without_quotes := str(self.language).replace('"', ""))
|
||||
in LiteralCodeLanguage.__args__ # type: ignore
|
||||
):
|
||||
imports_[
|
||||
f"react-syntax-highlighter/dist/cjs/languages/prism/{language_without_quotes}"
|
||||
] = [
|
||||
ImportVar(
|
||||
tag=format.to_camel_case(language_without_quotes),
|
||||
is_default=True,
|
||||
install=False,
|
||||
)
|
||||
]
|
||||
|
||||
return imports_
|
||||
|
||||
def _get_custom_code(self) -> Optional[str]:
|
||||
if (
|
||||
self.language is not None
|
||||
and (language_without_quotes := str(self.language).replace('"', ""))
|
||||
in LiteralCodeLanguage.__args__ # type: ignore
|
||||
):
|
||||
return f"{self.alias}.registerLanguage('{language_without_quotes}', {format.to_camel_case(language_without_quotes)})"
|
||||
# A custom copy button to override the default one.
|
||||
copy_button: Optional[Union[bool, Component]] = None
|
||||
|
||||
@classmethod
|
||||
def create(
|
||||
cls,
|
||||
*children,
|
||||
can_copy: Optional[bool] = False,
|
||||
copy_button: Optional[Union[bool, Component]] = None,
|
||||
**props,
|
||||
):
|
||||
"""Create a text component.
|
||||
|
||||
Args:
|
||||
*children: The children of the component.
|
||||
can_copy: Whether a copy button should appears.
|
||||
copy_button: A custom copy button to override the default one.
|
||||
**props: The props to pass to the component.
|
||||
|
||||
Returns:
|
||||
@ -465,6 +435,8 @@ class CodeBlock(Component):
|
||||
"""
|
||||
# This component handles style in a special prop.
|
||||
custom_style = props.pop("custom_style", {})
|
||||
can_copy = props.pop("can_copy", False)
|
||||
copy_button = props.pop("copy_button", None)
|
||||
|
||||
if "theme" not in props:
|
||||
# Default color scheme responds to global color mode.
|
||||
@ -530,12 +502,55 @@ class CodeBlock(Component):
|
||||
|
||||
theme = self.theme
|
||||
|
||||
out.add_props(style=theme).remove_props("theme", "code").add_props(
|
||||
children=self.code
|
||||
out.add_props(style=theme).remove_props("theme", "code", "language").add_props(
|
||||
children=self.code, language=_LANGUAGE
|
||||
)
|
||||
|
||||
return out
|
||||
|
||||
def _exclude_props(self) -> list[str]:
|
||||
return ["can_copy", "copy_button"]
|
||||
|
||||
@classmethod
|
||||
def _get_language_registration_hook(cls) -> str:
|
||||
"""Get the hook to register the language.
|
||||
|
||||
Returns:
|
||||
The hook to register the language.
|
||||
"""
|
||||
return f"""
|
||||
if ({_LANGUAGE!s}) {{
|
||||
(async () => {{
|
||||
try {{
|
||||
const module = await import(`react-syntax-highlighter/dist/cjs/languages/prism/${{{_LANGUAGE!s}}}`);
|
||||
SyntaxHighlighter.registerLanguage({_LANGUAGE!s}, module.default);
|
||||
}} catch (error) {{
|
||||
console.error(`Error importing language module for ${{{_LANGUAGE!s}}}:`, error);
|
||||
}}
|
||||
}})();
|
||||
}}
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def get_component_map_custom_code(cls) -> str:
|
||||
"""Get the custom code for the component.
|
||||
|
||||
Returns:
|
||||
The custom code for the component.
|
||||
"""
|
||||
return cls._get_language_registration_hook()
|
||||
|
||||
def add_hooks(self) -> list[str | Var]:
|
||||
"""Add hooks for the component.
|
||||
|
||||
Returns:
|
||||
The hooks for the component.
|
||||
"""
|
||||
return [
|
||||
f"const {_LANGUAGE!s} = {self.language!s}",
|
||||
self._get_language_registration_hook(),
|
||||
]
|
||||
|
||||
|
||||
class CodeblockNamespace(ComponentNamespace):
|
||||
"""Namespace for the CodeBlock component."""
|
||||
|
@ -4,13 +4,13 @@
|
||||
# This file was generated by `reflex/utils/pyi_generator.py`!
|
||||
# ------------------------------------------------------
|
||||
import dataclasses
|
||||
from typing import Any, Callable, ClassVar, Dict, Literal, Optional, Union, overload
|
||||
from typing import Any, ClassVar, Dict, Literal, Optional, Union, overload
|
||||
|
||||
from reflex.components.component import Component, ComponentNamespace
|
||||
from reflex.components.markdown.markdown import MarkdownComponentMap
|
||||
from reflex.constants.colors import Color
|
||||
from reflex.event import EventHandler, EventSpec
|
||||
from reflex.event import BASE_STATE, EventType
|
||||
from reflex.style import Style
|
||||
from reflex.utils.imports import ImportDict
|
||||
from reflex.vars.base import Var
|
||||
|
||||
LiteralCodeLanguage = Literal[
|
||||
@ -349,15 +349,12 @@ for theme_name in dir(Theme):
|
||||
continue
|
||||
setattr(Theme, theme_name, getattr(Theme, theme_name)._replace(_var_type=Theme))
|
||||
|
||||
class CodeBlock(Component):
|
||||
def add_imports(self) -> ImportDict: ...
|
||||
class CodeBlock(Component, MarkdownComponentMap):
|
||||
@overload
|
||||
@classmethod
|
||||
def create( # type: ignore
|
||||
cls,
|
||||
*children,
|
||||
can_copy: Optional[bool] = False,
|
||||
copy_button: Optional[Union[Component, bool]] = None,
|
||||
theme: Optional[Union[Theme, Var[Union[Theme, str]], str]] = None,
|
||||
language: Optional[
|
||||
Union[
|
||||
@ -933,55 +930,35 @@ class CodeBlock(Component):
|
||||
wrap_long_lines: Optional[Union[Var[bool], bool]] = None,
|
||||
custom_style: Optional[Dict[str, Union[str, Var, Color]]] = None,
|
||||
code_tag_props: Optional[Union[Dict[str, str], Var[Dict[str, str]]]] = None,
|
||||
can_copy: Optional[bool] = None,
|
||||
copy_button: Optional[Union[Component, bool]] = None,
|
||||
style: Optional[Style] = None,
|
||||
key: Optional[Any] = None,
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "CodeBlock":
|
||||
"""Create a text component.
|
||||
|
||||
Args:
|
||||
*children: The children of the component.
|
||||
can_copy: Whether a copy button should appears.
|
||||
copy_button: A custom copy button to override the default one.
|
||||
theme: The theme to use ("light" or "dark").
|
||||
language: The language to use.
|
||||
code: The code to display.
|
||||
@ -990,6 +967,8 @@ class CodeBlock(Component):
|
||||
wrap_long_lines: Whether to wrap long lines.
|
||||
custom_style: A custom style for the code block.
|
||||
code_tag_props: Props passed down to the code tag.
|
||||
can_copy: Whether a copy button should appear.
|
||||
copy_button: A custom copy button to override the default one.
|
||||
style: The style of the component.
|
||||
key: A unique key for the component.
|
||||
id: The id for the component.
|
||||
@ -1004,6 +983,9 @@ class CodeBlock(Component):
|
||||
...
|
||||
|
||||
def add_style(self): ...
|
||||
@classmethod
|
||||
def get_component_map_custom_code(cls) -> str: ...
|
||||
def add_hooks(self) -> list[str | Var]: ...
|
||||
|
||||
class CodeblockNamespace(ComponentNamespace):
|
||||
themes = Theme
|
||||
@ -1011,8 +993,6 @@ class CodeblockNamespace(ComponentNamespace):
|
||||
@staticmethod
|
||||
def __call__(
|
||||
*children,
|
||||
can_copy: Optional[bool] = False,
|
||||
copy_button: Optional[Union[Component, bool]] = None,
|
||||
theme: Optional[Union[Theme, Var[Union[Theme, str]], str]] = None,
|
||||
language: Optional[
|
||||
Union[
|
||||
@ -1588,55 +1568,35 @@ class CodeblockNamespace(ComponentNamespace):
|
||||
wrap_long_lines: Optional[Union[Var[bool], bool]] = None,
|
||||
custom_style: Optional[Dict[str, Union[str, Var, Color]]] = None,
|
||||
code_tag_props: Optional[Union[Dict[str, str], Var[Dict[str, str]]]] = None,
|
||||
can_copy: Optional[bool] = None,
|
||||
copy_button: Optional[Union[Component, bool]] = None,
|
||||
style: Optional[Style] = None,
|
||||
key: Optional[Any] = None,
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "CodeBlock":
|
||||
"""Create a text component.
|
||||
|
||||
Args:
|
||||
*children: The children of the component.
|
||||
can_copy: Whether a copy button should appears.
|
||||
copy_button: A custom copy button to override the default one.
|
||||
theme: The theme to use ("light" or "dark").
|
||||
language: The language to use.
|
||||
code: The code to display.
|
||||
@ -1645,6 +1605,8 @@ class CodeblockNamespace(ComponentNamespace):
|
||||
wrap_long_lines: Whether to wrap long lines.
|
||||
custom_style: A custom style for the code block.
|
||||
code_tag_props: Props passed down to the code tag.
|
||||
can_copy: Whether a copy button should appear.
|
||||
copy_button: A custom copy button to override the default one.
|
||||
style: The style of the component.
|
||||
key: A unique key for the component.
|
||||
id: The id for the component.
|
||||
|
@ -3,12 +3,14 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from enum import Enum
|
||||
from typing import Any, Dict, List, Literal, Optional, Union
|
||||
from typing import Any, Dict, List, Literal, Optional, Tuple, Union
|
||||
|
||||
from typing_extensions import TypedDict
|
||||
|
||||
from reflex.base import Base
|
||||
from reflex.components.component import Component, NoSSRComponent
|
||||
from reflex.components.literals import LiteralRowMarker
|
||||
from reflex.event import EventHandler
|
||||
from reflex.event import EventHandler, no_args_event_spec, passthrough_event_spec
|
||||
from reflex.utils import console, format, types
|
||||
from reflex.utils.imports import ImportDict, ImportVar
|
||||
from reflex.utils.serializers import serializer
|
||||
@ -49,27 +51,6 @@ class GridColumnIcons(Enum):
|
||||
VideoUri = "video_uri"
|
||||
|
||||
|
||||
# @serializer
|
||||
# def serialize_gridcolumn_icon(icon: GridColumnIcons) -> str:
|
||||
# """Serialize grid column icon.
|
||||
|
||||
# Args:
|
||||
# icon: the Icon to serialize.
|
||||
|
||||
# Returns:
|
||||
# The serialized value.
|
||||
# """
|
||||
# return "prefix" + str(icon)
|
||||
|
||||
|
||||
# class DataEditorColumn(Base):
|
||||
# """Column."""
|
||||
|
||||
# title: str
|
||||
# id: Optional[str] = None
|
||||
# type_: str = "str"
|
||||
|
||||
|
||||
class DataEditorTheme(Base):
|
||||
"""The theme for the DataEditor component."""
|
||||
|
||||
@ -107,17 +88,76 @@ class DataEditorTheme(Base):
|
||||
text_medium: Optional[str] = None
|
||||
|
||||
|
||||
def on_edit_spec(pos, data: dict[str, Any]):
|
||||
"""The on edit spec function.
|
||||
class Bounds(TypedDict):
|
||||
"""The bounds of the group header."""
|
||||
|
||||
Args:
|
||||
pos: The position of the edit event.
|
||||
data: The data of the edit event.
|
||||
x: int
|
||||
y: int
|
||||
width: int
|
||||
height: int
|
||||
|
||||
Returns:
|
||||
The position and data.
|
||||
"""
|
||||
return [pos, data]
|
||||
|
||||
class CompatSelection(TypedDict):
|
||||
"""The selection."""
|
||||
|
||||
items: list
|
||||
|
||||
|
||||
class Rectangle(TypedDict):
|
||||
"""The bounds of the group header."""
|
||||
|
||||
x: int
|
||||
y: int
|
||||
width: int
|
||||
height: int
|
||||
|
||||
|
||||
class GridSelectionCurrent(TypedDict):
|
||||
"""The current selection."""
|
||||
|
||||
cell: tuple[int, int]
|
||||
range: Rectangle
|
||||
rangeStack: list[Rectangle]
|
||||
|
||||
|
||||
class GridSelection(TypedDict):
|
||||
"""The grid selection."""
|
||||
|
||||
current: Optional[GridSelectionCurrent]
|
||||
columns: CompatSelection
|
||||
rows: CompatSelection
|
||||
|
||||
|
||||
class GroupHeaderClickedEventArgs(TypedDict):
|
||||
"""The arguments for the group header clicked event."""
|
||||
|
||||
kind: str
|
||||
group: str
|
||||
location: tuple[int, int]
|
||||
bounds: Bounds
|
||||
isEdge: bool
|
||||
shiftKey: bool
|
||||
ctrlKey: bool
|
||||
metaKey: bool
|
||||
isTouch: bool
|
||||
localEventX: int
|
||||
localEventY: int
|
||||
button: int
|
||||
buttons: int
|
||||
scrollEdge: tuple[int, int]
|
||||
|
||||
|
||||
class GridCell(TypedDict):
|
||||
"""The grid cell."""
|
||||
|
||||
span: Optional[List[int]]
|
||||
|
||||
|
||||
class GridColumn(TypedDict):
|
||||
"""The grid column."""
|
||||
|
||||
title: str
|
||||
group: Optional[str]
|
||||
|
||||
|
||||
class DataEditor(NoSSRComponent):
|
||||
@ -125,10 +165,9 @@ class DataEditor(NoSSRComponent):
|
||||
|
||||
tag = "DataEditor"
|
||||
is_default = True
|
||||
library: str = "@glideapps/glide-data-grid@^5.3.0"
|
||||
library: str = "@glideapps/glide-data-grid@^6.0.3"
|
||||
lib_dependencies: List[str] = [
|
||||
"lodash@^4.17.21",
|
||||
"marked@^4.0.10",
|
||||
"react-responsive-carousel@^3.2.7",
|
||||
]
|
||||
|
||||
@ -145,7 +184,7 @@ class DataEditor(NoSSRComponent):
|
||||
get_cell_content: Var[str]
|
||||
|
||||
# Allow selection for copying.
|
||||
get_cell_for_selection: Var[bool]
|
||||
get_cells_for_selection: Var[bool]
|
||||
|
||||
# Allow paste.
|
||||
on_paste: Var[bool]
|
||||
@ -169,7 +208,7 @@ class DataEditor(NoSSRComponent):
|
||||
header_height: Var[int]
|
||||
|
||||
# Additional header icons:
|
||||
# header_icons: Var[Any] # (TODO: must be a map of name: svg)
|
||||
# header_icons: Var[Any] # (TODO: must be a map of name: svg) #noqa: ERA001
|
||||
|
||||
# The maximum width a column can be automatically sized to.
|
||||
max_column_auto_width: Var[int]
|
||||
@ -223,52 +262,58 @@ class DataEditor(NoSSRComponent):
|
||||
theme: Var[Union[DataEditorTheme, Dict]]
|
||||
|
||||
# Fired when a cell is activated.
|
||||
on_cell_activated: EventHandler[lambda pos: [pos]]
|
||||
on_cell_activated: EventHandler[passthrough_event_spec(Tuple[int, int])]
|
||||
|
||||
# Fired when a cell is clicked.
|
||||
on_cell_clicked: EventHandler[lambda pos: [pos]]
|
||||
on_cell_clicked: EventHandler[passthrough_event_spec(Tuple[int, int])]
|
||||
|
||||
# Fired when a cell is right-clicked.
|
||||
on_cell_context_menu: EventHandler[lambda pos: [pos]]
|
||||
on_cell_context_menu: EventHandler[passthrough_event_spec(Tuple[int, int])]
|
||||
|
||||
# Fired when a cell is edited.
|
||||
on_cell_edited: EventHandler[on_edit_spec]
|
||||
on_cell_edited: EventHandler[passthrough_event_spec(Tuple[int, int], GridCell)]
|
||||
|
||||
# Fired when a group header is clicked.
|
||||
on_group_header_clicked: EventHandler[on_edit_spec]
|
||||
on_group_header_clicked: EventHandler[
|
||||
passthrough_event_spec(Tuple[int, int], GridCell)
|
||||
]
|
||||
|
||||
# Fired when a group header is right-clicked.
|
||||
on_group_header_context_menu: EventHandler[lambda grp_idx, data: [grp_idx, data]]
|
||||
on_group_header_context_menu: EventHandler[
|
||||
passthrough_event_spec(int, GroupHeaderClickedEventArgs)
|
||||
]
|
||||
|
||||
# Fired when a group header is renamed.
|
||||
on_group_header_renamed: EventHandler[lambda idx, val: [idx, val]]
|
||||
on_group_header_renamed: EventHandler[passthrough_event_spec(str, str)]
|
||||
|
||||
# Fired when a header is clicked.
|
||||
on_header_clicked: EventHandler[lambda pos: [pos]]
|
||||
on_header_clicked: EventHandler[passthrough_event_spec(Tuple[int, int])]
|
||||
|
||||
# Fired when a header is right-clicked.
|
||||
on_header_context_menu: EventHandler[lambda pos: [pos]]
|
||||
on_header_context_menu: EventHandler[passthrough_event_spec(Tuple[int, int])]
|
||||
|
||||
# Fired when a header menu item is clicked.
|
||||
on_header_menu_click: EventHandler[lambda col, pos: [col, pos]]
|
||||
on_header_menu_click: EventHandler[passthrough_event_spec(int, Rectangle)]
|
||||
|
||||
# Fired when an item is hovered.
|
||||
on_item_hovered: EventHandler[lambda pos: [pos]]
|
||||
on_item_hovered: EventHandler[passthrough_event_spec(Tuple[int, int])]
|
||||
|
||||
# Fired when a selection is deleted.
|
||||
on_delete: EventHandler[lambda selection: [selection]]
|
||||
on_delete: EventHandler[passthrough_event_spec(GridSelection)]
|
||||
|
||||
# Fired when editing is finished.
|
||||
on_finished_editing: EventHandler[lambda new_value, movement: [new_value, movement]]
|
||||
on_finished_editing: EventHandler[
|
||||
passthrough_event_spec(Union[GridCell, None], tuple[int, int])
|
||||
]
|
||||
|
||||
# Fired when a row is appended.
|
||||
on_row_appended: EventHandler[lambda: []]
|
||||
on_row_appended: EventHandler[no_args_event_spec]
|
||||
|
||||
# Fired when the selection is cleared.
|
||||
on_selection_cleared: EventHandler[lambda: []]
|
||||
on_selection_cleared: EventHandler[no_args_event_spec]
|
||||
|
||||
# Fired when a column is resized.
|
||||
on_column_resize: EventHandler[lambda col, width: [col, width]]
|
||||
on_column_resize: EventHandler[passthrough_event_spec(GridColumn, int)]
|
||||
|
||||
def add_imports(self) -> ImportDict:
|
||||
"""Add imports for the component.
|
||||
@ -279,7 +324,7 @@ class DataEditor(NoSSRComponent):
|
||||
return {
|
||||
"": f"{format.format_library_name(self.library)}/dist/index.css",
|
||||
self.library: "GridCellKind",
|
||||
"/utils/helpers/dataeditor.js": ImportVar(
|
||||
"$/utils/helpers/dataeditor.js": ImportVar(
|
||||
tag="formatDataEditorCells", is_default=False, install=False
|
||||
),
|
||||
}
|
||||
@ -329,7 +374,7 @@ class DataEditor(NoSSRComponent):
|
||||
|
||||
columns = props.get("columns", [])
|
||||
data = props.get("data", [])
|
||||
rows = props.get("rows", None)
|
||||
rows = props.get("rows")
|
||||
|
||||
# If rows is not provided, determine from data.
|
||||
if rows is None:
|
||||
@ -340,10 +385,8 @@ class DataEditor(NoSSRComponent):
|
||||
props["rows"] = data.length() if isinstance(data, Var) else len(data)
|
||||
|
||||
if not isinstance(columns, Var) and len(columns):
|
||||
if (
|
||||
types.is_dataframe(type(data))
|
||||
or isinstance(data, Var)
|
||||
and types.is_dataframe(data._var_type)
|
||||
if types.is_dataframe(type(data)) or (
|
||||
isinstance(data, Var) and types.is_dataframe(data._var_type)
|
||||
):
|
||||
raise ValueError(
|
||||
"Cannot pass in both a pandas dataframe and columns to the data_editor component."
|
||||
@ -359,7 +402,7 @@ class DataEditor(NoSSRComponent):
|
||||
props["theme"] = DataEditorTheme(**theme)
|
||||
|
||||
# Allow by default to select a region of cells in the grid.
|
||||
props.setdefault("get_cell_for_selection", True)
|
||||
props.setdefault("get_cells_for_selection", True)
|
||||
|
||||
# Disable on_paste by default if not provided.
|
||||
props.setdefault("on_paste", False)
|
||||
|
@ -4,11 +4,13 @@
|
||||
# This file was generated by `reflex/utils/pyi_generator.py`!
|
||||
# ------------------------------------------------------
|
||||
from enum import Enum
|
||||
from typing import Any, Callable, Dict, List, Literal, Optional, Union, overload
|
||||
from typing import Any, Dict, List, Literal, Optional, Union, overload
|
||||
|
||||
from typing_extensions import TypedDict
|
||||
|
||||
from reflex.base import Base
|
||||
from reflex.components.component import NoSSRComponent
|
||||
from reflex.event import EventHandler, EventSpec
|
||||
from reflex.event import BASE_STATE, EventType
|
||||
from reflex.style import Style
|
||||
from reflex.utils.imports import ImportDict
|
||||
from reflex.utils.serializers import serializer
|
||||
@ -76,7 +78,53 @@ class DataEditorTheme(Base):
|
||||
text_light: Optional[str]
|
||||
text_medium: Optional[str]
|
||||
|
||||
def on_edit_spec(pos, data: dict[str, Any]): ...
|
||||
class Bounds(TypedDict):
|
||||
x: int
|
||||
y: int
|
||||
width: int
|
||||
height: int
|
||||
|
||||
class CompatSelection(TypedDict):
|
||||
items: list
|
||||
|
||||
class Rectangle(TypedDict):
|
||||
x: int
|
||||
y: int
|
||||
width: int
|
||||
height: int
|
||||
|
||||
class GridSelectionCurrent(TypedDict):
|
||||
cell: tuple[int, int]
|
||||
range: Rectangle
|
||||
rangeStack: list[Rectangle]
|
||||
|
||||
class GridSelection(TypedDict):
|
||||
current: Optional[GridSelectionCurrent]
|
||||
columns: CompatSelection
|
||||
rows: CompatSelection
|
||||
|
||||
class GroupHeaderClickedEventArgs(TypedDict):
|
||||
kind: str
|
||||
group: str
|
||||
location: tuple[int, int]
|
||||
bounds: Bounds
|
||||
isEdge: bool
|
||||
shiftKey: bool
|
||||
ctrlKey: bool
|
||||
metaKey: bool
|
||||
isTouch: bool
|
||||
localEventX: int
|
||||
localEventY: int
|
||||
button: int
|
||||
buttons: int
|
||||
scrollEdge: tuple[int, int]
|
||||
|
||||
class GridCell(TypedDict):
|
||||
span: Optional[List[int]]
|
||||
|
||||
class GridColumn(TypedDict):
|
||||
title: str
|
||||
group: Optional[str]
|
||||
|
||||
class DataEditor(NoSSRComponent):
|
||||
def add_imports(self) -> ImportDict: ...
|
||||
@ -92,7 +140,7 @@ class DataEditor(NoSSRComponent):
|
||||
] = None,
|
||||
data: Optional[Union[List[List[Any]], Var[List[List[Any]]]]] = None,
|
||||
get_cell_content: Optional[Union[Var[str], str]] = None,
|
||||
get_cell_for_selection: Optional[Union[Var[bool], bool]] = None,
|
||||
get_cells_for_selection: Optional[Union[Var[bool], bool]] = None,
|
||||
on_paste: Optional[Union[Var[bool], bool]] = None,
|
||||
draw_focus_ring: Optional[Union[Var[bool], bool]] = None,
|
||||
fixed_shadow_x: Optional[Union[Var[bool], bool]] = None,
|
||||
@ -134,88 +182,94 @@ class DataEditor(NoSSRComponent):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_cell_activated: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
Union[EventType[[], BASE_STATE], EventType[[tuple[int, int]], BASE_STATE]]
|
||||
] = None,
|
||||
on_cell_clicked: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
Union[EventType[[], BASE_STATE], EventType[[tuple[int, int]], BASE_STATE]]
|
||||
] = None,
|
||||
on_cell_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
Union[EventType[[], BASE_STATE], EventType[[tuple[int, int]], BASE_STATE]]
|
||||
] = None,
|
||||
on_cell_edited: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
Union[
|
||||
EventType[[], BASE_STATE],
|
||||
EventType[[tuple[int, int]], BASE_STATE],
|
||||
EventType[[tuple[int, int], GridCell], BASE_STATE],
|
||||
]
|
||||
] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_column_resize: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
Union[
|
||||
EventType[[], BASE_STATE],
|
||||
EventType[[GridColumn], BASE_STATE],
|
||||
EventType[[GridColumn, int], BASE_STATE],
|
||||
]
|
||||
] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_delete: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_delete: Optional[
|
||||
Union[EventType[[], BASE_STATE], EventType[[GridSelection], BASE_STATE]]
|
||||
] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_finished_editing: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
Union[
|
||||
EventType[[], BASE_STATE],
|
||||
EventType[[Union[GridCell, None]], BASE_STATE],
|
||||
EventType[[Union[GridCell, None], tuple[int, int]], BASE_STATE],
|
||||
]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_group_header_clicked: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
Union[
|
||||
EventType[[], BASE_STATE],
|
||||
EventType[[tuple[int, int]], BASE_STATE],
|
||||
EventType[[tuple[int, int], GridCell], BASE_STATE],
|
||||
]
|
||||
] = None,
|
||||
on_group_header_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
Union[
|
||||
EventType[[], BASE_STATE],
|
||||
EventType[[int], BASE_STATE],
|
||||
EventType[[int, GroupHeaderClickedEventArgs], BASE_STATE],
|
||||
]
|
||||
] = None,
|
||||
on_group_header_renamed: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
Union[
|
||||
EventType[[], BASE_STATE],
|
||||
EventType[[str], BASE_STATE],
|
||||
EventType[[str, str], BASE_STATE],
|
||||
]
|
||||
] = None,
|
||||
on_header_clicked: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
Union[EventType[[], BASE_STATE], EventType[[tuple[int, int]], BASE_STATE]]
|
||||
] = None,
|
||||
on_header_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
Union[EventType[[], BASE_STATE], EventType[[tuple[int, int]], BASE_STATE]]
|
||||
] = None,
|
||||
on_header_menu_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
Union[
|
||||
EventType[[], BASE_STATE],
|
||||
EventType[[int], BASE_STATE],
|
||||
EventType[[int, Rectangle], BASE_STATE],
|
||||
]
|
||||
] = None,
|
||||
on_item_hovered: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_row_appended: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_selection_cleared: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
Union[EventType[[], BASE_STATE], EventType[[tuple[int, int]], BASE_STATE]]
|
||||
] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_row_appended: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_selection_cleared: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "DataEditor":
|
||||
"""Create the DataEditor component.
|
||||
@ -226,7 +280,7 @@ class DataEditor(NoSSRComponent):
|
||||
columns: Headers of the columns for the data grid.
|
||||
data: The data.
|
||||
get_cell_content: The name of the callback used to find the data to display.
|
||||
get_cell_for_selection: Allow selection for copying.
|
||||
get_cells_for_selection: Allow selection for copying.
|
||||
on_paste: Allow paste.
|
||||
draw_focus_ring: Controls the drawing of the focus ring.
|
||||
fixed_shadow_x: Enables or disables the overlay shadow when scrolling horizontally.
|
||||
@ -234,7 +288,7 @@ class DataEditor(NoSSRComponent):
|
||||
freeze_columns: The number of columns which should remain in place when scrolling horizontally. Doesn't include rowMarkers.
|
||||
group_header_height: Controls the header of the group header row.
|
||||
header_height: Controls the height of the header row.
|
||||
max_column_auto_width: Additional header icons: header_icons: Var[Any] # (TODO: must be a map of name: svg) The maximum width a column can be automatically sized to.
|
||||
max_column_auto_width: The maximum width a column can be automatically sized to.
|
||||
max_column_width: The maximum width a column can be resized to.
|
||||
min_column_width: The minimum width a column can be resized to.
|
||||
row_height: Determins the height of each row.
|
||||
@ -251,6 +305,22 @@ class DataEditor(NoSSRComponent):
|
||||
scroll_offset_x: Initial scroll offset on the horizontal axis.
|
||||
scroll_offset_y: Initial scroll offset on the vertical axis.
|
||||
theme: global theme
|
||||
on_cell_activated: Fired when a cell is activated.
|
||||
on_cell_clicked: Fired when a cell is clicked.
|
||||
on_cell_context_menu: Fired when a cell is right-clicked.
|
||||
on_cell_edited: Fired when a cell is edited.
|
||||
on_group_header_clicked: Fired when a group header is clicked.
|
||||
on_group_header_context_menu: Fired when a group header is right-clicked.
|
||||
on_group_header_renamed: Fired when a group header is renamed.
|
||||
on_header_clicked: Fired when a header is clicked.
|
||||
on_header_context_menu: Fired when a header is right-clicked.
|
||||
on_header_menu_click: Fired when a header menu item is clicked.
|
||||
on_item_hovered: Fired when an item is hovered.
|
||||
on_delete: Fired when a selection is deleted.
|
||||
on_finished_editing: Fired when editing is finished.
|
||||
on_row_appended: Fired when a row is appended.
|
||||
on_selection_cleared: Fired when the selection is cleared.
|
||||
on_column_resize: Fired when a column is resized.
|
||||
style: The style of the component.
|
||||
key: A unique key for the component.
|
||||
id: The id for the component.
|
||||
|
@ -1,22 +1,23 @@
|
||||
"""A Reflex logo component."""
|
||||
|
||||
from typing import Union
|
||||
|
||||
import reflex as rx
|
||||
|
||||
|
||||
def logo(**props):
|
||||
"""A Reflex logo.
|
||||
def svg_logo(color: Union[str, rx.Var[str]] = rx.color_mode_cond("#110F1F", "white")):
|
||||
"""A Reflex logo SVG.
|
||||
|
||||
Args:
|
||||
**props: The props to pass to the component.
|
||||
color: The color of the logo.
|
||||
|
||||
Returns:
|
||||
The logo component.
|
||||
The Reflex logo SVG.
|
||||
"""
|
||||
|
||||
def logo_path(d):
|
||||
return rx.el.svg.path(
|
||||
d=d,
|
||||
fill=rx.color_mode_cond("#110F1F", "white"),
|
||||
)
|
||||
|
||||
paths = [
|
||||
@ -28,18 +29,30 @@ def logo(**props):
|
||||
"M47.04 4.8799V0.399902H49.28V4.8799H47.04ZM53.76 4.8799V0.399902H56V4.8799H53.76ZM49.28 7.1199V4.8799H53.76V7.1199H49.28ZM47.04 11.5999V7.1199H49.28V11.5999H47.04ZM53.76 11.5999V7.1199H56V11.5999H53.76Z",
|
||||
]
|
||||
|
||||
return rx.el.svg(
|
||||
*[logo_path(d) for d in paths],
|
||||
width="56",
|
||||
height="12",
|
||||
viewBox="0 0 56 12",
|
||||
fill=color,
|
||||
xmlns="http://www.w3.org/2000/svg",
|
||||
)
|
||||
|
||||
|
||||
def logo(**props):
|
||||
"""A Reflex logo.
|
||||
|
||||
Args:
|
||||
**props: The props to pass to the component.
|
||||
|
||||
Returns:
|
||||
The logo component.
|
||||
"""
|
||||
return rx.center(
|
||||
rx.link(
|
||||
rx.hstack(
|
||||
"Built with ",
|
||||
rx.el.svg(
|
||||
*[logo_path(d) for d in paths],
|
||||
width="56",
|
||||
height="12",
|
||||
viewBox="0 0 56 12",
|
||||
fill="none",
|
||||
xmlns="http://www.w3.org/2000/svg",
|
||||
),
|
||||
svg_logo(),
|
||||
text_align="center",
|
||||
align="center",
|
||||
padding="1em",
|
||||
|
846
reflex/components/datadisplay/shiki_code_block.py
Normal file
846
reflex/components/datadisplay/shiki_code_block.py
Normal file
@ -0,0 +1,846 @@
|
||||
"""Shiki syntax hghlighter component."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from collections import defaultdict
|
||||
from typing import Any, Literal, Optional, Union
|
||||
|
||||
from reflex.base import Base
|
||||
from reflex.components.component import Component, ComponentNamespace
|
||||
from reflex.components.core.colors import color
|
||||
from reflex.components.core.cond import color_mode_cond
|
||||
from reflex.components.el.elements.forms import Button
|
||||
from reflex.components.lucide.icon import Icon
|
||||
from reflex.components.markdown.markdown import MarkdownComponentMap
|
||||
from reflex.components.props import NoExtrasAllowedProps
|
||||
from reflex.components.radix.themes.layout.box import Box
|
||||
from reflex.event import run_script, set_clipboard
|
||||
from reflex.style import Style
|
||||
from reflex.utils.exceptions import VarTypeError
|
||||
from reflex.utils.imports import ImportVar
|
||||
from reflex.vars.base import LiteralVar, Var
|
||||
from reflex.vars.function import FunctionStringVar
|
||||
from reflex.vars.sequence import StringVar, string_replace_operation
|
||||
|
||||
|
||||
def copy_script() -> Any:
|
||||
"""Copy script for the code block and modify the child SVG element.
|
||||
|
||||
Returns:
|
||||
Any: The result of calling the script.
|
||||
"""
|
||||
return run_script(
|
||||
"""
|
||||
// Event listener for the parent click
|
||||
document.addEventListener('click', function(event) {
|
||||
// Find the closest button (parent element)
|
||||
const parent = event.target.closest('button');
|
||||
// If the parent is found
|
||||
if (parent) {
|
||||
// Find the SVG element within the parent
|
||||
const svgIcon = parent.querySelector('svg');
|
||||
// If the SVG exists, proceed with the script
|
||||
if (svgIcon) {
|
||||
const originalPath = svgIcon.innerHTML;
|
||||
const checkmarkPath = '<polyline points="20 6 9 17 4 12"></polyline>'; // Checkmark SVG path
|
||||
function transition(element, scale, opacity) {
|
||||
element.style.transform = `scale(${scale})`;
|
||||
element.style.opacity = opacity;
|
||||
}
|
||||
// Animate the SVG
|
||||
transition(svgIcon, 0, '0');
|
||||
setTimeout(() => {
|
||||
svgIcon.innerHTML = checkmarkPath; // Replace content with checkmark
|
||||
svgIcon.setAttribute('viewBox', '0 0 24 24'); // Adjust viewBox if necessary
|
||||
transition(svgIcon, 1, '1');
|
||||
setTimeout(() => {
|
||||
transition(svgIcon, 0, '0');
|
||||
setTimeout(() => {
|
||||
svgIcon.innerHTML = originalPath; // Restore original SVG content
|
||||
transition(svgIcon, 1, '1');
|
||||
}, 125);
|
||||
}, 600);
|
||||
}, 125);
|
||||
} else {
|
||||
// console.error('SVG element not found within the parent.');
|
||||
}
|
||||
} else {
|
||||
// console.error('Parent element not found.');
|
||||
}
|
||||
})
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
SHIKIJS_TRANSFORMER_FNS = {
|
||||
"transformerNotationDiff",
|
||||
"transformerNotationHighlight",
|
||||
"transformerNotationWordHighlight",
|
||||
"transformerNotationFocus",
|
||||
"transformerNotationErrorLevel",
|
||||
"transformerRenderWhitespace",
|
||||
"transformerMetaHighlight",
|
||||
"transformerMetaWordHighlight",
|
||||
"transformerCompactLineOptions",
|
||||
# TODO: this transformer when included adds a weird behavior which removes other code lines. Need to figure out why.
|
||||
# "transformerRemoveLineBreak",
|
||||
"transformerRemoveNotationEscape",
|
||||
}
|
||||
LINE_NUMBER_STYLING = {
|
||||
"code": {
|
||||
"counter-reset": "step",
|
||||
"counter-increment": "step 0",
|
||||
"display": "grid",
|
||||
"line-height": "1.7",
|
||||
"font-size": "0.875em",
|
||||
},
|
||||
"code .line::before": {
|
||||
"content": "counter(step)",
|
||||
"counter-increment": "step",
|
||||
"width": "1rem",
|
||||
"margin-right": "1.5rem",
|
||||
"display": "inline-block",
|
||||
"text-align": "right",
|
||||
"color": "rgba(115,138,148,.4)",
|
||||
},
|
||||
}
|
||||
BOX_PARENT_STYLING = {
|
||||
"pre": {
|
||||
"margin": "0",
|
||||
"padding": "24px",
|
||||
"background": "transparent",
|
||||
"overflow-x": "auto",
|
||||
"border-radius": "6px",
|
||||
},
|
||||
}
|
||||
|
||||
THEME_MAPPING = {
|
||||
"light": "one-light",
|
||||
"dark": "one-dark-pro",
|
||||
"a11y-dark": "github-dark",
|
||||
}
|
||||
LANGUAGE_MAPPING = {"bash": "shellscript"}
|
||||
LiteralCodeLanguage = Literal[
|
||||
"abap",
|
||||
"actionscript-3",
|
||||
"ada",
|
||||
"angular-html",
|
||||
"angular-ts",
|
||||
"apache",
|
||||
"apex",
|
||||
"apl",
|
||||
"applescript",
|
||||
"ara",
|
||||
"asciidoc",
|
||||
"asm",
|
||||
"astro",
|
||||
"awk",
|
||||
"ballerina",
|
||||
"bat",
|
||||
"beancount",
|
||||
"berry",
|
||||
"bibtex",
|
||||
"bicep",
|
||||
"blade",
|
||||
"c",
|
||||
"cadence",
|
||||
"clarity",
|
||||
"clojure",
|
||||
"cmake",
|
||||
"cobol",
|
||||
"codeowners",
|
||||
"codeql",
|
||||
"coffee",
|
||||
"common-lisp",
|
||||
"coq",
|
||||
"cpp",
|
||||
"crystal",
|
||||
"csharp",
|
||||
"css",
|
||||
"csv",
|
||||
"cue",
|
||||
"cypher",
|
||||
"d",
|
||||
"dart",
|
||||
"dax",
|
||||
"desktop",
|
||||
"diff",
|
||||
"docker",
|
||||
"dotenv",
|
||||
"dream-maker",
|
||||
"edge",
|
||||
"elixir",
|
||||
"elm",
|
||||
"emacs-lisp",
|
||||
"erb",
|
||||
"erlang",
|
||||
"fennel",
|
||||
"fish",
|
||||
"fluent",
|
||||
"fortran-fixed-form",
|
||||
"fortran-free-form",
|
||||
"fsharp",
|
||||
"gdresource",
|
||||
"gdscript",
|
||||
"gdshader",
|
||||
"genie",
|
||||
"gherkin",
|
||||
"git-commit",
|
||||
"git-rebase",
|
||||
"gleam",
|
||||
"glimmer-js",
|
||||
"glimmer-ts",
|
||||
"glsl",
|
||||
"gnuplot",
|
||||
"go",
|
||||
"graphql",
|
||||
"groovy",
|
||||
"hack",
|
||||
"haml",
|
||||
"handlebars",
|
||||
"haskell",
|
||||
"haxe",
|
||||
"hcl",
|
||||
"hjson",
|
||||
"hlsl",
|
||||
"html",
|
||||
"html-derivative",
|
||||
"http",
|
||||
"hxml",
|
||||
"hy",
|
||||
"imba",
|
||||
"ini",
|
||||
"java",
|
||||
"javascript",
|
||||
"jinja",
|
||||
"jison",
|
||||
"json",
|
||||
"json5",
|
||||
"jsonc",
|
||||
"jsonl",
|
||||
"jsonnet",
|
||||
"jssm",
|
||||
"jsx",
|
||||
"julia",
|
||||
"kotlin",
|
||||
"kusto",
|
||||
"latex",
|
||||
"lean",
|
||||
"less",
|
||||
"liquid",
|
||||
"log",
|
||||
"logo",
|
||||
"lua",
|
||||
"luau",
|
||||
"make",
|
||||
"markdown",
|
||||
"marko",
|
||||
"matlab",
|
||||
"mdc",
|
||||
"mdx",
|
||||
"mermaid",
|
||||
"mojo",
|
||||
"move",
|
||||
"narrat",
|
||||
"nextflow",
|
||||
"nginx",
|
||||
"nim",
|
||||
"nix",
|
||||
"nushell",
|
||||
"objective-c",
|
||||
"objective-cpp",
|
||||
"ocaml",
|
||||
"pascal",
|
||||
"perl",
|
||||
"php",
|
||||
"plain",
|
||||
"plsql",
|
||||
"po",
|
||||
"postcss",
|
||||
"powerquery",
|
||||
"powershell",
|
||||
"prisma",
|
||||
"prolog",
|
||||
"proto",
|
||||
"pug",
|
||||
"puppet",
|
||||
"purescript",
|
||||
"python",
|
||||
"qml",
|
||||
"qmldir",
|
||||
"qss",
|
||||
"r",
|
||||
"racket",
|
||||
"raku",
|
||||
"razor",
|
||||
"reg",
|
||||
"regexp",
|
||||
"rel",
|
||||
"riscv",
|
||||
"rst",
|
||||
"ruby",
|
||||
"rust",
|
||||
"sas",
|
||||
"sass",
|
||||
"scala",
|
||||
"scheme",
|
||||
"scss",
|
||||
"shaderlab",
|
||||
"shellscript",
|
||||
"shellsession",
|
||||
"smalltalk",
|
||||
"solidity",
|
||||
"soy",
|
||||
"sparql",
|
||||
"splunk",
|
||||
"sql",
|
||||
"ssh-config",
|
||||
"stata",
|
||||
"stylus",
|
||||
"svelte",
|
||||
"swift",
|
||||
"system-verilog",
|
||||
"systemd",
|
||||
"tasl",
|
||||
"tcl",
|
||||
"templ",
|
||||
"terraform",
|
||||
"tex",
|
||||
"toml",
|
||||
"ts-tags",
|
||||
"tsv",
|
||||
"tsx",
|
||||
"turtle",
|
||||
"twig",
|
||||
"typescript",
|
||||
"typespec",
|
||||
"typst",
|
||||
"v",
|
||||
"vala",
|
||||
"vb",
|
||||
"verilog",
|
||||
"vhdl",
|
||||
"viml",
|
||||
"vue",
|
||||
"vue-html",
|
||||
"vyper",
|
||||
"wasm",
|
||||
"wenyan",
|
||||
"wgsl",
|
||||
"wikitext",
|
||||
"wolfram",
|
||||
"xml",
|
||||
"xsl",
|
||||
"yaml",
|
||||
"zenscript",
|
||||
"zig",
|
||||
]
|
||||
LiteralCodeTheme = Literal[
|
||||
"andromeeda",
|
||||
"aurora-x",
|
||||
"ayu-dark",
|
||||
"catppuccin-frappe",
|
||||
"catppuccin-latte",
|
||||
"catppuccin-macchiato",
|
||||
"catppuccin-mocha",
|
||||
"dark-plus",
|
||||
"dracula",
|
||||
"dracula-soft",
|
||||
"everforest-dark",
|
||||
"everforest-light",
|
||||
"github-dark",
|
||||
"github-dark-default",
|
||||
"github-dark-dimmed",
|
||||
"github-dark-high-contrast",
|
||||
"github-light",
|
||||
"github-light-default",
|
||||
"github-light-high-contrast",
|
||||
"houston",
|
||||
"laserwave",
|
||||
"light-plus",
|
||||
"material-theme",
|
||||
"material-theme-darker",
|
||||
"material-theme-lighter",
|
||||
"material-theme-ocean",
|
||||
"material-theme-palenight",
|
||||
"min-dark",
|
||||
"min-light",
|
||||
"monokai",
|
||||
"night-owl",
|
||||
"nord",
|
||||
"one-dark-pro",
|
||||
"one-light",
|
||||
"plastic",
|
||||
"poimandres",
|
||||
"red",
|
||||
# rose-pine themes dont work with the current version of shikijs transformers
|
||||
# https://github.com/shikijs/shiki/issues/730
|
||||
"rose-pine",
|
||||
"rose-pine-dawn",
|
||||
"rose-pine-moon",
|
||||
"slack-dark",
|
||||
"slack-ochin",
|
||||
"snazzy-light",
|
||||
"solarized-dark",
|
||||
"solarized-light",
|
||||
"synthwave-84",
|
||||
"tokyo-night",
|
||||
"vesper",
|
||||
"vitesse-black",
|
||||
"vitesse-dark",
|
||||
"vitesse-light",
|
||||
]
|
||||
|
||||
|
||||
class Position(NoExtrasAllowedProps):
|
||||
"""Position of the decoration."""
|
||||
|
||||
line: int
|
||||
character: int
|
||||
|
||||
|
||||
class ShikiDecorations(NoExtrasAllowedProps):
|
||||
"""Decorations for the code block."""
|
||||
|
||||
start: Union[int, Position]
|
||||
end: Union[int, Position]
|
||||
tag_name: str = "span"
|
||||
properties: dict[str, Any] = {}
|
||||
always_wrap: bool = False
|
||||
|
||||
|
||||
class ShikiBaseTransformers(Base):
|
||||
"""Base for creating transformers."""
|
||||
|
||||
library: str
|
||||
fns: list[FunctionStringVar]
|
||||
style: Optional[Style]
|
||||
|
||||
|
||||
class ShikiJsTransformer(ShikiBaseTransformers):
|
||||
"""A Wrapped shikijs transformer."""
|
||||
|
||||
library: str = "@shikijs/transformers"
|
||||
fns: list[FunctionStringVar] = [
|
||||
FunctionStringVar.create(fn) for fn in SHIKIJS_TRANSFORMER_FNS
|
||||
]
|
||||
style: Optional[Style] = Style(
|
||||
{
|
||||
"code": {"line-height": "1.7", "font-size": "0.875em", "display": "grid"},
|
||||
# Diffs
|
||||
".diff": {
|
||||
"margin": "0 -24px",
|
||||
"padding": "0 24px",
|
||||
"width": "calc(100% + 48px)",
|
||||
"display": "inline-block",
|
||||
},
|
||||
".diff.add": {
|
||||
"background-color": "rgba(16, 185, 129, .14)",
|
||||
"position": "relative",
|
||||
},
|
||||
".diff.remove": {
|
||||
"background-color": "rgba(244, 63, 94, .14)",
|
||||
"opacity": "0.7",
|
||||
"position": "relative",
|
||||
},
|
||||
".diff.remove:after": {
|
||||
"position": "absolute",
|
||||
"left": "10px",
|
||||
"content": "'-'",
|
||||
"color": "#b34e52",
|
||||
},
|
||||
".diff.add:after": {
|
||||
"position": "absolute",
|
||||
"left": "10px",
|
||||
"content": "'+'",
|
||||
"color": "#18794e",
|
||||
},
|
||||
# Highlight
|
||||
".highlighted": {
|
||||
"background-color": "rgba(142, 150, 170, .14)",
|
||||
"margin": "0 -24px",
|
||||
"padding": "0 24px",
|
||||
"width": "calc(100% + 48px)",
|
||||
"display": "inline-block",
|
||||
},
|
||||
".highlighted.error": {
|
||||
"background-color": "rgba(244, 63, 94, .14)",
|
||||
},
|
||||
".highlighted.warning": {
|
||||
"background-color": "rgba(234, 179, 8, .14)",
|
||||
},
|
||||
# Highlighted Word
|
||||
".highlighted-word": {
|
||||
"background-color": color("gray", 2),
|
||||
"border": f"1px solid {color('gray', 5)}",
|
||||
"padding": "1px 3px",
|
||||
"margin": "-1px -3px",
|
||||
"border-radius": "4px",
|
||||
},
|
||||
# Focused Lines
|
||||
".has-focused .line:not(.focused)": {
|
||||
"opacity": "0.7",
|
||||
"filter": "blur(0.095rem)",
|
||||
"transition": "filter .35s, opacity .35s",
|
||||
},
|
||||
".has-focused:hover .line:not(.focused)": {
|
||||
"opacity": "1",
|
||||
"filter": "none",
|
||||
},
|
||||
# White Space
|
||||
# ".tab, .space": {
|
||||
# "position": "relative", # noqa: ERA001
|
||||
# },
|
||||
# ".tab::before": {
|
||||
# "content": "'⇥'", # noqa: ERA001
|
||||
# "position": "absolute", # noqa: ERA001
|
||||
# "opacity": "0.3",# noqa: ERA001
|
||||
# },
|
||||
# ".space::before": {
|
||||
# "content": "'·'", # noqa: ERA001
|
||||
# "position": "absolute", # noqa: ERA001
|
||||
# "opacity": "0.3", # noqa: ERA001
|
||||
# },
|
||||
}
|
||||
)
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
"""Initialize the transformer.
|
||||
|
||||
Args:
|
||||
kwargs: Kwargs to initialize the props.
|
||||
|
||||
"""
|
||||
fns = kwargs.pop("fns", None)
|
||||
style = kwargs.pop("style", None)
|
||||
if fns:
|
||||
kwargs["fns"] = [
|
||||
(
|
||||
FunctionStringVar.create(x)
|
||||
if not isinstance(x, FunctionStringVar)
|
||||
else x
|
||||
)
|
||||
for x in fns
|
||||
]
|
||||
|
||||
if style:
|
||||
kwargs["style"] = Style(style)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
|
||||
class ShikiCodeBlock(Component, MarkdownComponentMap):
|
||||
"""A Code block."""
|
||||
|
||||
library = "/components/shiki/code"
|
||||
|
||||
tag = "Code"
|
||||
|
||||
alias = "ShikiCode"
|
||||
|
||||
lib_dependencies: list[str] = ["shiki"]
|
||||
|
||||
# The language to use.
|
||||
language: Var[LiteralCodeLanguage] = Var.create("python")
|
||||
|
||||
# The theme to use ("light" or "dark").
|
||||
theme: Var[LiteralCodeTheme] = Var.create("one-light")
|
||||
|
||||
# The set of themes to use for different modes.
|
||||
themes: Var[Union[list[dict[str, Any]], dict[str, str]]]
|
||||
|
||||
# The code to display.
|
||||
code: Var[str]
|
||||
|
||||
# The transformers to use for the syntax highlighter.
|
||||
transformers: Var[list[Union[ShikiBaseTransformers, dict[str, Any]]]] = Var.create(
|
||||
[]
|
||||
)
|
||||
|
||||
# The decorations to use for the syntax highlighter.
|
||||
decorations: Var[list[ShikiDecorations]] = Var.create([])
|
||||
|
||||
@classmethod
|
||||
def create(
|
||||
cls,
|
||||
*children,
|
||||
**props,
|
||||
) -> Component:
|
||||
"""Create a code block component using [shiki syntax highlighter](https://shiki.matsu.io/).
|
||||
|
||||
Args:
|
||||
*children: The children of the component.
|
||||
**props: The props to pass to the component.
|
||||
|
||||
Returns:
|
||||
The code block component.
|
||||
"""
|
||||
# Separate props for the code block and the wrapper
|
||||
code_block_props = {}
|
||||
code_wrapper_props = {}
|
||||
decorations = props.pop("decorations", [])
|
||||
|
||||
class_props = cls.get_props()
|
||||
|
||||
# Distribute props between the code block and wrapper
|
||||
for key, value in props.items():
|
||||
(code_block_props if key in class_props else code_wrapper_props)[key] = (
|
||||
value
|
||||
)
|
||||
|
||||
# cast decorations into ShikiDecorations.
|
||||
decorations = [
|
||||
ShikiDecorations(**decoration)
|
||||
if not isinstance(decoration, ShikiDecorations)
|
||||
else decoration
|
||||
for decoration in decorations
|
||||
]
|
||||
code_block_props["decorations"] = decorations
|
||||
|
||||
code_block_props["code"] = children[0]
|
||||
code_block = super().create(**code_block_props)
|
||||
|
||||
transformer_styles = {}
|
||||
# Collect styles from transformers and wrapper
|
||||
for transformer in code_block.transformers._var_value: # type: ignore
|
||||
if isinstance(transformer, ShikiBaseTransformers) and transformer.style:
|
||||
transformer_styles.update(transformer.style)
|
||||
transformer_styles.update(code_wrapper_props.pop("style", {}))
|
||||
|
||||
return Box.create(
|
||||
code_block,
|
||||
*children[1:],
|
||||
style=Style({**transformer_styles, **BOX_PARENT_STYLING}),
|
||||
**code_wrapper_props,
|
||||
)
|
||||
|
||||
def add_imports(self) -> dict[str, list[str]]:
|
||||
"""Add the necessary imports.
|
||||
We add all referenced transformer functions as imports from their corresponding
|
||||
libraries.
|
||||
|
||||
Returns:
|
||||
Imports for the component.
|
||||
"""
|
||||
imports = defaultdict(list)
|
||||
for transformer in self.transformers._var_value:
|
||||
if isinstance(transformer, ShikiBaseTransformers):
|
||||
imports[transformer.library].extend(
|
||||
[ImportVar(tag=str(fn)) for fn in transformer.fns]
|
||||
)
|
||||
(
|
||||
self.lib_dependencies.append(transformer.library)
|
||||
if transformer.library not in self.lib_dependencies
|
||||
else None
|
||||
)
|
||||
return imports
|
||||
|
||||
@classmethod
|
||||
def create_transformer(cls, library: str, fns: list[str]) -> ShikiBaseTransformers:
|
||||
"""Create a transformer from a third party library.
|
||||
|
||||
Args:
|
||||
library: The name of the library.
|
||||
fns: The str names of the functions/callables to invoke from the library.
|
||||
|
||||
Returns:
|
||||
A transformer for the specified library.
|
||||
|
||||
Raises:
|
||||
ValueError: If a supplied function name is not valid str.
|
||||
"""
|
||||
if any(not isinstance(fn_name, str) for fn_name in fns):
|
||||
raise ValueError(
|
||||
f"the function names should be str names of functions in the specified transformer: {library!r}"
|
||||
)
|
||||
return ShikiBaseTransformers( # type: ignore
|
||||
library=library, fns=[FunctionStringVar.create(fn) for fn in fns]
|
||||
)
|
||||
|
||||
def _render(self, props: dict[str, Any] | None = None):
|
||||
"""Renders the component with the given properties, processing transformers if present.
|
||||
|
||||
Args:
|
||||
props: Optional properties to pass to the render function.
|
||||
|
||||
Returns:
|
||||
Rendered component output.
|
||||
"""
|
||||
# Ensure props is initialized from class attributes if not provided
|
||||
props = props or {
|
||||
attr.rstrip("_"): getattr(self, attr) for attr in self.get_props()
|
||||
}
|
||||
|
||||
# Extract transformers and apply transformations
|
||||
transformers = props.get("transformers")
|
||||
if transformers is not None:
|
||||
transformed_values = self._process_transformers(transformers._var_value)
|
||||
props["transformers"] = LiteralVar.create(transformed_values)
|
||||
|
||||
return super()._render(props)
|
||||
|
||||
def _process_transformers(self, transformer_list: list) -> list:
|
||||
"""Processes a list of transformers, applying transformations where necessary.
|
||||
|
||||
Args:
|
||||
transformer_list: List of transformer objects or values.
|
||||
|
||||
Returns:
|
||||
list: A list of transformed values.
|
||||
"""
|
||||
processed = []
|
||||
|
||||
for transformer in transformer_list:
|
||||
if isinstance(transformer, ShikiBaseTransformers):
|
||||
processed.extend(fn.call() for fn in transformer.fns)
|
||||
else:
|
||||
processed.append(transformer)
|
||||
|
||||
return processed
|
||||
|
||||
|
||||
class ShikiHighLevelCodeBlock(ShikiCodeBlock):
|
||||
"""High level component for the shiki syntax highlighter."""
|
||||
|
||||
# If this is enabled, the default transformers(shikijs transformer) will be used.
|
||||
use_transformers: Var[bool]
|
||||
|
||||
# If this is enabled line numbers will be shown next to the code block.
|
||||
show_line_numbers: Var[bool]
|
||||
|
||||
# Whether a copy button should appear.
|
||||
can_copy: bool = False
|
||||
|
||||
# copy_button: A custom copy button to override the default one.
|
||||
copy_button: Optional[Union[Component, bool]] = None
|
||||
|
||||
@classmethod
|
||||
def create(
|
||||
cls,
|
||||
*children,
|
||||
**props,
|
||||
) -> Component:
|
||||
"""Create a code block component using [shiki syntax highlighter](https://shiki.matsu.io/).
|
||||
|
||||
Args:
|
||||
*children: The children of the component.
|
||||
**props: The props to pass to the component.
|
||||
|
||||
Returns:
|
||||
The code block component.
|
||||
"""
|
||||
use_transformers = props.pop("use_transformers", False)
|
||||
show_line_numbers = props.pop("show_line_numbers", False)
|
||||
language = props.pop("language", None)
|
||||
can_copy = props.pop("can_copy", False)
|
||||
copy_button = props.pop("copy_button", None)
|
||||
|
||||
if use_transformers:
|
||||
props["transformers"] = [ShikiJsTransformer()]
|
||||
|
||||
if language is not None:
|
||||
props["language"] = cls._map_languages(language)
|
||||
|
||||
# line numbers are generated via css
|
||||
if show_line_numbers:
|
||||
props["style"] = {**LINE_NUMBER_STYLING, **props.get("style", {})}
|
||||
|
||||
theme = props.pop("theme", None)
|
||||
props["theme"] = props["theme"] = (
|
||||
cls._map_themes(theme)
|
||||
if theme is not None
|
||||
else color_mode_cond( # Default color scheme responds to global color mode.
|
||||
light="one-light",
|
||||
dark="one-dark-pro",
|
||||
)
|
||||
)
|
||||
|
||||
if can_copy:
|
||||
code = children[0]
|
||||
copy_button = ( # type: ignore
|
||||
copy_button
|
||||
if copy_button is not None
|
||||
else Button.create(
|
||||
Icon.create(tag="copy", size=16, color=color("gray", 11)),
|
||||
on_click=[
|
||||
set_clipboard(cls._strip_transformer_triggers(code)), # type: ignore
|
||||
copy_script(),
|
||||
],
|
||||
style=Style(
|
||||
{
|
||||
"position": "absolute",
|
||||
"top": "4px",
|
||||
"right": "4px",
|
||||
"background": color("gray", 3),
|
||||
"border": "1px solid",
|
||||
"border-color": color("gray", 5),
|
||||
"border-radius": "6px",
|
||||
"padding": "5px",
|
||||
"opacity": "1",
|
||||
"cursor": "pointer",
|
||||
"_hover": {
|
||||
"background": color("gray", 4),
|
||||
},
|
||||
"transition": "background 0.250s ease-out",
|
||||
"&>svg": {
|
||||
"transition": "transform 0.250s ease-out, opacity 0.250s ease-out",
|
||||
},
|
||||
"_active": {
|
||||
"background": color("gray", 5),
|
||||
},
|
||||
}
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
if copy_button:
|
||||
return ShikiCodeBlock.create(
|
||||
children[0], copy_button, position="relative", **props
|
||||
)
|
||||
else:
|
||||
return ShikiCodeBlock.create(children[0], **props)
|
||||
|
||||
@staticmethod
|
||||
def _map_themes(theme: str) -> str:
|
||||
if isinstance(theme, str) and theme in THEME_MAPPING:
|
||||
return THEME_MAPPING[theme]
|
||||
return theme
|
||||
|
||||
@staticmethod
|
||||
def _map_languages(language: str) -> str:
|
||||
if isinstance(language, str) and language in LANGUAGE_MAPPING:
|
||||
return LANGUAGE_MAPPING[language]
|
||||
return language
|
||||
|
||||
@staticmethod
|
||||
def _strip_transformer_triggers(code: str | StringVar) -> StringVar | str:
|
||||
if not isinstance(code, (StringVar, str)):
|
||||
raise VarTypeError(
|
||||
f"code should be string literal or a StringVar type. Got {type(code)} instead."
|
||||
)
|
||||
regex_pattern = r"[\/#]+ *\[!code.*?\]"
|
||||
|
||||
if isinstance(code, Var):
|
||||
return string_replace_operation(
|
||||
code, StringVar(_js_expr=f"/{regex_pattern}/g", _var_type=str), ""
|
||||
)
|
||||
if isinstance(code, str):
|
||||
return re.sub(regex_pattern, "", code)
|
||||
|
||||
|
||||
class TransformerNamespace(ComponentNamespace):
|
||||
"""Namespace for the Transformers."""
|
||||
|
||||
shikijs = ShikiJsTransformer
|
||||
|
||||
|
||||
class CodeblockNamespace(ComponentNamespace):
|
||||
"""Namespace for the CodeBlock component."""
|
||||
|
||||
root = staticmethod(ShikiCodeBlock.create)
|
||||
create_transformer = staticmethod(ShikiCodeBlock.create_transformer)
|
||||
transformers = TransformerNamespace()
|
||||
__call__ = staticmethod(ShikiHighLevelCodeBlock.create)
|
||||
|
||||
|
||||
code_block = CodeblockNamespace()
|
2232
reflex/components/datadisplay/shiki_code_block.pyi
Normal file
2232
reflex/components/datadisplay/shiki_code_block.pyi
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,11 +1,18 @@
|
||||
"""Components that are dynamically generated on the backend."""
|
||||
|
||||
from typing import TYPE_CHECKING, Union
|
||||
|
||||
from reflex import constants
|
||||
from reflex.utils import imports
|
||||
from reflex.utils.exceptions import DynamicComponentMissingLibrary
|
||||
from reflex.utils.format import format_library_name
|
||||
from reflex.utils.serializers import serializer
|
||||
from reflex.vars import Var, get_unique_variable_name
|
||||
from reflex.vars.base import VarData, transform
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from reflex.components.component import Component
|
||||
|
||||
|
||||
def get_cdn_url(lib: str) -> str:
|
||||
"""Get the CDN URL for a library.
|
||||
@ -19,6 +26,26 @@ def get_cdn_url(lib: str) -> str:
|
||||
return f"https://cdn.jsdelivr.net/npm/{lib}" + "/+esm"
|
||||
|
||||
|
||||
bundled_libraries = {"react", "@radix-ui/themes", "@emotion/react", "next/link"}
|
||||
|
||||
|
||||
def bundle_library(component: Union["Component", str]):
|
||||
"""Bundle a library with the component.
|
||||
|
||||
Args:
|
||||
component: The component to bundle the library with.
|
||||
|
||||
Raises:
|
||||
DynamicComponentMissingLibrary: Raised when a dynamic component is missing a library.
|
||||
"""
|
||||
if isinstance(component, str):
|
||||
bundled_libraries.add(component)
|
||||
return
|
||||
if component.library is None:
|
||||
raise DynamicComponentMissingLibrary("Component must have a library to bundle.")
|
||||
bundled_libraries.add(format_library_name(component.library))
|
||||
|
||||
|
||||
def load_dynamic_serializer():
|
||||
"""Load the serializer for dynamic components."""
|
||||
# Causes a circular import, so we import here.
|
||||
@ -36,6 +63,9 @@ def load_dynamic_serializer():
|
||||
"""
|
||||
# Causes a circular import, so we import here.
|
||||
from reflex.compiler import templates, utils
|
||||
from reflex.components.base.bare import Bare
|
||||
|
||||
component = Bare.create(Var.create(component))
|
||||
|
||||
rendered_components = {}
|
||||
# Include dynamic imports in the shared component.
|
||||
@ -57,20 +87,15 @@ def load_dynamic_serializer():
|
||||
)
|
||||
] = None
|
||||
|
||||
libs_in_window = [
|
||||
"react",
|
||||
"@radix-ui/themes",
|
||||
]
|
||||
libs_in_window = bundled_libraries
|
||||
|
||||
imports = {}
|
||||
for lib, names in component._get_all_imports().items():
|
||||
formatted_lib_name = format_library_name(lib)
|
||||
if (
|
||||
not lib.startswith((".", "/"))
|
||||
not lib.startswith((".", "/", "$/"))
|
||||
and not lib.startswith("http")
|
||||
and all(
|
||||
not lib.startswith(lib_in_window)
|
||||
for lib_in_window in libs_in_window
|
||||
)
|
||||
and formatted_lib_name not in libs_in_window
|
||||
):
|
||||
imports[get_cdn_url(lib)] = names
|
||||
else:
|
||||
@ -84,11 +109,11 @@ def load_dynamic_serializer():
|
||||
# Rewrite imports from `/` to destructure from window
|
||||
for ix, line in enumerate(module_code_lines[:]):
|
||||
if line.startswith("import "):
|
||||
if 'from "/' in line:
|
||||
if 'from "$/' in line or 'from "/' in line:
|
||||
module_code_lines[ix] = (
|
||||
line.replace("import ", "const ", 1).replace(
|
||||
" from ", " = window['__reflex'][", 1
|
||||
)
|
||||
line.replace("import ", "const ", 1)
|
||||
.replace(" as ", ": ")
|
||||
.replace(" from ", " = window['__reflex'][", 1)
|
||||
+ "]"
|
||||
)
|
||||
else:
|
||||
@ -105,10 +130,18 @@ def load_dynamic_serializer():
|
||||
module_code_lines[ix] = line.replace(
|
||||
"export function", "export default function", 1
|
||||
)
|
||||
line_stripped = line.strip()
|
||||
if line_stripped.startswith("{") and line_stripped.endswith("}"):
|
||||
module_code_lines[ix] = line_stripped[1:-1]
|
||||
|
||||
module_code_lines.insert(0, "const React = window.__reflex.react;")
|
||||
|
||||
return "//__reflex_evaluate\n" + "\n".join(module_code_lines)
|
||||
return "\n".join(
|
||||
[
|
||||
"//__reflex_evaluate",
|
||||
*module_code_lines,
|
||||
]
|
||||
)
|
||||
|
||||
@transform
|
||||
def evaluate_component(js_string: Var[str]) -> Var[Component]:
|
||||
@ -128,7 +161,7 @@ def load_dynamic_serializer():
|
||||
merge_var_data=VarData.merge(
|
||||
VarData(
|
||||
imports={
|
||||
f"/{constants.Dirs.STATE_PATH}": [
|
||||
f"$/{constants.Dirs.STATE_PATH}": [
|
||||
imports.ImportVar(tag="evalReactComponent"),
|
||||
],
|
||||
"react": [
|
||||
@ -140,7 +173,7 @@ def load_dynamic_serializer():
|
||||
f"const [{unique_var_name}, set_{unique_var_name}] = useState(null);": None,
|
||||
"useEffect(() => {"
|
||||
"let isMounted = true;"
|
||||
f"evalReactComponent({str(js_string)})"
|
||||
f"evalReactComponent({js_string!s})"
|
||||
".then((component) => {"
|
||||
"if (isMounted) {"
|
||||
f"set_{unique_var_name}(component);"
|
||||
@ -150,7 +183,7 @@ def load_dynamic_serializer():
|
||||
"isMounted = false;"
|
||||
"};"
|
||||
"}"
|
||||
f", [{str(js_string)}]);": None,
|
||||
f", [{js_string!s}]);": None,
|
||||
},
|
||||
),
|
||||
),
|
||||
|
@ -3,7 +3,9 @@
|
||||
# This file was generated by `reflex/utils/pyi_generator.py`!
|
||||
# ------------------------------------------------------
|
||||
|
||||
from . import elements as elements
|
||||
from .elements.forms import Button as Button
|
||||
from .elements.forms import Datalist as Datalist
|
||||
from .elements.forms import Fieldset as Fieldset
|
||||
from .elements.forms import Form as Form
|
||||
from .elements.forms import Input as Input
|
||||
@ -17,6 +19,7 @@ from .elements.forms import Progress as Progress
|
||||
from .elements.forms import Select as Select
|
||||
from .elements.forms import Textarea as Textarea
|
||||
from .elements.forms import button as button
|
||||
from .elements.forms import datalist as datalist
|
||||
from .elements.forms import fieldset as fieldset
|
||||
from .elements.forms import form as form
|
||||
from .elements.forms import input as input
|
||||
|
@ -3,10 +3,10 @@
|
||||
# ------------------- DO NOT EDIT ----------------------
|
||||
# This file was generated by `reflex/utils/pyi_generator.py`!
|
||||
# ------------------------------------------------------
|
||||
from typing import Any, Callable, Dict, Optional, Union, overload
|
||||
from typing import Any, Dict, Optional, Union, overload
|
||||
|
||||
from reflex.components.component import Component
|
||||
from reflex.event import EventHandler, EventSpec
|
||||
from reflex.event import BASE_STATE, EventType
|
||||
from reflex.style import Style
|
||||
from reflex.vars.base import Var
|
||||
|
||||
@ -21,42 +21,22 @@ class Element(Component):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "Element":
|
||||
"""Create the component.
|
||||
|
@ -7,6 +7,7 @@ from reflex.utils import lazy_loader
|
||||
_MAPPING = {
|
||||
"forms": [
|
||||
"button",
|
||||
"datalist",
|
||||
"fieldset",
|
||||
"form",
|
||||
"input",
|
||||
|
@ -4,6 +4,7 @@
|
||||
# ------------------------------------------------------
|
||||
|
||||
from .forms import Button as Button
|
||||
from .forms import Datalist as Datalist
|
||||
from .forms import Fieldset as Fieldset
|
||||
from .forms import Form as Form
|
||||
from .forms import Input as Input
|
||||
@ -17,6 +18,7 @@ from .forms import Progress as Progress
|
||||
from .forms import Select as Select
|
||||
from .forms import Textarea as Textarea
|
||||
from .forms import button as button
|
||||
from .forms import datalist as datalist
|
||||
from .forms import fieldset as fieldset
|
||||
from .forms import form as form
|
||||
from .forms import input as input
|
||||
@ -226,6 +228,7 @@ from .typography import ul as ul
|
||||
_MAPPING = {
|
||||
"forms": [
|
||||
"button",
|
||||
"datalist",
|
||||
"fieldset",
|
||||
"form",
|
||||
"input",
|
||||
|
@ -1,4 +1,4 @@
|
||||
"""Element classes. This is an auto-generated file. Do not edit. See ../generate.py."""
|
||||
"""Base classes."""
|
||||
|
||||
from typing import Union
|
||||
|
||||
@ -9,7 +9,7 @@ from reflex.vars.base import Var
|
||||
class BaseHTML(Element):
|
||||
"""Base class for common attributes."""
|
||||
|
||||
# Provides a hint for generating a keyboard shortcut for the current element.
|
||||
# Provides a hint for generating a keyboard shortcut for the current element.
|
||||
access_key: Var[Union[str, int, bool]]
|
||||
|
||||
# Controls whether and how text input is automatically capitalized as it is entered/edited by the user.
|
||||
|
@ -3,10 +3,10 @@
|
||||
# ------------------- DO NOT EDIT ----------------------
|
||||
# This file was generated by `reflex/utils/pyi_generator.py`!
|
||||
# ------------------------------------------------------
|
||||
from typing import Any, Callable, Dict, Optional, Union, overload
|
||||
from typing import Any, Dict, Optional, Union, overload
|
||||
|
||||
from reflex.components.el.element import Element
|
||||
from reflex.event import EventHandler, EventSpec
|
||||
from reflex.event import BASE_STATE, EventType
|
||||
from reflex.style import Style
|
||||
from reflex.vars.base import Var
|
||||
|
||||
@ -45,49 +45,29 @@ class BaseHTML(Element):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "BaseHTML":
|
||||
"""Create the component.
|
||||
|
||||
Args:
|
||||
*children: The children of the component.
|
||||
access_key: Provides a hint for generating a keyboard shortcut for the current element.
|
||||
access_key: Provides a hint for generating a keyboard shortcut for the current element.
|
||||
auto_capitalize: Controls whether and how text input is automatically capitalized as it is entered/edited by the user.
|
||||
content_editable: Indicates whether the element's content is editable.
|
||||
context_menu: Defines the ID of a <menu> element which will serve as the element's context menu.
|
||||
|
@ -1,17 +1,24 @@
|
||||
"""Element classes. This is an auto-generated file. Do not edit. See ../generate.py."""
|
||||
"""Forms classes."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from hashlib import md5
|
||||
from typing import Any, Dict, Iterator, Set, Union
|
||||
from typing import Any, Dict, Iterator, Set, Tuple, Union
|
||||
|
||||
from jinja2 import Environment
|
||||
|
||||
from reflex.components.el.element import Element
|
||||
from reflex.components.tags.tag import Tag
|
||||
from reflex.constants import Dirs, EventTriggers
|
||||
from reflex.event import EventChain, EventHandler, prevent_default
|
||||
from reflex.event import (
|
||||
EventChain,
|
||||
EventHandler,
|
||||
input_event,
|
||||
key_event,
|
||||
prevent_default,
|
||||
)
|
||||
from reflex.utils.imports import ImportDict
|
||||
from reflex.utils.types import is_optional
|
||||
from reflex.vars import VarData
|
||||
from reflex.vars.base import LiteralVar, Var
|
||||
|
||||
@ -78,7 +85,6 @@ class Datalist(BaseHTML):
|
||||
"""Display the datalist element."""
|
||||
|
||||
tag = "datalist"
|
||||
# No unique attributes, only common ones are inherited
|
||||
|
||||
|
||||
class Fieldset(Element):
|
||||
@ -96,6 +102,24 @@ class Fieldset(Element):
|
||||
name: Var[Union[str, int, bool]]
|
||||
|
||||
|
||||
def on_submit_event_spec() -> Tuple[Var[Dict[str, Any]]]:
|
||||
"""Event handler spec for the on_submit event.
|
||||
|
||||
Returns:
|
||||
The event handler spec.
|
||||
"""
|
||||
return (FORM_DATA,)
|
||||
|
||||
|
||||
def on_submit_string_event_spec() -> Tuple[Var[Dict[str, str]]]:
|
||||
"""Event handler spec for the on_submit event.
|
||||
|
||||
Returns:
|
||||
The event handler spec.
|
||||
"""
|
||||
return (FORM_DATA,)
|
||||
|
||||
|
||||
class Form(BaseHTML):
|
||||
"""Display the form element."""
|
||||
|
||||
@ -135,7 +159,7 @@ class Form(BaseHTML):
|
||||
handle_submit_unique_name: Var[str]
|
||||
|
||||
# Fired when the form is submitted
|
||||
on_submit: EventHandler[lambda e0: [FORM_DATA]]
|
||||
on_submit: EventHandler[on_submit_event_spec, on_submit_string_event_spec]
|
||||
|
||||
@classmethod
|
||||
def create(cls, *children, **props):
|
||||
@ -172,7 +196,7 @@ class Form(BaseHTML):
|
||||
"""
|
||||
return {
|
||||
"react": "useCallback",
|
||||
f"/{Dirs.STATE_PATH}": ["getRefValue", "getRefValues"],
|
||||
f"$/{Dirs.STATE_PATH}": ["getRefValue", "getRefValues"],
|
||||
}
|
||||
|
||||
def add_hooks(self) -> list[str]:
|
||||
@ -215,18 +239,17 @@ class Form(BaseHTML):
|
||||
# when ref start with refs_ it's an array of refs, so we need different method
|
||||
# to collect data
|
||||
if ref.startswith("refs_"):
|
||||
ref_var = Var(_js_expr=ref[:-3]).as_ref()
|
||||
ref_var = Var(_js_expr=ref[:-3])._as_ref()
|
||||
form_refs[ref[len("refs_") : -3]] = Var(
|
||||
_js_expr=f"getRefValues({str(ref_var)})",
|
||||
_js_expr=f"getRefValues({ref_var!s})",
|
||||
_var_data=VarData.merge(ref_var._get_all_var_data()),
|
||||
)
|
||||
else:
|
||||
ref_var = Var(_js_expr=ref).as_ref()
|
||||
ref_var = Var(_js_expr=ref)._as_ref()
|
||||
form_refs[ref[4:]] = Var(
|
||||
_js_expr=f"getRefValue({str(ref_var)})",
|
||||
_js_expr=f"getRefValue({ref_var!s})",
|
||||
_var_data=VarData.merge(ref_var._get_all_var_data()),
|
||||
)
|
||||
# print(repr(form_refs))
|
||||
return form_refs
|
||||
|
||||
def _get_vars(self, include_children: bool = True) -> Iterator[Var]:
|
||||
@ -234,7 +257,8 @@ class Form(BaseHTML):
|
||||
yield from self._get_form_refs().values()
|
||||
|
||||
def _exclude_props(self) -> list[str]:
|
||||
return super()._exclude_props() + [
|
||||
return [
|
||||
*super()._exclude_props(),
|
||||
"reset_on_submit",
|
||||
"handle_submit_unique_name",
|
||||
]
|
||||
@ -345,19 +369,46 @@ class Input(BaseHTML):
|
||||
value: Var[Union[str, int, float]]
|
||||
|
||||
# Fired when the input value changes
|
||||
on_change: EventHandler[lambda e0: [e0.target.value]]
|
||||
on_change: EventHandler[input_event]
|
||||
|
||||
# Fired when the input gains focus
|
||||
on_focus: EventHandler[lambda e0: [e0.target.value]]
|
||||
on_focus: EventHandler[input_event]
|
||||
|
||||
# Fired when the input loses focus
|
||||
on_blur: EventHandler[lambda e0: [e0.target.value]]
|
||||
on_blur: EventHandler[input_event]
|
||||
|
||||
# Fired when a key is pressed down
|
||||
on_key_down: EventHandler[lambda e0: [e0.key]]
|
||||
on_key_down: EventHandler[key_event]
|
||||
|
||||
# Fired when a key is released
|
||||
on_key_up: EventHandler[lambda e0: [e0.key]]
|
||||
on_key_up: EventHandler[key_event]
|
||||
|
||||
@classmethod
|
||||
def create(cls, *children, **props):
|
||||
"""Create an Input component.
|
||||
|
||||
Args:
|
||||
*children: The children of the component.
|
||||
**props: The properties of the component.
|
||||
|
||||
Returns:
|
||||
The component.
|
||||
"""
|
||||
from reflex.vars.number import ternary_operation
|
||||
|
||||
value = props.get("value")
|
||||
|
||||
# React expects an empty string(instead of null) for controlled inputs.
|
||||
if value is not None and is_optional(
|
||||
(value_var := Var.create(value))._var_type
|
||||
):
|
||||
props["value"] = ternary_operation(
|
||||
(value_var != Var.create(None)) # pyright: ignore [reportGeneralTypeIssues]
|
||||
& (value_var != Var(_js_expr="undefined")),
|
||||
value,
|
||||
Var.create(""),
|
||||
)
|
||||
return super().create(*children, **props)
|
||||
|
||||
|
||||
class Label(BaseHTML):
|
||||
@ -376,7 +427,6 @@ class Legend(BaseHTML):
|
||||
"""Display the legend element."""
|
||||
|
||||
tag = "legend"
|
||||
# No unique attributes, only common ones are inherited
|
||||
|
||||
|
||||
class Meter(BaseHTML):
|
||||
@ -496,7 +546,7 @@ class Select(BaseHTML):
|
||||
size: Var[Union[str, int, bool]]
|
||||
|
||||
# Fired when the select value changes
|
||||
on_change: EventHandler[lambda e0: [e0.target.value]]
|
||||
on_change: EventHandler[input_event]
|
||||
|
||||
|
||||
AUTO_HEIGHT_JS = """
|
||||
@ -546,6 +596,9 @@ class Textarea(BaseHTML):
|
||||
# Visible width of the text control, in average character widths
|
||||
cols: Var[Union[str, int, bool]]
|
||||
|
||||
# The default value of the textarea when initially rendered
|
||||
default_value: Var[str]
|
||||
|
||||
# Name part of the textarea to submit in 'dir' and 'name' pair when form is submitted
|
||||
dirname: Var[Union[str, int, bool]]
|
||||
|
||||
@ -586,22 +639,59 @@ class Textarea(BaseHTML):
|
||||
wrap: Var[Union[str, int, bool]]
|
||||
|
||||
# Fired when the input value changes
|
||||
on_change: EventHandler[lambda e0: [e0.target.value]]
|
||||
on_change: EventHandler[input_event]
|
||||
|
||||
# Fired when the input gains focus
|
||||
on_focus: EventHandler[lambda e0: [e0.target.value]]
|
||||
on_focus: EventHandler[input_event]
|
||||
|
||||
# Fired when the input loses focus
|
||||
on_blur: EventHandler[lambda e0: [e0.target.value]]
|
||||
on_blur: EventHandler[input_event]
|
||||
|
||||
# Fired when a key is pressed down
|
||||
on_key_down: EventHandler[lambda e0: [e0.key]]
|
||||
on_key_down: EventHandler[key_event]
|
||||
|
||||
# Fired when a key is released
|
||||
on_key_up: EventHandler[lambda e0: [e0.key]]
|
||||
on_key_up: EventHandler[key_event]
|
||||
|
||||
@classmethod
|
||||
def create(cls, *children, **props):
|
||||
"""Create a textarea component.
|
||||
|
||||
Args:
|
||||
*children: The children of the textarea.
|
||||
**props: The properties of the textarea.
|
||||
|
||||
Returns:
|
||||
The textarea component.
|
||||
|
||||
Raises:
|
||||
ValueError: when `enter_key_submit` is combined with `on_key_down`.
|
||||
"""
|
||||
enter_key_submit = props.get("enter_key_submit")
|
||||
auto_height = props.get("auto_height")
|
||||
custom_attrs = props.setdefault("custom_attrs", {})
|
||||
|
||||
if enter_key_submit is not None:
|
||||
enter_key_submit = Var.create(enter_key_submit)
|
||||
if "on_key_down" in props:
|
||||
raise ValueError(
|
||||
"Cannot combine `enter_key_submit` with `on_key_down`.",
|
||||
)
|
||||
custom_attrs["on_key_down"] = Var(
|
||||
_js_expr=f"(e) => enterKeySubmitOnKeyDown(e, {enter_key_submit!s})",
|
||||
_var_data=VarData.merge(enter_key_submit._get_all_var_data()),
|
||||
)
|
||||
if auto_height is not None:
|
||||
auto_height = Var.create(auto_height)
|
||||
custom_attrs["on_input"] = Var(
|
||||
_js_expr=f"(e) => autoHeightOnInput(e, {auto_height!s})",
|
||||
_var_data=VarData.merge(auto_height._get_all_var_data()),
|
||||
)
|
||||
return super().create(*children, **props)
|
||||
|
||||
def _exclude_props(self) -> list[str]:
|
||||
return super()._exclude_props() + [
|
||||
return [
|
||||
*super()._exclude_props(),
|
||||
"auto_height",
|
||||
"enter_key_submit",
|
||||
]
|
||||
@ -619,30 +709,9 @@ class Textarea(BaseHTML):
|
||||
custom_code.add(ENTER_KEY_SUBMIT_JS)
|
||||
return custom_code
|
||||
|
||||
def _render(self) -> Tag:
|
||||
tag = super()._render()
|
||||
if self.enter_key_submit is not None:
|
||||
if "on_key_down" in self.event_triggers:
|
||||
raise ValueError(
|
||||
"Cannot combine `enter_key_submit` with `on_key_down`.",
|
||||
)
|
||||
tag.add_props(
|
||||
on_key_down=Var(
|
||||
_js_expr=f"(e) => enterKeySubmitOnKeyDown(e, {str(self.enter_key_submit)})",
|
||||
_var_data=VarData.merge(self.enter_key_submit._get_all_var_data()),
|
||||
)
|
||||
)
|
||||
if self.auto_height is not None:
|
||||
tag.add_props(
|
||||
on_input=Var(
|
||||
_js_expr=f"(e) => autoHeightOnInput(e, {str(self.auto_height)})",
|
||||
_var_data=VarData.merge(self.auto_height._get_all_var_data()),
|
||||
)
|
||||
)
|
||||
return tag
|
||||
|
||||
|
||||
button = Button.create
|
||||
datalist = Datalist.create
|
||||
fieldset = Fieldset.create
|
||||
form = Form.create
|
||||
input = Input.create
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
"""Element classes. This is an auto-generated file. Do not edit. See ../generate.py."""
|
||||
"""Inline classes."""
|
||||
|
||||
from typing import Union
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
"""Element classes. This is an auto-generated file. Do not edit. See ../generate.py."""
|
||||
"""Media classes."""
|
||||
|
||||
from typing import Any, Union
|
||||
|
||||
@ -129,7 +129,6 @@ class Img(BaseHTML):
|
||||
|
||||
Returns:
|
||||
The component.
|
||||
|
||||
"""
|
||||
return (
|
||||
super().create(src=children[0], **props)
|
||||
@ -274,14 +273,12 @@ class Picture(BaseHTML):
|
||||
"""Display the picture element."""
|
||||
|
||||
tag = "picture"
|
||||
# No unique attributes, only common ones are inherited
|
||||
|
||||
|
||||
class Portal(BaseHTML):
|
||||
"""Display the portal element."""
|
||||
|
||||
tag = "portal"
|
||||
# No unique attributes, only common ones are inherited
|
||||
|
||||
|
||||
class Source(BaseHTML):
|
||||
@ -317,6 +314,42 @@ class Svg(BaseHTML):
|
||||
xmlns: Var[str]
|
||||
|
||||
|
||||
class Text(BaseHTML):
|
||||
"""The SVG text component."""
|
||||
|
||||
tag = "text"
|
||||
# The x coordinate of the starting point of the text baseline.
|
||||
x: Var[Union[str, int]]
|
||||
# The y coordinate of the starting point of the text baseline.
|
||||
y: Var[Union[str, int]]
|
||||
# Shifts the text position horizontally from a previous text element.
|
||||
dx: Var[Union[str, int]]
|
||||
# Shifts the text position vertically from a previous text element.
|
||||
dy: Var[Union[str, int]]
|
||||
# Rotates orientation of each individual glyph.
|
||||
rotate: Var[Union[str, int]]
|
||||
# How the text is stretched or compressed to fit the width defined by the text_length attribute.
|
||||
length_adjust: Var[str]
|
||||
# A width that the text should be scaled to fit.
|
||||
text_length: Var[Union[str, int]]
|
||||
|
||||
|
||||
class Line(BaseHTML):
|
||||
"""The SVG line component."""
|
||||
|
||||
tag = "line"
|
||||
# The x-axis coordinate of the line starting point.
|
||||
x1: Var[Union[str, int]]
|
||||
# The x-axis coordinate of the the line ending point.
|
||||
x2: Var[Union[str, int]]
|
||||
# The y-axis coordinate of the line starting point.
|
||||
y1: Var[Union[str, int]]
|
||||
# The y-axis coordinate of the the line ending point.
|
||||
y2: Var[Union[str, int]]
|
||||
# The total path length, in user units.
|
||||
path_length: Var[int]
|
||||
|
||||
|
||||
class Circle(BaseHTML):
|
||||
"""The SVG circle component."""
|
||||
|
||||
@ -331,6 +364,22 @@ class Circle(BaseHTML):
|
||||
path_length: Var[int]
|
||||
|
||||
|
||||
class Ellipse(BaseHTML):
|
||||
"""The SVG ellipse component."""
|
||||
|
||||
tag = "ellipse"
|
||||
# The x position of the center of the ellipse.
|
||||
cx: Var[Union[str, int]]
|
||||
# The y position of the center of the ellipse.
|
||||
cy: Var[Union[str, int]]
|
||||
# The radius of the ellipse on the x axis.
|
||||
rx: Var[Union[str, int]]
|
||||
# The radius of the ellipse on the y axis.
|
||||
ry: Var[Union[str, int]]
|
||||
# The total length for the ellipse's circumference, in user units.
|
||||
path_length: Var[int]
|
||||
|
||||
|
||||
class Rect(BaseHTML):
|
||||
"""The SVG rect component."""
|
||||
|
||||
@ -394,6 +443,39 @@ class LinearGradient(BaseHTML):
|
||||
y2: Var[Union[str, int, bool]]
|
||||
|
||||
|
||||
class RadialGradient(BaseHTML):
|
||||
"""Display the radialGradient element."""
|
||||
|
||||
tag = "radialGradient"
|
||||
|
||||
# The x coordinate of the end circle of the radial gradient.
|
||||
cx: Var[Union[str, int, bool]]
|
||||
|
||||
# The y coordinate of the end circle of the radial gradient.
|
||||
cy: Var[Union[str, int, bool]]
|
||||
|
||||
# The radius of the start circle of the radial gradient.
|
||||
fr: Var[Union[str, int, bool]]
|
||||
|
||||
# The x coordinate of the start circle of the radial gradient.
|
||||
fx: Var[Union[str, int, bool]]
|
||||
|
||||
# The y coordinate of the start circle of the radial gradient.
|
||||
fy: Var[Union[str, int, bool]]
|
||||
|
||||
# Units for the gradient.
|
||||
gradient_units: Var[Union[str, bool]]
|
||||
|
||||
# Transform applied to the gradient.
|
||||
gradient_transform: Var[Union[str, bool]]
|
||||
|
||||
# The radius of the end circle of the radial gradient.
|
||||
r: Var[Union[str, int, bool]]
|
||||
|
||||
# Method used to spread the gradient.
|
||||
spread_method: Var[Union[str, bool]]
|
||||
|
||||
|
||||
class Stop(BaseHTML):
|
||||
"""Display the stop element."""
|
||||
|
||||
@ -421,12 +503,16 @@ class Path(BaseHTML):
|
||||
class SVG(ComponentNamespace):
|
||||
"""SVG component namespace."""
|
||||
|
||||
text = staticmethod(Text.create)
|
||||
line = staticmethod(Line.create)
|
||||
circle = staticmethod(Circle.create)
|
||||
ellipse = staticmethod(Ellipse.create)
|
||||
rect = staticmethod(Rect.create)
|
||||
polygon = staticmethod(Polygon.create)
|
||||
path = staticmethod(Path.create)
|
||||
stop = staticmethod(Stop.create)
|
||||
linear_gradient = staticmethod(LinearGradient.create)
|
||||
radial_gradient = staticmethod(RadialGradient.create)
|
||||
defs = staticmethod(Defs.create)
|
||||
__call__ = staticmethod(Svg.create)
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
"""Element classes. This is an auto-generated file. Do not edit. See ../generate.py."""
|
||||
"""Metadata classes."""
|
||||
|
||||
from typing import List, Union
|
||||
|
||||
@ -8,7 +8,7 @@ from reflex.vars.base import Var
|
||||
from .base import BaseHTML
|
||||
|
||||
|
||||
class Base(BaseHTML): # noqa: E742
|
||||
class Base(BaseHTML):
|
||||
"""Display the base element."""
|
||||
|
||||
tag = "base"
|
||||
@ -18,13 +18,13 @@ class Base(BaseHTML): # noqa: E742
|
||||
target: Var[Union[str, int, bool]]
|
||||
|
||||
|
||||
class Head(BaseHTML): # noqa: E742
|
||||
class Head(BaseHTML):
|
||||
"""Display the head element."""
|
||||
|
||||
tag = "head"
|
||||
|
||||
|
||||
class Link(BaseHTML): # noqa: E742
|
||||
class Link(BaseHTML):
|
||||
"""Display the link element."""
|
||||
|
||||
tag = "link"
|
||||
@ -75,14 +75,14 @@ class Meta(BaseHTML): # Inherits common attributes from BaseHTML
|
||||
name: Var[Union[str, int, bool]]
|
||||
|
||||
|
||||
class Title(Element): # noqa: E742
|
||||
class Title(Element):
|
||||
"""Display the title element."""
|
||||
|
||||
tag = "title"
|
||||
|
||||
|
||||
# Had to be named with an underscore so it doesnt conflict with reflex.style Style in pyi
|
||||
class StyleEl(Element): # noqa: E742
|
||||
class StyleEl(Element):
|
||||
"""Display the style element."""
|
||||
|
||||
tag = "style"
|
||||
|
@ -3,10 +3,10 @@
|
||||
# ------------------- DO NOT EDIT ----------------------
|
||||
# This file was generated by `reflex/utils/pyi_generator.py`!
|
||||
# ------------------------------------------------------
|
||||
from typing import Any, Callable, Dict, Optional, Union, overload
|
||||
from typing import Any, Dict, Optional, Union, overload
|
||||
|
||||
from reflex.components.el.element import Element
|
||||
from reflex.event import EventHandler, EventSpec
|
||||
from reflex.event import BASE_STATE, EventType
|
||||
from reflex.style import Style
|
||||
from reflex.vars.base import Var
|
||||
|
||||
@ -49,49 +49,29 @@ class Base(BaseHTML):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "Base":
|
||||
"""Create the component.
|
||||
|
||||
Args:
|
||||
*children: The children of the component.
|
||||
access_key: Provides a hint for generating a keyboard shortcut for the current element.
|
||||
access_key: Provides a hint for generating a keyboard shortcut for the current element.
|
||||
auto_capitalize: Controls whether and how text input is automatically capitalized as it is entered/edited by the user.
|
||||
content_editable: Indicates whether the element's content is editable.
|
||||
context_menu: Defines the ID of a <menu> element which will serve as the element's context menu.
|
||||
@ -155,49 +135,29 @@ class Head(BaseHTML):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "Head":
|
||||
"""Create the component.
|
||||
|
||||
Args:
|
||||
*children: The children of the component.
|
||||
access_key: Provides a hint for generating a keyboard shortcut for the current element.
|
||||
access_key: Provides a hint for generating a keyboard shortcut for the current element.
|
||||
auto_capitalize: Controls whether and how text input is automatically capitalized as it is entered/edited by the user.
|
||||
content_editable: Indicates whether the element's content is editable.
|
||||
context_menu: Defines the ID of a <menu> element which will serve as the element's context menu.
|
||||
@ -274,42 +234,22 @@ class Link(BaseHTML):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "Link":
|
||||
"""Create the component.
|
||||
@ -325,7 +265,7 @@ class Link(BaseHTML):
|
||||
rel: Specifies the relationship between the current document and the linked one
|
||||
sizes: Specifies the sizes of icons for visual media
|
||||
type: Specifies the MIME type of the linked document
|
||||
access_key: Provides a hint for generating a keyboard shortcut for the current element.
|
||||
access_key: Provides a hint for generating a keyboard shortcut for the current element.
|
||||
auto_capitalize: Controls whether and how text input is automatically capitalized as it is entered/edited by the user.
|
||||
content_editable: Indicates whether the element's content is editable.
|
||||
context_menu: Defines the ID of a <menu> element which will serve as the element's context menu.
|
||||
@ -393,42 +333,22 @@ class Meta(BaseHTML):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "Meta":
|
||||
"""Create the component.
|
||||
@ -439,7 +359,7 @@ class Meta(BaseHTML):
|
||||
content: Defines the content of the metadata
|
||||
http_equiv: Provides an HTTP header for the information/value of the content attribute
|
||||
name: Specifies a name for the metadata
|
||||
access_key: Provides a hint for generating a keyboard shortcut for the current element.
|
||||
access_key: Provides a hint for generating a keyboard shortcut for the current element.
|
||||
auto_capitalize: Controls whether and how text input is automatically capitalized as it is entered/edited by the user.
|
||||
content_editable: Indicates whether the element's content is editable.
|
||||
context_menu: Defines the ID of a <menu> element which will serve as the element's context menu.
|
||||
@ -479,42 +399,22 @@ class Title(Element):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "Title":
|
||||
"""Create the component.
|
||||
@ -546,42 +446,22 @@ class StyleEl(Element):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "StyleEl":
|
||||
"""Create the component.
|
||||
|
@ -1,4 +1,4 @@
|
||||
"""Element classes. This is an auto-generated file. Do not edit. See ../generate.py."""
|
||||
"""Other classes."""
|
||||
|
||||
from typing import Union
|
||||
|
||||
@ -26,31 +26,39 @@ class Dialog(BaseHTML):
|
||||
|
||||
|
||||
class Summary(BaseHTML):
|
||||
"""Display the summary element."""
|
||||
"""Display the summary element.
|
||||
|
||||
Used as a summary or caption for a <details> element.
|
||||
"""
|
||||
|
||||
tag = "summary"
|
||||
# No unique attributes, only common ones are inherited; used as a summary or caption for a <details> element
|
||||
|
||||
|
||||
class Slot(BaseHTML):
|
||||
"""Display the slot element."""
|
||||
"""Display the slot element.
|
||||
|
||||
Used as a placeholder inside a web component.
|
||||
"""
|
||||
|
||||
tag = "slot"
|
||||
# No unique attributes, only common ones are inherited; used as a placeholder inside a web component
|
||||
|
||||
|
||||
class Template(BaseHTML):
|
||||
"""Display the template element."""
|
||||
"""Display the template element.
|
||||
|
||||
Used for declaring fragments of HTML that can be cloned and inserted in the document.
|
||||
"""
|
||||
|
||||
tag = "template"
|
||||
# No unique attributes, only common ones are inherited; used for declaring fragments of HTML that can be cloned and inserted in the document
|
||||
|
||||
|
||||
class Math(BaseHTML):
|
||||
"""Display the math element."""
|
||||
"""Display the math element.
|
||||
|
||||
Represents a mathematical expression.
|
||||
"""
|
||||
|
||||
tag = "math"
|
||||
# No unique attributes, only common ones are inherited; used for displaying mathematical expressions
|
||||
|
||||
|
||||
class Html(BaseHTML):
|
||||
|
@ -3,9 +3,9 @@
|
||||
# ------------------- DO NOT EDIT ----------------------
|
||||
# This file was generated by `reflex/utils/pyi_generator.py`!
|
||||
# ------------------------------------------------------
|
||||
from typing import Any, Callable, Dict, Optional, Union, overload
|
||||
from typing import Any, Dict, Optional, Union, overload
|
||||
|
||||
from reflex.event import EventHandler, EventSpec
|
||||
from reflex.event import BASE_STATE, EventType
|
||||
from reflex.style import Style
|
||||
from reflex.vars.base import Var
|
||||
|
||||
@ -47,42 +47,22 @@ class Details(BaseHTML):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "Details":
|
||||
"""Create the component.
|
||||
@ -90,7 +70,7 @@ class Details(BaseHTML):
|
||||
Args:
|
||||
*children: The children of the component.
|
||||
open: Indicates whether the details will be visible (expanded) to the user
|
||||
access_key: Provides a hint for generating a keyboard shortcut for the current element.
|
||||
access_key: Provides a hint for generating a keyboard shortcut for the current element.
|
||||
auto_capitalize: Controls whether and how text input is automatically capitalized as it is entered/edited by the user.
|
||||
content_editable: Indicates whether the element's content is editable.
|
||||
context_menu: Defines the ID of a <menu> element which will serve as the element's context menu.
|
||||
@ -155,42 +135,22 @@ class Dialog(BaseHTML):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "Dialog":
|
||||
"""Create the component.
|
||||
@ -198,7 +158,7 @@ class Dialog(BaseHTML):
|
||||
Args:
|
||||
*children: The children of the component.
|
||||
open: Indicates whether the dialog is active and can be interacted with
|
||||
access_key: Provides a hint for generating a keyboard shortcut for the current element.
|
||||
access_key: Provides a hint for generating a keyboard shortcut for the current element.
|
||||
auto_capitalize: Controls whether and how text input is automatically capitalized as it is entered/edited by the user.
|
||||
content_editable: Indicates whether the element's content is editable.
|
||||
context_menu: Defines the ID of a <menu> element which will serve as the element's context menu.
|
||||
@ -262,49 +222,29 @@ class Summary(BaseHTML):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "Summary":
|
||||
"""Create the component.
|
||||
|
||||
Args:
|
||||
*children: The children of the component.
|
||||
access_key: No unique attributes, only common ones are inherited; used as a summary or caption for a <details> element Provides a hint for generating a keyboard shortcut for the current element.
|
||||
access_key: Provides a hint for generating a keyboard shortcut for the current element.
|
||||
auto_capitalize: Controls whether and how text input is automatically capitalized as it is entered/edited by the user.
|
||||
content_editable: Indicates whether the element's content is editable.
|
||||
context_menu: Defines the ID of a <menu> element which will serve as the element's context menu.
|
||||
@ -368,49 +308,29 @@ class Slot(BaseHTML):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "Slot":
|
||||
"""Create the component.
|
||||
|
||||
Args:
|
||||
*children: The children of the component.
|
||||
access_key: No unique attributes, only common ones are inherited; used as a placeholder inside a web component Provides a hint for generating a keyboard shortcut for the current element.
|
||||
access_key: Provides a hint for generating a keyboard shortcut for the current element.
|
||||
auto_capitalize: Controls whether and how text input is automatically capitalized as it is entered/edited by the user.
|
||||
content_editable: Indicates whether the element's content is editable.
|
||||
context_menu: Defines the ID of a <menu> element which will serve as the element's context menu.
|
||||
@ -474,49 +394,29 @@ class Template(BaseHTML):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "Template":
|
||||
"""Create the component.
|
||||
|
||||
Args:
|
||||
*children: The children of the component.
|
||||
access_key: No unique attributes, only common ones are inherited; used for declaring fragments of HTML that can be cloned and inserted in the document Provides a hint for generating a keyboard shortcut for the current element.
|
||||
access_key: Provides a hint for generating a keyboard shortcut for the current element.
|
||||
auto_capitalize: Controls whether and how text input is automatically capitalized as it is entered/edited by the user.
|
||||
content_editable: Indicates whether the element's content is editable.
|
||||
context_menu: Defines the ID of a <menu> element which will serve as the element's context menu.
|
||||
@ -580,49 +480,29 @@ class Math(BaseHTML):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "Math":
|
||||
"""Create the component.
|
||||
|
||||
Args:
|
||||
*children: The children of the component.
|
||||
access_key: No unique attributes, only common ones are inherited; used for displaying mathematical expressions Provides a hint for generating a keyboard shortcut for the current element.
|
||||
access_key: Provides a hint for generating a keyboard shortcut for the current element.
|
||||
auto_capitalize: Controls whether and how text input is automatically capitalized as it is entered/edited by the user.
|
||||
content_editable: Indicates whether the element's content is editable.
|
||||
context_menu: Defines the ID of a <menu> element which will serve as the element's context menu.
|
||||
@ -687,42 +567,22 @@ class Html(BaseHTML):
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, Callable, Var]
|
||||
] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
||||
**props,
|
||||
) -> "Html":
|
||||
"""Create the component.
|
||||
@ -730,7 +590,7 @@ class Html(BaseHTML):
|
||||
Args:
|
||||
*children: The children of the component.
|
||||
manifest: Specifies the URL of the document's cache manifest (obsolete in HTML5)
|
||||
access_key: Provides a hint for generating a keyboard shortcut for the current element.
|
||||
access_key: Provides a hint for generating a keyboard shortcut for the current element.
|
||||
auto_capitalize: Controls whether and how text input is automatically capitalized as it is entered/edited by the user.
|
||||
content_editable: Indicates whether the element's content is editable.
|
||||
context_menu: Defines the ID of a <menu> element which will serve as the element's context menu.
|
||||
|
@ -1,4 +1,4 @@
|
||||
"""Element classes. This is an auto-generated file. Do not edit. See ../generate.py."""
|
||||
"""Scripts classes."""
|
||||
|
||||
from typing import Union
|
||||
|
||||
@ -17,7 +17,6 @@ class Noscript(BaseHTML):
|
||||
"""Display the noscript element."""
|
||||
|
||||
tag = "noscript"
|
||||
# No unique attributes, only common ones are inherited
|
||||
|
||||
|
||||
class Script(BaseHTML):
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user