pythonnative 0.24.0__tar.gz → 0.25.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.24.0/src/pythonnative.egg-info → pythonnative-0.25.0}/PKG-INFO +2 -1
- {pythonnative-0.24.0 → pythonnative-0.25.0}/README.md +1 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/pyproject.toml +1 -1
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/__init__.py +16 -4
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/animated.py +2 -2
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/components.py +59 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/hooks.py +364 -81
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/native_modules/notifications.py +36 -4
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/native_modules/permissions.py +24 -1
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/native_views/android.py +7 -2
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/native_views/ios.py +12 -1
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/reconciler.py +518 -37
- pythonnative-0.25.0/src/pythonnative/runtime.py +704 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/screen.py +53 -7
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/storage.py +2 -2
- pythonnative-0.25.0/src/pythonnative/suspense.py +417 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0/src/pythonnative.egg-info}/PKG-INFO +2 -1
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative.egg-info/SOURCES.txt +3 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/tests/test_async_hooks.py +110 -83
- pythonnative-0.25.0/tests/test_runtime.py +252 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/tests/test_storage.py +15 -23
- pythonnative-0.25.0/tests/test_suspense.py +547 -0
- pythonnative-0.25.0/tests/test_transitions.py +178 -0
- pythonnative-0.24.0/src/pythonnative/runtime.py +0 -512
- pythonnative-0.24.0/tests/test_runtime.py +0 -146
- {pythonnative-0.24.0 → pythonnative-0.25.0}/LICENSE +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/setup.cfg +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/_ios_log.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/alerts.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/appearance.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/cli/__init__.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/cli/pn.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/diagnostics.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/element.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/events.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/gestures.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/hot_reload.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/images.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/layout.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/mutations.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/native_modules/__init__.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/native_modules/app_state.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/native_modules/battery.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/native_modules/biometrics.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/native_modules/camera.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/native_modules/clipboard.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/native_modules/file_system.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/native_modules/haptics.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/native_modules/linking.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/native_modules/location.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/native_modules/net_info.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/native_modules/secure_store.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/native_modules/share.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/native_views/__init__.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/native_views/base.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/native_views/desktop.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/navigation.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/net.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/platform.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/platform_metrics.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/preview.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/project/__init__.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/project/android.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/project/builder.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/project/config.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/project/doctor.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/project/icons.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/project/ios.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/project/permissions.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/project/runtime_assets.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/sdk/__init__.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/sdk/_components.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/style.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/android_template/app/build.gradle +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/android_template/app/proguard-rules.pro +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/android_template/app/src/androidTest/java/com/pythonnative/android_template/ExampleInstrumentedTest.kt +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/android_template/app/src/main/AndroidManifest.xml +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/MainActivity.kt +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/Navigator.kt +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/PNAccessibilityDelegate.kt +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/PNBorderDrawable.kt +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/PNVirtualListView.java +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/ScreenFragment.kt +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/android_template/app/src/main/res/drawable/ic_launcher_background.xml +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/android_template/app/src/main/res/drawable-v24/ic_launcher_foreground.xml +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/android_template/app/src/main/res/layout/activity_main.xml +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-hdpi/ic_launcher.webp +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-mdpi/ic_launcher.webp +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-xhdpi/ic_launcher.webp +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/android_template/app/src/main/res/navigation/nav_graph.xml +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/android_template/app/src/main/res/values/colors.xml +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/android_template/app/src/main/res/values/strings.xml +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/android_template/app/src/main/res/values/themes.xml +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/android_template/app/src/main/res/values-night/themes.xml +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/android_template/app/src/main/res/xml/backup_rules.xml +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/android_template/app/src/main/res/xml/data_extraction_rules.xml +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/android_template/app/src/test/java/com/pythonnative/android_template/ExampleUnitTest.kt +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/android_template/build.gradle +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/android_template/gradle/wrapper/gradle-wrapper.jar +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/android_template/gradle/wrapper/gradle-wrapper.properties +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/android_template/gradle.properties +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/android_template/gradlew +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/android_template/gradlew.bat +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/android_template/settings.gradle +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/ios_template/ios_template/AppDelegate.swift +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/ios_template/ios_template/Assets.xcassets/AccentColor.colorset/Contents.json +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/ios_template/ios_template/Assets.xcassets/AppIcon.appiconset/Contents.json +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/ios_template/ios_template/Assets.xcassets/Contents.json +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/ios_template/ios_template/Base.lproj/LaunchScreen.storyboard +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/ios_template/ios_template/Base.lproj/Main.storyboard +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/ios_template/ios_template/Info.plist +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/ios_template/ios_template/SceneDelegate.swift +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/ios_template/ios_template/ViewController.swift +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/ios_template/ios_template.xcodeproj/project.pbxproj +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/ios_template/ios_template.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/ios_template/ios_templateTests/ios_templateTests.swift +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/ios_template/ios_templateUITests/ios_templateUITests.swift +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/templates/ios_template/ios_templateUITests/ios_templateUITestsLaunchTests.swift +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/utils.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative/virtual_rows.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative.egg-info/dependency_links.txt +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative.egg-info/entry_points.txt +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative.egg-info/requires.txt +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/src/pythonnative.egg-info/top_level.txt +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/tests/test_alert.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/tests/test_animated.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/tests/test_appearance.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/tests/test_cli.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/tests/test_components.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/tests/test_core_semantics.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/tests/test_desktop_backend.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/tests/test_element.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/tests/test_events.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/tests/test_extended_components.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/tests/test_gestures.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/tests/test_hooks.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/tests/test_hot_reload.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/tests/test_images.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/tests/test_incremental_render.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/tests/test_ios_log.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/tests/test_layout.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/tests/test_metric_hooks.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/tests/test_mutations.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/tests/test_native_lists.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/tests/test_native_modules.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/tests/test_native_views.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/tests/test_navigation.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/tests/test_net.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/tests/test_new_components.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/tests/test_platform.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/tests/test_platform_metrics.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/tests/test_reconciler.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/tests/test_ref.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/tests/test_screen.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/tests/test_sdk.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/tests/test_smoke.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.0}/tests/test_style.py +0 -0
- {pythonnative-0.24.0 → pythonnative-0.25.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.25.0
|
|
4
4
|
Summary: Cross-platform native UI toolkit for Android and iOS
|
|
5
5
|
Author: Owen Carey
|
|
6
6
|
License: MIT License
|
|
@@ -105,6 +105,7 @@ PythonNative is a cross-platform toolkit for building native Android and iOS app
|
|
|
105
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
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` / `use_layout_effect`, refs and imperative handles with `use_ref` / `use_imperative_handle`, and navigation with `use_navigation`, all through one consistent pattern. Components can return a single element, a list of siblings, or `None`, and `Fragment`, `Portal`, and reactive `Provider` context work the way they do in React.
|
|
108
|
+
- **Async-first rendering:** One `asyncio` event loop runs the whole framework on the platform's main thread. Components can be `async def` and `await` data directly in the body; `Suspense` boundaries show declarative loading states while they wait. `use_resource` fetches during render, `use_effect` accepts coroutine callbacks (cancelled automatically on unmount), `lazy` code-splits components, and `use_transition` / `use_deferred_value` keep the UI responsive during expensive updates.
|
|
108
109
|
- **Developer feedback that finds your bugs:** In dev mode (`pn preview`, hot reload, or `PN_DEV=1`), uncaught errors from renders, effects, and event handlers show a full-screen RedBox with the traceback; unknown style keys and duplicate list keys print "did you mean" warnings; and conditional hooks raise a `HookOrderError` at the source instead of silently cross-wiring state.
|
|
109
110
|
- **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`.
|
|
110
111
|
- **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.
|
|
@@ -34,6 +34,7 @@ PythonNative is a cross-platform toolkit for building native Android and iOS app
|
|
|
34
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
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` / `use_layout_effect`, refs and imperative handles with `use_ref` / `use_imperative_handle`, and navigation with `use_navigation`, all through one consistent pattern. Components can return a single element, a list of siblings, or `None`, and `Fragment`, `Portal`, and reactive `Provider` context work the way they do in React.
|
|
37
|
+
- **Async-first rendering:** One `asyncio` event loop runs the whole framework on the platform's main thread. Components can be `async def` and `await` data directly in the body; `Suspense` boundaries show declarative loading states while they wait. `use_resource` fetches during render, `use_effect` accepts coroutine callbacks (cancelled automatically on unmount), `lazy` code-splits components, and `use_transition` / `use_deferred_value` keep the UI responsive during expensive updates.
|
|
37
38
|
- **Developer feedback that finds your bugs:** In dev mode (`pn preview`, hot reload, or `PN_DEV=1`), uncaught errors from renders, effects, and event handlers show a full-screen RedBox with the traceback; unknown style keys and duplicate list keys print "did you mean" warnings; and conditional hooks raise a `HookOrderError` at the source instead of silently cross-wiring state.
|
|
38
39
|
- **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`.
|
|
39
40
|
- **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.
|
|
@@ -60,7 +60,7 @@ Example:
|
|
|
60
60
|
```
|
|
61
61
|
"""
|
|
62
62
|
|
|
63
|
-
__version__ = "0.
|
|
63
|
+
__version__ = "0.25.0"
|
|
64
64
|
|
|
65
65
|
from . import appearance, diagnostics, gestures, images, runtime, sdk
|
|
66
66
|
from .alerts import Alert
|
|
@@ -92,6 +92,7 @@ from .components import (
|
|
|
92
92
|
Slider,
|
|
93
93
|
Spacer,
|
|
94
94
|
StatusBar,
|
|
95
|
+
Suspense,
|
|
95
96
|
Switch,
|
|
96
97
|
Text,
|
|
97
98
|
TextInput,
|
|
@@ -111,11 +112,11 @@ from .hooks import (
|
|
|
111
112
|
component,
|
|
112
113
|
create_context,
|
|
113
114
|
memo,
|
|
114
|
-
use_async_effect,
|
|
115
115
|
use_back_handler,
|
|
116
116
|
use_callback,
|
|
117
117
|
use_color_scheme,
|
|
118
118
|
use_context,
|
|
119
|
+
use_deferred_value,
|
|
119
120
|
use_effect,
|
|
120
121
|
use_imperative_handle,
|
|
121
122
|
use_keyboard_height,
|
|
@@ -126,8 +127,10 @@ from .hooks import (
|
|
|
126
127
|
use_query,
|
|
127
128
|
use_reducer,
|
|
128
129
|
use_ref,
|
|
130
|
+
use_resource,
|
|
129
131
|
use_safe_area_insets,
|
|
130
132
|
use_state,
|
|
133
|
+
use_transition,
|
|
131
134
|
use_window_dimensions,
|
|
132
135
|
)
|
|
133
136
|
from .native_modules import (
|
|
@@ -160,7 +163,7 @@ from .navigation import (
|
|
|
160
163
|
)
|
|
161
164
|
from .net import HTTPError, Response, fetch
|
|
162
165
|
from .platform import Platform
|
|
163
|
-
from .runtime import run_async
|
|
166
|
+
from .runtime import run_async, run_blocking
|
|
164
167
|
from .screen import create_screen
|
|
165
168
|
from .sdk import (
|
|
166
169
|
Props,
|
|
@@ -204,6 +207,7 @@ from .style import (
|
|
|
204
207
|
style,
|
|
205
208
|
use_theme,
|
|
206
209
|
)
|
|
210
|
+
from .suspense import Resource, lazy, start_resource
|
|
207
211
|
|
|
208
212
|
__all__ = [
|
|
209
213
|
# Components
|
|
@@ -233,6 +237,7 @@ __all__ = [
|
|
|
233
237
|
"Slider",
|
|
234
238
|
"Spacer",
|
|
235
239
|
"StatusBar",
|
|
240
|
+
"Suspense",
|
|
236
241
|
"Switch",
|
|
237
242
|
"Text",
|
|
238
243
|
"TextInput",
|
|
@@ -251,11 +256,11 @@ __all__ = [
|
|
|
251
256
|
"MutationState",
|
|
252
257
|
"QueryResult",
|
|
253
258
|
"Ref",
|
|
254
|
-
"use_async_effect",
|
|
255
259
|
"use_back_handler",
|
|
256
260
|
"use_callback",
|
|
257
261
|
"use_color_scheme",
|
|
258
262
|
"use_context",
|
|
263
|
+
"use_deferred_value",
|
|
259
264
|
"use_effect",
|
|
260
265
|
"use_focus_effect",
|
|
261
266
|
"use_imperative_handle",
|
|
@@ -268,11 +273,17 @@ __all__ = [
|
|
|
268
273
|
"use_query",
|
|
269
274
|
"use_reducer",
|
|
270
275
|
"use_ref",
|
|
276
|
+
"use_resource",
|
|
271
277
|
"use_route",
|
|
272
278
|
"use_safe_area_insets",
|
|
273
279
|
"use_state",
|
|
280
|
+
"use_transition",
|
|
274
281
|
"use_window_dimensions",
|
|
275
282
|
"Provider",
|
|
283
|
+
# Suspense and async rendering
|
|
284
|
+
"Resource",
|
|
285
|
+
"lazy",
|
|
286
|
+
"start_resource",
|
|
276
287
|
# Navigation
|
|
277
288
|
"NavigationContainer",
|
|
278
289
|
"ScreenOptions",
|
|
@@ -349,6 +360,7 @@ __all__ = [
|
|
|
349
360
|
"Response",
|
|
350
361
|
# Runtime
|
|
351
362
|
"run_async",
|
|
363
|
+
"run_blocking",
|
|
352
364
|
"runtime",
|
|
353
365
|
# Diagnostics
|
|
354
366
|
"HookOrderError",
|
|
@@ -47,7 +47,7 @@ Example:
|
|
|
47
47
|
await pn.Animated.timing(opacity, to=1.0, duration=400)
|
|
48
48
|
await pn.Animated.timing(opacity, to=0.5, duration=200)
|
|
49
49
|
|
|
50
|
-
pn.
|
|
50
|
+
pn.use_effect(fade_in, [])
|
|
51
51
|
|
|
52
52
|
return pn.Animated.View(
|
|
53
53
|
pn.Text("Hello!"),
|
|
@@ -1014,7 +1014,7 @@ def use_animated_value(initial: float = 0.0) -> AnimatedValue:
|
|
|
1014
1014
|
async def fade_in():
|
|
1015
1015
|
await pn.Animated.timing(opacity, to=1.0, duration=300)
|
|
1016
1016
|
|
|
1017
|
-
pn.
|
|
1017
|
+
pn.use_effect(fade_in, [])
|
|
1018
1018
|
return pn.Animated.View(
|
|
1019
1019
|
pn.Text("Hello"),
|
|
1020
1020
|
style=pn.style(opacity=opacity),
|
|
@@ -1732,6 +1732,65 @@ def ErrorBoundary(
|
|
|
1732
1732
|
return Element("__ErrorBoundary__", props, list(children), key=key)
|
|
1733
1733
|
|
|
1734
1734
|
|
|
1735
|
+
def Suspense(
|
|
1736
|
+
*children: Element,
|
|
1737
|
+
fallback: Optional[Any] = None,
|
|
1738
|
+
key: Optional[str] = None,
|
|
1739
|
+
) -> Element:
|
|
1740
|
+
"""Show ``fallback`` while descendants wait on async work, then swap in the content.
|
|
1741
|
+
|
|
1742
|
+
A Suspense boundary catches **suspensions** from the subtree it
|
|
1743
|
+
wraps: an ``async def`` component body blocking on a pending
|
|
1744
|
+
await, or a regular component calling
|
|
1745
|
+
[`Resource.read`][pythonnative.suspense.Resource.read] on data that hasn't
|
|
1746
|
+
arrived (see [`use_resource`][pythonnative.use_resource] and
|
|
1747
|
+
[`lazy`][pythonnative.lazy]). While anything is pending the
|
|
1748
|
+
boundary renders ``fallback``; when the awaited work completes it
|
|
1749
|
+
retries the content and swaps it in. Suspended components keep
|
|
1750
|
+
their hook state across retries, so cached resources aren't
|
|
1751
|
+
refetched.
|
|
1752
|
+
|
|
1753
|
+
Two timing behaviors, matching React:
|
|
1754
|
+
|
|
1755
|
+
- **Initial mount**: the fallback shows until the content is ready.
|
|
1756
|
+
- **Updates**: a component that's already on screen and suspends
|
|
1757
|
+
again (its dependencies changed) keeps its previous content
|
|
1758
|
+
visible and re-renders when ready; there's no fallback flash.
|
|
1759
|
+
|
|
1760
|
+
Args:
|
|
1761
|
+
*children: Subtree to wrap (the async content).
|
|
1762
|
+
fallback: Content shown while suspended: an
|
|
1763
|
+
[`Element`][pythonnative.Element] or a zero-arg callable
|
|
1764
|
+
returning one. Without it, suspensions propagate to the
|
|
1765
|
+
next Suspense boundary up.
|
|
1766
|
+
key: Stable identity for keyed reconciliation.
|
|
1767
|
+
|
|
1768
|
+
Returns:
|
|
1769
|
+
An [`Element`][pythonnative.Element] of type ``"__Suspense__"``.
|
|
1770
|
+
|
|
1771
|
+
Example:
|
|
1772
|
+
```python
|
|
1773
|
+
import pythonnative as pn
|
|
1774
|
+
|
|
1775
|
+
@pn.component
|
|
1776
|
+
async def Profile(user_id: str):
|
|
1777
|
+
user = await api.fetch_user(user_id)
|
|
1778
|
+
return pn.Text(user.name)
|
|
1779
|
+
|
|
1780
|
+
@pn.component
|
|
1781
|
+
def Screen():
|
|
1782
|
+
return pn.Suspense(
|
|
1783
|
+
Profile(user_id="42"),
|
|
1784
|
+
fallback=pn.ActivityIndicator(),
|
|
1785
|
+
)
|
|
1786
|
+
```
|
|
1787
|
+
"""
|
|
1788
|
+
props: Dict[str, Any] = {}
|
|
1789
|
+
if fallback is not None:
|
|
1790
|
+
props["__fallback__"] = fallback
|
|
1791
|
+
return Element("__Suspense__", props, list(children), key=key)
|
|
1792
|
+
|
|
1793
|
+
|
|
1735
1794
|
# ======================================================================
|
|
1736
1795
|
# Lists (native virtualization with a Python-windowed fallback)
|
|
1737
1796
|
# ======================================================================
|