srope 프로젝트의 주식/시세 화면에서 반복되는 UI 패턴을 doksam-ui 표준 컴포넌트와 시맨틱 토큰으로 재작성한 모음입니다. 등락률 색상은 한국 관례(상승=빨강, 하락=파랑)를 유지하되 하드코딩 hex 대신 text-destructive · text-chart-1 토큰으로 표현합니다.
시세 + 등락 + PER/PBR + 52주 범위를 한 카드에 담은 시세 스냅샷.
<Card>
<CardHeader className="pb-2">
<p className="text-sm font-semibold">{quote.name}</p>
<p className="text-xs text-muted-foreground">{quote.code} · {quote.sector}</p>
</CardHeader>
<CardContent className="space-y-3">
<span className="text-2xl font-bold tabular-nums">{quote.currentPrice.toLocaleString()}</span>
<span className={rateToneClass(quote.changePercent)}>
{rateSign(quote.priceChange)}{quote.priceChange} ({rateSign(quote.changePercent)}{quote.changePercent}%)
</span>
{/* 52주 범위 바 — currentPrice 위치를 low~high 사이 % 로 환산 */}
</CardContent>
</Card>선물/지수 스냅샷 — 상승/하락 방향 아이콘 + 색상.
{item.change > 0 ? (
<TrendUpIcon size={16} weight="bold" className="text-destructive" />
) : (
<TrendDownIcon size={16} weight="bold" className="text-chart-1" />
)}
<span className={rateToneClass(item.change)}>{rateSign(item.change)}{item.change}%</span>verdict 배지(강력매수~강력매도) + 매수/보유/매도 비중 점수 바.
<Badge variant={signal.verdictVariant}>{signal.verdictLabel}</Badge>
<div className="flex h-2 overflow-hidden rounded-full bg-secondary">
<div className="bg-success" style={{ width: `${signal.buyPercent}%` }} />
<div className="bg-warning" style={{ width: `${signal.holdPercent}%` }} />
<div className="bg-destructive" style={{ width: `${signal.sellPercent}%` }} />
</div>방향(호재/악재/중립) + 강도 바 + 감성 배지.
function DirectionIcon({ dir }: { dir: "bullish" | "bearish" | "neutral" }) {
if (dir === "bullish") return <ArrowUpIcon className="text-destructive" />
if (dir === "bearish") return <ArrowDownIcon className="text-chart-1" />
return <MinusIcon className="text-muted-foreground" />
}
// 강도 바: >=70 destructive, >=40 warning, else muted-foreground
// 센티먼트 배지: 긍정=default, 부정=destructive, 중립=secondary게이지(Progress) + 원인 태그 + 활성/만료 상태.
<Progress value={item.gaugeValue} className="h-1.5" />
<p className={item.causeTone === "success" ? "text-success" : "text-destructive"}>
{item.causeLabel} · {item.causeDescription}
</p>D+1~D+5 등락률 + 재료 배지 + 소스 아이콘.
<TableCell className={rateToneClass(rate)}>{rateSign(rate)}{rate.toFixed(1)}%</TableCell>
<Badge variant={catalystVariant(row.catalyst)}>{row.catalyst}</Badge>
{/* 소스 아이콘: news=warning, youtube=destructive, report=chart-1 */}요약 카드 4개 + 포트폴리오 가치 추이 차트 + 거래 내역 테이블.
const chartConfig = { value: { label: "포트폴리오 가치", color: "var(--chart-1)" } } satisfies ChartConfig
<ChartContainer config={chartConfig} className="max-h-48 w-full">
<LineChart data={PORTFOLIO_VALUE}>
<CartesianGrid vertical={false} />
<XAxis dataKey="day" tickLine={false} axisLine={false} />
<ChartTooltip content={<ChartTooltipContent />} />
<Line dataKey="value" type="monotone" stroke="var(--color-value)" strokeWidth={2} dot={false} />
</LineChart>
</ChartContainer>