diff --git a/.changeset/timeline-actions-narrow-viewport.md b/.changeset/timeline-actions-narrow-viewport.md new file mode 100644 index 00000000000..9adf82e3dc6 --- /dev/null +++ b/.changeset/timeline-actions-narrow-viewport.md @@ -0,0 +1,5 @@ +--- +'@primer/react': patch +--- + +Timeline: `Timeline.Actions` now wraps onto a new row below `Timeline.Body`, left-aligned with the body content, when `Timeline.Item` is narrower than 480px. diff --git a/packages/react/src/Timeline/Timeline.features.stories.module.css b/packages/react/src/Timeline/Timeline.features.stories.module.css index 475b9abf9db..d1337a60e6b 100644 --- a/packages/react/src/Timeline/Timeline.features.stories.module.css +++ b/packages/react/src/Timeline/Timeline.features.stories.module.css @@ -49,19 +49,31 @@ color: var(--fgColor-muted); } +.InlineAvatar { + vertical-align: middle; + margin-right: var(--base-size-4); +} + +/* Title on top, lock icon and state pill stacked below at narrow; + inline row with the title claiming remaining space above 480px. */ .CrossReferenceRow { display: flex; + flex-direction: row; align-items: flex-start; gap: var(--base-size-12); margin-top: var(--base-size-4); } -.CrossReferenceContent { - flex: 1; - min-width: 0; +@container (width < 480px) { + .CrossReferenceRow { + flex-direction: column; + gap: var(--base-size-4); + } } .CrossReferenceTitle { + flex: 1; + min-width: 0; font-size: var(--text-title-size-small); line-height: var(--text-title-lineHeight-small); } @@ -87,18 +99,6 @@ color: var(--fgColor-accent); } -.CrossReferenceMeta { - color: var(--fgColor-muted); - flex-shrink: 0; -} - -.CrossReferenceActions { - display: flex; - align-items: center; - gap: var(--base-size-12); - flex-shrink: 0; -} - .CrossReferenceTaskline { display: flex; align-items: center; @@ -108,9 +108,18 @@ color: var(--fgColor-muted); } -.InlineAvatar { - vertical-align: middle; - margin-right: var(--base-size-4); +.CrossReferenceMeta { + color: var(--fgColor-muted); + flex-shrink: 0; +} + +/* Hides Timeline.Actions children (Verified / Unverified signature labels + on commit rows) when Timeline is narrow, so only the compact icon + SHA + cluster remains after the Actions row wraps beneath Body. */ +@container (width < 480px) { + .HideAtNarrow { + display: none; + } } .Timestamp { diff --git a/packages/react/src/Timeline/Timeline.features.stories.tsx b/packages/react/src/Timeline/Timeline.features.stories.tsx index 806f7b42e5c..9c930722b09 100644 --- a/packages/react/src/Timeline/Timeline.features.stories.tsx +++ b/packages/react/src/Timeline/Timeline.features.stories.tsx @@ -280,7 +280,7 @@ export const WithActions = () => ( - + 3fbdc0 @@ -297,7 +297,7 @@ export const WithActions = () => ( - + 3fbdc0 @@ -322,24 +322,20 @@ export const WithActions = () => ( just now
-
-
- - Fix positioning of Autocomplete overlay menu{' '} - primer/react#7431 - -
-
- - 17 tasks -
-
-
- - - Open - +
+ + Fix positioning of Autocomplete overlay menu{' '} + primer/react#7431 +
+ + + Open + +
+
+ + 17 tasks
diff --git a/packages/react/src/Timeline/Timeline.module.css b/packages/react/src/Timeline/Timeline.module.css index bbedaee66a7..340516926f5 100644 --- a/packages/react/src/Timeline/Timeline.module.css +++ b/packages/react/src/Timeline/Timeline.module.css @@ -4,6 +4,10 @@ list-style: none; padding: 0; margin: 0; + /* Container for the narrow-viewport rules at the end of this file. Uses + an inline-size container so behavior tracks the timeline's own width, + not the viewport (works inside narrow side panels and split views). */ + container-type: inline-size; &:where([data-clip-sidebar='start']), &:where([data-clip-sidebar='both']) { @@ -194,3 +198,33 @@ gap: var(--base-size-8); flex-shrink: 0; } + +/* Below 480px inline size, wrap Timeline.Actions onto its own row under + Timeline.Body via a 2-column grid. The badge keeps the left column so + the vertical rule stays consistent. */ +@container (width < 480px) { + .TimelineItem { + display: grid; + grid-template-columns: auto 1fr; + grid-template-areas: + 'badge body' + '. actions'; + } + + .TimelineBadgeWrapper { + grid-area: badge; + } + + .TimelineBody { + grid-area: body; + } + + .TimelineItemActions { + grid-area: actions; + /* Reset flex-row auto-push; the wrapped row sits under Body. */ + margin-top: var(--base-size-8); + margin-left: 0; + justify-content: flex-start; + min-height: 0; + } +}