@3sv1n/react-lyrics
v0.1.2
Published
Headless hooks and components for syncing lyrics in React
Maintainers
Readme
@3sv1n/react-lyrics
Headless hooks and components for syncing and rendering LRC lyrics in React. Built on top of @3sv1n/lrc.
This package focuses entirely on the logic and structure of synchronized lyrics. It brings no opinions on styling, allowing you to integrate lyrics into any design system perfectly.
Installation
npm install @3sv1n/react-lyrics
# or
yarn add @3sv1n/react-lyrics
# or
pnpm add @3sv1n/react-lyricsNote: This package requires react >= 18 as a peer dependency.
Basic Usage
Using the Unopinionated Component
SyncedLyrics handles the parsing, state management, and auto-scrolling of lyrics, but allows you to completely control the CSS classes and styles.
import { useState } from 'react';
import { SyncedLyrics } from '@3sv1n/react-lyrics';
const lrcString = `
[00:10.00]First line of the song
[00:15.50]Second line here
`;
function App() {
const [currentTime, setCurrentTime] = useState(0);
// In a real app, you would update currentTime from an audio player's state
return (
<div style={{ height: '300px', width: '400px' }}>
<SyncedLyrics
lrc={lrcString}
currentTime={currentTime}
className="my-lyrics-container"
lineClassName="lyric-line"
activeLineClassName="lyric-line-active"
passedLineClassName="lyric-line-passed"
futureLineClassName="lyric-line-future"
onSeek={(time) => console.log('User clicked lyric to seek to:', time)}
/>
</div>
);
}Using the Headless Hook
If you need complete control over the DOM rendering, you can use the useSyncedLyrics hook.
import { useSyncedLyrics } from '@3sv1n/react-lyrics';
function CustomLyricsRenderer({ lrc, time }) {
const { lines, activeIndex, activeLine, error } = useSyncedLyrics(lrc, time, {
trimWhitespace: true,
offset: 0 // Optional time offset in seconds
});
if (error) return <div>Error loading lyrics</div>;
return (
<ul>
{lines.map((line, idx) => (
<li
key={idx}
style={{
fontWeight: idx === activeIndex ? 'bold' : 'normal',
opacity: idx < activeIndex ? 0.5 : 1
}}
>
{line.text}
</li>
))}
</ul>
);
}API Reference
SyncedLyrics (Component)
A scrolling container that renders parsed LRC lyrics.
Props:
lrc: string- The raw LRC text content.currentTime: number- Current playback time in seconds.fallbackContent?: React.ReactNode- Content to render if lyrics are missing.onSeek?: (time: number) => void- Callback fired when a user clicks on a lyric line.autoScroll?: boolean- Whether to automatically scroll the active line into view (default:true).offset?: number- Global offset in seconds to apply to the LRC timestamps.trimWhitespace?: boolean- Whether to trim whitespace from lyric lines.
Styling Props:
className?: string- CSS class for the scrolling container.style?: React.CSSProperties- Inline styles for the container.lineClassName?: string- Base CSS class applied to every line.activeLineClassName?: string- CSS class applied only to the currently active line.passedLineClassName?: string- CSS class applied to lines that have already passed.futureLineClassName?: string- CSS class applied to upcoming lines.
useSyncedLyrics(lrcContent, currentTime, options) (Hook)
Options:
offset?: numbertrimWhitespace?: boolean
Returns:
{
lines: LyricLine[]; // Array of parsed lyric lines
activeIndex: number; // The index of the active line (-1 if none)
activeLine: LyricLine | null; // The active line object
error?: Error; // Any parsing errors
}