Skip to content

컬럼 타입 가이드

WZ-Grid는 총 19종의 컬럼 타입을 지원합니다. 각 타입에 따라 셀 렌더링 방식, 편집 방법, 필터 UI, 정렬 기준이 다르게 동작합니다.

인터랙티브 데모: npm run dev 실행 후 "컬럼 타입" 탭에서 19종 컬럼 타입을 직접 조작하고 이벤트 로그를 실시간으로 확인할 수 있습니다.

라이브 데모

편집 가능 여부 요약

타입편집 방식필터 UI
text더블 클릭 / 즉시 타이핑텍스트 부분 일치
number더블 클릭 → number inputmin/max 범위
dateEnter / 더블 클릭 → datepicker날짜 범위
select더블 클릭 → 드롭다운다중 선택
currency더블 클릭 → number inputmin/max 범위
email더블 클릭 → email input텍스트 부분 일치
datetimeEnter / 더블 클릭 → datetime-localfrom/to 범위
boolean클릭 즉시 반영전체/예/아니요
radio클릭 즉시 반영텍스트 부분 일치
rating클릭 즉시 반영min/max 범위
color클릭 즉시 반영 (색상 피커)텍스트 부분 일치
badge편집 불가다중 선택
progress편집 불가
image편집 불가
button편집 불가 (@click:button 발생)
link편집 불가 (새 탭 열림)텍스트 부분 일치
tag편집 불가텍스트 포함 여부
sparkline편집 불가
textarea더블 클릭 / Enter → <textarea> 오버레이, Enter 다음 행 이동, Shift+Enter 줄바꿈텍스트 부분 일치

기본 타입

text

일반 텍스트. 더블 클릭 또는 즉시 타이핑으로 편집합니다.

ts
{ key: 'name', title: '이름', type: 'text' }

number

숫자. 읽기 모드에서 toLocaleString()으로 천 단위 쉼표 포맷 표시. 편집 시 <input type="number">.

ts
{ key: 'salary', title: '급여', type: 'number', align: 'right' }

date

날짜. 편집 시 브라우저 기본 datepicker 사용. 값은 YYYY-MM-DD 형식으로 저장됩니다. 알파벳/숫자 즉시 타이핑은 무시되며, Enter 또는 더블 클릭으로 달력을 엽니다.

ts
{ key: 'joinDate', title: '입사일', type: 'date', align: 'center' }

boolean

체크박스. 클릭 즉시 @update:cell 이벤트 발생.

ts
{ key: 'active', title: '활성', type: 'boolean', align: 'center' }

select

드롭다운. optionsvalue로 저장하고 label로 표시합니다.

ts
{
  key: 'dept', title: '부서', type: 'select',
  options: [
    { value: 'dev', label: '개발팀' },
    { value: 'biz', label: '사업팀' },
  ]
}

badge

색상 태그 표시. optionscolor에 Tailwind 클래스를 지정합니다. 편집 불가.

ts
{
  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 숫자를 프로그레스 바로 표시. 편집 불가.

ts
{ key: 'completion', title: '완료율', type: 'progress' }

image

URL을 38×38 원형 썸네일로 표시. 편집 불가.

ts
{ key: 'avatar', title: '사진', type: 'image', align: 'center' }

button

클릭 가능한 버튼 셀. 클릭 시 @click:button 이벤트 발생.

ts
{
  key: 'action', title: '관리', type: 'button', align: 'center',
  options: [{ label: '상세보기' }]
}

URL을 target="_blank" 하이퍼링크로 표시. 편집 불가.

ts
{ key: 'website', title: '홈페이지', type: 'link' }

radio

인라인 라디오 버튼 그룹. 선택 즉시 @update:cell 이벤트 발생.

ts
{
  key: 'gender', title: '성별', type: 'radio', align: 'center',
  options: [
    { label: '남', value: 'M' },
    { label: '여', value: 'F' },
  ]
}

신규 타입 (v1.4+)

tag

string[] 배열 데이터를 칩(chip) UI로 렌더링합니다. 편집 불가.

  • 필터: 텍스트 포함 여부 (태그 문자열 전체를 대상으로 부분 일치)
  • 정렬: 태그 개수 기준 오름차순/내림차순
ts
{ key: 'tags', title: '태그', type: 'tag', width: 200 }
ts
// row 데이터 예시
{ id: 1, name: '홍길동', tags: ['긴급', '검토중'] }

currency

숫자 데이터를 통화 기호 + 천 단위 포맷으로 표시합니다. 편집 시 <input type="number">.

  • 필터: min/max 숫자 범위
  • 컬럼 옵션:
옵션타입기본값설명
currencySymbolstring'₩'금액 앞에 붙는 통화 기호
decimalsnumber0소수점 자릿수
ts
{
  key: 'price', title: '가격', type: 'currency', align: 'right', width: 140,
  currencySymbol: '₩',
  decimals: 0,
}
// 표시 예: ₩1,200,000

rating

숫자 값(1~N)을 별점(★) UI로 표시합니다. 별 클릭 즉시 @update:cell 이벤트 발생.

  • 필터: min/max 숫자 범위
  • 컬럼 옵션:
옵션타입기본값설명
maxRatingnumber5최대 별 수
ts
{ 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 날짜+시간 범위
ts
{ key: 'createdAt', title: '등록일시', type: 'datetime', width: 160, align: 'center' }
// row.createdAt 예: '2026-03-17 09:30'

color

CSS 색상 문자열을 색상 박스로 표시합니다. 색상 피커 클릭 즉시 @update:cell 이벤트 발생.

  • 필터: 텍스트 포함 여부 (색상 코드 문자열 기준)
ts
{ key: 'labelColor', title: '색상', type: 'color', align: 'center', width: 80 }
// row.labelColor 예: '#3b82f6'

email

이메일 문자열을 mailto: 링크로 표시합니다. 편집 시 <input type="email">.

  • 필터: 텍스트 포함 여부
ts
{ key: 'email', title: '이메일', type: 'email', width: 200 }

기타 타입

sparkline

number[] 배열 데이터를 SVG 미니 차트로 렌더링합니다. 편집 불가. sparklineType으로 line, area, bar, column 4가지 차트 스타일을 선택할 수 있습니다.

  • 편집: 불가
  • 필터: 없음
옵션타입기본값설명
sparklineType'line' | 'area' | 'bar' | 'column''line'차트 타입
sparklineColorstring'#3b82f6'라인/막대 색상
sparklineHeightnumber32SVG 높이(px)

차트 타입별 차이

타입설명
line<polyline>을 사용한 기본 라인 차트
area<polygon>을 사용한 라인 + 아래 영역 채움
bar<rect>을 사용한 수평 막대 차트
column<rect>을 사용한 수직 막대 차트
ts
// 라인 차트 (기본)
{ 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 스타일로 줄바꿈 유지
  • 필터: 텍스트 부분 일치
ts
{ key: 'memo', title: '메모', type: 'textarea', width: 200 }

전체 타입을 사용하는 예제

vue
<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>

Released under the MIT License.