{"version":3,"file":"JShuttle.vue2.cjs","sources":["../../../../src/components/organisms/JShuttle.vue"],"sourcesContent":["<template>\n  <div :class=\"cn('j-shuttle', props.class)\">\n    <div class=\"j-shuttle-container\">\n      <!-- 왼쪽 패널 -->\n      <div class=\"j-shuttle-panel\">\n        <div class=\"j-shuttle-panel-card\">\n          <!-- 헤더 -->\n          <div class=\"j-shuttle-panel-header\">\n            <h4 class=\"j-shuttle-panel-title\">\n              {{ leftTitle || 'Unmapped' }}\n            </h4>\n            <span class=\"j-shuttle-panel-count\">\n              {{ filteredLeftData.length }} items\n            </span>\n          </div>\n\n          <!-- 검색 -->\n          <div v-if=\"searchable\" class=\"j-shuttle-search\">\n            <JInput\n              v-model=\"leftSearch\"\n              placeholder=\"검색...\"\n            >\n              <template #prefix>\n                <JIcon name=\"search\" class=\"w-4 h-4 text-muted-foreground\" />\n              </template>\n            </JInput>\n          </div>\n\n          <!-- 그리드 -->\n          <div class=\"j-shuttle-grid-wrapper\">\n            <JGrid\n              ref=\"leftGridRef\"\n              v-model:selected-rows=\"leftSelectedRows\"\n              :row-data=\"filteredLeftData\"\n              :column-defs=\"columnDefs\"\n              :checkbox=\"true\"\n              :row-numbers=\"false\"\n              :pagination=\"false\"\n              class=\"h-full\"\n            />\n          </div>\n\n          <!-- 푸터 (선택 개수) -->\n          <div class=\"j-shuttle-panel-footer\">\n            <span class=\"text-xs text-muted-foreground\">\n              <template v-if=\"leftSelectedRows.length > 0\">\n                <strong>{{ leftSelectedRows.length }}</strong> selected\n              </template>\n              <template v-else>\n                No items selected\n              </template>\n            </span>\n          </div>\n        </div>\n      </div>\n\n      <!-- 중앙 버튼 영역 -->\n      <div class=\"j-shuttle-actions\">\n        <div class=\"j-shuttle-actions-divider\" />\n        <div class=\"j-shuttle-actions-buttons\">\n          <JButton\n            styletype=\"primary\"\n            size=\"xs\"\n            :disabled=\"leftSelectedRows.length === 0\"\n            class=\"j-shuttle-action-btn\"\n            title=\"선택한 항목을 오른쪽으로 이동\"\n            @click=\"moveToRight\"\n          >\n            <JIcon name=\"chevronRight\" class=\"w-3.5 h-3.5\" />\n          </JButton>\n          <JButton\n            variant=\"outline\"\n            size=\"xs\"\n            :disabled=\"rightSelectedRows.length === 0\"\n            class=\"j-shuttle-action-btn\"\n            title=\"선택한 항목을 왼쪽으로 이동\"\n            @click=\"moveToLeft\"\n          >\n            <JIcon name=\"chevronLeft\" class=\"w-3.5 h-3.5\" />\n          </JButton>\n        </div>\n      </div>\n\n      <!-- 오른쪽 패널 -->\n      <div class=\"j-shuttle-panel\">\n        <div class=\"j-shuttle-panel-card\">\n          <!-- 헤더 -->\n          <div class=\"j-shuttle-panel-header j-shuttle-panel-header--primary\">\n            <h4 class=\"j-shuttle-panel-title\">\n              {{ rightTitle || 'Mapped' }}\n            </h4>\n            <span class=\"j-shuttle-panel-count j-shuttle-panel-count--primary\">\n              {{ filteredRightData.length }} items\n            </span>\n          </div>\n\n          <!-- 검색 -->\n          <div v-if=\"searchable\" class=\"j-shuttle-search\">\n            <JInput\n              v-model=\"rightSearch\"\n              placeholder=\"검색...\"\n            >\n              <template #prefix>\n                <JIcon name=\"search\" class=\"w-4 h-4 text-muted-foreground\" />\n              </template>\n            </JInput>\n          </div>\n\n          <!-- 그리드 -->\n          <div class=\"j-shuttle-grid-wrapper\">\n            <JGrid\n              ref=\"rightGridRef\"\n              v-model:selected-rows=\"rightSelectedRows\"\n              :row-data=\"filteredRightData\"\n              :column-defs=\"columnDefs\"\n              :checkbox=\"true\"\n              :row-numbers=\"false\"\n              :pagination=\"false\"\n              class=\"h-full\"\n            />\n          </div>\n\n          <!-- 푸터 (선택 개수) -->\n          <div class=\"j-shuttle-panel-footer\">\n            <span class=\"text-xs text-muted-foreground\">\n              <template v-if=\"rightSelectedRows.length > 0\">\n                <strong>{{ rightSelectedRows.length }}</strong> selected\n              </template>\n              <template v-else>\n                No items selected\n              </template>\n            </span>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed } from 'vue'\nimport { JGrid, JButton, JIcon, JInput } from '@/components/atoms'\nimport { cn } from '@/lib/utils'\nimport type { JShuttleProps, JShuttleEmits, ShuttleItem } from '@/types/shuttle.types'\n\nconst props = withDefaults(defineProps<JShuttleProps>(), {\n  searchable: false,\n  leftTitle: 'Unmapped',\n  rightTitle: 'Mapped',\n})\n\nconst emit = defineEmits<JShuttleEmits>()\n\n// 선택된 행\nconst leftSelectedRows = ref<ShuttleItem[]>([])\nconst rightSelectedRows = ref<ShuttleItem[]>([])\n\n// 검색어\nconst leftSearch = ref('')\nconst rightSearch = ref('')\n\n// 그리드 참조\nconst leftGridRef = ref()\nconst rightGridRef = ref()\n\n// 검색 필터링된 데이터\nconst filteredLeftData = computed(() => {\n  if (!props.searchable || !leftSearch.value) {\n    return props.leftData\n  }\n  const search = leftSearch.value.toLowerCase()\n  return props.leftData.filter((item) => {\n    return Object.values(item).some((val) =>\n      String(val).toLowerCase().includes(search)\n    )\n  })\n})\n\nconst filteredRightData = computed(() => {\n  if (!props.searchable || !rightSearch.value) {\n    return props.rightData\n  }\n  const search = rightSearch.value.toLowerCase()\n  return props.rightData.filter((item) => {\n    return Object.values(item).some((val) =>\n      String(val).toLowerCase().includes(search)\n    )\n  })\n})\n\n// 왼쪽 → 오른쪽 이동\nfunction moveToRight() {\n  if (leftSelectedRows.value.length === 0) return\n\n  const itemsToMove = [...leftSelectedRows.value]\n  const newLeftData = props.leftData.filter(\n    (item) => !itemsToMove.some((selected) => selected.id === item.id)\n  )\n  const newRightData = [...props.rightData, ...itemsToMove]\n\n  emit('update:leftData', newLeftData)\n  emit('update:rightData', newRightData)\n  emit('move', { items: itemsToMove, direction: 'toRight' })\n\n  leftSelectedRows.value = []\n}\n\n// 오른쪽 → 왼쪽 이동\nfunction moveToLeft() {\n  if (rightSelectedRows.value.length === 0) return\n\n  const itemsToMove = [...rightSelectedRows.value]\n  const newRightData = props.rightData.filter(\n    (item) => !itemsToMove.some((selected) => selected.id === item.id)\n  )\n  const newLeftData = [...props.leftData, ...itemsToMove]\n\n  emit('update:leftData', newLeftData)\n  emit('update:rightData', newRightData)\n  emit('move', { items: itemsToMove, direction: 'toLeft' })\n\n  rightSelectedRows.value = []\n}\n\ndefineExpose({\n  leftGridRef,\n  rightGridRef,\n})\n</script>\n\n<style scoped>\n.j-shuttle {\n  width: 100%;\n  height: 100%;\n  min-height: 500px;\n}\n\n.j-shuttle-container {\n  display: flex;\n  gap: 0.5rem;\n  height: 100%;\n  padding: 0;\n  border-radius: 0;\n  background: transparent;\n}\n\n.j-shuttle-panel {\n  flex: 1;\n  display: flex;\n  flex-direction: column;\n}\n\n.j-shuttle-panel-card {\n  display: flex;\n  flex-direction: column;\n  height: 100%;\n  background: hsl(var(--card));\n  border: 1px solid hsl(var(--border));\n  border-radius: 0.125rem; /* rounded-sm */\n  box-shadow: none;\n  overflow: hidden;\n}\n\n.j-shuttle-panel-header {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  padding: 0.4rem 1rem;\n  border-bottom: 1px solid hsl(var(--border));\n  background: hsl(var(--muted) / 0.3);\n  transition: background-color 0.2s ease;\n}\n\n.j-shuttle-panel-header--primary {\n  background: linear-gradient(135deg,\n    hsl(var(--primary) / 0.08) 0%,\n    hsl(var(--primary) / 0.02) 100%);\n}\n\n.j-shuttle-panel-title {\n  font-size: 0.8125rem;\n  font-weight: 600;\n  color: hsl(var(--foreground));\n  letter-spacing: -0.01em;\n}\n\n.j-shuttle-panel-count {\n  font-size: 0.75rem;\n  font-weight: 500;\n  color: hsl(var(--muted-foreground));\n  padding: 0.25rem 0.625rem;\n  border-radius: 0.125rem; /* rounded-sm */\n  background: hsl(var(--muted));\n  border: 1px solid hsl(var(--border) / 0.5);\n}\n\n.j-shuttle-panel-count--primary {\n  color: hsl(var(--primary));\n  background: hsl(var(--primary) / 0.1);\n  border-color: hsl(var(--primary) / 0.2);\n}\n\n.j-shuttle-search {\n  padding: 0.75rem 1rem;\n  border-bottom: 1px solid hsl(var(--border) / 0.5);\n  background: hsl(var(--card));\n}\n\n.j-shuttle-grid-wrapper {\n  flex: 1;\n  overflow: hidden;\n  padding: 0;\n  background: hsl(var(--background));\n}\n\n.j-shuttle-panel-footer {\n  display: flex;\n  align-items: center;\n  justify-content: flex-end;\n  padding: 0.625rem 1rem;\n  border-top: 1px solid hsl(var(--border) / 0.5);\n  background: hsl(var(--muted) / 0.2);\n  min-height: 2.5rem;\n}\n\n.j-shuttle-actions {\n  position: relative;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  justify-content: center;\n  padding: 0;\n  min-width: 2.5rem;\n}\n\n.j-shuttle-actions-divider {\n  position: absolute;\n  width: 1px;\n  height: 100%;\n  background: linear-gradient(to bottom,\n    transparent 0%,\n    hsl(var(--border)) 10%,\n    hsl(var(--border)) 90%,\n    transparent 100%);\n}\n\n.j-shuttle-actions-buttons {\n  position: relative;\n  display: flex;\n  flex-direction: column;\n  gap: 0.375rem;\n  padding: 0.375rem;\n  background: transparent;\n  border: none;\n  box-shadow: none;\n}\n\n.j-shuttle-action-btn {\n  min-width: 2rem;\n  min-height: 2rem;\n  transition: all 0.2s ease;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n}\n\n.j-shuttle-action-btn:not(:disabled):hover {\n  transform: scale(1.08);\n  box-shadow: 0 2px 6px 0 rgb(0 0 0 / 0.12);\n}\n\n.j-shuttle-action-btn:not(:disabled):active {\n  transform: scale(1.02);\n}\n\n.j-shuttle-action-btn:disabled {\n  opacity: 1;\n  background: hsl(var(--muted));\n  color: hsl(var(--muted-foreground) / 0.4);\n  border-color: hsl(var(--border));\n  cursor: not-allowed;\n  transform: scale(1);\n}\n\n/* 다크모드 조정 */\n.dark .j-shuttle-container {\n  background: linear-gradient(135deg, \n    hsl(var(--muted) / 0.2) 0%, \n    hsl(var(--muted) / 0.05) 100%);\n}\n\n.dark .j-shuttle-panel-card {\n  box-shadow: 0 2px 4px 0 rgb(0 0 0 / 0.2);\n}\n\n.dark .j-shuttle-panel-card:hover {\n  box-shadow: 0 4px 6px 0 rgb(0 0 0 / 0.3);\n}\n</style>\n"],"names":["props","__props","emit","__emit","leftSelectedRows","ref","rightSelectedRows","leftSearch","rightSearch","leftGridRef","rightGridRef","filteredLeftData","computed","search","item","val","filteredRightData","moveToRight","itemsToMove","newLeftData","selected","newRightData","moveToLeft","__expose","_createElementBlock","_normalizeClass","_unref","cn","_createElementVNode","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_toDisplayString","_hoisted_6","_openBlock","_hoisted_7","_createVNode","JInput","$event","JIcon","_hoisted_8","JGrid","_hoisted_9","_hoisted_10","_Fragment","_hoisted_11","_hoisted_12","JButton","_hoisted_13","_hoisted_14","_hoisted_15","_hoisted_16","_hoisted_17","_hoisted_18","_hoisted_19","_hoisted_20","_hoisted_21"],"mappings":"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"}