pythonnative 0.22.0__tar.gz → 0.22.1__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.22.0/src/pythonnative.egg-info → pythonnative-0.22.1}/PKG-INFO +13 -13
- {pythonnative-0.22.0 → pythonnative-0.22.1}/README.md +11 -11
- {pythonnative-0.22.0 → pythonnative-0.22.1}/pyproject.toml +3 -2
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/__init__.py +1 -1
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/animated.py +6 -6
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/cli/pn.py +1 -1
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/components.py +12 -12
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/events.py +5 -5
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/gestures.py +3 -3
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/hooks.py +3 -3
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/hot_reload.py +4 -4
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/layout.py +3 -3
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/mutations.py +1 -1
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/native_modules/camera.py +1 -1
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/native_modules/haptics.py +2 -2
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/native_modules/location.py +1 -1
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/native_modules/permissions.py +2 -2
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/native_modules/secure_store.py +1 -1
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/native_views/android.py +20 -20
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/native_views/base.py +3 -3
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/native_views/desktop.py +7 -7
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/native_views/ios.py +23 -23
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/navigation.py +4 -4
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/net.py +3 -3
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/platform.py +1 -1
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/platform_metrics.py +5 -5
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/preview.py +3 -3
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/project/builder.py +1 -1
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/project/config.py +3 -3
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/project/doctor.py +2 -2
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/project/icons.py +1 -1
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/project/ios.py +1 -1
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/project/permissions.py +2 -2
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/project/runtime_assets.py +3 -3
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/reconciler.py +9 -9
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/runtime.py +8 -8
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/screen.py +5 -5
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/sdk/_components.py +1 -1
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/storage.py +3 -3
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/style.py +1 -1
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/ios_template/ios_template.xcodeproj/project.pbxproj +2 -2
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/ios_template/ios_templateUITests/ios_templateUITests.swift +1 -1
- {pythonnative-0.22.0 → pythonnative-0.22.1/src/pythonnative.egg-info}/PKG-INFO +13 -13
- {pythonnative-0.22.0 → pythonnative-0.22.1}/tests/test_desktop_backend.py +1 -1
- {pythonnative-0.22.0 → pythonnative-0.22.1}/tests/test_events.py +1 -1
- {pythonnative-0.22.0 → pythonnative-0.22.1}/tests/test_hot_reload.py +2 -2
- {pythonnative-0.22.0 → pythonnative-0.22.1}/tests/test_ios_log.py +1 -1
- {pythonnative-0.22.0 → pythonnative-0.22.1}/tests/test_layout.py +1 -1
- {pythonnative-0.22.0 → pythonnative-0.22.1}/tests/test_ref.py +2 -2
- {pythonnative-0.22.0 → pythonnative-0.22.1}/tests/test_screen.py +1 -1
- {pythonnative-0.22.0 → pythonnative-0.22.1}/LICENSE +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/setup.cfg +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/_ios_log.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/alerts.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/cli/__init__.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/element.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/native_modules/__init__.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/native_modules/app_state.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/native_modules/battery.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/native_modules/biometrics.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/native_modules/clipboard.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/native_modules/file_system.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/native_modules/linking.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/native_modules/net_info.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/native_modules/notifications.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/native_modules/share.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/native_views/__init__.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/project/__init__.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/project/android.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/sdk/__init__.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/android_template/app/build.gradle +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/android_template/app/proguard-rules.pro +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/android_template/app/src/androidTest/java/com/pythonnative/android_template/ExampleInstrumentedTest.kt +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/android_template/app/src/main/AndroidManifest.xml +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/MainActivity.kt +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/Navigator.kt +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/ScreenFragment.kt +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/android_template/app/src/main/res/drawable/ic_launcher_background.xml +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/android_template/app/src/main/res/drawable-v24/ic_launcher_foreground.xml +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/android_template/app/src/main/res/layout/activity_main.xml +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-hdpi/ic_launcher.webp +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-mdpi/ic_launcher.webp +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-xhdpi/ic_launcher.webp +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/android_template/app/src/main/res/navigation/nav_graph.xml +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/android_template/app/src/main/res/values/colors.xml +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/android_template/app/src/main/res/values/strings.xml +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/android_template/app/src/main/res/values/themes.xml +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/android_template/app/src/main/res/values-night/themes.xml +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/android_template/app/src/main/res/xml/backup_rules.xml +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/android_template/app/src/main/res/xml/data_extraction_rules.xml +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/android_template/app/src/test/java/com/pythonnative/android_template/ExampleUnitTest.kt +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/android_template/build.gradle +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/android_template/gradle/wrapper/gradle-wrapper.jar +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/android_template/gradle/wrapper/gradle-wrapper.properties +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/android_template/gradle.properties +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/android_template/gradlew +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/android_template/gradlew.bat +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/android_template/settings.gradle +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/ios_template/ios_template/AppDelegate.swift +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/ios_template/ios_template/Assets.xcassets/AccentColor.colorset/Contents.json +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/ios_template/ios_template/Assets.xcassets/AppIcon.appiconset/Contents.json +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/ios_template/ios_template/Assets.xcassets/Contents.json +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/ios_template/ios_template/Base.lproj/LaunchScreen.storyboard +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/ios_template/ios_template/Base.lproj/Main.storyboard +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/ios_template/ios_template/Info.plist +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/ios_template/ios_template/SceneDelegate.swift +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/ios_template/ios_template/ViewController.swift +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/ios_template/ios_template.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/ios_template/ios_templateTests/ios_templateTests.swift +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/templates/ios_template/ios_templateUITests/ios_templateUITestsLaunchTests.swift +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative/utils.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative.egg-info/SOURCES.txt +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative.egg-info/dependency_links.txt +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative.egg-info/entry_points.txt +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative.egg-info/requires.txt +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/src/pythonnative.egg-info/top_level.txt +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/tests/test_alert.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/tests/test_animated.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/tests/test_async_hooks.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/tests/test_cli.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/tests/test_components.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/tests/test_element.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/tests/test_extended_components.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/tests/test_gestures.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/tests/test_hooks.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/tests/test_incremental_render.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/tests/test_metric_hooks.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/tests/test_mutations.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/tests/test_native_modules.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/tests/test_native_views.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/tests/test_navigation.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/tests/test_net.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/tests/test_new_components.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/tests/test_platform.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/tests/test_platform_metrics.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/tests/test_reconciler.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/tests/test_runtime.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/tests/test_sdk.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/tests/test_smoke.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/tests/test_storage.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/tests/test_style.py +0 -0
- {pythonnative-0.22.0 → pythonnative-0.22.1}/tests/test_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pythonnative
|
|
3
|
-
Version: 0.22.
|
|
3
|
+
Version: 0.22.1
|
|
4
4
|
Summary: Cross-platform native UI toolkit for Android and iOS
|
|
5
5
|
Author: Owen Carey
|
|
6
6
|
License: MIT License
|
|
@@ -28,7 +28,7 @@ License: MIT License
|
|
|
28
28
|
Project-URL: Homepage, https://github.com/pythonnative/pythonnative
|
|
29
29
|
Project-URL: Repository, https://github.com/pythonnative/pythonnative
|
|
30
30
|
Project-URL: Issues, https://github.com/pythonnative/pythonnative/issues
|
|
31
|
-
Project-URL: Documentation, https://
|
|
31
|
+
Project-URL: Documentation, https://pythonnative.com/
|
|
32
32
|
Classifier: Development Status :: 2 - Pre-Alpha
|
|
33
33
|
Classifier: Intended Audience :: Developers
|
|
34
34
|
Classifier: License :: OSI Approved :: MIT License
|
|
@@ -83,13 +83,13 @@ Dynamic: license-file
|
|
|
83
83
|
<a href="https://pypi.org/project/pythonnative/"><img src="https://img.shields.io/pypi/v/pythonnative" alt="PyPI Version" /></a>
|
|
84
84
|
<a href="https://pypi.org/project/pythonnative/"><img src="https://img.shields.io/pypi/pyversions/pythonnative" alt="Python Versions" /></a>
|
|
85
85
|
<a href="LICENSE"><img src="https://img.shields.io/pypi/l/pythonnative" alt="License: MIT" /></a>
|
|
86
|
-
<a href="https://
|
|
86
|
+
<a href="https://pythonnative.com/"><img src="https://img.shields.io/website?url=https%3A%2F%2Fpythonnative.com&label=docs" alt="Docs" /></a>
|
|
87
87
|
</p>
|
|
88
88
|
|
|
89
89
|
<p align="center">
|
|
90
|
-
<a href="https://
|
|
91
|
-
<a href="https://
|
|
92
|
-
<a href="https://
|
|
90
|
+
<a href="https://pythonnative.com/">Documentation</a> ·
|
|
91
|
+
<a href="https://pythonnative.com/getting-started/">Getting Started</a> ·
|
|
92
|
+
<a href="https://pythonnative.com/examples/">Examples</a> ·
|
|
93
93
|
<a href="CONTRIBUTING.md">Contributing</a>
|
|
94
94
|
</p>
|
|
95
95
|
|
|
@@ -102,19 +102,19 @@ PythonNative is a cross-platform toolkit for building native Android and iOS app
|
|
|
102
102
|
## Features
|
|
103
103
|
|
|
104
104
|
- **Declarative UI:** Describe *what* your UI should look like with element functions (`Text`, `Button`, `Column`, `Row`, etc.). PythonNative creates and updates native views automatically.
|
|
105
|
-
- **Rich component library:** 25+ built-in components backed by real native widgets
|
|
106
|
-
- **Device APIs:** Cross-platform modules for `Camera`, `Location`, `FileSystem`, `Notifications`, `Clipboard`, `Share`, `Linking`, `Permissions`, `AppState`, `NetInfo`, `SecureStore`, `Battery`, `Haptics` / `Vibration`, and `Biometrics
|
|
105
|
+
- **Rich component library:** 25+ built-in components backed by real native widgets: `TextInput`, `Image` / `ImageBackground`, `ScrollView`, `FlatList` / `SectionList`, `Modal`, `Pressable` / `TouchableOpacity`, `Switch` / `Checkbox`, `Slider`, `SegmentedControl`, `Picker`, `DatePicker`, `ProgressBar` / `ActivityIndicator`, `WebView`, and more.
|
|
106
|
+
- **Device APIs:** Cross-platform modules for `Camera`, `Location`, `FileSystem`, `Notifications`, `Clipboard`, `Share`, `Linking`, `Permissions`, `AppState`, `NetInfo`, `SecureStore`, `Battery`, `Haptics` / `Vibration`, and `Biometrics`, plus reactive `use_app_state` and `use_net_info` hooks.
|
|
107
107
|
- **Hooks and function components:** Manage state with `use_state`, side effects with `use_effect`, and navigation with `use_navigation`, all through one consistent pattern.
|
|
108
108
|
- **Typed `style` prop:** Pass all visual and layout properties through a single `style` dict, fully described by the `pn.Style` `TypedDict` and the ergonomic `pn.style(...)` helper for IDE autocomplete and static checking. Compose reusable styles with `StyleSheet`.
|
|
109
109
|
- **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.
|
|
110
|
-
- **Virtual view tree + reconciler:** Element trees are diffed and patched with minimal native mutations, similar to React's reconciliation. Each commit lands as **one batched transaction** of mutation ops, and event callbacks are routed through a tag-based registry so re-renders that only change closures cost zero native calls. State updates re-render **locally
|
|
110
|
+
- **Virtual view tree + reconciler:** Element trees are diffed and patched with minimal native mutations, similar to React's reconciliation. Each commit lands as **one batched transaction** of mutation ops, and event callbacks are routed through a tag-based registry so re-renders that only change closures cost zero native calls. State updates re-render **locally**: only the component whose state changed (and its subtree) re-runs, and unchanged leaves reuse cached intrinsic measurements, so deep UIs stay responsive instead of re-rendering the whole app from the root on every tap.
|
|
111
111
|
- **Native-driven animations:** The `Animated` API (timing / spring / decay, awaitable or fire-and-forget) hands animations to Core Animation and `ViewPropertyAnimator` whenever possible, so no Python code runs per frame; a pure-Python ticker covers the rest.
|
|
112
|
-
- **Native gesture system:** Attach `Tap`, `LongPress`, `Pan`, `Swipe`, `Pinch`, and `Rotation` recognizers to any view via the `gestures=` prop
|
|
113
|
-
- **Virtualized lists:** `FlatList` / `SectionList` window their rows in Python over the platform scroll view
|
|
112
|
+
- **Native gesture system:** Attach `Tap`, `LongPress`, `Pan`, `Swipe`, `Pinch`, and `Rotation` recognizers to any view via the `gestures=` prop, backed by `UIGestureRecognizer` on iOS and a unit-testable pure-Python arbiter on Android and desktop.
|
|
113
|
+
- **Virtualized lists:** `FlatList` / `SectionList` window their rows in Python over the platform scroll view: uniform, exact, or measured variable heights, grids, headers/footers, infinite scroll, and an imperative scroll controller, identical on every platform.
|
|
114
114
|
- **Direct native bindings:** Python calls platform APIs directly through Chaquopy and rubicon-objc, with no JavaScript bridge.
|
|
115
115
|
- **Custom-component SDK:** Wrap any platform widget as a first-class element with type-checked props via `pythonnative.sdk` (`Props`, `@native_component`, `element_factory`). Plugins distributed on PyPI auto-register through the `pythonnative.handlers` entry-point group.
|
|
116
116
|
- **CLI scaffolding:** `pn init` creates a ready-to-run project; `pn run android` and `pn run ios` build and launch your app.
|
|
117
|
-
- **Instant desktop preview:** `pn preview` renders your app in a native desktop window via Tkinter with Fast Refresh on every save
|
|
117
|
+
- **Instant desktop preview:** `pn preview` renders your app in a native desktop window via Tkinter with Fast Refresh on every save: iterate on layout, state, and navigation in milliseconds without booting a simulator or device. The reconciler, hooks, layout engine, and navigation are the same code that ships to the phone.
|
|
118
118
|
- **Native-backed navigation:** Declarative `Stack`, `Tab`, and `Drawer` navigators inspired by React Navigation. The root stack drives the platform's native navigation controller (`UINavigationController` on iOS, AndroidX Navigation Component on Android), so transitions, back gestures, and the hardware back button match what users expect.
|
|
119
119
|
- **Fast Refresh hot reload:** `pn run --hot-reload` watches `app/` and patches edits into the running app on save, preserving component state across most changes.
|
|
120
120
|
- **Bundled templates:** Android Gradle and iOS Xcode templates are included, so scaffolding requires no network access.
|
|
@@ -148,7 +148,7 @@ def App():
|
|
|
148
148
|
|
|
149
149
|
## Documentation
|
|
150
150
|
|
|
151
|
-
Visit [
|
|
151
|
+
Visit [pythonnative.com](https://pythonnative.com/) for the full documentation, including getting started guides, platform-specific instructions for Android and iOS, API reference, and working examples.
|
|
152
152
|
|
|
153
153
|
## Contributing
|
|
154
154
|
|
|
@@ -12,13 +12,13 @@
|
|
|
12
12
|
<a href="https://pypi.org/project/pythonnative/"><img src="https://img.shields.io/pypi/v/pythonnative" alt="PyPI Version" /></a>
|
|
13
13
|
<a href="https://pypi.org/project/pythonnative/"><img src="https://img.shields.io/pypi/pyversions/pythonnative" alt="Python Versions" /></a>
|
|
14
14
|
<a href="LICENSE"><img src="https://img.shields.io/pypi/l/pythonnative" alt="License: MIT" /></a>
|
|
15
|
-
<a href="https://
|
|
15
|
+
<a href="https://pythonnative.com/"><img src="https://img.shields.io/website?url=https%3A%2F%2Fpythonnative.com&label=docs" alt="Docs" /></a>
|
|
16
16
|
</p>
|
|
17
17
|
|
|
18
18
|
<p align="center">
|
|
19
|
-
<a href="https://
|
|
20
|
-
<a href="https://
|
|
21
|
-
<a href="https://
|
|
19
|
+
<a href="https://pythonnative.com/">Documentation</a> ·
|
|
20
|
+
<a href="https://pythonnative.com/getting-started/">Getting Started</a> ·
|
|
21
|
+
<a href="https://pythonnative.com/examples/">Examples</a> ·
|
|
22
22
|
<a href="CONTRIBUTING.md">Contributing</a>
|
|
23
23
|
</p>
|
|
24
24
|
|
|
@@ -31,19 +31,19 @@ PythonNative is a cross-platform toolkit for building native Android and iOS app
|
|
|
31
31
|
## Features
|
|
32
32
|
|
|
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
|
-
- **Rich component library:** 25+ built-in components backed by real native widgets
|
|
35
|
-
- **Device APIs:** Cross-platform modules for `Camera`, `Location`, `FileSystem`, `Notifications`, `Clipboard`, `Share`, `Linking`, `Permissions`, `AppState`, `NetInfo`, `SecureStore`, `Battery`, `Haptics` / `Vibration`, and `Biometrics
|
|
34
|
+
- **Rich component library:** 25+ built-in components backed by real native widgets: `TextInput`, `Image` / `ImageBackground`, `ScrollView`, `FlatList` / `SectionList`, `Modal`, `Pressable` / `TouchableOpacity`, `Switch` / `Checkbox`, `Slider`, `SegmentedControl`, `Picker`, `DatePicker`, `ProgressBar` / `ActivityIndicator`, `WebView`, and more.
|
|
35
|
+
- **Device APIs:** Cross-platform modules for `Camera`, `Location`, `FileSystem`, `Notifications`, `Clipboard`, `Share`, `Linking`, `Permissions`, `AppState`, `NetInfo`, `SecureStore`, `Battery`, `Haptics` / `Vibration`, and `Biometrics`, plus reactive `use_app_state` and `use_net_info` hooks.
|
|
36
36
|
- **Hooks and function components:** Manage state with `use_state`, side effects with `use_effect`, and navigation with `use_navigation`, all through one consistent pattern.
|
|
37
37
|
- **Typed `style` prop:** Pass all visual and layout properties through a single `style` dict, fully described by the `pn.Style` `TypedDict` and the ergonomic `pn.style(...)` helper for IDE autocomplete and static checking. Compose reusable styles with `StyleSheet`.
|
|
38
38
|
- **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.
|
|
39
|
-
- **Virtual view tree + reconciler:** Element trees are diffed and patched with minimal native mutations, similar to React's reconciliation. Each commit lands as **one batched transaction** of mutation ops, and event callbacks are routed through a tag-based registry so re-renders that only change closures cost zero native calls. State updates re-render **locally
|
|
39
|
+
- **Virtual view tree + reconciler:** Element trees are diffed and patched with minimal native mutations, similar to React's reconciliation. Each commit lands as **one batched transaction** of mutation ops, and event callbacks are routed through a tag-based registry so re-renders that only change closures cost zero native calls. State updates re-render **locally**: only the component whose state changed (and its subtree) re-runs, and unchanged leaves reuse cached intrinsic measurements, so deep UIs stay responsive instead of re-rendering the whole app from the root on every tap.
|
|
40
40
|
- **Native-driven animations:** The `Animated` API (timing / spring / decay, awaitable or fire-and-forget) hands animations to Core Animation and `ViewPropertyAnimator` whenever possible, so no Python code runs per frame; a pure-Python ticker covers the rest.
|
|
41
|
-
- **Native gesture system:** Attach `Tap`, `LongPress`, `Pan`, `Swipe`, `Pinch`, and `Rotation` recognizers to any view via the `gestures=` prop
|
|
42
|
-
- **Virtualized lists:** `FlatList` / `SectionList` window their rows in Python over the platform scroll view
|
|
41
|
+
- **Native gesture system:** Attach `Tap`, `LongPress`, `Pan`, `Swipe`, `Pinch`, and `Rotation` recognizers to any view via the `gestures=` prop, backed by `UIGestureRecognizer` on iOS and a unit-testable pure-Python arbiter on Android and desktop.
|
|
42
|
+
- **Virtualized lists:** `FlatList` / `SectionList` window their rows in Python over the platform scroll view: uniform, exact, or measured variable heights, grids, headers/footers, infinite scroll, and an imperative scroll controller, identical on every platform.
|
|
43
43
|
- **Direct native bindings:** Python calls platform APIs directly through Chaquopy and rubicon-objc, with no JavaScript bridge.
|
|
44
44
|
- **Custom-component SDK:** Wrap any platform widget as a first-class element with type-checked props via `pythonnative.sdk` (`Props`, `@native_component`, `element_factory`). Plugins distributed on PyPI auto-register through the `pythonnative.handlers` entry-point group.
|
|
45
45
|
- **CLI scaffolding:** `pn init` creates a ready-to-run project; `pn run android` and `pn run ios` build and launch your app.
|
|
46
|
-
- **Instant desktop preview:** `pn preview` renders your app in a native desktop window via Tkinter with Fast Refresh on every save
|
|
46
|
+
- **Instant desktop preview:** `pn preview` renders your app in a native desktop window via Tkinter with Fast Refresh on every save: iterate on layout, state, and navigation in milliseconds without booting a simulator or device. The reconciler, hooks, layout engine, and navigation are the same code that ships to the phone.
|
|
47
47
|
- **Native-backed navigation:** Declarative `Stack`, `Tab`, and `Drawer` navigators inspired by React Navigation. The root stack drives the platform's native navigation controller (`UINavigationController` on iOS, AndroidX Navigation Component on Android), so transitions, back gestures, and the hardware back button match what users expect.
|
|
48
48
|
- **Fast Refresh hot reload:** `pn run --hot-reload` watches `app/` and patches edits into the running app on save, preserving component state across most changes.
|
|
49
49
|
- **Bundled templates:** Android Gradle and iOS Xcode templates are included, so scaffolding requires no network access.
|
|
@@ -77,7 +77,7 @@ def App():
|
|
|
77
77
|
|
|
78
78
|
## Documentation
|
|
79
79
|
|
|
80
|
-
Visit [
|
|
80
|
+
Visit [pythonnative.com](https://pythonnative.com/) for the full documentation, including getting started guides, platform-specific instructions for Android and iOS, API reference, and working examples.
|
|
81
81
|
|
|
82
82
|
## Contributing
|
|
83
83
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pythonnative"
|
|
7
|
-
version = "0.22.
|
|
7
|
+
version = "0.22.1"
|
|
8
8
|
description = "Cross-platform native UI toolkit for Android and iOS"
|
|
9
9
|
authors = [
|
|
10
10
|
{ name = "Owen Carey" }
|
|
@@ -66,7 +66,8 @@ pn = "pythonnative.cli.pn:main"
|
|
|
66
66
|
Homepage = "https://github.com/pythonnative/pythonnative"
|
|
67
67
|
Repository = "https://github.com/pythonnative/pythonnative"
|
|
68
68
|
Issues = "https://github.com/pythonnative/pythonnative/issues"
|
|
69
|
-
Documentation = "https://
|
|
69
|
+
Documentation = "https://pythonnative.com/"
|
|
70
|
+
|
|
70
71
|
|
|
71
72
|
|
|
72
73
|
|
|
@@ -24,7 +24,7 @@ native view the value is attached to
|
|
|
24
24
|
|
|
25
25
|
- **Accepted** (iOS Core Animation, Android ``ViewPropertyAnimator`` /
|
|
26
26
|
``DynamicAnimation``): the platform animates the property entirely
|
|
27
|
-
natively
|
|
27
|
+
natively; no Python code runs per frame. Python receives exactly one
|
|
28
28
|
callback when the animation settles, updates the
|
|
29
29
|
[`AnimatedValue`][pythonnative.animated.AnimatedValue], and resolves
|
|
30
30
|
any awaiting tasks.
|
|
@@ -135,7 +135,7 @@ class AnimatedValue:
|
|
|
135
135
|
Animated components (``Animated.View`` et al.) **attach** the value
|
|
136
136
|
to ``(tag, prop)`` bindings after mount. Setting the value pushes
|
|
137
137
|
the new number to every attached native view through the registry's
|
|
138
|
-
``set_animated_property
|
|
138
|
+
``set_animated_property``, and when an animation can be driven
|
|
139
139
|
natively, the platform animates those same bindings directly.
|
|
140
140
|
|
|
141
141
|
Python-side listeners registered via
|
|
@@ -217,7 +217,7 @@ class AnimatedValue:
|
|
|
217
217
|
def add_listener(self, prop: str, callback: Callable[[float], None]) -> Callable[[], None]:
|
|
218
218
|
"""Register ``callback`` for Python-driven changes to this value.
|
|
219
219
|
|
|
220
|
-
Returns an unsubscribe callable. ``prop`` is metadata only
|
|
220
|
+
Returns an unsubscribe callable. ``prop`` is metadata only; it
|
|
221
221
|
lets the subscriber differentiate this binding from others on
|
|
222
222
|
the same ``AnimatedValue``.
|
|
223
223
|
"""
|
|
@@ -686,7 +686,7 @@ class _AnimationHandle(_AwaitableAnimation):
|
|
|
686
686
|
|
|
687
687
|
Each ``.start()`` call snapshots the value's current state, prefers
|
|
688
688
|
the native driver, and falls back to a fresh Python-ticked
|
|
689
|
-
animation otherwise (matches React Native
|
|
689
|
+
animation otherwise (matches React Native: the ``Animated.timing``
|
|
690
690
|
return value is reusable).
|
|
691
691
|
"""
|
|
692
692
|
|
|
@@ -780,7 +780,7 @@ class _CompositeAnimation(_AwaitableAnimation):
|
|
|
780
780
|
if item is None:
|
|
781
781
|
return
|
|
782
782
|
# ``_AwaitableAnimation`` and plain awaitables/coroutines are
|
|
783
|
-
# both supported
|
|
783
|
+
# both supported: lets users mix in ``asyncio.sleep``.
|
|
784
784
|
await item
|
|
785
785
|
|
|
786
786
|
|
|
@@ -824,7 +824,7 @@ def _make_animated_factory(
|
|
|
824
824
|
|
|
825
825
|
# ``@component`` packs positional children into the ``children``
|
|
826
826
|
# prop (this function declares ``*args``), and the reconciler
|
|
827
|
-
# re-invokes it with keyword props only
|
|
827
|
+
# re-invokes it with keyword props only, so at render time the
|
|
828
828
|
# payload arrives in ``kwargs``, never in ``args``.
|
|
829
829
|
children = list(args) or list(kwargs.pop("children", ()) or ())
|
|
830
830
|
|
|
@@ -5,7 +5,7 @@ The console script `pn` (declared in `pyproject.toml`) dispatches to:
|
|
|
5
5
|
- `pn init [name]`: scaffold a new project (``pythonnative.toml`` + ``app/``).
|
|
6
6
|
- `pn doctor [platform]`: diagnose the local toolchain and config.
|
|
7
7
|
- `pn preview [component]`: render the app in a desktop (Tkinter) window
|
|
8
|
-
with Fast Refresh
|
|
8
|
+
with Fast Refresh, the fast inner dev loop, no device required.
|
|
9
9
|
- `pn run android|ios`: stage + build + install + launch on a device or
|
|
10
10
|
simulator, with optional on-device hot reload.
|
|
11
11
|
- `pn build android|ios`: produce standalone artifacts (signed APK/AAB,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Built-in element factories and the typed prop schemas they share.
|
|
2
2
|
|
|
3
|
-
Each ``@dataclass(frozen=True)`` class in this module
|
|
4
|
-
``ButtonProps``, etc.
|
|
3
|
+
Each ``@dataclass(frozen=True)`` class in this module (``TextProps``,
|
|
4
|
+
``ButtonProps``, etc.) is the canonical schema for one built-in
|
|
5
5
|
component. Each factory function (``Text``, ``Button``, …) is a thin
|
|
6
6
|
ergonomic wrapper that builds an [`Element`][pythonnative.Element]
|
|
7
7
|
through the shared :func:`_make_element` helper, so style resolution,
|
|
@@ -827,7 +827,7 @@ def Spacer(
|
|
|
827
827
|
|
|
828
828
|
Args:
|
|
829
829
|
size: Fixed gap in dp/pt along the parent's main axis. Mirrored
|
|
830
|
-
on both axes
|
|
830
|
+
on both axes: whichever axis the parent's
|
|
831
831
|
``flex_direction`` chooses as main becomes the actual gap.
|
|
832
832
|
flex: Flex-grow weight; useful for pushing siblings to the
|
|
833
833
|
opposite end of a [`Row`][pythonnative.Row] or
|
|
@@ -912,14 +912,14 @@ def View(
|
|
|
912
912
|
- ``flex_direction``: ``"column"`` (default), ``"row"``,
|
|
913
913
|
``"column_reverse"``, ``"row_reverse"``.
|
|
914
914
|
- ``flex_wrap``: ``"nowrap"`` (default), ``"wrap"``,
|
|
915
|
-
``"wrap_reverse"
|
|
915
|
+
``"wrap_reverse"``, with ``align_content`` controlling how
|
|
916
916
|
wrapped lines share leftover cross-axis space.
|
|
917
917
|
- ``justify_content``: main-axis distribution. Accepts
|
|
918
918
|
``"flex_start"`` (default), ``"center"``, ``"flex_end"``,
|
|
919
919
|
``"space_between"``, ``"space_around"``, ``"space_evenly"``.
|
|
920
920
|
- ``align_items``: cross-axis alignment. Accepts ``"stretch"``
|
|
921
921
|
(default), ``"flex_start"``, ``"center"``, ``"flex_end"``.
|
|
922
|
-
- ``direction``: ``"ltr"`` (default) or ``"rtl"
|
|
922
|
+
- ``direction``: ``"ltr"`` (default) or ``"rtl"``. Flips rows and
|
|
923
923
|
resolves ``margin_start`` / ``padding_end`` / absolute ``start``
|
|
924
924
|
/ ``end`` insets.
|
|
925
925
|
- ``overflow``: ``"visible"`` (default) or ``"hidden"``.
|
|
@@ -1061,7 +1061,7 @@ def ScrollView(
|
|
|
1061
1061
|
wrapper (padding, alignment, spacing of the scrollable
|
|
1062
1062
|
content), distinct from ``style`` (the scroll view frame).
|
|
1063
1063
|
keyboard_dismiss_mode: ``"none"`` (default), ``"on_drag"``, or
|
|
1064
|
-
``"interactive"
|
|
1064
|
+
``"interactive"``. Controls whether scrolling dismisses
|
|
1065
1065
|
the keyboard.
|
|
1066
1066
|
style: Style dict (or list of dicts).
|
|
1067
1067
|
ref: Optional ``use_ref()`` dict.
|
|
@@ -1145,7 +1145,7 @@ def Modal(
|
|
|
1145
1145
|
animation_type: ``"slide"`` (default), ``"fade"``, or ``"none"``.
|
|
1146
1146
|
transparent: When ``True``, the underlying view is dimmed
|
|
1147
1147
|
instead of fully covered.
|
|
1148
|
-
presentation_style: iOS presentation style
|
|
1148
|
+
presentation_style: iOS presentation style,
|
|
1149
1149
|
``"page_sheet"`` (default), ``"form_sheet"``,
|
|
1150
1150
|
``"full_screen"``, or ``"overlay"`` (custom dimmed
|
|
1151
1151
|
overlay). On Android, ``"overlay"`` keeps the dialog
|
|
@@ -1604,8 +1604,8 @@ def ErrorBoundary(
|
|
|
1604
1604
|
# ======================================================================
|
|
1605
1605
|
#
|
|
1606
1606
|
# FlatList and SectionList are pure Python components, not native
|
|
1607
|
-
# elements. They render a windowed slice of rows into a ScrollView
|
|
1608
|
-
# leading spacer, visible rows, trailing spacer
|
|
1607
|
+
# elements. They render a windowed slice of rows into a ScrollView
|
|
1608
|
+
# (leading spacer, visible rows, trailing spacer) and shift the window
|
|
1609
1609
|
# from scroll events (the same architecture as React Native's
|
|
1610
1610
|
# VirtualizedList). Because every windowed row lives in the *main*
|
|
1611
1611
|
# layout tree, rows may be any height: estimates only steer the spacer
|
|
@@ -1872,7 +1872,7 @@ def FlatList(
|
|
|
1872
1872
|
leading and trailing spacers stand in for everything else, and the
|
|
1873
1873
|
window shifts as the user scrolls. Rows may have **variable
|
|
1874
1874
|
heights**: pass ``item_height`` when rows are uniform,
|
|
1875
|
-
``get_item_height`` for exact per-item extents, or nothing at all
|
|
1875
|
+
``get_item_height`` for exact per-item extents, or nothing at all;
|
|
1876
1876
|
unknown rows start at ``estimated_item_height`` and are corrected
|
|
1877
1877
|
with their measured extent once they've been on screen.
|
|
1878
1878
|
|
|
@@ -2040,7 +2040,7 @@ def SectionList(
|
|
|
2040
2040
|
|
|
2041
2041
|
Flattens ``sections`` into a single virtualized sequence where each
|
|
2042
2042
|
entry is either a header or an item, then reuses the same windowing
|
|
2043
|
-
engine as [`FlatList`][pythonnative.FlatList]
|
|
2043
|
+
engine as [`FlatList`][pythonnative.FlatList]; headers and items
|
|
2044
2044
|
may have different (and variable) heights.
|
|
2045
2045
|
|
|
2046
2046
|
Args:
|
|
@@ -2177,7 +2177,7 @@ def StatusBar(
|
|
|
2177
2177
|
``"dark"`` (dark icons over light backgrounds), or
|
|
2178
2178
|
``"default"`` (system default).
|
|
2179
2179
|
background_color: Color of the status-bar background (Android
|
|
2180
|
-
only
|
|
2180
|
+
only; iOS draws the bar transparent over your content).
|
|
2181
2181
|
hidden: When ``True``, the status bar is hidden.
|
|
2182
2182
|
key: Stable identity for keyed reconciliation.
|
|
2183
2183
|
|
|
@@ -10,7 +10,7 @@ the bridge. This module replaces that with a single dispatch channel:
|
|
|
10
10
|
- Handlers wire their platform listener **once** at view creation; the
|
|
11
11
|
listener calls [`dispatch_event`][pythonnative.events.dispatch_event]
|
|
12
12
|
with the view's tag and the event name.
|
|
13
|
-
- Re-renders only mutate this Python-side registry
|
|
13
|
+
- Re-renders only mutate this Python-side registry; no native call is
|
|
14
14
|
made when just a callback identity changes.
|
|
15
15
|
|
|
16
16
|
The set of event names present on an element is forwarded to handlers
|
|
@@ -78,7 +78,7 @@ class EventRegistry:
|
|
|
78
78
|
|
|
79
79
|
Returns:
|
|
80
80
|
``True`` when a callback existed and was invoked (even if
|
|
81
|
-
it raised
|
|
81
|
+
it raised: exceptions are swallowed so a buggy app
|
|
82
82
|
callback can't crash the platform's UI thread), ``False``
|
|
83
83
|
when nothing is registered.
|
|
84
84
|
"""
|
|
@@ -115,7 +115,7 @@ def dispatch_event(tag: int, name: str, *args: Any) -> bool:
|
|
|
115
115
|
|
|
116
116
|
Args:
|
|
117
117
|
tag: The view's reconciler-assigned tag.
|
|
118
|
-
name: Event name
|
|
118
|
+
name: Event name, the original prop name (``"on_click"``,
|
|
119
119
|
``"on_change"``, …) or a gesture channel (``"gesture:0"``).
|
|
120
120
|
*args: Positional arguments forwarded to the user callback,
|
|
121
121
|
preserving each prop's documented signature.
|
|
@@ -144,8 +144,8 @@ def extract_events(props: Dict[str, Any]) -> Tuple[Dict[str, Any], Dict[str, Cal
|
|
|
144
144
|
- ``gestures`` lists of gesture descriptors are serialized to plain
|
|
145
145
|
dicts (handlers wire recognizers from them) while their callbacks
|
|
146
146
|
are folded into per-gesture ``"gesture:<i>"`` routers.
|
|
147
|
-
- The resulting payload carries ``_pn_events``
|
|
148
|
-
event names present
|
|
147
|
+
- The resulting payload carries ``_pn_events`` (a frozenset of the
|
|
148
|
+
event names present), so handlers can wire listeners
|
|
149
149
|
conditionally and the prop differ can detect listener
|
|
150
150
|
addition/removal without comparing closures.
|
|
151
151
|
|
|
@@ -351,7 +351,7 @@ def serialize_gestures(
|
|
|
351
351
|
# guarantees identical semantics on both backends.
|
|
352
352
|
|
|
353
353
|
EmitFn = Callable[[int, Dict[str, Any]], None]
|
|
354
|
-
"""``emit(gesture_index, payload)
|
|
354
|
+
"""``emit(gesture_index, payload)``: the arbiter's output channel."""
|
|
355
355
|
|
|
356
356
|
|
|
357
357
|
class _VelocityTracker:
|
|
@@ -400,7 +400,7 @@ class _Recognizer:
|
|
|
400
400
|
def kind(self) -> str:
|
|
401
401
|
return str(self.config.get("kind", ""))
|
|
402
402
|
|
|
403
|
-
# Event hooks
|
|
403
|
+
# Event hooks: ``pointers`` maps pointer id -> (x, y).
|
|
404
404
|
def down(self, pointers: Dict[int, Tuple[float, float]], t: float) -> None:
|
|
405
405
|
pass
|
|
406
406
|
|
|
@@ -805,7 +805,7 @@ class GestureArbiter:
|
|
|
805
805
|
|
|
806
806
|
One arbiter serves one view. The host backend feeds it normalized
|
|
807
807
|
pointer events (positions in the view's coordinate space, times in
|
|
808
|
-
seconds
|
|
808
|
+
seconds, any monotonic clock) and provides an ``emit`` callback
|
|
809
809
|
that forwards ``(gesture_index, payload)`` pairs to
|
|
810
810
|
[`dispatch_event`][pythonnative.events.dispatch_event].
|
|
811
811
|
|
|
@@ -613,7 +613,7 @@ def use_query(
|
|
|
613
613
|
Args:
|
|
614
614
|
fetcher: Zero-arg ``async`` callable that resolves to the
|
|
615
615
|
current data.
|
|
616
|
-
deps: Dependency list
|
|
616
|
+
deps: Dependency list. Refetches whenever any entry changes.
|
|
617
617
|
initial: Optional starting value for ``data`` before the
|
|
618
618
|
first fetch completes.
|
|
619
619
|
|
|
@@ -698,7 +698,7 @@ class MutationCall(Generic[T]):
|
|
|
698
698
|
Returned by the second element of the
|
|
699
699
|
[`use_mutation`][pythonnative.use_mutation] tuple. Awaiting the
|
|
700
700
|
handle resolves to the mutator's return value (or re-raises its
|
|
701
|
-
exception); discarding the handle is safe
|
|
701
|
+
exception); discarding the handle is safe. Python won't warn
|
|
702
702
|
about an unawaited coroutine because this is a plain object.
|
|
703
703
|
|
|
704
704
|
Example:
|
|
@@ -1068,7 +1068,7 @@ class NavigationHandle:
|
|
|
1068
1068
|
Wraps the host's push/pop primitives so screens can navigate
|
|
1069
1069
|
without knowing the underlying native navigation stack. The
|
|
1070
1070
|
typical user-facing surface is the declarative handle returned by
|
|
1071
|
-
a [`Stack`][pythonnative.create_stack_navigator]
|
|
1071
|
+
a [`Stack`][pythonnative.create_stack_navigator]; this class is
|
|
1072
1072
|
the lower-level fallback used when no navigator is rendered (and
|
|
1073
1073
|
as the bridge that declarative navigators delegate to when they
|
|
1074
1074
|
need to push real native screens).
|
|
@@ -17,7 +17,7 @@ Two strategies share the device-side surface:
|
|
|
17
17
|
the reconciler tree is walked and every component function whose
|
|
18
18
|
module was reloaded is swapped in place. Hook state, navigation
|
|
19
19
|
state, and even scroll positions survive because the underlying
|
|
20
|
-
``VNode`` objects are reused
|
|
20
|
+
``VNode`` objects are reused; the next render simply calls the
|
|
21
21
|
new function bodies through the old slots.
|
|
22
22
|
- **Full remount**: when the in-place swap fails (e.g. the new
|
|
23
23
|
module raised at import time, or a render exception bubbled out
|
|
@@ -197,8 +197,8 @@ class ModuleReloader:
|
|
|
197
197
|
|
|
198
198
|
Designed to be invoked from device-side glue when a hot-reload
|
|
199
199
|
push completes. All public methods are static; the class holds a
|
|
200
|
-
single piece of process-wide state
|
|
201
|
-
has most recently been applied to ``sys.modules``
|
|
200
|
+
single piece of process-wide state (the manifest version that
|
|
201
|
+
has most recently been applied to ``sys.modules``) so that
|
|
202
202
|
multiple screen hosts polling the same manifest do not each
|
|
203
203
|
re-execute the user-app modules. The first host to see a new
|
|
204
204
|
version pays the ``reload_modules`` cost; subsequent hosts on the
|
|
@@ -302,7 +302,7 @@ class ModuleReloader:
|
|
|
302
302
|
|
|
303
303
|
Returns:
|
|
304
304
|
The list of module names that are currently fresh in
|
|
305
|
-
``sys.modules
|
|
305
|
+
``sys.modules``, either freshly reloaded by this call, or
|
|
306
306
|
already reloaded by an earlier host for the same version.
|
|
307
307
|
"""
|
|
308
308
|
with ModuleReloader._reload_lock:
|
|
@@ -9,7 +9,7 @@ The engine is invoked by the reconciler after each commit pass:
|
|
|
9
9
|
|
|
10
10
|
1. The reconciler maintains a parallel
|
|
11
11
|
[`LayoutNode`][pythonnative.layout.LayoutNode] tree (cached across
|
|
12
|
-
passes
|
|
12
|
+
passes: clean subtrees keep their nodes, dirty ones are rebuilt).
|
|
13
13
|
2. [`calculate_layout`][pythonnative.layout.calculate_layout] is called
|
|
14
14
|
with the viewport size; it recursively determines each node's
|
|
15
15
|
``(x, y, width, height)`` relative to its parent's coordinate space.
|
|
@@ -618,7 +618,7 @@ def _measure_node(
|
|
|
618
618
|
resolved_direction = _resolve_direction(style, direction)
|
|
619
619
|
|
|
620
620
|
# Incremental-layout memo: a clean node measured under identical
|
|
621
|
-
# inputs reuses its previous result without recursing
|
|
621
|
+
# inputs reuses its previous result without recursing; its whole
|
|
622
622
|
# subtree keeps the sizes from the prior pass.
|
|
623
623
|
memo = node._measure_memo
|
|
624
624
|
if (
|
|
@@ -863,7 +863,7 @@ def _layout_flex_children(
|
|
|
863
863
|
their line's cross size. The computed line structure is stored on
|
|
864
864
|
``parent._lines`` for the positioning pass.
|
|
865
865
|
|
|
866
|
-
Returns ``(used_main, used_cross)
|
|
866
|
+
Returns ``(used_main, used_cross)``, the total content size used
|
|
867
867
|
by the in-flow children, including inter-child gaps but excluding
|
|
868
868
|
the parent's own padding. The caller adds padding back in for the
|
|
869
869
|
container's outer size.
|
|
@@ -49,7 +49,7 @@ class CreateOp:
|
|
|
49
49
|
Attributes:
|
|
50
50
|
tag: Unique integer identity assigned by the reconciler.
|
|
51
51
|
type_name: Element type name (e.g. ``"Text"``).
|
|
52
|
-
props: Initial *clean* props
|
|
52
|
+
props: Initial *clean* props; callables have already been
|
|
53
53
|
routed to the [`EventRegistry`][pythonnative.events.EventRegistry]
|
|
54
54
|
and replaced by the ``_pn_events`` name set.
|
|
55
55
|
"""
|
|
@@ -152,7 +152,7 @@ def _ios_launch_picker(on_result: Callable[[Optional[str]], None], source: str)
|
|
|
152
152
|
_pending_delegates.pop(id(delegate), None)
|
|
153
153
|
on_result(None)
|
|
154
154
|
|
|
155
|
-
# Reference SEL/objc_method so the lint pass keeps the import
|
|
155
|
+
# Reference SEL/objc_method so the lint pass keeps the import;
|
|
156
156
|
# they're needed for the delegate class above.
|
|
157
157
|
_ = (SEL, objc_method)
|
|
158
158
|
except Exception:
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
Two interfaces live here:
|
|
4
4
|
|
|
5
|
-
- [`Haptics`][pythonnative.Haptics]
|
|
5
|
+
- [`Haptics`][pythonnative.Haptics]: semantic, iOS-style feedback
|
|
6
6
|
(impact / notification / selection) backed by
|
|
7
7
|
``UIFeedbackGenerator`` on iOS and ``VibrationEffect`` patterns on
|
|
8
8
|
Android.
|
|
9
|
-
- [`Vibration`][pythonnative.Vibration]
|
|
9
|
+
- [`Vibration`][pythonnative.Vibration]: a blunt "buzz for N
|
|
10
10
|
milliseconds" interface for cases where you want an explicit
|
|
11
11
|
duration.
|
|
12
12
|
|
|
@@ -167,7 +167,7 @@ def _android_get(on_result: Callable[[Optional[Coords]], None]) -> None:
|
|
|
167
167
|
Context = jclass("android.content.Context")
|
|
168
168
|
lm = ctx.getSystemService(Context.LOCATION_SERVICE)
|
|
169
169
|
|
|
170
|
-
# Try the most recent known fix first
|
|
170
|
+
# Try the most recent known fix first; it's instant and avoids
|
|
171
171
|
# the GPS warm-up delay.
|
|
172
172
|
try:
|
|
173
173
|
for provider in ("gps", "network", "passive"):
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
[`Permissions`][pythonnative.Permissions] normalizes the very different
|
|
4
4
|
iOS and Android permission models behind two calls:
|
|
5
5
|
|
|
6
|
-
- ``check(permission)
|
|
6
|
+
- ``check(permission)``: synchronous, returns a status string without
|
|
7
7
|
prompting.
|
|
8
|
-
- ``request(permission)
|
|
8
|
+
- ``request(permission)``: a coroutine that shows the system prompt
|
|
9
9
|
(if needed) and resolves to the resulting status.
|
|
10
10
|
|
|
11
11
|
Statuses are ``"granted"``, ``"denied"``, ``"blocked"`` (denied with
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Encrypted key/value storage for secrets (tokens, credentials).
|
|
2
2
|
|
|
3
3
|
[`SecureStore`][pythonnative.SecureStore] persists small string values
|
|
4
|
-
in the iOS Keychain and Android ``EncryptedSharedPreferences
|
|
4
|
+
in the iOS Keychain and Android ``EncryptedSharedPreferences``, the
|
|
5
5
|
right place for auth tokens and other secrets that
|
|
6
6
|
[`AsyncStorage`][pythonnative.AsyncStorage] (plain, unencrypted) should
|
|
7
7
|
never hold.
|