{"_id":"@3sv1n/react-lyrics","_rev":"3-bc0794c22a9ae89da4d17a59c8b19803","name":"@3sv1n/react-lyrics","dist-tags":{"latest":"0.1.2"},"versions":{"0.1.0":{"name":"@3sv1n/react-lyrics","version":"0.1.0","keywords":["react","lyrics","lrc","sync","audio"],"author":{"name":"3sv1n"},"license":"MIT","_id":"@3sv1n/react-lyrics@0.1.0","maintainers":[{"name":"esvinjoshuab","email":"joshua.esvin312@gmail.com"}],"homepage":"https://github.com/esvinjoshua/stem-packages/tree/main/packages/react-lyrics#readme","bugs":{"url":"https://github.com/esvinjoshua/stem-packages/issues"},"dist":{"shasum":"7b7723f32874f49df01b8a4abfa511e26020ba38","tarball":"https://registry.npmjs.org/@3sv1n/react-lyrics/-/react-lyrics-0.1.0.tgz","fileCount":8,"integrity":"sha512-QDLQV7pY9LdQJfzIjHATT2RMBfJp2i/DBuZi0b/Sm+/q/3GMmjWqBaMsHWmPIrbWbdDtiyAQQ8Kq5LtAqO80eQ==","signatures":[{"sig":"MEUCIQCYLTBJFQtFlza0WfsYxUTH8YDQ3JrNISvB2vjsAGnKUQIgcC1DHtok+B4g1aFp6vf3QbLnpkoN/k+u30t0v12UmDM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":35897},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"379be8a373efec3ee77f8e9088f4faa0682c4fe7","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup"},"_npmUser":{"name":"esvinjoshuab","email":"joshua.esvin312@gmail.com"},"repository":{"url":"git+https://github.com/esvinjoshua/stem-packages.git","type":"git","directory":"packages/react-lyrics"},"_npmVersion":"11.8.0","description":"Headless hooks and components for syncing lyrics in React","directories":{},"_nodeVersion":"25.5.0","dependencies":{"@3sv1n/lrc":"workspace:*"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.2","typescript":"^5.4.5","@types/react":"^18.2.79"},"peerDependencies":{"react":">=18"},"_npmOperationalInternal":{"tmp":"tmp/react-lyrics_0.1.0_1780649207124_0.5741251741422817","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@3sv1n/react-lyrics","version":"0.1.1","keywords":["react","lyrics","lrc","sync","audio"],"author":{"name":"3sv1n"},"license":"MIT","_id":"@3sv1n/react-lyrics@0.1.1","maintainers":[{"name":"esvinjoshuab","email":"joshua.esvin312@gmail.com"}],"homepage":"https://github.com/esvinjoshua/stem-packages/tree/main/packages/react-lyrics#readme","bugs":{"url":"https://github.com/esvinjoshua/stem-packages/issues"},"dist":{"shasum":"5b77d8f648a493a7da83ce24640165a9a6c3b84a","tarball":"https://registry.npmjs.org/@3sv1n/react-lyrics/-/react-lyrics-0.1.1.tgz","fileCount":8,"integrity":"sha512-95PeMF7rXheckUa+ZuLH2IaG9tQ80FCPrz95NPdl59Mu8Ktv0SzIzkJZR325dXpO3ojqUlJ5May5X3E/z0Kgfw==","signatures":[{"sig":"MEYCIQDtVSUqSWjJfaZHBEUoHqCcAc5LvdJCa2P5lxg36jTHOgIhAK5SGDpuXC4W3/lP3zHv3idT1WA0Ut0AV5cLztt6RXUs","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":35892},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"379be8a373efec3ee77f8e9088f4faa0682c4fe7","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup"},"_npmUser":{"name":"esvinjoshuab","email":"joshua.esvin312@gmail.com"},"repository":{"url":"git+https://github.com/esvinjoshua/stem-packages.git","type":"git","directory":"packages/react-lyrics"},"_npmVersion":"11.8.0","description":"Headless hooks and components for syncing lyrics in React","directories":{},"_nodeVersion":"25.5.0","dependencies":{"@3sv1n/lrc":"^0.1.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.2","typescript":"^5.4.5","@types/react":"^18.2.79"},"peerDependencies":{"react":">=18"},"_npmOperationalInternal":{"tmp":"tmp/react-lyrics_0.1.1_1780649739088_0.4567463183001401","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@3sv1n/react-lyrics","version":"0.1.2","description":"Headless hooks and components for syncing lyrics in React","author":{"name":"3sv1n"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/3sv1n/stem-packages.git","directory":"packages/react-lyrics"},"homepage":"https://github.com/3sv1n/stem-packages/tree/main/packages/react-lyrics#readme","keywords":["react","lyrics","lrc","sync","audio"],"main":"./dist/index.js","module":"./dist/index.mjs","types":"./dist/index.d.ts","exports":{".":{"require":"./dist/index.js","import":"./dist/index.mjs","types":"./dist/index.d.ts"}},"publishConfig":{"access":"public"},"scripts":{"build":"tsup","dev":"tsup --watch","test":"vitest run"},"dependencies":{"@3sv1n/lrc":"^0.1.2"},"peerDependencies":{"react":">=18"},"devDependencies":{"@types/react":"^18.2.79","tsup":"^8.0.2","typescript":"^5.4.5"},"gitHead":"379be8a373efec3ee77f8e9088f4faa0682c4fe7","_id":"@3sv1n/react-lyrics@0.1.2","bugs":{"url":"https://github.com/3sv1n/stem-packages/issues"},"_nodeVersion":"25.5.0","_npmVersion":"11.8.0","dist":{"integrity":"sha512-bC/w4VByQ4xXQ4hEx4kH6rsdr7C/AYJG3ge863s2gytBp637ZyUTXKRueN7O5gvU9U3gF2HwmvBRd8Lf3G9nCw==","shasum":"36690928f2d52445490333b8f96c228f8e576dea","tarball":"https://registry.npmjs.org/@3sv1n/react-lyrics/-/react-lyrics-0.1.2.tgz","fileCount":8,"unpackedSize":35880,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIBz3HeJDOxTuSJrbGJ2kZk6jrErm1HkNftshBDWE1bJYAiBT9ZuXXnSHfdSjruEjnj9yJL9dzz82irdPd3rtj3c3lw=="}]},"_npmUser":{"name":"esvinjoshuab","email":"joshua.esvin312@gmail.com"},"directories":{},"maintainers":[{"name":"esvinjoshuab","email":"joshua.esvin312@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/react-lyrics_0.1.2_1780650085681_0.2762885927820591"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-05T08:46:46.988Z","modified":"2026-06-05T09:01:25.974Z","0.1.0":"2026-06-05T08:46:47.283Z","0.1.1":"2026-06-05T08:55:39.255Z","0.1.2":"2026-06-05T09:01:25.814Z"},"bugs":{"url":"https://github.com/3sv1n/stem-packages/issues"},"author":{"name":"3sv1n"},"license":"MIT","homepage":"https://github.com/3sv1n/stem-packages/tree/main/packages/react-lyrics#readme","keywords":["react","lyrics","lrc","sync","audio"],"repository":{"type":"git","url":"git+https://github.com/3sv1n/stem-packages.git","directory":"packages/react-lyrics"},"description":"Headless hooks and components for syncing lyrics in React","maintainers":[{"name":"esvinjoshuab","email":"joshua.esvin312@gmail.com"}],"readme":"# @3sv1n/react-lyrics\n\nHeadless hooks and components for syncing and rendering LRC lyrics in React. Built on top of `@3sv1n/lrc`.\n\nThis 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.\n\n## Installation\n\n```bash\nnpm install @3sv1n/react-lyrics\n# or\nyarn add @3sv1n/react-lyrics\n# or\npnpm add @3sv1n/react-lyrics\n```\n\n*Note: This package requires `react >= 18` as a peer dependency.*\n\n## Basic Usage\n\n### Using the Unopinionated Component\n\n`SyncedLyrics` handles the parsing, state management, and auto-scrolling of lyrics, but allows you to completely control the CSS classes and styles.\n\n```tsx\nimport { useState } from 'react';\nimport { SyncedLyrics } from '@3sv1n/react-lyrics';\n\nconst lrcString = `\n[00:10.00]First line of the song\n[00:15.50]Second line here\n`;\n\nfunction App() {\n  const [currentTime, setCurrentTime] = useState(0);\n\n  // In a real app, you would update currentTime from an audio player's state\n  \n  return (\n    <div style={{ height: '300px', width: '400px' }}>\n      <SyncedLyrics \n        lrc={lrcString}\n        currentTime={currentTime}\n        className=\"my-lyrics-container\"\n        lineClassName=\"lyric-line\"\n        activeLineClassName=\"lyric-line-active\"\n        passedLineClassName=\"lyric-line-passed\"\n        futureLineClassName=\"lyric-line-future\"\n        onSeek={(time) => console.log('User clicked lyric to seek to:', time)}\n      />\n    </div>\n  );\n}\n```\n\n### Using the Headless Hook\n\nIf you need complete control over the DOM rendering, you can use the `useSyncedLyrics` hook.\n\n```tsx\nimport { useSyncedLyrics } from '@3sv1n/react-lyrics';\n\nfunction CustomLyricsRenderer({ lrc, time }) {\n  const { lines, activeIndex, activeLine, error } = useSyncedLyrics(lrc, time, {\n    trimWhitespace: true,\n    offset: 0 // Optional time offset in seconds\n  });\n\n  if (error) return <div>Error loading lyrics</div>;\n\n  return (\n    <ul>\n      {lines.map((line, idx) => (\n        <li \n          key={idx} \n          style={{ \n            fontWeight: idx === activeIndex ? 'bold' : 'normal',\n            opacity: idx < activeIndex ? 0.5 : 1\n          }}\n        >\n          {line.text}\n        </li>\n      ))}\n    </ul>\n  );\n}\n```\n\n## API Reference\n\n### `SyncedLyrics` (Component)\nA scrolling container that renders parsed LRC lyrics.\n\n**Props:**\n- `lrc: string` - The raw LRC text content.\n- `currentTime: number` - Current playback time in seconds.\n- `fallbackContent?: React.ReactNode` - Content to render if lyrics are missing.\n- `onSeek?: (time: number) => void` - Callback fired when a user clicks on a lyric line.\n- `autoScroll?: boolean` - Whether to automatically scroll the active line into view (default: `true`).\n- `offset?: number` - Global offset in seconds to apply to the LRC timestamps.\n- `trimWhitespace?: boolean` - Whether to trim whitespace from lyric lines.\n\n**Styling Props:**\n- `className?: string` - CSS class for the scrolling container.\n- `style?: React.CSSProperties` - Inline styles for the container.\n- `lineClassName?: string` - Base CSS class applied to every line.\n- `activeLineClassName?: string` - CSS class applied *only* to the currently active line.\n- `passedLineClassName?: string` - CSS class applied to lines that have already passed.\n- `futureLineClassName?: string` - CSS class applied to upcoming lines.\n\n### `useSyncedLyrics(lrcContent, currentTime, options)` (Hook)\n**Options:**\n- `offset?: number`\n- `trimWhitespace?: boolean`\n\n**Returns:**\n```typescript\n{\n  lines: LyricLine[];         // Array of parsed lyric lines\n  activeIndex: number;        // The index of the active line (-1 if none)\n  activeLine: LyricLine | null; // The active line object\n  error?: Error;              // Any parsing errors\n}\n```\n","readmeFilename":"README.md"}