feat(web-renderer): custom renderTarget with embedded dialog mode#51
feat(web-renderer): custom renderTarget with embedded dialog mode#51SuperstrongBE wants to merge 3 commits into
Conversation
Allow consumers to mount the SDK's dialog into a specific DOM element instead of document.body, and override it per-transact. - UIRendererOptions.renderTarget accepts HTMLElement or selector string - WebRenderer.setRenderTarget() re-parents the host element on the fly - selectWallet/login/sign/signManually/showError/recoverError payloads accept an optional renderTarget to switch targets per call - ConnectWallet now returns the renderer so consumers can call setRenderTarget before each session.transact(...)
- Modal.svelte calls dialog.show() (non-modal) when a renderTarget is set, so the SDK panel renders inside the target element instead of being promoted to the browser top layer. In embedded mode the dialog fills its container 100% width/height. - setRenderTarget / UIRendererOptions.renderTarget now accept null as an explicit reset to document.body. - New examples/react-render-target: two-pane "Challenge render target!" modal demonstrating an embedded SDK dialog (connect + burn) alongside a full-modal transfer using the default renderTarget.
The .content element used z-index: -1 without a position rule, which only rendered correctly because the native <dialog> in top-layer mode creates a root stacking context that hides the sinking. With the embedded renderTarget using dialog.show() (no top layer), the label was pushed below the dialog background and disappeared. Adds position: relative and z-index: 0; the absolutely-positioned .border ring still paints on top.
|
@SuperstrongBE Could you clarify a use case for such feature? |
Yeah sure. |
|
@SuperstrongBE I got the idea. But I don't fully like the implementation. It looks like a hack right now. I'll try to find a graceful solution for this use case. I guess need to decouple the rendering process from auth and transact process for better control of the dialog rendering. |
|
@SuperstrongBE I did another implementation of the embedded view based on your idea. It added |
Summary
Enregistrement.de.l.ecran.2026-04-19.a.19.43.07.mov
Lets consumers mount the SDK dialog into any DOM element instead of
document.body, and visually confine it to that element — not just reparent it.UIRendererOptions.renderTargetaccepts anHTMLElement, a CSS selector string, ornull(explicit reset todocument.body).WebRenderer.setRenderTarget(target)re-parents the host element on the fly; the ConnectWallet flow returns the renderer so consumers can switch targets persession.transact(...).selectWallet/login/sign/signManually/showError/recoverErrorpayloads (renderTarget?field).Modal.sveltecallsdialog.show()instead ofdialog.showModal(), so the browser does not promote the dialog to the top layer. A newembeddedModestore +data-embeddedattribute switches CSS so the dialog fills its container at 100% width/height (no border radius, no backdrop).examples/react-render-targetdemonstrating the flow: a two-pane "Challenge render target!" modal that drivesconnect+burn 0.0001 XPRthrough an embedded SDK dialog, plus a regular page-level transfer that resets the target tonulland uses the default full-viewport dialog.Test plan
pnpm installat the repo root.pnpm --filter example-react-render-target devboots Vite without type or build errors.Connected as @<actor>.setRenderTarget(null)reset).examples/react,vue,svelte,angular,vanilla-html,react-native) still behave as before (defaultdocument.bodymodal).