fix: 아이콘 표시 전환용 클래스를 span 래퍼로 이동
display: contents는 CSS 스펙상 대체 요소(svg 루트 포함)에는 적용되지 않고 none으로 계산된다(CSS Display §unbox-generating). svg 자체에 hidden theme-*:contents를 걸면 실제로는 항상 숨겨져 CSS 구동 아이콘 전환이 동작하지 않는다 — 헤드리스 Chrome으로 실측 확인. svg를 감싸는 span에 표시 제어 클래스를 옮겨 해결. Co-Authored-By: Claude Opus 5
@81a63ba121c6dd873c20ee343c9945f69ad93291
--- components/ui/icons/monitor-icon.tsx
+++ components/ui/icons/monitor-icon.tsx
... | ... | @@ -1,6 +1,9 @@ |
| 1 | 1 |
interface MonitorIconProps {
|
| 2 |
- /** 표시 제어용 클래스 패스스루(예: 테마 CSS 변형자 `hidden theme-system:contents`). |
|
| 3 |
- * 디자인 값(색상·치수 등) 주입은 금지 — 색은 상위 요소의 currentColor를 상속한다. */ |
|
| 2 |
+ /** 표시 제어용 클래스 패스스루(예: 테마 CSS 변형자 `hidden theme-system:contents`) — |
|
| 3 |
+ * 감싸는 `<span>`에 적용된다(`display: contents`는 CSS 스펙상 대체 요소인 `<svg>` |
|
| 4 |
+ * 루트에는 적용되지 않고 `none`으로 계산되므로, 아이콘 자체가 아니라 span에 |
|
| 5 |
+ * 걸어야 실제로 전환이 동작한다). 디자인 값(색상·치수 등) 주입은 금지 — 색은 |
|
| 6 |
+ * 상위 요소의 currentColor를 상속한다. */ |
|
| 4 | 7 |
className?: string; |
| 5 | 8 |
} |
| 6 | 9 |
|
... | ... | @@ -11,19 +14,21 @@ |
| 11 | 14 |
*/ |
| 12 | 15 |
export function MonitorIcon({ className }: MonitorIconProps) {
|
| 13 | 16 |
return ( |
| 14 |
- <svg |
|
| 15 |
- viewBox="0 0 24 24" |
|
| 16 |
- fill="none" |
|
| 17 |
- stroke="currentColor" |
|
| 18 |
- strokeWidth="2" |
|
| 19 |
- strokeLinecap="round" |
|
| 20 |
- strokeLinejoin="round" |
|
| 21 |
- aria-hidden="true" |
|
| 22 |
- className={`size-5 ${className ?? ""}`}
|
|
| 23 |
- > |
|
| 24 |
- <rect x="3" y="4" width="18" height="13" rx="1.5" /> |
|
| 25 |
- <path d="M8 21h8" /> |
|
| 26 |
- <path d="M12 17v4" /> |
|
| 27 |
- </svg> |
|
| 17 |
+ <span className={className}>
|
|
| 18 |
+ <svg |
|
| 19 |
+ viewBox="0 0 24 24" |
|
| 20 |
+ fill="none" |
|
| 21 |
+ stroke="currentColor" |
|
| 22 |
+ strokeWidth="2" |
|
| 23 |
+ strokeLinecap="round" |
|
| 24 |
+ strokeLinejoin="round" |
|
| 25 |
+ aria-hidden="true" |
|
| 26 |
+ className="size-5" |
|
| 27 |
+ > |
|
| 28 |
+ <rect x="3" y="4" width="18" height="13" rx="1.5" /> |
|
| 29 |
+ <path d="M8 21h8" /> |
|
| 30 |
+ <path d="M12 17v4" /> |
|
| 31 |
+ </svg> |
|
| 32 |
+ </span> |
|
| 28 | 33 |
); |
| 29 | 34 |
} |
--- components/ui/icons/moon-icon.tsx
+++ components/ui/icons/moon-icon.tsx
... | ... | @@ -1,6 +1,9 @@ |
| 1 | 1 |
interface MoonIconProps {
|
| 2 |
- /** 표시 제어용 클래스 패스스루(예: 테마 CSS 변형자 `hidden theme-dark:contents`). |
|
| 3 |
- * 디자인 값(색상·치수 등) 주입은 금지 — 색은 상위 요소의 currentColor를 상속한다. */ |
|
| 2 |
+ /** 표시 제어용 클래스 패스스루(예: 테마 CSS 변형자 `hidden theme-dark:contents`) — |
|
| 3 |
+ * 감싸는 `<span>`에 적용된다(`display: contents`는 CSS 스펙상 대체 요소인 `<svg>` |
|
| 4 |
+ * 루트에는 적용되지 않고 `none`으로 계산되므로, 아이콘 자체가 아니라 span에 |
|
| 5 |
+ * 걸어야 실제로 전환이 동작한다). 디자인 값(색상·치수 등) 주입은 금지 — 색은 |
|
| 6 |
+ * 상위 요소의 currentColor를 상속한다. */ |
|
| 4 | 7 |
className?: string; |
| 5 | 8 |
} |
| 6 | 9 |
|
... | ... | @@ -13,17 +16,19 @@ |
| 13 | 16 |
*/ |
| 14 | 17 |
export function MoonIcon({ className }: MoonIconProps) {
|
| 15 | 18 |
return ( |
| 16 |
- <svg |
|
| 17 |
- viewBox="0 0 24 24" |
|
| 18 |
- fill="none" |
|
| 19 |
- stroke="currentColor" |
|
| 20 |
- strokeWidth="2" |
|
| 21 |
- strokeLinecap="round" |
|
| 22 |
- strokeLinejoin="round" |
|
| 23 |
- aria-hidden="true" |
|
| 24 |
- className={`size-5 ${className ?? ""}`}
|
|
| 25 |
- > |
|
| 26 |
- <path d="M20 14.5A8.5 8.5 0 1 1 9.5 4A6.5 6.5 0 0 0 20 14.5Z" /> |
|
| 27 |
- </svg> |
|
| 19 |
+ <span className={className}>
|
|
| 20 |
+ <svg |
|
| 21 |
+ viewBox="0 0 24 24" |
|
| 22 |
+ fill="none" |
|
| 23 |
+ stroke="currentColor" |
|
| 24 |
+ strokeWidth="2" |
|
| 25 |
+ strokeLinecap="round" |
|
| 26 |
+ strokeLinejoin="round" |
|
| 27 |
+ aria-hidden="true" |
|
| 28 |
+ className="size-5" |
|
| 29 |
+ > |
|
| 30 |
+ <path d="M20 14.5A8.5 8.5 0 1 1 9.5 4A6.5 6.5 0 0 0 20 14.5Z" /> |
|
| 31 |
+ </svg> |
|
| 32 |
+ </span> |
|
| 28 | 33 |
); |
| 29 | 34 |
} |
--- components/ui/icons/sun-icon.tsx
+++ components/ui/icons/sun-icon.tsx
... | ... | @@ -1,6 +1,9 @@ |
| 1 | 1 |
interface SunIconProps {
|
| 2 |
- /** 표시 제어용 클래스 패스스루(예: 테마 CSS 변형자 `hidden theme-light:contents`). |
|
| 3 |
- * 디자인 값(색상·치수 등) 주입은 금지 — 색은 상위 요소의 currentColor를 상속한다. */ |
|
| 2 |
+ /** 표시 제어용 클래스 패스스루(예: 테마 CSS 변형자 `hidden theme-light:contents`) — |
|
| 3 |
+ * 감싸는 `<span>`에 적용된다(`display: contents`는 CSS 스펙상 대체 요소인 `<svg>` |
|
| 4 |
+ * 루트에는 적용되지 않고 `none`으로 계산되므로, 아이콘 자체가 아니라 span에 |
|
| 5 |
+ * 걸어야 실제로 전환이 동작한다). 디자인 값(색상·치수 등) 주입은 금지 — 색은 |
|
| 6 |
+ * 상위 요소의 currentColor를 상속한다. */ |
|
| 4 | 7 |
className?: string; |
| 5 | 8 |
} |
| 6 | 9 |
|
... | ... | @@ -11,25 +14,27 @@ |
| 11 | 14 |
*/ |
| 12 | 15 |
export function SunIcon({ className }: SunIconProps) {
|
| 13 | 16 |
return ( |
| 14 |
- <svg |
|
| 15 |
- viewBox="0 0 24 24" |
|
| 16 |
- fill="none" |
|
| 17 |
- stroke="currentColor" |
|
| 18 |
- strokeWidth="2" |
|
| 19 |
- strokeLinecap="round" |
|
| 20 |
- strokeLinejoin="round" |
|
| 21 |
- aria-hidden="true" |
|
| 22 |
- className={`size-5 ${className ?? ""}`}
|
|
| 23 |
- > |
|
| 24 |
- <circle cx="12" cy="12" r="4" /> |
|
| 25 |
- <path d="M12 2v2.5" /> |
|
| 26 |
- <path d="M12 19.5V22" /> |
|
| 27 |
- <path d="M2 12h2.5" /> |
|
| 28 |
- <path d="M19.5 12H22" /> |
|
| 29 |
- <path d="M4.93 4.93l1.77 1.77" /> |
|
| 30 |
- <path d="M17.3 17.3l1.77 1.77" /> |
|
| 31 |
- <path d="M4.93 19.07l1.77-1.77" /> |
|
| 32 |
- <path d="M17.3 6.7l1.77-1.77" /> |
|
| 33 |
- </svg> |
|
| 17 |
+ <span className={className}>
|
|
| 18 |
+ <svg |
|
| 19 |
+ viewBox="0 0 24 24" |
|
| 20 |
+ fill="none" |
|
| 21 |
+ stroke="currentColor" |
|
| 22 |
+ strokeWidth="2" |
|
| 23 |
+ strokeLinecap="round" |
|
| 24 |
+ strokeLinejoin="round" |
|
| 25 |
+ aria-hidden="true" |
|
| 26 |
+ className="size-5" |
|
| 27 |
+ > |
|
| 28 |
+ <circle cx="12" cy="12" r="4" /> |
|
| 29 |
+ <path d="M12 2v2.5" /> |
|
| 30 |
+ <path d="M12 19.5V22" /> |
|
| 31 |
+ <path d="M2 12h2.5" /> |
|
| 32 |
+ <path d="M19.5 12H22" /> |
|
| 33 |
+ <path d="M4.93 4.93l1.77 1.77" /> |
|
| 34 |
+ <path d="M17.3 17.3l1.77 1.77" /> |
|
| 35 |
+ <path d="M4.93 19.07l1.77-1.77" /> |
|
| 36 |
+ <path d="M17.3 6.7l1.77-1.77" /> |
|
| 37 |
+ </svg> |
|
| 38 |
+ </span> |
|
| 34 | 39 |
); |
| 35 | 40 |
} |
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?