0.4.4 • Published 7 months ago
@gcsc/common-compo v0.4.4
Vue 3 + TypeScript + Vite 공통 컴포넌트 패키지
1. BaseList 컴포넌트
1-1) 요약
BaseList는 세 가지 모드(기본, 드래그 가능, 트리 구조)를 지원하는 다목적 리스트 컴포넌트입니다. 체크박스 기능, 드래그 앤 드롭, 트리 구조의 계층형 데이터를 표시할 수 있으며, 각 요소를 슬롯을 통해 커스터마이징할 수 있습니다.
1-2) Props
Prop 이름 | 타입 | 필수 | 기본값 | 설명 |
---|---|---|---|---|
items | ListItem[] | ✓ | - | 리스트에 표시할 아이템 배열 |
draggable | boolean | - | false | 드래그 앤 드롭 기능 활성화 |
tree | boolean | - | false | 트리 구조 활성화 |
checkable | boolean | - | false | 체크박스 기능 활성화 |
1-3) Slots
Slot 이름 | Props | 설명 |
---|---|---|
header-checkbox-content | - | 전체 선택 헤더 커스터마이징 |
item-checkbox | { item, checked } | 아이템 체크박스 커스터마이징 |
item-image | { item } | 아이템 이미지 커스터마이징 |
item-header | { item } | 아이템 헤더 영역 커스터마이징 |
item-title | { item } | 아이템 제목 커스터마이징 |
item-time | { item } | 아이템 시간 커스터마이징 |
item-preview | { item } | 아이템 미리보기 커스터마이징 |
tree-toggle | { item } | 트리 토글 버튼 커스터마이징 |
child-item-checkbox | { item, checked } | 자식 아이템 체크박스 커스터마이징 |
child-item-image | { item } | 자식 아이템 이미지 커스터마이징 |
child-item-header | { item } | 자식 아이템 헤더 커스터마이징 |
child-item-title | { item } | 자식 아이템 제목 커스터마이징 |
child-item-time | { item } | 자식 아이템 시간 커스터마이징 |
child-item-preview | { item } | 자식 아이템 미리보기 커스터마이징 |
1-4) Events
이벤트 이름 | 파라미터 | 설명 |
---|---|---|
itemClick | (item: ListItem) | 아이템 클릭 시 발생 |
check | (checkedItems: number[]) | 체크박스 상태 변경 시 발생 |
checkAll | (checked: boolean) | 전체 선택/해제 시 발생 |
update:items | (items: ListItem[]) | 드래그로 순서 변경 시 발생 |
update:modelValue | (value: number[]) | 선택된 아이템 ID 배열 업데이트 |
1-5) 타입 정의
interface ListItem {
id: number;
imageUrl: string;
title: string;
preview: string;
time: string | Date;
checked?: boolean;
children?: ListItem[];
isOpen?: boolean;
}
interface BaseListProps {
modelValue?: number[];
items: ListItem[];
draggable?: boolean;
tree?: boolean;
checkable?: boolean;
}
type BaseListEmits = {
(e: 'itemClick', item: ListItem): void;
(e: 'update:items', items: ListItem[]): void;
(e: 'update:modelValue', value: number[]): void;
(e: 'check', checkedItems: number[]): void;
(e: 'checkAll', checked: boolean): void;
}
1-6) 사용 예시
1-6-1) 기본 리스트
<template>
<BaseList
:items="items"
:checkable="true"
@item-click="handleItemClick"
>
<template #item-title="{ item }">
<div class="custom-title">{{ item.title }}</div>
</template>
</BaseList>
</template>
1-6-2) 드래거블 리스트
<template>
<BaseList
:items="items"
:draggable="true"
@update:items="handleReorder"
>
<template #item-preview="{ item }">
<div class="preview-with-badge">
<span class="badge">{{ item.category }}</span>
<p>{{ item.preview }}</p>
</div>
</template>
</BaseList>
</template>
1-6-3) 트리 리스트
<template>
<BaseList
:items="treeItems"
:tree="true"
:checkable="true"
@check="handleCheck"
>
<template #tree-toggle="{ item }">
<i :class="['tree-icon', item.isOpen ? 'open' : 'closed']" />
</template>
<template #child-item-title="{ item }">
<span class="child-title">{{ item.title }}</span>
</template>
</BaseList>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { ListItem } from '@/components/BaseList.vue'
// 리스트 아이템 데이터
const items = ref<ListItem[]>([
{
id: 1,
imageUrl: 'https://example.com/image1.jpg',
title: '첫 번째 아이템',
preview: '이것은 첫 번째 아이템의 미리보기입니다.',
time: new Date(),
checked: false
},
{
id: 2,
imageUrl: 'https://example.com/image2.jpg',
title: '두 번째 아이템',
preview: '이것은 두 번째 아이템의 미리보기입니다.',
time: new Date(),
checked: false
},
...(생략)
</script>
2. BaseTable 컴포넌트
2-1) 요약
BaseTable은 정렬 기능을 지원하는 기본 테이블 컴포넌트입니다. 컬럼별 정렬, 행 클릭 이벤트, 슬롯을 통한 커스텀 셀 렌더링을 지원하며, 데이터가 없을 경우 안내 메시지를 표시합니다.
2-2) Props
Prop 이름 | 타입 | 필수 | 기본값 | 설명 |
---|---|---|---|---|
columns | TableColumn[] | ✓ | - | 테이블 컬럼 설정 배열 |
data | TableItem[] | ✓ | - | 테이블에 표시할 데이터 배열 |
2-3) Slots
Slot 이름 | Props | 설명 |
---|---|---|
column.key | { row: TableItem } | 각 컬럼별 커스텀 셀 렌더링 |
2-4) Events
이벤트 이름 | 파라미터 | 설명 |
---|---|---|
row-click | (row: TableItem) | 행 클릭 시 발생 |
sort | (sortStates: SortState[]) | 정렬 상태 변경 시 발생 |
2-5) 타입 정의
interface TableColumn {
key: string;
label: string;
sortable?: boolean;
}
interface TableItem {
[key: string]: any;
}
interface SortState {
column: string;
direction: 'asc' | 'desc';
}
interface TableProps {
columns: TableColumn[];
data: TableItem[];
}
type TableEmits = {
(e: 'row-click', row: TableItem): void;
(e: 'sort', sortStates: SortState[]): void;
}
2-6) 사용 예시
<template>
<BaseTable
:columns="columns"
:data="tableData"
@row-click="handleRowClick"
@sort="handleSort"
>
<!-- 이름 컬럼 커스터마이징 -->
<template #name="{ row }">
<div class="user-name">
<img :src="row.avatar" :alt="row.name" class="avatar">
<span>{{ row.name }}</span>
</div>
</template>
<!-- 상태 컬럼 커스터마이징 -->
<template #status="{ row }">
<span :class="['status-badge', row.status]">
{{ row.status }}
</span>
</template>
</BaseTable>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { TableColumn, TableItem, SortState } from '@gcsc/common-compo'
// 컬럼 정의
const columns: TableColumn[] = [
{ key: 'name', label: '이름', sortable: true },
{ key: 'email', label: '이메일', sortable: true },
{ key: 'status', label: '상태', sortable: true },
{ key: 'createdAt', label: '생성일', sortable: true }
]
// 테이블 데이터
const tableData = ref<TableItem[]>([
{
name: '홍길동',
email: 'hong@example.com',
status: 'active',
createdAt: '2024-03-20',
avatar: 'https://example.com/avatar1.jpg'
},
// ... 더 많은 데이터
])
...(생략)
</script>
3. BaseCalendar 컴포넌트
3-1) 요약
BaseCalendar는 날짜와 시간을 선택할 수 있는 캘린더 컴포넌트입니다. 연도, 월, 일 선택 기능을 제공하며, 시간 선택 옵션도 포함되어 있습니다. 다양한 뷰(연도, 월, 일)를 지원하고 날짜 범위 선택이 가능합니다.
3-2) Props
Prop 이름 | 타입 | 필수 | 기본값 | 설명 |
---|---|---|---|---|
modelValue | DateRange | - | { start: null, end: null } | 선택된 날짜 범위 |
currentDate | Dayjs | - | dayjs() | 현재 날짜 |
startDate | string | null | - | null | 시작 날짜 |
endDate | string | null | - | null | 종료 날짜 |
selectedInput | 'start' | 'end' | null | - | null | 선택된 입력 필드 |
enableTimeSelection | boolean | - | false | 시간 선택 활성화 |
minDate | string | undefined | - | undefined | 최소 선택 가능 날짜 |
maxDate | string | undefined | - | undefined | 최대 선택 가능 날짜 |
disabledDates | string[] | - | [] | 비활성화된 날짜 배열 |
firstDayOfWeek | number | - | 0 | 주의 첫 번째 요일 |
3-3) Slots
Slot 이름 | Props | 설명 |
---|---|---|
close-button | - | 닫기 버튼 커스터마이징 |
time-selection | { startDate, endDate, startTime, endTime, updateStartTime, updateEndTime } | 시간 선택 영역 커스터마이징 |
footer | { onRefresh, onCancel, onApply } | 푸터 영역 커스터마이징 |
3-4) Events
이벤트 이름 | 파라미터 | 설명 |
---|---|---|
select | (range: DateRange) | 날짜/시간 선택 시 발생 |
apply | (range: DateRange) | 선택 적용 시 발생 |
cancel | - | 취소 시 발생 |
3-5) 타입 정의
interface DateRange {
start: string | null;
end: string | null;
}
interface TimeValue {
hours: number;
minutes: number;
}
type CalendarView = 'calendar' | 'month' | 'year';
interface CalendarProps {
modelValue?: DateRange;
currentDate?: Dayjs;
startDate?: string | null;
endDate?: string | null;
selectedInput?: 'start' | 'end' | null;
enableTimeSelection?: boolean;
minDate?: string;
maxDate?: string;
disabledDates?: string[];
firstDayOfWeek?: number;
}
3-6) 사용 예시
<template>
<BaseCalendar
v-model="dateRange"
:enable-time-selection="true"
@select="handleDateSelect"
@apply="handleApply"
@cancel="handleCancel"
>
<!-- 닫기 버튼 커스터마이징 -->
<template #close-button>
<button class="close-btn">×</button>
</template>
<!-- 시간 선택 영역 커스터마이징 -->
<template #time-selection="{ startTime, endTime, updateStartTime, updateEndTime }">
<div class="custom-time-selector">
<TimeSelector
:start-time="startTime"
:end-time="endTime"
@update:start-time="updateStartTime"
@update:end-time="updateEndTime"
/>
</div>
</template>
<!-- 푸터 영역 커스터마이징 -->
<template #footer="{ onApply, onCancel }">
<div class="custom-footer">
<button @click="onCancel">취소</button>
<button @click="onApply">확인</button>
</div>
</template>
</BaseCalendar>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { DateRange } from '@gcsc/common-compo'
const dateRange = ref<DateRange>({
start: null,
end: null
})
...(생략)
</script>
4. InputCalendar 컴포넌트
4-1) 요약
InputCalendar는 날짜 범위를 선택할 수 있는 입력 필드와 캘린더 팝업을 제공하는 컴포넌트입니다. 시작일과 종료일을 선택할 수 있으며, 시간 선택 옵션도 지원합니다. 두 개의 연속된 캘린더를 통해 직관적인 날짜 범위 선택이 가능합니다.
4-2) Props
Prop 이름 | 타입 | 필수 | 기본값 | 설명 |
---|---|---|---|---|
modelValue | DateRange | ✓ | - | 선택된 날짜 범위 |
enableTimeSelection | boolean | - | false | 시간 선택 기능 활성화 |
placeholder | string | - | - | 입력 필드 플레이스홀더 |
4-3) Slots
Slot 이름 | Props | 설명 |
---|---|---|
close-button | { onCancel } | 닫기 버튼 커스터마이징 |
footer | { onRefresh, onCancel, onApply } | 푸터 영역 커스터마이징 |
4-4) Events
이벤트 이름 | 파라미터 | 설명 |
---|---|---|
update:modelValue | (value: DateRange) | 날짜 범위 변경 시 발생 |
cancel | - | 캘린더 닫기 시 발생 |
4-5) 타입 정의
interface DateRange {
start: string | null;
end: string | null;
}
interface DateTime {
date: string;
fullInput: string;
time: {
hours: number;
minutes: number;
};
}
interface InputCalendarProps {
modelValue: DateRange;
enableTimeSelection?: boolean;
placeholder?: string;
}
interface DateInfo {
date: string;
day: number;
currentMonth: boolean;
}
4-6) 사용 예시
<template>
<InputCalendar
v-model="dateRange"
:enable-time-selection="true"
placeholder="YYYY-MM-DD HH:mm"
@cancel="handleCancel"
>
<!-- 닫기 버튼 커스터마이징 -->
<template #close-button="{ onCancel }">
<button class="close-btn" @click="onCancel">×</button>
</template>
<!-- 푸터 커스터마이징 -->
<template #footer="{ onRefresh, onCancel, onApply }">
<div class="calendar-footer">
<button @click="onRefresh">초기화</button>
<button @click="onCancel">취소</button>
<button @click="onApply">확인</button>
</div>
</template>
</InputCalendar>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { DateRange } from '@gcsc/common-compo'
const dateRange = ref<DateRange>({
start: null,
end: null
})
...(생략)
</script>
5. BaseCheckbox 컴포넌트
5-1) 요약
BaseCheckbox는 단일 체크박스와 다중 선택(체크박스/라디오) 기능을 제공하는 컴포넌트입니다. 전체 선택 기능과 개별 항목 선택이 가능하며, 비활성화 상태도 지원합니다. 체크박스와 라디오 버튼 두 가지 타입을 제공합니다.
5-2) Props
Prop 이름 | 타입 | 필수 | 기본값 | 설명 |
---|---|---|---|---|
modelValue | boolean | (string | number)[] | string | number | ✓ | false | 선택된 값 |
items | CheckboxItem[] | - | [] | 선택 항목 배열 |
label | string | - | '' | 단일 체크박스 라벨 |
type | 'checkbox' | 'radio' | - | 'checkbox' | 체크박스 타입 |
name | string | - | '' | 입력 필드 이름 |
disabled | boolean | - | false | 비활성화 여부 |
5-3) Slots
Slot 이름 | Props | 설명 |
---|---|---|
default | - | 단일 체크박스 라벨 커스터마이징 |
select-all | { allChecked, indeterminate, toggleAll } | 전체 선택 영역 커스터마이징 |
5-4) Events
이벤트 이름 | 파라미터 | 설명 |
---|---|---|
update:modelValue | (value: boolean | (string | number)[] | string | number) | 값 변경 시 발생 |
check | (value: boolean | (string | number)[] | string | number) | 항목 선택 시 발생 |
checkAll | (checked: boolean) | 전체 선택/해제 시 발생 |
5-5) 타입 정의
interface CheckboxItem {
id: number;
label: string;
}
interface CheckboxProps {
modelValue?: boolean | (string | number)[] | string | number;
items?: CheckboxItem[];
label?: string;
type?: 'checkbox' | 'radio';
name?: string;
disabled?: boolean;
}
type CheckboxEmits = {
(e: 'update:modelValue', value: boolean | (string | number)[] | string | number): void;
(e: 'check', value: boolean | (string | number)[] | string | number): void;
(e: 'checkAll', checked: boolean): void;
}
5-6) 사용 예시
<template>
<!-- 단일 체크박스 -->
<BaseCheckbox
v-model="isChecked"
label="동의합니다"
@check="handleCheck"
/>
<!-- 다중 체크박스 -->
<BaseCheckbox
v-model="selectedItems"
:items="checkboxItems"
type="checkbox"
@check="handleItemsCheck"
@checkAll="handleCheckAll"
>
<!-- 전체 선택 커스터마이징 -->
<template #select-all="{ allChecked, indeterminate, toggleAll }">
<div class="select-all-wrapper">
<label class="checkbox-item">
<input
type="checkbox"
:checked="allChecked"
:indeterminate="indeterminate"
@change="toggleAll"
/>
<span class="item-label">전체 선택</span>
</label>
</div>
</template>
</BaseCheckbox>
<!-- 라디오 버튼 -->
<BaseCheckbox
v-model="selectedOption"
:items="radioItems"
type="radio"
name="options"
@check="handleOptionSelect"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { CheckboxItem } from '@gcsc/common-compo'
// 단일 체크박스
const isChecked = ref(false)
const handleCheck = (checked: boolean) => {
console.log('체크 상태:', checked)
}
// 다중 체크박스
const checkboxItems: CheckboxItem[] = [
{ id: 1, label: '옵션 1' },
{ id: 2, label: '옵션 2' },
{ id: 3, label: '옵션 3' }
]
const selectedItems = ref<(string | number)[]>([])
const handleItemsCheck = (items: (string | number)[]) => {
console.log('선택된 항목:', items)
}
const handleCheckAll = (checked: boolean) => {
console.log('전체 선택:', checked)
}
// 라디오 버튼
const radioItems: CheckboxItem[] = [
{ id: 1, label: '라디오 1' },
{ id: 2, label: '라디오 2' },
{ id: 3, label: '라디오 3' }
]
const selectedOption = ref<number | null>(null)
const handleOptionSelect = (option: number) => {
console.log('선택된 옵션:', option)
}
</script>
6. ListCheckbox 컴포넌트
6-1) 요약
ListCheckbox는 리스트 형태의 항목들에 대한 체크박스 기능을 제공하는 컴포넌트입니다. 전체 선택/해제 기능과 개별 항목 선택이 가능하며, 선택된 항목 수를 표시합니다. 리스트의 헤더에 위치하여 일괄적인 항목 선택을 관리합니다.
6-2) Props
Prop 이름 | 타입 | 필수 | 기본값 | 설명 |
---|---|---|---|---|
items | ListItem[] | ✓ | [] | 체크박스 항목 배열 |
modelValue | number[] | ✓ | [] | 선택된 항목 ID 배열 |
6-3) Slots
Slot 이름 | Props | 설명 |
---|---|---|
header-checkbox | { allChecked, indeterminate, toggleAll } | 헤더 체크박스 영역 커스터마이징 |
header-checkbox-content | - | 헤더 체크박스 내용 커스터마이징 |
6-4) Events
이벤트 이름 | 파라미터 | 설명 |
---|---|---|
update:modelValue | (value: number[]) | 선택된 항목 배열 변경 시 발생 |
check | (checkedIds: number[]) | 항목 선택/해제 시 발생 |
checkAll | (checked: boolean) | 전체 선택/해제 시 발생 |
6-5) 타입 정의
interface ListItem {
id: number;
label: string;
}
interface ListCheckboxProps {
items: ListItem[];
modelValue: number[];
}
type BaseListEmits = {
(e: 'update:modelValue', value: number[]): void;
(e: 'check', checkedIds: number[]): void;
(e: 'checkAll', checked: boolean): void;
}
6-6) 사용예시
<template>
<ListCheckbox
v-model="selectedItems"
:items="listItems"
@check="handleCheck"
@checkAll="handleCheckAll"
>
<!-- 헤더 체크박스 커스터마이징 -->
<template #header-checkbox="{ allChecked, indeterminate, toggleAll }">
<div class="custom-header-checkbox">
<label>
<input
type="checkbox"
:checked="allChecked"
:indeterminate="indeterminate"
@change="toggleAll"
/>
<slot name="header-checkbox-content">
<span class="selection-count">
선택된 항목: {{ selectedItems.length }}/{{ listItems.length }}
</span>
</slot>
</label>
</div>
</template>
</ListCheckbox>
<!-- 리스트 항목들 -->
<div class="list-items">
<div
v-for="item in listItems"
:key="item.id"
class="list-item"
@click="toggleItem(item.id, $event)"
>
<input
type="checkbox"
:checked="isChecked(item.id)"
@change="e => e.stopPropagation()"
/>
<span>{{ item.label }}</span>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { ListItem } from '@gcsc/common-compo'
// 리스트 항목 데이터
const listItems: ListItem[] = [
{ id: 1, label: '항목 1' },
{ id: 2, label: '항목 2' },
{ id: 3, label: '항목 3' },
{ id: 4, label: '항목 4' }
]
const selectedItems = ref<number[]>([])
// 이벤트 핸들러
const handleCheck = (checkedIds: number[]) => {
console.log('선택된 항목:', checkedIds)
}
const handleCheckAll = (checked: boolean) => {
console.log('전체 선택 상태:', checked)
}
// 항목 토글 함수
const toggleItem = (itemId: number, event: Event) => {
event.stopPropagation()
const index = selectedItems.value.indexOf(itemId)
if (index === -1) {
selectedItems.value.push(itemId)
} else {
selectedItems.value.splice(index, 1)
}
}
</script>
7. BaseButton 컴포넌트
7-1) 요약
BaseButton은 다양한 스타일과 기능을 제공하는 기본 버튼 컴포넌트입니다. 다양한 변형(variant)을 지원하며, 비활성화 상태와 타입(button, submit, reset)을 설정할 수 있습니다. 클릭과 제출 이벤트를 처리할 수 있습니다.
7-2) Props
Prop 이름 | 타입 | 필수 | 기본값 | 설명 |
---|---|---|---|---|
variant | 'primary' | 'secondary' | 'outline' | 'text' | ✓ | - | 버튼 스타일 변형 |
disabled | boolean | - | false | 비활성화 여부 |
type | 'button' | 'submit' | 'reset' | - | 'button' | 버튼 타입 |
7-3) Slots
Slot 이름 | Props | 설명 |
---|---|---|
default | - | 버튼 내용 커스터마이징 |
7-4) Events
이벤트 이름 | 파라미터 | 설명 |
---|---|---|
click | (event: MouseEvent) | 클릭 시 발생 |
submit | (event: Event) | 제출 시 발생 |
7-5) 타입 정의
type ButtonVariant = 'primary' | 'secondary' | 'outline' | 'text';
type ButtonType = 'button' | 'submit' | 'reset';
interface ButtonProps {
variant: ButtonVariant;
disabled?: boolean;
type?: ButtonType;
}
type ButtonEmits = {
(e: 'click', event: MouseEvent): void;
(e: 'submit', event: Event): void;
}
7-6) 사용 예시
<template>
<div class="button-examples">
<!-- 기본 버튼 -->
<BaseButton
variant="primary"
@click="handleClick"
>
기본 버튼
</BaseButton>
<!-- 제출 버튼 -->
<BaseButton
variant="primary"
type="submit"
@submit="handleSubmit"
>
제출
</BaseButton>
<!-- 비활성화된 버튼 -->
<BaseButton
variant="secondary"
:disabled="true"
>
비활성화
</BaseButton>
<!-- 아이콘이 있는 버튼 -->
<BaseButton
variant="outline"
@click="handleIconClick"
>
<i class="icon">+</i>
아이콘 버튼
</BaseButton>
<!-- 텍스트 버튼 -->
<BaseButton
variant="text"
@click="handleTextClick"
>
텍스트 버튼
</BaseButton>
</div>
</template>
<script setup lang="ts">
const handleClick = (event: MouseEvent) => {
console.log('버튼 클릭:', event)
}
const handleSubmit = (event: Event) => {
console.log('폼 제출:', event)
}
const handleIconClick = () => {
console.log('아이콘 버튼 클릭')
}
const handleTextClick = () => {
console.log('텍스트 버튼 클릭')
}
</script>
8. BaseInput 컴포넌트
8-1) 요약
BaseInput은 다양한 스타일과 기능을 제공하는 기본 입력 필드 컴포넌트입니다. 다양한 변형(variant)을 지원하며, 비활성화 상태와 필수 입력 여부를 설정할 수 있습니다. v-model을 통한 양방향 바인딩을 지원합니다.
8-2) Props
Prop 이름 | 타입 | 필수 | 기본값 | 설명 |
---|---|---|---|---|
modelValue | string | ✓ | - | 입력 필드 값 |
variant | 'default' | 'primary' | 'error' | - | 'default' | 입력 필드 스타일 변형 |
type | 'text' | 'password' | 'email' | 'number' | - | 'text' | 입력 필드 타입 |
disabled | boolean | - | false | 비활성화 여부 |
placeholder | string | - | - | 플레이스홀더 텍스트 |
required | boolean | - | false | 필수 입력 여부 |
8-3) Events
이벤트 이름 | 파라미터 | 설명 |
---|---|---|
update:modelValue | (value: string) | 입력값 변경 시 발생 |
8-4) 타입 정의
type InputVariant = 'default' | 'primary' | 'error';
type InputType = 'text' | 'password' | 'email' | 'number';
interface InputProps {
modelValue: string;
variant?: InputVariant;
type?: InputType;
disabled?: boolean;
placeholder?: string;
required?: boolean;
}
type InputEmits = {
(e: 'update:modelValue', value: string): void;
}
8-5) 사용 예시
<template>
<div class="input-examples">
<!-- 기본 입력 필드 -->
<BaseInput
v-model="textValue"
placeholder="기본 입력"
/>
<!-- 비밀번호 입력 필드 -->
<BaseInput
v-model="passwordValue"
type="password"
placeholder="비밀번호 입력"
/>
<!-- 이메일 입력 필드 -->
<BaseInput
v-model="emailValue"
type="email"
placeholder="이메일 입력"
required
/>
<!-- 숫자 입력 필드 -->
<BaseInput
v-model="numberValue"
type="number"
placeholder="숫자 입력"
/>
<!-- 에러 상태 입력 필드 -->
<BaseInput
v-model="errorValue"
variant="error"
placeholder="에러 상태"
/>
<!-- 비활성화된 입력 필드 -->
<BaseInput
v-model="disabledValue"
disabled
placeholder="비활성화"
/>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const textValue = ref('')
const passwordValue = ref('')
const emailValue = ref('')
const numberValue = ref('')
const errorValue = ref('')
const disabledValue = ref('비활성화된 값')
</script>
9. BaseSelect 컴포넌트
9-1) 요약
BaseSelect는 드롭다운 선택 필드를 제공하는 컴포넌트입니다. 옵션 배열을 통한 동적 렌더링과 사용자 정의 옵션을 위한 슬롯을 지원합니다. 플레이스홀더, 비활성화 상태, 필수 입력 여부를 설정할 수 있으며, 다양한 스타일 변형을 제공합니다.
9-2) Props
Prop 이름 | 타입 | 필수 | 기본값 | 설명 |
---|---|---|---|---|
modelValue | string | ✓ | - | 선택된 값 |
options | SelectOption[] | ✓ | - | 선택 옵션 배열 |
variant | 'default' | 'primary' | 'error' | - | 'default' | 선택 필드 스타일 변형 |
withAccompany | boolean | - | false | 동반 요소 표시 여부 |
disabled | boolean | - | false | 비활성화 여부 |
required | boolean | - | false | 필수 선택 여부 |
placeholder | string | - | - | 플레이스홀더 텍스트 |
9-3) Slots
Slot 이름 | Props | 설명 |
---|---|---|
default | - | 사용자 정의 옵션을 위한 슬롯 |
9-4) Events
이벤트 이름 | 파라미터 | 설명 |
---|---|---|
update:modelValue | (value: string) | 선택값 변경 시 발생 |
9-5) 타입 정의
type SelectVariant = 'default' | 'primary' | 'error';
interface SelectOption {
value: string;
label: string;
disabled?: boolean;
}
interface SelectProps {
modelValue: string;
options: SelectOption[];
variant?: SelectVariant;
withAccompany?: boolean;
disabled?: boolean;
required?: boolean;
placeholder?: string;
}
type SelectEmits = {
(e: 'update:modelValue', value: string): void;
}
9-6) 사용 예시
<template>
<div class="select-examples">
<!-- 기본 선택 필드 -->
<BaseSelect
v-model="selectedValue"
:options="options"
placeholder="선택하세요"
/>
<!-- 동반 요소가 있는 선택 필드 -->
<BaseSelect
v-model="accompanyValue"
:options="options"
with-accompany
placeholder="동반 요소 선택"
>
<template #accompany>
<span class="accompany-text">동반</span>
</template>
</BaseSelect>
<!-- 에러 상태 선택 필드 -->
<BaseSelect
v-model="errorValue"
:options="options"
variant="error"
placeholder="에러 상태"
/>
<!-- 비활성화된 선택 필드 -->
<BaseSelect
v-model="disabledValue"
:options="options"
disabled
placeholder="비활성화"
/>
<!-- 사용자 정의 옵션이 있는 선택 필드 -->
<BaseSelect
v-model="customValue"
:options="options"
placeholder="사용자 정의 옵션"
>
<option value="custom1">사용자 정의 옵션 1</option>
<option value="custom2">사용자 정의 옵션 2</option>
</BaseSelect>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { Option } from '@gcsc/common-compo'
const options: Option[] = [
{ value: 'option1', label: '옵션 1' },
{ value: 'option2', label: '옵션 2' },
{ value: 'option3', label: '옵션 3', disabled: true },
{ value: 'option4', label: '옵션 4' }
]
const selectedValue = ref('')
const accompanyValue = ref('')
const errorValue = ref('')
const disabledValue = ref('option1')
const customValue = ref('')
</script>
10. BaseDialog 컴포넌트
10-1) 요약
BaseDialog은 드래그 가능한 모달 다이얼로그를 제공하는 컴포넌트입니다. 오버레이, 헤더, 컨텐츠, 푸터 영역을 포함하며, 커스터마이징 가능한 슬롯을 제공합니다. 확인/취소 버튼을 기본으로 제공하며, 오버레이 클릭 시 닫기 옵션을 지원합니다.
10-2) Props
Prop 이름 | 타입 | 필수 | 기본값 | 설명 |
---|---|---|---|---|
modelValue | boolean | ✓ | - | 모달 표시 여부 |
title | string | - | '알림' | 모달 제목 |
content | string | - | '' | 모달 내용 |
showConfirm | boolean | - | true | 확인 버튼 표시 여부 |
showCancel | boolean | - | true | 취소 버튼 표시 여부 |
confirmText | string | - | '확인' | 확인 버튼 텍스트 |
cancelText | string | - | '취소' | 취소 버튼 텍스트 |
closeOnOverlayClick | boolean | - | true | 오버레이 클릭 시 닫기 여부 |
10-3) Slots
Slot 이름 | Props | 설명 |
---|---|---|
title | - | 제목 영역 커스터마이징 |
content | - | 내용 영역 커스터마이징 |
footer | { close } | 푸터 영역 커스터마이징 |
buttons | { close } | 버튼 영역 커스터마이징 |
10-4) Events
이벤트 이름 | 파라미터 | 설명 |
---|---|---|
update:modelValue | (value: boolean) | 모달 표시 상태 변경 시 발생 |
confirm | - | 확인 버튼 클릭 시 발생 |
cancel | - | 취소 버튼 클릭 시 발생 |
10-5) 타입 정의
interface DialogProps {
modelValue: boolean;
title?: string;
content?: string;
showConfirm?: boolean;
showCancel?: boolean;
confirmText?: string;
cancelText?: string;
closeOnOverlayClick?: boolean;
}
type DilogEmits = {
(e: 'update:modelValue', value: boolean): void;
(e: 'confirm'): void;
(e: 'cancel'): void;
}
10-6) 사용 예시
<template>
<BaseDialog
v-model="showDialog"
title="사용자 정보"
@confirm="handleConfirm"
@cancel="handleCancel"
>
<!-- 제목 커스터마이징 -->
<template #title>
<h2 class="custom-title">사용자 정보 수정</h2>
</template>
<!-- 내용 커스터마이징 -->
<template #content>
<div class="user-form">
<div class="form-group">
<label>이름</label>
<input v-model="userName" type="text" />
</div>
<div class="form-group">
<label>이메일</label>
<input v-model="userEmail" type="email" />
</div>
</div>
</template>
<!-- 버튼 커스터마이징 -->
<template #buttons="{ close }">
<button class="custom-button save" @click="handleSave">저장</button>
<button class="custom-button cancel" @click="close">닫기</button>
</template>
</BaseDialog>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const showDialog = ref(false)
const userName = ref('')
const userEmail = ref('')
const handleConfirm = () => {
console.log('확인 버튼 클릭')
}
const handleCancel = () => {
console.log('취소 버튼 클릭')
}
const handleSave = () => {
console.log('저장 버튼 클릭', {
name: userName.value,
email: userEmail.value
})
}
</script>
11. BasePagination 컴포넌트
11-1) 요약
BasePagination은 페이지 네비게이션을 제공하는 컴포넌트입니다. 첫 페이지, 이전 페이지, 페이지 번호, 다음 페이지, 마지막 페이지 버튼을 포함하며, 최대 표시 페이지 수를 설정할 수 있습니다. 현재 페이지 그룹에 따라 페이지 번호를 동적으로 표시합니다.
11-2) Props
Prop 이름 | 타입 | 필수 | 기본값 | 설명 |
---|---|---|---|---|
currentPage | number | ✓ | - | 현재 페이지 번호 |
totalPages | number | ✓ | - | 전체 페이지 수 |
maxDisplayPages | number | - | 5 | 한 번에 표시할 최대 페이지 수 |
11-3) Events
이벤트 이름 | 파라미터 | 설명 |
---|---|---|
update:currentPage | (page: number) | 페이지 변경 시 발생 |
11-4) 타입 정의
interface PaginationProps {
currentPage: number;
totalPages: number;
maxDisplayPages?: number;
}
11-5) 사용 예시
<template>
<div class="pagination-example">
<!-- 기본 페이지네이션 -->
<BasePagination
v-model:current-page="currentPage"
:total-pages="totalPages"
@update:current-page="handlePageChange"
/>
<!-- 커스텀 스타일 페이지네이션 -->
<BasePagination
v-model:current-page="customPage"
:total-pages="totalPages"
:max-display-pages="7"
class="custom-pagination"
@update:current-page="handleCustomPageChange"
/>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const currentPage = ref(1)
const customPage = ref(1)
const totalPages = 20
const handlePageChange = (page: number) => {
console.log('페이지 변경:', page)
}
const handleCustomPageChange = (page: number) => {
console.log('커스텀 페이지 변경:', page)
}
</script>
12. BaseLoading 컴포넌트
12-1) 요약
BaseLoading은 세 가지 다른 스타일의 로딩 인디케이터를 제공하는 컴포넌트입니다. 스피너, 바, 점 애니메이션 중 하나를 선택하여 사용할 수 있으며, 오버레이 옵션과 크기 조절이 가능합니다. 각 로딩 타입은 상황에 맞게 커스터마이징할 수 있습니다.
12-2) Props
Prop 이름 | 타입 | 필수 | 기본값 | 설명 |
---|---|---|---|---|
size | 'small' | 'medium' | 'large' | - | 'medium' | 로딩 인디케이터 크기 |
overlay | boolean | - | false | 오버레이 표시 여부 |
spinner | boolean | - | false | 스피너 로딩 표시 여부 |
bar | boolean | - | false | 바 로딩 표시 여부 |
dots | boolean | - | false | 점 로딩 표시 여부 |
12-3) 타입 정의
type LoadingSize = 'small' | 'medium' | 'large';
interface LoadingProps {
size?: LoadingSize;
overlay?: boolean;
spinner?: boolean;
bar?: boolean;
dots?: boolean;
}
12-4) 사용 예시
<template>
<div class="loading-examples">
<!-- 스피너 로딩 -->
<BaseLoading
spinner
size="medium"
/>
<!-- 바 로딩 -->
<BaseLoading
bar
size="large"
/>
<!-- 점 로딩 -->
<BaseLoading
dots
size="small"
/>
<!-- 오버레이가 있는 로딩 -->
<BaseLoading
spinner
overlay
size="large"
/>
</div>
</template>
<script setup lang="ts">
// 컴포넌트 import
</script>
13. BaseToast 컴포넌트
13-1) 요약
BaseToast는 알림 메시지를 표시하는 컴포넌트입니다. 성공, 에러, 경고, 정보 등 다양한 타입의 토스트 메시지를 지원하며, 위치와 지속 시간을 설정할 수 있습니다. 아이콘, 메시지, 닫기 버튼을 커스터마이징할 수 있는 슬롯을 제공합니다.
13-2) Props
Prop 이름 | 타입 | 필수 | 기본값 | 설명 |
---|---|---|---|---|
id | string | number | ✓ | - | 토스트 고유 식별자 |
message | string | ✓ | - | 토스트 메시지 |
type | 'success' | 'error' | 'warning' | 'info' | - | 'info' | 토스트 타입 |
duration | number | null | - | null | 표시 지속 시간 (ms) |
position | 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left' | - | 'top-right' | 표시 위치 |
13-3) Slots
Slot 이름 | Props | 설명 |
---|---|---|
icon | - | 아이콘 영역 커스터마이징 |
message | - | 메시지 영역 커스터마이징 |
close-button | - | 닫기 버튼 영역 커스터마이징 |
default | - | 전체 토스트 영역 커스터마이징 |
13-4) Events
이벤트 이름 | 파라미터 | 설명 |
---|---|---|
close | (id: string | number) | 토스트 닫힐 때 발생 |
13-5) 타입 정의
type ToastType = 'success' | 'error' | 'warning' | 'info';
type ToastPosition = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
interface ToastProps {
id: string | number;
message: string;
type?: ToastType;
duration?: number | null;
position?: ToastPosition;
}
type ToastEmits = {
(e: 'close', id: string | number): void;
}
13-6) 사용 예시
<template>
<div class="toast-examples">
<!-- 기본 토스트 -->
<BaseToast
id="1"
message="기본 알림 메시지입니다."
type="info"
/>
<!-- 성공 토스트 -->
<BaseToast
id="2"
message="성공적으로 저장되었습니다."
type="success"
duration="3000"
/>
<!-- 에러 토스트 -->
<BaseToast
id="3"
message="오류가 발생했습니다."
type="error"
position="top-left"
>
<!-- 커스텀 아이콘 -->
<template #icon>
<span class="custom-icon">⚠️</span>
</template>
</BaseToast>
<!-- 경고 토스트 -->
<BaseToast
id="4"
message="주의하세요!"
type="warning"
position="bottom-right"
>
<!-- 커스텀 닫기 버튼 -->
<template #close-button>
<button class="custom-close" @click="handleClose">닫기</button>
</template>
</BaseToast>
<!-- 완전 커스텀 토스트 -->
<BaseToast
id="5"
message="커스텀 토스트"
type="info"
position="bottom-left"
>
<div class="custom-toast">
<div class="custom-content">
<span class="custom-icon">🎉</span>
<span class="custom-message">커스텀 메시지</span>
</div>
<button class="custom-close" @click="handleCustomClose">×</button>
</div>
</BaseToast>
</div>
</template>
<script setup lang="ts">
const handleClose = () => {
console.log('토스트 닫기')
}
const handleCustomClose = () => {
console.log('커스텀 토스트 닫기')
}
</script>
14. BaseModal 컴포넌트
14-1) 요약
BaseModal은 드래그 가능한 모달 창으로, 커스터마이징 가능한 헤더/컨텐츠/푸터, 스크롤바 표시 옵션, 닫기 버튼 표시 옵션을 제공하며 TypeScript를 지원합니다.
14-2) Props
Prop | Type | Default | Description |
---|---|---|---|
draggable | boolean | true | 모달의 드래그 가능 여부 |
header | ModalHeader | { showCloseButton: true } | 헤더 관련 설정 |
content | ModalContent | { showScrollbar: true } | 컨텐츠 관련 설정 |
footer | ModalFooter | { showFooter: false } | 푸터 관련 설정 |
14-3) Slots
이름 | 설명 |
---|---|
default | 기본 컨텐츠 영역 |
header | 커스텀 헤더 영역 (header.customHeader가 true일 때) |
content | 커스텀 컨텐츠 영역 (content.customContent가 true일 때) |
footer | 기본 푸터 영역 |
custom-footer | 커스텀 푸터 영역 (footer.customFooter가 true일 때) |
14-4) Events
이벤트 | 설명 |
---|---|
close | 모달이 닫힐 때 발생하는 이벤트 |
14-5) 타입 정의
// ModalHeader 타입
interface ModalHeader {
title?: string; // 헤더 제목
showCloseButton?: boolean; // 닫기 버튼 표시 여부
customHeader?: boolean; // 커스텀 헤더 사용 여부
}
// ModalContent 타입
interface ModalContent {
customContent?: boolean; // 커스텀 컨텐츠 사용 여부
showScrollbar?: boolean; // 스크롤바 표시 여부
}
// ModalFooter 타입
interface ModalFooter {
showFooter?: boolean; // 푸터 표시 여부
customFooter?: boolean; // 커스텀 푸터 사용 여부
}
14-6) 사용 예시
(1) 기본 사용
<template>
<BaseModal
:header="{ title: '기본 모달' }"
:content="{ showScrollbar: true }"
@close="handleClose"
>
<p>모달 내용</p>
</BaseModal>
</template>
<script setup lang="ts">
import {ref} from "vue";
const isModalOpen = ref(false);
const handleClose = () => {
isModalOpen.value = false;
};
</script>
(2) 커스텀 헤더 사용
<template>
<BaseModal
:header="{ customHeader: true }"
@close="handleClose"
>
<template #header>
<div class="custom-header">
<h2>커스텀 헤더</h2>
</div>
</template>
<p>모달 내용</p>
</BaseModal>
</template>
<script setup lang="ts">
import {ref} from "vue";
const isModalOpen = ref(false);
const handleClose = () => {
isModalOpen.value = false;
};
</script>
(3) 커스텀 푸터 사용
<template>
<BaseModal
:header="{ title: '푸터 예시' }"
:footer="{ showFooter: true, customFooter: true }"
@close="handleClose"
>
<p>모달 내용</p>
<template #custom-footer>
<div class="custom-footer">
<button @click="handleSave">저장</button>
<button @click="handleClose">취소</button>
</div>
</template>
</BaseModal>
</template>
<script setup lang="ts">
import {ref} from "vue";
const isModalOpen = ref(false);
const handleClose = () => {
isModalOpen.value = false;
};
const handleSave = () => {
// 저장 처리
};
</script>
0.4.4
7 months ago
0.4.3
7 months ago
0.4.2
7 months ago
0.4.1
7 months ago
0.4.0
7 months ago
0.3.6
7 months ago
0.3.5
7 months ago
0.3.4
7 months ago
0.3.3
7 months ago
0.3.2
7 months ago
0.3.1
7 months ago
0.3.0
7 months ago
0.2.9
7 months ago
0.2.8
7 months ago
0.2.7
7 months ago
0.2.6
7 months ago
0.2.5
7 months ago
0.2.4
7 months ago
0.2.3
7 months ago
0.2.2
7 months ago
0.2.1
7 months ago
0.2.0
7 months ago
0.1.9
7 months ago
0.1.8
7 months ago
0.1.7
7 months ago
0.1.6
7 months ago
0.1.5
7 months ago
0.1.4
7 months ago
0.1.3
7 months ago
0.1.2
7 months ago
0.1.1
7 months ago
0.1.0
7 months ago
0.0.9
7 months ago
0.0.8
7 months ago
0.0.7
7 months ago
0.0.6
7 months ago
0.0.5
7 months ago
0.0.4
7 months ago
0.0.3
7 months ago
0.0.2
7 months ago
0.0.1
7 months ago