fix: refine chat header and diff scrolling UX

This commit is contained in:
Federico Jaramillo Martinez
2026-05-19 08:38:15 +02:00
parent ee6f60fea1
commit 6f7713f270
4 changed files with 30 additions and 12 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"@jmfederico/pi-web": patch
---
Contain long edit diff lines inside the diff viewer so they scroll horizontally within the tool card instead of widening the chat transcript.
+5
View File
@@ -0,0 +1,5 @@
---
"@jmfederico/pi-web": patch
---
Keep chat bubble and event group headers sticky while scrolling so long messages remain easier to orient within the transcript.
@@ -98,8 +98,8 @@ export class ToolExecutionView extends LitElement {
}
static override styles = css`
:host { display: block; max-width: 100%; min-width: 0; color: var(--pi-text); }
.tool-card { display: grid; gap: 8px; border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-bg); padding: 9px; color: var(--pi-text); }
:host { display: block; width: 100%; max-width: 100%; min-width: 0; color: var(--pi-text); }
.tool-card { display: grid; gap: 8px; width: 100%; max-width: 100%; min-width: 0; box-sizing: border-box; overflow: hidden; border: 1px solid var(--pi-border); border-radius: 8px; background: var(--pi-bg); padding: 9px; color: var(--pi-text); }
.tool-card.running, .tool-card.pending { border-color: var(--pi-warning-border); background: var(--pi-warning-surface); }
.tool-card.success { border-color: var(--pi-success-border); background: var(--pi-success-bg); }
.tool-card.error { border-color: var(--pi-danger); background: color-mix(in srgb, var(--pi-danger) 10%, var(--pi-bg)); }
@@ -119,13 +119,15 @@ export class ToolExecutionView extends LitElement {
.error-text { margin: 0; border: 1px solid var(--pi-danger); border-radius: 7px; background: color-mix(in srgb, var(--pi-danger) 10%, var(--pi-bg)); color: var(--pi-danger); padding: 8px; white-space: pre-wrap; overflow-wrap: anywhere; font: 12px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
.text-body { border-top: 1px solid var(--pi-border-muted); padding-top: 6px; }
.text-body pre { margin: 6px 0 0; white-space: pre-wrap; overflow-wrap: anywhere; font: 12px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; color: var(--pi-text); }
.diff-details { border-top: 1px solid var(--pi-border-muted); padding-top: 6px; }
.diff-details > summary { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; color: var(--pi-muted); cursor: pointer; }
.diff-details > summary small { color: var(--pi-dim); }
.diff-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 8px; color: var(--pi-muted); font-size: 12px; }
.diff-details { min-width: 0; max-width: 100%; border-top: 1px solid var(--pi-border-muted); padding-top: 6px; }
.diff-details > summary { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; min-width: 0; color: var(--pi-muted); cursor: pointer; }
.diff-details > summary span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.diff-details > summary small { flex: 0 0 auto; color: var(--pi-dim); }
.diff-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-width: 0; margin-top: 8px; color: var(--pi-muted); font-size: 12px; }
.diff-toolbar span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
button { border: 1px solid var(--pi-border); border-radius: 6px; background: var(--pi-surface); color: var(--pi-text); padding: 3px 7px; font: 12px system-ui, sans-serif; cursor: pointer; }
button:hover, button:focus { border-color: var(--pi-accent); }
.diff { margin: 0; max-width: 100%; overflow-x: auto; overflow-y: hidden; border: 1px solid var(--pi-border-muted); border-radius: 7px; background: var(--pi-bg); padding: 8px 0; color: var(--pi-muted); font: 12px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; line-height: 1.45; }
.diff { box-sizing: border-box; width: 100%; max-width: 100%; min-width: 0; margin: 0; overflow-x: auto; overflow-y: hidden; overscroll-behavior-x: contain; border: 1px solid var(--pi-border-muted); border-radius: 7px; background: var(--pi-bg); padding: 8px 0; color: var(--pi-muted); font: 12px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; line-height: 1.45; }
.diff span { display: block; min-height: 1.45em; padding: 0 8px; white-space: pre; }
.diff .context { color: var(--pi-muted); }
.diff .hunk { color: var(--pi-accent); }
+11 -5
View File
@@ -181,7 +181,7 @@ export const chatStyles = css`
.activity-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dot { width: 8px; height: 8px; border-radius: 50%; background: currentColor; opacity: .45; flex: 0 0 auto; }
.activity-dock.active .dot { animation: pulse 1s ease-in-out infinite; opacity: 1; }
.msg { max-width: 100%; min-width: 0; box-sizing: border-box; margin: 0 0 14px; padding: 12px; border: 1px solid var(--pi-border); border-radius: 10px; background: var(--pi-surface); overflow: hidden; }
.msg { max-width: 100%; min-width: 0; box-sizing: border-box; margin: 0 0 14px; padding: 12px; border: 1px solid var(--pi-border); border-radius: 10px; background: var(--pi-surface); overflow: visible; }
.msg.user { border-color: var(--pi-accent-border); background: var(--pi-selection-bg); }
.msg.tool { border-color: var(--pi-warning-border); background: var(--pi-warning-surface); color: var(--pi-warning); }
.msg.tool-execution-shell { padding: 0; border: 0; background: transparent; color: var(--pi-text); }
@@ -190,11 +190,11 @@ export const chatStyles = css`
.msg.skill { border-color: var(--pi-purple-border); background: var(--pi-purple-surface); }
.msg.event-group { padding: 0; border-color: var(--pi-border); background: var(--pi-bg); color: var(--pi-muted); }
.msg.event-group.live { border-color: var(--pi-success-border); background: var(--pi-success-bg); }
.msg.event-group > summary { display: flex; align-items: center; gap: 8px; padding: 8px 12px; color: var(--pi-muted); }
.msg.event-group.live > summary { color: var(--pi-success); }
.msg.event-group > summary { position: sticky; top: -16px; z-index: 3; display: flex; align-items: center; gap: 8px; padding: 8px 12px; border-radius: 9px 9px 0 0; border-bottom: 1px solid var(--pi-border-muted); background: var(--pi-bg); color: var(--pi-muted); }
.msg.event-group.live > summary { border-bottom-color: var(--pi-success-border); background: var(--pi-success-bg); color: var(--pi-success); }
.msg.event-group > summary .label { margin: 0; }
.group-body { padding: 0 12px 12px; }
.group-msg { max-width: 100%; min-width: 0; box-sizing: border-box; padding: 10px 0; border-top: 1px solid var(--pi-border-muted); color: var(--pi-text); overflow: hidden; }
.group-msg { max-width: 100%; min-width: 0; box-sizing: border-box; padding: 10px 0; border-top: 1px solid var(--pi-border-muted); color: var(--pi-text); overflow: visible; }
.group-msg.tool { color: var(--pi-warning); }
.group-msg.tool-execution-shell { color: var(--pi-text); }
.group-msg.system { color: var(--pi-danger); }
@@ -217,7 +217,13 @@ export const chatStyles = css`
.session-activity.receiving strong { color: var(--pi-success); }
.session-activity span, .session-activity small { color: var(--pi-muted); }
.history-boundary small { color: var(--pi-dim); }
.msg-header { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 8px; }
.msg-header { display: flex; align-items: center; justify-content: space-between; gap: 10px; min-height: 22px; margin-bottom: 8px; }
.msg > .msg-header { position: sticky; top: -16px; z-index: 2; margin: -12px -12px 8px; padding: 7px 10px 6px; border-radius: 9px 9px 0 0; border-bottom: 1px solid color-mix(in srgb, var(--pi-border-muted) 35%, transparent); background: var(--pi-surface); box-shadow: 0 8px 18px var(--pi-shadow-soft); }
.msg.user > .msg-header { border-bottom-color: color-mix(in srgb, var(--pi-accent-border) 35%, transparent); background: var(--pi-selection-bg); }
.msg.tool > .msg-header { border-bottom-color: color-mix(in srgb, var(--pi-warning-border) 35%, transparent); background: var(--pi-warning-surface); }
.msg.bash > .msg-header { border-bottom-color: color-mix(in srgb, var(--pi-success) 35%, transparent); background: var(--pi-success-bg); }
.msg.skill > .msg-header { border-bottom-color: color-mix(in srgb, var(--pi-purple-border) 35%, transparent); background: var(--pi-purple-surface); }
.group-msg > .msg-header { position: sticky; top: -16px; z-index: 2; margin: -10px 0 8px; padding: 7px 0 6px; border-bottom: 1px solid color-mix(in srgb, var(--pi-border-muted) 35%, transparent); background: var(--pi-bg); }
.msg-header-trailing { min-width: 0; display: inline-flex; align-items: baseline; justify-content: flex-end; gap: 8px; }
.msg-actions { display: inline-flex; gap: 6px; opacity: 0; transition: opacity .12s ease; }
.msg-action { display: inline-grid; place-items: center; width: 24px; height: 24px; border: 1px solid var(--pi-border); border-radius: 6px; background: var(--pi-surface); color: var(--pi-muted); padding: 0; font: 14px system-ui, sans-serif; line-height: 1; cursor: pointer; }