Enhanced Changelog UI with Starwind Tabs and AuthorHandle Integration

Summary

Replaced toggle buttons with Starwind tabs in the changelog layout and integrated the AuthorHandle component to display author information in changelog entries, with support for both single and multiple categories.

Why Care

These UI enhancements improve both the visual appeal and functionality of the changelog pages, making it easier for users to navigate between content and code changes while providing clear attribution to content authors. The flexible handling of categories improves consistency across different changelog entry formats.

Implementation

Changes Made

  • Replaced Toggle Buttons with Starwind Tabs:
    • Modified /site/src/layouts/ChangelogLayout.astro to use Starwind tabs components
    • Added styling for tabs with brand colors and improved hover/active states
    • Implemented tab content containers for content and code changes
  • Integrated AuthorHandle Component:
    • Enhanced /site/src/components/changelog/ChangelogEntry.astro to display author information
    • Positioned author information at the bottom left of each entry
    • Styled author display to match category tag colors
  • Added Support for Multiple Categories:
    • Updated /site/src/components/changelog/ChangelogEntry.astro to handle both category and categories properties
    • Implemented normalization function to convert all category formats to arrays
    • Added mapping to display each category as a separate tag
  • Created New Components:
    • Added /site/src/components/basics/AuthorHandle.astro for flexible author display
    • Integrated Starwind tab components from /site/src/components/starwind/tabs/

Technical Details

Starwind Tabs Implementation

astro
<!-- /site/src/layouts/ChangelogLayout.astro -->
<Tabs defaultValue="content" class="changelog-tabs">
  <TabsList class="changelog-tabs-list">
    <TabsTrigger value="content" class="changelog-tab">Content Changes</TabsTrigger>
    <TabsTrigger value="code" class="changelog-tab">Code Changes</TabsTrigger>
  </TabsList>
  <TabsContent value="content" class="changelog-tab-content">
    <ArticleListColumn entries={sortedContentChanges.map(entry => normalizeAuthorData(entry))} EntryComponent={ChangelogEntry} />
  </TabsContent>
  <TabsContent value="code" class="changelog-tab-content">
    <ArticleListColumn entries={sortedCodeChanges.map(entry => normalizeAuthorData(entry))} EntryComponent={ChangelogEntry} />
  </TabsContent>
</Tabs>

Tab Styling with Brand Colors

astro
<!-- /site/src/layouts/ChangelogLayout.astro -->
:global(.changelog-tabs-list) {
  background: var(--clr-lossless-primary-glass);
  border: 1px solid var(--clr-lossless-primary-light);
  border-radius: 0.5rem;
}

:global(.changelog-tab[data-state="active"]) {
  background: color-mix(in oklab, var(--clr-lossless-primary-light), transparent 40%);
  color: var(--clr-lossless-primary-dark);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}

:global(.changelog-tab[data-state="active"]:hover) {
  background: var(--clr-lossless-primary-light);
  color: var(--white--pure);
}

Multiple Categories Support

astro
<!-- /site/src/components/changelog/ChangelogEntry.astro -->
// Normalize categories to always be an array
const normalizeCategories = () => {
  if (categories) {
    // If categories is already an array, use it
    return Array.isArray(categories) ? categories : [categories];
  } else if (category) {
    // If only category is present (string), convert to array
    return Array.isArray(category) ? category : [category];
  }
  return [];
};

const categoryList = normalizeCategories();

// In template:
{categoryList.map(cat => (
  <span class="changelog-entry__category">{cat}</span>
))}

AuthorHandle Integration

astro
<!-- /site/src/components/changelog/ChangelogEntry.astro -->
<div class="changelog-entry__footer">
  {/* Author handle positioned at bottom left */}
  {hasAuthors && (
    <div class="changelog-entry__author">
      <AuthorHandle authors={authors} showName={true} showRole={false} />
    </div>
  )}
  
  <a href={`/log/${slug || ''}`} class="changelog-entry__button">
    Read Full Entry →
  </a>
</div>

Integration Points

  • The Starwind tabs component integrates with the existing changelog data fetching logic
  • The AuthorHandle component connects to the author data in the frontmatter of changelog entries
  • The category normalization function ensures consistent display regardless of how categories are defined in frontmatter

Documentation

  • The Starwind tabs implementation follows the component structure defined in /site/src/components/starwind/tabs/
  • The AuthorHandle component provides a reusable pattern for displaying author information across the site
  • The category normalization approach can be applied to other components that need to handle both singular and plural data formats