임동욱 임동욱 07-28
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
+++ components/ui/icons/monitor-icon.tsx
@@ -1,6 +1,9 @@
 interface MonitorIconProps {
-  /** 표시 제어용 클래스 패스스루(예: 테마 CSS 변형자 `hidden theme-system:contents`).
-   * 디자인 값(색상·치수 등) 주입은 금지 — 색은 상위 요소의 currentColor를 상속한다. */
+  /** 표시 제어용 클래스 패스스루(예: 테마 CSS 변형자 `hidden theme-system:contents`) —
+   * 감싸는 `<span>`에 적용된다(`display: contents`는 CSS 스펙상 대체 요소인 `<svg>`
+   * 루트에는 적용되지 않고 `none`으로 계산되므로, 아이콘 자체가 아니라 span에
+   * 걸어야 실제로 전환이 동작한다). 디자인 값(색상·치수 등) 주입은 금지 — 색은
+   * 상위 요소의 currentColor를 상속한다. */
   className?: string;
 }
 
@@ -11,19 +14,21 @@
  */
 export function MonitorIcon({ className }: MonitorIconProps) {
   return (
-    <svg
-      viewBox="0 0 24 24"
-      fill="none"
-      stroke="currentColor"
-      strokeWidth="2"
-      strokeLinecap="round"
-      strokeLinejoin="round"
-      aria-hidden="true"
-      className={`size-5 ${className ?? ""}`}
-    >
-      <rect x="3" y="4" width="18" height="13" rx="1.5" />
-      <path d="M8 21h8" />
-      <path d="M12 17v4" />
-    </svg>
+    <span className={className}>
+      <svg
+        viewBox="0 0 24 24"
+        fill="none"
+        stroke="currentColor"
+        strokeWidth="2"
+        strokeLinecap="round"
+        strokeLinejoin="round"
+        aria-hidden="true"
+        className="size-5"
+      >
+        <rect x="3" y="4" width="18" height="13" rx="1.5" />
+        <path d="M8 21h8" />
+        <path d="M12 17v4" />
+      </svg>
+    </span>
   );
 }
components/ui/icons/moon-icon.tsx
--- components/ui/icons/moon-icon.tsx
+++ components/ui/icons/moon-icon.tsx
@@ -1,6 +1,9 @@
 interface MoonIconProps {
-  /** 표시 제어용 클래스 패스스루(예: 테마 CSS 변형자 `hidden theme-dark:contents`).
-   * 디자인 값(색상·치수 등) 주입은 금지 — 색은 상위 요소의 currentColor를 상속한다. */
+  /** 표시 제어용 클래스 패스스루(예: 테마 CSS 변형자 `hidden theme-dark:contents`) —
+   * 감싸는 `<span>`에 적용된다(`display: contents`는 CSS 스펙상 대체 요소인 `<svg>`
+   * 루트에는 적용되지 않고 `none`으로 계산되므로, 아이콘 자체가 아니라 span에
+   * 걸어야 실제로 전환이 동작한다). 디자인 값(색상·치수 등) 주입은 금지 — 색은
+   * 상위 요소의 currentColor를 상속한다. */
   className?: string;
 }
 
@@ -13,17 +16,19 @@
  */
 export function MoonIcon({ className }: MoonIconProps) {
   return (
-    <svg
-      viewBox="0 0 24 24"
-      fill="none"
-      stroke="currentColor"
-      strokeWidth="2"
-      strokeLinecap="round"
-      strokeLinejoin="round"
-      aria-hidden="true"
-      className={`size-5 ${className ?? ""}`}
-    >
-      <path d="M20 14.5A8.5 8.5 0 1 1 9.5 4A6.5 6.5 0 0 0 20 14.5Z" />
-    </svg>
+    <span className={className}>
+      <svg
+        viewBox="0 0 24 24"
+        fill="none"
+        stroke="currentColor"
+        strokeWidth="2"
+        strokeLinecap="round"
+        strokeLinejoin="round"
+        aria-hidden="true"
+        className="size-5"
+      >
+        <path d="M20 14.5A8.5 8.5 0 1 1 9.5 4A6.5 6.5 0 0 0 20 14.5Z" />
+      </svg>
+    </span>
   );
 }
components/ui/icons/sun-icon.tsx
--- components/ui/icons/sun-icon.tsx
+++ components/ui/icons/sun-icon.tsx
@@ -1,6 +1,9 @@
 interface SunIconProps {
-  /** 표시 제어용 클래스 패스스루(예: 테마 CSS 변형자 `hidden theme-light:contents`).
-   * 디자인 값(색상·치수 등) 주입은 금지 — 색은 상위 요소의 currentColor를 상속한다. */
+  /** 표시 제어용 클래스 패스스루(예: 테마 CSS 변형자 `hidden theme-light:contents`) —
+   * 감싸는 `<span>`에 적용된다(`display: contents`는 CSS 스펙상 대체 요소인 `<svg>`
+   * 루트에는 적용되지 않고 `none`으로 계산되므로, 아이콘 자체가 아니라 span에
+   * 걸어야 실제로 전환이 동작한다). 디자인 값(색상·치수 등) 주입은 금지 — 색은
+   * 상위 요소의 currentColor를 상속한다. */
   className?: string;
 }
 
@@ -11,25 +14,27 @@
  */
 export function SunIcon({ className }: SunIconProps) {
   return (
-    <svg
-      viewBox="0 0 24 24"
-      fill="none"
-      stroke="currentColor"
-      strokeWidth="2"
-      strokeLinecap="round"
-      strokeLinejoin="round"
-      aria-hidden="true"
-      className={`size-5 ${className ?? ""}`}
-    >
-      <circle cx="12" cy="12" r="4" />
-      <path d="M12 2v2.5" />
-      <path d="M12 19.5V22" />
-      <path d="M2 12h2.5" />
-      <path d="M19.5 12H22" />
-      <path d="M4.93 4.93l1.77 1.77" />
-      <path d="M17.3 17.3l1.77 1.77" />
-      <path d="M4.93 19.07l1.77-1.77" />
-      <path d="M17.3 6.7l1.77-1.77" />
-    </svg>
+    <span className={className}>
+      <svg
+        viewBox="0 0 24 24"
+        fill="none"
+        stroke="currentColor"
+        strokeWidth="2"
+        strokeLinecap="round"
+        strokeLinejoin="round"
+        aria-hidden="true"
+        className="size-5"
+      >
+        <circle cx="12" cy="12" r="4" />
+        <path d="M12 2v2.5" />
+        <path d="M12 19.5V22" />
+        <path d="M2 12h2.5" />
+        <path d="M19.5 12H22" />
+        <path d="M4.93 4.93l1.77 1.77" />
+        <path d="M17.3 17.3l1.77 1.77" />
+        <path d="M4.93 19.07l1.77-1.77" />
+        <path d="M17.3 6.7l1.77-1.77" />
+      </svg>
+    </span>
   );
 }
Add a comment
List