Improve PR comment sidebar readability

Co-authored-by: Orca <help@stably.ai>
This commit is contained in:
brennanb2025
2026-06-24 12:28:59 -07:00
co-authored by Orca
parent 7369c4c957
commit 253ef03b1e
5 changed files with 65 additions and 12 deletions
@@ -145,6 +145,7 @@ import { localizedHostedReviewCopy } from '@/i18n/hosted-review-localized-copy'
import { translate } from '@/i18n/i18n'
import { groupPRComments, type PRCommentGroup } from '@/lib/pr-comment-groups'
import { openChecksPanelHostedReviewUrl } from './checks-panel-hosted-review-click-routing'
import { ChecksPanelUpdatedAtMetadata } from './checks-panel-updated-at-metadata'
import {
clearPullRequestGenerationRequiresPushBeforeCreate,
createRunningPullRequestGenerationRecord,
@@ -3469,11 +3470,10 @@ export default function ChecksPanel(): React.JSX.Element {
{/* Updated at */}
{activeReview.updatedAt && (
<div className="text-[10px] text-muted-foreground/60">
{reviewShortLabel}{' '}
{translate('auto.components.right.sidebar.ChecksPanel.34464d00b9', 'updated')}
{new Date(activeReview.updatedAt).toLocaleString()}
</div>
<ChecksPanelUpdatedAtMetadata
reviewShortLabel={reviewShortLabel}
updatedAt={activeReview.updatedAt}
/>
)}
{/* Merge / Delete Workspace actions */}
{activeReview && activeWorktree && repo && (
@@ -0,0 +1,28 @@
// @vitest-environment happy-dom
import { renderToStaticMarkup } from 'react-dom/server'
import { describe, expect, it } from 'vitest'
import { ChecksPanelUpdatedAtMetadata } from './checks-panel-updated-at-metadata'
function renderMetadataText(reviewShortLabel: string): string {
const container = document.createElement('div')
container.innerHTML = renderToStaticMarkup(
<ChecksPanelUpdatedAtMetadata
reviewShortLabel={reviewShortLabel}
updatedAt="2026-06-24T17:30:00.000Z"
/>
)
return container.textContent ?? ''
}
describe('ChecksPanel updated-at metadata', () => {
it.each(['PR', 'MR'])(
'renders a whitespace boundary between the %s updated label and timestamp',
(reviewShortLabel) => {
const text = renderMetadataText(reviewShortLabel)
expect(text).toMatch(new RegExp(`${reviewShortLabel} updated\\s+\\S`))
expect(text).not.toMatch(new RegExp(`${reviewShortLabel} updated\\S`))
}
)
})
@@ -0,0 +1,20 @@
import type React from 'react'
import { translate } from '@/i18n/i18n'
type ChecksPanelUpdatedAtMetadataProps = {
reviewShortLabel: string
updatedAt: string
}
export function ChecksPanelUpdatedAtMetadata({
reviewShortLabel,
updatedAt
}: ChecksPanelUpdatedAtMetadataProps): React.JSX.Element {
return (
<div className="text-[10px] text-muted-foreground/60">
{reviewShortLabel}{' '}
{translate('auto.components.right.sidebar.ChecksPanel.34464d00b9', 'updated')}{' '}
{new Date(updatedAt).toLocaleString()}
</div>
)
}
@@ -22,8 +22,12 @@ describe('pr-comment-presentation', () => {
expect(cards.avatar).toContain('border-border')
expect(cards.avatar).toContain('bg-background')
expect(getPRCommentPresentationClasses('focus').useCardLayout).toBe(true)
expect(getPRCommentPresentationClasses('focus').commentBody).toContain('text-[14px]')
const focus = getPRCommentPresentationClasses('focus')
expect(focus.useCardLayout).toBe(true)
expect(focus.commentBody).toContain('text-[13px]')
expect(focus.commentBodyReply).toContain('text-[13px]')
expect(focus.author).toContain('text-[13px]')
expect(focus.list).toContain('gap-3')
})
it('preserves the legacy flat layout tokens', () => {
@@ -96,6 +96,9 @@ const COMMENT_AVATAR =
const RESOLVED_SECTION_LABEL =
'text-[11px] font-semibold uppercase tracking-wider text-muted-foreground'
const CARD_COMMENT_BODY_SIZE = 'text-[13px] leading-relaxed'
const CARD_COMMENT_AUTHOR_SIZE = 'text-[13px]'
const RESOLVED_SECTION_TRIGGER = cn(
RESOLVED_SECTION_LABEL,
'rounded-none border-0 bg-transparent px-3 py-2 shadow-none hover:bg-accent/40 hover:text-foreground hover:no-underline'
@@ -173,8 +176,6 @@ export function getPRCommentPresentationClasses(
}
const isFocus = variant === 'focus'
const bodySize = isFocus ? 'text-[14px] leading-relaxed' : 'text-[13px] leading-relaxed'
const authorSize = isFocus ? 'text-[14px]' : 'text-[13px]'
const listGap = isFocus ? 'gap-3' : 'gap-2'
const bodyPadding = isFocus ? 'px-4 py-3' : 'px-4 py-2.5'
const headerPadding = isFocus ? 'px-3.5 py-2.5' : 'px-3 py-2'
@@ -191,10 +192,10 @@ export function getPRCommentPresentationClasses(
commentRowReply: `border-t ${COMMENT_CARD_DIVIDER} bg-muted/25 dark:bg-muted/10`,
commentHeader: `flex flex-col gap-1 border-b ${COMMENT_CARD_DIVIDER} ${headerPadding}`,
commentHeaderReply: `flex min-w-0 items-center gap-2 ${headerPadding}`,
commentBody: `${bodyPadding} ${bodySize} text-foreground`,
commentBodyReply: `${bodyPadding} ${bodySize} text-foreground`,
commentBody: `${bodyPadding} ${CARD_COMMENT_BODY_SIZE} text-foreground`,
commentBodyReply: `${bodyPadding} ${CARD_COMMENT_BODY_SIZE} text-foreground`,
commentBodyMarkdown: MARKDOWN_BASE,
author: `min-w-0 flex-1 truncate ${authorSize} font-semibold text-foreground`,
author: `min-w-0 flex-1 truncate ${CARD_COMMENT_AUTHOR_SIZE} font-semibold text-foreground`,
authorResolved: 'text-muted-foreground',
avatar: `size-5 ${COMMENT_AVATAR}`,
avatarReply: `size-4 ${COMMENT_AVATAR}`,