ColorPicker(색상선택)
Va.ColorPicker — 컬러 스와치 + 팝업 팔레트 입력 필드
색상을 선택하는 입력 컴포넌트입니다. 좌측에 현재 색상을 보여주는 스와치, 우측에 hex 코드 텍스트 입력창이 있고, 스와치를 클릭하거나 필드에서 Enter를 누르면 벌집(honeycomb) 모양 컬러맵 팝업이 열립니다.
- 클래스: Va.ColorPicker — va_colorpicker.js:27
- short name: colorPicker
- 상속: Va.PureField (Input/Search/Number와 형제)
- 파일: va_component.js가 아니라 별도 파일 va_colorpicker.js 에 정의 (직접 import 필요)
- 베이스 CSS: va-colorpicker (+ PureField의 field-wrapper)

1. 기본 사용
import '../../lib/va_colorpicker.js'; // ← 별도 import 필요
// config 안에서
{
tagName: 'colorPicker',
value: '#FF0000',
onSelect: 'onColorSelect'
}
⚠️ import 필수: 다른 대부분의 컴포넌트는 va_component.js에 포함되어 있지만, ColorPicker는 별도 파일이라 사용 전 명시적으로 import해야 등록됩니다.
2. 다른 PureField 계열과의 차이
항목Va.InputVa.NumberVa.ColorPicker
| 파일 | va_component.js | va_component.js | va_colorpicker.js (별도) |
| 입력 방식 | 직접 타이핑 | 스피너 + 타이핑 | 팝업 팔레트 + hex 타이핑 |
| 팝업 | ✕ | ✕ | ✓ (컬러맵 + 그레이스케일) |
| 스와치 미리보기 | ✕ | ✕ | ✓ (좌측 색상 사각형) |
| 텍스트 숨김 옵션 | ✕ | ✕ | ✓ (showText) |
| 자체 파일 크기 | (공유) | (공유) | 36KB (독립) |
한 줄 요약: "hex 코드로 색을 지정하되, 컬러맵 팝업으로도 선택할 수 있는 필드."
3. 주요 속성
ColorPicker 전용
속성기본값설명
| showText | true | hex 코드 텍스트 입력창 표시 여부. false면 스와치만 보이는 미니 UI |
| popWidth | 270 | 팝업 너비(px) |
| expanded | false | 팝업 초기 상태 (거의 안 씀) |
PureField 상속
속성설명
| value | 현재 색상값 — hex 문자열 ('#FF0000') |
| placeholder | 플레이스홀더 (텍스트 필드용) |
| readonly / disabled | 상태. 스와치도 함께 disabled 처리됨 |
| size / appearance | 시각 스타일 |
| stopPropagation | 이벤트 버블링 차단 |
4. 팝업 UI 구성
showColorPickerPop()에서 두 부분을 렌더링합니다 (va_colorpicker.js:186-371):
1) 벌집형 컬러맵
- img_colormap.gif에 <map>으로 100+ 개의 육각형 영역을 정의
- 각 영역 클릭 시 사전 정의된 hex 값(예: #0066CC)이 선택
- 총 136개 색상 팔레트 (표준 웹 컬러 계열)
2) 그레이스케일 스트립
- #FFFFFF → #000000까지 16단계 회색
- 각 사각형 클릭으로 선택
⚠️ 커스텀 색상 자유 선택 불가 — 팔레트에 정의된 색만 선택 가능. 완전 자유 색상이 필요하면 hex 코드를 직접 타이핑해야 합니다.
⚠️ RGB/HSL 슬라이더 없음 — 색상값을 슬라이더로 조절하는 UI는 제공 안 됨. 벌집 팔레트 + hex 직접 입력만.
5. 이벤트
이벤트시그니처발생 시점
| select | (component, element, value) | 팝업에서 색상 클릭 시. value는 hex 문자열 |
| change | (component, element, evt) | 텍스트 필드에서 hex 직접 입력 후 change |
| focus / blur | 표준 | |
| beforePop | (component, element, evt) | 팝업 열리기 직전 |
| afterPop | (component, element, evt) | 팝업 열린 직후 |
| hidePop | (component, element, evt) | 팝업 닫힘 요청 시 |
| expand / collapse | 팝업 확장/축소 |
팝업 색상 클릭 흐름
onColorSelect(component, element, value) {
console.log('선택된 색:', value); // 예: "#0066CC"
// setValue()가 이미 호출된 상태
// colorDivElement의 배경색도 이미 변경됨
}
텍스트로 hex 직접 입력
사용자가 #123456 같은 hex를 타이핑하면 blur 시 스와치 배경색이 업데이트됩니다 (va_colorpicker.js:104-106).
⚠️ 입력 검증 없음 — 잘못된 hex(#GGG, red 등)를 넣어도 필드가 막지 않음. 스와치는 그냥 CSS의 관대함에 맡깁니다.
6. 메서드
메서드설명
| setValue(value) | 오버라이드됨 — 값 세팅 + 스와치 배경색 동시 업데이트 |
| getValue() | 현재 hex 문자열 반환 (PureField 위임) |
| showColorPickerPop(evt) | 팝업 강제 열기 |
| hideColorPickerPop() | 팝업 강제 닫기 |
| showPop() / hidePop() | (레거시 별칭, 실제로는 drawCalendar() 호출인데 이 메서드 존재 안 함 — 사용하지 말 것) |
| expand() / collapse() | 동일 (레거시) |
| setDisabled(bool) / setReadOnly(bool) | PureField 상속 |
| focus() / blur() | 포커스 제어 |
⚠️ showPop(), expand() 등에 drawCalendar() 호출 코드가 있음 — DatePicker에서 복사되며 남은 버그. 존재하지 않는 메서드라 호출 시 에러. showColorPickerPop() / hideColorPickerPop() 사용 권장.
7. 내부 구조
<div elname="element" class="va-colorpicker [size] [focused] ..." tag-name="colorPicker" field="true">
<div elname="fieldWrapper" class="field-wrapper">
<div elname="colorDiv" class="color-div" style="background-color:#FF0000; cursor:pointer">
← 클릭하면 팝업 열림
</div>
<input elname="field" type="text" value="#FF0000" style="border:0px">
<div elname="focusLine" class="focus-line"></div>
</div>
<div elname="popDiv" class="menu-button-pop-div">
<div elname="pop" class="va-menu-pop" style="position:absolute; display:none">
<div elname="popInner" class="color-picker-inner">
<!-- 벌집 컬러맵 + 그레이스케일 스트립 -->
</div>
</div>
</div>
</div>
핵심 트릭:
- colorDiv(스와치)를 fieldWrapper 안 fieldElement 앞에 삽입 → 좌측 정렬
- 팝업(popElement)은 열릴 때 getHiddenAreaElement()로 이동해 부모 stacking context 회피
- 자동 위치 조정: 뷰포트 하단을 넘치면 위로 뒤집기 (va_colorpicker.js:161-166)
8. 팝업 상태머신 연동
프레임워크의 공용 팝업 상태머신(Va.addAutoHide, Va.hideOtherComponents)에 편입됩니다:
- 다른 팝업(Combobox, DatePicker 등) 열려 있으면 자동으로 닫고 자기 팝업 표시
- 외부 클릭 시 자동 닫힘
- autoHide 이벤트 리스너로 팝업 닫힘 감지 → 필드 blur까지 dispatch
CLAUDE.md 6장의 "민감 영역" 팝업 상태머신에 이 컴포넌트도 참여합니다.
9. showText: false — 스와치 전용 모드
hex 텍스트 없이 스와치만 보이는 미니 버전:
{
tagName: 'colorPicker',
value: '#FF0000',
showText: false,
style: 'width:40px; height:32px'
}
- 텍스트 필드 숨김
- 스와치가 flex:1로 필드 전체 폭 차지
- 아이콘/툴바 자리에 넣기 좋음
10. Va.ColorPicker vs Va.ColorField
같은 파일에 형제 컴포넌트가 있습니다 (va_colorpicker.js:431):
컴포넌트역할
| Va.ColorPicker | 순수 컬러 입력 (라벨 없음, 이 문서 대상) |
| Va.ColorField | ColorPicker + Field 래퍼 (라벨/검증/설명 포함) |
Field 계열의 패턴 그대로. 라벨이 필요하면 colorField, 인라인이면 colorPicker.
11. 언제 쓰나
ColorPicker가 맞을 때
- 색상 선택 UI (테마 커스터마이즈, 태그 색상, 카테고리 색상)
- 관리자 페이지에서 스타일 커스텀
- 사용자별 강조 색상 지정
다른 걸 쓸 때
- 자유 RGB/HSL 조절 필요 → 별도 커스텀 (프레임워크에 없음)
- 라벨 필요 → Va.ColorField
- 사전 정의된 몇 개 색상만 선택 → Va.Combobox + 각 옵션에 색 스와치 렌더링
- 컬러팔레트 여러 개 선택 → 여러 ColorPicker 나열
12. 알아두면 좋을 주의사항
- va_colorpicker.js import 필수 — 사용 전 명시적 import 없으면 tagName:'colorPicker' 인식 못 함.
- 팔레트 색상만 선택 가능 — 벌집 팔레트에 없는 색은 hex 직접 타이핑 필요.
- RGB/HSL/HSV 슬라이더 없음 — 정밀 색상 조절 UI 부재.
- 입력 검증 없음 — #GGG 같은 잘못된 hex도 그대로 들어감. 필요하면 change 콜백에서 정규식 검증.
- showPop()/expand() 사용 금지 — 존재하지 않는 drawCalendar() 호출 → 에러. showColorPickerPop() 사용.
- 팝업 열 때 다른 팝업 자동 닫힘 — Va.hideOtherComponents(this) 호출로 UX 일관성.
- 팝업 뷰포트 처리 — 아래로 넘치면 위로 뒤집기 자동. IntersectionObserver는 없음(MenuButton과 달리).
- ico_colormap.gif 이미지 의존 — lib/img/img_colormap.gif 파일이 있어야 팔레트 렌더됨. 리소스 누락 시 팝업 UI가 깨짐.
- hex 값 대소문자 — 팝업 선택 시 대문자로 세팅(#0066CC). 서버가 소문자만 받으면 변환 필요.
- 투명도(alpha) 미지원 — RGBA 형식(#FF000080) 등 4번째 채널 없음.
- 접근성 부족 — 색상 선택 UI에 ARIA 레이블/키보드 네비게이션이 취약. 색맹 사용자용 대체 라벨 없음.
13. 흔한 조합 예시
// 폼 안 컬러 선택 (ColorField 대신 인라인)
{
tagName: 'colorPicker',
value: '#3366CC',
style: 'width:200px',
onSelect: 'onPickColor'
}
// 툴바 아이콘형 (텍스트 숨김)
{
tagName: 'colorPicker',
value: '#000000',
showText: false,
style: 'width:32px; height:32px'
}
// 팝업 폭 조정
{
tagName: 'colorPicker',
popWidth: 320
}
// 라벨 필요 → ColorField 사용
{
tagName: 'colorField',
label: '카테고리 색상',
value: '#FF6600',
required: true
}