feat(perry/system): #917 — shareText/shareUrl system share sheet#972
Merged
Conversation
Exposes two perry/system entry points wrapping the native share
picker:
import { shareText, shareUrl } from "perry/system";
shareText("hello world");
shareUrl("https://example.com", "My link");
Use case: "share my invitation code" / "share this listing" flows
that the OS share sheet hands to Messages / Mail / WhatsApp / etc.
Wishare's invite-friends screen had to fall back to clipboardWrite +
manual paste; native apps already expose this surface.
## Cross-platform coverage
| Platform | Status |
|------------|-----------------------------------------------------------|
| **macOS** | Real impl: NSSharingServicePicker anchored to key window |
| iOS | Stub + #917 follow-up warning |
| tvOS | Stub (tvOS doesn't expose a programmatic share sheet) |
| watchOS | Stub (WatchKit doesn't expose a public API) |
| visionOS | Stub + #917 follow-up (window-anchored UIActivityViewController) |
| Android | Stub + #917 follow-up (Intent.ACTION_SEND chooser) |
| Windows | Stub + #917 follow-up (DataTransferManager.ShowShareUI) |
| Linux/GTK4 | Stub + #917 follow-up (XDG share portal) |
| WASM | Stub via dispatch table fallback |
| HarmonyOS | Stub auto-generated by perry-runtime/build.rs |
Every stub funnels through perry_runtime::stub_diag::perry_stub_warn,
so first call per process per symbol prints a [perry] warning naming
the platform and the #917 tracker.
## macOS implementation detail
NSSharingServicePicker initWithItems → showRelativeToRect:ofView:preferredEdge:
anchored to the key window's content view bounds, preferredEdge =
NSRectEdgeMinY so the popover renders above the view.
shareText wraps the value as NSString; shareUrl wraps as NSURL so
the picker offers Safari / Reading List / Bookmarks alongside the
Messages / Mail / Notes options. Malformed URLs fall back to
plain-text sharing.
The argument is currently dropped on macOS (Cocoa's picker
derives its label from the item type); kept in the signature for
cross-platform symmetry with iOS/Android where title is meaningful.
## Plumbing
- perry-api-manifest/src/entries.rs — shareText + shareUrl rows.
- perry-dispatch/src/lib.rs — two MethodRows with [Str, Str] args +
ReturnKind::Void. WASM falls through to ui_method_to_runtime() in
perry-codegen-wasm/src/emit.rs — gets symbol mapping for free.
- Per-platform exports: perry-ui-macos (real), and stubs in
perry-ui-ios, perry-ui-tvos, perry-ui-watchos, perry-ui-visionos,
perry-ui-android, perry-ui-gtk4, perry-ui-windows.
- perry-ui-test/src/lib.rs — Feature rows for both symbols across
every platform.
- HarmonyOS is auto-stubbed by perry-runtime/build.rs from the
dispatch table.
## Smoke test
Compiled App({body: VStack([Text("share me")])}) + shareText() +
shareUrl() against release perry; symbols resolve end-to-end, link
succeeds, binary writes cleanly. (Interactive picker pops on real
run; CI smoke verifies the link path.)
## What's deferred for #917 follow-ups
- iOS / Android / Windows / Linux / visionOS native impls (the issue
maps them out).
- shareItems({text?, url?, title?}) structured variant — the
dispatch is forward-compatible; will add a new MethodRow without
changing the two convenience entry points.
144dcef to
4176b75
Compare
3 tasks
proggeramlug
added a commit
that referenced
this pull request
May 18, 2026
…Rs (#1019) #981 (PERRY_SANDBOX_BUILDRS), #988 (--emit-attest), and #969 (perry.permissions) each landed via admin-bypass with their SUMMARY.md entries intact but without the actual .md content files (or, for #969, without any docs entry at all). docs/src/cli/lockdown.md and docs/src/cli/emit-sandbox.md did make it into main and are fine; the others left dead links. Separately, #976 / #972 / #974 added perry/system runtime methods (getOSVersion, shareText, shareUrl, appGroupSet/Get/Delete) but never updated the hand-maintained types/perry/system/index.d.ts. TypeScript users importing those APIs from `perry/system` get a type error today. This PR: - Creates docs/src/cli/sandbox-buildrs.md (#505) - Creates docs/src/cli/emit-attest.md (#504) - Creates docs/src/cli/capabilities.md (#501) and adds the SUMMARY.md entry - Adds the six new perry/system signatures to types/perry/system/index.d.ts The auto-generated docs/api/perry.d.ts + docs/src/api/reference.md were regenerated during the original PRs and are already current. Pure docs-only diff. No code changes.
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
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #917 (MVP — see follow-up matrix).
Summary
Two perry/system entry points wrapping the native share picker:
Use case: "share my invitation code" / "share this listing" flows where the OS share sheet hands the value to Messages / Mail / WhatsApp / etc. Wishare's invite-friends screen had to fall back to
clipboardWrite+ manual paste; native apps already expose this surface.Cross-platform coverage
NSSharingServicePickeranchored to key windowUIActivityViewController)UIActivityViewController)Intent.ACTION_SENDchooser)DataTransferManager.ShowShareUI)perry-runtime/build.rsEvery stub funnels through
perry_runtime::stub_diag::perry_stub_warn, so first call per process per symbol prints a[perry] warningline naming the platform and the #917 tracker.macOS implementation detail
NSSharingServicePicker initWithItems→showRelativeToRect:ofView:preferredEdge:anchored to the key window's content-view bounds (NSRectEdgeMinYso the popover renders above the view).shareTextwraps the value asNSString;shareUrlwraps asNSURLso the picker offers Safari / Reading List / Bookmarks alongside Messages / Mail / Notes. Malformed URLs fall back to plain-text sharing.The
titleargument is currently dropped on macOS (Cocoa's picker derives its label from the item type); kept in the signature for cross-platform symmetry with iOS/Android where title is meaningful.Plumbing (mirrors #918's takeScreenshot pattern)
build.rs. WASM falls through toui_method_to_runtime()so no parallel edit there.Smoke test
Compiled
App({body}) + shareText() + shareUrl()against release perry; symbols resolve end-to-end, link succeeds, binary writes cleanly.What's deferred (#917 follow-ups)
shareItems({text?, url?, title?})structured variant — dispatch is forward-compatible; a newMethodRowwill land it without changing the two convenience entry points.Notes
No
Cargo.tomlversion bump, noCLAUDE.mdtouch, noCHANGELOG.mdentry — maintainer folds those in at merge time.