Timeline: add comment event stories (Phase 2)#8072
Conversation
|
There was a problem hiding this comment.
Pull request overview
Adds a new Storybook-only “Features” story group that recreates GitHub Issues timeline comment cards using Timeline.Item + Timeline.Avatar plus a co-located CSS module for the card shell (header, caret, reactions).
Changes:
- Added
Timeline.comments.features.stories.tsxwith a localCommentCardhelper and a singleEventCommentexport showing 5 actor variants (standard user, bot, Copilot, Dependabot, via-app). - Added
Timeline.comments.features.stories.module.cssto style the comment-card layout (card chrome, caret, avatar positioning, reactions row). - Wrapped stories in the
primer_react_timeline_list_semanticsfeature-flag decorator for future<ol>/<li>semantics.
Show a summary per file
| File | Description |
|---|---|
| packages/react/src/Timeline/Timeline.comments.features.stories.tsx | Adds the Storybook “Issues” comment-card event group and supporting local composition helpers. |
| packages/react/src/Timeline/Timeline.comments.features.stories.module.css | Provides scoped CSS to visually compose a GitHub-like comment card (caret, header bar, reactions, octicon avatars). |
Review details
- Files reviewed: 2/2 changed files
- Comments generated: 1
- Review effort level: Low
Per the Figma spec, render the Dependabot comment gutter avatar as a white DependabotIcon on an accent-blue rounded square via the octicon-avatar mode (new avatarIconShape/avatarIconTone props), replacing the off-brand photo URL. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Match Figma: avatar left edge ~72px left of the rail, card overlaps the rail by 16px (so the rail runs behind the card's left edge), avatar→card ~56px, with the caret bridging the gap. Remove the divider above the reactions row to match the live comment card. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Avoid a runtime throw when the click target is a non-Element (e.g. an SVG octicon) by checking e.target instanceof Element before calling closest. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Reconstruct GitHub's dual-avatar pattern — a small app/agent avatar overlapping the bottom-right of the large author avatar, for app/agent co-authored comments (e.g. "monalisa … – with GitHub Actions"). Add an appAvatar prop to CommentCard and a new story section. Based on Primer's .avatar-parent-child but corrected: uses a symmetric offset and an opaque ring instead of .avatar-child's long-standing asymmetric right:-15%/bottom:-9% offset and translucent shadow (github/github#439417). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…nts to Private/ namespace
Add packages/react/src/Timeline/internal/timelineStoryHelpers.{tsx,module.css}
with six story-only helpers (VariantSection, RealisticTimeline, Examples,
BoldLink, InlineAvatar, MutedTime) for the Timeline event-story surfaces to
share. Never exported from the package index (stories don't ship), so no public
API surface. BoldLink/InlineAvatar/MutedTime shim live-GitHub styling Primer
doesn't express yet (tracked in github/primer#6826/#6827/#6828).
Retitle the Comments stories to Private/Components/Timeline/Events/Comments and
consume the shared VariantSection + RealisticTimeline. Pure refactor — Storybook
rendering unchanged.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ts story
Add a gutter-less comment form: a ~24px avatar inline in the header before the
author ('{author} commented {time}') with the body spanning full width, alongside
the existing large-gutter variants. This is both the new Issues issue_inline_avatars
rendering (github-ui ActivityHeader forceInlineAvatar) and the responsive
narrow-viewport form. Consumes the shared InlineAvatar helper; wraps the large-gutter
sections in a .GutterGroup so the inline section renders full-width.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
02c0dad to
a3b9975
Compare
…e Comments to Internal/, add Helpers story - Large-gutter comment cards now collapse to the compact inline form below 768px via a container query on the Comments root (mirrors live github.com: gutter avatar + 56px indent only at >=768px; small inline header avatar + full-width body below). Both avatars stay in the DOM, toggled by CSS. - The always-inline (compact) card now overlaps the rail by ~16px like the large card, instead of sitting flush. - Retitle Comments story to Components/Timeline/Internal/Comments (out of Private/). - Add Components/Timeline/Internal/Helpers story documenting the six shared internal helpers in isolation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…Comments story to Events/ (resolves #8072 review) Move the CommentCard component + CommentCardProps + its sub-helpers (octicon/inline avatars, parent-child app avatar, reactions) into internal/CommentCard.tsx, and all CommentCard-specific classes + the responsive @container collapse rules into internal/CommentCard.module.css. The story keeps only the example data, variant catalog, and the container-establishing .CommentsRoot. Retitle the story Components/Timeline/Internal/Comments -> Components/Timeline/Events/Comments (code location and sidebar location are decoupled; Internal/ is reserved for the Helpers primitive docs). Pure move — zero visual/functional change, verified at >=768px and <768px. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ts IA to Internal/Comment cards - The responsive large cards kept their speech-bubble caret when collapsing to the inline form below 768px, pointing at a gutter avatar that's no longer shown. Toggle the .CardResponsive caret with the same container query as the gutter avatar: hidden <768px, shown >=768px. - Retitle the Comments story to Components/Timeline/Internal/Comment cards so it sits next to Internal/Helpers (only one comment story; it documents the internal CommentCard). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…Helpers leaves Both internal stories now share title 'Components/Timeline/Internal' with the leaf name coming from the export: rename EventComment -> CommentCards (leaf 'Comment cards') and keep Helpers (leaf 'Helpers'). This removes the extra 'Event comment' sub-leaf and the redundant 'Helpers/Helpers' nesting, so both render as siblings directly under Internal. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add CommentCards.storyName = 'Comment cards' so the Internal leaf reads in sentence case instead of Storybook's auto-title-cased 'Comment Cards'. Story ID stays components-timeline-internal--comment-cards. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Part of github/primer#6663 (Phase 2).
Adds Storybook Features stories that recreate GitHub's timeline comment cards using Primer React, plus the shared internal helper module the whole Phase 2 stack builds on.
What's included
1. Comment card stories —
Components/Timeline/Internal/Comment cardspackages/react/src/Timeline/Timeline.comments.features.stories.tsx(+ co-located CSS module). A single story (CommentCards, shown as "Comment cards") renders 7 labeled sections, each built from the internalCommentCardhelper:Authorsubject-author badge, reactions rowbotlabelAIlabel, name renders as "Copilot"DependabotIconon brand blue),botlabel2. Shared internal helper module —
Timeline/internal/Extracted so the six surface stories consume components instead of copy-pasting primitive clusters (resolves review feedback about baking helpers into the story):
internal/timelineStoryHelpers.tsx(+.module.css) —VariantSection,RealisticTimeline,Examples,BoldLink,InlineAvatar,MutedTime. The last three reproduce live-GitHub styling Primer doesn't express natively yet and are tracked to remove upstream (github/primer#6826 bold inline link, feat(RelativeTime): remove support for sx prop #6827 inline avatar, feat: remove sx prop from Button, LinkButton, IconButton, and ButtonG… #6828 muted timestamp).internal/CommentCard.tsx(+.module.css) — the self-contained comment-card composition (header, body, reactions, caret, octicon/parent-child avatars, responsive rules). Internal only, not exported from the package index.internal/timelineStoryHelpers.stories.tsx— aComponents/Timeline/Internal/Helpersstory documenting the six shared helpers in isolation.Sidebar tree:
Responsive behavior (matches github.com)
The large-gutter comment cards collapse to the inline-avatar form below 768px — verified against live github-ui (
ActivityHeaderforceInlineAvatar/avatarHiddenOnMedium,LayoutHelpersnonLeadingElement_inlineAvatars). Implemented with a container query on a Comments-local root: ≥768px shows the 40px gutter avatar + rail + speech-bubble caret; <768px hides the gutter avatar and the caret, renders a 24px inline avatar in the header ("{author} commented {time}"), and runs the body full-width. The compact section demonstrates this form directly; it's also the responsive rendering for every comment.Source of truth
Recreated from the live React components in github-ui
packages/commenting(ActivityHeader,CommentAuthorAssociation,CommentSubjectAuthor,IssueComment). Key denotations were verified against live, not invented:bot/AI— fromLABELS.authorLabel(isBot, isCopilot)(botfor bots/Dependabot,AIfor Copilot, name shown as "Copilot"). Not "Bot"/"Copilot".Authorbadge is the subject-author badge (CommentSubjectAuthor,LABELS.commentAuthor), shown when the commenter opened the issue — distinct from association values (Member/Owner/Collaborator/Contributor).inline(underlined) link..avatar-childasymmetric offset (right: -15%/bottom: -9%) + translucent#fffcring with a symmetric offset + opaque ring (github/github#439417).Deferred (not in this PR): threaded review replies, embedded-in-thread comments, and minimized/collapsed states. The
CommentCardhelper has anisReplyprop wired (drops border/caret/gutter avatar) so those can be added later without reshaping it.Accessibility
Timeline.Badgeocticons render bare (aria-hidden) to avoid double-announcing the adjacent body text.data-a11y-link-underlines="true"wrapper that reproduces GitHub's default-on "Show link underlines" setting, so inline links satisfy axelink-in-text-block(WCAG 1.4.1) without diverging from live.e.target instanceof Elementbeforeclosest('a')(guards against SVG/octicon click targets).Scope & conventions
FeatureFlagsdecorator enablingprimer_react_timeline_list_semantics(future-state<ol>/<li>DOM; refs Timeline: Use list semantics for screen reader navigation #7910).Timeline.docs.jsonorbuild.ts). Individual timeline events are not consumer-facing components.data-*filtering taxonomy (github/primer#6663) is intentionally deferred.Changelog
New
Timeline.comments.features.stories.tsx(+ CSS module) — comment-card stories (Components/Timeline/Internal/Comment cards).Timeline/internal/timelineStoryHelpers.tsx(+ CSS module) — shared internal story helpers (VariantSection,RealisticTimeline,Examples,BoldLink,InlineAvatar,MutedTime), consumed by all six Phase 2 surface stories.Timeline/internal/CommentCard.tsx(+ CSS module) — internal comment-card composition helper.Timeline/internal/timelineStoryHelpers.stories.tsx—Components/Timeline/Internal/Helpersreference story.Changed
Removed
Rollout strategy
skip changesetlabel is applied.Testing & Reviewing
@primer/doc-genbaseline error inscript/components-json/build.tsis unchanged).packages/commentingReact components; responsive collapse measured headless at ≥768px and <768px.Merge checklist