Components
Timeline

Timeline

The Timeline component uses the compound component pattern to provide a highly customizable interface for time-based interactions. It manages time ranges, animation states, and user interactions while remaining flexible enough to support various UI configurations.

Features

The Timeline utilizes the compound component pattern, offering several advantages:

  1. Flexibility: Users can compose the timeline interface according to their specific needs
  2. Configurability: Each sub-component can be easily customized or replaced
  3. Encapsulation: The internal state is managed by the parent component, simplifying usage
  4. Reusability: Sub-components can be used independently or combined in various ways

Usage

Basic Timeline Setup

This example demonstrates a simple timeline with basic playback controls:

<Timeline
  startDate={new Date('2023-7-09')}
  endDate={new Date('2024-7-11')}
  currentDate={new Date()}
  onPlay={handlePlay}
  onPause={handlePause}
  onPositionChange={handlePositionChange}
>
  <Timeline.Container>
    <Timeline.AnimationControl />
    <Timeline.Track>
      <Timeline.Scrubber>
        <Timeline.TimeProgressIndicator />
      </Timeline.Scrubber>
    </Timeline.Track>
  </Timeline.Container>
</Timeline>

Advanced Timeline with Expand/Collapse

This example shows a more complex implementation with expandable views and settings:

<Timeline
  startDate={new Date('2023-07-09')}
  endDate={new Date('2024-07-11')}
  currentDate={new Date()}
  position={0.5}
  onPlay={handlePlay}
  onPause={handlePause}
  onPositionChange={handlePositionChange}
>
  <ExpandCollapseProvider initialState={breakpoint === BREAKPOINTS.base.className ? collapsed : expanded}>
    <ExpandCollapseContext.Consumer>
      {({ setAnimationState, toggle, isCollapsed, isExpanded, isExpanding }) => (
        <ExpandCollapseHorizontal expanded={isExpanded || isExpanding} collapsedWidth={collapsedWidth}>
          <Timeline.Container className="rounded-xl bg-slate-900">
            <Timeline.AnimationControl />
            
            {/* Settings Popover */}
            <Popover>
              <Popover.Trigger>
                <IconButton icon={PreferencesFillPartialIcon} />
              </Popover.Trigger>
              <Popover.Content>
                <Timeline.SettingsControl
                  config={timelineSettingsConfig}
                  onStartDateChange={handleStartDateChange}
                  onEndDateChange={handleEndDateChange}
                  onSpeedChange={handleSpeedChange}
                />
              </Popover.Content>
            </Popover>
            {/* Expanded View */}
            <AnimatePresence mode="wait">
              {isExpanded && (
                <Fade duration={0.2} key="expanded">
                  <Timeline.MoveToStart />
                  <Timeline.Track>
                    <Timeline.Scrubber>
                      <Timeline.TimeProgressIndicator />
                    </Timeline.Scrubber>
                    <Timeline.MoveToNow />
                    <Timeline.Ticks>
                      {(tick) => (
                        <>
                          <Timeline.Tick tick={tick} />
                          <Timeline.TickDateText tick={tick} />
                        </>
                      )}
                    </Timeline.Ticks>
                  </Timeline.Track>
                  <Timeline.MoveToEnd />
                </Fade>
              )}
              {/* Collapsed View */}
              {isCollapsed && (
                <Fade duration={0.2} key="collapsed">
                  <VStack>
                    <HStack>
                      <Timeline.DateText />
                      <Timeline.TimeText />
                    </HStack>
                    <Timeline.Track>
                      <Timeline.Scrubber>
                        <Timeline.LineProgressIndicator />
                      </Timeline.Scrubber>
                    </Timeline.Track>
                  </VStack>
                </Fade>
              )}
            </AnimatePresence>
            {/* Expand/Collapse Button */}
            <IconButton
              onClick={toggle}
              icon={isExpanded ? CollapseIcon : ExpandIcon}
            />
          </Timeline.Container>
        </ExpandCollapseHorizontal>
      )}
    </ExpandCollapseContext.Consumer>
  </ExpandCollapseProvider>
</Timeline>

API Reference

Timeline (Root)

The main component that coordinates all timeline functionality. Combines Timeline.Root (ref management) and Timeline.Provider (state management).

OptionDescriptionDefault
startDateType: Date (required)The start date of the timeline range
endDateType: Date (required)The end date of the timeline range
currentDateType: Date (required)The current position date in the timeline
positionType: number (required)Current position value between 0-1
onPlayType: () => void (required)Callback when animation starts
onPauseType: () => void (required)Callback when animation pauses
onPositionChangeType: (position: number) => void (required)Callback when scrubber position changes
childrenType: ReactNode (required)Timeline sub-components

Timeline.Container

Container component that provides layout structure for timeline components.

OptionDescriptionDefault
classNameType: string ()Additional CSS classes
childrenType: ReactNode (required)Timeline content components

Timeline.Track

The interactive area containing tick marks and the scrubber.

OptionDescriptionDefault
classNameType: string ()Additional CSS classes
childrenType: ReactNode (required)Track content (typically Scrubber and Ticks)

Timeline.Ticks

Renders time interval markers along the track. Uses the useTicks hook to dynamically calculate tick positions.

OptionDescriptionDefault
childrenType: (tick: TickData) => ReactNode (required)Render function for individual ticks
minSpacingType: number ()Minimum pixels between ticks
densityType: 'low' | 'normal' | 'high' ()Controls tick spacing density'normal'

Timeline.SettingsControl

Provides controls for adjusting timeline range and animation speed.

OptionDescriptionDefault
configType: TimelineSettingsConfig (required)Configuration for speed and range options
onStartDateChangeType: (date: Date) => void (required)Callback when start date changes
onEndDateChangeType: (date: Date) => void (required)Callback when end date changes
onSpeedChangeType: (speed: number) => void (required)Callback when animation speed changes

Timeline.AnimationControl

Play/pause button for timeline animation.

OptionDescriptionDefault
classNameType: string ()Additional CSS classes

Timeline.Scrubber

Draggable indicator showing current position.

OptionDescriptionDefault
childrenType: ReactNode ()Custom scrubber indicator component

Progress Indicators

The Timeline provides two built-in progress indicators:

Timeline.TimeProgressIndicator

Displays the current time in a pill-shaped container.

OptionDescriptionDefault
childrenType: ReactNode ()Custom time display component<TimelineTimeText />

Timeline.LineProgressIndicator

Shows a simple vertical line indicator.

Navigation Components

  • Timeline.MoveToStart: Jump to timeline start
  • Timeline.MoveToEnd: Jump to timeline end
  • Timeline.MoveToNow: Jump to current time

Hooks

useTicks

Generates tick marks for the timeline based on the current time range and dimensions.

const ticks = useTicks({
  minSpacing?: number;
  density?: 'low' | 'normal' | 'high';
});

Example

import { Timeline } from '@xweather/map-ui-sdk';
 
const TimelineExample = () => (
  <Timeline
    startDate={new Date('2024-01-01')}
    endDate={new Date('2024-12-31')}
    currentDate={new Date()}
    position={0.5}
    onPlay={handlePlay}
    onPause={handlePause}
    onPositionChange={handlePositionChange}
  >
    <Timeline.Container>
      <Timeline.AnimationControl />
      <Timeline.Track>
        <Timeline.Scrubber>
          <Timeline.TimeProgressIndicator />
        </Timeline.Scrubber>
        <Timeline.Ticks>
          {(tick) => (
            <Timeline.Tick tick={tick} />
          )}
        </Timeline.Ticks>
      </Timeline.Track>
    </Timeline.Container>
  </Timeline>
);