DEV Community

Cover image for React Chrono v3.0: Redefining Timeline Components for Modern React
Prabhu Murthy
Prabhu Murthy

Posted on

React Chrono v3.0: Redefining Timeline Components for Modern React

React Chrono v3.0: A Complete Evolution

We're thrilled to announce React Chrono v3.0, the most significant release in the library's history. After months of development and a complete architectural overhaul, v3.0 delivers enhanced performance, developer experience, and a rich set of new features while maintaining backward compatibility with your existing code.

What's New at a Glance

React Chrono v3.0 introduces:

  • 🎨 Zero-runtime CSS with Vanilla Extract migration
  • 🌐 Comprehensive internationalization
  • 🎭 Google Fonts integration with per-element font control
  • πŸ–ΌοΈ Fullscreen mode with cross-browser support
  • 🎯 Grouped configuration API for better developer experience
  • πŸŽͺ Enhanced dark mode with 36 theme properties (13 new in v3.0)
  • πŸ“Œ Sticky toolbar for always-accessible controls
  • πŸ” Advanced search with configurable dimensions

πŸ—οΈ Architectural Overhaul

From Styled-Components to Vanilla Extract

One of the most significant changes in v3.0 is the complete migration from styled-components to Vanilla Extract. This migration brings substantial benefits to both performance and developer experience.

Why Vanilla Extract?
Vanilla Extract generates static CSS at build time, resulting in zero runtime overhead. Your timeline components now load faster with smaller bundle sizes, while maintaining full TypeScript support and type-safe styling.

Performance improvements:

  • ⚑ Zero runtime CSS-in-JS overhead
  • πŸ“¦ Smaller bundle size - no runtime style generation
  • πŸš€ Faster initial render - styles are pre-generated
  • πŸ’ͺ Type-safe styles - full TypeScript integration

Before (styled-components):

const TimelineCard = styled.div`
  background: ${props => props.theme.cardBgColor};
  border-radius: 8px;
  padding: 1rem;
`;
Enter fullscreen mode Exit fullscreen mode

After (Vanilla Extract):

// timeline-card.css.ts
import { style } from '@vanilla-extract/css';
import { tokens } from '../../styles/tokens';

export const card = style({
  background: tokens.color.cardBackground,
  borderRadius: tokens.radius.medium,
  padding: tokens.space[4],
});
Enter fullscreen mode Exit fullscreen mode

The migration spans 46+ CSS files across the entire codebase, with styles organized into logical groups:

  • src/styles/tokens/ - Design tokens and theme variables
  • src/styles/sprinkles/ - Utility-based styling system
  • src/styles/recipes/ - Component variants and patterns
  • Component-specific *.css.ts files co-located with components

Migration benefits for developers:

  • All styles are type-checked at compile time
  • IDE autocomplete for style properties
  • Impossible to introduce invalid CSS
  • Better refactoring support with TypeScript
  • Improved debugging with static class names

Unified Context Architecture

v3.0 introduces a single optimized context provider replacing multiple nested contexts, reducing re-renders and improving performance.

Old approach (multiple contexts):

<TimelineStaticContext.Provider>
  <TimelineDynamicContext.Provider>
    <TimelineComputedContext.Provider>
      {/* Component tree */}
    </TimelineComputedContext.Provider>
  </TimelineDynamicContext.Provider>
</TimelineStaticContext.Provider>
Enter fullscreen mode Exit fullscreen mode

New approach (unified context):

<TimelineContextProvider {...props}>
  {/* Component tree */}
</TimelineContextProvider>
Enter fullscreen mode Exit fullscreen mode

The new context architecture organizes values into three logical groups:

  • Static Config - Rarely changing configuration (theme, mode, layout settings)
  • Dynamic State - Frequently changing state (activeItemIndex, slideshow state)
  • Memoized Objects - Computed values (handlers, derived state)

This results in fewer re-renders and better performance across the entire component tree.


✨ New Features

🌐 Comprehensive Internationalization (i18n)

v3.0 introduces a complete internationalization system supporting 60+ configurable text elements across 11 categories, making React Chrono truly global-ready.

Full localization support
Every user-facing text in the timeline is now configurable, from navigation buttons to accessibility labels, search placeholders to keyboard help text.

Supported text categories:

  • Navigation controls (first, last, next, previous, play, pause)
  • Search functionality (placeholder, results count, no results)
  • Theme controls (dark mode, light mode, toggle theme)
  • Layout modes (vertical, horizontal, alternating)
  • Fullscreen (enter, exit, error messages)
  • Quick jump navigation
  • Content interactions (read more, show less, expand, collapse)
  • Loading and status messages
  • Accessibility labels (ARIA labels, screen reader text)
  • View density controls
  • Keyboard navigation help

Example - Spanish localization:

<Chrono
  items={items}
  i18n={{
    texts: {
      navigation: {
        first: 'Ir al primer elemento',
        last: 'Ir al ΓΊltimo elemento',
        next: 'Siguiente elemento',
        previous: 'Elemento anterior',
        play: 'Iniciar presentaciΓ³n',
        pause: 'Pausar presentaciΓ³n'
      },
      search: {
        placeholder: 'Buscar en la lΓ­nea de tiempo',
        ariaLabel: 'Buscar contenido de la lΓ­nea de tiempo',
        clearLabel: 'Limpiar bΓΊsqueda',
        resultsCount: '{current} de {total}',
        noResults: 'No se encontraron resultados'
      },
      theme: {
        darkMode: 'Cambiar a modo oscuro',
        lightMode: 'Cambiar a modo claro'
      },
      accessibility: {
        timelineNavigation: 'NavegaciΓ³n de lΓ­nea de tiempo',
        timelineItem: 'Elemento de lΓ­nea de tiempo',
        activeItem: 'Elemento activo de lΓ­nea de tiempo',
        itemPosition: 'Elemento {current} de {total}'
      }
    },
    locale: 'es',
    direction: 'ltr'
  }}
/>
Enter fullscreen mode Exit fullscreen mode

Template string support:

The i18n system includes intelligent template string interpolation:

// Define template with placeholders
i18n={{
  texts: {
    search: {
      resultsCount: '{current} of {total}'
    },
    accessibility: {
      itemPosition: 'Item {current} of {total}'
    }
  }
}}

// Runtime: "3 of 15", "Item 5 of 20", etc.
Enter fullscreen mode Exit fullscreen mode

Built-in utilities:

import { mergeI18nConfig, interpolateString } from '@models/TimelineI18n';

// Merge custom config with defaults
const config = mergeI18nConfig(userConfig);

// Interpolate template strings
const text = interpolateString('{current} of {total}', { current: 3, total: 15 });
// Result: "3 of 15"
Enter fullscreen mode Exit fullscreen mode

🎭 Google Fonts Integration

Dynamically load and apply Google Fonts with per-element font control - set different weights, styles, and sizes for titles, card content, subtitles, and controls.

Granular typography control
Load a single Google Font family and configure different weights, styles, and sizes for each text element in your timeline.

Basic usage:

<Chrono
  items={items}
  style={{
    googleFonts: {
      fontFamily: 'Inter',
      weights: [400, 600, 700],
      display: 'swap',
      preconnect: true
    }
  }}
/>
Enter fullscreen mode Exit fullscreen mode

Advanced - per-element configuration:

<Chrono
  items={items}
  style={{
    googleFonts: {
      fontFamily: 'Playfair Display',
      elements: {
        title: {
          weight: 'bold',      // 700
          style: 'normal',
          size: '1.5rem'
        },
        cardTitle: {
          weight: 'semi-bold', // 600
          style: 'italic',
          size: '1.25rem'
        },
        cardSubtitle: {
          weight: 'regular',   // 400
          style: 'normal',
          size: '1rem'
        },
        cardText: {
          weight: 300,         // light
          style: 'normal',
          size: '0.95rem'
        },
        controls: {
          weight: 'medium',    // 500
          style: 'normal'
        }
      },
      display: 'swap',
      preconnect: true
    }
  }}
/>
Enter fullscreen mode Exit fullscreen mode

Font loading features:

  • Automatic preconnect to Google Fonts for faster loading
  • Configurable font-display strategy (swap, fallback, optional)
  • Intelligent weight deduplication (only loads required weights)
  • TypeScript-safe weight and style configuration
  • Fallback font stack for better accessibility
  • Support for both numeric (100-900) and named weights (thin, regular, bold, etc.)

Generated CSS variables:

The Google Fonts system automatically generates CSS variables for theming:

--timeline-font-family: "Inter", system-ui, sans-serif;
--timeline-title-font-weight: 700;
--timeline-title-font-style: normal;
--timeline-cardTitle-font-weight: 600;
--timeline-cardTitle-font-style: italic;
Enter fullscreen mode Exit fullscreen mode

πŸ–ΌοΈ Fullscreen Mode

Experience timelines in immersive fullscreen mode with cross-browser support (Chrome, Firefox, Safari, Edge).

Browser compatibility built-in
Fullscreen mode automatically handles vendor prefixes and browser-specific APIs, ensuring consistent behavior across all major browsers.

Cross-browser support includes:

  • Standard Fullscreen API
  • WebKit prefixed API (Safari)
  • Mozilla prefixed API (Firefox)
  • MS prefixed API (Edge legacy)
  • Automatic vendor prefix detection
  • Feature detection for unsupported browsers
  • Portal rendering to fullscreen element for overlays

Fullscreen-aware components:

Components like popover menus automatically detect fullscreen mode and portal to the correct container:

// Automatically portals to fullscreen element when active
const portalContainer = getFullscreenElement() || document.body;
ReactDOM.createPortal(content, portalContainer);
Enter fullscreen mode Exit fullscreen mode

🎯 Grouped Configuration API

Organize props into 9 logical groups for better discoverability and maintainability. The old flat API is still supported for backward compatibility.

Better developer experience
Props are now organized into intuitive groups: layout, interaction, content, display, media, animation, style, accessibility, and i18n.

Old API (still works):

<Chrono
  items={items}
  borderLessCards={true}
  disableNavOnKey={false}
  timelinePointDimension={18}
  parseDetailsAsHTML={true}
  mediaHeight={400}
  slideShow={true}
  slideItemDuration={3000}
/>
Enter fullscreen mode Exit fullscreen mode

New grouped API (recommended):

<Chrono
  items={items}
  display={{
    borderless: true,
    pointShape: 'circle'
  }}
  interaction={{
    keyboardNavigation: true,
    autoScroll: true
  }}
  layout={{
    pointSize: 18,
    cardWidth: 400
  }}
  content={{
    allowHTML: true
  }}
  media={{
    height: 400,
    fit: 'cover'
  }}
  animation={{
    slideshow: {
      enabled: true,
      duration: 3000,
      type: 'fade'
    }
  }}
/>
Enter fullscreen mode Exit fullscreen mode

Configuration groups:

  1. layout - Sizing and positioning

    • cardWidth, cardHeight, pointSize, lineWidth
    • responsive.breakpoint, positioning.cardPosition
  2. interaction - User interactions

    • keyboardNavigation, pointClick, autoScroll
    • focusOnLoad, cardHover, disabled
  3. content - Content handling

    • allowHTML, readMore, textOverlay
    • dateFormat, compactText, semanticTags
  4. display - Visual appearance

    • borderless, cardsDisabled, pointsDisabled
    • pointShape, allCardsVisible, scrollable
    • toolbar.enabled, toolbar.position, toolbar.sticky
  5. media - Media configuration

    • height, align, fit
  6. animation - Slideshow and animations

    • slideshow.enabled, slideshow.duration, slideshow.type
    • slideshow.autoStart, slideshow.showProgress
  7. style - Custom styling

    • classNames, fontSizes, googleFonts
  8. accessibility - A11y and i18n

    • buttonTexts, search labels
  9. i18n - Internationalization

    • texts, locale, direction

TypeScript autocomplete:

The grouped API provides excellent IDE autocomplete and type checking:

<Chrono
  display={{
    toolbar: {
      enabled: true,
      position: 'top' | 'bottom',  // βœ… Type-safe
      sticky: true,
      search: {
        width: '200px',
        maxWidth: '400px'
      }
    }
  }}
/>
Enter fullscreen mode Exit fullscreen mode

πŸ“Œ Sticky Toolbar

Pin the toolbar to the top or bottom of the viewport for always-accessible controls during scrolling.

<Chrono
  items={items}
  display={{
    toolbar: {
      enabled: true,
      position: 'top',
      sticky: true,  // πŸ†• Sticky positioning
      search: {
        width: '250px',
        maxWidth: '400px'
      }
    }
  }}
/>
Enter fullscreen mode Exit fullscreen mode

The sticky toolbar maintains position during scroll, ensuring users always have access to:

  • Navigation controls (first, previous, next, last)
  • Slideshow controls (play, pause, stop)
  • Dark mode toggle
  • Layout switcher
  • Search functionality
  • Quick jump navigation

πŸ” Enhanced Search Configuration

Fine-tune search input dimensions and positioning with granular width controls.

<Chrono
  items={items}
  display={{
    toolbar: {
      enabled: true,
      search: {
        width: '200px',        // Default search section width
        maxWidth: '400px',     // Maximum expansion width
        minWidth: '150px',     // Minimum width
        inputWidth: '180px',   // Actual input field width
        inputMaxWidth: '350px' // Maximum input expansion
      }
    }
  }}
/>
Enter fullscreen mode Exit fullscreen mode

Search features:

  • Real-time highlighting of matches
  • Navigate between matches with Enter/Shift+Enter
  • Results counter ({current} of {total})
  • Clear search button
  • Configurable placeholder and ARIA labels (via i18n)
  • Case-insensitive search
  • Search across title, subtitle, and card content

πŸŽͺ Enhanced Dark Mode

v3.0 introduces 36 comprehensive theme properties (including 13 new dark mode-specific properties) for complete customization.

Enhanced theme system:

<Chrono
  items={items}
  theme={{
    primary: '#3b82f6',
    secondary: '#1e40af',

    // Card theming
    cardBgColor: '#1f2937',
    cardForeColor: '#f3f4f6',

    // Enhanced dark mode properties
    iconColor: '#9ca3af',
    buttonHoverBgColor: '#374151',
    shadowColor: 'rgba(0, 0, 0, 0.5)',
    glowColor: '#3b82f6',

    // Timeline elements
    titleColor: '#f9fafb',
    titleColorActive: '#3b82f6',
    cardTitleColor: '#e5e7eb',
    cardSubtitleColor: '#9ca3af',
    cardDetailsColor: '#d1d5db',

    // Interactive elements
    focusRingColor: '#3b82f6',
    borderColor: '#374151'
  }}
  darkMode={{
    enabled: true,
    showToggle: true
  }}
  onThemeChange={(theme) => {
    console.log('Theme changed:', theme);
  }}
/>
Enter fullscreen mode Exit fullscreen mode

Theme callback:

React to theme changes programmatically:

<Chrono
  items={items}
  darkMode={{ enabled: true, showToggle: true }}
  onThemeChange={(theme) => {
    // Persist preference
    localStorage.setItem('timeline-theme', JSON.stringify(theme));

    // Update app-level theme
    document.body.classList.toggle('dark-mode', theme.isDark);
  }}
/>
Enter fullscreen mode Exit fullscreen mode

πŸ› Bug Fixes and Improvements

v3.0 includes numerous bug fixes and quality-of-life improvements based on community feedback:

Navigation and Slideshow

  • βœ… Fixed slideshow media deadlock causing frozen animations
  • βœ… Resolved keyboard navigation conflicts with slideshow
  • βœ… Improved slideshow card scrolling behavior
  • βœ… Standardized icon dimensions across all controls
  • βœ… Fixed slideshow not respecting pause state

Layout and Positioning

  • βœ… Fixed popover positioning in fullscreen mode
  • βœ… Improved responsive breakpoint behavior for vertical alternating mode
  • βœ… Resolved nested timeline rendering issues
  • βœ… Fixed icon positioning in alternating mode
  • βœ… Better card remeasurement on text density changes

Styling and Theming

  • βœ… Fixed theme color inheritance issues
  • βœ… Improved text overlay color handling
  • βœ… Better dark mode CSS variable support
  • βœ… Resolved horizontal timeline point sizing
  • βœ… Enhanced list and popover responsive styles

Performance

  • βœ… Reduced unnecessary re-renders with optimized context
  • βœ… Improved bundle size with Vanilla Extract migration
  • βœ… Better lazy loading for media elements
  • βœ… Optimized font loading with preconnect
  • βœ… Faster initial render times

πŸ“¦ Migration Guide

For Existing Users

Good news! v3.0 maintains full backward compatibility. Your existing code will continue to work without changes.

Immediate benefits (no code changes required):

  • ⚑ Faster performance (Vanilla Extract)
  • πŸ“¦ Smaller bundle size
  • πŸ› Bug fixes automatically applied
  • 🎨 Enhanced theming with new dark mode properties

Recommended: Migrate to grouped API

While the old flat API still works, we recommend migrating to the new grouped API for better maintainability:

Migration example:

// Before (v2.x)
<Chrono
  items={items}
  borderLessCards={true}
  disableNavOnKey={false}
  timelinePointDimension={18}
  parseDetailsAsHTML={true}
  mediaHeight={400}
  slideShow={true}
  slideItemDuration={3000}
  showProgressOnSlideshow={true}
  disableToolbar={false}
  toolbarPosition="top"
/>

// After (v3.0 - recommended)
<Chrono
  items={items}
  display={{
    borderless: true,
    toolbar: {
      enabled: true,
      position: 'top'
    }
  }}
  interaction={{
    keyboardNavigation: true
  }}
  layout={{
    pointSize: 18
  }}
  content={{
    allowHTML: true
  }}
  media={{
    height: 400
  }}
  animation={{
    slideshow: {
      enabled: true,
      duration: 3000,
      showProgress: true
    }
  }}
/>
Enter fullscreen mode Exit fullscreen mode

Deprecated props mapping:

Old Prop (v2.x) New Prop (v3.0)
borderLessCards display.borderless
disableNavOnKey interaction.keyboardNavigation (inverted)
timelinePointDimension layout.pointSize
parseDetailsAsHTML content.allowHTML
mediaHeight media.height
slideShow animation.slideshow.enabled
slideItemDuration animation.slideshow.duration
disableToolbar display.toolbar.enabled (inverted)
toolbarPosition display.toolbar.position
useReadMore content.readMore
highlightCardsOnHover interaction.cardHover
buttonTexts accessibility.buttonTexts

TypeScript support:

All deprecated props are still typed and will show deprecation warnings with suggestions for new props:

// TypeScript will show:
// ⚠️ 'borderLessCards' is deprecated. Use 'display.borderless' instead.
Enter fullscreen mode Exit fullscreen mode

New Project Setup

Installation:

npm install react-chrono@latest
# or
pnpm add react-chrono@latest
# or
yarn add react-chrono@latest
Enter fullscreen mode Exit fullscreen mode

Minimal setup:

import { Chrono } from 'react-chrono';

const items = [
  {
    title: 'January 2024',
    cardTitle: 'Project Kickoff',
    cardDetailedText: 'Started the new initiative with the team'
  },
  {
    title: 'February 2024',
    cardTitle: 'First Milestone',
    cardDetailedText: 'Completed initial design and architecture'
  }
];

function App() {
  return <Chrono items={items} mode="vertical" />;
}
Enter fullscreen mode Exit fullscreen mode

Recommended setup with new features:

import { Chrono } from 'react-chrono';

const items = [...]; // Your timeline items

function App() {
  return (
    <Chrono
      items={items}
      mode="vertical"

      // Enhanced theming
      theme={{
        primary: '#3b82f6',
        cardBgColor: '#ffffff',
        cardForeColor: '#1f2937'
      }}

      // Dark mode with toggle
      darkMode={{
        enabled: false,
        showToggle: true
      }}

      // Google Fonts
      style={{
        googleFonts: {
          fontFamily: 'Inter',
          weights: [400, 600, 700],
          display: 'swap'
        }
      }}

      // Sticky toolbar with search
      display={{
        toolbar: {
          enabled: true,
          position: 'top',
          sticky: true,
          search: {
            width: '250px',
            maxWidth: '400px'
          }
        }
      }}

      // Internationalization
      i18n={{
        texts: {
          search: {
            placeholder: 'Search Timeline'
          }
        },
        locale: 'en'
      }}

      // Enhanced interactions
      interaction={{
        keyboardNavigation: true,
        autoScroll: true,
        cardHover: true
      }}
    />
  );
}
Enter fullscreen mode Exit fullscreen mode

🎯 What's Next

We're committed to continuous improvement of React Chrono. Here's what's on the roadmap:

Upcoming Features

  • 🌍 Additional pre-built i18n locale packages (French, German, Spanish, Japanese)
  • πŸ“± Enhanced mobile gestures (swipe navigation)
  • πŸ“Š Timeline data visualization modes (Gantt-style, density view)
  • 🎭 More animation presets for slideshow
  • πŸ“Έ Image gallery mode with lightbox

Community

  • πŸ“š Comprehensive Storybook documentation
  • πŸŽ“ Video tutorials and guides
  • πŸ—οΈ Real-world example projects
  • πŸ’¬ Community showcase gallery

πŸ™ Acknowledgments

React Chrono v3.0 is the result of months of work, feedback from the community, and contributions from developers worldwide. A special thanks to:

  • All contributors who submitted issues, PRs, and feedback
  • The Vanilla Extract team for the excellent CSS-in-TypeScript framework
  • Everyone using React Chrono in production applications

πŸ“š Resources


πŸš€ Get Started Today

Upgrade to React Chrono v3.0 and experience the next generation of timeline components:

npm install react-chrono@latest
Enter fullscreen mode Exit fullscreen mode

We can't wait to see what you build with React Chrono v3.0! If you have questions, feedback, or want to showcase your timeline, join us on GitHub Discussions.

Happy timeline building! πŸŽ‰


πŸ’¬ Feedback & Support

We value your feedback and want to make React Chrono better for everyone. Here's how you can get help or contribute:

πŸ“ Bug Reports & Feature Requests

Found a bug or have an idea for a new feature?

πŸ’‘ Questions & Help

Need help using React Chrono?

🀝 Contributing

We welcome contributions from the community!

  • Code contributions: Check out open issues labeled good first issue
  • Documentation: Help improve our docs and examples
  • Testing: Add test coverage or report edge cases
  • Spread the word: Star the repo ⭐ and share with others

See our Contributing Guidelines for more details.

🌟 Show Your Support

If React Chrono has been helpful in your projects:

  • ⭐ Star the repository on GitHub
  • 🐦 Share your projects using #ReactChrono on social media
  • πŸ’¬ Join the discussion and help others in the community
  • β˜• Sponsor development via GitHub Sponsors

Thank you for using React Chrono! Your feedback drives our development and helps us build a better library for everyone. πŸ™

Top comments (0)