컬럼 타입 가이드
WZ-Grid는 총 19종의 컬럼 타입을 지원합니다. 각 타입에 따라 셀 렌더링 방식, 편집 방법, 필터 UI, 정렬 기준이 다르게 동작합니다.
인터랙티브 데모:
npm run dev실행 후 "컬럼 타입" 탭에서 19종 컬럼 타입을 직접 조작하고 이벤트 로그를 실시간으로 확인할 수 있습니다.
라이브 데모
편집 가능 여부 요약
| 타입 | 편집 방식 | 필터 UI |
|---|---|---|
text | 더블 클릭 / 즉시 타이핑 | 텍스트 부분 일치 |
number | 더블 클릭 → number input | min/max 범위 |
date | Enter / 더블 클릭 → datepicker | 날짜 범위 |
select | 더블 클릭 → 드롭다운 | 다중 선택 |
currency | 더블 클릭 → number input | min/max 범위 |
email | 더블 클릭 → email input | 텍스트 부분 일치 |
datetime | Enter / 더블 클릭 → datetime-local | from/to 범위 |
boolean | 클릭 즉시 반영 | 전체/예/아니요 |
radio | 클릭 즉시 반영 | 텍스트 부분 일치 |
rating | 클릭 즉시 반영 | min/max 범위 |
color | 클릭 즉시 반영 (색상 피커) | 텍스트 부분 일치 |
badge | 편집 불가 | 다중 선택 |
progress | 편집 불가 | — |
image | 편집 불가 | — |
button | 편집 불가 (@click:button 발생) | — |
link | 편집 불가 (새 탭 열림) | 텍스트 부분 일치 |
tag | 편집 불가 | 텍스트 포함 여부 |
sparkline | 편집 불가 | — |
textarea | 더블 클릭 / Enter → <textarea> 오버레이, Enter 다음 행 이동, Shift+Enter 줄바꿈 | 텍스트 부분 일치 |
기본 타입
text
일반 텍스트. 더블 클릭 또는 즉시 타이핑으로 편집합니다.
{ key: 'name', title: '이름', type: 'text' }number
숫자. 읽기 모드에서 toLocaleString()으로 천 단위 쉼표 포맷 표시. 편집 시 <input type="number">.
{ key: 'salary', title: '급여', type: 'number', align: 'right' }date
날짜. 편집 시 브라우저 기본 datepicker 사용. 값은 YYYY-MM-DD 형식으로 저장됩니다. 알파벳/숫자 즉시 타이핑은 무시되며, Enter 또는 더블 클릭으로 달력을 엽니다.
{ key: 'joinDate', title: '입사일', type: 'date', align: 'center' }boolean
체크박스. 클릭 즉시 @update:cell 이벤트 발생.
{ key: 'active', title: '활성', type: 'boolean', align: 'center' }select
드롭다운. options의 value로 저장하고 label로 표시합니다.
{
key: 'dept', title: '부서', type: 'select',
options: [
{ value: 'dev', label: '개발팀' },
{ value: 'biz', label: '사업팀' },
]
}badge
색상 태그 표시. options의 color에 Tailwind 클래스를 지정합니다. 편집 불가.
{
key: 'status', title: '상태', type: 'badge', align: 'center',
options: [
{ value: 'Active', label: '활성', color: 'bg-green-100 text-green-700' },
{ value: 'Inactive', label: '중단', color: 'bg-red-100 text-red-700' },
]
}progress
0~100 숫자를 프로그레스 바로 표시. 편집 불가.
{ key: 'completion', title: '완료율', type: 'progress' }image
URL을 38×38 원형 썸네일로 표시. 편집 불가.
{ key: 'avatar', title: '사진', type: 'image', align: 'center' }button
클릭 가능한 버튼 셀. 클릭 시 @click:button 이벤트 발생.
{
key: 'action', title: '관리', type: 'button', align: 'center',
options: [{ label: '상세보기' }]
}link
URL을 target="_blank" 하이퍼링크로 표시. 편집 불가.
{ key: 'website', title: '홈페이지', type: 'link' }radio
인라인 라디오 버튼 그룹. 선택 즉시 @update:cell 이벤트 발생.
{
key: 'gender', title: '성별', type: 'radio', align: 'center',
options: [
{ label: '남', value: 'M' },
{ label: '여', value: 'F' },
]
}신규 타입 (v1.4+)
tag
string[] 배열 데이터를 칩(chip) UI로 렌더링합니다. 편집 불가.
- 필터: 텍스트 포함 여부 (태그 문자열 전체를 대상으로 부분 일치)
- 정렬: 태그 개수 기준 오름차순/내림차순
{ key: 'tags', title: '태그', type: 'tag', width: 200 }// row 데이터 예시
{ id: 1, name: '홍길동', tags: ['긴급', '검토중'] }currency
숫자 데이터를 통화 기호 + 천 단위 포맷으로 표시합니다. 편집 시 <input type="number">.
- 필터: min/max 숫자 범위
- 컬럼 옵션:
| 옵션 | 타입 | 기본값 | 설명 |
|---|---|---|---|
currencySymbol | string | '₩' | 금액 앞에 붙는 통화 기호 |
decimals | number | 0 | 소수점 자릿수 |
{
key: 'price', title: '가격', type: 'currency', align: 'right', width: 140,
currencySymbol: '₩',
decimals: 0,
}
// 표시 예: ₩1,200,000rating
숫자 값(1~N)을 별점(★) UI로 표시합니다. 별 클릭 즉시 @update:cell 이벤트 발생.
- 필터: min/max 숫자 범위
- 컬럼 옵션:
| 옵션 | 타입 | 기본값 | 설명 |
|---|---|---|---|
maxRating | number | 5 | 최대 별 수 |
{ key: 'score', title: '평점', type: 'rating', align: 'center', width: 140, maxRating: 5 }
// row.score 예: 4 → ★★★★☆datetime
날짜+시간 문자열. 편집 시 <input type="datetime-local"> 사용.
- 표시/저장 형식:
YYYY-MM-DD HH:mm - 필터: from/to 날짜+시간 범위
{ key: 'createdAt', title: '등록일시', type: 'datetime', width: 160, align: 'center' }
// row.createdAt 예: '2026-03-17 09:30'color
CSS 색상 문자열을 색상 박스로 표시합니다. 색상 피커 클릭 즉시 @update:cell 이벤트 발생.
- 필터: 텍스트 포함 여부 (색상 코드 문자열 기준)
{ key: 'labelColor', title: '색상', type: 'color', align: 'center', width: 80 }
// row.labelColor 예: '#3b82f6'email
이메일 문자열을 mailto: 링크로 표시합니다. 편집 시 <input type="email">.
- 필터: 텍스트 포함 여부
{ key: 'email', title: '이메일', type: 'email', width: 200 }기타 타입
sparkline
number[] 배열 데이터를 SVG 미니 차트로 렌더링합니다. 편집 불가. sparklineType으로 line, area, bar, column 4가지 차트 스타일을 선택할 수 있습니다.
- 편집: 불가
- 필터: 없음
| 옵션 | 타입 | 기본값 | 설명 |
|---|---|---|---|
sparklineType | 'line' | 'area' | 'bar' | 'column' | 'line' | 차트 타입 |
sparklineColor | string | '#3b82f6' | 라인/막대 색상 |
sparklineHeight | number | 32 | SVG 높이(px) |
차트 타입별 차이
| 타입 | 설명 |
|---|---|
line | <polyline>을 사용한 기본 라인 차트 |
area | <polygon>을 사용한 라인 + 아래 영역 채움 |
bar | <rect>을 사용한 수평 막대 차트 |
column | <rect>을 사용한 수직 막대 차트 |
// 라인 차트 (기본)
{ key: 'trend', title: '트렌드', type: 'sparkline', width: 140 }
// area 차트
{
key: 'trend', title: '트렌드', type: 'sparkline', width: 140,
sparklineType: 'area',
sparklineColor: '#10b981',
sparklineHeight: 32,
}
// 수직 막대 차트
{
key: 'trend', title: '트렌드', type: 'sparkline', width: 140,
sparklineType: 'column',
sparklineColor: '#f59e0b',
}
// row.trend 예: [12, 34, 28, 45, 33, 52, 41]textarea
멀티라인 텍스트 입력. 더블 클릭 또는 Enter로 편집 모드 진입, <textarea> 오버레이를 셀 위에 표시합니다.
- 편집: 더블 클릭 또는 Enter로 편집 모드 진입
- 편집 중 Enter: 저장 후 동일 컬럼 다음 행으로 포커스 이동 (Excel 동작)
- 편집 중 Shift+Enter: 줄바꿈 입력
- 편집 중 Esc: 편집 취소
- 읽기 모드:
whitespace-pre스타일로 줄바꿈 유지 - 필터: 텍스트 부분 일치
{ key: 'memo', title: '메모', type: 'textarea', width: 200 }전체 타입을 사용하는 예제
<script setup lang="ts">
import { ref } from 'vue'
import WZGrid from 'wz-grid'
import type { Column } from 'wz-grid'
const columns = ref<Column[]>([
{ key: 'id', title: 'ID', type: 'number', width: 60, align: 'right' },
{ key: 'name', title: '이름', type: 'text', width: 120 },
{ key: 'email', title: '이메일', type: 'email', width: 200 },
{ key: 'dept', title: '부서', type: 'select', width: 120,
options: [
{ value: 'dev', label: '개발팀' },
{ value: 'hr', label: '인사팀' },
]
},
{ key: 'salary', title: '급여', type: 'currency', width: 140, align: 'right',
currencySymbol: '₩', decimals: 0
},
{ key: 'score', title: '평점', type: 'rating', width: 130, align: 'center', maxRating: 5 },
{ key: 'tags', title: '태그', type: 'tag', width: 180 },
{ key: 'labelColor', title: '색상', type: 'color', width: 80, align: 'center' },
{ key: 'joinDate', title: '입사일', type: 'date', width: 130, align: 'center' },
{ key: 'updatedAt', title: '최종수정', type: 'datetime', width: 160, align: 'center' },
{ key: 'active', title: '활성', type: 'boolean', width: 70, align: 'center' },
{ key: 'status', title: '상태', type: 'badge', width: 100, align: 'center',
options: [
{ value: 'Active', label: '활성', color: 'bg-green-100 text-green-700' },
{ value: 'Inactive', label: '중단', color: 'bg-red-100 text-red-700' },
]
},
{ key: 'completion', title: '완료율', type: 'progress', width: 140 },
{ key: 'website', title: '홈페이지', type: 'link', width: 180 },
{ key: 'avatar', title: '사진', type: 'image', width: 60, align: 'center' },
{ key: 'gender', title: '성별', type: 'radio', width: 120, align: 'center',
options: [{ label: '남', value: 'M' }, { label: '여', value: 'F' }]
},
{ key: 'action', title: '관리', type: 'button', width: 100, align: 'center',
options: [{ label: '상세보기' }]
},
{ key: 'memo', title: '메모', type: 'textarea', width: 200 },
])
const rows = ref([
{
id: 1, name: '홍길동', email: 'hong@example.com', dept: 'dev',
salary: 5500000, score: 4, tags: ['긴급', '검토중'],
labelColor: '#3b82f6', joinDate: '2022-03-15', updatedAt: '2026-03-17 09:30',
active: true, status: 'Active', completion: 75,
website: 'https://example.com', avatar: 'https://i.pravatar.cc/38?u=1',
gender: 'M',
},
])
</script>
<template>
<WZGrid :columns="columns" :rows="rows" :useFilter="true" @update:cell="(e) => console.log(e)" />
</template>