| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent d0aa342 commit 13eb034
122 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -151,16 +151,19 @@ Recommended scopes (choose the smallest, most accurate unit; prefer module/direc | |||
| 151 | 151 | - `gestures`: gesture descriptors and the pure-Python recognition arbiter (`gestures.py`) | |
| 152 | 152 | - `hooks`: hooks and contexts (`hooks.py`) | |
| 153 | 153 | - `hosts`: screen hosts, lifecycle forwarding, and render scheduling (`hosts/`) | |
| 154 | - - `hot_reload`: file watcher and module reloader (`hot_reload.py`) | ||
| 154 | + - `devserver`: dev server, file watcher, and WebSocket implementation (`devserver/`) | ||
| 155 | + - `devclient`: on-device dev client that syncs sources and Fast Refreshes (`devclient.py`) | ||
| 156 | + - `hot_reload`: module reloader and Fast Refresh (`hot_reload.py`) | ||
| 155 | 157 | - `layout`: pure-Python flexbox engine (`layout.py`) | |
| 156 | 158 | - `mutations`: batched mutation ops between reconciler and native backends (`mutations.py`) | |
| 157 | - - `native_modules`: native module registry, Python facades, and desktop implementations (`native_modules/`) | ||
| 158 | - - `native_views`: view registry protocol, bridge backend, and desktop handlers (`native_views/`) | ||
| 159 | + - `native_modules`: native module registry, Python facades, and Python fallbacks (`native_modules/`) | ||
| 160 | + - `native_views`: view registry protocol and bridge backend (`native_views/`) | ||
| 159 | 161 | - `navigation`: navigation state, container, navigators, hooks, and linking (`navigation/`) | |
| 160 | 162 | - `net`: awaitable HTTP client (`net.py`) | |
| 161 | 163 | - `package`: `src/pythonnative/__init__.py` exports and package boundary | |
| 162 | 164 | - `platform`: `Platform.OS`/`Platform.select` and version detection (`platform.py`) | |
| 163 | 165 | - `platform_metrics`: platform-reported metrics like safe-area insets and bar heights (`platform_metrics.py`) | |
| 166 | + - `preview`: `pn start` / `pn preview` session and the browser preview page (`preview.py`, `devserver/static/`) | ||
| 164 | 167 | - `project`: `pythonnative.toml` config, template configurators, plugin staging, and the builder (`project/`) | |
| 165 | 168 | - `reconciler`: virtual view tree diffing, boundaries, and the layout pass (`reconciler/`) | |
| 166 | 169 | - `runtime`: framework-wide asyncio loop and thread-safe future helpers (`runtime.py`) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -35,20 +35,20 @@ PythonNative is a cross-platform toolkit for building native Android and iOS app | |||
| 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 | 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. | |
| 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 | + - **Developer feedback that finds your bugs:** In dev mode (`pn start`, `pn preview`, debug builds from `pn run`, 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. | ||
| 39 | 39 | - **Typed `style` prop and theme:** 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`, and read design tokens from a typed, immutable `pn.Theme` via `use_theme()` that follows light and dark mode by default. | |
| 40 | 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. | |
| 41 | 41 | - **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. | |
| 42 | 42 | - **Native-driven animations:** The `Animated` API (timing / spring / decay / loop / stagger, 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. `interpolate`, arithmetic operators on animated nodes, `Animated.event` scroll binding, and `diff_clamp` cover the scroll-driven patterns (collapsing headers, parallax) that define native feel. | |
| 43 | - - **Native gesture system:** Attach `Tap`, `LongPress`, `Pan`, `Swipe`, `Fling`, `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. Compose them with `Race`, `Exclusive`, and `Simultaneous` for cross-gesture arbitration (single vs. double tap, drag vs. long press). | ||
| 43 | + - **Native gesture system:** Attach `Tap`, `LongPress`, `Pan`, `Swipe`, `Fling`, `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 in the browser preview. Compose them with `Race`, `Exclusive`, and `Simultaneous` for cross-gesture arbitration (single vs. double tap, drag vs. long press). | ||
| 44 | 44 | - **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. | |
| 45 | 45 | - **Native rendering core:** each commit is one serialized transaction applied by Swift and Kotlin component managers, the same shape as React Native's Fabric. Device APIs are native modules registered by name (TurboModules-style), callable from thin Python facades. | |
| 46 | 46 | - **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. | |
| 47 | - - **CLI scaffolding:** `pn init` creates a ready-to-run project; `pn run android` and `pn run ios` build and launch your app. | ||
| 47 | + - **Metro-style dev loop:** `pn start` runs one dev server that serves the browser preview and every connected debug build. Save a file and each client Fast Refreshes in place, keeping component state; their `print` output and tracebacks stream back into the same terminal. `pn run android` / `pn run ios` bakes the server URL into a debug build and rebuilds the native project only when a native input actually changed, so relaunching after a Python edit takes seconds, not minutes. | ||
| 48 | 48 | - **PyPI packages, binary wheels included:** List requirements in `pythonnative.toml` and the CLI resolves them for the *device* (iOS wheels via PEP 730 and BeeWare's index, Android wheels via PEP 738 and Chaquopy), bundling numpy, Pillow, cryptography, and friends alongside pure-Python packages. `pn deps` reports what each target resolves to before you build, and a weekly-checked compatibility matrix keeps the docs honest. | |
| 49 | - - **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. | ||
| 49 | + - **Browser preview:** `pn preview` renders your app in a browser tab inside a phone frame (pick a device, rotate, toggle dark mode) with Fast Refresh on every save. The page is a bridge peer exactly like the Swift and Kotlin runtimes, so the reconciler, hooks, layout engine, navigation, and screen host are the same code that ships to the phone; only the leaf widgets are DOM elements. | ||
| 50 | 50 | - **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; `use_back_handler` intercepts the back action when a screen needs to. | |
| 51 | - - **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. | ||
| 51 | + - **Dev client:** Build a shell app once with `pn run ios --dev-client` and point it at any project's dev server from a connect screen, the way Expo Go does; physical phones on the same Wi-Fi get the same Fast Refresh as simulators. | ||
| 52 | 52 | - **Bundled templates:** Android Gradle and iOS Xcode templates are included, so scaffolding requires no network access. | |
| 53 | 53 | ||
| 54 | 54 | ## Quick Start | |
@@ -80,6 +80,16 @@ def App(): | |||
| 80 | 80 | ) | |
| 81 | 81 | ``` | |
| 82 | 82 | ||
| 83 | + ### Develop | ||
| 84 | + | ||
| 85 | + ```bash | ||
| 86 | + pn init my-app && cd my-app | ||
| 87 | + pn preview # dev server + browser preview with Fast Refresh | ||
| 88 | + pn run ios # in another terminal: debug build that connects to the same server | ||
| 89 | + pn run android | ||
| 90 | + pn build ios # standalone release artifacts | ||
| 91 | + ``` | ||
| 92 | + | ||
| 83 | 93 | ## Documentation | |
| 84 | 94 | ||
| 85 | 95 | 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. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -23,17 +23,29 @@ the documented behavior never drifts from the code. | |||
| 23 | 23 | `--json` for a machine-readable report, `--python` to pick the | |
| 24 | 24 | interpreter that runs pip. Exits non-zero when any target can't be | |
| 25 | 25 | satisfied. See [PyPI packages](../guides/pypi-packages.md). | |
| 26 | - - `pn preview [component]`: render the app in a desktop (Tkinter) window | ||
| 27 | - with Fast Refresh, the fastest way to iterate on UI. Flags: | ||
| 28 | - `--width`, `--height`, `--title`, `--no-hot-reload`. See the | ||
| 29 | - [Desktop preview guide](../guides/desktop-preview.md). | ||
| 26 | + - `pn start [entry]`: run the dev server. It watches `app/`, syncs | ||
| 27 | + every save to each connected debug build with Fast Refresh, relays | ||
| 28 | + their logs, and serves the browser preview page. Flags: `--port` | ||
| 29 | + (default 8765), `--host` (default `0.0.0.0`), `--open` to also open | ||
| 30 | + the browser preview. See the | ||
| 31 | + [Development workflow](../guides/dev-workflow.md). | ||
| 32 | + - `pn preview [entry]`: `pn start` plus opening the browser preview in | ||
| 33 | + your default browser. Flags: `--port`, `--host`, `--no-open`. See the | ||
| 34 | + [Browser preview guide](../guides/browser-preview.md). | ||
| 30 | 35 | - `pn devices [android|ios]`: list connected devices, emulators, and | |
| 31 | 36 | simulators with the identifiers `--device` accepts. Flag: `--json` to | |
| 32 | 37 | print a JSON array to stdout for scripting; the "no devices" hints go | |
| 33 | 38 | to stderr instead, and an empty list prints `[]` and exits 0. | |
| 34 | - - `pn run android|ios`: build and run on a connected device or | ||
| 35 | - simulator. Flags: `--device` (target a specific device by identifier | ||
| 36 | - or name), `--prepare-only`, `--hot-reload`, `--no-logs`. | ||
| 39 | + - `pn run android|ios`: build, install, and launch a debug build that | ||
| 40 | + connects to the running dev server. The native toolchain runs only | ||
| 41 | + when a native input changed (config, template, `pythonnative` | ||
| 42 | + itself, native plugins); otherwise the previous artifact is | ||
| 43 | + reinstalled. Flags: `--device` (target a specific device by | ||
| 44 | + identifier or name), `--prepare-only`, `--no-logs`, `--rebuild` | ||
| 45 | + (force the toolchain), `--dev-server URL` (override the server URL | ||
| 46 | + baked into the app), `--port` (where `pn start` listens), | ||
| 47 | + `--dev-client` (build a shell app with a connect screen that loads | ||
| 48 | + any project from a dev server). | ||
| 37 | 49 | - `pn logs android|ios`: stream logs from the running app without | |
| 38 | 50 | rebuilding. Flag: `--device` (target a specific device by identifier | |
| 39 | 51 | or name, same as `pn run`). Physical iOS devices aren't supported for | |
@@ -57,5 +69,5 @@ the documented behavior never drifts from the code. | |||
| 57 | 69 | ## Next steps | |
| 58 | 70 | ||
| 59 | 71 | - See the [Getting started](../getting-started.md) walkthrough. | |
| 60 | - - Read about [Hot reload](../guides/hot-reload.md) when you turn on | ||
| 61 | - `--hot-reload`. | ||
| 72 | + - Read the [Development workflow](../guides/dev-workflow.md) for how | ||
| 73 | + `pn start` and `pn run` work together. | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,84 @@ | |||
| 1 | + # Dev server and dev client | ||
| 2 | + | ||
| 3 | + The development loop is a server process (`pn start`) and any number of | ||
| 4 | + clients: the browser preview and debug builds on simulators, emulators, | ||
| 5 | + and devices. See the [Development workflow](../guides/dev-workflow.md) | ||
| 6 | + guide for how they fit together; this page documents the modules. | ||
| 7 | + | ||
| 8 | + ## `pythonnative.devserver` | ||
| 9 | + | ||
| 10 | + ::: pythonnative.devserver | ||
| 11 | + options: | ||
| 12 | + show_root_heading: false | ||
| 13 | + show_root_toc_entry: false | ||
| 14 | + members_order: source | ||
| 15 | + filters: ["!^_"] | ||
| 16 | + | ||
| 17 | + ### Server | ||
| 18 | + | ||
| 19 | + ::: pythonnative.devserver.server | ||
| 20 | + options: | ||
| 21 | + show_root_heading: false | ||
| 22 | + show_root_toc_entry: false | ||
| 23 | + members_order: source | ||
| 24 | + filters: ["!^_"] | ||
| 25 | + | ||
| 26 | + ### File watcher and source snapshots | ||
| 27 | + | ||
| 28 | + ::: pythonnative.devserver.watcher | ||
| 29 | + options: | ||
| 30 | + show_root_heading: false | ||
| 31 | + show_root_toc_entry: false | ||
| 32 | + members_order: source | ||
| 33 | + filters: ["!^_"] | ||
| 34 | + | ||
| 35 | + ### WebSocket | ||
| 36 | + | ||
| 37 | + ::: pythonnative.devserver.ws | ||
| 38 | + options: | ||
| 39 | + show_root_heading: false | ||
| 40 | + show_root_toc_entry: false | ||
| 41 | + members_order: source | ||
| 42 | + filters: ["!^_"] | ||
| 43 | + | ||
| 44 | + ## `pythonnative.devclient` | ||
| 45 | + | ||
| 46 | + ::: pythonnative.devclient | ||
| 47 | + options: | ||
| 48 | + show_root_heading: false | ||
| 49 | + show_root_toc_entry: false | ||
| 50 | + members_order: source | ||
| 51 | + filters: ["!^_"] | ||
| 52 | + | ||
| 53 | + ## `pythonnative.preview` | ||
| 54 | + | ||
| 55 | + ::: pythonnative.preview | ||
| 56 | + options: | ||
| 57 | + show_root_heading: false | ||
| 58 | + show_root_toc_entry: false | ||
| 59 | + members_order: source | ||
| 60 | + filters: ["!^_"] | ||
| 61 | + | ||
| 62 | + ## `pythonnative.bridge.web` | ||
| 63 | + | ||
| 64 | + ::: pythonnative.bridge.web | ||
| 65 | + options: | ||
| 66 | + show_root_heading: false | ||
| 67 | + show_root_toc_entry: false | ||
| 68 | + members_order: source | ||
| 69 | + filters: ["!^_"] | ||
| 70 | + | ||
| 71 | + ## `pythonnative.project.fingerprint` | ||
| 72 | + | ||
| 73 | + ::: pythonnative.project.fingerprint | ||
| 74 | + options: | ||
| 75 | + show_root_heading: false | ||
| 76 | + show_root_toc_entry: false | ||
| 77 | + members_order: source | ||
| 78 | + filters: ["!^_"] | ||
| 79 | + | ||
| 80 | + ## Next steps | ||
| 81 | + | ||
| 82 | + - [Fast Refresh](../guides/hot-reload.md) and the | ||
| 83 | + [hot reload API](hot_reload.md) for the device-side reload. | ||
| 84 | + - [Browser preview](../guides/browser-preview.md). | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -6,8 +6,9 @@ props and styles, the [`HookOrderError`][pythonnative.HookOrderError] | |||
| 6 | 6 | raised on conditional hooks, and the RedBox overlay that surfaces | |
| 7 | 7 | uncaught errors from renders, effects, and event handlers. | |
| 8 | 8 | ||
| 9 | - Dev mode is enabled automatically by `pn preview` and by `pn run | ||
| 10 | - --hot-reload`, or explicitly with the `PN_DEV=1` environment variable. | ||
| 9 | + Dev mode is enabled automatically by `pn start` / `pn preview` and in | ||
| 10 | + the debug builds `pn run` produces, or explicitly with the `PN_DEV=1` | ||
| 11 | + environment variable. | ||
| 11 | 12 | In production builds every check in this module is skipped, so | |
| 12 | 13 | shipping apps pay no overhead. | |
| 13 | 14 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -12,8 +12,10 @@ templates create a host through the `Host` native module's `create` | |||
| 12 | 12 | event and never need to be edited by app code; one | |
| 13 | 13 | [`NativeScreenHost`][pythonnative.hosts.native.NativeScreenHost] class | |
| 14 | 14 | serves both platforms because every platform-specific step goes over | |
| 15 | - the [bridge](../concepts/bridge.md). The desktop preview uses | ||
| 16 | - [`DesktopScreenHost`][pythonnative.hosts.desktop.DesktopScreenHost]. | ||
| 15 | + the [bridge](../concepts/bridge.md). The browser preview uses the same | ||
| 16 | + class: its page is a bridge peer that speaks the `Host` module protocol | ||
| 17 | + over a WebSocket (see | ||
| 18 | + [`WebTransport`][pythonnative.bridge.web.WebTransport]). | ||
| 17 | 19 | ||
| 18 | 20 | ::: pythonnative.hosts | |
| 19 | 21 | options: | |
@@ -40,13 +42,6 @@ the [bridge](../concepts/bridge.md). The desktop preview uses | |||
| 40 | 42 | members_order: source | |
| 41 | 43 | filters: ["!^_"] | |
| 42 | 44 | ||
| 43 | - ::: pythonnative.hosts.desktop | ||
| 44 | - options: | ||
| 45 | - show_root_heading: false | ||
| 46 | - show_root_toc_entry: false | ||
| 47 | - members: ["DesktopScreenHost"] | ||
| 48 | - filters: ["!^_"] | ||
| 49 | - | ||
| 50 | 45 | ## Next steps | |
| 51 | 46 | ||
| 52 | 47 | - Understand the render queue in [Lifecycle](../concepts/lifecycle.md). | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,9 +1,11 @@ | |||
| 1 | 1 | # Hot reload | |
| 2 | 2 | ||
| 3 | - Hot-reload comes in two cooperating pieces: a host-side file watcher | ||
| 4 | - that pushes changed `.py` files to the device, and a device-side | ||
| 5 | - module reloader that swaps the new code in and re-renders the active | ||
| 6 | - page. Both are wired up automatically by `pn run --hot-reload`. | ||
| 3 | + Fast Refresh comes in two cooperating pieces: the | ||
| 4 | + [dev server](devserver.md) that watches `app/` and pushes changed files | ||
| 5 | + to every connected client, and this device-side module reloader that | ||
| 6 | + swaps the new code in and refreshes every mounted screen. Debug builds | ||
| 7 | + launched with `pn run` while `pn start` is running are wired up | ||
| 8 | + automatically. | ||
| 7 | 9 | ||
| 8 | 10 | ::: pythonnative.hot_reload | |
| 9 | 11 | options: | |
@@ -14,4 +16,5 @@ page. Both are wired up automatically by `pn run --hot-reload`. | |||
| 14 | 16 | ||
| 15 | 17 | ## Next steps | |
| 16 | 18 | ||
| 17 | - - See the workflow in [Hot reload guide](../guides/hot-reload.md). | ||
| 19 | + - See the workflow in the [Fast Refresh guide](../guides/hot-reload.md). | ||
| 20 | + - The other half: [Dev server and dev client](devserver.md). | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -26,7 +26,7 @@ and the [Async + data guide](../guides/async.md). | |||
| 26 | 26 | ||
| 27 | 27 | ## Desktop implementations | |
| 28 | 28 | ||
| 29 | - ::: pythonnative.native_modules.desktop | ||
| 29 | + ::: pythonnative.native_modules.fallback | ||
| 30 | 30 | options: | |
| 31 | 31 | show_root_heading: false | |
| 32 | 32 | show_root_toc_entry: false | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -9,9 +9,10 @@ call on a [`NativeViewRegistry`][pythonnative.native_views.NativeViewRegistry]. | |||
| 9 | 9 | On device that registry is the | |
| 10 | 10 | [`BridgeBackend`][pythonnative.native_views.bridge_backend.BridgeBackend], | |
| 11 | 11 | which forwards the transaction to Swift and Kotlin component managers | |
| 12 | - over the [native bridge](bridge.md). Off device it dispatches to Python | ||
| 13 | - [`ViewHandler`][pythonnative.native_views.base.ViewHandler] objects | ||
| 14 | - (Tkinter for `pn preview`, a fake for tests). | ||
| 12 | + over the [native bridge](bridge.md). The browser preview uses the same | ||
| 13 | + backend with a WebSocket transport to the page. In tests it dispatches | ||
| 14 | + to Python [`ViewHandler`][pythonnative.native_views.base.ViewHandler] | ||
| 15 | + objects (an in-memory fake). | ||
| 15 | 16 | ||
| 16 | 17 | ::: pythonnative.native_views | |
| 17 | 18 | options: | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -16,12 +16,12 @@ branches throughout the codebase. | |||
| 16 | 16 | ||
| 17 | 17 | | Attribute | Values | | |
| 18 | 18 | |---|---| | |
| 19 | - | `Platform.OS` | `"ios"`, `"android"`, `"desktop"`, or `"test"` | | ||
| 19 | + | `Platform.OS` | `"ios"`, `"android"`, `"web"`, or `"test"` | | ||
| 20 | 20 | | `Platform.Version` | Best-effort OS version string | | |
| 21 | - | `Platform.is_ios` / `Platform.is_android` / `Platform.is_desktop` / `Platform.is_test` | Booleans | | ||
| 21 | + | `Platform.is_ios` / `Platform.is_android` / `Platform.is_web` / `Platform.is_test` | Booleans | | ||
| 22 | 22 | | `Platform.select(spec, default=None)` | Pick a value matching the current platform | | |
| 23 | 23 | ||
| 24 | - - `"desktop"` means the `pn preview` Tkinter backend. | ||
| 24 | + - `"web"` means the `pn preview` browser preview. | ||
| 25 | 25 | ||
| 26 | 26 | ## See also | |
| 27 | 27 | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments