Skip to main content

AnnotationData

Base annotation data structure representing a time region with text labels.

Import

import type { AnnotationData } from '@waveform-playlist/core';

Type Definition

interface AnnotationData {
  id: string;
  start: number;
  end: number;
  lines: string[];
  language?: string;
}

Properties

id
string
required
Unique identifier for this annotation
start
number
required
Start time of the annotation in seconds
end
number
required
End time of the annotation in seconds
lines
string[]
required
Array of text lines for this annotation. Multi-line support allows for subtitles, transcriptions, or detailed notes.
language
string
Optional language code (e.g., ‘en’, ‘es’, ‘fr’) for this annotation

Example

const annotation: AnnotationData = {
  id: 'ann-1',
  start: 10.5,
  end: 15.2,
  lines: ['Intro section', 'Fade in guitar'],
  language: 'en'
};

AnnotationFormat

Defines how annotations are parsed from external formats and serialized back.

Import

import type { AnnotationFormat } from '@waveform-playlist/core';

Type Definition

interface AnnotationFormat {
  name: string;
  parse: (data: unknown) => AnnotationData[];
  serialize: (annotations: AnnotationData[]) => unknown;
}

Properties

name
string
required
Format name (e.g., ‘srt’, ‘vtt’, ‘json’)
parse
function
required
Function to parse external data into AnnotationData array
serialize
function
required
Function to serialize AnnotationData array back to external format

Example

import type { AnnotationFormat, AnnotationData } from '@waveform-playlist/core';

const jsonFormat: AnnotationFormat = {
  name: 'json',
  parse: (data: unknown) => {
    const parsed = JSON.parse(data as string);
    return parsed.annotations as AnnotationData[];
  },
  serialize: (annotations: AnnotationData[]) => {
    return JSON.stringify({ annotations }, null, 2);
  }
};

AnnotationListOptions

Configuration options for annotation list behavior.

Import

import type { AnnotationListOptions } from '@waveform-playlist/core';

Type Definition

interface AnnotationListOptions {
  editable?: boolean;
  linkEndpoints?: boolean;
  isContinuousPlay?: boolean;
}

Properties

editable
boolean
Whether annotations can be edited by the user. Default: true
Whether annotation endpoints are linked (moving one endpoint moves the other). Default: false
isContinuousPlay
boolean
Whether to continue playing after an annotation ends. Default: false

AnnotationAction

Defines an action control shown on annotation items (e.g., delete, split buttons).

Import

import type { AnnotationAction } from '@waveform-playlist/core';

Type Definition

interface AnnotationAction {
  class?: string;
  text?: string;
  title: string;
  action: (
    annotation: AnnotationData,
    index: number,
    annotations: AnnotationData[],
    opts: AnnotationActionOptions
  ) => void;
}

Properties

class
string
CSS class name for the action button
text
string
Button text content
title
string
required
Tooltip text for the action
action
function
required
Function called when the action is triggeredParameters:
  • annotation - The annotation being acted upon
  • index - Index of the annotation in the list
  • annotations - All annotations
  • opts - Action options (linkEndpoints, continuousPlay, etc.)

Example

import type { AnnotationAction, AnnotationData } from '@waveform-playlist/core';

const deleteAction: AnnotationAction = {
  class: 'btn-delete',
  text: 'Delete',
  title: 'Remove this annotation',
  action: (annotation, index, annotations, opts) => {
    // Remove annotation from list
    annotations.splice(index, 1);
  }
};

const splitAction: AnnotationAction = {
  class: 'btn-split',
  text: 'Split',
  title: 'Split annotation at current position',
  action: (annotation, index, annotations, opts) => {
    const splitTime = (annotation.start + annotation.end) / 2;
    const newAnnotation: AnnotationData = {
      id: `ann-${Date.now()}`,
      start: splitTime,
      end: annotation.end,
      lines: [...annotation.lines],
      language: annotation.language
    };
    annotation.end = splitTime;
    annotations.splice(index + 1, 0, newAnnotation);
  }
};

AnnotationActionOptions

Configuration options passed to annotation action handlers.

Import

import type { AnnotationActionOptions } from '@waveform-playlist/core';

Type Definition

interface AnnotationActionOptions {
  linkEndpoints?: boolean;
  continuousPlay?: boolean;
  [key: string]: unknown;
}

Properties

Whether annotation endpoints are linked
continuousPlay
boolean
Whether to continue playing after an annotation ends
[key: string]
unknown
Additional custom properties can be added

AnnotationEventMap

Event handlers for annotation operations.

Import

import type { AnnotationEventMap } from '@waveform-playlist/core';

Type Definition

interface AnnotationEventMap {
  'annotation-select': (annotation: AnnotationData) => void;
  'annotation-update': (annotation: AnnotationData) => void;
  'annotation-delete': (id: string) => void;
  'annotation-create': (annotation: AnnotationData) => void;
}

Event Handlers

annotation-select
function
Called when an annotation is selectedParameters:
  • annotation - The selected annotation
annotation-update
function
Called when an annotation is modified (time range or text changed)Parameters:
  • annotation - The updated annotation
annotation-delete
function
Called when an annotation is deletedParameters:
  • id - ID of the deleted annotation
annotation-create
function
Called when a new annotation is createdParameters:
  • annotation - The newly created annotation

RenderAnnotationItemProps

Props passed to custom annotation item render functions.

Import

import type { RenderAnnotationItemProps } from '@waveform-playlist/core';

Type Definition

interface RenderAnnotationItemProps {
  annotation: AnnotationData;
  index: number;
  isActive: boolean;
  onClick: () => void;
  formatTime: (seconds: number) => string;
}

Properties

annotation
AnnotationData
required
The annotation data to render
index
number
required
Index of this annotation in the list
isActive
boolean
required
Whether this annotation is currently active/selected
onClick
() => void
required
Function to call when the annotation item is clicked
formatTime
(seconds: number) => string
required
Utility function to format time values for display

Example

import type { RenderAnnotationItemProps } from '@waveform-playlist/core';

function renderAnnotationItem(props: RenderAnnotationItemProps) {
  const { annotation, index, isActive, onClick, formatTime } = props;
  
  return (
    <div 
      className={`annotation-item ${isActive ? 'active' : ''}`}
      onClick={onClick}
    >
      <div className="annotation-index">#{index + 1}</div>
      <div className="annotation-time">
        {formatTime(annotation.start)} - {formatTime(annotation.end)}
      </div>
      <div className="annotation-text">
        {annotation.lines.map((line, i) => (
          <p key={i}>{line}</p>
        ))}
      </div>
      {annotation.language && (
        <div className="annotation-language">{annotation.language}</div>
      )}
    </div>
  );
}

Usage Examples

Creating Annotations

import type { AnnotationData } from '@waveform-playlist/core';

const annotations: AnnotationData[] = [
  {
    id: '1',
    start: 0,
    end: 5.5,
    lines: ['Introduction'],
    language: 'en'
  },
  {
    id: '2',
    start: 5.5,
    end: 12.3,
    lines: ['First verse', 'Vocals enter'],
    language: 'en'
  },
  {
    id: '3',
    start: 12.3,
    end: 20.0,
    lines: ['Chorus'],
    language: 'en'
  }
];

Using with AnnotationList Component

import { AnnotationList } from '@waveform-playlist/annotations';
import type { AnnotationData, AnnotationAction } from '@waveform-playlist/core';

const annotations: AnnotationData[] = [/* ... */];

const deleteAction: AnnotationAction = {
  title: 'Delete',
  action: (annotation, index, annotations) => {
    annotations.splice(index, 1);
  }
};

<AnnotationList
  annotations={annotations}
  currentTime={currentTime}
  onAnnotationSelect={(annotation) => {
    console.log('Selected:', annotation);
  }}
  actions={[deleteAction]}
  editable={true}
  linkEndpoints={false}
  continuousPlay={false}
/>

Build docs developers (and LLMs) love