Skip to content

Conversation

@osterman
Copy link
Member

@osterman osterman commented Nov 28, 2025

Summary

Completely redesigned the changelog/blog list page to replace the narrow sidebar layout with a full-width vertical timeline view. The new design makes better use of screen real estate and provides an intuitive way to browse release notes.

What Changed

  • Vertical timeline layout with year/month grouping and alternate left/right entry positioning
  • Filter controls for filtering by year and tag
  • Collapsible sidebar on individual blog posts (collapsed by default to maximize content width)
  • Full abstracts on timeline cards (shows content before <!--truncate--> instead of "...")
  • Smooth hover effects with color transitions and connector line animations
  • Animated gradient title on the changelog index page
CleanShot 2025-11-28 at 18 40 55@2x

Implementation Details

  • Created ChangelogTimeline component with month/year grouping logic
  • Custom theme swizzles for BlogListPage, BlogLayout, and BlogSidebar/Desktop
  • CSS modules for scoped styling with responsive design
  • Filter state management using React hooks

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Interactive changelog timeline with year and tag filters and reset action
    • Timeline grouping by year/month with linked entries and optional excerpts
    • Tag badges with distinct color styling and accessible controls
    • Full‑width changelog page and custom blog layout for improved visual hierarchy
    • Collapsible blog sidebar (desktop) and responsive behavior for mobile/tablet

✏️ Tip: You can customize this high-level summary in your review settings.

…sidebar

Replace the narrow sidebar layout with a full-width vertical timeline view featuring:
- Year/month-based timeline grouping with alternate left/right entry positioning
- Filter controls for year and tag selection
- Collapsible sidebar on individual blog posts (collapsed by default)
- Full abstract display (content before <!--truncate-->) on timeline cards
- Smooth hover effects with color transitions and connector line animations

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@osterman osterman requested a review from a team as a code owner November 28, 2025 22:51
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 28, 2025

📝 Walkthrough

Walkthrough

Adds a new changelog timeline feature with year/tag filtering, grouping utilities, styles, and integration into a custom blog list layout plus a collapsible desktop sidebar.

Changes

Cohort / File(s) Summary
ChangelogTimeline Core
website/src/components/ChangelogTimeline/index.tsx, website/src/components/ChangelogTimeline/FilterBar.tsx, website/src/components/ChangelogTimeline/TimelineEntry.tsx, website/src/components/ChangelogTimeline/TimelineMonth.tsx, website/src/components/ChangelogTimeline/TimelineYear.tsx
New React components: main ChangelogTimeline (state, filtering, grouping), FilterBar (year/tag controls), TimelineEntry/TimelineMonth/TimelineYear (hierarchical timeline rendering).
ChangelogTimeline Utilities & Styles
website/src/components/ChangelogTimeline/utils.ts, website/src/components/ChangelogTimeline/styles.module.css
New utilities and types (BlogPostItem, grouping/filtering functions, tag color mapping) and comprehensive CSS module for timeline layout, responsiveness, and dark mode.
BlogListPage Integration
website/src/theme/BlogListPage/index.tsx, website/src/theme/BlogListPage/styles.module.css, website/src/css/custom.css
Replaces blog list with full-width changelog page that mounts ChangelogTimeline; adds page styles and global CSS to hide original sidebar and expand content.
BlogLayout
website/src/theme/BlogLayout/index.tsx, website/src/theme/BlogLayout/styles.module.css
New custom BlogLayout component and styles providing flexbox layout and support for a collapsible sidebar area.
BlogSidebar (Desktop variant)
website/src/theme/BlogSidebar/index.tsx, website/src/theme/BlogSidebar/Desktop/index.tsx, website/src/theme/BlogSidebar/Desktop/styles.module.css
New BlogSidebar wrapper that selects desktop/mobile variants; desktop variant implements a collapsible sidebar with toggle and year-grouped items plus associated styles.

Sequence Diagram

sequenceDiagram
    actor User
    participant FilterBar
    participant ChangelogTimeline
    participant Utils as Utils (filter/group)
    participant Timeline as Timeline components
    participant DOM

    User->>FilterBar: choose year/tag
    FilterBar->>ChangelogTimeline: onYearChange/onTagChange
    ChangelogTimeline->>ChangelogTimeline: update selectedYear/selectedTag
    ChangelogTimeline->>Utils: filterBlogPosts(items, year, tag)
    Utils-->>ChangelogTimeline: filtered items
    ChangelogTimeline->>Utils: groupBlogPostsByYearMonth(filtered items)
    Utils-->>ChangelogTimeline: YearGroup[]
    ChangelogTimeline->>Timeline: render TimelineYear/Month/Entry
    Timeline-->>DOM: render timeline nodes
    DOM-->>User: display filtered timeline

    alt no results
        User->>ChangelogTimeline: click reset
        ChangelogTimeline->>ChangelogTimeline: clear filters
        ChangelogTimeline->>Timeline: render reset state
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

  • Pay attention to: website/src/components/ChangelogTimeline/utils.ts (date parsing, grouping, filtering), prop typings across timeline components, integration points in website/src/theme/BlogListPage/index.tsx, and CSS module responsive/animation rules.

Possibly related PRs

Suggested reviewers

  • aknysh

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 31.25% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: redesigning the changelog page with a vertical timeline layout, which is the primary objective of this changeset.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch osterman/changelog-timeline

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 632d9ad and 8d3f400.

📒 Files selected for processing (2)
  • website/src/theme/BlogListPage/styles.module.css (1 hunks)
  • website/src/theme/BlogSidebar/Desktop/index.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • website/src/theme/BlogListPage/styles.module.css
  • website/src/theme/BlogSidebar/Desktop/index.tsx
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (linux)
  • GitHub Check: Summary

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot added the size/xl Extra large size PR label Nov 28, 2025
@mergify
Copy link

mergify bot commented Nov 28, 2025

Warning

This PR exceeds the recommended limit of 1,000 lines.

Large PRs are difficult to review and may be rejected due to their size.

Please verify that this PR does not address multiple issues.
Consider refactoring it into smaller, more focused PRs to facilitate a smoother review process.

@github-actions
Copy link

github-actions bot commented Nov 28, 2025

Dependency Review

✅ No vulnerabilities or license issues found.

Scanned Files

None

@codecov
Copy link

codecov bot commented Nov 28, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 71.98%. Comparing base (103aa0d) to head (e340e66).

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##             main    #1818   +/-   ##
=======================================
  Coverage   71.98%   71.98%           
=======================================
  Files         471      471           
  Lines       45222    45222           
=======================================
+ Hits        32553    32555    +2     
+ Misses      10071    10070    -1     
+ Partials     2598     2597    -1     
Flag Coverage Δ
unittests 71.98% <ø> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.
see 2 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@osterman osterman added the no-release Do not create a new release (wait for additional code changes) label Nov 29, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (5)
website/src/components/ChangelogTimeline/styles.module.css (1)

204-245: Add comments to explain positioning calculations.

The magic numbers 11.11% in the node and connector positioning (lines 219, 223, 237, 243) aren't immediately obvious. These likely derive from your 45% entry width and gap calculations, but adding brief comments would improve maintainability.

Example:

/* Position node at center line: 100% (entry width) + 11.11% (gap to center) - 8px (half node width) */
.entryLeft .entryNode {
  left: calc(111.11% - 8px);
}
website/src/components/ChangelogTimeline/TimelineEntry.tsx (3)

20-23: Consider locale flexibility for date formatting.

The date format is hardcoded to 'en-US'. If your site supports multiple locales, consider using the user's preferred locale or making this configurable.

-  const formattedDate = new Date(date).toLocaleDateString('en-US', {
+  const formattedDate = new Date(date).toLocaleDateString(undefined, {
     month: 'short',
     day: 'numeric',
   });

Passing undefined uses the browser's locale automatically.


20-23: Date format excludes year information.

The formatted date only shows month and day. For changelog entries spanning multiple years, this could cause confusion about which year an entry belongs to.

If year context is important, consider adding it conditionally:

   const formattedDate = new Date(date).toLocaleDateString('en-US', {
+    year: 'numeric',
     month: 'short',
     day: 'numeric',
   });

39-46: Tag truncation is silent.

Tags are silently limited to 3 without visual indication. Users won't know if there are additional tags.

Consider adding a "+N more" indicator when tags exceed 3:

           <div className={styles.entryTags}>
             {tags.slice(0, 3).map((tag) => (
               <span
                 key={tag.label}
                 className={clsx(styles.tag, styles[getTagColorClass(tag.label)])}
               >
                 {tag.label}
               </span>
             ))}
+            {tags.length > 3 && (
+              <span className={clsx(styles.tag, styles.tagDefault)}>
+                +{tags.length - 3} more
+              </span>
+            )}
           </div>
website/src/components/ChangelogTimeline/utils.ts (1)

59-59: Month name uses default locale.

Line 59 uses toLocaleString('default', ...) for month names. This differs from TimelineEntry.tsx which hardcodes 'en-US' for date formatting. Consider consistency across components if internationalization matters.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 154490b and 632d9ad.

📒 Files selected for processing (15)
  • website/src/components/ChangelogTimeline/FilterBar.tsx (1 hunks)
  • website/src/components/ChangelogTimeline/TimelineEntry.tsx (1 hunks)
  • website/src/components/ChangelogTimeline/TimelineMonth.tsx (1 hunks)
  • website/src/components/ChangelogTimeline/TimelineYear.tsx (1 hunks)
  • website/src/components/ChangelogTimeline/index.tsx (1 hunks)
  • website/src/components/ChangelogTimeline/styles.module.css (1 hunks)
  • website/src/components/ChangelogTimeline/utils.ts (1 hunks)
  • website/src/css/custom.css (1 hunks)
  • website/src/theme/BlogLayout/index.tsx (1 hunks)
  • website/src/theme/BlogLayout/styles.module.css (1 hunks)
  • website/src/theme/BlogListPage/index.tsx (1 hunks)
  • website/src/theme/BlogListPage/styles.module.css (1 hunks)
  • website/src/theme/BlogSidebar/Desktop/index.tsx (1 hunks)
  • website/src/theme/BlogSidebar/Desktop/styles.module.css (1 hunks)
  • website/src/theme/BlogSidebar/index.tsx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
website/**

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

website/**: Update website documentation in the website/ directory when adding new features, ensure consistency between CLI help text and website documentation, and follow the website's documentation structure and style
Keep website code in the website/ directory, follow the existing website architecture and style, and test website changes locally before committing
Keep CLI documentation and website documentation in sync and document new features on the website with examples and use cases

Files:

  • website/src/theme/BlogLayout/index.tsx
  • website/src/components/ChangelogTimeline/utils.ts
  • website/src/components/ChangelogTimeline/TimelineEntry.tsx
  • website/src/components/ChangelogTimeline/TimelineMonth.tsx
  • website/src/css/custom.css
  • website/src/theme/BlogSidebar/index.tsx
  • website/src/theme/BlogSidebar/Desktop/index.tsx
  • website/src/theme/BlogListPage/index.tsx
  • website/src/components/ChangelogTimeline/FilterBar.tsx
  • website/src/components/ChangelogTimeline/TimelineYear.tsx
  • website/src/theme/BlogSidebar/Desktop/styles.module.css
  • website/src/components/ChangelogTimeline/index.tsx
  • website/src/theme/BlogLayout/styles.module.css
  • website/src/components/ChangelogTimeline/styles.module.css
  • website/src/theme/BlogListPage/styles.module.css
🧠 Learnings (2)
📓 Common learnings
Learnt from: Listener430
Repo: cloudposse/atmos PR: 934
File: tests/fixtures/scenarios/docs-generate/README.md.gotmpl:99-118
Timestamp: 2025-01-25T03:51:57.689Z
Learning: For the cloudposse/atmos repository, changes to template contents should be handled in dedicated PRs and are typically considered out of scope for PRs focused on other objectives.
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T17:35:20.297Z
Learning: Applies to website/blog/**/*.mdx : PRs labeled minor/major MUST include blog post at website/blog/YYYY-MM-DD-feature-name.mdx with YAML front matter, <!--truncate--> after intro, tags (feature/enhancement/bugfix/contributors), and author (committer's GitHub username).
📚 Learning: 2025-11-24T17:35:20.297Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T17:35:20.297Z
Learning: Applies to website/blog/**/*.mdx : PRs labeled minor/major MUST include blog post at website/blog/YYYY-MM-DD-feature-name.mdx with YAML front matter, <!--truncate--> after intro, tags (feature/enhancement/bugfix/contributors), and author (committer's GitHub username).

Applied to files:

  • website/src/components/ChangelogTimeline/utils.ts
  • website/src/theme/BlogSidebar/Desktop/index.tsx
  • website/src/theme/BlogListPage/index.tsx
  • website/src/components/ChangelogTimeline/index.tsx
🧬 Code graph analysis (6)
website/src/theme/BlogLayout/index.tsx (1)
website/src/theme/BlogSidebar/index.tsx (1)
  • BlogSidebar (10-20)
website/src/components/ChangelogTimeline/TimelineEntry.tsx (3)
website/src/components/ChangelogTimeline/index.tsx (1)
  • BlogPostItem (76-76)
website/src/components/ChangelogTimeline/utils.ts (2)
  • BlogPostItem (21-25)
  • getTagColorClass (155-170)
website/plugins/docusaurus-plugin-llms-txt/src/index.js (2)
  • title (84-84)
  • description (85-85)
website/src/components/ChangelogTimeline/TimelineMonth.tsx (2)
website/src/components/ChangelogTimeline/utils.ts (1)
  • MonthGroup (27-31)
website/src/components/ChangelogTimeline/TimelineEntry.tsx (1)
  • TimelineEntry (13-59)
website/src/theme/BlogListPage/index.tsx (1)
website/src/components/ChangelogTimeline/index.tsx (1)
  • ChangelogTimeline (17-74)
website/src/components/ChangelogTimeline/TimelineYear.tsx (2)
website/src/components/ChangelogTimeline/utils.ts (1)
  • YearGroup (33-36)
website/src/components/ChangelogTimeline/TimelineMonth.tsx (1)
  • TimelineMonth (11-33)
website/src/components/ChangelogTimeline/index.tsx (3)
website/src/components/ChangelogTimeline/utils.ts (5)
  • BlogPostItem (21-25)
  • extractYears (100-109)
  • extractTags (114-122)
  • filterBlogPosts (127-150)
  • groupBlogPostsByYearMonth (41-95)
website/src/components/ChangelogTimeline/FilterBar.tsx (1)
  • FilterBar (14-70)
website/src/components/ChangelogTimeline/TimelineYear.tsx (1)
  • TimelineYear (10-36)
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (linux)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Summary
🔇 Additional comments (17)
website/src/css/custom.css (1)

921-936: Full-width layout implementation looks good.

The approach of hiding the sidebar and expanding main to full width is clean. The use of !important is justified here since you're overriding Docusaurus theme defaults.

website/src/theme/BlogListPage/styles.module.css (1)

1-27: Gradient title animation looks great.

The multi-stop gradient with animation creates a nice visual effect. Good use of both prefixed and standard properties for compatibility.

website/src/components/ChangelogTimeline/styles.module.css (3)

1-92: Filter bar implementation is solid.

The filter controls are well-structured with proper spacing, transitions, and hover states. The flex layouts will handle responsive wrapping nicely.


250-402: Entry card styling and interactions are well-crafted.

The hover effects are smooth and the tag color system provides clear visual differentiation between feature/enhancement/bugfix/contributors categories.


489-587: Excellent accessibility and responsive design.

The mobile adaptation is well-thought-out, shifting from alternating layout to left-aligned. The focus states for keyboard navigation and reduced-motion support demonstrate solid accessibility practices.

website/src/components/ChangelogTimeline/TimelineMonth.tsx (1)

1-33: Clean implementation of month grouping.

The component correctly handles alternating entry positions across month boundaries using the startIndex prop. Using permalink as the key is appropriate since it's unique per post.

website/src/theme/BlogLayout/index.tsx (1)

1-30: BlogLayout implementation is straightforward and correct.

The flexbox-based layout with conditional sidebar rendering works well. The logic properly handles cases where sidebar or TOC may not be present.

website/src/theme/BlogLayout/styles.module.css (1)

1-29: Flex layout styling is well-constructed.

Good use of min-width: 0 on the main flex item to prevent overflow issues. The responsive breakpoint appropriately handles smaller screens.

website/src/theme/BlogSidebar/index.tsx (1)

1-20: Sidebar component logic is clean and correct.

The window size-based rendering and null guard for empty sidebars are handled properly. The comment about mobile not needing SSR is a helpful note.

website/src/components/ChangelogTimeline/TimelineYear.tsx (1)

1-36: TimelineYear correctly manages continuous alternation.

The runningIndex accumulation ensures entries alternate consistently across month boundaries. The logic is clear and the implementation is solid. Good use of aria-label for the section.

website/src/components/ChangelogTimeline/index.tsx (1)

1-76: Solid implementation of the timeline component.

The component structure is clean with proper use of React hooks and memoization. Dependencies are correctly tracked, state management is straightforward, and the empty state handling is user-friendly.

website/src/theme/BlogSidebar/Desktop/index.tsx (1)

18-28: LGTM on the ListComponent wrapper.

Clean delegation to BlogSidebarItemList with appropriate class names for styling customization.

website/src/theme/BlogListPage/index.tsx (1)

1-63: Well-structured blog list page implementation.

The component follows Docusaurus theming conventions properly. Metadata handling is correct, including the blog-only mode detection. The layout integration with the custom timeline is clean.

website/src/components/ChangelogTimeline/FilterBar.tsx (1)

1-70: Excellent accessibility implementation.

The filter bar uses proper ARIA attributes (role="group", aria-label, aria-pressed) and semantic HTML. The year pills and tag select work together cleanly.

website/src/components/ChangelogTimeline/utils.ts (2)

41-95: Robust grouping logic with proper validation.

The function handles invalid dates gracefully with warnings, sorts correctly (years and months descending), and builds the hierarchical structure cleanly. Good defensive programming.


155-170: Tag color mapping is straightforward.

The switch statement handles common tag types and provides a sensible default. The case-insensitive matching (toLowerCase()) prevents issues with inconsistent capitalization.

website/src/theme/BlogSidebar/Desktop/styles.module.css (1)

1-98: Clean CSS implementation for collapsible sidebar.

The styles use proper CSS variables for theming, smooth transitions for the collapse animation, and responsive behavior at the standard Docusaurus breakpoint. The sticky positioning with calculated max-height ensures the sidebar stays within viewport bounds.

- Remove unused useEffect and import from BlogSidebar/Desktop
- Remove duplicate @Keyframes gradient definition (uses global from custom.css)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-release Do not create a new release (wait for additional code changes) size/xl Extra large size PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants