Skip to content

feat(web): collapse the question prompt from its header - #6773

Merged
juliusmarminge merged 1 commit into
pingdotgg:mainfrom
Jardo-51:feature/4431-collapsible-question-prompt
Aug 15, 2026
Merged

feat(web): collapse the question prompt from its header#6773
juliusmarminge merged 1 commit into
pingdotgg:mainfrom
Jardo-51:feature/4431-collapsible-question-prompt

feat(web): collapse the question prompt from its header

c26aed8
Select commit
Loading
Failed to load commit list.
MacroscopeApp / Macroscope - UI Consistency succeeded Aug 15, 2026 in 5m 24s

UI Consistency: No issues found

All clear

Details

Note

Your check run agent prompt is: .macroscope/check-run-agents/ui-consistency.md
More information about how Check Run Agents work can be found in our Help Center.


🔍 Agent activity — reasoning, no tool calls

💭 I'm looking at the collapsible primitive component and examining how it's used in the ComposerPendingUserInputPanel. I'm noticing the Collapsible root is getting the py-3 class, but I need to verify it actually accepts className as a prop. Looking at the spacing issue — the original card wrapper had px-4 py-3 sm:px-5, but now the root only has py-3 while the trigger wrapper adds px-1.5 sm:px-2.5 with the trigger itself at px-2.5, which means the effective left padding for the header ends up being 16px on mobile (matching the original px-4) and 10px on small screens. The panel padding changed slightly with pt-2 pb-0.5 instead of the original bottom margin, and when collapsed the panel content gets hidden while the root's py-3 padding remains intact. The height animation on the panel works through the CSS custom property, and keyboard shortcuts are intentionally disabled when the section is collapsed — all of this seems consistent with the design. The trigger styling looks good with outline-none and focus-visible:ring-1 matching the option buttons, and the negative margin on the trigger (-my-1) doesn't cause any overlap issues. The counter badge positioning is unchanged, and the test expectations for aria-expanded and the panel div should render correctly with Base UI's SSR. Now I'm checking if there's an existing pattern elsewhere in the repo for collapsible headers with chevrons to ensure consistency, and verifying the keyboard behavior and accessible naming are correct. I'm checking whether the focus ring on the bottom button might get clipped by the panel's overflow-hidden constraint, especially considering the padding and ring offset behavior in Tailwind. Now I need to verify the parent container's padding structure — the wrapper previously had px-4 py-3 sm:px-5, so I should check if moving padding to individual children affects things like border separators or other layout expectations. The binary detection is cutting off my search, so I'll try looking for "pendingUserInputs=" in the ChatComposer file instead to locate the render site. Looking at the mobile-collapsed state, the compact row persists when the pending user input panel collapses, which is expected. When collapsed, the option keyboard shortcuts are intentionally disabled and the buttons inside the collapsed panel become unfocusable since Base UI's Collapsible.Panel uses the hidden attribute. The primitive handles the height styling correctly in this state. Checking the trigger classes against the primitive contract — CollapsibleTrigger includes cursor-pointer styling, and the focus-visible ring matches the pattern used by option buttons in the same file. The Collapsible.Root renders a div by default, so the className applies as expected, and the data-pending-user-input-toggle attribute spreads through props to the DOM without issues. The test-only data attribute in production DOM isn't a UI consistency violation. Now checking the spacing math: the collapsed root's py-3 (12px) plus the trigger's -my-1 py-1.5 creates a net 2px extra vertical space, and with the panel's pt-2 (8px), the gap between trigger and content is about 10px — matching the previous 8px header margin-bottom. Left alignment stays consistent at 16px inset (6px wrapper + 10px trigger padding), and the chevron sits flush at the right edge where the text column ends. The hover background extends 10px beyond the text column on both sides as intended. Checking for potential issues: the focus ring on option buttons has 1px width against 8px top padding, so no clipping there. The panel's overflow-hidden clips content only if it exceeds the measured height, but the UI re-measures on changes so that's handled. The keyboard handler dependency on isCollapsed is fine. When collapsed, keyboard selection is disabled anyway. Still looking at the mobile-collapsed composer variant with its compact row. The trigger uses a shared primitive across call sites, which is good. Chevron rotation varies between group-data-panel-open:rotate-90 (data attribute driven) and React state with isCollapsed && rotate-180 — both patterns exist in the codebase. The focus ring on the trigger uses focus-visible:ring-1 but also sets outline-none, and in Tailwind v4 that affects outline styling. Theme tokens like hover:bg-muted/40 and text-secondary-label are consistent with existing usage. Now I need to check whether Base UI's Collapsible properly renders aria-expanded and the panel content during SSR. Looking at the hit target size for the trigger — it's around 32px with the badge and padding, which is below the 44px guideline for coarse pointers but seems acceptable given what the repo already uses elsewhere. Now I'm thinking through the margin collapsing behavior with the -my-1 negative margin on the trigger inside the wrapper div. The wrapper has horizontal padding but no vertical padding or border, so the child's vertical margins should collapse through to the parent. The Collapsible root's py-3 padding would prevent the margin from collapsing further up the tree. So effectively, the wrapper gets shifted up by 4px relative to the root's padding edge, creating an 8px top gap instead of 12px. The bottom margin similarly reduces the gap between the wrapper and the following panel to about 4px. It's an intentional spacing adjustment. For accessibility, the header change from a span label to a button is fine, and the truncated question text in the span works with the aria-label when collapsed. One thing that stands out: the code uses a native title attribute for tooltips instead of the repo's Tooltip component. The codebase probably has other title= usages, but it's worth noting since the repo seems to prefer its own UI primitives over native controls. This could be flagged as a minor inconsistency. The focus-ring clipping is what I need to examine next. Looking at whether Base UI's Collapsible.Panel unmounts children when closed — if keepMounted defaults to false, the children would unmount, which is fine. But I should verify the auto-advance and keyboard behaviors still work correctly, and check whether the test requirements around focused tests are being met. The existing tests cover the initial expanded render via SSR, but they don't actually test the collapse interaction itself or keyboard-shortcut suppression when the panel is collapsed. If this repo has a DOM testing setup like jsdom and testing-library, relying only on SSR tests seems insufficient given that the behavior changed — keyboard shortcuts are now disabled when collapsed, and state transitions occur. This could be a legitimate finding about needing more comprehensive interaction tests. Let me look at how tests are structured in this codebase to see what's expected. Looking at the padding structure more carefully — the horizontal padding that was previously on the whole card is now split between the header wrapper and the panel separately, which should be fine. The mobile-collapsed variant's compact row is a separate sibling so that shouldn't cause issues either. I'm checking whether the Collapsible component itself has the right padding applied... When the panel is collapsed, the root still has bottom padding, so the collapsed header gets the expected spacing. The Base UI Collapsible's transition classes are shared across variants, which is consistent. I'm examining potential issues with the layout when collapsed — the truncated question span uses flex-1 with the chevron using ml-auto, which means ml-auto has no effect when there's a flex-1 sibling, but that's harmless. When not collapsed, ml-auto correctly pushes the chevron right. The row structure when collapsed with multiple questions (header, counter, truncated question, chevron) looks fine too. Now checking whether the group class on the trigger conflicts with group classes on the option buttons inside the panel... the option buttons' group-hover: styles would only trigger on their own hover since they're nested groups, but the trigger's group is a sibling to the panel, not an ancestor, so there's no conflict. The kbd inside the panel uses group-hover: but that refers to the option button's group, not the trigger's. The chevron's group-hover:text-foreground on the trigger works as expected. I'm noticing the trigger has focus-visible:ring-1 focus-visible:ring-primary/25 without a border, while the option buttons add focus-visible:border-primary/40 on top of the ring — checking if this inconsistency matters... There's no focus-visible outline issue to worry about. I'm thinking through potential functional regressions—like when a card is collapsed and the user answers a question, the collapsed state might reopen unexpectedly if the question ID doesn't update properly. That's unlikely in normal flows, but I should consider edge cases like multi-question prompts where collapsing one question, answering, and advancing could cause issues. The memoization of the card might also play a role here. The CollapsiblePanel structure looks solid—it applies horizontal padding to the animated element, which is fine since the height animation doesn't care about left/right padding. The scrollHeight measurement works correctly with this setup. The trigger's title attribute provides useful context since the visible label is already there. When the header is long and the trigger becomes a wide row with truncation, that should work fine too. The negative margin on the trigger creates a subtle visual effect where the hover background extends about 4 pixels closer to the question text below, but that's a minor spacing consideration. Looking at the broader pattern, the chevron-in-collapsible-trigger approach is repeated across several files with different geometry each time, so that's not a concern for this PR. The mobile padding matches the original design, though I'm noticing the ChatComposer has slightly different padding values on its other rows—worth checking if there's an inconsistency there. Now I'm thinking about the CSS variable behavior on initial render: if --collapsible-panel-height is undefined before the panel measures itself, the height declaration falls back to auto, which is fine since this is how the base primitive already works elsewhere. The real consideration here is that the panel content is dynamic—the options list changes based on selection state, which could affect the measured height. I'm wondering if Base UI's Collapsible panel uses a ResizeObserver to handle content changes, or if it only remeasures during open/close transitions. There's a potential issue: if the question advances while the panel is open (changing the number of options and thus the content height), and the height CSS variable doesn't get recomputed, the overflow-hidden constraint could clip the new content. I need to check the Base UI version and how the panel implementation handles dynamic content updates. I'm wondering if Base UI actually sets the height variable to auto once the open animation completes, or if it stays locked at the measured height — that would explain why dynamic content would get clipped if the panel doesn't remeasure. Looking at Base UI's recommended CSS pattern and how their implementation uses a ResizeObserver to track dimension changes, it seems like the library is designed to continuously update that height variable as content shifts. The real issue might be simpler: the content was previously unconstrained in a regular div, but now it's locked inside a fixed-height overflow-hidden container. If the question content expands while the panel is open, it would get cut off since the height isn't being recalculated to match the new content size. Let me check the dependency versions and search the codebase for any existing handling of dynamic content in collapsible panels. Looking at Base UI v1.4.1's Collapsible.Panel implementation, there's a ResizeObserver being used with a layout effect that checks conditions like whether the panel is hidden until found or should stay mounted, and it appears to be handling content resize behavior. The documentation mentions that CSS variables get updated when panel contents change size while open, and there was likely a PR addressing dynamic content resizing in later versions. Since v1.4.1 is fairly recent post-1.0, it probably handles this scenario. I'm uncertain whether changing the active question ID would trigger a re-measure, so I won't flag that speculatively based on the instructions. Now I'm examining another potential issue: the negative margin and wrapper padding combination that might be overriding the panel's core height properties. I'm also checking the outline-none class in forced-colors mode — Tailwind v4 sets outline-style:none which can remove focus outlines in that context. The repo has a forced-colors media block in index.css, but since the existing option buttons already use this same pattern, it's consistent within the file and not a new issue worth failing on. I'm verifying the data attributes and imports are correct — data-pending-user-input-toggle gets forwarded by Base UI's Trigger, the type="button" assertion matches what Trigger renders, and useState is already imported on line 2. Now I'm checking the hover treatment on the trigger against other collapsible triggers in the repo — it uses hover:bg-muted/40 and group-hover:text-foreground while others use opacity transitions, but that's purely aesthetic. I'm also confirming the collapsed state doesn't break keyboard shortcuts or the auto-advance timer, and I want to see if ComposerPendingApprovalPanel has a similar collapse pattern for consistency. Checking the hover state styling on the trigger — the hover:bg-muted/40 over bg-muted/20 should layer fine. I'm also verifying that text-secondary-label is actually defined as a utility since it's used elsewhere in the file. There's one more potential accessibility concern I want to flag: when the panel collapses, Base UI applies hidden, but the primitive's class is setting a height value that might conflict with that behavior. Looking at Base UI's Collapsible.Panel behavior — it has keepMounted defaulting to false, so when closed the panel unmounts after animation, which means it won't be focusable anyway. The number keys shortcut is document-level and properly disabled while collapsed, so that's safe. I'm not finding any actual issues here, so my conclusion is "All clear" — though I'm realizing the output format expects JSON while the instruction asks for plain text, so I need to reconcile that in the response.


Agent Credits: 169 credits