@j-solution/components 1.6.1 → 1.8.0

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.
Files changed (272) hide show
  1. package/README.md +8 -6
  2. package/assets/jwms-portal-frontend-BtHTA-UF.css +1 -0
  3. package/assets/styles/global-utilities.css +34 -0
  4. package/assets/styles/j-components.css +1 -1
  5. package/assets/styles/themes.css +128 -21
  6. package/components/atoms/JAvatar.vue.cjs +1 -1
  7. package/components/atoms/JAvatar.vue.cjs.map +1 -1
  8. package/components/atoms/JAvatar.vue.js +10 -7
  9. package/components/atoms/JAvatar.vue.js.map +1 -1
  10. package/components/atoms/JBadge.vue.cjs +1 -1
  11. package/components/atoms/JBadge.vue.cjs.map +1 -1
  12. package/components/atoms/JBadge.vue.js +7 -6
  13. package/components/atoms/JBadge.vue.js.map +1 -1
  14. package/components/atoms/JButton.vue.cjs +6 -1
  15. package/components/atoms/JButton.vue.cjs.map +1 -1
  16. package/components/atoms/JButton.vue.js +10 -85
  17. package/components/atoms/JButton.vue.js.map +1 -1
  18. package/components/atoms/JButton.vue2.cjs +1 -1
  19. package/components/atoms/JButton.vue2.cjs.map +1 -1
  20. package/components/atoms/JButton.vue2.js +85 -2
  21. package/components/atoms/JButton.vue2.js.map +1 -1
  22. package/components/atoms/JDatepicker.vue.cjs +1 -1
  23. package/components/atoms/JDatepicker.vue.cjs.map +1 -1
  24. package/components/atoms/JDatepicker.vue.js +10 -10
  25. package/components/atoms/JDatepicker.vue.js.map +1 -1
  26. package/components/atoms/JEditor.vue.cjs +1 -1
  27. package/components/atoms/JEditor.vue.js +1 -1
  28. package/components/atoms/JEditor.vue2.cjs +1 -1
  29. package/components/atoms/JEditor.vue2.cjs.map +1 -1
  30. package/components/atoms/JEditor.vue2.js +31 -17
  31. package/components/atoms/JEditor.vue2.js.map +1 -1
  32. package/components/atoms/JGrid.vue.cjs +1 -1
  33. package/components/atoms/JGrid.vue.js +2 -2
  34. package/components/atoms/JGrid.vue2.cjs +1 -1
  35. package/components/atoms/JGrid.vue2.cjs.map +1 -1
  36. package/components/atoms/JGrid.vue2.js +59 -43
  37. package/components/atoms/JGrid.vue2.js.map +1 -1
  38. package/components/atoms/JIcon.vue.cjs +1 -1
  39. package/components/atoms/JIcon.vue.cjs.map +1 -1
  40. package/components/atoms/JIcon.vue.js +14 -13
  41. package/components/atoms/JIcon.vue.js.map +1 -1
  42. package/components/atoms/JKbd.vue.cjs +1 -1
  43. package/components/atoms/JKbd.vue.cjs.map +1 -1
  44. package/components/atoms/JKbd.vue.js +13 -10
  45. package/components/atoms/JKbd.vue.js.map +1 -1
  46. package/components/atoms/JLabel.vue.cjs +1 -1
  47. package/components/atoms/JLabel.vue.cjs.map +1 -1
  48. package/components/atoms/JLabel.vue.js +26 -22
  49. package/components/atoms/JLabel.vue.js.map +1 -1
  50. package/components/atoms/JLink.vue.cjs +1 -1
  51. package/components/atoms/JLink.vue.cjs.map +1 -1
  52. package/components/atoms/JLink.vue.js +5 -5
  53. package/components/atoms/JLink.vue.js.map +1 -1
  54. package/components/atoms/JPreview.vue.cjs +1 -1
  55. package/components/atoms/JPreview.vue.js +2 -2
  56. package/components/atoms/JPreview.vue2.cjs +1 -1
  57. package/components/atoms/JPreview.vue2.cjs.map +1 -1
  58. package/components/atoms/JPreview.vue2.js +33 -20
  59. package/components/atoms/JPreview.vue2.js.map +1 -1
  60. package/components/atoms/JProgress.vue.cjs +1 -1
  61. package/components/atoms/JProgress.vue.cjs.map +1 -1
  62. package/components/atoms/JProgress.vue.js +15 -9
  63. package/components/atoms/JProgress.vue.js.map +1 -1
  64. package/components/atoms/JRadio.vue.cjs +1 -1
  65. package/components/atoms/JRadio.vue.cjs.map +1 -1
  66. package/components/atoms/JRadio.vue.js +1 -1
  67. package/components/atoms/JRadio.vue.js.map +1 -1
  68. package/components/atoms/JSearchCombo.vue.cjs +1 -1
  69. package/components/atoms/JSearchCombo.vue.cjs.map +1 -1
  70. package/components/atoms/JSearchCombo.vue.js +38 -37
  71. package/components/atoms/JSearchCombo.vue.js.map +1 -1
  72. package/components/atoms/JSectionTitle.vue.cjs +7 -0
  73. package/components/atoms/JSectionTitle.vue.cjs.map +1 -0
  74. package/components/atoms/JSectionTitle.vue.js +13 -0
  75. package/components/atoms/JSectionTitle.vue.js.map +1 -0
  76. package/components/atoms/JSectionTitle.vue2.cjs +2 -0
  77. package/components/atoms/JSectionTitle.vue2.cjs.map +1 -0
  78. package/components/atoms/JSectionTitle.vue2.js +67 -0
  79. package/components/atoms/JSectionTitle.vue2.js.map +1 -0
  80. package/components/atoms/JSpinner.vue.cjs +1 -1
  81. package/components/atoms/JSpinner.vue.cjs.map +1 -1
  82. package/components/atoms/JSpinner.vue.js +8 -7
  83. package/components/atoms/JSpinner.vue.js.map +1 -1
  84. package/components/atoms/JSplitter.vue.cjs +6 -1
  85. package/components/atoms/JSplitter.vue.cjs.map +1 -1
  86. package/components/atoms/JSplitter.vue.js +10 -54
  87. package/components/atoms/JSplitter.vue.js.map +1 -1
  88. package/components/atoms/JSplitter.vue2.cjs +1 -1
  89. package/components/atoms/JSplitter.vue2.cjs.map +1 -1
  90. package/components/atoms/JSplitter.vue2.js +59 -2
  91. package/components/atoms/JSplitter.vue2.js.map +1 -1
  92. package/components/atoms/JTooltip.vue.cjs +1 -1
  93. package/components/atoms/JTooltip.vue.cjs.map +1 -1
  94. package/components/atoms/JTooltip.vue.js +18 -15
  95. package/components/atoms/JTooltip.vue.js.map +1 -1
  96. package/components/examples/ExampleCrudPage.vue.cjs +1 -1
  97. package/components/examples/ExampleCrudPage.vue.cjs.map +1 -1
  98. package/components/examples/ExampleCrudPage.vue.js +265 -191
  99. package/components/examples/ExampleCrudPage.vue.js.map +1 -1
  100. package/components/examples/ExampleTabMappingPage.vue.cjs +1 -1
  101. package/components/examples/ExampleTabMappingPage.vue.cjs.map +1 -1
  102. package/components/examples/ExampleTabMappingPage.vue.js +349 -333
  103. package/components/examples/ExampleTabMappingPage.vue.js.map +1 -1
  104. package/components/molecules/JAlert.vue.cjs +1 -1
  105. package/components/molecules/JAlert.vue.cjs.map +1 -1
  106. package/components/molecules/JAlert.vue.js +18 -16
  107. package/components/molecules/JAlert.vue.js.map +1 -1
  108. package/components/molecules/JBreadcrumb.vue.cjs +1 -1
  109. package/components/molecules/JBreadcrumb.vue.cjs.map +1 -1
  110. package/components/molecules/JBreadcrumb.vue.js +3 -3
  111. package/components/molecules/JBreadcrumb.vue.js.map +1 -1
  112. package/components/molecules/JCard.vue.cjs +1 -1
  113. package/components/molecules/JCard.vue.cjs.map +1 -1
  114. package/components/molecules/JCard.vue.js +55 -39
  115. package/components/molecules/JCard.vue.js.map +1 -1
  116. package/components/molecules/JEmptyState.vue.cjs +7 -0
  117. package/components/molecules/JEmptyState.vue.cjs.map +1 -0
  118. package/components/molecules/JEmptyState.vue.js +13 -0
  119. package/components/molecules/JEmptyState.vue.js.map +1 -0
  120. package/components/molecules/JEmptyState.vue2.cjs +2 -0
  121. package/components/molecules/JEmptyState.vue2.cjs.map +1 -0
  122. package/components/molecules/JEmptyState.vue2.js +127 -0
  123. package/components/molecules/JEmptyState.vue2.js.map +1 -0
  124. package/components/molecules/JFormField.vue.cjs +6 -1
  125. package/components/molecules/JFormField.vue.cjs.map +1 -1
  126. package/components/molecules/JFormField.vue.js +10 -262
  127. package/components/molecules/JFormField.vue.js.map +1 -1
  128. package/components/molecules/JFormField.vue2.cjs +2 -0
  129. package/components/molecules/JFormField.vue2.cjs.map +1 -0
  130. package/components/molecules/JFormField.vue2.js +271 -0
  131. package/components/molecules/JFormField.vue2.js.map +1 -0
  132. package/components/molecules/JTabs.vue.cjs +1 -1
  133. package/components/molecules/JTabs.vue.js +1 -1
  134. package/components/molecules/JTabs.vue2.cjs +1 -1
  135. package/components/molecules/JTabs.vue2.cjs.map +1 -1
  136. package/components/molecules/JTabs.vue2.js +50 -56
  137. package/components/molecules/JTabs.vue2.js.map +1 -1
  138. package/components/molecules/JTitlebar.vue.cjs +1 -1
  139. package/components/molecules/JTitlebar.vue.cjs.map +1 -1
  140. package/components/molecules/JTitlebar.vue.js +49 -47
  141. package/components/molecules/JTitlebar.vue.js.map +1 -1
  142. package/components/organisms/JDynamicForm.vue2.cjs +1 -1
  143. package/components/organisms/JDynamicForm.vue2.cjs.map +1 -1
  144. package/components/organisms/JDynamicForm.vue2.js +35 -32
  145. package/components/organisms/JDynamicForm.vue2.js.map +1 -1
  146. package/components/organisms/JDynamicTabs.vue.cjs +1 -1
  147. package/components/organisms/JDynamicTabs.vue.cjs.map +1 -1
  148. package/components/organisms/JDynamicTabs.vue.js +47 -52
  149. package/components/organisms/JDynamicTabs.vue.js.map +1 -1
  150. package/components/organisms/JFilterBar.vue.cjs +6 -1
  151. package/components/organisms/JFilterBar.vue.cjs.map +1 -1
  152. package/components/organisms/JFilterBar.vue.js +10 -137
  153. package/components/organisms/JFilterBar.vue.js.map +1 -1
  154. package/components/organisms/JFilterBar.vue2.cjs +1 -1
  155. package/components/organisms/JFilterBar.vue2.cjs.map +1 -1
  156. package/components/organisms/JFilterBar.vue2.js +141 -2
  157. package/components/organisms/JFilterBar.vue2.js.map +1 -1
  158. package/components/organisms/JFormModal.vue.cjs +1 -1
  159. package/components/organisms/JFormModal.vue.cjs.map +1 -1
  160. package/components/organisms/JFormModal.vue.js +54 -49
  161. package/components/organisms/JFormModal.vue.js.map +1 -1
  162. package/components/organisms/JHeader.vue.cjs +1 -1
  163. package/components/organisms/JHeader.vue.cjs.map +1 -1
  164. package/components/organisms/JHeader.vue.js +211 -208
  165. package/components/organisms/JHeader.vue.js.map +1 -1
  166. package/components/organisms/JModal.vue.cjs +1 -1
  167. package/components/organisms/JModal.vue.cjs.map +1 -1
  168. package/components/organisms/JModal.vue.js +31 -26
  169. package/components/organisms/JModal.vue.js.map +1 -1
  170. package/components/organisms/JPageContainer.vue.cjs +1 -1
  171. package/components/organisms/JPageContainer.vue.cjs.map +1 -1
  172. package/components/organisms/JPageContainer.vue.js +22 -22
  173. package/components/organisms/JPageContainer.vue.js.map +1 -1
  174. package/components/organisms/JSearchPanel.vue2.cjs +1 -1
  175. package/components/organisms/JSearchPanel.vue2.cjs.map +1 -1
  176. package/components/organisms/JSearchPanel.vue2.js +34 -32
  177. package/components/organisms/JSearchPanel.vue2.js.map +1 -1
  178. package/components/organisms/JShuttle.vue.cjs +7 -0
  179. package/components/organisms/JShuttle.vue.cjs.map +1 -0
  180. package/components/organisms/JShuttle.vue.js +13 -0
  181. package/components/organisms/JShuttle.vue.js.map +1 -0
  182. package/components/organisms/JShuttle.vue2.cjs +2 -0
  183. package/components/organisms/JShuttle.vue2.cjs.map +1 -0
  184. package/components/organisms/JShuttle.vue2.js +216 -0
  185. package/components/organisms/JShuttle.vue2.js.map +1 -0
  186. package/components/organisms/JSidebarAdvanced.vue.cjs +1 -1
  187. package/components/organisms/JSidebarAdvanced.vue.js +7 -7
  188. package/components/organisms/JSidebarAdvanced.vue2.cjs +1 -1
  189. package/components/organisms/JSidebarAdvanced.vue2.cjs.map +1 -1
  190. package/components/organisms/JSidebarAdvanced.vue2.js +40 -40
  191. package/components/organisms/JSidebarAdvanced.vue2.js.map +1 -1
  192. package/components/organisms/JSidebarSimple/JDynamicMenuItem.vue.cjs +1 -1
  193. package/components/organisms/JSidebarSimple/JDynamicMenuItem.vue.cjs.map +1 -1
  194. package/components/organisms/JSidebarSimple/JDynamicMenuItem.vue.js +83 -63
  195. package/components/organisms/JSidebarSimple/JDynamicMenuItem.vue.js.map +1 -1
  196. package/components/organisms/JSidebarSimple.vue.cjs +1 -1
  197. package/components/organisms/JSidebarSimple.vue.js +2 -2
  198. package/components/organisms/JSidebarSimple.vue2.cjs +1 -1
  199. package/components/organisms/JSidebarSimple.vue2.cjs.map +1 -1
  200. package/components/organisms/JSidebarSimple.vue2.js +2 -2
  201. package/components/organisms/JSidebarSimple.vue2.js.map +1 -1
  202. package/components/shadcn/AccordionTrigger.vue.cjs +1 -1
  203. package/components/shadcn/AccordionTrigger.vue.cjs.map +1 -1
  204. package/components/shadcn/AccordionTrigger.vue.js +3 -3
  205. package/components/shadcn/AccordionTrigger.vue.js.map +1 -1
  206. package/components/shadcn/Card.vue.cjs +1 -1
  207. package/components/shadcn/Card.vue.cjs.map +1 -1
  208. package/components/shadcn/Card.vue.js +1 -1
  209. package/components/shadcn/Card.vue.js.map +1 -1
  210. package/components/shadcn/CardContent.vue.cjs +1 -1
  211. package/components/shadcn/CardContent.vue.cjs.map +1 -1
  212. package/components/shadcn/CardContent.vue.js +4 -4
  213. package/components/shadcn/CardContent.vue.js.map +1 -1
  214. package/components/shadcn/CardDescription.vue.cjs +1 -1
  215. package/components/shadcn/CardDescription.vue.cjs.map +1 -1
  216. package/components/shadcn/CardDescription.vue.js +1 -1
  217. package/components/shadcn/CardDescription.vue.js.map +1 -1
  218. package/components/shadcn/CardFooter.vue.cjs +1 -1
  219. package/components/shadcn/CardFooter.vue.cjs.map +1 -1
  220. package/components/shadcn/CardFooter.vue.js +7 -7
  221. package/components/shadcn/CardFooter.vue.js.map +1 -1
  222. package/components/shadcn/CardHeader.vue.cjs +1 -1
  223. package/components/shadcn/CardHeader.vue.cjs.map +1 -1
  224. package/components/shadcn/CardHeader.vue.js +8 -8
  225. package/components/shadcn/CardHeader.vue.js.map +1 -1
  226. package/components/shadcn/CardTitle.vue.cjs +1 -1
  227. package/components/shadcn/CardTitle.vue.cjs.map +1 -1
  228. package/components/shadcn/CardTitle.vue.js +5 -5
  229. package/components/shadcn/CardTitle.vue.js.map +1 -1
  230. package/components/shadcn/Input.vue.cjs +1 -1
  231. package/components/shadcn/Input.vue.cjs.map +1 -1
  232. package/components/shadcn/Input.vue.js +3 -3
  233. package/components/shadcn/Input.vue.js.map +1 -1
  234. package/components/shadcn/SelectTrigger.vue.cjs +1 -1
  235. package/components/shadcn/SelectTrigger.vue.cjs.map +1 -1
  236. package/components/shadcn/SelectTrigger.vue.js +2 -2
  237. package/components/shadcn/SelectTrigger.vue.js.map +1 -1
  238. package/components/shadcn/Switch.vue.cjs +1 -1
  239. package/components/shadcn/Switch.vue.cjs.map +1 -1
  240. package/components/shadcn/Switch.vue.js +2 -2
  241. package/components/shadcn/Switch.vue.js.map +1 -1
  242. package/components/shadcn/TabsContent.vue.cjs +1 -1
  243. package/components/shadcn/TabsContent.vue.cjs.map +1 -1
  244. package/components/shadcn/TabsContent.vue.js +1 -1
  245. package/components/shadcn/TabsContent.vue.js.map +1 -1
  246. package/components/shadcn/TabsList.vue.cjs +1 -1
  247. package/components/shadcn/TabsList.vue.cjs.map +1 -1
  248. package/components/shadcn/TabsList.vue.js +10 -10
  249. package/components/shadcn/TabsList.vue.js.map +1 -1
  250. package/components/shadcn/TabsTrigger.vue.cjs +1 -1
  251. package/components/shadcn/TabsTrigger.vue.cjs.map +1 -1
  252. package/components/shadcn/TabsTrigger.vue.js +4 -4
  253. package/components/shadcn/TabsTrigger.vue.js.map +1 -1
  254. package/components/shadcn/Textarea.vue.cjs +1 -1
  255. package/components/shadcn/Textarea.vue.cjs.map +1 -1
  256. package/components/shadcn/Textarea.vue.js +2 -2
  257. package/components/shadcn/Textarea.vue.js.map +1 -1
  258. package/components/shadcn/index.cjs +1 -1
  259. package/components/shadcn/index.cjs.map +1 -1
  260. package/components/shadcn/index.js +9 -8
  261. package/components/shadcn/index.js.map +1 -1
  262. package/components/templates/JLayout.vue.cjs.map +1 -1
  263. package/components/templates/JLayout.vue.js.map +1 -1
  264. package/index.cjs +1 -1
  265. package/index.js +73 -67
  266. package/package.json +1 -1
  267. package/types/index.d.ts +1025 -766
  268. package/assets/jwms-portal-frontend-DntSIcYt.css +0 -1
  269. package/components/molecules/JFormField.vue3.cjs +0 -2
  270. package/components/molecules/JFormField.vue3.cjs.map +0 -1
  271. package/components/molecules/JFormField.vue3.js +0 -6
  272. package/components/molecules/JFormField.vue3.js.map +0 -1
@@ -1,5 +1,144 @@
1
- import f from "./JFilterBar.vue.js";
1
+ import { defineComponent as D, computed as x, createElementBlock as u, openBlock as o, normalizeClass as v, unref as p, createElementVNode as n, withDirectives as T, createCommentVNode as i, createBlock as f, createVNode as b, Fragment as $, renderList as z, withCtx as m, toDisplayString as d, withModifiers as E, renderSlot as V, createTextVNode as B, vShow as F } from "vue";
2
+ import { ChevronDown as N, X as R } from "lucide-vue-next";
3
+ import J from "../atoms/JBadge.vue.js";
4
+ import k from "../atoms/JButton.vue.js";
5
+ import O from "../atoms/JLabel.vue.js";
6
+ import { cn as L } from "../../lib/utils.js";
7
+ const M = { class: "flex items-center justify-between px-3 py-1.5" }, X = { class: "flex items-center gap-2" }, q = {
8
+ key: 2,
9
+ class: "flex items-center gap-1 flex-wrap"
10
+ }, G = { class: "text-muted-foreground" }, H = ["onClick"], I = { class: "flex items-center gap-2" }, K = { class: "px-3 pb-3" }, ee = /* @__PURE__ */ D({
11
+ __name: "JFilterBar",
12
+ props: {
13
+ class: {},
14
+ title: {},
15
+ collapsed: { type: Boolean, default: !0 },
16
+ collapsible: { type: Boolean, default: !0 },
17
+ filterValues: { default: () => ({}) },
18
+ filterDisplay: { default: () => ({}) },
19
+ showResetButton: { type: Boolean, default: !1 },
20
+ showSearchButton: { type: Boolean, default: !1 },
21
+ resetButtonText: { default: "초기화" },
22
+ searchButtonText: { default: "조회" }
23
+ },
24
+ emits: ["update:collapsed", "update:filterValues", "search", "reset"],
25
+ setup(r, { emit: w }) {
26
+ const l = r, a = w, y = x(() => l.collapsible ? !l.collapsed : !0);
27
+ function C(e) {
28
+ return !!(e == null || typeof e == "string" && e.trim() === "" || Array.isArray(e) && e.length === 0);
29
+ }
30
+ const h = x(() => {
31
+ const e = [];
32
+ for (const [t, s] of Object.entries(l.filterDisplay)) {
33
+ const c = l.filterValues[t];
34
+ if (C(c)) continue;
35
+ const g = s.displayValue ? s.displayValue(c) : String(c);
36
+ g.trim() !== "" && e.push({
37
+ key: t,
38
+ label: s.label,
39
+ value: g
40
+ });
41
+ }
42
+ return e;
43
+ });
44
+ function _() {
45
+ a("update:collapsed", !l.collapsed);
46
+ }
47
+ function S() {
48
+ const e = {};
49
+ for (const t of Object.keys(l.filterValues)) {
50
+ const s = l.filterValues[t];
51
+ typeof s == "string" ? e[t] = "" : Array.isArray(s) ? e[t] = [] : e[t] = null;
52
+ }
53
+ a("update:filterValues", e), a("reset");
54
+ }
55
+ function A() {
56
+ a("search");
57
+ }
58
+ function j(e) {
59
+ const t = { ...l.filterValues }, s = t[e];
60
+ typeof s == "string" ? t[e] = "" : Array.isArray(s) ? t[e] = [] : t[e] = null, a("update:filterValues", t);
61
+ }
62
+ return (e, t) => (o(), u("div", {
63
+ class: v(p(L)("j-filter-bar w-full rounded-sm border bg-card text-card-foreground", l.class))
64
+ }, [
65
+ n("div", M, [
66
+ n("div", X, [
67
+ r.collapsible ? (o(), u("button", {
68
+ key: 0,
69
+ type: "button",
70
+ class: "flex items-center justify-center h-6 w-6 rounded hover:bg-accent hover:text-accent-foreground transition-colors",
71
+ onClick: _
72
+ }, [
73
+ b(p(N), {
74
+ class: v([
75
+ "h-3.5 w-3.5 transition-transform",
76
+ y.value ? "rotate-0" : "-rotate-90"
77
+ ])
78
+ }, null, 8, ["class"])
79
+ ])) : i("", !0),
80
+ r.title ? (o(), f(O, {
81
+ key: 1,
82
+ text: r.title,
83
+ class: "text-sm font-semibold text-foreground"
84
+ }, null, 8, ["text"])) : i("", !0),
85
+ h.value.length > 0 ? (o(), u("div", q, [
86
+ (o(!0), u($, null, z(h.value, (s) => (o(), f(J, {
87
+ key: s.key,
88
+ variant: "secondary",
89
+ size: "sm",
90
+ class: "flex items-center gap-1 cursor-default"
91
+ }, {
92
+ default: m(() => [
93
+ n("span", G, d(s.label) + ":", 1),
94
+ n("span", null, d(s.value), 1),
95
+ n("button", {
96
+ type: "button",
97
+ class: "ml-0.5 rounded-full hover:bg-gray-300 p-0.5 transition-colors",
98
+ onClick: E((c) => j(s.key), ["stop"])
99
+ }, [
100
+ b(p(R), { class: "h-3 w-3" })
101
+ ], 8, H)
102
+ ]),
103
+ _: 2
104
+ }, 1024))), 128))
105
+ ])) : i("", !0)
106
+ ]),
107
+ n("div", I, [
108
+ V(e.$slots, "actions", {}, void 0, !0),
109
+ r.showResetButton ? (o(), f(k, {
110
+ key: 0,
111
+ variant: "secondary",
112
+ size: "sm",
113
+ onClick: S
114
+ }, {
115
+ default: m(() => [
116
+ B(d(r.resetButtonText), 1)
117
+ ]),
118
+ _: 1
119
+ })) : i("", !0),
120
+ r.showSearchButton ? (o(), f(k, {
121
+ key: 1,
122
+ styletype: "primary",
123
+ size: "sm",
124
+ onClick: A
125
+ }, {
126
+ default: m(() => [
127
+ B(d(r.searchButtonText), 1)
128
+ ]),
129
+ _: 1
130
+ })) : i("", !0)
131
+ ])
132
+ ]),
133
+ T(n("div", K, [
134
+ V(e.$slots, "filters", {}, void 0, !0)
135
+ ], 512), [
136
+ [F, y.value]
137
+ ])
138
+ ], 2));
139
+ }
140
+ });
2
141
  export {
3
- f as default
142
+ ee as default
4
143
  };
5
144
  //# sourceMappingURL=JFilterBar.vue2.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"JFilterBar.vue2.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
1
+ {"version":3,"file":"JFilterBar.vue2.js","sources":["../../../../src/components/organisms/JFilterBar.vue"],"sourcesContent":["<template>\r\n <div :class=\"cn('j-filter-bar w-full rounded-sm border bg-card text-card-foreground', props.class)\">\r\n <!-- Row 1: toolbar -->\r\n <div class=\"flex items-center justify-between px-3 py-1.5\">\r\n <div class=\"flex items-center gap-2\">\r\n <button\r\n v-if=\"collapsible\"\r\n type=\"button\"\r\n class=\"flex items-center justify-center h-6 w-6 rounded hover:bg-accent hover:text-accent-foreground transition-colors\"\r\n @click=\"toggleCollapsed\"\r\n >\r\n <ChevronDown\r\n :class=\"[\r\n 'h-3.5 w-3.5 transition-transform',\r\n isExpanded ? 'rotate-0' : '-rotate-90',\r\n ]\"\r\n />\r\n </button>\r\n <!-- 타이틀 -->\r\n <JLabel\r\n v-if=\"title\"\r\n :text=\"title\"\r\n class=\"text-sm font-semibold text-foreground\"\r\n />\r\n <!-- 선택된 필터 뱃지 표시 -->\r\n <div v-if=\"activeFilters.length > 0\" class=\"flex items-center gap-1 flex-wrap\">\r\n <JBadge\r\n v-for=\"filter in activeFilters\"\r\n :key=\"filter.key\"\r\n variant=\"secondary\"\r\n size=\"sm\"\r\n class=\"flex items-center gap-1 cursor-default\"\r\n >\r\n <span class=\"text-muted-foreground\">{{ filter.label }}:</span>\r\n <span>{{ filter.value }}</span>\r\n <button\r\n type=\"button\"\r\n class=\"ml-0.5 rounded-full hover:bg-gray-300 p-0.5 transition-colors\"\r\n @click.stop=\"removeFilter(filter.key)\"\r\n >\r\n <X class=\"h-3 w-3\" />\r\n </button>\r\n </JBadge>\r\n </div>\r\n </div>\r\n <div class=\"flex items-center gap-2\">\r\n <slot name=\"actions\" />\r\n <JButton\r\n v-if=\"showResetButton\"\r\n variant=\"secondary\"\r\n size=\"sm\"\r\n @click=\"handleReset\"\r\n >\r\n {{ resetButtonText }}\r\n </JButton>\r\n <JButton\r\n v-if=\"showSearchButton\"\r\n styletype=\"primary\"\r\n size=\"sm\"\r\n @click=\"handleSearch\"\r\n >\r\n {{ searchButtonText }}\r\n </JButton>\r\n </div>\r\n </div>\r\n\r\n <!-- Row 2: filters -->\r\n <div v-show=\"isExpanded\" class=\"px-3 pb-3\">\r\n <slot name=\"filters\" />\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { computed } from 'vue'\r\nimport { ChevronDown, X } from 'lucide-vue-next'\r\nimport JBadge from '@/components/atoms/JBadge.vue'\r\nimport JButton from '@/components/atoms/JButton.vue'\r\nimport JLabel from '@/components/atoms/JLabel.vue'\r\nimport { cn } from '@/lib/utils'\r\n\r\n/** 활성 필터 아이템 타입 */\r\nexport interface ActiveFilterItem {\r\n /** 필터 식별 키 */\r\n key: string\r\n /** 표시할 라벨 (필터명) */\r\n label: string\r\n /** 표시할 값 */\r\n value: string\r\n}\r\n\r\n/** 필터 설정 타입 */\r\nexport interface FilterDisplayItem {\r\n /** 표시할 라벨 */\r\n label: string\r\n /** 값을 표시용 문자열로 변환 (예: combo value -> label) */\r\n displayValue?: (value: unknown) => string\r\n}\r\n\r\nexport interface JFilterBarProps {\r\n /** 추가 클래스 (외부 커스터마이징용) */\r\n class?: string\r\n /** 필터바 타이틀 */\r\n title?: string\r\n /** 필터 접힘 상태 (v-model 지원) */\r\n collapsed?: boolean\r\n /** 접기/펼치기 가능 여부. false면 토글 버튼 숨김 & 필터 항상 표시 */\r\n collapsible?: boolean\r\n /** 필터 값 객체 (v-model:filterValues 지원) */\r\n filterValues?: Record<string, unknown>\r\n /** 필터 표시 설정 (label, displayValue 등) */\r\n filterDisplay?: Record<string, FilterDisplayItem>\r\n /** 초기화 버튼 표시 여부 */\r\n showResetButton?: boolean\r\n /** 조회 버튼 표시 여부 */\r\n showSearchButton?: boolean\r\n /** 초기화 버튼 텍스트 */\r\n resetButtonText?: string\r\n /** 조회 버튼 텍스트 */\r\n searchButtonText?: string\r\n}\r\n\r\nconst props = withDefaults(defineProps<JFilterBarProps>(), {\r\n collapsed: true,\r\n collapsible: true,\r\n filterValues: () => ({}),\r\n filterDisplay: () => ({}),\r\n showResetButton: false,\r\n showSearchButton: false,\r\n resetButtonText: '초기화',\r\n searchButtonText: '조회',\r\n})\r\n\r\nconst emit = defineEmits<{\r\n 'update:collapsed': [value: boolean]\r\n 'update:filterValues': [value: Record<string, unknown>]\r\n /** 조회 버튼 클릭 */\r\n search: []\r\n /** 초기화 버튼 클릭 */\r\n reset: []\r\n}>()\r\n\r\nconst isExpanded = computed(() => {\r\n if (!props.collapsible) return true\r\n return !props.collapsed\r\n})\r\n\r\n/** 값이 비어있는지 확인 */\r\nfunction isEmpty(value: unknown): boolean {\r\n if (value === null || value === undefined) return true\r\n if (typeof value === 'string' && value.trim() === '') return true\r\n if (Array.isArray(value) && value.length === 0) return true\r\n return false\r\n}\r\n\r\n/** filterValues + filterDisplay 기반으로 활성 필터 목록 자동 생성 */\r\nconst activeFilters = computed<ActiveFilterItem[]>(() => {\r\n const filters: ActiveFilterItem[] = []\r\n\r\n for (const [key, config] of Object.entries(props.filterDisplay)) {\r\n const value = props.filterValues[key]\r\n if (isEmpty(value)) continue\r\n\r\n const displayValue = config.displayValue ? config.displayValue(value) : String(value)\r\n if (displayValue.trim() === '') continue\r\n\r\n filters.push({\r\n key,\r\n label: config.label,\r\n value: displayValue,\r\n })\r\n }\r\n\r\n return filters\r\n})\r\n\r\nfunction toggleCollapsed() {\r\n emit('update:collapsed', !props.collapsed)\r\n}\r\n\r\nfunction handleReset() {\r\n // filterValues의 모든 값을 초기화\r\n const resetValues: Record<string, unknown> = {}\r\n for (const key of Object.keys(props.filterValues)) {\r\n const currentValue = props.filterValues[key]\r\n if (typeof currentValue === 'string') {\r\n resetValues[key] = ''\r\n } else if (Array.isArray(currentValue)) {\r\n resetValues[key] = []\r\n } else {\r\n resetValues[key] = null\r\n }\r\n }\r\n emit('update:filterValues', resetValues)\r\n emit('reset')\r\n}\r\n\r\nfunction handleSearch() {\r\n emit('search')\r\n}\r\n\r\nfunction removeFilter(key: string) {\r\n // filterValues 업데이트 (해당 키 값을 초기화)\r\n const newValues = { ...props.filterValues }\r\n const currentValue = newValues[key]\r\n\r\n // 타입에 따라 적절한 초기값으로 설정\r\n if (typeof currentValue === 'string') {\r\n newValues[key] = ''\r\n } else if (Array.isArray(currentValue)) {\r\n newValues[key] = []\r\n } else {\r\n newValues[key] = null\r\n }\r\n\r\n emit('update:filterValues', newValues)\r\n}\r\n</script>\r\n\r\n<style scoped>\r\n/* ========================================\r\n 패턴 3: Tabs 아래 배치 시 연결 스타일\r\n ======================================== */\r\n\r\n:deep([data-state=\"active\"]) > .j-filter-bar {\r\n border-top: none;\r\n border-top-left-radius: 0;\r\n border-top-right-radius: 0;\r\n}\r\n\r\n:deep([role=\"tabpanel\"]) .j-filter-bar {\r\n border-top: none;\r\n}\r\n</style>\r\n"],"names":["props","__props","emit","__emit","isExpanded","computed","isEmpty","value","activeFilters","filters","key","config","displayValue","toggleCollapsed","handleReset","resetValues","currentValue","handleSearch","removeFilter","newValues","_createElementBlock","_normalizeClass","_unref","cn","_createElementVNode","_hoisted_1","_hoisted_2","_createVNode","ChevronDown","_createBlock","JLabel","_openBlock","_hoisted_3","_Fragment","_renderList","filter","JBadge","_hoisted_4","_toDisplayString","_withModifiers","$event","X","_hoisted_6","_renderSlot","_ctx","JButton","_withDirectives","_hoisted_7"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AA0HA,UAAMA,IAAQC,GAWRC,IAAOC,GASPC,IAAaC,EAAS,MACrBL,EAAM,cACJ,CAACA,EAAM,YADiB,EAEhC;AAGD,aAASM,EAAQC,GAAyB;AAGxC,aAFI,GAAAA,KAAU,QACV,OAAOA,KAAU,YAAYA,EAAM,KAAA,MAAW,MAC9C,MAAM,QAAQA,CAAK,KAAKA,EAAM,WAAW;AAAA,IAE/C;AAGA,UAAMC,IAAgBH,EAA6B,MAAM;AACvD,YAAMI,IAA8B,CAAA;AAEpC,iBAAW,CAACC,GAAKC,CAAM,KAAK,OAAO,QAAQX,EAAM,aAAa,GAAG;AAC/D,cAAMO,IAAQP,EAAM,aAAaU,CAAG;AACpC,YAAIJ,EAAQC,CAAK,EAAG;AAEpB,cAAMK,IAAeD,EAAO,eAAeA,EAAO,aAAaJ,CAAK,IAAI,OAAOA,CAAK;AACpF,QAAIK,EAAa,KAAA,MAAW,MAE5BH,EAAQ,KAAK;AAAA,UACX,KAAAC;AAAA,UACA,OAAOC,EAAO;AAAA,UACd,OAAOC;AAAA,QAAA,CACR;AAAA,MACH;AAEA,aAAOH;AAAA,IACT,CAAC;AAED,aAASI,IAAkB;AACzB,MAAAX,EAAK,oBAAoB,CAACF,EAAM,SAAS;AAAA,IAC3C;AAEA,aAASc,IAAc;AAErB,YAAMC,IAAuC,CAAA;AAC7C,iBAAWL,KAAO,OAAO,KAAKV,EAAM,YAAY,GAAG;AACjD,cAAMgB,IAAehB,EAAM,aAAaU,CAAG;AAC3C,QAAI,OAAOM,KAAiB,WAC1BD,EAAYL,CAAG,IAAI,KACV,MAAM,QAAQM,CAAY,IACnCD,EAAYL,CAAG,IAAI,CAAA,IAEnBK,EAAYL,CAAG,IAAI;AAAA,MAEvB;AACA,MAAAR,EAAK,uBAAuBa,CAAW,GACvCb,EAAK,OAAO;AAAA,IACd;AAEA,aAASe,IAAe;AACtB,MAAAf,EAAK,QAAQ;AAAA,IACf;AAEA,aAASgB,EAAaR,GAAa;AAEjC,YAAMS,IAAY,EAAE,GAAGnB,EAAM,aAAA,GACvBgB,IAAeG,EAAUT,CAAG;AAGlC,MAAI,OAAOM,KAAiB,WAC1BG,EAAUT,CAAG,IAAI,KACR,MAAM,QAAQM,CAAY,IACnCG,EAAUT,CAAG,IAAI,CAAA,IAEjBS,EAAUT,CAAG,IAAI,MAGnBR,EAAK,uBAAuBiB,CAAS;AAAA,IACvC;2BAvNEC,EAqEM,OAAA;AAAA,MArEA,OAAKC,EAAEC,EAAAC,CAAA,EAAE,sEAAuEvB,EAAM,KAAK,CAAA;AAAA,IAAA;MAE/FwB,EA6DM,OA7DNC,GA6DM;AAAA,QA5DJD,EAwCM,OAxCNE,GAwCM;AAAA,UAtCIzB,EAAA,oBADRmB,EAYS,UAAA;AAAA;YAVP,MAAK;AAAA,YACL,OAAM;AAAA,YACL,SAAOP;AAAA,UAAA;YAERc,EAKEL,EAAAM,CAAA,GAAA;AAAA,cAJC,OAAKP,EAAA;AAAA;gBAAsEjB,EAAA,QAAU,aAAA;AAAA,cAAA;;;UAQlFH,EAAA,cADR4B,EAIEC,GAAA;AAAA;YAFC,MAAM7B,EAAA;AAAA,YACP,OAAM;AAAA,UAAA;UAGGO,EAAA,MAAc,SAAM,KAA/BuB,KAAAX,EAkBM,OAlBNY,GAkBM;AAAA,oBAjBJZ,EAgBSa,GAAA,MAAAC,EAfU1B,EAAA,OAAa,CAAvB2B,YADTN,EAgBSO,GAAA;AAAA,cAdN,KAAKD,EAAO;AAAA,cACb,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,OAAM;AAAA,YAAA;yBAEN,MAA8D;AAAA,gBAA9DX,EAA8D,QAA9Da,GAA8DC,EAAvBH,EAAO,KAAK,IAAG,KAAC,CAAA;AAAA,gBACvDX,EAA+B,QAAA,MAAAc,EAAtBH,EAAO,KAAK,GAAA,CAAA;AAAA,gBACrBX,EAMS,UAAA;AAAA,kBALP,MAAK;AAAA,kBACL,OAAM;AAAA,kBACL,SAAKe,EAAA,CAAAC,MAAOtB,EAAaiB,EAAO,GAAG,GAAA,CAAA,MAAA,CAAA;AAAA,gBAAA;kBAEpCR,EAAqBL,EAAAmB,CAAA,GAAA,EAAlB,OAAM,WAAS;AAAA,gBAAA;;;;;;QAK1BjB,EAkBM,OAlBNkB,GAkBM;AAAA,UAjBJC,EAAuBC,EAAA,QAAA,WAAA,CAAA,GAAA,QAAA,EAAA;AAAA,UAEf3C,EAAA,wBADR4B,EAOUgB,GAAA;AAAA;YALR,SAAQ;AAAA,YACR,MAAK;AAAA,YACJ,SAAO/B;AAAA,UAAA;uBAER,MAAqB;AAAA,kBAAlBb,EAAA,eAAe,GAAA,CAAA;AAAA,YAAA;;;UAGZA,EAAA,yBADR4B,EAOUgB,GAAA;AAAA;YALR,WAAU;AAAA,YACV,MAAK;AAAA,YACJ,SAAO5B;AAAA,UAAA;uBAER,MAAsB;AAAA,kBAAnBhB,EAAA,gBAAgB,GAAA,CAAA;AAAA,YAAA;;;;;MAMzB6C,EAAAtB,EAEM,OAFNuB,GAEM;AAAA,QADJJ,EAAuBC,EAAA,QAAA,WAAA,CAAA,GAAA,QAAA,EAAA;AAAA,MAAA;YADZxC,EAAA,KAAU;AAAA,MAAA;;;;"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue");require("../shadcn/index.cjs");const i=require("../atoms/JButton.vue.cjs");require("lucide-vue-next");require("clsx");require("tailwind-merge");require("@internationalized/date");require("md-editor-v3");;/* empty css */;/* empty css */require("../shadcn/badge-variants.cjs");require("@vueuse/core");require("reka-ui");;/* empty css */require("../shadcn/avatar-variants.cjs");require("dompurify");;/* empty css */require("ag-grid-vue3");require("ag-grid-community");require("ag-grid-enterprise");;/* empty css */;/* empty css */;/* empty css */;/* empty css */require("vue-sonner");;/* empty css */;/* empty css */;/* empty css */;/* empty css */const x=require("./JDynamicForm.vue.cjs");;/* empty css */require("vue-router");;/* empty css */;/* empty css */const h=require("../shadcn/Dialog.vue.cjs"),y=require("../shadcn/DialogContent.vue.cjs"),C=require("../shadcn/DialogHeader.vue.cjs"),V=require("../shadcn/DialogTitle.vue.cjs"),b=require("../shadcn/DialogBody.vue.cjs"),k=require("../shadcn/DialogFooter.vue.cjs"),w={class:"space-y-4"},D={key:0,class:"text-sm text-muted-foreground"},N=e.defineComponent({__name:"JFormModal",props:{open:{type:Boolean,default:!1},title:{},description:{},schema:{},modelValue:{},size:{default:"lg"},buttonType:{default:"OkCancel"},confirmText:{default:"확인"},cancelText:{default:"취소"},confirmVariant:{default:"default"},confirmDisabled:{type:Boolean,default:!1}},emits:["update:open","update:modelValue","confirm","cancel","submit","change","error"],setup(r,{expose:d,emit:s}){const o=r,u=s,a=e.ref(null),l=e.ref(o.modelValue||{}),n=e.ref(!1),m=e.computed(()=>({sm:"!max-w-sm",md:"!max-w-md",lg:"!max-w-2xl",xl:"!max-w-4xl","2xl":"!max-w-6xl",full:"!max-w-[95vw]"})[o.size]);e.watch(()=>o.modelValue,t=>{t!=null?l.value={...t}:l.value={}},{deep:!0});const f=t=>{l.value=t,u("update:modelValue",t)},v=t=>{u("change",t)},q=t=>{u("submit",t),n.value&&(u("confirm",t),n.value=!1)},_=t=>{u("error",t),n.value=!1},p=t=>{u("update:open",t)},c=()=>{n.value=!0,a.value&&a.value.submit()},g=()=>{u("cancel"),a.value&&a.value.reset()};return d({reset:()=>a.value?.reset(),submit:()=>a.value?.submit(),formState:e.computed(()=>a.value?.formState)}),(t,B)=>(e.openBlock(),e.createBlock(e.unref(h.default),{open:r.open,"onUpdate:open":p,class:e.normalizeClass(m.value)},{default:e.withCtx(()=>[e.createVNode(e.unref(y.default),null,{default:e.withCtx(()=>[r.title?(e.openBlock(),e.createBlock(e.unref(C.default),{key:0,class:"bg-muted/50 border-b"},{default:e.withCtx(()=>[e.createVNode(e.unref(V.default),null,{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(r.title),1)]),_:1})]),_:1})):e.createCommentVNode("",!0),e.createVNode(e.unref(b.default),{class:"max-h-[70vh] overflow-y-auto"},{default:e.withCtx(()=>[e.createElementVNode("div",w,[r.description?(e.openBlock(),e.createElementBlock("p",D,e.toDisplayString(r.description),1)):e.createCommentVNode("",!0),e.createVNode(e.unref(x.default),{ref_key:"dynamicFormRef",ref:a,schema:r.schema,"model-value":l.value,"onUpdate:modelValue":f,onSubmit:q,onChange:v,onError:_},null,8,["schema","model-value"]),e.renderSlot(t.$slots,"body")])]),_:3}),e.createVNode(e.unref(k.default),null,{default:e.withCtx(()=>[r.buttonType==="OkCancel"?(e.openBlock(),e.createElementBlock(e.Fragment,{key:0},[e.createVNode(e.unref(i.default),{variant:"outline",onClick:g},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(r.cancelText),1)]),_:1}),e.createVNode(e.unref(i.default),{variant:r.confirmVariant,disabled:r.confirmDisabled,onClick:c},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(r.confirmText),1)]),_:1},8,["variant","disabled"])],64)):r.buttonType==="Ok"?(e.openBlock(),e.createBlock(e.unref(i.default),{key:1,variant:r.confirmVariant,disabled:r.confirmDisabled,onClick:c,class:"w-full"},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(r.confirmText),1)]),_:1},8,["variant","disabled"])):e.createCommentVNode("",!0),e.renderSlot(t.$slots,"footer")]),_:3})]),_:3})]),_:3},8,["open","class"]))}});exports.default=N;
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue");require("../shadcn/index.cjs");const o=require("../atoms/JButton.vue.cjs");require("lucide-vue-next");require("clsx");require("tailwind-merge");require("@internationalized/date");require("md-editor-v3");;/* empty css */;/* empty css */require("../shadcn/badge-variants.cjs");require("@vueuse/core");require("reka-ui");;/* empty css */require("../shadcn/avatar-variants.cjs");require("dompurify");;/* empty css */require("ag-grid-vue3");require("ag-grid-community");require("ag-grid-enterprise");;/* empty css */;/* empty css */;/* empty css */;/* empty css */;/* empty css */;/* empty css */require("vue-sonner");;/* empty css */;/* empty css */;/* empty css */;/* empty css */;/* empty css */const g=require("./JDynamicForm.vue.cjs");;/* empty css */;/* empty css */require("vue-router");;/* empty css */;/* empty css */;/* empty css */const h=require("../shadcn/Dialog.vue.cjs"),y=require("../shadcn/DialogContent.vue.cjs"),C=require("../shadcn/DialogHeader.vue.cjs"),V=require("../shadcn/DialogTitle.vue.cjs"),b=require("../shadcn/DialogBody.vue.cjs"),k=require("../shadcn/DialogFooter.vue.cjs"),w={class:"space-y-4"},D={key:0,class:"text-sm text-muted-foreground"},N=e.defineComponent({__name:"JFormModal",props:{open:{type:Boolean,default:!1},title:{},description:{},schema:{},modelValue:{},size:{default:"lg"},buttonType:{default:"OkCancel"},confirmText:{default:"확인"},cancelText:{default:"취소"},confirmVariant:{default:"default"},confirmDisabled:{type:Boolean,default:!1}},emits:["update:open","update:modelValue","confirm","cancel","submit","change","error"],setup(r,{expose:d,emit:s}){const n=r,u=s,a=e.ref(null),l=e.ref(n.modelValue||{}),i=e.ref(!1),m=e.computed(()=>({sm:"!max-w-sm",md:"!max-w-md",lg:"!max-w-2xl",xl:"!max-w-4xl","2xl":"!max-w-6xl",full:"!max-w-[95vw]"})[n.size]);e.watch(()=>n.modelValue,t=>{t!=null?l.value={...t}:l.value={}},{deep:!0});const f=t=>{l.value=t,u("update:modelValue",t)},q=t=>{u("change",t)},v=t=>{u("submit",t),i.value&&(u("confirm",t),i.value=!1)},p=t=>{u("error",t),i.value=!1},x=t=>{u("update:open",t)},c=()=>{i.value=!0,a.value&&a.value.submit()},_=()=>{u("cancel"),a.value&&a.value.reset()};return d({reset:()=>a.value?.reset(),submit:()=>a.value?.submit(),formState:e.computed(()=>a.value?.formState)}),(t,B)=>(e.openBlock(),e.createBlock(e.unref(h.default),{open:r.open,"onUpdate:open":x,class:e.normalizeClass(m.value)},{default:e.withCtx(()=>[e.createVNode(e.unref(y.default),null,{default:e.withCtx(()=>[r.title?(e.openBlock(),e.createBlock(e.unref(C.default),{key:0,class:"bg-muted/50 border-b"},{default:e.withCtx(()=>[e.createVNode(e.unref(V.default),null,{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(r.title),1)]),_:1})]),_:1})):e.createCommentVNode("",!0),e.createVNode(e.unref(b.default),{class:"max-h-[70vh] overflow-y-auto"},{default:e.withCtx(()=>[e.createElementVNode("div",w,[r.description?(e.openBlock(),e.createElementBlock("p",D,e.toDisplayString(r.description),1)):e.createCommentVNode("",!0),e.createVNode(e.unref(g.default),{ref_key:"dynamicFormRef",ref:a,schema:r.schema,"model-value":l.value,"onUpdate:modelValue":f,onSubmit:v,onChange:q,onError:p},null,8,["schema","model-value"]),e.renderSlot(t.$slots,"body")])]),_:3}),e.createVNode(e.unref(k.default),null,{default:e.withCtx(()=>[r.buttonType==="OkCancel"?(e.openBlock(),e.createElementBlock(e.Fragment,{key:0},[e.createVNode(e.unref(o.default),{variant:"outline",onClick:_},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(r.cancelText),1)]),_:1}),e.createVNode(e.unref(o.default),{variant:r.confirmVariant,disabled:r.confirmDisabled,onClick:c},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(r.confirmText),1)]),_:1},8,["variant","disabled"])],64)):r.buttonType==="Ok"?(e.openBlock(),e.createBlock(e.unref(o.default),{key:1,variant:r.confirmVariant,disabled:r.confirmDisabled,onClick:c,class:"w-full"},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(r.confirmText),1)]),_:1},8,["variant","disabled"])):e.createCommentVNode("",!0),e.renderSlot(t.$slots,"footer")]),_:3})]),_:3})]),_:3},8,["open","class"]))}});exports.default=N;
2
2
  //# sourceMappingURL=JFormModal.vue.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"JFormModal.vue.cjs","sources":["../../../../src/components/organisms/JFormModal.vue"],"sourcesContent":["<template>\r\n <Dialog\r\n :open=\"open\"\r\n @update:open=\"onOpenChange\"\r\n :class=\"sizeClass\"\r\n >\r\n <DialogContent>\r\n <!-- Header -->\r\n <DialogHeader v-if=\"title\" class=\"bg-muted/50 border-b\">\r\n <DialogTitle>\r\n {{ title }}\r\n </DialogTitle>\r\n </DialogHeader>\r\n\r\n <!-- Body -->\r\n <DialogBody class=\"max-h-[70vh] overflow-y-auto\">\r\n <div class=\"space-y-4\">\r\n <!-- Description -->\r\n <p v-if=\"description\" class=\"text-sm text-muted-foreground\">\r\n {{ description }}\r\n </p>\r\n\r\n <!-- JDynamicForm -->\r\n <JDynamicForm\r\n ref=\"dynamicFormRef\"\r\n :schema=\"schema\"\r\n :model-value=\"internalFormValue\"\r\n @update:model-value=\"handleFormChange\"\r\n @submit=\"handleFormSubmit\"\r\n @change=\"handleFieldChange\"\r\n @error=\"handleFormError\"\r\n />\r\n\r\n <!-- 커스텀 컨텐츠 슬롯 -->\r\n <slot name=\"body\" />\r\n </div>\r\n </DialogBody>\r\n\r\n <!-- Footer -->\r\n <DialogFooter>\r\n <!-- 확인/취소 버튼 -->\r\n <template v-if=\"buttonType === 'OkCancel'\">\r\n <JButton\r\n variant=\"outline\"\r\n @click=\"handleCancel\"\r\n >\r\n {{ cancelText }}\r\n </JButton>\r\n <JButton\r\n :variant=\"confirmVariant\"\r\n :disabled=\"confirmDisabled\"\r\n @click=\"handleConfirm\"\r\n >\r\n {{ confirmText }}\r\n </JButton>\r\n </template>\r\n \r\n <!-- 확인 버튼만 -->\r\n <template v-else-if=\"buttonType === 'Ok'\">\r\n <JButton\r\n :variant=\"confirmVariant\"\r\n :disabled=\"confirmDisabled\"\r\n @click=\"handleConfirm\"\r\n class=\"w-full\"\r\n >\r\n {{ confirmText }}\r\n </JButton>\r\n </template>\r\n\r\n <!-- 커스텀 푸터 슬롯 -->\r\n <slot name=\"footer\" />\r\n </DialogFooter>\r\n </DialogContent>\r\n </Dialog>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { computed, ref, watch } from 'vue'\r\nimport {\r\n Dialog,\r\n DialogBody,\r\n DialogContent,\r\n DialogFooter,\r\n DialogHeader,\r\n DialogTitle,\r\n} from '@/components/shadcn'\r\nimport { JButton } from '@/components/atoms'\r\nimport { JDynamicForm } from '@/components/organisms'\r\nimport type { FormSchema } from '@/types/dynamic-form'\r\n\r\nexport interface JFormModalProps {\r\n // 모달 표시 여부\r\n open: boolean\r\n // 헤더\r\n title?: string\r\n description?: string\r\n // 다이나믹 폼 스키마 (필수)\r\n schema: FormSchema\r\n // 폼 값\r\n modelValue?: Record<string, any>\r\n // 모달 사이즈 (유동적)\r\n size?: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'full'\r\n // 버튼 설정\r\n buttonType?: 'Ok' | 'OkCancel'\r\n confirmText?: string\r\n cancelText?: string\r\n confirmVariant?: 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link'\r\n confirmDisabled?: boolean\r\n}\r\n\r\nconst props = withDefaults(defineProps<JFormModalProps>(), {\r\n open: false,\r\n size: 'lg',\r\n buttonType: 'OkCancel',\r\n confirmText: '확인',\r\n cancelText: '취소',\r\n confirmVariant: 'default',\r\n confirmDisabled: false,\r\n})\r\n\r\nconst emit = defineEmits<{\r\n 'update:open': [value: boolean]\r\n 'update:modelValue': [value: Record<string, any>]\r\n 'confirm': [value: Record<string, any>]\r\n 'cancel': []\r\n 'submit': [value: Record<string, any>]\r\n 'change': [data: { field: string; value: any }]\r\n 'error': [errors: any]\r\n}>()\r\n\r\n// 다이나믹 폼 ref\r\nconst dynamicFormRef = ref<InstanceType<typeof JDynamicForm> | null>(null)\r\n\r\n// 내부 폼 값 관리\r\nconst internalFormValue = ref<Record<string, any>>(props.modelValue || {})\r\n// 확인 버튼 클릭 이후 검증 성공 시점에만 confirm 이벤트를 방출하기 위한 플래그\r\nconst isConfirming = ref<boolean>(false)\r\n\r\n// 사이즈 클래스 계산\r\nconst sizeClass = computed(() => {\r\n // Dialog.vue에 기본 max-w-lg가 하드코딩되어 있어 !max-w-*로 오버라이드\r\n const sizeMap: Record<NonNullable<JFormModalProps['size']>, string> = {\r\n 'sm': '!max-w-sm',\r\n 'md': '!max-w-md',\r\n 'lg': '!max-w-2xl',\r\n 'xl': '!max-w-4xl',\r\n '2xl': '!max-w-6xl',\r\n 'full': '!max-w-[95vw]'\r\n }\r\n return sizeMap[props.size]\r\n})\r\n\r\n// props.modelValue 변경 감지\r\nwatch(() => props.modelValue, (newValue) => {\r\n if (newValue != null) {\r\n internalFormValue.value = { ...newValue }\r\n } else {\r\n internalFormValue.value = {}\r\n }\r\n}, { deep: true })\r\n\r\n// 폼 변경 핸들러\r\nconst handleFormChange = (value: Record<string, any>) => {\r\n internalFormValue.value = value\r\n emit('update:modelValue', value)\r\n}\r\n\r\n// 필드 변경 핸들러\r\nconst handleFieldChange = (data: { field: string; value: any }) => {\r\n emit('change', data)\r\n}\r\n\r\n// 폼 제출 핸들러\r\nconst handleFormSubmit = (value: Record<string, any>) => {\r\n emit('submit', value)\r\n if (isConfirming.value) {\r\n emit('confirm', value)\r\n isConfirming.value = false\r\n }\r\n}\r\n\r\n// 폼 에러 핸들러\r\nconst handleFormError = (errors: any) => {\r\n emit('error', errors)\r\n // 검증 실패 시 confirm 방출을 차단\r\n isConfirming.value = false\r\n}\r\n\r\n// 모달 열기/닫기 핸들러\r\nconst onOpenChange = (value: boolean) => {\r\n emit('update:open', value)\r\n}\r\n\r\n// 확인 버튼 핸들러\r\nconst handleConfirm = () => {\r\n // 폼 제출 트리거 (검증 성공 시점에 handleFormSubmit에서 confirm 방출)\r\n isConfirming.value = true\r\n if (dynamicFormRef.value) {\r\n dynamicFormRef.value.submit()\r\n }\r\n}\r\n\r\n// 취소 버튼 핸들러\r\nconst handleCancel = () => {\r\n emit('cancel')\r\n // 폼 리셋\r\n if (dynamicFormRef.value) {\r\n dynamicFormRef.value.reset()\r\n }\r\n}\r\n\r\n// 외부에서 접근 가능한 메서드\r\ndefineExpose({\r\n reset: () => dynamicFormRef.value?.reset(),\r\n submit: () => dynamicFormRef.value?.submit(),\r\n formState: computed(() => dynamicFormRef.value?.formState),\r\n})\r\n</script>\r\n"],"names":["props","__props","emit","__emit","dynamicFormRef","ref","internalFormValue","isConfirming","sizeClass","computed","watch","newValue","handleFormChange","value","handleFieldChange","data","handleFormSubmit","handleFormError","errors","onOpenChange","handleConfirm","handleCancel","__expose","_createBlock","_unref","Dialog","_createVNode","DialogContent","DialogHeader","DialogTitle","DialogBody","_createElementVNode","_hoisted_1","_createElementBlock","_hoisted_2","_toDisplayString","JDynamicForm","_renderSlot","_ctx","DialogFooter","_Fragment","JButton"],"mappings":"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"}
1
+ {"version":3,"file":"JFormModal.vue.cjs","sources":["../../../../src/components/organisms/JFormModal.vue"],"sourcesContent":["<template>\r\n <Dialog\r\n :open=\"open\"\r\n @update:open=\"onOpenChange\"\r\n :class=\"sizeClass\"\r\n >\r\n <DialogContent>\r\n <!-- Header -->\r\n <DialogHeader v-if=\"title\" class=\"bg-muted/50 border-b\">\r\n <DialogTitle>\r\n {{ title }}\r\n </DialogTitle>\r\n </DialogHeader>\r\n\r\n <!-- Body -->\r\n <DialogBody class=\"max-h-[70vh] overflow-y-auto\">\r\n <div class=\"space-y-4\">\r\n <!-- Description -->\r\n <p v-if=\"description\" class=\"text-sm text-muted-foreground\">\r\n {{ description }}\r\n </p>\r\n\r\n <!-- JDynamicForm -->\r\n <JDynamicForm\r\n ref=\"dynamicFormRef\"\r\n :schema=\"schema\"\r\n :model-value=\"internalFormValue\"\r\n @update:model-value=\"handleFormChange\"\r\n @submit=\"handleFormSubmit\"\r\n @change=\"handleFieldChange\"\r\n @error=\"handleFormError\"\r\n />\r\n\r\n <!-- 커스텀 컨텐츠 슬롯 -->\r\n <slot name=\"body\" />\r\n </div>\r\n </DialogBody>\r\n\r\n <!-- Footer -->\r\n <DialogFooter>\r\n <!-- 확인/취소 버튼 -->\r\n <template v-if=\"buttonType === 'OkCancel'\">\r\n <JButton\r\n variant=\"outline\"\r\n @click=\"handleCancel\"\r\n >\r\n {{ cancelText }}\r\n </JButton>\r\n <JButton\r\n :variant=\"confirmVariant\"\r\n :disabled=\"confirmDisabled\"\r\n @click=\"handleConfirm\"\r\n >\r\n {{ confirmText }}\r\n </JButton>\r\n </template>\r\n \r\n <!-- 확인 버튼만 -->\r\n <template v-else-if=\"buttonType === 'Ok'\">\r\n <JButton\r\n :variant=\"confirmVariant\"\r\n :disabled=\"confirmDisabled\"\r\n @click=\"handleConfirm\"\r\n class=\"w-full\"\r\n >\r\n {{ confirmText }}\r\n </JButton>\r\n </template>\r\n\r\n <!-- 커스텀 푸터 슬롯 -->\r\n <slot name=\"footer\" />\r\n </DialogFooter>\r\n </DialogContent>\r\n </Dialog>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { computed, ref, watch } from 'vue'\r\nimport {\r\n Dialog,\r\n DialogBody,\r\n DialogContent,\r\n DialogFooter,\r\n DialogHeader,\r\n DialogTitle,\r\n} from '@/components/shadcn'\r\nimport { JButton } from '@/components/atoms'\r\nimport { JDynamicForm } from '@/components/organisms'\r\nimport type { FormSchema } from '@/types/dynamic-form'\r\n\r\nexport interface JFormModalProps {\r\n // 모달 표시 여부\r\n open: boolean\r\n // 헤더\r\n title?: string\r\n description?: string\r\n // 다이나믹 폼 스키마 (필수)\r\n schema: FormSchema\r\n // 폼 값\r\n modelValue?: Record<string, any>\r\n // 모달 사이즈 (유동적)\r\n size?: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'full'\r\n // 버튼 설정\r\n buttonType?: 'Ok' | 'OkCancel'\r\n confirmText?: string\r\n cancelText?: string\r\n confirmVariant?: 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link'\r\n confirmDisabled?: boolean\r\n}\r\n\r\nconst props = withDefaults(defineProps<JFormModalProps>(), {\r\n open: false,\r\n size: 'lg',\r\n buttonType: 'OkCancel',\r\n confirmText: '확인',\r\n cancelText: '취소',\r\n confirmVariant: 'default',\r\n confirmDisabled: false,\r\n})\r\n\r\nconst emit = defineEmits<{\r\n 'update:open': [value: boolean]\r\n 'update:modelValue': [value: Record<string, any>]\r\n 'confirm': [value: Record<string, any>]\r\n 'cancel': []\r\n 'submit': [value: Record<string, any>]\r\n 'change': [data: { field: string; value: any }]\r\n 'error': [errors: any]\r\n}>()\r\n\r\n// 다이나믹 폼 ref\r\nconst dynamicFormRef = ref<InstanceType<typeof JDynamicForm> | null>(null)\r\n\r\n// 내부 폼 값 관리\r\nconst internalFormValue = ref<Record<string, any>>(props.modelValue || {})\r\n// 확인 버튼 클릭 이후 검증 성공 시점에만 confirm 이벤트를 방출하기 위한 플래그\r\nconst isConfirming = ref<boolean>(false)\r\n\r\n// 사이즈 클래스 계산\r\nconst sizeClass = computed(() => {\r\n // Dialog.vue에 기본 max-w-lg가 하드코딩되어 있어 !max-w-*로 오버라이드\r\n const sizeMap: Record<NonNullable<JFormModalProps['size']>, string> = {\r\n 'sm': '!max-w-sm',\r\n 'md': '!max-w-md',\r\n 'lg': '!max-w-2xl',\r\n 'xl': '!max-w-4xl',\r\n '2xl': '!max-w-6xl',\r\n 'full': '!max-w-[95vw]'\r\n }\r\n return sizeMap[props.size]\r\n})\r\n\r\n// props.modelValue 변경 감지\r\nwatch(() => props.modelValue, (newValue) => {\r\n if (newValue != null) {\r\n internalFormValue.value = { ...newValue }\r\n } else {\r\n internalFormValue.value = {}\r\n }\r\n}, { deep: true })\r\n\r\n// 폼 변경 핸들러\r\nconst handleFormChange = (value: Record<string, any>) => {\r\n internalFormValue.value = value\r\n emit('update:modelValue', value)\r\n}\r\n\r\n// 필드 변경 핸들러\r\nconst handleFieldChange = (data: { field: string; value: any }) => {\r\n emit('change', data)\r\n}\r\n\r\n// 폼 제출 핸들러\r\nconst handleFormSubmit = (value: Record<string, any>) => {\r\n emit('submit', value)\r\n if (isConfirming.value) {\r\n emit('confirm', value)\r\n isConfirming.value = false\r\n }\r\n}\r\n\r\n// 폼 에러 핸들러\r\nconst handleFormError = (errors: any) => {\r\n emit('error', errors)\r\n // 검증 실패 시 confirm 방출을 차단\r\n isConfirming.value = false\r\n}\r\n\r\n// 모달 열기/닫기 핸들러\r\nconst onOpenChange = (value: boolean) => {\r\n emit('update:open', value)\r\n}\r\n\r\n// 확인 버튼 핸들러\r\nconst handleConfirm = () => {\r\n // 폼 제출 트리거 (검증 성공 시점에 handleFormSubmit에서 confirm 방출)\r\n isConfirming.value = true\r\n if (dynamicFormRef.value) {\r\n dynamicFormRef.value.submit()\r\n }\r\n}\r\n\r\n// 취소 버튼 핸들러\r\nconst handleCancel = () => {\r\n emit('cancel')\r\n // 폼 리셋\r\n if (dynamicFormRef.value) {\r\n dynamicFormRef.value.reset()\r\n }\r\n}\r\n\r\n// 외부에서 접근 가능한 메서드\r\ndefineExpose({\r\n reset: () => dynamicFormRef.value?.reset(),\r\n submit: () => dynamicFormRef.value?.submit(),\r\n formState: computed(() => dynamicFormRef.value?.formState),\r\n})\r\n</script>\r\n"],"names":["props","__props","emit","__emit","dynamicFormRef","ref","internalFormValue","isConfirming","sizeClass","computed","watch","newValue","handleFormChange","value","handleFieldChange","data","handleFormSubmit","handleFormError","errors","onOpenChange","handleConfirm","handleCancel","__expose","_createBlock","_unref","Dialog","_createVNode","DialogContent","DialogHeader","DialogTitle","DialogBody","_createElementVNode","_hoisted_1","_createElementBlock","_hoisted_2","_toDisplayString","JDynamicForm","_renderSlot","_ctx","DialogFooter","_Fragment","JButton"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { defineComponent as B, ref as f, computed as b, watch as D, createBlock as p, openBlock as n, unref as a, normalizeClass as E, withCtx as o, createVNode as i, createCommentVNode as v, createTextVNode as u, toDisplayString as r, createElementVNode as N, createElementBlock as y, renderSlot as C, Fragment as O } from "vue";
1
+ import { defineComponent as S, ref as f, computed as b, watch as D, createBlock as p, openBlock as r, unref as o, normalizeClass as E, withCtx as a, createVNode as i, createCommentVNode as v, createTextVNode as s, toDisplayString as n, createElementVNode as N, createElementBlock as y, renderSlot as C, Fragment as O } from "vue";
2
2
  import "../shadcn/index.js";
3
3
  import h from "../atoms/JButton.vue.js";
4
4
  import "lucide-vue-next";
@@ -22,26 +22,31 @@ import "ag-grid-enterprise";
22
22
  /* empty css */
23
23
  /* empty css */
24
24
  /* empty css */
25
+ /* empty css */
26
+ /* empty css */
25
27
  import "vue-sonner";
26
28
  /* empty css */
27
29
  /* empty css */
28
30
  /* empty css */
29
31
  /* empty css */
30
- import M from "./JDynamicForm.vue.js";
32
+ /* empty css */
33
+ import J from "./JDynamicForm.vue.js";
31
34
  /* empty css */
35
+ /* empty css */
32
36
  import "vue-router";
33
37
  /* empty css */
34
38
  /* empty css */
35
- import J from "../shadcn/Dialog.vue.js";
39
+ /* empty css */
40
+ import M from "../shadcn/Dialog.vue.js";
36
41
  import R from "../shadcn/DialogContent.vue.js";
37
42
  import U from "../shadcn/DialogHeader.vue.js";
38
- import _ from "../shadcn/DialogTitle.vue.js";
39
- import j from "../shadcn/DialogBody.vue.js";
40
- import q from "../shadcn/DialogFooter.vue.js";
41
- const A = { class: "space-y-4" }, G = {
43
+ import j from "../shadcn/DialogTitle.vue.js";
44
+ import q from "../shadcn/DialogBody.vue.js";
45
+ import A from "../shadcn/DialogFooter.vue.js";
46
+ const G = { class: "space-y-4" }, H = {
42
47
  key: 0,
43
48
  class: "text-sm text-muted-foreground"
44
- }, De = /* @__PURE__ */ B({
49
+ }, Me = /* @__PURE__ */ S({
45
50
  __name: "JFormModal",
46
51
  props: {
47
52
  open: { type: Boolean, default: !1 },
@@ -58,7 +63,7 @@ const A = { class: "space-y-4" }, G = {
58
63
  },
59
64
  emits: ["update:open", "update:modelValue", "confirm", "cancel", "submit", "change", "error"],
60
65
  setup(t, { expose: k, emit: g }) {
61
- const d = t, m = g, l = f(null), c = f(d.modelValue || {}), s = f(!1), V = b(() => ({
66
+ const d = t, l = g, m = f(null), c = f(d.modelValue || {}), u = f(!1), V = b(() => ({
62
67
  sm: "!max-w-sm",
63
68
  md: "!max-w-md",
64
69
  lg: "!max-w-2xl",
@@ -70,53 +75,53 @@ const A = { class: "space-y-4" }, G = {
70
75
  e != null ? c.value = { ...e } : c.value = {};
71
76
  }, { deep: !0 });
72
77
  const w = (e) => {
73
- c.value = e, m("update:modelValue", e);
78
+ c.value = e, l("update:modelValue", e);
74
79
  }, F = (e) => {
75
- m("change", e);
80
+ l("change", e);
76
81
  }, T = (e) => {
77
- m("submit", e), s.value && (m("confirm", e), s.value = !1);
82
+ l("submit", e), u.value && (l("confirm", e), u.value = !1);
78
83
  }, $ = (e) => {
79
- m("error", e), s.value = !1;
84
+ l("error", e), u.value = !1;
80
85
  }, z = (e) => {
81
- m("update:open", e);
86
+ l("update:open", e);
82
87
  }, x = () => {
83
- s.value = !0, l.value && l.value.submit();
84
- }, S = () => {
85
- m("cancel"), l.value && l.value.reset();
88
+ u.value = !0, m.value && m.value.submit();
89
+ }, B = () => {
90
+ l("cancel"), m.value && m.value.reset();
86
91
  };
87
92
  return k({
88
- reset: () => l.value?.reset(),
89
- submit: () => l.value?.submit(),
90
- formState: b(() => l.value?.formState)
91
- }), (e, H) => (n(), p(a(J), {
93
+ reset: () => m.value?.reset(),
94
+ submit: () => m.value?.submit(),
95
+ formState: b(() => m.value?.formState)
96
+ }), (e, I) => (r(), p(o(M), {
92
97
  open: t.open,
93
98
  "onUpdate:open": z,
94
99
  class: E(V.value)
95
100
  }, {
96
- default: o(() => [
97
- i(a(R), null, {
98
- default: o(() => [
99
- t.title ? (n(), p(a(U), {
101
+ default: a(() => [
102
+ i(o(R), null, {
103
+ default: a(() => [
104
+ t.title ? (r(), p(o(U), {
100
105
  key: 0,
101
106
  class: "bg-muted/50 border-b"
102
107
  }, {
103
- default: o(() => [
104
- i(a(_), null, {
105
- default: o(() => [
106
- u(r(t.title), 1)
108
+ default: a(() => [
109
+ i(o(j), null, {
110
+ default: a(() => [
111
+ s(n(t.title), 1)
107
112
  ]),
108
113
  _: 1
109
114
  })
110
115
  ]),
111
116
  _: 1
112
117
  })) : v("", !0),
113
- i(a(j), { class: "max-h-[70vh] overflow-y-auto" }, {
114
- default: o(() => [
115
- N("div", A, [
116
- t.description ? (n(), y("p", G, r(t.description), 1)) : v("", !0),
117
- i(a(M), {
118
+ i(o(q), { class: "max-h-[70vh] overflow-y-auto" }, {
119
+ default: a(() => [
120
+ N("div", G, [
121
+ t.description ? (r(), y("p", H, n(t.description), 1)) : v("", !0),
122
+ i(o(J), {
118
123
  ref_key: "dynamicFormRef",
119
- ref: l,
124
+ ref: m,
120
125
  schema: t.schema,
121
126
  "model-value": c.value,
122
127
  "onUpdate:modelValue": w,
@@ -129,37 +134,37 @@ const A = { class: "space-y-4" }, G = {
129
134
  ]),
130
135
  _: 3
131
136
  }),
132
- i(a(q), null, {
133
- default: o(() => [
134
- t.buttonType === "OkCancel" ? (n(), y(O, { key: 0 }, [
135
- i(a(h), {
137
+ i(o(A), null, {
138
+ default: a(() => [
139
+ t.buttonType === "OkCancel" ? (r(), y(O, { key: 0 }, [
140
+ i(o(h), {
136
141
  variant: "outline",
137
- onClick: S
142
+ onClick: B
138
143
  }, {
139
- default: o(() => [
140
- u(r(t.cancelText), 1)
144
+ default: a(() => [
145
+ s(n(t.cancelText), 1)
141
146
  ]),
142
147
  _: 1
143
148
  }),
144
- i(a(h), {
149
+ i(o(h), {
145
150
  variant: t.confirmVariant,
146
151
  disabled: t.confirmDisabled,
147
152
  onClick: x
148
153
  }, {
149
- default: o(() => [
150
- u(r(t.confirmText), 1)
154
+ default: a(() => [
155
+ s(n(t.confirmText), 1)
151
156
  ]),
152
157
  _: 1
153
158
  }, 8, ["variant", "disabled"])
154
- ], 64)) : t.buttonType === "Ok" ? (n(), p(a(h), {
159
+ ], 64)) : t.buttonType === "Ok" ? (r(), p(o(h), {
155
160
  key: 1,
156
161
  variant: t.confirmVariant,
157
162
  disabled: t.confirmDisabled,
158
163
  onClick: x,
159
164
  class: "w-full"
160
165
  }, {
161
- default: o(() => [
162
- u(r(t.confirmText), 1)
166
+ default: a(() => [
167
+ s(n(t.confirmText), 1)
163
168
  ]),
164
169
  _: 1
165
170
  }, 8, ["variant", "disabled"])) : v("", !0),
@@ -176,6 +181,6 @@ const A = { class: "space-y-4" }, G = {
176
181
  }
177
182
  });
178
183
  export {
179
- De as default
184
+ Me as default
180
185
  };
181
186
  //# sourceMappingURL=JFormModal.vue.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"JFormModal.vue.js","sources":["../../../../src/components/organisms/JFormModal.vue"],"sourcesContent":["<template>\r\n <Dialog\r\n :open=\"open\"\r\n @update:open=\"onOpenChange\"\r\n :class=\"sizeClass\"\r\n >\r\n <DialogContent>\r\n <!-- Header -->\r\n <DialogHeader v-if=\"title\" class=\"bg-muted/50 border-b\">\r\n <DialogTitle>\r\n {{ title }}\r\n </DialogTitle>\r\n </DialogHeader>\r\n\r\n <!-- Body -->\r\n <DialogBody class=\"max-h-[70vh] overflow-y-auto\">\r\n <div class=\"space-y-4\">\r\n <!-- Description -->\r\n <p v-if=\"description\" class=\"text-sm text-muted-foreground\">\r\n {{ description }}\r\n </p>\r\n\r\n <!-- JDynamicForm -->\r\n <JDynamicForm\r\n ref=\"dynamicFormRef\"\r\n :schema=\"schema\"\r\n :model-value=\"internalFormValue\"\r\n @update:model-value=\"handleFormChange\"\r\n @submit=\"handleFormSubmit\"\r\n @change=\"handleFieldChange\"\r\n @error=\"handleFormError\"\r\n />\r\n\r\n <!-- 커스텀 컨텐츠 슬롯 -->\r\n <slot name=\"body\" />\r\n </div>\r\n </DialogBody>\r\n\r\n <!-- Footer -->\r\n <DialogFooter>\r\n <!-- 확인/취소 버튼 -->\r\n <template v-if=\"buttonType === 'OkCancel'\">\r\n <JButton\r\n variant=\"outline\"\r\n @click=\"handleCancel\"\r\n >\r\n {{ cancelText }}\r\n </JButton>\r\n <JButton\r\n :variant=\"confirmVariant\"\r\n :disabled=\"confirmDisabled\"\r\n @click=\"handleConfirm\"\r\n >\r\n {{ confirmText }}\r\n </JButton>\r\n </template>\r\n \r\n <!-- 확인 버튼만 -->\r\n <template v-else-if=\"buttonType === 'Ok'\">\r\n <JButton\r\n :variant=\"confirmVariant\"\r\n :disabled=\"confirmDisabled\"\r\n @click=\"handleConfirm\"\r\n class=\"w-full\"\r\n >\r\n {{ confirmText }}\r\n </JButton>\r\n </template>\r\n\r\n <!-- 커스텀 푸터 슬롯 -->\r\n <slot name=\"footer\" />\r\n </DialogFooter>\r\n </DialogContent>\r\n </Dialog>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { computed, ref, watch } from 'vue'\r\nimport {\r\n Dialog,\r\n DialogBody,\r\n DialogContent,\r\n DialogFooter,\r\n DialogHeader,\r\n DialogTitle,\r\n} from '@/components/shadcn'\r\nimport { JButton } from '@/components/atoms'\r\nimport { JDynamicForm } from '@/components/organisms'\r\nimport type { FormSchema } from '@/types/dynamic-form'\r\n\r\nexport interface JFormModalProps {\r\n // 모달 표시 여부\r\n open: boolean\r\n // 헤더\r\n title?: string\r\n description?: string\r\n // 다이나믹 폼 스키마 (필수)\r\n schema: FormSchema\r\n // 폼 값\r\n modelValue?: Record<string, any>\r\n // 모달 사이즈 (유동적)\r\n size?: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'full'\r\n // 버튼 설정\r\n buttonType?: 'Ok' | 'OkCancel'\r\n confirmText?: string\r\n cancelText?: string\r\n confirmVariant?: 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link'\r\n confirmDisabled?: boolean\r\n}\r\n\r\nconst props = withDefaults(defineProps<JFormModalProps>(), {\r\n open: false,\r\n size: 'lg',\r\n buttonType: 'OkCancel',\r\n confirmText: '확인',\r\n cancelText: '취소',\r\n confirmVariant: 'default',\r\n confirmDisabled: false,\r\n})\r\n\r\nconst emit = defineEmits<{\r\n 'update:open': [value: boolean]\r\n 'update:modelValue': [value: Record<string, any>]\r\n 'confirm': [value: Record<string, any>]\r\n 'cancel': []\r\n 'submit': [value: Record<string, any>]\r\n 'change': [data: { field: string; value: any }]\r\n 'error': [errors: any]\r\n}>()\r\n\r\n// 다이나믹 폼 ref\r\nconst dynamicFormRef = ref<InstanceType<typeof JDynamicForm> | null>(null)\r\n\r\n// 내부 폼 값 관리\r\nconst internalFormValue = ref<Record<string, any>>(props.modelValue || {})\r\n// 확인 버튼 클릭 이후 검증 성공 시점에만 confirm 이벤트를 방출하기 위한 플래그\r\nconst isConfirming = ref<boolean>(false)\r\n\r\n// 사이즈 클래스 계산\r\nconst sizeClass = computed(() => {\r\n // Dialog.vue에 기본 max-w-lg가 하드코딩되어 있어 !max-w-*로 오버라이드\r\n const sizeMap: Record<NonNullable<JFormModalProps['size']>, string> = {\r\n 'sm': '!max-w-sm',\r\n 'md': '!max-w-md',\r\n 'lg': '!max-w-2xl',\r\n 'xl': '!max-w-4xl',\r\n '2xl': '!max-w-6xl',\r\n 'full': '!max-w-[95vw]'\r\n }\r\n return sizeMap[props.size]\r\n})\r\n\r\n// props.modelValue 변경 감지\r\nwatch(() => props.modelValue, (newValue) => {\r\n if (newValue != null) {\r\n internalFormValue.value = { ...newValue }\r\n } else {\r\n internalFormValue.value = {}\r\n }\r\n}, { deep: true })\r\n\r\n// 폼 변경 핸들러\r\nconst handleFormChange = (value: Record<string, any>) => {\r\n internalFormValue.value = value\r\n emit('update:modelValue', value)\r\n}\r\n\r\n// 필드 변경 핸들러\r\nconst handleFieldChange = (data: { field: string; value: any }) => {\r\n emit('change', data)\r\n}\r\n\r\n// 폼 제출 핸들러\r\nconst handleFormSubmit = (value: Record<string, any>) => {\r\n emit('submit', value)\r\n if (isConfirming.value) {\r\n emit('confirm', value)\r\n isConfirming.value = false\r\n }\r\n}\r\n\r\n// 폼 에러 핸들러\r\nconst handleFormError = (errors: any) => {\r\n emit('error', errors)\r\n // 검증 실패 시 confirm 방출을 차단\r\n isConfirming.value = false\r\n}\r\n\r\n// 모달 열기/닫기 핸들러\r\nconst onOpenChange = (value: boolean) => {\r\n emit('update:open', value)\r\n}\r\n\r\n// 확인 버튼 핸들러\r\nconst handleConfirm = () => {\r\n // 폼 제출 트리거 (검증 성공 시점에 handleFormSubmit에서 confirm 방출)\r\n isConfirming.value = true\r\n if (dynamicFormRef.value) {\r\n dynamicFormRef.value.submit()\r\n }\r\n}\r\n\r\n// 취소 버튼 핸들러\r\nconst handleCancel = () => {\r\n emit('cancel')\r\n // 폼 리셋\r\n if (dynamicFormRef.value) {\r\n dynamicFormRef.value.reset()\r\n }\r\n}\r\n\r\n// 외부에서 접근 가능한 메서드\r\ndefineExpose({\r\n reset: () => dynamicFormRef.value?.reset(),\r\n submit: () => dynamicFormRef.value?.submit(),\r\n formState: computed(() => dynamicFormRef.value?.formState),\r\n})\r\n</script>\r\n"],"names":["props","__props","emit","__emit","dynamicFormRef","ref","internalFormValue","isConfirming","sizeClass","computed","watch","newValue","handleFormChange","value","handleFieldChange","data","handleFormSubmit","handleFormError","errors","onOpenChange","handleConfirm","handleCancel","__expose","_createBlock","_unref","Dialog","_createVNode","DialogContent","DialogHeader","DialogTitle","DialogBody","_createElementVNode","_hoisted_1","_createElementBlock","_hoisted_2","_toDisplayString","JDynamicForm","_renderSlot","_ctx","DialogFooter","_Fragment","JButton"],"mappings":"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"}
1
+ {"version":3,"file":"JFormModal.vue.js","sources":["../../../../src/components/organisms/JFormModal.vue"],"sourcesContent":["<template>\r\n <Dialog\r\n :open=\"open\"\r\n @update:open=\"onOpenChange\"\r\n :class=\"sizeClass\"\r\n >\r\n <DialogContent>\r\n <!-- Header -->\r\n <DialogHeader v-if=\"title\" class=\"bg-muted/50 border-b\">\r\n <DialogTitle>\r\n {{ title }}\r\n </DialogTitle>\r\n </DialogHeader>\r\n\r\n <!-- Body -->\r\n <DialogBody class=\"max-h-[70vh] overflow-y-auto\">\r\n <div class=\"space-y-4\">\r\n <!-- Description -->\r\n <p v-if=\"description\" class=\"text-sm text-muted-foreground\">\r\n {{ description }}\r\n </p>\r\n\r\n <!-- JDynamicForm -->\r\n <JDynamicForm\r\n ref=\"dynamicFormRef\"\r\n :schema=\"schema\"\r\n :model-value=\"internalFormValue\"\r\n @update:model-value=\"handleFormChange\"\r\n @submit=\"handleFormSubmit\"\r\n @change=\"handleFieldChange\"\r\n @error=\"handleFormError\"\r\n />\r\n\r\n <!-- 커스텀 컨텐츠 슬롯 -->\r\n <slot name=\"body\" />\r\n </div>\r\n </DialogBody>\r\n\r\n <!-- Footer -->\r\n <DialogFooter>\r\n <!-- 확인/취소 버튼 -->\r\n <template v-if=\"buttonType === 'OkCancel'\">\r\n <JButton\r\n variant=\"outline\"\r\n @click=\"handleCancel\"\r\n >\r\n {{ cancelText }}\r\n </JButton>\r\n <JButton\r\n :variant=\"confirmVariant\"\r\n :disabled=\"confirmDisabled\"\r\n @click=\"handleConfirm\"\r\n >\r\n {{ confirmText }}\r\n </JButton>\r\n </template>\r\n \r\n <!-- 확인 버튼만 -->\r\n <template v-else-if=\"buttonType === 'Ok'\">\r\n <JButton\r\n :variant=\"confirmVariant\"\r\n :disabled=\"confirmDisabled\"\r\n @click=\"handleConfirm\"\r\n class=\"w-full\"\r\n >\r\n {{ confirmText }}\r\n </JButton>\r\n </template>\r\n\r\n <!-- 커스텀 푸터 슬롯 -->\r\n <slot name=\"footer\" />\r\n </DialogFooter>\r\n </DialogContent>\r\n </Dialog>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { computed, ref, watch } from 'vue'\r\nimport {\r\n Dialog,\r\n DialogBody,\r\n DialogContent,\r\n DialogFooter,\r\n DialogHeader,\r\n DialogTitle,\r\n} from '@/components/shadcn'\r\nimport { JButton } from '@/components/atoms'\r\nimport { JDynamicForm } from '@/components/organisms'\r\nimport type { FormSchema } from '@/types/dynamic-form'\r\n\r\nexport interface JFormModalProps {\r\n // 모달 표시 여부\r\n open: boolean\r\n // 헤더\r\n title?: string\r\n description?: string\r\n // 다이나믹 폼 스키마 (필수)\r\n schema: FormSchema\r\n // 폼 값\r\n modelValue?: Record<string, any>\r\n // 모달 사이즈 (유동적)\r\n size?: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'full'\r\n // 버튼 설정\r\n buttonType?: 'Ok' | 'OkCancel'\r\n confirmText?: string\r\n cancelText?: string\r\n confirmVariant?: 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link'\r\n confirmDisabled?: boolean\r\n}\r\n\r\nconst props = withDefaults(defineProps<JFormModalProps>(), {\r\n open: false,\r\n size: 'lg',\r\n buttonType: 'OkCancel',\r\n confirmText: '확인',\r\n cancelText: '취소',\r\n confirmVariant: 'default',\r\n confirmDisabled: false,\r\n})\r\n\r\nconst emit = defineEmits<{\r\n 'update:open': [value: boolean]\r\n 'update:modelValue': [value: Record<string, any>]\r\n 'confirm': [value: Record<string, any>]\r\n 'cancel': []\r\n 'submit': [value: Record<string, any>]\r\n 'change': [data: { field: string; value: any }]\r\n 'error': [errors: any]\r\n}>()\r\n\r\n// 다이나믹 폼 ref\r\nconst dynamicFormRef = ref<InstanceType<typeof JDynamicForm> | null>(null)\r\n\r\n// 내부 폼 값 관리\r\nconst internalFormValue = ref<Record<string, any>>(props.modelValue || {})\r\n// 확인 버튼 클릭 이후 검증 성공 시점에만 confirm 이벤트를 방출하기 위한 플래그\r\nconst isConfirming = ref<boolean>(false)\r\n\r\n// 사이즈 클래스 계산\r\nconst sizeClass = computed(() => {\r\n // Dialog.vue에 기본 max-w-lg가 하드코딩되어 있어 !max-w-*로 오버라이드\r\n const sizeMap: Record<NonNullable<JFormModalProps['size']>, string> = {\r\n 'sm': '!max-w-sm',\r\n 'md': '!max-w-md',\r\n 'lg': '!max-w-2xl',\r\n 'xl': '!max-w-4xl',\r\n '2xl': '!max-w-6xl',\r\n 'full': '!max-w-[95vw]'\r\n }\r\n return sizeMap[props.size]\r\n})\r\n\r\n// props.modelValue 변경 감지\r\nwatch(() => props.modelValue, (newValue) => {\r\n if (newValue != null) {\r\n internalFormValue.value = { ...newValue }\r\n } else {\r\n internalFormValue.value = {}\r\n }\r\n}, { deep: true })\r\n\r\n// 폼 변경 핸들러\r\nconst handleFormChange = (value: Record<string, any>) => {\r\n internalFormValue.value = value\r\n emit('update:modelValue', value)\r\n}\r\n\r\n// 필드 변경 핸들러\r\nconst handleFieldChange = (data: { field: string; value: any }) => {\r\n emit('change', data)\r\n}\r\n\r\n// 폼 제출 핸들러\r\nconst handleFormSubmit = (value: Record<string, any>) => {\r\n emit('submit', value)\r\n if (isConfirming.value) {\r\n emit('confirm', value)\r\n isConfirming.value = false\r\n }\r\n}\r\n\r\n// 폼 에러 핸들러\r\nconst handleFormError = (errors: any) => {\r\n emit('error', errors)\r\n // 검증 실패 시 confirm 방출을 차단\r\n isConfirming.value = false\r\n}\r\n\r\n// 모달 열기/닫기 핸들러\r\nconst onOpenChange = (value: boolean) => {\r\n emit('update:open', value)\r\n}\r\n\r\n// 확인 버튼 핸들러\r\nconst handleConfirm = () => {\r\n // 폼 제출 트리거 (검증 성공 시점에 handleFormSubmit에서 confirm 방출)\r\n isConfirming.value = true\r\n if (dynamicFormRef.value) {\r\n dynamicFormRef.value.submit()\r\n }\r\n}\r\n\r\n// 취소 버튼 핸들러\r\nconst handleCancel = () => {\r\n emit('cancel')\r\n // 폼 리셋\r\n if (dynamicFormRef.value) {\r\n dynamicFormRef.value.reset()\r\n }\r\n}\r\n\r\n// 외부에서 접근 가능한 메서드\r\ndefineExpose({\r\n reset: () => dynamicFormRef.value?.reset(),\r\n submit: () => dynamicFormRef.value?.submit(),\r\n formState: computed(() => dynamicFormRef.value?.formState),\r\n})\r\n</script>\r\n"],"names":["props","__props","emit","__emit","dynamicFormRef","ref","internalFormValue","isConfirming","sizeClass","computed","watch","newValue","handleFormChange","value","handleFieldChange","data","handleFormSubmit","handleFormError","errors","onOpenChange","handleConfirm","handleCancel","__expose","_createBlock","_unref","Dialog","_createVNode","DialogContent","DialogHeader","DialogTitle","DialogBody","_createElementVNode","_hoisted_1","_createElementBlock","_hoisted_2","_toDisplayString","JDynamicForm","_renderSlot","_ctx","DialogFooter","_Fragment","JButton"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8GA,UAAMA,IAAQC,GAURC,IAAOC,GAWPC,IAAiBC,EAA8C,IAAI,GAGnEC,IAAoBD,EAAyBL,EAAM,cAAc,CAAA,CAAE,GAEnEO,IAAeF,EAAa,EAAK,GAGjCG,IAAYC,EAAS,OAE6C;AAAA,MACpE,IAAM;AAAA,MACN,IAAM;AAAA,MACN,IAAM;AAAA,MACN,IAAM;AAAA,MACN,OAAO;AAAA,MACP,MAAQ;AAAA,IAAA,GAEKT,EAAM,IAAI,CAC1B;AAGD,IAAAU,EAAM,MAAMV,EAAM,YAAY,CAACW,MAAa;AAC1C,MAAIA,KAAY,OACdL,EAAkB,QAAQ,EAAE,GAAGK,EAAA,IAE/BL,EAAkB,QAAQ,CAAA;AAAA,IAE9B,GAAG,EAAE,MAAM,IAAM;AAGjB,UAAMM,IAAmB,CAACC,MAA+B;AACvD,MAAAP,EAAkB,QAAQO,GAC1BX,EAAK,qBAAqBW,CAAK;AAAA,IACjC,GAGMC,IAAoB,CAACC,MAAwC;AACjE,MAAAb,EAAK,UAAUa,CAAI;AAAA,IACrB,GAGMC,IAAmB,CAACH,MAA+B;AACvD,MAAAX,EAAK,UAAUW,CAAK,GAChBN,EAAa,UACfL,EAAK,WAAWW,CAAK,GACrBN,EAAa,QAAQ;AAAA,IAEzB,GAGMU,IAAkB,CAACC,MAAgB;AACvC,MAAAhB,EAAK,SAASgB,CAAM,GAEpBX,EAAa,QAAQ;AAAA,IACvB,GAGMY,IAAe,CAACN,MAAmB;AACvC,MAAAX,EAAK,eAAeW,CAAK;AAAA,IAC3B,GAGMO,IAAgB,MAAM;AAE1B,MAAAb,EAAa,QAAQ,IACjBH,EAAe,SACjBA,EAAe,MAAM,OAAA;AAAA,IAEzB,GAGMiB,IAAe,MAAM;AACzB,MAAAnB,EAAK,QAAQ,GAETE,EAAe,SACjBA,EAAe,MAAM,MAAA;AAAA,IAEzB;AAGA,WAAAkB,EAAa;AAAA,MACX,OAAO,MAAMlB,EAAe,OAAO,MAAA;AAAA,MACnC,QAAQ,MAAMA,EAAe,OAAO,OAAA;AAAA,MACpC,WAAWK,EAAS,MAAML,EAAe,OAAO,SAAS;AAAA,IAAA,CAC1D,mBAvNCmB,EAwESC,EAAAC,CAAA,GAAA;AAAA,MAvEN,MAAMxB,EAAA;AAAA,MACN,iBAAakB;AAAA,MACb,SAAOX,EAAA,KAAS;AAAA,IAAA;iBAEjB,MAkEgB;AAAA,QAlEhBkB,EAkEgBF,EAAAG,CAAA,GAAA,MAAA;AAAA,qBAhEd,MAIe;AAAA,YAJK1B,EAAA,cAApBsB,EAIeC,EAAAI,CAAA,GAAA;AAAA;cAJY,OAAM;AAAA,YAAA;yBAC/B,MAEc;AAAA,gBAFdF,EAEcF,EAAAK,CAAA,GAAA,MAAA;AAAA,6BADZ,MAAW;AAAA,wBAAR5B,EAAA,KAAK,GAAA,CAAA;AAAA,kBAAA;;;;;;YAKZyB,EAqBaF,EAAAM,CAAA,GAAA,EArBD,OAAM,kCAA8B;AAAA,yBAC9C,MAmBM;AAAA,gBAnBNC,EAmBM,OAnBNC,GAmBM;AAAA,kBAjBK/B,EAAA,oBAATgC,EAEI,KAFJC,GAEIC,EADClC,EAAA,WAAW,GAAA,CAAA;kBAIhByB,EAQEF,EAAAY,CAAA,GAAA;AAAA,6BAPI;AAAA,oBAAJ,KAAIhC;AAAA,oBACH,QAAQH,EAAA;AAAA,oBACR,eAAaK,EAAA;AAAA,oBACb,uBAAoBM;AAAA,oBACpB,UAAQI;AAAA,oBACR,UAAQF;AAAA,oBACR,SAAOG;AAAA,kBAAA;kBAIVoB,EAAoBC,EAAA,QAAA,MAAA;AAAA,gBAAA;;;;YAKxBZ,EAgCeF,EAAAe,CAAA,GAAA,MAAA;AAAA,yBA9Bb,MAcW;AAAA,gBAdKtC,EAAA,eAAU,mBAA1BgC,EAcWO,GAAA,EAAA,KAAA,KAAA;AAAA,kBAbTd,EAKUF,EAAAiB,CAAA,GAAA;AAAA,oBAJR,SAAQ;AAAA,oBACP,SAAOpB;AAAA,kBAAA;+BAER,MAAgB;AAAA,0BAAbpB,EAAA,UAAU,GAAA,CAAA;AAAA,oBAAA;;;kBAEfyB,EAMUF,EAAAiB,CAAA,GAAA;AAAA,oBALP,SAASxC,EAAA;AAAA,oBACT,UAAUA,EAAA;AAAA,oBACV,SAAOmB;AAAA,kBAAA;+BAER,MAAiB;AAAA,0BAAdnB,EAAA,WAAW,GAAA,CAAA;AAAA,oBAAA;;;0BAKGA,EAAA,eAAU,aAC7BsB,EAOUC,EAAAiB,CAAA,GAAA;AAAA;kBANP,SAASxC,EAAA;AAAA,kBACT,UAAUA,EAAA;AAAA,kBACV,SAAOmB;AAAA,kBACR,OAAM;AAAA,gBAAA;6BAEN,MAAiB;AAAA,wBAAdnB,EAAA,WAAW,GAAA,CAAA;AAAA,kBAAA;;;gBAKlBoC,EAAsBC,EAAA,QAAA,QAAA;AAAA,cAAA;;;;;;;;;;;"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue"),u=require("../atoms/JIcon.vue.cjs"),K=require("../atoms/JAvatar.vue.cjs"),g=require("../atoms/JButton.vue.cjs"),N=require("../atoms/JPopover.vue.cjs"),v=require("../../lib/utils.cjs"),r=require("../../lib/theme-utils.cjs"),z=require("../../assets/images/logo-fallback.png.cjs"),W={class:"flex items-center gap-6 flex-1"},H=["src"],Q={key:1,class:"text-lg font-bold text-foreground"},X={key:2,class:"flex items-center gap-1"},Z={class:"flex items-center gap-3"},ee={class:"p-2 min-w-[200px]"},te={class:"space-y-1"},oe=["onClick"],le={key:1,class:"w-4"},ne={class:"flex-1 capitalize"},ae={key:0,class:"absolute top-0 right-0 h-4 w-4 rounded-full bg-destructive text-destructive-foreground text-xs flex items-center justify-center"},se={class:"p-2"},re={key:0,class:"max-h-96 overflow-y-auto space-y-1"},ce=["onClick"],ie={class:"flex items-start gap-2"},de={class:"flex-1 min-w-0"},ue={class:"text-sm font-medium text-foreground"},me={key:0,class:"text-xs text-muted-foreground mt-1"},fe={key:1,class:"text-xs text-muted-foreground/60 mt-1"},he={key:1,class:"p-4 text-center text-sm text-muted-foreground"},ke={class:"flex items-center gap-2 cursor-pointer hover:opacity-80 transition-opacity"},ge={class:"text-sm text-foreground hidden sm:inline"},ve={class:"w-full rounded-md overflow-hidden"},pe={class:"px-3 py-2 border-b border-border"},xe={class:"text-sm font-medium text-foreground"},ye={key:0,class:"text-xs text-muted-foreground mt-0.5"},be=["disabled","onClick"],Be={class:"flex-1 text-left truncate"},_e={key:1,class:"h-px bg-muted my-1"},Ce={key:0,class:"h-px bg-muted my-1"},Te=e.defineComponent({__name:"JHeader",props:{logo:{},logoText:{default:"JWMS Portal"},navItems:{},showNotifications:{type:Boolean,default:!1},notifications:{default:()=>[]},userAvatar:{},userName:{},isLoggedIn:{type:Boolean},userEmail:{},userId:{},styletype:{default:"default"},showSidebarToggle:{type:Boolean,default:!0},isSidebarOpen:{type:Boolean,default:!0},showThemeSelector:{type:Boolean,default:!0},defaultTheme:{default:void 0},availableThemes:{default:void 0}},emits:["logoClick","navClick","notificationClick","userMenuSelect","sidebarToggle","login"],setup(l,{emit:L}){const d=l,f=L,S={default:{containerClass:"h-14 px-4 border-b border-border bg-background",navItemClass:"text-sm text-muted-foreground hover:text-foreground transition-colors px-3 py-2 rounded-md hover:bg-accent",navItemActiveClass:"text-foreground font-medium bg-accent"},minimal:{containerClass:"h-12 px-3 border-b border-border bg-background",navItemClass:"text-xs text-muted-foreground hover:text-foreground transition-colors px-2 py-1 rounded-md hover:bg-accent",navItemActiveClass:"text-foreground font-medium bg-accent"}},B=e.computed(()=>S[d.styletype]??S.default),h=e.ref(0),D=e.computed(()=>{if(d.logo)return d.logo}),_=e.computed(()=>{if(d.logo)return h.value>=1&&z.default?z.default:D.value}),O=()=>{h.value===0?h.value=1:h.value===1&&(h.value=2)},C=e.computed(()=>d.notifications?.filter(o=>!o.read).length||0),M=[{id:"profile",label:"프로필",icon:"user"},{id:"settings",label:"설정",icon:"settings"},{id:"separator",label:"",separator:!0},{id:"logout",label:"로그아웃",icon:"logOut"}],V=e.computed(()=>[{items:M}]),A=()=>{f("logoClick")},F=(o,a)=>{o.onClick?.(),f("navClick",o,a)},q=o=>{o.onClick?.(),f("notificationClick",o)},G=o=>{f("userMenuSelect",o)},J=()=>{f("login")},U=()=>{f("sidebarToggle")},m=e.ref(!1),k=e.ref(r.getDefaultTheme()),p=e.ref([]);let x=!1,y=null,b=null;const I=()=>typeof window>"u"?!1:!!(window.location?.href?.includes("storybook")||window.__STORYBOOK_GLOBALS__),T=()=>{const o=r.detectThemeClasses(),a=r.ensureDefaultTheme(o);if(d.availableThemes&&d.availableThemes.length>0){const t=a.filter(n=>d.availableThemes.includes(n));p.value=r.ensureDefaultTheme(t)}else p.value=a},$=()=>{if(typeof window>"u")return"light";const o=localStorage.getItem("theme");return o==="dark"||o==="light"?o:window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"},E=o=>{x=!0;const a=document.documentElement;o==="dark"?(a.classList.add("dark"),m.value=!0):(a.classList.remove("dark"),m.value=!1),localStorage.setItem("theme",o),x=!1},P=()=>{const o=m.value?"light":"dark";E(o)},R=()=>{if(d.defaultTheme)return r.validateThemeExists(d.defaultTheme);const o=r.getStoredTheme("tweakcn-theme");return o?r.validateThemeExists(o):r.getDefaultTheme()},w=o=>{x=!0;const a=r.validateThemeExists(o),t=r.applyTheme(a);if(t){if(k.value=a,r.setStoredTheme(a,"tweakcn-theme"),I())try{const n=window.__STORYBOOK_GLOBALS__;n&&(n.theme=a)}catch{}}else{const n=r.getDefaultTheme();r.applyTheme(n),k.value=n,r.setStoredTheme(n,"tweakcn-theme")}return x=!1,t},Y=o=>{w(String(o))},j=e.computed(()=>m.value?"sun":"moon");return e.onMounted(()=>{T();const o=$();E(o);const a=R();w(a);const t=document.documentElement;m.value=t.classList.contains("dark"),y=new MutationObserver(()=>{if(x)return;const s=t.classList.contains("dark");s!==m.value&&(m.value=s,localStorage.setItem("theme",s?"dark":"light")),T();const c=Array.from(t.classList).find(i=>i.startsWith("theme-"));if(c){const i=c.replace("theme-","");p.value.includes(i)&&(k.value=i)}}),y.observe(document.documentElement,{attributes:!0,attributeFilter:["class"]}),b=new MutationObserver(()=>{T()}),b.observe(document.head,{childList:!0,subtree:!0});let n=null;if(I()){const s=()=>{try{const c=window.__STORYBOOK_GLOBALS__;if(c){if(typeof c.darkMode<"u"){const i=c.darkMode;i!==m.value&&E(i?"dark":"light")}if(c.theme&&c.theme!==k.value){const i=String(c.theme);p.value.includes(i)&&w(i)}}}catch{}};s(),n=setInterval(s,500)}e.onUnmounted(()=>{y&&(y.disconnect(),y=null),b&&(b.disconnect(),b=null),n&&clearInterval(n)})}),(o,a)=>(e.openBlock(),e.createElementBlock("header",{class:e.normalizeClass(e.unref(v.cn)("flex items-center justify-between w-full",B.value.containerClass))},[e.createElementVNode("div",W,[l.showSidebarToggle?(e.openBlock(),e.createBlock(g.default,{key:0,variant:"ghost",size:"icon",class:"flex-shrink-0","aria-label":"사이드바 토글",onClick:U},{default:e.withCtx(()=>[e.createVNode(u.default,{name:"menu",size:"md"})]),_:1})):e.createCommentVNode("",!0),_.value||l.logoText?(e.openBlock(),e.createElementBlock("div",{key:1,class:"flex items-center cursor-pointer",onClick:A},[_.value&&h.value<2?(e.openBlock(),e.createElementBlock("img",{key:0,src:_.value,alt:"로고",class:"h-8 w-auto",onError:O},null,40,H)):l.logoText?(e.openBlock(),e.createElementBlock("span",Q,e.toDisplayString(l.logoText),1)):e.createCommentVNode("",!0)])):e.createCommentVNode("",!0),l.navItems&&l.navItems.length>0?(e.openBlock(),e.createElementBlock("nav",X,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(l.navItems,(t,n)=>(e.openBlock(),e.createBlock(g.default,{key:n,variant:"ghost",class:e.normalizeClass(e.unref(v.cn)(B.value.navItemClass,t.active&&B.value.navItemActiveClass)),onClick:s=>F(t,n)},{default:e.withCtx(()=>[t.icon?(e.openBlock(),e.createBlock(u.default,{key:0,name:t.icon,size:"sm",class:"mr-1.5"},null,8,["name"])):e.createCommentVNode("",!0),e.createTextVNode(" "+e.toDisplayString(t.label),1)]),_:2},1032,["class","onClick"]))),128))])):e.createCommentVNode("",!0)]),e.createElementVNode("div",Z,[l.showThemeSelector?(e.openBlock(),e.createBlock(N.default,{key:0,position:"bottom",align:"end",styletype:"default-sm"},{trigger:e.withCtx(()=>[e.createVNode(g.default,{variant:"ghost",size:"icon","aria-label":"테마 선택"},{default:e.withCtx(()=>[e.createVNode(u.default,{name:"palette",size:"md"})]),_:1})]),default:e.withCtx(()=>[e.createElementVNode("div",ee,[a[0]||(a[0]=e.createElementVNode("div",{class:"text-xs font-medium text-muted-foreground px-2 py-1.5 mb-1"}," 테마 선택 ",-1)),e.createElementVNode("div",te,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(p.value,t=>(e.openBlock(),e.createElementBlock("button",{key:t,class:e.normalizeClass(e.unref(v.cn)("w-full flex items-center gap-2 px-2 py-1.5 text-sm rounded-md transition-colors","hover:bg-accent hover:text-accent-foreground","border-0 outline-none text-left",k.value===t&&"bg-accent text-accent-foreground font-medium")),onClick:n=>Y(t)},[k.value===t?(e.openBlock(),e.createBlock(u.default,{key:0,name:"check",size:"sm",class:"flex-shrink-0"})):(e.openBlock(),e.createElementBlock("span",le)),e.createElementVNode("span",ne,e.toDisplayString(t),1)],10,oe))),128))])])]),_:1})):e.createCommentVNode("",!0),l.showNotifications?(e.openBlock(),e.createBlock(N.default,{key:1,position:"bottom",align:"end",styletype:"default-sm"},{trigger:e.withCtx(()=>[e.createVNode(g.default,{variant:"ghost",size:"icon",class:"relative","aria-label":"알림"},{default:e.withCtx(()=>[e.createVNode(u.default,{name:"circleAlert",size:"md"}),C.value>0?(e.openBlock(),e.createElementBlock("span",ae,e.toDisplayString(C.value>9?"9+":C.value),1)):e.createCommentVNode("",!0)]),_:1})]),default:e.withCtx(()=>[e.createElementVNode("div",se,[l.notifications&&l.notifications.length>0?(e.openBlock(),e.createElementBlock("div",re,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(l.notifications,t=>(e.openBlock(),e.createElementBlock("div",{key:t.id,class:e.normalizeClass(e.unref(v.cn)("p-3 rounded-md cursor-pointer transition-colors",t.read?"hover:bg-accent/50":"bg-accent")),onClick:n=>q(t)},[e.createElementVNode("div",ie,[t.icon?(e.openBlock(),e.createBlock(u.default,{key:0,name:t.icon,size:"sm",class:"mt-0.5 flex-shrink-0"},null,8,["name"])):e.createCommentVNode("",!0),e.createElementVNode("div",de,[e.createElementVNode("p",ue,e.toDisplayString(t.title),1),t.message?(e.openBlock(),e.createElementBlock("p",me,e.toDisplayString(t.message),1)):e.createCommentVNode("",!0),t.time?(e.openBlock(),e.createElementBlock("p",fe,e.toDisplayString(t.time),1)):e.createCommentVNode("",!0)])])],10,ce))),128))])):(e.openBlock(),e.createElementBlock("div",he," 알림이 없습니다. "))])]),_:1})):e.createCommentVNode("",!0),e.createVNode(g.default,{variant:"ghost",size:"icon","aria-label":m.value?"라이트 모드로 전환":"다크 모드로 전환",onClick:P},{default:e.withCtx(()=>[e.createVNode(u.default,{name:j.value,size:"md"},null,8,["name"])]),_:1},8,["aria-label"]),l.userName?(e.openBlock(),e.createBlock(N.default,{key:2,position:"bottom",align:"end",styletype:"default-sm"},{trigger:e.withCtx(()=>[e.createElementVNode("div",ke,[e.createVNode(K.default,{src:l.userAvatar,fallback:l.userName?l.userName[0]:"U",size:"sm"},null,8,["src","fallback"]),e.createElementVNode("span",ge,e.toDisplayString(l.userName),1),e.createVNode(u.default,{name:"chevronDown",size:"sm",class:"text-muted-foreground hidden sm:inline"})])]),default:e.withCtx(()=>[e.createElementVNode("div",ve,[e.createElementVNode("div",pe,[e.createElementVNode("p",xe,e.toDisplayString(l.userName),1),l.userEmail?(e.openBlock(),e.createElementBlock("p",ye,e.toDisplayString(l.userEmail),1)):e.createCommentVNode("",!0)]),(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(V.value,(t,n)=>(e.openBlock(),e.createElementBlock(e.Fragment,{key:n},[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(t.items,(s,c)=>(e.openBlock(),e.createElementBlock(e.Fragment,{key:s.id},[s.separator?s.separator&&c>0?(e.openBlock(),e.createElementBlock("div",_e)):e.createCommentVNode("",!0):(e.openBlock(),e.createElementBlock("button",{key:0,disabled:s.disabled,class:e.normalizeClass(e.unref(v.cn)("w-full flex items-center gap-2 px-3 py-1.5 text-sm transition-colors",s.id==="logout"?"text-destructive hover:bg-destructive/10 hover:text-destructive":"hover:bg-accent hover:text-accent-foreground","disabled:opacity-50 disabled:pointer-events-none","border-0 outline-none",t.items[c+1]?.separator&&"border-b-0")),onClick:i=>G(s.id)},[s.icon?(e.openBlock(),e.createBlock(u.default,{key:0,name:s.icon,size:"sm",class:e.normalizeClass(e.unref(v.cn)("flex-shrink-0",s.id==="logout"&&"text-destructive"))},null,8,["name","class"])):e.createCommentVNode("",!0),e.createElementVNode("span",Be,e.toDisplayString(s.label),1)],10,be))],64))),128)),n<V.value.length-1?(e.openBlock(),e.createElementBlock("div",Ce)):e.createCommentVNode("",!0)],64))),128))])]),_:1})):(e.openBlock(),e.createBlock(g.default,{key:3,variant:"ghost",size:"sm","aria-label":"로그인",onClick:J},{default:e.withCtx(()=>[e.createVNode(u.default,{name:"logIn",size:"sm",class:"sm:mr-1.5"}),a[1]||(a[1]=e.createElementVNode("span",{class:"hidden sm:inline"},"로그인",-1))]),_:1})),e.renderSlot(o.$slots,"actions")])],2))}});exports.default=Te;
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue"),m=require("../atoms/JIcon.vue.cjs"),W=require("../atoms/JAvatar.vue.cjs"),v=require("../atoms/JButton.vue.cjs"),w=require("../atoms/JPopover.vue.cjs"),g=require("../../lib/utils.cjs"),r=require("../../lib/theme-utils.cjs"),L=require("../../assets/images/logo-fallback.png.cjs"),H={class:"flex items-center gap-6 flex-1"},Q=["src"],X={key:1,class:"text-sm font-bold text-foreground"},Z={key:2,class:"flex items-center gap-1"},ee={class:"flex items-center gap-3"},te={class:"p-2 min-w-[200px]"},oe={class:"space-y-1"},le=["onClick"],ae={key:1,class:"w-4"},ne={class:"flex-1 capitalize"},se={key:0,class:"absolute top-0 right-0 h-4 w-4 rounded-full bg-destructive text-destructive-foreground text-xs flex items-center justify-center"},re={class:"p-2"},ce={key:0,class:"max-h-96 overflow-y-auto space-y-1"},ie=["onClick"],de={class:"flex items-start gap-2"},ue={class:"flex-1 min-w-0"},me={class:"text-xs font-medium text-foreground"},fe={key:0,class:"text-xs text-muted-foreground mt-1"},he={key:1,class:"text-xs text-muted-foreground/60 mt-1"},ke={key:1,class:"p-4 text-center text-xs text-muted-foreground"},ve={class:"flex items-center gap-2 cursor-pointer hover:opacity-80 transition-opacity"},ge={class:"text-xs text-foreground hidden sm:inline"},pe={class:"w-full rounded-md overflow-hidden"},xe={class:"px-3 py-1.5 border-b border-border"},be={class:"text-xs font-medium text-foreground"},ye={key:0,class:"text-xs text-muted-foreground mt-0.5"},Be=["disabled","onClick"],Ce={class:"flex-1 text-left truncate"},_e={key:1,class:"h-px bg-muted my-1"},Te={key:0,class:"h-px bg-muted my-1"},Ee=e.defineComponent({__name:"JHeader",props:{logo:{},logoText:{default:"JWMS Portal"},navItems:{},showNotifications:{type:Boolean,default:!1},notifications:{default:()=>[]},userAvatar:{},userName:{},isLoggedIn:{type:Boolean},userEmail:{},userId:{},styletype:{default:"default"},showSidebarToggle:{type:Boolean,default:!0},isSidebarOpen:{type:Boolean,default:!0},showThemeSelector:{type:Boolean,default:!0},defaultTheme:{default:void 0},availableThemes:{default:void 0}},emits:["logoClick","navClick","notificationClick","userMenuSelect","sidebarToggle","login"],setup(l,{emit:D}){const u=l,h=D,N={default:{containerClass:"h-10 px-4 border-b border-border bg-muted dark:bg-card",navItemClass:"text-xs text-muted-foreground hover:text-foreground transition-colors px-3 py-1.5 rounded-md hover:bg-accent",navItemActiveClass:"text-foreground font-medium bg-accent"},minimal:{containerClass:"h-8 px-3 border-b border-border bg-muted dark:bg-card",navItemClass:"text-xs text-muted-foreground hover:text-foreground transition-colors px-2 py-1 rounded-md hover:bg-accent",navItemActiveClass:"text-foreground font-medium bg-accent"}},C=e.computed(()=>N[u.styletype]??N.default),k=e.ref(0),M=e.computed(()=>{if(u.logo)return u.logo}),_=e.computed(()=>{if(u.logo)return k.value>=1&&L.default?L.default:M.value}),O=()=>{k.value===0?k.value=1:k.value===1&&(k.value=2)},T=e.computed(()=>u.notifications?.filter(o=>!o.read).length||0),A=[{id:"profile",label:"프로필",icon:"user"},{id:"settings",label:"설정",icon:"settings"},{id:"separator",label:"",separator:!0},{id:"logout",label:"로그아웃",icon:"logOut"}],S=e.computed(()=>[{items:A}]),F=()=>{h("logoClick")},q=(o,a)=>{o.onClick?.(),h("navClick",o,a)},J=o=>{o.onClick?.(),h("notificationClick",o)},U=o=>{h("userMenuSelect",o)},G=()=>{h("login")},$=()=>{h("sidebarToggle")},i=e.ref(!1),f=e.ref(r.getDefaultTheme()),p=e.ref([]);let x=!1,b=null,y=null;const V=()=>typeof window>"u"?!1:!!(window.location?.href?.includes("storybook")||window.__STORYBOOK_GLOBALS__),E=()=>{const o=r.detectThemeClasses(),a=r.ensureDefaultTheme(o);if(u.availableThemes&&u.availableThemes.length>0){const t=a.filter(s=>u.availableThemes.includes(s));p.value=r.ensureDefaultTheme(t)}else p.value=a},P=()=>{if(typeof window>"u")return"light";const o=localStorage.getItem("theme");return o==="dark"||o==="light"?o:window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"},I=o=>{x=!0;const a=document.documentElement;o==="dark"?(a.classList.add("dark"),i.value=!0):(a.classList.remove("dark"),i.value=!1),localStorage.setItem("theme",o),x=!1},j=()=>{const o=i.value?"light":"dark";I(o)},R=()=>{if(u.defaultTheme)return r.validateThemeExists(u.defaultTheme);const o=r.getStoredTheme("tweakcn-theme");return o?r.validateThemeExists(o):r.getDefaultTheme()},z=o=>{x=!0;const a=r.validateThemeExists(o),t=r.applyTheme(a);if(t)f.value=a,V()||r.setStoredTheme(a,"tweakcn-theme");else{const s=r.getDefaultTheme();r.applyTheme(s),f.value=s,r.setStoredTheme(s,"tweakcn-theme")}return x=!1,t},Y=o=>{z(String(o))},K=e.computed(()=>i.value?"sun":"moon");return e.onMounted(()=>{E();const o=P();I(o);const a=R();z(a);const t=document.documentElement;i.value=t.classList.contains("dark"),b=new MutationObserver(()=>{if(x)return;const n=t.classList.contains("dark");n!==i.value&&(i.value=n,localStorage.setItem("theme",n?"dark":"light")),E();const c=Array.from(t.classList).find(d=>d.startsWith("theme-"));if(c){const d=c.replace("theme-","");p.value.includes(d)&&(f.value=d)}}),b.observe(document.documentElement,{attributes:!0,attributeFilter:["class"]}),y=new MutationObserver(()=>{E()}),y.observe(document.head,{childList:!0,subtree:!0});let s=null;if(V()){const n=()=>{try{const c=window.__STORYBOOK_GLOBALS__;if(c){if(typeof c.darkMode<"u"){const d=c.darkMode;if(d!==i.value){const B=document.documentElement;d?(B.classList.add("dark"),i.value=!0):(B.classList.remove("dark"),i.value=!1)}}if(c.theme&&c.theme!==f.value){const d=String(c.theme);if(p.value.includes(d)){const B=r.validateThemeExists(d);r.applyTheme(B),f.value=B}}}}catch{}};n(),s=setInterval(n,200)}e.onUnmounted(()=>{b&&(b.disconnect(),b=null),y&&(y.disconnect(),y=null),s&&clearInterval(s)})}),(o,a)=>(e.openBlock(),e.createElementBlock("header",{class:e.normalizeClass(e.unref(g.cn)("flex items-center justify-between w-full",C.value.containerClass))},[e.createElementVNode("div",H,[l.showSidebarToggle?(e.openBlock(),e.createBlock(v.default,{key:0,variant:"ghost",size:"sm",class:"flex-shrink-0 w-8 h-8 p-0","aria-label":"사이드바 토글",onClick:$},{default:e.withCtx(()=>[e.createVNode(m.default,{name:"menu",size:"sm"})]),_:1})):e.createCommentVNode("",!0),_.value||l.logoText?(e.openBlock(),e.createElementBlock("div",{key:1,class:"flex items-center cursor-pointer",onClick:F},[_.value&&k.value<2?(e.openBlock(),e.createElementBlock("img",{key:0,src:_.value,alt:"로고",class:"h-6 w-auto",onError:O},null,40,Q)):l.logoText?(e.openBlock(),e.createElementBlock("span",X,e.toDisplayString(l.logoText),1)):e.createCommentVNode("",!0)])):e.createCommentVNode("",!0),l.navItems&&l.navItems.length>0?(e.openBlock(),e.createElementBlock("nav",Z,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(l.navItems,(t,s)=>(e.openBlock(),e.createBlock(v.default,{key:s,variant:"ghost",class:e.normalizeClass(e.unref(g.cn)(C.value.navItemClass,t.active&&C.value.navItemActiveClass)),onClick:n=>q(t,s)},{default:e.withCtx(()=>[t.icon?(e.openBlock(),e.createBlock(m.default,{key:0,name:t.icon,size:"sm",class:"mr-1.5"},null,8,["name"])):e.createCommentVNode("",!0),e.createTextVNode(" "+e.toDisplayString(t.label),1)]),_:2},1032,["class","onClick"]))),128))])):e.createCommentVNode("",!0)]),e.createElementVNode("div",ee,[l.showThemeSelector?(e.openBlock(),e.createBlock(w.default,{key:0,position:"bottom",align:"end",styletype:"default-sm"},{trigger:e.withCtx(()=>[e.createVNode(v.default,{variant:"ghost",size:"sm",class:"w-8 h-8 p-0","aria-label":"테마 선택"},{default:e.withCtx(()=>[e.createVNode(m.default,{name:"palette",size:"sm"})]),_:1})]),default:e.withCtx(()=>[e.createElementVNode("div",te,[a[0]||(a[0]=e.createElementVNode("div",{class:"text-xs font-medium text-muted-foreground px-2 py-1.5 mb-1"}," 테마 선택 ",-1)),e.createElementVNode("div",oe,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(p.value,t=>(e.openBlock(),e.createElementBlock("button",{key:t,class:e.normalizeClass(e.unref(g.cn)("w-full flex items-center gap-2 px-2 py-1.5 text-xs rounded-md transition-colors","hover:bg-accent hover:text-accent-foreground","border-0 outline-none text-left",f.value===t&&"bg-accent text-accent-foreground font-medium")),onClick:s=>Y(t)},[f.value===t?(e.openBlock(),e.createBlock(m.default,{key:0,name:"check",size:"sm",class:"flex-shrink-0"})):(e.openBlock(),e.createElementBlock("span",ae)),e.createElementVNode("span",ne,e.toDisplayString(t),1)],10,le))),128))])])]),_:1})):e.createCommentVNode("",!0),l.showNotifications?(e.openBlock(),e.createBlock(w.default,{key:1,position:"bottom",align:"end",styletype:"default-sm"},{trigger:e.withCtx(()=>[e.createVNode(v.default,{variant:"ghost",size:"sm",class:"relative w-8 h-8 p-0","aria-label":"알림"},{default:e.withCtx(()=>[e.createVNode(m.default,{name:"circleAlert",size:"sm"}),T.value>0?(e.openBlock(),e.createElementBlock("span",se,e.toDisplayString(T.value>9?"9+":T.value),1)):e.createCommentVNode("",!0)]),_:1})]),default:e.withCtx(()=>[e.createElementVNode("div",re,[l.notifications&&l.notifications.length>0?(e.openBlock(),e.createElementBlock("div",ce,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(l.notifications,t=>(e.openBlock(),e.createElementBlock("div",{key:t.id,class:e.normalizeClass(e.unref(g.cn)("p-3 rounded-md cursor-pointer transition-colors",t.read?"hover:bg-accent/50":"bg-accent")),onClick:s=>J(t)},[e.createElementVNode("div",de,[t.icon?(e.openBlock(),e.createBlock(m.default,{key:0,name:t.icon,size:"sm",class:"mt-0.5 flex-shrink-0"},null,8,["name"])):e.createCommentVNode("",!0),e.createElementVNode("div",ue,[e.createElementVNode("p",me,e.toDisplayString(t.title),1),t.message?(e.openBlock(),e.createElementBlock("p",fe,e.toDisplayString(t.message),1)):e.createCommentVNode("",!0),t.time?(e.openBlock(),e.createElementBlock("p",he,e.toDisplayString(t.time),1)):e.createCommentVNode("",!0)])])],10,ie))),128))])):(e.openBlock(),e.createElementBlock("div",ke," 알림이 없습니다. "))])]),_:1})):e.createCommentVNode("",!0),e.createVNode(v.default,{variant:"ghost",size:"sm",class:"w-8 h-8 p-0","aria-label":i.value?"라이트 모드로 전환":"다크 모드로 전환",onClick:j},{default:e.withCtx(()=>[e.createVNode(m.default,{name:K.value,size:"sm"},null,8,["name"])]),_:1},8,["aria-label"]),e.renderSlot(o.$slots,"toolbar"),l.userName?(e.openBlock(),e.createBlock(w.default,{key:2,position:"bottom",align:"end",styletype:"default-sm"},{trigger:e.withCtx(()=>[e.createElementVNode("div",ve,[e.createVNode(W.default,{src:l.userAvatar,fallback:l.userName?l.userName[0]:"U",size:"xs"},null,8,["src","fallback"]),e.createElementVNode("span",ge,e.toDisplayString(l.userName),1),e.createVNode(m.default,{name:"chevronDown",size:"sm",class:"text-muted-foreground hidden sm:inline"})])]),default:e.withCtx(()=>[e.createElementVNode("div",pe,[e.createElementVNode("div",xe,[e.createElementVNode("p",be,e.toDisplayString(l.userName),1),l.userEmail?(e.openBlock(),e.createElementBlock("p",ye,e.toDisplayString(l.userEmail),1)):e.createCommentVNode("",!0)]),(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(S.value,(t,s)=>(e.openBlock(),e.createElementBlock(e.Fragment,{key:s},[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(t.items,(n,c)=>(e.openBlock(),e.createElementBlock(e.Fragment,{key:n.id},[n.separator?n.separator&&c>0?(e.openBlock(),e.createElementBlock("div",_e)):e.createCommentVNode("",!0):(e.openBlock(),e.createElementBlock("button",{key:0,disabled:n.disabled,class:e.normalizeClass(e.unref(g.cn)("w-full flex items-center gap-2 px-3 py-1.5 text-xs transition-colors",n.id==="logout"?"text-destructive hover:bg-destructive/10 hover:text-destructive":"hover:bg-accent hover:text-accent-foreground","disabled:opacity-50 disabled:pointer-events-none","border-0 outline-none",t.items[c+1]?.separator&&"border-b-0")),onClick:d=>U(n.id)},[n.icon?(e.openBlock(),e.createBlock(m.default,{key:0,name:n.icon,size:"sm",class:e.normalizeClass(e.unref(g.cn)("flex-shrink-0",n.id==="logout"&&"text-destructive"))},null,8,["name","class"])):e.createCommentVNode("",!0),e.createElementVNode("span",Ce,e.toDisplayString(n.label),1)],10,Be))],64))),128)),s<S.value.length-1?(e.openBlock(),e.createElementBlock("div",Te)):e.createCommentVNode("",!0)],64))),128))])]),_:1})):(e.openBlock(),e.createBlock(v.default,{key:3,variant:"ghost",size:"sm","aria-label":"로그인",onClick:G},{default:e.withCtx(()=>[e.createVNode(m.default,{name:"logIn",size:"sm",class:"sm:mr-1.5"}),a[1]||(a[1]=e.createElementVNode("span",{class:"hidden sm:inline"},"로그인",-1))]),_:1}))])],2))}});exports.default=Ee;
2
2
  //# sourceMappingURL=JHeader.vue.cjs.map