Downstream unblock
Required by stacksjs/stx#2089: shared Dialog/Drawer, Tabs, and Tooltip/Popover must use host operations rather than browser DOM APIs or separate native component implementations.
Craft implementation belongs to the agent working in this repository; the STX agent will handle the consuming adapter. No Craft code was changed for this report.
Verified source evidence
Inspected Craft commit af4463007d5b1bec09cd32238e568e83262147c3:
- iOS Modal event emission sends
onRequestClosewith an emptynativeEvent. - iOS blocker tap calls the reasonless
requestClose(). - Android Modal event emission likewise sends an empty
nativeEvent. - Android back handling routes back through the same reasonless request used by backdrop taps.
STX cannot enforce independent close-on-backdrop and close-on-back/escape policies from that payload. Its current regression test explicitly denies an ambiguous request when the policies differ, rather than guessing.
Source inspection also has not identified a public bridge operation for focusing or measuring an existing native view by stable node ID. Existing TextInput autoFocus behavior is not an imperative focus/restore API. If an appropriate API already exists, identify its supported contract instead of duplicating it.
Required host contract
- Dismissal reason: add an additive
nativeEvent.reasonto Modal request-close events, distinguishingbackdrop,back, andescapewherever supported. Route only to the top visible modal. Preserve controlled dismissal: a denied request must leave the modal visible and interactive; repeated requests must work. - Focus: expose host-backed focus operations addressing a mounted view by stable native node ID. Define keyboard versus accessibility focus, supported targets, modal initial focus, and restoration after close. Unsupported targets and removed nodes must return actionable errors, not silently succeed.
- Measurement: expose an asynchronous operation returning a mounted view's viewport-relative bounds and viewport dimensions, with documented units, safe-area/scroll semantics, and validity after layout. This is needed for shared anchored Tooltip/Popover positioning.
- Capabilities: advertise actual support and document the request/response contract so STX can detect unsupported versions. Do not require DOM access or app-owned Swift/Kotlin.
Exact API names are for the Craft implementer to choose consistently with existing bridge conventions. Please provide the final schema and version floor for the STX adapter.
Acceptance / maintained tests
- iOS backdrop and Android backdrop/back report distinct accurate reasons; supported escape paths do too.
- Nested modals dismiss only the top layer; denied dismissal, reopen, and teardown remain functional.
- Focus reaches a supported mounted control, does not jump back on unrelated reconciliation, and restoration handles a removed opener safely.
- Measurement is correct after layout, scrolling, and viewport changes; unmounted IDs reject cleanly.
- Cover host behavior in the maintained native renderer suites, not only source-string assertions or a JS mock. Report which platforms were actually run.
- Keep existing consumers compatible with the additive event payload.
- On completion, record commit(s), maintained test results, and the released Craft version (or explicitly say unreleased).
Coordination
STX owns shared component behavior, overlay stack policy, adapter integration, and same-source tests. Craft owns platform event reasons, actual view focus/measurement, and truthful capability reporting. This issue tracks only the Craft side.