{"version":3,"file":"JImage.vue.cjs","sources":["../../../../src/components/atoms/JImage.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\n\ntype StyleType = 'default' | 'primary' | 'secondary' | 'muted' | 'sm' | 'lg' | 'rounded'\n\nconst props = withDefaults(\n  defineProps<{\n    /** 이미지 소스 */\n    src?: string\n    /** 이미지 너비 */\n    width?: string | number\n    /** 이미지 높이 */\n    height?: string | number\n    /** 이미지 대체 텍스트 */\n    alt?: string\n    /** 이미지 스타일 테마 */\n    styletype?: StyleType\n    /** 에러 메시지 */\n    errorText?: string\n    /** 플레이스홀더 텍스트 */\n    placeholder?: string\n    /** 클릭 가능 여부 */\n    clickable?: boolean\n    /** 추가 CSS 클래스 */\n    class?: string\n  }>(),\n  {\n    styletype: 'default',\n    alt: '',\n    errorText: '',\n    placeholder: '이미지를 불러올 수 없습니다',\n    clickable: false,\n  },\n)\n\nconst emit = defineEmits<{\n  'click': [event: MouseEvent]\n  'mouseover': [event: MouseEvent]\n  'mouseout': [event: MouseEvent]\n}>()\n\nconst STYLE_PRESETS: Record<StyleType, { class?: string }> = {\n  default: { class: '' },\n  primary: { class: 'border-primary border-2' },\n  secondary: { class: 'border-secondary border-2' },\n  muted: { class: 'border-muted border-2' },\n  sm: { class: 'w-8 h-8' },\n  lg: { class: 'w-16 h-16' },\n  rounded: { class: 'rounded-full' },\n}\n\nconst isError = ref(false)\nconst isLoading = ref(false) // 초기 로딩 상태를 false로 변경\n\nconst imageStyle = computed(() => {\n  const style: Record<string, string> = {}\n  \n  if (props.width) {\n    style.width = typeof props.width === 'number' ? `${props.width}px` : props.width\n  }\n  \n  if (props.height) {\n    style.height = typeof props.height === 'number' ? `${props.height}px` : props.height\n  }\n  \n  return style\n})\n\nconst imageClass = computed(() => {\n  const styleKey = props.styletype || 'default'\n  const preset = STYLE_PRESETS[styleKey] ?? STYLE_PRESETS.default\n  \n  const classes = [\n    'object-cover',\n    styleKey === 'rounded' ? 'rounded-full' : 'rounded-md',\n    preset?.class,\n    props.clickable ? 'cursor-pointer hover:opacity-80 transition-opacity' : '',\n    props.class\n  ].filter(Boolean).join(' ')\n\n  return classes\n})\n\nconst handleClick = (event: MouseEvent) => {\n  if (props.clickable) {\n    emit('click', event)\n  }\n}\n\nconst handleMouseOver = (event: MouseEvent) => {\n  emit('mouseover', event)\n}\n\nconst handleMouseOut = (event: MouseEvent) => {\n  emit('mouseout', event)\n}\n\nconst handleImageLoad = () => {\n  isLoading.value = false\n  isError.value = false\n}\n\nconst handleImageError = () => {\n  isLoading.value = false\n  isError.value = true\n}\n</script>\n\n<template>\n  <div class=\"inline-block\">\n    <!-- 로딩 상태 -->\n    <div v-if=\"isLoading\" class=\"flex items-center justify-center bg-muted rounded-md\" :style=\"imageStyle\">\n      <div class=\"text-muted-foreground text-sm\">로딩 중...</div>\n    </div>\n    \n    <!-- 에러 상태 -->\n    <div v-else-if=\"isError\" class=\"flex items-center justify-center bg-muted rounded-md text-center\" :style=\"imageStyle\">\n      <div class=\"text-muted-foreground text-sm\">\n        {{ errorText || placeholder }}\n      </div>\n    </div>\n    \n    <!-- 이미지 표시 -->\n    <img \n      v-else \n      :src=\"src\"\n      :alt=\"alt\"\n      :style=\"imageStyle\"\n      :class=\"imageClass\"\n      @load=\"handleImageLoad\" \n      @error=\"handleImageError\"\n      @click=\"handleClick\"\n      @mouseover=\"handleMouseOver\"\n      @mouseout=\"handleMouseOut\"\n    />\n  </div>\n</template>\n"],"names":["props","__props","emit","__emit","STYLE_PRESETS","isError","ref","isLoading","imageStyle","computed","style","imageClass","styleKey","preset","handleClick","event","handleMouseOver","handleMouseOut","handleImageLoad","handleImageError","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_hoisted_2","_toDisplayString"],"mappings":"ifAKA,MAAMA,EAAQC,EA8BRC,EAAOC,EAMPC,EAAuD,CAC3D,QAAS,CAAE,MAAO,EAAA,EAClB,QAAS,CAAE,MAAO,yBAAA,EAClB,UAAW,CAAE,MAAO,2BAAA,EACpB,MAAO,CAAE,MAAO,uBAAA,EAChB,GAAI,CAAE,MAAO,SAAA,EACb,GAAI,CAAE,MAAO,WAAA,EACb,QAAS,CAAE,MAAO,cAAA,CAAe,EAG7BC,EAAUC,EAAAA,IAAI,EAAK,EACnBC,EAAYD,EAAAA,IAAI,EAAK,EAErBE,EAAaC,EAAAA,SAAS,IAAM,CAChC,MAAMC,EAAgC,CAAA,EAEtC,OAAIV,EAAM,QACRU,EAAM,MAAQ,OAAOV,EAAM,OAAU,SAAW,GAAGA,EAAM,KAAK,KAAOA,EAAM,OAGzEA,EAAM,SACRU,EAAM,OAAS,OAAOV,EAAM,QAAW,SAAW,GAAGA,EAAM,MAAM,KAAOA,EAAM,QAGzEU,CACT,CAAC,EAEKC,EAAaF,EAAAA,SAAS,IAAM,CAChC,MAAMG,EAAWZ,EAAM,WAAa,UAC9Ba,EAAST,EAAcQ,CAAQ,GAAKR,EAAc,QAUxD,MARgB,CACd,eACAQ,IAAa,UAAY,eAAiB,aAC1CC,GAAQ,MACRb,EAAM,UAAY,qDAAuD,GACzEA,EAAM,KAAA,EACN,OAAO,OAAO,EAAE,KAAK,GAAG,CAG5B,CAAC,EAEKc,EAAeC,GAAsB,CACrCf,EAAM,WACRE,EAAK,QAASa,CAAK,CAEvB,EAEMC,EAAmBD,GAAsB,CAC7Cb,EAAK,YAAaa,CAAK,CACzB,EAEME,EAAkBF,GAAsB,CAC5Cb,EAAK,WAAYa,CAAK,CACxB,EAEMG,EAAkB,IAAM,CAC5BX,EAAU,MAAQ,GAClBF,EAAQ,MAAQ,EAClB,EAEMc,EAAmB,IAAM,CAC7BZ,EAAU,MAAQ,GAClBF,EAAQ,MAAQ,EAClB,gBAIEe,YAAA,EAAAC,qBA0BM,MA1BNC,EA0BM,CAxBOf,EAAA,qBAAXc,EAAAA,mBAEM,MAAA,OAFgB,MAAM,uDAAwD,uBAAOb,EAAA,KAAU,CAAA,mBACnGe,EAAAA,mBAAwD,MAAA,CAAnD,MAAM,+BAAA,EAAgC,UAAO,EAAA,CAAA,QAIpClB,EAAA,qBAAhBgB,EAAAA,mBAIM,MAAA,OAJmB,MAAM,mEAAoE,uBAAOb,EAAA,KAAU,CAAA,GAClHe,qBAEM,MAFNC,EAEMC,EAAAA,gBADDxB,EAAA,WAAaA,EAAA,WAAW,EAAA,CAAA,CAAA,qBAK/BoB,EAAAA,mBAWE,MAAA,OATC,IAAKpB,EAAA,IACL,IAAKA,EAAA,IACL,uBAAOO,EAAA,KAAU,EACjB,uBAAOG,EAAA,KAAU,EACjB,OAAMO,EACN,QAAOC,EACP,QAAOL,EACP,YAAWE,EACX,WAAUC,CAAA"}