FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

feat!: close React Native parity gaps, and fix correctness bugs by owenthcarey · Pull Request #104 · pythonnative/pythonnative · GitHub

feat!: close React Native parity gaps, and fix correctness bugs - #104

Merged
owenthcarey merged 2 commits into
mainfrom
feat/core-parity-correctness
Sep 21, 2026
Merged

owenthcarey merged 2 commits into
mainfrom
feat/core-parity-correctness

Conversation

Copy link
Copy Markdown
Contributor

Implement RFC 0002 (rfcs/0002-core-parity-and-correctness.md) across Python, Swift, Kotlin, and the browser preview.

Runtime correctness

  • Route use_effect and use_layout_effect errors to the nearest ErrorBoundary; post-commit Python errors no longer retire the surface.
  • Keep Suspense siblings mounted (hidden) when a new descendant suspends.
  • Step async components eagerly so resolved awaits render inline.
  • Batch state updates automatically on every host; one render-storm policy (50 passes, RuntimeError through the boundary and RedBox).
  • Dev warnings for unkeyed lists, setters after unmount or during render, in-place mutations, and changing dependency lengths.

Components, style, and accessibility

  • Pressable disabled/delay_long_press/android_ripple and PressState; ScrollView horizontal, content_container_style, insets, throttle, drag and momentum events, snapping, keyboard persistence; Text ellipsize_mode, selectable, allow_font_scaling, pressable spans; TextInput selection, key presses, content size, keyboard appearance; Image load lifecycle, fade, headers; Modal on_request_close; StatusBar translucent/animated; FlatList/SectionList inverted, separators, initial index, sticky section headers.
  • Typed event records (LayoutEvent, ScrollEvent, SelectionEvent, KeyPressEvent, ContentSizeEvent) and typed imperative handles (ViewHandle, TextInputHandle, ScrollViewHandle, WebViewHandle).
  • border_style, inset shorthands, 3D transforms, DynamicColor on every renderer; pn.style typed with Unpack[Style].
  • accessibility_value/actions/important_for_accessibility on every view.

Device APIs

  • AccessibilityInfo, Keyboard, Dimensions, PixelRatio, Device, Localization modules with hooks; iOS keyboard height; Android camera full-resolution capture, location permission prompt; SecureStore raises on failure.

Navigation

  • Navigator screen_options, Group, create_navigation_ref, pop_to, before_remove on every removal with an iOS guarded-back path, NavigationTheme with dark mode, tab bar styling, tab_bar_visible, freeze_on_blur, presentation and animation variants on iOS and Android, Android slide transitions, back arrow, inset-aware toolbar, large titles, and predictive back. The browser preview's native stacks draw navigation bars.

Animation and gestures

  • React Native's decay model everywhere, composed iOS transform channels, Easing namespace with bezier passthrough, AnimationResult, a clear error for non-animatable props; gesture enabled flags, Pan offsets, max_pointers, min_velocity, and absolute coordinates.

Found on the simulator and emulator

  • Events a view emits while its own commit applies carry that commit's identity, so a new Image's on_load_start arrives.
  • Pressable spans are bounded by their glyphs; Android Text labels with on_press are clickable.
  • Horizontal ScrollView content lays out in a row on every renderer.
  • WebViewHandle.eval_js settles with the page's answer through an async WebViews module.
  • iOS Pan gestures with activation offsets begin; iOS single-line fields report Enter; TextInputHandle.clear() reports on_change everywhere.
  • A reopened Modal shows its content on iOS and Android; one iOS sheet pull-down is one on_request_close; on_dismiss fires on every renderer when visible turns false; overlay backdrop taps request close.

Testing, tooling, and docs

  • Role, placeholder, and display-value queries, find_by_*, within, wait_for, a fake clock, and a pytest plugin.
  • pn start names missing requirements with an exact install command.
  • Regenerated native contracts, 115 e2e demos and Maestro flows, updated guides and API reference.

Removals

  • The Python view-handler layer (NativeViewRegistry, ViewHandler, register_component, native_component, get_registry), scroll_axis, positional Context.Provider values, dict event payloads, Ref._pn_tag and _pn_frame, free-form easing strings, the eval_js view command, the unused requests dependency, duplicate equality helpers, and dead host hooks.

BREAKING CHANGE: Context.Provider takes value as a keyword; ScrollView uses horizontal instead of scroll_axis; on_layout, on_scroll, and on_selection_change deliver dataclasses; Pressable style callables receive PressState; refs on built-in elements hold typed handles; sdk register_component and native_component are replaced by define_component; pythonnative.native_views.get_registry is replaced by get_backend; Animated.decay uses React Native's model; SecureStore.set_item and delete_item raise on failure; a Modal no longer closes itself on a back press or backdrop tap and calls on_request_close instead.

Implement RFC 0002 (rfcs/0002-core-parity-and-correctness.md) across
Python, Swift, Kotlin, and the browser preview.

Runtime correctness
- Route use_effect and use_layout_effect errors to the nearest
  ErrorBoundary; post-commit Python errors no longer retire the surface.
- Keep Suspense siblings mounted (hidden) when a new descendant
  suspends.
- Step async components eagerly so resolved awaits render inline.
- Batch state updates automatically on every host; one render-storm
  policy (50 passes, RuntimeError through the boundary and RedBox).
- Dev warnings for unkeyed lists, setters after unmount or during
  render, in-place mutations, and changing dependency lengths.

Components, style, and accessibility
- Pressable disabled/delay_long_press/android_ripple and PressState;
  ScrollView horizontal, content_container_style, insets, throttle, drag
  and momentum events, snapping, keyboard persistence; Text
  ellipsize_mode, selectable, allow_font_scaling, pressable spans;
  TextInput selection, key presses, content size, keyboard appearance;
  Image load lifecycle, fade, headers; Modal on_request_close; StatusBar
  translucent/animated; FlatList/SectionList inverted, separators,
  initial index, sticky section headers.
- Typed event records (LayoutEvent, ScrollEvent, SelectionEvent,
  KeyPressEvent, ContentSizeEvent) and typed imperative handles
  (ViewHandle, TextInputHandle, ScrollViewHandle, WebViewHandle).
- border_style, inset shorthands, 3D transforms, DynamicColor on every
  renderer; pn.style typed with Unpack[Style].
- accessibility_value/actions/important_for_accessibility on every view.

Device APIs
- AccessibilityInfo, Keyboard, Dimensions, PixelRatio, Device,
  Localization modules with hooks; iOS keyboard height; Android camera
  full-resolution capture, location permission prompt; SecureStore
  raises on failure.

Navigation
- Navigator screen_options, Group, create_navigation_ref, pop_to,
  before_remove on every removal with an iOS guarded-back path,
  NavigationTheme with dark mode, tab bar styling, tab_bar_visible,
  freeze_on_blur, presentation and animation variants on iOS and
  Android, Android slide transitions, back arrow, inset-aware toolbar,
  large titles, and predictive back. The browser preview's native stacks
  draw navigation bars.

Animation and gestures
- React Native's decay model everywhere, composed iOS transform
  channels, Easing namespace with bezier passthrough, AnimationResult, a
  clear error for non-animatable props; gesture enabled flags, Pan
  offsets, max_pointers, min_velocity, and absolute coordinates.

Found on the simulator and emulator
- Events a view emits while its own commit applies carry that commit's
  identity, so a new Image's on_load_start arrives.
- Pressable spans are bounded by their glyphs; Android Text labels with
  on_press are clickable.
- Horizontal ScrollView content lays out in a row on every renderer.
- WebViewHandle.eval_js settles with the page's answer through an async
  WebViews module.
- iOS Pan gestures with activation offsets begin; iOS single-line fields
  report Enter; TextInputHandle.clear() reports on_change everywhere.
- A reopened Modal shows its content on iOS and Android; one iOS sheet
  pull-down is one on_request_close; on_dismiss fires on every renderer
  when visible turns false; overlay backdrop taps request close.

Testing, tooling, and docs
- Role, placeholder, and display-value queries, find_by_*, within,
  wait_for, a fake clock, and a pytest plugin.
- pn start names missing requirements with an exact install command.
- Regenerated native contracts, 115 e2e demos and Maestro flows, updated
  guides and API reference.

Removals
- The Python view-handler layer (NativeViewRegistry, ViewHandler,
  register_component, native_component, get_registry), scroll_axis,
  positional Context.Provider values, dict event payloads, Ref._pn_tag
  and _pn_frame, free-form easing strings, the eval_js view command, the
  unused requests dependency, duplicate equality helpers, and dead host
  hooks.

BREAKING CHANGE: Context.Provider takes value as a keyword; ScrollView
uses horizontal instead of scroll_axis; on_layout, on_scroll, and
on_selection_change deliver dataclasses; Pressable style callables
receive PressState; refs on built-in elements hold typed handles; sdk
register_component and native_component are replaced by
define_component; pythonnative.native_views.get_registry is replaced by
get_backend; Animated.decay uses React Native's model;
SecureStore.set_item and delete_item raise on failure; a Modal no longer
closes itself on a back press or backdrop tap and calls on_request_close
instead.
CI's Android shards failed while every iOS shard passed.

- Codegen compared shared View props with Python equality, so a plugin
  manifest loaded from JSON (lists, not tuples) renamed built-in types
  such as PNViewWidth and broke the inbox app's Kotlin compile. Compare
  JSON forms, stop naming the union in ScrollViewManager, regenerate the
  inbox extension's manifest, and test both.
- The Android Keyboard module never saw the keyboard: under adjustResize
  the content view reads a zero IME inset. Observe the decor view, and
  assert the keyboard's visibility in the Android flow.
- Demos and flows written for a tall phone missed controls on CI's
  320x640 screen. Flows scroll their targets into view, the Keyboard and
  Stack options demos move their controls above the field and the
  nested stack, and reduce-motion checks no longer assume the setting is
  off (CI's emulator disables animations, which Android reports as
  Reduce Motion).
- Split the hooks suite in two and rebalance the Android shards so none
  outlasts the emulator's roughly ten-minute stable session.
owenthcarey changed the title feat!: implement RFC 0002 core parity and correctness feat!: close core React Native parity gaps and fix runtime correctness Sep 21, 2026
owenthcarey changed the title feat!: close core React Native parity gaps and fix runtime correctness feat!: close React Native parity gaps and fix correctness bugs Sep 21, 2026
owenthcarey changed the title feat!: close React Native parity gaps and fix correctness bugs feat!: close React Native parity gaps, and fix correctness bugs Sep 21, 2026
owenthcarey merged commit 66f486e into main Sep 21, 2026
44 checks passed
owenthcarey deleted the feat/core-parity-correctness branch September 21, 2026 02:33
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant


Back | FazBrowse Home | New Git URL