fix(collab): embed online badge in tab row instead of fixed overlay
The "N online" collab badge was position:fixed at top:8px, overlapping the header login area. Move it into the tab bar slot (main shell) or header-right section (standalone shells) so it flows inline with other chrome elements. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
51be476694
commit
0c46e33148
|
|
@ -251,6 +251,7 @@ export function renderShell(opts: ShellOptions): string {
|
||||||
</header>
|
</header>
|
||||||
<div class="rstack-tab-row">
|
<div class="rstack-tab-row">
|
||||||
<rstack-tab-bar space="${escapeAttr(spaceSlug)}" active="" view-mode="flat">
|
<rstack-tab-bar space="${escapeAttr(spaceSlug)}" active="" view-mode="flat">
|
||||||
|
<rstack-collab-overlay module-id="${escapeAttr(moduleId)}" space="${escapeAttr(spaceSlug)}"></rstack-collab-overlay>
|
||||||
<button class="rapp-info-btn" id="rapp-info-btn" title="About this rApp"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></svg></button>
|
<button class="rapp-info-btn" id="rapp-info-btn" title="About this rApp"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></svg></button>
|
||||||
</rstack-tab-bar>
|
</rstack-tab-bar>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -271,7 +272,6 @@ export function renderShell(opts: ShellOptions): string {
|
||||||
${opts.tabs ? renderTabBar(opts.tabs, opts.activeTab, opts.tabBasePath || ((opts.isSubdomain ?? IS_PRODUCTION) ? `/${escapeAttr(moduleId)}` : `/${escapeAttr(spaceSlug)}/${escapeAttr(moduleId)}`)) : ''}
|
${opts.tabs ? renderTabBar(opts.tabs, opts.activeTab, opts.tabBasePath || ((opts.isSubdomain ?? IS_PRODUCTION) ? `/${escapeAttr(moduleId)}` : `/${escapeAttr(spaceSlug)}/${escapeAttr(moduleId)}`)) : ''}
|
||||||
${body}
|
${body}
|
||||||
</main>
|
</main>
|
||||||
<rstack-collab-overlay module-id="${escapeAttr(moduleId)}" space="${escapeAttr(spaceSlug)}"></rstack-collab-overlay>
|
|
||||||
|
|
||||||
${renderWelcomeOverlay()}
|
${renderWelcomeOverlay()}
|
||||||
|
|
||||||
|
|
@ -1409,7 +1409,9 @@ export function renderExternalAppShell(opts: ExternalAppShellOptions): string {
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<div class="rstack-tab-row">
|
<div class="rstack-tab-row">
|
||||||
<rstack-tab-bar space="${escapeAttr(spaceSlug)}" active="" view-mode="flat"></rstack-tab-bar>
|
<rstack-tab-bar space="${escapeAttr(spaceSlug)}" active="" view-mode="flat">
|
||||||
|
<rstack-collab-overlay module-id="${escapeAttr(moduleId)}" space="${escapeAttr(spaceSlug)}" mode="badge-only"></rstack-collab-overlay>
|
||||||
|
</rstack-tab-bar>
|
||||||
</div>
|
</div>
|
||||||
<div class="rspace-iframe-wrap">
|
<div class="rspace-iframe-wrap">
|
||||||
<div class="rspace-iframe-loading" id="iframe-loading">
|
<div class="rspace-iframe-loading" id="iframe-loading">
|
||||||
|
|
@ -1426,7 +1428,6 @@ export function renderExternalAppShell(opts: ExternalAppShellOptions): string {
|
||||||
></iframe>
|
></iframe>
|
||||||
<a class="rspace-iframe-newtab" href="${escapeAttr(appUrl)}" target="_blank" rel="noopener">Open in new tab ↗</a>
|
<a class="rspace-iframe-newtab" href="${escapeAttr(appUrl)}" target="_blank" rel="noopener">Open in new tab ↗</a>
|
||||||
</div>
|
</div>
|
||||||
<rstack-collab-overlay module-id="${escapeAttr(moduleId)}" space="${escapeAttr(spaceSlug)}" mode="badge-only"></rstack-collab-overlay>
|
|
||||||
|
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import '/shell.js';
|
import '/shell.js';
|
||||||
|
|
@ -2012,11 +2013,11 @@ export function renderModuleLanding(opts: ModuleLandingOptions): string {
|
||||||
<rstack-mi></rstack-mi>
|
<rstack-mi></rstack-mi>
|
||||||
</div>
|
</div>
|
||||||
<div class="rstack-header__right">
|
<div class="rstack-header__right">
|
||||||
|
<rstack-collab-overlay module-id="${escapeAttr(mod.id)}" mode="badge-only"></rstack-collab-overlay>
|
||||||
<rstack-identity></rstack-identity>
|
<rstack-identity></rstack-identity>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
${bodyContent}
|
${bodyContent}
|
||||||
<rstack-collab-overlay module-id="${escapeAttr(mod.id)}" mode="badge-only"></rstack-collab-overlay>
|
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import '/shell.js';
|
import '/shell.js';
|
||||||
if ("serviceWorker" in navigator && location.hostname !== "localhost") {
|
if ("serviceWorker" in navigator && location.hostname !== "localhost") {
|
||||||
|
|
@ -2359,11 +2360,11 @@ export function renderSubPageInfo(opts: SubPageInfoOptions): string {
|
||||||
<rstack-mi></rstack-mi>
|
<rstack-mi></rstack-mi>
|
||||||
</div>
|
</div>
|
||||||
<div class="rstack-header__right">
|
<div class="rstack-header__right">
|
||||||
|
<rstack-collab-overlay module-id="${escapeAttr(mod.id)}" mode="badge-only"></rstack-collab-overlay>
|
||||||
<rstack-identity></rstack-identity>
|
<rstack-identity></rstack-identity>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
${bodyContent}
|
${bodyContent}
|
||||||
<rstack-collab-overlay module-id="${escapeAttr(mod.id)}" mode="badge-only"></rstack-collab-overlay>
|
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import '/shell.js';
|
import '/shell.js';
|
||||||
if ("serviceWorker" in navigator && location.hostname !== "localhost") {
|
if ("serviceWorker" in navigator && location.hostname !== "localhost") {
|
||||||
|
|
|
||||||
|
|
@ -441,20 +441,13 @@ export class RStackCollabOverlay extends HTMLElement {
|
||||||
|
|
||||||
const OVERLAY_CSS = `
|
const OVERLAY_CSS = `
|
||||||
:host {
|
:host {
|
||||||
display: block;
|
display: inline-flex;
|
||||||
position: fixed;
|
align-items: center;
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 0;
|
|
||||||
height: 0;
|
|
||||||
z-index: 9999;
|
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.collab-badge {
|
.collab-badge {
|
||||||
position: fixed;
|
|
||||||
top: 8px;
|
|
||||||
right: 80px;
|
|
||||||
display: none;
|
display: none;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
|
|
@ -468,9 +461,9 @@ const OVERLAY_CSS = `
|
||||||
pointer-events: auto;
|
pointer-events: auto;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
z-index: 10000;
|
|
||||||
border: 1px solid var(--rs-border, rgba(255,255,255,0.08));
|
border: 1px solid var(--rs-border, rgba(255,255,255,0.08));
|
||||||
transition: opacity 0.2s, border-color 0.2s;
|
transition: opacity 0.2s, border-color 0.2s;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.collab-badge:hover {
|
.collab-badge:hover {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue