pythonnative 0.14.0__tar.gz → 0.16.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.
Files changed (117) hide show
  1. {pythonnative-0.14.0/src/pythonnative.egg-info → pythonnative-0.16.0}/PKG-INFO +5 -4
  2. {pythonnative-0.14.0 → pythonnative-0.16.0}/README.md +4 -3
  3. {pythonnative-0.14.0 → pythonnative-0.16.0}/pyproject.toml +3 -1
  4. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/__init__.py +120 -6
  5. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/animated.py +40 -2
  6. pythonnative-0.16.0/src/pythonnative/components.py +1515 -0
  7. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/hooks.py +74 -20
  8. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/native_views/__init__.py +62 -14
  9. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/native_views/android.py +96 -3
  10. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/native_views/base.py +3 -92
  11. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/native_views/ios.py +121 -2
  12. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/reconciler.py +123 -14
  13. pythonnative-0.16.0/src/pythonnative/sdk/__init__.py +131 -0
  14. pythonnative-0.16.0/src/pythonnative/sdk/_components.py +429 -0
  15. pythonnative-0.16.0/src/pythonnative/style.py +548 -0
  16. {pythonnative-0.14.0 → pythonnative-0.16.0/src/pythonnative.egg-info}/PKG-INFO +5 -4
  17. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative.egg-info/SOURCES.txt +3 -0
  18. {pythonnative-0.14.0 → pythonnative-0.16.0}/tests/test_animated.py +78 -1
  19. {pythonnative-0.14.0 → pythonnative-0.16.0}/tests/test_components.py +34 -0
  20. {pythonnative-0.14.0 → pythonnative-0.16.0}/tests/test_hooks.py +113 -0
  21. {pythonnative-0.14.0 → pythonnative-0.16.0}/tests/test_native_views.py +0 -59
  22. {pythonnative-0.14.0 → pythonnative-0.16.0}/tests/test_new_components.py +21 -16
  23. {pythonnative-0.14.0 → pythonnative-0.16.0}/tests/test_reconciler.py +62 -0
  24. pythonnative-0.16.0/tests/test_sdk.py +446 -0
  25. pythonnative-0.16.0/tests/test_style.py +170 -0
  26. pythonnative-0.14.0/src/pythonnative/components.py +0 -1215
  27. pythonnative-0.14.0/src/pythonnative/style.py +0 -196
  28. pythonnative-0.14.0/tests/test_style.py +0 -80
  29. {pythonnative-0.14.0 → pythonnative-0.16.0}/LICENSE +0 -0
  30. {pythonnative-0.14.0 → pythonnative-0.16.0}/setup.cfg +0 -0
  31. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/_ios_log.py +0 -0
  32. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/alerts.py +0 -0
  33. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/cli/__init__.py +0 -0
  34. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/cli/pn.py +0 -0
  35. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/element.py +0 -0
  36. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/hot_reload.py +0 -0
  37. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/layout.py +0 -0
  38. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/native_modules/__init__.py +0 -0
  39. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/native_modules/camera.py +0 -0
  40. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/native_modules/file_system.py +0 -0
  41. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/native_modules/location.py +0 -0
  42. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/native_modules/notifications.py +0 -0
  43. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/navigation.py +0 -0
  44. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/platform.py +0 -0
  45. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/platform_metrics.py +0 -0
  46. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/screen.py +0 -0
  47. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/android_template/app/build.gradle +0 -0
  48. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/android_template/app/proguard-rules.pro +0 -0
  49. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/android_template/app/src/androidTest/java/com/pythonnative/android_template/ExampleInstrumentedTest.kt +0 -0
  50. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/android_template/app/src/main/AndroidManifest.xml +0 -0
  51. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/MainActivity.kt +0 -0
  52. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/Navigator.kt +0 -0
  53. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/PNVirtualListView.java +0 -0
  54. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/ScreenFragment.kt +0 -0
  55. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/android_template/app/src/main/res/drawable/ic_launcher_background.xml +0 -0
  56. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/android_template/app/src/main/res/drawable-v24/ic_launcher_foreground.xml +0 -0
  57. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/android_template/app/src/main/res/layout/activity_main.xml +0 -0
  58. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +0 -0
  59. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +0 -0
  60. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-hdpi/ic_launcher.webp +0 -0
  61. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp +0 -0
  62. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-mdpi/ic_launcher.webp +0 -0
  63. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp +0 -0
  64. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-xhdpi/ic_launcher.webp +0 -0
  65. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp +0 -0
  66. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp +0 -0
  67. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp +0 -0
  68. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp +0 -0
  69. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/android_template/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp +0 -0
  70. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/android_template/app/src/main/res/navigation/nav_graph.xml +0 -0
  71. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/android_template/app/src/main/res/values/colors.xml +0 -0
  72. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/android_template/app/src/main/res/values/strings.xml +0 -0
  73. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/android_template/app/src/main/res/values/themes.xml +0 -0
  74. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/android_template/app/src/main/res/values-night/themes.xml +0 -0
  75. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/android_template/app/src/main/res/xml/backup_rules.xml +0 -0
  76. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/android_template/app/src/main/res/xml/data_extraction_rules.xml +0 -0
  77. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/android_template/app/src/test/java/com/pythonnative/android_template/ExampleUnitTest.kt +0 -0
  78. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/android_template/build.gradle +0 -0
  79. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/android_template/gradle/wrapper/gradle-wrapper.jar +0 -0
  80. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/android_template/gradle/wrapper/gradle-wrapper.properties +0 -0
  81. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/android_template/gradle.properties +0 -0
  82. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/android_template/gradlew +0 -0
  83. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/android_template/gradlew.bat +0 -0
  84. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/android_template/settings.gradle +0 -0
  85. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/ios_template/ios_template/AppDelegate.swift +0 -0
  86. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/ios_template/ios_template/Assets.xcassets/AccentColor.colorset/Contents.json +0 -0
  87. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/ios_template/ios_template/Assets.xcassets/AppIcon.appiconset/Contents.json +0 -0
  88. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/ios_template/ios_template/Assets.xcassets/Contents.json +0 -0
  89. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/ios_template/ios_template/Base.lproj/LaunchScreen.storyboard +0 -0
  90. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/ios_template/ios_template/Base.lproj/Main.storyboard +0 -0
  91. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/ios_template/ios_template/Info.plist +0 -0
  92. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/ios_template/ios_template/SceneDelegate.swift +0 -0
  93. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/ios_template/ios_template/ViewController.swift +0 -0
  94. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/ios_template/ios_template.xcodeproj/project.pbxproj +0 -0
  95. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/ios_template/ios_template.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -0
  96. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/ios_template/ios_templateTests/ios_templateTests.swift +0 -0
  97. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/ios_template/ios_templateUITests/ios_templateUITests.swift +0 -0
  98. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/templates/ios_template/ios_templateUITests/ios_templateUITestsLaunchTests.swift +0 -0
  99. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative/utils.py +0 -0
  100. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative.egg-info/dependency_links.txt +0 -0
  101. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative.egg-info/entry_points.txt +0 -0
  102. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative.egg-info/requires.txt +0 -0
  103. {pythonnative-0.14.0 → pythonnative-0.16.0}/src/pythonnative.egg-info/top_level.txt +0 -0
  104. {pythonnative-0.14.0 → pythonnative-0.16.0}/tests/test_alert.py +0 -0
  105. {pythonnative-0.14.0 → pythonnative-0.16.0}/tests/test_cli.py +0 -0
  106. {pythonnative-0.14.0 → pythonnative-0.16.0}/tests/test_element.py +0 -0
  107. {pythonnative-0.14.0 → pythonnative-0.16.0}/tests/test_hot_reload.py +0 -0
  108. {pythonnative-0.14.0 → pythonnative-0.16.0}/tests/test_ios_log.py +0 -0
  109. {pythonnative-0.14.0 → pythonnative-0.16.0}/tests/test_layout.py +0 -0
  110. {pythonnative-0.14.0 → pythonnative-0.16.0}/tests/test_metric_hooks.py +0 -0
  111. {pythonnative-0.14.0 → pythonnative-0.16.0}/tests/test_navigation.py +0 -0
  112. {pythonnative-0.14.0 → pythonnative-0.16.0}/tests/test_platform.py +0 -0
  113. {pythonnative-0.14.0 → pythonnative-0.16.0}/tests/test_platform_metrics.py +0 -0
  114. {pythonnative-0.14.0 → pythonnative-0.16.0}/tests/test_ref.py +0 -0
  115. {pythonnative-0.14.0 → pythonnative-0.16.0}/tests/test_screen.py +0 -0
  116. {pythonnative-0.14.0 → pythonnative-0.16.0}/tests/test_smoke.py +0 -0
  117. {pythonnative-0.14.0 → pythonnative-0.16.0}/tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pythonnative
3
- Version: 0.14.0
3
+ Version: 0.16.0
4
4
  Summary: Cross-platform native UI toolkit for Android and iOS
5
5
  Author: Owen Carey
6
6
  License: MIT License
@@ -96,10 +96,11 @@ PythonNative is a cross-platform toolkit for building native Android and iOS app
96
96
 
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
- - **`style` prop:** Pass all visual and layout properties through a single `style` dict, composable via `StyleSheet`.
99
+ - **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`.
100
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.
101
101
  - **Virtual view tree + reconciler:** Element trees are diffed and patched with minimal native mutations, similar to React's reconciliation.
102
102
  - **Direct native bindings:** Python calls platform APIs directly through Chaquopy and rubicon-objc, with no JavaScript bridge.
103
+ - **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.
103
104
  - **CLI scaffolding:** `pn init` creates a ready-to-run project; `pn run android` and `pn run ios` build and launch your app.
104
105
  - **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.
105
106
  - **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.
@@ -123,12 +124,12 @@ import pythonnative as pn
123
124
  def App():
124
125
  count, set_count = pn.use_state(0)
125
126
  return pn.Column(
126
- pn.Text(f"Count: {count}", style={"font_size": 24}),
127
+ pn.Text(f"Count: {count}", style=pn.style(font_size=24, bold=True)),
127
128
  pn.Button(
128
129
  "Tap me",
129
130
  on_click=lambda: set_count(count + 1),
130
131
  ),
131
- style={"spacing": 12, "padding": 16},
132
+ style=pn.style(spacing=12, padding=16),
132
133
  )
133
134
  ```
134
135
 
@@ -32,10 +32,11 @@ PythonNative is a cross-platform toolkit for building native Android and iOS app
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
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
- - **`style` prop:** Pass all visual and layout properties through a single `style` dict, composable via `StyleSheet`.
35
+ - **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`.
36
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.
37
37
  - **Virtual view tree + reconciler:** Element trees are diffed and patched with minimal native mutations, similar to React's reconciliation.
38
38
  - **Direct native bindings:** Python calls platform APIs directly through Chaquopy and rubicon-objc, with no JavaScript bridge.
39
+ - **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.
39
40
  - **CLI scaffolding:** `pn init` creates a ready-to-run project; `pn run android` and `pn run ios` build and launch your app.
40
41
  - **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.
41
42
  - **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.
@@ -59,12 +60,12 @@ import pythonnative as pn
59
60
  def App():
60
61
  count, set_count = pn.use_state(0)
61
62
  return pn.Column(
62
- pn.Text(f"Count: {count}", style={"font_size": 24}),
63
+ pn.Text(f"Count: {count}", style=pn.style(font_size=24, bold=True)),
63
64
  pn.Button(
64
65
  "Tap me",
65
66
  on_click=lambda: set_count(count + 1),
66
67
  ),
67
- style={"spacing": 12, "padding": 16},
68
+ style=pn.style(spacing=12, padding=16),
68
69
  )
69
70
  ```
70
71
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pythonnative"
7
- version = "0.14.0"
7
+ version = "0.16.0"
8
8
  description = "Cross-platform native UI toolkit for Android and iOS"
9
9
  authors = [
10
10
  { name = "Owen Carey" }
@@ -64,6 +64,8 @@ Documentation = "https://docs.pythonnative.com/"
64
64
 
65
65
 
66
66
 
67
+
68
+
67
69
  [tool.setuptools.packages.find]
68
70
  where = ["src"]
69
71
 
@@ -23,8 +23,18 @@ Key building blocks:
23
23
  factories.
24
24
  - **Styling** uses a single ``style`` dict per element (or a list of
25
25
  dicts), composable via [`StyleSheet`][pythonnative.StyleSheet].
26
+ PythonNative ships a fully-typed [`Style`][pythonnative.style.Style]
27
+ TypedDict so editors and ``mypy`` validate every key as you type.
26
28
  - **Animations** use the ``Animated`` namespace, modeled on React
27
29
  Native's animation API.
30
+ - **Custom native components** can be authored with the
31
+ ``pythonnative.sdk`` package: define a typed
32
+ [`Props`][pythonnative.sdk.Props] dataclass, implement a
33
+ [`ViewHandler`][pythonnative.native_views.base.ViewHandler] for each
34
+ platform, and register it via
35
+ [`@native_component`][pythonnative.sdk.native_component] (or expose
36
+ it from a PyPI package via the ``pythonnative.handlers`` entry-point
37
+ group).
28
38
 
29
39
  Example:
30
40
  ```python
@@ -34,42 +44,62 @@ Example:
34
44
  def App():
35
45
  count, set_count = pn.use_state(0)
36
46
  return pn.Column(
37
- pn.Text(f"Count: {count}", style={"font_size": 24}),
47
+ pn.Text(f"Count: {count}", style=pn.style(font_size=24)),
38
48
  pn.Button("+", on_click=lambda: set_count(count + 1)),
39
- style={"spacing": 12},
49
+ style=pn.style(spacing=12),
40
50
  )
41
51
  ```
42
52
  """
43
53
 
44
- __version__ = "0.14.0"
54
+ __version__ = "0.16.0"
45
55
 
56
+ from . import sdk
46
57
  from .alerts import Alert
47
- from .animated import Animated, AnimatedValue
58
+ from .animated import Animated, AnimatedValue, use_animated_value
48
59
  from .components import (
49
60
  ActivityIndicator,
61
+ ActivityIndicatorProps,
50
62
  Button,
63
+ ButtonProps,
51
64
  Column,
52
65
  ErrorBoundary,
53
66
  FlatList,
67
+ Fragment,
54
68
  Image,
69
+ ImageProps,
55
70
  KeyboardAvoidingView,
71
+ KeyboardAvoidingViewProps,
56
72
  Modal,
73
+ ModalProps,
57
74
  Picker,
75
+ PickerProps,
58
76
  Pressable,
77
+ PressableProps,
59
78
  ProgressBar,
79
+ ProgressBarProps,
60
80
  RefreshControl,
61
81
  Row,
62
82
  SafeAreaView,
83
+ SafeAreaViewProps,
63
84
  ScrollView,
85
+ ScrollViewProps,
64
86
  SectionList,
65
87
  Slider,
88
+ SliderProps,
66
89
  Spacer,
90
+ SpacerProps,
67
91
  StatusBar,
92
+ StatusBarProps,
68
93
  Switch,
94
+ SwitchProps,
69
95
  Text,
70
96
  TextInput,
97
+ TextInputProps,
98
+ TextProps,
71
99
  View,
100
+ ViewProps,
72
101
  WebView,
102
+ WebViewProps,
73
103
  )
74
104
  from .element import Element
75
105
  from .hooks import (
@@ -77,6 +107,7 @@ from .hooks import (
77
107
  batch_updates,
78
108
  component,
79
109
  create_context,
110
+ memo,
80
111
  use_callback,
81
112
  use_context,
82
113
  use_effect,
@@ -100,7 +131,39 @@ from .navigation import (
100
131
  )
101
132
  from .platform import Platform
102
133
  from .screen import create_screen
103
- from .style import StyleSheet, ThemeContext
134
+ from .sdk import (
135
+ Props,
136
+ ViewHandler,
137
+ element_factory,
138
+ native_component,
139
+ register_component,
140
+ )
141
+ from .style import (
142
+ AlignItems,
143
+ AlignSelf,
144
+ AutoCapitalize,
145
+ Color,
146
+ Dimension,
147
+ EdgeInsets,
148
+ FlexDirection,
149
+ FontWeight,
150
+ JustifyContent,
151
+ KeyboardType,
152
+ Overflow,
153
+ Position,
154
+ ReturnKeyType,
155
+ ScaleType,
156
+ ShadowOffset,
157
+ Style,
158
+ StyleProp,
159
+ StyleSheet,
160
+ TextAlign,
161
+ TextDecoration,
162
+ ThemeContext,
163
+ TransformSpec,
164
+ resolve_style,
165
+ style,
166
+ )
104
167
 
105
168
  __all__ = [
106
169
  # Components
@@ -109,6 +172,7 @@ __all__ = [
109
172
  "Column",
110
173
  "ErrorBoundary",
111
174
  "FlatList",
175
+ "Fragment",
112
176
  "Image",
113
177
  "KeyboardAvoidingView",
114
178
  "Modal",
@@ -128,6 +192,25 @@ __all__ = [
128
192
  "TextInput",
129
193
  "View",
130
194
  "WebView",
195
+ # Built-in Props dataclasses
196
+ "ActivityIndicatorProps",
197
+ "ButtonProps",
198
+ "ImageProps",
199
+ "KeyboardAvoidingViewProps",
200
+ "ModalProps",
201
+ "PickerProps",
202
+ "PressableProps",
203
+ "ProgressBarProps",
204
+ "SafeAreaViewProps",
205
+ "ScrollViewProps",
206
+ "SliderProps",
207
+ "SpacerProps",
208
+ "StatusBarProps",
209
+ "SwitchProps",
210
+ "TextInputProps",
211
+ "TextProps",
212
+ "ViewProps",
213
+ "WebViewProps",
131
214
  # Core
132
215
  "Element",
133
216
  "create_screen",
@@ -135,6 +218,7 @@ __all__ = [
135
218
  "batch_updates",
136
219
  "component",
137
220
  "create_context",
221
+ "memo",
138
222
  "use_callback",
139
223
  "use_context",
140
224
  "use_effect",
@@ -154,12 +238,35 @@ __all__ = [
154
238
  "create_drawer_navigator",
155
239
  "create_stack_navigator",
156
240
  "create_tab_navigator",
157
- # Styling
241
+ # Styling - typed primitives
242
+ "AlignItems",
243
+ "AlignSelf",
244
+ "AutoCapitalize",
245
+ "Color",
246
+ "Dimension",
247
+ "EdgeInsets",
248
+ "FlexDirection",
249
+ "FontWeight",
250
+ "JustifyContent",
251
+ "KeyboardType",
252
+ "Overflow",
253
+ "Position",
254
+ "ReturnKeyType",
255
+ "ScaleType",
256
+ "ShadowOffset",
257
+ "Style",
258
+ "StyleProp",
158
259
  "StyleSheet",
260
+ "TextAlign",
261
+ "TextDecoration",
159
262
  "ThemeContext",
263
+ "TransformSpec",
264
+ "resolve_style",
265
+ "style",
160
266
  # Animation
161
267
  "Animated",
162
268
  "AnimatedValue",
269
+ "use_animated_value",
163
270
  # Imperative
164
271
  "Alert",
165
272
  # Native modules
@@ -169,4 +276,11 @@ __all__ = [
169
276
  "Notifications",
170
277
  # Platform
171
278
  "Platform",
279
+ # Custom-component SDK
280
+ "Props",
281
+ "ViewHandler",
282
+ "element_factory",
283
+ "native_component",
284
+ "register_component",
285
+ "sdk",
172
286
  ]
@@ -58,7 +58,7 @@ from typing import Any, Callable, Dict, List, Optional, Tuple
58
58
 
59
59
  from .element import Element
60
60
  from .hooks import use_effect, use_ref
61
- from .style import StyleValue, resolve_style
61
+ from .style import StyleProp, resolve_style
62
62
 
63
63
  # Maximum frame rate at which the Python ticker drives animations.
64
64
  # We aim for 60 Hz but back off when no animation is active.
@@ -433,7 +433,7 @@ class _AnimationHandle:
433
433
  # ======================================================================
434
434
 
435
435
 
436
- def _resolve_style_with_values(style: StyleValue) -> Tuple[Dict[str, Any], Dict[str, AnimatedValue]]:
436
+ def _resolve_style_with_values(style: StyleProp) -> Tuple[Dict[str, Any], Dict[str, AnimatedValue]]:
437
437
  """Return ``(plain_style, animated_bindings)``.
438
438
 
439
439
  AnimatedValue entries in the style are replaced with their
@@ -661,7 +661,45 @@ class _AnimatedNamespace:
661
661
  Animated = _AnimatedNamespace()
662
662
 
663
663
 
664
+ def use_animated_value(initial: float = 0.0) -> AnimatedValue:
665
+ """Return an [`AnimatedValue`][pythonnative.AnimatedValue] with a stable identity across renders.
666
+
667
+ Convenience wrapper for the common pattern
668
+ ``pn.use_memo(lambda: AnimatedValue(initial), [])``. The same
669
+ instance is returned on every render of the same component, so
670
+ you can drive it from event handlers without recreating it.
671
+
672
+ Args:
673
+ initial: The starting numeric value.
674
+
675
+ Returns:
676
+ A mount-stable [`AnimatedValue`][pythonnative.AnimatedValue].
677
+
678
+ Example:
679
+ ```python
680
+ import pythonnative as pn
681
+
682
+ @pn.component
683
+ def FadeIn():
684
+ opacity = pn.use_animated_value(0.0)
685
+
686
+ def fade_in():
687
+ pn.Animated.timing(opacity, to=1.0, duration=300).start()
688
+
689
+ pn.use_effect(lambda: fade_in(), [])
690
+ return pn.Animated.View(
691
+ pn.Text("Hello"),
692
+ style=pn.style(opacity=opacity),
693
+ )
694
+ ```
695
+ """
696
+ from .hooks import use_memo
697
+
698
+ return use_memo(lambda: AnimatedValue(initial), [])
699
+
700
+
664
701
  __all__ = [
665
702
  "AnimatedValue",
666
703
  "Animated",
704
+ "use_animated_value",
667
705
  ]