# Alert

## Introduction

Alert 컴포넌트는 사용자에게 중요한 정보, 성공 메시지, 경고, 오류 등을 전달하는 피드백 컴포넌트입니다. Joy UI의 Alert를 기반으로 하며, 다양한 색상과 변형을 통해 메시지의 중요도와 성격을 시각적으로 구분할 수 있습니다. 시스템 알림, 폼 검증 결과, 작업 완료 상태 등을 사용자에게 명확하게 전달하는 데 사용됩니다.

```tsx
<Alert
  content="Alert Content"
  variant="solid"
/>
```

| Field          | Description | Default         |
| -------------- | ----------- | --------------- |
| title          | —           | —               |
| content        | —           | "Alert Content" |
| variant        | —           | "solid"         |
| color          | —           | —               |
| size           | —           | —               |
| invertedColors | —           | —               |
| startDecorator | —           | —               |
| actions        | —           | —               |

## Usage

```tsx
import { Alert } from '@ceed/cds';

function MyComponent() {
  return (
    <div>
      {/* 기본 알림 */}
      <Alert content="이것은 기본 알림입니다." />

      {/* 성공 메시지 */}
      <Alert
        color="success"
        title="저장 완료"
        content="문서가 성공적으로 저장되었습니다."
        startDecorator={<CheckCircleIcon />}
      />

      {/* 오류 메시지 */}
      <Alert
        color="danger"
        title="오류 발생"
        content="파일 업로드에 실패했습니다. 다시 시도해주세요."
        startDecorator={<ErrorIcon />}
        actions={<Button size="sm">다시 시도</Button>}
      />
    </div>
  );
}
```

## Examples

### Basic Usage

가장 기본적인 Alert 사용법입니다.

```tsx
<Alert
  content="Alert Content"
  variant="solid"
/>
```

### Colors

다양한 색상을 통해 메시지의 성격을 구분할 수 있습니다.

```tsx
<div style={{
  display: 'flex',
  flexDirection: 'column',
  gap: '5px'
}}>
<div style={{
  display: 'flex',
  flexDirection: 'column',
  gap: '5px'
}}>
<Alert {...props} color="primary" variant="plain" />
<Alert {...props} color="neutral" variant="plain" />
<Alert {...props} color="danger" variant="plain" />
<Alert {...props} color="success" variant="plain" />
<Alert {...props} color="warning" variant="plain" />
</div>
<div style={{
  display: 'flex',
  flexDirection: 'column',
  gap: '5px'
}}>
<Alert {...props} color="primary" variant="soft" />
<Alert {...props} color="neutral" variant="soft" />
<Alert {...props} color="danger" variant="soft" />
<Alert {...props} color="success" variant="soft" />
<Alert {...props} color="warning" variant="soft" />
</div>
<div style={{
  display: 'flex',
  flexDirection: 'column',
  gap: '5px'
}}>
<Alert {...props} color="primary" variant="solid" />
<Alert {...props} color="neutral" variant="solid" />
<Alert {...props} color="danger" variant="solid" />
<Alert {...props} color="success" variant="solid" />
<Alert {...props} color="warning" variant="solid" />
</div>
<div style={{
  display: 'flex',
  flexDirection: 'column',
  gap: '5px'
}}>
<Alert {...props} color="primary" variant="outlined" />
<Alert {...props} color="neutral" variant="outlined" />
<Alert {...props} color="danger" variant="outlined" />
<Alert {...props} color="success" variant="outlined" />
<Alert {...props} color="warning" variant="outlined" />
</div>
</div>
```

- **primary**: 일반적인 정보 메시지
- **success**: 성공, 완료 메시지
- **warning**: 주의, 경고 메시지
- **danger**: 오류, 위험 메시지
- **neutral**: 중립적인 메시지

### With Start Decorator

아이콘이나 다른 요소를 메시지 앞에 추가할 수 있습니다.

```tsx
<Alert
  content="Alert Content"
  variant="solid"
  startDecorator={<AccountCircle />}
/>
```

### With Title

제목을 추가하여 메시지를 구조화할 수 있습니다.

```tsx
<Alert
  content="Alert Content"
  variant="solid"
  title="Alert Title"
/>
```

### With Actions

사용자가 수행할 수 있는 액션을 추가할 수 있습니다.

```tsx
<Alert
  content="Alert Content"
  variant="solid"
  actions={<Button>Action</Button>}
/>
```

### Complete Alert

모든 요소를 포함한 완전한 Alert입니다.

```tsx
<Alert
  content="Alert Content"
  variant="solid"
  startDecorator={<AccountCircle />}
  title="Alert Title"
  actions={<Button>Action</Button>}
/>
```

## Common Use Cases

### Form Validation

폼 검증 결과를 표시할 때 사용합니다.

```tsx
function LoginForm() {
  const [error, setError] = useState('');
  const [success, setSuccess] = useState(false);

  const handleSubmit = async (formData) => {
    try {
      await login(formData);
      setSuccess(true);
      setError('');
    } catch (err) {
      setError(err.message);
      setSuccess(false);
    }
  };

  return (
    <Stack spacing={3}>
      {error && (
        <Alert
          color="danger"
          title="로그인 실패"
          content={error}
          startDecorator={<ErrorIcon />}
          actions={
            <Button size="sm" variant="plain" onClick={() => setError('')}>
              닫기
            </Button>
          }
        />
      )}

      {success && <Alert color="success" content="로그인이 완료되었습니다." startDecorator={<CheckCircleIcon />} />}

      <form onSubmit={handleSubmit}>{/* 폼 필드들 */}</form>
    </Stack>
  );
}
```

### System Notifications

시스템 상태나 알림을 표시할 때 사용합니다.

```tsx
function SystemStatus() {
  return (
    <Stack spacing={2}>
      <Alert
        color="success"
        title="시스템 정상"
        content="모든 서비스가 정상적으로 작동하고 있습니다."
        startDecorator={<CheckCircleIcon />}
      />

      <Alert
        color="warning"
        title="예정된 점검"
        content="오늘 밤 12시부터 2시까지 시스템 점검이 예정되어 있습니다."
        startDecorator={<WarningIcon />}
        actions={
          <Button size="sm" variant="plain">
            자세히 보기
          </Button>
        }
      />

      <Alert
        color="danger"
        title="서비스 장애"
        content="결제 서비스에 일시적인 장애가 발생했습니다."
        startDecorator={<ErrorIcon />}
        actions={
          <Stack direction="row" spacing={1}>
            <Button size="sm" variant="plain">
              새로고침
            </Button>
            <Button size="sm" variant="solid" color="danger">
              고객센터
            </Button>
          </Stack>
        }
      />
    </Stack>
  );
}
```

### Data Processing Status

데이터 처리 상태를 보여줄 때 사용합니다.

```tsx
function DataProcessingStatus({ status, progress, onCancel, onRetry }) {
  const getAlertProps = () => {
    switch (status) {
      case 'processing':
        return {
          color: 'primary',
          title: '데이터 처리 중',
          content: `진행률: ${progress}%`,
          startDecorator: <CircularProgress size="sm" />,
          actions: (
            <Button size="sm" onClick={onCancel}>
              취소
            </Button>
          ),
        };
      case 'completed':
        return {
          color: 'success',
          title: '처리 완료',
          content: '모든 데이터가 성공적으로 처리되었습니다.',
          startDecorator: <CheckCircleIcon />,
        };
      case 'failed':
        return {
          color: 'danger',
          title: '처리 실패',
          content: '데이터 처리 중 오류가 발생했습니다.',
          startDecorator: <ErrorIcon />,
          actions: (
            <Button size="sm" onClick={onRetry}>
              다시 시도
            </Button>
          ),
        };
      default:
        return null;
    }
  };

  const alertProps = getAlertProps();

  return alertProps ? <Alert {...alertProps} /> : null;
}
```

### Feature Announcements

새로운 기능 소개나 중요한 공지사항을 표시할 때 사용합니다.

```tsx
function FeatureAnnouncement() {
  const [dismissed, setDismissed] = useState(false);

  if (dismissed) return null;

  return (
    <Alert
      color="primary"
      title="🎉 새로운 기능 출시"
      content="이제 문서를 팀원들과 실시간으로 공동 편집할 수 있습니다!"
      startDecorator={<NewReleasesIcon />}
      actions={
        <Stack direction="row" spacing={1}>
          <Button size="sm" variant="soft">
            자세히 보기
          </Button>
          <Button size="sm" variant="plain" onClick={() => setDismissed(true)}>
            닫기
          </Button>
        </Stack>
      }
    />
  );
}
```

### Permission Requests

권한 요청이나 설정 변경을 안내할 때 사용합니다.

```tsx
function PermissionAlert() {
  return (
    <Stack spacing={2}>
      <Alert
        color="warning"
        title="알림 권한 필요"
        content="중요한 업데이트를 놓치지 않으려면 브라우저 알림을 허용해주세요."
        startDecorator={<NotificationsIcon />}
        actions={
          <Stack direction="row" spacing={1}>
            <Button size="sm" variant="solid" color="warning">
              허용
            </Button>
            <Button size="sm" variant="plain">
              나중에
            </Button>
          </Stack>
        }
      />

      <Alert
        color="neutral"
        title="쿠키 사용 안내"
        content="이 웹사이트는 사용자 경험 개선을 위해 쿠키를 사용합니다."
        startDecorator={<InfoIcon />}
        actions={
          <Button size="sm" variant="outlined">
            설정
          </Button>
        }
      />
    </Stack>
  );
}
```

### Inline Messages

폼 필드나 특정 섹션에 인라인으로 표시하는 메시지입니다.

```tsx
function InlineMessages() {
  return (
    <Stack spacing={3}>
      <FormControl>
        <FormLabel>비밀번호</FormLabel>
        <Input type="password" />
        <Alert
          size="sm"
          color="warning"
          content="비밀번호는 최소 8자 이상이어야 합니다."
          startDecorator={<WarningIcon />}
          variant="soft"
        />
      </FormControl>

      <FormControl>
        <FormLabel>이메일 주소</FormLabel>
        <Input type="email" />
        <Alert
          size="sm"
          color="success"
          content="사용 가능한 이메일 주소입니다."
          startDecorator={<CheckIcon />}
          variant="soft"
        />
      </FormControl>
    </Stack>
  );
}
```

### Dismissible Alerts

사용자가 닫을 수 있는 Alert 구현 예제입니다.

```tsx
function DismissibleAlerts() {
  const [alerts, setAlerts] = useState([
    { id: 1, type: 'info', message: '새로운 메시지가 도착했습니다.' },
    { id: 2, type: 'warning', message: '계정 보안을 위해 비밀번호를 변경해주세요.' },
    { id: 3, type: 'success', message: '프로필이 성공적으로 업데이트되었습니다.' },
  ]);

  const dismissAlert = (id) => {
    setAlerts((prev) => prev.filter((alert) => alert.id !== id));
  };

  return (
    <Stack spacing={2}>
      {alerts.map((alert) => (
        <Alert
          key={alert.id}
          color={getAlertColor(alert.type)}
          content={alert.message}
          startDecorator={getAlertIcon(alert.type)}
          actions={
            <IconButton size="sm" variant="plain" onClick={() => dismissAlert(alert.id)}>
              <CloseIcon />
            </IconButton>
          }
        />
      ))}
    </Stack>
  );
}
```

## Props and Customization

### Content Types

Alert는 다양한 형태의 콘텐츠를 지원합니다.

```tsx
// 단순 텍스트
<Alert content="간단한 메시지" />

// React 요소
<Alert
  content={
    <div>
      <strong>중요:</strong> 이 작업은 되돌릴 수 없습니다.
      <Link href="/help">도움말 보기</Link>
    </div>
  }
/>

// 제목과 내용 분리
<Alert
  title="업데이트 완료"
  content="애플리케이션이 최신 버전으로 업데이트되었습니다."
/>
```

### Variants

다양한 시각적 스타일을 제공합니다.

```tsx
<Stack spacing={2}>
  <Alert variant="solid" color="primary" content="Solid 변형" />
  <Alert variant="soft" color="primary" content="Soft 변형" />
  <Alert variant="outlined" color="primary" content="Outlined 변형" />
  <Alert variant="plain" color="primary" content="Plain 변형" />
</Stack>
```

### Sizes

Alert의 크기를 조절할 수 있습니다.

```tsx
<Stack spacing={2}>
  <Alert size="sm" content="Small Alert" />
  <Alert size="md" content="Medium Alert (기본값)" />
  <Alert size="lg" content="Large Alert" />
</Stack>
```

### Custom Styling

sx prop을 사용해 커스텀 스타일을 적용할 수 있습니다.

```tsx
<Alert
  content="커스텀 스타일 Alert"
  sx={{
    borderRadius: 'xl',
    boxShadow: 'lg',
    '&:hover': {
      transform: 'translateY(-2px)',
      transition: 'transform 0.2s ease',
    },
  }}
/>
```

## Accessibility

Alert 컴포넌트는 다음과 같은 접근성 기능을 제공합니다:

### ARIA 속성

자동으로 적절한 ARIA 속성이 적용됩니다.

- `role="alert"`: 즉시 사용자에게 알려야 하는 중요한 메시지
- `aria-live="polite"`: 덜 긴급한 메시지의 경우

### 키보드 탐색

Alert 내의 액션 버튼들은 키보드로 탐색 가능합니다.

### 스크린 리더 지원

제목과 내용이 적절히 구조화되어 스크린 리더가 읽을 수 있습니다.

```tsx
<Alert
  title="오류 발생"
  content="입력하신 정보를 다시 확인해주세요."
  startDecorator={<ErrorIcon aria-hidden="true" />}
  actions={<Button aria-label="오류 메시지 닫기">닫기</Button>}
/>
```

## Best Practices

1. **적절한 색상 사용**: 메시지의 성격에 맞는 색상을 사용하세요.

```tsx
// ✅ 좋은 예
<Alert color="success" content="저장 완료" />
<Alert color="danger" content="오류 발생" />
<Alert color="warning" content="주의 필요" />

// ❌ 나쁜 예
<Alert color="success" content="오류 발생" /> // 잘못된 색상
```

2. **명확한 메시지**: 사용자가 이해하기 쉬운 명확한 메시지를 작성하세요.

```tsx
// ✅ 명확한 메시지
<Alert
  color="danger"
  title="업로드 실패"
  content="파일이 너무 큽니다. 10MB 이하의 파일을 선택해주세요."
/>

// ❌ 모호한 메시지
<Alert content="오류가 발생했습니다." />
```

3. **적절한 액션**: 사용자가 취할 수 있는 다음 단계를 제공하세요.

```tsx
<Alert
  color="warning"
  content="세션이 곧 만료됩니다."
  actions={
    <Button size="sm" onClick={extendSession}>
      연장
    </Button>
  }
/>
```

4. **과도한 사용 금지**: 너무 많은 Alert가 동시에 표시되지 않도록 하세요.

5. **자동 해제**: 일시적인 메시지는 자동으로 해제되도록 구현하세요.

```tsx
function AutoDismissAlert() {
  const [visible, setVisible] = useState(true);

  useEffect(() => {
    const timer = setTimeout(() => {
      setVisible(false);
    }, 5000);

    return () => clearTimeout(timer);
  }, []);

  if (!visible) return null;

  return <Alert color="success" content="저장이 완료되었습니다." startDecorator={<CheckIcon />} />;
}
```

## Performance Considerations

1. **조건부 렌더링**: 필요할 때만 Alert를 렌더링하세요.

2. **메모이제이션**: 복잡한 Alert 내용은 메모이제이션을 고려하세요.

```tsx
const alertContent = useMemo(() => <ComplexAlertContent data={data} />, [data]);

<Alert content={alertContent} />;
```

3. **배치 처리**: 여러 Alert를 효율적으로 관리하세요.

Alert는 사용자와의 커뮤니케이션에서 핵심적인 역할을 하는 컴포넌트입니다. 적절한 색상, 명확한 메시지, 유용한 액션을 통해 우수한 사용자 경험을 제공할 수 있습니다.
