# Stack

## Introduction

Stack 컴포넌트는 자식 요소들을 하나의 차원(수직 또는 수평)에서 일정한 간격으로 배치하는 레이아웃 컴포넌트입니다. Flexbox를 기반으로 하여 간단하고 직관적인 API로 복잡한 레이아웃을 쉽게 구현할 수 있습니다. 내비게이션 바, 폼 레이아웃, 카드 내부 구조 등 다양한 UI 패턴에서 활용됩니다.

```tsx
<Stack {...args}>
  <StackItem>첫 번째 아이템</StackItem>
  <StackItem>두 번째 아이템</StackItem>
  <StackItem>세 번째 아이템</StackItem>
</Stack>
```

| Field          | Description | Default  |
| -------------- | ----------- | -------- |
| direction      | 배치 방향       | "column" |
| spacing        | 요소 간 간격     | 2        |
| alignItems     | 교차축 정렬      | —        |
| justifyContent | 주축 정렬       | —        |

## Usage

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

function MyComponent() {
  return (
    <Stack spacing={2}>
      <div>첫 번째 아이템</div>
      <div>두 번째 아이템</div>
      <div>세 번째 아이템</div>
    </Stack>
  );
}
```

## Examples

### Basic Usage

세로(column)와 가로(row) 배치의 기본 사용법입니다.

```tsx
<div style={{
  display: 'flex',
  gap: '3rem',
  flexWrap: 'wrap'
}}>
<div>
  <Typography level="title-md" sx={{
    mb: 2
  }}>
  세로 스택 (Column)
</Typography>
<Stack spacing={2}>
  <StackItem>Item 1</StackItem>
  <StackItem>Item 2</StackItem>
  <StackItem>Item 3</StackItem>
</Stack>
</div>

<div>
  <Typography level="title-md" sx={{
    mb: 2
  }}>
  가로 스택 (Row)
</Typography>
<Stack direction="row" spacing={2}>
  <StackItem>Item 1</StackItem>
  <StackItem>Item 2</StackItem>
  <StackItem>Item 3</StackItem>
</Stack>
</div>
</div>
```

### Directions

다양한 배치 방향을 사용할 수 있습니다.

```tsx
<div style={{
  display: 'flex',
  flexDirection: 'column',
  gap: '3rem'
}}>
<div>
  <Typography level="title-sm" sx={{
    mb: 1
  }}>
  Row (가로)
</Typography>
<Stack direction="row" spacing={2}>
  <StackItem>1</StackItem>
  <StackItem>2</StackItem>
  <StackItem>3</StackItem>
</Stack>
</div>

<div>
  <Typography level="title-sm" sx={{
    mb: 1
  }}>
  Row Reverse (가로 역순)
</Typography>
<Stack direction="row-reverse" spacing={2}>
  <StackItem>1</StackItem>
  <StackItem>2</StackItem>
  <StackItem>3</StackItem>
</Stack>
</div>

<div style={{
  display: 'flex',
  gap: '3rem'
}}>
<div>
  <Typography level="title-sm" sx={{
    mb: 1
  }}>
  Column (세로)
</Typography>
<Stack direction="column" spacing={2}>
  <StackItem>1</StackItem>
  <StackItem>2</StackItem>
  <StackItem>3</StackItem>
</Stack>
</div>

<div>
  <Typography level="title-sm" sx={{
    mb: 1
  }}>
  Column Reverse (세로 역순)
</Typography>
<Stack direction="column-reverse" spacing={2}>
  <StackItem>1</StackItem>
  <StackItem>2</StackItem>
  <StackItem>3</StackItem>
</Stack>
</div>
</div>
</div>
```

### Different Spacing

다양한 간격을 적용할 수 있습니다.

```tsx
<div style={{
  display: 'flex',
  flexDirection: 'column',
  gap: '3rem'
}}>
<div>
  <Typography level="title-sm" sx={{
    mb: 1
  }}>
  간격 없음 (spacing=0)
</Typography>
<Stack direction="row" spacing={0}>
  <StackItem>Item 1</StackItem>
  <StackItem>Item 2</StackItem>
  <StackItem>Item 3</StackItem>
</Stack>
</div>

<div>
  <Typography level="title-sm" sx={{
    mb: 1
  }}>
  작은 간격 (spacing=1)
</Typography>
<Stack direction="row" spacing={1}>
  <StackItem>Item 1</StackItem>
  <StackItem>Item 2</StackItem>
  <StackItem>Item 3</StackItem>
</Stack>
</div>

<div>
  <Typography level="title-sm" sx={{
    mb: 1
  }}>
  중간 간격 (spacing=2)
</Typography>
<Stack direction="row" spacing={2}>
  <StackItem>Item 1</StackItem>
  <StackItem>Item 2</StackItem>
  <StackItem>Item 3</StackItem>
</Stack>
</div>

<div>
  <Typography level="title-sm" sx={{
    mb: 1
  }}>
  큰 간격 (spacing=4)
</Typography>
<Stack direction="row" spacing={4}>
  <StackItem>Item 1</StackItem>
  <StackItem>Item 2</StackItem>
  <StackItem>Item 3</StackItem>
</Stack>
</div>
</div>
```

### Alignment

요소들의 정렬을 다양하게 조절할 수 있습니다.

```tsx
<div style={{
  display: 'flex',
  flexDirection: 'column',
  gap: '3rem'
}}>
<div>
  <Typography level="title-sm" sx={{
    mb: 1
  }}>
  Center Alignment
</Typography>
<Stack direction="row" spacing={2} alignItems="center" justifyContent="center" sx={{
  minHeight: 120,
  bgcolor: 'neutral.50',
  borderRadius: 'md',
  p: 2
}}>
<StackItem sx={{
  height: 40
}}>짧은 아이템</StackItem>
<StackItem sx={{
  height: 80
}}>중간 아이템</StackItem>
<StackItem sx={{
  height: 60
}}>다른 아이템</StackItem>
</Stack>
</div>

<div>
  <Typography level="title-sm" sx={{
    mb: 1
  }}>
  Space Between
</Typography>
<Stack direction="row" spacing={0} justifyContent="space-between" sx={{
  bgcolor: 'neutral.50',
  borderRadius: 'md',
  p: 2
}}>
<StackItem>왼쪽</StackItem>
<StackItem>가운데</StackItem>
<StackItem>오른쪽</StackItem>
</Stack>
</div>

<div>
  <Typography level="title-sm" sx={{
    mb: 1
  }}>
  Flex End
</Typography>
<Stack direction="row" spacing={2} justifyContent="flex-end" sx={{
  bgcolor: 'neutral.50',
  borderRadius: 'md',
  p: 2
}}>
<StackItem>Item 1</StackItem>
<StackItem>Item 2</StackItem>
</Stack>
</div>
</div>
```

### Responsive Direction

화면 크기에 따라 배치 방향을 변경할 수 있습니다.

```tsx
<div>
  <Typography level="title-md" sx={{
    mb: 2
  }}>
  반응형 방향 (화면 크기에 따라 세로↔가로 전환)
</Typography>
<Stack direction={{
  xs: 'column',
  sm: 'row'
}} spacing={2} sx={{
  p: 2,
  bgcolor: 'background.level1',
  borderRadius: 'md'
}}>
<Box sx={{
  flex: 1,
  p: 2,
  bgcolor: 'primary.100',
  borderRadius: 'sm'
}}>
<Typography level="body-sm">
  작은 화면: 세로 배치
  <br />큰 화면: 가로 배치
  </Typography>
</Box>
<Box sx={{
  flex: 1,
  p: 2,
  bgcolor: 'success.100',
  borderRadius: 'sm'
}}>
<Typography level="body-sm">
  반응형 레이아웃으로
  <br />
  자동 조정됩니다
</Typography>
</Box>
<Box sx={{
  flex: 1,
  p: 2,
  bgcolor: 'warning.100',
  borderRadius: 'sm'
}}>
<Typography level="body-sm">
  브라우저 크기를
  <br />
  조절해보세요
</Typography>
</Box>
</Stack>
</div>
```

### Nested Stacks

Stack을 중첩하여 더 복잡한 레이아웃을 만들 수 있습니다.

```tsx
<div>
  <Typography level="title-md" sx={{
    mb: 2
  }}>
  중첩된 스택
</Typography>
<Stack spacing={3}>
  <Box sx={{
    p: 2,
    bgcolor: 'primary.50',
    borderRadius: 'md'
  }}>
  <Typography level="title-sm" sx={{
    mb: 2
  }}>
  세로 스택 안의 가로 스택
</Typography>
<Stack direction="row" spacing={2}>
  <StackItem sx={{
    bgcolor: 'primary.200'
  }}>Item 1</StackItem>
  <StackItem sx={{
    bgcolor: 'primary.200'
  }}>Item 2</StackItem>
  <StackItem sx={{
    bgcolor: 'primary.200'
  }}>Item 3</StackItem>
</Stack>
</Box>

<Box sx={{
  p: 2,
  bgcolor: 'success.50',
  borderRadius: 'md'
}}>
<Typography level="title-sm" sx={{
  mb: 2
}}>
또 다른 가로 스택
</Typography>
<Stack direction="row" spacing={2} justifyContent="center">
  <StackItem sx={{
    bgcolor: 'success.200'
  }}>중앙</StackItem>
  <StackItem sx={{
    bgcolor: 'success.200'
  }}>정렬</StackItem>
</Stack>
</Box>
</Stack>
</div>
```

### Real World Examples

실제 사용 사례를 보여주는 예제들입니다.

```tsx
<div style={{
  display: 'flex',
  flexDirection: 'column',
  gap: '3rem',
  maxWidth: 600
}}>
{/* Navigation Bar */}
<div>
  <Typography level="title-sm" sx={{
    mb: 2
  }}>
  내비게이션 바
</Typography>
<Stack direction="row" spacing={0} justifyContent="space-between" alignItems="center" sx={{
  p: 2,
  bgcolor: 'background.body',
  border: '1px solid',
  borderColor: 'divider',
  borderRadius: 'md'
}}>
<Typography level="title-md">로고</Typography>
<Stack direction="row" spacing={2}>
  <Button variant="plain" size="sm">
    홈
  </Button>
  <Button variant="plain" size="sm">
    소개
  </Button>
  <Button variant="plain" size="sm">
    연락처
  </Button>
</Stack>
<Button size="sm">로그인</Button>
</Stack>
</div>

{/* Profile Card */}
<div>
  <Typography level="title-sm" sx={{
    mb: 2
  }}>
  프로필 카드
</Typography>
<Box sx={{
  p: 3,
  bgcolor: 'background.body',
  border: '1px solid',
  borderColor: 'divider',
  borderRadius: 'lg'
}}>
<Stack spacing={2}>
  <Stack direction="row" spacing={2} alignItems="center">
    <Avatar size="lg" />
    <Stack spacing={0.5}>
      <Typography level="title-md">홍길동</Typography>
      <Typography level="body-sm" sx={{
        color: 'text.secondary'
      }}>
      프론트엔드 개발자
    </Typography>
  </Stack>
</Stack>

<Typography level="body-md">
  사용자 경험을 중시하는 프론트엔드 개발자입니다. React와 TypeScript를 주로 사용합니다.
</Typography>

<Stack direction="row" spacing={1}>
  <Chip size="sm" variant="soft">
    React
  </Chip>
  <Chip size="sm" variant="soft">
    TypeScript
  </Chip>
  <Chip size="sm" variant="soft">
    Next.js
  </Chip>
</Stack>

<Stack direction="row" spacing={1} justifyContent="flex-end">
  <Button size="sm" variant="outlined" startDecorator={<BookmarkIcon />}>
    저장
  </Button>
  <Button size="sm" variant="outlined" startDecorator={<ShareIcon />}>
    공유
  </Button>
</Stack>
</Stack>
</Box>
</div>

{/* Article Card */}
<div>
  <Typography level="title-sm" sx={{
    mb: 2
  }}>
  아티클 카드
</Typography>
<Box sx={{
  p: 3,
  bgcolor: 'background.body',
  border: '1px solid',
  borderColor: 'divider',
  borderRadius: 'lg'
}}>
<Stack spacing={2}>
  <Stack direction="row" justifyContent="space-between" alignItems="flex-start">
    <Stack spacing={1}>
      <Typography level="title-lg">React 18의 새로운 기능들</Typography>
      <Typography level="body-sm" sx={{
        color: 'text.secondary'
      }}>
      2024년 1월 15일 • 5분 읽기
    </Typography>
  </Stack>
  <Button variant="plain" size="sm" sx={{
    color: 'warning.500'
  }}>
  <StarIcon />
</Button>
</Stack>

<Typography level="body-md">
  React 18에서 도입된 Concurrent Features와 새로운 Hooks에 대해 자세히 알아보겠습니다. Suspense,
  useTransition, useDeferredValue 등...
</Typography>

<Stack direction="row" spacing={1}>
  <Chip size="sm" variant="outlined">
    React
  </Chip>
  <Chip size="sm" variant="outlined">
    JavaScript
  </Chip>
  <Chip size="sm" variant="outlined">
    개발
  </Chip>
</Stack>

<Stack direction="row" justifyContent="space-between" alignItems="center">
  <Stack direction="row" spacing={1} alignItems="center">
    <Avatar size="sm" />
    <Typography level="body-sm">김개발</Typography>
  </Stack>
  <Stack direction="row" spacing={1}>
    <Button size="sm" variant="plain">
      좋아요 24
    </Button>
    <Button size="sm" variant="plain">
      댓글 5
    </Button>
  </Stack>
</Stack>
</Stack>
</Box>
</div>

{/* Form Layout */}
<div>
  <Typography level="title-sm" sx={{
    mb: 2
  }}>
  폼 레이아웃
</Typography>
<Box sx={{
  p: 3,
  bgcolor: 'background.body',
  border: '1px solid',
  borderColor: 'divider',
  borderRadius: 'lg'
}}>
<Stack spacing={3}>
  <Typography level="title-md">문의하기</Typography>

  <Stack spacing={2}>
    <Stack spacing={1}>
      <Typography level="body-sm" fontWeight="500">
        이름
      </Typography>
      <Box sx={{
        p: 1.5,
        bgcolor: 'background.level1',
        borderRadius: 'sm'
      }}>
      <Typography level="body-sm" sx={{
        color: 'text.secondary'
      }}>
      이름을 입력하세요
    </Typography>
  </Box>
</Stack>

<Stack spacing={1}>
  <Typography level="body-sm" fontWeight="500">
    이메일
  </Typography>
  <Box sx={{
    p: 1.5,
    bgcolor: 'background.level1',
    borderRadius: 'sm'
  }}>
  <Typography level="body-sm" sx={{
    color: 'text.secondary'
  }}>
  이메일을 입력하세요
</Typography>
</Box>
</Stack>

<Stack spacing={1}>
  <Typography level="body-sm" fontWeight="500">
    메시지
  </Typography>
  <Box sx={{
    p: 1.5,
    minHeight: 80,
    bgcolor: 'background.level1',
    borderRadius: 'sm'
  }}>
  <Typography level="body-sm" sx={{
    color: 'text.secondary'
  }}>
  메시지를 입력하세요
</Typography>
</Box>
</Stack>
</Stack>

<Stack direction="row" spacing={2} justifyContent="flex-end">
  <Button variant="outlined">취소</Button>
  <Button>전송</Button>
</Stack>
</Stack>
</Box>
</div>
</div>
```

## Key Props

### direction

요소들의 배치 방향을 설정합니다.

```tsx
<Stack direction="row">가로 배치</Stack>
<Stack direction="column">세로 배치</Stack>
<Stack direction="row-reverse">가로 역순</Stack>
<Stack direction="column-reverse">세로 역순</Stack>

// 반응형 방향
<Stack direction={{ xs: 'column', sm: 'row' }}>
  반응형 배치
</Stack>
```

### spacing

요소들 간의 간격을 설정합니다.

| 값     | 크기   | 설명          |
| ----- | ---- | ----------- |
| `0`   | 0px  | 간격 없음       |
| `0.5` | 4px  | 아주 작은 간격    |
| `1`   | 8px  | 작은 간격       |
| `1.5` | 12px | 작은-중간 간격    |
| `2`   | 16px | 중간 간격 (기본값) |
| `3`   | 24px | 큰 간격        |
| `4`   | 32px | 아주 큰 간격     |
| `5`   | 40px | 매우 큰 간격     |
| `6`   | 48px | 최대 간격       |

```tsx
<Stack spacing={2}>기본 간격</Stack>
<Stack spacing={0}>간격 없음</Stack>
<Stack spacing={4}>큰 간격</Stack>

// 반응형 간격
<Stack spacing={{ xs: 1, sm: 2, md: 3 }}>
  반응형 간격
</Stack>
```

### alignItems

교차축(cross axis) 정렬을 설정합니다.

```tsx
<Stack alignItems="center">중앙 정렬</Stack>
<Stack alignItems="flex-start">시작점 정렬</Stack>
<Stack alignItems="flex-end">끝점 정렬</Stack>
<Stack alignItems="stretch">늘이기</Stack>
<Stack alignItems="baseline">베이스라인 정렬</Stack>
```

### justifyContent

주축(main axis) 정렬을 설정합니다.

```tsx
<Stack justifyContent="center">중앙 정렬</Stack>
<Stack justifyContent="space-between">양끝 정렬</Stack>
<Stack justifyContent="space-around">균등 분할</Stack>
<Stack justifyContent="space-evenly">균등 간격</Stack>
<Stack justifyContent="flex-end">끝점 정렬</Stack>
```

## Responsive Behavior

Stack은 모든 props에서 반응형 값을 지원합니다:

```tsx
<Stack
  direction={{ xs: 'column', md: 'row' }}
  spacing={{ xs: 1, sm: 2, md: 3 }}
  alignItems={{ xs: 'stretch', md: 'center' }}
>
  {/* 화면 크기별로 다른 레이아웃 */}
</Stack>
```

## Common Use Cases

### Navigation Bar

```tsx
<Stack direction="row" justifyContent="space-between" alignItems="center" sx={{ p: 2 }}>
  <Typography level="title-lg">Logo</Typography>
  <Stack direction="row" spacing={2}>
    <Button variant="plain">Home</Button>
    <Button variant="plain">About</Button>
    <Button variant="plain">Contact</Button>
  </Stack>
  <Button>Login</Button>
</Stack>
```

### Form Layout

```tsx
<Stack spacing={3}>
  <Typography level="title-lg">Contact Form</Typography>

  <Stack spacing={2}>
    <FormControl>
      <FormLabel>Name</FormLabel>
      <Input placeholder="Enter your name" />
    </FormControl>

    <FormControl>
      <FormLabel>Email</FormLabel>
      <Input type="email" placeholder="Enter your email" />
    </FormControl>

    <FormControl>
      <FormLabel>Message</FormLabel>
      <Textarea placeholder="Enter your message" minRows={3} />
    </FormControl>
  </Stack>

  <Stack direction="row" spacing={2} justifyContent="flex-end">
    <Button variant="outlined">Cancel</Button>
    <Button>Send</Button>
  </Stack>
</Stack>
```

### Card Content

```tsx
<Card sx={{ maxWidth: 400 }}>
  <CardContent>
    <Stack spacing={2}>
      <Stack direction="row" justifyContent="space-between" alignItems="center">
        <Typography level="title-lg">Product Name</Typography>
        <Chip variant="soft">New</Chip>
      </Stack>

      <Typography level="body-md">Product description goes here...</Typography>

      <Stack direction="row" spacing={1}>
        <Chip size="sm" variant="outlined">
          Tag 1
        </Chip>
        <Chip size="sm" variant="outlined">
          Tag 2
        </Chip>
      </Stack>

      <Stack direction="row" justifyContent="space-between" alignItems="center">
        <Typography level="title-lg" color="primary">
          $99.99
        </Typography>
        <Button>Add to Cart</Button>
      </Stack>
    </Stack>
  </CardContent>
</Card>
```

### User Profile

```tsx
<Stack spacing={3}>
  <Stack direction="row" spacing={2} alignItems="center">
    <Avatar size="lg" src="/avatar.jpg" />
    <Stack>
      <Typography level="title-lg">John Doe</Typography>
      <Typography level="body-sm" color="neutral">
        Frontend Developer
      </Typography>
    </Stack>
  </Stack>

  <Typography level="body-md">Passionate about creating great user experiences...</Typography>

  <Stack direction="row" spacing={1}>
    <Chip variant="soft">React</Chip>
    <Chip variant="soft">TypeScript</Chip>
    <Chip variant="soft">Next.js</Chip>
  </Stack>

  <Stack direction="row" spacing={2}>
    <Button variant="outlined" fullWidth>
      Follow
    </Button>
    <Button fullWidth>Message</Button>
  </Stack>
</Stack>
```

### List Layout

```tsx
<Stack spacing={2}>
  {items.map((item) => (
    <Stack
      key={item.id}
      direction="row"
      spacing={2}
      alignItems="center"
      sx={{
        p: 2,
        bgcolor: 'background.level1',
        borderRadius: 'md',
      }}
    >
      <Avatar src={item.avatar} />
      <Stack sx={{ flex: 1 }}>
        <Typography level="title-sm">{item.name}</Typography>
        <Typography level="body-xs" color="neutral">
          {item.description}
        </Typography>
      </Stack>
      <Typography level="body-xs" color="neutral">
        {item.time}
      </Typography>
    </Stack>
  ))}
</Stack>
```

### Button Group

```tsx
<Stack direction="row" spacing={1}>
  <Button variant="outlined">Cancel</Button>
  <Button variant="outlined">Save Draft</Button>
  <Button>Publish</Button>
</Stack>

<Stack direction="row" spacing={0} sx={{ border: '1px solid', borderColor: 'divider', borderRadius: 'sm' }}>
  <Button variant="plain" sx={{ borderRadius: 0, borderRight: '1px solid', borderColor: 'divider' }}>
    Bold
  </Button>
  <Button variant="plain" sx={{ borderRadius: 0, borderRight: '1px solid', borderColor: 'divider' }}>
    Italic
  </Button>
  <Button variant="plain" sx={{ borderRadius: 0 }}>
    Underline
  </Button>
</Stack>
```

## Best Practices

1. **적절한 간격**: 콘텐츠의 계층구조에 맞는 적절한 spacing을 선택하세요.

2. **반응형 고려**: 다양한 화면 크기에서 잘 작동하도록 반응형 props를 활용하세요.

3. **의미있는 정렬**: alignItems와 justifyContent를 사용해 의미있는 정렬을 적용하세요.

4. **중첩 최소화**: 과도한 중첩은 피하고, 필요한 경우에만 Stack을 중첩하세요.

5. **성능 고려**: 많은 아이템이 있는 경우 가상화를 고려하세요.

6. **접근성**:
   - 논리적인 탭 순서가 되도록 요소를 배치하세요
   - 적절한 시맨틱 태그와 함께 사용하세요

7. **일관성**: 프로젝트 전반에서 일관된 spacing 값을 사용하세요.

## When to Use Stack vs Other Layout Components

### Stack vs Flexbox (Box)

- **Stack**: 단순한 1차원 레이아웃, 일정한 간격이 필요한 경우
- **Box with flex**: 복잡한 flexbox 속성이 필요한 경우

### Stack vs Grid

- **Stack**: 1차원 레이아웃 (세로 또는 가로)
- **Grid**: 2차원 레이아웃 (행과 열)

### Stack vs Space (if available)

- **Stack**: 컨테이너와 간격을 함께 제공
- **Space**: 간격만 제공 (자식들 사이에)

## Troubleshooting

### 흔한 문제들

1. **간격이 적용되지 않음**
   - 자식 요소들이 직접적인 자식인지 확인하세요
   - Fragment나 다른 래퍼가 방해하지 않는지 확인하세요

2. **정렬이 예상과 다름**
   - direction에 따라 주축과 교차축이 바뀐다는 점을 기억하세요
   - alignItems와 justifyContent의 차이를 이해하세요

3. **반응형이 동작하지 않음**
   - 객체 문법 `{ xs: 'column', md: 'row' }`가 올바른지 확인하세요
   - 브레이크포인트 값이 올바른지 확인하세요

Stack은 직관적이고 강력한 레이아웃 도구입니다. 간단한 API로 복잡한 레이아웃을 쉽게 구현할 수 있어 많은 UI 패턴에서 활용됩니다.
