@j-solution/components 2.0.4 → 2.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
- import { defineComponent as P, computed as s, ref as D, watch as _, createBlock as u, openBlock as o, unref as v, normalizeClass as m, withCtx as f, createVNode as y, createElementVNode as g, createElementBlock as p, Fragment as C, renderList as k, createCommentVNode as T, toDisplayString as w, renderSlot as L, resolveDynamicComponent as F, mergeProps as H, nextTick as $ } from "vue";
1
+ import { defineComponent as P, computed as i, ref as D, watch as _, createBlock as u, openBlock as n, unref as v, normalizeClass as f, withCtx as m, createVNode as y, createElementVNode as b, createElementBlock as p, Fragment as C, renderList as k, createCommentVNode as T, toDisplayString as w, renderSlot as L, resolveDynamicComponent as F, mergeProps as H, nextTick as $ } from "vue";
2
2
  import "../shadcn/index.js";
3
3
  import { X as J } from "lucide-vue-next";
4
- import { cn as b } from "../../lib/utils.js";
4
+ import { cn as g } from "../../lib/utils.js";
5
5
  import R from "../atoms/JIcon.vue.js";
6
6
  import U from "../shadcn/Tabs.vue.js";
7
7
  import W from "../shadcn/TabsList.vue.js";
@@ -10,7 +10,7 @@ import Y from "../shadcn/TabsContent.vue.js";
10
10
  const q = { class: "flex-1 truncate" }, G = ["aria-label", "onClick"], K = {
11
11
  key: 1,
12
12
  class: "p-4"
13
- }, M = { class: "text-muted-foreground" }, ie = /* @__PURE__ */ P({
13
+ }, M = { class: "text-muted-foreground" }, se = /* @__PURE__ */ P({
14
14
  __name: "JTabs",
15
15
  props: {
16
16
  tabs: {},
@@ -21,71 +21,64 @@ const q = { class: "flex-1 truncate" }, G = ["aria-label", "onClick"], K = {
21
21
  },
22
22
  emits: ["tabChange", "tabClose", "update:activeTabId"],
23
23
  setup(j, { emit: E }) {
24
- const n = j, l = E, d = s(() => Array.isArray(n.tabs) ? n.tabs : []), a = D(
25
- n.activeTabId || (d.value.length > 0 ? d.value[0]?.id : "") || ""
24
+ const o = j, l = E, c = i(() => Array.isArray(o.tabs) ? o.tabs : []), a = D(
25
+ o.activeTabId || (c.value.length > 0 ? c.value[0]?.id : "") || ""
26
26
  );
27
- let i = !1;
28
- _(() => n.activeTabId, (e) => {
27
+ let s = !1;
28
+ _(() => o.activeTabId, (e) => {
29
29
  e !== void 0 && e !== a.value && (a.value = e);
30
- }, { immediate: !0 }), _(d, (e) => {
31
- !n.activeTabId && e.length > 0 && !e.find((r) => r.id === a.value) && e[0] && (a.value = e[0].id);
30
+ }, { immediate: !0 }), _(c, (e) => {
31
+ !o.activeTabId && e.length > 0 && !e.find((r) => r.id === a.value) && e[0] && (a.value = e[0].id);
32
32
  });
33
33
  const S = (e) => {
34
- if (i) return;
34
+ if (s) return;
35
35
  const r = String(e);
36
- r !== a.value && (i = !0, a.value = r, l("update:activeTabId", r), l("tabChange", r), $(() => {
37
- i = !1;
36
+ r !== a.value && (s = !0, a.value = r, l("update:activeTabId", r), l("tabChange", r), $(() => {
37
+ s = !1;
38
38
  }));
39
39
  }, I = (e) => {
40
- i || e === a.value || (i = !0, a.value = e, l("update:activeTabId", e), l("tabChange", e), $(() => {
41
- i = !1;
40
+ s || e === a.value || (s = !0, a.value = e, l("update:activeTabId", e), l("tabChange", e), $(() => {
41
+ s = !1;
42
42
  }));
43
- }, z = (e, r) => {
43
+ }, V = (e, r) => {
44
44
  e.stopPropagation(), l("tabClose", r);
45
45
  }, h = {
46
- // Default: Bordered/Card 스타일 (엔터프라이즈)
47
- // 상단 primary accent + 탭↔콘텐츠 시각적 연결
46
+ // Default: Modern Underline 스타일 (Linear/Stripe/GitHub 패턴)
47
+ // 하단 primary indicator + 텍스트 색상 전환 + 플랫 디자인
48
48
  default: {
49
- list: "w-full justify-start gap-1 px-1 bg-muted/30 border-b border-border overflow-x-auto overflow-y-hidden h-auto min-h-[2rem]",
49
+ list: "w-full justify-start gap-0 px-0 bg-transparent border-b border-border overflow-x-auto overflow-y-hidden h-auto min-h-[2rem]",
50
50
  trigger: [
51
- "relative px-3 py-1.5 text-xs font-medium",
52
- "rounded-t-md rounded-b-none",
53
- "border border-transparent border-b-0",
54
- "transition-all duration-150",
51
+ "relative px-3 py-2 text-xs font-medium",
52
+ "rounded-none border-b-2 border-transparent -mb-px",
53
+ "transition-all duration-200",
55
54
  "flex items-center gap-2"
56
55
  ].join(" "),
57
56
  active: [
58
- "data-[state=active]:bg-background",
59
57
  "data-[state=active]:text-foreground",
60
- "data-[state=active]:font-medium",
61
- "data-[state=active]:border-border",
62
- "data-[state=active]:border-t-primary",
63
- "data-[state=active]:border-t-2",
64
- "data-[state=active]:shadow-sm",
65
- "data-[state=active]:z-10",
66
- "data-[state=active]:-mb-px"
58
+ "data-[state=active]:border-b-primary",
59
+ "data-[state=active]:bg-transparent",
60
+ "data-[state=active]:shadow-none"
67
61
  ].join(" "),
68
62
  inactive: [
69
- "data-[state=inactive]:bg-muted/20",
70
63
  "data-[state=inactive]:text-muted-foreground",
71
- "data-[state=inactive]:border-border/40",
72
- "data-[state=inactive]:hover:bg-muted/40",
73
- "data-[state=inactive]:hover:text-foreground"
64
+ "data-[state=inactive]:bg-transparent",
65
+ "data-[state=inactive]:hover:text-foreground",
66
+ "data-[state=inactive]:hover:border-b-muted-foreground/30"
74
67
  ].join(" "),
75
- content: "border border-border border-t-0 bg-background rounded-b-md"
68
+ content: ""
76
69
  },
77
- // Minimal: Underline 스타일 (심플/사이드바용)
78
- // 하단 indicator 바만 표시, 테두리 없음
70
+ // Minimal: 컴팩트 Underline (사이드바/중첩 탭용)
71
+ // 작은 패딩, 밀도 높은 배치
79
72
  minimal: {
80
- list: "w-full justify-start gap-0.5 px-0 bg-transparent border-b border-border overflow-x-auto overflow-y-hidden h-auto min-h-[2rem]",
73
+ list: "w-full justify-start gap-0 px-0 bg-transparent border-b border-border overflow-x-auto overflow-y-hidden h-auto min-h-[1.75rem]",
81
74
  trigger: [
82
- "relative px-2.5 py-1 text-xs font-medium",
83
- "rounded-none border-b-2 border-transparent",
84
- "transition-all duration-150",
85
- "flex items-center gap-2"
75
+ "relative px-2 py-1.5 text-xs font-medium",
76
+ "rounded-none border-b-2 border-transparent -mb-px",
77
+ "transition-all duration-200",
78
+ "flex items-center gap-1.5"
86
79
  ].join(" "),
87
80
  active: [
88
- "data-[state=active]:text-primary",
81
+ "data-[state=active]:text-foreground",
89
82
  "data-[state=active]:border-b-primary",
90
83
  "data-[state=active]:bg-transparent",
91
84
  "data-[state=active]:shadow-none"
@@ -94,46 +87,46 @@ const q = { class: "flex-1 truncate" }, G = ["aria-label", "onClick"], K = {
94
87
  "data-[state=inactive]:text-muted-foreground",
95
88
  "data-[state=inactive]:bg-transparent",
96
89
  "data-[state=inactive]:hover:text-foreground",
97
- "data-[state=inactive]:hover:border-b-border"
90
+ "data-[state=inactive]:hover:border-b-muted-foreground/30"
98
91
  ].join(" "),
99
92
  content: ""
100
93
  }
101
- }, c = s(() => h[n.styletype] ?? h.default), V = s(() => b("flex flex-col w-full h-full", n.class)), A = s(() => b(c.value.list, n.listClass)), B = s(() => b(
102
- c.value.trigger,
103
- c.value.active,
104
- c.value.inactive
105
- )), N = s(() => b("flex-1 w-full overflow-auto", c.value.content));
106
- return (e, r) => (o(), u(v(U), {
94
+ }, d = i(() => h[o.styletype] ?? h.default), z = i(() => g("flex flex-col w-full h-full", o.class)), A = i(() => g(d.value.list, o.listClass)), B = i(() => g(
95
+ d.value.trigger,
96
+ d.value.active,
97
+ d.value.inactive
98
+ )), N = i(() => g("flex-1 w-full overflow-auto", d.value.content));
99
+ return (e, r) => (n(), u(v(U), {
107
100
  "model-value": a.value,
108
101
  "onUpdate:modelValue": S,
109
102
  orientation: "horizontal",
110
- class: m(V.value)
103
+ class: f(z.value)
111
104
  }, {
112
- default: f(() => [
105
+ default: m(() => [
113
106
  y(v(W), {
114
- class: m(A.value)
107
+ class: f(A.value)
115
108
  }, {
116
- default: f(() => [
117
- (o(!0), p(C, null, k(d.value, (t) => (o(), u(v(X), {
109
+ default: m(() => [
110
+ (n(!0), p(C, null, k(c.value, (t) => (n(), u(v(X), {
118
111
  key: t.id,
119
112
  value: t.id,
120
113
  onClick: (x) => I(t.id),
121
- class: m(B.value)
114
+ class: f(B.value)
122
115
  }, {
123
- default: f(() => [
124
- t.icon ? (o(), u(R, {
116
+ default: m(() => [
117
+ t.icon ? (n(), u(R, {
125
118
  key: 0,
126
119
  name: t.icon,
127
120
  size: "sm",
128
121
  class: "flex-shrink-0"
129
122
  }, null, 8, ["name"])) : T("", !0),
130
- g("span", q, w(t.label), 1),
131
- t.closable ? (o(), p("button", {
123
+ b("span", q, w(t.label), 1),
124
+ t.closable ? (n(), p("button", {
132
125
  key: 1,
133
126
  type: "button",
134
127
  class: "flex-shrink-0 h-3.5 w-3.5 rounded-sm hover:bg-destructive/10 hover:text-destructive transition-colors focus:outline-none focus:ring-2 focus:ring-ring flex items-center justify-center",
135
128
  "aria-label": `${t.label} 탭 닫기`,
136
- onClick: (x) => z(x, t.id)
129
+ onClick: (x) => V(x, t.id)
137
130
  }, [
138
131
  y(v(J), { class: "h-2.5 w-2.5" })
139
132
  ], 8, G)) : T("", !0)
@@ -143,21 +136,21 @@ const q = { class: "flex-1 truncate" }, G = ["aria-label", "onClick"], K = {
143
136
  ]),
144
137
  _: 1
145
138
  }, 8, ["class"]),
146
- g("div", {
147
- class: m(N.value)
139
+ b("div", {
140
+ class: f(N.value)
148
141
  }, [
149
- (o(!0), p(C, null, k(d.value, (t) => (o(), u(v(Y), {
142
+ (n(!0), p(C, null, k(c.value, (t) => (n(), u(v(Y), {
150
143
  key: `content-${t.id}`,
151
144
  value: t.id,
152
145
  class: "h-full mt-0 data-[state=active]:flex data-[state=active]:flex-col data-[state=active]:animate-tab-fade-in"
153
146
  }, {
154
- default: f(() => [
147
+ default: m(() => [
155
148
  L(e.$slots, `content-${t.id}`, { tab: t }, () => [
156
- t.component ? (o(), u(F(t.component), H({
149
+ t.component ? (n(), u(F(t.component), H({
157
150
  key: 0,
158
151
  ref_for: !0
159
- }, t.props || {}), null, 16)) : (o(), p("div", K, [
160
- g("p", M, w(t.label) + " 콘텐츠", 1)
152
+ }, t.props || {}), null, 16)) : (n(), p("div", K, [
153
+ b("p", M, w(t.label) + " 콘텐츠", 1)
161
154
  ]))
162
155
  ], !0)
163
156
  ]),
@@ -170,6 +163,6 @@ const q = { class: "flex-1 truncate" }, G = ["aria-label", "onClick"], K = {
170
163
  }
171
164
  });
172
165
  export {
173
- ie as default
166
+ se as default
174
167
  };
175
168
  //# sourceMappingURL=JTabs.vue2.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"JTabs.vue2.js","sources":["../../../../src/components/molecules/JTabs.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref, watch, nextTick } from 'vue'\nimport { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/shadcn'\nimport type { JTabsProps, JTabsEmits } from '@/types/dynamic-tabs.types'\nimport { X } from 'lucide-vue-next'\nimport { cn } from '@/lib/utils'\nimport JIcon from '@/components/atoms/JIcon.vue'\n\n/**\n * JTabs - 기본 탭 UI 컴포넌트 (molecules)\n * Basic Tabs UI Component\n *\n * @description\n * 정적인 탭 목록을 렌더링하는 기본 탭 컴포넌트입니다.\n * 닫기 버튼, 아이콘 등을 지원합니다.\n *\n * @example\n * ```vue\n * <JTabs\n * :tabs=\"tabs\"\n * :active-tab-id=\"activeId\"\n * @tab-change=\"handleChange\"\n * @tab-close=\"handleClose\"\n * />\n * ```\n */\n\ntype StyleType = 'default' | 'minimal'\n\nconst props = withDefaults(defineProps<JTabsProps>(), {\n styletype: 'default',\n})\n\nconst emit = defineEmits<JTabsEmits>()\n\n/**\n * 안전한 tabs 배열 (undefined/null 체크)\n * Safe tabs array (undefined/null check)\n */\nconst safeTabs = computed(() => {\n return Array.isArray(props.tabs) ? props.tabs : []\n})\n\n/**\n * 현재 활성화된 탭 ID (내부 상태)\n * Current active tab ID (internal state)\n */\nconst internalActiveId = ref<string>(\n props.activeTabId || (safeTabs.value.length > 0 ? safeTabs.value[0]?.id : '') || ''\n)\n\n/**\n * 이벤트 처리 중 플래그 (중복 이벤트 방지)\n * Flag to prevent duplicate events\n */\nlet isHandlingEvent = false\n\n/**\n * props.activeTabId가 변경되면 내부 상태 동기화\n * Sync internal state when props.activeTabId changes\n */\nwatch(() => props.activeTabId, (newValue) => {\n if (newValue !== undefined && newValue !== internalActiveId.value) {\n internalActiveId.value = newValue\n }\n}, { immediate: true })\n\n/**\n * props.tabs가 변경되고 activeTabId가 없으면 첫 번째 탭 활성화\n * Activate first tab when tabs change and no activeTabId\n */\nwatch(safeTabs, (newTabs) => {\n if (!props.activeTabId && newTabs.length > 0 && !newTabs.find(t => t.id === internalActiveId.value) && newTabs[0]) {\n internalActiveId.value = newTabs[0].id\n }\n})\n\n/**\n * 탭 값 변경 핸들러 (reka-ui TabsRoot에서 직접 호출됨)\n * Tab value change handler (called directly from reka-ui TabsRoot)\n */\nconst handleTabValueChange = (value: string | number) => {\n if (isHandlingEvent) return\n\n const stringValue = String(value)\n if (stringValue !== internalActiveId.value) {\n isHandlingEvent = true\n internalActiveId.value = stringValue\n emit('update:activeTabId', stringValue)\n emit('tabChange', stringValue)\n nextTick(() => {\n isHandlingEvent = false\n })\n }\n}\n\n/**\n * 탭 클릭 핸들러 (백업 방안 - reka-ui 이벤트가 작동하지 않을 경우)\n * Tab click handler (backup - in case reka-ui events don't work)\n */\nconst handleTabClick = (tabId: string) => {\n if (isHandlingEvent || tabId === internalActiveId.value) return\n\n isHandlingEvent = true\n internalActiveId.value = tabId\n emit('update:activeTabId', tabId)\n emit('tabChange', tabId)\n nextTick(() => {\n isHandlingEvent = false\n })\n}\n\n/**\n * 탭 닫기 핸들러\n * Tab close handler\n */\nconst handleCloseTab = (e: Event, tabId: string) => {\n e.stopPropagation()\n emit('tabClose', tabId)\n}\n\n// ── Style Presets ──────────────────────────────────────────────────\nconst STYLE_PRESETS: Record<StyleType, {\n list: string\n trigger: string\n active: string\n inactive: string\n content: string\n}> = {\n // Default: Bordered/Card 스타일 (엔터프라이즈)\n // 상단 primary accent + 탭↔콘텐츠 시각적 연결\n default: {\n list: 'w-full justify-start gap-1 px-1 bg-muted/30 border-b border-border overflow-x-auto overflow-y-hidden h-auto min-h-[2rem]',\n trigger: [\n 'relative px-3 py-1.5 text-xs font-medium',\n 'rounded-t-md rounded-b-none',\n 'border border-transparent border-b-0',\n 'transition-all duration-150',\n 'flex items-center gap-2',\n ].join(' '),\n active: [\n 'data-[state=active]:bg-background',\n 'data-[state=active]:text-foreground',\n 'data-[state=active]:font-medium',\n 'data-[state=active]:border-border',\n 'data-[state=active]:border-t-primary',\n 'data-[state=active]:border-t-2',\n 'data-[state=active]:shadow-sm',\n 'data-[state=active]:z-10',\n 'data-[state=active]:-mb-px',\n ].join(' '),\n inactive: [\n 'data-[state=inactive]:bg-muted/20',\n 'data-[state=inactive]:text-muted-foreground',\n 'data-[state=inactive]:border-border/40',\n 'data-[state=inactive]:hover:bg-muted/40',\n 'data-[state=inactive]:hover:text-foreground',\n ].join(' '),\n content: 'border border-border border-t-0 bg-background rounded-b-md',\n },\n\n // Minimal: Underline 스타일 (심플/사이드바용)\n // 하단 indicator 바만 표시, 테두리 없음\n minimal: {\n list: 'w-full justify-start gap-0.5 px-0 bg-transparent border-b border-border overflow-x-auto overflow-y-hidden h-auto min-h-[2rem]',\n trigger: [\n 'relative px-2.5 py-1 text-xs font-medium',\n 'rounded-none border-b-2 border-transparent',\n 'transition-all duration-150',\n 'flex items-center gap-2',\n ].join(' '),\n active: [\n 'data-[state=active]:text-primary',\n 'data-[state=active]:border-b-primary',\n 'data-[state=active]:bg-transparent',\n 'data-[state=active]:shadow-none',\n ].join(' '),\n inactive: [\n 'data-[state=inactive]:text-muted-foreground',\n 'data-[state=inactive]:bg-transparent',\n 'data-[state=inactive]:hover:text-foreground',\n 'data-[state=inactive]:hover:border-b-border',\n ].join(' '),\n content: '',\n },\n}\n\nconst preset = computed(() => {\n return STYLE_PRESETS[props.styletype] ?? STYLE_PRESETS.default\n})\n\n// ── Computed Classes ──────────────────────────────────────────────\nconst rootClasses = computed(() => {\n return cn('flex flex-col w-full h-full', props.class)\n})\n\nconst listClasses = computed(() => {\n return cn(preset.value.list, props.listClass)\n})\n\nconst triggerClasses = computed(() => {\n return cn(\n preset.value.trigger,\n preset.value.active,\n preset.value.inactive,\n )\n})\n\nconst contentWrapperClasses = computed(() => {\n return cn('flex-1 w-full overflow-auto', preset.value.content)\n})\n</script>\n\n<template>\n <Tabs\n :model-value=\"internalActiveId\"\n @update:model-value=\"handleTabValueChange\"\n orientation=\"horizontal\"\n :class=\"rootClasses\"\n >\n <!-- 탭 헤더 영역 / Tab Headers -->\n <TabsList :class=\"listClasses\">\n <TabsTrigger\n v-for=\"tab in safeTabs\"\n :key=\"tab.id\"\n :value=\"tab.id\"\n @click=\"handleTabClick(tab.id)\"\n :class=\"triggerClasses\"\n >\n <!-- 탭 아이콘 / Tab Icon -->\n <JIcon\n v-if=\"tab.icon\"\n :name=\"tab.icon\"\n size=\"sm\"\n class=\"flex-shrink-0\"\n />\n\n <!-- 탭 레이블 / Tab Label -->\n <span class=\"flex-1 truncate\">{{ tab.label }}</span>\n\n <!-- 닫기 버튼 / Close Button -->\n <button\n v-if=\"tab.closable\"\n type=\"button\"\n class=\"flex-shrink-0 h-3.5 w-3.5 rounded-sm hover:bg-destructive/10 hover:text-destructive transition-colors focus:outline-none focus:ring-2 focus:ring-ring flex items-center justify-center\"\n :aria-label=\"`${tab.label} 탭 닫기`\"\n @click=\"(e) => handleCloseTab(e, tab.id)\"\n >\n <X class=\"h-2.5 w-2.5\" />\n </button>\n </TabsTrigger>\n </TabsList>\n\n <!-- 탭 콘텐츠 영역 / Tab Contents -->\n <div :class=\"contentWrapperClasses\">\n <TabsContent\n v-for=\"tab in safeTabs\"\n :key=\"`content-${tab.id}`\"\n :value=\"tab.id\"\n class=\"h-full mt-0 data-[state=active]:flex data-[state=active]:flex-col data-[state=active]:animate-tab-fade-in\"\n >\n <slot :name=\"`content-${tab.id}`\" :tab=\"tab\">\n <component\n v-if=\"tab.component\"\n :is=\"tab.component\"\n v-bind=\"tab.props || {}\"\n />\n <div v-else class=\"p-4\">\n <p class=\"text-muted-foreground\">{{ tab.label }} 콘텐츠</p>\n </div>\n </slot>\n </TabsContent>\n </div>\n </Tabs>\n</template>\n\n<style scoped>\n/* ── 스크롤바: Tailwind으로 불가능한 pseudo-element만 `:deep()` 사용 ── */\n:deep([role=\"tablist\"]) {\n scrollbar-width: thin;\n scrollbar-color: hsl(var(--border)) transparent;\n}\n\n:deep([role=\"tablist\"]::-webkit-scrollbar) {\n height: 4px;\n}\n\n:deep([role=\"tablist\"]::-webkit-scrollbar-track) {\n background: transparent;\n}\n\n:deep([role=\"tablist\"]::-webkit-scrollbar-thumb) {\n background-color: hsl(var(--border));\n border-radius: 2px;\n}\n\n:deep([role=\"tablist\"]::-webkit-scrollbar-thumb:hover) {\n background-color: hsl(var(--muted-foreground) / 0.4);\n}\n\n/* ── 콘텐츠 전환 애니메이션 ── */\n@keyframes tab-fade-in {\n from {\n opacity: 0;\n transform: translateY(2px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n:deep(.animate-tab-fade-in) {\n animation: tab-fade-in 0.15s ease-out;\n}\n</style>\n"],"names":["props","__props","emit","__emit","safeTabs","computed","internalActiveId","ref","isHandlingEvent","watch","newValue","newTabs","t","handleTabValueChange","value","stringValue","nextTick","handleTabClick","tabId","handleCloseTab","STYLE_PRESETS","preset","rootClasses","cn","listClasses","triggerClasses","contentWrapperClasses","_createBlock","_unref","Tabs","_createVNode","TabsList","_createElementBlock","_Fragment","_renderList","tab","TabsTrigger","$event","JIcon","_createElementVNode","_hoisted_1","_toDisplayString","e","X","TabsContent","_renderSlot","_ctx","_openBlock","_resolveDynamicComponent","_mergeProps","_hoisted_3","_hoisted_4"],"mappings":"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"}
1
+ {"version":3,"file":"JTabs.vue2.js","sources":["../../../../src/components/molecules/JTabs.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref, watch, nextTick } from 'vue'\nimport { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/shadcn'\nimport type { JTabsProps, JTabsEmits } from '@/types/dynamic-tabs.types'\nimport { X } from 'lucide-vue-next'\nimport { cn } from '@/lib/utils'\nimport JIcon from '@/components/atoms/JIcon.vue'\n\n/**\n * JTabs - 기본 탭 UI 컴포넌트 (molecules)\n * Basic Tabs UI Component\n *\n * @description\n * 정적인 탭 목록을 렌더링하는 기본 탭 컴포넌트입니다.\n * 닫기 버튼, 아이콘 등을 지원합니다.\n *\n * @example\n * ```vue\n * <JTabs\n * :tabs=\"tabs\"\n * :active-tab-id=\"activeId\"\n * @tab-change=\"handleChange\"\n * @tab-close=\"handleClose\"\n * />\n * ```\n */\n\ntype StyleType = 'default' | 'minimal'\n\nconst props = withDefaults(defineProps<JTabsProps>(), {\n styletype: 'default',\n})\n\nconst emit = defineEmits<JTabsEmits>()\n\n/**\n * 안전한 tabs 배열 (undefined/null 체크)\n * Safe tabs array (undefined/null check)\n */\nconst safeTabs = computed(() => {\n return Array.isArray(props.tabs) ? props.tabs : []\n})\n\n/**\n * 현재 활성화된 탭 ID (내부 상태)\n * Current active tab ID (internal state)\n */\nconst internalActiveId = ref<string>(\n props.activeTabId || (safeTabs.value.length > 0 ? safeTabs.value[0]?.id : '') || ''\n)\n\n/**\n * 이벤트 처리 중 플래그 (중복 이벤트 방지)\n * Flag to prevent duplicate events\n */\nlet isHandlingEvent = false\n\n/**\n * props.activeTabId가 변경되면 내부 상태 동기화\n * Sync internal state when props.activeTabId changes\n */\nwatch(() => props.activeTabId, (newValue) => {\n if (newValue !== undefined && newValue !== internalActiveId.value) {\n internalActiveId.value = newValue\n }\n}, { immediate: true })\n\n/**\n * props.tabs가 변경되고 activeTabId가 없으면 첫 번째 탭 활성화\n * Activate first tab when tabs change and no activeTabId\n */\nwatch(safeTabs, (newTabs) => {\n if (!props.activeTabId && newTabs.length > 0 && !newTabs.find(t => t.id === internalActiveId.value) && newTabs[0]) {\n internalActiveId.value = newTabs[0].id\n }\n})\n\n/**\n * 탭 값 변경 핸들러 (reka-ui TabsRoot에서 직접 호출됨)\n * Tab value change handler (called directly from reka-ui TabsRoot)\n */\nconst handleTabValueChange = (value: string | number) => {\n if (isHandlingEvent) return\n\n const stringValue = String(value)\n if (stringValue !== internalActiveId.value) {\n isHandlingEvent = true\n internalActiveId.value = stringValue\n emit('update:activeTabId', stringValue)\n emit('tabChange', stringValue)\n nextTick(() => {\n isHandlingEvent = false\n })\n }\n}\n\n/**\n * 탭 클릭 핸들러 (백업 방안 - reka-ui 이벤트가 작동하지 않을 경우)\n * Tab click handler (backup - in case reka-ui events don't work)\n */\nconst handleTabClick = (tabId: string) => {\n if (isHandlingEvent || tabId === internalActiveId.value) return\n\n isHandlingEvent = true\n internalActiveId.value = tabId\n emit('update:activeTabId', tabId)\n emit('tabChange', tabId)\n nextTick(() => {\n isHandlingEvent = false\n })\n}\n\n/**\n * 탭 닫기 핸들러\n * Tab close handler\n */\nconst handleCloseTab = (e: Event, tabId: string) => {\n e.stopPropagation()\n emit('tabClose', tabId)\n}\n\n// ── Style Presets ──────────────────────────────────────────────────\nconst STYLE_PRESETS: Record<StyleType, {\n list: string\n trigger: string\n active: string\n inactive: string\n content: string\n}> = {\n // Default: Modern Underline 스타일 (Linear/Stripe/GitHub 패턴)\n // 하단 primary indicator + 텍스트 색상 전환 + 플랫 디자인\n default: {\n list: 'w-full justify-start gap-0 px-0 bg-transparent border-b border-border overflow-x-auto overflow-y-hidden h-auto min-h-[2rem]',\n trigger: [\n 'relative px-3 py-2 text-xs font-medium',\n 'rounded-none border-b-2 border-transparent -mb-px',\n 'transition-all duration-200',\n 'flex items-center gap-2',\n ].join(' '),\n active: [\n 'data-[state=active]:text-foreground',\n 'data-[state=active]:border-b-primary',\n 'data-[state=active]:bg-transparent',\n 'data-[state=active]:shadow-none',\n ].join(' '),\n inactive: [\n 'data-[state=inactive]:text-muted-foreground',\n 'data-[state=inactive]:bg-transparent',\n 'data-[state=inactive]:hover:text-foreground',\n 'data-[state=inactive]:hover:border-b-muted-foreground/30',\n ].join(' '),\n content: '',\n },\n\n // Minimal: 컴팩트 Underline (사이드바/중첩 탭용)\n // 더 작은 패딩, 밀도 높은 배치\n minimal: {\n list: 'w-full justify-start gap-0 px-0 bg-transparent border-b border-border overflow-x-auto overflow-y-hidden h-auto min-h-[1.75rem]',\n trigger: [\n 'relative px-2 py-1.5 text-xs font-medium',\n 'rounded-none border-b-2 border-transparent -mb-px',\n 'transition-all duration-200',\n 'flex items-center gap-1.5',\n ].join(' '),\n active: [\n 'data-[state=active]:text-foreground',\n 'data-[state=active]:border-b-primary',\n 'data-[state=active]:bg-transparent',\n 'data-[state=active]:shadow-none',\n ].join(' '),\n inactive: [\n 'data-[state=inactive]:text-muted-foreground',\n 'data-[state=inactive]:bg-transparent',\n 'data-[state=inactive]:hover:text-foreground',\n 'data-[state=inactive]:hover:border-b-muted-foreground/30',\n ].join(' '),\n content: '',\n },\n}\n\nconst preset = computed(() => {\n return STYLE_PRESETS[props.styletype] ?? STYLE_PRESETS.default\n})\n\n// ── Computed Classes ──────────────────────────────────────────────\nconst rootClasses = computed(() => {\n return cn('flex flex-col w-full h-full', props.class)\n})\n\nconst listClasses = computed(() => {\n return cn(preset.value.list, props.listClass)\n})\n\nconst triggerClasses = computed(() => {\n return cn(\n preset.value.trigger,\n preset.value.active,\n preset.value.inactive,\n )\n})\n\nconst contentWrapperClasses = computed(() => {\n return cn('flex-1 w-full overflow-auto', preset.value.content)\n})\n</script>\n\n<template>\n <Tabs\n :model-value=\"internalActiveId\"\n @update:model-value=\"handleTabValueChange\"\n orientation=\"horizontal\"\n :class=\"rootClasses\"\n >\n <!-- 탭 헤더 영역 / Tab Headers -->\n <TabsList :class=\"listClasses\">\n <TabsTrigger\n v-for=\"tab in safeTabs\"\n :key=\"tab.id\"\n :value=\"tab.id\"\n @click=\"handleTabClick(tab.id)\"\n :class=\"triggerClasses\"\n >\n <!-- 탭 아이콘 / Tab Icon -->\n <JIcon\n v-if=\"tab.icon\"\n :name=\"tab.icon\"\n size=\"sm\"\n class=\"flex-shrink-0\"\n />\n\n <!-- 탭 레이블 / Tab Label -->\n <span class=\"flex-1 truncate\">{{ tab.label }}</span>\n\n <!-- 닫기 버튼 / Close Button -->\n <button\n v-if=\"tab.closable\"\n type=\"button\"\n class=\"flex-shrink-0 h-3.5 w-3.5 rounded-sm hover:bg-destructive/10 hover:text-destructive transition-colors focus:outline-none focus:ring-2 focus:ring-ring flex items-center justify-center\"\n :aria-label=\"`${tab.label} 탭 닫기`\"\n @click=\"(e) => handleCloseTab(e, tab.id)\"\n >\n <X class=\"h-2.5 w-2.5\" />\n </button>\n </TabsTrigger>\n </TabsList>\n\n <!-- 탭 콘텐츠 영역 / Tab Contents -->\n <div :class=\"contentWrapperClasses\">\n <TabsContent\n v-for=\"tab in safeTabs\"\n :key=\"`content-${tab.id}`\"\n :value=\"tab.id\"\n class=\"h-full mt-0 data-[state=active]:flex data-[state=active]:flex-col data-[state=active]:animate-tab-fade-in\"\n >\n <slot :name=\"`content-${tab.id}`\" :tab=\"tab\">\n <component\n v-if=\"tab.component\"\n :is=\"tab.component\"\n v-bind=\"tab.props || {}\"\n />\n <div v-else class=\"p-4\">\n <p class=\"text-muted-foreground\">{{ tab.label }} 콘텐츠</p>\n </div>\n </slot>\n </TabsContent>\n </div>\n </Tabs>\n</template>\n\n<style scoped>\n/* ── 스크롤바: Tailwind으로 불가능한 pseudo-element만 `:deep()` 사용 ── */\n:deep([role=\"tablist\"]) {\n scrollbar-width: thin;\n scrollbar-color: hsl(var(--border)) transparent;\n}\n\n:deep([role=\"tablist\"]::-webkit-scrollbar) {\n height: 4px;\n}\n\n:deep([role=\"tablist\"]::-webkit-scrollbar-track) {\n background: transparent;\n}\n\n:deep([role=\"tablist\"]::-webkit-scrollbar-thumb) {\n background-color: hsl(var(--border));\n border-radius: 2px;\n}\n\n:deep([role=\"tablist\"]::-webkit-scrollbar-thumb:hover) {\n background-color: hsl(var(--muted-foreground) / 0.4);\n}\n\n/* ── 콘텐츠 전환 애니메이션 ── */\n@keyframes tab-fade-in {\n from {\n opacity: 0;\n transform: translateY(2px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n:deep(.animate-tab-fade-in) {\n animation: tab-fade-in 0.15s ease-out;\n}\n</style>\n"],"names":["props","__props","emit","__emit","safeTabs","computed","internalActiveId","ref","isHandlingEvent","watch","newValue","newTabs","t","handleTabValueChange","value","stringValue","nextTick","handleTabClick","tabId","handleCloseTab","STYLE_PRESETS","preset","rootClasses","cn","listClasses","triggerClasses","contentWrapperClasses","_createBlock","_unref","Tabs","_createVNode","TabsList","_createElementBlock","_Fragment","_renderList","tab","TabsTrigger","$event","JIcon","_createElementVNode","_hoisted_1","_toDisplayString","e","X","TabsContent","_renderSlot","_ctx","_openBlock","_resolveDynamicComponent","_mergeProps","_hoisted_3","_hoisted_4"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@j-solution/components",
3
3
  "description": "Vue 3 Atomic Design component kit for enterprise dashboards",
4
- "version": "2.0.4",
4
+ "version": "2.0.5",
5
5
  "type": "module",
6
6
  "main": "./index.cjs",
7
7
  "module": "./index.js",