feat(app): add ChordChart component with monospaced rendering
This commit is contained in:
48
app/app/components/chord-chart.tsx
Normal file
48
app/app/components/chord-chart.tsx
Normal file
@@ -0,0 +1,48 @@
|
||||
import type { Section } from "~/lib/types";
|
||||
|
||||
interface Props {
|
||||
sections: Section[];
|
||||
}
|
||||
|
||||
function buildChordRow(chords: { offset: number; chord: string }[]): string {
|
||||
let row = "";
|
||||
for (const { offset, chord } of chords) {
|
||||
while (row.length < offset) row += " ";
|
||||
row += chord;
|
||||
}
|
||||
return row;
|
||||
}
|
||||
|
||||
function SectionBlock({ section }: { section: Section }) {
|
||||
return (
|
||||
<div className="mb-6">
|
||||
{section.label && (
|
||||
<p className="text-xs text-muted-foreground mb-1">[{section.label}]</p>
|
||||
)}
|
||||
{section.lines.map((line, i) => (
|
||||
<div key={i} className="leading-tight">
|
||||
{line.chords.length > 0 && (
|
||||
<pre className="text-primary text-sm font-mono whitespace-pre">
|
||||
{buildChordRow(line.chords)}
|
||||
</pre>
|
||||
)}
|
||||
{line.text && (
|
||||
<pre className="text-foreground text-sm font-mono whitespace-pre">
|
||||
{line.text}
|
||||
</pre>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function ChordChart({ sections }: Props) {
|
||||
return (
|
||||
<div className="px-4 py-3">
|
||||
{sections.map((section, i) => (
|
||||
<SectionBlock key={i} section={section} />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user