/** * 가요 다방 — 턴테이블 하나 + 도넛판 캐러셀. * * 판을 누르면 톤암이 내려오고 판이 돈다. 가사를 못 싣는 제약(DB_Guide: 원문 전재 금지)을 * 숨기지 않고 라벨 아래 각인으로 드러낸다 — 제약이 곧 이 아이템의 인상이다. */ import {useState} from 'react'; import {Rail, SectionBody, SectionFrame} from '../../primitives'; import type {SectionRenderProps} from '../../types'; import {parseSectionData, type SongItem} from '@o2o/shared'; import { ITEM_ACCENT, ITEM_BODY, ITEM_HEADING, ITEM_INVERSE, ParseError, PasteHint, SourceLine, } from '../items/common'; import '../items/items.css'; /** 곡이 라벨 색을 안 주면 템플릿 강조색이 라벨이 된다 — hex 를 박으면 팔레트를 바꿔도 판만 남는다. */ const FALLBACK_LABEL = ITEM_ACCENT; export function SongsTurntable(props: SectionRenderProps) { const {section, isSelected, onSelect, template} = props; const parsed = parseSectionData(section.type, section.data); const [playing, setPlaying] = useState(0); // 항목이 줄어 인덱스가 범위를 벗어나도 첫 곡으로 떨어진다 — 빈 화면을 만들지 않는다. const current = parsed.items[playing] ?? parsed.items[0]; return ( {/* ★ 어두운 면 위의 글자색을 여기서 한 번만 정한다. 아래는 전부 currentColor·opacity 로 단을 만든다 — 자식마다 색을 박으면 템플릿을 바꿨을 때 한두 곳이 옛 색으로 남는다. */}

33⅓ RPM

{parsed.title || section.name}

{(parsed.subtitle || section.description) && (

{parsed.subtitle || section.description}

)}
{parsed.error ? ( ) : !current ? ( ) : ( <>
{/* 턴테이블 */}
{/* 플래터 — 판 아래 깔리는 원반. 어두운 면 위에 글자색을 옅게 얹어 단을 만든다. */}
{/* 톤암 — 곡이 얹혀 있으니 항상 내려와 있다. */}
{/* 지금 도는 곡 */}

A면 · {playing + 1} / {parsed.items.length}

{current.title}

{[ current.artist, current.year ? String(current.year) : undefined, current.lyricist || current.composer ? `작사 ${current.lyricist ?? '미상'} / 작곡 ${current.composer ?? '미상'}` : undefined, current.label, ] .filter(Boolean) .join(' · ')}

{current.story && (

{current.story}

)} {current.connection && (

{current.connection}

)} ◎ 가사 대신 이야기 — 원문은 싣지 않습니다
{/* 판 고르기 */} {parsed.items.map((song, index) => ( ))} )} ); }