Skip to content

feat(web-renderer): custom renderTarget with embedded dialog mode#51

Open
SuperstrongBE wants to merge 3 commits into
XPRNetwork:masterfrom
SuperstrongBE:improvements/render-target
Open

feat(web-renderer): custom renderTarget with embedded dialog mode#51
SuperstrongBE wants to merge 3 commits into
XPRNetwork:masterfrom
SuperstrongBE:improvements/render-target

Conversation

@SuperstrongBE
Copy link
Copy Markdown
Contributor

@SuperstrongBE SuperstrongBE commented Apr 19, 2026

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.renderTarget accepts an HTMLElement, a CSS selector string, or null (explicit reset to document.body).
  • WebRenderer.setRenderTarget(target) re-parents the host element on the fly; the ConnectWallet flow returns the renderer so consumers can switch targets per session.transact(...).
  • Per-call overrides on selectWallet / login / sign / signManually / showError / recoverError payloads (renderTarget? field).
  • Embedded mode: when a custom render target is active, Modal.svelte calls dialog.show() instead of dialog.showModal(), so the browser does not promote the dialog to the top layer. A new embeddedMode store + data-embedded attribute switches CSS so the dialog fills its container at 100% width/height (no border radius, no backdrop).
  • New example examples/react-render-target demonstrating the flow: a two-pane "Challenge render target!" modal that drives connect + burn 0.0001 XPR through an embedded SDK dialog, plus a regular page-level transfer that resets the target to null and uses the default full-viewport dialog.

Test plan

  • pnpm install at the repo root.
  • pnpm --filter example-react-render-target dev boots Vite without type or build errors.
  • Click Connect wallet — the two-pane modal opens and the SDK panel renders inside the 340px right column (not over the viewport).
  • Inside the modal, click Burn 0.0001 XPR — SDK signing panel re-appears inline in the same right column; on broadcast, checkbox 2 ticks.
  • Complete login — left pane checkbox 1 ticks with Connected as @<actor>.
  • Close the modal, then click Send 0.0001 XPR on the page — the SDK opens as the regular full-viewport modal (validates setRenderTarget(null) reset).
  • Click Logout — session clears, checklist state resets.
  • Existing examples (examples/react, vue, svelte, angular, vanilla-html, react-native) still behave as before (default document.body modal).

claude and others added 3 commits April 19, 2026 07:16
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 SuperstrongBE marked this pull request as ready for review April 19, 2026 17:46
@andreyjamer
Copy link
Copy Markdown
Collaborator

@SuperstrongBE Could you clarify a use case for such feature?
I don't fully understand the need to change the parent of the dialog window on the fly.

@SuperstrongBE
Copy link
Copy Markdown
Contributor Author

SuperstrongBE commented Apr 19, 2026

@SuperstrongBE Could you clarify a use case for such feature? I don't fully understand the need to change the parent of the dialog window on the fly.

Yeah sure.
Projects are growing and relying more and more on off-chain endpoints that require identity proof via the generateauth action immediately following login (it's the case for three of my projects). In such cases, the UX becomes clunky, relying on stacked modals and awkward flows that confuse users. This render target feature allows developers to build smoother flows/multistep driven login while maintaining the same visual cues from Metallicus branding.

@andreyjamer
Copy link
Copy Markdown
Collaborator

@SuperstrongBE I got the idea. But I don't fully like the implementation. It looks like a hack right now.
Also session is not restored in your example. Every page reload leads to loss of session. I guess you missed calling login with restore parameter. But in current implementation it will lead to renderer instance creation.

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.

@andreyjamer
Copy link
Copy Markdown
Collaborator

@SuperstrongBE I did another implementation of the embedded view based on your idea. It added embedTo method for WebRenderer and embedTo payload field to every method. Also there are some improvements to layout to make it easier to embed. Check this draft PR #52 to get more details.

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.

3 participants