컴포넌트/필드 컴포넌트

ColorPicker(색상선택)

VanillaFront 2026. 9. 10. 15:02

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. 알아두면 좋을 주의사항

  1. va_colorpicker.js import 필수 — 사용 전 명시적 import 없으면 tagName:'colorPicker' 인식 못 함.
  2. 팔레트 색상만 선택 가능 — 벌집 팔레트에 없는 색은 hex 직접 타이핑 필요.
  3. RGB/HSL/HSV 슬라이더 없음 — 정밀 색상 조절 UI 부재.
  4. 입력 검증 없음  #GGG 같은 잘못된 hex도 그대로 들어감. 필요하면 change 콜백에서 정규식 검증.
  5. showPop()/expand() 사용 금지 — 존재하지 않는 drawCalendar() 호출 → 에러. showColorPickerPop() 사용.
  6. 팝업 열 때 다른 팝업 자동 닫힘  Va.hideOtherComponents(this) 호출로 UX 일관성.
  7. 팝업 뷰포트 처리 — 아래로 넘치면 위로 뒤집기 자동. IntersectionObserver는 없음(MenuButton과 달리).
  8. ico_colormap.gif 이미지 의존  lib/img/img_colormap.gif 파일이 있어야 팔레트 렌더됨. 리소스 누락 시 팝업 UI가 깨짐.
  9. hex 값 대소문자 — 팝업 선택 시 대문자로 세팅(#0066CC). 서버가 소문자만 받으면 변환 필요.
  10. 투명도(alpha) 미지원 — RGBA 형식(#FF000080) 등 4번째 채널 없음.
  11. 접근성 부족 — 색상 선택 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
}

'컴포넌트 > 필드 컴포넌트' 카테고리의 다른 글

ComboboxField (콤보박스필드)  (0) 2026.09.10
ColorField (색상필드)  (0) 2026.09.10
NumberField (숫자필드)  (0) 2026.09.10
Number (숫자)  (0) 2026.09.10
SearchField (검색필드)  (0) 2026.09.10