fix(sirius-x/register-flow): inline render actually writes to the inline mount

renderSignInInline() reassigned the module-level 'sheet' variable to the
host page's container, but render() had been shadowing that with a
separate 'mountTarget' constant captured at module init — so every step
kept writing into the modal sheet instead of the inline container.
Portal.html therefore showed an empty #signin-inline while the tabs +
form rendered off-screen inside the (closed) modal.

Drop mountTarget entirely and let render() write directly into 'sheet'.
'sheet' is already the reassignable target for both modal and inline
paths, and renderSignInInline / close() already keep it in sync.
This commit is contained in:
Local Dev 2026-09-08 13:06:16 +02:00
parent 14cc83dfae
commit 6378e179b6

View file

@ -89,6 +89,76 @@ const sats = (v) => Number(v).toLocaleString("en-US");
#sirius-register-modal .signin-tabs button.active{
color:var(--acid,#d6ff3d);border-bottom-color:var(--acid,#d6ff3d)
}
/* Inline-sheet variant: same step content styling as the modal, but
rendered as a normal page section (no fixed positioning, no backdrop,
no shadow). Portal.html uses this so the tabbed sign-in IS the page. */
.sirius-inline-sheet{
background:var(--panel,#141a24);border:1px solid var(--line,rgba(255,255,255,.09));
border-radius:16px;padding:22px 24px;color:var(--ink,#e7eaf1)
}
.sirius-inline-sheet h3{margin:0 0 .2rem;font-size:1.15rem}
.sirius-inline-sheet .sub{color:var(--mut,#8b98a9);font-size:14px;margin:0 0 1.2rem}
.sirius-inline-sheet label{display:block;font-size:13px;color:var(--mut,#8b98a9);margin:14px 0 5px}
.sirius-inline-sheet input[type=text],
.sirius-inline-sheet input[type=password],
.sirius-inline-sheet textarea,
.sirius-inline-sheet select{
width:100%;padding:11px 13px;border-radius:10px;border:1px solid #ffffff22;background:#0e131b;
color:var(--ink,#e7eaf1);font-size:14px;font-family:inherit;outline:none
}
.sirius-inline-sheet textarea{min-height:76px;resize:vertical;font-family:ui-monospace,monospace;font-size:13px}
.sirius-inline-sheet input:focus,.sirius-inline-sheet textarea:focus{border-color:#4b7bec}
.sirius-inline-sheet .row{display:flex;gap:10px;flex-wrap:wrap;margin-top:18px}
.sirius-inline-sheet .row.end{justify-content:flex-end}
.sirius-inline-sheet .phrase{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-top:10px}
.sirius-inline-sheet .phrase span{background:#0e131b;border:1px solid var(--line,rgba(255,255,255,.09));
border-radius:8px;padding:8px 10px;font-family:ui-monospace,monospace;font-size:13px}
.sirius-inline-sheet .phrase span b{color:var(--dim,#5e6678);font-weight:400;margin-right:6px;font-size:11px}
.sirius-inline-sheet .addr{display:flex;gap:8px;align-items:center;margin-top:8px}
.sirius-inline-sheet .addr code{flex:1;word-break:break-all;background:#0e131b;
border:1px solid var(--line,rgba(255,255,255,.09));border-radius:8px;padding:9px 11px;
font-family:ui-monospace,monospace;font-size:12.5px}
.sirius-inline-sheet .steps-log{margin-top:14px;font-family:ui-monospace,monospace;font-size:12.5px;
color:var(--mut,#8b98a9);background:#0e131b;border:1px solid var(--line,rgba(255,255,255,.09));
border-radius:10px;padding:12px 14px;max-height:180px;overflow-y:auto}
.sirius-inline-sheet .steps-log div::before{content:"› ";color:var(--acid,#d6ff3d)}
.sirius-inline-sheet .err{color:var(--taken,#f6768a);font-size:13.5px;margin-top:12px}
.sirius-inline-sheet .ok{color:var(--ok,#4fd1a5)}
.sirius-inline-sheet .note{background:var(--panel2,#18202c);border:1px solid var(--line,rgba(255,255,255,.09));
border-left:3px solid var(--acid,#d6ff3d);border-radius:10px;padding:14px 18px;
color:var(--mut,#8b98a9);font-size:14px;margin-top:1.4rem}
.sirius-inline-sheet .note.warn{border-left-color:var(--warn,#ffc75f)}
.sirius-inline-sheet .note b{color:var(--ink,#e7eaf1)}
.sirius-inline-sheet .mono{background:#0e131b;border:1px solid var(--line,rgba(255,255,255,.09));
border-radius:6px;padding:1px 6px;font-family:ui-monospace,monospace;font-size:13px}
.sirius-inline-sheet .chk{display:flex;gap:9px;align-items:flex-start;margin-top:14px;font-size:13.5px;color:var(--mut,#8b98a9)}
.sirius-inline-sheet .chk input{margin-top:3px}
.sirius-inline-sheet .signin-tabs{
display:flex;gap:2px;margin:-6px -8px 18px;padding:0 4px;
border-bottom:1px solid var(--line,rgba(255,255,255,.09));overflow-x:auto
}
.sirius-inline-sheet .signin-tabs button{
background:none;border:none;color:var(--mut,#8b98a9);font-family:inherit;font-size:13px;
padding:10px 14px;cursor:pointer;border-bottom:2px solid transparent;
white-space:nowrap;letter-spacing:.2px;transition:color .1s,border-color .1s
}
.sirius-inline-sheet .signin-tabs button:hover{color:var(--ink,#e7eaf1)}
.sirius-inline-sheet .signin-tabs button.active{
color:var(--acid,#d6ff3d);border-bottom-color:var(--acid,#d6ff3d)
}
.sirius-inline-sheet .btn{display:inline-block;text-decoration:none;padding:10px 18px;border-radius:10px;
background:#4b7bec;color:#fff;font-size:14px;border:none;cursor:pointer;font-family:inherit}
.sirius-inline-sheet .btn.ghost{background:transparent;border:1px solid var(--line,rgba(255,255,255,.09));color:var(--ink,#e7eaf1)}
.sirius-inline-sheet .btn.acid{background:var(--acid,#d6ff3d);color:#0b0e14;font-weight:600}
.sirius-inline-sheet .btn:hover{filter:brightness(1.12)}
.sirius-inline-sheet .btn:disabled{opacity:.45;cursor:not-allowed;filter:none}
.sirius-inline-sheet .wopt{display:flex;gap:14px;align-items:flex-start;background:var(--panel2,#18202c);
border:1px solid var(--line,rgba(255,255,255,.09));border-radius:12px;padding:14px 16px;cursor:pointer;
text-align:left;width:100%;color:inherit;font:inherit;margin-top:10px}
.sirius-inline-sheet .wopt:hover{border-color:#4b7bec}
.sirius-inline-sheet .wopt .ic{font-size:22px;line-height:1}
.sirius-inline-sheet .wopt b{display:block;font-size:14.5px}
.sirius-inline-sheet .wopt span{color:var(--mut,#8b98a9);font-size:13px}
#sirius-register-modal .btn{display:inline-block;text-decoration:none;padding:10px 18px;border-radius:10px;
background:#4b7bec;color:#fff;font-size:14px;border:none;cursor:pointer;font-family:inherit}
#sirius-register-modal .btn.ghost{background:transparent;border:1px solid var(--line,rgba(255,255,255,.09));color:var(--ink,#e7eaf1)}
@ -121,18 +191,37 @@ const sats = (v) => Number(v).toLocaleString("en-US");
// signInOnly: when true, the flow is used for wallet onboarding from the nav
// dropdown — no name to mint, so instead of walking through Fund/Confirm/
// Register we stop at 'wallet is ready', write siriusProfile, and close.
const state = { name: null, signInOnly: false, wallet: null, session: null, client: null, quote: null, result: null };
// inlineTarget: when set, the flow renders into that page element instead
// of the modal sheet (portal.html uses this to embed the tabbed sign-in as
// the page's main content). The modal is left closed in inline mode.
const state = { name: null, signInOnly: false, inlineTarget: null, wallet: null, session: null, client: null, quote: null, result: null };
const modal = $("sirius-register-modal");
const sheet = $("sirius-reg-sheet");
const modalSheet = $("sirius-reg-sheet");
// `sheet` is the element the step functions render into — the modal's sheet
// by default, or an inline container when siriusRenderSignInInline() is
// active. `let` so it can be reassigned per call.
let sheet = modalSheet;
function open() { modal.classList.add("open"); }
function open() {
// Inline mode never opens the modal — the sign-in UI lives on the page.
if (state.inlineTarget) return;
modal.classList.add("open");
}
function close() {
modal.classList.remove("open");
// In inline mode we can't "close" — leave the content in place. State is
// still reset so the next call starts fresh.
if (!state.inlineTarget) modal.classList.remove("open");
if (state.client) { try { state.client.close(); } catch {} state.client = null; }
// Keep the WC session alive when signing in — later record edits or TLD
// mints will need it; only tear it down for the mint flow.
if (state.session && !state.signInOnly) { try { state.session.disconnect(); } catch {} state.session = null; }
state.signInOnly = false;
// Restore the modal sheet as the default render target so subsequent
// register/mint flows (which are modal-based) work.
if (state.inlineTarget) {
state.inlineTarget = null;
sheet = modalSheet;
}
}
// Persist wallet identity so profile-menu.js and any other tab see the
@ -171,6 +260,10 @@ function finishSignIn(w) {
$("sirius-reg-close").onclick = close;
modal.addEventListener("click", (e) => { if (e.target === modal) close(); });
// Step functions render into `sheet`, which is reassigned per call by
// renderSignInInline() when the flow is mounted inline on a host page
// (portal.html). Modal by default. Direct write — no separate variable
// needed since `sheet` above is the single mutable target.
function render(html) { sheet.innerHTML = html; }
// Tab bar for sign-in mode — lets the user jump between the four wallet
@ -193,11 +286,12 @@ function renderTabs(active) {
</div>
`;
}
// Wire tab clicks — event delegation on the sheet so freshly-rendered
// tabs pick up the handler without rewiring per step. Switching away from
// a live WC session tears it down first so we don't leak connections.
sheet.addEventListener("click", async (e) => {
const t = e.target.closest("[data-tab]");
// Wire tab clicks — document-level delegation so both the modal sheet and
// any inline container hosting the tabs work with one listener. Switching
// away from a live WC session tears it down first so we don't leak
// connections. Guarded to only match .signin-tabs buttons we render.
document.addEventListener("click", async (e) => {
const t = e.target.closest(".signin-tabs [data-tab]");
if (!t) return;
const which = t.dataset.tab;
if (which !== "wc" && state.session) {
@ -261,10 +355,32 @@ function startSignIn(mode) {
else stepWallet();
}
// Sign-in rendered inline on the host page (not in a modal). Pass a target
// element and portal-style tabs + form get painted into it. Used by
// portal.html so the "sign up / sign in" experience IS the page rather than
// an overlay on top of a launcher card.
function renderSignInInline(container, mode = "import") {
if (!container) return;
state.name = "your wallet";
state.tld = null;
state.signInOnly = true;
state.inlineTarget = container;
sheet = container;
// Give inline container the same visual bones as the modal sheet so the
// step content styling ports 1:1. Kept as a class so host CSS can override.
container.classList.add("sirius-inline-sheet");
if (mode === "new") stepCreate();
else if (mode === "import") stepImport();
else if (mode === "wc") stepExternal();
else if (mode === "unlock") stepUnlock();
else stepWallet();
}
// Public API
window.siriusRegisterName = startFlow;
window.siriusRegisterTld = startTldFlow;
window.siriusSignInWallet = startSignIn;
window.siriusRenderSignInInline = renderSignInInline;
// ---------- step 1: wallet choice ----------
function stepWallet() {