fix(frontend): Badge 다크 팔레트를 translucent로 통일 + 쇼케이스 한/영 병기
- badgeVariants 다크 팔레트를 classes 기반 4종 카탈로그와 동일 패턴으로 통일 - 이전: dark:bg-X-400 dark:text-slate-900 dark:border-X-600 (솔리드) - 이후: dark:bg-X-500/20 dark:text-X-400 dark:border-X-500/30 (translucent) - 라이트 팔레트는 그대로 유지 (이미 통일되어 있음) - CatalogSection: 각 카탈로그 항목을 [code / 한글 배지 / 영문 배지] 3열 행으로 렌더 - 한글/영문 라벨 두 버전을 한눈에 비교 검토 가능 - 추적 ID Trk는 행 전체를 감싸서 호버/복사 동작
This commit is contained in:
부모
f589cb0f94
커밋
d7f8db88ee
@ -43,10 +43,14 @@ interface AnyMeta {
|
||||
|
||||
type AnyCatalog = Record<string, AnyMeta>;
|
||||
|
||||
function getLabel(meta: AnyMeta): string {
|
||||
function getKoLabel(meta: AnyMeta): string {
|
||||
return meta.fallback?.ko ?? meta.label ?? meta.code;
|
||||
}
|
||||
|
||||
function getEnLabel(meta: AnyMeta): string | undefined {
|
||||
return meta.fallback?.en;
|
||||
}
|
||||
|
||||
/** classes가 문자열인 경우 그대로, 객체인 경우 bg+text 조합 */
|
||||
function getFallbackClasses(meta: AnyMeta): string | undefined {
|
||||
if (typeof meta.classes === 'string') return meta.classes;
|
||||
@ -56,31 +60,49 @@ function getFallbackClasses(meta: AnyMeta): string | undefined {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/** 카탈로그 항목을 Badge 또는 fallback span으로 렌더 */
|
||||
/** 단일 배지 렌더 — Badge(intent) 또는 span(classes) */
|
||||
function renderBadge(meta: AnyMeta, label: string): ReactNode {
|
||||
if (meta.intent) {
|
||||
return (
|
||||
<Badge intent={meta.intent} size="sm">
|
||||
{label}
|
||||
</Badge>
|
||||
);
|
||||
}
|
||||
const classes =
|
||||
getFallbackClasses(meta) ??
|
||||
'bg-slate-100 text-slate-700 border-slate-300 dark:bg-slate-500/20 dark:text-slate-300 dark:border-slate-500/30';
|
||||
return (
|
||||
<span
|
||||
className={`inline-flex items-center px-2 py-0.5 rounded-md border text-[12px] font-semibold ${classes}`}
|
||||
>
|
||||
{label}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
/** 카탈로그 항목을 행 단위로 렌더: [code] [한글 배지] [영문 배지] */
|
||||
function CatalogBadges({ catalog, idPrefix }: { catalog: AnyCatalog; idPrefix: string }) {
|
||||
const entries = Object.values(catalog);
|
||||
return (
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<div className="space-y-1.5">
|
||||
{entries.map((meta) => {
|
||||
const label = getLabel(meta);
|
||||
const koLabel = getKoLabel(meta);
|
||||
const enLabel = getEnLabel(meta);
|
||||
const trkId = `${idPrefix}-${meta.code}`;
|
||||
const content: ReactNode = meta.intent ? (
|
||||
<Badge intent={meta.intent} size="sm">
|
||||
{label}
|
||||
</Badge>
|
||||
) : (
|
||||
<span
|
||||
className={`inline-flex items-center px-2 py-0.5 rounded-md border text-[12px] font-semibold ${
|
||||
getFallbackClasses(meta) ??
|
||||
'bg-slate-100 text-slate-700 border-slate-300 dark:bg-slate-500/20 dark:text-slate-300 dark:border-slate-500/30'
|
||||
}`}
|
||||
>
|
||||
{label}
|
||||
</span>
|
||||
);
|
||||
return (
|
||||
<Trk key={meta.code} id={trkId} inline>
|
||||
{content}
|
||||
<Trk key={meta.code} id={trkId} className="flex items-center gap-3 rounded-sm">
|
||||
<code className="text-[10px] text-hint font-mono whitespace-nowrap w-32 shrink-0 truncate">
|
||||
{meta.code}
|
||||
</code>
|
||||
<div className="flex-1">{renderBadge(meta, koLabel)}</div>
|
||||
<div className="flex-1">
|
||||
{enLabel ? (
|
||||
renderBadge(meta, enLabel)
|
||||
) : (
|
||||
<span className="text-[10px] text-hint italic">(no en)</span>
|
||||
)}
|
||||
</div>
|
||||
</Trk>
|
||||
);
|
||||
})}
|
||||
|
||||
@ -19,9 +19,9 @@ export const cardVariants = cva('rounded-xl border border-border', {
|
||||
|
||||
/** 뱃지 변형 — 위험도/상태별 150회+ 반복 패턴 통합
|
||||
*
|
||||
* 가독성 정책 (테마별 팔레트 분리):
|
||||
* - **다크 모드**: 솔리드 밝은 배경(-400) + 진한 글자(slate-900) + 강한 보더(-600)
|
||||
* → 어두운 페이지에서 밝게 튀어 명확한 분류 식별
|
||||
* 가독성 정책 (테마별 팔레트 분리 + classes 기반 카탈로그와 통일):
|
||||
* - **다크 모드**: 반투명 배경(-500/20) + 밝은 글자(-400) + 반투명 보더(-500/30)
|
||||
* → 어두운 페이지에서 은은하게 녹아들며 글자 강조 (classes 기반 4종과 동일 패턴)
|
||||
* - **라이트 모드**: 파스텔 배경(-100) + 진한 글자(-900) + 부드러운 보더(-300)
|
||||
* → 흰 배경에 어울리는 소프트 토큰, 글자와 배경 대비 충분
|
||||
* - 가운데 정렬
|
||||
@ -35,18 +35,18 @@ export const badgeVariants = cva(
|
||||
variants: {
|
||||
intent: {
|
||||
critical:
|
||||
'bg-red-100 text-red-900 border-red-300 dark:bg-red-400 dark:text-slate-900 dark:border-red-600',
|
||||
high: 'bg-orange-100 text-orange-900 border-orange-300 dark:bg-orange-400 dark:text-slate-900 dark:border-orange-600',
|
||||
'bg-red-100 text-red-900 border-red-300 dark:bg-red-500/20 dark:text-red-400 dark:border-red-500/30',
|
||||
high: 'bg-orange-100 text-orange-900 border-orange-300 dark:bg-orange-500/20 dark:text-orange-400 dark:border-orange-500/30',
|
||||
warning:
|
||||
'bg-yellow-100 text-yellow-900 border-yellow-300 dark:bg-yellow-400 dark:text-slate-900 dark:border-yellow-600',
|
||||
info: 'bg-blue-100 text-blue-900 border-blue-300 dark:bg-blue-400 dark:text-slate-900 dark:border-blue-600',
|
||||
'bg-yellow-100 text-yellow-900 border-yellow-300 dark:bg-yellow-500/20 dark:text-yellow-400 dark:border-yellow-500/30',
|
||||
info: 'bg-blue-100 text-blue-900 border-blue-300 dark:bg-blue-500/20 dark:text-blue-400 dark:border-blue-500/30',
|
||||
success:
|
||||
'bg-green-100 text-green-900 border-green-300 dark:bg-green-400 dark:text-slate-900 dark:border-green-600',
|
||||
'bg-green-100 text-green-900 border-green-300 dark:bg-green-500/20 dark:text-green-400 dark:border-green-500/30',
|
||||
muted:
|
||||
'bg-slate-100 text-slate-800 border-slate-300 dark:bg-slate-400 dark:text-slate-900 dark:border-slate-600',
|
||||
'bg-slate-100 text-slate-700 border-slate-300 dark:bg-slate-500/20 dark:text-slate-300 dark:border-slate-500/30',
|
||||
purple:
|
||||
'bg-purple-100 text-purple-900 border-purple-300 dark:bg-purple-400 dark:text-slate-900 dark:border-purple-600',
|
||||
cyan: 'bg-cyan-100 text-cyan-900 border-cyan-300 dark:bg-cyan-400 dark:text-slate-900 dark:border-cyan-600',
|
||||
'bg-purple-100 text-purple-900 border-purple-300 dark:bg-purple-500/20 dark:text-purple-400 dark:border-purple-500/30',
|
||||
cyan: 'bg-cyan-100 text-cyan-900 border-cyan-300 dark:bg-cyan-500/20 dark:text-cyan-400 dark:border-cyan-500/30',
|
||||
},
|
||||
// rem 기반 — root font-size 대비 비율, 화면 비율 변경 시 자동 조정
|
||||
// xs ≈ 11px, sm ≈ 12px, md ≈ 13px, lg ≈ 14px (root 14px 기준)
|
||||
|
||||
불러오는 중...
Reference in New Issue
Block a user