임동욱 임동욱 07-27
feat: 공용 Spinner 컴포넌트 추가
Co-Authored-By: Claude Opus 5 
@e34e171a86ef0b8d9ce5d25c55d6834181e924eb
 
components/ui/spinner.tsx (added)
+++ components/ui/spinner.tsx
@@ -0,0 +1,38 @@
+type SpinnerSize = "sm" | "md" | "lg";
+type SpinnerTone = "primary" | "inverse" | "muted";
+
+const SIZE_CLASSES: Record<SpinnerSize, string> = {
+  sm: "size-4 border-2",
+  md: "size-6 border-2",
+  lg: "size-8 border-4",
+};
+
+const TONE_CLASSES: Record<SpinnerTone, string> = {
+  primary: "text-primary",
+  inverse: "text-on-primary",
+  muted: "text-foreground-subtle",
+};
+
+interface SpinnerProps {
+  size?: SpinnerSize;
+  tone?: SpinnerTone;
+  /** 스크린리더 전용 안내 문구. 기본 '불러오는 중'. */
+  label?: string;
+}
+
+/** 로딩 인디케이터. 상태 없는 프레젠테이션 컴포넌트 — 표시 여부는 호출부 책임. */
+export function Spinner({
+  size = "md",
+  tone = "primary",
+  label = "불러오는 중",
+}: SpinnerProps) {
+  return (
+    <span role="status" className="inline-flex items-center">
+      <span
+        aria-hidden="true"
+        className={`inline-block animate-spin rounded-full border-current border-t-transparent ${SIZE_CLASSES[size]} ${TONE_CLASSES[tone]}`}
+      />
+      <span className="sr-only">{label}</span>
+    </span>
+  );
+}
Add a comment
List