UX/UI 개편 Phase A-6.
신규 컴포넌트 (lib/components/ui/)
- TextInput.svelte: \$bindable value, label/error/hint, leading/trailing icon,
\$props.id() 기반 SSR-safe 자동 id, aria-describedby 자동 연결.
- Textarea.svelte: TextInput과 동일 구조 + autoGrow 옵션
(\$effect로 scrollHeight 동기화, maxRows 지원).
- Select.svelte: 네이티브 <select> 래퍼, ChevronDown 표시.
options: { value, label, disabled? }[]
빌드 환경 보정
- frontend/tsconfig.json 신규: svelte-kit 자동 생성 .svelte-kit/tsconfig.json을
extends. 이게 없으면 svelte-check가 \$lib path mapping과 .svelte.ts 모듈
resolution을 못 잡아 "Cannot find module" 에러 발생. SvelteKit 표준 패턴.
strict는 false로 시작 (기존 코드 implicit any 다수 — 점진적 정리 예정).
- Button/IconButton/EmptyState/TextInput의 icon prop 타입을 IconComponent(any)로
완화. lucide-svelte v0.400은 legacy SvelteComponentTyped 기반이라 Svelte 5의
Component<P, E, B> 시그니처와 호환 안 됨. v0.469+ 업그레이드 후 좁힐 예정.
svelte-check: 0 errors / 8 warnings (전부 기존 latent, 새 코드 무관)
build: 2.07s 무경고
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
40 lines
1.0 KiB
Svelte
40 lines
1.0 KiB
Svelte
<script lang="ts">
|
|
// 빈 상태/추후 지원/검색 결과 없음 등에 사용.
|
|
// children은 액션 슬롯 (Button 등).
|
|
import type { Snippet } from 'svelte';
|
|
|
|
// lucide-svelte v0.400 legacy 타입 호환을 위한 임시 IconComponent.
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
type IconComponent = any;
|
|
|
|
interface Props {
|
|
icon?: IconComponent;
|
|
title: string;
|
|
description?: string;
|
|
children?: Snippet;
|
|
class?: string;
|
|
}
|
|
|
|
let { icon: Icon, title, description, children, class: className = '', ...rest }: Props = $props();
|
|
</script>
|
|
|
|
<div
|
|
class={'flex flex-col items-center justify-center text-center py-12 px-4 ' + className}
|
|
{...rest}
|
|
>
|
|
{#if Icon}
|
|
<div class="text-faint mb-3">
|
|
<Icon size={40} strokeWidth={1.5} />
|
|
</div>
|
|
{/if}
|
|
<p class="text-sm font-medium text-text">{title}</p>
|
|
{#if description}
|
|
<p class="text-xs text-dim mt-1 max-w-sm">{description}</p>
|
|
{/if}
|
|
{#if children}
|
|
<div class="mt-4">
|
|
{@render children()}
|
|
</div>
|
|
{/if}
|
|
</div>
|