diff --git a/frontend/src/lib/components/ui/Button.svelte b/frontend/src/lib/components/ui/Button.svelte index 9f7d461..af3a6cb 100644 --- a/frontend/src/lib/components/ui/Button.svelte +++ b/frontend/src/lib/components/ui/Button.svelte @@ -7,7 +7,12 @@ // - loading이면 disabled + 회전 아이콘 import { Loader2 } from 'lucide-svelte'; import type { Snippet } from 'svelte'; - import type { Component } from 'svelte'; + + // lucide-svelte v0.400은 아직 legacy SvelteComponentTyped 기반이라 Svelte 5의 + // Component 타입과 호환되지 않는다. 향후 lucide v0.469+ 업그레이드 시 정식 타입으로 좁히기. + // 우리는 size prop만 넘기므로 any로 받아도 충분히 안전. + // eslint-disable-next-line @typescript-eslint/no-explicit-any + type IconComponent = any; type Variant = 'primary' | 'secondary' | 'ghost' | 'danger'; type Size = 'sm' | 'md'; @@ -18,7 +23,7 @@ loading?: boolean; disabled?: boolean; type?: 'button' | 'submit' | 'reset'; - icon?: Component; + icon?: IconComponent; iconPosition?: 'left' | 'right'; href?: string; target?: string; diff --git a/frontend/src/lib/components/ui/EmptyState.svelte b/frontend/src/lib/components/ui/EmptyState.svelte index 45a2dbd..f903213 100644 --- a/frontend/src/lib/components/ui/EmptyState.svelte +++ b/frontend/src/lib/components/ui/EmptyState.svelte @@ -2,10 +2,13 @@ // 빈 상태/추후 지원/검색 결과 없음 등에 사용. // children은 액션 슬롯 (Button 등). import type { Snippet } from 'svelte'; - import type { Component } from 'svelte'; + + // lucide-svelte v0.400 legacy 타입 호환을 위한 임시 IconComponent. + // eslint-disable-next-line @typescript-eslint/no-explicit-any + type IconComponent = any; interface Props { - icon?: Component; + icon?: IconComponent; title: string; description?: string; children?: Snippet; diff --git a/frontend/src/lib/components/ui/IconButton.svelte b/frontend/src/lib/components/ui/IconButton.svelte index d9121b3..3bcfc1b 100644 --- a/frontend/src/lib/components/ui/IconButton.svelte +++ b/frontend/src/lib/components/ui/IconButton.svelte @@ -2,13 +2,16 @@ // 정사각형 아이콘 전용 버튼. nav/toolbar에서 사용. // aria-label 필수 (스크린 리더 라벨링). import { Loader2 } from 'lucide-svelte'; - import type { Component } from 'svelte'; + + // lucide-svelte v0.400은 legacy 타입. 향후 v0.469+ 업그레이드 후 정식 타입으로 좁히기. + // eslint-disable-next-line @typescript-eslint/no-explicit-any + type IconComponent = any; type Variant = 'primary' | 'secondary' | 'ghost' | 'danger'; type Size = 'sm' | 'md'; interface Props { - icon: Component; + icon: IconComponent; 'aria-label': string; variant?: Variant; size?: Size; diff --git a/frontend/src/lib/components/ui/Select.svelte b/frontend/src/lib/components/ui/Select.svelte new file mode 100644 index 0000000..7cb5aac --- /dev/null +++ b/frontend/src/lib/components/ui/Select.svelte @@ -0,0 +1,100 @@ + + +
+ {#if label} + + {/if} + +
+ +
+ +
+
+ + {#if error} +

{error}

+ {:else if hint} +

{hint}

+ {/if} +
diff --git a/frontend/src/lib/components/ui/TextInput.svelte b/frontend/src/lib/components/ui/TextInput.svelte new file mode 100644 index 0000000..b3b10cb --- /dev/null +++ b/frontend/src/lib/components/ui/TextInput.svelte @@ -0,0 +1,115 @@ + + +
+ {#if label} + + {/if} + +
+ {#if LeadingIcon} +
+ +
+ {/if} + + + + {#if TrailingIcon} +
+ +
+ {/if} +
+ + {#if error} +

{error}

+ {:else if hint} +

{hint}

+ {/if} +
diff --git a/frontend/src/lib/components/ui/Textarea.svelte b/frontend/src/lib/components/ui/Textarea.svelte new file mode 100644 index 0000000..69bcfcf --- /dev/null +++ b/frontend/src/lib/components/ui/Textarea.svelte @@ -0,0 +1,105 @@ + + +
+ {#if label} + + {/if} + + + + {#if error} +

{error}

+ {:else if hint} +

{hint}

+ {/if} +
diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json new file mode 100644 index 0000000..8810c77 --- /dev/null +++ b/frontend/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "./.svelte-kit/tsconfig.json", + "compilerOptions": { + "allowJs": true, + "checkJs": false, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "sourceMap": true, + "strict": false + } +}