```
### 양쪽 정렬
```tsx
```
### 반응형 레이아웃
```tsx
카드 1카드 2카드 3
```
## Best Practices
✅ **올바른 사용법**
- 단순한 가로/세로 정렬에 사용
- 복잡한 flex 속성이 필요한 레이아웃에 사용
❌ **피해야 할 사용법**
- 단순한 수직 스택에는 `VStack` 사용 권장
- 단순한 수평 스택에는 `HStack` 사용 권장
---
file: float.md
# Float
절대 위치로 요소를 배치하는 컴포넌트입니다. 9가지 배치 옵션을 제공합니다.
## 개요
Float는 부모 요소 내에서 절대 위치(absolute)로 자식 요소를 배치하는 컴포넌트입니다. 9가지 사전 정의된 배치 옵션과 오프셋 조정 기능을 제공합니다.
## Import
```tsx
import { Float } from '@inpock/ids';
```
## 기본 사용법
```tsx
NEW
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `placement` | `FloatPlacement` | **필수** | 배치 위치 |
| `offsetX` | `number \| string` | `0` | X축 오프셋 |
| `offsetY` | `number \| string` | `0` | Y축 오프셋 |
### FloatPlacement 타입
```tsx
type FloatPlacement =
| 'top-start' // 좌상단
| 'top-center' // 상단 중앙
| 'top-end' // 우상단
| 'middle-start' // 좌측 중앙
| 'middle-center' // 정중앙
| 'middle-end' // 우측 중앙
| 'bottom-start' // 좌하단
| 'bottom-center' // 하단 중앙
| 'bottom-end'; // 우하단
```
## 배치 위치 시각화
```
┌─────────────────────────────┐
│ top-start top-center top-end │
│ │
│ middle-start middle-center middle-end │
│ │
│ bottom-start bottom-center bottom-end │
└─────────────────────────────┘
```
## 예시
### 배지 표시
```tsx
```
### 알림 뱃지
```tsx
3
```
### 이미지 오버레이
```tsx
SALE
```
### 로딩 오버레이
```tsx
{isLoading && (
)}
```
## Best Practices
✅ **올바른 사용법**
- 부모 요소에 `position: relative` 설정 필수
- 뱃지, 인디케이터 등 오버레이 요소에 사용
- offset으로 미세 조정
❌ **피해야 할 사용법**
- 복잡한 레이아웃에는 Flex/Grid 사용 권장
- 반응형 위치 변경이 필요한 경우 주의
---
file: icon-button.md
# IconButton
아이콘만 표시하는 버튼 컴포넌트입니다. 접근성을 위해 aria-label이 필수입니다.
## 개요
IconButton은 텍스트 없이 아이콘만 표시하는 버튼 컴포넌트입니다. 접근성을 위해 `aria-label` prop이 필수입니다. `default`와 `ghost` 두 가지 variant와 세 가지 사이즈를 제공합니다.
## Import
```tsx
import { IconButton } from '@inpock/ids';
```
## 기본 사용법
```tsx
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `children` | `React.ReactNode` | **필수** | 버튼 내부 아이콘 |
| `aria-label` | `string` | **필수** | 접근성을 위한 레이블 |
| `size` | `'small' \| 'medium' \| 'large'` | `'medium'` | 버튼 사이즈 |
| `variant` | `'default' \| 'ghost'` | `'default'` | 버튼 스타일 |
| `disabled` | `boolean` | `false` | 비활성화 상태 |
| `onClick` | `() => void` | - | 클릭 핸들러 |
## 예시
### Variant
```tsx
// Default
// Ghost
```
### Size
```tsx
```
### 툴바에서 사용
```tsx
```
### 비활성화 상태
```tsx
```
### Float과 함께 사용
```tsx
카드 콘텐츠
```
## 접근성
- `aria-label`은 **필수**입니다. 스크린 리더 사용자를 위해 버튼의 기능을 설명합니다.
- 키보드 포커스와 네비게이션을 지원합니다.
- disabled 상태에서는 포커스되지 않습니다.
```tsx
// ✅ 좋은 예
// ❌ 나쁜 예 (aria-label 누락)
```
## 스타일링
IconButton은 CVA(class-variance-authority)를 사용하며, BEM 네이밍을 따릅니다.
```scss
.ids-icon-button { }
.ids-icon-button--small { }
.ids-icon-button--medium { }
.ids-icon-button--large { }
.ids-icon-button--default { }
.ids-icon-button--ghost { }
```
## Best Practices
✅ **올바른 사용법**
- 명확한 aria-label 제공
- 아이콘 크기를 버튼 사이즈에 맞게 조정
- 액션을 명확히 전달하는 아이콘 사용
❌ **피해야 할 사용법**
- aria-label 없이 사용하지 않기
- 텍스트가 필요한 경우 일반 Button 사용
- 너무 복잡한 아이콘 사용 지양
---
file: page-header.md
# PageHeader
페이지의 제목과 설명을 표시하는 시맨틱 헤더 컴포넌트입니다.
## 개요
PageHeader는 페이지의 제목과 설명을 일관된 스타일로 표시하는 컴포넌트입니다. `small`과 `large` 두 가지 사이즈를 제공합니다.
## Import
```tsx
import { PageHeader } from '@inpock/ids';
```
## 기본 사용법
```tsx
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `title` | `string \| React.ReactNode` | - | 페이지 제목 |
| `description` | `string \| React.ReactNode` | - | 페이지 설명 |
| `size` | `'small' \| 'large'` | `'large'` | 헤더 사이즈 |
| `className` | `string` | - | 추가 CSS 클래스 |
## 예시
### Large 사이즈 (기본)
```tsx
```
### Small 사이즈
```tsx
```
### 커스텀 타이틀
```tsx
대시보드
}
description="실시간 데이터를 모니터링합니다."
/>
```
### 페이지 레이아웃과 함께 사용
```tsx
```
## 스타일링
PageHeader는 내부적으로 VStack을 사용하며, BEM 네이밍 규칙을 따릅니다.
```scss
.ids-page-header { }
.ids-page-header--small { }
.ids-page-header--large { }
.ids-page-header__title { }
.ids-page-header__description { }
```
## Best Practices
✅ **올바른 사용법**
- 페이지 최상단에 배치
- 간결하고 명확한 제목 사용
- 설명은 1-2문장으로 제한
❌ **피해야 할 사용법**
- 섹션 제목으로는 일반 heading 태그 사용 권장
- 너무 긴 설명 텍스트 지양
---
file: page-layout.md
# PageLayout
사이드바와 헤더를 포함한 전체 페이지 레이아웃 컴포넌트입니다.
## 개요
PageLayout은 사이드바, 헤더, 메인 콘텐츠 영역을 포함한 전체 페이지 레이아웃을 제공하는 Compound 컴포넌트입니다. 반응형 사이드바, 헤더 포털 시스템, Safari 뷰포트 높이 수정 등의 기능을 내장하고 있습니다.
## Import
```tsx
import { PageLayout } from '@inpock/ids';
```
## 기본 사용법
```tsx
페이지 콘텐츠
```
## Compound Components
| Component | Description |
|-----------|-------------|
| `PageLayout` | 루트 컴포넌트 |
| `PageLayout.Header` | 헤더 영역 (포털 지원) |
## Props
### PageLayout
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `children` | `React.ReactNode` | **필수** | 페이지 콘텐츠 |
| `user` | `{ data: UserData; loading: boolean }` | **필수** | 사용자 정보 |
| `mainNavItems` | `NavItem[]` | `[]` | 메인 네비게이션 아이템 |
| `currentPath` | `string` | - | 현재 경로 (활성 메뉴 표시용) |
| `activeMenu` | `string` | - | 고정으로 활성화할 메뉴 key |
| `router` | `Router` | - | 라우터 핸들러 |
| `sidebarConfig` | `SidebarConfig` | - | 사이드바 설정 |
| `sidebarActions` | `SidebarActions` | - | 사이드바 액션 핸들러 |
| `createMenuSections` | `CreateMenuSection[]` | `[]` | 생성 메뉴 섹션 |
| `layoutConfig` | `LayoutConfig` | - | 레이아웃 설정 |
| `shouldShowSidebar` | `() => boolean` | - | 사이드바 표시 여부 |
### 타입 정의
```tsx
interface UserData {
username: string;
profile_image?: string;
plan?: 'basic' | 'pro' | 'manager';
}
interface NavItem {
key: string;
label: string;
path: string;
icon?: string;
nav?: 'push' | 'href' | 'open';
}
interface Router {
push?: (path: string) => void;
href?: (path: string) => void;
open?: (path: string) => void;
}
interface SidebarConfig {
logoPath?: string;
settingsPath?: string;
inviteFriendsPath?: string;
membershipPlanPath?: string;
renderInviteFriends?: () => ReactNode;
}
interface SidebarActions {
onLogoutClick?: () => void;
onCreateMenuItemClick?: (item: CreateMenuItem) => void;
}
interface LayoutConfig {
sidebar?: 'visible' | 'hidden';
contentWidth?: 'default' | 'full';
}
```
## 예시
### Next.js App Router와 함께 사용
```tsx
'use client';
import { usePathname, useRouter } from 'next/navigation';
import { PageLayout } from '@inpock/ids';
export default function DashboardLayout({ children }) {
const pathname = usePathname();
const router = useRouter();
return (
(window.location.href = path),
open: (path) => window.open(path, '_blank'),
}}
mainNavItems={[
{ key: 'home', label: '홈', path: '/', icon: 'home' },
{ key: 'dashboard', label: '대시보드', path: '/dashboard', icon: 'chart' },
{ key: 'settings', label: '설정', path: '/settings', icon: 'settings' },
]}
>
{children}
);
}
```
### 사이드바 숨기기
```tsx
```
### 전체 너비 콘텐츠
```tsx
```
## Hooks
### usePageLayout
PageLayout 내부에서 레이아웃 상태에 접근할 수 있는 훅입니다.
```tsx
import { usePageLayout } from '@inpock/ids';
function MyComponent() {
const {
layoutConfig,
shouldShowSidebar,
user,
currentPath,
headerBehavior,
setHeaderBehavior,
} = usePageLayout();
return
...
;
}
```
## Best Practices
✅ **올바른 사용법**
- 앱의 최상위 레이아웃으로 사용
- Next.js의 layout.tsx에서 사용
- 라우터 핸들러를 제공하여 SPA 네비게이션 지원
❌ **피해야 할 사용법**
- 중첩 PageLayout 사용 금지
- PageLayout 외부에서 usePageLayout 호출 금지
---
file: stack.md
# Stack (VStack, HStack)
수직(VStack) 또는 수평(HStack) 방향으로 요소를 정렬하는 컴포넌트입니다.
## 개요
Stack은 요소들을 일정한 간격으로 수직 또는 수평 정렬하는 컴포넌트입니다. Flex 컴포넌트를 기반으로 하며, `VStack`(수직)과 `HStack`(수평) 두 가지 변형을 제공합니다.
## Import
```tsx
import { VStack, HStack } from '@inpock/ids';
```
## 기본 사용법
### VStack (수직 스택)
```tsx
항목 1
항목 2
항목 3
```
### HStack (수평 스택)
```tsx
```
## Props
VStack과 HStack은 Flex의 모든 props를 상속받습니다. 단, `direction` prop은 각각 고정되어 있습니다.
| Component | Fixed Direction |
|-----------|-----------------|
| `VStack` | `column` |
| `HStack` | `row` |
### 공통 Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `gap` | `CSSProperties['gap']` | - | 아이템 간 간격 |
| `align` | `CSSProperties['alignItems']` | - | 교차 축 정렬 |
| `justify` | `CSSProperties['justifyContent']` | - | 주 축 정렬 |
## 예시
### 폼 레이아웃
```tsx
```
### 카드 레이아웃
```tsx
카드 제목
카드 설명 텍스트입니다.
태그1태그2
```
### 네비게이션 바
```tsx
홈소개문의
```
## Best Practices
✅ **올바른 사용법**
- 일관된 간격의 리스트 레이아웃에 사용
- 폼 필드 그룹핑에 사용
- 버튼 그룹에 사용
❌ **피해야 할 사용법**
- 복잡한 flex 속성이 필요하면 `Flex` 컴포넌트 사용
- Grid 레이아웃이 필요하면 `Box`의 grid 속성 사용