Rudder's corner panel scrolls on a phone and keeps the draft in view

The panel clipped its content, so at 390x844 the lower controls and the draft
could not be reached. The widget element now scrolls inside the panel, the
panel height follows the dynamic viewport minus the safe-area insets, the
corner host sits inside the safe area, and on a narrow screen Rudder uses less
padding and a shorter draft so the draft stays visible below the controls.
This commit is contained in:
Doxa Maps 2026-09-27 19:52:36 +00:00
parent 7ce2e2419a
commit 808b03b71c
2 changed files with 12 additions and 4 deletions

View file

@ -1073,7 +1073,7 @@ export default defineComponent({
const h = document.createElement('div')
h.setAttribute('data-studio-widgets', corner)
const [v, x] = corner.split('-')
h.style.cssText = `position:fixed;${v}:12px;${x}:12px;z-index:2147483647;display:flex;flex-direction:column;align-items:${x === 'right' ? 'flex-end' : 'flex-start'};gap:8px;`
h.style.cssText = `position:fixed;${v}:max(12px,env(safe-area-inset-${v}));${x}:max(12px,env(safe-area-inset-${x}));z-index:2147483647;display:flex;flex-direction:column;align-items:${x === 'right' ? 'flex-end' : 'flex-start'};gap:8px;`
document.body.appendChild(h)
W.hosts[corner] = h
return h
@ -1089,7 +1089,7 @@ export default defineComponent({
box.style.cssText = 'display:flex;flex-direction:column;align-items:inherit;gap:6px;'
const panel = document.createElement('div')
panel.setAttribute('data-widget-panel', '')
panel.style.cssText = 'display:none;width:min(380px,calc(100vw - 24px));height:min(520px,calc(100vh - 80px));position:relative;background:#fff;border-radius:10px;box-shadow:0 8px 30px rgba(0,0,0,.25);overflow:hidden;'
panel.style.cssText = 'display:none;width:min(380px,calc(100vw - 24px));height:min(520px,calc(100vh - 80px));height:min(520px,calc(100dvh - 80px - env(safe-area-inset-top) - env(safe-area-inset-bottom)));position:relative;background:#fff;border-radius:10px;box-shadow:0 8px 30px rgba(0,0,0,.25);overflow:hidden;'
const btn = document.createElement('button')
btn.type = 'button'
// A catalogue label per widget ("widget:<row key>"), not the row key (rega / repo: the button read
@ -1124,7 +1124,9 @@ export default defineComponent({
const el = document.createElement(row.tag)
el.setAttribute('profile-config', JSON.stringify(this.paneConfig(row, this.locale)))
if (this.base) el.setAttribute('tree-base', this.base.replace(/\/+$/, ''))
el.style.cssText = 'display:block;position:absolute;inset:0;width:100%;height:100%;'
// The panel is a fixed size; on a phone the widget's content is taller than it, so the element scrolls
// inside the panel rather than being clipped by it.
el.style.cssText = 'display:block;position:absolute;inset:0;width:100%;height:100%;overflow-y:auto;overscroll-behavior:contain;'
// LIVE MIC, VISIBLE WHEN COLLAPSED: a widget that emits `recording` (Rudder does) turns its corner
// button red with a dot while it listens, so closing the panel never hides that the mic is on.
el.addEventListener('recording', (e) => {

View file

@ -590,7 +590,7 @@ const statusText = computed(() => ({
.rudder {
--bg: #0b0f14; --panel: #111823; --line: #1f2937; --text: #e5e7eb; --muted: #9ca3af;
--accent: #38bdf8; --rec: #ef4444; --ok: #22c55e; --warn: #f59e0b;
box-sizing: border-box; display: flex; flex-direction: column; gap: 14px; min-height: 480px; height: 100%;
box-sizing: border-box; display: flex; flex-direction: column; gap: 14px; min-height: max(100%, 480px);
padding: 18px; background: var(--bg); color: var(--text);
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif; font-size: 15px;
}
@ -658,4 +658,10 @@ code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 1
.debug dl { display: grid; grid-template-columns: 90px 1fr; gap: 6px 10px; margin: 0 0 10px; }
.debug dt { color: var(--muted); }
.debug dd { margin: 0; overflow-wrap: anywhere; }
/* A phone-sized panel: less padding, and a shorter draft so it stays in view below the controls. */
@media (max-width: 480px) {
.rudder { min-height: 100%; padding: 12px; gap: 10px; }
.compose { min-height: 200px; }
.draft { min-height: 180px; }
}
</style>