npm package: @jk-core/components
Description: components for jk
Author: KimKyungYun
Latest version: 1.2.2

# @jk-core/components

jk-core 프로젝트를 위한 React 커스텀 컴포넌트 모음입니다.

<br/>

## 설치
```bash
npm install @jk-core/components
yarn add @jk-core/components
```

<br/>
<br/>


## Calendar

Calendar 컴포넌트는 날짜 선택 기능을 제공하는 사용자 정의 React 컴포넌트입니다. 일, 월, 년 단위로 날짜를 선택할 수 있으며, 다양한 커스터마이징 옵션을 제공합니다.

<br/>

## 특징

- 일/월/년 단위의 날짜 선택
- 커스텀 스타일링 지원
- 최소/최대 날짜 설정 기능
- 타일 내용 커스터마이징 가능
- 반응형 디자인

<br/>

## 사용법
```typescript
import { Calendar, CalendarView } from '@jk-core/components';
import { useState } from 'react';
function App() {
const [view, setView] = useState<CalendarView>('month');
const [date, setDate] = useState<Date>(new Date());
return (
<Calendar
date={date}
view={view}
setView={setView}
onChange={setDate}
/>
);
}
```

<br/>

## Props

| Prop | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| className | string | '' | 추가적인 CSS 클래스 |
| date | Date | undefined | 선택된 날짜 |
| view | CalendarView | 'day' | 현재 보기 모드 ('day', 'month', 'year') |
| setView | (view: CalendarView) => void | () => {} | 보기 모드 변경 함수 |
| tileContent | (date: Date \| undefined, view: CalendarView) => React.ReactNode | undefined | 타일 내용 커스터마이징 함수 |
| onChange | (date: Date) => void | () => {} | 날짜 선택 시 호출되는 함수 |
| min | Date | new Date(2000, 0, 1) | 선택 가능한 최소 날짜 |
| max | Date | new Date(2099, 11, 31) | 선택 가능한 최대 날짜 |
| onClose | () => void | undefined | 닫기 버튼 클릭 시 호출되는 함수 |
| viewSelector | boolean | true | 보기 모드 선택기 표시 여부 |

<br/>

## 스타일링

Calendar 컴포넌트는 CSS 모듈을 사용하여 스타일링되어 있습니다. 커스텀 스타일을 적용하려면 `className` prop을 사용하거나 컴포넌트의 CSS 모듈 파일을 직접 수정하세요.

<br/>
<br/>

---

## Accordion

클릭 시 내용이 펼쳐지거나 접히는 아코디언 UI 컴포넌트입니다.

<br/>

### Props

| Prop | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| children | React.ReactNode | - | 아코디언 본문에 표시할 내용 |

<br/>

### 사용법

```tsx
import { Accordion } from '@jk-core/components';

<Accordion>
  <p>펼쳐지는 내용입니다.</p>
</Accordion>
```

<br/>
<br/>

---

## Breadcrumbs

여러 개의 `BreadcrumbsItem`을 자식으로 받아 경로(브레드크럼)를 표시합니다. 각 항목 클릭 시 해당 경로로 이동합니다.

<br/>

### Breadcrumbs Props

| Prop | 타입 | 설명 |
|------|------|------|
| children | React.ReactNode | `BreadcrumbsItem` 컴포넌트들 |

### BreadcrumbsItem Props

| Prop | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| children | React.ReactNode | - | 표시할 텍스트 |
| path | string | - | 클릭 시 이동할 경로 |
| root | boolean | false | true일 때 홈 아이콘 표시 |

<br/>

### 사용법

```tsx
import { Breadcrumbs, BreadcrumbsItem } from '@jk-core/components';

<Breadcrumbs>
  <BreadcrumbsItem path="/" root>홈</BreadcrumbsItem>
  <BreadcrumbsItem path="/products">상품</BreadcrumbsItem>
  <BreadcrumbsItem path="/products/123">상품 상세</BreadcrumbsItem>
</Breadcrumbs>
```

<br/>
<br/>

---

## Button

등급(primary, secondary, tertiary, cancel)과 로딩·비활성화 상태를 지원하는 공용 버튼 컴포넌트입니다.

<br/>

### Props

| Prop | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| children | ReactNode | - | 버튼 내용 |
| grade | 'tertiary' \| 'secondary' \| 'primary' \| 'cancel' | 'primary' | 버튼 스타일 등급 |
| disabled | boolean | false | 비활성화 여부 |
| className | string | '' | 추가 CSS 클래스 |
| isLoading | boolean | false | 로딩 중일 때 내부 스피너 표시 |
| onClick | (e: React.MouseEvent<HTMLButtonElement>) => void | - | 클릭 핸들러 |

`React.ButtonHTMLAttributes<HTMLButtonElement>` 의 나머지 속성도 사용할 수 있습니다.

<br/>

### 사용법

```tsx
import { Button } from '@jk-core/components';

<Button grade="primary" onClick={() => {}}>저장</Button>
<Button grade="secondary" disabled>비활성</Button>
<Button isLoading>처리 중...</Button>
```

<br/>
<br/>

---

## Card

제목과 본문 영역을 가진 카드 컨테이너 컴포넌트입니다.

<br/>

### Props

| Prop | 타입 | 설명 |
|------|------|------|
| title | string \| React.ReactNode | 카드 제목 |
| children | React.ReactNode | 카드 본문 (선택) |

<br/>

### 사용법

```tsx
import { Card } from '@jk-core/components';

<Card title="카드 제목">
  <p>카드 본문 내용입니다.</p>
</Card>
```

<br/>
<br/>

---

## Carousel

슬라이드 형태로 콘텐츠를 보여주는 캐러셀 컴포넌트입니다. 무한 루프, 드래그/스와이프, 자동 재생, 키보드·터치 지원을 제공합니다.

<br/>

### Props

| Prop | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| children | ReactNode[] | - | 슬라이드로 표시할 요소 배열 |
| autoPlay | boolean | false | 자동 재생 여부 |
| autoPlayInterval | number | 3000 | 자동 재생 간격(ms) |
| showIndicators | boolean | true | 인디케이터(점) 표시 여부 |
| showNavigation | boolean | true | 이전/다음 버튼 표시 여부 |
| className | string | '' | 추가 CSS 클래스 |

<br/>

### 사용법

```tsx
import { Carousel } from '@jk-core/components';

<Carousel autoPlay autoPlayInterval={5000} showIndicators showNavigation>
  <div>슬라이드 1</div>
  <div>슬라이드 2</div>
  <div>슬라이드 3</div>
</Carousel>
```

<br/>
<br/>

---

## DropDown

선택 가능한 목록을 제공하는 드롭다운 컴포넌트입니다. 선택 시 버튼에 선택된 값이 표시되며, 필터(검색) 기능을 옵션으로 사용할 수 있습니다.

<br/>

### Props

| Prop | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| list | string[] | - | 선택 가능한 목록 |
| value | string | - | 버튼에 표시할 값(제어용) |
| onSelect | (item: string, index: number) => void | - | 항목 선택 시 호출되는 함수 |
| filter | boolean | - | 필터(검색) 활성화 여부 |
| placeholder | string | '선택하세요' | 플레이스홀더 텍스트 |
| style | React.CSSProperties | - | 버튼 영역 인라인 스타일 |

<br/>

### 사용법

```tsx
import { DropDown } from '@jk-core/components';

const options = ['옵션1', '옵션2', '옵션3'];

<DropDown
  list={options}
  placeholder="선택하세요"
  filter
  onSelect={(item, index) => console.log(item, index)}
/>
```

<br/>
<br/>

---

## Pagination

총 페이지 수와 현재 페이지를 기준으로 페이지 번호를 표시하고, 클릭 시 해당 페이지로 이동할 수 있는 페이지네이션 컴포넌트입니다.

<br/>

### Props

| Prop | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| totalPage | number | - | 총 페이지 수 |
| currentPage | number | - | 현재 페이지 |
| onPageClick | (page: number) => void | - | 페이지 클릭 핸들러 |
| large | boolean | false | true일 때 표시되는 페이지 개수 확대(5 → 7) |

<br/>

### 사용법

```tsx
import { Pagination } from '@jk-core/components';

const [page, setPage] = useState(1);

<Pagination
  totalPage={20}
  currentPage={page}
  onPageClick={setPage}
  large={false}
/>
```

<br/>
<br/>

---

## RollingBanner

자식 요소를 가로 또는 세로로 무한 스크롤하는 롤링 배너(마키) 컴포넌트입니다. 그라데이션 마스크와 속도·방향 설정을 지원합니다.

<br/>

### Props

| Prop | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| children | React.ReactNode \| React.ReactNode[] | - | 스크롤할 콘텐츠 |
| speed | number | 50 | 스크롤 속도(픽셀/초) |
| reverse | boolean | false | 역방향 재생 여부 |
| direction | 'row' \| 'column' | 'row' | 스크롤 방향 |
| gradient | boolean | true | 그라데이션 마스크 사용 여부 |
| gradientColor | string | 'white' | 그라데이션 색상 |
| gradientWidth | number \| string | 200 | 그라데이션 너비(px 또는 문자열) |

<br/>

### 사용법

```tsx
import { RollingBanner } from '@jk-core/components';

<RollingBanner speed={50} direction="row" gradient>
  <span>항목 1</span>
  <span>항목 2</span>
  <span>항목 3</span>
</RollingBanner>
```

<br/>
<br/>

---

## SegmentButton

여러 옵션 중 하나를 선택하는 세그먼트 형태의 버튼 그룹입니다. 선택된 항목이 시각적으로 강조됩니다.

<br/>

### Props

| Prop | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| option | Array<{ text: string; onClick: () => void }> | - | 각 옵션의 텍스트와 클릭 핸들러 |
| selected | number | 0 | 선택된 옵션 인덱스(제어용) |
| width | string | 'auto' | 버튼 그룹 너비 |
| stretch | boolean | false | true일 때 부모 너비 전체 사용 |

<br/>

### 사용법

```tsx
import { SegmentButton } from '@jk-core/components';

const options = [
  { text: '오늘', onClick: () => setDate(new Date()) },
  { text: '내일', onClick: () => setDate(addDays(new Date(), 1)) },
];

<SegmentButton option={options} selected={0} stretch />
```

<br/>
<br/>

---

## Skeleton

로딩 상태를 나타내는 스켈레톤 UI 컴포넌트입니다. 모양(circle, rectangle, round)과 애니메이션(glow, blink)을 선택할 수 있습니다.

<br/>

### Props

| Prop | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| shape | 'circle' \| 'rectangle' \| 'round' | 'rectangle' | 스켈레톤 모양 |
| width | string \| number | '100%' | 너비 |
| height | string \| number | '20px' | 높이 |
| animation | 'glow' \| 'blink' | 'glow' | 로딩 애니메이션 종류 |

<br/>

### 사용법

```tsx
import { Skeleton } from '@jk-core/components';

<Skeleton shape="rectangle" width="100%" height={20} />
<Skeleton shape="circle" width={40} height={40} />
<Skeleton shape="round" animation="blink" />
```

<br/>
<br/>

---

## SwitchButton

켜짐/꺼짐 상태를 전환하는 스위치 버튼 컴포넌트입니다.

<br/>

### Props

| Prop | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| checked | boolean | false | 스위치 켜짐 여부 |
| onChange | (value: boolean) => void | () => {} | 상태 변경 시 호출되는 함수 |

<br/>

### 사용법

```tsx
import { SwitchButton } from '@jk-core/components';

const [on, setOn] = useState(false);

<SwitchButton checked={on} onChange={setOn} />
```

<br/>
<br/>

---

## Table

헤더와 바디 설정으로 테이블을 렌더링하는 컴포넌트입니다. 서브 헤더(2단 헤더), 행별 헤더, 정렬 표시, 둥근 모서리·테두리 옵션을 지원합니다.

<br/>

### Props

| Prop | 타입 | 설명 |
|------|------|------|
| header | TableHeaderType[] | 테이블 헤더 설정 |
| body | TableBodyType[] | 테이블 바디(행) 설정 |
| rounded | boolean | 모서리 둥글게 처리 여부 |
| border | boolean | 테두리 표시 여부 |

**TableHeaderType**

- `label`: { text: string \| number; align?: 'left' \| 'center' \| 'right' }
- `width`: 열 너비 (선택)
- `subWidth`: 서브 헤더 열 너비 배열 (선택)
- `subLabel`: 서브 헤더 라벨 배열 (선택)

**TableBodyType**

- `head`: 행 헤더(첫 번째 열) (선택)
- `labels`: 셀 배열, 각 셀은 { text: string \| number; align?: 'left' \| 'center' \| 'right' }

<br/>

### 사용법

```tsx
import { Table } from '@jk-core/components';

const header = [
  { label: { text: '이름', align: 'left' }, width: '100px' },
  { label: { text: '점수', align: 'center' } },
];
const body = [
  { labels: [{ text: '홍길동' }, { text: '90', align: 'center' }] },
  { labels: [{ text: '김철수' }, { text: '85', align: 'center' }] },
];

<Table header={header} body={body} rounded border />
```