@hua-labs/ui 1.0.0 → 1.1.0-alpha.0.2

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 (348) hide show
  1. package/README.md +897 -210
  2. package/dist/ComponentLayout-BxCenSAm.d.mts +73 -0
  3. package/dist/advanced/dashboard.d.ts +7 -0
  4. package/dist/advanced/dashboard.d.ts.map +1 -0
  5. package/dist/advanced/motion.d.ts +2 -0
  6. package/dist/advanced/motion.d.ts.map +1 -0
  7. package/dist/advanced-dashboard.d.mts +4 -0
  8. package/dist/advanced-dashboard.js +2 -0
  9. package/dist/advanced-dashboard.js.map +1 -0
  10. package/dist/advanced-dashboard.mjs +2 -0
  11. package/dist/advanced-dashboard.mjs.map +1 -0
  12. package/dist/advanced-motion.d.mts +93 -0
  13. package/dist/advanced-motion.js +2 -0
  14. package/dist/advanced-motion.js.map +1 -0
  15. package/dist/advanced-motion.mjs +2 -0
  16. package/dist/advanced-motion.mjs.map +1 -0
  17. package/dist/advanced.d.mts +734 -0
  18. package/dist/advanced.d.ts +17 -0
  19. package/dist/advanced.d.ts.map +1 -0
  20. package/dist/advanced.js +2 -0
  21. package/dist/advanced.js.map +1 -0
  22. package/dist/advanced.mjs +2 -0
  23. package/dist/advanced.mjs.map +1 -0
  24. package/dist/chunk-627HOIRV.mjs +2 -0
  25. package/dist/chunk-627HOIRV.mjs.map +1 -0
  26. package/dist/chunk-ACEKLG37.mjs +2 -0
  27. package/dist/chunk-ACEKLG37.mjs.map +1 -0
  28. package/dist/chunk-E5PN4LUS.mjs +2 -0
  29. package/dist/chunk-E5PN4LUS.mjs.map +1 -0
  30. package/dist/chunk-KHEJZ3U4.mjs +2 -0
  31. package/dist/chunk-KHEJZ3U4.mjs.map +1 -0
  32. package/dist/chunk-MXGXBG63.mjs +2 -0
  33. package/dist/chunk-MXGXBG63.mjs.map +1 -0
  34. package/dist/chunk-R5KCFRYV.mjs +2 -0
  35. package/dist/chunk-R5KCFRYV.mjs.map +1 -0
  36. package/dist/chunk-UGSYQDR4.mjs +2 -0
  37. package/dist/chunk-UGSYQDR4.mjs.map +1 -0
  38. package/dist/chunk-UUHAXGMO.mjs +2 -0
  39. package/dist/chunk-UUHAXGMO.mjs.map +1 -0
  40. package/dist/chunk-VU264VFN.mjs +2 -0
  41. package/dist/chunk-VU264VFN.mjs.map +1 -0
  42. package/dist/chunk-ZFS4B5QT.mjs +2 -0
  43. package/dist/chunk-ZFS4B5QT.mjs.map +1 -0
  44. package/dist/components/Accordion.d.ts +109 -1
  45. package/dist/components/Accordion.d.ts.map +1 -1
  46. package/dist/components/Action.d.ts +68 -0
  47. package/dist/components/Action.d.ts.map +1 -0
  48. package/dist/components/ActionToolbar.d.ts +65 -0
  49. package/dist/components/ActionToolbar.d.ts.map +1 -0
  50. package/dist/components/Alert.d.ts +49 -0
  51. package/dist/components/Alert.d.ts.map +1 -1
  52. package/dist/components/Autocomplete.d.ts +88 -0
  53. package/dist/components/Autocomplete.d.ts.map +1 -0
  54. package/dist/components/Avatar.d.ts +71 -1
  55. package/dist/components/Avatar.d.ts.map +1 -1
  56. package/dist/components/Badge.d.ts +32 -2
  57. package/dist/components/Badge.d.ts.map +1 -1
  58. package/dist/components/Bookmark.d.ts +49 -0
  59. package/dist/components/Bookmark.d.ts.map +1 -0
  60. package/dist/components/BottomSheet.d.ts +91 -1
  61. package/dist/components/BottomSheet.d.ts.map +1 -1
  62. package/dist/components/Breadcrumb.d.ts +73 -14
  63. package/dist/components/Breadcrumb.d.ts.map +1 -1
  64. package/dist/components/Button.d.ts +82 -7
  65. package/dist/components/Button.d.ts.map +1 -1
  66. package/dist/components/Card.d.ts +122 -5
  67. package/dist/components/Card.d.ts.map +1 -1
  68. package/dist/components/ChatMessage.d.ts +67 -1
  69. package/dist/components/ChatMessage.d.ts.map +1 -1
  70. package/dist/components/Checkbox.d.ts +48 -2
  71. package/dist/components/Checkbox.d.ts.map +1 -1
  72. package/dist/components/Command.d.ts +82 -1
  73. package/dist/components/Command.d.ts.map +1 -1
  74. package/dist/components/ComponentLayout.d.ts +72 -0
  75. package/dist/components/ComponentLayout.d.ts.map +1 -0
  76. package/dist/components/ConfirmModal.d.ts +66 -1
  77. package/dist/components/ConfirmModal.d.ts.map +1 -1
  78. package/dist/components/Container.d.ts +39 -0
  79. package/dist/components/Container.d.ts.map +1 -1
  80. package/dist/components/ContextMenu.d.ts +51 -1
  81. package/dist/components/ContextMenu.d.ts.map +1 -1
  82. package/dist/components/DatePicker.d.ts +62 -0
  83. package/dist/components/DatePicker.d.ts.map +1 -0
  84. package/dist/components/Divider.d.ts +13 -3
  85. package/dist/components/Divider.d.ts.map +1 -1
  86. package/dist/components/Drawer.d.ts +103 -1
  87. package/dist/components/Drawer.d.ts.map +1 -1
  88. package/dist/components/Dropdown.d.ts +51 -1
  89. package/dist/components/Dropdown.d.ts.map +1 -1
  90. package/dist/components/EmotionAnalysis.d.ts +59 -1
  91. package/dist/components/EmotionAnalysis.d.ts.map +1 -1
  92. package/dist/components/EmotionButton.d.ts +35 -1
  93. package/dist/components/EmotionButton.d.ts.map +1 -1
  94. package/dist/components/EmotionMeter.d.ts +38 -2
  95. package/dist/components/EmotionMeter.d.ts.map +1 -1
  96. package/dist/components/EmotionSelector.d.ts +51 -1
  97. package/dist/components/EmotionSelector.d.ts.map +1 -1
  98. package/dist/components/FeatureCard.d.ts +61 -0
  99. package/dist/components/FeatureCard.d.ts.map +1 -0
  100. package/dist/components/Form.d.ts +114 -0
  101. package/dist/components/Form.d.ts.map +1 -0
  102. package/dist/components/Grid.d.ts +42 -1
  103. package/dist/components/Grid.d.ts.map +1 -1
  104. package/dist/components/HeroSection.d.ts +77 -0
  105. package/dist/components/HeroSection.d.ts.map +1 -0
  106. package/dist/components/Icon/Icon.d.ts +159 -0
  107. package/dist/components/Icon/Icon.d.ts.map +1 -0
  108. package/dist/components/Icon/IconProvider.d.ts +94 -0
  109. package/dist/components/Icon/IconProvider.d.ts.map +1 -0
  110. package/dist/components/Icon/icon-store.d.ts +21 -0
  111. package/dist/components/Icon/icon-store.d.ts.map +1 -0
  112. package/dist/components/Icon/index.d.ts +10 -0
  113. package/dist/components/Icon/index.d.ts.map +1 -0
  114. package/dist/components/InfoCard.d.ts +48 -0
  115. package/dist/components/InfoCard.d.ts.map +1 -0
  116. package/dist/components/Input.d.ts +40 -8
  117. package/dist/components/Input.d.ts.map +1 -1
  118. package/dist/components/Label.d.ts +50 -0
  119. package/dist/components/Label.d.ts.map +1 -0
  120. package/dist/components/LanguageToggle.d.ts +41 -1
  121. package/dist/components/LanguageToggle.d.ts.map +1 -1
  122. package/dist/components/Link.d.ts +52 -0
  123. package/dist/components/Link.d.ts.map +1 -0
  124. package/dist/components/LoadingSpinner.d.ts +44 -5
  125. package/dist/components/LoadingSpinner.d.ts.map +1 -1
  126. package/dist/components/Menu.d.ts +92 -1
  127. package/dist/components/Menu.d.ts.map +1 -1
  128. package/dist/components/Modal.d.ts +67 -5
  129. package/dist/components/Modal.d.ts.map +1 -1
  130. package/dist/components/Navigation.d.ts +72 -0
  131. package/dist/components/Navigation.d.ts.map +1 -0
  132. package/dist/components/PageNavigation.d.ts +48 -0
  133. package/dist/components/PageNavigation.d.ts.map +1 -0
  134. package/dist/components/PageTransition.d.ts +44 -1
  135. package/dist/components/PageTransition.d.ts.map +1 -1
  136. package/dist/components/Pagination.d.ts +52 -1
  137. package/dist/components/Pagination.d.ts.map +1 -1
  138. package/dist/components/Panel.d.ts +99 -0
  139. package/dist/components/Panel.d.ts.map +1 -0
  140. package/dist/components/Popover.d.ts +46 -1
  141. package/dist/components/Popover.d.ts.map +1 -1
  142. package/dist/components/Progress.d.ts +52 -3
  143. package/dist/components/Progress.d.ts.map +1 -1
  144. package/dist/components/Radio.d.ts +44 -2
  145. package/dist/components/Radio.d.ts.map +1 -1
  146. package/dist/components/ScrollArea.d.ts +53 -1
  147. package/dist/components/ScrollArea.d.ts.map +1 -1
  148. package/dist/components/ScrollIndicator.d.ts +43 -1
  149. package/dist/components/ScrollIndicator.d.ts.map +1 -1
  150. package/dist/components/ScrollProgress.d.ts +37 -0
  151. package/dist/components/ScrollProgress.d.ts.map +1 -1
  152. package/dist/components/ScrollToTop.d.ts +48 -11
  153. package/dist/components/ScrollToTop.d.ts.map +1 -1
  154. package/dist/components/SectionHeader.d.ts +42 -0
  155. package/dist/components/SectionHeader.d.ts.map +1 -0
  156. package/dist/components/Select.d.ts +59 -2
  157. package/dist/components/Select.d.ts.map +1 -1
  158. package/dist/components/Skeleton.d.ts +44 -1
  159. package/dist/components/Skeleton.d.ts.map +1 -1
  160. package/dist/components/Slider.d.ts +75 -0
  161. package/dist/components/Slider.d.ts.map +1 -0
  162. package/dist/components/Stack.d.ts +42 -1
  163. package/dist/components/Stack.d.ts.map +1 -1
  164. package/dist/components/StatsPanel.d.ts +72 -0
  165. package/dist/components/StatsPanel.d.ts.map +1 -0
  166. package/dist/components/Switch.d.ts +48 -2
  167. package/dist/components/Switch.d.ts.map +1 -1
  168. package/dist/components/Table.d.ts +206 -0
  169. package/dist/components/Table.d.ts.map +1 -0
  170. package/dist/components/Tabs.d.ts +123 -10
  171. package/dist/components/Tabs.d.ts.map +1 -1
  172. package/dist/components/Textarea.d.ts +48 -2
  173. package/dist/components/Textarea.d.ts.map +1 -1
  174. package/dist/components/ThemeProvider.d.ts +67 -2
  175. package/dist/components/ThemeProvider.d.ts.map +1 -1
  176. package/dist/components/ThemeToggle.d.ts +44 -0
  177. package/dist/components/ThemeToggle.d.ts.map +1 -1
  178. package/dist/components/Toast.d.ts +75 -1
  179. package/dist/components/Toast.d.ts.map +1 -1
  180. package/dist/components/Toggle.d.ts +62 -0
  181. package/dist/components/Toggle.d.ts.map +1 -0
  182. package/dist/components/Tooltip.d.ts +48 -1
  183. package/dist/components/Tooltip.d.ts.map +1 -1
  184. package/dist/components/Upload.d.ts +87 -0
  185. package/dist/components/Upload.d.ts.map +1 -0
  186. package/dist/components/advanced/AdvancedPageTransition.d.ts +25 -0
  187. package/dist/components/advanced/AdvancedPageTransition.d.ts.map +1 -0
  188. package/dist/components/advanced/index.d.ts +4 -0
  189. package/dist/components/advanced/index.d.ts.map +1 -0
  190. package/dist/components/advanced/usePageTransition.d.ts +33 -0
  191. package/dist/components/advanced/usePageTransition.d.ts.map +1 -0
  192. package/dist/components/advanced/usePageTransitionManager.d.ts +44 -0
  193. package/dist/components/advanced/usePageTransitionManager.d.ts.map +1 -0
  194. package/dist/components/dashboard/ActivityFeed.d.ts +87 -0
  195. package/dist/components/dashboard/ActivityFeed.d.ts.map +1 -0
  196. package/dist/components/dashboard/BarChart.d.ts +82 -0
  197. package/dist/components/dashboard/BarChart.d.ts.map +1 -0
  198. package/dist/components/dashboard/DashboardGrid.d.ts +44 -0
  199. package/dist/components/dashboard/DashboardGrid.d.ts.map +1 -0
  200. package/dist/components/dashboard/DashboardSidebar.d.ts +105 -0
  201. package/dist/components/dashboard/DashboardSidebar.d.ts.map +1 -0
  202. package/dist/components/dashboard/DashboardToolbar.d.ts +120 -0
  203. package/dist/components/dashboard/DashboardToolbar.d.ts.map +1 -0
  204. package/dist/components/dashboard/EmptyState.d.ts +61 -0
  205. package/dist/components/dashboard/EmptyState.d.ts.map +1 -0
  206. package/dist/components/dashboard/MembershipBadge.d.ts +45 -0
  207. package/dist/components/dashboard/MembershipBadge.d.ts.map +1 -0
  208. package/dist/components/dashboard/MerchantList.d.ts +98 -0
  209. package/dist/components/dashboard/MerchantList.d.ts.map +1 -0
  210. package/dist/components/dashboard/MetricCard.d.ts +75 -0
  211. package/dist/components/dashboard/MetricCard.d.ts.map +1 -0
  212. package/dist/components/dashboard/MiniBarChart.d.ts +60 -0
  213. package/dist/components/dashboard/MiniBarChart.d.ts.map +1 -0
  214. package/dist/components/dashboard/NotificationCard.d.ts +89 -0
  215. package/dist/components/dashboard/NotificationCard.d.ts.map +1 -0
  216. package/dist/components/dashboard/ProfileCard.d.ts +82 -0
  217. package/dist/components/dashboard/ProfileCard.d.ts.map +1 -0
  218. package/dist/components/dashboard/ProgressCard.d.ts +71 -0
  219. package/dist/components/dashboard/ProgressCard.d.ts.map +1 -0
  220. package/dist/components/dashboard/QuickActionCard.d.ts +63 -0
  221. package/dist/components/dashboard/QuickActionCard.d.ts.map +1 -0
  222. package/dist/components/dashboard/RoutingBreakdownCard.d.ts +88 -0
  223. package/dist/components/dashboard/RoutingBreakdownCard.d.ts.map +1 -0
  224. package/dist/components/dashboard/SettlementTimeline.d.ts +90 -0
  225. package/dist/components/dashboard/SettlementTimeline.d.ts.map +1 -0
  226. package/dist/components/dashboard/StatCard.d.ts +70 -0
  227. package/dist/components/dashboard/StatCard.d.ts.map +1 -0
  228. package/dist/components/dashboard/SummaryCard.d.ts +73 -0
  229. package/dist/components/dashboard/SummaryCard.d.ts.map +1 -0
  230. package/dist/components/dashboard/TransactionDetailDrawer.d.ts +183 -0
  231. package/dist/components/dashboard/TransactionDetailDrawer.d.ts.map +1 -0
  232. package/dist/components/dashboard/TransactionsTable.d.ts +137 -0
  233. package/dist/components/dashboard/TransactionsTable.d.ts.map +1 -0
  234. package/dist/components/dashboard/TrendChart.d.ts +75 -0
  235. package/dist/components/dashboard/TrendChart.d.ts.map +1 -0
  236. package/dist/components/dashboard/index.d.ts +41 -0
  237. package/dist/components/dashboard/index.d.ts.map +1 -0
  238. package/dist/components/scrollbar/scrollbar.d.ts +12 -0
  239. package/dist/components/scrollbar/scrollbar.d.ts.map +1 -0
  240. package/dist/dashboard-QMssHf5j.d.mts +1801 -0
  241. package/dist/feedback.d.mts +103 -0
  242. package/dist/feedback.d.ts +21 -0
  243. package/dist/feedback.d.ts.map +1 -0
  244. package/dist/feedback.js +2 -0
  245. package/dist/feedback.js.map +1 -0
  246. package/dist/feedback.mjs +2 -0
  247. package/dist/feedback.mjs.map +1 -0
  248. package/dist/form.d.mts +803 -0
  249. package/dist/form.d.ts +42 -0
  250. package/dist/form.d.ts.map +1 -0
  251. package/dist/form.js +2 -0
  252. package/dist/form.js.map +1 -0
  253. package/dist/form.mjs +2 -0
  254. package/dist/form.mjs.map +1 -0
  255. package/dist/hooks/useScrollToggle.d.ts +12 -0
  256. package/dist/hooks/useScrollToggle.d.ts.map +1 -0
  257. package/dist/icons-DoSGIez_.d.mts +135 -0
  258. package/dist/index.d.mts +3770 -0
  259. package/dist/index.d.ts +76 -38
  260. package/dist/index.d.ts.map +1 -1
  261. package/dist/index.js +37 -49
  262. package/dist/index.js.map +1 -0
  263. package/dist/index.mjs +37 -0
  264. package/dist/index.mjs.map +1 -0
  265. package/dist/lib/icon-aliases.d.ts +24 -0
  266. package/dist/lib/icon-aliases.d.ts.map +1 -0
  267. package/dist/lib/icon-names.d.ts +47 -0
  268. package/dist/lib/icon-names.d.ts.map +1 -0
  269. package/dist/lib/icon-providers.d.ts +559 -0
  270. package/dist/lib/icon-providers.d.ts.map +1 -0
  271. package/dist/lib/icons.d.ts +113 -24
  272. package/dist/lib/icons.d.ts.map +1 -1
  273. package/dist/lib/phosphor-icons.d.ts +6 -0
  274. package/dist/lib/phosphor-icons.d.ts.map +1 -0
  275. package/dist/lib/styles/colors.d.ts +131 -0
  276. package/dist/lib/styles/colors.d.ts.map +1 -0
  277. package/dist/lib/styles/index.d.ts +8 -0
  278. package/dist/lib/styles/index.d.ts.map +1 -0
  279. package/dist/lib/styles/utils.d.ts +87 -0
  280. package/dist/lib/styles/utils.d.ts.map +1 -0
  281. package/dist/lib/styles/variants.d.ts +79 -0
  282. package/dist/lib/styles/variants.d.ts.map +1 -0
  283. package/dist/lib/types/common.d.ts +80 -0
  284. package/dist/lib/types/common.d.ts.map +1 -0
  285. package/dist/lib/types/index.d.ts +6 -0
  286. package/dist/lib/types/index.d.ts.map +1 -0
  287. package/dist/lib/utils.d.ts +73 -1
  288. package/dist/lib/utils.d.ts.map +1 -1
  289. package/dist/navigation.d.mts +105 -0
  290. package/dist/navigation.d.ts +22 -0
  291. package/dist/navigation.d.ts.map +1 -0
  292. package/dist/navigation.js +2 -0
  293. package/dist/navigation.js.map +1 -0
  294. package/dist/navigation.mjs +2 -0
  295. package/dist/navigation.mjs.map +1 -0
  296. package/package.json +92 -25
  297. package/src/styles/toast.css +23 -0
  298. package/dist/components/Accordion.js +0 -84
  299. package/dist/components/Alert.js +0 -61
  300. package/dist/components/Avatar.js +0 -18
  301. package/dist/components/Badge.js +0 -15
  302. package/dist/components/BottomSheet.js +0 -96
  303. package/dist/components/Breadcrumb.js +0 -47
  304. package/dist/components/Button.js +0 -23
  305. package/dist/components/Card.js +0 -18
  306. package/dist/components/ChatMessage.js +0 -59
  307. package/dist/components/Checkbox.js +0 -30
  308. package/dist/components/Command.js +0 -119
  309. package/dist/components/ConfirmModal.js +0 -53
  310. package/dist/components/Container.js +0 -23
  311. package/dist/components/ContextMenu.js +0 -110
  312. package/dist/components/Divider.js +0 -39
  313. package/dist/components/Drawer.js +0 -79
  314. package/dist/components/Dropdown.js +0 -174
  315. package/dist/components/EmotionAnalysis.js +0 -40
  316. package/dist/components/EmotionButton.js +0 -16
  317. package/dist/components/EmotionMeter.js +0 -21
  318. package/dist/components/EmotionSelector.js +0 -46
  319. package/dist/components/Grid.js +0 -44
  320. package/dist/components/Icon.d.ts +0 -26
  321. package/dist/components/Icon.d.ts.map +0 -1
  322. package/dist/components/Icon.js +0 -48
  323. package/dist/components/Input.js +0 -25
  324. package/dist/components/LanguageToggle.js +0 -61
  325. package/dist/components/LoadingSpinner.js +0 -37
  326. package/dist/components/Menu.js +0 -122
  327. package/dist/components/Modal.js +0 -62
  328. package/dist/components/PageTransition.js +0 -39
  329. package/dist/components/Pagination.js +0 -87
  330. package/dist/components/Popover.js +0 -159
  331. package/dist/components/Progress.js +0 -51
  332. package/dist/components/Radio.js +0 -29
  333. package/dist/components/ScrollArea.js +0 -42
  334. package/dist/components/ScrollIndicator.js +0 -60
  335. package/dist/components/ScrollProgress.js +0 -39
  336. package/dist/components/ScrollToTop.js +0 -46
  337. package/dist/components/Select.js +0 -29
  338. package/dist/components/Skeleton.js +0 -71
  339. package/dist/components/Stack.js +0 -34
  340. package/dist/components/Switch.js +0 -29
  341. package/dist/components/Tabs.js +0 -117
  342. package/dist/components/Textarea.js +0 -31
  343. package/dist/components/ThemeProvider.js +0 -76
  344. package/dist/components/ThemeToggle.js +0 -49
  345. package/dist/components/Toast.js +0 -138
  346. package/dist/components/Tooltip.js +0 -102
  347. package/dist/lib/icons.js +0 -321
  348. package/dist/lib/utils.js +0 -5
@@ -1,3 +1,75 @@
1
1
  import { type ClassValue } from "clsx";
2
- export declare function cn(...inputs: ClassValue[]): string;
2
+ /**
3
+ * HUA UI의 스마트 클래스 병합 유틸리티
4
+ * clsx와 tailwind-merge를 결합하여 중복 클래스를 자동으로 해결합니다.
5
+ *
6
+ * @param inputs - 병합할 클래스 값들
7
+ * @returns 병합된 클래스 문자열
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * merge("px-2 py-1", "px-4") // "py-1 px-4"
12
+ * merge("text-red-500", "text-blue-500") // "text-blue-500"
13
+ * merge("bg-white", "dark:bg-slate-900") // "bg-white dark:bg-slate-900"
14
+ * ```
15
+ */
16
+ export declare function merge(...inputs: ClassValue[]): string;
17
+ /**
18
+ * 조건부 클래스 병합 유틸리티
19
+ * 조건에 따라 클래스를 선택적으로 병합합니다.
20
+ *
21
+ * @param condition - 클래스를 적용할 조건
22
+ * @param trueClass - 조건이 true일 때 적용할 클래스
23
+ * @param falseClass - 조건이 false일 때 적용할 클래스 (선택사항)
24
+ * @returns 병합된 클래스 문자열
25
+ *
26
+ * @example
27
+ * ```tsx
28
+ * mergeIf(isActive, "bg-blue-500", "bg-gray-200")
29
+ * mergeIf(isLoading, "opacity-50 cursor-not-allowed")
30
+ * ```
31
+ */
32
+ export declare function mergeIf(condition: boolean, trueClass: ClassValue, falseClass?: ClassValue): string;
33
+ /**
34
+ * 상대 시간 포맷팅 유틸리티
35
+ *
36
+ * 날짜를 상대 시간 형식으로 포맷팅합니다 (예: "방금 전", "5분 전", "2시간 전", "3일 전").
37
+ * 7일 이상 경과한 경우 절대 날짜를 반환합니다.
38
+ *
39
+ * Formats a date as relative time (e.g., "방금 전", "5분 전", "2시간 전", "3일 전").
40
+ * Returns absolute date for dates older than 7 days.
41
+ *
42
+ * @param timestamp - 포맷팅할 날짜 (Date 객체 또는 ISO 문자열) / Date to format (Date object or ISO string)
43
+ * @param locale - 로케일 (기본값: "ko-KR") / Locale (default: "ko-KR")
44
+ * @returns 포맷팅된 상대 시간 문자열 / Formatted relative time string
45
+ *
46
+ * @example
47
+ * ```tsx
48
+ * formatRelativeTime(new Date()) // "방금 전"
49
+ * formatRelativeTime(new Date(Date.now() - 5 * 60000)) // "5분 전"
50
+ * formatRelativeTime(new Date(Date.now() - 2 * 3600000)) // "2시간 전"
51
+ * formatRelativeTime(new Date(Date.now() - 3 * 86400000)) // "3일 전"
52
+ * formatRelativeTime(new Date("2024-01-01")) // "2024. 1. 1." (7일 이상 경과)
53
+ * ```
54
+ */
55
+ export declare function formatRelativeTime(timestamp: Date | string, locale?: string): string;
56
+ /**
57
+ * 객체 기반 클래스 병합 유틸리티
58
+ * 객체의 키-값 쌍을 기반으로 조건부 클래스를 병합합니다.
59
+ *
60
+ * @param classMap - 클래스 맵 객체
61
+ * @returns 병합된 클래스 문자열
62
+ *
63
+ * @example
64
+ * ```tsx
65
+ * mergeMap({
66
+ * "bg-blue-500": isPrimary,
67
+ * "bg-gray-500": !isPrimary,
68
+ * "text-white": true,
69
+ * "opacity-50": isDisabled
70
+ * })
71
+ * ```
72
+ */
73
+ export declare function mergeMap(classMap: Record<string, boolean | undefined | null>): string;
74
+ export declare const cn: typeof merge;
3
75
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/lib/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,UAAU,EAAQ,MAAM,MAAM,CAAA;AAG5C,wBAAgB,EAAE,CAAC,GAAG,MAAM,EAAE,UAAU,EAAE,UAEzC"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/lib/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,UAAU,EAAQ,MAAM,MAAM,CAAA;AAG5C;;;;;;;;;;;;;GAaG;AACH,wBAAgB,KAAK,CAAC,GAAG,MAAM,EAAE,UAAU,EAAE,UAE5C;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,OAAO,CACrB,SAAS,EAAE,OAAO,EAClB,SAAS,EAAE,UAAU,EACrB,UAAU,CAAC,EAAE,UAAU,UAGxB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,IAAI,GAAG,MAAM,EAAE,MAAM,SAAU,GAAG,MAAM,CAarF;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,GAAG,IAAI,CAAC,UAM5E;AAGD,eAAO,MAAM,EAAE,cAAQ,CAAA"}
@@ -0,0 +1,105 @@
1
+ import React from 'react';
2
+
3
+ /**
4
+ * PageNavigation 컴포넌트의 props / PageNavigation component props
5
+ * @typedef {Object} PageNavigationProps
6
+ * @property {Object} [prevPage] - 이전 페이지 정보 / Previous page information
7
+ * @property {string} prevPage.title - 이전 페이지 제목 / Previous page title
8
+ * @property {string} prevPage.href - 이전 페이지 링크 / Previous page link
9
+ * @property {Object} [nextPage] - 다음 페이지 정보 / Next page information
10
+ * @property {string} nextPage.title - 다음 페이지 제목 / Next page title
11
+ * @property {string} nextPage.href - 다음 페이지 링크 / Next page link
12
+ * @property {boolean} [showOnMobile=false] - 모바일에서 표시 여부 / Show on mobile
13
+ * @extends {React.HTMLAttributes<HTMLDivElement>}
14
+ */
15
+ interface PageNavigationProps extends React.HTMLAttributes<HTMLDivElement> {
16
+ prevPage?: {
17
+ title: string;
18
+ href: string;
19
+ };
20
+ nextPage?: {
21
+ title: string;
22
+ href: string;
23
+ };
24
+ showOnMobile?: boolean;
25
+ }
26
+ /**
27
+ * PageNavigation 컴포넌트 / PageNavigation component
28
+ *
29
+ * 이전/다음 페이지로 이동하는 네비게이션 컴포넌트입니다.
30
+ * 문서 페이지나 가이드 페이지에서 사용하기 적합합니다.
31
+ *
32
+ * Navigation component for moving to previous/next pages.
33
+ * Suitable for documentation or guide pages.
34
+ *
35
+ * @component
36
+ * @example
37
+ * // 기본 사용 / Basic usage
38
+ * <PageNavigation
39
+ * prevPage={{ title: "이전 페이지", href: "/prev" }}
40
+ * nextPage={{ title: "다음 페이지", href: "/next" }}
41
+ * />
42
+ *
43
+ * @param {PageNavigationProps} props - PageNavigation 컴포넌트의 props / PageNavigation component props
44
+ * @param {React.Ref<HTMLDivElement>} ref - div 요소 ref / div element ref
45
+ * @returns {JSX.Element} PageNavigation 컴포넌트 / PageNavigation component
46
+ */
47
+ declare const PageNavigation: React.ForwardRefExoticComponent<PageNavigationProps & React.RefAttributes<HTMLDivElement>>;
48
+
49
+ /**
50
+ * PageTransition 컴포넌트의 props / PageTransition component props
51
+ * @typedef {Object} PageTransitionProps
52
+ * @property {React.ReactNode} children - 페이지 내용 / Page content
53
+ * @property {string} [className] - 추가 CSS 클래스 / Additional CSS class
54
+ * @property {number} [duration=300] - 전환 지속 시간 (ms) / Transition duration (ms)
55
+ * @property {'fade' | 'slide' | 'scale' | 'flip'} [variant='fade'] - 전환 애니메이션 타입 / Transition animation type
56
+ * @property {'default' | 'dots' | 'bars' | 'ring' | 'ripple'} [loadingVariant='ripple'] - 로딩 스피너 타입 / Loading spinner type
57
+ * @property {string} [loadingText='페이지 로딩 중...'] - 로딩 텍스트 / Loading text
58
+ * @property {boolean} [showLoading=true] - 로딩 표시 여부 / Show loading
59
+ * @property {() => void} [onTransitionStart] - 전환 시작 콜백 / Transition start callback
60
+ * @property {() => void} [onTransitionEnd] - 전환 종료 콜백 / Transition end callback
61
+ */
62
+ interface PageTransitionProps {
63
+ children: React.ReactNode;
64
+ className?: string;
65
+ duration?: number;
66
+ variant?: 'fade' | 'slide' | 'scale' | 'flip';
67
+ loadingVariant?: 'default' | 'dots' | 'bars' | 'ring' | 'ripple';
68
+ loadingText?: string;
69
+ showLoading?: boolean;
70
+ onTransitionStart?: () => void;
71
+ onTransitionEnd?: () => void;
72
+ }
73
+ /**
74
+ * PageTransition 컴포넌트 / PageTransition component
75
+ *
76
+ * 페이지 전환 애니메이션을 제공하는 컴포넌트입니다.
77
+ * 다양한 전환 효과와 로딩 스피너를 지원합니다.
78
+ *
79
+ * Component that provides page transition animations.
80
+ * Supports various transition effects and loading spinners.
81
+ *
82
+ * @component
83
+ * @example
84
+ * // 기본 사용 / Basic usage
85
+ * <PageTransition>
86
+ * <div>페이지 내용</div>
87
+ * </PageTransition>
88
+ *
89
+ * @example
90
+ * // Slide 전환 / Slide transition
91
+ * <PageTransition
92
+ * variant="slide"
93
+ * duration={500}
94
+ * loadingVariant="dots"
95
+ * >
96
+ * <div>페이지 내용</div>
97
+ * </PageTransition>
98
+ *
99
+ * @param {PageTransitionProps} props - PageTransition 컴포넌트의 props / PageTransition component props
100
+ * @param {React.Ref<HTMLDivElement>} ref - div 요소 ref / div element ref
101
+ * @returns {JSX.Element} PageTransition 컴포넌트 / PageTransition component
102
+ */
103
+ declare const PageTransition: React.ForwardRefExoticComponent<PageTransitionProps & React.RefAttributes<HTMLDivElement>>;
104
+
105
+ export { PageNavigation, type PageNavigationProps, PageTransition, type PageTransitionProps };
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Navigation Components Entrypoint
3
+ *
4
+ * 네비게이션 관련 컴포넌트들을 모아서 export하는 엔트리 포인트입니다.
5
+ * 대규모 앱 구조에 필요한 네비게이션 컴포넌트만 포함합니다.
6
+ *
7
+ * Entry point that aggregates navigation-related components.
8
+ * Includes navigation components needed for large-scale app structures.
9
+ *
10
+ * @example
11
+ * // 네비게이션 컴포넌트만 import / Import only navigation components
12
+ * import { PageNavigation, PageTransition } from '@hua-labs/ui/navigation';
13
+ *
14
+ * @example
15
+ * // Core에서도 여전히 사용 가능 (하위 호환성) / Still available from core (backward compatibility)
16
+ * import { PageNavigation, PageTransition } from '@hua-labs/ui';
17
+ */
18
+ export { PageNavigation } from './components/PageNavigation';
19
+ export type { PageNavigationProps } from './components/PageNavigation';
20
+ export { PageTransition } from './components/PageTransition';
21
+ export type { PageTransitionProps } from './components/PageTransition';
22
+ //# sourceMappingURL=navigation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../src/navigation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,YAAY,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAEvE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,YAAY,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC"}
@@ -0,0 +1,2 @@
1
+ 'use strict';var d=require('react'),clsx=require('clsx'),tailwindMerge=require('tailwind-merge'),N=require('lucide-react'),jsxRuntime=require('react/jsx-runtime');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var d__default=/*#__PURE__*/_interopDefault(d);var N__namespace=/*#__PURE__*/_interopNamespace(N);function t(...e){return tailwindMerge.twMerge(clsx.clsx(e))}function E(e){let o=Object.entries(e).filter(([,r])=>r).map(([r])=>r);return t(...o)}var $={home:N.Home,arrowLeft:N.ArrowLeft,arrowRight:N.ArrowRight,arrowUp:N.ArrowUp,arrowDown:N.ArrowDown,menu:N.Menu,close:N.X,search:N.Search,settings:N.Settings,externalLink:N.ExternalLink,chevronLeft:N.ChevronLeft,chevronRight:N.ChevronRight,chevronDown:N.ChevronDown,chevronUp:N.ChevronUp,edit:N.Edit,delete:N.Trash2,add:N.Plus,remove:N.Minus,download:N.Download,upload:N.Upload,refresh:N.RefreshCw,save:N.Save,copy:N.Copy,loader:N.Loader2,success:N.CheckCircle,error:N.XCircle,alertCircle:N.AlertCircle,warning:N.AlertCircle,info:N.Info,check:N.Check,circle:N.Circle,helpCircle:N.HelpCircle,user:N.User,users:N.Users,userPlus:N.UserPlus,logIn:N.LogIn,logOut:N.LogOut,eye:N.Eye,eyeOff:N.EyeOff,chart:N.BarChart3,barChart:N.BarChart3,trendingUp:N.TrendingUp,activity:N.Activity,database:N.Database,zap:N.Zap,fileText:N.FileText,file:N.File,folder:N.Folder,book:N.Book,bookOpen:N.BookOpen,mail:N.Mail,message:N.MessageCircle,phone:N.Phone,image:N.Image,video:N.Video,camera:N.Camera,smile:N.Smile,frown:N.Frown,meh:N.Meh,lock:N.Lock,unlock:N.Unlock,shield:N.Shield,wallet:N.Wallet,key:N.Key,clock:N.Clock,calendar:N.Calendar,calendarPlus:N.CalendarPlus,bell:N.Bell,heart:N.Heart,star:N.Star,bookmark:N.Bookmark,share:N.Share,monitor:N.Monitor,sun:N.Sun,moon:N.Moon,lightbulb:N.Lightbulb,brain:N.Brain,flag:N.Flag,square:N.Square},K={happy:"smile",sad:"frown",neutral:"meh",excited:"smile",angry:"frown",love:"heart",like:"heart",dislike:"frown"},X={loading:"loader",success:"success",error:"error",warning:"warning",info:"info",locked:"lock",unlocked:"unlock",visible:"eye",hidden:"eyeOff"};var i=null,Uo={home:{lucide:"Home",phosphor:"House",untitled:"home"},"layout-dashboard":{lucide:"LayoutDashboard",phosphor:"SquaresFour",untitled:"layout-dashboard"},folder:{lucide:"Folder",phosphor:"Folder",untitled:"folder"},"alert-circle":{lucide:"AlertCircle",phosphor:"WarningCircle",untitled:"alert-circle"},alertCircle:{lucide:"AlertCircle",phosphor:"WarningCircle",untitled:"alert-circle"},columns:{lucide:"Columns",phosphor:"Columns",untitled:"columns"},users:{lucide:"Users",phosphor:"Users",untitled:"users"},settings:{lucide:"Settings",phosphor:"Gear",untitled:"settings"},menu:{lucide:"Menu",phosphor:"List",untitled:"menu"},close:{lucide:"X",phosphor:"X",untitled:"close"},chevronLeft:{lucide:"ChevronLeft",phosphor:"CaretLeft",untitled:"chevron-left"},chevronRight:{lucide:"ChevronRight",phosphor:"CaretRight",untitled:"chevron-right"},chevronDown:{lucide:"ChevronDown",phosphor:"CaretDown",untitled:"chevron-down"},chevronUp:{lucide:"ChevronUp",phosphor:"CaretUp",untitled:"chevron-up"},arrowLeft:{lucide:"ArrowLeft",phosphor:"ArrowLeft",untitled:"arrow-left"},arrowRight:{lucide:"ArrowRight",phosphor:"ArrowRight",untitled:"arrow-right"},arrowUp:{lucide:"ArrowUp",phosphor:"ArrowUp",untitled:"arrow-up"},arrowDown:{lucide:"ArrowDown",phosphor:"ArrowDown",untitled:"arrow-down"},add:{lucide:"Plus",phosphor:"Plus",untitled:"add"},edit:{lucide:"Edit",phosphor:"Pencil",untitled:"edit"},pencil:{lucide:"Pencil",phosphor:"Pencil",untitled:"pencil"},delete:{lucide:"Trash2",phosphor:"Trash",untitled:"trash"},trash:{lucide:"Trash2",phosphor:"Trash",untitled:"trash"},upload:{lucide:"Upload",phosphor:"Upload",untitled:"upload"},download:{lucide:"Download",phosphor:"Download",untitled:"download"},x:{lucide:"X",phosphor:"X",untitled:"close"},check:{lucide:"Check",phosphor:"Check",untitled:"check"},search:{lucide:"Search",phosphor:"MagnifyingGlass",untitled:"search"},share:{lucide:"Share",phosphor:"Share",untitled:"share"},copy:{lucide:"Copy",phosphor:"Copy",untitled:"copy"},save:{lucide:"Save",phosphor:"FloppyDisk",untitled:"save"},loader:{lucide:"Loader2",phosphor:"Spinner",untitled:"loader"},loader2:{lucide:"Loader2",phosphor:"Spinner",untitled:"loader"},"check-circle":{lucide:"CheckCircle",phosphor:"CheckCircle",untitled:"check-circle"},checkCircle:{lucide:"CheckCircle",phosphor:"CheckCircle",untitled:"check-circle"},success:{lucide:"CheckCircle",phosphor:"CheckCircle",untitled:"check-circle"},error:{lucide:"XCircle",phosphor:"XCircle",untitled:"error"},warning:{lucide:"AlertCircle",phosphor:"WarningCircle",untitled:"warning"},info:{lucide:"Info",phosphor:"Info",untitled:"info"},refresh:{lucide:"RefreshCw",phosphor:"ArrowClockwise",untitled:"refresh"},refreshCw:{lucide:"RefreshCw",phosphor:"ArrowClockwise",untitled:"refresh"},bell:{lucide:"Bell",phosphor:"Bell",untitled:"bell"},heart:{lucide:"Heart",phosphor:"Heart",untitled:"heart"},star:{lucide:"Star",phosphor:"Star",untitled:"star"},bookmark:{lucide:"Bookmark",phosphor:"Bookmark",untitled:"bookmark"},user:{lucide:"User",phosphor:"User",untitled:"user"},userPlus:{lucide:"UserPlus",phosphor:"UserPlus",untitled:"user-plus"},logIn:{lucide:"LogIn",phosphor:"SignIn",untitled:"log-in"},logOut:{lucide:"LogOut",phosphor:"SignOut",untitled:"log-out"},chrome:{lucide:"Chrome",phosphor:"ChromeLogo",untitled:"chrome"},github:{lucide:"Github",phosphor:"GithubLogo",untitled:"github"},message:{lucide:"MessageCircle",phosphor:"ChatCircle",untitled:"message"},messageSquare:{lucide:"MessageSquare",phosphor:"ChatSquare",untitled:"message-square"},"message-square":{lucide:"MessageSquare",phosphor:"ChatSquare",untitled:"message-square"},inbox:{lucide:"Inbox",phosphor:"Inbox",untitled:"inbox"},calendar:{lucide:"Calendar",phosphor:"Calendar",untitled:"calendar"},calendarPlus:{lucide:"CalendarPlus",phosphor:"CalendarPlus",untitled:"calendar-plus"},checkSquare:{lucide:"CheckSquare",phosphor:"CheckSquare",untitled:"check-square"},clock:{lucide:"Clock",phosphor:"Clock",untitled:"clock"},book:{lucide:"Book",phosphor:"Book",untitled:"book"},bookOpen:{lucide:"BookOpen",phosphor:"BookOpen",untitled:"book-open"},monitor:{lucide:"Monitor",phosphor:"Monitor",untitled:"monitor"},sun:{lucide:"Sun",phosphor:"Sun",untitled:"sun"},moon:{lucide:"Moon",phosphor:"Moon",untitled:"moon"},sparkles:{lucide:"Sparkles",phosphor:"Sparkle",untitled:"sparkles"},lightbulb:{lucide:"Lightbulb",phosphor:"Lightbulb",untitled:"lightbulb"},brain:{lucide:"Brain",phosphor:"Brain",untitled:"brain"},zap:{lucide:"Zap",phosphor:"Lightning",untitled:"zap"},chart:{lucide:"BarChart3",phosphor:"ChartBar",untitled:"chart"},barChart:{lucide:"BarChart",phosphor:"ChartBar",untitled:"bar-chart"},trendingUp:{lucide:"TrendingUp",phosphor:"TrendUp",untitled:"trending-up"},trendingDown:{lucide:"TrendingDown",phosphor:"TrendDown",untitled:"trending-down"},activity:{lucide:"Activity",phosphor:"Activity",untitled:"activity"},database:{lucide:"Database",phosphor:"Database",untitled:"database"},dollarSign:{lucide:"DollarSign",phosphor:"CurrencyDollar",untitled:"dollar-sign"},dollar:{lucide:"DollarSign",phosphor:"CurrencyDollar",untitled:"dollar-sign"},currency:{lucide:"DollarSign",phosphor:"CurrencyDollar",untitled:"currency"},lock:{lucide:"Lock",phosphor:"Lock",untitled:"lock"},unlock:{lucide:"Unlock",phosphor:"LockOpen",untitled:"unlock"},shield:{lucide:"Shield",phosphor:"Shield",untitled:"shield"},key:{lucide:"Key",phosphor:"Key",untitled:"key"},play:{lucide:"Play",phosphor:"Play",untitled:"play"},pause:{lucide:"Pause",phosphor:"Pause",untitled:"pause"},image:{lucide:"Image",phosphor:"Image",untitled:"image"},video:{lucide:"Video",phosphor:"Video",untitled:"video"},camera:{lucide:"Camera",phosphor:"Camera",untitled:"camera"},fileText:{lucide:"FileText",phosphor:"FileText",untitled:"file-text"},file:{lucide:"File",phosphor:"File",untitled:"file"},externalLink:{lucide:"ExternalLink",phosphor:"ArrowSquareOut",untitled:"external-link"},link:{lucide:"Link",phosphor:"Link",untitled:"link"},moreHorizontal:{lucide:"MoreHorizontal",phosphor:"DotsThreeOutline",untitled:"more-horizontal"},moreVertical:{lucide:"MoreVertical",phosphor:"DotsThreeVertical",untitled:"more-vertical"},remove:{lucide:"Minus",phosphor:"Minus",untitled:"remove"},eye:{lucide:"Eye",phosphor:"Eye",untitled:"eye"},eyeOff:{lucide:"EyeOff",phosphor:"EyeSlash",untitled:"eye-off"},smile:{lucide:"Smile",phosphor:"Smiley",untitled:"smile"},frown:{lucide:"Frown",phosphor:"SmileySad",untitled:"frown"},meh:{lucide:"Meh",phosphor:"SmileyMeh",untitled:"meh"},mail:{lucide:"Mail",phosphor:"Envelope",untitled:"mail"},phone:{lucide:"Phone",phosphor:"Phone",untitled:"phone"},flag:{lucide:"Flag",phosphor:"Flag",untitled:"flag"}};async function j(){if(typeof window=="undefined")return null;if(!i)try{i=await import('@phosphor-icons/react');}catch{return console.warn("Phosphor Icons not available. Install @phosphor-icons/react to use."),null}return i}function W(e,o="lucide"){let r=Uo[e];if(!r)return Eo(e,o);let a=r[o];switch(o){case "lucide":return N__namespace[a]||null;case "phosphor":return i&&(i==null?void 0:i[a])||null;case "untitled":return null;default:return null}}function Eo(e,o){switch(o){case "lucide":let r=e.charAt(0).toUpperCase()+e.slice(1),a=e.replace(/([A-Z])/g,(n,h)=>n===e[0]?n.toLowerCase():n);return N__namespace[r]||N__namespace[e]||N__namespace[a]||null;case "phosphor":if(!i)return null;let c=e.charAt(0).toUpperCase()+e.slice(1),p=e.split(/(?=[A-Z])/).map(n=>n.charAt(0).toUpperCase()+n.slice(1)).join("");return (i==null?void 0:i[c])||(i==null?void 0:i[p])||(i==null?void 0:i[e])||null;case "untitled":return null;default:return null}}var Wo={back:"arrowLeft",prev:"arrowLeft",previous:"arrowLeft",forward:"arrowRight",next:"arrowRight",close:"x",cancel:"x",remove:"delete",trash:"delete",plus:"add",new:"add",pencil:"edit",modify:"edit",store:"save",floppy:"save",magnify:"search",person:"user",account:"user",profile:"user",gear:"settings",config:"settings",preferences:"settings",house:"home",main:"home",done:"check",complete:"check",tick:"check",information:"info",help:"info",alert:"warning",caution:"warning",checkmark:"success",checkCircle:"success",fail:"error",cross:"error",xCircle:"error",spinner:"loader",loading:"loader",wait:"loader",reload:"refresh",update:"refresh",sync:"refresh",show:"eye",view:"eye",hide:"eyeOff",hidden:"eyeOff",secure:"lock",locked:"lock",unsecure:"unlock",unlocked:"unlock",get:"download",fetch:"download",post:"upload",send:"share",export:"share",duplicate:"copy",clone:"copy",email:"mail",envelope:"mail",chat:"message",comment:"message",talk:"message",date:"calendar",schedule:"calendar",time:"clock",watch:"clock",document:"fileText",doc:"fileText",text:"fileText",directory:"folder",dir:"folder",picture:"image",img:"image",movie:"video",film:"video",photo:"camera",capture:"camera",start:"play",run:"play",stop:"pause",halt:"pause",like:"heart",love:"heart",favorite:"star",saveBookmark:"bookmark",notification:"bell",notify:"bell",alarm:"bell",prefs:"settings",lookup:"search",dots:"moreHorizontal",moreMenu:"moreHorizontal",moreOptions:"moreVertical",external:"externalLink",outbound:"externalLink",open:"externalLink",url:"link",hyperlink:"link",graph:"barChart",stats:"barChart",analytics:"barChart",db:"database",storage:"database",pulse:"activity",monitor:"activity",up:"trendingUp",down:"trendingDown",lightning:"zap",bolt:"zap",flash:"zap",security:"shield",protect:"shield",password:"key",secret:"key",signin:"logIn",login:"logIn",enter:"logIn",signout:"logOut",logout:"logOut",exit:"logOut",people:"users",group:"users",team:"users",addUser:"userPlus",invite:"userPlus",read:"book",library:"book",reading:"bookOpen",openBook:"bookOpen",light:"sun",day:"sun",dark:"moon",night:"moon",screen:"monitor",display:"monitor",ai:"brain",intelligence:"brain",think:"brain",idea:"lightbulb",bulb:"lightbulb",inspiration:"lightbulb",magic:"sparkles",stars:"sparkles",glitter:"sparkles"};function G(e){if(typeof e!="string")throw new TypeError("iconName must be a string");return Wo[e]||e}var D={set:"phosphor",weight:"regular",size:20,color:"currentColor",strokeWidth:1.25};var Ho=d.createContext(D);function z(){return d.useContext(Ho)}var _=d__default.default.forwardRef(({name:e,size:o,className:r,emotion:a,status:c,provider:p,weight:n,animated:h=false,pulse:v=false,spin:O=false,bounce:A=false,variant:m="default","aria-label":f,"aria-hidden":x},T)=>{var H;let b=z(),y=p||b.set,l=o!=null?o:b.size,ne=n||b.weight,ie=b.color,ae=(H=b.strokeWidth)!=null?H:1.25,[le,se]=d__default.default.useState(false),[ce,B]=d__default.default.useState(false);d__default.default.useEffect(()=>{se(true),y==="phosphor"?j().then(()=>{B(true);}):B(true);},[y]);let k=a?K[a]:c?X[c]:e;k=G(k);let R=E({"text-gray-900 dark:text-white":m==="default","text-blue-600 dark:text-blue-400":m==="primary","text-gray-600 dark:text-gray-400":m==="secondary","text-green-600 dark:text-green-400":m==="success","text-yellow-600 dark:text-yellow-400":m==="warning","text-red-600 dark:text-red-400":m==="error","text-gray-500 dark:text-gray-500":m==="muted"});if(!le||y==="phosphor"&&!ce)return jsxRuntime.jsx("span",{style:{width:l,height:l},className:t(R,r),"aria-hidden":x!==void 0?x:true,"aria-label":f});let w=null;if(y==="lucide"?(w=$[k]||null,w||(w=W(k,y))):w=W(k,y),!w)return console.warn(`Icon "${k}" not found for provider "${y}"`),jsxRuntime.jsx("span",{ref:T,className:t("inline-flex items-center justify-center rounded-full border-2 border-dashed border-gray-300 dark:border-gray-600",R,r),style:{width:l,height:l},"aria-label":f||`\uC544\uC774\uCF58\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC74C: ${k}`,title:`Icon not found: ${k}`,children:jsxRuntime.jsx("span",{className:"text-xs text-gray-400 dark:text-gray-500","aria-hidden":"true",children:"?"})});let U={size:typeof l=="number"?l:void 0,width:l,height:l,color:ie};y==="phosphor"?U.weight=ne:U.strokeWidth=ae;let de=E({"animate-pulse":v,"animate-spin":O,"animate-bounce":A,"transition-all duration-200 ease-in-out":h}),L={};return f?(L["aria-label"]=f,L["aria-hidden"]=false):x!==void 0?L["aria-hidden"]=x:L["aria-hidden"]=true,jsxRuntime.jsx("span",{ref:T,className:t("inline-flex items-center justify-center",de,R,r),style:{width:l,height:l},...L,children:w&&d__default.default.createElement(w,{...U,className:R,"aria-hidden":true})})});_.displayName="Icon";var Vo=d__default.default.memo(_,(e,o)=>e.name===o.name&&e.size===o.size&&e.className===o.className&&e.emotion===o.emotion&&e.status===o.status&&e.provider===o.provider&&e.animated===o.animated&&e.pulse===o.pulse&&e.spin===o.spin&&e.bounce===o.bounce&&e.variant===o.variant&&e.weight===o.weight&&e["aria-label"]===o["aria-label"]&&e["aria-hidden"]===o["aria-hidden"]),u=Vo;u.displayName="Icon";var Z=d__default.default.forwardRef((e,o)=>jsxRuntime.jsx(u,{ref:o,name:"smile",...e}));Z.displayName="EmotionIcon";var J=d__default.default.forwardRef((e,o)=>jsxRuntime.jsx(u,{ref:o,name:"info",...e}));J.displayName="StatusIcon";var Q=d__default.default.forwardRef((e,o)=>jsxRuntime.jsx(u,{ref:o,name:"loader",status:"loading",spin:true,"aria-label":"\uB85C\uB529 \uC911",...e}));Q.displayName="LoadingIcon";var Y=d__default.default.forwardRef((e,o)=>jsxRuntime.jsx(u,{ref:o,name:"check",status:"success",variant:"success","aria-label":"\uC131\uACF5",...e}));Y.displayName="SuccessIcon";var ee=d__default.default.forwardRef((e,o)=>jsxRuntime.jsx(u,{ref:o,name:"alertCircle",status:"error",variant:"error","aria-label":"\uC624\uB958",...e}));ee.displayName="ErrorIcon";var oe=d__default.default.forwardRef(({className:e,prevPage:o,nextPage:r,showOnMobile:a=false,...c},p)=>!o&&!r?null:jsxRuntime.jsxs("div",{ref:p,className:t("flex items-center justify-between py-4",!a&&"hidden md:flex",e),...c,children:[jsxRuntime.jsx("div",{className:"flex-1",children:o&&jsxRuntime.jsxs("a",{href:o.href,className:"group inline-flex items-center text-sm text-slate-600 hover:text-slate-900 dark:text-slate-400 dark:hover:text-slate-100 transition-colors",children:[jsxRuntime.jsx(u,{name:"chevronLeft",className:"w-4 h-4 mr-2 transition-transform group-hover:-translate-x-1"}),jsxRuntime.jsx("span",{className:"hidden sm:inline",children:o.title})]})}),jsxRuntime.jsx("div",{className:"flex-1 flex justify-end",children:r&&jsxRuntime.jsxs("a",{href:r.href,className:"group inline-flex items-center text-sm text-slate-600 hover:text-slate-900 dark:text-slate-400 dark:hover:text-slate-100 transition-colors",children:[jsxRuntime.jsx("span",{className:"hidden sm:inline mr-2",children:r.title}),jsxRuntime.jsx(u,{name:"chevronRight",className:"w-4 h-4 transition-transform group-hover:translate-x-1"})]})})]}));oe.displayName="PageNavigation";function re({className:e,size:o="md",variant:r="default",text:a,color:c="default"}){let p={sm:"w-6 h-6",md:"w-8 h-8",lg:"w-12 h-12",xl:"w-16 h-16"},n={default:"border-gray-300 border-t-gray-600 dark:border-gray-600 dark:border-t-gray-300",primary:"border-blue-300 border-t-blue-600 dark:border-blue-600 dark:border-t-blue-300",secondary:"border-gray-300 border-t-gray-600 dark:border-gray-600 dark:border-t-gray-300",success:"border-green-300 border-t-green-600 dark:border-green-600 dark:border-t-green-300",warning:"border-yellow-300 border-t-yellow-600 dark:border-yellow-600 dark:border-t-yellow-300",error:"border-red-300 border-t-red-600 dark:border-red-600 dark:border-t-red-300",glass:"border-white/30 border-t-white/50 dark:border-slate-600/50 dark:border-t-slate-400/50"},h=()=>{switch(r){case "dots":return jsxRuntime.jsxs("div",{className:"flex space-x-1",children:[jsxRuntime.jsx("div",{className:"w-2 h-2 bg-current rounded-full animate-bounce"}),jsxRuntime.jsx("div",{className:"w-2 h-2 bg-current rounded-full animate-bounce delay-100"}),jsxRuntime.jsx("div",{className:"w-2 h-2 bg-current rounded-full animate-bounce delay-200"})]});case "bars":return jsxRuntime.jsxs("div",{className:"flex space-x-1 h-full items-end",children:[jsxRuntime.jsx("div",{className:"w-1 bg-current animate-pulse",style:{height:"60%"}}),jsxRuntime.jsx("div",{className:"w-1 bg-current animate-pulse delay-100",style:{height:"80%"}}),jsxRuntime.jsx("div",{className:"w-1 bg-current animate-pulse delay-200",style:{height:"40%"}}),jsxRuntime.jsx("div",{className:"w-1 bg-current animate-pulse delay-300",style:{height:"100%"}}),jsxRuntime.jsx("div",{className:"w-1 bg-current animate-pulse delay-500",style:{height:"70%"}})]});case "ring":return jsxRuntime.jsx("div",{className:t("animate-spin rounded-full border-2",n[c]||n.default)});case "ripple":return jsxRuntime.jsxs("div",{className:"relative",children:[jsxRuntime.jsx("div",{className:t("absolute inset-0 rounded-full border-2 animate-ping",n[c]||n.default)}),jsxRuntime.jsx("div",{className:t("rounded-full border-2",n[c]||n.default)})]});default:return jsxRuntime.jsx("div",{className:t("animate-spin rounded-full border-2",n[c]||n.default)})}};return jsxRuntime.jsxs("div",{className:t("flex flex-col items-center justify-center",e),children:[jsxRuntime.jsx("div",{className:t(p[o],"text-gray-600 dark:text-gray-400"),children:h()}),a&&jsxRuntime.jsx("p",{className:"mt-3 text-sm text-gray-600 dark:text-gray-400 text-center",children:a})]})}var S=d__default.default.forwardRef(({children:e,className:o,duration:r=300,variant:a="fade",loadingVariant:c="ripple",loadingText:p="\uD398\uC774\uC9C0 \uB85C\uB529 \uC911...",showLoading:n=true,onTransitionStart:h,onTransitionEnd:v},O)=>{let[A,m]=d.useState(true),[f,x]=d.useState(false);d.useEffect(()=>{let b=setTimeout(()=>{m(false),x(true),v==null||v();},r);return h==null||h(),()=>clearTimeout(b)},[r,h,v]);let T={fade:t("transition-opacity duration-300 ease-in-out",f?"opacity-100":"opacity-0"),slide:t("transition-transform duration-300 ease-in-out",f?"translate-x-0":"translate-x-full"),scale:t("transition-all duration-300 ease-in-out",f?"scale-100 opacity-100":"scale-95 opacity-0"),flip:t("transition-all duration-500 ease-in-out",f?"rotate-y-0 opacity-100":"rotate-y-90 opacity-0")};return A&&n?jsxRuntime.jsx("div",{className:t("flex flex-col items-center justify-center min-h-screen bg-gradient-to-br from-blue-50 to-purple-50 dark:from-slate-900 dark:to-slate-800",o),children:jsxRuntime.jsx(re,{size:"lg",variant:c,text:p})}):jsxRuntime.jsx("div",{ref:O,className:t("w-full",T[a],o),style:{transitionDuration:`${r}ms`},children:e})});S.displayName="PageTransition";var Ko=d__default.default.forwardRef((e,o)=>jsxRuntime.jsx(S,{ref:o,variant:"fade",...e})),Xo=d__default.default.forwardRef((e,o)=>jsxRuntime.jsx(S,{ref:o,variant:"slide",...e})),jo=d__default.default.forwardRef((e,o)=>jsxRuntime.jsx(S,{ref:o,variant:"scale",...e})),Go=d__default.default.forwardRef((e,o)=>jsxRuntime.jsx(S,{ref:o,variant:"flip",...e}));Ko.displayName="FadeTransition";Xo.displayName="SlideTransition";jo.displayName="ScaleTransition";Go.displayName="FlipTransition";exports.PageNavigation=oe;exports.PageTransition=S;//# sourceMappingURL=navigation.js.map
2
+ //# sourceMappingURL=navigation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/utils.ts","../src/lib/icons.ts","../src/lib/icon-providers.ts","../src/lib/icon-aliases.ts","../src/components/Icon/icon-store.ts","../src/components/Icon/IconProvider.tsx","../src/components/Icon/Icon.tsx","../src/components/PageNavigation.tsx","../src/components/LoadingSpinner.tsx","../src/components/PageTransition.tsx"],"names":["merge","inputs","twMerge","clsx","mergeMap","classMap","classes","condition","className","icons","Home","ArrowLeft","ArrowRight","ArrowUp","ArrowDown","Menu","X","Search","Settings","ExternalLink","ChevronLeft","ChevronRight","ChevronDown","ChevronUp","Edit","Trash2","Plus","Minus","Download","Upload","RefreshCw","Save","Copy","Loader2","CheckCircle","XCircle","AlertCircle","Info","Check","Circle","HelpCircle","User","Users","UserPlus","LogIn","LogOut","Eye","EyeOff","BarChart3","TrendingUp","Activity","Database","Zap","FileText","File","Folder","Book","BookOpen","Mail","MessageCircle","Phone","Image","Video","Camera","Smile","Frown","Meh","Lock","Unlock","Shield","Wallet","Key","Clock","Calendar","CalendarPlus","Bell","Heart","Star","Bookmark","Share","Monitor","Sun","Moon","Lightbulb","Brain","Flag","Square","emotionIcons","statusIcons","PhosphorIcons","PROJECT_ICONS","initPhosphorIcons","getIconFromProvider","iconName","provider","iconMapping","getIconDirect","mappedName","LucideIcons","lucideName","camelCaseName","match","p1","phosphorName1","phosphorName2","word","ICON_ALIASES","resolveIconAlias","defaultIconConfig","IconContext","createContext","useIconContext","useContext","IconComponent","React","name","size","emotion","status","weight","animated","pulse","spin","bounce","variant","ariaLabel","ariaHidden","ref","_a","config","iconSet","iconSize","iconWeight","iconColor","iconStrokeWidth","isClient","setIsClient","phosphorReady","setPhosphorReady","variantClasses","jsx","iconProps","animationClasses","accessibilityProps","MemoizedIcon","prevProps","nextProps","Icon","EmotionIcon","props","StatusIcon","LoadingIcon","SuccessIcon","ErrorIcon","PageNavigation","prevPage","nextPage","showOnMobile","jsxs","LoadingSpinner","text","color","sizeClasses","spinnerColors","renderSpinner","PageTransition","children","duration","loadingVariant","loadingText","showLoading","onTransitionStart","onTransitionEnd","isLoading","setIsLoading","useState","isVisible","setIsVisible","useEffect","timer","transitionClasses","FadeTransition","SlideTransition","ScaleTransition","FlipTransition"],"mappings":"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","file":"navigation.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\n/**\n * HUA UI의 스마트 클래스 병합 유틸리티\n * clsx와 tailwind-merge를 결합하여 중복 클래스를 자동으로 해결합니다.\n * \n * @param inputs - 병합할 클래스 값들\n * @returns 병합된 클래스 문자열\n * \n * @example\n * ```tsx\n * merge(\"px-2 py-1\", \"px-4\") // \"py-1 px-4\"\n * merge(\"text-red-500\", \"text-blue-500\") // \"text-blue-500\"\n * merge(\"bg-white\", \"dark:bg-slate-900\") // \"bg-white dark:bg-slate-900\"\n * ```\n */\nexport function merge(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n\n/**\n * 조건부 클래스 병합 유틸리티\n * 조건에 따라 클래스를 선택적으로 병합합니다.\n * \n * @param condition - 클래스를 적용할 조건\n * @param trueClass - 조건이 true일 때 적용할 클래스\n * @param falseClass - 조건이 false일 때 적용할 클래스 (선택사항)\n * @returns 병합된 클래스 문자열\n * \n * @example\n * ```tsx\n * mergeIf(isActive, \"bg-blue-500\", \"bg-gray-200\")\n * mergeIf(isLoading, \"opacity-50 cursor-not-allowed\")\n * ```\n */\nexport function mergeIf(\n condition: boolean,\n trueClass: ClassValue,\n falseClass?: ClassValue\n) {\n return merge(condition ? trueClass : falseClass || \"\")\n}\n\n/**\n * 상대 시간 포맷팅 유틸리티\n * \n * 날짜를 상대 시간 형식으로 포맷팅합니다 (예: \"방금 전\", \"5분 전\", \"2시간 전\", \"3일 전\").\n * 7일 이상 경과한 경우 절대 날짜를 반환합니다.\n * \n * Formats a date as relative time (e.g., \"방금 전\", \"5분 전\", \"2시간 전\", \"3일 전\").\n * Returns absolute date for dates older than 7 days.\n * \n * @param timestamp - 포맷팅할 날짜 (Date 객체 또는 ISO 문자열) / Date to format (Date object or ISO string)\n * @param locale - 로케일 (기본값: \"ko-KR\") / Locale (default: \"ko-KR\")\n * @returns 포맷팅된 상대 시간 문자열 / Formatted relative time string\n * \n * @example\n * ```tsx\n * formatRelativeTime(new Date()) // \"방금 전\"\n * formatRelativeTime(new Date(Date.now() - 5 * 60000)) // \"5분 전\"\n * formatRelativeTime(new Date(Date.now() - 2 * 3600000)) // \"2시간 전\"\n * formatRelativeTime(new Date(Date.now() - 3 * 86400000)) // \"3일 전\"\n * formatRelativeTime(new Date(\"2024-01-01\")) // \"2024. 1. 1.\" (7일 이상 경과)\n * ```\n */\nexport function formatRelativeTime(timestamp: Date | string, locale = \"ko-KR\"): string {\n const date = typeof timestamp === \"string\" ? new Date(timestamp) : timestamp;\n const now = new Date();\n const diff = now.getTime() - date.getTime();\n const minutes = Math.floor(diff / 60000);\n const hours = Math.floor(diff / 3600000);\n const days = Math.floor(diff / 86400000);\n\n if (minutes < 1) return locale === \"ko-KR\" ? \"방금 전\" : \"just now\";\n if (minutes < 60) return locale === \"ko-KR\" ? `${minutes}분 전` : `${minutes}m ago`;\n if (hours < 24) return locale === \"ko-KR\" ? `${hours}시간 전` : `${hours}h ago`;\n if (days < 7) return locale === \"ko-KR\" ? `${days}일 전` : `${days}d ago`;\n return date.toLocaleDateString(locale);\n}\n\n/**\n * 객체 기반 클래스 병합 유틸리티\n * 객체의 키-값 쌍을 기반으로 조건부 클래스를 병합합니다.\n * \n * @param classMap - 클래스 맵 객체\n * @returns 병합된 클래스 문자열\n * \n * @example\n * ```tsx\n * mergeMap({\n * \"bg-blue-500\": isPrimary,\n * \"bg-gray-500\": !isPrimary,\n * \"text-white\": true,\n * \"opacity-50\": isDisabled\n * })\n * ```\n */\nexport function mergeMap(classMap: Record<string, boolean | undefined | null>) {\n const classes = Object.entries(classMap)\n .filter(([, condition]) => condition)\n .map(([className]) => className)\n \n return merge(...classes)\n}\n\n// 하위 호환성을 위해 cn도 export (점진적 마이그레이션 지원)\nexport const cn = merge ","/**\n * Core Icons\n * \n * 핵심 아이콘만 포함하여 번들 크기를 최적화합니다.\n * 나머지 아이콘은 동적 fallback으로 처리됩니다.\n * \n * 포함 기준:\n * 1. sum-diary에서 실제 사용 중인 아이콘\n * 2. UI 컴포넌트에서 자주 사용되는 아이콘\n * 3. 각 카테고리의 대표 아이콘\n * \n * 새로운 아이콘이 필요하면 동적 fallback이 자동으로 처리합니다.\n */\n\nimport {\n // Navigation\n Home,\n ArrowLeft,\n ArrowRight,\n ArrowUp,\n ArrowDown,\n Menu,\n X,\n Search,\n Settings,\n ExternalLink,\n ChevronLeft,\n ChevronRight,\n ChevronDown,\n ChevronUp,\n \n // Actions\n Edit,\n Trash2,\n Plus,\n Minus,\n Download,\n Upload,\n RefreshCw,\n Save,\n Copy,\n \n // Status & Feedback\n Loader2,\n CheckCircle,\n XCircle,\n AlertCircle,\n Info,\n Check,\n Circle,\n HelpCircle,\n \n // User & Auth\n User,\n Users,\n UserPlus,\n LogIn,\n LogOut,\n Eye,\n EyeOff,\n \n // Data & Analytics\n BarChart3,\n TrendingUp,\n Activity,\n Database,\n Zap,\n \n // Files & Content\n FileText,\n File,\n Folder,\n Book,\n BookOpen,\n \n // Communication\n Mail,\n MessageCircle,\n Phone,\n \n // Media\n Image,\n Video,\n Camera,\n \n // Emotions\n Smile,\n Frown,\n Meh,\n \n // Security\n Lock,\n Unlock,\n Shield,\n Wallet,\n Key,\n \n // Time & Date\n Clock,\n Calendar,\n CalendarPlus,\n \n // UI Elements\n Bell,\n Heart,\n Star,\n Bookmark,\n Share,\n \n // Theme\n Monitor,\n Sun,\n Moon,\n \n // Additional\n Lightbulb,\n Brain,\n Flag,\n Square,\n} from 'lucide-react'\n\n// 핵심 아이콘 객체\nexport const icons = {\n // Navigation\n home: Home,\n arrowLeft: ArrowLeft,\n arrowRight: ArrowRight,\n arrowUp: ArrowUp,\n arrowDown: ArrowDown,\n menu: Menu,\n close: X,\n search: Search,\n settings: Settings,\n externalLink: ExternalLink,\n chevronLeft: ChevronLeft,\n chevronRight: ChevronRight,\n chevronDown: ChevronDown,\n chevronUp: ChevronUp,\n \n // Actions\n edit: Edit,\n delete: Trash2,\n add: Plus,\n remove: Minus,\n download: Download,\n upload: Upload,\n refresh: RefreshCw,\n save: Save,\n copy: Copy,\n \n // Status & Feedback\n loader: Loader2,\n success: CheckCircle,\n error: XCircle,\n alertCircle: AlertCircle,\n warning: AlertCircle, // warning은 alertCircle과 동일\n info: Info,\n check: Check,\n circle: Circle,\n helpCircle: HelpCircle,\n \n // User & Auth\n user: User,\n users: Users,\n userPlus: UserPlus,\n logIn: LogIn,\n logOut: LogOut,\n eye: Eye,\n eyeOff: EyeOff,\n \n // Data & Analytics\n chart: BarChart3,\n barChart: BarChart3,\n trendingUp: TrendingUp,\n activity: Activity,\n database: Database,\n zap: Zap,\n \n // Files & Content\n fileText: FileText,\n file: File,\n folder: Folder,\n book: Book,\n bookOpen: BookOpen,\n \n // Communication\n mail: Mail,\n message: MessageCircle,\n phone: Phone,\n \n // Media\n image: Image,\n video: Video,\n camera: Camera,\n \n // Emotions\n smile: Smile,\n frown: Frown,\n meh: Meh,\n \n // Security\n lock: Lock,\n unlock: Unlock,\n shield: Shield,\n wallet: Wallet,\n key: Key,\n \n // Time & Date\n clock: Clock,\n calendar: Calendar,\n calendarPlus: CalendarPlus,\n \n // UI Elements\n bell: Bell,\n heart: Heart,\n star: Star,\n bookmark: Bookmark,\n share: Share,\n \n // Theme\n monitor: Monitor,\n sun: Sun,\n moon: Moon,\n \n // Additional\n lightbulb: Lightbulb,\n brain: Brain,\n flag: Flag,\n square: Square,\n} as const\n\n// 아이콘 이름 타입\nexport type IconName = keyof typeof icons\n\n// 감정별 아이콘 매핑\nexport const emotionIcons = {\n happy: 'smile',\n sad: 'frown',\n neutral: 'meh',\n excited: 'smile', // laugh 대신 smile 사용\n angry: 'frown', // angry 대신 frown 사용\n love: 'heart',\n like: 'heart', // thumbsUp 대신 heart 사용\n dislike: 'frown', // thumbsDown 대신 frown 사용\n} as const\n\n// 상태별 아이콘 매핑\nexport const statusIcons = {\n loading: 'loader',\n success: 'success',\n error: 'error',\n warning: 'warning',\n info: 'info',\n locked: 'lock',\n unlocked: 'unlock',\n visible: 'eye',\n hidden: 'eyeOff',\n} as const\n\n// 아이콘 카테고리별 그룹화 (참고용)\nexport const iconCategories = {\n navigation: ['home', 'arrowLeft', 'arrowRight', 'arrowUp', 'arrowDown', 'menu', 'close', 'search', 'settings', 'externalLink', 'chevronLeft', 'chevronRight', 'chevronDown', 'chevronUp'],\n actions: ['edit', 'delete', 'add', 'remove', 'download', 'upload', 'refresh', 'save', 'copy'],\n status: ['loader', 'success', 'error', 'alertCircle', 'warning', 'info', 'check', 'circle'],\n user: ['user', 'users', 'userPlus', 'logIn', 'logOut', 'eye', 'eyeOff'],\n data: ['chart', 'barChart', 'trendingUp', 'activity', 'database', 'zap'],\n files: ['fileText', 'file', 'folder', 'book'],\n communication: ['mail', 'message', 'phone'],\n media: ['image', 'video', 'camera'],\n emotions: ['smile', 'frown', 'meh'],\n security: ['lock', 'unlock', 'shield'],\n time: ['clock', 'calendar'],\n ui: ['bell', 'heart', 'star', 'bookmark', 'share'],\n theme: ['monitor', 'sun', 'moon'],\n} as const\n","/**\n * Icon Provider System\n * \n * Supports multiple icon libraries:\n * - Lucide Icons (default)\n * - Phosphor Icons\n * - Untitled Icons (SVG-based)\n * \n * Only imports icons that are actually used in the project for optimal bundle size.\n */\n\nimport * as LucideIcons from 'lucide-react'\nimport type { LucideIcon } from 'lucide-react'\n\n// Phosphor Icons - lazy loaded, tree-shakeable\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nlet PhosphorIcons: any = null\n\n// Icon Provider Type\nexport type IconProvider = 'lucide' | 'phosphor' | 'untitled'\n\n// Icon Provider Configuration\nexport interface IconProviderConfig {\n provider: IconProvider\n prefix?: string\n}\n\n/**\n * Project-specific icon list\n * These are the icons actually used in SumUp project\n * Only these icons will be loaded for optimal bundle size\n */\nexport const PROJECT_ICONS = {\n // Navigation & Layout\n 'home': { lucide: 'Home', phosphor: 'House', untitled: 'home' },\n 'layout-dashboard': { lucide: 'LayoutDashboard', phosphor: 'SquaresFour', untitled: 'layout-dashboard' },\n 'folder': { lucide: 'Folder', phosphor: 'Folder', untitled: 'folder' },\n 'alert-circle': { lucide: 'AlertCircle', phosphor: 'WarningCircle', untitled: 'alert-circle' },\n 'alertCircle': { lucide: 'AlertCircle', phosphor: 'WarningCircle', untitled: 'alert-circle' },\n 'columns': { lucide: 'Columns', phosphor: 'Columns', untitled: 'columns' },\n 'users': { lucide: 'Users', phosphor: 'Users', untitled: 'users' },\n 'settings': { lucide: 'Settings', phosphor: 'Gear', untitled: 'settings' },\n 'menu': { lucide: 'Menu', phosphor: 'List', untitled: 'menu' },\n 'close': { lucide: 'X', phosphor: 'X', untitled: 'close' },\n 'chevronLeft': { lucide: 'ChevronLeft', phosphor: 'CaretLeft', untitled: 'chevron-left' },\n 'chevronRight': { lucide: 'ChevronRight', phosphor: 'CaretRight', untitled: 'chevron-right' },\n 'chevronDown': { lucide: 'ChevronDown', phosphor: 'CaretDown', untitled: 'chevron-down' },\n 'chevronUp': { lucide: 'ChevronUp', phosphor: 'CaretUp', untitled: 'chevron-up' },\n 'arrowLeft': { lucide: 'ArrowLeft', phosphor: 'ArrowLeft', untitled: 'arrow-left' },\n 'arrowRight': { lucide: 'ArrowRight', phosphor: 'ArrowRight', untitled: 'arrow-right' },\n 'arrowUp': { lucide: 'ArrowUp', phosphor: 'ArrowUp', untitled: 'arrow-up' },\n 'arrowDown': { lucide: 'ArrowDown', phosphor: 'ArrowDown', untitled: 'arrow-down' },\n\n // Actions\n 'add': { lucide: 'Plus', phosphor: 'Plus', untitled: 'add' },\n 'edit': { lucide: 'Edit', phosphor: 'Pencil', untitled: 'edit' },\n 'pencil': { lucide: 'Pencil', phosphor: 'Pencil', untitled: 'pencil' },\n 'delete': { lucide: 'Trash2', phosphor: 'Trash', untitled: 'trash' },\n 'trash': { lucide: 'Trash2', phosphor: 'Trash', untitled: 'trash' },\n 'upload': { lucide: 'Upload', phosphor: 'Upload', untitled: 'upload' },\n 'download': { lucide: 'Download', phosphor: 'Download', untitled: 'download' },\n 'x': { lucide: 'X', phosphor: 'X', untitled: 'close' },\n 'check': { lucide: 'Check', phosphor: 'Check', untitled: 'check' },\n 'search': { lucide: 'Search', phosphor: 'MagnifyingGlass', untitled: 'search' },\n 'share': { lucide: 'Share', phosphor: 'Share', untitled: 'share' },\n 'copy': { lucide: 'Copy', phosphor: 'Copy', untitled: 'copy' },\n 'save': { lucide: 'Save', phosphor: 'FloppyDisk', untitled: 'save' },\n\n // Status & Feedback\n 'loader': { lucide: 'Loader2', phosphor: 'Spinner', untitled: 'loader' },\n 'loader2': { lucide: 'Loader2', phosphor: 'Spinner', untitled: 'loader' },\n 'check-circle': { lucide: 'CheckCircle', phosphor: 'CheckCircle', untitled: 'check-circle' },\n 'checkCircle': { lucide: 'CheckCircle', phosphor: 'CheckCircle', untitled: 'check-circle' },\n 'success': { lucide: 'CheckCircle', phosphor: 'CheckCircle', untitled: 'check-circle' },\n 'error': { lucide: 'XCircle', phosphor: 'XCircle', untitled: 'error' },\n 'warning': { lucide: 'AlertCircle', phosphor: 'WarningCircle', untitled: 'warning' },\n 'info': { lucide: 'Info', phosphor: 'Info', untitled: 'info' },\n 'refresh': { lucide: 'RefreshCw', phosphor: 'ArrowClockwise', untitled: 'refresh' },\n 'refreshCw': { lucide: 'RefreshCw', phosphor: 'ArrowClockwise', untitled: 'refresh' },\n 'bell': { lucide: 'Bell', phosphor: 'Bell', untitled: 'bell' },\n 'heart': { lucide: 'Heart', phosphor: 'Heart', untitled: 'heart' },\n 'star': { lucide: 'Star', phosphor: 'Star', untitled: 'star' },\n 'bookmark': { lucide: 'Bookmark', phosphor: 'Bookmark', untitled: 'bookmark' },\n\n // User & Auth\n 'user': { lucide: 'User', phosphor: 'User', untitled: 'user' },\n 'userPlus': { lucide: 'UserPlus', phosphor: 'UserPlus', untitled: 'user-plus' },\n 'logIn': { lucide: 'LogIn', phosphor: 'SignIn', untitled: 'log-in' },\n 'logOut': { lucide: 'LogOut', phosphor: 'SignOut', untitled: 'log-out' },\n 'chrome': { lucide: 'Chrome', phosphor: 'ChromeLogo', untitled: 'chrome' },\n 'github': { lucide: 'Github', phosphor: 'GithubLogo', untitled: 'github' },\n 'message': { lucide: 'MessageCircle', phosphor: 'ChatCircle', untitled: 'message' },\n\n // Content\n 'messageSquare': { lucide: 'MessageSquare', phosphor: 'ChatSquare', untitled: 'message-square' },\n 'message-square': { lucide: 'MessageSquare', phosphor: 'ChatSquare', untitled: 'message-square' },\n 'inbox': { lucide: 'Inbox', phosphor: 'Inbox', untitled: 'inbox' },\n 'calendar': { lucide: 'Calendar', phosphor: 'Calendar', untitled: 'calendar' },\n 'calendarPlus': { lucide: 'CalendarPlus', phosphor: 'CalendarPlus', untitled: 'calendar-plus' },\n 'checkSquare': { lucide: 'CheckSquare', phosphor: 'CheckSquare', untitled: 'check-square' },\n 'clock': { lucide: 'Clock', phosphor: 'Clock', untitled: 'clock' },\n 'book': { lucide: 'Book', phosphor: 'Book', untitled: 'book' },\n 'bookOpen': { lucide: 'BookOpen', phosphor: 'BookOpen', untitled: 'book-open' },\n\n // Theme & UI\n 'monitor': { lucide: 'Monitor', phosphor: 'Monitor', untitled: 'monitor' },\n 'sun': { lucide: 'Sun', phosphor: 'Sun', untitled: 'sun' },\n 'moon': { lucide: 'Moon', phosphor: 'Moon', untitled: 'moon' },\n\n // AI & Features\n 'sparkles': { lucide: 'Sparkles', phosphor: 'Sparkle', untitled: 'sparkles' },\n 'lightbulb': { lucide: 'Lightbulb', phosphor: 'Lightbulb', untitled: 'lightbulb' },\n 'brain': { lucide: 'Brain', phosphor: 'Brain', untitled: 'brain' },\n 'zap': { lucide: 'Zap', phosphor: 'Lightning', untitled: 'zap' },\n\n // Data & Analytics\n 'chart': { lucide: 'BarChart3', phosphor: 'ChartBar', untitled: 'chart' },\n 'barChart': { lucide: 'BarChart', phosphor: 'ChartBar', untitled: 'bar-chart' },\n 'trendingUp': { lucide: 'TrendingUp', phosphor: 'TrendUp', untitled: 'trending-up' },\n 'trendingDown': { lucide: 'TrendingDown', phosphor: 'TrendDown', untitled: 'trending-down' },\n 'activity': { lucide: 'Activity', phosphor: 'Activity', untitled: 'activity' },\n 'database': { lucide: 'Database', phosphor: 'Database', untitled: 'database' },\n 'dollarSign': { lucide: 'DollarSign', phosphor: 'CurrencyDollar', untitled: 'dollar-sign' },\n 'dollar': { lucide: 'DollarSign', phosphor: 'CurrencyDollar', untitled: 'dollar-sign' },\n 'currency': { lucide: 'DollarSign', phosphor: 'CurrencyDollar', untitled: 'currency' },\n\n // Security\n 'lock': { lucide: 'Lock', phosphor: 'Lock', untitled: 'lock' },\n 'unlock': { lucide: 'Unlock', phosphor: 'LockOpen', untitled: 'unlock' },\n 'shield': { lucide: 'Shield', phosphor: 'Shield', untitled: 'shield' },\n 'key': { lucide: 'Key', phosphor: 'Key', untitled: 'key' },\n\n // Media\n 'play': { lucide: 'Play', phosphor: 'Play', untitled: 'play' },\n 'pause': { lucide: 'Pause', phosphor: 'Pause', untitled: 'pause' },\n 'image': { lucide: 'Image', phosphor: 'Image', untitled: 'image' },\n 'video': { lucide: 'Video', phosphor: 'Video', untitled: 'video' },\n 'camera': { lucide: 'Camera', phosphor: 'Camera', untitled: 'camera' },\n\n // Files\n 'fileText': { lucide: 'FileText', phosphor: 'FileText', untitled: 'file-text' },\n 'file': { lucide: 'File', phosphor: 'File', untitled: 'file' },\n\n // Navigation\n 'externalLink': { lucide: 'ExternalLink', phosphor: 'ArrowSquareOut', untitled: 'external-link' },\n 'link': { lucide: 'Link', phosphor: 'Link', untitled: 'link' },\n 'moreHorizontal': { lucide: 'MoreHorizontal', phosphor: 'DotsThreeOutline', untitled: 'more-horizontal' },\n 'moreVertical': { lucide: 'MoreVertical', phosphor: 'DotsThreeVertical', untitled: 'more-vertical' },\n\n // Priority\n 'remove': { lucide: 'Minus', phosphor: 'Minus', untitled: 'remove' },\n\n // Eye (password)\n 'eye': { lucide: 'Eye', phosphor: 'Eye', untitled: 'eye' },\n 'eyeOff': { lucide: 'EyeOff', phosphor: 'EyeSlash', untitled: 'eye-off' },\n\n // Emotions\n 'smile': { lucide: 'Smile', phosphor: 'Smiley', untitled: 'smile' },\n 'frown': { lucide: 'Frown', phosphor: 'SmileySad', untitled: 'frown' },\n 'meh': { lucide: 'Meh', phosphor: 'SmileyMeh', untitled: 'meh' },\n\n // Social\n 'mail': { lucide: 'Mail', phosphor: 'Envelope', untitled: 'mail' },\n 'phone': { lucide: 'Phone', phosphor: 'Phone', untitled: 'phone' },\n\n // Additional\n 'flag': { lucide: 'Flag', phosphor: 'Flag', untitled: 'flag' },\n} as const\n\n/**\n * Initialize Phosphor Icons (lazy load)\n * Only loads when Phosphor provider is used\n * Uses tree-shaking to only include used icons\n */\nexport async function initPhosphorIcons() {\n if (typeof window === 'undefined') return null\n\n if (!PhosphorIcons) {\n try {\n // Dynamic import with tree-shaking support\n // Only icons actually used will be included in bundle\n const phosphorModule = await import('@phosphor-icons/react')\n PhosphorIcons = phosphorModule\n } catch (error) {\n console.warn('Phosphor Icons not available. Install @phosphor-icons/react to use.')\n return null\n }\n }\n return PhosphorIcons\n}\n\n/**\n * Get icon from provider\n * Only resolves icons that are in PROJECT_ICONS for optimal bundle size\n * \n * @param iconName - 아이콘 이름 / Icon name\n * @param provider - 아이콘 프로바이더 / Icon provider\n * @returns 아이콘 컴포넌트 또는 null / Icon component or null\n */\nexport function getIconFromProvider(\n iconName: string,\n provider: IconProvider | 'lucide' | 'phosphor' | 'untitled' = 'lucide'\n): LucideIcon | React.ComponentType<Record<string, unknown>> | null {\n // Check if icon is in project icon list\n const iconMapping = PROJECT_ICONS[iconName as keyof typeof PROJECT_ICONS]\n\n if (!iconMapping) {\n // Fallback to direct lookup for backward compatibility\n return getIconDirect(iconName, provider)\n }\n\n const mappedName = iconMapping[provider]\n\n switch (provider) {\n case 'lucide':\n return (LucideIcons as unknown as Record<string, LucideIcon>)[mappedName] || null\n\n case 'phosphor':\n if (!PhosphorIcons) {\n return null\n }\n return PhosphorIcons?.[mappedName] || null\n\n case 'untitled':\n // Untitled Icons are SVG-based, handled separately\n return null\n\n default:\n return null\n }\n}\n\n/**\n * Direct icon lookup (fallback for icons not in PROJECT_ICONS)\n * \n * 동적으로 Lucide 아이콘을 가져옵니다.\n * icons.ts에 없는 아이콘도 사용 가능하도록 합니다.\n * \n * Dynamically loads Lucide icons.\n * Allows using icons not in icons.ts.\n * \n * @param iconName - 아이콘 이름 / Icon name\n * @param provider - 아이콘 프로바이더 / Icon provider\n * @returns 아이콘 컴포넌트 또는 null / Icon component or null\n */\nfunction getIconDirect(\n iconName: string,\n provider: IconProvider | 'lucide' | 'phosphor' | 'untitled'\n): LucideIcon | React.ComponentType<Record<string, unknown>> | null {\n switch (provider) {\n case 'lucide':\n // icons.ts에 없는 아이콘을 동적으로 찾기\n // PascalCase 변환 시도\n const lucideName = iconName.charAt(0).toUpperCase() + iconName.slice(1)\n // camelCase도 시도\n const camelCaseName = iconName.replace(/([A-Z])/g, (match, p1) =>\n match === iconName[0] ? match.toLowerCase() : match\n )\n\n return (LucideIcons as unknown as Record<string, LucideIcon>)[lucideName] ||\n (LucideIcons as unknown as Record<string, LucideIcon>)[iconName] ||\n (LucideIcons as unknown as Record<string, LucideIcon>)[camelCaseName] ||\n null\n\n case 'phosphor':\n if (!PhosphorIcons) {\n return null\n }\n const phosphorName1 = iconName.charAt(0).toUpperCase() + iconName.slice(1)\n const phosphorName2 = iconName\n .split(/(?=[A-Z])/)\n .map(word => word.charAt(0).toUpperCase() + word.slice(1))\n .join('')\n return PhosphorIcons?.[phosphorName1] ||\n PhosphorIcons?.[phosphorName2] ||\n PhosphorIcons?.[iconName] ||\n null\n\n case 'untitled':\n return null\n\n default:\n return null\n }\n}\n\n/**\n * Get icon name for provider\n * \n * 프로바이더별 아이콘 이름을 가져옵니다.\n * Gets icon name for the specified provider.\n * \n * @param iconName - 아이콘 이름 / Icon name\n * @param provider - 아이콘 프로바이더 / Icon provider\n * @returns 프로바이더별 아이콘 이름 / Icon name for provider\n */\nexport function getIconNameForProvider(\n iconName: string,\n provider: IconProvider | 'lucide' | 'phosphor' | 'untitled'\n): string {\n const iconMapping = PROJECT_ICONS[iconName as keyof typeof PROJECT_ICONS]\n if (iconMapping && iconMapping[provider]) {\n return iconMapping[provider]\n }\n return iconName\n}\n\n/**\n * Get all project icon names\n */\nexport function getProjectIconNames(): string[] {\n return Object.keys(PROJECT_ICONS)\n}\n","/**\n * Icon Aliases\n * \n * 여러 이름이 같은 아이콘을 가리키도록 하는 alias 시스템\n * DX 향상을 위해 직관적인 이름들을 지원합니다.\n */\n\nexport const ICON_ALIASES: Record<string, string> = {\n // Navigation aliases\n 'back': 'arrowLeft',\n 'prev': 'arrowLeft',\n 'previous': 'arrowLeft',\n 'forward': 'arrowRight',\n 'next': 'arrowRight',\n \n // Close aliases\n 'close': 'x',\n 'cancel': 'x',\n \n // Delete aliases\n 'remove': 'delete',\n 'trash': 'delete',\n \n // Add aliases\n 'plus': 'add',\n 'new': 'add',\n \n // Edit aliases\n 'pencil': 'edit',\n 'modify': 'edit',\n \n // Save aliases\n 'store': 'save',\n 'floppy': 'save',\n \n // Search aliases\n 'magnify': 'search',\n \n // User aliases\n 'person': 'user',\n 'account': 'user',\n 'profile': 'user',\n \n // Settings aliases\n 'gear': 'settings',\n 'config': 'settings',\n 'preferences': 'settings',\n \n // Home aliases\n 'house': 'home',\n 'main': 'home',\n \n // Check aliases\n 'done': 'check',\n 'complete': 'check',\n 'tick': 'check',\n \n // Info aliases\n 'information': 'info',\n 'help': 'info',\n \n // Warning aliases\n 'alert': 'warning',\n 'caution': 'warning',\n \n // Success aliases\n 'checkmark': 'success',\n 'checkCircle': 'success',\n \n // Error aliases\n 'fail': 'error',\n 'cross': 'error',\n 'xCircle': 'error',\n \n // Loading aliases\n 'spinner': 'loader',\n 'loading': 'loader',\n 'wait': 'loader',\n \n // Refresh aliases\n 'reload': 'refresh',\n 'update': 'refresh',\n 'sync': 'refresh',\n \n // Eye aliases\n 'show': 'eye',\n 'view': 'eye',\n 'hide': 'eyeOff',\n 'hidden': 'eyeOff',\n \n // Lock aliases\n 'secure': 'lock',\n 'locked': 'lock',\n 'unsecure': 'unlock',\n 'unlocked': 'unlock',\n \n // Download aliases\n 'get': 'download',\n 'fetch': 'download',\n \n // Upload aliases\n 'post': 'upload',\n \n // Share aliases\n 'send': 'share',\n 'export': 'share',\n \n // Copy aliases\n 'duplicate': 'copy',\n 'clone': 'copy',\n \n // Mail aliases\n 'email': 'mail',\n 'envelope': 'mail',\n \n // Message aliases\n 'chat': 'message',\n 'comment': 'message',\n 'talk': 'message',\n \n // Calendar aliases\n 'date': 'calendar',\n 'schedule': 'calendar',\n \n // Clock aliases\n 'time': 'clock',\n 'watch': 'clock',\n \n // File aliases\n 'document': 'fileText',\n 'doc': 'fileText',\n 'text': 'fileText',\n \n // Folder aliases\n 'directory': 'folder',\n 'dir': 'folder',\n \n // Image aliases\n 'picture': 'image',\n 'img': 'image',\n \n // Video aliases\n 'movie': 'video',\n 'film': 'video',\n \n // Camera aliases\n 'photo': 'camera',\n 'capture': 'camera',\n \n // Play aliases\n 'start': 'play',\n 'run': 'play',\n \n // Pause aliases\n 'stop': 'pause',\n 'halt': 'pause',\n \n // Heart aliases\n 'like': 'heart',\n 'love': 'heart',\n \n // Star aliases\n 'favorite': 'star',\n \n // Bookmark aliases\n 'saveBookmark': 'bookmark',\n \n // Bell aliases\n 'notification': 'bell',\n 'notify': 'bell',\n 'alarm': 'bell',\n \n // Settings aliases\n 'prefs': 'settings',\n \n // Search aliases (duplicate removed - see line 37)\n 'lookup': 'search',\n \n // More aliases\n 'dots': 'moreHorizontal',\n 'moreMenu': 'moreHorizontal',\n 'moreOptions': 'moreVertical',\n \n // External link aliases\n 'external': 'externalLink',\n 'outbound': 'externalLink',\n 'open': 'externalLink',\n \n // Link aliases\n 'url': 'link',\n 'hyperlink': 'link',\n \n // Chart aliases\n 'graph': 'barChart',\n 'stats': 'barChart',\n 'analytics': 'barChart',\n \n // Database aliases\n 'db': 'database',\n 'storage': 'database',\n \n // Activity aliases\n 'pulse': 'activity',\n 'monitor': 'activity',\n \n // Trending aliases\n 'up': 'trendingUp',\n 'down': 'trendingDown',\n \n // Zap aliases\n 'lightning': 'zap',\n 'bolt': 'zap',\n 'flash': 'zap',\n \n // Shield aliases\n 'security': 'shield',\n 'protect': 'shield',\n \n // Key aliases\n 'password': 'key',\n 'secret': 'key',\n \n // Log in aliases\n 'signin': 'logIn',\n 'login': 'logIn',\n 'enter': 'logIn',\n \n // Log out aliases\n 'signout': 'logOut',\n 'logout': 'logOut',\n 'exit': 'logOut',\n \n // Users aliases\n 'people': 'users',\n 'group': 'users',\n 'team': 'users',\n \n // User plus aliases\n 'addUser': 'userPlus',\n 'invite': 'userPlus',\n \n // Book aliases\n 'read': 'book',\n 'library': 'book',\n \n // Book open aliases\n 'reading': 'bookOpen',\n 'openBook': 'bookOpen',\n \n // Sun aliases\n 'light': 'sun',\n 'day': 'sun',\n \n // Moon aliases\n 'dark': 'moon',\n 'night': 'moon',\n \n // Monitor aliases\n 'screen': 'monitor',\n 'display': 'monitor',\n \n // Brain aliases\n 'ai': 'brain',\n 'intelligence': 'brain',\n 'think': 'brain',\n \n // Lightbulb aliases\n 'idea': 'lightbulb',\n 'bulb': 'lightbulb',\n 'inspiration': 'lightbulb',\n \n // Sparkles aliases\n 'magic': 'sparkles',\n 'stars': 'sparkles',\n 'glitter': 'sparkles',\n} as const\n\n/**\n * Resolve icon alias to actual icon name\n * \n * @param iconName - 아이콘 이름 또는 별칭 / Icon name or alias\n * @returns 실제 아이콘 이름 / Actual icon name\n * @throws {TypeError} iconName이 문자열이 아닌 경우\n */\nexport function resolveIconAlias(iconName: string): string {\n if (typeof iconName !== 'string') {\n throw new TypeError('iconName must be a string');\n }\n return ICON_ALIASES[iconName] || iconName;\n}\n\n/**\n * Get all aliases for an icon name\n * \n * @param iconName - 아이콘 이름 / Icon name\n * @returns 해당 아이콘의 모든 별칭 배열 / Array of all aliases for the icon\n * @throws {TypeError} iconName이 문자열이 아닌 경우\n */\nexport function getIconAliases(iconName: string): string[] {\n if (typeof iconName !== 'string') {\n throw new TypeError('iconName must be a string');\n }\n return Object.entries(ICON_ALIASES)\n .filter(([_, target]) => target === iconName)\n .map(([alias]) => alias);\n}\n\n\n","/**\n * Icon Config Types\n * \n * Icon 시스템의 설정 타입 정의\n * 상태관리는 서비스 레벨에서 관리 (Zustand 등)\n */\n\nexport type IconSet = 'lucide' | 'phosphor' | 'untitled'\n\nexport type PhosphorWeight = 'thin' | 'light' | 'regular' | 'bold' | 'duotone' | 'fill'\n\nexport interface IconConfig {\n set: IconSet\n weight: PhosphorWeight\n size: number\n color: string\n strokeWidth?: number // Lucide/Untitled용\n}\n\nexport const defaultIconConfig: IconConfig = {\n set: 'phosphor',\n weight: 'regular',\n size: 20,\n color: 'currentColor',\n strokeWidth: 1.25,\n}\n\n/**\n * 세트별 기본 strokeWidth\n */\nexport const getDefaultStrokeWidth = (set: IconSet): number => {\n switch (set) {\n case 'lucide':\n return 1.25\n case 'phosphor':\n return 1.25 // Phosphor는 weight 사용\n case 'untitled':\n return 1.5\n default:\n return 1.25\n }\n}\n","'use client'\n\n/**\n * IconProvider - Icon 시스템 전역 설정 Provider\n * \n * React Context를 사용하여 전역 아이콘 설정을 제공합니다.\n * 서비스 레벨에서 Zustand 등으로 상태관리 후 props로 전달 가능합니다.\n * \n * IconProvider - Global Icon Settings Provider\n * \n * Provides global icon settings using React Context API.\n * Can be integrated with state management (e.g., Zustand) at the service level.\n */\n\nimport React, { createContext, useContext } from 'react'\nimport { type IconConfig, type IconSet, type PhosphorWeight, defaultIconConfig } from './icon-store'\n\n/**\n * IconProvider 컴포넌트 Props\n * \n * IconProvider component props interface.\n * \n * @interface IconProviderProps\n */\nexport interface IconProviderProps {\n /** 아이콘 세트 (lucide, phosphor, untitled) / Icon set (lucide, phosphor, untitled) */\n set?: IconSet\n /** Phosphor 아이콘 weight (thin, light, regular, bold, duotone, fill) / Phosphor icon weight */\n weight?: PhosphorWeight\n /** 기본 아이콘 크기 / Default icon size */\n size?: number\n /** 기본 아이콘 색상 / Default icon color */\n color?: string\n /** Lucide/Untitled 아이콘 stroke width / Lucide/Untitled icon stroke width */\n strokeWidth?: number\n /** 자식 컴포넌트 / Child components */\n children: React.ReactNode\n}\n\ninterface IconContextValue extends IconConfig {}\n\nconst IconContext = createContext<IconContextValue>(defaultIconConfig)\n\n/**\n * IconProvider 컴포넌트\n * \n * 전역 아이콘 설정을 Context로 제공합니다.\n * 서비스에서 Zustand로 관리한 값을 props로 전달할 수 있습니다.\n * \n * IconProvider component\n * \n * Provides global icon settings through Context API.\n * Can receive values managed by Zustand at the service level.\n * \n * @component\n * @example\n * ```tsx\n * // 기본 사용 / Basic usage\n * <IconProvider set=\"phosphor\" weight=\"regular\" size={20}>\n * <App />\n * </IconProvider>\n * \n * // Zustand와 함께 사용 / With Zustand\n * const iconConfig = useIconStore(state => state.iconConfig)\n * <IconProvider {...iconConfig}>\n * <App />\n * </IconProvider>\n * \n * // Lucide 아이콘 사용 / Using Lucide icons\n * <IconProvider set=\"lucide\" size={24} strokeWidth={1.5}>\n * <App />\n * </IconProvider>\n * ```\n * \n * @param props - IconProvider 컴포넌트 props / IconProvider component props\n * @returns IconProvider 컴포넌트 / IconProvider component\n */\nexport function IconProvider({\n set = defaultIconConfig.set,\n weight = defaultIconConfig.weight,\n size = defaultIconConfig.size,\n color = defaultIconConfig.color,\n strokeWidth = defaultIconConfig.strokeWidth,\n children,\n}: IconProviderProps) {\n const value: IconContextValue = {\n set,\n weight,\n size,\n color,\n strokeWidth,\n }\n\n return (\n <IconContext.Provider value={value}>\n {children}\n </IconContext.Provider>\n )\n}\n\n/**\n * useIconContext Hook\n * \n * Icon Context를 사용하는 Hook입니다.\n * Icon 컴포넌트 내부에서 사용됩니다.\n * \n * Hook to use Icon Context.\n * Used internally by Icon component.\n * \n * @returns Icon 설정 값 / Icon configuration value\n * \n * @example\n * ```tsx\n * // Icon 컴포넌트 내부에서 사용 / Used inside Icon component\n * const config = useIconContext()\n * const iconSet = config.set\n * const iconSize = config.size\n * ```\n */\nexport function useIconContext(): IconContextValue {\n return useContext(IconContext)\n}\n\n// Re-export types for convenience\nexport type { IconSet, PhosphorWeight, IconConfig } from './icon-store'\nexport { defaultIconConfig, getDefaultStrokeWidth } from './icon-store'\n\n","import React from 'react'\nimport type { LucideProps } from 'lucide-react'\nimport { merge, mergeMap } from '../../lib/utils'\nimport { icons, IconName, emotionIcons, statusIcons } from '../../lib/icons'\nimport { getIconFromProvider, initPhosphorIcons } from '../../lib/icon-providers'\nimport { resolveIconAlias } from '../../lib/icon-aliases'\nimport { useIconContext, type IconSet } from './IconProvider'\nimport { type PhosphorWeight } from './icon-store'\nimport type { AllIconName } from '../../lib/icon-names'\n\n/**\n * Icon 컴포넌트 Props\n * \n * Icon component props interface.\n * \n * @interface IconProps\n */\nexport interface IconProps {\n /** 아이콘 이름 / Icon name */\n name: AllIconName\n /** 아이콘 크기 (숫자 또는 문자열) / Icon size (number or string) */\n size?: number | string\n /** 추가 CSS 클래스 / Additional CSS classes */\n className?: string\n /** 감정 아이콘 타입 / Emotion icon type */\n emotion?: keyof typeof emotionIcons\n /** 상태 아이콘 타입 / Status icon type */\n status?: keyof typeof statusIcons\n /** 아이콘 프로바이더 오버라이드 (전역 설정 무시) / Icon provider override (ignores global config) */\n provider?: IconSet\n /** 부드러운 애니메이션 효과 / Smooth animation effect */\n animated?: boolean\n /** 펄스 애니메이션 / Pulse animation */\n pulse?: boolean\n /** 회전 애니메이션 / Spin animation */\n spin?: boolean\n /** 바운스 애니메이션 / Bounce animation */\n bounce?: boolean\n /** 색상 변형 / Color variant */\n variant?: 'default' | 'primary' | 'secondary' | 'success' | 'warning' | 'error' | 'muted'\n /** Phosphor 아이콘 weight 오버라이드 / Phosphor icon weight override */\n weight?: PhosphorWeight\n /** 스크린 리더용 라벨 (의미 있는 아이콘인 경우) / Screen reader label (for meaningful icons) */\n 'aria-label'?: string\n /** 장식용 아이콘인 경우 true (스크린 리더에서 숨김) / Set to true for decorative icons (hidden from screen readers) */\n 'aria-hidden'?: boolean\n}\n\n/**\n * Icon 컴포넌트\n * \n * 다중 아이콘 라이브러리(Lucide, Phosphor, Untitled)를 지원하는 통합 아이콘 컴포넌트입니다.\n * IconProvider를 통해 전역 설정을 관리할 수 있으며, 개별 아이콘에서도 설정을 오버라이드할 수 있습니다.\n * \n * Icon component that supports multiple icon libraries (Lucide, Phosphor, Untitled).\n * Global settings can be managed through IconProvider, and individual icons can override settings.\n * \n * @component\n * @example\n * ```tsx\n * // 기본 사용 / Basic usage\n * <Icon name=\"heart\" />\n * \n * // 크기 지정 / Specify size\n * <Icon name=\"user\" size={24} />\n * \n * // 색상 변형 / Color variant\n * <Icon name=\"check\" variant=\"success\" />\n * \n * // 애니메이션 / Animation\n * <Icon name=\"loader\" spin />\n * <Icon name=\"heart\" pulse />\n * \n * // 접근성 / Accessibility\n * <Icon name=\"search\" aria-label=\"검색\" />\n * <Icon name=\"decorative-icon\" aria-hidden />\n * \n * // 감정 아이콘 / Emotion icon\n * <Icon emotion=\"happy\" />\n * \n * // 상태 아이콘 / Status icon\n * <Icon status=\"loading\" spin />\n * ```\n * \n * @param props - Icon 컴포넌트 props / Icon component props\n * @returns Icon 컴포넌트 / Icon component\n */\nconst IconComponent = React.forwardRef<HTMLSpanElement, IconProps>(({\n name,\n size,\n className,\n emotion,\n status,\n provider,\n weight,\n animated = false,\n pulse = false,\n spin = false,\n bounce = false,\n variant = 'default',\n 'aria-label': ariaLabel,\n 'aria-hidden': ariaHidden\n}, ref) => {\n // Context에서 전역 설정 가져오기\n const config = useIconContext()\n \n // prop으로 오버라이드 가능, 없으면 Context에서 가져옴\n const iconSet = provider || config.set\n const iconSize = size ?? config.size\n const iconWeight = weight || config.weight\n const iconColor = config.color\n const iconStrokeWidth = config.strokeWidth ?? 1.25\n \n // 클라이언트 사이드에서만 아이콘 렌더링 (hydration 오류 방지)\n const [isClient, setIsClient] = React.useState(false)\n const [phosphorReady, setPhosphorReady] = React.useState(false)\n \n React.useEffect(() => {\n setIsClient(true)\n \n // Phosphor Icons 초기화 (provider가 phosphor일 때만)\n if (iconSet === 'phosphor') {\n initPhosphorIcons().then(() => {\n setPhosphorReady(true)\n })\n } else {\n setPhosphorReady(true)\n }\n }, [iconSet])\n\n // 감정이나 상태가 지정되면 해당 아이콘으로 오버라이드\n let iconName = emotion ? emotionIcons[emotion] : \n status ? statusIcons[status] : \n name\n \n // Alias 해결 (back, prev → arrowLeft 등)\n iconName = resolveIconAlias(iconName) as AllIconName\n \n // 색상 변형 클래스 (먼저 선언 - fallback에서 사용)\n const variantClasses = mergeMap({\n 'text-gray-900 dark:text-white': variant === 'default',\n 'text-blue-600 dark:text-blue-400': variant === 'primary',\n 'text-gray-600 dark:text-gray-400': variant === 'secondary',\n 'text-green-600 dark:text-green-400': variant === 'success',\n 'text-yellow-600 dark:text-yellow-400': variant === 'warning',\n 'text-red-600 dark:text-red-400': variant === 'error',\n 'text-gray-500 dark:text-gray-500': variant === 'muted',\n })\n \n // 서버사이드에서는 빈 span 반환 (hydration 오류 방지)\n // Return empty span on server-side (prevent hydration errors)\n if (!isClient || (iconSet === 'phosphor' && !phosphorReady)) {\n return (\n <span\n style={{ width: iconSize, height: iconSize }}\n className={merge(variantClasses, className)}\n aria-hidden={ariaHidden !== undefined ? ariaHidden : true}\n aria-label={ariaLabel}\n />\n )\n }\n\n // Provider에 따라 아이콘 가져오기\n type IconComponentType = React.ComponentType<LucideProps | React.SVGProps<SVGSVGElement> | Record<string, unknown>>\n let IconComponent: IconComponentType | null = null\n \n if (iconSet === 'lucide') {\n // 1. icons.ts에서 먼저 찾기 (실제 사용되는 아이콘만 포함)\n // 타입 단언: AllIconName에는 있지만 icons 객체에 없는 경우를 위해\n IconComponent = (icons[iconName as IconName] || null) as IconComponentType | null\n \n // 2. 없으면 동적으로 Lucide에서 가져오기 (fallback)\n if (!IconComponent) {\n IconComponent = getIconFromProvider(iconName, iconSet) as IconComponentType | null\n }\n } else {\n // Phosphor나 다른 provider는 getIconFromProvider 사용\n // phosphorReady가 true일 때만 호출됨 (위에서 체크)\n IconComponent = getIconFromProvider(iconName, iconSet) as IconComponentType | null\n }\n \n if (!IconComponent) {\n console.warn(`Icon \"${iconName}\" not found for provider \"${iconSet}\"`)\n // Fallback: 빈 원형 아이콘 표시 (에러 표시)\n // Fallback: display empty circle icon (error indicator)\n return (\n <span\n ref={ref}\n className={merge(\n 'inline-flex items-center justify-center rounded-full border-2 border-dashed border-gray-300 dark:border-gray-600',\n variantClasses,\n className\n )}\n style={{ width: iconSize, height: iconSize }}\n aria-label={ariaLabel || `아이콘을 찾을 수 없음: ${iconName}`}\n title={`Icon not found: ${iconName}`}\n >\n <span className=\"text-xs text-gray-400 dark:text-gray-500\" aria-hidden=\"true\">\n ?\n </span>\n </span>\n )\n }\n \n // 세트별 props 준비\n type IconPropsType = LucideProps & {\n size?: number\n width?: number | string\n height?: number | string\n color?: string\n weight?: PhosphorWeight\n strokeWidth?: number\n }\n \n const iconProps: IconPropsType = {\n size: typeof iconSize === 'number' ? iconSize : undefined,\n width: typeof iconSize === 'string' ? iconSize : iconSize,\n height: typeof iconSize === 'string' ? iconSize : iconSize,\n color: iconColor,\n } as IconPropsType\n \n // Phosphor는 weight 사용\n if (iconSet === 'phosphor') {\n iconProps.weight = iconWeight\n } else {\n // Lucide/Untitled는 strokeWidth 사용\n iconProps.strokeWidth = iconStrokeWidth\n }\n\n // 애니메이션 클래스 생성\n const animationClasses = mergeMap({\n 'animate-pulse': pulse,\n 'animate-spin': spin,\n 'animate-bounce': bounce,\n 'transition-all duration-200 ease-in-out': animated,\n })\n\n // 접근성 속성 결정 / Determine accessibility attributes\n // aria-label이 제공되면 사용, 없으면 aria-hidden이 true인지 확인\n // If aria-label is provided, use it; otherwise check if aria-hidden is true\n const accessibilityProps: React.AriaAttributes = {}\n \n if (ariaLabel) {\n accessibilityProps['aria-label'] = ariaLabel\n accessibilityProps['aria-hidden'] = false\n } else if (ariaHidden !== undefined) {\n accessibilityProps['aria-hidden'] = ariaHidden\n } else {\n // 기본값: 장식용으로 간주 (의미 있는 아이콘은 명시적으로 aria-label 제공 필요)\n // Default: considered decorative (meaningful icons should explicitly provide aria-label)\n accessibilityProps['aria-hidden'] = true\n }\n\n return (\n <span\n ref={ref}\n className={merge(\n 'inline-flex items-center justify-center',\n animationClasses,\n variantClasses,\n className\n )}\n style={{ width: iconSize, height: iconSize }}\n {...accessibilityProps}\n >\n {IconComponent && React.createElement(IconComponent, { \n ...iconProps,\n className: variantClasses,\n 'aria-hidden': true // SVG 내부 요소는 항상 숨김 (외부 span이 접근성 담당)\n } as React.ComponentProps<typeof IconComponent>)}\n </span>\n )\n})\n\nIconComponent.displayName = 'Icon'\n\n// 성능 최적화: React.memo 적용\n// Performance optimization: Apply React.memo\n// forwardRef와 함께 사용할 때는 React.memo로 감싸기\n// When using with forwardRef, wrap with React.memo\nconst MemoizedIcon = React.memo(IconComponent, (prevProps, nextProps) => {\n // props 비교 함수: 변경된 props만 체크\n // Props comparison function: only check changed props\n return (\n prevProps.name === nextProps.name &&\n prevProps.size === nextProps.size &&\n prevProps.className === nextProps.className &&\n prevProps.emotion === nextProps.emotion &&\n prevProps.status === nextProps.status &&\n prevProps.provider === nextProps.provider &&\n prevProps.animated === nextProps.animated &&\n prevProps.pulse === nextProps.pulse &&\n prevProps.spin === nextProps.spin &&\n prevProps.bounce === nextProps.bounce &&\n prevProps.variant === nextProps.variant &&\n prevProps.weight === nextProps.weight &&\n prevProps['aria-label'] === nextProps['aria-label'] &&\n prevProps['aria-hidden'] === nextProps['aria-hidden']\n )\n})\n\n// 타입 안전성을 위해 export\n// Export for type safety\nexport const Icon = MemoizedIcon as typeof IconComponent\n\nIcon.displayName = 'Icon'\n\n/**\n * EmotionIcon 컴포넌트\n * \n * 감정을 표현하는 아이콘 컴포넌트입니다.\n * Icon component for expressing emotions.\n * \n * @component\n * @example\n * ```tsx\n * <EmotionIcon emotion=\"happy\" />\n * <EmotionIcon emotion=\"sad\" size={24} />\n * ```\n */\nexport const EmotionIcon = React.forwardRef<HTMLSpanElement, Omit<IconProps, 'name'> & { emotion: keyof typeof emotionIcons }>(\n (props, ref) => <Icon ref={ref} name=\"smile\" {...props} />\n)\n\nEmotionIcon.displayName = 'EmotionIcon'\n\n/**\n * StatusIcon 컴포넌트\n * \n * 상태를 표현하는 아이콘 컴포넌트입니다.\n * Icon component for expressing status.\n * \n * @component\n * @example\n * ```tsx\n * <StatusIcon status=\"loading\" spin />\n * <StatusIcon status=\"success\" variant=\"success\" />\n * ```\n */\nexport const StatusIcon = React.forwardRef<HTMLSpanElement, Omit<IconProps, 'name'> & { status: keyof typeof statusIcons }>(\n (props, ref) => <Icon ref={ref} name=\"info\" {...props} />\n)\n\nStatusIcon.displayName = 'StatusIcon'\n\n/**\n * LoadingIcon 컴포넌트\n * \n * 로딩 상태를 표시하는 전용 아이콘 컴포넌트입니다.\n * Dedicated icon component for displaying loading status.\n * \n * @component\n * @example\n * ```tsx\n * <LoadingIcon />\n * <LoadingIcon size={32} />\n * ```\n */\nexport const LoadingIcon = React.forwardRef<HTMLDivElement, Omit<IconProps, 'name' | 'status'>>(\n (props, ref) => (\n <Icon ref={ref} name=\"loader\" status=\"loading\" spin aria-label=\"로딩 중\" {...props} />\n )\n)\n\nLoadingIcon.displayName = 'LoadingIcon'\n\n/**\n * SuccessIcon 컴포넌트\n * \n * 성공 상태를 표시하는 전용 아이콘 컴포넌트입니다.\n * Dedicated icon component for displaying success status.\n * \n * @component\n * @example\n * ```tsx\n * <SuccessIcon />\n * <SuccessIcon size={24} />\n * ```\n */\nexport const SuccessIcon = React.forwardRef<HTMLDivElement, Omit<IconProps, 'name' | 'status'>>(\n (props, ref) => (\n <Icon ref={ref} name=\"check\" status=\"success\" variant=\"success\" aria-label=\"성공\" {...props} />\n )\n)\n\nSuccessIcon.displayName = 'SuccessIcon'\n\n/**\n * ErrorIcon 컴포넌트\n * \n * 에러 상태를 표시하는 전용 아이콘 컴포넌트입니다.\n * Dedicated icon component for displaying error status.\n * \n * @component\n * @example\n * ```tsx\n * <ErrorIcon />\n * <ErrorIcon size={24} />\n * ```\n */\nexport const ErrorIcon = React.forwardRef<HTMLDivElement, Omit<IconProps, 'name' | 'status'>>(\n (props, ref) => (\n <Icon ref={ref} name=\"alertCircle\" status=\"error\" variant=\"error\" aria-label=\"오류\" {...props} />\n )\n)\n\nErrorIcon.displayName = 'ErrorIcon'\n\n","\"use client\"\n\nimport React from \"react\"\nimport { merge } from \"../lib/utils\"\nimport { Icon } from \"./Icon\"\n\n/**\n * PageNavigation 컴포넌트의 props / PageNavigation component props\n * @typedef {Object} PageNavigationProps\n * @property {Object} [prevPage] - 이전 페이지 정보 / Previous page information\n * @property {string} prevPage.title - 이전 페이지 제목 / Previous page title\n * @property {string} prevPage.href - 이전 페이지 링크 / Previous page link\n * @property {Object} [nextPage] - 다음 페이지 정보 / Next page information\n * @property {string} nextPage.title - 다음 페이지 제목 / Next page title\n * @property {string} nextPage.href - 다음 페이지 링크 / Next page link\n * @property {boolean} [showOnMobile=false] - 모바일에서 표시 여부 / Show on mobile\n * @extends {React.HTMLAttributes<HTMLDivElement>}\n */\nexport interface PageNavigationProps extends React.HTMLAttributes<HTMLDivElement> {\n prevPage?: {\n title: string\n href: string\n }\n nextPage?: {\n title: string\n href: string\n }\n showOnMobile?: boolean\n}\n\n/**\n * PageNavigation 컴포넌트 / PageNavigation component\n * \n * 이전/다음 페이지로 이동하는 네비게이션 컴포넌트입니다.\n * 문서 페이지나 가이드 페이지에서 사용하기 적합합니다.\n * \n * Navigation component for moving to previous/next pages.\n * Suitable for documentation or guide pages.\n * \n * @component\n * @example\n * // 기본 사용 / Basic usage\n * <PageNavigation\n * prevPage={{ title: \"이전 페이지\", href: \"/prev\" }}\n * nextPage={{ title: \"다음 페이지\", href: \"/next\" }}\n * />\n * \n * @param {PageNavigationProps} props - PageNavigation 컴포넌트의 props / PageNavigation component props\n * @param {React.Ref<HTMLDivElement>} ref - div 요소 ref / div element ref\n * @returns {JSX.Element} PageNavigation 컴포넌트 / PageNavigation component\n */\nconst PageNavigation = React.forwardRef<HTMLDivElement, PageNavigationProps>(\n ({ \n className, \n prevPage, \n nextPage, \n showOnMobile = false,\n ...props \n }, ref) => {\n if (!prevPage && !nextPage) {\n return null\n }\n\n return (\n <div\n ref={ref}\n className={merge(\n \"flex items-center justify-between py-4\",\n !showOnMobile && \"hidden md:flex\",\n className\n )}\n {...props}\n >\n {/* 이전 페이지 */}\n <div className=\"flex-1\">\n {prevPage && (\n <a\n href={prevPage.href}\n className=\"group inline-flex items-center text-sm text-slate-600 hover:text-slate-900 dark:text-slate-400 dark:hover:text-slate-100 transition-colors\"\n >\n <Icon \n name=\"chevronLeft\" \n className=\"w-4 h-4 mr-2 transition-transform group-hover:-translate-x-1\" \n />\n <span className=\"hidden sm:inline\">{prevPage.title}</span>\n </a>\n )}\n </div>\n\n {/* 다음 페이지 */}\n <div className=\"flex-1 flex justify-end\">\n {nextPage && (\n <a\n href={nextPage.href}\n className=\"group inline-flex items-center text-sm text-slate-600 hover:text-slate-900 dark:text-slate-400 dark:hover:text-slate-100 transition-colors\"\n >\n <span className=\"hidden sm:inline mr-2\">{nextPage.title}</span>\n <Icon \n name=\"chevronRight\" \n className=\"w-4 h-4 transition-transform group-hover:translate-x-1\" \n />\n </a>\n )}\n </div>\n </div>\n )\n }\n)\nPageNavigation.displayName = \"PageNavigation\"\n\nexport { PageNavigation } ","\"use client\"\n\nimport React from \"react\"\nimport { merge } from \"../lib/utils\"\n\n/**\n * LoadingSpinner 컴포넌트의 props / LoadingSpinner component props\n * @typedef {Object} LoadingSpinnerProps\n * @property {\"sm\" | \"md\" | \"lg\" | \"xl\"} [size=\"md\"] - Spinner 크기 / Spinner size\n * @property {\"default\" | \"dots\" | \"bars\" | \"ring\" | \"ripple\"} [variant=\"default\"] - Spinner 애니메이션 타입 / Spinner animation type\n * @property {string} [text] - Spinner 아래 표시할 텍스트 / Text to display below spinner\n * @property {\"default\" | \"primary\" | \"secondary\" | \"success\" | \"warning\" | \"error\" | \"glass\"} [color=\"default\"] - Spinner 색상 / Spinner color\n * @property {string} [className] - 추가 CSS 클래스 / Additional CSS class\n */\nexport interface LoadingSpinnerProps {\n size?: \"sm\" | \"md\" | \"lg\" | \"xl\"\n variant?: \"default\" | \"dots\" | \"bars\" | \"ring\" | \"ripple\"\n text?: string\n color?: \"default\" | \"primary\" | \"secondary\" | \"success\" | \"warning\" | \"error\" | \"glass\"\n className?: string\n}\n\n/**\n * LoadingSpinner 컴포넌트 / LoadingSpinner component\n * \n * 로딩 상태를 표시하는 스피너 컴포넌트입니다.\n * 다양한 애니메이션 타입과 크기를 지원합니다.\n * \n * Spinner component that displays loading state.\n * Supports various animation types and sizes.\n * \n * @component\n * @example\n * // 기본 사용 / Basic usage\n * <LoadingSpinner />\n * \n * @example\n * // 텍스트와 함께 / With text\n * <LoadingSpinner \n * text=\"로딩 중...\"\n * size=\"lg\"\n * color=\"primary\"\n * />\n * \n * @example\n * // 다양한 애니메이션 / Various animations\n * <LoadingSpinner variant=\"dots\" />\n * <LoadingSpinner variant=\"bars\" color=\"success\" />\n * <LoadingSpinner variant=\"ripple\" size=\"xl\" />\n * \n * @param {LoadingSpinnerProps} props - LoadingSpinner 컴포넌트의 props / LoadingSpinner component props\n * @returns {JSX.Element} LoadingSpinner 컴포넌트 / LoadingSpinner component\n */\nexport function LoadingSpinner({ \n className, \n size = \"md\", \n variant = \"default\", \n text, \n color = \"default\" \n}: LoadingSpinnerProps) {\n const sizeClasses = {\n sm: \"w-6 h-6\", // 24px - 더 넉넉한 크기\n md: \"w-8 h-8\", // 32px - 더 넉넉한 크기\n lg: \"w-12 h-12\", // 48px - 더 넉넉한 크기\n xl: \"w-16 h-16\" // 64px - 더 넉넉한 크기\n }\n\n // LoadingSpinner는 border 색상을 사용하므로 특화 색상 시스템 사용\n const spinnerColors: Record<string, string> = {\n default: \"border-gray-300 border-t-gray-600 dark:border-gray-600 dark:border-t-gray-300\",\n primary: \"border-blue-300 border-t-blue-600 dark:border-blue-600 dark:border-t-blue-300\",\n secondary: \"border-gray-300 border-t-gray-600 dark:border-gray-600 dark:border-t-gray-300\",\n success: \"border-green-300 border-t-green-600 dark:border-green-600 dark:border-t-green-300\",\n warning: \"border-yellow-300 border-t-yellow-600 dark:border-yellow-600 dark:border-t-yellow-300\",\n error: \"border-red-300 border-t-red-600 dark:border-red-600 dark:border-t-red-300\",\n glass: \"border-white/30 border-t-white/50 dark:border-slate-600/50 dark:border-t-slate-400/50\"\n }\n\n const renderSpinner = () => {\n switch (variant) {\n case \"dots\":\n return (\n <div className=\"flex space-x-1\">\n <div className=\"w-2 h-2 bg-current rounded-full animate-bounce\" />\n <div className=\"w-2 h-2 bg-current rounded-full animate-bounce delay-100\" />\n <div className=\"w-2 h-2 bg-current rounded-full animate-bounce delay-200\" />\n </div>\n )\n case \"bars\":\n return (\n <div className=\"flex space-x-1 h-full items-end\">\n <div className=\"w-1 bg-current animate-pulse\" style={{ height: '60%' }} />\n <div className=\"w-1 bg-current animate-pulse delay-100\" style={{ height: '80%' }} />\n <div className=\"w-1 bg-current animate-pulse delay-200\" style={{ height: '40%' }} />\n <div className=\"w-1 bg-current animate-pulse delay-300\" style={{ height: '100%' }} />\n <div className=\"w-1 bg-current animate-pulse delay-500\" style={{ height: '70%' }} />\n </div>\n )\n case \"ring\":\n return (\n <div className={merge(\n \"animate-spin rounded-full border-2\",\n spinnerColors[color] || spinnerColors.default\n )} />\n )\n case \"ripple\":\n return (\n <div className=\"relative\">\n <div className={merge(\n \"absolute inset-0 rounded-full border-2 animate-ping\",\n spinnerColors[color] || spinnerColors.default\n )} />\n <div className={merge(\n \"rounded-full border-2\",\n spinnerColors[color] || spinnerColors.default\n )} />\n </div>\n )\n default:\n return (\n <div className={merge(\n \"animate-spin rounded-full border-2\",\n spinnerColors[color] || spinnerColors.default\n )} />\n )\n }\n }\n\n return (\n <div className={merge(\"flex flex-col items-center justify-center\", className)}>\n <div className={merge(sizeClasses[size], \"text-gray-600 dark:text-gray-400\")}>\n {renderSpinner()}\n </div>\n {text && (\n <p className=\"mt-3 text-sm text-gray-600 dark:text-gray-400 text-center\">\n {text}\n </p>\n )}\n </div>\n )\n} ","'use client'\n\nimport React, { useState, useEffect } from 'react'\nimport { merge } from '../lib/utils'\nimport { LoadingSpinner } from './LoadingSpinner'\n\n/**\n * PageTransition 컴포넌트의 props / PageTransition component props\n * @typedef {Object} PageTransitionProps\n * @property {React.ReactNode} children - 페이지 내용 / Page content\n * @property {string} [className] - 추가 CSS 클래스 / Additional CSS class\n * @property {number} [duration=300] - 전환 지속 시간 (ms) / Transition duration (ms)\n * @property {'fade' | 'slide' | 'scale' | 'flip'} [variant='fade'] - 전환 애니메이션 타입 / Transition animation type\n * @property {'default' | 'dots' | 'bars' | 'ring' | 'ripple'} [loadingVariant='ripple'] - 로딩 스피너 타입 / Loading spinner type\n * @property {string} [loadingText='페이지 로딩 중...'] - 로딩 텍스트 / Loading text\n * @property {boolean} [showLoading=true] - 로딩 표시 여부 / Show loading\n * @property {() => void} [onTransitionStart] - 전환 시작 콜백 / Transition start callback\n * @property {() => void} [onTransitionEnd] - 전환 종료 콜백 / Transition end callback\n */\nexport interface PageTransitionProps {\n children: React.ReactNode\n className?: string\n duration?: number\n variant?: 'fade' | 'slide' | 'scale' | 'flip'\n loadingVariant?: 'default' | 'dots' | 'bars' | 'ring' | 'ripple'\n loadingText?: string\n showLoading?: boolean\n onTransitionStart?: () => void\n onTransitionEnd?: () => void\n}\n\n/**\n * PageTransition 컴포넌트 / PageTransition component\n * \n * 페이지 전환 애니메이션을 제공하는 컴포넌트입니다.\n * 다양한 전환 효과와 로딩 스피너를 지원합니다.\n * \n * Component that provides page transition animations.\n * Supports various transition effects and loading spinners.\n * \n * @component\n * @example\n * // 기본 사용 / Basic usage\n * <PageTransition>\n * <div>페이지 내용</div>\n * </PageTransition>\n * \n * @example\n * // Slide 전환 / Slide transition\n * <PageTransition\n * variant=\"slide\"\n * duration={500}\n * loadingVariant=\"dots\"\n * >\n * <div>페이지 내용</div>\n * </PageTransition>\n * \n * @param {PageTransitionProps} props - PageTransition 컴포넌트의 props / PageTransition component props\n * @param {React.Ref<HTMLDivElement>} ref - div 요소 ref / div element ref\n * @returns {JSX.Element} PageTransition 컴포넌트 / PageTransition component\n */\nexport const PageTransition = React.forwardRef<HTMLDivElement, PageTransitionProps>(({\n children,\n className,\n duration = 300,\n variant = 'fade',\n loadingVariant = 'ripple',\n loadingText = '페이지 로딩 중...',\n showLoading = true,\n onTransitionStart,\n onTransitionEnd\n}, ref) => {\n const [isLoading, setIsLoading] = useState(true)\n const [isVisible, setIsVisible] = useState(false)\n\n useEffect(() => {\n const timer = setTimeout(() => {\n setIsLoading(false)\n setIsVisible(true)\n onTransitionEnd?.()\n }, duration)\n\n onTransitionStart?.()\n\n return () => clearTimeout(timer)\n }, [duration, onTransitionStart, onTransitionEnd])\n\n const transitionClasses = {\n fade: merge(\n 'transition-opacity duration-300 ease-in-out',\n isVisible ? 'opacity-100' : 'opacity-0'\n ),\n slide: merge(\n 'transition-transform duration-300 ease-in-out',\n isVisible ? 'translate-x-0' : 'translate-x-full'\n ),\n scale: merge(\n 'transition-all duration-300 ease-in-out',\n isVisible ? 'scale-100 opacity-100' : 'scale-95 opacity-0'\n ),\n flip: merge(\n 'transition-all duration-500 ease-in-out',\n isVisible ? 'rotate-y-0 opacity-100' : 'rotate-y-90 opacity-0'\n )\n }\n\n if (isLoading && showLoading) {\n return (\n <div className={merge('flex flex-col items-center justify-center min-h-screen bg-gradient-to-br from-blue-50 to-purple-50 dark:from-slate-900 dark:to-slate-800', className)}>\n <LoadingSpinner\n size=\"lg\"\n variant={loadingVariant}\n text={loadingText}\n />\n </div>\n )\n }\n\n return (\n <div\n ref={ref}\n className={merge(\n 'w-full',\n transitionClasses[variant],\n className\n )}\n style={{ transitionDuration: `${duration}ms` }}\n >\n {children}\n </div>\n )\n})\n\nPageTransition.displayName = 'PageTransition'\n\n// Convenience components for different transition types\nexport const FadeTransition = React.forwardRef<HTMLDivElement, Omit<PageTransitionProps, 'variant'>>((props, ref) => (\n <PageTransition ref={ref} variant=\"fade\" {...props} />\n))\n\nexport const SlideTransition = React.forwardRef<HTMLDivElement, Omit<PageTransitionProps, 'variant'>>((props, ref) => (\n <PageTransition ref={ref} variant=\"slide\" {...props} />\n))\n\nexport const ScaleTransition = React.forwardRef<HTMLDivElement, Omit<PageTransitionProps, 'variant'>>((props, ref) => (\n <PageTransition ref={ref} variant=\"scale\" {...props} />\n))\n\nexport const FlipTransition = React.forwardRef<HTMLDivElement, Omit<PageTransitionProps, 'variant'>>((props, ref) => (\n <PageTransition ref={ref} variant=\"flip\" {...props} />\n))\n\n// Add displayName for convenience components\nFadeTransition.displayName = 'FadeTransition'\nSlideTransition.displayName = 'SlideTransition'\nScaleTransition.displayName = 'ScaleTransition'\nFlipTransition.displayName = 'FlipTransition' "]}
@@ -0,0 +1,2 @@
1
+ export{a as PageNavigation,c as PageTransition}from'./chunk-MXGXBG63.mjs';import'./chunk-UGSYQDR4.mjs';import'./chunk-UUHAXGMO.mjs';//# sourceMappingURL=navigation.mjs.map
2
+ //# sourceMappingURL=navigation.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"navigation.mjs"}