Repository navigation
feat(apollo-wind): compact density for the chat primitives - #1403
Open
BenGSchulz wants to merge 1 commit into
Open
BenGSchulz wants to merge 1 commit into
BenGSchulz wants to merge 1 commit into
Conversation
Contributor
Dependency License Review
License distribution
Excluded packages
|
BenGSchulz
added this pull request to stack #1414
October 19, 2026 17:13
Contributor
📊 Coverage + size by packagePer-package coverage and bundle size on this PR. New-line coverage = of the source lines this PR adds or changes, the % hit by tests.
"Coverage" is each package's own |
BenGSchulz
force-pushed
the
feat/apollo-wind-chat-compact-density
branch
from
October 19, 2026 19:03
018ee7c to
4cccb1d
Compare
BenGSchulz
force-pushed
the
feat/apollo-wind-chat-compact-density
branch
from
October 19, 2026 19:19
4cccb1d to
46f43a9
Compare
BenGSchulz
force-pushed
the
feat/apollo-wind-chat-compact-density
branch
from
October 19, 2026 19:49
46f43a9 to
3cc5745
Compare
Material's spacing.compactMode shrinks the chat's type and spacing, and the Wind chat marks compact mode with data-density="compact" on its root. The chat primitives now follow that attribute on any ancestor, with no prop plumbing. Root-level sizes read CSS variables whose fallbacks are today's values (gap-(--markdown-gap,0.75rem) and so on), and an in-data-[density=compact] variant sets the variables. A host className on the root replaces the variable-reading class, so it wins in both densities, and the default computed styles are unchanged. Nested elements (headings, lists, the thinking icon, avatar offsets) use the variant directly. - Markdown: body, lists and tables 14px to 12px, each heading one step down. Wind's own choices: an 18px line (Material uses 16px; this keeps the comfortable ratio) and tighter block, list and quote spacing (Material keeps 24px). - CodeBlock: source 13px on 20.8px to 12px on 18px, as Material's compact code renders, through two variables since the Prism style is inline. Code blocks in a ToolCall shrink too, which Material's do not. - Message and Bubble: text 14px to 12px, gaps between a group's messages and a message's parts halved, avatar offsets adjusted. - ThinkingIndicator and Citation: the sm look when no size is given. - Sources: items 14px to 12px. - ChatComposer and EmptyState: compact under any compact ancestor when no density prop or size is given; the prop wins. They change props or markup (textarea rows, button and chip sizes, the heading element), which classes cannot, so a shared internal hook finds the ancestor and watches only its attribute. Wind-only compact choices, where Material keeps its sizes: the code block header shortens to 28px with 24px buttons, bubble padding tightens to 10px by 6px, message actions drop to 20px, an unsized ToolCall takes the sm look with a 4px body gap, ToolCall and DisclosureTree rows lose 2px of vertical padding, and attachment chips step their padding and media down one size (an xs chip goes from 38px to 30px). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
BenGSchulz
force-pushed
the
feat/apollo-wind-chat-compact-density
branch
from
October 19, 2026 21:11
3cc5745 to
d1d14ba
Compare
This branch had an error being deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
MST-16573, part of the Wind chat epic MST-16172. Stacked on #1402 (chat primitive gaps), which is stacked on #1400 (math fences). This is the last PR of the apollo-wind stack.
Material's
spacing.compactModeshrinks the chat's type and spacing. The Wind chat marks compact mode withdata-density="compact"on its root. The apollo-wind chat primitives now follow that attribute on any ancestor, with no prop plumbing.Mechanism and contract
in-data-[density=compact]:variant, which compiles to:where(*[data-density="compact"]) &(checked with Tailwind 4.1.17, the build's version, and 4.3.0, the test runner's).gap-(--markdown-gap,0.75rem) text-(length:--markdown-font-size,0.875rem) leading-(--markdown-leading,1.625), and the compact variant only sets the variables (in-data-[density=compact]:[--markdown-gap:0.5rem]). A host class such asgap-1replaces the variable-reading class throughcn()(tailwind-merge groups them; tested), so the compact value has nothing to change. The Wind chat'sMessageContent className="gap-0"andMarkdown className="gap-1 text-xs leading-4"keep working.densityprop orsizethey are compact under any compact ancestor, like the CSS variant. They share an internal hook (src/lib/use-ancestor-density.ts, not exported) that finds the nearest compact ancestor after each render and watches only that ancestor's attribute; an ancestor that gains the attribute later is picked up on the next render. The prop orsizewins.smlook in compact only when nosizeis given.Why the composer and EmptyState use JS when everything else uses classes: density there changes props or markup, not just classes. The composer switches the textarea's
rows/minRows(1 or 2; the autosizing Textarea writes its height inline from them), the attach and submit Buttonsize(3xsor2xs), the attachment chipsize(xsorsm), and it exposesuseChatComposer().densityto host parts; EmptyState swaps its heading for a paragraph. A pure CSS version would repeat Button's and Attachment's size scales as compact overrides (about ten class strings that would drift), make the shared Textarea read its minimum rows from CSS, and leave the context value stale for host parts, so the roughly 30-line hook stays.Material to Wind mapping
smpill (10px), no size givendensitypropsize="default", heading titlesizeis givensizesmlook: p 8px, 12px/16px text, 16px icon, indent 8px, body gap 4px (Wind's choice)Ticket claims corrected
The brief asked for a shorter code block header and smaller copy button, reduced bubble padding, smaller MessageActions controls, and possibly smaller ToolCall, DisclosureTree and Attachment gaps. Material's compact mode does none of these:
compactMode; only the code font changes.compactMode; only the type and the two message gaps change.3xs, notmd, and Material's action bar ignores compact mode.compactMode.So none of these is Material parity. At review they were adopted as Wind-only choices (Wind leads here; Material may follow), listed below.
Wind-only choices
smlook with a 4px body gap, ToolCall and DisclosureTree rows lose 2px of vertical padding, and Attachment chips step padding and media down one size (anxschip 38px to 30px) while their type stays legible. Root-level properties follow the variable contract, so a host className still wins; Attachment's padding classes were alreadyhas-*variants, so a host override needs the same variant, as before.What the Wind chat needs to do
Nothing for compact beyond the
data-densityattribute it already sets on its root. It may drop thedensityprop it passes to the composer, render its empty history message withEmptyState(nosizeneeded), and drop its own!size overrides on attachment chips, since anxschip is now 30px in compact.Stories
compactarg (off by default, so the default canvas is unchanged) that setsdata-density="compact"on the panel and lets the footer composer and the empty state take their density from the panel.Markdown/CompactDensity(default and compact side by side, with a wide table and a long code line) andCodeBlock/CompactDensity.Tests
:where(*[data-density="compact"]).gap-1 text-xs leading-4on Markdown andgap-0on MessageContent replace the variable-reading classes inside a compact ancestor.gap-(--x,…),text-(length:--x,…),leading-(--x,…)andh-(--x,…)with their plain counterparts.comfortable, and the prop wins.tsc --noEmit, the full apollo-wind suite andpnpm --filter @uipath/apollo-wind build.🤖 Generated with Claude Code