feat(chat): colored streaming code and a reveal for committed blocks

With block-level commit the open code fence grows by whole lines at the
throttle cadence, so the old reason to skip highlighting it (re-tokenizing
a growing block ~40x/sec) no longer applies: a partial fence now
highlights too, and streamed code arrives colored instead of colorizing
only when the fence closes. Fences beyond 300 lines fall back to plain
text until closed, keeping the repeated worker re-tokenization bounded.

A freshly committed block also enters with a short fade-and-rise. The
class goes on the block's children (the wrapper is display:contents and
cannot animate) and the transform is paint-only, so virtualized row
measurement is unaffected; reduced motion disables it.

Verified over CDP on a production build: streamed code inside a still-
open fence renders highlighted, and the code text's x-position is
identical during and after the stream.
This commit is contained in:
Bohdan Triapitsyn
2026-08-25 18:40:42 +03:00
parent 3b8ed8fc36
commit d71bcb5025
3 changed files with 48 additions and 4 deletions
+23
View File
@@ -1378,6 +1378,29 @@ html:not(.dark) .chat-scroll {
}
}
/* A block committed mid-stream enters with a short fade-and-rise; the
transform is paint-only, so virtualized row measurement is unaffected. */
@keyframes oc-md-block-enter {
from {
opacity: 0;
transform: translateY(4px);
}
to {
opacity: 1;
transform: none;
}
}
.oc-md-block-enter {
animation: oc-md-block-enter 140ms ease-out both;
}
@media (prefers-reduced-motion: reduce) {
.oc-md-block-enter {
animation: none;
}
}
/* While streaming defers the per-line gutter markup, hold its horizontal
footprint (2rem column + 0.75rem gap) so the finished pass only fills in
the numbers instead of shifting every code line. */