pythonnative 0.10.0__tar.gz → 0.11.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pythonnative-0.10.0/src/pythonnative.egg-info → pythonnative-0.11.0}/PKG-INFO +2 -1
- {pythonnative-0.10.0 → pythonnative-0.11.0}/README.md +1 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/pyproject.toml +1 -1
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/__init__.py +1 -1
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/cli/pn.py +85 -11
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/components.py +7 -0
- pythonnative-0.11.0/src/pythonnative/layout.py +949 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/native_views/__init__.py +39 -3
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/native_views/android.py +175 -220
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/native_views/base.py +87 -42
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/native_views/ios.py +245 -180
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/page.py +457 -31
- pythonnative-0.11.0/src/pythonnative/platform_metrics.py +139 -0
- pythonnative-0.11.0/src/pythonnative/reconciler.py +807 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/ios_template/ios_template/ViewController.swift +24 -3
- {pythonnative-0.10.0 → pythonnative-0.11.0/src/pythonnative.egg-info}/PKG-INFO +2 -1
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative.egg-info/SOURCES.txt +4 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/tests/test_cli.py +42 -0
- pythonnative-0.11.0/tests/test_layout.py +773 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/tests/test_native_views.py +65 -27
- pythonnative-0.11.0/tests/test_page.py +189 -0
- pythonnative-0.11.0/tests/test_platform_metrics.py +148 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/tests/test_reconciler.py +285 -1
- pythonnative-0.10.0/src/pythonnative/reconciler.py +0 -384
- pythonnative-0.10.0/tests/test_page.py +0 -68
- {pythonnative-0.10.0 → pythonnative-0.11.0}/LICENSE +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/setup.cfg +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/_ios_log.py +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/cli/__init__.py +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/element.py +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/hooks.py +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/hot_reload.py +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/native_modules/__init__.py +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/native_modules/camera.py +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/native_modules/file_system.py +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/native_modules/location.py +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/native_modules/notifications.py +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/navigation.py +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/style.py +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/android_template/app/build.gradle +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/android_template/app/proguard-rules.pro +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/android_template/app/src/androidTest/java/com/pythonnative/android_template/ExampleInstrumentedTest.kt +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/android_template/app/src/main/AndroidManifest.xml +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/MainActivity.kt +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/Navigator.kt +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/PageFragment.kt +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/android_template/app/src/main/res/drawable/ic_launcher_background.xml +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/android_template/app/src/main/res/drawable-v24/ic_launcher_foreground.xml +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/android_template/app/src/main/res/layout/activity_main.xml +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-hdpi/ic_launcher.webp +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-mdpi/ic_launcher.webp +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-xhdpi/ic_launcher.webp +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/android_template/app/src/main/res/navigation/nav_graph.xml +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/android_template/app/src/main/res/values/colors.xml +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/android_template/app/src/main/res/values/strings.xml +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/android_template/app/src/main/res/values/themes.xml +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/android_template/app/src/main/res/values-night/themes.xml +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/android_template/app/src/main/res/xml/backup_rules.xml +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/android_template/app/src/main/res/xml/data_extraction_rules.xml +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/android_template/app/src/test/java/com/pythonnative/android_template/ExampleUnitTest.kt +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/android_template/build.gradle +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/android_template/gradle/wrapper/gradle-wrapper.jar +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/android_template/gradle/wrapper/gradle-wrapper.properties +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/android_template/gradle.properties +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/android_template/gradlew +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/android_template/gradlew.bat +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/android_template/settings.gradle +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/ios_template/ios_template/AppDelegate.swift +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/ios_template/ios_template/Assets.xcassets/AccentColor.colorset/Contents.json +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/ios_template/ios_template/Assets.xcassets/AppIcon.appiconset/Contents.json +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/ios_template/ios_template/Assets.xcassets/Contents.json +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/ios_template/ios_template/Base.lproj/LaunchScreen.storyboard +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/ios_template/ios_template/Base.lproj/Main.storyboard +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/ios_template/ios_template/Info.plist +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/ios_template/ios_template/SceneDelegate.swift +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/ios_template/ios_template.xcodeproj/project.pbxproj +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/ios_template/ios_template.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/ios_template/ios_templateTests/ios_templateTests.swift +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/ios_template/ios_templateUITests/ios_templateUITests.swift +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/templates/ios_template/ios_templateUITests/ios_templateUITestsLaunchTests.swift +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative/utils.py +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative.egg-info/dependency_links.txt +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative.egg-info/entry_points.txt +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative.egg-info/requires.txt +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/src/pythonnative.egg-info/top_level.txt +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/tests/test_components.py +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/tests/test_element.py +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/tests/test_hooks.py +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/tests/test_hot_reload.py +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/tests/test_ios_log.py +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/tests/test_navigation.py +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/tests/test_smoke.py +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/tests/test_style.py +0 -0
- {pythonnative-0.10.0 → pythonnative-0.11.0}/tests/test_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pythonnative
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.11.0
|
|
4
4
|
Summary: Cross-platform native UI toolkit for Android and iOS
|
|
5
5
|
Author: Owen Carey
|
|
6
6
|
License: MIT License
|
|
@@ -97,6 +97,7 @@ PythonNative is a cross-platform toolkit for building native Android and iOS app
|
|
|
97
97
|
- **Declarative UI:** Describe *what* your UI should look like with element functions (`Text`, `Button`, `Column`, `Row`, etc.). PythonNative creates and updates native views automatically.
|
|
98
98
|
- **Hooks and function components:** Manage state with `use_state`, side effects with `use_effect`, and navigation with `use_navigation`, all through one consistent pattern.
|
|
99
99
|
- **`style` prop:** Pass all visual and layout properties through a single `style` dict, composable via `StyleSheet`.
|
|
100
|
+
- **Cross-platform flexbox engine:** A pure-Python, Yoga-style layout engine computes frames once and applies them to native views, so `flex`, `padding`, `aspect_ratio`, and `position: "absolute"` produce the same geometry on Android and iOS.
|
|
100
101
|
- **Virtual view tree + reconciler:** Element trees are diffed and patched with minimal native mutations, similar to React's reconciliation.
|
|
101
102
|
- **Direct native bindings:** Python calls platform APIs directly through Chaquopy and rubicon-objc, with no JavaScript bridge.
|
|
102
103
|
- **CLI scaffolding:** `pn init` creates a ready-to-run project; `pn run android` and `pn run ios` build and launch your app.
|
|
@@ -33,6 +33,7 @@ PythonNative is a cross-platform toolkit for building native Android and iOS app
|
|
|
33
33
|
- **Declarative UI:** Describe *what* your UI should look like with element functions (`Text`, `Button`, `Column`, `Row`, etc.). PythonNative creates and updates native views automatically.
|
|
34
34
|
- **Hooks and function components:** Manage state with `use_state`, side effects with `use_effect`, and navigation with `use_navigation`, all through one consistent pattern.
|
|
35
35
|
- **`style` prop:** Pass all visual and layout properties through a single `style` dict, composable via `StyleSheet`.
|
|
36
|
+
- **Cross-platform flexbox engine:** A pure-Python, Yoga-style layout engine computes frames once and applies them to native views, so `flex`, `padding`, `aspect_ratio`, and `position: "absolute"` produce the same geometry on Android and iOS.
|
|
36
37
|
- **Virtual view tree + reconciler:** Element trees are diffed and patched with minimal native mutations, similar to React's reconciliation.
|
|
37
38
|
- **Direct native bindings:** Python calls platform APIs directly through Chaquopy and rubicon-objc, with no JavaScript bridge.
|
|
38
39
|
- **CLI scaffolding:** `pn init` creates a ready-to-run project; `pn run android` and `pn run ios` build and launch your app.
|
|
@@ -354,6 +354,76 @@ def _start_android_log_stream() -> Optional[subprocess.Popen]:
|
|
|
354
354
|
return proc
|
|
355
355
|
|
|
356
356
|
|
|
357
|
+
def _booted_ios_udid() -> Optional[str]:
|
|
358
|
+
"""Return a booted iOS Simulator's UDID, or `None` if none is booted.
|
|
359
|
+
|
|
360
|
+
Used by `_start_ios_log_stream` so the hot-reload path doesn't
|
|
361
|
+
need to thread the UDID through from the install step.
|
|
362
|
+
"""
|
|
363
|
+
try:
|
|
364
|
+
result = subprocess.run(
|
|
365
|
+
["xcrun", "simctl", "list", "devices", "booted", "--json"],
|
|
366
|
+
check=False,
|
|
367
|
+
capture_output=True,
|
|
368
|
+
text=True,
|
|
369
|
+
)
|
|
370
|
+
except FileNotFoundError:
|
|
371
|
+
return None
|
|
372
|
+
try:
|
|
373
|
+
data = json.loads(result.stdout or "{}")
|
|
374
|
+
except json.JSONDecodeError:
|
|
375
|
+
return None
|
|
376
|
+
for _runtime, devices in (data.get("devices") or {}).items():
|
|
377
|
+
for device in devices or []:
|
|
378
|
+
if device.get("state") == "Booted":
|
|
379
|
+
udid = device.get("udid")
|
|
380
|
+
if udid:
|
|
381
|
+
return str(udid)
|
|
382
|
+
return None
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
def _start_ios_log_stream() -> Optional[subprocess.Popen]:
|
|
386
|
+
"""Re-launch the iOS app with a console PTY so its stdio streams here.
|
|
387
|
+
|
|
388
|
+
Mirrors the approach `pn run ios` (without `--hot-reload`) takes:
|
|
389
|
+
``xcrun simctl launch --console-pty`` attaches the parent
|
|
390
|
+
terminal to the app's stderr, which is where Python ``print()``
|
|
391
|
+
output is routed (see `pythonnative._ios_log`) and where Swift
|
|
392
|
+
``NSLog`` calls land. Unlike ``log stream``, this *only*
|
|
393
|
+
surfaces what the app writes itself — none of UIKit's verbose
|
|
394
|
+
``os_log`` chatter.
|
|
395
|
+
|
|
396
|
+
Returns:
|
|
397
|
+
The launched subprocess (output inherits the parent
|
|
398
|
+
terminal), or `None` when no simulator is booted or
|
|
399
|
+
`xcrun` is unavailable.
|
|
400
|
+
"""
|
|
401
|
+
udid = _booted_ios_udid()
|
|
402
|
+
if udid is None:
|
|
403
|
+
print("Note: no booted iOS Simulator found; skipping log streaming.")
|
|
404
|
+
return None
|
|
405
|
+
sim_env = os.environ.copy()
|
|
406
|
+
sim_env["SIMCTL_CHILD_PYTHONUNBUFFERED"] = "1"
|
|
407
|
+
try:
|
|
408
|
+
proc = subprocess.Popen(
|
|
409
|
+
[
|
|
410
|
+
"xcrun",
|
|
411
|
+
"simctl",
|
|
412
|
+
"launch",
|
|
413
|
+
"--console-pty",
|
|
414
|
+
"--terminate-running-process",
|
|
415
|
+
udid,
|
|
416
|
+
IOS_BUNDLE_ID,
|
|
417
|
+
],
|
|
418
|
+
env=sim_env,
|
|
419
|
+
)
|
|
420
|
+
except FileNotFoundError:
|
|
421
|
+
print("Note: 'xcrun' not found on PATH; skipping iOS log streaming.")
|
|
422
|
+
return None
|
|
423
|
+
print("Streaming iOS app logs from the simulator (Ctrl+C to stop)...")
|
|
424
|
+
return proc
|
|
425
|
+
|
|
426
|
+
|
|
357
427
|
def _terminate_subprocess(proc: Optional[subprocess.Popen]) -> None:
|
|
358
428
|
"""Politely stop a subprocess, escalating to `SIGKILL` if needed.
|
|
359
429
|
|
|
@@ -947,14 +1017,15 @@ def run_project(args: argparse.Namespace) -> None:
|
|
|
947
1017
|
capture_output=True,
|
|
948
1018
|
)
|
|
949
1019
|
print("Stopped log streaming.")
|
|
1020
|
+
elif hot_reload:
|
|
1021
|
+
# Skip launching here; ``_run_hot_reload`` will
|
|
1022
|
+
# spawn the app via ``simctl launch --console-pty``
|
|
1023
|
+
# so its ``print()`` / ``NSLog`` output streams to
|
|
1024
|
+
# the parent terminal alongside the file watcher.
|
|
1025
|
+
pass
|
|
950
1026
|
else:
|
|
951
1027
|
subprocess.run(["xcrun", "simctl", "launch", udid, IOS_BUNDLE_ID], check=False)
|
|
952
1028
|
print("Launched iOS app on Simulator (best-effort).")
|
|
953
|
-
if show_logs and hot_reload:
|
|
954
|
-
print(
|
|
955
|
-
"Note: live Python log streaming on iOS is disabled while --hot-reload is active; "
|
|
956
|
-
"use Console.app or Xcode to view logs."
|
|
957
|
-
)
|
|
958
1029
|
except Exception:
|
|
959
1030
|
print("Failed to auto-run on Simulator; open the project in Xcode to run.")
|
|
960
1031
|
|
|
@@ -1000,13 +1071,16 @@ def _run_hot_reload(platform: str, project_dir: str, build_dir: str, show_logs:
|
|
|
1000
1071
|
watcher = FileWatcher(app_dir, on_change, interval=1.0)
|
|
1001
1072
|
watcher.start()
|
|
1002
1073
|
|
|
1003
|
-
|
|
1004
|
-
if show_logs
|
|
1005
|
-
|
|
1074
|
+
log_proc: Optional[subprocess.Popen] = None
|
|
1075
|
+
if show_logs:
|
|
1076
|
+
if platform == "android":
|
|
1077
|
+
log_proc = _start_android_log_stream()
|
|
1078
|
+
elif platform == "ios":
|
|
1079
|
+
log_proc = _start_ios_log_stream()
|
|
1006
1080
|
|
|
1007
1081
|
try:
|
|
1008
|
-
if
|
|
1009
|
-
|
|
1082
|
+
if log_proc is not None:
|
|
1083
|
+
log_proc.wait()
|
|
1010
1084
|
else:
|
|
1011
1085
|
import time
|
|
1012
1086
|
|
|
@@ -1015,7 +1089,7 @@ def _run_hot_reload(platform: str, project_dir: str, build_dir: str, show_logs:
|
|
|
1015
1089
|
except KeyboardInterrupt:
|
|
1016
1090
|
pass
|
|
1017
1091
|
finally:
|
|
1018
|
-
_terminate_subprocess(
|
|
1092
|
+
_terminate_subprocess(log_proc)
|
|
1019
1093
|
watcher.stop()
|
|
1020
1094
|
print("\n[hot-reload] Stopped.")
|
|
1021
1095
|
|
|
@@ -287,7 +287,14 @@ def Spacer(
|
|
|
287
287
|
"""
|
|
288
288
|
props: Dict[str, Any] = {}
|
|
289
289
|
if size is not None:
|
|
290
|
+
# The layout engine sees ``width`` / ``height`` only, so a fixed
|
|
291
|
+
# ``size`` is mirrored on both axes. Whichever axis the parent
|
|
292
|
+
# container's ``flex_direction`` chooses as main becomes the
|
|
293
|
+
# actual gap; the cross axis is constrained by the parent's
|
|
294
|
+
# ``align_items`` (typically ``stretch``) anyway.
|
|
290
295
|
props["size"] = size
|
|
296
|
+
props["width"] = size
|
|
297
|
+
props["height"] = size
|
|
291
298
|
if flex is not None:
|
|
292
299
|
props["flex"] = flex
|
|
293
300
|
return Element("Spacer", props, [], key=key)
|