Merge branch 'main' into lendemor/fix_duplicate_tab_issue
This commit is contained in:
commit
d2b183e3f9
2
.github/codeql-config.yml
vendored
Normal file
2
.github/codeql-config.yml
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
paths-ignore:
|
||||||
|
- "**/tests/**"
|
58
.github/workflows/benchmarks.yml
vendored
58
.github/workflows/benchmarks.yml
vendored
@ -70,58 +70,6 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
GITHUB_SHA: ${{ github.sha }}
|
GITHUB_SHA: ${{ github.sha }}
|
||||||
|
|
||||||
simple-apps-benchmarks: # This app tests the compile times of various compoonents and pages
|
|
||||||
if: github.event.pull_request.merged == true
|
|
||||||
env:
|
|
||||||
OUTPUT_FILE: benchmarks.json
|
|
||||||
timeout-minutes: 50
|
|
||||||
strategy:
|
|
||||||
# Prioritize getting more information out of the workflow (even if something fails)
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
# Show OS combos first in GUI
|
|
||||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
|
||||||
python-version: ["3.9.21", "3.10.16", "3.11.11", "3.12.8"]
|
|
||||||
exclude:
|
|
||||||
- os: windows-latest
|
|
||||||
python-version: "3.10.16"
|
|
||||||
- os: windows-latest
|
|
||||||
python-version: "3.9.21"
|
|
||||||
# keep only one python version for MacOS
|
|
||||||
- os: macos-latest
|
|
||||||
python-version: "3.9.21"
|
|
||||||
- os: macos-latest
|
|
||||||
python-version: "3.10.16"
|
|
||||||
- os: macos-latest
|
|
||||||
python-version: "3.11.11"
|
|
||||||
include:
|
|
||||||
- os: windows-latest
|
|
||||||
python-version: "3.10.11"
|
|
||||||
- os: windows-latest
|
|
||||||
python-version: "3.9.13"
|
|
||||||
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
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 benchmark tests
|
|
||||||
env:
|
|
||||||
APP_HARNESS_HEADLESS: 1
|
|
||||||
PYTHONUNBUFFERED: 1
|
|
||||||
run: |
|
|
||||||
poetry run pytest -v benchmarks/ --benchmark-json=${{ env.OUTPUT_FILE }} -s
|
|
||||||
- name: Upload benchmark results
|
|
||||||
# Only run if the database creds are available in this context.
|
|
||||||
run:
|
|
||||||
poetry run python benchmarks/benchmark_compile_times.py --os "${{ matrix.os }}"
|
|
||||||
--python-version "${{ matrix.python-version }}" --commit-sha "${{ github.sha }}"
|
|
||||||
--benchmark-json "${{ env.OUTPUT_FILE }}" --branch-name "${{ github.head_ref || github.ref_name }}"
|
|
||||||
--event-type "${{ github.event_name }}" --pr-id "${{ github.event.pull_request.id }}"
|
|
||||||
|
|
||||||
reflex-dist-size: # This job is used to calculate the size of the Reflex distribution (wheel file)
|
reflex-dist-size: # This job is used to calculate the size of the Reflex distribution (wheel file)
|
||||||
if: github.event.pull_request.merged == true
|
if: github.event.pull_request.merged == true
|
||||||
timeout-minutes: 30
|
timeout-minutes: 30
|
||||||
@ -161,7 +109,11 @@ jobs:
|
|||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
- name: Set up python
|
||||||
|
id: setup-python
|
||||||
|
uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: ${{ matrix.python-version }}
|
||||||
- name: Install Poetry
|
- name: Install Poetry
|
||||||
uses: snok/install-poetry@v1
|
uses: snok/install-poetry@v1
|
||||||
with:
|
with:
|
||||||
|
@ -16,7 +16,7 @@ jobs:
|
|||||||
|
|
||||||
- uses: ./.github/actions/setup_build_env
|
- uses: ./.github/actions/setup_build_env
|
||||||
with:
|
with:
|
||||||
python-version: "3.9.21"
|
python-version: '3.10'
|
||||||
run-poetry-install: true
|
run-poetry-install: true
|
||||||
create-venv-at-path: .venv
|
create-venv-at-path: .venv
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ jobs:
|
|||||||
path: reflex-web
|
path: reflex-web
|
||||||
- name: Install Requirements for reflex-web
|
- name: Install Requirements for reflex-web
|
||||||
working-directory: ./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
|
- name: Install additional dependencies for DB access
|
||||||
run: poetry run uv pip install psycopg
|
run: poetry run uv pip install psycopg
|
||||||
- name: Init Website for reflex-web
|
- name: Init Website for reflex-web
|
||||||
@ -73,7 +73,7 @@ jobs:
|
|||||||
echo "$outdated"
|
echo "$outdated"
|
||||||
|
|
||||||
# Ignore 3rd party dependencies that are not updated.
|
# 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)
|
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|ag-grid' || true)
|
||||||
no_extra=$(echo "$filtered_outdated" | grep -vE '\|\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-' || true)
|
no_extra=$(echo "$filtered_outdated" | grep -vE '\|\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-' || true)
|
||||||
|
|
||||||
|
|
||||||
|
103
.github/workflows/codeql.yml
vendored
Normal file
103
.github/workflows/codeql.yml
vendored
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
# For most projects, this workflow file will not need changing; you simply need
|
||||||
|
# to commit it to your repository.
|
||||||
|
#
|
||||||
|
# You may wish to alter this file to override the set of languages analyzed,
|
||||||
|
# or to provide custom queries or build logic.
|
||||||
|
#
|
||||||
|
# ******** NOTE ********
|
||||||
|
# We have attempted to detect the languages in your repository. Please check
|
||||||
|
# the `language` matrix defined below to confirm you have the correct set of
|
||||||
|
# supported CodeQL languages.
|
||||||
|
#
|
||||||
|
name: "CodeQL Advanced"
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: ["main"]
|
||||||
|
pull_request:
|
||||||
|
branches: ["main"]
|
||||||
|
schedule:
|
||||||
|
- cron: "36 7 * * 4"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
analyze:
|
||||||
|
name: Analyze (${{ matrix.language }})
|
||||||
|
# Runner size impacts CodeQL analysis time. To learn more, please see:
|
||||||
|
# - https://gh.io/recommended-hardware-resources-for-running-codeql
|
||||||
|
# - https://gh.io/supported-runners-and-hardware-resources
|
||||||
|
# - https://gh.io/using-larger-runners (GitHub.com only)
|
||||||
|
# Consider using larger runners or machines with greater resources for possible analysis time improvements.
|
||||||
|
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
|
||||||
|
permissions:
|
||||||
|
# required for all workflows
|
||||||
|
security-events: write
|
||||||
|
|
||||||
|
# required to fetch internal or private CodeQL packs
|
||||||
|
packages: read
|
||||||
|
|
||||||
|
# only required for workflows in private repositories
|
||||||
|
actions: read
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- language: javascript-typescript
|
||||||
|
build-mode: none
|
||||||
|
- language: python
|
||||||
|
build-mode: none
|
||||||
|
- language: actions
|
||||||
|
build-mode: none
|
||||||
|
# CodeQL supports the following values keywords for 'language': 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift'
|
||||||
|
# Use `c-cpp` to analyze code written in C, C++ or both
|
||||||
|
# Use 'java-kotlin' to analyze code written in Java, Kotlin or both
|
||||||
|
# Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both
|
||||||
|
# To learn more about changing the languages that are analyzed or customizing the build mode for your analysis,
|
||||||
|
# see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning.
|
||||||
|
# If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how
|
||||||
|
# your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
# Add any setup steps before running the `github/codeql-action/init` action.
|
||||||
|
# This includes steps like installing compilers or runtimes (`actions/setup-node`
|
||||||
|
# or others). This is typically only required for manual builds.
|
||||||
|
# - name: Setup runtime (example)
|
||||||
|
# uses: actions/setup-example@v1
|
||||||
|
|
||||||
|
# Initializes the CodeQL tools for scanning.
|
||||||
|
- name: Initialize CodeQL
|
||||||
|
uses: github/codeql-action/init@v3
|
||||||
|
with:
|
||||||
|
languages: ${{ matrix.language }}
|
||||||
|
config-file: .github/codeql-config.yml
|
||||||
|
build-mode: ${{ matrix.build-mode }}
|
||||||
|
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||||
|
# By default, queries listed here will override any specified in a config file.
|
||||||
|
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||||
|
|
||||||
|
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
||||||
|
# queries: security-extended,security-and-quality
|
||||||
|
|
||||||
|
# If the analyze step fails for one of the languages you are analyzing with
|
||||||
|
# "We were unable to automatically build your code", modify the matrix above
|
||||||
|
# to set the build mode to "manual" for that language. Then modify this step
|
||||||
|
# to build your code.
|
||||||
|
# ℹ️ Command-line programs to run using the OS shell.
|
||||||
|
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||||
|
- if: matrix.build-mode == 'manual'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
echo 'If you are using a "manual" build mode for one or more of the' \
|
||||||
|
'languages you are analyzing, replace this with the commands to build' \
|
||||||
|
'your code, for example:'
|
||||||
|
echo ' make bootstrap'
|
||||||
|
echo ' make release'
|
||||||
|
exit 1
|
||||||
|
|
||||||
|
- name: Perform CodeQL Analysis
|
||||||
|
uses: github/codeql-action/analyze@v3
|
||||||
|
with:
|
||||||
|
category: "/language:${{matrix.language}}"
|
11
.github/workflows/integration_app_harness.yml
vendored
11
.github/workflows/integration_app_harness.yml
vendored
@ -47,17 +47,10 @@ jobs:
|
|||||||
python-version: ${{ matrix.python-version }}
|
python-version: ${{ matrix.python-version }}
|
||||||
run-poetry-install: true
|
run-poetry-install: true
|
||||||
create-venv-at-path: .venv
|
create-venv-at-path: .venv
|
||||||
- run: poetry run uv pip install pyvirtualdisplay pillow pytest-split
|
- run: poetry run uv pip install pyvirtualdisplay pillow pytest-split pytest-retry
|
||||||
- name: Run app harness tests
|
- name: Run app harness tests
|
||||||
env:
|
env:
|
||||||
SCREENSHOT_DIR: /tmp/screenshots/${{ matrix.state_manager }}/${{ matrix.python-version }}/${{ matrix.split_index }}
|
|
||||||
REDIS_URL: ${{ matrix.state_manager == 'redis' && 'redis://localhost:6379' || '' }}
|
REDIS_URL: ${{ matrix.state_manager == 'redis' && 'redis://localhost:6379' || '' }}
|
||||||
run: |
|
run: |
|
||||||
poetry run playwright install chromium
|
poetry run playwright install chromium
|
||||||
poetry run pytest tests/integration --splits 2 --group ${{matrix.split_index}}
|
poetry run pytest tests/integration --retries 3 --maxfail=5 --splits 2 --group ${{matrix.split_index}}
|
||||||
- uses: actions/upload-artifact@v4
|
|
||||||
name: Upload failed test screenshots
|
|
||||||
if: always()
|
|
||||||
with:
|
|
||||||
name: failed_test_screenshots
|
|
||||||
path: /tmp/screenshots
|
|
||||||
|
67
.github/workflows/integration_tests.yml
vendored
67
.github/workflows/integration_tests.yml
vendored
@ -33,7 +33,7 @@ env:
|
|||||||
PR_TITLE: ${{ github.event.pull_request.title }}
|
PR_TITLE: ${{ github.event.pull_request.title }}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
example-counter:
|
example-counter-and-nba-proxy:
|
||||||
env:
|
env:
|
||||||
OUTPUT_FILE: import_benchmark.json
|
OUTPUT_FILE: import_benchmark.json
|
||||||
timeout-minutes: 30
|
timeout-minutes: 30
|
||||||
@ -43,22 +43,17 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
# Show OS combos first in GUI
|
# Show OS combos first in GUI
|
||||||
os: [ubuntu-latest, windows-latest]
|
os: [ubuntu-latest, windows-latest]
|
||||||
python-version: ["3.9.21", "3.10.16", "3.11.11", "3.12.8", "3.13.1"]
|
python-version: ['3.10.16', '3.11.11', '3.12.8', '3.13.1']
|
||||||
# Windows is a bit behind on Python version availability in Github
|
|
||||||
exclude:
|
exclude:
|
||||||
- os: windows-latest
|
- os: windows-latest
|
||||||
python-version: "3.11.11"
|
python-version: "3.11.11"
|
||||||
- os: windows-latest
|
- os: windows-latest
|
||||||
python-version: "3.10.16"
|
python-version: '3.10.16'
|
||||||
- os: windows-latest
|
|
||||||
python-version: "3.9.21"
|
|
||||||
include:
|
include:
|
||||||
- os: windows-latest
|
- os: windows-latest
|
||||||
python-version: "3.11.9"
|
python-version: "3.11.9"
|
||||||
- os: windows-latest
|
- os: windows-latest
|
||||||
python-version: "3.10.11"
|
python-version: '3.10.11'
|
||||||
- os: windows-latest
|
|
||||||
python-version: "3.9.13"
|
|
||||||
|
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
@ -84,8 +79,6 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
poetry run reflex export --backend-only
|
poetry run reflex export --backend-only
|
||||||
- name: Check run --backend-only before init for counter example
|
- name: Check run --backend-only before init for counter example
|
||||||
env:
|
|
||||||
WAIT_FOR_LISTENING_PORT_ARGS: --path ping
|
|
||||||
run: |
|
run: |
|
||||||
poetry run bash scripts/integration.sh ./reflex-examples/counter dev 8001 --backend-only --backend-port 8001
|
poetry run bash scripts/integration.sh ./reflex-examples/counter dev 8001 --backend-only --backend-port 8001
|
||||||
- name: Init Website for counter example
|
- name: Init Website for counter example
|
||||||
@ -101,26 +94,26 @@ jobs:
|
|||||||
# Check that npm is home
|
# Check that npm is home
|
||||||
npm -v
|
npm -v
|
||||||
poetry run bash scripts/integration.sh ./reflex-examples/counter dev
|
poetry run bash scripts/integration.sh ./reflex-examples/counter dev
|
||||||
- name: Measure and upload .web size
|
- name: Install requirements for nba proxy example
|
||||||
run:
|
working-directory: ./reflex-examples/nba-proxy
|
||||||
poetry run python benchmarks/benchmark_web_size.py --os "${{ matrix.os }}"
|
run: |
|
||||||
--python-version "${{ matrix.python-version }}" --commit-sha "${{ github.sha }}"
|
poetry run uv pip install -r requirements.txt
|
||||||
--pr-id "${{ github.event.pull_request.id }}"
|
- name: Install additional dependencies for DB access
|
||||||
--branch-name "${{ github.head_ref || github.ref_name }}"
|
run: poetry run uv pip install psycopg
|
||||||
--path ./reflex-examples/counter/.web
|
- name: Check export --backend-only before init for nba-proxy example
|
||||||
--app-name "counter"
|
working-directory: ./reflex-examples/nba-proxy
|
||||||
- name: Install hyperfine
|
run: |
|
||||||
run: cargo install hyperfine
|
poetry run reflex export --backend-only
|
||||||
- name: Benchmark imports
|
- name: Init Website for nba-proxy example
|
||||||
working-directory: ./reflex-examples/counter
|
working-directory: ./reflex-examples/nba-proxy
|
||||||
run: hyperfine --warmup 3 "export POETRY_VIRTUALENVS_PATH=../../.venv; poetry run python counter/counter.py" --show-output --export-json "${{ env.OUTPUT_FILE }}" --shell bash
|
run: |
|
||||||
- name: Upload Benchmarks
|
poetry run reflex init --loglevel debug
|
||||||
run:
|
- name: Run Website and Check for errors
|
||||||
poetry run python benchmarks/benchmark_imports.py --os "${{ matrix.os }}"
|
run: |
|
||||||
--python-version "${{ matrix.python-version }}" --commit-sha "${{ github.sha }}"
|
# Check that npm is home
|
||||||
--benchmark-json "./reflex-examples/counter/${{ env.OUTPUT_FILE }}"
|
npm -v
|
||||||
--branch-name "${{ github.head_ref || github.ref_name }}" --pr-id "${{ github.event.pull_request.id }}"
|
poetry run bash scripts/integration.sh ./reflex-examples/nba-proxy dev
|
||||||
--app-name "counter"
|
|
||||||
|
|
||||||
reflex-web:
|
reflex-web:
|
||||||
strategy:
|
strategy:
|
||||||
@ -161,12 +154,6 @@ jobs:
|
|||||||
# Check that npm is home
|
# Check that npm is home
|
||||||
npm -v
|
npm -v
|
||||||
poetry run bash scripts/integration.sh ./reflex-web prod
|
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
|
|
||||||
|
|
||||||
rx-shout-from-template:
|
rx-shout-from-template:
|
||||||
strategy:
|
strategy:
|
||||||
@ -230,9 +217,3 @@ jobs:
|
|||||||
# Check that npm is home
|
# Check that npm is home
|
||||||
npm -v
|
npm -v
|
||||||
poetry run bash scripts/integration.sh ./reflex-web prod
|
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
|
|
||||||
|
1
.github/workflows/integration_tests_wsl.yml
vendored
1
.github/workflows/integration_tests_wsl.yml
vendored
@ -78,7 +78,6 @@ jobs:
|
|||||||
shell: wsl-bash {0}
|
shell: wsl-bash {0}
|
||||||
run: |
|
run: |
|
||||||
export TELEMETRY_ENABLED=false
|
export TELEMETRY_ENABLED=false
|
||||||
export WAIT_FOR_LISTENING_PORT_ARGS="--path ping"
|
|
||||||
dos2unix scripts/integration.sh
|
dos2unix scripts/integration.sh
|
||||||
poetry run bash scripts/integration.sh ./reflex-examples/counter dev 8001 --backend-only --backend-port 8001
|
poetry run bash scripts/integration.sh ./reflex-examples/counter dev 8001 --backend-only --backend-port 8001
|
||||||
- name: Init Website for counter example
|
- name: Init Website for counter example
|
||||||
|
34
.github/workflows/performance.yml
vendored
Normal file
34
.github/workflows/performance.yml
vendored
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
name: performance-tests
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- "main" # or "master"
|
||||||
|
paths-ignore:
|
||||||
|
- "**/*.md"
|
||||||
|
pull_request:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
env:
|
||||||
|
TELEMETRY_ENABLED: false
|
||||||
|
NODE_OPTIONS: "--max_old_space_size=8192"
|
||||||
|
PR_TITLE: ${{ github.event.pull_request.title }}
|
||||||
|
APP_HARNESS_HEADLESS: 1
|
||||||
|
PYTHONUNBUFFERED: 1
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
benchmarks:
|
||||||
|
name: Run benchmarks
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: ./.github/actions/setup_build_env
|
||||||
|
with:
|
||||||
|
python-version: 3.12.8
|
||||||
|
run-poetry-install: true
|
||||||
|
create-venv-at-path: .venv
|
||||||
|
- name: Run benchmarks
|
||||||
|
uses: CodSpeedHQ/action@v3
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.CODSPEED_TOKEN }}
|
||||||
|
run: poetry run pytest tests/benchmarks --codspeed
|
10
.github/workflows/unit_tests.yml
vendored
10
.github/workflows/unit_tests.yml
vendored
@ -28,22 +28,18 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, windows-latest]
|
os: [ubuntu-latest, windows-latest]
|
||||||
python-version: ["3.9.21", "3.10.16", "3.11.11", "3.12.8", "3.13.1"]
|
python-version: ["3.10.16", "3.11.11", "3.12.8", "3.13.1"]
|
||||||
# Windows is a bit behind on Python version availability in Github
|
# Windows is a bit behind on Python version availability in Github
|
||||||
exclude:
|
exclude:
|
||||||
- os: windows-latest
|
- os: windows-latest
|
||||||
python-version: "3.11.11"
|
python-version: "3.11.11"
|
||||||
- os: windows-latest
|
- os: windows-latest
|
||||||
python-version: "3.10.16"
|
python-version: "3.10.16"
|
||||||
- os: windows-latest
|
|
||||||
python-version: "3.9.21"
|
|
||||||
include:
|
include:
|
||||||
- os: windows-latest
|
- os: windows-latest
|
||||||
python-version: "3.11.9"
|
python-version: "3.11.9"
|
||||||
- os: windows-latest
|
- os: windows-latest
|
||||||
python-version: "3.10.11"
|
python-version: "3.10.11"
|
||||||
- os: windows-latest
|
|
||||||
python-version: "3.9.13"
|
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
||||||
# Service containers to run with `runner-job`
|
# Service containers to run with `runner-job`
|
||||||
@ -92,8 +88,8 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
# Note: py39, py310, py311 versions chosen due to available arm64 darwin builds.
|
# Note: py310, py311 versions chosen due to available arm64 darwin builds.
|
||||||
python-version: ["3.9.13", "3.10.11", "3.11.9", "3.12.8", "3.13.1"]
|
python-version: ["3.10.11", "3.11.9", "3.12.8", "3.13.1"]
|
||||||
runs-on: macos-latest
|
runs-on: macos-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -4,6 +4,7 @@ assets/external/*
|
|||||||
dist/*
|
dist/*
|
||||||
examples/
|
examples/
|
||||||
.web
|
.web
|
||||||
|
.states
|
||||||
.idea
|
.idea
|
||||||
.vscode
|
.vscode
|
||||||
.coverage
|
.coverage
|
||||||
@ -14,3 +15,4 @@ requirements.txt
|
|||||||
.pyi_generator_last_run
|
.pyi_generator_last_run
|
||||||
.pyi_generator_diff
|
.pyi_generator_diff
|
||||||
reflex.db
|
reflex.db
|
||||||
|
.codspeed
|
@ -3,7 +3,7 @@ fail_fast: true
|
|||||||
repos:
|
repos:
|
||||||
|
|
||||||
- repo: https://github.com/charliermarsh/ruff-pre-commit
|
- repo: https://github.com/charliermarsh/ruff-pre-commit
|
||||||
rev: v0.8.2
|
rev: v0.9.6
|
||||||
hooks:
|
hooks:
|
||||||
- id: ruff-format
|
- id: ruff-format
|
||||||
args: [reflex, tests]
|
args: [reflex, tests]
|
||||||
@ -24,11 +24,12 @@ repos:
|
|||||||
name: update-pyi-files
|
name: update-pyi-files
|
||||||
always_run: true
|
always_run: true
|
||||||
language: system
|
language: system
|
||||||
|
require_serial: true
|
||||||
description: 'Update pyi files as needed'
|
description: 'Update pyi files as needed'
|
||||||
entry: python3 scripts/make_pyi.py
|
entry: python3 scripts/make_pyi.py
|
||||||
|
|
||||||
- repo: https://github.com/RobertCraigie/pyright-python
|
- repo: https://github.com/RobertCraigie/pyright-python
|
||||||
rev: v1.1.313
|
rev: v1.1.393
|
||||||
hooks:
|
hooks:
|
||||||
- id: pyright
|
- id: pyright
|
||||||
args: [reflex, tests]
|
args: [reflex, tests]
|
||||||
|
@ -8,7 +8,7 @@ Here is a quick guide on how to run Reflex repo locally so you can start contrib
|
|||||||
|
|
||||||
**Prerequisites:**
|
**Prerequisites:**
|
||||||
|
|
||||||
- Python >= 3.9
|
- Python >= 3.10
|
||||||
- Poetry version >= 1.4.0 and add it to your path (see [Poetry Docs](https://python-poetry.org/docs/#installation) for more info).
|
- Poetry version >= 1.4.0 and add it to your path (see [Poetry Docs](https://python-poetry.org/docs/#installation) for more info).
|
||||||
|
|
||||||
**1. Fork this repository:**
|
**1. Fork this repository:**
|
||||||
@ -87,7 +87,7 @@ poetry run ruff format .
|
|||||||
```
|
```
|
||||||
|
|
||||||
Consider installing git pre-commit hooks so Ruff, Pyright, Darglint and `make_pyi` will run automatically before each commit.
|
Consider installing git pre-commit hooks so Ruff, Pyright, Darglint and `make_pyi` will run automatically before each commit.
|
||||||
Note that pre-commit will only be installed when you use a Python version >= 3.9.
|
Note that pre-commit will only be installed when you use a Python version >= 3.10.
|
||||||
|
|
||||||
``` bash
|
``` bash
|
||||||
pre-commit install
|
pre-commit install
|
||||||
|
@ -34,7 +34,7 @@ See our [architecture page](https://reflex.dev/blog/2024-03-21-reflex-architectu
|
|||||||
|
|
||||||
## ⚙️ Installation
|
## ⚙️ Installation
|
||||||
|
|
||||||
Open a terminal and run (Requires Python 3.9+):
|
Open a terminal and run (Requires Python 3.10+):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pip install reflex
|
pip install reflex
|
||||||
|
@ -21,7 +21,7 @@ def get_package_size(venv_path: Path, os_name):
|
|||||||
ValueError: when venv does not exist or python version is None.
|
ValueError: when venv does not exist or python version is None.
|
||||||
"""
|
"""
|
||||||
python_version = get_python_version(venv_path, os_name)
|
python_version = get_python_version(venv_path, os_name)
|
||||||
print("Python version:", python_version) # noqa: T201
|
print("Python version:", python_version)
|
||||||
if python_version is None:
|
if python_version is None:
|
||||||
raise ValueError("Error: Failed to determine Python version.")
|
raise ValueError("Error: Failed to determine Python version.")
|
||||||
|
|
||||||
|
@ -1,376 +0,0 @@
|
|||||||
"""Benchmark tests for apps with varying component numbers."""
|
|
||||||
|
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
import functools
|
|
||||||
import time
|
|
||||||
from typing import Generator
|
|
||||||
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
from benchmarks import WINDOWS_SKIP_REASON
|
|
||||||
from reflex import constants
|
|
||||||
from reflex.compiler import utils
|
|
||||||
from reflex.testing import AppHarness, chdir
|
|
||||||
from reflex.utils import build
|
|
||||||
from reflex.utils.prerequisites import get_web_dir
|
|
||||||
|
|
||||||
web_pages = get_web_dir() / constants.Dirs.PAGES
|
|
||||||
|
|
||||||
|
|
||||||
def render_component(num: int):
|
|
||||||
"""Generate a number of components based on num.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
num: number of components to produce.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
The rendered number of components.
|
|
||||||
"""
|
|
||||||
import reflex as rx
|
|
||||||
|
|
||||||
return [
|
|
||||||
rx.fragment(
|
|
||||||
rx.box(
|
|
||||||
rx.accordion.root(
|
|
||||||
rx.accordion.item(
|
|
||||||
header="Full Ingredients", # type: ignore
|
|
||||||
content="Yes. It's built with accessibility in mind.", # type: ignore
|
|
||||||
font_size="3em",
|
|
||||||
),
|
|
||||||
rx.accordion.item(
|
|
||||||
header="Applications", # type: ignore
|
|
||||||
content="Yes. It's unstyled by default, giving you freedom over the look and feel.", # type: ignore
|
|
||||||
),
|
|
||||||
collapsible=True,
|
|
||||||
variant="ghost",
|
|
||||||
width="25rem",
|
|
||||||
),
|
|
||||||
padding_top="20px",
|
|
||||||
),
|
|
||||||
rx.box(
|
|
||||||
rx.drawer.root(
|
|
||||||
rx.drawer.trigger(
|
|
||||||
rx.button("Open Drawer with snap points"), as_child=True
|
|
||||||
),
|
|
||||||
rx.drawer.overlay(),
|
|
||||||
rx.drawer.portal(
|
|
||||||
rx.drawer.content(
|
|
||||||
rx.flex(
|
|
||||||
rx.drawer.title("Drawer Content"),
|
|
||||||
rx.drawer.description("Drawer description"),
|
|
||||||
rx.drawer.close(
|
|
||||||
rx.button("Close Button"),
|
|
||||||
as_child=True,
|
|
||||||
),
|
|
||||||
direction="column",
|
|
||||||
margin="5em",
|
|
||||||
align_items="center",
|
|
||||||
),
|
|
||||||
top="auto",
|
|
||||||
height="100%",
|
|
||||||
flex_direction="column",
|
|
||||||
background_color="var(--green-3)",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
snap_points=["148px", "355px", 1],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
rx.box(
|
|
||||||
rx.callout(
|
|
||||||
"You will need admin privileges to install and access this application.",
|
|
||||||
icon="info",
|
|
||||||
size="3",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
rx.box(
|
|
||||||
rx.table.root(
|
|
||||||
rx.table.header(
|
|
||||||
rx.table.row(
|
|
||||||
rx.table.column_header_cell("Full name"),
|
|
||||||
rx.table.column_header_cell("Email"),
|
|
||||||
rx.table.column_header_cell("Group"),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
rx.table.body(
|
|
||||||
rx.table.row(
|
|
||||||
rx.table.row_header_cell("Danilo Sousa"),
|
|
||||||
rx.table.cell("danilo@example.com"),
|
|
||||||
rx.table.cell("Developer"),
|
|
||||||
),
|
|
||||||
rx.table.row(
|
|
||||||
rx.table.row_header_cell("Zahra Ambessa"),
|
|
||||||
rx.table.cell("zahra@example.com"),
|
|
||||||
rx.table.cell("Admin"),
|
|
||||||
),
|
|
||||||
rx.table.row(
|
|
||||||
rx.table.row_header_cell("Jasper Eriksson"),
|
|
||||||
rx.table.cell("jasper@example.com"),
|
|
||||||
rx.table.cell("Developer"),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
),
|
|
||||||
)
|
|
||||||
] * num
|
|
||||||
|
|
||||||
|
|
||||||
def AppWithTenComponentsOnePage():
|
|
||||||
"""A reflex app with roughly 10 components on one page."""
|
|
||||||
import reflex as rx
|
|
||||||
|
|
||||||
def index() -> rx.Component:
|
|
||||||
return rx.center(rx.vstack(*render_component(1)))
|
|
||||||
|
|
||||||
app = rx.App(state=rx.State)
|
|
||||||
app.add_page(index)
|
|
||||||
|
|
||||||
|
|
||||||
def AppWithHundredComponentOnePage():
|
|
||||||
"""A reflex app with roughly 100 components on one page."""
|
|
||||||
import reflex as rx
|
|
||||||
|
|
||||||
def index() -> rx.Component:
|
|
||||||
return rx.center(rx.vstack(*render_component(100)))
|
|
||||||
|
|
||||||
app = rx.App(state=rx.State)
|
|
||||||
app.add_page(index)
|
|
||||||
|
|
||||||
|
|
||||||
def AppWithThousandComponentsOnePage():
|
|
||||||
"""A reflex app with roughly 1000 components on one page."""
|
|
||||||
import reflex as rx
|
|
||||||
|
|
||||||
def index() -> rx.Component:
|
|
||||||
return rx.center(rx.vstack(*render_component(1000)))
|
|
||||||
|
|
||||||
app = rx.App(state=rx.State)
|
|
||||||
app.add_page(index)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
|
||||||
def app_with_10_components(
|
|
||||||
tmp_path_factory,
|
|
||||||
) -> Generator[AppHarness, None, None]:
|
|
||||||
"""Start Blank Template app at tmp_path via AppHarness.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
tmp_path_factory: pytest tmp_path_factory fixture
|
|
||||||
|
|
||||||
Yields:
|
|
||||||
running AppHarness instance
|
|
||||||
"""
|
|
||||||
root = tmp_path_factory.mktemp("app10components")
|
|
||||||
|
|
||||||
yield AppHarness.create(
|
|
||||||
root=root,
|
|
||||||
app_source=functools.partial(
|
|
||||||
AppWithTenComponentsOnePage,
|
|
||||||
render_component=render_component, # type: ignore
|
|
||||||
),
|
|
||||||
) # type: ignore
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
|
||||||
def app_with_100_components(
|
|
||||||
tmp_path_factory,
|
|
||||||
) -> Generator[AppHarness, None, None]:
|
|
||||||
"""Start Blank Template app at tmp_path via AppHarness.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
tmp_path_factory: pytest tmp_path_factory fixture
|
|
||||||
|
|
||||||
Yields:
|
|
||||||
running AppHarness instance
|
|
||||||
"""
|
|
||||||
root = tmp_path_factory.mktemp("app100components")
|
|
||||||
|
|
||||||
yield AppHarness.create(
|
|
||||||
root=root,
|
|
||||||
app_source=functools.partial(
|
|
||||||
AppWithHundredComponentOnePage,
|
|
||||||
render_component=render_component, # type: ignore
|
|
||||||
),
|
|
||||||
) # type: ignore
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
|
||||||
def app_with_1000_components(
|
|
||||||
tmp_path_factory,
|
|
||||||
) -> Generator[AppHarness, None, None]:
|
|
||||||
"""Create an app with 1000 components at tmp_path via AppHarness.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
tmp_path_factory: pytest tmp_path_factory fixture
|
|
||||||
|
|
||||||
Yields:
|
|
||||||
an AppHarness instance
|
|
||||||
"""
|
|
||||||
root = tmp_path_factory.mktemp("app1000components")
|
|
||||||
|
|
||||||
yield AppHarness.create(
|
|
||||||
root=root,
|
|
||||||
app_source=functools.partial(
|
|
||||||
AppWithThousandComponentsOnePage,
|
|
||||||
render_component=render_component, # type: ignore
|
|
||||||
),
|
|
||||||
) # type: ignore
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(constants.IS_WINDOWS, reason=WINDOWS_SKIP_REASON)
|
|
||||||
@pytest.mark.benchmark(
|
|
||||||
group="Compile time of varying component numbers",
|
|
||||||
timer=time.perf_counter,
|
|
||||||
disable_gc=True,
|
|
||||||
warmup=False,
|
|
||||||
)
|
|
||||||
def test_app_10_compile_time_cold(benchmark, app_with_10_components):
|
|
||||||
"""Test the compile time on a cold start for an app with roughly 10 components.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
benchmark: The benchmark fixture.
|
|
||||||
app_with_10_components: The app harness.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def setup():
|
|
||||||
with chdir(app_with_10_components.app_path):
|
|
||||||
utils.empty_dir(web_pages, ["_app.js"])
|
|
||||||
app_with_10_components._initialize_app()
|
|
||||||
build.setup_frontend(app_with_10_components.app_path)
|
|
||||||
|
|
||||||
def benchmark_fn():
|
|
||||||
with chdir(app_with_10_components.app_path):
|
|
||||||
app_with_10_components.app_instance._compile()
|
|
||||||
|
|
||||||
benchmark.pedantic(benchmark_fn, setup=setup, rounds=10)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.benchmark(
|
|
||||||
group="Compile time of varying component numbers",
|
|
||||||
min_rounds=5,
|
|
||||||
timer=time.perf_counter,
|
|
||||||
disable_gc=True,
|
|
||||||
warmup=False,
|
|
||||||
)
|
|
||||||
def test_app_10_compile_time_warm(benchmark, app_with_10_components):
|
|
||||||
"""Test the compile time on a warm start for an app with roughly 10 components.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
benchmark: The benchmark fixture.
|
|
||||||
app_with_10_components: The app harness.
|
|
||||||
"""
|
|
||||||
with chdir(app_with_10_components.app_path):
|
|
||||||
app_with_10_components._initialize_app()
|
|
||||||
build.setup_frontend(app_with_10_components.app_path)
|
|
||||||
|
|
||||||
def benchmark_fn():
|
|
||||||
with chdir(app_with_10_components.app_path):
|
|
||||||
app_with_10_components.app_instance._compile()
|
|
||||||
|
|
||||||
benchmark(benchmark_fn)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(constants.IS_WINDOWS, reason=WINDOWS_SKIP_REASON)
|
|
||||||
@pytest.mark.benchmark(
|
|
||||||
group="Compile time of varying component numbers",
|
|
||||||
timer=time.perf_counter,
|
|
||||||
disable_gc=True,
|
|
||||||
warmup=False,
|
|
||||||
)
|
|
||||||
def test_app_100_compile_time_cold(benchmark, app_with_100_components):
|
|
||||||
"""Test the compile time on a cold start for an app with roughly 100 components.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
benchmark: The benchmark fixture.
|
|
||||||
app_with_100_components: The app harness.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def setup():
|
|
||||||
with chdir(app_with_100_components.app_path):
|
|
||||||
utils.empty_dir(web_pages, ["_app.js"])
|
|
||||||
app_with_100_components._initialize_app()
|
|
||||||
build.setup_frontend(app_with_100_components.app_path)
|
|
||||||
|
|
||||||
def benchmark_fn():
|
|
||||||
with chdir(app_with_100_components.app_path):
|
|
||||||
app_with_100_components.app_instance._compile()
|
|
||||||
|
|
||||||
benchmark.pedantic(benchmark_fn, setup=setup, rounds=5)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.benchmark(
|
|
||||||
group="Compile time of varying component numbers",
|
|
||||||
min_rounds=5,
|
|
||||||
timer=time.perf_counter,
|
|
||||||
disable_gc=True,
|
|
||||||
warmup=False,
|
|
||||||
)
|
|
||||||
def test_app_100_compile_time_warm(benchmark, app_with_100_components):
|
|
||||||
"""Test the compile time on a warm start for an app with roughly 100 components.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
benchmark: The benchmark fixture.
|
|
||||||
app_with_100_components: The app harness.
|
|
||||||
"""
|
|
||||||
with chdir(app_with_100_components.app_path):
|
|
||||||
app_with_100_components._initialize_app()
|
|
||||||
build.setup_frontend(app_with_100_components.app_path)
|
|
||||||
|
|
||||||
def benchmark_fn():
|
|
||||||
with chdir(app_with_100_components.app_path):
|
|
||||||
app_with_100_components.app_instance._compile()
|
|
||||||
|
|
||||||
benchmark(benchmark_fn)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(constants.IS_WINDOWS, reason=WINDOWS_SKIP_REASON)
|
|
||||||
@pytest.mark.benchmark(
|
|
||||||
group="Compile time of varying component numbers",
|
|
||||||
timer=time.perf_counter,
|
|
||||||
disable_gc=True,
|
|
||||||
warmup=False,
|
|
||||||
)
|
|
||||||
def test_app_1000_compile_time_cold(benchmark, app_with_1000_components):
|
|
||||||
"""Test the compile time on a cold start for an app with roughly 1000 components.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
benchmark: The benchmark fixture.
|
|
||||||
app_with_1000_components: The app harness.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def setup():
|
|
||||||
with chdir(app_with_1000_components.app_path):
|
|
||||||
utils.empty_dir(web_pages, keep_files=["_app.js"])
|
|
||||||
app_with_1000_components._initialize_app()
|
|
||||||
build.setup_frontend(app_with_1000_components.app_path)
|
|
||||||
|
|
||||||
def benchmark_fn():
|
|
||||||
with chdir(app_with_1000_components.app_path):
|
|
||||||
app_with_1000_components.app_instance._compile()
|
|
||||||
|
|
||||||
benchmark.pedantic(benchmark_fn, setup=setup, rounds=5)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.benchmark(
|
|
||||||
group="Compile time of varying component numbers",
|
|
||||||
min_rounds=5,
|
|
||||||
timer=time.perf_counter,
|
|
||||||
disable_gc=True,
|
|
||||||
warmup=False,
|
|
||||||
)
|
|
||||||
def test_app_1000_compile_time_warm(benchmark, app_with_1000_components):
|
|
||||||
"""Test the compile time on a warm start for an app with roughly 1000 components.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
benchmark: The benchmark fixture.
|
|
||||||
app_with_1000_components: The app harness.
|
|
||||||
"""
|
|
||||||
with chdir(app_with_1000_components.app_path):
|
|
||||||
app_with_1000_components._initialize_app()
|
|
||||||
build.setup_frontend(app_with_1000_components.app_path)
|
|
||||||
|
|
||||||
def benchmark_fn():
|
|
||||||
with chdir(app_with_1000_components.app_path):
|
|
||||||
app_with_1000_components.app_instance._compile()
|
|
||||||
|
|
||||||
benchmark(benchmark_fn)
|
|
@ -1,579 +0,0 @@
|
|||||||
"""Benchmark tests for apps with varying page numbers."""
|
|
||||||
|
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
import functools
|
|
||||||
import time
|
|
||||||
from typing import Generator
|
|
||||||
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
from benchmarks import WINDOWS_SKIP_REASON
|
|
||||||
from reflex import constants
|
|
||||||
from reflex.compiler import utils
|
|
||||||
from reflex.testing import AppHarness, chdir
|
|
||||||
from reflex.utils import build
|
|
||||||
from reflex.utils.prerequisites import get_web_dir
|
|
||||||
|
|
||||||
web_pages = get_web_dir() / constants.Dirs.PAGES
|
|
||||||
|
|
||||||
|
|
||||||
def render_multiple_pages(app, num: int):
|
|
||||||
"""Add multiple pages based on num.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
app: The App object.
|
|
||||||
num: number of pages to render.
|
|
||||||
|
|
||||||
"""
|
|
||||||
from typing import Tuple
|
|
||||||
|
|
||||||
from rxconfig import config # type: ignore
|
|
||||||
|
|
||||||
import reflex as rx
|
|
||||||
|
|
||||||
docs_url = "https://reflex.dev/docs/getting-started/introduction/"
|
|
||||||
filename = f"{config.app_name}/{config.app_name}.py"
|
|
||||||
college = [
|
|
||||||
"Stanford University",
|
|
||||||
"Arizona",
|
|
||||||
"Arizona state",
|
|
||||||
"Baylor",
|
|
||||||
"Boston College",
|
|
||||||
"Boston University",
|
|
||||||
]
|
|
||||||
|
|
||||||
class State(rx.State):
|
|
||||||
"""The app state."""
|
|
||||||
|
|
||||||
position: str
|
|
||||||
college: str
|
|
||||||
age: Tuple[int, int] = (18, 50)
|
|
||||||
salary: Tuple[int, int] = (0, 25000000)
|
|
||||||
|
|
||||||
comp1 = rx.center(
|
|
||||||
rx.theme_panel(),
|
|
||||||
rx.vstack(
|
|
||||||
rx.heading("Welcome to Reflex!", size="9"),
|
|
||||||
rx.text("Get started by editing ", rx.code(filename)),
|
|
||||||
rx.button(
|
|
||||||
"Check out our docs!",
|
|
||||||
on_click=lambda: rx.redirect(docs_url),
|
|
||||||
size="4",
|
|
||||||
),
|
|
||||||
align="center",
|
|
||||||
spacing="7",
|
|
||||||
font_size="2em",
|
|
||||||
),
|
|
||||||
height="100vh",
|
|
||||||
)
|
|
||||||
|
|
||||||
comp2 = rx.vstack(
|
|
||||||
rx.hstack(
|
|
||||||
rx.vstack(
|
|
||||||
rx.select(
|
|
||||||
["C", "PF", "SF", "PG", "SG"],
|
|
||||||
placeholder="Select a position. (All)",
|
|
||||||
on_change=State.set_position, # type: ignore
|
|
||||||
size="3",
|
|
||||||
),
|
|
||||||
rx.select(
|
|
||||||
college,
|
|
||||||
placeholder="Select a college. (All)",
|
|
||||||
on_change=State.set_college, # type: ignore
|
|
||||||
size="3",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
rx.vstack(
|
|
||||||
rx.vstack(
|
|
||||||
rx.hstack(
|
|
||||||
rx.badge("Min Age: ", State.age[0]),
|
|
||||||
rx.divider(orientation="vertical"),
|
|
||||||
rx.badge("Max Age: ", State.age[1]),
|
|
||||||
),
|
|
||||||
rx.slider(
|
|
||||||
default_value=[18, 50],
|
|
||||||
min=18,
|
|
||||||
max=50,
|
|
||||||
on_value_commit=State.set_age, # type: ignore
|
|
||||||
),
|
|
||||||
align_items="left",
|
|
||||||
width="100%",
|
|
||||||
),
|
|
||||||
rx.vstack(
|
|
||||||
rx.hstack(
|
|
||||||
rx.badge("Min Sal: ", State.salary[0] // 1000000, "M"),
|
|
||||||
rx.divider(orientation="vertical"),
|
|
||||||
rx.badge("Max Sal: ", State.salary[1] // 1000000, "M"),
|
|
||||||
),
|
|
||||||
rx.slider(
|
|
||||||
default_value=[0, 25000000],
|
|
||||||
min=0,
|
|
||||||
max=25000000,
|
|
||||||
on_value_commit=State.set_salary, # type: ignore
|
|
||||||
),
|
|
||||||
align_items="left",
|
|
||||||
width="100%",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
spacing="4",
|
|
||||||
),
|
|
||||||
width="100%",
|
|
||||||
)
|
|
||||||
|
|
||||||
for i in range(1, num + 1):
|
|
||||||
if i % 2 == 1:
|
|
||||||
app.add_page(comp1, route=f"page{i}")
|
|
||||||
else:
|
|
||||||
app.add_page(comp2, route=f"page{i}")
|
|
||||||
|
|
||||||
|
|
||||||
def AppWithOnePage():
|
|
||||||
"""A reflex app with one page."""
|
|
||||||
from rxconfig import config # type: ignore
|
|
||||||
|
|
||||||
import reflex as rx
|
|
||||||
|
|
||||||
docs_url = "https://reflex.dev/docs/getting-started/introduction/"
|
|
||||||
filename = f"{config.app_name}/{config.app_name}.py"
|
|
||||||
|
|
||||||
class State(rx.State):
|
|
||||||
"""The app state."""
|
|
||||||
|
|
||||||
pass
|
|
||||||
|
|
||||||
def index() -> rx.Component:
|
|
||||||
return rx.center(
|
|
||||||
rx.input(
|
|
||||||
id="token", value=State.router.session.client_token, is_read_only=True
|
|
||||||
),
|
|
||||||
rx.vstack(
|
|
||||||
rx.heading("Welcome to Reflex!", size="9"),
|
|
||||||
rx.text("Get started by editing ", rx.code(filename)),
|
|
||||||
rx.button(
|
|
||||||
"Check out our docs!",
|
|
||||||
on_click=lambda: rx.redirect(docs_url),
|
|
||||||
size="4",
|
|
||||||
),
|
|
||||||
align="center",
|
|
||||||
spacing="7",
|
|
||||||
font_size="2em",
|
|
||||||
),
|
|
||||||
height="100vh",
|
|
||||||
)
|
|
||||||
|
|
||||||
app = rx.App(state=rx.State)
|
|
||||||
app.add_page(index)
|
|
||||||
|
|
||||||
|
|
||||||
def AppWithTenPages():
|
|
||||||
"""A reflex app with 10 pages."""
|
|
||||||
import reflex as rx
|
|
||||||
|
|
||||||
app = rx.App(state=rx.State)
|
|
||||||
render_multiple_pages(app, 10)
|
|
||||||
|
|
||||||
|
|
||||||
def AppWithHundredPages():
|
|
||||||
"""A reflex app with 100 pages."""
|
|
||||||
import reflex as rx
|
|
||||||
|
|
||||||
app = rx.App(state=rx.State)
|
|
||||||
render_multiple_pages(app, 100)
|
|
||||||
|
|
||||||
|
|
||||||
def AppWithThousandPages():
|
|
||||||
"""A reflex app with Thousand pages."""
|
|
||||||
import reflex as rx
|
|
||||||
|
|
||||||
app = rx.App(state=rx.State)
|
|
||||||
render_multiple_pages(app, 1000)
|
|
||||||
|
|
||||||
|
|
||||||
def AppWithTenThousandPages():
|
|
||||||
"""A reflex app with ten thousand pages."""
|
|
||||||
import reflex as rx
|
|
||||||
|
|
||||||
app = rx.App(state=rx.State)
|
|
||||||
render_multiple_pages(app, 10000)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
|
||||||
def app_with_one_page(
|
|
||||||
tmp_path_factory,
|
|
||||||
) -> Generator[AppHarness, None, None]:
|
|
||||||
"""Create an app with 10000 pages at tmp_path via AppHarness.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
tmp_path_factory: pytest tmp_path_factory fixture
|
|
||||||
|
|
||||||
Yields:
|
|
||||||
an AppHarness instance
|
|
||||||
"""
|
|
||||||
root = tmp_path_factory.mktemp("app1")
|
|
||||||
|
|
||||||
yield AppHarness.create(root=root, app_source=AppWithOnePage)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
|
||||||
def app_with_ten_pages(
|
|
||||||
tmp_path_factory,
|
|
||||||
) -> Generator[AppHarness, None, None]:
|
|
||||||
"""Create an app with 10 pages at tmp_path via AppHarness.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
tmp_path_factory: pytest tmp_path_factory fixture
|
|
||||||
|
|
||||||
Yields:
|
|
||||||
an AppHarness instance
|
|
||||||
"""
|
|
||||||
root = tmp_path_factory.mktemp("app10")
|
|
||||||
yield AppHarness.create(
|
|
||||||
root=root,
|
|
||||||
app_source=functools.partial(
|
|
||||||
AppWithTenPages,
|
|
||||||
render_comp=render_multiple_pages, # type: ignore
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
|
||||||
def app_with_hundred_pages(
|
|
||||||
tmp_path_factory,
|
|
||||||
) -> Generator[AppHarness, None, None]:
|
|
||||||
"""Create an app with 100 pages at tmp_path via AppHarness.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
tmp_path_factory: pytest tmp_path_factory fixture
|
|
||||||
|
|
||||||
Yields:
|
|
||||||
an AppHarness instance
|
|
||||||
"""
|
|
||||||
root = tmp_path_factory.mktemp("app100")
|
|
||||||
|
|
||||||
yield AppHarness.create(
|
|
||||||
root=root,
|
|
||||||
app_source=functools.partial(
|
|
||||||
AppWithHundredPages,
|
|
||||||
render_comp=render_multiple_pages, # type: ignore
|
|
||||||
),
|
|
||||||
) # type: ignore
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
|
||||||
def app_with_thousand_pages(
|
|
||||||
tmp_path_factory,
|
|
||||||
) -> Generator[AppHarness, None, None]:
|
|
||||||
"""Create an app with 1000 pages at tmp_path via AppHarness.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
tmp_path_factory: pytest tmp_path_factory fixture
|
|
||||||
|
|
||||||
Yields:
|
|
||||||
an AppHarness instance
|
|
||||||
"""
|
|
||||||
root = tmp_path_factory.mktemp("app1000")
|
|
||||||
|
|
||||||
yield AppHarness.create(
|
|
||||||
root=root,
|
|
||||||
app_source=functools.partial(
|
|
||||||
AppWithThousandPages,
|
|
||||||
render_comp=render_multiple_pages, # type: ignore
|
|
||||||
),
|
|
||||||
) # type: ignore
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
|
||||||
def app_with_ten_thousand_pages(
|
|
||||||
tmp_path_factory,
|
|
||||||
) -> Generator[AppHarness, None, None]:
|
|
||||||
"""Create an app with 10000 pages at tmp_path via AppHarness.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
tmp_path_factory: pytest tmp_path_factory fixture
|
|
||||||
|
|
||||||
Yields:
|
|
||||||
running AppHarness instance
|
|
||||||
"""
|
|
||||||
root = tmp_path_factory.mktemp("app10000")
|
|
||||||
|
|
||||||
yield AppHarness.create(
|
|
||||||
root=root,
|
|
||||||
app_source=functools.partial(
|
|
||||||
AppWithTenThousandPages,
|
|
||||||
render_comp=render_multiple_pages, # type: ignore
|
|
||||||
),
|
|
||||||
) # type: ignore
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(constants.IS_WINDOWS, reason=WINDOWS_SKIP_REASON)
|
|
||||||
@pytest.mark.benchmark(
|
|
||||||
group="Compile time of varying page numbers",
|
|
||||||
timer=time.perf_counter,
|
|
||||||
disable_gc=True,
|
|
||||||
warmup=False,
|
|
||||||
)
|
|
||||||
def test_app_1_compile_time_cold(benchmark, app_with_one_page):
|
|
||||||
"""Test the compile time on a cold start for an app with 1 page.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
benchmark: The benchmark fixture.
|
|
||||||
app_with_one_page: The app harness.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def setup():
|
|
||||||
with chdir(app_with_one_page.app_path):
|
|
||||||
utils.empty_dir(web_pages, keep_files=["_app.js"])
|
|
||||||
app_with_one_page._initialize_app()
|
|
||||||
build.setup_frontend(app_with_one_page.app_path)
|
|
||||||
|
|
||||||
def benchmark_fn():
|
|
||||||
with chdir(app_with_one_page.app_path):
|
|
||||||
app_with_one_page.app_instance._compile()
|
|
||||||
|
|
||||||
benchmark.pedantic(benchmark_fn, setup=setup, rounds=5)
|
|
||||||
app_with_one_page._reload_state_module()
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.benchmark(
|
|
||||||
group="Compile time of varying page numbers",
|
|
||||||
min_rounds=5,
|
|
||||||
timer=time.perf_counter,
|
|
||||||
disable_gc=True,
|
|
||||||
warmup=False,
|
|
||||||
)
|
|
||||||
def test_app_1_compile_time_warm(benchmark, app_with_one_page):
|
|
||||||
"""Test the compile time on a warm start for an app with 1 page.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
benchmark: The benchmark fixture.
|
|
||||||
app_with_one_page: The app harness.
|
|
||||||
"""
|
|
||||||
with chdir(app_with_one_page.app_path):
|
|
||||||
app_with_one_page._initialize_app()
|
|
||||||
build.setup_frontend(app_with_one_page.app_path)
|
|
||||||
|
|
||||||
def benchmark_fn():
|
|
||||||
with chdir(app_with_one_page.app_path):
|
|
||||||
app_with_one_page.app_instance._compile()
|
|
||||||
|
|
||||||
benchmark(benchmark_fn)
|
|
||||||
app_with_one_page._reload_state_module()
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(constants.IS_WINDOWS, reason=WINDOWS_SKIP_REASON)
|
|
||||||
@pytest.mark.benchmark(
|
|
||||||
group="Compile time of varying page numbers",
|
|
||||||
timer=time.perf_counter,
|
|
||||||
disable_gc=True,
|
|
||||||
warmup=False,
|
|
||||||
)
|
|
||||||
def test_app_10_compile_time_cold(benchmark, app_with_ten_pages):
|
|
||||||
"""Test the compile time on a cold start for an app with 10 page.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
benchmark: The benchmark fixture.
|
|
||||||
app_with_ten_pages: The app harness.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def setup():
|
|
||||||
with chdir(app_with_ten_pages.app_path):
|
|
||||||
utils.empty_dir(web_pages, keep_files=["_app.js"])
|
|
||||||
app_with_ten_pages._initialize_app()
|
|
||||||
build.setup_frontend(app_with_ten_pages.app_path)
|
|
||||||
|
|
||||||
def benchmark_fn():
|
|
||||||
with chdir(app_with_ten_pages.app_path):
|
|
||||||
app_with_ten_pages.app_instance._compile()
|
|
||||||
|
|
||||||
benchmark.pedantic(benchmark_fn, setup=setup, rounds=5)
|
|
||||||
app_with_ten_pages._reload_state_module()
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.benchmark(
|
|
||||||
group="Compile time of varying page numbers",
|
|
||||||
min_rounds=5,
|
|
||||||
timer=time.perf_counter,
|
|
||||||
disable_gc=True,
|
|
||||||
warmup=False,
|
|
||||||
)
|
|
||||||
def test_app_10_compile_time_warm(benchmark, app_with_ten_pages):
|
|
||||||
"""Test the compile time on a warm start for an app with 10 page.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
benchmark: The benchmark fixture.
|
|
||||||
app_with_ten_pages: The app harness.
|
|
||||||
"""
|
|
||||||
with chdir(app_with_ten_pages.app_path):
|
|
||||||
app_with_ten_pages._initialize_app()
|
|
||||||
build.setup_frontend(app_with_ten_pages.app_path)
|
|
||||||
|
|
||||||
def benchmark_fn():
|
|
||||||
with chdir(app_with_ten_pages.app_path):
|
|
||||||
app_with_ten_pages.app_instance._compile()
|
|
||||||
|
|
||||||
benchmark(benchmark_fn)
|
|
||||||
app_with_ten_pages._reload_state_module()
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(constants.IS_WINDOWS, reason=WINDOWS_SKIP_REASON)
|
|
||||||
@pytest.mark.benchmark(
|
|
||||||
group="Compile time of varying page numbers",
|
|
||||||
timer=time.perf_counter,
|
|
||||||
disable_gc=True,
|
|
||||||
warmup=False,
|
|
||||||
)
|
|
||||||
def test_app_100_compile_time_cold(benchmark, app_with_hundred_pages):
|
|
||||||
"""Test the compile time on a cold start for an app with 100 page.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
benchmark: The benchmark fixture.
|
|
||||||
app_with_hundred_pages: The app harness.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def setup():
|
|
||||||
with chdir(app_with_hundred_pages.app_path):
|
|
||||||
utils.empty_dir(web_pages, keep_files=["_app.js"])
|
|
||||||
app_with_hundred_pages._initialize_app()
|
|
||||||
build.setup_frontend(app_with_hundred_pages.app_path)
|
|
||||||
|
|
||||||
def benchmark_fn():
|
|
||||||
with chdir(app_with_hundred_pages.app_path):
|
|
||||||
app_with_hundred_pages.app_instance._compile()
|
|
||||||
|
|
||||||
benchmark.pedantic(benchmark_fn, setup=setup, rounds=5)
|
|
||||||
app_with_hundred_pages._reload_state_module()
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.benchmark(
|
|
||||||
group="Compile time of varying page numbers",
|
|
||||||
min_rounds=5,
|
|
||||||
timer=time.perf_counter,
|
|
||||||
disable_gc=True,
|
|
||||||
warmup=False,
|
|
||||||
)
|
|
||||||
def test_app_100_compile_time_warm(benchmark, app_with_hundred_pages):
|
|
||||||
"""Test the compile time on a warm start for an app with 100 page.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
benchmark: The benchmark fixture.
|
|
||||||
app_with_hundred_pages: The app harness.
|
|
||||||
"""
|
|
||||||
with chdir(app_with_hundred_pages.app_path):
|
|
||||||
app_with_hundred_pages._initialize_app()
|
|
||||||
build.setup_frontend(app_with_hundred_pages.app_path)
|
|
||||||
|
|
||||||
def benchmark_fn():
|
|
||||||
with chdir(app_with_hundred_pages.app_path):
|
|
||||||
app_with_hundred_pages.app_instance._compile()
|
|
||||||
|
|
||||||
benchmark(benchmark_fn)
|
|
||||||
app_with_hundred_pages._reload_state_module()
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(constants.IS_WINDOWS, reason=WINDOWS_SKIP_REASON)
|
|
||||||
@pytest.mark.benchmark(
|
|
||||||
group="Compile time of varying page numbers",
|
|
||||||
timer=time.perf_counter,
|
|
||||||
disable_gc=True,
|
|
||||||
warmup=False,
|
|
||||||
)
|
|
||||||
def test_app_1000_compile_time_cold(benchmark, app_with_thousand_pages):
|
|
||||||
"""Test the compile time on a cold start for an app with 1000 page.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
benchmark: The benchmark fixture.
|
|
||||||
app_with_thousand_pages: The app harness.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def setup():
|
|
||||||
with chdir(app_with_thousand_pages.app_path):
|
|
||||||
utils.empty_dir(web_pages, keep_files=["_app.js"])
|
|
||||||
app_with_thousand_pages._initialize_app()
|
|
||||||
build.setup_frontend(app_with_thousand_pages.app_path)
|
|
||||||
|
|
||||||
def benchmark_fn():
|
|
||||||
with chdir(app_with_thousand_pages.app_path):
|
|
||||||
app_with_thousand_pages.app_instance._compile()
|
|
||||||
|
|
||||||
benchmark.pedantic(benchmark_fn, setup=setup, rounds=5)
|
|
||||||
app_with_thousand_pages._reload_state_module()
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.benchmark(
|
|
||||||
group="Compile time of varying page numbers",
|
|
||||||
min_rounds=5,
|
|
||||||
timer=time.perf_counter,
|
|
||||||
disable_gc=True,
|
|
||||||
warmup=False,
|
|
||||||
)
|
|
||||||
def test_app_1000_compile_time_warm(benchmark, app_with_thousand_pages):
|
|
||||||
"""Test the compile time on a warm start for an app with 1000 page.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
benchmark: The benchmark fixture.
|
|
||||||
app_with_thousand_pages: The app harness.
|
|
||||||
"""
|
|
||||||
with chdir(app_with_thousand_pages.app_path):
|
|
||||||
app_with_thousand_pages._initialize_app()
|
|
||||||
build.setup_frontend(app_with_thousand_pages.app_path)
|
|
||||||
|
|
||||||
def benchmark_fn():
|
|
||||||
with chdir(app_with_thousand_pages.app_path):
|
|
||||||
app_with_thousand_pages.app_instance._compile()
|
|
||||||
|
|
||||||
benchmark(benchmark_fn)
|
|
||||||
app_with_thousand_pages._reload_state_module()
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skip
|
|
||||||
@pytest.mark.benchmark(
|
|
||||||
group="Compile time of varying page numbers",
|
|
||||||
timer=time.perf_counter,
|
|
||||||
disable_gc=True,
|
|
||||||
warmup=False,
|
|
||||||
)
|
|
||||||
def test_app_10000_compile_time_cold(benchmark, app_with_ten_thousand_pages):
|
|
||||||
"""Test the compile time on a cold start for an app with 10000 page.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
benchmark: The benchmark fixture.
|
|
||||||
app_with_ten_thousand_pages: The app harness.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def setup():
|
|
||||||
with chdir(app_with_ten_thousand_pages.app_path):
|
|
||||||
utils.empty_dir(web_pages, keep_files=["_app.js"])
|
|
||||||
app_with_ten_thousand_pages._initialize_app()
|
|
||||||
build.setup_frontend(app_with_ten_thousand_pages.app_path)
|
|
||||||
|
|
||||||
def benchmark_fn():
|
|
||||||
with chdir(app_with_ten_thousand_pages.app_path):
|
|
||||||
app_with_ten_thousand_pages.app_instance._compile()
|
|
||||||
|
|
||||||
benchmark.pedantic(benchmark_fn, setup=setup, rounds=5)
|
|
||||||
app_with_ten_thousand_pages._reload_state_module()
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skip
|
|
||||||
@pytest.mark.benchmark(
|
|
||||||
group="Compile time of varying page numbers",
|
|
||||||
min_rounds=5,
|
|
||||||
timer=time.perf_counter,
|
|
||||||
disable_gc=True,
|
|
||||||
warmup=False,
|
|
||||||
)
|
|
||||||
def test_app_10000_compile_time_warm(benchmark, app_with_ten_thousand_pages):
|
|
||||||
"""Test the compile time on a warm start for an app with 10000 page.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
benchmark: The benchmark fixture.
|
|
||||||
app_with_ten_thousand_pages: The app harness.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def benchmark_fn():
|
|
||||||
with chdir(app_with_ten_thousand_pages.app_path):
|
|
||||||
app_with_ten_thousand_pages.app_instance._compile()
|
|
||||||
|
|
||||||
benchmark(benchmark_fn)
|
|
||||||
app_with_ten_thousand_pages._reload_state_module()
|
|
@ -34,7 +34,7 @@ Auf unserer [Architektur-Seite](https://reflex.dev/blog/2024-03-21-reflex-archit
|
|||||||
|
|
||||||
## ⚙️ Installation
|
## ⚙️ Installation
|
||||||
|
|
||||||
Öffne ein Terminal und führe den folgenden Befehl aus (benötigt Python 3.9+):
|
Öffne ein Terminal und führe den folgenden Befehl aus (benötigt Python 3.10+):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pip install reflex
|
pip install reflex
|
||||||
|
@ -35,7 +35,7 @@ Consulta nuestra [página de arquitectura](https://reflex.dev/blog/2024-03-21-re
|
|||||||
|
|
||||||
## ⚙️ Instalación
|
## ⚙️ Instalación
|
||||||
|
|
||||||
Abra un terminal y ejecute (Requiere Python 3.9+):
|
Abra un terminal y ejecute (Requiere Python 3.10+):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pip install reflex
|
pip install reflex
|
||||||
@ -239,7 +239,7 @@ Reflex se lanzó en diciembre de 2022 con el nombre de Pynecone.
|
|||||||
- **Discusiones de GitHub**: Una excelente manera de hablar sobre las características que deseas agregar o las cosas que te resultan confusas o necesitan aclaración.
|
- **Discusiones de GitHub**: Una excelente manera de hablar sobre las características que deseas agregar o las cosas que te resultan confusas o necesitan aclaración.
|
||||||
- **GitHub Issues**: Las incidencias son una forma excelente de informar de errores. Además, puedes intentar resolver un problema existente y enviar un PR.
|
- **GitHub Issues**: Las incidencias son una forma excelente de informar de errores. Además, puedes intentar resolver un problema existente y enviar un PR.
|
||||||
|
|
||||||
Buscamos colaboradores, sin importar su nivel o experiencia. Para contribuir consulta [CONTIBUTING.md](https://github.com/reflex-dev/reflex/blob/main/CONTRIBUTING.md)
|
Buscamos colaboradores, sin importar su nivel o experiencia. Para contribuir consulta [CONTRIBUTING.md](https://github.com/reflex-dev/reflex/blob/main/CONTRIBUTING.md)
|
||||||
|
|
||||||
## Licencia
|
## Licencia
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ Reflex के अंदर के कामकाज को जानने क
|
|||||||
|
|
||||||
## ⚙️ इंस्टॉलेशन (Installation)
|
## ⚙️ इंस्टॉलेशन (Installation)
|
||||||
|
|
||||||
एक टर्मिनल खोलें और चलाएं (Python 3.9+ की आवश्यकता है):
|
एक टर्मिनल खोलें और चलाएं (Python 3.10+ की आवश्यकता है):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pip install reflex
|
pip install reflex
|
||||||
@ -239,7 +239,7 @@ Reflex में हर सप्ताह नए रिलीज़ और फ
|
|||||||
- **GitHub Discussions** (गिटहब चर्चाएँ): उन सुविधाओं के बारे में बात करने का एक शानदार तरीका जिन्हें आप जोड़ना चाहते हैं या ऐसी चीज़ें जो भ्रमित करने वाली हैं/स्पष्टीकरण की आवश्यकता है।
|
- **GitHub Discussions** (गिटहब चर्चाएँ): उन सुविधाओं के बारे में बात करने का एक शानदार तरीका जिन्हें आप जोड़ना चाहते हैं या ऐसी चीज़ें जो भ्रमित करने वाली हैं/स्पष्टीकरण की आवश्यकता है।
|
||||||
- **GitHub Issues** (गिटहब समस्याएं): ये [बग](https://github.com/reflex-dev/reflex/issues) की रिपोर्ट करने का एक शानदार तरीका है। इसके अतिरिक्त, आप किसी मौजूदा समस्या को हल करने का प्रयास कर सकते हैं और एक पीआर सबमिट कर सकते हैं।
|
- **GitHub Issues** (गिटहब समस्याएं): ये [बग](https://github.com/reflex-dev/reflex/issues) की रिपोर्ट करने का एक शानदार तरीका है। इसके अतिरिक्त, आप किसी मौजूदा समस्या को हल करने का प्रयास कर सकते हैं और एक पीआर सबमिट कर सकते हैं।
|
||||||
|
|
||||||
हम सक्रिय रूप से योगदानकर्ताओं की तलाश कर रहे हैं, चाहे आपका कौशल स्तर या अनुभव कुछ भी हो।योगदान करने के लिए [CONTIBUTING.md](https://github.com/reflex-dev/reflex/blob/main/CONTRIBUTING.md) देखें।
|
हम सक्रिय रूप से योगदानकर्ताओं की तलाश कर रहे हैं, चाहे आपका कौशल स्तर या अनुभव कुछ भी हो।योगदान करने के लिए [CONTRIBUTING.md](https://github.com/reflex-dev/reflex/blob/main/CONTRIBUTING.md) देखें।
|
||||||
|
|
||||||
## हमारे सभी योगदानकर्ताओं का धन्यवाद:
|
## हमारे सभी योगदानकर्ताओं का धन्यवाद:
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
## ⚙️ Installazione
|
## ⚙️ Installazione
|
||||||
|
|
||||||
Apri un terminale ed esegui (Richiede Python 3.9+):
|
Apri un terminale ed esegui (Richiede Python 3.10+):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pip install reflex
|
pip install reflex
|
||||||
|
@ -37,7 +37,7 @@ Reflex がどのように動作しているかを知るには、[アーキテク
|
|||||||
|
|
||||||
## ⚙️ インストール
|
## ⚙️ インストール
|
||||||
|
|
||||||
ターミナルを開いて以下のコマンドを実行してください。(Python 3.9 以上が必要です。):
|
ターミナルを開いて以下のコマンドを実行してください。(Python 3.10 以上が必要です。):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pip install reflex
|
pip install reflex
|
||||||
@ -222,7 +222,7 @@ app.add_page(index, title="DALL-E")
|
|||||||
|
|
||||||
<div align="center">
|
<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>
|
</div>
|
||||||
|
|
||||||
@ -242,7 +242,7 @@ Reflex は毎週、新しいリリースや機能追加を行っています!
|
|||||||
- **GitHub Discussions**: GitHub Discussions では、追加したい機能や、複雑で解明が必要な事柄についての議論に適している場所です。
|
- **GitHub Discussions**: GitHub Discussions では、追加したい機能や、複雑で解明が必要な事柄についての議論に適している場所です。
|
||||||
- **GitHub Issues**: [Issues](https://github.com/reflex-dev/reflex/issues)はバグの報告に適している場所です。また、課題を解決した PR のサブミットにチャレンジしていただくことも、可能です。
|
- **GitHub Issues**: [Issues](https://github.com/reflex-dev/reflex/issues)はバグの報告に適している場所です。また、課題を解決した PR のサブミットにチャレンジしていただくことも、可能です。
|
||||||
|
|
||||||
スキルや経験に関わらず、私たちはコントリビュータを積極的に探しています。コントリビュートするために、[CONTIBUTING.md](https://github.com/reflex-dev/reflex/blob/main/CONTRIBUTING.md)をご覧ください。
|
CONTスキルや経験に関わらず、私たちはコントリビュータを積極的に探しています。コントリビュートするために、[CONTRIBUTING.md](https://github.com/reflex-dev/reflex/blob/main/CONTRIBUTING.md)をご覧ください。
|
||||||
|
|
||||||
## 私たちのコントリビュータに感謝!:
|
## 私たちのコントリビュータに感謝!:
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
---
|
---
|
||||||
## ⚙️ 설치
|
## ⚙️ 설치
|
||||||
|
|
||||||
터미널을 열고 실행하세요. (Python 3.9+ 필요):
|
터미널을 열고 실행하세요. (Python 3.10+ 필요):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pip install reflex
|
pip install reflex
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
|
|
||||||
## ⚙️ Installation - نصب و راه اندازی
|
## ⚙️ Installation - نصب و راه اندازی
|
||||||
|
|
||||||
یک ترمینال را باز کنید و اجرا کنید (نیازمند Python 3.9+):
|
یک ترمینال را باز کنید و اجرا کنید (نیازمند Python 3.10+):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pip install reflex
|
pip install reflex
|
||||||
@ -249,7 +249,7 @@ app.add_page(index, title="DALL-E")
|
|||||||
- **بحث های GitHub**: راهی عالی برای صحبت در مورد ویژگی هایی که می خواهید اضافه کنید یا چیزهایی که گیج کننده هستند/نیاز به توضیح دارند.
|
- **بحث های GitHub**: راهی عالی برای صحبت در مورد ویژگی هایی که می خواهید اضافه کنید یا چیزهایی که گیج کننده هستند/نیاز به توضیح دارند.
|
||||||
- **قسمت مشکلات GitHub**: [قسمت مشکلات](https://github.com/reflex-dev/reflex/issues) یک راه عالی برای گزارش اشکال هستند. علاوه بر این، می توانید یک مشکل موجود را حل کنید و یک PR(pull request) ارسال کنید.
|
- **قسمت مشکلات GitHub**: [قسمت مشکلات](https://github.com/reflex-dev/reflex/issues) یک راه عالی برای گزارش اشکال هستند. علاوه بر این، می توانید یک مشکل موجود را حل کنید و یک PR(pull request) ارسال کنید.
|
||||||
|
|
||||||
ما فعالانه به دنبال مشارکت کنندگان هستیم، فارغ از سطح مهارت یا تجربه شما. برای مشارکت [CONTIBUTING.md](https://github.com/reflex-dev/reflex/blob/main/CONTRIBUTING.md) را بررسی کنید.
|
ما فعالانه به دنبال مشارکت کنندگان هستیم، فارغ از سطح مهارت یا تجربه شما. برای مشارکت [CONTRIBUTING.md](https://github.com/reflex-dev/reflex/blob/main/CONTRIBUTING.md) را بررسی کنید.
|
||||||
|
|
||||||
|
|
||||||
## All Thanks To Our Contributors - با تشکر از همکاران ما:
|
## All Thanks To Our Contributors - با تشکر از همکاران ما:
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
---
|
---
|
||||||
## ⚙️ Instalação
|
## ⚙️ Instalação
|
||||||
|
|
||||||
Abra um terminal e execute (Requer Python 3.9+):
|
Abra um terminal e execute (Requer Python 3.10+):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pip install reflex
|
pip install reflex
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
## ⚙️ Kurulum
|
## ⚙️ Kurulum
|
||||||
|
|
||||||
Bir terminal açın ve çalıştırın (Python 3.9+ gerekir):
|
Bir terminal açın ve çalıştırın (Python 3.10+ gerekir):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pip install reflex
|
pip install reflex
|
||||||
@ -200,7 +200,7 @@ Daha fazla sayfa ekleyerek çok sayfalı bir uygulama oluşturabilirsiniz.
|
|||||||
|
|
||||||
<div align="center">
|
<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)
|
📑 [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)
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -229,7 +229,7 @@ Her boyuttaki katkıları memnuniyetle karşılıyoruz! Aşağıda Reflex toplul
|
|||||||
- **GitHub Discussions**: Eklemek istediğiniz özellikler veya kafa karıştırıcı, açıklığa kavuşturulması gereken şeyler hakkında konuşmanın harika bir yolu.
|
- **GitHub Discussions**: Eklemek istediğiniz özellikler veya kafa karıştırıcı, açıklığa kavuşturulması gereken şeyler hakkında konuşmanın harika bir yolu.
|
||||||
- **GitHub Issues**: [Issues](https://github.com/reflex-dev/reflex/issues) hataları bildirmenin mükemmel bir yoludur. Ayrıca mevcut bir sorunu deneyip çözebilir ve bir PR (Pull Requests) gönderebilirsiniz.
|
- **GitHub Issues**: [Issues](https://github.com/reflex-dev/reflex/issues) hataları bildirmenin mükemmel bir yoludur. Ayrıca mevcut bir sorunu deneyip çözebilir ve bir PR (Pull Requests) gönderebilirsiniz.
|
||||||
|
|
||||||
Beceri düzeyiniz veya deneyiminiz ne olursa olsun aktif olarak katkıda bulunacak kişiler arıyoruz. Katkı sağlamak için katkı sağlama rehberimize bakabilirsiniz: [CONTIBUTING.md](https://github.com/reflex-dev/reflex/blob/main/CONTRIBUTING.md)
|
Beceri düzeyiniz veya deneyiminiz ne olursa olsun aktif olarak katkıda bulunacak kişiler arıyoruz. Katkı sağlamak için katkı sağlama rehberimize bakabilirsiniz: [CONTRIBUTING.md](https://github.com/reflex-dev/reflex/blob/main/CONTRIBUTING.md)
|
||||||
|
|
||||||
## Hepsi Katkıda Bulunanlar Sayesinde:
|
## Hepsi Katkıda Bulunanlar Sayesinde:
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ Các tính năng chính:
|
|||||||
|
|
||||||
## ⚙️ Cài đặt
|
## ⚙️ Cài đặt
|
||||||
|
|
||||||
Mở cửa sổ lệnh và chạy (Yêu cầu Python phiên bản 3.9+):
|
Mở cửa sổ lệnh và chạy (Yêu cầu Python phiên bản 3.10+):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pip install reflex
|
pip install reflex
|
||||||
@ -232,7 +232,7 @@ Bạn có thể tạo một ứng dụng nhiều trang bằng cách thêm trang.
|
|||||||
|
|
||||||
<div align="center">
|
<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>
|
</div>
|
||||||
|
|
||||||
@ -254,7 +254,7 @@ Chúng tôi chào đón mọi đóng góp dù lớn hay nhỏ. Dưới đây là
|
|||||||
- **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.
|
- **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
|
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)
|
[CONTRIBUTING.md](https://github.com/reflex-dev/reflex/blob/main/CONTRIBUTING.md)
|
||||||
|
|
||||||
|
|
||||||
## Xin cảm ơn các Contributors:
|
## Xin cảm ơn các Contributors:
|
||||||
|
@ -34,7 +34,7 @@ Reflex 是一个使用纯Python构建全栈web应用的库。
|
|||||||
|
|
||||||
## ⚙️ 安装
|
## ⚙️ 安装
|
||||||
|
|
||||||
打开一个终端并且运行(要求Python3.9+):
|
打开一个终端并且运行(要求Python3.10+):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pip install reflex
|
pip install reflex
|
||||||
|
@ -36,7 +36,7 @@ Reflex 是一個可以用純 Python 構建全端網頁應用程式的函式庫
|
|||||||
|
|
||||||
## ⚙️ 安裝
|
## ⚙️ 安裝
|
||||||
|
|
||||||
開啟一個終端機並且執行 (需要 Python 3.9+):
|
開啟一個終端機並且執行 (需要 Python 3.10+):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pip install reflex
|
pip install reflex
|
||||||
@ -229,7 +229,7 @@ app.add_page(index, title="DALL-E")
|
|||||||
|
|
||||||
<div align="center">
|
<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>
|
</div>
|
||||||
|
|
||||||
@ -251,7 +251,7 @@ Reflex 每周都有新功能和釋出新版本! 確保你按下 :star: 和 :eyes
|
|||||||
- **GitHub Discussions**: 這是一個討論您想新增的功能或對於一些困惑/需要澄清事項的好方法。
|
- **GitHub Discussions**: 這是一個討論您想新增的功能或對於一些困惑/需要澄清事項的好方法。
|
||||||
- **GitHub Issues**: 在 [Issues](https://github.com/reflex-dev/reflex/issues) 頁面報告錯誤是一個絕佳的方式。此外,您也可以嘗試解決現有 Issue 並提交 PR。
|
- **GitHub Issues**: 在 [Issues](https://github.com/reflex-dev/reflex/issues) 頁面報告錯誤是一個絕佳的方式。此外,您也可以嘗試解決現有 Issue 並提交 PR。
|
||||||
|
|
||||||
我們積極尋找貢獻者,不論您的技能水平或經驗如何。要貢獻,請查看 [CONTIBUTING.md](https://github.com/reflex-dev/reflex/blob/main/CONTRIBUTING.md)
|
我們積極尋找貢獻者,不論您的技能水平或經驗如何。要貢獻,請查看 [CONTRIBUTING.md](https://github.com/reflex-dev/reflex/blob/main/CONTRIBUTING.md)
|
||||||
|
|
||||||
|
|
||||||
## 感謝所有貢獻者:
|
## 感謝所有貢獻者:
|
||||||
|
2638
poetry.lock
generated
2638
poetry.lock
generated
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
|||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "reflex"
|
name = "reflex"
|
||||||
version = "0.6.8dev1"
|
version = "0.7.1dev1"
|
||||||
description = "Web apps in pure Python."
|
description = "Web apps in pure Python."
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
authors = [
|
authors = [
|
||||||
@ -18,30 +18,27 @@ keywords = ["web", "framework"]
|
|||||||
classifiers = ["Development Status :: 4 - Beta"]
|
classifiers = ["Development Status :: 4 - Beta"]
|
||||||
|
|
||||||
[tool.poetry.dependencies]
|
[tool.poetry.dependencies]
|
||||||
python = "^3.9"
|
python = ">=3.10, <4.0"
|
||||||
fastapi = ">=0.96.0,!=0.111.0,!=0.111.1"
|
fastapi = ">=0.96.0,!=0.111.0,!=0.111.1"
|
||||||
gunicorn = ">=20.1.0,<24.0"
|
gunicorn = ">=20.1.0,<24.0"
|
||||||
jinja2 = ">=3.1.2,<4.0"
|
jinja2 = ">=3.1.2,<4.0"
|
||||||
psutil = ">=5.9.4,<7.0"
|
psutil = ">=5.9.4,<7.0"
|
||||||
pydantic = ">=1.10.2,<3.0"
|
pydantic = ">=1.10.21,<3.0"
|
||||||
python-multipart = ">=0.0.5,<0.1"
|
python-multipart = ">=0.0.5,<0.1"
|
||||||
python-socketio = ">=5.7.0,<6.0"
|
python-socketio = ">=5.7.0,<6.0"
|
||||||
redis = ">=4.3.5,<6.0"
|
redis = ">=4.3.5,<6.0"
|
||||||
rich = ">=13.0.0,<14.0"
|
rich = ">=13.0.0,<14.0"
|
||||||
sqlmodel = ">=0.0.14,<0.1"
|
sqlmodel = ">=0.0.14,<0.1"
|
||||||
typer = ">=0.4.2,<1.0"
|
typer = ">=0.15.1,<1.0"
|
||||||
uvicorn = ">=0.20.0"
|
uvicorn = ">=0.20.0"
|
||||||
starlette-admin = ">=0.11.0,<1.0"
|
starlette-admin = ">=0.11.0,<1.0"
|
||||||
alembic = ">=1.11.1,<2.0"
|
alembic = ">=1.11.1,<2.0"
|
||||||
platformdirs = ">=3.10.0,<5.0"
|
platformdirs = ">=3.10.0,<5.0"
|
||||||
distro = { version = ">=1.8.0,<2.0", platform = "linux" }
|
distro = { version = ">=1.8.0,<2.0", platform = "linux" }
|
||||||
python-engineio = "!=4.6.0"
|
python-engineio = "!=4.6.0"
|
||||||
wrapt = [
|
wrapt = ">=1.17.0,<2.0"
|
||||||
{ version = ">=1.14.0,<2.0", python = ">=3.11" },
|
|
||||||
{ version = ">=1.11.0,<2.0", python = "<3.11" },
|
|
||||||
]
|
|
||||||
packaging = ">=23.1,<25.0"
|
packaging = ">=23.1,<25.0"
|
||||||
reflex-hosting-cli = ">=0.1.29,<2.0"
|
reflex-hosting-cli = ">=0.1.29"
|
||||||
charset-normalizer = ">=3.3.2,<4.0"
|
charset-normalizer = ">=3.3.2,<4.0"
|
||||||
wheel = ">=0.42.0,<1.0"
|
wheel = ">=0.42.0,<1.0"
|
||||||
build = ">=1.0.3,<2.0"
|
build = ">=1.0.3,<2.0"
|
||||||
@ -49,21 +46,19 @@ setuptools = ">=75.0"
|
|||||||
httpx = ">=0.25.1,<1.0"
|
httpx = ">=0.25.1,<1.0"
|
||||||
twine = ">=4.0.0,<7.0"
|
twine = ">=4.0.0,<7.0"
|
||||||
tomlkit = ">=0.12.4,<1.0"
|
tomlkit = ">=0.12.4,<1.0"
|
||||||
asgiproxy = { version = "==0.1.1", optional = true }
|
|
||||||
lazy_loader = ">=0.4"
|
lazy_loader = ">=0.4"
|
||||||
reflex-chakra = ">=0.6.0"
|
|
||||||
typing_extensions = ">=4.6.0"
|
typing_extensions = ">=4.6.0"
|
||||||
|
|
||||||
[tool.poetry.group.dev.dependencies]
|
[tool.poetry.group.dev.dependencies]
|
||||||
pytest = ">=7.1.2,<9.0"
|
pytest = ">=7.1.2,<9.0"
|
||||||
pytest-mock = ">=3.10.0,<4.0"
|
pytest-mock = ">=3.10.0,<4.0"
|
||||||
pyright = ">=1.1.229,<1.1.335"
|
pyright = ">=1.1.394, <1.2"
|
||||||
darglint = ">=1.8.1,<2.0"
|
darglint = ">=1.8.1,<2.0"
|
||||||
dill = ">=0.3.8"
|
dill = ">=0.3.8"
|
||||||
toml = ">=0.10.2,<1.0"
|
toml = ">=0.10.2,<1.0"
|
||||||
pytest-asyncio = ">=0.24.0"
|
pytest-asyncio = ">=0.24.0"
|
||||||
pytest-cov = ">=4.0.0,<7.0"
|
pytest-cov = ">=4.0.0,<7.0"
|
||||||
ruff = "0.8.2"
|
ruff = "0.9.6"
|
||||||
pandas = ">=2.1.1,<3.0"
|
pandas = ">=2.1.1,<3.0"
|
||||||
pillow = ">=10.0.0,<12.0"
|
pillow = ">=10.0.0,<12.0"
|
||||||
plotly = ">=5.13.0,<6.0"
|
plotly = ">=5.13.0,<6.0"
|
||||||
@ -73,39 +68,70 @@ selenium = ">=4.11.0,<5.0"
|
|||||||
pytest-benchmark = ">=4.0.0,<6.0"
|
pytest-benchmark = ">=4.0.0,<6.0"
|
||||||
playwright = ">=1.46.0"
|
playwright = ">=1.46.0"
|
||||||
pytest-playwright = ">=0.5.1"
|
pytest-playwright = ">=0.5.1"
|
||||||
asgiproxy = "==0.1.1"
|
pytest-codspeed = "^3.1.2"
|
||||||
|
|
||||||
[tool.poetry.scripts]
|
[tool.poetry.scripts]
|
||||||
reflex = "reflex.reflex:cli"
|
reflex = "reflex.reflex:cli"
|
||||||
|
|
||||||
[tool.poetry.extras]
|
|
||||||
proxy = ["asgiproxy"]
|
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["poetry-core>=1.5.1"]
|
requires = ["poetry-core>=1.5.1"]
|
||||||
build-backend = "poetry.core.masonry.api"
|
build-backend = "poetry.core.masonry.api"
|
||||||
|
|
||||||
[tool.pyright]
|
[tool.pyright]
|
||||||
|
reportIncompatibleMethodOverride = false
|
||||||
|
|
||||||
[tool.ruff]
|
[tool.ruff]
|
||||||
target-version = "py39"
|
target-version = "py310"
|
||||||
output-format = "concise"
|
output-format = "concise"
|
||||||
lint.isort.split-on-trailing-comma = false
|
lint.isort.split-on-trailing-comma = false
|
||||||
lint.select = ["B", "C4", "D", "E", "ERA", "F", "FURB", "I", "PERF", "PTH", "RUF", "SIM", "T", "W"]
|
lint.select = [
|
||||||
lint.ignore = ["B008", "D205", "E501", "F403", "SIM115", "RUF006", "RUF012"]
|
"ANN001",
|
||||||
|
"B",
|
||||||
|
"C4",
|
||||||
|
"D",
|
||||||
|
"E",
|
||||||
|
"ERA",
|
||||||
|
"F",
|
||||||
|
"FURB",
|
||||||
|
"I",
|
||||||
|
"N",
|
||||||
|
"PERF",
|
||||||
|
"PGH",
|
||||||
|
"PTH",
|
||||||
|
"RUF",
|
||||||
|
"SIM",
|
||||||
|
"T",
|
||||||
|
"TRY",
|
||||||
|
"W",
|
||||||
|
]
|
||||||
|
lint.ignore = [
|
||||||
|
"B008",
|
||||||
|
"D205",
|
||||||
|
"E501",
|
||||||
|
"F403",
|
||||||
|
"SIM115",
|
||||||
|
"RUF006",
|
||||||
|
"RUF008",
|
||||||
|
"RUF012",
|
||||||
|
"TRY0",
|
||||||
|
]
|
||||||
lint.pydocstyle.convention = "google"
|
lint.pydocstyle.convention = "google"
|
||||||
|
|
||||||
[tool.ruff.lint.per-file-ignores]
|
[tool.ruff.lint.per-file-ignores]
|
||||||
"__init__.py" = ["F401"]
|
"__init__.py" = ["F401"]
|
||||||
"tests/*.py" = ["D100", "D103", "D104", "B018", "PERF", "T"]
|
"tests/*.py" = ["ANN001", "D100", "D103", "D104", "B018", "PERF", "T", "N"]
|
||||||
|
"benchmarks/*.py" = ["ANN001", "D100", "D103", "D104", "B018", "PERF", "T", "N"]
|
||||||
"reflex/.templates/*.py" = ["D100", "D103", "D104"]
|
"reflex/.templates/*.py" = ["D100", "D103", "D104"]
|
||||||
"*.pyi" = ["D301", "D415", "D417", "D418", "E742"]
|
"*.pyi" = ["D301", "D415", "D417", "D418", "E742", "N", "PGH"]
|
||||||
|
"pyi_generator.py" = ["N802"]
|
||||||
|
"reflex/constants/*.py" = ["N"]
|
||||||
"*/blank.py" = ["I001"]
|
"*/blank.py" = ["I001"]
|
||||||
|
|
||||||
[tool.pytest.ini_options]
|
[tool.pytest.ini_options]
|
||||||
|
filterwarnings = "ignore:fields may not start with an underscore:RuntimeWarning"
|
||||||
asyncio_default_fixture_loop_scope = "function"
|
asyncio_default_fixture_loop_scope = "function"
|
||||||
asyncio_mode = "auto"
|
asyncio_mode = "auto"
|
||||||
|
|
||||||
[tool.codespell]
|
[tool.codespell]
|
||||||
skip = "docs/*,*.html,examples/*, *.pyi"
|
skip = "docs/*,*.html,examples/*, *.pyi, poetry.lock"
|
||||||
ignore-words-list = "te, TreeE"
|
ignore-words-list = "te, TreeE"
|
||||||
|
@ -8,7 +8,7 @@ version = "0.0.1"
|
|||||||
description = "Reflex custom component {{ module_name }}"
|
description = "Reflex custom component {{ module_name }}"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
license = { text = "Apache-2.0" }
|
license = { text = "Apache-2.0" }
|
||||||
requires-python = ">=3.9"
|
requires-python = ">=3.10"
|
||||||
authors = [{ name = "", email = "YOUREMAIL@domain.com" }]
|
authors = [{ name = "", email = "YOUREMAIL@domain.com" }]
|
||||||
keywords = ["reflex","reflex-custom-components"]
|
keywords = ["reflex","reflex-custom-components"]
|
||||||
|
|
||||||
|
@ -38,13 +38,13 @@ export default function MyApp({ Component, pageProps }) {
|
|||||||
}, []);
|
}, []);
|
||||||
return (
|
return (
|
||||||
<ThemeProvider defaultTheme={ defaultColorMode } attribute="class">
|
<ThemeProvider defaultTheme={ defaultColorMode } attribute="class">
|
||||||
<AppWrap>
|
<StateProvider>
|
||||||
<StateProvider>
|
<EventLoopProvider>
|
||||||
<EventLoopProvider>
|
<AppWrap>
|
||||||
<Component {...pageProps} />
|
<Component {...pageProps} />
|
||||||
</EventLoopProvider>
|
</AppWrap>
|
||||||
</StateProvider>
|
</EventLoopProvider>
|
||||||
</AppWrap>
|
</StateProvider>
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@
|
|||||||
{# Args: #}
|
{# Args: #}
|
||||||
{# component: component dictionary #}
|
{# component: component dictionary #}
|
||||||
{% macro render_iterable_tag(component) %}
|
{% macro render_iterable_tag(component) %}
|
||||||
<>{ {%- if component.iterable_type == 'dict' -%}Object.entries({{- component.iterable_state }}){%- else -%}{{- component.iterable_state }}{%- endif -%}.map(({{ component.arg_name }}, {{ component.arg_index }}) => (
|
<>{ {{ component.iterable_state }}.map(({{ component.arg_name }}, {{ component.arg_index }}) => (
|
||||||
{% for child in component.children %}
|
{% for child in component.children %}
|
||||||
{{ render(child) }}
|
{{ render(child) }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
@ -86,11 +86,11 @@
|
|||||||
{% for condition in case[:-1] %}
|
{% for condition in case[:-1] %}
|
||||||
case JSON.stringify({{ condition._js_expr }}):
|
case JSON.stringify({{ condition._js_expr }}):
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
return {{ case[-1] }};
|
return {{ render(case[-1]) }};
|
||||||
break;
|
break;
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
default:
|
default:
|
||||||
return {{ component.default }};
|
return {{ render(component.default) }};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
})()
|
})()
|
||||||
|
@ -10,16 +10,15 @@ import {
|
|||||||
export default function RadixThemesColorModeProvider({ children }) {
|
export default function RadixThemesColorModeProvider({ children }) {
|
||||||
const { theme, resolvedTheme, setTheme } = useTheme();
|
const { theme, resolvedTheme, setTheme } = useTheme();
|
||||||
const [rawColorMode, setRawColorMode] = useState(defaultColorMode);
|
const [rawColorMode, setRawColorMode] = useState(defaultColorMode);
|
||||||
const [resolvedColorMode, setResolvedColorMode] = useState("dark");
|
const [resolvedColorMode, setResolvedColorMode] = useState(
|
||||||
|
defaultColorMode === "dark" ? "dark" : "light"
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isDevMode) {
|
if (isDevMode) {
|
||||||
const lastCompiledTimeInLocalStorage =
|
const lastCompiledTimeInLocalStorage =
|
||||||
localStorage.getItem("last_compiled_time");
|
localStorage.getItem("last_compiled_time");
|
||||||
if (
|
if (lastCompiledTimeInLocalStorage !== lastCompiledTimeStamp) {
|
||||||
lastCompiledTimeInLocalStorage &&
|
|
||||||
lastCompiledTimeInLocalStorage !== lastCompiledTimeStamp
|
|
||||||
) {
|
|
||||||
// on app startup, make sure the application color mode is persisted correctly.
|
// on app startup, make sure the application color mode is persisted correctly.
|
||||||
setTheme(defaultColorMode);
|
setTheme(defaultColorMode);
|
||||||
localStorage.setItem("last_compiled_time", lastCompiledTimeStamp);
|
localStorage.setItem("last_compiled_time", lastCompiledTimeStamp);
|
||||||
|
@ -3,6 +3,7 @@ import axios from "axios";
|
|||||||
import io from "socket.io-client";
|
import io from "socket.io-client";
|
||||||
import JSON5 from "json5";
|
import JSON5 from "json5";
|
||||||
import env from "$/env.json";
|
import env from "$/env.json";
|
||||||
|
import reflexEnvironment from "$/reflex.json";
|
||||||
import Cookies from "universal-cookie";
|
import Cookies from "universal-cookie";
|
||||||
import { useEffect, useRef, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
import Router, { useRouter } from "next/router";
|
import Router, { useRouter } from "next/router";
|
||||||
@ -105,6 +106,18 @@ export const getBackendURL = (url_str) => {
|
|||||||
return endpoint;
|
return endpoint;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the backend is disabled.
|
||||||
|
*
|
||||||
|
* @returns True if the backend is disabled, false otherwise.
|
||||||
|
*/
|
||||||
|
export const isBackendDisabled = () => {
|
||||||
|
const cookie = document.cookie
|
||||||
|
.split("; ")
|
||||||
|
.find((row) => row.startsWith("backend-enabled="));
|
||||||
|
return cookie !== undefined && cookie.split("=")[1] == "false";
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if any event in the event queue is stateful.
|
* Determine if any event in the event queue is stateful.
|
||||||
*
|
*
|
||||||
@ -404,11 +417,19 @@ export const connect = async (
|
|||||||
socket.current = io(endpoint.href, {
|
socket.current = io(endpoint.href, {
|
||||||
path: endpoint["pathname"],
|
path: endpoint["pathname"],
|
||||||
transports: transports,
|
transports: transports,
|
||||||
|
protocols: [reflexEnvironment.version],
|
||||||
autoUnref: false,
|
autoUnref: false,
|
||||||
query: { token: getToken() },
|
query: { token: getToken() },
|
||||||
});
|
});
|
||||||
// Ensure undefined fields in events are sent as null instead of removed
|
// Ensure undefined fields in events are sent as null instead of removed
|
||||||
socket.current.io.encoder.replacer = (k, v) => (v === undefined ? null : v);
|
socket.current.io.encoder.replacer = (k, v) => (v === undefined ? null : v);
|
||||||
|
socket.current.io.decoder.tryParse = (str) => {
|
||||||
|
try {
|
||||||
|
return JSON5.parse(str);
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
function checkVisibility() {
|
function checkVisibility() {
|
||||||
if (document.visibilityState === "visible") {
|
if (document.visibilityState === "visible") {
|
||||||
@ -801,14 +822,10 @@ export const useEventLoop = (
|
|||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// Main event loop.
|
// Handle socket connect/disconnect.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Skip if the router is not ready.
|
// only use websockets if state is present and backend is not disabled (reflex cloud).
|
||||||
if (!router.isReady) {
|
if (Object.keys(initialState).length > 1 && !isBackendDisabled()) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
// only use websockets if state is present
|
|
||||||
if (Object.keys(initialState).length > 1) {
|
|
||||||
// Initialize the websocket connection.
|
// Initialize the websocket connection.
|
||||||
if (!socket.current) {
|
if (!socket.current) {
|
||||||
connect(
|
connect(
|
||||||
@ -819,13 +836,28 @@ export const useEventLoop = (
|
|||||||
client_storage
|
client_storage
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
(async () => {
|
|
||||||
// Process all outstanding events.
|
|
||||||
while (event_queue.length > 0 && !event_processing) {
|
|
||||||
await processEvent(socket.current);
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cleanup function.
|
||||||
|
return () => {
|
||||||
|
if (socket.current) {
|
||||||
|
socket.current.disconnect();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// Main event loop.
|
||||||
|
useEffect(() => {
|
||||||
|
// Skip if the router is not ready.
|
||||||
|
if (!router.isReady || isBackendDisabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
(async () => {
|
||||||
|
// Process all outstanding events.
|
||||||
|
while (event_queue.length > 0 && !event_processing) {
|
||||||
|
await processEvent(socket.current);
|
||||||
|
}
|
||||||
|
})();
|
||||||
});
|
});
|
||||||
|
|
||||||
// localStorage event handling
|
// localStorage event handling
|
||||||
|
@ -84,6 +84,9 @@ In the example above, you will be able to do `rx.list`
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from types import ModuleType
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from reflex.utils import (
|
from reflex.utils import (
|
||||||
compat, # for side-effects
|
compat, # for side-effects
|
||||||
lazy_loader,
|
lazy_loader,
|
||||||
@ -245,6 +248,7 @@ COMPONENTS_CORE_MAPPING: dict = {
|
|||||||
"selected_files",
|
"selected_files",
|
||||||
"upload",
|
"upload",
|
||||||
],
|
],
|
||||||
|
"components.core.auto_scroll": ["auto_scroll"],
|
||||||
}
|
}
|
||||||
|
|
||||||
COMPONENTS_BASE_MAPPING: dict = {
|
COMPONENTS_BASE_MAPPING: dict = {
|
||||||
@ -303,7 +307,6 @@ _MAPPING: dict = {
|
|||||||
"event": [
|
"event": [
|
||||||
"EventChain",
|
"EventChain",
|
||||||
"EventHandler",
|
"EventHandler",
|
||||||
"background",
|
|
||||||
"call_script",
|
"call_script",
|
||||||
"call_function",
|
"call_function",
|
||||||
"run_script",
|
"run_script",
|
||||||
@ -366,20 +369,5 @@ getattr, __dir__, __all__ = lazy_loader.attach(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def __getattr__(name):
|
def __getattr__(name: ModuleType | Any):
|
||||||
if name == "chakra":
|
|
||||||
from reflex.utils import console
|
|
||||||
|
|
||||||
console.deprecate(
|
|
||||||
"rx.chakra",
|
|
||||||
reason="and moved to a separate package. "
|
|
||||||
"To continue using Chakra UI components, install the `reflex-chakra` package via `pip install "
|
|
||||||
"reflex-chakra`.",
|
|
||||||
deprecation_version="0.6.0",
|
|
||||||
removal_version="0.7.0",
|
|
||||||
dedupe=True,
|
|
||||||
)
|
|
||||||
import reflex_chakra as rc
|
|
||||||
|
|
||||||
return rc
|
|
||||||
return getattr(name)
|
return getattr(name)
|
||||||
|
@ -34,6 +34,7 @@ from .components.component import Component as Component
|
|||||||
from .components.component import ComponentNamespace as ComponentNamespace
|
from .components.component import ComponentNamespace as ComponentNamespace
|
||||||
from .components.component import NoSSRComponent as NoSSRComponent
|
from .components.component import NoSSRComponent as NoSSRComponent
|
||||||
from .components.component import memo as memo
|
from .components.component import memo as memo
|
||||||
|
from .components.core.auto_scroll import auto_scroll as auto_scroll
|
||||||
from .components.core.banner import connection_banner as connection_banner
|
from .components.core.banner import connection_banner as connection_banner
|
||||||
from .components.core.banner import connection_modal as connection_modal
|
from .components.core.banner import connection_modal as connection_modal
|
||||||
from .components.core.breakpoints import breakpoints as breakpoints
|
from .components.core.breakpoints import breakpoints as breakpoints
|
||||||
@ -131,7 +132,7 @@ from .components.radix.themes.layout.container import container as container
|
|||||||
from .components.radix.themes.layout.flex import flex as flex
|
from .components.radix.themes.layout.flex import flex as flex
|
||||||
from .components.radix.themes.layout.grid import grid as grid
|
from .components.radix.themes.layout.grid import grid as grid
|
||||||
from .components.radix.themes.layout.list import list_item as list_item
|
from .components.radix.themes.layout.list import list_item as list_item
|
||||||
from .components.radix.themes.layout.list import list_ns as list # noqa
|
from .components.radix.themes.layout.list import list_ns as list # noqa: F401
|
||||||
from .components.radix.themes.layout.list import ordered_list as ordered_list
|
from .components.radix.themes.layout.list import ordered_list as ordered_list
|
||||||
from .components.radix.themes.layout.list import unordered_list as unordered_list
|
from .components.radix.themes.layout.list import unordered_list as unordered_list
|
||||||
from .components.radix.themes.layout.section import section as section
|
from .components.radix.themes.layout.section import section as section
|
||||||
@ -156,7 +157,6 @@ from .constants import Env as Env
|
|||||||
from .constants.colors import Color as Color
|
from .constants.colors import Color as Color
|
||||||
from .event import EventChain as EventChain
|
from .event import EventChain as EventChain
|
||||||
from .event import EventHandler as EventHandler
|
from .event import EventHandler as EventHandler
|
||||||
from .event import background as background
|
|
||||||
from .event import call_function as call_function
|
from .event import call_function as call_function
|
||||||
from .event import call_script as call_script
|
from .event import call_script as call_script
|
||||||
from .event import clear_local_storage as clear_local_storage
|
from .event import clear_local_storage as clear_local_storage
|
||||||
|
708
reflex/app.py
708
reflex/app.py
File diff suppressed because it is too large
Load Diff
@ -12,7 +12,7 @@ from typing import Callable, Coroutine, Set, Union
|
|||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
|
|
||||||
from reflex.utils import console
|
from reflex.utils import console
|
||||||
from reflex.utils.exceptions import InvalidLifespanTaskType
|
from reflex.utils.exceptions import InvalidLifespanTaskTypeError
|
||||||
|
|
||||||
from .mixin import AppMixin
|
from .mixin import AppMixin
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ class LifespanMixin(AppMixin):
|
|||||||
try:
|
try:
|
||||||
async with contextlib.AsyncExitStack() as stack:
|
async with contextlib.AsyncExitStack() as stack:
|
||||||
for task in self.lifespan_tasks:
|
for task in self.lifespan_tasks:
|
||||||
run_msg = f"Started lifespan task: {task.__name__} as {{type}}" # type: ignore
|
run_msg = f"Started lifespan task: {task.__name__} as {{type}}" # pyright: ignore [reportAttributeAccessIssue]
|
||||||
if isinstance(task, asyncio.Task):
|
if isinstance(task, asyncio.Task):
|
||||||
running_tasks.append(task)
|
running_tasks.append(task)
|
||||||
else:
|
else:
|
||||||
@ -61,19 +61,19 @@ class LifespanMixin(AppMixin):
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
task: The task to register.
|
task: The task to register.
|
||||||
task_kwargs: The kwargs of the task.
|
**task_kwargs: The kwargs of the task.
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
InvalidLifespanTaskType: If the task is a generator function.
|
InvalidLifespanTaskTypeError: If the task is a generator function.
|
||||||
"""
|
"""
|
||||||
if inspect.isgeneratorfunction(task) or inspect.isasyncgenfunction(task):
|
if inspect.isgeneratorfunction(task) or inspect.isasyncgenfunction(task):
|
||||||
raise InvalidLifespanTaskType(
|
raise InvalidLifespanTaskTypeError(
|
||||||
f"Task {task.__name__} of type generator must be decorated with contextlib.asynccontextmanager."
|
f"Task {task.__name__} of type generator must be decorated with contextlib.asynccontextmanager."
|
||||||
)
|
)
|
||||||
|
|
||||||
if task_kwargs:
|
if task_kwargs:
|
||||||
original_task = task
|
original_task = task
|
||||||
task = functools.partial(task, **task_kwargs) # type: ignore
|
task = functools.partial(task, **task_kwargs) # pyright: ignore [reportArgumentType]
|
||||||
functools.update_wrapper(task, original_task) # type: ignore
|
functools.update_wrapper(task, original_task) # pyright: ignore [reportArgumentType]
|
||||||
self.lifespan_tasks.add(task) # type: ignore
|
self.lifespan_tasks.add(task)
|
||||||
console.debug(f"Registered lifespan task: {task.__name__}") # type: ignore
|
console.debug(f"Registered lifespan task: {task.__name__}") # pyright: ignore [reportAttributeAccessIssue]
|
||||||
|
@ -53,11 +53,11 @@ class MiddlewareMixin(AppMixin):
|
|||||||
"""
|
"""
|
||||||
for middleware in self.middleware:
|
for middleware in self.middleware:
|
||||||
if asyncio.iscoroutinefunction(middleware.preprocess):
|
if asyncio.iscoroutinefunction(middleware.preprocess):
|
||||||
out = await middleware.preprocess(app=self, state=state, event=event) # type: ignore
|
out = await middleware.preprocess(app=self, state=state, event=event) # pyright: ignore [reportArgumentType]
|
||||||
else:
|
else:
|
||||||
out = middleware.preprocess(app=self, state=state, event=event) # type: ignore
|
out = middleware.preprocess(app=self, state=state, event=event) # pyright: ignore [reportArgumentType]
|
||||||
if out is not None:
|
if out is not None:
|
||||||
return out # type: ignore
|
return out # pyright: ignore [reportReturnType]
|
||||||
|
|
||||||
async def _postprocess(
|
async def _postprocess(
|
||||||
self, state: BaseState, event: Event, update: StateUpdate
|
self, state: BaseState, event: Event, update: StateUpdate
|
||||||
@ -78,18 +78,18 @@ class MiddlewareMixin(AppMixin):
|
|||||||
for middleware in self.middleware:
|
for middleware in self.middleware:
|
||||||
if asyncio.iscoroutinefunction(middleware.postprocess):
|
if asyncio.iscoroutinefunction(middleware.postprocess):
|
||||||
out = await middleware.postprocess(
|
out = await middleware.postprocess(
|
||||||
app=self, # type: ignore
|
app=self, # pyright: ignore [reportArgumentType]
|
||||||
state=state,
|
state=state,
|
||||||
event=event,
|
event=event,
|
||||||
update=update,
|
update=update,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
out = middleware.postprocess(
|
out = middleware.postprocess(
|
||||||
app=self, # type: ignore
|
app=self, # pyright: ignore [reportArgumentType]
|
||||||
state=state,
|
state=state,
|
||||||
event=event,
|
event=event,
|
||||||
update=update,
|
update=update,
|
||||||
)
|
)
|
||||||
if out is not None:
|
if out is not None:
|
||||||
return out # type: ignore
|
return out # pyright: ignore [reportReturnType]
|
||||||
return update
|
return update
|
||||||
|
@ -5,16 +5,13 @@ Only the app attribute is explicitly exposed.
|
|||||||
from concurrent.futures import ThreadPoolExecutor
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
|
|
||||||
from reflex import constants
|
from reflex import constants
|
||||||
from reflex.utils import telemetry
|
|
||||||
from reflex.utils.exec import is_prod_mode
|
from reflex.utils.exec import is_prod_mode
|
||||||
from reflex.utils.prerequisites import get_app
|
from reflex.utils.prerequisites import get_and_validate_app
|
||||||
|
|
||||||
if constants.CompileVars.APP != "app":
|
if constants.CompileVars.APP != "app":
|
||||||
raise AssertionError("unexpected variable name for 'app'")
|
raise AssertionError("unexpected variable name for 'app'")
|
||||||
|
|
||||||
telemetry.send("compile")
|
app, app_module = get_and_validate_app(reload=False)
|
||||||
app_module = get_app(reload=False)
|
|
||||||
app = getattr(app_module, constants.CompileVars.APP)
|
|
||||||
# For py3.9 compatibility when redis is used, we MUST add any decorator pages
|
# For py3.9 compatibility when redis is used, we MUST add any decorator pages
|
||||||
# before compiling the app in a thread to avoid event loop error (REF-2172).
|
# before compiling the app in a thread to avoid event loop error (REF-2172).
|
||||||
app._apply_decorated_pages()
|
app._apply_decorated_pages()
|
||||||
@ -30,8 +27,7 @@ if is_prod_mode():
|
|||||||
# ensure only "app" is exposed.
|
# ensure only "app" is exposed.
|
||||||
del app_module
|
del app_module
|
||||||
del compile_future
|
del compile_future
|
||||||
del get_app
|
del get_and_validate_app
|
||||||
del is_prod_mode
|
del is_prod_mode
|
||||||
del telemetry
|
|
||||||
del constants
|
del constants
|
||||||
del ThreadPoolExecutor
|
del ThreadPoolExecutor
|
||||||
|
@ -5,15 +5,9 @@ from __future__ import annotations
|
|||||||
import os
|
import os
|
||||||
from typing import TYPE_CHECKING, Any, List, Type
|
from typing import TYPE_CHECKING, Any, List, Type
|
||||||
|
|
||||||
try:
|
import pydantic.v1.main as pydantic_main
|
||||||
import pydantic.v1.main as pydantic_main
|
from pydantic.v1 import BaseModel
|
||||||
from pydantic.v1 import BaseModel
|
from pydantic.v1.fields import ModelField
|
||||||
from pydantic.v1.fields import ModelField
|
|
||||||
except ModuleNotFoundError:
|
|
||||||
if not TYPE_CHECKING:
|
|
||||||
import pydantic.main as pydantic_main
|
|
||||||
from pydantic import BaseModel
|
|
||||||
from pydantic.fields import ModelField # type: ignore
|
|
||||||
|
|
||||||
|
|
||||||
def validate_field_name(bases: List[Type["BaseModel"]], field_name: str) -> None:
|
def validate_field_name(bases: List[Type["BaseModel"]], field_name: str) -> None:
|
||||||
@ -44,13 +38,13 @@ def validate_field_name(bases: List[Type["BaseModel"]], field_name: str) -> None
|
|||||||
|
|
||||||
# monkeypatch pydantic validate_field_name method to skip validating
|
# monkeypatch pydantic validate_field_name method to skip validating
|
||||||
# shadowed state vars when reloading app via utils.prerequisites.get_app(reload=True)
|
# shadowed state vars when reloading app via utils.prerequisites.get_app(reload=True)
|
||||||
pydantic_main.validate_field_name = validate_field_name # type: ignore
|
pydantic_main.validate_field_name = validate_field_name # pyright: ignore [reportPossiblyUnboundVariable, reportPrivateImportUsage]
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from reflex.vars import Var
|
from reflex.vars import Var
|
||||||
|
|
||||||
|
|
||||||
class Base(BaseModel): # pyright: ignore [reportUnboundVariable]
|
class Base(BaseModel):
|
||||||
"""The base class subclassed by all Reflex classes.
|
"""The base class subclassed by all Reflex classes.
|
||||||
|
|
||||||
This class wraps Pydantic and provides common methods such as
|
This class wraps Pydantic and provides common methods such as
|
||||||
@ -75,12 +69,12 @@ class Base(BaseModel): # pyright: ignore [reportUnboundVariable]
|
|||||||
"""
|
"""
|
||||||
from reflex.utils.serializers import serialize
|
from reflex.utils.serializers import serialize
|
||||||
|
|
||||||
return self.__config__.json_dumps( # type: ignore
|
return self.__config__.json_dumps(
|
||||||
self.dict(),
|
self.dict(),
|
||||||
default=serialize,
|
default=serialize,
|
||||||
)
|
)
|
||||||
|
|
||||||
def set(self, **kwargs):
|
def set(self, **kwargs: Any):
|
||||||
"""Set multiple fields and return the object.
|
"""Set multiple fields and return the object.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -113,12 +107,12 @@ class Base(BaseModel): # pyright: ignore [reportUnboundVariable]
|
|||||||
default_value: The default value of the field
|
default_value: The default value of the field
|
||||||
"""
|
"""
|
||||||
var_name = var._var_field_name
|
var_name = var._var_field_name
|
||||||
new_field = ModelField.infer(
|
new_field = ModelField.infer( # pyright: ignore [reportPossiblyUnboundVariable]
|
||||||
name=var_name,
|
name=var_name,
|
||||||
value=default_value,
|
value=default_value,
|
||||||
annotation=var._var_type,
|
annotation=var._var_type,
|
||||||
class_validators=None,
|
class_validators=None,
|
||||||
config=cls.__config__, # type: ignore
|
config=cls.__config__,
|
||||||
)
|
)
|
||||||
cls.__fields__.update({var_name: new_field})
|
cls.__fields__.update({var_name: new_field})
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ from __future__ import annotations
|
|||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import TYPE_CHECKING, Dict, Iterable, Optional, Tuple, Type, Union
|
from typing import TYPE_CHECKING, Dict, Iterable, Optional, Sequence, Tuple, Type, Union
|
||||||
|
|
||||||
from reflex import constants
|
from reflex import constants
|
||||||
from reflex.compiler import templates, utils
|
from reflex.compiler import templates, utils
|
||||||
@ -78,6 +78,7 @@ def _compile_app(app_root: Component) -> str:
|
|||||||
hooks=app_root._get_all_hooks(),
|
hooks=app_root._get_all_hooks(),
|
||||||
window_libraries=window_libraries,
|
window_libraries=window_libraries,
|
||||||
render=app_root.render(),
|
render=app_root.render(),
|
||||||
|
dynamic_imports=app_root._get_all_dynamic_imports(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -239,11 +240,19 @@ def _compile_components(
|
|||||||
component_renders.append(component_render)
|
component_renders.append(component_render)
|
||||||
imports = utils.merge_imports(imports, component_imports)
|
imports = utils.merge_imports(imports, component_imports)
|
||||||
|
|
||||||
|
dynamic_imports = {
|
||||||
|
comp_import: None
|
||||||
|
for comp_render in component_renders
|
||||||
|
if "dynamic_imports" in comp_render
|
||||||
|
for comp_import in comp_render["dynamic_imports"]
|
||||||
|
}
|
||||||
|
|
||||||
# Compile the components page.
|
# Compile the components page.
|
||||||
return (
|
return (
|
||||||
templates.COMPONENTS.render(
|
templates.COMPONENTS.render(
|
||||||
imports=utils.compile_imports(imports),
|
imports=utils.compile_imports(imports),
|
||||||
components=component_renders,
|
components=component_renders,
|
||||||
|
dynamic_imports=dynamic_imports,
|
||||||
),
|
),
|
||||||
imports,
|
imports,
|
||||||
)
|
)
|
||||||
@ -499,7 +508,7 @@ def compile_tailwind(
|
|||||||
The compiled Tailwind config.
|
The compiled Tailwind config.
|
||||||
"""
|
"""
|
||||||
# Get the path for the output file.
|
# Get the path for the output file.
|
||||||
output_path = get_web_dir() / constants.Tailwind.CONFIG
|
output_path = str((get_web_dir() / constants.Tailwind.CONFIG).absolute())
|
||||||
|
|
||||||
# Compile the config.
|
# Compile the config.
|
||||||
code = _compile_tailwind(config)
|
code = _compile_tailwind(config)
|
||||||
@ -536,7 +545,47 @@ def purge_web_pages_dir():
|
|||||||
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from reflex.app import UnevaluatedPage
|
from reflex.app import ComponentCallable, UnevaluatedPage
|
||||||
|
|
||||||
|
|
||||||
|
def _into_component_once(component: Component | ComponentCallable) -> Component | None:
|
||||||
|
"""Convert a component to a Component.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
component: The component to convert.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The converted component.
|
||||||
|
"""
|
||||||
|
if isinstance(component, Component):
|
||||||
|
return component
|
||||||
|
if isinstance(component, (Var, int, float, str)):
|
||||||
|
return Fragment.create(component)
|
||||||
|
if isinstance(component, Sequence):
|
||||||
|
return Fragment.create(*component)
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def into_component(component: Component | ComponentCallable) -> Component:
|
||||||
|
"""Convert a component to a Component.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
component: The component to convert.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The converted component.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
TypeError: If the component is not a Component.
|
||||||
|
"""
|
||||||
|
if (converted := _into_component_once(component)) is not None:
|
||||||
|
return converted
|
||||||
|
if (
|
||||||
|
callable(component)
|
||||||
|
and (converted := _into_component_once(component())) is not None
|
||||||
|
):
|
||||||
|
return converted
|
||||||
|
raise TypeError(f"Expected a Component, got {type(component)}")
|
||||||
|
|
||||||
|
|
||||||
def compile_unevaluated_page(
|
def compile_unevaluated_page(
|
||||||
@ -559,12 +608,7 @@ def compile_unevaluated_page(
|
|||||||
The compiled component and whether state should be enabled.
|
The compiled component and whether state should be enabled.
|
||||||
"""
|
"""
|
||||||
# Generate the component if it is a callable.
|
# Generate the component if it is a callable.
|
||||||
component = page.component
|
component = into_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)
|
component._add_style_recursive(style or {}, theme)
|
||||||
|
|
||||||
@ -669,10 +713,8 @@ class ExecutorSafeFunctions:
|
|||||||
The route, compiled component, and compiled page.
|
The route, compiled component, and compiled page.
|
||||||
"""
|
"""
|
||||||
component, enable_state = compile_unevaluated_page(
|
component, enable_state = compile_unevaluated_page(
|
||||||
route, cls.UNCOMPILED_PAGES[route]
|
route, cls.UNCOMPILED_PAGES[route], cls.STATE, style, theme
|
||||||
)
|
)
|
||||||
component = component if isinstance(component, Component) else component()
|
|
||||||
component._add_style_recursive(style, theme)
|
|
||||||
return route, component, compile_page(route, component, cls.STATE)
|
return route, component, compile_page(route, component, cls.STATE)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -48,11 +48,10 @@ class ReflexJinjaEnvironment(Environment):
|
|||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
"""Set default environment."""
|
"""Set default environment."""
|
||||||
extensions = ["jinja2.ext.debug"]
|
|
||||||
super().__init__(
|
super().__init__(
|
||||||
extensions=extensions,
|
|
||||||
trim_blocks=True,
|
trim_blocks=True,
|
||||||
lstrip_blocks=True,
|
lstrip_blocks=True,
|
||||||
|
auto_reload=False,
|
||||||
)
|
)
|
||||||
self.filters["json_dumps"] = json_dumps
|
self.filters["json_dumps"] = json_dumps
|
||||||
self.filters["react_setter"] = lambda state: f"set{state.capitalize()}"
|
self.filters["react_setter"] = lambda state: f"set{state.capitalize()}"
|
||||||
|
@ -2,17 +2,15 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import asyncio
|
||||||
|
import concurrent.futures
|
||||||
|
import traceback
|
||||||
|
from datetime import datetime
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any, Callable, Dict, Optional, Type, Union
|
from typing import Any, Callable, Dict, Optional, Type, Union
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
from reflex.utils.prerequisites import get_web_dir
|
from pydantic.v1.fields import ModelField
|
||||||
from reflex.vars.base import Var
|
|
||||||
|
|
||||||
try:
|
|
||||||
from pydantic.v1.fields import ModelField
|
|
||||||
except ModuleNotFoundError:
|
|
||||||
from pydantic.fields import ModelField # type: ignore
|
|
||||||
|
|
||||||
from reflex import constants
|
from reflex import constants
|
||||||
from reflex.components.base import (
|
from reflex.components.base import (
|
||||||
@ -29,10 +27,13 @@ from reflex.components.base import (
|
|||||||
)
|
)
|
||||||
from reflex.components.component import Component, ComponentStyle, CustomComponent
|
from reflex.components.component import Component, ComponentStyle, CustomComponent
|
||||||
from reflex.istate.storage import Cookie, LocalStorage, SessionStorage
|
from reflex.istate.storage import Cookie, LocalStorage, SessionStorage
|
||||||
from reflex.state import BaseState
|
from reflex.state import BaseState, _resolve_delta
|
||||||
from reflex.style import Style
|
from reflex.style import Style
|
||||||
from reflex.utils import console, format, imports, path_ops
|
from reflex.utils import console, format, imports, path_ops
|
||||||
|
from reflex.utils.exec import is_in_app_harness
|
||||||
from reflex.utils.imports import ImportVar, ParsedImportDict
|
from reflex.utils.imports import ImportVar, ParsedImportDict
|
||||||
|
from reflex.utils.prerequisites import get_web_dir
|
||||||
|
from reflex.vars.base import Var
|
||||||
|
|
||||||
# To re-export this function.
|
# To re-export this function.
|
||||||
merge_imports = imports.merge_imports
|
merge_imports = imports.merge_imports
|
||||||
@ -112,24 +113,34 @@ def compile_imports(import_dict: ParsedImportDict) -> list[dict]:
|
|||||||
validate_imports(collapsed_import_dict)
|
validate_imports(collapsed_import_dict)
|
||||||
import_dicts = []
|
import_dicts = []
|
||||||
for lib, fields in collapsed_import_dict.items():
|
for lib, fields in collapsed_import_dict.items():
|
||||||
default, rest = compile_import_statement(fields)
|
|
||||||
|
|
||||||
# prevent lib from being rendered on the page if all imports are non rendered kind
|
# prevent lib from being rendered on the page if all imports are non rendered kind
|
||||||
if not any(f.render for f in fields): # type: ignore
|
if not any(f.render for f in fields):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if not lib:
|
lib_paths: dict[str, list[ImportVar]] = {}
|
||||||
if default:
|
|
||||||
raise ValueError("No default field allowed for empty library.")
|
|
||||||
if rest is None or len(rest) == 0:
|
|
||||||
raise ValueError("No fields to import.")
|
|
||||||
import_dicts.extend(get_import_dict(module) for module in sorted(rest))
|
|
||||||
continue
|
|
||||||
|
|
||||||
# remove the version before rendering the package imports
|
for field in fields:
|
||||||
lib = format.format_library_name(lib)
|
lib_paths.setdefault(field.package_path, []).append(field)
|
||||||
|
|
||||||
import_dicts.append(get_import_dict(lib, default, rest))
|
compiled = {
|
||||||
|
path: compile_import_statement(fields) for path, fields in lib_paths.items()
|
||||||
|
}
|
||||||
|
|
||||||
|
for path, (default, rest) in compiled.items():
|
||||||
|
if not lib:
|
||||||
|
if default:
|
||||||
|
raise ValueError("No default field allowed for empty library.")
|
||||||
|
if rest is None or len(rest) == 0:
|
||||||
|
raise ValueError("No fields to import.")
|
||||||
|
import_dicts.extend(get_import_dict(module) for module in sorted(rest))
|
||||||
|
continue
|
||||||
|
|
||||||
|
# remove the version before rendering the package imports
|
||||||
|
formatted_lib = format.format_library_name(lib) + (
|
||||||
|
path if path != "/" else ""
|
||||||
|
)
|
||||||
|
|
||||||
|
import_dicts.append(get_import_dict(formatted_lib, default, rest))
|
||||||
return import_dicts
|
return import_dicts
|
||||||
|
|
||||||
|
|
||||||
@ -151,6 +162,22 @@ def get_import_dict(lib: str, default: str = "", rest: list[str] | None = None)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def save_error(error: Exception) -> str:
|
||||||
|
"""Save the error to a file.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
error: The error to save.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The path of the saved error.
|
||||||
|
"""
|
||||||
|
timestamp = datetime.now().strftime("%Y-%m-%d__%H-%M-%S")
|
||||||
|
constants.Reflex.LOGS_DIR.mkdir(parents=True, exist_ok=True)
|
||||||
|
log_path = constants.Reflex.LOGS_DIR / f"error_{timestamp}.log"
|
||||||
|
traceback.TracebackException.from_exception(error).print(file=log_path.open("w+"))
|
||||||
|
return str(log_path)
|
||||||
|
|
||||||
|
|
||||||
def compile_state(state: Type[BaseState]) -> dict:
|
def compile_state(state: Type[BaseState]) -> dict:
|
||||||
"""Compile the state of the app.
|
"""Compile the state of the app.
|
||||||
|
|
||||||
@ -163,13 +190,31 @@ def compile_state(state: Type[BaseState]) -> dict:
|
|||||||
try:
|
try:
|
||||||
initial_state = state(_reflex_internal_init=True).dict(initial=True)
|
initial_state = state(_reflex_internal_init=True).dict(initial=True)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
log_path = save_error(e)
|
||||||
console.warn(
|
console.warn(
|
||||||
f"Failed to compile initial state with computed vars, excluding them: {e}"
|
f"Failed to compile initial state with computed vars. Error log saved to {log_path}"
|
||||||
)
|
)
|
||||||
initial_state = state(_reflex_internal_init=True).dict(
|
initial_state = state(_reflex_internal_init=True).dict(
|
||||||
initial=True, include_computed=False
|
initial=True, include_computed=False
|
||||||
)
|
)
|
||||||
return initial_state
|
try:
|
||||||
|
_ = asyncio.get_running_loop()
|
||||||
|
except RuntimeError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
if is_in_app_harness():
|
||||||
|
# Playwright tests already have an event loop running, so we can't use asyncio.run.
|
||||||
|
with concurrent.futures.ThreadPoolExecutor() as pool:
|
||||||
|
resolved_initial_state = pool.submit(
|
||||||
|
asyncio.run, _resolve_delta(initial_state)
|
||||||
|
).result()
|
||||||
|
console.warn(
|
||||||
|
f"Had to get initial state in a thread 🤮 {resolved_initial_state}",
|
||||||
|
)
|
||||||
|
return resolved_initial_state
|
||||||
|
|
||||||
|
# Normally the compile runs before any event loop starts, we asyncio.run is available for calling.
|
||||||
|
return asyncio.run(_resolve_delta(initial_state))
|
||||||
|
|
||||||
|
|
||||||
def _compile_client_storage_field(
|
def _compile_client_storage_field(
|
||||||
@ -292,6 +337,7 @@ def compile_custom_component(
|
|||||||
"render": render.render(),
|
"render": render.render(),
|
||||||
"hooks": render._get_all_hooks(),
|
"hooks": render._get_all_hooks(),
|
||||||
"custom_code": render._get_all_custom_code(),
|
"custom_code": render._get_all_custom_code(),
|
||||||
|
"dynamic_imports": render._get_all_dynamic_imports(),
|
||||||
},
|
},
|
||||||
imports,
|
imports,
|
||||||
)
|
)
|
||||||
@ -471,6 +517,8 @@ def write_page(path: str | Path, code: str):
|
|||||||
"""
|
"""
|
||||||
path = Path(path)
|
path = Path(path)
|
||||||
path_ops.mkdir(path.parent)
|
path_ops.mkdir(path.parent)
|
||||||
|
if path.exists() and path.read_text(encoding="utf-8") == code:
|
||||||
|
return
|
||||||
path.write_text(code, encoding="utf-8")
|
path.write_text(code, encoding="utf-8")
|
||||||
|
|
||||||
|
|
||||||
@ -494,7 +542,7 @@ def empty_dir(path: str | Path, keep_files: list[str] | None = None):
|
|||||||
path_ops.rm(element)
|
path_ops.rm(element)
|
||||||
|
|
||||||
|
|
||||||
def is_valid_url(url) -> bool:
|
def is_valid_url(url: str) -> bool:
|
||||||
"""Check if a url is valid.
|
"""Check if a url is valid.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
from typing import Any, Dict, Optional, Union, overload
|
from typing import Any, Dict, Optional, Union, overload
|
||||||
|
|
||||||
from reflex.components.base.fragment import Fragment
|
from reflex.components.base.fragment import Fragment
|
||||||
from reflex.event import BASE_STATE, EventType
|
from reflex.event import EventType
|
||||||
from reflex.style import Style
|
from reflex.style import Style
|
||||||
from reflex.vars.base import Var
|
from reflex.vars.base import Var
|
||||||
|
|
||||||
@ -22,21 +22,21 @@ class AppWrap(Fragment):
|
|||||||
class_name: Optional[Any] = None,
|
class_name: Optional[Any] = None,
|
||||||
autofocus: Optional[bool] = None,
|
autofocus: Optional[bool] = None,
|
||||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
on_blur: Optional[EventType[()]] = None,
|
||||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_click: Optional[EventType[()]] = None,
|
||||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
on_focus: Optional[EventType[()]] = None,
|
||||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
on_mount: Optional[EventType[()]] = None,
|
||||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
**props,
|
**props,
|
||||||
) -> "AppWrap":
|
) -> "AppWrap":
|
||||||
"""Create a new AppWrap component.
|
"""Create a new AppWrap component.
|
||||||
|
@ -2,14 +2,54 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import Any, Iterator
|
from typing import Any, Iterator, Sequence
|
||||||
|
|
||||||
from reflex.components.component import Component, LiteralComponentVar
|
from reflex.components.component import BaseComponent, Component, ComponentStyle
|
||||||
from reflex.components.tags import Tag
|
from reflex.components.tags import Tag
|
||||||
from reflex.components.tags.tagless import Tagless
|
from reflex.components.tags.tagless import Tagless
|
||||||
|
from reflex.config import PerformanceMode, environment
|
||||||
|
from reflex.utils import console
|
||||||
|
from reflex.utils.decorator import once
|
||||||
from reflex.utils.imports import ParsedImportDict
|
from reflex.utils.imports import ParsedImportDict
|
||||||
from reflex.vars import BooleanVar, ObjectVar, Var
|
from reflex.vars import BooleanVar, ObjectVar, Var
|
||||||
from reflex.vars.base import VarData
|
from reflex.vars.base import GLOBAL_CACHE, VarData
|
||||||
|
from reflex.vars.sequence import LiteralStringVar
|
||||||
|
|
||||||
|
|
||||||
|
@once
|
||||||
|
def get_performance_mode():
|
||||||
|
"""Get the performance mode.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The performance mode.
|
||||||
|
"""
|
||||||
|
return environment.REFLEX_PERF_MODE.get()
|
||||||
|
|
||||||
|
|
||||||
|
def validate_str(value: str):
|
||||||
|
"""Validate a string value.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
value: The value to validate.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
ValueError: If the value is a Var and the performance mode is set to raise.
|
||||||
|
"""
|
||||||
|
perf_mode = get_performance_mode()
|
||||||
|
if perf_mode != PerformanceMode.OFF and value.startswith("reflex___state"):
|
||||||
|
if perf_mode == PerformanceMode.WARN:
|
||||||
|
console.warn(
|
||||||
|
f"Output includes {value!s} which will be displayed as a string. If you are calling `str` on a Var, consider using .to_string() instead."
|
||||||
|
)
|
||||||
|
elif perf_mode == PerformanceMode.RAISE:
|
||||||
|
raise ValueError(
|
||||||
|
f"Output includes {value!s} which will be displayed as a string. If you are calling `str` on a Var, consider using .to_string() instead."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _components_from_var(var: Var) -> Sequence[BaseComponent]:
|
||||||
|
var_data = var._get_all_var_data()
|
||||||
|
return var_data.components if var_data else ()
|
||||||
|
|
||||||
|
|
||||||
class Bare(Component):
|
class Bare(Component):
|
||||||
@ -28,10 +68,15 @@ class Bare(Component):
|
|||||||
The component.
|
The component.
|
||||||
"""
|
"""
|
||||||
if isinstance(contents, Var):
|
if isinstance(contents, Var):
|
||||||
|
if isinstance(contents, LiteralStringVar):
|
||||||
|
validate_str(contents._var_value)
|
||||||
return cls(contents=contents)
|
return cls(contents=contents)
|
||||||
else:
|
else:
|
||||||
|
if isinstance(contents, str):
|
||||||
|
validate_str(contents)
|
||||||
contents = str(contents) if contents is not None else ""
|
contents = str(contents) if contents is not None else ""
|
||||||
return cls(contents=contents) # type: ignore
|
|
||||||
|
return cls(contents=contents)
|
||||||
|
|
||||||
def _get_all_hooks_internal(self) -> dict[str, VarData | None]:
|
def _get_all_hooks_internal(self) -> dict[str, VarData | None]:
|
||||||
"""Include the hooks for the component.
|
"""Include the hooks for the component.
|
||||||
@ -40,8 +85,9 @@ class Bare(Component):
|
|||||||
The hooks for the component.
|
The hooks for the component.
|
||||||
"""
|
"""
|
||||||
hooks = super()._get_all_hooks_internal()
|
hooks = super()._get_all_hooks_internal()
|
||||||
if isinstance(self.contents, LiteralComponentVar):
|
if isinstance(self.contents, Var):
|
||||||
hooks |= self.contents._var_value._get_all_hooks_internal()
|
for component in _components_from_var(self.contents):
|
||||||
|
hooks |= component._get_all_hooks_internal()
|
||||||
return hooks
|
return hooks
|
||||||
|
|
||||||
def _get_all_hooks(self) -> dict[str, VarData | None]:
|
def _get_all_hooks(self) -> dict[str, VarData | None]:
|
||||||
@ -51,18 +97,22 @@ class Bare(Component):
|
|||||||
The hooks for the component.
|
The hooks for the component.
|
||||||
"""
|
"""
|
||||||
hooks = super()._get_all_hooks()
|
hooks = super()._get_all_hooks()
|
||||||
if isinstance(self.contents, LiteralComponentVar):
|
if isinstance(self.contents, Var):
|
||||||
hooks |= self.contents._var_value._get_all_hooks()
|
for component in _components_from_var(self.contents):
|
||||||
|
hooks |= component._get_all_hooks()
|
||||||
return hooks
|
return hooks
|
||||||
|
|
||||||
def _get_all_imports(self) -> ParsedImportDict:
|
def _get_all_imports(self, collapse: bool = False) -> ParsedImportDict:
|
||||||
"""Include the imports for the component.
|
"""Include the imports for the component.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
collapse: Whether to collapse the imports.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The imports for the component.
|
The imports for the component.
|
||||||
"""
|
"""
|
||||||
imports = super()._get_all_imports()
|
imports = super()._get_all_imports(collapse=collapse)
|
||||||
if isinstance(self.contents, LiteralComponentVar):
|
if isinstance(self.contents, Var):
|
||||||
var_data = self.contents._get_all_var_data()
|
var_data = self.contents._get_all_var_data()
|
||||||
if var_data:
|
if var_data:
|
||||||
imports |= {k: list(v) for k, v in var_data.imports}
|
imports |= {k: list(v) for k, v in var_data.imports}
|
||||||
@ -75,8 +125,9 @@ class Bare(Component):
|
|||||||
The dynamic imports.
|
The dynamic imports.
|
||||||
"""
|
"""
|
||||||
dynamic_imports = super()._get_all_dynamic_imports()
|
dynamic_imports = super()._get_all_dynamic_imports()
|
||||||
if isinstance(self.contents, LiteralComponentVar):
|
if isinstance(self.contents, Var):
|
||||||
dynamic_imports |= self.contents._var_value._get_all_dynamic_imports()
|
for component in _components_from_var(self.contents):
|
||||||
|
dynamic_imports |= component._get_all_dynamic_imports()
|
||||||
return dynamic_imports
|
return dynamic_imports
|
||||||
|
|
||||||
def _get_all_custom_code(self) -> set[str]:
|
def _get_all_custom_code(self) -> set[str]:
|
||||||
@ -86,10 +137,24 @@ class Bare(Component):
|
|||||||
The custom code.
|
The custom code.
|
||||||
"""
|
"""
|
||||||
custom_code = super()._get_all_custom_code()
|
custom_code = super()._get_all_custom_code()
|
||||||
if isinstance(self.contents, LiteralComponentVar):
|
if isinstance(self.contents, Var):
|
||||||
custom_code |= self.contents._var_value._get_all_custom_code()
|
for component in _components_from_var(self.contents):
|
||||||
|
custom_code |= component._get_all_custom_code()
|
||||||
return custom_code
|
return custom_code
|
||||||
|
|
||||||
|
def _get_all_app_wrap_components(self) -> dict[tuple[int, str], Component]:
|
||||||
|
"""Get the components that should be wrapped in the app.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The components that should be wrapped in the app.
|
||||||
|
"""
|
||||||
|
app_wrap_components = super()._get_all_app_wrap_components()
|
||||||
|
if isinstance(self.contents, Var):
|
||||||
|
for component in _components_from_var(self.contents):
|
||||||
|
if isinstance(component, Component):
|
||||||
|
app_wrap_components |= component._get_all_app_wrap_components()
|
||||||
|
return app_wrap_components
|
||||||
|
|
||||||
def _get_all_refs(self) -> set[str]:
|
def _get_all_refs(self) -> set[str]:
|
||||||
"""Get the refs for the children of the component.
|
"""Get the refs for the children of the component.
|
||||||
|
|
||||||
@ -97,8 +162,9 @@ class Bare(Component):
|
|||||||
The refs for the children.
|
The refs for the children.
|
||||||
"""
|
"""
|
||||||
refs = super()._get_all_refs()
|
refs = super()._get_all_refs()
|
||||||
if isinstance(self.contents, LiteralComponentVar):
|
if isinstance(self.contents, Var):
|
||||||
refs |= self.contents._var_value._get_all_refs()
|
for component in _components_from_var(self.contents):
|
||||||
|
refs |= component._get_all_refs()
|
||||||
return refs
|
return refs
|
||||||
|
|
||||||
def _render(self) -> Tag:
|
def _render(self) -> Tag:
|
||||||
@ -108,6 +174,33 @@ class Bare(Component):
|
|||||||
return Tagless(contents=f"{{{self.contents!s}}}")
|
return Tagless(contents=f"{{{self.contents!s}}}")
|
||||||
return Tagless(contents=str(self.contents))
|
return Tagless(contents=str(self.contents))
|
||||||
|
|
||||||
|
def _add_style_recursive(
|
||||||
|
self, style: ComponentStyle, theme: Component | None = None
|
||||||
|
) -> Component:
|
||||||
|
"""Add style to the component and its children.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
style: The style to add.
|
||||||
|
theme: The theme to add.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The component with the style added.
|
||||||
|
"""
|
||||||
|
new_self = super()._add_style_recursive(style, theme)
|
||||||
|
|
||||||
|
are_components_touched = False
|
||||||
|
|
||||||
|
if isinstance(self.contents, Var):
|
||||||
|
for component in _components_from_var(self.contents):
|
||||||
|
if isinstance(component, Component):
|
||||||
|
component._add_style_recursive(style, theme)
|
||||||
|
are_components_touched = True
|
||||||
|
|
||||||
|
if are_components_touched:
|
||||||
|
GLOBAL_CACHE.clear()
|
||||||
|
|
||||||
|
return new_self
|
||||||
|
|
||||||
def _get_vars(
|
def _get_vars(
|
||||||
self, include_children: bool = False, ignore_ids: set[int] | None = None
|
self, include_children: bool = False, ignore_ids: set[int] | None = None
|
||||||
) -> Iterator[Var]:
|
) -> Iterator[Var]:
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
from typing import Any, Dict, Optional, Union, overload
|
from typing import Any, Dict, Optional, Union, overload
|
||||||
|
|
||||||
from reflex.components.component import Component
|
from reflex.components.component import Component
|
||||||
from reflex.event import BASE_STATE, EventType
|
from reflex.event import EventType
|
||||||
from reflex.style import Style
|
from reflex.style import Style
|
||||||
from reflex.vars.base import Var
|
from reflex.vars.base import Var
|
||||||
|
|
||||||
@ -22,21 +22,21 @@ class Body(Component):
|
|||||||
class_name: Optional[Any] = None,
|
class_name: Optional[Any] = None,
|
||||||
autofocus: Optional[bool] = None,
|
autofocus: Optional[bool] = None,
|
||||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
on_blur: Optional[EventType[()]] = None,
|
||||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_click: Optional[EventType[()]] = None,
|
||||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
on_focus: Optional[EventType[()]] = None,
|
||||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
on_mount: Optional[EventType[()]] = None,
|
||||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
**props,
|
**props,
|
||||||
) -> "Body":
|
) -> "Body":
|
||||||
"""Create the component.
|
"""Create the component.
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
from typing import Any, Dict, Optional, Union, overload
|
from typing import Any, Dict, Optional, Union, overload
|
||||||
|
|
||||||
from reflex.components.component import Component
|
from reflex.components.component import Component
|
||||||
from reflex.event import BASE_STATE, EventType
|
from reflex.event import EventType
|
||||||
from reflex.style import Style
|
from reflex.style import Style
|
||||||
from reflex.vars.base import Var
|
from reflex.vars.base import Var
|
||||||
|
|
||||||
@ -22,21 +22,21 @@ class NextDocumentLib(Component):
|
|||||||
class_name: Optional[Any] = None,
|
class_name: Optional[Any] = None,
|
||||||
autofocus: Optional[bool] = None,
|
autofocus: Optional[bool] = None,
|
||||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
on_blur: Optional[EventType[()]] = None,
|
||||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_click: Optional[EventType[()]] = None,
|
||||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
on_focus: Optional[EventType[()]] = None,
|
||||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
on_mount: Optional[EventType[()]] = None,
|
||||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
**props,
|
**props,
|
||||||
) -> "NextDocumentLib":
|
) -> "NextDocumentLib":
|
||||||
"""Create the component.
|
"""Create the component.
|
||||||
@ -69,21 +69,21 @@ class Html(NextDocumentLib):
|
|||||||
class_name: Optional[Any] = None,
|
class_name: Optional[Any] = None,
|
||||||
autofocus: Optional[bool] = None,
|
autofocus: Optional[bool] = None,
|
||||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
on_blur: Optional[EventType[()]] = None,
|
||||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_click: Optional[EventType[()]] = None,
|
||||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
on_focus: Optional[EventType[()]] = None,
|
||||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
on_mount: Optional[EventType[()]] = None,
|
||||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
**props,
|
**props,
|
||||||
) -> "Html":
|
) -> "Html":
|
||||||
"""Create the component.
|
"""Create the component.
|
||||||
@ -115,21 +115,21 @@ class DocumentHead(NextDocumentLib):
|
|||||||
class_name: Optional[Any] = None,
|
class_name: Optional[Any] = None,
|
||||||
autofocus: Optional[bool] = None,
|
autofocus: Optional[bool] = None,
|
||||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
on_blur: Optional[EventType[()]] = None,
|
||||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_click: Optional[EventType[()]] = None,
|
||||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
on_focus: Optional[EventType[()]] = None,
|
||||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
on_mount: Optional[EventType[()]] = None,
|
||||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
**props,
|
**props,
|
||||||
) -> "DocumentHead":
|
) -> "DocumentHead":
|
||||||
"""Create the component.
|
"""Create the component.
|
||||||
@ -161,21 +161,21 @@ class Main(NextDocumentLib):
|
|||||||
class_name: Optional[Any] = None,
|
class_name: Optional[Any] = None,
|
||||||
autofocus: Optional[bool] = None,
|
autofocus: Optional[bool] = None,
|
||||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
on_blur: Optional[EventType[()]] = None,
|
||||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_click: Optional[EventType[()]] = None,
|
||||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
on_focus: Optional[EventType[()]] = None,
|
||||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
on_mount: Optional[EventType[()]] = None,
|
||||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
**props,
|
**props,
|
||||||
) -> "Main":
|
) -> "Main":
|
||||||
"""Create the component.
|
"""Create the component.
|
||||||
@ -207,21 +207,21 @@ class NextScript(NextDocumentLib):
|
|||||||
class_name: Optional[Any] = None,
|
class_name: Optional[Any] = None,
|
||||||
autofocus: Optional[bool] = None,
|
autofocus: Optional[bool] = None,
|
||||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
on_blur: Optional[EventType[()]] = None,
|
||||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_click: Optional[EventType[()]] = None,
|
||||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
on_focus: Optional[EventType[()]] = None,
|
||||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
on_mount: Optional[EventType[()]] = None,
|
||||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
**props,
|
**props,
|
||||||
) -> "NextScript":
|
) -> "NextScript":
|
||||||
"""Create the component.
|
"""Create the component.
|
||||||
|
@ -11,10 +11,11 @@ from reflex.event import EventHandler, set_clipboard
|
|||||||
from reflex.state import FrontendEventExceptionState
|
from reflex.state import FrontendEventExceptionState
|
||||||
from reflex.vars.base import Var
|
from reflex.vars.base import Var
|
||||||
from reflex.vars.function import ArgsFunctionOperation
|
from reflex.vars.function import ArgsFunctionOperation
|
||||||
|
from reflex.vars.object import ObjectVar
|
||||||
|
|
||||||
|
|
||||||
def on_error_spec(
|
def on_error_spec(
|
||||||
error: Var[Dict[str, str]], info: Var[Dict[str, str]]
|
error: ObjectVar[Dict[str, str]], info: ObjectVar[Dict[str, str]]
|
||||||
) -> Tuple[Var[str], Var[str]]:
|
) -> Tuple[Var[str], Var[str]]:
|
||||||
"""The spec for the on_error event handler.
|
"""The spec for the on_error event handler.
|
||||||
|
|
||||||
|
@ -6,12 +6,13 @@
|
|||||||
from typing import Any, Dict, Optional, Tuple, Union, overload
|
from typing import Any, Dict, Optional, Tuple, Union, overload
|
||||||
|
|
||||||
from reflex.components.component import Component
|
from reflex.components.component import Component
|
||||||
from reflex.event import BASE_STATE, EventType
|
from reflex.event import EventType
|
||||||
from reflex.style import Style
|
from reflex.style import Style
|
||||||
from reflex.vars.base import Var
|
from reflex.vars.base import Var
|
||||||
|
from reflex.vars.object import ObjectVar
|
||||||
|
|
||||||
def on_error_spec(
|
def on_error_spec(
|
||||||
error: Var[Dict[str, str]], info: Var[Dict[str, str]]
|
error: ObjectVar[Dict[str, str]], info: ObjectVar[Dict[str, str]]
|
||||||
) -> Tuple[Var[str], Var[str]]: ...
|
) -> Tuple[Var[str], Var[str]]: ...
|
||||||
|
|
||||||
class ErrorBoundary(Component):
|
class ErrorBoundary(Component):
|
||||||
@ -27,28 +28,24 @@ class ErrorBoundary(Component):
|
|||||||
class_name: Optional[Any] = None,
|
class_name: Optional[Any] = None,
|
||||||
autofocus: Optional[bool] = None,
|
autofocus: Optional[bool] = None,
|
||||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
on_blur: Optional[EventType[()]] = None,
|
||||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_click: Optional[EventType[()]] = None,
|
||||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
on_error: Optional[
|
on_error: Optional[
|
||||||
Union[
|
Union[EventType[()], EventType[str], EventType[str, str]]
|
||||||
EventType[[], BASE_STATE],
|
|
||||||
EventType[[str], BASE_STATE],
|
|
||||||
EventType[[str, str], BASE_STATE],
|
|
||||||
]
|
|
||||||
] = None,
|
] = None,
|
||||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
on_focus: Optional[EventType[()]] = None,
|
||||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
on_mount: Optional[EventType[()]] = None,
|
||||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
**props,
|
**props,
|
||||||
) -> "ErrorBoundary":
|
) -> "ErrorBoundary":
|
||||||
"""Create an ErrorBoundary component.
|
"""Create an ErrorBoundary component.
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
from typing import Any, Dict, Optional, Union, overload
|
from typing import Any, Dict, Optional, Union, overload
|
||||||
|
|
||||||
from reflex.components.component import Component
|
from reflex.components.component import Component
|
||||||
from reflex.event import BASE_STATE, EventType
|
from reflex.event import EventType
|
||||||
from reflex.style import Style
|
from reflex.style import Style
|
||||||
from reflex.vars.base import Var
|
from reflex.vars.base import Var
|
||||||
|
|
||||||
@ -22,21 +22,21 @@ class Fragment(Component):
|
|||||||
class_name: Optional[Any] = None,
|
class_name: Optional[Any] = None,
|
||||||
autofocus: Optional[bool] = None,
|
autofocus: Optional[bool] = None,
|
||||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
on_blur: Optional[EventType[()]] = None,
|
||||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_click: Optional[EventType[()]] = None,
|
||||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
on_focus: Optional[EventType[()]] = None,
|
||||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
on_mount: Optional[EventType[()]] = None,
|
||||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
**props,
|
**props,
|
||||||
) -> "Fragment":
|
) -> "Fragment":
|
||||||
"""Create the component.
|
"""Create the component.
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
from typing import Any, Dict, Optional, Union, overload
|
from typing import Any, Dict, Optional, Union, overload
|
||||||
|
|
||||||
from reflex.components.component import Component, MemoizationLeaf
|
from reflex.components.component import Component, MemoizationLeaf
|
||||||
from reflex.event import BASE_STATE, EventType
|
from reflex.event import EventType
|
||||||
from reflex.style import Style
|
from reflex.style import Style
|
||||||
from reflex.vars.base import Var
|
from reflex.vars.base import Var
|
||||||
|
|
||||||
@ -22,21 +22,21 @@ class NextHeadLib(Component):
|
|||||||
class_name: Optional[Any] = None,
|
class_name: Optional[Any] = None,
|
||||||
autofocus: Optional[bool] = None,
|
autofocus: Optional[bool] = None,
|
||||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
on_blur: Optional[EventType[()]] = None,
|
||||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_click: Optional[EventType[()]] = None,
|
||||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
on_focus: Optional[EventType[()]] = None,
|
||||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
on_mount: Optional[EventType[()]] = None,
|
||||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
**props,
|
**props,
|
||||||
) -> "NextHeadLib":
|
) -> "NextHeadLib":
|
||||||
"""Create the component.
|
"""Create the component.
|
||||||
@ -68,21 +68,21 @@ class Head(NextHeadLib, MemoizationLeaf):
|
|||||||
class_name: Optional[Any] = None,
|
class_name: Optional[Any] = None,
|
||||||
autofocus: Optional[bool] = None,
|
autofocus: Optional[bool] = None,
|
||||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
on_blur: Optional[EventType[()]] = None,
|
||||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_click: Optional[EventType[()]] = None,
|
||||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
on_focus: Optional[EventType[()]] = None,
|
||||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
on_mount: Optional[EventType[()]] = None,
|
||||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
**props,
|
**props,
|
||||||
) -> "Head":
|
) -> "Head":
|
||||||
"""Create a new memoization leaf component.
|
"""Create a new memoization leaf component.
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
from typing import Any, Dict, Optional, Union, overload
|
from typing import Any, Dict, Optional, Union, overload
|
||||||
|
|
||||||
from reflex.components.component import Component
|
from reflex.components.component import Component
|
||||||
from reflex.event import BASE_STATE, EventType
|
from reflex.event import EventType
|
||||||
from reflex.style import Style
|
from reflex.style import Style
|
||||||
from reflex.vars.base import Var
|
from reflex.vars.base import Var
|
||||||
|
|
||||||
@ -24,21 +24,21 @@ class RawLink(Component):
|
|||||||
class_name: Optional[Any] = None,
|
class_name: Optional[Any] = None,
|
||||||
autofocus: Optional[bool] = None,
|
autofocus: Optional[bool] = None,
|
||||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
on_blur: Optional[EventType[()]] = None,
|
||||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_click: Optional[EventType[()]] = None,
|
||||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
on_focus: Optional[EventType[()]] = None,
|
||||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
on_mount: Optional[EventType[()]] = None,
|
||||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
**props,
|
**props,
|
||||||
) -> "RawLink":
|
) -> "RawLink":
|
||||||
"""Create the component.
|
"""Create the component.
|
||||||
@ -79,21 +79,21 @@ class ScriptTag(Component):
|
|||||||
class_name: Optional[Any] = None,
|
class_name: Optional[Any] = None,
|
||||||
autofocus: Optional[bool] = None,
|
autofocus: Optional[bool] = None,
|
||||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
on_blur: Optional[EventType[()]] = None,
|
||||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_click: Optional[EventType[()]] = None,
|
||||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
on_focus: Optional[EventType[()]] = None,
|
||||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
on_mount: Optional[EventType[()]] = None,
|
||||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
**props,
|
**props,
|
||||||
) -> "ScriptTag":
|
) -> "ScriptTag":
|
||||||
"""Create the component.
|
"""Create the component.
|
||||||
|
@ -53,11 +53,11 @@ class Description(Meta):
|
|||||||
"""A component that displays the title of the current page."""
|
"""A component that displays the title of the current page."""
|
||||||
|
|
||||||
# The type of the description.
|
# The type of the description.
|
||||||
name: str = "description"
|
name: str | None = "description"
|
||||||
|
|
||||||
|
|
||||||
class Image(Meta):
|
class Image(Meta):
|
||||||
"""A component that displays the title of the current page."""
|
"""A component that displays the title of the current page."""
|
||||||
|
|
||||||
# The type of the image.
|
# The type of the image.
|
||||||
property: str = "og:image"
|
property: str | None = "og:image"
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
from typing import Any, Dict, Optional, Union, overload
|
from typing import Any, Dict, Optional, Union, overload
|
||||||
|
|
||||||
from reflex.components.component import Component
|
from reflex.components.component import Component
|
||||||
from reflex.event import BASE_STATE, EventType
|
from reflex.event import EventType
|
||||||
from reflex.style import Style
|
from reflex.style import Style
|
||||||
from reflex.vars.base import Var
|
from reflex.vars.base import Var
|
||||||
|
|
||||||
@ -23,21 +23,21 @@ class Title(Component):
|
|||||||
class_name: Optional[Any] = None,
|
class_name: Optional[Any] = None,
|
||||||
autofocus: Optional[bool] = None,
|
autofocus: Optional[bool] = None,
|
||||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
on_blur: Optional[EventType[()]] = None,
|
||||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_click: Optional[EventType[()]] = None,
|
||||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
on_focus: Optional[EventType[()]] = None,
|
||||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
on_mount: Optional[EventType[()]] = None,
|
||||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
**props,
|
**props,
|
||||||
) -> "Title":
|
) -> "Title":
|
||||||
"""Create the component.
|
"""Create the component.
|
||||||
@ -74,21 +74,21 @@ class Meta(Component):
|
|||||||
class_name: Optional[Any] = None,
|
class_name: Optional[Any] = None,
|
||||||
autofocus: Optional[bool] = None,
|
autofocus: Optional[bool] = None,
|
||||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
on_blur: Optional[EventType[()]] = None,
|
||||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_click: Optional[EventType[()]] = None,
|
||||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
on_focus: Optional[EventType[()]] = None,
|
||||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
on_mount: Optional[EventType[()]] = None,
|
||||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
**props,
|
**props,
|
||||||
) -> "Meta":
|
) -> "Meta":
|
||||||
"""Create the component.
|
"""Create the component.
|
||||||
@ -130,21 +130,21 @@ class Description(Meta):
|
|||||||
class_name: Optional[Any] = None,
|
class_name: Optional[Any] = None,
|
||||||
autofocus: Optional[bool] = None,
|
autofocus: Optional[bool] = None,
|
||||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
on_blur: Optional[EventType[()]] = None,
|
||||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_click: Optional[EventType[()]] = None,
|
||||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
on_focus: Optional[EventType[()]] = None,
|
||||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
on_mount: Optional[EventType[()]] = None,
|
||||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
**props,
|
**props,
|
||||||
) -> "Description":
|
) -> "Description":
|
||||||
"""Create the component.
|
"""Create the component.
|
||||||
@ -186,21 +186,21 @@ class Image(Meta):
|
|||||||
class_name: Optional[Any] = None,
|
class_name: Optional[Any] = None,
|
||||||
autofocus: Optional[bool] = None,
|
autofocus: Optional[bool] = None,
|
||||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
on_blur: Optional[EventType[()]] = None,
|
||||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_click: Optional[EventType[()]] = None,
|
||||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
on_focus: Optional[EventType[()]] = None,
|
||||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
on_mount: Optional[EventType[()]] = None,
|
||||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
**props,
|
**props,
|
||||||
) -> "Image":
|
) -> "Image":
|
||||||
"""Create the component.
|
"""Create the component.
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
from typing import Any, Dict, Literal, Optional, Union, overload
|
from typing import Any, Dict, Literal, Optional, Union, overload
|
||||||
|
|
||||||
from reflex.components.component import Component
|
from reflex.components.component import Component
|
||||||
from reflex.event import BASE_STATE, EventType
|
from reflex.event import EventType
|
||||||
from reflex.style import Style
|
from reflex.style import Style
|
||||||
from reflex.vars.base import Var
|
from reflex.vars.base import Var
|
||||||
|
|
||||||
@ -29,24 +29,24 @@ class Script(Component):
|
|||||||
class_name: Optional[Any] = None,
|
class_name: Optional[Any] = None,
|
||||||
autofocus: Optional[bool] = None,
|
autofocus: Optional[bool] = None,
|
||||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
on_blur: Optional[EventType[()]] = None,
|
||||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_click: Optional[EventType[()]] = None,
|
||||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
on_error: Optional[EventType[[], BASE_STATE]] = None,
|
on_error: Optional[EventType[()]] = None,
|
||||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
on_focus: Optional[EventType[()]] = None,
|
||||||
on_load: Optional[EventType[[], BASE_STATE]] = None,
|
on_load: Optional[EventType[()]] = None,
|
||||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
on_mount: Optional[EventType[()]] = None,
|
||||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
on_ready: Optional[EventType[[], BASE_STATE]] = None,
|
on_ready: Optional[EventType[()]] = None,
|
||||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
**props,
|
**props,
|
||||||
) -> "Script":
|
) -> "Script":
|
||||||
"""Create an inline or user-defined script.
|
"""Create an inline or user-defined script.
|
||||||
|
10
reflex/components/base/strict_mode.py
Normal file
10
reflex/components/base/strict_mode.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
"""Module for the StrictMode component."""
|
||||||
|
|
||||||
|
from reflex.components.component import Component
|
||||||
|
|
||||||
|
|
||||||
|
class StrictMode(Component):
|
||||||
|
"""A React strict mode component to enable strict mode for its children."""
|
||||||
|
|
||||||
|
library = "react"
|
||||||
|
tag = "StrictMode"
|
57
reflex/components/base/strict_mode.pyi
Normal file
57
reflex/components/base/strict_mode.pyi
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
"""Stub file for reflex/components/base/strict_mode.py"""
|
||||||
|
|
||||||
|
# ------------------- DO NOT EDIT ----------------------
|
||||||
|
# This file was generated by `reflex/utils/pyi_generator.py`!
|
||||||
|
# ------------------------------------------------------
|
||||||
|
from typing import Any, Dict, Optional, Union, overload
|
||||||
|
|
||||||
|
from reflex.components.component import Component
|
||||||
|
from reflex.event import EventType
|
||||||
|
from reflex.style import Style
|
||||||
|
from reflex.vars.base import Var
|
||||||
|
|
||||||
|
class StrictMode(Component):
|
||||||
|
@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[()]] = None,
|
||||||
|
on_click: Optional[EventType[()]] = None,
|
||||||
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
|
on_focus: Optional[EventType[()]] = None,
|
||||||
|
on_mount: Optional[EventType[()]] = None,
|
||||||
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
|
**props,
|
||||||
|
) -> "StrictMode":
|
||||||
|
"""Create the component.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
*children: The children of the component.
|
||||||
|
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.
|
||||||
|
"""
|
||||||
|
...
|
@ -4,6 +4,7 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import copy
|
import copy
|
||||||
import dataclasses
|
import dataclasses
|
||||||
|
import inspect
|
||||||
import typing
|
import typing
|
||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
from functools import lru_cache, wraps
|
from functools import lru_cache, wraps
|
||||||
@ -21,9 +22,11 @@ from typing import (
|
|||||||
Set,
|
Set,
|
||||||
Type,
|
Type,
|
||||||
Union,
|
Union,
|
||||||
|
get_args,
|
||||||
|
get_origin,
|
||||||
)
|
)
|
||||||
|
|
||||||
from typing_extensions import deprecated
|
from typing_extensions import Self
|
||||||
|
|
||||||
import reflex.state
|
import reflex.state
|
||||||
from reflex.base import Base
|
from reflex.base import Base
|
||||||
@ -43,22 +46,16 @@ from reflex.constants import (
|
|||||||
from reflex.constants.compiler import SpecialAttributes
|
from reflex.constants.compiler import SpecialAttributes
|
||||||
from reflex.constants.state import FRONTEND_EVENT_STATE
|
from reflex.constants.state import FRONTEND_EVENT_STATE
|
||||||
from reflex.event import (
|
from reflex.event import (
|
||||||
|
EventActionsMixin,
|
||||||
EventCallback,
|
EventCallback,
|
||||||
EventChain,
|
EventChain,
|
||||||
EventHandler,
|
EventHandler,
|
||||||
EventSpec,
|
EventSpec,
|
||||||
EventVar,
|
|
||||||
no_args_event_spec,
|
no_args_event_spec,
|
||||||
)
|
)
|
||||||
from reflex.style import Style, format_as_emotion
|
from reflex.style import Style, format_as_emotion
|
||||||
from reflex.utils import console, format, imports, types
|
from reflex.utils import format, imports, types
|
||||||
from reflex.utils.imports import (
|
from reflex.utils.imports import ImportDict, ImportVar, ParsedImportDict, parse_imports
|
||||||
ImmutableParsedImportDict,
|
|
||||||
ImportDict,
|
|
||||||
ImportVar,
|
|
||||||
ParsedImportDict,
|
|
||||||
parse_imports,
|
|
||||||
)
|
|
||||||
from reflex.vars import VarData
|
from reflex.vars import VarData
|
||||||
from reflex.vars.base import (
|
from reflex.vars.base import (
|
||||||
CachedVarOperation,
|
CachedVarOperation,
|
||||||
@ -153,7 +150,7 @@ class BaseComponent(Base, ABC):
|
|||||||
class ComponentNamespace(SimpleNamespace):
|
class ComponentNamespace(SimpleNamespace):
|
||||||
"""A namespace to manage components with subcomponents."""
|
"""A namespace to manage components with subcomponents."""
|
||||||
|
|
||||||
def __hash__(self) -> int:
|
def __hash__(self) -> int: # pyright: ignore [reportIncompatibleVariableOverride]
|
||||||
"""Get the hash of the namespace.
|
"""Get the hash of the namespace.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@ -182,6 +179,7 @@ ComponentStyle = Dict[
|
|||||||
Union[str, Type[BaseComponent], Callable, ComponentNamespace], Any
|
Union[str, Type[BaseComponent], Callable, ComponentNamespace], Any
|
||||||
]
|
]
|
||||||
ComponentChild = Union[types.PrimitiveType, Var, BaseComponent]
|
ComponentChild = Union[types.PrimitiveType, Var, BaseComponent]
|
||||||
|
ComponentChildTypes = (*types.PrimitiveTypes, Var, BaseComponent)
|
||||||
|
|
||||||
|
|
||||||
def satisfies_type_hint(obj: Any, type_hint: Any) -> bool:
|
def satisfies_type_hint(obj: Any, type_hint: Any) -> bool:
|
||||||
@ -194,11 +192,26 @@ def satisfies_type_hint(obj: Any, type_hint: Any) -> bool:
|
|||||||
Returns:
|
Returns:
|
||||||
Whether the object satisfies the type hint.
|
Whether the object satisfies the type hint.
|
||||||
"""
|
"""
|
||||||
if isinstance(obj, LiteralVar):
|
return types._isinstance(obj, type_hint, nested=1)
|
||||||
return types._isinstance(obj._var_value, type_hint)
|
|
||||||
if isinstance(obj, Var):
|
|
||||||
return types._issubclass(obj._var_type, type_hint)
|
def _components_from(
|
||||||
return types._isinstance(obj, type_hint)
|
component_or_var: Union[BaseComponent, Var],
|
||||||
|
) -> tuple[BaseComponent, ...]:
|
||||||
|
"""Get the components from a component or Var.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
component_or_var: The component or Var to get the components from.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The components.
|
||||||
|
"""
|
||||||
|
if isinstance(component_or_var, Var):
|
||||||
|
var_data = component_or_var._get_all_var_data()
|
||||||
|
return var_data.components if var_data else ()
|
||||||
|
if isinstance(component_or_var, BaseComponent):
|
||||||
|
return (component_or_var,)
|
||||||
|
return ()
|
||||||
|
|
||||||
|
|
||||||
class Component(BaseComponent, ABC):
|
class Component(BaseComponent, ABC):
|
||||||
@ -429,20 +442,22 @@ class Component(BaseComponent, ABC):
|
|||||||
else:
|
else:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
def determine_key(value: Any):
|
||||||
|
# Try to create a var from the value
|
||||||
|
key = value if isinstance(value, Var) else LiteralVar.create(value)
|
||||||
|
|
||||||
|
# Check that the var type is not None.
|
||||||
|
if key is None:
|
||||||
|
raise TypeError
|
||||||
|
|
||||||
|
return key
|
||||||
|
|
||||||
# Check whether the key is a component prop.
|
# Check whether the key is a component prop.
|
||||||
if types._issubclass(field_type, Var):
|
if types._issubclass(field_type, Var):
|
||||||
# Used to store the passed types if var type is a union.
|
# Used to store the passed types if var type is a union.
|
||||||
passed_types = None
|
passed_types = None
|
||||||
try:
|
try:
|
||||||
# Try to create a var from the value.
|
kwargs[key] = determine_key(value)
|
||||||
if isinstance(value, Var):
|
|
||||||
kwargs[key] = value
|
|
||||||
else:
|
|
||||||
kwargs[key] = LiteralVar.create(value)
|
|
||||||
|
|
||||||
# Check that the var type is not None.
|
|
||||||
if kwargs[key] is None:
|
|
||||||
raise TypeError
|
|
||||||
|
|
||||||
expected_type = fields[key].outer_type_.__args__[0]
|
expected_type = fields[key].outer_type_.__args__[0]
|
||||||
# validate literal fields.
|
# validate literal fields.
|
||||||
@ -463,9 +478,7 @@ class Component(BaseComponent, ABC):
|
|||||||
if types.is_union(passed_type):
|
if types.is_union(passed_type):
|
||||||
# We need to check all possible types in the union.
|
# We need to check all possible types in the union.
|
||||||
passed_types = (
|
passed_types = (
|
||||||
arg
|
arg for arg in passed_type.__args__ if arg is not type(None)
|
||||||
for arg in passed_type.__args__ # type: ignore
|
|
||||||
if arg is not type(None)
|
|
||||||
)
|
)
|
||||||
if (
|
if (
|
||||||
# If the passed var is a union, check if all possible types are valid.
|
# If the passed var is a union, check if all possible types are valid.
|
||||||
@ -492,14 +505,14 @@ class Component(BaseComponent, ABC):
|
|||||||
# Check if the key is an event trigger.
|
# Check if the key is an event trigger.
|
||||||
if key in component_specific_triggers:
|
if key in component_specific_triggers:
|
||||||
kwargs["event_triggers"][key] = EventChain.create(
|
kwargs["event_triggers"][key] = EventChain.create(
|
||||||
value=value, # type: ignore
|
value=value,
|
||||||
args_spec=component_specific_triggers[key],
|
args_spec=component_specific_triggers[key],
|
||||||
key=key,
|
key=key,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Remove any keys that were added as events.
|
# Remove any keys that were added as events.
|
||||||
for key in kwargs["event_triggers"]:
|
for key in kwargs["event_triggers"]:
|
||||||
del kwargs[key]
|
kwargs.pop(key, None)
|
||||||
|
|
||||||
# Place data_ and aria_ attributes into custom_attrs
|
# Place data_ and aria_ attributes into custom_attrs
|
||||||
special_attributes = tuple(
|
special_attributes = tuple(
|
||||||
@ -545,41 +558,6 @@ class Component(BaseComponent, ABC):
|
|||||||
# Construct the component.
|
# Construct the component.
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
@deprecated("Use rx.EventChain.create instead.")
|
|
||||||
def _create_event_chain(
|
|
||||||
self,
|
|
||||||
args_spec: types.ArgsSpec | Sequence[types.ArgsSpec],
|
|
||||||
value: Union[
|
|
||||||
Var,
|
|
||||||
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.
|
|
||||||
"""
|
|
||||||
console.deprecate(
|
|
||||||
"Component._create_event_chain",
|
|
||||||
"Use rx.EventChain.create instead.",
|
|
||||||
deprecation_version="0.6.8",
|
|
||||||
removal_version="0.7.0",
|
|
||||||
)
|
|
||||||
return EventChain.create(
|
|
||||||
value=value, # type: ignore
|
|
||||||
args_spec=args_spec,
|
|
||||||
key=key,
|
|
||||||
)
|
|
||||||
|
|
||||||
def get_event_triggers(
|
def get_event_triggers(
|
||||||
self,
|
self,
|
||||||
) -> Dict[str, types.ArgsSpec | Sequence[types.ArgsSpec]]:
|
) -> Dict[str, types.ArgsSpec | Sequence[types.ArgsSpec]]:
|
||||||
@ -614,7 +592,7 @@ class Component(BaseComponent, ABC):
|
|||||||
annotation = field.annotation
|
annotation = field.annotation
|
||||||
if (metadata := getattr(annotation, "__metadata__", None)) is not None:
|
if (metadata := getattr(annotation, "__metadata__", None)) is not None:
|
||||||
args_spec = metadata[0]
|
args_spec = metadata[0]
|
||||||
default_triggers[field.name] = args_spec or (no_args_event_spec) # type: ignore
|
default_triggers[field.name] = args_spec or (no_args_event_spec)
|
||||||
return default_triggers
|
return default_triggers
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
@ -661,8 +639,7 @@ class Component(BaseComponent, ABC):
|
|||||||
if props is None:
|
if props is None:
|
||||||
# Add component props to the tag.
|
# Add component props to the tag.
|
||||||
props = {
|
props = {
|
||||||
attr[:-1] if attr.endswith("_") else attr: getattr(self, attr)
|
attr.removesuffix("_"): getattr(self, attr) for attr in self.get_props()
|
||||||
for attr in self.get_props()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Add ref to element if `id` is not None.
|
# Add ref to element if `id` is not None.
|
||||||
@ -712,12 +689,21 @@ class Component(BaseComponent, ABC):
|
|||||||
return set()
|
return set()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@lru_cache(maxsize=None)
|
def _are_fields_known(cls) -> bool:
|
||||||
def get_component_props(cls) -> set[str]:
|
"""Check if all fields are known at compile time. True for most components.
|
||||||
"""Get the props that expected a component as value.
|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The components props.
|
Whether all fields are known at compile time.
|
||||||
|
"""
|
||||||
|
return True
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
@lru_cache(maxsize=None)
|
||||||
|
def _get_component_prop_names(cls) -> Set[str]:
|
||||||
|
"""Get the names of the component props. NOTE: This assumes all fields are known.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The names of the component props.
|
||||||
"""
|
"""
|
||||||
return {
|
return {
|
||||||
name
|
name
|
||||||
@ -726,8 +712,28 @@ class Component(BaseComponent, ABC):
|
|||||||
and types._issubclass(field.outer_type_, Component)
|
and types._issubclass(field.outer_type_, Component)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def _get_components_in_props(self) -> Sequence[BaseComponent]:
|
||||||
|
"""Get the components in the props.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The components in the props
|
||||||
|
"""
|
||||||
|
if self._are_fields_known():
|
||||||
|
return [
|
||||||
|
component
|
||||||
|
for name in self._get_component_prop_names()
|
||||||
|
for component in _components_from(getattr(self, name))
|
||||||
|
]
|
||||||
|
return [
|
||||||
|
component
|
||||||
|
for prop in self.get_props()
|
||||||
|
if (value := getattr(self, prop)) is not None
|
||||||
|
and isinstance(value, (BaseComponent, Var))
|
||||||
|
for component in _components_from(value)
|
||||||
|
]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create(cls, *children, **props) -> Component:
|
def create(cls, *children, **props) -> Self:
|
||||||
"""Create the component.
|
"""Create the component.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -740,22 +746,21 @@ class Component(BaseComponent, ABC):
|
|||||||
# Import here to avoid circular imports.
|
# Import here to avoid circular imports.
|
||||||
from reflex.components.base.bare import Bare
|
from reflex.components.base.bare import Bare
|
||||||
from reflex.components.base.fragment import Fragment
|
from reflex.components.base.fragment import Fragment
|
||||||
from reflex.utils.exceptions import ComponentTypeError
|
from reflex.utils.exceptions import ChildrenTypeError
|
||||||
|
|
||||||
# Filter out None props
|
# Filter out None props
|
||||||
props = {key: value for key, value in props.items() if value is not None}
|
props = {key: value for key, value in props.items() if value is not None}
|
||||||
|
|
||||||
def validate_children(children):
|
def validate_children(children: tuple | list):
|
||||||
for child in children:
|
for child in children:
|
||||||
if isinstance(child, tuple):
|
if isinstance(child, (tuple, list)):
|
||||||
validate_children(child)
|
validate_children(child)
|
||||||
|
|
||||||
# Make sure the child is a valid type.
|
# Make sure the child is a valid type.
|
||||||
if not types._isinstance(child, ComponentChild):
|
if isinstance(child, dict) or not isinstance(
|
||||||
raise ComponentTypeError(
|
child, ComponentChildTypes
|
||||||
"Children of Reflex components must be other components, "
|
):
|
||||||
"state vars, or primitive Python types. "
|
raise ChildrenTypeError(component=cls.__name__, child=child)
|
||||||
f"Got child {child} of type {type(child)}.",
|
|
||||||
)
|
|
||||||
|
|
||||||
# Validate all the children.
|
# Validate all the children.
|
||||||
validate_children(children)
|
validate_children(children)
|
||||||
@ -798,7 +803,7 @@ class Component(BaseComponent, ABC):
|
|||||||
|
|
||||||
# Walk the MRO to call all `add_style` methods.
|
# Walk the MRO to call all `add_style` methods.
|
||||||
for base in self._iter_parent_classes_with_method("add_style"):
|
for base in self._iter_parent_classes_with_method("add_style"):
|
||||||
s = base.add_style(self) # type: ignore
|
s = base.add_style(self)
|
||||||
if s is not None:
|
if s is not None:
|
||||||
styles.append(s)
|
styles.append(s)
|
||||||
|
|
||||||
@ -890,7 +895,7 @@ class Component(BaseComponent, ABC):
|
|||||||
else {}
|
else {}
|
||||||
)
|
)
|
||||||
|
|
||||||
def render(self) -> Dict:
|
def render(self) -> dict:
|
||||||
"""Render the component.
|
"""Render the component.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@ -908,7 +913,7 @@ class Component(BaseComponent, ABC):
|
|||||||
self._replace_prop_names(rendered_dict)
|
self._replace_prop_names(rendered_dict)
|
||||||
return rendered_dict
|
return rendered_dict
|
||||||
|
|
||||||
def _replace_prop_names(self, rendered_dict) -> None:
|
def _replace_prop_names(self, rendered_dict: dict) -> None:
|
||||||
"""Replace the prop names in the render dictionary.
|
"""Replace the prop names in the render dictionary.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -948,7 +953,7 @@ class Component(BaseComponent, ABC):
|
|||||||
comp.__name__ for comp in (Fragment, Foreach, Cond, Match)
|
comp.__name__ for comp in (Fragment, Foreach, Cond, Match)
|
||||||
]
|
]
|
||||||
|
|
||||||
def validate_child(child):
|
def validate_child(child: Any):
|
||||||
child_name = type(child).__name__
|
child_name = type(child).__name__
|
||||||
|
|
||||||
# Iterate through the immediate children of fragment
|
# Iterate through the immediate children of fragment
|
||||||
@ -1183,6 +1188,9 @@ class Component(BaseComponent, ABC):
|
|||||||
if custom_code is not None:
|
if custom_code is not None:
|
||||||
code.add(custom_code)
|
code.add(custom_code)
|
||||||
|
|
||||||
|
for component in self._get_components_in_props():
|
||||||
|
code |= component._get_all_custom_code()
|
||||||
|
|
||||||
# Add the custom code from add_custom_code method.
|
# Add the custom code from add_custom_code method.
|
||||||
for clz in self._iter_parent_classes_with_method("add_custom_code"):
|
for clz in self._iter_parent_classes_with_method("add_custom_code"):
|
||||||
for item in clz.add_custom_code(self):
|
for item in clz.add_custom_code(self):
|
||||||
@ -1210,7 +1218,7 @@ class Component(BaseComponent, ABC):
|
|||||||
The dynamic imports.
|
The dynamic imports.
|
||||||
"""
|
"""
|
||||||
# Store the import in a set to avoid duplicates.
|
# Store the import in a set to avoid duplicates.
|
||||||
dynamic_imports = set()
|
dynamic_imports: set[str] = set()
|
||||||
|
|
||||||
# Get dynamic import for this component.
|
# Get dynamic import for this component.
|
||||||
dynamic_import = self._get_dynamic_imports()
|
dynamic_import = self._get_dynamic_imports()
|
||||||
@ -1221,25 +1229,12 @@ class Component(BaseComponent, ABC):
|
|||||||
for child in self.children:
|
for child in self.children:
|
||||||
dynamic_imports |= child._get_all_dynamic_imports()
|
dynamic_imports |= child._get_all_dynamic_imports()
|
||||||
|
|
||||||
for prop in self.get_component_props():
|
for component in self._get_components_in_props():
|
||||||
if getattr(self, prop) is not None:
|
dynamic_imports |= component._get_all_dynamic_imports()
|
||||||
dynamic_imports |= getattr(self, prop)._get_all_dynamic_imports()
|
|
||||||
|
|
||||||
# Return the dynamic imports
|
# Return the dynamic imports
|
||||||
return dynamic_imports
|
return dynamic_imports
|
||||||
|
|
||||||
def _get_props_imports(self) -> List[ParsedImportDict]:
|
|
||||||
"""Get the imports needed for components props.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
The imports for the components props of the component.
|
|
||||||
"""
|
|
||||||
return [
|
|
||||||
getattr(self, prop)._get_all_imports()
|
|
||||||
for prop in self.get_component_props()
|
|
||||||
if getattr(self, prop) is not None
|
|
||||||
]
|
|
||||||
|
|
||||||
def _should_transpile(self, dep: str | None) -> bool:
|
def _should_transpile(self, dep: str | None) -> bool:
|
||||||
"""Check if a dependency should be transpiled.
|
"""Check if a dependency should be transpiled.
|
||||||
|
|
||||||
@ -1249,7 +1244,7 @@ class Component(BaseComponent, ABC):
|
|||||||
Returns:
|
Returns:
|
||||||
True if the dependency should be transpiled.
|
True if the dependency should be transpiled.
|
||||||
"""
|
"""
|
||||||
return (
|
return bool(self.transpile_packages) and (
|
||||||
dep in self.transpile_packages
|
dep in self.transpile_packages
|
||||||
or format.format_library_name(dep or "") in self.transpile_packages
|
or format.format_library_name(dep or "") in self.transpile_packages
|
||||||
)
|
)
|
||||||
@ -1332,9 +1327,10 @@ class Component(BaseComponent, ABC):
|
|||||||
event_imports = Imports.EVENTS if self.event_triggers else {}
|
event_imports = Imports.EVENTS if self.event_triggers else {}
|
||||||
|
|
||||||
# Collect imports from Vars used directly by this component.
|
# Collect imports from Vars used directly by this component.
|
||||||
var_datas = [var._get_all_var_data() for var in self._get_vars()]
|
var_imports = [
|
||||||
var_imports: List[ImmutableParsedImportDict] = [
|
var_data.imports
|
||||||
var_data.imports for var_data in var_datas if var_data is not None
|
for var in self._get_vars()
|
||||||
|
if (var_data := var._get_all_var_data()) is not None
|
||||||
]
|
]
|
||||||
|
|
||||||
added_import_dicts: list[ParsedImportDict] = []
|
added_import_dicts: list[ParsedImportDict] = []
|
||||||
@ -1349,7 +1345,6 @@ class Component(BaseComponent, ABC):
|
|||||||
)
|
)
|
||||||
|
|
||||||
return imports.merge_imports(
|
return imports.merge_imports(
|
||||||
*self._get_props_imports(),
|
|
||||||
self._get_dependencies_imports(),
|
self._get_dependencies_imports(),
|
||||||
self._get_hooks_imports(),
|
self._get_hooks_imports(),
|
||||||
_imports,
|
_imports,
|
||||||
@ -1426,6 +1421,8 @@ class Component(BaseComponent, ABC):
|
|||||||
for k in var_data.hooks
|
for k in var_data.hooks
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
for component in var_data.components:
|
||||||
|
vars_hooks.update(component._get_all_hooks())
|
||||||
return vars_hooks
|
return vars_hooks
|
||||||
|
|
||||||
def _get_events_hooks(self) -> dict[str, VarData | None]:
|
def _get_events_hooks(self) -> dict[str, VarData | None]:
|
||||||
@ -1574,6 +1571,9 @@ class Component(BaseComponent, ABC):
|
|||||||
refs.add(ref)
|
refs.add(ref)
|
||||||
for child in self.children:
|
for child in self.children:
|
||||||
refs |= child._get_all_refs()
|
refs |= child._get_all_refs()
|
||||||
|
for component in self._get_components_in_props():
|
||||||
|
refs |= component._get_all_refs()
|
||||||
|
|
||||||
return refs
|
return refs
|
||||||
|
|
||||||
def _get_all_custom_components(
|
def _get_all_custom_components(
|
||||||
@ -1597,6 +1597,9 @@ class Component(BaseComponent, ABC):
|
|||||||
if not isinstance(child, Component):
|
if not isinstance(child, Component):
|
||||||
continue
|
continue
|
||||||
custom_components |= child._get_all_custom_components(seen=seen)
|
custom_components |= child._get_all_custom_components(seen=seen)
|
||||||
|
for component in self._get_components_in_props():
|
||||||
|
if isinstance(component, Component) and component.tag is not None:
|
||||||
|
custom_components |= component._get_all_custom_components(seen=seen)
|
||||||
return custom_components
|
return custom_components
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -1660,17 +1663,65 @@ class CustomComponent(Component):
|
|||||||
# The props of the component.
|
# The props of the component.
|
||||||
props: Dict[str, Any] = {}
|
props: Dict[str, Any] = {}
|
||||||
|
|
||||||
# Props that reference other components.
|
def __init__(self, **kwargs):
|
||||||
component_props: Dict[str, Component] = {}
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
"""Initialize the custom component.
|
"""Initialize the custom component.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
*args: The args to pass to the component.
|
|
||||||
**kwargs: The kwargs to pass to the component.
|
**kwargs: The kwargs to pass to the component.
|
||||||
"""
|
"""
|
||||||
super().__init__(*args, **kwargs)
|
component_fn = kwargs.get("component_fn")
|
||||||
|
|
||||||
|
# Set the props.
|
||||||
|
props_types = typing.get_type_hints(component_fn) if component_fn else {}
|
||||||
|
props = {key: value for key, value in kwargs.items() if key in props_types}
|
||||||
|
kwargs = {key: value for key, value in kwargs.items() if key not in props_types}
|
||||||
|
|
||||||
|
event_types = {
|
||||||
|
key
|
||||||
|
for key in props
|
||||||
|
if (
|
||||||
|
(get_origin((annotation := props_types.get(key))) or annotation)
|
||||||
|
== EventHandler
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_args_spec(key: str) -> types.ArgsSpec | Sequence[types.ArgsSpec]:
|
||||||
|
type_ = props_types[key]
|
||||||
|
|
||||||
|
return (
|
||||||
|
args[0]
|
||||||
|
if (args := get_args(type_))
|
||||||
|
else (
|
||||||
|
annotation_args[1]
|
||||||
|
if get_origin(
|
||||||
|
(
|
||||||
|
annotation := inspect.getfullargspec(
|
||||||
|
component_fn
|
||||||
|
).annotations[key]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
is typing.Annotated
|
||||||
|
and (annotation_args := get_args(annotation))
|
||||||
|
else no_args_event_spec
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
super().__init__(
|
||||||
|
event_triggers={
|
||||||
|
key: EventChain.create(
|
||||||
|
value=props[key],
|
||||||
|
args_spec=get_args_spec(key),
|
||||||
|
key=key,
|
||||||
|
)
|
||||||
|
for key in event_types
|
||||||
|
},
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
to_camel_cased_props = {
|
||||||
|
format.to_camel_case(key) for key in props if key not in event_types
|
||||||
|
}
|
||||||
|
self.get_props = lambda: to_camel_cased_props # pyright: ignore [reportIncompatibleVariableOverride]
|
||||||
|
|
||||||
# Unset the style.
|
# Unset the style.
|
||||||
self.style = Style()
|
self.style = Style()
|
||||||
@ -1678,51 +1729,36 @@ class CustomComponent(Component):
|
|||||||
# Set the tag to the name of the function.
|
# Set the tag to the name of the function.
|
||||||
self.tag = format.to_title_case(self.component_fn.__name__)
|
self.tag = format.to_title_case(self.component_fn.__name__)
|
||||||
|
|
||||||
# Get the event triggers defined in the component declaration.
|
for key, value in props.items():
|
||||||
event_triggers_in_component_declaration = self.get_event_triggers()
|
|
||||||
|
|
||||||
# Set the props.
|
|
||||||
props = typing.get_type_hints(self.component_fn)
|
|
||||||
for key, value in kwargs.items():
|
|
||||||
# Skip kwargs that are not props.
|
# Skip kwargs that are not props.
|
||||||
if key not in props:
|
if key not in props_types:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
camel_cased_key = format.to_camel_case(key)
|
||||||
|
|
||||||
# Get the type based on the annotation.
|
# Get the type based on the annotation.
|
||||||
type_ = props[key]
|
type_ = props_types[key]
|
||||||
|
|
||||||
# Handle event chains.
|
# Handle event chains.
|
||||||
if types._issubclass(type_, EventChain):
|
if types._issubclass(type_, EventActionsMixin):
|
||||||
value = EventChain.create(
|
inspect.getfullargspec(component_fn).annotations[key]
|
||||||
value=value,
|
self.props[camel_cased_key] = EventChain.create(
|
||||||
args_spec=event_triggers_in_component_declaration.get(
|
value=value, args_spec=get_args_spec(key), key=key
|
||||||
key, no_args_event_spec
|
|
||||||
),
|
|
||||||
key=key,
|
|
||||||
)
|
)
|
||||||
self.props[format.to_camel_case(key)] = value
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Handle subclasses of Base.
|
value = LiteralVar.create(value)
|
||||||
if isinstance(value, Base):
|
self.props[camel_cased_key] = value
|
||||||
base_value = LiteralVar.create(value)
|
setattr(self, camel_cased_key, value)
|
||||||
|
|
||||||
# Track hooks and imports associated with Component instances.
|
@classmethod
|
||||||
if base_value is not None and isinstance(value, Component):
|
def _are_fields_known(cls) -> bool:
|
||||||
self.component_props[key] = value
|
"""Check if the fields are known.
|
||||||
value = base_value._replace(
|
|
||||||
merge_var_data=VarData( # type: ignore
|
|
||||||
imports=value._get_all_imports(),
|
|
||||||
hooks=value._get_all_hooks(),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
value = base_value
|
|
||||||
else:
|
|
||||||
value = LiteralVar.create(value)
|
|
||||||
|
|
||||||
# Set the prop.
|
Returns:
|
||||||
self.props[format.to_camel_case(key)] = value
|
Whether the fields are known.
|
||||||
|
"""
|
||||||
|
return False
|
||||||
|
|
||||||
def __eq__(self, other: Any) -> bool:
|
def __eq__(self, other: Any) -> bool:
|
||||||
"""Check if the component is equal to another.
|
"""Check if the component is equal to another.
|
||||||
@ -1781,27 +1817,8 @@ class CustomComponent(Component):
|
|||||||
seen=seen
|
seen=seen
|
||||||
)
|
)
|
||||||
|
|
||||||
# Fetch custom components from props as well.
|
|
||||||
for child_component in self.component_props.values():
|
|
||||||
if child_component.tag is None:
|
|
||||||
continue
|
|
||||||
if child_component.tag not in seen:
|
|
||||||
seen.add(child_component.tag)
|
|
||||||
if isinstance(child_component, CustomComponent):
|
|
||||||
custom_components |= {child_component}
|
|
||||||
custom_components |= child_component._get_all_custom_components(
|
|
||||||
seen=seen
|
|
||||||
)
|
|
||||||
return custom_components
|
return custom_components
|
||||||
|
|
||||||
def _render(self) -> Tag:
|
|
||||||
"""Define how to render the component in React.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
The tag to render.
|
|
||||||
"""
|
|
||||||
return super()._render(props=self.props)
|
|
||||||
|
|
||||||
def get_prop_vars(self) -> List[Var]:
|
def get_prop_vars(self) -> List[Var]:
|
||||||
"""Get the prop vars.
|
"""Get the prop vars.
|
||||||
|
|
||||||
@ -1812,34 +1829,19 @@ class CustomComponent(Component):
|
|||||||
Var(
|
Var(
|
||||||
_js_expr=name,
|
_js_expr=name,
|
||||||
_var_type=(
|
_var_type=(
|
||||||
prop._var_type if types._isinstance(prop, Var) else type(prop)
|
prop._var_type
|
||||||
|
if isinstance(prop, Var)
|
||||||
|
else (
|
||||||
|
type(prop)
|
||||||
|
if not isinstance(prop, EventActionsMixin)
|
||||||
|
else EventChain
|
||||||
|
)
|
||||||
),
|
),
|
||||||
).guess_type()
|
).guess_type()
|
||||||
for name, prop in self.props.items()
|
for name, prop in self.props.items()
|
||||||
]
|
]
|
||||||
|
|
||||||
def _get_vars(
|
@lru_cache(maxsize=None) # noqa: B019
|
||||||
self, include_children: bool = False, ignore_ids: set[int] | None = None
|
|
||||||
) -> Iterator[Var]:
|
|
||||||
"""Walk all Vars used in this component.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
include_children: Whether to include Vars from children.
|
|
||||||
ignore_ids: The ids to ignore.
|
|
||||||
|
|
||||||
Yields:
|
|
||||||
Each var referenced by the component (props, styles, event handlers).
|
|
||||||
"""
|
|
||||||
ignore_ids = ignore_ids or set()
|
|
||||||
yield from super()._get_vars(
|
|
||||||
include_children=include_children, ignore_ids=ignore_ids
|
|
||||||
)
|
|
||||||
yield from filter(lambda prop: isinstance(prop, Var), self.props.values())
|
|
||||||
yield from self.get_component(self)._get_vars(
|
|
||||||
include_children=include_children, ignore_ids=ignore_ids
|
|
||||||
)
|
|
||||||
|
|
||||||
@lru_cache(maxsize=None) # noqa
|
|
||||||
def get_component(self) -> Component:
|
def get_component(self) -> Component:
|
||||||
"""Render the component.
|
"""Render the component.
|
||||||
|
|
||||||
@ -1983,7 +1985,7 @@ class StatefulComponent(BaseComponent):
|
|||||||
|
|
||||||
if not should_memoize:
|
if not should_memoize:
|
||||||
# Determine if any Vars have associated data.
|
# Determine if any Vars have associated data.
|
||||||
for prop_var in component._get_vars():
|
for prop_var in component._get_vars(include_children=True):
|
||||||
if prop_var._get_all_var_data():
|
if prop_var._get_all_var_data():
|
||||||
should_memoize = True
|
should_memoize = True
|
||||||
break
|
break
|
||||||
@ -2366,8 +2368,8 @@ class MemoizationLeaf(Component):
|
|||||||
"""
|
"""
|
||||||
comp = super().create(*children, **props)
|
comp = super().create(*children, **props)
|
||||||
if comp._get_all_hooks():
|
if comp._get_all_hooks():
|
||||||
comp._memoization_mode = cls._memoization_mode.copy(
|
comp._memoization_mode = dataclasses.replace(
|
||||||
update={"disposition": MemoizationDisposition.ALWAYS}
|
comp._memoization_mode, disposition=MemoizationDisposition.ALWAYS
|
||||||
)
|
)
|
||||||
return comp
|
return comp
|
||||||
|
|
||||||
@ -2428,7 +2430,7 @@ def render_dict_to_var(tag: dict | Component | str, imported_names: set[str]) ->
|
|||||||
if tag["name"] == "match":
|
if tag["name"] == "match":
|
||||||
element = tag["cond"]
|
element = tag["cond"]
|
||||||
|
|
||||||
conditionals = tag["default"]
|
conditionals = render_dict_to_var(tag["default"], imported_names)
|
||||||
|
|
||||||
for case in tag["match_cases"][::-1]:
|
for case in tag["match_cases"][::-1]:
|
||||||
condition = case[0].to_string() == element.to_string()
|
condition = case[0].to_string() == element.to_string()
|
||||||
@ -2437,7 +2439,7 @@ def render_dict_to_var(tag: dict | Component | str, imported_names: set[str]) ->
|
|||||||
|
|
||||||
conditionals = ternary_operation(
|
conditionals = ternary_operation(
|
||||||
condition,
|
condition,
|
||||||
case[-1],
|
render_dict_to_var(case[-1], imported_names),
|
||||||
conditionals,
|
conditionals,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -2496,6 +2498,7 @@ def render_dict_to_var(tag: dict | Component | str, imported_names: set[str]) ->
|
|||||||
@dataclasses.dataclass(
|
@dataclasses.dataclass(
|
||||||
eq=False,
|
eq=False,
|
||||||
frozen=True,
|
frozen=True,
|
||||||
|
slots=True,
|
||||||
)
|
)
|
||||||
class LiteralComponentVar(CachedVarOperation, LiteralVar, ComponentVar):
|
class LiteralComponentVar(CachedVarOperation, LiteralVar, ComponentVar):
|
||||||
"""A Var that represents a Component."""
|
"""A Var that represents a Component."""
|
||||||
@ -2525,6 +2528,7 @@ class LiteralComponentVar(CachedVarOperation, LiteralVar, ComponentVar):
|
|||||||
The VarData for the var.
|
The VarData for the var.
|
||||||
"""
|
"""
|
||||||
return VarData.merge(
|
return VarData.merge(
|
||||||
|
self._var_data,
|
||||||
VarData(
|
VarData(
|
||||||
imports={
|
imports={
|
||||||
"@emotion/react": [
|
"@emotion/react": [
|
||||||
@ -2567,9 +2571,21 @@ class LiteralComponentVar(CachedVarOperation, LiteralVar, ComponentVar):
|
|||||||
Returns:
|
Returns:
|
||||||
The var.
|
The var.
|
||||||
"""
|
"""
|
||||||
|
var_datas = [
|
||||||
|
var_data
|
||||||
|
for var in value._get_vars(include_children=True)
|
||||||
|
if (var_data := var._get_all_var_data())
|
||||||
|
]
|
||||||
|
|
||||||
return LiteralComponentVar(
|
return LiteralComponentVar(
|
||||||
_js_expr="",
|
_js_expr="",
|
||||||
_var_type=type(value),
|
_var_type=type(value),
|
||||||
_var_data=_var_data,
|
_var_data=VarData.merge(
|
||||||
|
_var_data,
|
||||||
|
*var_datas,
|
||||||
|
VarData(
|
||||||
|
components=(value,),
|
||||||
|
),
|
||||||
|
),
|
||||||
_var_value=value,
|
_var_value=value,
|
||||||
)
|
)
|
||||||
|
@ -48,6 +48,7 @@ _SUBMOD_ATTRS: dict[str, list[str]] = {
|
|||||||
"get_upload_url",
|
"get_upload_url",
|
||||||
"selected_files",
|
"selected_files",
|
||||||
],
|
],
|
||||||
|
"auto_scroll": ["auto_scroll"],
|
||||||
}
|
}
|
||||||
|
|
||||||
__getattr__, __dir__, __all__ = lazy_loader.attach(
|
__getattr__, __dir__, __all__ = lazy_loader.attach(
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
# ------------------------------------------------------
|
# ------------------------------------------------------
|
||||||
|
|
||||||
from . import layout as layout
|
from . import layout as layout
|
||||||
|
from .auto_scroll import auto_scroll as auto_scroll
|
||||||
from .banner import ConnectionBanner as ConnectionBanner
|
from .banner import ConnectionBanner as ConnectionBanner
|
||||||
from .banner import ConnectionModal as ConnectionModal
|
from .banner import ConnectionModal as ConnectionModal
|
||||||
from .banner import ConnectionPulser as ConnectionPulser
|
from .banner import ConnectionPulser as ConnectionPulser
|
||||||
|
111
reflex/components/core/auto_scroll.py
Normal file
111
reflex/components/core/auto_scroll.py
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
"""A component that automatically scrolls to the bottom when new content is added."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from reflex.components.el.elements.typography import Div
|
||||||
|
from reflex.constants.compiler import MemoizationDisposition, MemoizationMode
|
||||||
|
from reflex.utils.imports import ImportDict
|
||||||
|
from reflex.vars.base import Var, get_unique_variable_name
|
||||||
|
|
||||||
|
|
||||||
|
class AutoScroll(Div):
|
||||||
|
"""A div that automatically scrolls to the bottom when new content is added."""
|
||||||
|
|
||||||
|
_memoization_mode = MemoizationMode(disposition=MemoizationDisposition.ALWAYS)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create(cls, *children, **props):
|
||||||
|
"""Create an AutoScroll component.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
*children: The children of the component.
|
||||||
|
**props: The props of the component.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
An AutoScroll component.
|
||||||
|
"""
|
||||||
|
props.setdefault("overflow", "auto")
|
||||||
|
props.setdefault("id", get_unique_variable_name())
|
||||||
|
return super().create(*children, **props)
|
||||||
|
|
||||||
|
def add_imports(self) -> ImportDict | list[ImportDict]:
|
||||||
|
"""Add imports required for the component.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The imports required for the component.
|
||||||
|
"""
|
||||||
|
return {"react": ["useEffect", "useRef"]}
|
||||||
|
|
||||||
|
def add_hooks(self) -> list[str | Var]:
|
||||||
|
"""Add hooks required for the component.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The hooks required for the component.
|
||||||
|
"""
|
||||||
|
ref_name = self.get_ref()
|
||||||
|
return [
|
||||||
|
"const containerRef = useRef(null);",
|
||||||
|
"const wasNearBottom = useRef(false);",
|
||||||
|
"const hadScrollbar = useRef(false);",
|
||||||
|
f"""
|
||||||
|
const checkIfNearBottom = () => {{
|
||||||
|
if (!{ref_name}.current) return;
|
||||||
|
|
||||||
|
const container = {ref_name}.current;
|
||||||
|
const nearBottomThreshold = 50; // pixels from bottom to trigger auto-scroll
|
||||||
|
|
||||||
|
const distanceFromBottom = container.scrollHeight - container.scrollTop - container.clientHeight;
|
||||||
|
|
||||||
|
wasNearBottom.current = distanceFromBottom <= nearBottomThreshold;
|
||||||
|
|
||||||
|
// Track if container had a scrollbar
|
||||||
|
hadScrollbar.current = container.scrollHeight > container.clientHeight;
|
||||||
|
}};
|
||||||
|
""",
|
||||||
|
f"""
|
||||||
|
const scrollToBottomIfNeeded = () => {{
|
||||||
|
if (!{ref_name}.current) return;
|
||||||
|
|
||||||
|
const container = {ref_name}.current;
|
||||||
|
const hasScrollbarNow = container.scrollHeight > container.clientHeight;
|
||||||
|
|
||||||
|
// Scroll if:
|
||||||
|
// 1. User was near bottom, OR
|
||||||
|
// 2. Container didn't have scrollbar before but does now
|
||||||
|
if (wasNearBottom.current || (!hadScrollbar.current && hasScrollbarNow)) {{
|
||||||
|
container.scrollTop = container.scrollHeight;
|
||||||
|
}}
|
||||||
|
|
||||||
|
// Update scrollbar state for next check
|
||||||
|
hadScrollbar.current = hasScrollbarNow;
|
||||||
|
}};
|
||||||
|
""",
|
||||||
|
f"""
|
||||||
|
useEffect(() => {{
|
||||||
|
const container = {ref_name}.current;
|
||||||
|
if (!container) return;
|
||||||
|
|
||||||
|
// Create ResizeObserver to detect height changes
|
||||||
|
const resizeObserver = new ResizeObserver(() => {{
|
||||||
|
scrollToBottomIfNeeded();
|
||||||
|
}});
|
||||||
|
|
||||||
|
// Track scroll position before height changes
|
||||||
|
container.addEventListener('scroll', checkIfNearBottom);
|
||||||
|
|
||||||
|
// Initial check
|
||||||
|
checkIfNearBottom();
|
||||||
|
|
||||||
|
// Observe container for size changes
|
||||||
|
resizeObserver.observe(container);
|
||||||
|
|
||||||
|
return () => {{
|
||||||
|
container.removeEventListener('scroll', checkIfNearBottom);
|
||||||
|
resizeObserver.disconnect();
|
||||||
|
}};
|
||||||
|
}});
|
||||||
|
""",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
auto_scroll = AutoScroll.create
|
284
reflex/components/core/auto_scroll.pyi
Normal file
284
reflex/components/core/auto_scroll.pyi
Normal file
@ -0,0 +1,284 @@
|
|||||||
|
"""Stub file for reflex/components/core/auto_scroll.py"""
|
||||||
|
|
||||||
|
# ------------------- DO NOT EDIT ----------------------
|
||||||
|
# This file was generated by `reflex/utils/pyi_generator.py`!
|
||||||
|
# ------------------------------------------------------
|
||||||
|
from typing import Any, Dict, Literal, Optional, Union, overload
|
||||||
|
|
||||||
|
from reflex.components.el.elements.typography import Div
|
||||||
|
from reflex.event import EventType
|
||||||
|
from reflex.style import Style
|
||||||
|
from reflex.utils.imports import ImportDict
|
||||||
|
from reflex.vars.base import Var
|
||||||
|
|
||||||
|
class AutoScroll(Div):
|
||||||
|
@overload
|
||||||
|
@classmethod
|
||||||
|
def create( # type: ignore
|
||||||
|
cls,
|
||||||
|
*children,
|
||||||
|
access_key: Optional[Union[Var[str], str]] = None,
|
||||||
|
auto_capitalize: Optional[
|
||||||
|
Union[
|
||||||
|
Literal["characters", "none", "off", "on", "sentences", "words"],
|
||||||
|
Var[Literal["characters", "none", "off", "on", "sentences", "words"]],
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
|
content_editable: Optional[
|
||||||
|
Union[
|
||||||
|
Literal["inherit", "plaintext-only", False, True],
|
||||||
|
Var[Literal["inherit", "plaintext-only", False, True]],
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
|
context_menu: Optional[Union[Var[str], str]] = None,
|
||||||
|
dir: Optional[Union[Var[str], str]] = None,
|
||||||
|
draggable: Optional[Union[Var[bool], bool]] = None,
|
||||||
|
enter_key_hint: Optional[
|
||||||
|
Union[
|
||||||
|
Literal["done", "enter", "go", "next", "previous", "search", "send"],
|
||||||
|
Var[
|
||||||
|
Literal["done", "enter", "go", "next", "previous", "search", "send"]
|
||||||
|
],
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
|
hidden: Optional[Union[Var[bool], bool]] = None,
|
||||||
|
input_mode: Optional[
|
||||||
|
Union[
|
||||||
|
Literal[
|
||||||
|
"decimal",
|
||||||
|
"email",
|
||||||
|
"none",
|
||||||
|
"numeric",
|
||||||
|
"search",
|
||||||
|
"tel",
|
||||||
|
"text",
|
||||||
|
"url",
|
||||||
|
],
|
||||||
|
Var[
|
||||||
|
Literal[
|
||||||
|
"decimal",
|
||||||
|
"email",
|
||||||
|
"none",
|
||||||
|
"numeric",
|
||||||
|
"search",
|
||||||
|
"tel",
|
||||||
|
"text",
|
||||||
|
"url",
|
||||||
|
]
|
||||||
|
],
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
|
item_prop: Optional[Union[Var[str], str]] = None,
|
||||||
|
lang: Optional[Union[Var[str], str]] = None,
|
||||||
|
role: Optional[
|
||||||
|
Union[
|
||||||
|
Literal[
|
||||||
|
"alert",
|
||||||
|
"alertdialog",
|
||||||
|
"application",
|
||||||
|
"article",
|
||||||
|
"banner",
|
||||||
|
"button",
|
||||||
|
"cell",
|
||||||
|
"checkbox",
|
||||||
|
"columnheader",
|
||||||
|
"combobox",
|
||||||
|
"complementary",
|
||||||
|
"contentinfo",
|
||||||
|
"definition",
|
||||||
|
"dialog",
|
||||||
|
"directory",
|
||||||
|
"document",
|
||||||
|
"feed",
|
||||||
|
"figure",
|
||||||
|
"form",
|
||||||
|
"grid",
|
||||||
|
"gridcell",
|
||||||
|
"group",
|
||||||
|
"heading",
|
||||||
|
"img",
|
||||||
|
"link",
|
||||||
|
"list",
|
||||||
|
"listbox",
|
||||||
|
"listitem",
|
||||||
|
"log",
|
||||||
|
"main",
|
||||||
|
"marquee",
|
||||||
|
"math",
|
||||||
|
"menu",
|
||||||
|
"menubar",
|
||||||
|
"menuitem",
|
||||||
|
"menuitemcheckbox",
|
||||||
|
"menuitemradio",
|
||||||
|
"navigation",
|
||||||
|
"none",
|
||||||
|
"note",
|
||||||
|
"option",
|
||||||
|
"presentation",
|
||||||
|
"progressbar",
|
||||||
|
"radio",
|
||||||
|
"radiogroup",
|
||||||
|
"region",
|
||||||
|
"row",
|
||||||
|
"rowgroup",
|
||||||
|
"rowheader",
|
||||||
|
"scrollbar",
|
||||||
|
"search",
|
||||||
|
"searchbox",
|
||||||
|
"separator",
|
||||||
|
"slider",
|
||||||
|
"spinbutton",
|
||||||
|
"status",
|
||||||
|
"switch",
|
||||||
|
"tab",
|
||||||
|
"table",
|
||||||
|
"tablist",
|
||||||
|
"tabpanel",
|
||||||
|
"term",
|
||||||
|
"textbox",
|
||||||
|
"timer",
|
||||||
|
"toolbar",
|
||||||
|
"tooltip",
|
||||||
|
"tree",
|
||||||
|
"treegrid",
|
||||||
|
"treeitem",
|
||||||
|
],
|
||||||
|
Var[
|
||||||
|
Literal[
|
||||||
|
"alert",
|
||||||
|
"alertdialog",
|
||||||
|
"application",
|
||||||
|
"article",
|
||||||
|
"banner",
|
||||||
|
"button",
|
||||||
|
"cell",
|
||||||
|
"checkbox",
|
||||||
|
"columnheader",
|
||||||
|
"combobox",
|
||||||
|
"complementary",
|
||||||
|
"contentinfo",
|
||||||
|
"definition",
|
||||||
|
"dialog",
|
||||||
|
"directory",
|
||||||
|
"document",
|
||||||
|
"feed",
|
||||||
|
"figure",
|
||||||
|
"form",
|
||||||
|
"grid",
|
||||||
|
"gridcell",
|
||||||
|
"group",
|
||||||
|
"heading",
|
||||||
|
"img",
|
||||||
|
"link",
|
||||||
|
"list",
|
||||||
|
"listbox",
|
||||||
|
"listitem",
|
||||||
|
"log",
|
||||||
|
"main",
|
||||||
|
"marquee",
|
||||||
|
"math",
|
||||||
|
"menu",
|
||||||
|
"menubar",
|
||||||
|
"menuitem",
|
||||||
|
"menuitemcheckbox",
|
||||||
|
"menuitemradio",
|
||||||
|
"navigation",
|
||||||
|
"none",
|
||||||
|
"note",
|
||||||
|
"option",
|
||||||
|
"presentation",
|
||||||
|
"progressbar",
|
||||||
|
"radio",
|
||||||
|
"radiogroup",
|
||||||
|
"region",
|
||||||
|
"row",
|
||||||
|
"rowgroup",
|
||||||
|
"rowheader",
|
||||||
|
"scrollbar",
|
||||||
|
"search",
|
||||||
|
"searchbox",
|
||||||
|
"separator",
|
||||||
|
"slider",
|
||||||
|
"spinbutton",
|
||||||
|
"status",
|
||||||
|
"switch",
|
||||||
|
"tab",
|
||||||
|
"table",
|
||||||
|
"tablist",
|
||||||
|
"tabpanel",
|
||||||
|
"term",
|
||||||
|
"textbox",
|
||||||
|
"timer",
|
||||||
|
"toolbar",
|
||||||
|
"tooltip",
|
||||||
|
"tree",
|
||||||
|
"treegrid",
|
||||||
|
"treeitem",
|
||||||
|
]
|
||||||
|
],
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
|
slot: Optional[Union[Var[str], str]] = None,
|
||||||
|
spell_check: Optional[Union[Var[bool], bool]] = None,
|
||||||
|
tab_index: Optional[Union[Var[int], int]] = None,
|
||||||
|
title: Optional[Union[Var[str], str]] = 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, Any]]] = None,
|
||||||
|
on_blur: Optional[EventType[()]] = None,
|
||||||
|
on_click: Optional[EventType[()]] = None,
|
||||||
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
|
on_focus: Optional[EventType[()]] = None,
|
||||||
|
on_mount: Optional[EventType[()]] = None,
|
||||||
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
|
**props,
|
||||||
|
) -> "AutoScroll":
|
||||||
|
"""Create an AutoScroll component.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
*children: The children of the component.
|
||||||
|
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.
|
||||||
|
dir: Defines the text direction. Allowed values are ltr (Left-To-Right) or rtl (Right-To-Left)
|
||||||
|
draggable: Defines whether the element can be dragged.
|
||||||
|
enter_key_hint: Hints what media types the media element is able to play.
|
||||||
|
hidden: Defines whether the element is hidden.
|
||||||
|
input_mode: Defines the type of the element.
|
||||||
|
item_prop: Defines the name of the element for metadata purposes.
|
||||||
|
lang: Defines the language used in the element.
|
||||||
|
role: Defines the role of the element.
|
||||||
|
slot: Assigns a slot in a shadow DOM shadow tree to an element.
|
||||||
|
spell_check: Defines whether the element may be checked for spelling errors.
|
||||||
|
tab_index: Defines the position of the current element in the tabbing order.
|
||||||
|
title: Defines a tooltip for the element.
|
||||||
|
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:
|
||||||
|
An AutoScroll component.
|
||||||
|
"""
|
||||||
|
...
|
||||||
|
|
||||||
|
def add_imports(self) -> ImportDict | list[ImportDict]: ...
|
||||||
|
def add_hooks(self) -> list[str | Var]: ...
|
||||||
|
|
||||||
|
auto_scroll = AutoScroll.create
|
@ -4,6 +4,7 @@ from __future__ import annotations
|
|||||||
|
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
|
from reflex import constants
|
||||||
from reflex.components.component import Component
|
from reflex.components.component import Component
|
||||||
from reflex.components.core.cond import cond
|
from reflex.components.core.cond import cond
|
||||||
from reflex.components.el.elements.typography import Div
|
from reflex.components.el.elements.typography import Div
|
||||||
@ -16,6 +17,7 @@ from reflex.components.radix.themes.components.dialog import (
|
|||||||
from reflex.components.radix.themes.layout.flex import Flex
|
from reflex.components.radix.themes.layout.flex import Flex
|
||||||
from reflex.components.radix.themes.typography.text import Text
|
from reflex.components.radix.themes.typography.text import Text
|
||||||
from reflex.components.sonner.toast import Toaster, ToastProps
|
from reflex.components.sonner.toast import Toaster, ToastProps
|
||||||
|
from reflex.config import environment
|
||||||
from reflex.constants import Dirs, Hooks, Imports
|
from reflex.constants import Dirs, Hooks, Imports
|
||||||
from reflex.constants.compiler import CompileVars
|
from reflex.constants.compiler import CompileVars
|
||||||
from reflex.utils.imports import ImportVar
|
from reflex.utils.imports import ImportVar
|
||||||
@ -25,7 +27,7 @@ from reflex.vars.function import FunctionStringVar
|
|||||||
from reflex.vars.number import BooleanVar
|
from reflex.vars.number import BooleanVar
|
||||||
from reflex.vars.sequence import LiteralArrayVar
|
from reflex.vars.sequence import LiteralArrayVar
|
||||||
|
|
||||||
connect_error_var_data: VarData = VarData( # type: ignore
|
connect_error_var_data: VarData = VarData(
|
||||||
imports=Imports.EVENTS,
|
imports=Imports.EVENTS,
|
||||||
hooks={Hooks.EVENTS: None},
|
hooks={Hooks.EVENTS: None},
|
||||||
)
|
)
|
||||||
@ -99,24 +101,56 @@ class ConnectionToaster(Toaster):
|
|||||||
"""
|
"""
|
||||||
toast_id = "websocket-error"
|
toast_id = "websocket-error"
|
||||||
target_url = WebsocketTargetURL.create()
|
target_url = WebsocketTargetURL.create()
|
||||||
props = ToastProps( # type: ignore
|
props = ToastProps(
|
||||||
description=LiteralVar.create(
|
description=LiteralVar.create(
|
||||||
f"Check if server is reachable at {target_url}",
|
f"Check if server is reachable at {target_url}",
|
||||||
),
|
),
|
||||||
close_button=True,
|
close_button=True,
|
||||||
duration=120000,
|
duration=120000,
|
||||||
id=toast_id,
|
id=toast_id,
|
||||||
)
|
) # pyright: ignore [reportCallIssue]
|
||||||
|
|
||||||
|
if environment.REFLEX_DOES_BACKEND_COLD_START.get():
|
||||||
|
loading_message = Var.create("Backend is starting.")
|
||||||
|
backend_is_loading_toast_var = Var(
|
||||||
|
f"toast.loading({loading_message!s}, {{...toast_props, description: '', closeButton: false, onDismiss: () => setUserDismissed(true)}},)"
|
||||||
|
)
|
||||||
|
backend_is_not_responding = Var.create("Backend is not responding.")
|
||||||
|
backend_is_down_toast_var = Var(
|
||||||
|
f"toast.error({backend_is_not_responding!s}, {{...toast_props, description: '', onDismiss: () => setUserDismissed(true)}},)"
|
||||||
|
)
|
||||||
|
toast_var = Var(
|
||||||
|
f"""
|
||||||
|
if (waitedForBackend) {{
|
||||||
|
{backend_is_down_toast_var!s}
|
||||||
|
}} else {{
|
||||||
|
{backend_is_loading_toast_var!s};
|
||||||
|
}}
|
||||||
|
setTimeout(() => {{
|
||||||
|
if ({has_too_many_connection_errors!s}) {{
|
||||||
|
setWaitedForBackend(true);
|
||||||
|
}}
|
||||||
|
}}, {environment.REFLEX_BACKEND_COLD_START_TIMEOUT.get() * 1000});
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
loading_message = Var.create(
|
||||||
|
f"Cannot connect to server: {connection_error}."
|
||||||
|
)
|
||||||
|
toast_var = Var(
|
||||||
|
f"toast.error({loading_message!s}, {{...toast_props, onDismiss: () => setUserDismissed(true)}},)"
|
||||||
|
)
|
||||||
|
|
||||||
individual_hooks = [
|
individual_hooks = [
|
||||||
f"const toast_props = {LiteralVar.create(props)!s};",
|
f"const toast_props = {LiteralVar.create(props)!s};",
|
||||||
"const [userDismissed, setUserDismissed] = useState(false);",
|
"const [userDismissed, setUserDismissed] = useState(false);",
|
||||||
|
"const [waitedForBackend, setWaitedForBackend] = useState(false);",
|
||||||
FunctionStringVar(
|
FunctionStringVar(
|
||||||
"useEffect",
|
"useEffect",
|
||||||
_var_data=VarData(
|
_var_data=VarData(
|
||||||
imports={
|
imports={
|
||||||
"react": ["useEffect", "useState"],
|
"react": ["useEffect", "useState"],
|
||||||
**dict(target_url._get_all_var_data().imports), # type: ignore
|
**dict(target_url._get_all_var_data().imports), # pyright: ignore [reportArgumentType, reportOptionalMemberAccess]
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
).call(
|
).call(
|
||||||
@ -126,10 +160,7 @@ class ConnectionToaster(Toaster):
|
|||||||
() => {{
|
() => {{
|
||||||
if ({has_too_many_connection_errors!s}) {{
|
if ({has_too_many_connection_errors!s}) {{
|
||||||
if (!userDismissed) {{
|
if (!userDismissed) {{
|
||||||
toast.error(
|
{toast_var!s}
|
||||||
`Cannot connect to server: ${{{connection_error}}}.`,
|
|
||||||
{{...toast_props, onDismiss: () => setUserDismissed(true)}},
|
|
||||||
)
|
|
||||||
}}
|
}}
|
||||||
}} else {{
|
}} else {{
|
||||||
toast.dismiss("{toast_id}");
|
toast.dismiss("{toast_id}");
|
||||||
@ -138,7 +169,7 @@ class ConnectionToaster(Toaster):
|
|||||||
}}
|
}}
|
||||||
"""
|
"""
|
||||||
),
|
),
|
||||||
LiteralArrayVar.create([connect_errors]),
|
LiteralArrayVar.create([connect_errors, Var("waitedForBackend")]),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -293,7 +324,161 @@ class ConnectionPulser(Div):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class BackendDisabled(Div):
|
||||||
|
"""A component that displays a message when the backend is disabled."""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create(cls, **props) -> Component:
|
||||||
|
"""Create a backend disabled component.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
**props: The properties of the component.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The backend disabled component.
|
||||||
|
"""
|
||||||
|
import reflex as rx
|
||||||
|
|
||||||
|
is_backend_disabled = Var(
|
||||||
|
"backendDisabled",
|
||||||
|
_var_type=bool,
|
||||||
|
_var_data=VarData(
|
||||||
|
hooks={
|
||||||
|
"const [backendDisabled, setBackendDisabled] = useState(false);": None,
|
||||||
|
"useEffect(() => { setBackendDisabled(isBackendDisabled()); }, []);": None,
|
||||||
|
},
|
||||||
|
imports={
|
||||||
|
f"$/{constants.Dirs.STATE_PATH}": [
|
||||||
|
ImportVar(tag="isBackendDisabled")
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
return super().create(
|
||||||
|
rx.cond(
|
||||||
|
is_backend_disabled,
|
||||||
|
rx.box(
|
||||||
|
rx.el.link(
|
||||||
|
rel="preconnect",
|
||||||
|
href="https://fonts.googleapis.com",
|
||||||
|
),
|
||||||
|
rx.el.link(
|
||||||
|
rel="preconnect",
|
||||||
|
href="https://fonts.gstatic.com",
|
||||||
|
crossorigin="",
|
||||||
|
),
|
||||||
|
rx.el.link(
|
||||||
|
href="https://fonts.googleapis.com/css2?family=Instrument+Sans:ital,wght@0,500;0,600&display=swap",
|
||||||
|
rel="stylesheet",
|
||||||
|
),
|
||||||
|
rx.box(
|
||||||
|
rx.vstack(
|
||||||
|
rx.text(
|
||||||
|
"This app is paused",
|
||||||
|
font_size="1.5rem",
|
||||||
|
font_weight="600",
|
||||||
|
line_height="1.25rem",
|
||||||
|
letter_spacing="-0.0375rem",
|
||||||
|
),
|
||||||
|
rx.hstack(
|
||||||
|
rx.el.svg(
|
||||||
|
rx.el.svg.path(
|
||||||
|
d="M6.90816 1.34341C7.61776 1.10786 8.38256 1.10786 9.09216 1.34341C9.7989 1.57799 10.3538 2.13435 10.9112 2.91605C11.4668 3.69515 12.0807 4.78145 12.872 6.18175L12.9031 6.23672C13.6946 7.63721 14.3085 8.72348 14.6911 9.60441C15.0755 10.4896 15.267 11.2539 15.1142 11.9881C14.9604 12.7275 14.5811 13.3997 14.0287 13.9079C13.4776 14.4147 12.7273 14.6286 11.7826 14.7313C10.8432 14.8334 9.6143 14.8334 8.0327 14.8334H7.9677C6.38604 14.8334 5.15719 14.8334 4.21778 14.7313C3.27301 14.6286 2.52269 14.4147 1.97164 13.9079C1.41924 13.3997 1.03995 12.7275 0.88613 11.9881C0.733363 11.2539 0.92483 10.4896 1.30926 9.60441C1.69184 8.72348 2.30573 7.63721 3.09722 6.23671L3.12828 6.18175C3.91964 4.78146 4.53355 3.69515 5.08914 2.91605C5.64658 2.13435 6.20146 1.57799 6.90816 1.34341ZM7.3335 11.3334C7.3335 10.9652 7.63063 10.6667 7.99716 10.6667H8.00316C8.3697 10.6667 8.66683 10.9652 8.66683 11.3334C8.66683 11.7016 8.3697 12.0001 8.00316 12.0001H7.99716C7.63063 12.0001 7.3335 11.7016 7.3335 11.3334ZM7.3335 8.66675C7.3335 9.03495 7.63196 9.33341 8.00016 9.33341C8.36836 9.33341 8.66683 9.03495 8.66683 8.66675V6.00008C8.66683 5.63189 8.36836 5.33341 8.00016 5.33341C7.63196 5.33341 7.3335 5.63189 7.3335 6.00008V8.66675Z",
|
||||||
|
fill_rule="evenodd",
|
||||||
|
clip_rule="evenodd",
|
||||||
|
fill=rx.color("amber", 11),
|
||||||
|
),
|
||||||
|
width="16",
|
||||||
|
height="16",
|
||||||
|
viewBox="0 0 16 16",
|
||||||
|
fill="none",
|
||||||
|
xmlns="http://www.w3.org/2000/svg",
|
||||||
|
margin_top="0.125rem",
|
||||||
|
flex_shrink="0",
|
||||||
|
),
|
||||||
|
rx.text(
|
||||||
|
"If you are the owner of this app, visit ",
|
||||||
|
rx.link(
|
||||||
|
"Reflex Cloud",
|
||||||
|
color=rx.color("amber", 11),
|
||||||
|
underline="always",
|
||||||
|
_hover={
|
||||||
|
"color": rx.color("amber", 11),
|
||||||
|
"text_decoration_color": rx.color(
|
||||||
|
"amber", 11
|
||||||
|
),
|
||||||
|
},
|
||||||
|
text_decoration_color=rx.color("amber", 10),
|
||||||
|
href="https://cloud.reflex.dev/",
|
||||||
|
font_weight="600",
|
||||||
|
is_external=True,
|
||||||
|
),
|
||||||
|
" for more information on how to resume your app.",
|
||||||
|
font_size="0.875rem",
|
||||||
|
font_weight="500",
|
||||||
|
line_height="1.25rem",
|
||||||
|
letter_spacing="-0.01094rem",
|
||||||
|
color=rx.color("amber", 11),
|
||||||
|
),
|
||||||
|
align="start",
|
||||||
|
gap="0.625rem",
|
||||||
|
border_radius="0.75rem",
|
||||||
|
border_width="1px",
|
||||||
|
border_color=rx.color("amber", 5),
|
||||||
|
background_color=rx.color("amber", 3),
|
||||||
|
padding="0.625rem",
|
||||||
|
),
|
||||||
|
rx.link(
|
||||||
|
rx.el.button(
|
||||||
|
"Resume app",
|
||||||
|
color="rgba(252, 252, 253, 1)",
|
||||||
|
font_size="0.875rem",
|
||||||
|
font_weight="600",
|
||||||
|
line_height="1.25rem",
|
||||||
|
letter_spacing="-0.01094rem",
|
||||||
|
height="2.5rem",
|
||||||
|
padding="0rem 0.75rem",
|
||||||
|
width="100%",
|
||||||
|
border_radius="0.75rem",
|
||||||
|
background=f"linear-gradient(180deg, {rx.color('violet', 9)} 0%, {rx.color('violet', 10)} 100%)",
|
||||||
|
_hover={
|
||||||
|
"background": f"linear-gradient(180deg, {rx.color('violet', 10)} 0%, {rx.color('violet', 10)} 100%)",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
width="100%",
|
||||||
|
underline="none",
|
||||||
|
href="https://cloud.reflex.dev/",
|
||||||
|
is_external=True,
|
||||||
|
),
|
||||||
|
gap="1rem",
|
||||||
|
),
|
||||||
|
font_family='"Instrument Sans", "Helvetica", "Arial", sans-serif',
|
||||||
|
position="fixed",
|
||||||
|
top="50%",
|
||||||
|
left="50%",
|
||||||
|
transform="translate(-50%, -50%)",
|
||||||
|
width="60ch",
|
||||||
|
max_width="90vw",
|
||||||
|
border_radius="0.75rem",
|
||||||
|
border_width="1px",
|
||||||
|
border_color=rx.color("slate", 4),
|
||||||
|
padding="1.5rem",
|
||||||
|
background_color=rx.color("slate", 1),
|
||||||
|
box_shadow="0px 2px 5px 0px light-dark(rgba(28, 32, 36, 0.03), rgba(0, 0, 0, 0.00))",
|
||||||
|
),
|
||||||
|
position="fixed",
|
||||||
|
z_index=9999,
|
||||||
|
backdrop_filter="grayscale(1) blur(5px)",
|
||||||
|
width="100dvw",
|
||||||
|
height="100dvh",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
connection_banner = ConnectionBanner.create
|
connection_banner = ConnectionBanner.create
|
||||||
connection_modal = ConnectionModal.create
|
connection_modal = ConnectionModal.create
|
||||||
connection_toaster = ConnectionToaster.create
|
connection_toaster = ConnectionToaster.create
|
||||||
connection_pulser = ConnectionPulser.create
|
connection_pulser = ConnectionPulser.create
|
||||||
|
backend_disabled = BackendDisabled.create
|
||||||
|
@ -10,7 +10,7 @@ from reflex.components.el.elements.typography import Div
|
|||||||
from reflex.components.lucide.icon import Icon
|
from reflex.components.lucide.icon import Icon
|
||||||
from reflex.components.sonner.toast import Toaster, ToastProps
|
from reflex.components.sonner.toast import Toaster, ToastProps
|
||||||
from reflex.constants.compiler import CompileVars
|
from reflex.constants.compiler import CompileVars
|
||||||
from reflex.event import BASE_STATE, EventType
|
from reflex.event import EventType
|
||||||
from reflex.style import Style
|
from reflex.style import Style
|
||||||
from reflex.utils.imports import ImportVar
|
from reflex.utils.imports import ImportVar
|
||||||
from reflex.vars import VarData
|
from reflex.vars import VarData
|
||||||
@ -89,21 +89,21 @@ class ConnectionToaster(Toaster):
|
|||||||
class_name: Optional[Any] = None,
|
class_name: Optional[Any] = None,
|
||||||
autofocus: Optional[bool] = None,
|
autofocus: Optional[bool] = None,
|
||||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
on_blur: Optional[EventType[()]] = None,
|
||||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_click: Optional[EventType[()]] = None,
|
||||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
on_focus: Optional[EventType[()]] = None,
|
||||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
on_mount: Optional[EventType[()]] = None,
|
||||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
**props,
|
**props,
|
||||||
) -> "ConnectionToaster":
|
) -> "ConnectionToaster":
|
||||||
"""Create a connection toaster component.
|
"""Create a connection toaster component.
|
||||||
@ -149,21 +149,21 @@ class ConnectionBanner(Component):
|
|||||||
class_name: Optional[Any] = None,
|
class_name: Optional[Any] = None,
|
||||||
autofocus: Optional[bool] = None,
|
autofocus: Optional[bool] = None,
|
||||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
on_blur: Optional[EventType[()]] = None,
|
||||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_click: Optional[EventType[()]] = None,
|
||||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
on_focus: Optional[EventType[()]] = None,
|
||||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
on_mount: Optional[EventType[()]] = None,
|
||||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
**props,
|
**props,
|
||||||
) -> "ConnectionBanner":
|
) -> "ConnectionBanner":
|
||||||
"""Create a connection banner component.
|
"""Create a connection banner component.
|
||||||
@ -188,21 +188,21 @@ class ConnectionModal(Component):
|
|||||||
class_name: Optional[Any] = None,
|
class_name: Optional[Any] = None,
|
||||||
autofocus: Optional[bool] = None,
|
autofocus: Optional[bool] = None,
|
||||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
on_blur: Optional[EventType[()]] = None,
|
||||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_click: Optional[EventType[()]] = None,
|
||||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
on_focus: Optional[EventType[()]] = None,
|
||||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
on_mount: Optional[EventType[()]] = None,
|
||||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
**props,
|
**props,
|
||||||
) -> "ConnectionModal":
|
) -> "ConnectionModal":
|
||||||
"""Create a connection banner component.
|
"""Create a connection banner component.
|
||||||
@ -228,21 +228,21 @@ class WifiOffPulse(Icon):
|
|||||||
class_name: Optional[Any] = None,
|
class_name: Optional[Any] = None,
|
||||||
autofocus: Optional[bool] = None,
|
autofocus: Optional[bool] = None,
|
||||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
on_blur: Optional[EventType[()]] = None,
|
||||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_click: Optional[EventType[()]] = None,
|
||||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
on_focus: Optional[EventType[()]] = None,
|
||||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
on_mount: Optional[EventType[()]] = None,
|
||||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
**props,
|
**props,
|
||||||
) -> "WifiOffPulse":
|
) -> "WifiOffPulse":
|
||||||
"""Create a wifi_off icon with an animated opacity pulse.
|
"""Create a wifi_off icon with an animated opacity pulse.
|
||||||
@ -271,51 +271,232 @@ class ConnectionPulser(Div):
|
|||||||
def create( # type: ignore
|
def create( # type: ignore
|
||||||
cls,
|
cls,
|
||||||
*children,
|
*children,
|
||||||
access_key: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
|
access_key: Optional[Union[Var[str], str]] = None,
|
||||||
auto_capitalize: Optional[
|
auto_capitalize: Optional[
|
||||||
Union[Var[Union[bool, int, str]], bool, int, str]
|
Union[
|
||||||
|
Literal["characters", "none", "off", "on", "sentences", "words"],
|
||||||
|
Var[Literal["characters", "none", "off", "on", "sentences", "words"]],
|
||||||
|
]
|
||||||
] = None,
|
] = None,
|
||||||
content_editable: Optional[
|
content_editable: Optional[
|
||||||
Union[Var[Union[bool, int, str]], bool, int, str]
|
Union[
|
||||||
|
Literal["inherit", "plaintext-only", False, True],
|
||||||
|
Var[Literal["inherit", "plaintext-only", False, True]],
|
||||||
|
]
|
||||||
] = None,
|
] = None,
|
||||||
context_menu: Optional[
|
context_menu: Optional[Union[Var[str], str]] = None,
|
||||||
Union[Var[Union[bool, int, str]], bool, int, str]
|
dir: Optional[Union[Var[str], str]] = None,
|
||||||
] = None,
|
draggable: Optional[Union[Var[bool], bool]] = None,
|
||||||
dir: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
|
|
||||||
draggable: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
|
|
||||||
enter_key_hint: Optional[
|
enter_key_hint: Optional[
|
||||||
Union[Var[Union[bool, int, str]], bool, int, str]
|
Union[
|
||||||
|
Literal["done", "enter", "go", "next", "previous", "search", "send"],
|
||||||
|
Var[
|
||||||
|
Literal["done", "enter", "go", "next", "previous", "search", "send"]
|
||||||
|
],
|
||||||
|
]
|
||||||
] = None,
|
] = None,
|
||||||
hidden: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
|
hidden: Optional[Union[Var[bool], bool]] = None,
|
||||||
input_mode: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
|
input_mode: Optional[
|
||||||
item_prop: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
|
Union[
|
||||||
lang: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
|
Literal[
|
||||||
role: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
|
"decimal",
|
||||||
slot: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
|
"email",
|
||||||
spell_check: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
|
"none",
|
||||||
tab_index: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
|
"numeric",
|
||||||
title: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
|
"search",
|
||||||
|
"tel",
|
||||||
|
"text",
|
||||||
|
"url",
|
||||||
|
],
|
||||||
|
Var[
|
||||||
|
Literal[
|
||||||
|
"decimal",
|
||||||
|
"email",
|
||||||
|
"none",
|
||||||
|
"numeric",
|
||||||
|
"search",
|
||||||
|
"tel",
|
||||||
|
"text",
|
||||||
|
"url",
|
||||||
|
]
|
||||||
|
],
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
|
item_prop: Optional[Union[Var[str], str]] = None,
|
||||||
|
lang: Optional[Union[Var[str], str]] = None,
|
||||||
|
role: Optional[
|
||||||
|
Union[
|
||||||
|
Literal[
|
||||||
|
"alert",
|
||||||
|
"alertdialog",
|
||||||
|
"application",
|
||||||
|
"article",
|
||||||
|
"banner",
|
||||||
|
"button",
|
||||||
|
"cell",
|
||||||
|
"checkbox",
|
||||||
|
"columnheader",
|
||||||
|
"combobox",
|
||||||
|
"complementary",
|
||||||
|
"contentinfo",
|
||||||
|
"definition",
|
||||||
|
"dialog",
|
||||||
|
"directory",
|
||||||
|
"document",
|
||||||
|
"feed",
|
||||||
|
"figure",
|
||||||
|
"form",
|
||||||
|
"grid",
|
||||||
|
"gridcell",
|
||||||
|
"group",
|
||||||
|
"heading",
|
||||||
|
"img",
|
||||||
|
"link",
|
||||||
|
"list",
|
||||||
|
"listbox",
|
||||||
|
"listitem",
|
||||||
|
"log",
|
||||||
|
"main",
|
||||||
|
"marquee",
|
||||||
|
"math",
|
||||||
|
"menu",
|
||||||
|
"menubar",
|
||||||
|
"menuitem",
|
||||||
|
"menuitemcheckbox",
|
||||||
|
"menuitemradio",
|
||||||
|
"navigation",
|
||||||
|
"none",
|
||||||
|
"note",
|
||||||
|
"option",
|
||||||
|
"presentation",
|
||||||
|
"progressbar",
|
||||||
|
"radio",
|
||||||
|
"radiogroup",
|
||||||
|
"region",
|
||||||
|
"row",
|
||||||
|
"rowgroup",
|
||||||
|
"rowheader",
|
||||||
|
"scrollbar",
|
||||||
|
"search",
|
||||||
|
"searchbox",
|
||||||
|
"separator",
|
||||||
|
"slider",
|
||||||
|
"spinbutton",
|
||||||
|
"status",
|
||||||
|
"switch",
|
||||||
|
"tab",
|
||||||
|
"table",
|
||||||
|
"tablist",
|
||||||
|
"tabpanel",
|
||||||
|
"term",
|
||||||
|
"textbox",
|
||||||
|
"timer",
|
||||||
|
"toolbar",
|
||||||
|
"tooltip",
|
||||||
|
"tree",
|
||||||
|
"treegrid",
|
||||||
|
"treeitem",
|
||||||
|
],
|
||||||
|
Var[
|
||||||
|
Literal[
|
||||||
|
"alert",
|
||||||
|
"alertdialog",
|
||||||
|
"application",
|
||||||
|
"article",
|
||||||
|
"banner",
|
||||||
|
"button",
|
||||||
|
"cell",
|
||||||
|
"checkbox",
|
||||||
|
"columnheader",
|
||||||
|
"combobox",
|
||||||
|
"complementary",
|
||||||
|
"contentinfo",
|
||||||
|
"definition",
|
||||||
|
"dialog",
|
||||||
|
"directory",
|
||||||
|
"document",
|
||||||
|
"feed",
|
||||||
|
"figure",
|
||||||
|
"form",
|
||||||
|
"grid",
|
||||||
|
"gridcell",
|
||||||
|
"group",
|
||||||
|
"heading",
|
||||||
|
"img",
|
||||||
|
"link",
|
||||||
|
"list",
|
||||||
|
"listbox",
|
||||||
|
"listitem",
|
||||||
|
"log",
|
||||||
|
"main",
|
||||||
|
"marquee",
|
||||||
|
"math",
|
||||||
|
"menu",
|
||||||
|
"menubar",
|
||||||
|
"menuitem",
|
||||||
|
"menuitemcheckbox",
|
||||||
|
"menuitemradio",
|
||||||
|
"navigation",
|
||||||
|
"none",
|
||||||
|
"note",
|
||||||
|
"option",
|
||||||
|
"presentation",
|
||||||
|
"progressbar",
|
||||||
|
"radio",
|
||||||
|
"radiogroup",
|
||||||
|
"region",
|
||||||
|
"row",
|
||||||
|
"rowgroup",
|
||||||
|
"rowheader",
|
||||||
|
"scrollbar",
|
||||||
|
"search",
|
||||||
|
"searchbox",
|
||||||
|
"separator",
|
||||||
|
"slider",
|
||||||
|
"spinbutton",
|
||||||
|
"status",
|
||||||
|
"switch",
|
||||||
|
"tab",
|
||||||
|
"table",
|
||||||
|
"tablist",
|
||||||
|
"tabpanel",
|
||||||
|
"term",
|
||||||
|
"textbox",
|
||||||
|
"timer",
|
||||||
|
"toolbar",
|
||||||
|
"tooltip",
|
||||||
|
"tree",
|
||||||
|
"treegrid",
|
||||||
|
"treeitem",
|
||||||
|
]
|
||||||
|
],
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
|
slot: Optional[Union[Var[str], str]] = None,
|
||||||
|
spell_check: Optional[Union[Var[bool], bool]] = None,
|
||||||
|
tab_index: Optional[Union[Var[int], int]] = None,
|
||||||
|
title: Optional[Union[Var[str], str]] = None,
|
||||||
style: Optional[Style] = None,
|
style: Optional[Style] = None,
|
||||||
key: Optional[Any] = None,
|
key: Optional[Any] = None,
|
||||||
id: Optional[Any] = None,
|
id: Optional[Any] = None,
|
||||||
class_name: Optional[Any] = None,
|
class_name: Optional[Any] = None,
|
||||||
autofocus: Optional[bool] = None,
|
autofocus: Optional[bool] = None,
|
||||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
on_blur: Optional[EventType[()]] = None,
|
||||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_click: Optional[EventType[()]] = None,
|
||||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
on_focus: Optional[EventType[()]] = None,
|
||||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
on_mount: Optional[EventType[()]] = None,
|
||||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
**props,
|
**props,
|
||||||
) -> "ConnectionPulser":
|
) -> "ConnectionPulser":
|
||||||
"""Create a connection pulser component.
|
"""Create a connection pulser component.
|
||||||
@ -350,7 +531,274 @@ class ConnectionPulser(Div):
|
|||||||
"""
|
"""
|
||||||
...
|
...
|
||||||
|
|
||||||
|
class BackendDisabled(Div):
|
||||||
|
@overload
|
||||||
|
@classmethod
|
||||||
|
def create( # type: ignore
|
||||||
|
cls,
|
||||||
|
*children,
|
||||||
|
access_key: Optional[Union[Var[str], str]] = None,
|
||||||
|
auto_capitalize: Optional[
|
||||||
|
Union[
|
||||||
|
Literal["characters", "none", "off", "on", "sentences", "words"],
|
||||||
|
Var[Literal["characters", "none", "off", "on", "sentences", "words"]],
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
|
content_editable: Optional[
|
||||||
|
Union[
|
||||||
|
Literal["inherit", "plaintext-only", False, True],
|
||||||
|
Var[Literal["inherit", "plaintext-only", False, True]],
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
|
context_menu: Optional[Union[Var[str], str]] = None,
|
||||||
|
dir: Optional[Union[Var[str], str]] = None,
|
||||||
|
draggable: Optional[Union[Var[bool], bool]] = None,
|
||||||
|
enter_key_hint: Optional[
|
||||||
|
Union[
|
||||||
|
Literal["done", "enter", "go", "next", "previous", "search", "send"],
|
||||||
|
Var[
|
||||||
|
Literal["done", "enter", "go", "next", "previous", "search", "send"]
|
||||||
|
],
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
|
hidden: Optional[Union[Var[bool], bool]] = None,
|
||||||
|
input_mode: Optional[
|
||||||
|
Union[
|
||||||
|
Literal[
|
||||||
|
"decimal",
|
||||||
|
"email",
|
||||||
|
"none",
|
||||||
|
"numeric",
|
||||||
|
"search",
|
||||||
|
"tel",
|
||||||
|
"text",
|
||||||
|
"url",
|
||||||
|
],
|
||||||
|
Var[
|
||||||
|
Literal[
|
||||||
|
"decimal",
|
||||||
|
"email",
|
||||||
|
"none",
|
||||||
|
"numeric",
|
||||||
|
"search",
|
||||||
|
"tel",
|
||||||
|
"text",
|
||||||
|
"url",
|
||||||
|
]
|
||||||
|
],
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
|
item_prop: Optional[Union[Var[str], str]] = None,
|
||||||
|
lang: Optional[Union[Var[str], str]] = None,
|
||||||
|
role: Optional[
|
||||||
|
Union[
|
||||||
|
Literal[
|
||||||
|
"alert",
|
||||||
|
"alertdialog",
|
||||||
|
"application",
|
||||||
|
"article",
|
||||||
|
"banner",
|
||||||
|
"button",
|
||||||
|
"cell",
|
||||||
|
"checkbox",
|
||||||
|
"columnheader",
|
||||||
|
"combobox",
|
||||||
|
"complementary",
|
||||||
|
"contentinfo",
|
||||||
|
"definition",
|
||||||
|
"dialog",
|
||||||
|
"directory",
|
||||||
|
"document",
|
||||||
|
"feed",
|
||||||
|
"figure",
|
||||||
|
"form",
|
||||||
|
"grid",
|
||||||
|
"gridcell",
|
||||||
|
"group",
|
||||||
|
"heading",
|
||||||
|
"img",
|
||||||
|
"link",
|
||||||
|
"list",
|
||||||
|
"listbox",
|
||||||
|
"listitem",
|
||||||
|
"log",
|
||||||
|
"main",
|
||||||
|
"marquee",
|
||||||
|
"math",
|
||||||
|
"menu",
|
||||||
|
"menubar",
|
||||||
|
"menuitem",
|
||||||
|
"menuitemcheckbox",
|
||||||
|
"menuitemradio",
|
||||||
|
"navigation",
|
||||||
|
"none",
|
||||||
|
"note",
|
||||||
|
"option",
|
||||||
|
"presentation",
|
||||||
|
"progressbar",
|
||||||
|
"radio",
|
||||||
|
"radiogroup",
|
||||||
|
"region",
|
||||||
|
"row",
|
||||||
|
"rowgroup",
|
||||||
|
"rowheader",
|
||||||
|
"scrollbar",
|
||||||
|
"search",
|
||||||
|
"searchbox",
|
||||||
|
"separator",
|
||||||
|
"slider",
|
||||||
|
"spinbutton",
|
||||||
|
"status",
|
||||||
|
"switch",
|
||||||
|
"tab",
|
||||||
|
"table",
|
||||||
|
"tablist",
|
||||||
|
"tabpanel",
|
||||||
|
"term",
|
||||||
|
"textbox",
|
||||||
|
"timer",
|
||||||
|
"toolbar",
|
||||||
|
"tooltip",
|
||||||
|
"tree",
|
||||||
|
"treegrid",
|
||||||
|
"treeitem",
|
||||||
|
],
|
||||||
|
Var[
|
||||||
|
Literal[
|
||||||
|
"alert",
|
||||||
|
"alertdialog",
|
||||||
|
"application",
|
||||||
|
"article",
|
||||||
|
"banner",
|
||||||
|
"button",
|
||||||
|
"cell",
|
||||||
|
"checkbox",
|
||||||
|
"columnheader",
|
||||||
|
"combobox",
|
||||||
|
"complementary",
|
||||||
|
"contentinfo",
|
||||||
|
"definition",
|
||||||
|
"dialog",
|
||||||
|
"directory",
|
||||||
|
"document",
|
||||||
|
"feed",
|
||||||
|
"figure",
|
||||||
|
"form",
|
||||||
|
"grid",
|
||||||
|
"gridcell",
|
||||||
|
"group",
|
||||||
|
"heading",
|
||||||
|
"img",
|
||||||
|
"link",
|
||||||
|
"list",
|
||||||
|
"listbox",
|
||||||
|
"listitem",
|
||||||
|
"log",
|
||||||
|
"main",
|
||||||
|
"marquee",
|
||||||
|
"math",
|
||||||
|
"menu",
|
||||||
|
"menubar",
|
||||||
|
"menuitem",
|
||||||
|
"menuitemcheckbox",
|
||||||
|
"menuitemradio",
|
||||||
|
"navigation",
|
||||||
|
"none",
|
||||||
|
"note",
|
||||||
|
"option",
|
||||||
|
"presentation",
|
||||||
|
"progressbar",
|
||||||
|
"radio",
|
||||||
|
"radiogroup",
|
||||||
|
"region",
|
||||||
|
"row",
|
||||||
|
"rowgroup",
|
||||||
|
"rowheader",
|
||||||
|
"scrollbar",
|
||||||
|
"search",
|
||||||
|
"searchbox",
|
||||||
|
"separator",
|
||||||
|
"slider",
|
||||||
|
"spinbutton",
|
||||||
|
"status",
|
||||||
|
"switch",
|
||||||
|
"tab",
|
||||||
|
"table",
|
||||||
|
"tablist",
|
||||||
|
"tabpanel",
|
||||||
|
"term",
|
||||||
|
"textbox",
|
||||||
|
"timer",
|
||||||
|
"toolbar",
|
||||||
|
"tooltip",
|
||||||
|
"tree",
|
||||||
|
"treegrid",
|
||||||
|
"treeitem",
|
||||||
|
]
|
||||||
|
],
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
|
slot: Optional[Union[Var[str], str]] = None,
|
||||||
|
spell_check: Optional[Union[Var[bool], bool]] = None,
|
||||||
|
tab_index: Optional[Union[Var[int], int]] = None,
|
||||||
|
title: Optional[Union[Var[str], str]] = 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, Any]]] = None,
|
||||||
|
on_blur: Optional[EventType[()]] = None,
|
||||||
|
on_click: Optional[EventType[()]] = None,
|
||||||
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
|
on_focus: Optional[EventType[()]] = None,
|
||||||
|
on_mount: Optional[EventType[()]] = None,
|
||||||
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
|
**props,
|
||||||
|
) -> "BackendDisabled":
|
||||||
|
"""Create a backend disabled component.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
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.
|
||||||
|
dir: Defines the text direction. Allowed values are ltr (Left-To-Right) or rtl (Right-To-Left)
|
||||||
|
draggable: Defines whether the element can be dragged.
|
||||||
|
enter_key_hint: Hints what media types the media element is able to play.
|
||||||
|
hidden: Defines whether the element is hidden.
|
||||||
|
input_mode: Defines the type of the element.
|
||||||
|
item_prop: Defines the name of the element for metadata purposes.
|
||||||
|
lang: Defines the language used in the element.
|
||||||
|
role: Defines the role of the element.
|
||||||
|
slot: Assigns a slot in a shadow DOM shadow tree to an element.
|
||||||
|
spell_check: Defines whether the element may be checked for spelling errors.
|
||||||
|
tab_index: Defines the position of the current element in the tabbing order.
|
||||||
|
title: Defines a tooltip for the element.
|
||||||
|
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 properties of the component.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The backend disabled component.
|
||||||
|
"""
|
||||||
|
...
|
||||||
|
|
||||||
connection_banner = ConnectionBanner.create
|
connection_banner = ConnectionBanner.create
|
||||||
connection_modal = ConnectionModal.create
|
connection_modal = ConnectionModal.create
|
||||||
connection_toaster = ConnectionToaster.create
|
connection_toaster = ConnectionToaster.create
|
||||||
connection_pulser = ConnectionPulser.create
|
connection_pulser = ConnectionPulser.create
|
||||||
|
backend_disabled = BackendDisabled.create
|
||||||
|
@ -18,7 +18,7 @@ def set_breakpoints(values: Tuple[str, str, str, str, str]):
|
|||||||
breakpoints_values.extend(values)
|
breakpoints_values.extend(values)
|
||||||
|
|
||||||
|
|
||||||
K = TypeVar("K")
|
K = TypeVar("K", bound=str)
|
||||||
V = TypeVar("V")
|
V = TypeVar("V")
|
||||||
|
|
||||||
|
|
||||||
@ -82,7 +82,9 @@ class Breakpoints(Dict[K, V]):
|
|||||||
return Breakpoints(
|
return Breakpoints(
|
||||||
{
|
{
|
||||||
k: v
|
k: v
|
||||||
for k, v in zip(["initial", *breakpoint_names], thresholds)
|
for k, v in zip(
|
||||||
|
["initial", *breakpoint_names], thresholds, strict=True
|
||||||
|
)
|
||||||
if v is not None
|
if v is not None
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -41,7 +41,7 @@ class ClientSideRouting(Component):
|
|||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
def wait_for_client_redirect(component) -> Component:
|
def wait_for_client_redirect(component: Component) -> Component:
|
||||||
"""Wait for a redirect to occur before rendering a component.
|
"""Wait for a redirect to occur before rendering a component.
|
||||||
|
|
||||||
This prevents the 404 page from flashing while the redirect is happening.
|
This prevents the 404 page from flashing while the redirect is happening.
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
from typing import Any, Dict, Optional, Union, overload
|
from typing import Any, Dict, Optional, Union, overload
|
||||||
|
|
||||||
from reflex.components.component import Component
|
from reflex.components.component import Component
|
||||||
from reflex.event import BASE_STATE, EventType
|
from reflex.event import EventType
|
||||||
from reflex.style import Style
|
from reflex.style import Style
|
||||||
from reflex.vars.base import Var
|
from reflex.vars.base import Var
|
||||||
|
|
||||||
@ -26,21 +26,21 @@ class ClientSideRouting(Component):
|
|||||||
class_name: Optional[Any] = None,
|
class_name: Optional[Any] = None,
|
||||||
autofocus: Optional[bool] = None,
|
autofocus: Optional[bool] = None,
|
||||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
on_blur: Optional[EventType[()]] = None,
|
||||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_click: Optional[EventType[()]] = None,
|
||||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
on_focus: Optional[EventType[()]] = None,
|
||||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
on_mount: Optional[EventType[()]] = None,
|
||||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
**props,
|
**props,
|
||||||
) -> "ClientSideRouting":
|
) -> "ClientSideRouting":
|
||||||
"""Create the component.
|
"""Create the component.
|
||||||
@ -60,7 +60,7 @@ class ClientSideRouting(Component):
|
|||||||
"""
|
"""
|
||||||
...
|
...
|
||||||
|
|
||||||
def wait_for_client_redirect(component) -> Component: ...
|
def wait_for_client_redirect(component: Component) -> Component: ...
|
||||||
|
|
||||||
class Default404Page(Component):
|
class Default404Page(Component):
|
||||||
@overload
|
@overload
|
||||||
@ -75,21 +75,21 @@ class Default404Page(Component):
|
|||||||
class_name: Optional[Any] = None,
|
class_name: Optional[Any] = None,
|
||||||
autofocus: Optional[bool] = None,
|
autofocus: Optional[bool] = None,
|
||||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
on_blur: Optional[EventType[()]] = None,
|
||||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_click: Optional[EventType[()]] = None,
|
||||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
on_focus: Optional[EventType[()]] = None,
|
||||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
on_mount: Optional[EventType[()]] = None,
|
||||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
**props,
|
**props,
|
||||||
) -> "Default404Page":
|
) -> "Default404Page":
|
||||||
"""Create the component.
|
"""Create the component.
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
from typing import Any, Dict, List, Optional, Union, overload
|
from typing import Any, Dict, List, Optional, Union, overload
|
||||||
|
|
||||||
from reflex.components.base.fragment import Fragment
|
from reflex.components.base.fragment import Fragment
|
||||||
from reflex.event import BASE_STATE, EventType
|
from reflex.event import EventType
|
||||||
from reflex.style import Style
|
from reflex.style import Style
|
||||||
from reflex.utils.imports import ImportVar
|
from reflex.utils.imports import ImportVar
|
||||||
from reflex.vars.base import Var
|
from reflex.vars.base import Var
|
||||||
@ -27,27 +27,24 @@ class Clipboard(Fragment):
|
|||||||
class_name: Optional[Any] = None,
|
class_name: Optional[Any] = None,
|
||||||
autofocus: Optional[bool] = None,
|
autofocus: Optional[bool] = None,
|
||||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
on_blur: Optional[EventType[()]] = None,
|
||||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_click: Optional[EventType[()]] = None,
|
||||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
on_focus: Optional[EventType[()]] = None,
|
||||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
on_mount: Optional[EventType[()]] = None,
|
||||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
on_paste: Optional[
|
on_paste: Optional[
|
||||||
Union[
|
Union[EventType[()], EventType[list[tuple[str, str]]]]
|
||||||
EventType[[], BASE_STATE],
|
|
||||||
EventType[[list[tuple[str, str]]], BASE_STATE],
|
|
||||||
]
|
|
||||||
] = None,
|
] = None,
|
||||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
**props,
|
**props,
|
||||||
) -> "Clipboard":
|
) -> "Clipboard":
|
||||||
"""Create a Clipboard component.
|
"""Create a Clipboard component.
|
||||||
|
@ -26,10 +26,9 @@ class Cond(MemoizationLeaf):
|
|||||||
cond: Var[Any]
|
cond: Var[Any]
|
||||||
|
|
||||||
# The component to render if the cond is true.
|
# The component to render if the cond is true.
|
||||||
comp1: BaseComponent = None # type: ignore
|
comp1: BaseComponent | None = None
|
||||||
|
|
||||||
# The component to render if the cond is false.
|
# The component to render if the cond is false.
|
||||||
comp2: BaseComponent = None # type: ignore
|
comp2: BaseComponent | None = None
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create(
|
def create(
|
||||||
@ -62,19 +61,11 @@ class Cond(MemoizationLeaf):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
def _get_props_imports(self):
|
|
||||||
"""Get the imports needed for component's props.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
The imports for the component's props of the component.
|
|
||||||
"""
|
|
||||||
return []
|
|
||||||
|
|
||||||
def _render(self) -> Tag:
|
def _render(self) -> Tag:
|
||||||
return CondTag(
|
return CondTag(
|
||||||
cond=self.cond,
|
cond=self.cond,
|
||||||
true_value=self.comp1.render(),
|
true_value=self.comp1.render(), # pyright: ignore [reportOptionalMemberAccess]
|
||||||
false_value=self.comp2.render(),
|
false_value=self.comp2.render(), # pyright: ignore [reportOptionalMemberAccess]
|
||||||
)
|
)
|
||||||
|
|
||||||
def render(self) -> Dict:
|
def render(self) -> Dict:
|
||||||
@ -111,7 +102,7 @@ class Cond(MemoizationLeaf):
|
|||||||
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def cond(condition: Any, c1: Component, c2: Any) -> Component: ...
|
def cond(condition: Any, c1: Component, c2: Any) -> Component: ... # pyright: ignore [reportOverlappingOverload]
|
||||||
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
@ -154,7 +145,7 @@ def cond(condition: Any, c1: Any, c2: Any = None) -> Component | Var:
|
|||||||
if c2 is None:
|
if c2 is None:
|
||||||
raise ValueError("For conditional vars, the second argument must be set.")
|
raise ValueError("For conditional vars, the second argument must be set.")
|
||||||
|
|
||||||
def create_var(cond_part):
|
def create_var(cond_part: Any) -> Var[Any]:
|
||||||
return LiteralVar.create(cond_part)
|
return LiteralVar.create(cond_part)
|
||||||
|
|
||||||
# convert the truth and false cond parts into vars so the _var_data can be obtained.
|
# convert the truth and false cond parts into vars so the _var_data can be obtained.
|
||||||
@ -163,16 +154,16 @@ def cond(condition: Any, c1: Any, c2: Any = None) -> Component | Var:
|
|||||||
|
|
||||||
# Create the conditional var.
|
# Create the conditional var.
|
||||||
return ternary_operation(
|
return ternary_operation(
|
||||||
cond_var.bool()._replace( # type: ignore
|
cond_var.bool()._replace(
|
||||||
merge_var_data=VarData(imports=_IS_TRUE_IMPORT),
|
merge_var_data=VarData(imports=_IS_TRUE_IMPORT),
|
||||||
), # type: ignore
|
),
|
||||||
c1,
|
c1,
|
||||||
c2,
|
c2,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def color_mode_cond(light: Component, dark: Component | None = None) -> Component: ... # type: ignore
|
def color_mode_cond(light: Component, dark: Component | None = None) -> Component: ... # pyright: ignore [reportOverlappingOverload]
|
||||||
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
|
@ -28,7 +28,7 @@ class DebounceInput(Component):
|
|||||||
min_length: Var[int]
|
min_length: Var[int]
|
||||||
|
|
||||||
# Time to wait between end of input and triggering on_change
|
# Time to wait between end of input and triggering on_change
|
||||||
debounce_timeout: Var[int] = DEFAULT_DEBOUNCE_TIMEOUT # type: ignore
|
debounce_timeout: Var[int] = Var.create(DEFAULT_DEBOUNCE_TIMEOUT)
|
||||||
|
|
||||||
# If true, notify when Enter key is pressed
|
# If true, notify when Enter key is pressed
|
||||||
force_notify_by_enter: Var[bool]
|
force_notify_by_enter: Var[bool]
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
from typing import Any, Dict, Optional, Type, Union, overload
|
from typing import Any, Dict, Optional, Type, Union, overload
|
||||||
|
|
||||||
from reflex.components.component import Component
|
from reflex.components.component import Component
|
||||||
from reflex.event import BASE_STATE, EventType
|
from reflex.event import EventType
|
||||||
from reflex.style import Style
|
from reflex.style import Style
|
||||||
from reflex.vars.base import Var
|
from reflex.vars.base import Var
|
||||||
|
|
||||||
@ -31,22 +31,22 @@ class DebounceInput(Component):
|
|||||||
class_name: Optional[Any] = None,
|
class_name: Optional[Any] = None,
|
||||||
autofocus: Optional[bool] = None,
|
autofocus: Optional[bool] = None,
|
||||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
on_blur: Optional[EventType[()]] = None,
|
||||||
on_change: Optional[EventType[[], BASE_STATE]] = None,
|
on_change: Optional[EventType[()]] = None,
|
||||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_click: Optional[EventType[()]] = None,
|
||||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
on_focus: Optional[EventType[()]] = None,
|
||||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
on_mount: Optional[EventType[()]] = None,
|
||||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
**props,
|
**props,
|
||||||
) -> "DebounceInput":
|
) -> "DebounceInput":
|
||||||
"""Create a DebounceInput component.
|
"""Create a DebounceInput component.
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import functools
|
||||||
import inspect
|
import inspect
|
||||||
from typing import Any, Callable, Iterable
|
from typing import Any, Callable, Iterable
|
||||||
|
|
||||||
@ -10,6 +11,7 @@ from reflex.components.component import Component
|
|||||||
from reflex.components.tags import IterTag
|
from reflex.components.tags import IterTag
|
||||||
from reflex.constants import MemoizationMode
|
from reflex.constants import MemoizationMode
|
||||||
from reflex.state import ComponentState
|
from reflex.state import ComponentState
|
||||||
|
from reflex.utils.exceptions import UntypedVarError
|
||||||
from reflex.vars.base import LiteralVar, Var
|
from reflex.vars.base import LiteralVar, Var
|
||||||
|
|
||||||
|
|
||||||
@ -50,8 +52,12 @@ class Foreach(Component):
|
|||||||
Raises:
|
Raises:
|
||||||
ForeachVarError: If the iterable is of type Any.
|
ForeachVarError: If the iterable is of type Any.
|
||||||
TypeError: If the render function is a ComponentState.
|
TypeError: If the render function is a ComponentState.
|
||||||
|
UntypedVarError: If the iterable is of type Any without a type annotation.
|
||||||
"""
|
"""
|
||||||
iterable = LiteralVar.create(iterable)
|
from reflex.vars import ArrayVar, ObjectVar, StringVar
|
||||||
|
|
||||||
|
iterable = LiteralVar.create(iterable).guess_type()
|
||||||
|
|
||||||
if iterable._var_type == Any:
|
if iterable._var_type == Any:
|
||||||
raise ForeachVarError(
|
raise ForeachVarError(
|
||||||
f"Could not foreach over var `{iterable!s}` of type Any. "
|
f"Could not foreach over var `{iterable!s}` of type Any. "
|
||||||
@ -67,12 +73,30 @@ class Foreach(Component):
|
|||||||
"Using a ComponentState as `render_fn` inside `rx.foreach` is not supported yet."
|
"Using a ComponentState as `render_fn` inside `rx.foreach` is not supported yet."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if isinstance(iterable, ObjectVar):
|
||||||
|
iterable = iterable.entries()
|
||||||
|
|
||||||
|
if isinstance(iterable, StringVar):
|
||||||
|
iterable = iterable.split()
|
||||||
|
|
||||||
|
if not isinstance(iterable, ArrayVar):
|
||||||
|
raise ForeachVarError(
|
||||||
|
f"Could not foreach over var `{iterable!s}` of type {iterable._var_type}. "
|
||||||
|
"See https://reflex.dev/docs/library/dynamic-rendering/foreach/"
|
||||||
|
)
|
||||||
|
|
||||||
component = cls(
|
component = cls(
|
||||||
iterable=iterable,
|
iterable=iterable,
|
||||||
render_fn=render_fn,
|
render_fn=render_fn,
|
||||||
)
|
)
|
||||||
# Keep a ref to a rendered component to determine correct imports/hooks/styles.
|
try:
|
||||||
component.children = [component._render().render_component()]
|
# Keep a ref to a rendered component to determine correct imports/hooks/styles.
|
||||||
|
component.children = [component._render().render_component()]
|
||||||
|
except UntypedVarError as e:
|
||||||
|
raise UntypedVarError(
|
||||||
|
f"Could not foreach over var `{iterable!s}` without a type annotation. "
|
||||||
|
"See https://reflex.dev/docs/library/dynamic-rendering/foreach/"
|
||||||
|
) from e
|
||||||
return component
|
return component
|
||||||
|
|
||||||
def _render(self) -> IterTag:
|
def _render(self) -> IterTag:
|
||||||
@ -97,9 +121,20 @@ class Foreach(Component):
|
|||||||
# Determine the index var name based on the params accepted by render_fn.
|
# Determine the index var name based on the params accepted by render_fn.
|
||||||
props["index_var_name"] = params[1].name
|
props["index_var_name"] = params[1].name
|
||||||
else:
|
else:
|
||||||
|
render_fn = self.render_fn
|
||||||
# Otherwise, use a deterministic index, based on the render function bytecode.
|
# Otherwise, use a deterministic index, based on the render function bytecode.
|
||||||
code_hash = (
|
code_hash = (
|
||||||
hash(self.render_fn.__code__)
|
hash(
|
||||||
|
getattr(
|
||||||
|
render_fn,
|
||||||
|
"__code__",
|
||||||
|
(
|
||||||
|
repr(self.render_fn)
|
||||||
|
if not isinstance(render_fn, functools.partial)
|
||||||
|
else render_fn.func.__code__
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
.to_bytes(
|
.to_bytes(
|
||||||
length=8,
|
length=8,
|
||||||
byteorder="big",
|
byteorder="big",
|
||||||
|
@ -14,7 +14,7 @@ class Html(Div):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# The HTML to render.
|
# The HTML to render.
|
||||||
dangerouslySetInnerHTML: Var[Dict[str, str]]
|
dangerouslySetInnerHTML: Var[Dict[str, str]] # noqa: N815
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create(cls, *children, **props):
|
def create(cls, *children, **props):
|
||||||
|
@ -3,10 +3,10 @@
|
|||||||
# ------------------- DO NOT EDIT ----------------------
|
# ------------------- DO NOT EDIT ----------------------
|
||||||
# This file was generated by `reflex/utils/pyi_generator.py`!
|
# This file was generated by `reflex/utils/pyi_generator.py`!
|
||||||
# ------------------------------------------------------
|
# ------------------------------------------------------
|
||||||
from typing import Any, Dict, Optional, Union, overload
|
from typing import Any, Dict, Literal, Optional, Union, overload
|
||||||
|
|
||||||
from reflex.components.el.elements.typography import Div
|
from reflex.components.el.elements.typography import Div
|
||||||
from reflex.event import BASE_STATE, EventType
|
from reflex.event import EventType
|
||||||
from reflex.style import Style
|
from reflex.style import Style
|
||||||
from reflex.vars.base import Var
|
from reflex.vars.base import Var
|
||||||
|
|
||||||
@ -19,51 +19,232 @@ class Html(Div):
|
|||||||
dangerouslySetInnerHTML: Optional[
|
dangerouslySetInnerHTML: Optional[
|
||||||
Union[Dict[str, str], Var[Dict[str, str]]]
|
Union[Dict[str, str], Var[Dict[str, str]]]
|
||||||
] = None,
|
] = None,
|
||||||
access_key: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
|
access_key: Optional[Union[Var[str], str]] = None,
|
||||||
auto_capitalize: Optional[
|
auto_capitalize: Optional[
|
||||||
Union[Var[Union[bool, int, str]], bool, int, str]
|
Union[
|
||||||
|
Literal["characters", "none", "off", "on", "sentences", "words"],
|
||||||
|
Var[Literal["characters", "none", "off", "on", "sentences", "words"]],
|
||||||
|
]
|
||||||
] = None,
|
] = None,
|
||||||
content_editable: Optional[
|
content_editable: Optional[
|
||||||
Union[Var[Union[bool, int, str]], bool, int, str]
|
Union[
|
||||||
|
Literal["inherit", "plaintext-only", False, True],
|
||||||
|
Var[Literal["inherit", "plaintext-only", False, True]],
|
||||||
|
]
|
||||||
] = None,
|
] = None,
|
||||||
context_menu: Optional[
|
context_menu: Optional[Union[Var[str], str]] = None,
|
||||||
Union[Var[Union[bool, int, str]], bool, int, str]
|
dir: Optional[Union[Var[str], str]] = None,
|
||||||
] = None,
|
draggable: Optional[Union[Var[bool], bool]] = None,
|
||||||
dir: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
|
|
||||||
draggable: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
|
|
||||||
enter_key_hint: Optional[
|
enter_key_hint: Optional[
|
||||||
Union[Var[Union[bool, int, str]], bool, int, str]
|
Union[
|
||||||
|
Literal["done", "enter", "go", "next", "previous", "search", "send"],
|
||||||
|
Var[
|
||||||
|
Literal["done", "enter", "go", "next", "previous", "search", "send"]
|
||||||
|
],
|
||||||
|
]
|
||||||
] = None,
|
] = None,
|
||||||
hidden: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
|
hidden: Optional[Union[Var[bool], bool]] = None,
|
||||||
input_mode: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
|
input_mode: Optional[
|
||||||
item_prop: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
|
Union[
|
||||||
lang: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
|
Literal[
|
||||||
role: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
|
"decimal",
|
||||||
slot: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
|
"email",
|
||||||
spell_check: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
|
"none",
|
||||||
tab_index: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
|
"numeric",
|
||||||
title: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
|
"search",
|
||||||
|
"tel",
|
||||||
|
"text",
|
||||||
|
"url",
|
||||||
|
],
|
||||||
|
Var[
|
||||||
|
Literal[
|
||||||
|
"decimal",
|
||||||
|
"email",
|
||||||
|
"none",
|
||||||
|
"numeric",
|
||||||
|
"search",
|
||||||
|
"tel",
|
||||||
|
"text",
|
||||||
|
"url",
|
||||||
|
]
|
||||||
|
],
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
|
item_prop: Optional[Union[Var[str], str]] = None,
|
||||||
|
lang: Optional[Union[Var[str], str]] = None,
|
||||||
|
role: Optional[
|
||||||
|
Union[
|
||||||
|
Literal[
|
||||||
|
"alert",
|
||||||
|
"alertdialog",
|
||||||
|
"application",
|
||||||
|
"article",
|
||||||
|
"banner",
|
||||||
|
"button",
|
||||||
|
"cell",
|
||||||
|
"checkbox",
|
||||||
|
"columnheader",
|
||||||
|
"combobox",
|
||||||
|
"complementary",
|
||||||
|
"contentinfo",
|
||||||
|
"definition",
|
||||||
|
"dialog",
|
||||||
|
"directory",
|
||||||
|
"document",
|
||||||
|
"feed",
|
||||||
|
"figure",
|
||||||
|
"form",
|
||||||
|
"grid",
|
||||||
|
"gridcell",
|
||||||
|
"group",
|
||||||
|
"heading",
|
||||||
|
"img",
|
||||||
|
"link",
|
||||||
|
"list",
|
||||||
|
"listbox",
|
||||||
|
"listitem",
|
||||||
|
"log",
|
||||||
|
"main",
|
||||||
|
"marquee",
|
||||||
|
"math",
|
||||||
|
"menu",
|
||||||
|
"menubar",
|
||||||
|
"menuitem",
|
||||||
|
"menuitemcheckbox",
|
||||||
|
"menuitemradio",
|
||||||
|
"navigation",
|
||||||
|
"none",
|
||||||
|
"note",
|
||||||
|
"option",
|
||||||
|
"presentation",
|
||||||
|
"progressbar",
|
||||||
|
"radio",
|
||||||
|
"radiogroup",
|
||||||
|
"region",
|
||||||
|
"row",
|
||||||
|
"rowgroup",
|
||||||
|
"rowheader",
|
||||||
|
"scrollbar",
|
||||||
|
"search",
|
||||||
|
"searchbox",
|
||||||
|
"separator",
|
||||||
|
"slider",
|
||||||
|
"spinbutton",
|
||||||
|
"status",
|
||||||
|
"switch",
|
||||||
|
"tab",
|
||||||
|
"table",
|
||||||
|
"tablist",
|
||||||
|
"tabpanel",
|
||||||
|
"term",
|
||||||
|
"textbox",
|
||||||
|
"timer",
|
||||||
|
"toolbar",
|
||||||
|
"tooltip",
|
||||||
|
"tree",
|
||||||
|
"treegrid",
|
||||||
|
"treeitem",
|
||||||
|
],
|
||||||
|
Var[
|
||||||
|
Literal[
|
||||||
|
"alert",
|
||||||
|
"alertdialog",
|
||||||
|
"application",
|
||||||
|
"article",
|
||||||
|
"banner",
|
||||||
|
"button",
|
||||||
|
"cell",
|
||||||
|
"checkbox",
|
||||||
|
"columnheader",
|
||||||
|
"combobox",
|
||||||
|
"complementary",
|
||||||
|
"contentinfo",
|
||||||
|
"definition",
|
||||||
|
"dialog",
|
||||||
|
"directory",
|
||||||
|
"document",
|
||||||
|
"feed",
|
||||||
|
"figure",
|
||||||
|
"form",
|
||||||
|
"grid",
|
||||||
|
"gridcell",
|
||||||
|
"group",
|
||||||
|
"heading",
|
||||||
|
"img",
|
||||||
|
"link",
|
||||||
|
"list",
|
||||||
|
"listbox",
|
||||||
|
"listitem",
|
||||||
|
"log",
|
||||||
|
"main",
|
||||||
|
"marquee",
|
||||||
|
"math",
|
||||||
|
"menu",
|
||||||
|
"menubar",
|
||||||
|
"menuitem",
|
||||||
|
"menuitemcheckbox",
|
||||||
|
"menuitemradio",
|
||||||
|
"navigation",
|
||||||
|
"none",
|
||||||
|
"note",
|
||||||
|
"option",
|
||||||
|
"presentation",
|
||||||
|
"progressbar",
|
||||||
|
"radio",
|
||||||
|
"radiogroup",
|
||||||
|
"region",
|
||||||
|
"row",
|
||||||
|
"rowgroup",
|
||||||
|
"rowheader",
|
||||||
|
"scrollbar",
|
||||||
|
"search",
|
||||||
|
"searchbox",
|
||||||
|
"separator",
|
||||||
|
"slider",
|
||||||
|
"spinbutton",
|
||||||
|
"status",
|
||||||
|
"switch",
|
||||||
|
"tab",
|
||||||
|
"table",
|
||||||
|
"tablist",
|
||||||
|
"tabpanel",
|
||||||
|
"term",
|
||||||
|
"textbox",
|
||||||
|
"timer",
|
||||||
|
"toolbar",
|
||||||
|
"tooltip",
|
||||||
|
"tree",
|
||||||
|
"treegrid",
|
||||||
|
"treeitem",
|
||||||
|
]
|
||||||
|
],
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
|
slot: Optional[Union[Var[str], str]] = None,
|
||||||
|
spell_check: Optional[Union[Var[bool], bool]] = None,
|
||||||
|
tab_index: Optional[Union[Var[int], int]] = None,
|
||||||
|
title: Optional[Union[Var[str], str]] = None,
|
||||||
style: Optional[Style] = None,
|
style: Optional[Style] = None,
|
||||||
key: Optional[Any] = None,
|
key: Optional[Any] = None,
|
||||||
id: Optional[Any] = None,
|
id: Optional[Any] = None,
|
||||||
class_name: Optional[Any] = None,
|
class_name: Optional[Any] = None,
|
||||||
autofocus: Optional[bool] = None,
|
autofocus: Optional[bool] = None,
|
||||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
on_blur: Optional[EventType[()]] = None,
|
||||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_click: Optional[EventType[()]] = None,
|
||||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
on_focus: Optional[EventType[()]] = None,
|
||||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
on_mount: Optional[EventType[()]] = None,
|
||||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
**props,
|
**props,
|
||||||
) -> "Html":
|
) -> "Html":
|
||||||
"""Create a html component.
|
"""Create a html component.
|
||||||
|
@ -109,7 +109,7 @@ class Match(MemoizationLeaf):
|
|||||||
return cases, default
|
return cases, default
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _create_case_var_with_var_data(cls, case_element):
|
def _create_case_var_with_var_data(cls, case_element: Any) -> Var:
|
||||||
"""Convert a case element into a Var.If the case
|
"""Convert a case element into a Var.If the case
|
||||||
is a Style type, we extract the var data and merge it with the
|
is a Style type, we extract the var data and merge it with the
|
||||||
newly created Var.
|
newly created Var.
|
||||||
@ -178,9 +178,9 @@ class Match(MemoizationLeaf):
|
|||||||
first_case_return = match_cases[0][-1]
|
first_case_return = match_cases[0][-1]
|
||||||
return_type = type(first_case_return)
|
return_type = type(first_case_return)
|
||||||
|
|
||||||
if types._isinstance(first_case_return, BaseComponent):
|
if isinstance(first_case_return, BaseComponent):
|
||||||
return_type = BaseComponent
|
return_type = BaseComponent
|
||||||
elif types._isinstance(first_case_return, Var):
|
elif isinstance(first_case_return, Var):
|
||||||
return_type = Var
|
return_type = Var
|
||||||
|
|
||||||
for index, case in enumerate(match_cases):
|
for index, case in enumerate(match_cases):
|
||||||
@ -222,27 +222,27 @@ class Match(MemoizationLeaf):
|
|||||||
cond=match_cond_var,
|
cond=match_cond_var,
|
||||||
match_cases=match_cases,
|
match_cases=match_cases,
|
||||||
default=default,
|
default=default,
|
||||||
children=[case[-1] for case in match_cases] + [default], # type: ignore
|
children=[case[-1] for case in match_cases] + [default], # pyright: ignore [reportArgumentType]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
# Validate the match cases (as well as the default case) to have Var return types.
|
# Validate the match cases (as well as the default case) to have Var return types.
|
||||||
if any(
|
if any(
|
||||||
case for case in match_cases if not types._isinstance(case[-1], Var)
|
case for case in match_cases if not isinstance(case[-1], Var)
|
||||||
) or not types._isinstance(default, Var):
|
) or not isinstance(default, Var):
|
||||||
raise ValueError("Return types of match cases should be Vars.")
|
raise ValueError("Return types of match cases should be Vars.")
|
||||||
|
|
||||||
return Var(
|
return Var(
|
||||||
_js_expr=format.format_match(
|
_js_expr=format.format_match(
|
||||||
cond=str(match_cond_var),
|
cond=str(match_cond_var),
|
||||||
match_cases=match_cases,
|
match_cases=match_cases,
|
||||||
default=default, # type: ignore
|
default=default, # pyright: ignore [reportArgumentType]
|
||||||
),
|
),
|
||||||
_var_type=default._var_type, # type: ignore
|
_var_type=default._var_type, # pyright: ignore [reportAttributeAccessIssue,reportOptionalMemberAccess]
|
||||||
_var_data=VarData.merge(
|
_var_data=VarData.merge(
|
||||||
match_cond_var._get_all_var_data(),
|
match_cond_var._get_all_var_data(),
|
||||||
*[el._get_all_var_data() for case in match_cases for el in case],
|
*[el._get_all_var_data() for case in match_cases for el in case],
|
||||||
default._get_all_var_data(), # type: ignore
|
default._get_all_var_data(), # pyright: ignore [reportAttributeAccessIssue, reportOptionalMemberAccess]
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
134
reflex/components/core/sticky.py
Normal file
134
reflex/components/core/sticky.py
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
"""Components for displaying the Reflex sticky logo."""
|
||||||
|
|
||||||
|
from reflex.components.component import ComponentNamespace
|
||||||
|
from reflex.components.core.colors import color
|
||||||
|
from reflex.components.core.cond import color_mode_cond
|
||||||
|
from reflex.components.core.responsive import desktop_only
|
||||||
|
from reflex.components.el.elements.inline import A
|
||||||
|
from reflex.components.el.elements.media import Path, Rect, Svg
|
||||||
|
from reflex.components.radix.themes.typography.text import Text
|
||||||
|
from reflex.style import Style
|
||||||
|
|
||||||
|
|
||||||
|
class StickyLogo(Svg):
|
||||||
|
"""A simple Reflex logo SVG with only the letter R."""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create(cls):
|
||||||
|
"""Create the simple Reflex logo SVG.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The simple Reflex logo SVG.
|
||||||
|
"""
|
||||||
|
return super().create(
|
||||||
|
Rect.create(width="16", height="16", rx="2", fill="#6E56CF"),
|
||||||
|
Path.create(d="M10 9V13H12V9H10Z", fill="white"),
|
||||||
|
Path.create(d="M4 3V13H6V9H10V7H6V5H10V7H12V3H4Z", fill="white"),
|
||||||
|
width="16",
|
||||||
|
height="16",
|
||||||
|
viewBox="0 0 16 16",
|
||||||
|
xmlns="http://www.w3.org/2000/svg",
|
||||||
|
)
|
||||||
|
|
||||||
|
def add_style(self):
|
||||||
|
"""Add the style to the component.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The style of the component.
|
||||||
|
"""
|
||||||
|
return Style(
|
||||||
|
{
|
||||||
|
"fill": "white",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class StickyLabel(Text):
|
||||||
|
"""A label that displays the Reflex sticky."""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create(cls):
|
||||||
|
"""Create the sticky label.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The sticky label.
|
||||||
|
"""
|
||||||
|
return super().create("Built with Reflex")
|
||||||
|
|
||||||
|
def add_style(self):
|
||||||
|
"""Add the style to the component.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The style of the component.
|
||||||
|
"""
|
||||||
|
return Style(
|
||||||
|
{
|
||||||
|
"color": color("slate", 1),
|
||||||
|
"font_weight": "600",
|
||||||
|
"font_family": "'Instrument Sans', sans-serif",
|
||||||
|
"font_size": "0.875rem",
|
||||||
|
"line_height": "1rem",
|
||||||
|
"letter_spacing": "-0.00656rem",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class StickyBadge(A):
|
||||||
|
"""A badge that displays the Reflex sticky logo."""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create(cls):
|
||||||
|
"""Create the sticky badge.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The sticky badge.
|
||||||
|
"""
|
||||||
|
return super().create(
|
||||||
|
StickyLogo.create(),
|
||||||
|
desktop_only(StickyLabel.create()),
|
||||||
|
href="https://reflex.dev",
|
||||||
|
target="_blank",
|
||||||
|
width="auto",
|
||||||
|
padding="0.375rem",
|
||||||
|
align="center",
|
||||||
|
text_align="center",
|
||||||
|
)
|
||||||
|
|
||||||
|
def add_style(self):
|
||||||
|
"""Add the style to the component.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The style of the component.
|
||||||
|
"""
|
||||||
|
return Style(
|
||||||
|
{
|
||||||
|
"position": "fixed",
|
||||||
|
"bottom": "1rem",
|
||||||
|
"right": "1rem",
|
||||||
|
"display": "flex",
|
||||||
|
"flex-direction": "row",
|
||||||
|
"gap": "0.375rem",
|
||||||
|
"align-items": "center",
|
||||||
|
"width": "auto",
|
||||||
|
"border-radius": "0.5rem",
|
||||||
|
"color": color_mode_cond("#E5E7EB", "#27282B"),
|
||||||
|
"border": color_mode_cond("1px solid #27282B", "1px solid #E5E7EB"),
|
||||||
|
"background-color": color_mode_cond("#151618", "#FCFCFD"),
|
||||||
|
"padding": "0.375rem",
|
||||||
|
"transition": "background-color 0.2s ease-in-out",
|
||||||
|
"box-shadow": "0 1px 2px 0 rgba(0, 0, 0, 0.05)",
|
||||||
|
"z-index": "9998",
|
||||||
|
"cursor": "pointer",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class StickyNamespace(ComponentNamespace):
|
||||||
|
"""Sticky components namespace."""
|
||||||
|
|
||||||
|
__call__ = staticmethod(StickyBadge.create)
|
||||||
|
label = staticmethod(StickyLabel.create)
|
||||||
|
logo = staticmethod(StickyLogo.create)
|
||||||
|
|
||||||
|
|
||||||
|
sticky = StickyNamespace()
|
1233
reflex/components/core/sticky.pyi
Normal file
1233
reflex/components/core/sticky.pyi
Normal file
File diff suppressed because it is too large
Load Diff
@ -29,7 +29,7 @@ from reflex.event import (
|
|||||||
from reflex.utils import format
|
from reflex.utils import format
|
||||||
from reflex.utils.imports import ImportVar
|
from reflex.utils.imports import ImportVar
|
||||||
from reflex.vars import VarData
|
from reflex.vars import VarData
|
||||||
from reflex.vars.base import CallableVar, Var, get_unique_variable_name
|
from reflex.vars.base import Var, get_unique_variable_name
|
||||||
from reflex.vars.sequence import LiteralStringVar
|
from reflex.vars.sequence import LiteralStringVar
|
||||||
|
|
||||||
DEFAULT_UPLOAD_ID: str = "default"
|
DEFAULT_UPLOAD_ID: str = "default"
|
||||||
@ -45,7 +45,6 @@ upload_files_context_var_data: VarData = VarData(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@CallableVar
|
|
||||||
def upload_file(id_: str = DEFAULT_UPLOAD_ID) -> Var:
|
def upload_file(id_: str = DEFAULT_UPLOAD_ID) -> Var:
|
||||||
"""Get the file upload drop trigger.
|
"""Get the file upload drop trigger.
|
||||||
|
|
||||||
@ -75,7 +74,6 @@ def upload_file(id_: str = DEFAULT_UPLOAD_ID) -> Var:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@CallableVar
|
|
||||||
def selected_files(id_: str = DEFAULT_UPLOAD_ID) -> Var:
|
def selected_files(id_: str = DEFAULT_UPLOAD_ID) -> Var:
|
||||||
"""Get the list of selected files.
|
"""Get the list of selected files.
|
||||||
|
|
||||||
@ -149,7 +147,7 @@ uploaded_files_url_prefix = Var(
|
|||||||
).to(str)
|
).to(str)
|
||||||
|
|
||||||
|
|
||||||
def get_upload_url(file_path: str) -> Var[str]:
|
def get_upload_url(file_path: str | Var[str]) -> Var[str]:
|
||||||
"""Get the URL of an uploaded file.
|
"""Get the URL of an uploaded file.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -160,7 +158,7 @@ def get_upload_url(file_path: str) -> Var[str]:
|
|||||||
"""
|
"""
|
||||||
Upload.is_used = True
|
Upload.is_used = True
|
||||||
|
|
||||||
return uploaded_files_url_prefix + "/" + file_path
|
return Var.create(f"{uploaded_files_url_prefix}/{file_path}")
|
||||||
|
|
||||||
|
|
||||||
def _on_drop_spec(files: Var) -> Tuple[Var[Any]]:
|
def _on_drop_spec(files: Var) -> Tuple[Var[Any]]:
|
||||||
@ -192,7 +190,7 @@ class GhostUpload(Fragment):
|
|||||||
class Upload(MemoizationLeaf):
|
class Upload(MemoizationLeaf):
|
||||||
"""A file upload component."""
|
"""A file upload component."""
|
||||||
|
|
||||||
library = "react-dropzone@14.2.10"
|
library = "react-dropzone@14.3.5"
|
||||||
|
|
||||||
tag = ""
|
tag = ""
|
||||||
|
|
||||||
@ -269,7 +267,7 @@ class Upload(MemoizationLeaf):
|
|||||||
on_drop = upload_props["on_drop"]
|
on_drop = upload_props["on_drop"]
|
||||||
if isinstance(on_drop, Callable):
|
if isinstance(on_drop, Callable):
|
||||||
# Call the lambda to get the event chain.
|
# Call the lambda to get the event chain.
|
||||||
on_drop = call_event_fn(on_drop, _on_drop_spec) # type: ignore
|
on_drop = call_event_fn(on_drop, _on_drop_spec)
|
||||||
if isinstance(on_drop, EventSpec):
|
if isinstance(on_drop, EventSpec):
|
||||||
# Update the provided args for direct use with on_drop.
|
# Update the provided args for direct use with on_drop.
|
||||||
on_drop = on_drop.with_args(
|
on_drop = on_drop.with_args(
|
||||||
|
@ -9,18 +9,16 @@ from typing import Any, ClassVar, Dict, List, Optional, Union, overload
|
|||||||
from reflex.components.base.fragment import Fragment
|
from reflex.components.base.fragment import Fragment
|
||||||
from reflex.components.component import Component, ComponentNamespace, MemoizationLeaf
|
from reflex.components.component import Component, ComponentNamespace, MemoizationLeaf
|
||||||
from reflex.constants import Dirs
|
from reflex.constants import Dirs
|
||||||
from reflex.event import BASE_STATE, CallableEventSpec, EventSpec, EventType
|
from reflex.event import CallableEventSpec, EventSpec, EventType
|
||||||
from reflex.style import Style
|
from reflex.style import Style
|
||||||
from reflex.utils.imports import ImportVar
|
from reflex.utils.imports import ImportVar
|
||||||
from reflex.vars import VarData
|
from reflex.vars import VarData
|
||||||
from reflex.vars.base import CallableVar, Var
|
from reflex.vars.base import Var
|
||||||
|
|
||||||
DEFAULT_UPLOAD_ID: str
|
DEFAULT_UPLOAD_ID: str
|
||||||
upload_files_context_var_data: VarData
|
upload_files_context_var_data: VarData
|
||||||
|
|
||||||
@CallableVar
|
|
||||||
def upload_file(id_: str = DEFAULT_UPLOAD_ID) -> Var: ...
|
def upload_file(id_: str = DEFAULT_UPLOAD_ID) -> Var: ...
|
||||||
@CallableVar
|
|
||||||
def selected_files(id_: str = DEFAULT_UPLOAD_ID) -> Var: ...
|
def selected_files(id_: str = DEFAULT_UPLOAD_ID) -> Var: ...
|
||||||
@CallableEventSpec
|
@CallableEventSpec
|
||||||
def clear_selected_files(id_: str = DEFAULT_UPLOAD_ID) -> EventSpec: ...
|
def clear_selected_files(id_: str = DEFAULT_UPLOAD_ID) -> EventSpec: ...
|
||||||
@ -37,7 +35,7 @@ uploaded_files_url_prefix = Var(
|
|||||||
),
|
),
|
||||||
).to(str)
|
).to(str)
|
||||||
|
|
||||||
def get_upload_url(file_path: str) -> Var[str]: ...
|
def get_upload_url(file_path: str | Var[str]) -> Var[str]: ...
|
||||||
|
|
||||||
class UploadFilesProvider(Component):
|
class UploadFilesProvider(Component):
|
||||||
@overload
|
@overload
|
||||||
@ -51,21 +49,21 @@ class UploadFilesProvider(Component):
|
|||||||
class_name: Optional[Any] = None,
|
class_name: Optional[Any] = None,
|
||||||
autofocus: Optional[bool] = None,
|
autofocus: Optional[bool] = None,
|
||||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
on_blur: Optional[EventType[()]] = None,
|
||||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_click: Optional[EventType[()]] = None,
|
||||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
on_focus: Optional[EventType[()]] = None,
|
||||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
on_mount: Optional[EventType[()]] = None,
|
||||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
**props,
|
**props,
|
||||||
) -> "UploadFilesProvider":
|
) -> "UploadFilesProvider":
|
||||||
"""Create the component.
|
"""Create the component.
|
||||||
@ -97,24 +95,22 @@ class GhostUpload(Fragment):
|
|||||||
class_name: Optional[Any] = None,
|
class_name: Optional[Any] = None,
|
||||||
autofocus: Optional[bool] = None,
|
autofocus: Optional[bool] = None,
|
||||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
on_blur: Optional[EventType[()]] = None,
|
||||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_click: Optional[EventType[()]] = None,
|
||||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
on_drop: Optional[
|
on_drop: Optional[Union[EventType[()], EventType[Any]]] = None,
|
||||||
Union[EventType[[], BASE_STATE], EventType[[Any], BASE_STATE]]
|
on_focus: Optional[EventType[()]] = None,
|
||||||
] = None,
|
on_mount: Optional[EventType[()]] = None,
|
||||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
|
||||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
|
||||||
**props,
|
**props,
|
||||||
) -> "GhostUpload":
|
) -> "GhostUpload":
|
||||||
"""Create the component.
|
"""Create the component.
|
||||||
@ -158,24 +154,22 @@ class Upload(MemoizationLeaf):
|
|||||||
class_name: Optional[Any] = None,
|
class_name: Optional[Any] = None,
|
||||||
autofocus: Optional[bool] = None,
|
autofocus: Optional[bool] = None,
|
||||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
on_blur: Optional[EventType[()]] = None,
|
||||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_click: Optional[EventType[()]] = None,
|
||||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
on_drop: Optional[
|
on_drop: Optional[Union[EventType[()], EventType[Any]]] = None,
|
||||||
Union[EventType[[], BASE_STATE], EventType[[Any], BASE_STATE]]
|
on_focus: Optional[EventType[()]] = None,
|
||||||
] = None,
|
on_mount: Optional[EventType[()]] = None,
|
||||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
|
||||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
|
||||||
**props,
|
**props,
|
||||||
) -> "Upload":
|
) -> "Upload":
|
||||||
"""Create an upload component.
|
"""Create an upload component.
|
||||||
@ -226,24 +220,22 @@ class StyledUpload(Upload):
|
|||||||
class_name: Optional[Any] = None,
|
class_name: Optional[Any] = None,
|
||||||
autofocus: Optional[bool] = None,
|
autofocus: Optional[bool] = None,
|
||||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
on_blur: Optional[EventType[()]] = None,
|
||||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_click: Optional[EventType[()]] = None,
|
||||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
on_drop: Optional[
|
on_drop: Optional[Union[EventType[()], EventType[Any]]] = None,
|
||||||
Union[EventType[[], BASE_STATE], EventType[[Any], BASE_STATE]]
|
on_focus: Optional[EventType[()]] = None,
|
||||||
] = None,
|
on_mount: Optional[EventType[()]] = None,
|
||||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
|
||||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
|
||||||
**props,
|
**props,
|
||||||
) -> "StyledUpload":
|
) -> "StyledUpload":
|
||||||
"""Create the styled upload component.
|
"""Create the styled upload component.
|
||||||
@ -294,24 +286,22 @@ class UploadNamespace(ComponentNamespace):
|
|||||||
class_name: Optional[Any] = None,
|
class_name: Optional[Any] = None,
|
||||||
autofocus: Optional[bool] = None,
|
autofocus: Optional[bool] = None,
|
||||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
on_blur: Optional[EventType[()]] = None,
|
||||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_click: Optional[EventType[()]] = None,
|
||||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
on_drop: Optional[
|
on_drop: Optional[Union[EventType[()], EventType[Any]]] = None,
|
||||||
Union[EventType[[], BASE_STATE], EventType[[Any], BASE_STATE]]
|
on_focus: Optional[EventType[()]] = None,
|
||||||
] = None,
|
on_mount: Optional[EventType[()]] = None,
|
||||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
|
||||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
|
||||||
**props,
|
**props,
|
||||||
) -> "StyledUpload":
|
) -> "StyledUpload":
|
||||||
"""Create the styled upload component.
|
"""Create the styled upload component.
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import dataclasses
|
import dataclasses
|
||||||
|
import typing
|
||||||
from typing import ClassVar, Dict, Literal, Optional, Union
|
from typing import ClassVar, Dict, Literal, Optional, Union
|
||||||
|
|
||||||
from reflex.components.component import Component, ComponentNamespace
|
from reflex.components.component import Component, ComponentNamespace
|
||||||
@ -14,7 +15,7 @@ from reflex.components.radix.themes.layout.box import Box
|
|||||||
from reflex.constants.colors import Color
|
from reflex.constants.colors import Color
|
||||||
from reflex.event import set_clipboard
|
from reflex.event import set_clipboard
|
||||||
from reflex.style import Style
|
from reflex.style import Style
|
||||||
from reflex.utils import console, format
|
from reflex.utils import format
|
||||||
from reflex.utils.imports import ImportVar
|
from reflex.utils.imports import ImportVar
|
||||||
from reflex.vars.base import LiteralVar, Var, VarData
|
from reflex.vars.base import LiteralVar, Var, VarData
|
||||||
|
|
||||||
@ -382,7 +383,7 @@ for theme_name in dir(Theme):
|
|||||||
class CodeBlock(Component, MarkdownComponentMap):
|
class CodeBlock(Component, MarkdownComponentMap):
|
||||||
"""A code block."""
|
"""A code block."""
|
||||||
|
|
||||||
library = "react-syntax-highlighter@15.6.0"
|
library = "react-syntax-highlighter@15.6.1"
|
||||||
|
|
||||||
tag = "PrismAsyncLight"
|
tag = "PrismAsyncLight"
|
||||||
|
|
||||||
@ -438,6 +439,8 @@ class CodeBlock(Component, MarkdownComponentMap):
|
|||||||
can_copy = props.pop("can_copy", False)
|
can_copy = props.pop("can_copy", False)
|
||||||
copy_button = props.pop("copy_button", None)
|
copy_button = props.pop("copy_button", None)
|
||||||
|
|
||||||
|
# react-syntax-highlighter doesn't have an explicit "light" or "dark" theme so we use one-light and one-dark
|
||||||
|
# themes respectively to ensure code compatibility.
|
||||||
if "theme" not in props:
|
if "theme" not in props:
|
||||||
# Default color scheme responds to global color mode.
|
# Default color scheme responds to global color mode.
|
||||||
props["theme"] = color_mode_cond(
|
props["theme"] = color_mode_cond(
|
||||||
@ -445,20 +448,9 @@ class CodeBlock(Component, MarkdownComponentMap):
|
|||||||
dark=Theme.one_dark,
|
dark=Theme.one_dark,
|
||||||
)
|
)
|
||||||
|
|
||||||
# react-syntax-highlighter doesn't have an explicit "light" or "dark" theme so we use one-light and one-dark
|
|
||||||
# themes respectively to ensure code compatibility.
|
|
||||||
if "theme" in props and not isinstance(props["theme"], Var):
|
|
||||||
props["theme"] = getattr(Theme, format.to_snake_case(props["theme"])) # type: ignore
|
|
||||||
console.deprecate(
|
|
||||||
feature_name="theme prop as string",
|
|
||||||
reason="Use code_block.themes instead.",
|
|
||||||
deprecation_version="0.6.0",
|
|
||||||
removal_version="0.7.0",
|
|
||||||
)
|
|
||||||
|
|
||||||
if can_copy:
|
if can_copy:
|
||||||
code = children[0]
|
code = children[0]
|
||||||
copy_button = ( # type: ignore
|
copy_button = (
|
||||||
copy_button
|
copy_button
|
||||||
if copy_button is not None
|
if copy_button is not None
|
||||||
else Button.create(
|
else Button.create(
|
||||||
@ -512,7 +504,7 @@ class CodeBlock(Component, MarkdownComponentMap):
|
|||||||
return ["can_copy", "copy_button"]
|
return ["can_copy", "copy_button"]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _get_language_registration_hook(cls, language_var: Var = _LANGUAGE) -> str:
|
def _get_language_registration_hook(cls, language_var: Var = _LANGUAGE) -> Var:
|
||||||
"""Get the hook to register the language.
|
"""Get the hook to register the language.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -523,21 +515,46 @@ class CodeBlock(Component, MarkdownComponentMap):
|
|||||||
Returns:
|
Returns:
|
||||||
The hook to register the language.
|
The hook to register the language.
|
||||||
"""
|
"""
|
||||||
return f"""
|
language_in_there = Var.create(typing.get_args(LiteralCodeLanguage)).contains(
|
||||||
if ({language_var!s}) {{
|
language_var
|
||||||
(async () => {{
|
)
|
||||||
try {{
|
async_load = f"""
|
||||||
|
(async () => {{
|
||||||
|
try {{
|
||||||
const module = await import(`react-syntax-highlighter/dist/cjs/languages/prism/${{{language_var!s}}}`);
|
const module = await import(`react-syntax-highlighter/dist/cjs/languages/prism/${{{language_var!s}}}`);
|
||||||
SyntaxHighlighter.registerLanguage({language_var!s}, module.default);
|
SyntaxHighlighter.registerLanguage({language_var!s}, module.default);
|
||||||
}} catch (error) {{
|
}} catch (error) {{
|
||||||
console.error(`Error importing language module for ${{{language_var!s}}}:`, error);
|
console.error(`Language ${{{language_var!s}}} is not supported for code blocks inside of markdown: `, error);
|
||||||
}}
|
}}
|
||||||
}})();
|
}})();
|
||||||
|
"""
|
||||||
|
return Var(
|
||||||
|
f"""
|
||||||
|
if ({language_var!s}) {{
|
||||||
|
if (!{language_in_there!s}) {{
|
||||||
|
console.warn(`Language \\`${{{language_var!s}}}\\` is not supported for code blocks inside of markdown.`);
|
||||||
|
{language_var!s} = '';
|
||||||
|
}} else {{
|
||||||
|
{async_load!s}
|
||||||
|
}}
|
||||||
}}
|
}}
|
||||||
"""
|
"""
|
||||||
|
if not isinstance(language_var, LiteralVar)
|
||||||
|
else f"""
|
||||||
|
if ({language_var!s}) {{
|
||||||
|
{async_load!s}
|
||||||
|
}}""",
|
||||||
|
_var_data=VarData(
|
||||||
|
imports={
|
||||||
|
cls.__fields__["library"].default: [
|
||||||
|
ImportVar(tag="PrismAsyncLight", alias="SyntaxHighlighter")
|
||||||
|
]
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_component_map_custom_code(cls) -> str:
|
def get_component_map_custom_code(cls) -> Var:
|
||||||
"""Get the custom code for the component.
|
"""Get the custom code for the component.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, Literal, Optional, Union, overload
|
|||||||
from reflex.components.component import Component, ComponentNamespace
|
from reflex.components.component import Component, ComponentNamespace
|
||||||
from reflex.components.markdown.markdown import MarkdownComponentMap
|
from reflex.components.markdown.markdown import MarkdownComponentMap
|
||||||
from reflex.constants.colors import Color
|
from reflex.constants.colors import Color
|
||||||
from reflex.event import BASE_STATE, EventType
|
from reflex.event import EventType
|
||||||
from reflex.style import Style
|
from reflex.style import Style
|
||||||
from reflex.vars.base import Var
|
from reflex.vars.base import Var
|
||||||
|
|
||||||
@ -938,21 +938,21 @@ class CodeBlock(Component, MarkdownComponentMap):
|
|||||||
class_name: Optional[Any] = None,
|
class_name: Optional[Any] = None,
|
||||||
autofocus: Optional[bool] = None,
|
autofocus: Optional[bool] = None,
|
||||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
on_blur: Optional[EventType[()]] = None,
|
||||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_click: Optional[EventType[()]] = None,
|
||||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
on_focus: Optional[EventType[()]] = None,
|
||||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
on_mount: Optional[EventType[()]] = None,
|
||||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
**props,
|
**props,
|
||||||
) -> "CodeBlock":
|
) -> "CodeBlock":
|
||||||
"""Create a text component.
|
"""Create a text component.
|
||||||
@ -984,7 +984,7 @@ class CodeBlock(Component, MarkdownComponentMap):
|
|||||||
|
|
||||||
def add_style(self): ...
|
def add_style(self): ...
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_component_map_custom_code(cls) -> str: ...
|
def get_component_map_custom_code(cls) -> Var: ...
|
||||||
def add_hooks(self) -> list[str | Var]: ...
|
def add_hooks(self) -> list[str | Var]: ...
|
||||||
|
|
||||||
class CodeblockNamespace(ComponentNamespace):
|
class CodeblockNamespace(ComponentNamespace):
|
||||||
@ -1576,21 +1576,21 @@ class CodeblockNamespace(ComponentNamespace):
|
|||||||
class_name: Optional[Any] = None,
|
class_name: Optional[Any] = None,
|
||||||
autofocus: Optional[bool] = None,
|
autofocus: Optional[bool] = None,
|
||||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
on_blur: Optional[EventType[()]] = None,
|
||||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_click: Optional[EventType[()]] = None,
|
||||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
on_focus: Optional[EventType[()]] = None,
|
||||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
on_mount: Optional[EventType[()]] = None,
|
||||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
**props,
|
**props,
|
||||||
) -> "CodeBlock":
|
) -> "CodeBlock":
|
||||||
"""Create a text component.
|
"""Create a text component.
|
||||||
|
@ -3,9 +3,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from typing import Any, Dict, List, Literal, Optional, Tuple, Union
|
from typing import Any, Dict, List, Literal, Optional, Tuple, TypedDict, Union
|
||||||
|
|
||||||
from typing_extensions import TypedDict
|
|
||||||
|
|
||||||
from reflex.base import Base
|
from reflex.base import Base
|
||||||
from reflex.components.component import Component, NoSSRComponent
|
from reflex.components.component import Component, NoSSRComponent
|
||||||
@ -165,7 +163,7 @@ class DataEditor(NoSSRComponent):
|
|||||||
|
|
||||||
tag = "DataEditor"
|
tag = "DataEditor"
|
||||||
is_default = True
|
is_default = True
|
||||||
library: str = "@glideapps/glide-data-grid@^6.0.3"
|
library: str | None = "@glideapps/glide-data-grid@^6.0.3"
|
||||||
lib_dependencies: List[str] = [
|
lib_dependencies: List[str] = [
|
||||||
"lodash@^4.17.21",
|
"lodash@^4.17.21",
|
||||||
"react-responsive-carousel@^3.2.7",
|
"react-responsive-carousel@^3.2.7",
|
||||||
@ -321,6 +319,8 @@ class DataEditor(NoSSRComponent):
|
|||||||
Returns:
|
Returns:
|
||||||
The import dict.
|
The import dict.
|
||||||
"""
|
"""
|
||||||
|
if self.library is None:
|
||||||
|
return {}
|
||||||
return {
|
return {
|
||||||
"": f"{format.format_library_name(self.library)}/dist/index.css",
|
"": f"{format.format_library_name(self.library)}/dist/index.css",
|
||||||
self.library: "GridCellKind",
|
self.library: "GridCellKind",
|
||||||
@ -343,9 +343,9 @@ class DataEditor(NoSSRComponent):
|
|||||||
data_callback = self.get_cell_content._js_expr
|
data_callback = self.get_cell_content._js_expr
|
||||||
else:
|
else:
|
||||||
data_callback = f"getData_{editor_id}"
|
data_callback = f"getData_{editor_id}"
|
||||||
self.get_cell_content = Var(_js_expr=data_callback) # type: ignore
|
self.get_cell_content = Var(_js_expr=data_callback)
|
||||||
|
|
||||||
code = [f"function {data_callback}([col, row])" "{"]
|
code = [f"function {data_callback}([col, row]){{"]
|
||||||
|
|
||||||
columns_path = str(self.columns)
|
columns_path = str(self.columns)
|
||||||
data_path = str(self.data)
|
data_path = str(self.data)
|
||||||
@ -385,7 +385,8 @@ class DataEditor(NoSSRComponent):
|
|||||||
raise ValueError(
|
raise ValueError(
|
||||||
"DataEditor data must be an ArrayVar if rows is not provided."
|
"DataEditor data must be an ArrayVar if rows is not provided."
|
||||||
)
|
)
|
||||||
props["rows"] = data.length() if isinstance(data, Var) else len(data)
|
|
||||||
|
props["rows"] = data.length() if isinstance(data, ArrayVar) else len(data)
|
||||||
|
|
||||||
if not isinstance(columns, Var) and len(columns):
|
if not isinstance(columns, Var) and len(columns):
|
||||||
if types.is_dataframe(type(data)) or (
|
if types.is_dataframe(type(data)) or (
|
||||||
|
@ -4,13 +4,11 @@
|
|||||||
# This file was generated by `reflex/utils/pyi_generator.py`!
|
# This file was generated by `reflex/utils/pyi_generator.py`!
|
||||||
# ------------------------------------------------------
|
# ------------------------------------------------------
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from typing import Any, Dict, List, Literal, Optional, Union, overload
|
from typing import Any, Dict, List, Literal, Optional, TypedDict, Union, overload
|
||||||
|
|
||||||
from typing_extensions import TypedDict
|
|
||||||
|
|
||||||
from reflex.base import Base
|
from reflex.base import Base
|
||||||
from reflex.components.component import NoSSRComponent
|
from reflex.components.component import NoSSRComponent
|
||||||
from reflex.event import BASE_STATE, EventType
|
from reflex.event import EventType
|
||||||
from reflex.style import Style
|
from reflex.style import Style
|
||||||
from reflex.utils.imports import ImportDict
|
from reflex.utils.imports import ImportDict
|
||||||
from reflex.utils.serializers import serializer
|
from reflex.utils.serializers import serializer
|
||||||
@ -183,93 +181,79 @@ class DataEditor(NoSSRComponent):
|
|||||||
class_name: Optional[Any] = None,
|
class_name: Optional[Any] = None,
|
||||||
autofocus: Optional[bool] = None,
|
autofocus: Optional[bool] = None,
|
||||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
on_blur: Optional[EventType[()]] = None,
|
||||||
on_cell_activated: Optional[
|
on_cell_activated: Optional[
|
||||||
Union[EventType[[], BASE_STATE], EventType[[tuple[int, int]], BASE_STATE]]
|
Union[EventType[()], EventType[tuple[int, int]]]
|
||||||
] = None,
|
] = None,
|
||||||
on_cell_clicked: Optional[
|
on_cell_clicked: Optional[
|
||||||
Union[EventType[[], BASE_STATE], EventType[[tuple[int, int]], BASE_STATE]]
|
Union[EventType[()], EventType[tuple[int, int]]]
|
||||||
] = None,
|
] = None,
|
||||||
on_cell_context_menu: Optional[
|
on_cell_context_menu: Optional[
|
||||||
Union[EventType[[], BASE_STATE], EventType[[tuple[int, int]], BASE_STATE]]
|
Union[EventType[()], EventType[tuple[int, int]]]
|
||||||
] = None,
|
] = None,
|
||||||
on_cell_edited: Optional[
|
on_cell_edited: Optional[
|
||||||
Union[
|
Union[
|
||||||
EventType[[], BASE_STATE],
|
EventType[()],
|
||||||
EventType[[tuple[int, int]], BASE_STATE],
|
EventType[tuple[int, int]],
|
||||||
EventType[[tuple[int, int], GridCell], BASE_STATE],
|
EventType[tuple[int, int], GridCell],
|
||||||
]
|
]
|
||||||
] = None,
|
] = None,
|
||||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_click: Optional[EventType[()]] = None,
|
||||||
on_column_resize: Optional[
|
on_column_resize: Optional[
|
||||||
Union[
|
Union[EventType[()], EventType[GridColumn], EventType[GridColumn, int]]
|
||||||
EventType[[], BASE_STATE],
|
|
||||||
EventType[[GridColumn], BASE_STATE],
|
|
||||||
EventType[[GridColumn, int], BASE_STATE],
|
|
||||||
]
|
|
||||||
] = None,
|
] = None,
|
||||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
on_delete: Optional[
|
on_delete: Optional[Union[EventType[()], EventType[GridSelection]]] = None,
|
||||||
Union[EventType[[], BASE_STATE], EventType[[GridSelection], BASE_STATE]]
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
] = None,
|
|
||||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
|
||||||
on_finished_editing: Optional[
|
on_finished_editing: Optional[
|
||||||
Union[
|
Union[
|
||||||
EventType[[], BASE_STATE],
|
EventType[()],
|
||||||
EventType[[Union[GridCell, None]], BASE_STATE],
|
EventType[Union[GridCell, None]],
|
||||||
EventType[[Union[GridCell, None], tuple[int, int]], BASE_STATE],
|
EventType[Union[GridCell, None], tuple[int, int]],
|
||||||
]
|
]
|
||||||
] = None,
|
] = None,
|
||||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
on_focus: Optional[EventType[()]] = None,
|
||||||
on_group_header_clicked: Optional[
|
on_group_header_clicked: Optional[
|
||||||
Union[
|
Union[
|
||||||
EventType[[], BASE_STATE],
|
EventType[()],
|
||||||
EventType[[tuple[int, int]], BASE_STATE],
|
EventType[tuple[int, int]],
|
||||||
EventType[[tuple[int, int], GridCell], BASE_STATE],
|
EventType[tuple[int, int], GridCell],
|
||||||
]
|
]
|
||||||
] = None,
|
] = None,
|
||||||
on_group_header_context_menu: Optional[
|
on_group_header_context_menu: Optional[
|
||||||
Union[
|
Union[
|
||||||
EventType[[], BASE_STATE],
|
EventType[()],
|
||||||
EventType[[int], BASE_STATE],
|
EventType[int],
|
||||||
EventType[[int, GroupHeaderClickedEventArgs], BASE_STATE],
|
EventType[int, GroupHeaderClickedEventArgs],
|
||||||
]
|
]
|
||||||
] = None,
|
] = None,
|
||||||
on_group_header_renamed: Optional[
|
on_group_header_renamed: Optional[
|
||||||
Union[
|
Union[EventType[()], EventType[str], EventType[str, str]]
|
||||||
EventType[[], BASE_STATE],
|
|
||||||
EventType[[str], BASE_STATE],
|
|
||||||
EventType[[str, str], BASE_STATE],
|
|
||||||
]
|
|
||||||
] = None,
|
] = None,
|
||||||
on_header_clicked: Optional[
|
on_header_clicked: Optional[
|
||||||
Union[EventType[[], BASE_STATE], EventType[[tuple[int, int]], BASE_STATE]]
|
Union[EventType[()], EventType[tuple[int, int]]]
|
||||||
] = None,
|
] = None,
|
||||||
on_header_context_menu: Optional[
|
on_header_context_menu: Optional[
|
||||||
Union[EventType[[], BASE_STATE], EventType[[tuple[int, int]], BASE_STATE]]
|
Union[EventType[()], EventType[tuple[int, int]]]
|
||||||
] = None,
|
] = None,
|
||||||
on_header_menu_click: Optional[
|
on_header_menu_click: Optional[
|
||||||
Union[
|
Union[EventType[()], EventType[int], EventType[int, Rectangle]]
|
||||||
EventType[[], BASE_STATE],
|
|
||||||
EventType[[int], BASE_STATE],
|
|
||||||
EventType[[int, Rectangle], BASE_STATE],
|
|
||||||
]
|
|
||||||
] = None,
|
] = None,
|
||||||
on_item_hovered: Optional[
|
on_item_hovered: Optional[
|
||||||
Union[EventType[[], BASE_STATE], EventType[[tuple[int, int]], BASE_STATE]]
|
Union[EventType[()], EventType[tuple[int, int]]]
|
||||||
] = None,
|
] = None,
|
||||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
on_mount: Optional[EventType[()]] = None,
|
||||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
on_row_appended: Optional[EventType[[], BASE_STATE]] = None,
|
on_row_appended: Optional[EventType[()]] = None,
|
||||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
on_selection_cleared: Optional[EventType[[], BASE_STATE]] = None,
|
on_selection_cleared: Optional[EventType[()]] = None,
|
||||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
**props,
|
**props,
|
||||||
) -> "DataEditor":
|
) -> "DataEditor":
|
||||||
"""Create the DataEditor component.
|
"""Create the DataEditor component.
|
||||||
|
@ -5,20 +5,22 @@ from typing import Union
|
|||||||
import reflex as rx
|
import reflex as rx
|
||||||
|
|
||||||
|
|
||||||
def svg_logo(color: Union[str, rx.Var[str]] = rx.color_mode_cond("#110F1F", "white")):
|
def svg_logo(
|
||||||
|
color: Union[str, rx.Var[str]] = rx.color_mode_cond("#110F1F", "white"),
|
||||||
|
**props,
|
||||||
|
):
|
||||||
"""A Reflex logo SVG.
|
"""A Reflex logo SVG.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
color: The color of the logo.
|
color: The color of the logo.
|
||||||
|
props: Extra props to pass to the svg component.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The Reflex logo SVG.
|
The Reflex logo SVG.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def logo_path(d):
|
def logo_path(d: str):
|
||||||
return rx.el.svg.path(
|
return rx.el.svg.path(d=d)
|
||||||
d=d,
|
|
||||||
)
|
|
||||||
|
|
||||||
paths = [
|
paths = [
|
||||||
"M0 11.5999V0.399902H8.96V4.8799H6.72V2.6399H2.24V4.8799H6.72V7.1199H2.24V11.5999H0ZM6.72 11.5999V7.1199H8.96V11.5999H6.72Z",
|
"M0 11.5999V0.399902H8.96V4.8799H6.72V2.6399H2.24V4.8799H6.72V7.1199H2.24V11.5999H0ZM6.72 11.5999V7.1199H8.96V11.5999H6.72Z",
|
||||||
@ -31,11 +33,14 @@ def svg_logo(color: Union[str, rx.Var[str]] = rx.color_mode_cond("#110F1F", "whi
|
|||||||
|
|
||||||
return rx.el.svg(
|
return rx.el.svg(
|
||||||
*[logo_path(d) for d in paths],
|
*[logo_path(d) for d in paths],
|
||||||
width="56",
|
rx.el.title("Reflex"),
|
||||||
height="12",
|
aria_label="Reflex",
|
||||||
viewBox="0 0 56 12",
|
role="img",
|
||||||
|
width=props.pop("width", "56"),
|
||||||
|
height=props.pop("height", "12"),
|
||||||
fill=color,
|
fill=color,
|
||||||
xmlns="http://www.w3.org/2000/svg",
|
xmlns="http://www.w3.org/2000/svg",
|
||||||
|
**props,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -602,7 +602,7 @@ class ShikiCodeBlock(Component, MarkdownComponentMap):
|
|||||||
|
|
||||||
transformer_styles = {}
|
transformer_styles = {}
|
||||||
# Collect styles from transformers and wrapper
|
# Collect styles from transformers and wrapper
|
||||||
for transformer in code_block.transformers._var_value: # type: ignore
|
for transformer in code_block.transformers._var_value: # pyright: ignore [reportAttributeAccessIssue]
|
||||||
if isinstance(transformer, ShikiBaseTransformers) and transformer.style:
|
if isinstance(transformer, ShikiBaseTransformers) and transformer.style:
|
||||||
transformer_styles.update(transformer.style)
|
transformer_styles.update(transformer.style)
|
||||||
transformer_styles.update(code_wrapper_props.pop("style", {}))
|
transformer_styles.update(code_wrapper_props.pop("style", {}))
|
||||||
@ -621,18 +621,22 @@ class ShikiCodeBlock(Component, MarkdownComponentMap):
|
|||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Imports for the component.
|
Imports for the component.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
ValueError: If the transformers are not of type LiteralVar.
|
||||||
"""
|
"""
|
||||||
imports = defaultdict(list)
|
imports = defaultdict(list)
|
||||||
|
if not isinstance(self.transformers, LiteralVar):
|
||||||
|
raise ValueError(
|
||||||
|
f"transformers should be a LiteralVar type. Got {type(self.transformers)} instead."
|
||||||
|
)
|
||||||
for transformer in self.transformers._var_value:
|
for transformer in self.transformers._var_value:
|
||||||
if isinstance(transformer, ShikiBaseTransformers):
|
if isinstance(transformer, ShikiBaseTransformers):
|
||||||
imports[transformer.library].extend(
|
imports[transformer.library].extend(
|
||||||
[ImportVar(tag=str(fn)) for fn in transformer.fns]
|
[ImportVar(tag=str(fn)) for fn in transformer.fns]
|
||||||
)
|
)
|
||||||
(
|
if transformer.library not in self.lib_dependencies:
|
||||||
self.lib_dependencies.append(transformer.library)
|
self.lib_dependencies.append(transformer.library)
|
||||||
if transformer.library not in self.lib_dependencies
|
|
||||||
else None
|
|
||||||
)
|
|
||||||
return imports
|
return imports
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -653,8 +657,9 @@ class ShikiCodeBlock(Component, MarkdownComponentMap):
|
|||||||
raise ValueError(
|
raise ValueError(
|
||||||
f"the function names should be str names of functions in the specified transformer: {library!r}"
|
f"the function names should be str names of functions in the specified transformer: {library!r}"
|
||||||
)
|
)
|
||||||
return ShikiBaseTransformers( # type: ignore
|
return ShikiBaseTransformers(
|
||||||
library=library, fns=[FunctionStringVar.create(fn) for fn in fns]
|
library=library,
|
||||||
|
fns=[FunctionStringVar.create(fn) for fn in fns], # pyright: ignore [reportCallIssue]
|
||||||
)
|
)
|
||||||
|
|
||||||
def _render(self, props: dict[str, Any] | None = None):
|
def _render(self, props: dict[str, Any] | None = None):
|
||||||
@ -757,13 +762,13 @@ class ShikiHighLevelCodeBlock(ShikiCodeBlock):
|
|||||||
|
|
||||||
if can_copy:
|
if can_copy:
|
||||||
code = children[0]
|
code = children[0]
|
||||||
copy_button = ( # type: ignore
|
copy_button = (
|
||||||
copy_button
|
copy_button
|
||||||
if copy_button is not None
|
if copy_button is not None
|
||||||
else Button.create(
|
else Button.create(
|
||||||
Icon.create(tag="copy", size=16, color=color("gray", 11)),
|
Icon.create(tag="copy", size=16, color=color("gray", 11)),
|
||||||
on_click=[
|
on_click=[
|
||||||
set_clipboard(cls._strip_transformer_triggers(code)), # type: ignore
|
set_clipboard(cls._strip_transformer_triggers(code)),
|
||||||
copy_script(),
|
copy_script(),
|
||||||
],
|
],
|
||||||
style=Style(
|
style=Style(
|
||||||
|
@ -9,7 +9,7 @@ from reflex.base import Base
|
|||||||
from reflex.components.component import Component, ComponentNamespace
|
from reflex.components.component import Component, ComponentNamespace
|
||||||
from reflex.components.markdown.markdown import MarkdownComponentMap
|
from reflex.components.markdown.markdown import MarkdownComponentMap
|
||||||
from reflex.components.props import NoExtrasAllowedProps
|
from reflex.components.props import NoExtrasAllowedProps
|
||||||
from reflex.event import BASE_STATE, EventType
|
from reflex.event import EventType
|
||||||
from reflex.style import Style
|
from reflex.style import Style
|
||||||
from reflex.vars.base import Var
|
from reflex.vars.base import Var
|
||||||
from reflex.vars.function import FunctionStringVar
|
from reflex.vars.function import FunctionStringVar
|
||||||
@ -928,21 +928,21 @@ class ShikiCodeBlock(Component, MarkdownComponentMap):
|
|||||||
class_name: Optional[Any] = None,
|
class_name: Optional[Any] = None,
|
||||||
autofocus: Optional[bool] = None,
|
autofocus: Optional[bool] = None,
|
||||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
on_blur: Optional[EventType[()]] = None,
|
||||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_click: Optional[EventType[()]] = None,
|
||||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
on_focus: Optional[EventType[()]] = None,
|
||||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
on_mount: Optional[EventType[()]] = None,
|
||||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
**props,
|
**props,
|
||||||
) -> "ShikiCodeBlock":
|
) -> "ShikiCodeBlock":
|
||||||
"""Create a code block component using [shiki syntax highlighter](https://shiki.matsu.io/).
|
"""Create a code block component using [shiki syntax highlighter](https://shiki.matsu.io/).
|
||||||
@ -1555,21 +1555,21 @@ class ShikiHighLevelCodeBlock(ShikiCodeBlock):
|
|||||||
class_name: Optional[Any] = None,
|
class_name: Optional[Any] = None,
|
||||||
autofocus: Optional[bool] = None,
|
autofocus: Optional[bool] = None,
|
||||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
on_blur: Optional[EventType[()]] = None,
|
||||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_click: Optional[EventType[()]] = None,
|
||||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
on_focus: Optional[EventType[()]] = None,
|
||||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
on_mount: Optional[EventType[()]] = None,
|
||||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
**props,
|
**props,
|
||||||
) -> "ShikiHighLevelCodeBlock":
|
) -> "ShikiHighLevelCodeBlock":
|
||||||
"""Create a code block component using [shiki syntax highlighter](https://shiki.matsu.io/).
|
"""Create a code block component using [shiki syntax highlighter](https://shiki.matsu.io/).
|
||||||
@ -2185,21 +2185,21 @@ class CodeblockNamespace(ComponentNamespace):
|
|||||||
class_name: Optional[Any] = None,
|
class_name: Optional[Any] = None,
|
||||||
autofocus: Optional[bool] = None,
|
autofocus: Optional[bool] = None,
|
||||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
on_blur: Optional[EventType[()]] = None,
|
||||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_click: Optional[EventType[()]] = None,
|
||||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
on_focus: Optional[EventType[()]] = None,
|
||||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
on_mount: Optional[EventType[()]] = None,
|
||||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
**props,
|
**props,
|
||||||
) -> "ShikiHighLevelCodeBlock":
|
) -> "ShikiHighLevelCodeBlock":
|
||||||
"""Create a code block component using [shiki syntax highlighter](https://shiki.matsu.io/).
|
"""Create a code block component using [shiki syntax highlighter](https://shiki.matsu.io/).
|
||||||
|
@ -4,7 +4,7 @@ from typing import TYPE_CHECKING, Union
|
|||||||
|
|
||||||
from reflex import constants
|
from reflex import constants
|
||||||
from reflex.utils import imports
|
from reflex.utils import imports
|
||||||
from reflex.utils.exceptions import DynamicComponentMissingLibrary
|
from reflex.utils.exceptions import DynamicComponentMissingLibraryError
|
||||||
from reflex.utils.format import format_library_name
|
from reflex.utils.format import format_library_name
|
||||||
from reflex.utils.serializers import serializer
|
from reflex.utils.serializers import serializer
|
||||||
from reflex.vars import Var, get_unique_variable_name
|
from reflex.vars import Var, get_unique_variable_name
|
||||||
@ -36,13 +36,15 @@ def bundle_library(component: Union["Component", str]):
|
|||||||
component: The component to bundle the library with.
|
component: The component to bundle the library with.
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
DynamicComponentMissingLibrary: Raised when a dynamic component is missing a library.
|
DynamicComponentMissingLibraryError: Raised when a dynamic component is missing a library.
|
||||||
"""
|
"""
|
||||||
if isinstance(component, str):
|
if isinstance(component, str):
|
||||||
bundled_libraries.add(component)
|
bundled_libraries.add(component)
|
||||||
return
|
return
|
||||||
if component.library is None:
|
if component.library is None:
|
||||||
raise DynamicComponentMissingLibrary("Component must have a library to bundle.")
|
raise DynamicComponentMissingLibraryError(
|
||||||
|
"Component must have a library to bundle."
|
||||||
|
)
|
||||||
bundled_libraries.add(format_library_name(component.library))
|
bundled_libraries.add(format_library_name(component.library))
|
||||||
|
|
||||||
|
|
||||||
@ -136,6 +138,23 @@ def load_dynamic_serializer():
|
|||||||
|
|
||||||
module_code_lines.insert(0, "const React = window.__reflex.react;")
|
module_code_lines.insert(0, "const React = window.__reflex.react;")
|
||||||
|
|
||||||
|
function_line = next(
|
||||||
|
index
|
||||||
|
for index, line in enumerate(module_code_lines)
|
||||||
|
if line.startswith("export default function")
|
||||||
|
)
|
||||||
|
|
||||||
|
module_code_lines = [
|
||||||
|
line
|
||||||
|
for _, line in sorted(
|
||||||
|
enumerate(module_code_lines),
|
||||||
|
key=lambda x: (
|
||||||
|
not (x[1].startswith("import ") and x[0] < function_line),
|
||||||
|
x[0],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
return "\n".join(
|
return "\n".join(
|
||||||
[
|
[
|
||||||
"//__reflex_evaluate",
|
"//__reflex_evaluate",
|
||||||
|
@ -48,4 +48,4 @@ PROP_TO_ELEMENTS = {
|
|||||||
ELEMENT_TO_PROPS = defaultdict(list)
|
ELEMENT_TO_PROPS = defaultdict(list)
|
||||||
for prop, elements in PROP_TO_ELEMENTS.items():
|
for prop, elements in PROP_TO_ELEMENTS.items():
|
||||||
for el in elements:
|
for el in elements:
|
||||||
ELEMENT_TO_PROPS[el].append(prop) # type: ignore
|
ELEMENT_TO_PROPS[el].append(prop)
|
||||||
|
@ -6,7 +6,7 @@ from reflex.components.component import Component
|
|||||||
class Element(Component):
|
class Element(Component):
|
||||||
"""The base class for all raw HTML elements."""
|
"""The base class for all raw HTML elements."""
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other: object):
|
||||||
"""Two elements are equal if they have the same tag.
|
"""Two elements are equal if they have the same tag.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
from typing import Any, Dict, Optional, Union, overload
|
from typing import Any, Dict, Optional, Union, overload
|
||||||
|
|
||||||
from reflex.components.component import Component
|
from reflex.components.component import Component
|
||||||
from reflex.event import BASE_STATE, EventType
|
from reflex.event import EventType
|
||||||
from reflex.style import Style
|
from reflex.style import Style
|
||||||
from reflex.vars.base import Var
|
from reflex.vars.base import Var
|
||||||
|
|
||||||
@ -22,21 +22,21 @@ class Element(Component):
|
|||||||
class_name: Optional[Any] = None,
|
class_name: Optional[Any] = None,
|
||||||
autofocus: Optional[bool] = None,
|
autofocus: Optional[bool] = None,
|
||||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
on_blur: Optional[EventType[()]] = None,
|
||||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_click: Optional[EventType[()]] = None,
|
||||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
on_focus: Optional[EventType[()]] = None,
|
||||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
on_mount: Optional[EventType[()]] = None,
|
||||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
**props,
|
**props,
|
||||||
) -> "Element":
|
) -> "Element":
|
||||||
"""Create the component.
|
"""Create the component.
|
||||||
|
@ -1,58 +1,136 @@
|
|||||||
"""Base classes."""
|
"""Base classes."""
|
||||||
|
|
||||||
from typing import Union
|
from typing import Literal
|
||||||
|
|
||||||
from reflex.components.el.element import Element
|
from reflex.components.el.element import Element
|
||||||
from reflex.vars.base import Var
|
from reflex.vars.base import Var
|
||||||
|
|
||||||
|
AutoCapitalize = Literal["off", "none", "on", "sentences", "words", "characters"]
|
||||||
|
ContentEditable = Literal[True, False, "inherit", "plaintext-only"]
|
||||||
|
EnterKeyHint = Literal["enter", "done", "go", "next", "previous", "search", "send"]
|
||||||
|
InputMode = Literal[
|
||||||
|
"none", "text", "tel", "url", "email", "numeric", "decimal", "search", "search"
|
||||||
|
]
|
||||||
|
AriaRole = Literal[
|
||||||
|
"alert",
|
||||||
|
"alertdialog",
|
||||||
|
"application",
|
||||||
|
"article",
|
||||||
|
"banner",
|
||||||
|
"button",
|
||||||
|
"cell",
|
||||||
|
"checkbox",
|
||||||
|
"columnheader",
|
||||||
|
"combobox",
|
||||||
|
"complementary",
|
||||||
|
"contentinfo",
|
||||||
|
"definition",
|
||||||
|
"dialog",
|
||||||
|
"directory",
|
||||||
|
"document",
|
||||||
|
"feed",
|
||||||
|
"figure",
|
||||||
|
"form",
|
||||||
|
"grid",
|
||||||
|
"gridcell",
|
||||||
|
"group",
|
||||||
|
"heading",
|
||||||
|
"img",
|
||||||
|
"link",
|
||||||
|
"list",
|
||||||
|
"listbox",
|
||||||
|
"listitem",
|
||||||
|
"log",
|
||||||
|
"main",
|
||||||
|
"marquee",
|
||||||
|
"math",
|
||||||
|
"menu",
|
||||||
|
"menubar",
|
||||||
|
"menuitem",
|
||||||
|
"menuitemcheckbox",
|
||||||
|
"menuitemradio",
|
||||||
|
"navigation",
|
||||||
|
"none",
|
||||||
|
"note",
|
||||||
|
"option",
|
||||||
|
"presentation",
|
||||||
|
"progressbar",
|
||||||
|
"radio",
|
||||||
|
"radiogroup",
|
||||||
|
"region",
|
||||||
|
"row",
|
||||||
|
"rowgroup",
|
||||||
|
"rowheader",
|
||||||
|
"scrollbar",
|
||||||
|
"search",
|
||||||
|
"searchbox",
|
||||||
|
"separator",
|
||||||
|
"slider",
|
||||||
|
"spinbutton",
|
||||||
|
"status",
|
||||||
|
"switch",
|
||||||
|
"tab",
|
||||||
|
"table",
|
||||||
|
"tablist",
|
||||||
|
"tabpanel",
|
||||||
|
"term",
|
||||||
|
"textbox",
|
||||||
|
"timer",
|
||||||
|
"toolbar",
|
||||||
|
"tooltip",
|
||||||
|
"tree",
|
||||||
|
"treegrid",
|
||||||
|
"treeitem",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class BaseHTML(Element):
|
class BaseHTML(Element):
|
||||||
"""Base class for common attributes."""
|
"""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]]
|
access_key: Var[str]
|
||||||
|
|
||||||
# Controls whether and how text input is automatically capitalized as it is entered/edited by the user.
|
# Controls whether and how text input is automatically capitalized as it is entered/edited by the user.
|
||||||
auto_capitalize: Var[Union[str, int, bool]]
|
auto_capitalize: Var[AutoCapitalize]
|
||||||
|
|
||||||
# Indicates whether the element's content is editable.
|
# Indicates whether the element's content is editable.
|
||||||
content_editable: Var[Union[str, int, bool]]
|
content_editable: Var[ContentEditable]
|
||||||
|
|
||||||
# Defines the ID of a <menu> element which will serve as the element's context menu.
|
# Defines the ID of a <menu> element which will serve as the element's context menu.
|
||||||
context_menu: Var[Union[str, int, bool]]
|
context_menu: Var[str]
|
||||||
|
|
||||||
# Defines the text direction. Allowed values are ltr (Left-To-Right) or rtl (Right-To-Left)
|
# Defines the text direction. Allowed values are ltr (Left-To-Right) or rtl (Right-To-Left)
|
||||||
dir: Var[Union[str, int, bool]]
|
dir: Var[str]
|
||||||
|
|
||||||
# Defines whether the element can be dragged.
|
# Defines whether the element can be dragged.
|
||||||
draggable: Var[Union[str, int, bool]]
|
draggable: Var[bool]
|
||||||
|
|
||||||
# Hints what media types the media element is able to play.
|
# Hints what media types the media element is able to play.
|
||||||
enter_key_hint: Var[Union[str, int, bool]]
|
enter_key_hint: Var[EnterKeyHint]
|
||||||
|
|
||||||
# Defines whether the element is hidden.
|
# Defines whether the element is hidden.
|
||||||
hidden: Var[Union[str, int, bool]]
|
hidden: Var[bool]
|
||||||
|
|
||||||
# Defines the type of the element.
|
# Defines the type of the element.
|
||||||
input_mode: Var[Union[str, int, bool]]
|
input_mode: Var[InputMode]
|
||||||
|
|
||||||
# Defines the name of the element for metadata purposes.
|
# Defines the name of the element for metadata purposes.
|
||||||
item_prop: Var[Union[str, int, bool]]
|
item_prop: Var[str]
|
||||||
|
|
||||||
# Defines the language used in the element.
|
# Defines the language used in the element.
|
||||||
lang: Var[Union[str, int, bool]]
|
lang: Var[str]
|
||||||
|
|
||||||
# Defines the role of the element.
|
# Defines the role of the element.
|
||||||
role: Var[Union[str, int, bool]]
|
role: Var[AriaRole]
|
||||||
|
|
||||||
# Assigns a slot in a shadow DOM shadow tree to an element.
|
# Assigns a slot in a shadow DOM shadow tree to an element.
|
||||||
slot: Var[Union[str, int, bool]]
|
slot: Var[str]
|
||||||
|
|
||||||
# Defines whether the element may be checked for spelling errors.
|
# Defines whether the element may be checked for spelling errors.
|
||||||
spell_check: Var[Union[str, int, bool]]
|
spell_check: Var[bool]
|
||||||
|
|
||||||
# Defines the position of the current element in the tabbing order.
|
# Defines the position of the current element in the tabbing order.
|
||||||
tab_index: Var[Union[str, int, bool]]
|
tab_index: Var[int]
|
||||||
|
|
||||||
# Defines a tooltip for the element.
|
# Defines a tooltip for the element.
|
||||||
title: Var[Union[str, int, bool]]
|
title: Var[str]
|
||||||
|
@ -3,64 +3,323 @@
|
|||||||
# ------------------- DO NOT EDIT ----------------------
|
# ------------------- DO NOT EDIT ----------------------
|
||||||
# This file was generated by `reflex/utils/pyi_generator.py`!
|
# This file was generated by `reflex/utils/pyi_generator.py`!
|
||||||
# ------------------------------------------------------
|
# ------------------------------------------------------
|
||||||
from typing import Any, Dict, Optional, Union, overload
|
from typing import Any, Dict, Literal, Optional, Union, overload
|
||||||
|
|
||||||
from reflex.components.el.element import Element
|
from reflex.components.el.element import Element
|
||||||
from reflex.event import BASE_STATE, EventType
|
from reflex.event import EventType
|
||||||
from reflex.style import Style
|
from reflex.style import Style
|
||||||
from reflex.vars.base import Var
|
from reflex.vars.base import Var
|
||||||
|
|
||||||
|
AutoCapitalize = Literal["off", "none", "on", "sentences", "words", "characters"]
|
||||||
|
ContentEditable = Literal[True, False, "inherit", "plaintext-only"]
|
||||||
|
EnterKeyHint = Literal["enter", "done", "go", "next", "previous", "search", "send"]
|
||||||
|
InputMode = Literal[
|
||||||
|
"none", "text", "tel", "url", "email", "numeric", "decimal", "search", "search"
|
||||||
|
]
|
||||||
|
AriaRole = Literal[
|
||||||
|
"alert",
|
||||||
|
"alertdialog",
|
||||||
|
"application",
|
||||||
|
"article",
|
||||||
|
"banner",
|
||||||
|
"button",
|
||||||
|
"cell",
|
||||||
|
"checkbox",
|
||||||
|
"columnheader",
|
||||||
|
"combobox",
|
||||||
|
"complementary",
|
||||||
|
"contentinfo",
|
||||||
|
"definition",
|
||||||
|
"dialog",
|
||||||
|
"directory",
|
||||||
|
"document",
|
||||||
|
"feed",
|
||||||
|
"figure",
|
||||||
|
"form",
|
||||||
|
"grid",
|
||||||
|
"gridcell",
|
||||||
|
"group",
|
||||||
|
"heading",
|
||||||
|
"img",
|
||||||
|
"link",
|
||||||
|
"list",
|
||||||
|
"listbox",
|
||||||
|
"listitem",
|
||||||
|
"log",
|
||||||
|
"main",
|
||||||
|
"marquee",
|
||||||
|
"math",
|
||||||
|
"menu",
|
||||||
|
"menubar",
|
||||||
|
"menuitem",
|
||||||
|
"menuitemcheckbox",
|
||||||
|
"menuitemradio",
|
||||||
|
"navigation",
|
||||||
|
"none",
|
||||||
|
"note",
|
||||||
|
"option",
|
||||||
|
"presentation",
|
||||||
|
"progressbar",
|
||||||
|
"radio",
|
||||||
|
"radiogroup",
|
||||||
|
"region",
|
||||||
|
"row",
|
||||||
|
"rowgroup",
|
||||||
|
"rowheader",
|
||||||
|
"scrollbar",
|
||||||
|
"search",
|
||||||
|
"searchbox",
|
||||||
|
"separator",
|
||||||
|
"slider",
|
||||||
|
"spinbutton",
|
||||||
|
"status",
|
||||||
|
"switch",
|
||||||
|
"tab",
|
||||||
|
"table",
|
||||||
|
"tablist",
|
||||||
|
"tabpanel",
|
||||||
|
"term",
|
||||||
|
"textbox",
|
||||||
|
"timer",
|
||||||
|
"toolbar",
|
||||||
|
"tooltip",
|
||||||
|
"tree",
|
||||||
|
"treegrid",
|
||||||
|
"treeitem",
|
||||||
|
]
|
||||||
|
|
||||||
class BaseHTML(Element):
|
class BaseHTML(Element):
|
||||||
@overload
|
@overload
|
||||||
@classmethod
|
@classmethod
|
||||||
def create( # type: ignore
|
def create( # type: ignore
|
||||||
cls,
|
cls,
|
||||||
*children,
|
*children,
|
||||||
access_key: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
|
access_key: Optional[Union[Var[str], str]] = None,
|
||||||
auto_capitalize: Optional[
|
auto_capitalize: Optional[
|
||||||
Union[Var[Union[bool, int, str]], bool, int, str]
|
Union[
|
||||||
|
Literal["characters", "none", "off", "on", "sentences", "words"],
|
||||||
|
Var[Literal["characters", "none", "off", "on", "sentences", "words"]],
|
||||||
|
]
|
||||||
] = None,
|
] = None,
|
||||||
content_editable: Optional[
|
content_editable: Optional[
|
||||||
Union[Var[Union[bool, int, str]], bool, int, str]
|
Union[
|
||||||
|
Literal["inherit", "plaintext-only", False, True],
|
||||||
|
Var[Literal["inherit", "plaintext-only", False, True]],
|
||||||
|
]
|
||||||
] = None,
|
] = None,
|
||||||
context_menu: Optional[
|
context_menu: Optional[Union[Var[str], str]] = None,
|
||||||
Union[Var[Union[bool, int, str]], bool, int, str]
|
dir: Optional[Union[Var[str], str]] = None,
|
||||||
] = None,
|
draggable: Optional[Union[Var[bool], bool]] = None,
|
||||||
dir: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
|
|
||||||
draggable: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
|
|
||||||
enter_key_hint: Optional[
|
enter_key_hint: Optional[
|
||||||
Union[Var[Union[bool, int, str]], bool, int, str]
|
Union[
|
||||||
|
Literal["done", "enter", "go", "next", "previous", "search", "send"],
|
||||||
|
Var[
|
||||||
|
Literal["done", "enter", "go", "next", "previous", "search", "send"]
|
||||||
|
],
|
||||||
|
]
|
||||||
] = None,
|
] = None,
|
||||||
hidden: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
|
hidden: Optional[Union[Var[bool], bool]] = None,
|
||||||
input_mode: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
|
input_mode: Optional[
|
||||||
item_prop: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
|
Union[
|
||||||
lang: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
|
Literal[
|
||||||
role: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
|
"decimal",
|
||||||
slot: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
|
"email",
|
||||||
spell_check: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
|
"none",
|
||||||
tab_index: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
|
"numeric",
|
||||||
title: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
|
"search",
|
||||||
|
"tel",
|
||||||
|
"text",
|
||||||
|
"url",
|
||||||
|
],
|
||||||
|
Var[
|
||||||
|
Literal[
|
||||||
|
"decimal",
|
||||||
|
"email",
|
||||||
|
"none",
|
||||||
|
"numeric",
|
||||||
|
"search",
|
||||||
|
"tel",
|
||||||
|
"text",
|
||||||
|
"url",
|
||||||
|
]
|
||||||
|
],
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
|
item_prop: Optional[Union[Var[str], str]] = None,
|
||||||
|
lang: Optional[Union[Var[str], str]] = None,
|
||||||
|
role: Optional[
|
||||||
|
Union[
|
||||||
|
Literal[
|
||||||
|
"alert",
|
||||||
|
"alertdialog",
|
||||||
|
"application",
|
||||||
|
"article",
|
||||||
|
"banner",
|
||||||
|
"button",
|
||||||
|
"cell",
|
||||||
|
"checkbox",
|
||||||
|
"columnheader",
|
||||||
|
"combobox",
|
||||||
|
"complementary",
|
||||||
|
"contentinfo",
|
||||||
|
"definition",
|
||||||
|
"dialog",
|
||||||
|
"directory",
|
||||||
|
"document",
|
||||||
|
"feed",
|
||||||
|
"figure",
|
||||||
|
"form",
|
||||||
|
"grid",
|
||||||
|
"gridcell",
|
||||||
|
"group",
|
||||||
|
"heading",
|
||||||
|
"img",
|
||||||
|
"link",
|
||||||
|
"list",
|
||||||
|
"listbox",
|
||||||
|
"listitem",
|
||||||
|
"log",
|
||||||
|
"main",
|
||||||
|
"marquee",
|
||||||
|
"math",
|
||||||
|
"menu",
|
||||||
|
"menubar",
|
||||||
|
"menuitem",
|
||||||
|
"menuitemcheckbox",
|
||||||
|
"menuitemradio",
|
||||||
|
"navigation",
|
||||||
|
"none",
|
||||||
|
"note",
|
||||||
|
"option",
|
||||||
|
"presentation",
|
||||||
|
"progressbar",
|
||||||
|
"radio",
|
||||||
|
"radiogroup",
|
||||||
|
"region",
|
||||||
|
"row",
|
||||||
|
"rowgroup",
|
||||||
|
"rowheader",
|
||||||
|
"scrollbar",
|
||||||
|
"search",
|
||||||
|
"searchbox",
|
||||||
|
"separator",
|
||||||
|
"slider",
|
||||||
|
"spinbutton",
|
||||||
|
"status",
|
||||||
|
"switch",
|
||||||
|
"tab",
|
||||||
|
"table",
|
||||||
|
"tablist",
|
||||||
|
"tabpanel",
|
||||||
|
"term",
|
||||||
|
"textbox",
|
||||||
|
"timer",
|
||||||
|
"toolbar",
|
||||||
|
"tooltip",
|
||||||
|
"tree",
|
||||||
|
"treegrid",
|
||||||
|
"treeitem",
|
||||||
|
],
|
||||||
|
Var[
|
||||||
|
Literal[
|
||||||
|
"alert",
|
||||||
|
"alertdialog",
|
||||||
|
"application",
|
||||||
|
"article",
|
||||||
|
"banner",
|
||||||
|
"button",
|
||||||
|
"cell",
|
||||||
|
"checkbox",
|
||||||
|
"columnheader",
|
||||||
|
"combobox",
|
||||||
|
"complementary",
|
||||||
|
"contentinfo",
|
||||||
|
"definition",
|
||||||
|
"dialog",
|
||||||
|
"directory",
|
||||||
|
"document",
|
||||||
|
"feed",
|
||||||
|
"figure",
|
||||||
|
"form",
|
||||||
|
"grid",
|
||||||
|
"gridcell",
|
||||||
|
"group",
|
||||||
|
"heading",
|
||||||
|
"img",
|
||||||
|
"link",
|
||||||
|
"list",
|
||||||
|
"listbox",
|
||||||
|
"listitem",
|
||||||
|
"log",
|
||||||
|
"main",
|
||||||
|
"marquee",
|
||||||
|
"math",
|
||||||
|
"menu",
|
||||||
|
"menubar",
|
||||||
|
"menuitem",
|
||||||
|
"menuitemcheckbox",
|
||||||
|
"menuitemradio",
|
||||||
|
"navigation",
|
||||||
|
"none",
|
||||||
|
"note",
|
||||||
|
"option",
|
||||||
|
"presentation",
|
||||||
|
"progressbar",
|
||||||
|
"radio",
|
||||||
|
"radiogroup",
|
||||||
|
"region",
|
||||||
|
"row",
|
||||||
|
"rowgroup",
|
||||||
|
"rowheader",
|
||||||
|
"scrollbar",
|
||||||
|
"search",
|
||||||
|
"searchbox",
|
||||||
|
"separator",
|
||||||
|
"slider",
|
||||||
|
"spinbutton",
|
||||||
|
"status",
|
||||||
|
"switch",
|
||||||
|
"tab",
|
||||||
|
"table",
|
||||||
|
"tablist",
|
||||||
|
"tabpanel",
|
||||||
|
"term",
|
||||||
|
"textbox",
|
||||||
|
"timer",
|
||||||
|
"toolbar",
|
||||||
|
"tooltip",
|
||||||
|
"tree",
|
||||||
|
"treegrid",
|
||||||
|
"treeitem",
|
||||||
|
]
|
||||||
|
],
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
|
slot: Optional[Union[Var[str], str]] = None,
|
||||||
|
spell_check: Optional[Union[Var[bool], bool]] = None,
|
||||||
|
tab_index: Optional[Union[Var[int], int]] = None,
|
||||||
|
title: Optional[Union[Var[str], str]] = None,
|
||||||
style: Optional[Style] = None,
|
style: Optional[Style] = None,
|
||||||
key: Optional[Any] = None,
|
key: Optional[Any] = None,
|
||||||
id: Optional[Any] = None,
|
id: Optional[Any] = None,
|
||||||
class_name: Optional[Any] = None,
|
class_name: Optional[Any] = None,
|
||||||
autofocus: Optional[bool] = None,
|
autofocus: Optional[bool] = None,
|
||||||
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
||||||
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
on_blur: Optional[EventType[()]] = None,
|
||||||
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_click: Optional[EventType[()]] = None,
|
||||||
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
on_context_menu: Optional[EventType[()]] = None,
|
||||||
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
|
on_double_click: Optional[EventType[()]] = None,
|
||||||
on_focus: Optional[EventType[[], BASE_STATE]] = None,
|
on_focus: Optional[EventType[()]] = None,
|
||||||
on_mount: Optional[EventType[[], BASE_STATE]] = None,
|
on_mount: Optional[EventType[()]] = None,
|
||||||
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_down: Optional[EventType[()]] = None,
|
||||||
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_enter: Optional[EventType[()]] = None,
|
||||||
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_leave: Optional[EventType[()]] = None,
|
||||||
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_move: Optional[EventType[()]] = None,
|
||||||
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_out: Optional[EventType[()]] = None,
|
||||||
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_over: Optional[EventType[()]] = None,
|
||||||
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
|
on_mouse_up: Optional[EventType[()]] = None,
|
||||||
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
|
on_scroll: Optional[EventType[()]] = None,
|
||||||
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
|
on_unmount: Optional[EventType[()]] = None,
|
||||||
**props,
|
**props,
|
||||||
) -> "BaseHTML":
|
) -> "BaseHTML":
|
||||||
"""Create the component.
|
"""Create the component.
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from hashlib import md5
|
from hashlib import md5
|
||||||
from typing import Any, Dict, Iterator, Set, Tuple, Union
|
from typing import Any, Dict, Iterator, Literal, Set, Tuple, Union
|
||||||
|
|
||||||
from jinja2 import Environment
|
from jinja2 import Environment
|
||||||
|
|
||||||
@ -41,6 +41,8 @@ HANDLE_SUBMIT_JS_JINJA2 = Environment().from_string(
|
|||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
|
ButtonType = Literal["submit", "reset", "button"]
|
||||||
|
|
||||||
|
|
||||||
class Button(BaseHTML):
|
class Button(BaseHTML):
|
||||||
"""Display the button element."""
|
"""Display the button element."""
|
||||||
@ -48,37 +50,37 @@ class Button(BaseHTML):
|
|||||||
tag = "button"
|
tag = "button"
|
||||||
|
|
||||||
# Automatically focuses the button when the page loads
|
# Automatically focuses the button when the page loads
|
||||||
auto_focus: Var[Union[str, int, bool]]
|
auto_focus: Var[bool]
|
||||||
|
|
||||||
# Disables the button
|
# Disables the button
|
||||||
disabled: Var[bool]
|
disabled: Var[bool]
|
||||||
|
|
||||||
# Associates the button with a form (by id)
|
# Associates the button with a form (by id)
|
||||||
form: Var[Union[str, int, bool]]
|
form: Var[str]
|
||||||
|
|
||||||
# URL to send the form data to (for type="submit" buttons)
|
# URL to send the form data to (for type="submit" buttons)
|
||||||
form_action: Var[Union[str, int, bool]]
|
form_action: Var[str]
|
||||||
|
|
||||||
# How the form data should be encoded when submitting to the server (for type="submit" buttons)
|
# How the form data should be encoded when submitting to the server (for type="submit" buttons)
|
||||||
form_enc_type: Var[Union[str, int, bool]]
|
form_enc_type: Var[str]
|
||||||
|
|
||||||
# HTTP method to use for sending form data (for type="submit" buttons)
|
# HTTP method to use for sending form data (for type="submit" buttons)
|
||||||
form_method: Var[Union[str, int, bool]]
|
form_method: Var[str]
|
||||||
|
|
||||||
# Bypasses form validation when submitting (for type="submit" buttons)
|
# Bypasses form validation when submitting (for type="submit" buttons)
|
||||||
form_no_validate: Var[Union[str, int, bool]]
|
form_no_validate: Var[bool]
|
||||||
|
|
||||||
# Specifies where to display the response after submitting the form (for type="submit" buttons)
|
# Specifies where to display the response after submitting the form (for type="submit" buttons)
|
||||||
form_target: Var[Union[str, int, bool]]
|
form_target: Var[str]
|
||||||
|
|
||||||
# Name of the button, used when sending form data
|
# Name of the button, used when sending form data
|
||||||
name: Var[Union[str, int, bool]]
|
name: Var[str]
|
||||||
|
|
||||||
# Type of the button (submit, reset, or button)
|
# Type of the button (submit, reset, or button)
|
||||||
type: Var[Union[str, int, bool]]
|
type: Var[ButtonType]
|
||||||
|
|
||||||
# Value of the button, used when sending form data
|
# Value of the button, used when sending form data
|
||||||
value: Var[Union[str, int, bool]]
|
value: Var[Union[str, int, float]]
|
||||||
|
|
||||||
|
|
||||||
class Datalist(BaseHTML):
|
class Datalist(BaseHTML):
|
||||||
@ -93,16 +95,16 @@ class Fieldset(Element):
|
|||||||
tag = "fieldset"
|
tag = "fieldset"
|
||||||
|
|
||||||
# Disables all the form control descendants of the fieldset
|
# Disables all the form control descendants of the fieldset
|
||||||
disabled: Var[Union[str, int, bool]]
|
disabled: Var[bool]
|
||||||
|
|
||||||
# Associates the fieldset with a form (by id)
|
# Associates the fieldset with a form (by id)
|
||||||
form: Var[Union[str, int, bool]]
|
form: Var[str]
|
||||||
|
|
||||||
# Name of the fieldset, used for scripting
|
# Name of the fieldset, used for scripting
|
||||||
name: Var[Union[str, int, bool]]
|
name: Var[str]
|
||||||
|
|
||||||
|
|
||||||
def on_submit_event_spec() -> Tuple[Var[Dict[str, Any]]]:
|
def on_submit_event_spec() -> Tuple[Var[dict[str, Any]]]:
|
||||||
"""Event handler spec for the on_submit event.
|
"""Event handler spec for the on_submit event.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@ -111,7 +113,7 @@ def on_submit_event_spec() -> Tuple[Var[Dict[str, Any]]]:
|
|||||||
return (FORM_DATA,)
|
return (FORM_DATA,)
|
||||||
|
|
||||||
|
|
||||||
def on_submit_string_event_spec() -> Tuple[Var[Dict[str, str]]]:
|
def on_submit_string_event_spec() -> Tuple[Var[dict[str, str]]]:
|
||||||
"""Event handler spec for the on_submit event.
|
"""Event handler spec for the on_submit event.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@ -126,34 +128,34 @@ class Form(BaseHTML):
|
|||||||
tag = "form"
|
tag = "form"
|
||||||
|
|
||||||
# MIME types the server accepts for file upload
|
# MIME types the server accepts for file upload
|
||||||
accept: Var[Union[str, int, bool]]
|
accept: Var[str]
|
||||||
|
|
||||||
# Character encodings to be used for form submission
|
# Character encodings to be used for form submission
|
||||||
accept_charset: Var[Union[str, int, bool]]
|
accept_charset: Var[str]
|
||||||
|
|
||||||
# URL where the form's data should be submitted
|
# URL where the form's data should be submitted
|
||||||
action: Var[Union[str, int, bool]]
|
action: Var[str]
|
||||||
|
|
||||||
# Whether the form should have autocomplete enabled
|
# Whether the form should have autocomplete enabled
|
||||||
auto_complete: Var[Union[str, int, bool]]
|
auto_complete: Var[str]
|
||||||
|
|
||||||
# Encoding type for the form data when submitted
|
# Encoding type for the form data when submitted
|
||||||
enc_type: Var[Union[str, int, bool]]
|
enc_type: Var[str]
|
||||||
|
|
||||||
# HTTP method to use for form submission
|
# HTTP method to use for form submission
|
||||||
method: Var[Union[str, int, bool]]
|
method: Var[str]
|
||||||
|
|
||||||
# Name of the form
|
# Name of the form
|
||||||
name: Var[Union[str, int, bool]]
|
name: Var[str]
|
||||||
|
|
||||||
# Indicates that the form should not be validated on submit
|
# Indicates that the form should not be validated on submit
|
||||||
no_validate: Var[Union[str, int, bool]]
|
no_validate: Var[bool]
|
||||||
|
|
||||||
# Where to display the response after submitting the form
|
# Where to display the response after submitting the form
|
||||||
target: Var[Union[str, int, bool]]
|
target: Var[str]
|
||||||
|
|
||||||
# If true, the form will be cleared after submit.
|
# If true, the form will be cleared after submit.
|
||||||
reset_on_submit: Var[bool] = False # type: ignore
|
reset_on_submit: Var[bool] = Var.create(False)
|
||||||
|
|
||||||
# The name used to make this form's submit handler function unique.
|
# The name used to make this form's submit handler function unique.
|
||||||
handle_submit_unique_name: Var[str]
|
handle_submit_unique_name: Var[str]
|
||||||
@ -266,106 +268,126 @@ class Form(BaseHTML):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
HTMLInputTypeAttribute = Literal[
|
||||||
|
"button",
|
||||||
|
"checkbox",
|
||||||
|
"color",
|
||||||
|
"date",
|
||||||
|
"datetime-local",
|
||||||
|
"email",
|
||||||
|
"file",
|
||||||
|
"hidden",
|
||||||
|
"image",
|
||||||
|
"month",
|
||||||
|
"number",
|
||||||
|
"password",
|
||||||
|
"radio",
|
||||||
|
"range",
|
||||||
|
"reset",
|
||||||
|
"search",
|
||||||
|
"submit",
|
||||||
|
"tel",
|
||||||
|
"text",
|
||||||
|
"time",
|
||||||
|
"url",
|
||||||
|
"week",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class Input(BaseHTML):
|
class Input(BaseHTML):
|
||||||
"""Display the input element."""
|
"""Display the input element."""
|
||||||
|
|
||||||
tag = "input"
|
tag = "input"
|
||||||
|
|
||||||
# Accepted types of files when the input is file type
|
# Accepted types of files when the input is file type
|
||||||
accept: Var[Union[str, int, bool]]
|
accept: Var[str]
|
||||||
|
|
||||||
# Alternate text for input type="image"
|
# Alternate text for input type="image"
|
||||||
alt: Var[Union[str, int, bool]]
|
alt: Var[str]
|
||||||
|
|
||||||
# Whether the input should have autocomplete enabled
|
# Whether the input should have autocomplete enabled
|
||||||
auto_complete: Var[Union[str, int, bool]]
|
auto_complete: Var[str]
|
||||||
|
|
||||||
# Automatically focuses the input when the page loads
|
# Automatically focuses the input when the page loads
|
||||||
auto_focus: Var[Union[str, int, bool]]
|
auto_focus: Var[bool]
|
||||||
|
|
||||||
# Captures media from the user (camera or microphone)
|
# Captures media from the user (camera or microphone)
|
||||||
capture: Var[Union[str, int, bool]]
|
capture: Var[Literal[True, False, "user", "environment"]]
|
||||||
|
|
||||||
# Indicates whether the input is checked (for checkboxes and radio buttons)
|
# Indicates whether the input is checked (for checkboxes and radio buttons)
|
||||||
checked: Var[Union[str, int, bool]]
|
checked: Var[bool]
|
||||||
|
|
||||||
# The initial value (for checkboxes and radio buttons)
|
# The initial value (for checkboxes and radio buttons)
|
||||||
default_checked: Var[bool]
|
default_checked: Var[bool]
|
||||||
|
|
||||||
# The initial value for a text field
|
# The initial value for a text field
|
||||||
default_value: Var[str]
|
default_value: Var[Union[str, int, float]]
|
||||||
|
|
||||||
# Name part of the input to submit in 'dir' and 'name' pair when form is submitted
|
|
||||||
dirname: Var[Union[str, int, bool]]
|
|
||||||
|
|
||||||
# Disables the input
|
# Disables the input
|
||||||
disabled: Var[Union[str, int, bool]]
|
disabled: Var[bool]
|
||||||
|
|
||||||
# Associates the input with a form (by id)
|
# Associates the input with a form (by id)
|
||||||
form: Var[Union[str, int, bool]]
|
form: Var[str]
|
||||||
|
|
||||||
# URL to send the form data to (for type="submit" buttons)
|
# URL to send the form data to (for type="submit" buttons)
|
||||||
form_action: Var[Union[str, int, bool]]
|
form_action: Var[str]
|
||||||
|
|
||||||
# How the form data should be encoded when submitting to the server (for type="submit" buttons)
|
# How the form data should be encoded when submitting to the server (for type="submit" buttons)
|
||||||
form_enc_type: Var[Union[str, int, bool]]
|
form_enc_type: Var[str]
|
||||||
|
|
||||||
# HTTP method to use for sending form data (for type="submit" buttons)
|
# HTTP method to use for sending form data (for type="submit" buttons)
|
||||||
form_method: Var[Union[str, int, bool]]
|
form_method: Var[str]
|
||||||
|
|
||||||
# Bypasses form validation when submitting (for type="submit" buttons)
|
# Bypasses form validation when submitting (for type="submit" buttons)
|
||||||
form_no_validate: Var[Union[str, int, bool]]
|
form_no_validate: Var[bool]
|
||||||
|
|
||||||
# Specifies where to display the response after submitting the form (for type="submit" buttons)
|
# Specifies where to display the response after submitting the form (for type="submit" buttons)
|
||||||
form_target: Var[Union[str, int, bool]]
|
form_target: Var[str]
|
||||||
|
|
||||||
# References a datalist for suggested options
|
# References a datalist for suggested options
|
||||||
list: Var[Union[str, int, bool]]
|
list: Var[str]
|
||||||
|
|
||||||
# Specifies the maximum value for the input
|
# Specifies the maximum value for the input
|
||||||
max: Var[Union[str, int, bool]]
|
max: Var[Union[str, int, float]]
|
||||||
|
|
||||||
# Specifies the maximum number of characters allowed in the input
|
# Specifies the maximum number of characters allowed in the input
|
||||||
max_length: Var[Union[str, int, bool]]
|
max_length: Var[Union[int, float]]
|
||||||
|
|
||||||
# Specifies the minimum number of characters required in the input
|
# Specifies the minimum number of characters required in the input
|
||||||
min_length: Var[Union[str, int, bool]]
|
min_length: Var[Union[int, float]]
|
||||||
|
|
||||||
# Specifies the minimum value for the input
|
# Specifies the minimum value for the input
|
||||||
min: Var[Union[str, int, bool]]
|
min: Var[Union[str, int, float]]
|
||||||
|
|
||||||
# Indicates whether multiple values can be entered in an input of the type email or file
|
# Indicates whether multiple values can be entered in an input of the type email or file
|
||||||
multiple: Var[Union[str, int, bool]]
|
multiple: Var[bool]
|
||||||
|
|
||||||
# Name of the input, used when sending form data
|
# Name of the input, used when sending form data
|
||||||
name: Var[Union[str, int, bool]]
|
name: Var[str]
|
||||||
|
|
||||||
# Regex pattern the input's value must match to be valid
|
# Regex pattern the input's value must match to be valid
|
||||||
pattern: Var[Union[str, int, bool]]
|
pattern: Var[str]
|
||||||
|
|
||||||
# Placeholder text in the input
|
# Placeholder text in the input
|
||||||
placeholder: Var[Union[str, int, bool]]
|
placeholder: Var[str]
|
||||||
|
|
||||||
# Indicates whether the input is read-only
|
# Indicates whether the input is read-only
|
||||||
read_only: Var[Union[str, int, bool]]
|
read_only: Var[bool]
|
||||||
|
|
||||||
# Indicates that the input is required
|
# Indicates that the input is required
|
||||||
required: Var[Union[str, int, bool]]
|
required: Var[bool]
|
||||||
|
|
||||||
# Specifies the visible width of a text control
|
# Specifies the visible width of a text control
|
||||||
size: Var[Union[str, int, bool]]
|
size: Var[Union[int, float]]
|
||||||
|
|
||||||
# URL for image inputs
|
# URL for image inputs
|
||||||
src: Var[Union[str, int, bool]]
|
src: Var[str]
|
||||||
|
|
||||||
# Specifies the legal number intervals for an input
|
# Specifies the legal number intervals for an input
|
||||||
step: Var[Union[str, int, bool]]
|
step: Var[Union[str, int, float]]
|
||||||
|
|
||||||
# Specifies the type of input
|
# Specifies the type of input
|
||||||
type: Var[Union[str, int, bool]]
|
type: Var[HTMLInputTypeAttribute]
|
||||||
|
|
||||||
# Name of the image map used with the input
|
|
||||||
use_map: Var[Union[str, int, bool]]
|
|
||||||
|
|
||||||
# Value of the input
|
# Value of the input
|
||||||
value: Var[Union[str, int, float]]
|
value: Var[Union[str, int, float]]
|
||||||
@ -405,7 +427,7 @@ class Input(BaseHTML):
|
|||||||
(value_var := Var.create(value))._var_type
|
(value_var := Var.create(value))._var_type
|
||||||
):
|
):
|
||||||
props["value"] = ternary_operation(
|
props["value"] = ternary_operation(
|
||||||
(value_var != Var.create(None)) # pyright: ignore [reportGeneralTypeIssues]
|
(value_var != Var.create(None)) # pyright: ignore [reportArgumentType]
|
||||||
& (value_var != Var(_js_expr="undefined")),
|
& (value_var != Var(_js_expr="undefined")),
|
||||||
value,
|
value,
|
||||||
Var.create(""),
|
Var.create(""),
|
||||||
@ -419,10 +441,10 @@ class Label(BaseHTML):
|
|||||||
tag = "label"
|
tag = "label"
|
||||||
|
|
||||||
# ID of a form control with which the label is associated
|
# ID of a form control with which the label is associated
|
||||||
html_for: Var[Union[str, int, bool]]
|
html_for: Var[str]
|
||||||
|
|
||||||
# Associates the label with a form (by id)
|
# Associates the label with a form (by id)
|
||||||
form: Var[Union[str, int, bool]]
|
form: Var[str]
|
||||||
|
|
||||||
|
|
||||||
class Legend(BaseHTML):
|
class Legend(BaseHTML):
|
||||||
@ -437,25 +459,25 @@ class Meter(BaseHTML):
|
|||||||
tag = "meter"
|
tag = "meter"
|
||||||
|
|
||||||
# Associates the meter with a form (by id)
|
# Associates the meter with a form (by id)
|
||||||
form: Var[Union[str, int, bool]]
|
form: Var[str]
|
||||||
|
|
||||||
# High limit of range (above this is considered high value)
|
# High limit of range (above this is considered high value)
|
||||||
high: Var[Union[str, int, bool]]
|
high: Var[Union[int, float]]
|
||||||
|
|
||||||
# Low limit of range (below this is considered low value)
|
# Low limit of range (below this is considered low value)
|
||||||
low: Var[Union[str, int, bool]]
|
low: Var[Union[int, float]]
|
||||||
|
|
||||||
# Maximum value of the range
|
# Maximum value of the range
|
||||||
max: Var[Union[str, int, bool]]
|
max: Var[Union[int, float]]
|
||||||
|
|
||||||
# Minimum value of the range
|
# Minimum value of the range
|
||||||
min: Var[Union[str, int, bool]]
|
min: Var[Union[int, float]]
|
||||||
|
|
||||||
# Optimum value in the range
|
# Optimum value in the range
|
||||||
optimum: Var[Union[str, int, bool]]
|
optimum: Var[Union[int, float]]
|
||||||
|
|
||||||
# Current value of the meter
|
# Current value of the meter
|
||||||
value: Var[Union[str, int, bool]]
|
value: Var[Union[int, float]]
|
||||||
|
|
||||||
|
|
||||||
class Optgroup(BaseHTML):
|
class Optgroup(BaseHTML):
|
||||||
@ -464,10 +486,10 @@ class Optgroup(BaseHTML):
|
|||||||
tag = "optgroup"
|
tag = "optgroup"
|
||||||
|
|
||||||
# Disables the optgroup
|
# Disables the optgroup
|
||||||
disabled: Var[Union[str, int, bool]]
|
disabled: Var[bool]
|
||||||
|
|
||||||
# Label for the optgroup
|
# Label for the optgroup
|
||||||
label: Var[Union[str, int, bool]]
|
label: Var[str]
|
||||||
|
|
||||||
|
|
||||||
class Option(BaseHTML):
|
class Option(BaseHTML):
|
||||||
@ -476,16 +498,16 @@ class Option(BaseHTML):
|
|||||||
tag = "option"
|
tag = "option"
|
||||||
|
|
||||||
# Disables the option
|
# Disables the option
|
||||||
disabled: Var[Union[str, int, bool]]
|
disabled: Var[bool]
|
||||||
|
|
||||||
# Label for the option, if the text is not the label
|
# Label for the option, if the text is not the label
|
||||||
label: Var[Union[str, int, bool]]
|
label: Var[str]
|
||||||
|
|
||||||
# Indicates that the option is initially selected
|
# Indicates that the option is initially selected
|
||||||
selected: Var[Union[str, int, bool]]
|
selected: Var[bool]
|
||||||
|
|
||||||
# Value to be sent as form data
|
# Value to be sent as form data
|
||||||
value: Var[Union[str, int, bool]]
|
value: Var[Union[str, int, float]]
|
||||||
|
|
||||||
|
|
||||||
class Output(BaseHTML):
|
class Output(BaseHTML):
|
||||||
@ -494,13 +516,13 @@ class Output(BaseHTML):
|
|||||||
tag = "output"
|
tag = "output"
|
||||||
|
|
||||||
# Associates the output with one or more elements (by their IDs)
|
# Associates the output with one or more elements (by their IDs)
|
||||||
html_for: Var[Union[str, int, bool]]
|
html_for: Var[str]
|
||||||
|
|
||||||
# Associates the output with a form (by id)
|
# Associates the output with a form (by id)
|
||||||
form: Var[Union[str, int, bool]]
|
form: Var[str]
|
||||||
|
|
||||||
# Name of the output element for form submission
|
# Name of the output element for form submission
|
||||||
name: Var[Union[str, int, bool]]
|
name: Var[str]
|
||||||
|
|
||||||
|
|
||||||
class Progress(BaseHTML):
|
class Progress(BaseHTML):
|
||||||
@ -509,13 +531,13 @@ class Progress(BaseHTML):
|
|||||||
tag = "progress"
|
tag = "progress"
|
||||||
|
|
||||||
# Associates the progress element with a form (by id)
|
# Associates the progress element with a form (by id)
|
||||||
form: Var[Union[str, int, bool]]
|
form: Var[str]
|
||||||
|
|
||||||
# Maximum value of the progress indicator
|
# Maximum value of the progress indicator
|
||||||
max: Var[Union[str, int, bool]]
|
max: Var[Union[str, int, float]]
|
||||||
|
|
||||||
# Current value of the progress indicator
|
# Current value of the progress indicator
|
||||||
value: Var[Union[str, int, bool]]
|
value: Var[Union[str, int, float]]
|
||||||
|
|
||||||
|
|
||||||
class Select(BaseHTML):
|
class Select(BaseHTML):
|
||||||
@ -524,28 +546,28 @@ class Select(BaseHTML):
|
|||||||
tag = "select"
|
tag = "select"
|
||||||
|
|
||||||
# Whether the form control should have autocomplete enabled
|
# Whether the form control should have autocomplete enabled
|
||||||
auto_complete: Var[Union[str, int, bool]]
|
auto_complete: Var[str]
|
||||||
|
|
||||||
# Automatically focuses the select when the page loads
|
# Automatically focuses the select when the page loads
|
||||||
auto_focus: Var[Union[str, int, bool]]
|
auto_focus: Var[bool]
|
||||||
|
|
||||||
# Disables the select control
|
# Disables the select control
|
||||||
disabled: Var[Union[str, int, bool]]
|
disabled: Var[bool]
|
||||||
|
|
||||||
# Associates the select with a form (by id)
|
# Associates the select with a form (by id)
|
||||||
form: Var[Union[str, int, bool]]
|
form: Var[str]
|
||||||
|
|
||||||
# Indicates that multiple options can be selected
|
# Indicates that multiple options can be selected
|
||||||
multiple: Var[Union[str, int, bool]]
|
multiple: Var[bool]
|
||||||
|
|
||||||
# Name of the select, used when submitting the form
|
# Name of the select, used when submitting the form
|
||||||
name: Var[Union[str, int, bool]]
|
name: Var[str]
|
||||||
|
|
||||||
# Indicates that the select control must have a selected option
|
# Indicates that the select control must have a selected option
|
||||||
required: Var[Union[str, int, bool]]
|
required: Var[bool]
|
||||||
|
|
||||||
# Number of visible options in a drop-down list
|
# Number of visible options in a drop-down list
|
||||||
size: Var[Union[str, int, bool]]
|
size: Var[int]
|
||||||
|
|
||||||
# Fired when the select value changes
|
# Fired when the select value changes
|
||||||
on_change: EventHandler[input_event]
|
on_change: EventHandler[input_event]
|
||||||
@ -587,58 +609,58 @@ class Textarea(BaseHTML):
|
|||||||
tag = "textarea"
|
tag = "textarea"
|
||||||
|
|
||||||
# Whether the form control should have autocomplete enabled
|
# Whether the form control should have autocomplete enabled
|
||||||
auto_complete: Var[Union[str, int, bool]]
|
auto_complete: Var[str]
|
||||||
|
|
||||||
# Automatically focuses the textarea when the page loads
|
# Automatically focuses the textarea when the page loads
|
||||||
auto_focus: Var[Union[str, int, bool]]
|
auto_focus: Var[bool]
|
||||||
|
|
||||||
# Automatically fit the content height to the text (use min-height with this prop)
|
# Automatically fit the content height to the text (use min-height with this prop)
|
||||||
auto_height: Var[bool]
|
auto_height: Var[bool]
|
||||||
|
|
||||||
# Visible width of the text control, in average character widths
|
# Visible width of the text control, in average character widths
|
||||||
cols: Var[Union[str, int, bool]]
|
cols: Var[int]
|
||||||
|
|
||||||
# The default value of the textarea when initially rendered
|
# The default value of the textarea when initially rendered
|
||||||
default_value: Var[str]
|
default_value: Var[str]
|
||||||
|
|
||||||
# Name part of the textarea to submit in 'dir' and 'name' pair when form is submitted
|
# Name part of the textarea to submit in 'dir' and 'name' pair when form is submitted
|
||||||
dirname: Var[Union[str, int, bool]]
|
dirname: Var[str]
|
||||||
|
|
||||||
# Disables the textarea
|
# Disables the textarea
|
||||||
disabled: Var[Union[str, int, bool]]
|
disabled: Var[bool]
|
||||||
|
|
||||||
# Enter key submits form (shift-enter adds new line)
|
# Enter key submits form (shift-enter adds new line)
|
||||||
enter_key_submit: Var[bool]
|
enter_key_submit: Var[bool]
|
||||||
|
|
||||||
# Associates the textarea with a form (by id)
|
# Associates the textarea with a form (by id)
|
||||||
form: Var[Union[str, int, bool]]
|
form: Var[str]
|
||||||
|
|
||||||
# Maximum number of characters allowed in the textarea
|
# Maximum number of characters allowed in the textarea
|
||||||
max_length: Var[Union[str, int, bool]]
|
max_length: Var[int]
|
||||||
|
|
||||||
# Minimum number of characters required in the textarea
|
# Minimum number of characters required in the textarea
|
||||||
min_length: Var[Union[str, int, bool]]
|
min_length: Var[int]
|
||||||
|
|
||||||
# Name of the textarea, used when submitting the form
|
# Name of the textarea, used when submitting the form
|
||||||
name: Var[Union[str, int, bool]]
|
name: Var[str]
|
||||||
|
|
||||||
# Placeholder text in the textarea
|
# Placeholder text in the textarea
|
||||||
placeholder: Var[Union[str, int, bool]]
|
placeholder: Var[str]
|
||||||
|
|
||||||
# Indicates whether the textarea is read-only
|
# Indicates whether the textarea is read-only
|
||||||
read_only: Var[Union[str, int, bool]]
|
read_only: Var[bool]
|
||||||
|
|
||||||
# Indicates that the textarea is required
|
# Indicates that the textarea is required
|
||||||
required: Var[Union[str, int, bool]]
|
required: Var[bool]
|
||||||
|
|
||||||
# Visible number of lines in the text control
|
# Visible number of lines in the text control
|
||||||
rows: Var[Union[str, int, bool]]
|
rows: Var[int]
|
||||||
|
|
||||||
# The controlled value of the textarea, read only unless used with on_change
|
# The controlled value of the textarea, read only unless used with on_change
|
||||||
value: Var[Union[str, int, bool]]
|
value: Var[str]
|
||||||
|
|
||||||
# How the text in the textarea is to be wrapped when submitting the form
|
# How the text in the textarea is to be wrapped when submitting the form
|
||||||
wrap: Var[Union[str, int, bool]]
|
wrap: Var[str]
|
||||||
|
|
||||||
# Fired when the input value changes
|
# Fired when the input value changes
|
||||||
on_change: EventHandler[input_event]
|
on_change: EventHandler[input_event]
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,11 +1,23 @@
|
|||||||
"""Inline classes."""
|
"""Inline classes."""
|
||||||
|
|
||||||
from typing import Union
|
from typing import Literal, Union
|
||||||
|
|
||||||
from reflex.vars.base import Var
|
from reflex.vars.base import Var
|
||||||
|
|
||||||
from .base import BaseHTML
|
from .base import BaseHTML
|
||||||
|
|
||||||
|
ReferrerPolicy = Literal[
|
||||||
|
"",
|
||||||
|
"no-referrer",
|
||||||
|
"no-referrer-when-downgrade",
|
||||||
|
"origin",
|
||||||
|
"origin-when-cross-origin",
|
||||||
|
"same-origin",
|
||||||
|
"strict-origin",
|
||||||
|
"strict-origin-when-cross-origin",
|
||||||
|
"unsafe-url",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class A(BaseHTML): # Inherits common attributes from BaseMeta
|
class A(BaseHTML): # Inherits common attributes from BaseMeta
|
||||||
"""Display the 'a' element."""
|
"""Display the 'a' element."""
|
||||||
@ -13,31 +25,28 @@ class A(BaseHTML): # Inherits common attributes from BaseMeta
|
|||||||
tag = "a"
|
tag = "a"
|
||||||
|
|
||||||
# Specifies that the target (the file specified in the href attribute) will be downloaded when a user clicks on the hyperlink.
|
# Specifies that the target (the file specified in the href attribute) will be downloaded when a user clicks on the hyperlink.
|
||||||
download: Var[Union[str, int, bool]]
|
download: Var[Union[str, bool]]
|
||||||
|
|
||||||
# Specifies the URL of the page the link goes to
|
# Specifies the URL of the page the link goes to
|
||||||
href: Var[Union[str, int, bool]]
|
href: Var[str]
|
||||||
|
|
||||||
# Specifies the language of the linked document
|
# Specifies the language of the linked document
|
||||||
href_lang: Var[Union[str, int, bool]]
|
href_lang: Var[str]
|
||||||
|
|
||||||
# Specifies what media/device the linked document is optimized for
|
# Specifies what media/device the linked document is optimized for
|
||||||
media: Var[Union[str, int, bool]]
|
media: Var[str]
|
||||||
|
|
||||||
# Specifies which referrer is sent when fetching the resource
|
# Specifies which referrer is sent when fetching the resource
|
||||||
ping: Var[Union[str, int, bool]]
|
ping: Var[str]
|
||||||
|
|
||||||
# Specifies the relationship between the current document and the linked document
|
# Specifies the relationship between the current document and the linked document
|
||||||
referrer_policy: Var[Union[str, int, bool]]
|
referrer_policy: Var[ReferrerPolicy]
|
||||||
|
|
||||||
# Specifies the relationship between the linked document and the current document
|
# Specifies the relationship between the linked document and the current document
|
||||||
rel: Var[Union[str, int, bool]]
|
rel: Var[str]
|
||||||
|
|
||||||
# Specifies the shape of the area
|
|
||||||
shape: Var[Union[str, int, bool]]
|
|
||||||
|
|
||||||
# Specifies where to open the linked document
|
# Specifies where to open the linked document
|
||||||
target: Var[Union[str, int, bool]]
|
target: Var[Union[str, Literal["_self", "_blank", "_parent", "_top"]]]
|
||||||
|
|
||||||
|
|
||||||
class Abbr(BaseHTML):
|
class Abbr(BaseHTML):
|
||||||
@ -88,7 +97,7 @@ class Data(BaseHTML):
|
|||||||
tag = "data"
|
tag = "data"
|
||||||
|
|
||||||
# Specifies the machine-readable translation of the data element.
|
# Specifies the machine-readable translation of the data element.
|
||||||
value: Var[Union[str, int, bool]]
|
value: Var[Union[str, int, float]]
|
||||||
|
|
||||||
|
|
||||||
class Dfn(BaseHTML):
|
class Dfn(BaseHTML):
|
||||||
@ -127,7 +136,7 @@ class Q(BaseHTML):
|
|||||||
tag = "q"
|
tag = "q"
|
||||||
|
|
||||||
# Specifies the source URL of the quote.
|
# Specifies the source URL of the quote.
|
||||||
cite: Var[Union[str, int, bool]]
|
cite: Var[str]
|
||||||
|
|
||||||
|
|
||||||
class Rp(BaseHTML):
|
class Rp(BaseHTML):
|
||||||
@ -196,7 +205,7 @@ class Time(BaseHTML):
|
|||||||
tag = "time"
|
tag = "time"
|
||||||
|
|
||||||
# Specifies the date and/or time of the element.
|
# Specifies the date and/or time of the element.
|
||||||
date_time: Var[Union[str, int, bool]]
|
date_time: Var[str]
|
||||||
|
|
||||||
|
|
||||||
class U(BaseHTML):
|
class U(BaseHTML):
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,8 +1,9 @@
|
|||||||
"""Media classes."""
|
"""Media classes."""
|
||||||
|
|
||||||
from typing import Any, Union
|
from typing import Any, Literal, Union
|
||||||
|
|
||||||
from reflex import Component, ComponentNamespace
|
from reflex import Component, ComponentNamespace
|
||||||
|
from reflex.components.el.elements.inline import ReferrerPolicy
|
||||||
from reflex.constants.colors import Color
|
from reflex.constants.colors import Color
|
||||||
from reflex.vars.base import Var
|
from reflex.vars.base import Var
|
||||||
|
|
||||||
@ -15,37 +16,37 @@ class Area(BaseHTML):
|
|||||||
tag = "area"
|
tag = "area"
|
||||||
|
|
||||||
# Alternate text for the area, used for accessibility
|
# Alternate text for the area, used for accessibility
|
||||||
alt: Var[Union[str, int, bool]]
|
alt: Var[str]
|
||||||
|
|
||||||
# Coordinates to define the shape of the area
|
# Coordinates to define the shape of the area
|
||||||
coords: Var[Union[str, int, bool]]
|
coords: Var[str]
|
||||||
|
|
||||||
# Specifies that the target will be downloaded when clicked
|
# Specifies that the target will be downloaded when clicked
|
||||||
download: Var[Union[str, int, bool]]
|
download: Var[Union[str, bool]]
|
||||||
|
|
||||||
# Hyperlink reference for the area
|
# Hyperlink reference for the area
|
||||||
href: Var[Union[str, int, bool]]
|
href: Var[str]
|
||||||
|
|
||||||
# Language of the linked resource
|
# Language of the linked resource
|
||||||
href_lang: Var[Union[str, int, bool]]
|
href_lang: Var[str]
|
||||||
|
|
||||||
# Specifies what media/device the linked resource is optimized for
|
# Specifies what media/device the linked resource is optimized for
|
||||||
media: Var[Union[str, int, bool]]
|
media: Var[str]
|
||||||
|
|
||||||
# A list of URLs to be notified if the user follows the hyperlink
|
|
||||||
ping: Var[Union[str, int, bool]]
|
|
||||||
|
|
||||||
# Specifies which referrer information to send with the link
|
# Specifies which referrer information to send with the link
|
||||||
referrer_policy: Var[Union[str, int, bool]]
|
referrer_policy: Var[ReferrerPolicy]
|
||||||
|
|
||||||
# Specifies the relationship of the target object to the link object
|
# Specifies the relationship of the target object to the link object
|
||||||
rel: Var[Union[str, int, bool]]
|
rel: Var[str]
|
||||||
|
|
||||||
# Defines the shape of the area (rectangle, circle, polygon)
|
# Defines the shape of the area (rectangle, circle, polygon)
|
||||||
shape: Var[Union[str, int, bool]]
|
shape: Var[str]
|
||||||
|
|
||||||
# Specifies where to open the linked document
|
# Specifies where to open the linked document
|
||||||
target: Var[Union[str, int, bool]]
|
target: Var[str]
|
||||||
|
|
||||||
|
|
||||||
|
CrossOrigin = Literal["anonymous", "use-credentials", ""]
|
||||||
|
|
||||||
|
|
||||||
class Audio(BaseHTML):
|
class Audio(BaseHTML):
|
||||||
@ -54,28 +55,29 @@ class Audio(BaseHTML):
|
|||||||
tag = "audio"
|
tag = "audio"
|
||||||
|
|
||||||
# Specifies that the audio will start playing as soon as it is ready
|
# Specifies that the audio will start playing as soon as it is ready
|
||||||
auto_play: Var[Union[str, int, bool]]
|
auto_play: Var[bool]
|
||||||
|
|
||||||
# Represents the time range of the buffered media
|
|
||||||
buffered: Var[Union[str, int, bool]]
|
|
||||||
|
|
||||||
# Displays the standard audio controls
|
# Displays the standard audio controls
|
||||||
controls: Var[Union[str, int, bool]]
|
controls: Var[bool]
|
||||||
|
|
||||||
# Configures the CORS requests for the element
|
# Configures the CORS requests for the element
|
||||||
cross_origin: Var[Union[str, int, bool]]
|
cross_origin: Var[CrossOrigin]
|
||||||
|
|
||||||
# Specifies that the audio will loop
|
# Specifies that the audio will loop
|
||||||
loop: Var[Union[str, int, bool]]
|
loop: Var[bool]
|
||||||
|
|
||||||
# Indicates whether the audio is muted by default
|
# Indicates whether the audio is muted by default
|
||||||
muted: Var[Union[str, int, bool]]
|
muted: Var[bool]
|
||||||
|
|
||||||
# Specifies how the audio file should be preloaded
|
# Specifies how the audio file should be preloaded
|
||||||
preload: Var[Union[str, int, bool]]
|
preload: Var[str]
|
||||||
|
|
||||||
# URL of the audio to play
|
# URL of the audio to play
|
||||||
src: Var[Union[str, int, bool]]
|
src: Var[str]
|
||||||
|
|
||||||
|
|
||||||
|
ImageDecoding = Literal["async", "auto", "sync"]
|
||||||
|
ImageLoading = Literal["eager", "lazy"]
|
||||||
|
|
||||||
|
|
||||||
class Img(BaseHTML):
|
class Img(BaseHTML):
|
||||||
@ -83,41 +85,32 @@ class Img(BaseHTML):
|
|||||||
|
|
||||||
tag = "img"
|
tag = "img"
|
||||||
|
|
||||||
# Image alignment with respect to its surrounding elements
|
|
||||||
align: Var[Union[str, int, bool]]
|
|
||||||
|
|
||||||
# Alternative text for the image
|
# Alternative text for the image
|
||||||
alt: Var[Union[str, int, bool]]
|
alt: Var[str]
|
||||||
|
|
||||||
# Configures the CORS requests for the image
|
# Configures the CORS requests for the image
|
||||||
cross_origin: Var[Union[str, int, bool]]
|
cross_origin: Var[CrossOrigin]
|
||||||
|
|
||||||
# How the image should be decoded
|
# How the image should be decoded
|
||||||
decoding: Var[Union[str, int, bool]]
|
decoding: Var[ImageDecoding]
|
||||||
|
|
||||||
# Specifies an intrinsic size for the image
|
|
||||||
intrinsicsize: Var[Union[str, int, bool]]
|
|
||||||
|
|
||||||
# Whether the image is a server-side image map
|
|
||||||
ismap: Var[Union[str, int, bool]]
|
|
||||||
|
|
||||||
# Specifies the loading behavior of the image
|
# Specifies the loading behavior of the image
|
||||||
loading: Var[Union[str, int, bool]]
|
loading: Var[ImageLoading]
|
||||||
|
|
||||||
# Referrer policy for the image
|
# Referrer policy for the image
|
||||||
referrer_policy: Var[Union[str, int, bool]]
|
referrer_policy: Var[ReferrerPolicy]
|
||||||
|
|
||||||
# Sizes of the image for different layouts
|
# Sizes of the image for different layouts
|
||||||
sizes: Var[Union[str, int, bool]]
|
sizes: Var[str]
|
||||||
|
|
||||||
# URL of the image to display
|
# URL of the image to display
|
||||||
src: Var[Any]
|
src: Var[Any]
|
||||||
|
|
||||||
# A set of source sizes and URLs for responsive images
|
# A set of source sizes and URLs for responsive images
|
||||||
src_set: Var[Union[str, int, bool]]
|
src_set: Var[str]
|
||||||
|
|
||||||
# The name of the map to use with the image
|
# The name of the map to use with the image
|
||||||
use_map: Var[Union[str, int, bool]]
|
use_map: Var[str]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create(cls, *children, **props) -> Component:
|
def create(cls, *children, **props) -> Component:
|
||||||
@ -143,7 +136,7 @@ class Map(BaseHTML):
|
|||||||
tag = "map"
|
tag = "map"
|
||||||
|
|
||||||
# Name of the map, referenced by the 'usemap' attribute in 'img' and 'object' elements
|
# Name of the map, referenced by the 'usemap' attribute in 'img' and 'object' elements
|
||||||
name: Var[Union[str, int, bool]]
|
name: Var[str]
|
||||||
|
|
||||||
|
|
||||||
class Track(BaseHTML):
|
class Track(BaseHTML):
|
||||||
@ -152,19 +145,19 @@ class Track(BaseHTML):
|
|||||||
tag = "track"
|
tag = "track"
|
||||||
|
|
||||||
# Indicates that the track should be enabled unless the user's preferences indicate otherwise
|
# Indicates that the track should be enabled unless the user's preferences indicate otherwise
|
||||||
default: Var[Union[str, int, bool]]
|
default: Var[bool]
|
||||||
|
|
||||||
# Specifies the kind of text track
|
# Specifies the kind of text track
|
||||||
kind: Var[Union[str, int, bool]]
|
kind: Var[str]
|
||||||
|
|
||||||
# Title of the text track, used by the browser when listing available text tracks
|
# Title of the text track, used by the browser when listing available text tracks
|
||||||
label: Var[Union[str, int, bool]]
|
label: Var[str]
|
||||||
|
|
||||||
# URL of the track file
|
# URL of the track file
|
||||||
src: Var[Union[str, int, bool]]
|
src: Var[str]
|
||||||
|
|
||||||
# Language of the track text data
|
# Language of the track text data
|
||||||
src_lang: Var[Union[str, int, bool]]
|
src_lang: Var[str]
|
||||||
|
|
||||||
|
|
||||||
class Video(BaseHTML):
|
class Video(BaseHTML):
|
||||||
@ -173,34 +166,31 @@ class Video(BaseHTML):
|
|||||||
tag = "video"
|
tag = "video"
|
||||||
|
|
||||||
# Specifies that the video will start playing as soon as it is ready
|
# Specifies that the video will start playing as soon as it is ready
|
||||||
auto_play: Var[Union[str, int, bool]]
|
auto_play: Var[bool]
|
||||||
|
|
||||||
# Represents the time range of the buffered media
|
|
||||||
buffered: Var[Union[str, int, bool]]
|
|
||||||
|
|
||||||
# Displays the standard video controls
|
# Displays the standard video controls
|
||||||
controls: Var[Union[str, int, bool]]
|
controls: Var[bool]
|
||||||
|
|
||||||
# Configures the CORS requests for the video
|
# Configures the CORS requests for the video
|
||||||
cross_origin: Var[Union[str, int, bool]]
|
cross_origin: Var[CrossOrigin]
|
||||||
|
|
||||||
# Specifies that the video will loop
|
# Specifies that the video will loop
|
||||||
loop: Var[Union[str, int, bool]]
|
loop: Var[bool]
|
||||||
|
|
||||||
# Indicates whether the video is muted by default
|
# Indicates whether the video is muted by default
|
||||||
muted: Var[Union[str, int, bool]]
|
muted: Var[bool]
|
||||||
|
|
||||||
# Indicates that the video should play 'inline', inside its element's playback area
|
# Indicates that the video should play 'inline', inside its element's playback area
|
||||||
plays_inline: Var[Union[str, int, bool]]
|
plays_inline: Var[bool]
|
||||||
|
|
||||||
# URL of an image to show while the video is downloading, or until the user hits the play button
|
# URL of an image to show while the video is downloading, or until the user hits the play button
|
||||||
poster: Var[Union[str, int, bool]]
|
poster: Var[str]
|
||||||
|
|
||||||
# Specifies how the video file should be preloaded
|
# Specifies how the video file should be preloaded
|
||||||
preload: Var[Union[str, int, bool]]
|
preload: Var[str]
|
||||||
|
|
||||||
# URL of the video to play
|
# URL of the video to play
|
||||||
src: Var[Union[str, int, bool]]
|
src: Var[str]
|
||||||
|
|
||||||
|
|
||||||
class Embed(BaseHTML):
|
class Embed(BaseHTML):
|
||||||
@ -209,10 +199,10 @@ class Embed(BaseHTML):
|
|||||||
tag = "embed"
|
tag = "embed"
|
||||||
|
|
||||||
# URL of the embedded content
|
# URL of the embedded content
|
||||||
src: Var[Union[str, int, bool]]
|
src: Var[str]
|
||||||
|
|
||||||
# Media type of the embedded content
|
# Media type of the embedded content
|
||||||
type: Var[Union[str, int, bool]]
|
type: Var[str]
|
||||||
|
|
||||||
|
|
||||||
class Iframe(BaseHTML):
|
class Iframe(BaseHTML):
|
||||||
@ -220,32 +210,26 @@ class Iframe(BaseHTML):
|
|||||||
|
|
||||||
tag = "iframe"
|
tag = "iframe"
|
||||||
|
|
||||||
# Alignment of the iframe within the page or surrounding elements
|
|
||||||
align: Var[Union[str, int, bool]]
|
|
||||||
|
|
||||||
# Permissions policy for the iframe
|
# Permissions policy for the iframe
|
||||||
allow: Var[Union[str, int, bool]]
|
allow: Var[str]
|
||||||
|
|
||||||
# Content Security Policy to apply to the iframe's content
|
|
||||||
csp: Var[Union[str, int, bool]]
|
|
||||||
|
|
||||||
# Specifies the loading behavior of the iframe
|
# Specifies the loading behavior of the iframe
|
||||||
loading: Var[Union[str, int, bool]]
|
loading: Var[Literal["eager", "lazy"]]
|
||||||
|
|
||||||
# Name of the iframe, used as a target for hyperlinks and forms
|
# Name of the iframe, used as a target for hyperlinks and forms
|
||||||
name: Var[Union[str, int, bool]]
|
name: Var[str]
|
||||||
|
|
||||||
# Referrer policy for the iframe
|
# Referrer policy for the iframe
|
||||||
referrer_policy: Var[Union[str, int, bool]]
|
referrer_policy: Var[ReferrerPolicy]
|
||||||
|
|
||||||
# Security restrictions for the content in the iframe
|
# Security restrictions for the content in the iframe
|
||||||
sandbox: Var[Union[str, int, bool]]
|
sandbox: Var[str]
|
||||||
|
|
||||||
# URL of the document to display in the iframe
|
# URL of the document to display in the iframe
|
||||||
src: Var[Union[str, int, bool]]
|
src: Var[str]
|
||||||
|
|
||||||
# HTML content to embed directly within the iframe
|
# HTML content to embed directly within the iframe
|
||||||
src_doc: Var[Union[str, int, bool]]
|
src_doc: Var[str]
|
||||||
|
|
||||||
|
|
||||||
class Object(BaseHTML):
|
class Object(BaseHTML):
|
||||||
@ -254,19 +238,19 @@ class Object(BaseHTML):
|
|||||||
tag = "object"
|
tag = "object"
|
||||||
|
|
||||||
# URL of the data to be used by the object
|
# URL of the data to be used by the object
|
||||||
data: Var[Union[str, int, bool]]
|
data: Var[str]
|
||||||
|
|
||||||
# Associates the object with a form element
|
# Associates the object with a form element
|
||||||
form: Var[Union[str, int, bool]]
|
form: Var[str]
|
||||||
|
|
||||||
# Name of the object, used for scripting or as a target for forms and links
|
# Name of the object, used for scripting or as a target for forms and links
|
||||||
name: Var[Union[str, int, bool]]
|
name: Var[str]
|
||||||
|
|
||||||
# Media type of the data specified in the data attribute
|
# Media type of the data specified in the data attribute
|
||||||
type: Var[Union[str, int, bool]]
|
type: Var[str]
|
||||||
|
|
||||||
# Name of an image map to use with the object
|
# Name of an image map to use with the object
|
||||||
use_map: Var[Union[str, int, bool]]
|
use_map: Var[str]
|
||||||
|
|
||||||
|
|
||||||
class Picture(BaseHTML):
|
class Picture(BaseHTML):
|
||||||
@ -287,19 +271,19 @@ class Source(BaseHTML):
|
|||||||
tag = "source"
|
tag = "source"
|
||||||
|
|
||||||
# Media query indicating what device the linked resource is optimized for
|
# Media query indicating what device the linked resource is optimized for
|
||||||
media: Var[Union[str, int, bool]]
|
media: Var[str]
|
||||||
|
|
||||||
# Sizes of the source for different layouts
|
# Sizes of the source for different layouts
|
||||||
sizes: Var[Union[str, int, bool]]
|
sizes: Var[str]
|
||||||
|
|
||||||
# URL of the media file or an image for the element to use
|
# URL of the media file or an image for the element to use
|
||||||
src: Var[Union[str, int, bool]]
|
src: Var[str]
|
||||||
|
|
||||||
# A set of source sizes and URLs for responsive images
|
# A set of source sizes and URLs for responsive images
|
||||||
src_set: Var[Union[str, int, bool]]
|
src_set: Var[str]
|
||||||
|
|
||||||
# Media type of the source
|
# Media type of the source
|
||||||
type: Var[Union[str, int, bool]]
|
type: Var[str]
|
||||||
|
|
||||||
|
|
||||||
class Svg(BaseHTML):
|
class Svg(BaseHTML):
|
||||||
@ -431,16 +415,16 @@ class LinearGradient(BaseHTML):
|
|||||||
spread_method: Var[Union[str, bool]]
|
spread_method: Var[Union[str, bool]]
|
||||||
|
|
||||||
# X coordinate of the starting point of the gradient.
|
# X coordinate of the starting point of the gradient.
|
||||||
x1: Var[Union[str, int, bool]]
|
x1: Var[Union[str, int, float]]
|
||||||
|
|
||||||
# X coordinate of the ending point of the gradient.
|
# X coordinate of the ending point of the gradient.
|
||||||
x2: Var[Union[str, int, bool]]
|
x2: Var[Union[str, int, float]]
|
||||||
|
|
||||||
# Y coordinate of the starting point of the gradient.
|
# Y coordinate of the starting point of the gradient.
|
||||||
y1: Var[Union[str, int, bool]]
|
y1: Var[Union[str, int, float]]
|
||||||
|
|
||||||
# Y coordinate of the ending point of the gradient.
|
# Y coordinate of the ending point of the gradient.
|
||||||
y2: Var[Union[str, int, bool]]
|
y2: Var[Union[str, int, float]]
|
||||||
|
|
||||||
|
|
||||||
class RadialGradient(BaseHTML):
|
class RadialGradient(BaseHTML):
|
||||||
@ -449,19 +433,19 @@ class RadialGradient(BaseHTML):
|
|||||||
tag = "radialGradient"
|
tag = "radialGradient"
|
||||||
|
|
||||||
# The x coordinate of the end circle of the radial gradient.
|
# The x coordinate of the end circle of the radial gradient.
|
||||||
cx: Var[Union[str, int, bool]]
|
cx: Var[Union[str, int, float]]
|
||||||
|
|
||||||
# The y coordinate of the end circle of the radial gradient.
|
# The y coordinate of the end circle of the radial gradient.
|
||||||
cy: Var[Union[str, int, bool]]
|
cy: Var[Union[str, int, float]]
|
||||||
|
|
||||||
# The radius of the start circle of the radial gradient.
|
# The radius of the start circle of the radial gradient.
|
||||||
fr: Var[Union[str, int, bool]]
|
fr: Var[Union[str, int, float]]
|
||||||
|
|
||||||
# The x coordinate of the start circle of the radial gradient.
|
# The x coordinate of the start circle of the radial gradient.
|
||||||
fx: Var[Union[str, int, bool]]
|
fx: Var[Union[str, int, float]]
|
||||||
|
|
||||||
# The y coordinate of the start circle of the radial gradient.
|
# The y coordinate of the start circle of the radial gradient.
|
||||||
fy: Var[Union[str, int, bool]]
|
fy: Var[Union[str, int, float]]
|
||||||
|
|
||||||
# Units for the gradient.
|
# Units for the gradient.
|
||||||
gradient_units: Var[Union[str, bool]]
|
gradient_units: Var[Union[str, bool]]
|
||||||
@ -470,7 +454,7 @@ class RadialGradient(BaseHTML):
|
|||||||
gradient_transform: Var[Union[str, bool]]
|
gradient_transform: Var[Union[str, bool]]
|
||||||
|
|
||||||
# The radius of the end circle of the radial gradient.
|
# The radius of the end circle of the radial gradient.
|
||||||
r: Var[Union[str, int, bool]]
|
r: Var[Union[str, int, float]]
|
||||||
|
|
||||||
# Method used to spread the gradient.
|
# Method used to spread the gradient.
|
||||||
spread_method: Var[Union[str, bool]]
|
spread_method: Var[Union[str, bool]]
|
||||||
@ -497,7 +481,7 @@ class Path(BaseHTML):
|
|||||||
tag = "path"
|
tag = "path"
|
||||||
|
|
||||||
# Defines the shape of the path.
|
# Defines the shape of the path.
|
||||||
d: Var[Union[str, int, bool]]
|
d: Var[Union[str, int, float]]
|
||||||
|
|
||||||
|
|
||||||
class SVG(ComponentNamespace):
|
class SVG(ComponentNamespace):
|
||||||
|
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user