Changelog
Version 0.16.2
Every @aparte/* package ships at this version (they are released in lockstep).
Patch Changes
-
705224b: Moving a chat in the DOM (into an
<aparte-split>pane, an app shell, any reparenting) no longer disconnects the composer’s wiring: the editor kept the draft in the DOM butvaluenever heard of it, the send button stayed disabled with text visibly in the box, and every composer button had lost its click.Every composer child bound its listeners inside
_render(), behind the “DOM already there” early return, whiledisconnectedCallbackremoved them — so the first reconnect left them deaf. Binding is the connect’s job now, in all five (input,send,cancel,action,add-attachment);_renderonly builds. The vanilla example’s?layout=splitand?layout=shellvariants moved the chat exactly this way, so the bug was live on both — nothing sent a message there, which is why nothing saw it.@aparte/core -
9df343c:
overlay-composeron<aparte-chat>(andoverlayComposeron all four wrappers): the transcript’s scroll surface spans the whole column and the composer floats over it, so the scrollbar runs edge to edge instead of stopping at the composer’s top — the full-page anatomy the Layout guide sold without this half. Opt-in, never the default: a chat embedded in a small box should not have its composer eating the transcript.The viewport leaves the flow (absolute over the shell); elicitation, an above-composer row and the composer keep flowing, bottom-anchored, painted over it. The viewport measures that stack and publishes
--aparte-bottom-inset; content, the spacer and the scroll button clear it — and its readers are unconditional (0px unset), so a host that overlays a composer of its own can write the variable by hand without the attribute. When the composer grows under a reader pinned at the bottom, the inset is re-measured and the reader re-anchored in the same observer pass — the view-jump every hand-rolled overlay hits.The attribute is read when the viewport wires its observers: set it in the initial markup. Angular binds it on its inner
.aparte-chat-container(there the host is theaparte-chatelement and the viewport is the inner div’s child) — use theoverlayComposerinput.@aparte/core,@aparte/angular,@aparte/react,@aparte/svelte,@aparte/vue -
39b777f: The scroll-to-bottom button floats 16px above the transcript’s bottom edge in framework-managed mode (React, Vue, Svelte, Angular wrappers), at every scroll position. It used to sit the whole
padding + spacerhigher — up to a few hundred pixels into the messages.Two causes, one per symptom. A
position: stickychild is clamped to its parent’s content box, and the bottom spacer was carried aspadding-bottomon the scrolling host — territory the button could never enter — so it hungpadding + spacerabove the edge wherever the reader was. The clearance now lives in an::afterflex item instead: still nothing in the DOM, so the framework’s reconciliation sees exactly what it saw before. And a bottom-sticky element sits at its flow position whenever that is above the sticky line, so a button flowing before a 230px spacer drifted upward as the reader neared the bottom —order: 1puts its flow position after the spacer, and the sticky line always wins.If you worked around this with your own
padding-bottom: 0+::afteroverride on the viewport, you can remove it — it is now a no-op with the same values.Two side effects of the rework, caught on screen and now asserted in the smoke suite: an empty transcript no longer grows a scrollbar (the
::afterpaid the column’s gap the padding never did, and the hidden button’s slide overhung the content end), and the hidden button now fades instead of sliding in framework-managed mode — its flow position is the very end of the content, so the 8px slide was pure scrollable overflow. Core mode keeps the slide.Measured in the browser (spacer 0/60/130/230px): the button holds 16px at every distance from the bottom; before, it floated 48/108/178/278px. A new e2e spec (
scroll-button.spec.ts) asserts the rendered geometry in both transcript modes on Chromium and WebKit — the first assertion in the repo that locates this button rather than driving it.@aparte/core
Version-only bumps (no changes of their own): @aparte/engine, @aparte/provider-ai-sdk, @aparte/provider-openai-compat, @aparte/provider-scenario, @aparte/provider-transformers, @aparte/plugin-approval, @aparte/plugin-artifacts, @aparte/plugin-ask-user, @aparte/plugin-compaction, @aparte/plugin-marked, @aparte/plugin-model-selector, @aparte/plugin-shiki, @aparte/plugin-streaming-markdown, @aparte/locale-fr, @aparte/docs-mcp.