{"version":3,"file":"JCombo.vue.cjs","sources":["../../../../src/components/atoms/JCombo.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/shadcn'\n\n// 빈 문자열 value를 위한 내부 플레이스홀더\n// reka-ui SelectItem이 빈 문자열을 처리하지 못하는 버그 우회\nconst EMPTY_VALUE_PLACEHOLDER = '__EMPTY_STRING__'\n\nexport interface Option {\n  value: string | number\n  label: string\n}\n\ntype StyleType =\n  | 'default'   // 기본 스타일\n  | 'error'     // 에러 상태\n  | 'success'   // 성공 상태\n  | 'warning'   // 경고 상태\n  | 'sm'        // 작은 크기\n  | 'lg'        // 큰 크기\n\nconst props = withDefaults(\n  defineProps<{\n    modelValue?: string | number\n    options?: Option[]\n    placeholder?: string\n    disabled?: boolean\n    required?: boolean\n    name?: string\n    id?: string\n    multiple?: boolean\n    class?: string\n    /** 스타일 프리셋 */\n    styletype?: StyleType\n  }>(),\n  {\n    options: () => [],\n    placeholder: '',\n    disabled: false,\n    required: false,\n    multiple: false,\n    styletype: 'default',\n  },\n)\n\nconst emit = defineEmits<{\n  'update:modelValue': [value: string | number]\n  'change': [value: string | number]\n  'focus': [event: FocusEvent]\n  'blur': [event: FocusEvent]\n}>()\n\n/**\n * styletype -> class 매핑\n */\nconst STYLE_PRESETS: Record<StyleType, { class: string }> = {\n  default: { class: '' },\n  error: { \n    class: 'border-destructive focus:ring-destructive',\n  },\n  success: { \n    class: 'border-green-500 focus:ring-green-500',\n  },\n  warning: { \n    class: 'border-amber-500 focus:ring-amber-500',\n  },\n  sm: { \n    class: 'h-7 text-xs px-2',\n  },\n  lg: { \n    class: 'h-12 text-base px-4',\n  },\n}\n\nconst triggerClass = computed(() => {\n  const styleKey = props.styletype || 'default'\n  const preset = STYLE_PRESETS[styleKey] ?? STYLE_PRESETS.default\n  return [preset?.class, props.class].filter(Boolean).join(' ')\n})\n\n/**\n * 외부 value를 내부 value로 변환\n * 빈 문자열 -> __EMPTY_STRING__\n */\nconst toInternalValue = (value: string | number | undefined): string => {\n  if (value === '' || value === undefined) {\n    return EMPTY_VALUE_PLACEHOLDER\n  }\n  return String(value)\n}\n\n/**\n * 내부 value를 외부 value로 변환\n * __EMPTY_STRING__ -> ''\n */\nconst toExternalValue = (value: string): string | number => {\n  if (value === EMPTY_VALUE_PLACEHOLDER) {\n    return ''\n  }\n  return value\n}\n\n/**\n * 옵션의 value를 내부 형식으로 변환\n * 빈 문자열 value를 가진 옵션 -> __EMPTY_STRING__으로 변환\n */\nconst processedOptions = computed(() => {\n  return props.options.map((option) => ({\n    ...option,\n    value: toInternalValue(option.value),\n  }))\n})\n\n/**\n * 현재 modelValue를 내부 형식으로 변환\n */\nconst internalModelValue = computed(() => toInternalValue(props.modelValue))\n\nconst handleChange = (internalValue: string) => {\n  const externalValue = toExternalValue(internalValue)\n  emit('update:modelValue', externalValue)\n  emit('change', externalValue)\n}\n</script>\n\n<template>\n  <Select\n    :model-value=\"internalModelValue\"\n    :disabled=\"disabled\"\n    :required=\"required\"\n    :name=\"name\"\n    @update:model-value=\"(value) => handleChange(value as string)\"\n    @focus=\"emit('focus', $event as FocusEvent)\"\n    @blur=\"emit('blur', $event as FocusEvent)\"\n  >\n    <SelectTrigger :id=\"id\" :class=\"triggerClass\">\n      <SelectValue :placeholder=\"placeholder\" />\n    </SelectTrigger>\n    <SelectContent>\n      <SelectItem\n        v-for=\"option in processedOptions\"\n        :key=\"option.value\"\n        :value=\"option.value\"\n      >\n        {{ option.label }}\n      </SelectItem>\n    </SelectContent>\n  </Select>\n</template>\n"],"names":["EMPTY_VALUE_PLACEHOLDER","props","__props","emit","__emit","STYLE_PRESETS","triggerClass","computed","styleKey","toInternalValue","value","toExternalValue","processedOptions","option","internalModelValue","handleChange","internalValue","externalValue","_createBlock","_unref","Select","_cache","$event","_createVNode","SelectTrigger","SelectValue","SelectContent","_createElementBlock","_Fragment","_renderList","SelectItem","_createTextVNode","_toDisplayString"],"mappings":"6XAMMA,EAA0B,oWAehC,MAAMC,EAAQC,EAwBRC,EAAOC,EAUPC,EAAsD,CAC1D,QAAS,CAAE,MAAO,EAAA,EAClB,MAAO,CACL,MAAO,2CAAA,EAET,QAAS,CACP,MAAO,uCAAA,EAET,QAAS,CACP,MAAO,uCAAA,EAET,GAAI,CACF,MAAO,kBAAA,EAET,GAAI,CACF,MAAO,qBAAA,CACT,EAGIC,EAAeC,EAAAA,SAAS,IAAM,CAClC,MAAMC,EAAWP,EAAM,WAAa,UAEpC,MAAO,EADQI,EAAcG,CAAQ,GAAKH,EAAc,UACxC,MAAOJ,EAAM,KAAK,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,CAC9D,CAAC,EAMKQ,EAAmBC,GACnBA,IAAU,IAAMA,IAAU,OACrBV,EAEF,OAAOU,CAAK,EAOfC,EAAmBD,GACnBA,IAAUV,EACL,GAEFU,EAOHE,EAAmBL,EAAAA,SAAS,IACzBN,EAAM,QAAQ,IAAKY,IAAY,CACpC,GAAGA,EACH,MAAOJ,EAAgBI,EAAO,KAAK,CAAA,EACnC,CACH,EAKKC,EAAqBP,EAAAA,SAAS,IAAME,EAAgBR,EAAM,UAAU,CAAC,EAErEc,EAAgBC,GAA0B,CAC9C,MAAMC,EAAgBN,EAAgBK,CAAa,EACnDb,EAAK,oBAAqBc,CAAa,EACvCd,EAAK,SAAUc,CAAa,CAC9B,8BAIEC,EAAAA,YAqBSC,EAAAA,MAAAC,EAAAA,OAAA,EAAA,CApBN,cAAaN,EAAA,MACb,SAAUZ,EAAA,SACV,SAAUA,EAAA,SACV,KAAMA,EAAA,KACN,sBAAkBmB,EAAA,CAAA,IAAAA,EAAA,CAAA,EAAGX,GAAUK,EAAaL,CAAK,GACjD,QAAKW,EAAA,CAAA,IAAAA,EAAA,CAAA,EAAAC,GAAEnB,EAAI,QAAUmB,CAAM,GAC3B,OAAID,EAAA,CAAA,IAAAA,EAAA,CAAA,EAAAC,GAAEnB,EAAI,OAASmB,CAAM,EAAA,qBAE1B,IAEgB,CAFhBC,cAEgBJ,EAAAA,MAAAK,EAAAA,OAAA,EAAA,CAFA,GAAItB,EAAA,GAAK,uBAAOI,EAAA,KAAY,CAAA,qBAC1C,IAA0C,CAA1CiB,EAAAA,YAA0CJ,EAAAA,MAAAM,SAAA,EAAA,CAA5B,YAAavB,EAAA,aAAW,KAAA,EAAA,CAAA,aAAA,CAAA,CAAA,0BAExCqB,EAAAA,YAQgBJ,EAAAA,MAAAO,SAAA,EAAA,KAAA,mBANZ,IAAkC,kBADpCC,EAAAA,mBAMaC,EAAAA,SAAA,KAAAC,EAAAA,WALMjB,EAAA,MAAVC,kBADTK,EAAAA,YAMaC,EAAAA,MAAAW,EAAAA,OAAA,EAAA,CAJV,IAAKjB,EAAO,MACZ,MAAOA,EAAO,KAAA,qBAEf,IAAkB,CAAfkB,EAAAA,gBAAAC,EAAAA,gBAAAnB,EAAO,KAAK,EAAA,CAAA,CAAA"}